Design review: bug fixes, token convergence, and a consolidated design-system guide - #324
Conversation
…igrate detail dialog to Sheet The three mobile detail rows (Check first / Needed input / Output) were rendered as buttons with a chevron affordance but no handler; they now expand accordion-style with aria-expanded/aria-controls wiring. The hand-rolled detail modal is replaced by the shared Sheet primitive, gaining focus trap, initial focus, and return-focus-on-close. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
notFound() calls previously fell through to the unstyled Next.js default; the new not-found page mirrors the root error boundary's card. The document viewer page param is now parsed and clamped so ?page=abc no longer renders "page NaN" in the header and page input. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…launcher tones The launcher category filters exposed role=tab with aria-selected but no aria-controls or tabpanel; the results region is now the referenced panel, matching the dashboard upload-tabs precedent. Answer images fall back to a descriptive alt when the caption is empty. Launcher icon tones and the safety selection state move from raw Tailwind palette classes to the categorical --type-* and semantic danger triads so they respond to dark mode and forced-colors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…ze residuals ServicesNavigatorPreview was exported but referenced nowhere; it carried ~80 hardcoded hex values from a pre-token palette. The live navigator's remaining hardcodes (Filters/Sort buttons, best-fit chip glow, badge inset highlight, Suspense fallback wash) now use the design tokens, so the /services route follows dark mode like every other surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…dder doc, mockups noindex Migrates arbitrary px font sizes to the named size-only scale steps (9→4xs, 10→3xs, 11→2xs, 13→sm-minus, 15→base-minus) across production components; the [12px]/[18px] sites move to text-xs/text-lg with explicit leading pinned where none was set so nothing shifts. Remaining hits are rem display headings (accepted exceptions) and one mockup file. Also: documents the z-index ladder alongside the radius rules in globals.css, replaces the one rounded-[var(--radius-md)] with rounded-md, and adds noindex metadata to the mockups layout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…tchet docs/design-system.md becomes the single front door for UI work: token contract (semantic vs categorical vs brand), legacy-hex migration table, type-scale rules and ratchet, tap-target and radius/shadow rules, the z-index ladder, Sheet-only modal policy, accessibility requirements, a do/don't gallery drawn from this branch's fixes, verification gates, and file conventions. The deep docs in docs/redesign/ gain entry-point pointers; process-hardening records the new type-scale baseline (20, was 168) and the debts cleared this pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…teral in design guide The free-port scan required binding every address family, so containers without IPv6 (EAFNOSUPPORT) reported every port busy and the dev server could never start. An unsupported family cannot host a conflicting listener, so it no longer vetoes the port. Also rewords one design-guide example: Tailwind v4 scans markdown sources, and the literal rounded-[var(--radius-star)] pattern generated unparseable CSS that broke the dev build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
…n Playwright port probe Sandboxed containers pre-install one Chromium at a fixed path rather than the revision this Playwright version pins; an optional PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH env var now routes the chromium project at it. The Playwright runner's free-port probe gets the same unsupported-address-family tolerance as dev-free-port.mjs so it can start its own server in IPv6-less containers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
This pull request has been ignored for the connected project Preview Branches by Supabase. |
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Tabpanel label ignores active filter
- The tabpanel aria-label now derives from the active filter via launcherFilterPanelLabel(activeFilter), so screen readers announce Assess, Evidence, Treat, Saved, More, or All tools to match the filtered list.
You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 78ccd3a. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
The tabpanel kept a static "All tools" aria-label while the filter tabs changed what the list shows; assistive tech now hears the active filter's name (e.g. "Assess tools", "Saved tools"). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
Fall back to mobileFilters when resolving the results tabpanel label so the More tab announces a matching region name for screen readers.
Resolves conflicts by taking main's equivalents of the dev-environment fixes (independently landed there), keeping both process-hardening sections, and combining the launcher's Sheet dialog work with main's tools-catalog extraction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
Uh oh!
There was an error while loading. Please reload this page.

Summary
aria-expanded/aria-controls, chevron rotation withmotion-reducehandling).Sheetprimitive, gaining focus trap, initial focus, and return-focus-on-close.src/app/not-found.tsx(modeled on the root error boundary, info-toned) —notFound()calls in differentials and unknown URLs no longer render the unstyled Next.js default./documents/[id]?page=abcno longer leaksNaNinto the viewer header and page input — the param is parsed and clamped to ≥ 1.aria-controlsand arole="tabpanel"results region (matching the dashboard upload-tabs precedent); answer images get a fallbackalt; launcher icon tones and the safety selection state move from raw Tailwind palette classes to the categorical--type-*/ semantic danger token triads so they respond to dark mode and forced-colors.services-navigator-preview.tsx(dead export carrying ~80 pre-token hex hardcodes) and tokenized the live/servicesnavigator's residual hardcodes — the route now follows dark mode like every other surface.globals.css; onerounded-[var(--radius-md)]→rounded-md;/mockups/*layout now emitsrobots: noindex.docs/design-system.md— a consolidated front-door design guide (token contract, legacy-hex migration table, type-scale rules and ratchet, tap targets, z-ladder, Sheet-only modal policy, a11y requirements, do/don't gallery, UI Definition of Done).docs/redesign/*deep docs gain entry-point pointers;docs/process-hardening.mdrecords the ratchet baseline and cleared debts.dev-free-port.mjs/run-playwright.mjsno longer treat a missing IPv6 stack as "every port busy";playwright.config.tshonours an optionalPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATHoverride.Verification
npm run verify:cheap(lint, typecheck, 1097 vitest tests, runtime + sitemap checks — green)npm run verify:uiwhen UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed — 103/103 Chromium Playwright tests passed (smoke, stress, accessibility incl. reduced-motion + forced-colors, tools, overlap)npm run verify:releasebefore release or handoff confidence claims — not run (not a release/handoff PR)npm run format:checknpm run eval:retrieval:quality— not applicable: no retrieval, ranking, selection, chunking, or scoring behavior changednpm run eval:rag/eval:quality --rag-only— not applicable: no answer generation or post-processing changednpm run check:production-readiness— not applicable: no clinical workflow, privacy, environment, Supabase, source governance, or deployment behavior changednpm run check:deployment-readiness— not applicable: no deployment startup/hosting changesManual checks on the running app: styled 404 at unknown URLs and bad differential slugs;
?page=abc/?page=-3render page 1 with no NaN;/applicationsand/services?q=crisis&run=1render correctly.Clinical Governance Preflight
This change is UI-only: no ingestion, answer generation, search/ranking, source rendering, document access, privacy, production env, or clinical output behavior was touched. For completeness:
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
docs/process-hardening.md; UI PRs must not raise it. Flipcheck:type-scale --strictintoverify:cheaponly once the accepted rem display exceptions are tokenized.🤖 Generated with Claude Code
https://claude.ai/code/session_01QEEkTKt4eS4oqftBsaQKpG
Generated by Claude Code
Note
Low Risk
UI, documentation, and dev-script changes only; no auth, RAG, or data-path changes. Launcher modal migration is the main behavioral surface area and aligns with an existing Sheet primitive.
Overview
Adds
docs/design-system.mdas the day-to-day UI contract and pointsdocs/redesign/*anddocs/process-hardening.mdat it (type-scale ratchet baseline 20 hits, cleared debts).Behavior & a11y: Applications launcher mobile detail sections become real disclosures; the detail overlay moves to
Sheet; filter tabs wirearia-controlsand arole="tabpanel"results region. New token-stylednot-found, safe?page=parsing on document routes, and fallback imagealtin answer content.Design convergence: Removes dead
services-navigator-previewand tokenizes live services UI; swaps arbitrary px type for named scale steps across dashboard/launcher surfaces; documents z-index inglobals.css;mockupslayout getsrobots: noindex.Tooling: Playwright can use
PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH; dev port probes ignore IPv6EAFNOSUPPORTso sandboxes can start the app and run UI gates.Reviewed by Cursor Bugbot for commit 78ccd3a. Configure here.