Dashboard mock
StableA still picture of the product: four headline numbers, a bar list of skill runs and a ledger with verdicts, on sample data.
The app as a static screenshot drawn in markup, with no chart library: a sidebar, four KPI cards, skill runs with the idle tail drawn dashed, and a ledger that says what to keep, fix, merge or cut. It lays itself out by its own width (a container query), so it fits a narrow column as well as a hero: the sidebar shows from 656 pixels (41rem), runs sit beside the ledger from 976 (61rem), and under 464 (29rem) the ledger keeps only Name, Runs and Verdict. All numbers are SAMPLE data from home/content.ts and carry a “Sample data” tag. It is one image to assistive technology; nothing in it is interactive.
At its full width
import { DashboardMock } from '@rchursin/home/DashboardMock'
/** * A still picture of the app on sample data. It lays itself out by its own width, not the * window's: one column when narrow, a sidebar from 656 pixels, and skill runs beside the ledger * from 976 pixels. Resize the window to watch it change. */export default function DashboardMockOverview() { return <DashboardMock className="w-full" />}Usage
import { DashboardMock } from '@rchursin/home/DashboardMock'<DashboardMock rows={6} />Examples
Every ledger row, in a narrow column
rows={7} shows the whole sample ledger. Under 464 pixels wide the mock stacks and the ledger drops its Success and $ / task columns, so nothing is cropped.
import { DashboardMock } from '@rchursin/home/DashboardMock'
/** * `rows` sets how many ledger rows show; the sample ledger has seven. In a column this narrow * (under 464 pixels) the mock stacks, and the ledger keeps Name, Runs and Verdict. */export default function DashboardMockAllRows() { return <DashboardMock rows={7} className="w-full max-w-sm" />}API
Dashboard mock props
| Prop | Type | Default | Description |
|---|---|---|---|
rows | number | 5 | How many ledger rows to show, from the top of the sample ledger (seven rows). |
className | string | – | Extra classes on the frame. |
formatCost(row)
| Prop | Type | Default | Description |
|---|---|---|---|
rowrequired | LedgerRow | – | A ledger row. Returns its cost as "$0.92", or "—" when it never ran (cost is null). |
Accessibility
- The whole mock is role="img" with an aria-label that sums it up: 3 of 12 agents active, 11 of 81 skills used, and a table saying what to keep, fix, merge or cut. Everything inside is aria-hidden.
- The label is fixed: it doesn’t change with rows. If you change the content, say so in your own text nearby.
- Nothing inside can be focused or pressed, so it adds no tab stops.
- Verdicts are words with shapes (solid, outline, dashed, struck through), never colour alone.
Guidelines
Do
- Use it to show what the product looks like, next to text that says what it does.
- Keep the Sample data tag visible.
Don’t
- Don’t use it as a real dashboard: screen readers get one sentence, not the table.
- Don’t expect the whole ledger in a narrow column: under 464 pixels it drops two columns. Give it about 976 pixels for the full layout.
In use
Related
- Run wallA month of agent runs as a wall of squares, with a sweeping day highlight you can pause.
- Verdict badgeKeep, fix, merge or cut: a mono badge where each verdict has its own shape, and the word is always there.
- Sample badgeA small “Sample data” marker for anything that shows invented records or numbers.
- Control RoomA home page where the product is the hero: a live dashboard shot, a bento of features, a run wall and an FAQ.
Source
The component’s own files, exactly as they run on this site.
/** * Product UI mock: the RChursin_ app showing a SAMPLE workspace. * Static markup (no chart library). Monochrome; verdicts use shape + text. * * The layout follows its own width (a container query on the root), not the window's, so it fits * a narrow column as well as a full-width hero: * under 29rem one column; the ledger drops its Success and $ / task columns * from 41rem the sidebar appears * from 61rem four KPIs in a row, skill runs beside the ledger */import type { CSSProperties } from "react"import { Logo } from "../brand/Logo"import { cx } from "../components/cx"import { ledger, sample, type LedgerRow } from "./content"import { SampleTag, VerdictBadge } from "./ui"
const appNav = ["Overview", "Agents", "Skills", "Sessions", "Reports"]
/** Skill runs in the last 30 days: a few do the work, the long tail never runs */const runs = [