Initial commit: plan, spec, tickets and dashboard skill templates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
VasanthandClaude Opus 5.5 committed 2026-10-16 13:33:03 +05:30
commit 49f8f49b65
39 files changed
+10736

No files matched your search

@@ -0,0 +1,451 @@
---
name: Superbill Extraction and Automation Tool
description: Extract billing fields from a scan, verify them against the page, post to eClinicalWorks.
# ── Colour ───────────────────────────────────────────────────────────────────
# Two appearances, light and dark, declared as CSS variables in web/src/index.css
# and registered as Tailwind utilities there via `@theme inline`. A component
# names a token (`bg-surface`, `text-muted`); it never names a hex.
colors:
# Surfaces and ink — light
ground: "#F4F3F7"
rail: "#FFFFFF"
surface: "#FFFFFF"
surface-2: "#F7F6FA"
line: "#E2DFE9"
line-soft: "#ECEAF1"
ink: "#18151F"
ink-2: "#3D3850"
muted: "#66607A"
# Surfaces and ink — dark
dark-ground: "#0A0912"
dark-rail: "#100E1A"
dark-surface: "#151220"
dark-surface-2: "#1B1727"
dark-line: "#2A2438"
dark-line-soft: "#221D31"
dark-ink: "#F3F1F8"
dark-ink-2: "#C9C4D8"
dark-muted: "#8D87A0"
# The brand ramp. Identical in both appearances, and the only saturated thing
# on a page: header bar, primary buttons, active nav bar, super-admin badge,
# progress fill. Nothing else gets the gradient.
accent-1: "#FF3049"
accent-2: "#F26B21"
# Grading. Semantic, never decorative — print clarity, not correctness.
clean: "#51A68F"
verify: "#E39B34"
review: "#DE5243"
absent: "#6B6580"
# Artwork. The logo shield is the same mark in both appearances.
shield: "#21395A"
# The workbook's own cell fills. NOT interface colours — these are the
# highlight chips drawn over the scanned page, matching what
# patient_extractor_v2.py writes into the spreadsheet, so a reviewer moving
# between the sheet and the screen sees one language.
confidence-green: "#B6E2B6"
confidence-green-border: "#9AC79A"
confidence-amber: "#F4E2B6"
confidence-amber-border: "#D9C79A"
confidence-red: "#F4B6B6"
confidence-red-border: "#D99A9A"
confidence-unscored: "#FFFFFF"
confidence-unscored-border: "#D0D0D0"
# ── Type ─────────────────────────────────────────────────────────────────────
# Two families, both loaded from Google Fonts with display=swap and a full
# system fallback. Sora is display — headings, figures, brand name, buttons,
# batch ids. IBM Plex Sans is everything read as prose — body, labels, table
# cells, captions. Numbers that sit in a column carry tabular-nums.
typography:
display-page: { fontFamily: "'Sora'", fontSize: "22px", fontWeight: 700, lineHeight: 1.2 }
display-figure: { fontFamily: "'Sora'", fontSize: "21px", fontWeight: 700, lineHeight: 1.1 }
display-spend: { fontFamily: "'Sora'", fontSize: "24px", fontWeight: 700, lineHeight: 1.1 }
display-appbar: { fontFamily: "'Sora'", fontSize: "17px", fontWeight: 700, lineHeight: 1.15 }
display-runbar: { fontFamily: "'Sora'", fontSize: "17px", fontWeight: 700, lineHeight: 1.2 }
display-drop: { fontFamily: "'Sora'", fontSize: "16px", fontWeight: 700, lineHeight: 1.2 }
display-panel: { fontFamily: "'Sora'", fontSize: "14px", fontWeight: 600, lineHeight: 1.25 }
display-group: { fontFamily: "'Sora'", fontSize: "11.5px", fontWeight: 600, lineHeight: 1.25 }
button: { fontFamily: "'Sora'", fontSize: "13px", fontWeight: 600, lineHeight: 1.2 }
button-sm: { fontFamily: "'Sora'", fontSize: "12px", fontWeight: 600, lineHeight: 1.2 }
body: { fontFamily: "'IBM Plex Sans'", fontSize: "14px", fontWeight: 400, lineHeight: 1.5 }
body-doc: { fontFamily: "'IBM Plex Sans'", fontSize: "13.5px", fontWeight: 600, lineHeight: 1.3 }
body-table: { fontFamily: "'IBM Plex Sans'", fontSize: "13px", fontWeight: 400, lineHeight: 1.4 }
nav: { fontFamily: "'IBM Plex Sans'", fontSize: "13px", fontWeight: 500, lineHeight: 1.3 }
meta: { fontFamily: "'IBM Plex Sans'", fontSize: "12.5px", fontWeight: 400, lineHeight: 1.4 }
caption: { fontFamily: "'IBM Plex Sans'", fontSize: "11.5px", fontWeight: 400, lineHeight: 1.4 }
label: { fontFamily: "'IBM Plex Sans'", fontSize: "12px", fontWeight: 600, lineHeight: 1.3 }
# Uppercase, letter-spaced. Table headers and section eyebrows.
eyebrow: { fontFamily: "'IBM Plex Sans'", fontSize: "10.5px", fontWeight: 600, lineHeight: 1.3, textTransform: "uppercase", letterSpacing: "0.1em" }
badge: { fontFamily: "'IBM Plex Sans'", fontSize: "11px", fontWeight: 600, lineHeight: 1.2 }
# ── Sign-in screen only ──
# Its own scale, deliberately an island — see Typography > "Sign-in scale".
signin-title: { fontFamily: "'Sora'", fontSize: "clamp(22px, 3.2vw, 26px)", fontWeight: 700, lineHeight: 1.2 }
signin-brand: { fontFamily: "'Sora'", fontSize: "16px", fontWeight: 700, lineHeight: 1.2 }
signin-body: { fontFamily: "'IBM Plex Sans'", fontSize: "14.5px", fontWeight: 400, lineHeight: 1.55 }
signin-label: { fontFamily: "'IBM Plex Sans'", fontSize: "12.5px", fontWeight: 600, lineHeight: 1.3, textTransform: "uppercase", letterSpacing: "0.06em" }
# ── Shape ────────────────────────────────────────────────────────────────────
# ONE card radius. Everything that is a card, panel, table container, dropzone
# or empty state is 14px; the smaller steps are for controls inside them.
rounded:
card: "14px"
field: "11px"
control: "9px"
input: "8px"
icon: "7px"
chip: "10px"
swatch: "3px"
full: "9999px"
# Sign-in only.
signin-card: "20px"
signin-control: "10px"
spacing:
xs: "4px"
sm: "8px"
md: "12px"
lg: "16px"
xl: "18px"
xxl: "22px"
components:
app-bar:
background: "linear-gradient(100deg, {colors.accent-1}, {colors.accent-2})"
textColor: "#FFFFFF"
padding: "12px 18px"
nav-item-active:
borderLeft: "3px solid {colors.accent-1}"
background: "linear-gradient(90deg, color-mix(in srgb, {colors.accent-1} 12%, transparent), transparent)"
button-primary:
background: "linear-gradient(115deg, {colors.accent-1}, {colors.accent-2})"
textColor: "#FFFFFF"
rounded: "{rounded.control}"
padding: "9px 16px"
button-quiet:
backgroundColor: "{colors.surface-2}"
textColor: "{colors.ink}"
border: "1px solid {colors.line}"
rounded: "{rounded.control}"
card:
backgroundColor: "{colors.surface}"
border: "1px solid {colors.line}"
rounded: "{rounded.card}"
padding: "14px 16px"
pill-clean:
backgroundColor: "color-mix(in srgb, {colors.clean} 22%, transparent)"
textColor: "{colors.clean}"
rounded: "{rounded.full}"
pill-verify:
backgroundColor: "color-mix(in srgb, {colors.verify} 20%, transparent)"
textColor: "{colors.verify}"
rounded: "{rounded.full}"
pill-review:
backgroundColor: "color-mix(in srgb, {colors.review} 20%, transparent)"
textColor: "{colors.review}"
rounded: "{rounded.full}"
badge-super-admin:
background: "linear-gradient(115deg, {colors.accent-1}, {colors.accent-2})"
textColor: "#FFFFFF"
rounded: "{rounded.full}"
field-row:
backgroundColor: "{colors.surface}"
border: "1px solid {colors.line}"
rounded: "{rounded.field}"
gridTemplateColumns: "78px minmax(0,1fr) 42px 70px"
---
# Design System: Superbill Review
## Overview
**Creative North Star: "The Triage Desk"**
Superbill Review reads like an emergency triage desk, not a spreadsheet. Every
extracted field arrives already sorted by how urgently it needs attention —
green passes through untouched, amber gets a spot-check, red stops for a full
look — so a reviewer's eye lands exactly where judgment is actually required
and nowhere else. The interface itself stays out of the way: a dark, quiet
"console" surface with almost no decoration, so the one signal that is allowed
to be loud — the confidence band on a field — is never competing with anything
else for attention.
The system is calm, precise, and unhurried by design, because the job it
supports is not: a reviewer working through dozens of patients per document
needs an interface that does not add its own visual noise on top of already
noisy handwritten source material. Confirmed rejection: no bright accent
palette, no illustrative flourishes, no "friendly SaaS" warmth — this is an
operations tool for people doing careful, repetitive verification work, and it
should feel like a well-run night shift, not a marketing site.
**Key Characteristics:**
- One loud signal only — the green/amber/red confidence band — everything else recedes
- Flat by default; depth appears only as a response to state, not as decoration
- Dense, scannable typography tuned for many short fields in a row, not prose
- Every screen answers "what needs me right now" before anything else
## Colors
Two appearances — **Light and Dark, and only those two** — declared once as CSS
variables in `web/src/index.css` and registered there as Tailwind utilities via
`@theme inline`. A component names a token (`bg-surface`, `text-muted`,
`border-line`); it never names a hex. If a colour decision is not in that file,
it is not a colour decision this product makes.
`@theme inline` rather than plain `@theme` is load-bearing: inline emits each
utility as `var(--surface)` at the use site instead of snapshotting the value,
which is what lets `.dark` reassign a token and repaint every utility built on
it. Plain `@theme` would freeze the light value into the stylesheet.
### Surfaces and ink
| token | light | dark | what it is |
|---|---|---|---|
| `ground` | `#F4F3F7` | `#0A0912` | the page behind everything |
| `rail` | `#FFFFFF` | `#100E1A` | the sidebar, and the review screen's own strips |
| `surface` | `#FFFFFF` | `#151220` | cards, panels, tables |
| `surface-2` | `#F7F6FA` | `#1B1727` | inset things: inputs, chips, wells |
| `line` | `#E2DFE9` | `#2A2438` | the one border colour |
| `line-soft` | `#ECEAF1` | `#221D31` | the divider between rows of a list |
| `ink` | `#18151F` | `#F3F1F8` | anything being read |
| `ink-2` | `#3D3850` | `#C9C4D8` | text that supports it |
| `muted` | `#66607A` | `#8D87A0` | labels and captions, found rather than read |
The ink ramp is three steps on purpose. Anything reaching for a fourth is
usually reaching for the wrong one of the three.
### Brand ramp — the only saturated thing on a page
- **Accent 1** (`#FF3049`) → **Accent 2** (`#F26B21`), identical in both
appearances, and the same two hues the sign-in screen uses — so signing in is
a continuation rather than a change of product.
- `linear-gradient(115deg, …)` on controls, `100deg` on the wide header band.
- It appears on exactly six things: the header bar, primary buttons, the active
nav row's 3px bar and 12% wash, the super-admin badge, the review progress
fill, and a batch id. **Nothing else gets the gradient.**
### Grading — semantic, never decorative
- **Clean** (`#51A68F`): legibility ≥0.95 — clean print, passes straight through.
- **Verify** (`#E39B34`): 0.90–0.95 — sampled rather than checked one by one.
- **Review** (`#DE5243`): <0.90 — handwritten or hard to read, always reviewed.
- **Absent** (`#6B6580`): no legibility signal at all. Grey because nothing was
read, so there is no clarity to grade — distinct from "read badly".
These appear on status pills, the 3px grade rule down a field input, legend
swatches, donut segments and quality meters. **Never on a button, never on a
heading.** The moment green also means "primary action", neither reading
survives. `BAND_VAR` in `web/src/bands.ts` is the one map from a band to its
token.
### The workbook fills are not interface colours
`confidence-green/amber/red` (`#B6E2B6` / `#F4E2B6` / `#F4B6B6`) and their
borders are still in the token list and still used — but only for the highlight
chips drawn **over the scanned page**. They mirror what
`patient_extractor_v2.py` fills spreadsheet cells with, so a reviewer moving
between the sheet and this screen sees one language. Interface tokens would
break that, and these pastels would be invisible on a white scan besides.
### Named Rules
**The One Loud Colour Rule.** The brand ramp is the only saturated thing on a
page, and grading is the only colour carrying meaning. A third loud hue would
compete with the one signal the product exists to surface.
**Grading Never Becomes Chrome.** A grading colour on a button or a heading
destroys both readings at once. The only adjacent case is a destructive action
(`Remove` on the People screen), which uses `review` as text — not as a fill.
**One Border, One Radius.** Every card, panel, table container, dropzone and
empty state is `1px solid line` at `14px`. Hierarchy comes from spacing, not
from stacking shadows: a page of cards at three elevations reads as a pile, and
every screen in this product is a list of peers.
**There Is No Third Appearance.** An `eye` mode — the light palette under a
warm sepia filter — was removed. It was a third surface to keep in sync
forever, it tinted the scanned page a reviewer is trying to read accurately,
and both the OS and the monitor already offer the same warmth system-wide.
## Typography
**Display Font:** Sora 600/700 — page titles, panel headings, figures, the app-bar title, buttons, batch ids, group headers in the rail.
**Body Font:** IBM Plex Sans 400/500/600 — everything read as prose: body copy, nav labels, table cells, captions, form labels, metadata.
Both load from Google Fonts with `display=swap`, and every rule that names one carries the full system stack (`ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif`) behind it.
**This changed.** The interface used to run entirely on the system stack — a density argument for 11–13px lists: at label size, Inter beside Segoe UI is a distinction nobody reading a field list notices, and it cost a network dependency on an internal deployment. That argument was sound in isolation and wrong in aggregate. Once the sign-in screen was rebuilt on Sora/IBM Plex, signing in read as leaving one product and arriving at another. Two families across the whole product is the cheaper inconsistency.
**Why these two.** They are the sign-in screen's pairing, which is the approved mockup's pairing, carried inward rather than re-chosen. Sora has a real 600 and 700 so weights are drawn rather than synthesised, and its figures hold up at 21–24px where this product puts its money. IBM Plex Sans was drawn for interfaces and stays legible at the 10.5–13px the tables and rails live at.
**The rule that survives.** A blocked CDN must cost voice and nothing else. No layout figure may depend on either font's metrics without a re-measurement noted beside it, and adding a third family needs a reason written down here first.
**Numbers.** Anything that sits in a column — money, counts, timestamps, confidence figures, percentages — carries `tabular-nums` (the `tnum` class). Figures that shift width as they update are the single most common reason a dashboard looks unstable.
### Sign-in scale — a documented exception
The sign-in screen shares the two families but not the size or radius scales. It carries the mockup's own geometry so implementation and mockup stay comparable: **radius** 20px (card) and 10px (fields, button), **type** `clamp(22px, 3.2vw, 26px)` headline, 16px brand name, 14.5px lede/fields/button, 12.5px uppercase labels.
This is a deliberate island, not drift. It is the only surface that is neither a list nor a board, it is seen once per session, and it never renders beside a component built from the scales below — so there is nothing for it to be inconsistent *with*. A value from that list appearing on any other surface is a bug.
### Hierarchy
- **Figure Lead** (700 weight, 26px, 1.15 line-height): the one dominant quantity on a reporting surface — total spend on the ROI board. At most one per screen; a second one means neither is the answer.
- **Figure** (700 weight, 20px, 1.2 line-height): a supporting quantity that still has to be read before its own label — the settled-field percentage, each side of the by-hand comparison.
- **Heading** (700 weight, 16px, 1.25 line-height): patient name in the review header, document title, the brand wordmark.
- **Control** (600 weight, 13px, 1.3 line-height): navigation that has to be found before it is read — the Extraction/Automation tabs, a batch card's name, a primary button on the batch boards.
- **Body** (400 weight, 12px, 1.4 line-height): field values, document metadata, most UI copy.
- **Label** (500 weight, 11px, 1.3 line-height): field names, filter pills, band captions, timestamps.
### Named Rules
**The Flat Hierarchy Problem — partially addressed.** The shipped UI used only 11px, 12px, and 16px, roughly 1.45:1 from smallest to heading. A hierarchy that flat asks color and weight to do all the work vision normally gets from size. The **Control** step (13px/600) was added for the batch-board and tab-bar chrome, which sits above the data-dense lists and needs to be found without competing with a heading. The ramp is now 11/12/13/16/20/26. 16px stays the ceiling inside any data-dense list, reserved for the one heading that anchors the view; 20px and 26px appear only on surfaces that are not lists — today that is the ROI board, which carries both. The sign-in screen no longer counts toward this ramp: it runs on the `signin-*` steps instead, for the reasons in Typography > "Sign-in scale".
### Sign-in screen
The one screen with nothing else on it, so the brand sweep carries the whole
left panel rather than a bar across the top — the only place in the product
where the palette is decorative rather than functional. Below `lg` that panel
collapses entirely and the form takes the full width: a half-screen of
decoration would push the fields under the fold on a laptop. Type runs
26px headline / 20px title / 13px controls / 12px supporting copy.
**Display — removed.** There used to be a 44–72px step
(`clamp(2.75rem, 4.6vw, 4.5rem)`) for a product wordmark set across the waist
of a viewport-tall monogram. Both are gone: the letter spanned the screen with
the card sitting on its spine, so the parts that showed around the card read as
a ring rather than as a letter. Nothing now exceeds the 26px ceiling, and the
sign-in screen's own type is the `signin-*` steps in the token block above.
**The rule divides the lockup.** The name sits above the brand rule and
`AUTOMATION` below it, so the rule that cuts the S is also the line of the
wordmark — one gesture doing both jobs. The whole block is therefore rotated
onto the rule's own −8° axis: set horizontal, the rule climbs ~53px across the
width of the name and clips a letter at one end or the other, and the dodge
(parking the wordmark in the clear space above) reads as a wordmark avoiding a
line. Parallel, the gap stays constant at every viewport width. The tilt is
structural, not stylistic — it is the only reason the geometry holds without
pinning a gap to a text width the font resolves at runtime.
Implementation note: the lockup's container is `h-0` at `top-1/2`, so it shares
the rule's rotation pivot and its own axis *is* the rule. The two lines are then
offset by fixed distances (0.5rem / 0.85rem) rather than by anything computed
per breakpoint. The offsets are deliberately unequal because cap height is not
box height — uppercase leaves ~8px of empty descender space below the 72px line
and only ~2px above the 20px one, so equal offsets read as unequal air.
It is sized like a headline but weighted like a background: white at 88%
stepping to 52% across a gradient raked to match the light behind it, so the
card's 26px pure-white headline is still the loudest type on the screen. That
the sign-in headline leads is unchanged — the wordmark is the room, not the
sentence. A wordmark at full white here reverses that and the screen becomes a
poster rather than a sign-in.
Gated at `xl`, not `lg`. Between the two the card's left edge lands roughly
where the wordmark ends; below `xl` the S carries the screen alone and the
card's own header names the product.
**The reveal covers the whole hero, not just the letter.** The cursor torch
lights the monogram and the wordmark together, as one field: the letter goes
brand red, the name goes red-into-orange on the same 150° rake as its resting
white gradient. It is one mask on one unrotated, full-size layer that carries
both marks — which is the only arrangement that works, since a mask on the
wordmark's own container would rotate with it and the torch would slide off the
cursor. Everything in the hero is therefore rendered twice, once per layer.
**Where the name overlaps the letter, a halo separates them.** The name is
placed to clear the monogram's painted edge where the screen is wide enough,
but on squarer screens the letter grows until no channel remains between it and
the card, and the name sits on the letter instead. A single tight dark halo
behind the glyphs keeps the two from tangling. It stays tight on purpose: a
wider one reaches the brand rule ~16px below and veils the very gesture the
lockup is built on. The halo is a `filter`, never a `text-shadow` — these glyphs
are a background clipped to text, and a text shadow on transparent text paints
straight through the letterform.
## Layout
The document list is a vertical stack of full-width rows on a light `Paper`
background, each row a single click target. Opening a document replaces the
list entirely with a two-pane, full-window split (draggable divider, ratio
persisted in `localStorage`): the source PDF on the left inside a `Midnight
Console Deep` canvas, the field-by-field review queue on the right on
`Midnight Console`. Density is high by design — the review pane favors many
short rows over few tall ones, since the job is scanning many fields fast, not
reading long-form content.
Within the review pane, navigation is patient-by-patient rather than a long
scroll: one patient's full field record fills the pane at a time, with
Prev/Next controls, a jump dropdown, and left/right arrow-key navigation. The
PDF pane follows the active patient's page automatically.
## Elevation & Depth
Flat by default. Surfaces sit at the same visual plane at rest — no ambient
drop shadows on cards, panels, or list rows. Depth appears only as a direct
response to state: the currently-open patient card gets `shadow-lg
shadow-black/20` to read as "in focus," and the PDF page itself gets
`shadow-xl shadow-black/40` specifically to read as a physical page sitting on
the dark canvas rather than blending into it. Nothing gets a shadow simply for
decoration.
### Named Rules
**The Flat-at-Rest Rule.** Depth is a state signal, not a texture. If a shadow is not communicating "this is the thing that's active/focused/physical right now," it does not belong.
## Shapes
Corners are consistently soft but modest: `rounded-md` (6px) is the default for
inputs, value chips, and buttons; `rounded-lg` (8px) for cards and the larger
patient/document containers; `rounded-full` for pill-shaped filter buttons and
status badges. No sharp corners, no aggressively rounded (>8px) surfaces —
the form language stays understated rather than either clinical-sharp or
playful-round.
## Components
Every interactive element is restrained and functional: minimal ornament, a
single clear affordance, and just enough state feedback to confirm what
happened. Nothing asks to be noticed on its own — the confidence bands already
carry that job.
### Buttons
- **Shape:** `rounded-md` (6px), except pill-shaped filters (`rounded-full`).
- **Primary (Confirm/OK/Approve):** `accent-confirm` emerald background, dark text, used for "Verify," "OK," and "Approve for posting."
- **Secondary/Neutral:** `bg-slate-800` with `text-slate-300`, used for Undo, Retry, and non-destructive secondary actions.
- **Hover / Focus:** background lightens one step (`hover:bg-slate-700`, `hover:bg-emerald-400`); no transform or shadow added on hover, consistent with the flat-at-rest rule.
- **Disabled:** `opacity-40` plus `cursor-not-allowed`, used specifically to make the Approve gate's "you can't do this yet" state legible.
### Filter Pills
- **Style:** pill (`rounded-full`), `bg-slate-800`/`text-slate-300` at rest, inverted to `bg-slate-200`/`text-slate-900` when active.
- **State:** exactly one pill active at a time (Red / Amber / Missing code / Unscored / All).
### Cards / Containers (Patient record)
- **Corner Style:** `rounded-lg` (8px).
- **Background:** `bg-slate-900` (open) / `bg-slate-900/60` (collapsed, in the list-style views).
- **Shadow Strategy:** none at rest; `shadow-lg shadow-black/20` only on the currently-open item.
- **Border:** 1px, `border-slate-800` at rest, `border-slate-700` when open or hovered.
- **Internal Padding:** `px-3.5 py-3` header, `px-2.5 py-2` per field row.
### Inputs / Fields (correction input)
- **Style:** `rounded-md`, `border-slate-700`, `bg-slate-800`, `text-slate-100`.
- **Focus:** border shifts to `border-slate-500`; no glow/ring — consistent with the flat, restrained component philosophy.
- **Placeholder:** `text-slate-500`, always "correct value" — never blank, so an empty input still communicates its purpose.
### Confidence Band Chip (signature component)
The one component that is allowed to be visually loud. A field's extracted
value renders inside a solid chip colored by its band (`confidence-green` /
`-amber` / `-red`), dark text for contrast, with a 1px border one shade darker
than the fill. On dark surfaces, `unscored`/`blank` never uses the literal
white token — see the Literal-White Trap rule under Colors.
### Navigation (document-open header)
- Back control (`← All documents`, bordered, neutral) plus the current document's name and template, band legend right-aligned on wide viewports.
- No persistent sidebar or tab bar — this is a single-task, single-document focus model, not a multi-section app shell.
## Do's and Don'ts
### Do:
- **Do** treat the confidence band as the only color allowed to demand attention on a review screen.
- **Do** render `unscored`/`blank` fields as a dashed muted chip on dark surfaces, never as literal white.
- **Do** use shadow only as a state signal (open/active/physical), never as ambient decoration.
- **Do** keep every button, pill, and input restrained — one clear affordance, minimal ornament.
- **Do** animate `transform`/`opacity` for progress and state changes, not `width`/`height` — a `width` transition re-triggers layout on every frame, a `transform: scaleX()` does not.
### Don't:
- **Don't** introduce a second loud accent hue anywhere near the confidence bands — it competes with the one signal the product depends on.
- **Don't** add ambient drop shadows to cards or panels at rest; depth is earned by state, not applied by default.
- **Don't** rely on a single font family across every size and weight without also varying size deliberately — see the Flat Hierarchy Problem: the current 11/12/16px scale is undersized for a system this data-dense and should widen (e.g., toward a 11/13/16/20px, ~1.8:1 progression) the next time typography is revisited.