Template
Morrowcast
A monitoring page for teams running AI-assisted workflows in production. It tracks how human reviewers grade those runs over time: rolling accuracy, review coverage, incorrect count and a confidence interval. The design treats 'not enough data yet' as a first-class state rather than showing misleading zeros.
Review-quality monitoring dashboard for automation runs · 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, 26px, tracking -0.02em for page title; stat values 24px 600 tabular
- InterBody: Inter 400, 16px/1.5 for descriptions; nav 15px 500; card labels 14px 500; captions 13px muted
Patterns
- persistent left sidebar with grouped nav
- black pill active nav item
- breadcrumb top bar with workspace switcher
- filter toolbar (entity select, segmented granularity, window select, date range)
- stat cards row with explicit insufficient-data values
- chart card with inline legend
- chart empty state with CTA
- theme switcher in sidebar footer
States it is designed for
- loading skeleton for cards and chart
- no reviewed runs (em dash values, explanatory captions, empty chart with 'Review runs' CTA)
- insufficient data for confidence (text value, caption stating required count)
- populated with trends
- partial data warning when coverage below threshold
- fetch error card with retry
- no workflows exist (full-page empty with create CTA)
- dark theme
Who it is for
- automation and ops engineers
- AI product owners
- quality reviewers
Layout
- Sidebar (240px, light grey): logo mark and name, flat primary items, then small-caps groups (Agent, Workflow, Developer) with icon items; bottom: docs link with external icon, avatar, 3-way theme toggle, collapse button
- Top bar: workspace switcher chip, slash separator, page crumb
- Header: title, one-line description
- Toolbar: workflow select left; right cluster of segmented Daily/Weekly, window select, date-range select
- Stat row: 4 equal cards (label, big value, caption)
- Chart card: title with trend icon, legend (solid and dashed swatches), line chart or empty state
- Second chart card (coverage by period) below
- Below 1024px sidebar becomes an off-canvas drawer; stat cards 2x2; below 640px 1 column and toolbar wraps
Palette
Neutral, technical, trustworthy. Greyscale shell with two chart hues so data stands out.
- canvas
#f7f7f7 - surface
#ffffff - sidebar
#f3f3f3 - text
#171717 - muted
#646464 - border
#e4e4e4 - control-border
#8f8f8f - nav-active
#171717 - on-active
#ffffff - series-accuracy
#2563eb - series-coverage
#9333ea - focus
#2563eb
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on canvas | 16.73:1 | 4.5:1 |
| Aa | muted caption on card | 5.92:1 | 4.5:1 |
| Aa | active nav label | 17.93:1 | 4.5:1 |
| Aa | sidebar muted group label | 5.33:1 | 4.5:1 |
| select control border on white | 3.23:1 | 3:1 | |
| accuracy series on white | 5.17:1 | 3:1 | |
| coverage series on white | 5.38:1 | 3:1 | |
| focus ring on canvas | 4.82: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, 26px, tracking -0.02em for page title; stat values 24px 600 tabular
- Body
- Inter 400, 16px/1.5 for descriptions; nav 15px 500; card labels 14px 500; captions 13px muted
Similar to the observed neo-grotesk. Sidebar group labels 12px 600 uppercase +0.06em.
Spacing and imagery
Medium density; 4px base; sidebar 240px; content padding 24px; card padding 16px; 12px gap in stat row; radius 10px cards, 8px controls, 8px nav pill; no shadows, 1px borders.
Line charts only; muted line-chart glyph for empty state. Lucide stroke icons at 16px in nav.
Components
- sidebar nav with groups
- workspace switcher
- entity select
- segmented control
- date range picker
- stat card
- line chart with legend
- chart empty state with CTA
- theme toggle
- docs link
Interactions
- Changing any filter updates the URL query and refetches with a skeleton over cards
- Hovering the chart shows a crosshair and tooltip with both series
- Legend items toggle series visibility
- Theme toggle switches system/light/dark instantly and persists
- Sidebar collapses to icons with tooltip labels
- Keyboard: '[' toggles sidebar, arrow keys move chart points when focused
Data
Workflow{id, workspace_id, name, slug}Run{id, workflow_id, started_at, status (success|failed|running)}Review{id, run_id, reviewer_id, verdict (correct|incorrect), created_at}MetricPoint{workflow_id, bucket_start, accuracy, coverage, reviewed, total}
Guardrails
Experience
- Never show 0% when the true value is 'no data'; use an em dash and a caption
- State sample sizes next to percentages (e.g. 0 of 1)
- Keep filters in the URL so views can be shared
- Give every empty chart a next action
- Show the confidence interval only when the minimum sample is met
- Default to last 30 days, daily
Accessibility
- Each chart has an accessible summary and a 'View as table' toggle
- Series are distinguished by line style (solid vs dashed) as well as colour
- Segmented control uses radio-group semantics
- Stat values are announced with their labels (e.g. 'Review coverage 0 percent, 0 of 1 runs')
- Theme toggle buttons have aria-pressed and text labels for screen readers
- Focus rings visible on every nav item and control
Security
- RLS: runs, reviews and metrics readable only by workspace members
- Aggregations run in SQL views or RPCs scoped by workspace, never by client-side filtering of all rows
- Date-range params validated and clamped (max 365 days)
- API keys and webhooks pages require admin role
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 **Morrowcast**, the Monitoring page of an automation platform where AI workflows run in production and humans review samples. The page shows review quality over time for one workflow: rolling reviewed accuracy, review coverage, incorrect count and a 95% confidence interval, and it handles the common 'nothing reviewed yet' case gracefully. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Select, ToggleGroup, Popover, Calendar, Card, Tooltip), lucide-react, Recharts for lines, date-fns for buckets, TanStack Query for data. Supabase Auth and Postgres with SQL views for metrics. ### Pages & layout 1. **App shell**: 240px sidebar (Trigger, Runs, Reviews, Monitoring; AGENT: Agents, Shared resources; WORKFLOW: Workflows, Templates; DEVELOPER: Webhooks, API keys, Connect; Settings), footer with docs link, avatar, theme toggle and collapse. Top bar with workspace switcher and crumb. 2. **/monitoring** (this screen): title, description 'Follow reviewer-graded quality for production runs over time.', toolbar (workflow select showing e.g. 'invoice-triage-7k2', Daily/Weekly, window select, 'Last 30 days'), stat row (Reviewed accuracy, Review coverage, Incorrect, Confidence 95%), 'Rolling reviewed accuracy' chart card, 'Coverage by period' bar chart card. 3. Responsive: drawer sidebar under 1024px, 2x2 stats, stacked toolbar under 640px. ### Design system - Colors: `--canvas: #f7f7f7`, `--surface: #ffffff`, `--sidebar: #f3f3f3`, `--text: #171717`, `--muted: #646464`, `--border: #e4e4e4`, `--control-border: #8f8f8f`, `--nav-active: #171717`, `--on-active: #ffffff`, `--series-accuracy: #2563eb`, `--series-coverage: #9333ea`, `--focus: #2563eb`. - Fonts: Inter (similar to observed). Title 26px/600; stat values 24px/600 tabular-nums; body 16px/1.5; captions 13px; nav group labels 12px uppercase +0.06em. - Spacing: 4px base; 24px page padding; 16px card padding; 12px grid gaps. - Radius: cards 10px, controls 8px, nav pill 8px. - Shadows: none; borders define surfaces. - Motion: 150ms colour transitions; chart draw-in 300ms, disabled with reduced motion. - Dark theme: canvas `#111111`, surface `#1a1a1a`, text `#f2f2f2`, muted `#a3a3a3` (verify each pair). ### Components & interactions `AppSidebar` (NavGroup, NavItem with active black pill), `WorkspaceSwitcher`, `FilterToolbar`, `StatCard` (value may be number, percent with fraction, em dash, or text like 'Not enough data'), `TrendChartCard` (legend toggles, tooltip, table toggle), `ChartEmpty` (icon, sentence, dark 'Review runs' button with arrow), `ThemeToggle`. Hover on nav items tints grey; filter changes show skeleton shimmer on cards only. ### Data & state `workflows`, `runs`, `reviews` as in the data model, plus a SQL function `review_metrics(workflow_id, from, to, granularity)` returning buckets with accuracy, coverage, reviewed, total and Wilson interval bounds. Filters live in URL params. Mock scenarios: (a) 1 run, 0 reviews (empty); (b) 30 days with 420 runs and 96 reviews showing accuracy between 88% and 97%. ### Accessibility Charts have `role="img"` with a generated summary plus an accessible table view. Dashed vs solid lines distinguish series. ToggleGroup is a radio group. Tooltips reachable by keyboard when the chart is focused. Colour is never the sole signal for status. Verified contrast: body text on canvas: #171717 on #f7f7f7 = 16.73:1; muted caption on card: #646464 on #ffffff = 5.92:1; active nav label: #ffffff on #171717 = 17.93:1; sidebar muted group label: #646464 on #f3f3f3 = 5.33:1; select control border on white: #8f8f8f on #ffffff = 3.23:1; accuracy series on white: #2563eb on #ffffff = 5.17:1; coverage series on white: #9333ea on #ffffff = 5.38:1; focus ring on canvas: #2563eb on #f7f7f7 = 4.82:1. ### Security RLS on `workflows`, `runs`, `reviews`: members of the owning workspace. `review_metrics` is `security invoker` so RLS applies. Clamp date ranges server-side. Role checks (admin) guard Webhooks and API keys routes. ### Performance & SEO Lazy-load Recharts. Cache metrics per filter key for 60s. Avoid layout shift by reserving chart height. App routes noindex. ### Guardrails - Invented workflow names and numbers only - Do not fabricate accuracy when there are no reviews - Keep the page usable without charts (tables) - Typed code; errors surfaced in cards - Acceptance criteria: (1) empty scenario shows em dashes, captions and the CTA; (2) populated scenario renders both series with legend toggles; (3) filters persist in the URL; (4) dark theme passes contrast; (5) sidebar and stats reflow at 390px.