Template
Siftline
A search modal in a BI and AI-analyst workspace that finds dashboards, metric fields and settings from one query. Filters narrow by item type, date and creator, and results are grouped so users can jump straight to the right object.
Analytics workspace global search modal with filter chips and grouped results · App screen: search · 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 500, 20px search input
- InterBody: Inter 400 16px body; 15px row titles (500); 13px descriptions and group labels
Patterns
- global search modal over dimmed app
- filter chip dropdowns (Item type, Date, Created by)
- collapsible result groups with tinted headers
- result row with type icon, title and one-line description
- clear-input icon button
- dark top bar with New / Browse / Metrics / Ask AI
- left thread history list
- context crumb for AI analyst
States it is designed for
- Empty query (recent items and saved searches)
- Loading (row skeletons per group)
- No results with suggestion to clear filters
- Partial results with a failed group ("Couldn't load settings -- retry")
- Long descriptions truncated to one line with tooltip
- Permission-limited results ("Some items hidden")
Who it is for
- Data analysts and analytics engineers
- Business users asking an AI analyst questions
- Workspace admins managing connections
Layout
- Dark top bar: logo tile; New, Browse, Metrics, Ask AI; right: settings, bell, help, updates badge, project switcher, avatar
- Left rail: "New thread" and RECENT thread titles list with "View more"
- Main (dimmed): AI analyst chat context with model picker
- Search modal (~530px, top 60px): input with clear button; filter chips row; groups (Dashboards, Fields, Settings) with collapse chevrons; rows with icon tile, title, sub text
- Mobile: modal full screen with sticky input
Palette
efficient, analytical, crisp, calm. A precise instrument for finding the right number fast.
- top bar background
#1a1a1f - top bar text
#ffffff - modal and page background
#ffffff - group header fill
#f8f9fa - row titles
#1a1b1e - row descriptions, group labels
#5c5f66 - filter chip outline
#868e96 - logo tile, selected row bar, focus
#7048e8 - updates count badge
#e03131 - dashboard type icon
#2b8a3e
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | row title | 17.22:1 | 4.5:1 |
| Aa | muted description | 6.40:1 | 4.5:1 |
| Aa | group label on group fill | 6.07:1 | 4.5:1 |
| Aa | top bar text | 17.33:1 | 4.5:1 |
| chip border | 3.32:1 | 3:1 | |
| selected bar / focus | 5.55:1 | 3:1 | |
| dashboard icon | 4.14:1 | 3:1 | |
| Aa | badge text | 4.51: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 500, 20px search input
- Body
- Inter 400 16px body; 15px row titles (500); 13px descriptions and group labels
Similar to the observed system grotesk. Group labels sentence case 13px 500.
Spacing and imagery
Dense: 4px base; rows 52px with 12px padding; group headers 32px; chips 28px tall; radius 8px modal, 6px chips and icon tiles; modal shadow 0 20px 50px rgba(0,0,0,.25).
No imagery. Type icons in small grey tiles (dashboard grid, number "123", database, validator, user).
Components
- Dark top bar with nav buttons
- Thread history list
- Search modal
- Search input with clear
- Filter chip dropdown (multi-select)
- Collapsible result group
- Result row (icon tile, title, emoji/icon, description)
- Keyboard hint footer
Interactions
- Cmd/Ctrl+K opens; Esc closes; arrows move across groups; Enter opens; Cmd/Ctrl+Enter opens in new tab
- Typing debounced 150ms; matched terms highlighted
- Chips open popovers with checkboxes and date presets; active chips show count and a clear x
- Group headers collapse/expand and remember state
- Hover and keyboard selection share the same highlight
Data
SearchItem{id, type (dashboard|chart|field|metric|setting|space), title, description, project_id, created_by, updated_at}Project{id, name}Thread{id, user_id, title, created_at}SavedSearch{id, user_id, query, filters jsonb}
Guardrails
Experience
- Group results by object type in a fixed, predictable order
- Show where each result lives (project or "Your settings")
- Keep filters visible and clearable in one click
- Remember the last query for the session
- Show a footer hint for keyboard shortcuts
Accessibility
- Combobox + listbox with group roles (role="group" with aria-labelledby per section)
- Collapse toggles are buttons with aria-expanded
- Highlight is not colour-only (bold text on matches)
- Filter popovers are keyboard operable and announce selected counts
- Modal traps focus and restores it
Security
- Search runs server-side with row-level permissions; never return items the user cannot open
- Full-text query parameterised; highlight snippets escaped
- Rate-limit search requests per user
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 **Siftline**, the global search modal of an analytics workspace with an AI analyst. One query returns dashboards, metric fields and settings, grouped by type. Filter chips narrow by item type, date and creator. The modal opens over the analyst chat view.
### Stack
React + TypeScript + Vite, Tailwind CSS, shadcn/ui (Command, Popover, Checkbox, Collapsible) on Radix, lucide-react, TanStack Query, date-fns for date presets. Supabase Postgres full-text search behind an RPC that applies permissions.
### Pages & layout
1. **Top bar** (dark): violet logo tile; New, Browse, Metrics, Ask AI; on the right settings, bell, help, an updates icon with a red count badge, a project switcher ("Harbor Coffee Co.") and avatar.
2. **Left rail**: "New thread" and a RECENT list of thread titles such as "Revenue trend, last 30 days" and "Top products by margin", with "View more".
3. **Main** (dimmed): analyst chat with a model picker.
4. **Search modal** (560px wide, 60px from the top): search icon, input, clear button; filter chips (Item type, Date, Created by); groups Dashboards, Fields and Settings on light grey header bars with collapse chevrons; rows with an icon tile, a title and a one-line description or location ("Current project", "Your settings").
5. Mobile: full-screen modal with a sticky input and horizontally scrolling chips.
### Design system
- Colors: `--topbar: #1a1a1f` (top bar background), `--on-topbar: #ffffff` (top bar text), `--bg: #ffffff` (modal and page background), `--group: #f8f9fa` (group header fill), `--fg: #1a1b1e` (row titles), `--muted: #5c5f66` (row descriptions, group labels), `--chip-border: #868e96` (filter chip outline), `--brand: #7048e8` (logo tile, selected row bar, focus), `--badge: #e03131` (updates count badge), `--success: #2b8a3e` (dashboard type icon).
- Fonts: Inter (similar to the observed system grotesk): input 20px/500, row titles 15px/500, body 16px/1.5, descriptions and group labels 13px.
- Spacing: 4px base; 52px rows; 32px group headers; 28px chips.
- Radius: modal 8px; chips and icon tiles 6px.
- Shadows: modal `0 20px 50px rgba(0,0,0,.25)`; scrim 40% black.
- Motion: 120ms modal fade; 150ms collapse; none under reduced motion.
### Components & interactions
TopBar, ThreadList, SearchDialog, SearchInput (clear, 150ms debounce), FilterChip (popover with checkboxes, date presets like Last 7 days, count and clear x when active), ResultGroup (collapsible, remembered), ResultRow (icon by type, highlighted matches, location line), FooterHints (arrow keys, Enter, Cmd/Ctrl+Enter, Esc). Cmd/Ctrl+K opens; arrows traverse groups; Enter navigates; Cmd/Ctrl+Enter opens in a new tab.
### Data & state
A view `search_items(id, type, title, description, project_id, created_by, updated_at, tsv)`, plus `projects`, `threads(id, user_id, title)` and `saved_searches(id, user_id, query, filters)`. Seed about 30 invented dashboards, fields and settings. Keep filter state in the modal and the last query in session storage. Handle states: empty query (recents), loading skeletons, no results, a failed group with retry, truncation, hidden-items notice.
### Accessibility
Use combobox and listbox semantics; each group is `role="group"` labelled by its header; collapse buttons expose aria-expanded. Mark matches with bold weight as well as colour. Filter popovers are keyboard-operable and announce counts. Focus is trapped and restored. Focus ring: 2px violet.
Verified contrast: row title: #1a1b1e on #ffffff = 17.22:1; muted description: #5c5f66 on #ffffff = 6.40:1; group label on group fill: #5c5f66 on #f8f9fa = 6.07:1; top bar text: #ffffff on #1a1a1f = 17.33:1; chip border: #868e96 on #ffffff = 3.32:1; selected bar / focus: #7048e8 on #ffffff = 5.55:1; dashboard icon: #2b8a3e on #f8f9fa = 4.14:1; badge text: #ffffff on #e03131 = 4.51:1.
### Security
The search RPC runs with the caller's permissions (RLS on source tables by project membership) so no hidden object leaks into results. Parameterise the full-text query and escape snippets. Rate-limit to 10 requests per second per user.
### Performance & SEO
Cancel in-flight requests on new keystrokes. Cap results at 8 per group with "Show all". Prefetch the top result on highlight. The app is noindex.
### Guardrails
- Invented project, metric and thread names.
- Group order stays fixed: Dashboards, Charts, Fields, Spaces, Settings.
- Acceptance criteria: (1) Cmd/Ctrl+K opens from anywhere; (2) filters combine and clear; (3) groups collapse and persist; (4) permissions are respected; (5) every state renders with mock data; (6) full keyboard use works.