The reserve and the row's label column were carried as comments with pixel figures nobody could reproduce: the tool that produced them was never committed. This adds one that is, and the figures change. The reserve did not hold anything. Its declared minimum was 30rem while its own blocks added up to more than that, so the height was whatever the blocks happened to be and the constant was decoration. The blocks are back under the floor and the floor is 28rem, which sits between the shortest and the tallest panel a real report produces: three scored rows come to 410 pixels at the 352 pixel column, four 438, five 466, six 494, and the reserve is 448. A short report is no longer pushed down by 74 pixels when the score lands. The label column goes back to the 7rem the design specifies. It had been widened to 8rem on the grounds that 7rem clipped the longest label in five of six languages and 8rem cleared them; measured, the longest label overruns both widths in five of six, and the only difference is English, by a margin smaller than the error introduced by measuring in a substitute typeface. The extra width came off the fill bar for nothing. The new check renders the real band with the compiled stylesheet and reads the boxes back in a browser: the reserve against the panel it stands in for, every row in all six languages on one line with an ellipsis rather than a push, and no sideways scroll at the 352 pixel column or at 360 pixels stacked. It states plainly that it cannot know the shipped typeface, since the font is fetched at build time and no font file is committed, so every assertion in it is one that holds in any typeface.
src/components/
React components. The UI primitives are shadcn/ui (new-york style, zinc base) over Radix + Tailwind 4 + Lucide; everything above the primitives is feature-grouped by surface. Components are server components unless they need a hook, state, or browser API, in which case they open with "use client". Charts use Recharts 3 — replacing the chart library requires explicit approval.
Primitives and shell
ui/— shadcn/ui primitives (button, dialog, sheet, table, …). Generated by the shadcn CLI; keep edits minimal and on-style.layout/— the app shell: sidebar, topbar, bottom nav.providers.tsx,version-poller.tsx— top-level context providers and the self-healing stale-shell poller.i18n/— translation context + locale switcher.
Feature groups
insights/— insight status, assessment cards, Coach surface, advisor cards (the largest group).medications/— medication cards, the schedule wizard, intake timeline, detail history.settings/— the section components behind each settings page.measurements/,mood/,dashboard/— entry forms, lists, dashboard tiles.charts/— Recharts wrappers.monitoring/— Umami / GlitchTip client bootstrap.gamification/,targets/,comparison/,doctor-report/,clinician/,onboarding/,admin/— the remaining per-surface groups.
Conventions
Kebab-case filenames; React component exports stay PascalCase regardless. (A handful of PascalCase-filename outliers under medications/ + onboarding/ are pre-existing drift, noted in ../../CLAUDE.md.) Every t() call needs a matching key in messages/en.json — guarded by i18n-call-site-coverage.test.ts. Data reads go through TanStack Query with keys from @/lib/query-keys and unwrap (await res.json()).data. Tests live in __tests__/.