Template
Moorline
A performance overview inside a website infrastructure console. For one site it summarises field-measured page experience metrics at the 75th percentile, compares them with a week ago and lists suggestions. It is aimed at developers who need to know at a glance whether each vital is healthy.
Web-performance vitals overview page · App screen: analytics · 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, 32px, tracking -0.02em for page title; metric values 22px 600 tabular
- InterBody: Inter 400, 16px/1.5; card titles 16px 600; labels 14px; legend 14px
Patterns
- collapsible grouped sidebar with beta badges
- eyebrow + title + status badge page header
- outlined documentation pill link
- underline tabs
- all-clear suggestion state
- metric cards with percentile value, trend delta and rating badge
- mini bar chart per card
- good / needs-improvement / poor distribution legend
- segmented percentile switch
States it is designed for
- loading skeleton cards
- not enough traffic to compute (card shows 'Collecting data' with ETA)
- all clear suggestions
- suggestions available (list with severity)
- metric regressed (red delta, poor badge)
- metric improved (green delta)
- fetch error with retry
- feature in beta notice
Who it is for
- web developers
- site reliability engineers
- technical marketers
Layout
- Top bar: account switcher, starred site name with plan badge and switcher, right: assistant button, Support, profile
- Sidebar: back-to-sites button, flat items with chevrons that expand into sub-lists, active sub-item highlighted, beta badges
- Header: small eyebrow ('Speed'), large title with beta badge, description, outlined docs pill
- Tabs: Summary | All suggestions
- Suggestions section: status line with check
- Vitals section: heading with info icon, segmented P75 | All requests right
- Three metric cards in a row: name (dotted underline tooltip), chevron to detail, P75 label, value + delta arrow, rating badge, 2-bar chart (7 days ago vs now), distribution legend with coloured dots
- Below 1100px cards wrap 2+1; below 700px stack
Palette
Clinical, clear, reassuring when green and direct when red.
- canvas
#fbfbfb - surface
#ffffff - text
#1d1d1f - muted
#595959 - border
#d8d9db - link
#0b57c2 - good
#1e7d3b - poor-bar
#d93b3f - warn
#b35c00 - good-badge-bg
#e1f4e5 - poor-badge-bg
#fde4e4 - poor-text
#b42318
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on canvas | 16.26:1 | 4.5:1 |
| Aa | muted text on card | 7.00:1 | 4.5:1 |
| Aa | docs link text on canvas | 6.43:1 | 4.5:1 |
| Aa | good badge text | 4.51:1 | 4.5:1 |
| Aa | poor badge text | 5.45:1 | 4.5:1 |
| poor bar on card | 4.52:1 | 3:1 | |
| good bar on card | 5.18:1 | 3:1 | |
| needs-improvement dot on card | 4.72:1 | 3:1 | |
| Aa | beta badge text (muted on hairline tint) | 11.92: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, 32px, tracking -0.02em for page title; metric values 22px 600 tabular
- Body
- Inter 400, 16px/1.5; card titles 16px 600; labels 14px; legend 14px
Similar to the observed neo-grotesk. Eyebrow 14px 500 muted, not uppercase.
Spacing and imagery
Medium density; 8px base; content max 960px with 36px side padding; cards 16px padding, 16px gap; radius 6px cards, 999px pills; no shadows, 1px borders.
Tiny two-bar comparison charts per metric; coloured status dots; line icons in nav.
Components
- top bar with site switcher
- collapsible sidebar
- beta badge
- docs pill link
- underline tabs
- suggestion status row
- segmented control
- vital metric card
- rating badge
- mini bar chart
- distribution legend
Interactions
- Metric names show a definition tooltip on hover and focus
- Card chevron opens a detail page with a time-series and page breakdown
- Segmented control switches all cards between percentile and all-requests views
- Sidebar sections expand/collapse with a 150ms height transition and remember state
- Tabs are keyboard navigable with arrow keys
Data
Site{id, account_id, hostname, plan (free|pro|business)}VitalSnapshot{site_id, metric (lcp|inp|cls), p75, good_pct, ni_pct, poor_pct, captured_on}Suggestion{id, site_id, metric, severity (info|warn|critical), title, body, dismissed_at}
Guardrails
Experience
- Pair every rating colour with a word badge (Good, Needs work, Poor)
- Show the unit next to each value (ms or unitless)
- Explain what a delta arrow compares (vs 7 days ago)
- Keep the all-clear message visible so an empty list is not ambiguous
- Link each card to a deeper view
- Never truncate metric names; wrap to two lines
Accessibility
- Tooltips for metric definitions open on keyboard focus and are dismissible with Escape
- Delta arrows have text alternatives ('up 6,600 ms, worse')
- Mini bar charts include hidden text values
- Tabs use the tabs pattern with aria-selected
- Status is never colour-only
- Sidebar expanded state exposed with aria-expanded
Security
- RLS: vitals and suggestions scoped by account membership
- Validate site id belongs to the current account on every request
- Dismissing suggestions requires editor role and is logged
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 **Moorline**, the Speed > Vitals page of a website infrastructure console. For the selected site it shows three field-measured page-experience metrics (largest paint, interaction latency, layout shift) at the 75th percentile, the change versus a week ago, a rating, and the share of visits in each rating band, plus a suggestions list.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Tabs, ToggleGroup, Tooltip, Badge, Collapsible), lucide-react, Recharts for mini bars and the detail chart, TanStack Query, date-fns. Supabase Auth and Postgres for snapshots and suggestions.
### Pages & layout
1. **Shell**: top bar (account switcher, site 'harbor-notes.example' with plan badge, assistant and Support buttons, avatar); sidebar with Back to sites, Overview, Analytics, DNS, Security, Speed (expanded: Vitals [Beta], Field data, Lab tests [Beta], Settings).
2. **/speed/vitals** (this screen): eyebrow, title + Beta, description, docs pill; tabs; Suggestions ('Nothing to fix right now'); vitals heading with P75 | All requests; three cards, e.g. LCP 2,480 ms (down 310 ms, Good), INP 64 ms (up 8 ms, Good), CLS 0.27 (up 0.05, Poor), each with a two-bar chart and band percentages.
3. **/speed/vitals/:metric**: detail with 30-day line and top pages table.
4. Responsive: cards wrap then stack; sidebar becomes a drawer below 1024px.
### Design system
- Colors: `--canvas: #fbfbfb`, `--surface: #ffffff`, `--text: #1d1d1f`, `--muted: #595959`, `--border: #d8d9db`, `--link: #0b57c2`, `--good: #1e7d3b`, `--poor-bar: #d93b3f`, `--warn: #b35c00`, `--good-badge-bg: #e1f4e5`, `--poor-badge-bg: #fde4e4`, `--poor-text: #b42318`.
- Fonts: Inter (similar to observed). Title 32px/600; section heads 20px/600; card titles 16px/600; values 22px/600 tabular; body 16px/1.5; labels 14px.
- Spacing: 8px base, 16px card padding, 24px between sections.
- Radius: 6px cards and controls, full pills for badges and docs link.
- Shadows: none.
- Motion: 150ms sidebar collapse; tooltips 100ms fade; reduced motion respected.
### Components & interactions
`SiteSwitcher`, `ConsoleSidebar` (Collapsible sections, BetaBadge), `PageHeader` (eyebrow, title, badge, description, DocsPill), `Tabs`, `SuggestionsPanel`, `PercentileToggle`, `VitalCard` (TermWithTooltip, value, DeltaText with arrow + words, RatingBadge, MiniBars, BandLegend). Cards hover with a border darken; the whole card is not a link, only the chevron is.
### Data & state
`sites`, `vital_snapshots`, `suggestions` per the data model. Current vs 7-days-ago computed in SQL. Rating thresholds live in a typed constants module (e.g. LCP good <= 2500 ms). Mock three sites with different health.
### Accessibility
Rating shown as colour plus a badge word. Delta includes 'better/worse' text. Mini bars have `aria-hidden` with an adjacent visually hidden sentence. Metric term tooltips are buttons with `aria-describedby`. Tabs and toggle group follow WAI-ARIA patterns.
Verified contrast: body text on canvas: #1d1d1f on #fbfbfb = 16.26:1; muted text on card: #595959 on #ffffff = 7.0:1; docs link text on canvas: #0b57c2 on #fbfbfb = 6.43:1; good badge text: #1e7d3b on #e1f4e5 = 4.51:1; poor badge text: #b42318 on #fde4e4 = 5.45:1; poor bar on card: #d93b3f on #ffffff = 4.52:1; good bar on card: #1e7d3b on #ffffff = 5.18:1; needs-improvement dot on card: #b35c00 on #ffffff = 4.72:1; beta badge text (muted on hairline tint): #1d1d1f on #d8d9db = 11.92:1.
### Security
RLS on `sites`, `vital_snapshots`, `suggestions` via account membership. Suggestion dismissal requires editor role and inserts an audit row. Validate `site_id` against the session account on every RPC.
### Performance & SEO
Mini charts are tiny SVGs, not full chart instances where possible. Prefetch detail data on chevron hover. Console routes noindex.
### Guardrails
- Invent site names and figures
- Keep rating thresholds in one place
- Do not hide poor results behind collapsed UI
- Typed code, clear errors
- Acceptance criteria: (1) each card shows value, delta, rating word and bands; (2) percentile toggle updates all cards; (3) tooltips work by keyboard; (4) RLS prevents seeing another account's sites; (5) page works at 390px.