Skip to main content
vibld

Template

Rastelo

The history of natural-language event searches in a news data product. Each card shows the query, run status, age and mode; finished searches can be downloaded, and all can be re-run, duplicated or deleted.

Past-searches list with status and actions · App screen: playground · 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, 26px title
  • InterBody: Inter 400, 16px; query 16px 600, meta 14px, line-height 1.5

Patterns

  • title with refresh spinner and count
  • search input with Filters button
  • list of query cards
  • status dot plus label
  • relative time and mode meta
  • download and overflow icon buttons
  • referral card in sidebar footer
  • floating support chat bubble

States it is designed for

  • loading skeleton cards
  • empty: 'No searches yet' with New search button
  • no matches for filter with Clear filters
  • in progress
  • completed
  • failed with reason and Re-run
  • deleting (row fades)
  • download error toast

Who it is for

  • analysts and developers using a news events API
  • research teams revisiting earlier queries

Layout

  1. sidebar (shared) with Past searches active and a referral card at the bottom
  2. header: title, refresh indicator, count
  3. search input full width with Filters
  4. stack of full-width cards
  5. support chat bubble bottom-right
  6. below 768px the sidebar collapses and card actions move into the overflow menu

Palette

Orderly and scannable, like a job queue.

  • bg#f5f6fa
  • card#ffffff
  • text#15181f
  • muted#5b6170
  • running#2f55d4
  • done#1d864a
  • failed#c62828
  • active#e7ecfb
  • border#8b91a0

Every checked pair, measured again

SampleWhereRatioNeeds
Aaquery text17.76:14.5:1
Aameta text6.20:14.5:1
Aain-progress label6.23:14.5:1
Aacompleted label4.60:14.5:1
Aafailed label5.62:14.5:1
Aaactive nav text5.28:14.5:1
input border3.16:13:1
focus ring5.77:13: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, 26px title
Body
Inter 400, 16px; query 16px 600, meta 14px, line-height 1.5

Status label 14px 500 next to an 8px dot.

Spacing and imagery

Density: Medium. Grid: 8px; card padding 16px; 8px between cards. Container: fluid, max 1080px. Radius: 8px cards and input; 6px icon buttons. Shadows: Cards 1px border, no shadow.

None; line icons for actions.

Components

  • PageHeader with RefreshIndicator
  • SearchInput
  • FiltersPopover (status, mode, date range)
  • SearchCard
  • StatusDot
  • RowActions (download, overflow)
  • ReferralCard
  • SupportBubble
  • EmptyState

Interactions

  • Clicking a card opens that search's results
  • Download exports results as CSV or JSON (completed only)
  • Overflow: Re-run, Duplicate & edit, Rename, Delete (confirm)
  • Search filters by query text (debounced)
  • In-progress rows update via polling

Data

  • Search{id, project_id, query, mode (lite|base), status (queued|running|done|failed), results_count, created_at, finished_at}
  • Export{id, search_id, format (csv|json), url, expires_at}

Guardrails

Experience

  • Show status in text next to the dot
  • Only show Download when results exist
  • Relative times with exact time on hover
  • Keep destructive Delete behind confirmation
  • Keep filters visible as removable chips when applied

Accessibility

  • Each card is a link with the query as its name; action buttons are separate focus stops with labels
  • Status not by colour alone
  • Live region announces when a search completes
  • Filters popover is keyboard navigable
  • Support bubble has an accessible name and doesn't cover actions

Security

  • RLS: searches visible only to project members
  • Exports use short-lived signed URLs
  • Rate-limit re-runs
  • Delete is soft with 30-day restore for admins

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 **Rastelo**, the past-searches page of a news data product: a searchable, filterable list of earlier queries with status, time and mode, plus download and row actions. Build the sidebar shell, the list and all states.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui on Radix primitives and lucide-react icons. TanStack Query for server state, react-hook-form + zod for every form, date-fns for relative times. Supabase for Auth, Postgres with row-level security and Edge Functions for anything that needs a secret.

### Pages & layout
1. **Header**: title with spinner while any search runs; count below.
2. **Search + Filters** row.
3. **Cards**: query as heading; status dot and label, relative time, mode; download (if done) and overflow.
4. **Sidebar footer** referral card; support bubble.

### Design system
- Colors: `--bg: #f5f6fa` (page), `--card: #ffffff` (cards), `--text: #15181f` (primary text), `--muted: #5b6170` (meta text), `--running: #2f55d4` (in-progress status), `--done: #1d864a` (completed status), `--failed: #c62828` (failed status), `--active: #e7ecfb` (active nav item), `--border: #8b91a0` (input border).
- Fonts: Inter 600, 26px title for headings; Inter 400, 16px; query 16px 600, meta 14px, line-height 1.5 for body. Status label 14px 500 next to an 8px dot.
- Spacing: Medium. 8px; card padding 16px; 8px between cards. Container: fluid, max 1080px.
- Radius: 8px cards and input; 6px icon buttons.
- Shadows: Cards 1px border, no shadow.
- Motion: Refresh icon spins while any search is running; new searches slide in at the top; status transitions crossfade.

### Components & interactions
SearchCard lays out the query on the first line and meta on the second; actions align right and vertically centre.

- Clicking a card opens that search's results
- Download exports results as CSV or JSON (completed only)
- Overflow: Re-run, Duplicate & edit, Rename, Delete (confirm)
- Search filters by query text (debounced)
- In-progress rows update via polling

### Data & state
Seed six invented searches across statuses. Poll every 5s while any are running. Filters in URL params.

Entities: `Search{id, project_id, query, mode (lite|base), status (queued|running|done|failed), results_count, created_at, finished_at}`; `Export{id, search_id, format (csv|json), url, expires_at}`.

States to build and show in a dev-only state switcher:
- loading skeleton cards
- empty: 'No searches yet' with New search button
- no matches for filter with Clear filters
- in progress
- completed
- failed with reason and Re-run
- deleting (row fades)
- download error toast

### Accessibility
- Each card is a link with the query as its name; action buttons are separate focus stops with labels
- Status not by colour alone
- Live region announces when a search completes
- Filters popover is keyboard navigable
- Support bubble has an accessible name and doesn't cover actions
Verified contrast: query text: #15181f on #ffffff = 17.76:1; meta text: #5b6170 on #ffffff = 6.2:1; in-progress label: #2f55d4 on #ffffff = 6.23:1; completed label: #1d864a on #ffffff = 4.6:1; failed label: #c62828 on #ffffff = 5.62:1; active nav text: #2f55d4 on #e7ecfb = 5.28:1; input border: #8b91a0 on #ffffff = 3.16:1; focus ring: #2f55d4 on #f5f6fa = 5.77:1.

### Security
- RLS: searches visible only to project members
- Exports use short-lived signed URLs
- Rate-limit re-runs
- Delete is soft with 30-day restore for admins
RLS detail: `searches` select/insert/delete for project members (delete for creator or admin); `exports` select for members of the search's project; storage bucket private.

### Performance & SEO
Paginate 25 per page with infinite scroll; private route noindex.

### Guardrails
- Show status in text next to the dot
- Only show Download when results exist
- Relative times with exact time on hover
- Keep destructive Delete behind confirmation
- Keep filters visible as removable chips when applied
- Write fresh, generic copy and invented sample data; no real brands, logos, product names or people.
- Keep components small and typed (no `any`); surface every error visibly with a way to recover.

Acceptance criteria:
- Status updates live
- Download works for completed searches
- Filters and search combine
- Delete confirms
- Keyboard access to every action

Open the builderAll templatesThis palette on its own