Template
Xylo Desk
The overview page of a news-search API during a free trial. It gets a developer from sign-up to a first successful request by surfacing the trial key, a playground link and docs, then shows how many trial calls remain and when the trial expires.
API trial overview with first-call card and calls-left meter · App screen: usage · 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 page title, card titles 17px 600
- InterBody: Inter 400 16px / 1.5; helper lines 14px
Patterns
- persistent left sidebar with collapsible product groups
- status badge beside page title
- first-call quick-start card
- masked key field with show and copy
- primary + secondary button pair
- calls-remaining progress card
- floating support chat launcher
States it is designed for
- Loading: skeleton card blocks
- No calls yet: tip line suggests a first query
- After first call: card shows a success check and 'See usage' link
- Trial nearly expired (<2 days): amber badge and banner with upgrade
- Trial expired: badge 'Trial ended', key disabled, CTA to choose a plan
- Copy failed (clipboard blocked): tooltip with instructions to select manually
- Error loading key: inline error with Retry
Who it is for
- developers evaluating a data API
- product engineers building news or monitoring features
- technical buyers on a trial
Layout
- Left sidebar (240px, light grey): wordmark with collapse chevron; collapsible group for the events product with a project picker and search/monitoring links; collapsible group for the search API (Overview active, Playground); 'Manage' group (API keys, Usage, Billing) with an inbox icon badge; account footer with initials avatar, name, account type and credit count
- Main (fluid, 24px gutters): H1 with a small uppercase 'Trial active' badge
- Card 1 'Make your first call': short explainer, 'Your trial key' label, masked key field with Show and Copy, helper line, black 'Open playground' button with arrow and grey 'Read the docs' button, divider, starter tip line
- Card 2: '2,500 calls left' label, full-width progress bar, 'Expires in 8 days' caption
- Bottom-right floating chat launcher
- Below 1024px the sidebar collapses to icons; below 640px buttons stack full width and key field wraps
Palette
Practical and welcoming, like a well-organised lab bench: black-and-white with one saturated blue for progress.
- canvas
#f5f6f8 - surface
#ffffff - sidebar
#f7f8fa - text
#141414 - muted
#61646b - border
#e3e5ea - input-border
#878b94 - primary
#111111 - on-primary
#ffffff - meter
#2340d8 - nav-active-bg
#e8ebfb - trial-badge
#1d7a45
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 18.42:1 | 4.5:1 |
| Aa | muted helper | 5.93:1 | 4.5:1 |
| Aa | nav text on sidebar | 17.34:1 | 4.5:1 |
| Aa | primary button label | 18.88:1 | 4.5:1 |
| Aa | trial badge text | 5.35:1 | 4.5:1 |
| Aa | active nav label | 6.33:1 | 4.5:1 |
| meter bar | 7.51:1 | 3:1 | |
| input border | 3.41:1 | 3: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 page title, card titles 17px 600
- Body
- Inter 400 16px / 1.5; helper lines 14px
Key value in JetBrains Mono 15px with 0.02em tracking. Badges and group labels 12px uppercase 0.06em.
Spacing and imagery
Comfortable; 4px base; card padding 20-24px, 16px between cards; radius 8px cards, 6px buttons and key field; shadows none, 1px borders; progress bar 4px tall.
No imagery; small outline icons in nav; the chat launcher is a solid dark circle with a speech icon.
Components
- Sidebar with collapsible groups and ProjectPicker
- TitleBadge
- FirstCallCard
- MaskedKeyField (Show/Copy)
- PrimaryButton + SecondaryButton
- StarterTip
- CallsLeftMeter
- AccountFooter
- ChatLauncher
- Toast
Interactions
- Show toggles the key between masked and full; Copy copies and shows 'Copied' for 2s
- Playground opens a split request builder with the trial key pre-filled
- Group chevrons collapse/expand with 150ms height animation and remember state
- The first-call card's tip line changes to reflect the user's recent queries once they make calls
- Meter animates on load and turns amber under 10% remaining
Data
Account{id, name, type (personal|team), credits}Trial{account_id, calls_total, calls_used, expires_at, status (active|ended)}ApiKey{id, account_id, label, prefix, secret_hash, is_trial, created_at}Project{id, account_id, name}
Guardrails
Experience
- Put the trial key and the next action (playground) above the fold
- Show calls left as a number plus a bar and the expiry date in words
- Keep the secondary docs button clearly less prominent than the playground
- Explain the key's scope in the helper line and link to key management
- Never block the page with the chat launcher; keep it bottom-right, small
Accessibility
- Masked key field has an accessible name and the Show button uses aria-pressed
- Copy result announced via aria-live='polite'
- Progress bar exposes value, max and text equivalent
- Trial badge text meets 4.5:1 and is not colour-only
- Collapsible nav groups use buttons with aria-expanded
Security
- Store only a hash of the key; reveal the plaintext trial key once per session via an authenticated Edge Function
- RLS: api_keys, trials and projects readable only by the owning account
- Rate-limit key reveal and playground calls
- Trial calls enforced server-side, never by the client meter
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 **Xylo Desk**, the overview page of a news-search API during a free trial. It must get a developer to their first successful call fast (trial key, playground, docs) and show how many trial calls remain and when the trial ends. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react, TanStack Query, zod, date-fns (relative expiry). Supabase Auth and Postgres; one Edge Function reveals the trial key and another proxies playground calls. ### Pages & layout 1. **Sidebar**: wordmark with collapse; collapsible 'Events API' group (project picker, New search, Past searches, Monitoring, Company watchlist); collapsible 'Search API' group (Overview active, Playground); 'Manage' group (API keys, Usage, Billing); account footer with initials avatar, name, account type and credits. 2. **Overview**: H1 with 'Trial active' badge; first-call card (title, explainer, key label, masked key field with Show and Copy, helper line, 'Open playground' + 'Read the docs', divider, starter tip); calls-left card (number label, progress bar, expiry caption). 3. **Playground** (linked): request builder left, JSON response right, trial key pre-filled. 4. Floating chat launcher bottom-right. Responsive: icon-only sidebar under 1024px, stacked buttons under 640px. ### Design system - Colors: `--canvas: #f5f6f8`, `--surface: #ffffff`, `--sidebar: #f7f8fa`, `--text: #141414`, `--muted: #61646b`, `--border: #e3e5ea`, `--input-border: #878b94`, `--primary: #111111`, `--on-primary: #ffffff`, `--meter: #2340d8`, `--nav-active-bg: #e8ebfb`, `--trial-badge: #1d7a45`. - Fonts: Inter 400/600, 16px/1.5 body, 24px H1; JetBrains Mono 15px for the key. - Spacing: 4px scale; card padding 24px; 16px card gap; sidebar items 36px. - Radius: 8px cards, 6px buttons/fields, 4px badges. - Shadows: none; cards separated by 1px `--border`. Chat launcher 0 4px 12px rgba(0,0,0,.15). - Motion: 150ms group collapse; meter fill 400ms ease-out (off with reduced motion). ### Components & interactions Sidebar (collapsible groups with aria-expanded, active item tinted `--nav-active-bg` with blue label), ProjectPicker, TitleBadge, FirstCallCard, MaskedKeyField (Show with aria-pressed, Copy with live 'Copied' message and clipboard fallback), ButtonPair, StarterTip (dynamic text), CallsLeftMeter (amber below 10%), TrialBanner (ending / ended), AccountFooter, ChatLauncher. ### Data & state Tables `accounts`, `trials(account_id, calls_total, calls_used, expires_at, status)`, `api_keys(id, account_id, prefix, secret_hash, is_trial)`, `projects`, `query_log(account_id, query, created_at)` for tip personalisation. TanStack Query for trial and key metadata; the plaintext key is fetched on demand and kept in memory only. Seed: trial with 2,500 of 2,500 calls, 8 days left; a second state with 40 calls left and 1 day left; an ended trial. ### Accessibility Label the key field, announce copy results, expose progressbar values and text, use aria-expanded on groups, keep badge text readable, ensure the chat launcher has an accessible name and does not cover focusable content at 200% zoom. Verified contrast: body text: #141414 on #ffffff = 18.42:1; muted helper: #61646b on #ffffff = 5.93:1; nav text on sidebar: #141414 on #f7f8fa = 17.34:1; primary button label: #ffffff on #111111 = 18.88:1; trial badge text: #1d7a45 on #ffffff = 5.35:1; active nav label: #2340d8 on #e8ebfb = 6.33:1; meter bar: #2340d8 on #ffffff = 7.51:1; input border: #878b94 on #ffffff = 3.41:1. ### Security Hash keys at rest; reveal via authenticated Edge Function with rate limit and audit log. RLS: `trials`, `api_keys`, `projects`, `query_log` restricted to `account_id = auth.uid()` (or team membership). Playground proxy enforces trial limits server-side and never exposes the service key. Validate playground params with zod. ### Performance & SEO Code-split the playground. Prefetch trial data on login. Console routes noindex; initial JS under 150KB gzipped. ### Guardrails - Invented queries, names and figures only. - Never show the full key by default. - Acceptance criteria: (1) Show/Copy work and announce; (2) meter reflects server count; (3) ending and ended trial states render; (4) playground uses the trial key without exposing it in the URL; (5) all nav groups are keyboard operable.