Template
Ruvelle
The loading state of a developer console's coding-assistant usage page: stat tiles, activity and spend charts and a per-member table all render as skeletons matching their final shapes, so the layout doesn't jump when data arrives.
Usage analytics dashboard in skeleton loading state · App screen: loading · 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.
- Source Serif 4Headings: Source Serif 4 500 for the wordmark; Inter 500 24px page title
- InterBody: Inter 400, 16px, line-height 1.5; table 15px
Patterns
- warm neutral skeleton cards
- month picker with prev/next
- two stat cards over two chart cards
- info note bar with link
- team table with search and export
- grouped sidebar with section labels
- serif wordmark
States it is designed for
- all loading (skeletons)
- partial: some cards loaded
- loaded
- empty month: 'No usage recorded' in each card
- error per card with Retry
- no permission to view spend: spend card shows a lock message
- export in progress
Who it is for
- engineering managers tracking AI coding assistant adoption
- finance or platform admins watching spend
Layout
- sidebar (~155px): serif wordmark, collapse icon, groups Build, Analytics, Coding tool, Manage
- header: page title left, month picker right
- row 1: two stat cards (lines accepted, accept rate)
- row 2: two chart cards (Activity, Spend)
- info note bar spanning full width
- Team card with title, search input, Export button, table headers and skeleton rows
- below 900px cards stack in one column; table scrolls horizontally inside its card
Palette
Warm, restrained, editorial; loading feels composed rather than broken.
- bg
#faf8f3 - card
#f2efe8 - skeleton
#e6e1d7 - text
#1f1d19 - muted
#66625a - note
#f4f1ea - button
#1f1d19 - border
#8f897d - accent
#b1542f
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 15.85:1 | 4.5:1 |
| Aa | text on card | 14.65:1 | 4.5:1 |
| Aa | muted labels on card | 5.29:1 | 4.5:1 |
| Aa | Export label | 16.83:1 | 4.5:1 |
| input border | 3.48:1 | 3:1 | |
| focus ring | 4.74:1 | 3:1 | |
| chart accent on card | 4.38: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
- Source Serif 4 500 for the wordmark; Inter 500 24px page title
- Body
- Inter 400, 16px, line-height 1.5; table 15px
Sidebar group labels 12px uppercase 600 with 0.06em tracking; numbers use tabular numerals.
Spacing and imagery
Density: Medium. Grid: 8px; card padding 16px; 16px gaps. Container: fluid with 16px page padding; two-column grid. Radius: 8px cards and inputs. Shadows: None; tone separates cards.
Charts only (line for activity, bar for spend) once loaded; skeleton blocks mirror them.
Components
- ConsoleSidebar
- MonthPicker
- StatCard (with skeleton)
- ChartCard (Activity line, Spend bars)
- InfoNote
- TeamTable (search, Export, sortable 'Lines this month')
- SkeletonRow
Interactions
- Each card loads independently and swaps skeleton for content
- Month picker disables 'next' for the current month
- Search filters members client-side with 200ms debounce
- Export downloads CSV of the current month
- Clicking a column header sorts
Data
UsageDaily{org_id, user_id, day, lines_accepted, suggestions_shown, suggestions_accepted, spend_cents}Member{id, org_id, name, email, role (admin|developer|billing)}
Guardrails
Experience
- Skeletons must match final dimensions to avoid layout shift
- Load cards independently; never block the page on the slowest query
- Label spend as an estimate and link to the cost page
- Default the month to the current one
- Keep Export available once the table loads
Accessibility
- Each loading card has aria-busy and a visually hidden 'Loading activity'
- Charts have a hidden data table alternative
- Month picker buttons have labels 'Previous month' / 'Next month'
- Sortable headers use aria-sort
- Focus ring visible on warm surfaces
Security
- RLS: usage rows readable only by org members; spend columns only for admin or billing roles (separate view)
- Export generated server-side with the same RLS
- Rate-limit exports
- Don't include emails in exports unless the caller is admin
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 **Ruvelle**, the coding-assistant usage page of a developer console, with a first-class skeleton loading state. Build the sidebar shell, the page in loading, loaded, empty and error states, and seed a month of invented usage for six members.
### 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. Recharts for the two charts.
### Pages & layout
1. **Sidebar**: wordmark, Build (Dashboard, Workbench, Files, Skills), Analytics (Usage, Cost, Logs, Batches), Coding tool (Usage, Preferences), Manage (Keys, Limits, Settings).
2. **Usage page**: title, month picker; two stat cards; two chart cards; info note ('Spend is an estimate… see cost dashboard'); Team table with search and Export.
### Design system
- Colors: `--bg: #faf8f3` (page), `--card: #f2efe8` (cards), `--skeleton: #e6e1d7` (skeleton blocks), `--text: #1f1d19` (primary text), `--muted: #66625a` (labels), `--note: #f4f1ea` (info note fill), `--button: #1f1d19` (Export button), `--border: #8f897d` (input border), `--accent: #b1542f` (focus ring and chart accent).
- Fonts: Source Serif 4 500 for the wordmark; Inter 500 24px page title for headings; Inter 400, 16px, line-height 1.5; table 15px for body. Sidebar group labels 12px uppercase 600 with 0.06em tracking; numbers use tabular numerals.
- Spacing: Medium. 8px; card padding 16px; 16px gaps. Container: fluid with 16px page padding; two-column grid.
- Radius: 8px cards and inputs.
- Shadows: None; tone separates cards.
- Motion: Skeleton pulse 1.4s ease-in-out; data fades in 200ms per card as each query resolves; reduced motion uses a static tone.
### Components & interactions
Every card owns its skeleton: stat cards show a 160px bar, chart cards a full-area block, table rows three bars aligned to columns.
- Each card loads independently and swaps skeleton for content
- Month picker disables 'next' for the current month
- Search filters members client-side with 200ms debounce
- Export downloads CSV of the current month
- Clicking a column header sorts
### Data & state
Seed 30 days × 6 invented members. Each card uses its own TanStack Query so they resolve at different times; add an artificial delay toggle.
Entities: `UsageDaily{org_id, user_id, day, lines_accepted, suggestions_shown, suggestions_accepted, spend_cents}`; `Member{id, org_id, name, email, role (admin|developer|billing)}`.
States to build and show in a dev-only state switcher:
- all loading (skeletons)
- partial: some cards loaded
- loaded
- empty month: 'No usage recorded' in each card
- error per card with Retry
- no permission to view spend: spend card shows a lock message
- export in progress
### Accessibility
- Each loading card has aria-busy and a visually hidden 'Loading activity'
- Charts have a hidden data table alternative
- Month picker buttons have labels 'Previous month' / 'Next month'
- Sortable headers use aria-sort
- Focus ring visible on warm surfaces
Verified contrast: body text: #1f1d19 on #faf8f3 = 15.85:1; text on card: #1f1d19 on #f2efe8 = 14.65:1; muted labels on card: #66625a on #f2efe8 = 5.29:1; Export label: #ffffff on #1f1d19 = 16.83:1; input border: #8f897d on #ffffff = 3.48:1; focus ring: #b1542f on #faf8f3 = 4.74:1; chart accent on card: #b1542f on #f2efe8 = 4.38:1.
### Security
- RLS: usage rows readable only by org members; spend columns only for admin or billing roles (separate view)
- Export generated server-side with the same RLS
- Rate-limit exports
- Don't include emails in exports unless the caller is admin
RLS detail: `usage_daily` select where user is a member of org_id; `usage_spend` view restricted to admin/billing; `members` select for org members.
### Performance & SEO
Aggregate on the server (SQL view) rather than shipping raw rows; lazy-load Recharts; CLS under 0.05.
### Guardrails
- Skeletons must match final dimensions to avoid layout shift
- Load cards independently; never block the page on the slowest query
- Label spend as an estimate and link to the cost page
- Default the month to the current one
- Keep Export available once the table loads
- 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:
- No layout shift when data loads
- Each card can fail and retry alone
- Spend hidden for non-billing roles
- Export matches the table
- Charts have table fallbacks