Template
Quarrylist
A contact list page in a contact-data enrichment tool, showing found work emails and letting the user export the list. The export popover asks which contacts to include and which email quality tiers (verified, likely valid, catch-all) to keep, each with an expected accuracy badge, so users avoid bounces.
Enriched contact list with export popover and email-quality filters · App screen: import export · Small tools and apps · full-stack app (auth + DB)
A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.
Start from this screenRead the build prompt
Typefaces
The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.
- InterHeadings: Inter 600, 24px list title; 20px section header
- InterBody: Inter 400 16px/1.5; 15px in the table
Patterns
- top nav with pill-highlighted active tab
- credit balance chip with upgrade pill
- stat card with ring progress
- status pill (done with count)
- export popover with radio scope and checkbox quality tiers
- confidence badges per tier
- illustrated checkbox cards
States it is designed for
- enrichment running (status pill 'Running' with progress)
- done
- no emails found for some contacts (dash + reason)
- export count zero (Export disabled with hint)
- exporting (spinner)
- export ready (toast with download)
- insufficient credits (upgrade prompt)
- empty list (enrich or import CTA)
Who it is for
- sales development reps
- recruiters
- growth marketers
Layout
- top nav: round logo, tabs (Enrichment active in a lavender pill, API console, Integrations, List builder); right: credit chip, pink Upgrade pill, settings menu with account domain
- page header: list name; right 'credits used' note and green outlined Done status pill with count
- stat card: coloured icon + 'Work emails' with found/total and a ring progress with percent and sources
- section header: '{n} contacts', secondary 'Enrich new contact', purple Download with icon
- table: contact (name + title), company (globe icon + name), work email (icon + address + help), more columns
- export popover anchored to Download: Export radio cards (all contacts / contacts with emails, with counts), 'Emails to include' checkbox cards with small illustrations and confidence badges
- mobile: table becomes cards; popover becomes a bottom sheet
Palette
Confident and transactional; purple for actions, green/amber for data quality.
- page background
#ffffff - primary text
#1b1b1f - secondary text
#63636e - primary / download
#6a3cf0 - selected card fill
#efeefa - valid badge
#157347 - likely badge
#1f7a4d - catch-all badge
#a15500 - credit chip fill
#fff4cc - credit chip text
#6b4e00 - upgrade pill
#d61f69 - card border
#e4e4ea
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.17:1 | 4.5:1 |
| Aa | muted text | 5.93:1 | 4.5:1 |
| Aa | download label | 5.97:1 | 4.5:1 |
| Aa | text on selected card | 14.95:1 | 4.5:1 |
| Aa | valid badge text | 5.87:1 | 4.5:1 |
| Aa | catch-all badge text | 5.50:1 | 4.5:1 |
| Aa | credit chip text | 7.02:1 | 4.5:1 |
| Aa | upgrade pill label | 4.93:1 | 4.5:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent
- destructive *
Type scale
- Display
- Inter 600, 24px list title; 20px section header
- Body
- Inter 400 16px/1.5; 15px in the table
Stat value 24px 600 tabular; popover labels 14px 600; badges 12px 600.
Spacing and imagery
Medium: table rows 48px; popover 320px wide, 12px radius, 0 12px 32px shadow; option cards 56px with 8px radius; buttons 36px, 6px radius.
Tiny envelope illustrations with check/question marks on the quality cards; coloured line icons in the stat card; no photos.
Components
- TopNav (tabs, CreditChip, UpgradePill, AccountMenu)
- ListHeader with StatusPill
- StatCard with RingProgress
- ContactsTable
- DownloadButton
- ExportPopover (ScopeRadioCards, QualityCheckboxCards, ConfidenceBadge, format select, Export button)
- EnrichContactDialog
Interactions
- Download opens the popover; Escape or outside click closes it
- scope radios and quality checkboxes update the live count on the Export button ('Export 1 contact')
- format select (CSV / spreadsheet)
- export runs server-side and downloads; large exports email a link
- help icon next to an email explains its quality tier
Data
ContactList{id, workspace_id, name, status (running|done|failed), credits_used, created_at}Contact{id, list_id, full_name, title, company_name, company_domain, work_email, email_quality (valid|likely|catch_all|none), sources int}ExportJob{id, list_id, scope (all|with_email), qualities text[], format (csv|xlsx), status, file_path, created_by}
Guardrails
Experience
- Show expected accuracy next to each quality tier so users choose knowingly.
- Default to the two safest tiers; leave catch-all unchecked.
- Reflect the resulting row count on the Export button in real time.
- Keep the popover compact; move rarely used options (columns) behind 'More options'.
- Never charge credits for exporting data already paid for; say so.
Accessibility
- Popover is a dialog with a heading; scope is a radio group and qualities a checkbox group, each with legends.
- Confidence badges include text ('99% accurate'), not just icons.
- Ring progress has a text equivalent.
- Table has column headers and a caption with the list name.
- Status pill conveys state in text.
Security
- RLS: lists, contacts and export jobs scoped to workspace members.
- Neutralise spreadsheet formula injection in exported cells.
- Export files live in a private bucket with 24h signed links; purge after 7 days.
- Log exports (who, how many rows) for data-protection accountability; minimise fields exported by default.
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack entries) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs. ### SaaS screen baseline - Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs. - Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible. - Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy. - Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke. - Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Quarrylist**, the contact list page of an email-enrichment tool, centred on its export popover. Users see enrichment results and export contacts filtered by scope and email-quality tier, with accuracy badges and a live row count.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Popover, RadioGroup, Checkbox, Select, Table, Dialog), lucide-react, TanStack Query and Table, react-hook-form + zod. Supabase Auth, Postgres, Storage and an Edge Function that builds export files.
### Pages & layout
1. **App shell** with top nav.
2. **/lists/:id**: header, stat card, table, export popover.
3. **Enrich contact dialog** (name + company domain).
4. Mobile: cards and bottom-sheet export.
### Design system
- Colors: `--bg: #ffffff` (page background), `--fg: #1b1b1f` (primary text), `--muted: #63636e` (secondary text), `--primary: #6a3cf0` (primary / download), `--selected: #efeefa` (selected card fill), `--valid: #157347` (valid badge), `--likely: #1f7a4d` (likely badge), `--catchall: #a15500` (catch-all badge), `--credit: #fff4cc` (credit chip fill), `--credit-fg: #6b4e00` (credit chip text), `--upgrade: #d61f69` (upgrade pill), `--border: #e4e4ea` (card border).
- Fonts: Inter 600, 24px list title; 20px section header for headings; Inter 400 16px/1.5; 15px in the table for body. Stat value 24px 600 tabular; popover labels 14px 600; badges 12px 600.
- Spacing: Medium: table rows 48px; popover 320px wide, 12px radius, 0 12px 32px shadow; option cards 56px with 8px radius; buttons 36px, 6px radius.
- Radius: 12px popover and stat card, 8px option cards, 6px buttons, full pills for status and credits.
- Shadows: popover only.
- Motion: 150ms popover fade/scale; ring progress animates once.
### Components & interactions
TopNav, CreditChip, UpgradePill, AccountMenu, ListHeader, StatusPill, StatCard, RingProgress, ContactsTable, DownloadButton, ExportPopover, ScopeRadioCards, QualityCheckboxCards, ConfidenceBadge, EnrichContactDialog.
Interactions: Download opens the popover; Escape or outside click closes it; scope radios and quality checkboxes update the live count on the Export button ('Export 1 contact'); format select (CSV / spreadsheet); export runs server-side and downloads; large exports email a link; help icon next to an email explains its quality tier.
States to build: enrichment running (status pill 'Running' with progress); done; no emails found for some contacts (dash + reason); export count zero (Export disabled with hint); exporting (spinner); export ready (toast with download); insufficient credits (upgrade prompt); empty list (enrich or import CTA).
### Data & state
Export count = contacts matching scope and selected qualities, computed client-side from the loaded list (server-side for >5k). Export jobs return a signed URL. Seed a list 'Q3 partners' with 12 invented contacts across four quality tiers.
Model: `ContactList{id, workspace_id, name, status (running|done|failed), credits_used, created_at}`; `Contact{id, list_id, full_name, title, company_name, company_domain, work_email, email_quality (valid|likely|catch_all|none), sources int}`; `ExportJob{id, list_id, scope (all|with_email), qualities text[], format (csv|xlsx), status, file_path, created_by}`.
### Accessibility
Popover is a dialog with a heading; scope is a radio group and qualities a checkbox group, each with legends. Confidence badges include text ('99% accurate'), not just icons. Ring progress has a text equivalent. Table has column headers and a caption with the list name. Status pill conveys state in text.
Verified contrast: body text: #1b1b1f on #ffffff = 17.17:1; muted text: #63636e on #ffffff = 5.93:1; download label: #ffffff on #6a3cf0 = 5.97:1; text on selected card: #1b1b1f on #efeefa = 14.95:1; valid badge text: #157347 on #ffffff = 5.87:1; catch-all badge text: #a15500 on #ffffff = 5.5:1; credit chip text: #6b4e00 on #fff4cc = 7.02:1; upgrade pill label: #ffffff on #d61f69 = 4.93:1.
### Security
RLS: lists, contacts and export jobs scoped to workspace members. Neutralise spreadsheet formula injection in exported cells. Export files live in a private bucket with 24h signed links; purge after 7 days. Log exports (who, how many rows) for data-protection accountability; minimise fields exported by default. RLS per table: `contact_lists`, `contacts`, `export_jobs` select/insert for workspace members; updates to contacts only via enrichment functions; `export_jobs` file paths readable only by creator via signed URL.
### Performance & SEO
Paginate table at 100; generate exports in a background function. App routes noindex.
### Guardrails
- Show expected accuracy next to each quality tier so users choose knowingly.
- Default to the two safest tiers; leave catch-all unchecked.
- Reflect the resulting row count on the Export button in real time.
- Keep the popover compact; move rarely used options (columns) behind 'More options'.
- Never charge credits for exporting data already paid for; say so.
- Write all copy fresh; use invented people, companies and numbers only. No real brands, logos, wordmarks or third-party product names anywhere in the UI or seed data.
- Do not trace or copy any existing product's layout assets, icons or illustrations; draw generic ones.
- Acceptance criteria:
- [ ] Popover shows scope and quality options with badges
- [ ] Export count updates live
- [ ] Catch-all is unchecked by default
- [ ] Exported CSV contains only selected rows and is formula-safe
- [ ] Popover is fully keyboard accessible