Import WA psychiatric services catalogue and clinical registry snapshots - #261
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Updates to Preview Branch (codex/pr-258-header-only-final) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
Wire Psych Differentials v10 into differential_records, snapshot loaders, API routes, presentation workflows, and seed scripts. Fix option label parsing for hyphenated names like Post-ictal confusion. Co-authored-by: Cursor <cursoragent@cursor.com>
Add medication and services snapshots, Supabase migrations, API routes, registry catalog payload, document admin drawer, and cross-mode search integration. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…cope. Restore unauthenticated fixture responses for medication routes and drop redundant local-no-auth publicOnly branching in search scope. Co-authored-by: Cursor <cursoragent@cursor.com>
BigSimmo
force-pushed
the
codex/pr-258-header-only-final
branch
from
July 5, 2026 08:15
0a87719 to
065d95f
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
Drop before recreating the text retrieval RPC when its OUT signature changes, and keep retrieval_synopsis through the lexical_score migration so fresh branch replays do not hit SQLSTATE 42P13. Co-authored-by: Cursor <cursoragent@cursor.com>
Guard retention cron migrations so Supabase Preview branch replays succeed without cron.job, and neutralize the duplicate rag_queries retention migration. Co-authored-by: Cursor <cursoragent@cursor.com>
…rations Document fresh-replay invariants and assert match_document_chunks_text drops and cron schedules are guarded. Co-authored-by: Cursor <cursoragent@cursor.com>
Split snapshot loading into medication-snapshot.ts so client components do not bundle the full medications JSON. Remove an invalid query prop from MobileEvidenceSheetContent. Co-authored-by: Cursor <cursoragent@cursor.com>
Owner
Author
|
@copilot resolve the merge conflicts in this pull request |
BigSimmo
enabled auto-merge (squash)
July 5, 2026 09:18
Contributor
Resolved and pushed. Merge conflicts were fixed in |
auto-merge was automatically disabled
July 5, 2026 09:22
Head branch was pushed to by a user without write access
Co-authored-by: Cursor <cursoragent@cursor.com>
BigSimmo
enabled auto-merge (squash)
July 5, 2026 09:37
Avoid a redundant 30s API wait on repeat navigations and give the prescribing workflow smoke test enough time for CI Chromium runs. Co-authored-by: Cursor <cursoragent@cursor.com>
Route unauthenticated subject limiting through consume_api_subject_rate_limit so registry public-access tests pass, and teach the private-access mock to count subject RPC calls for burst-limit coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
Update mode-home, document-search, differentials, and command-surface expectations introduced by the WA catalogue import work. Co-authored-by: Cursor <cursoragent@cursor.com>
Align ui-tools and ui-smoke assertions with snapshot-driven differential counts, hero search portaling, document-search layout order, and mobile settings fullscreen tolerance. Co-authored-by: Cursor <cursoragent@cursor.com>
2 tasks
BigSimmo
pushed a commit
that referenced
this pull request
Aug 7, 2026
…n-kind decision #256 was 'suspected remaining' for form-overview and the differential-presentation-* set. Both are now confirmed dead, so two live routes draw no section nav at all: /forms/<slug> (one anchor is a testId rather than an element id, the other five are rendered nowhere) and /differentials/presentations/<slug> (all six absent, and the only dynamic section id in that family uses a different prefix on a different route, so nothing is hiding behind a sectionId prop). Also captures #261: whether to delete SecondaryNavigationActionItem, which lost its last live consumer in PR #1679 and was deliberately kept. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01823Ctwj4vinGhGuRNyK7oE
BigSimmo
added a commit
that referenced
this pull request
Aug 8, 2026
…sured (#1719) * docs(issues): correct the re-measured A3 scope and B1 adoption count Replays a correction stranded in a local-only worktree when PR #1712 squash-merged and its branch was deleted before the commit could be pushed. Both figures were re-measured today against origin/main 2675e6e rather than copied forward, and one claim in the stranded version turned out to be wrong. #262: legacyShadowAliases counts SEVEN tokens, not one and not eight — the regex has matched tight|card|soft|hover|elevated|lux|lift since PR #1616 and has never included focus. Measured total 228 = tight 100, soft 72, elevated 17, hover 17, card 12, lux 8, lift 2. So --shadow-tight is 100 production sites across 55 files rather than the 155 or 229 previously recorded, clearing all 100 will not zero the ratchet, and #261's --shadow-focus does not appear in this metric at all. #266: adoption is 23 unadopted, not 24, since Button moved via #263 — its sole production importer is src/components/AccessibleTable.tsx. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(design-system): mark the TextField/SearchField/Select row done, it was stale Replays a correction stranded in a local-only worktree when PR #1712 squash-merged and its branch was deleted before the commit could be pushed. Re-measured today against origin/main 2675e6e: all three fold onto FormField, which renders hint AND error unconditionally (form-field.tsx:131-132) and merges aria-describedby caller -> hint -> error (form-field.tsx:107-109); TextField and SearchField each take an external id and a Ref<HTMLInputElement>, Select an external id and a Ref<HTMLSelectElement>. Landed in PR 13, not the PR 7 the row pointed at. Section 4's 'Do: fold TextField/SearchField/Select/Checkbox/RadioGroup onto this shell (PR 7)' was stale in a second way and is corrected too: Checkbox and RadioGroup deliberately do NOT fold onto FormField — a group keeps fieldset/legend and composes FieldHint/FieldError directly (choice.tsx:207-210). Left as written, that line asks a future session to 'finish' a fold that is finished and to break one that was a deliberate decision. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: correct future-dated re-measurement records to 2026-08-08 Codex review on PR #1719 flagged SCOPE/COUNT RE-MEASURED and COMPONENTS.md rows dated 2026-08-09 while the recording commits were authored on 2026-08-08. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com> * docs(design-system): separate FormField integration from product adoption, re-measure the ui-primitives row Two review findings on PR #1719, both valid. Section 4 said 'Select/choice controls remain separate adoption work', which contradicted the section above it and was wrong on both axes for Select: select.tsx consumes FormField (folded in PR 13), and adoption-manifest.json gives Select 2 production importers, so it is adopted. The genuinely unadopted member of the trio is SearchField, at zero, which the sentence did not mention. Rewritten to state the two axes explicitly — integration is complete for TextField, SearchField and Select, and deliberately declined for Checkbox/RadioGroup; adoption is measured TextField 3, Select 2, SearchField/Checkbox/RadioGroup 0 — so a control cannot be read as pending on one axis because it is pending on the other. The ui-primitives row carried three stale figures. Re-measured on this head: the module is 698 lines, not 686; 157 production files import it, not 200 — that figure is 202 including mockups, the same mockup-inclusive mislabelling this PR already corrects for the shadow aliases; and 30 of the 53 registered components are adopted, not 27. Future-dated 2026-08-09 records were already corrected to 2026-08-08 by f3a91c6 before this commit; verified none remain under docs/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
BigSimmo
added a commit
that referenced
this pull request
Aug 8, 2026
* docs(design-system): stamp the 7 August handover superseded Nine open ledger rows (#261, #262, #264-#270) cite docs/design-system/HANDOVER-2026-08-07.md as their Source, and docs/design-system/README.md sent anyone picking the work up cold straight to it as "measured state, the ordered plan". Four of its figures have since been disproved, and the corrections were written into the ledger rows rather than the document, so the document still asserts the originals. A session scoping from it re-derives work that is already known wrong. Recorded as #277. A banner rather than a rewrite, which is what #277 asks for: the corrections already live in the rows, and duplicating them re-creates the drift this fixes. The banner names the four measured errors -- the "229 --shadow-tight aliases" that is really a seven-token total mislabelled as one token (100 sites across 55 files, 228 total), the 24-vs-23 unadopted count, the "baselines cannot be generated on Windows" conclusion that overlooked the ubuntu CI job now used under #118, and #270's 22-site premise that has zero same-variant pairs -- then points at the rows. The README now sends a cold start to docs/outstanding-issues.md and marks the handover superseded in the link text itself, where the misdirection was. Deliberately not done: the document is not deleted, moved, or corrected in place. The nine Source citations, the PR and commit record, and its verification and gotcha sections are provenance the ledger is meant to preserve, and silently correcting it would leave those rows citing a document that no longer says what they were derived from. Verified: npm run docs:check-links -- "docs link check passed: 1667 repo path references resolve"; npm run docs:check-inventory -- current; npm run format:check -- "All matched files use Prettier code style!". Refs #277 * docs(design-system): drop false #118 baseline-adoption claim The superseded banner said all six visual baselines were adopted under #118, but the ledger still has #118 open and tests/__screenshots__/ holds only README.md. Keep the accurate Ubuntu-CI generation point without implying visual-regression protection exists yet. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
BigSimmo
pushed a commit
that referenced
this pull request
Aug 11, 2026
Handoff record for PR #1807 (DS Track A2, --shadow-focus retirement). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012spLo9ry4zjoDyZi7j89kT
BigSimmo
pushed a commit
that referenced
this pull request
Aug 11, 2026
DS Track A2. `--shadow-focus` packed a 3px accent halo in front of `--shadow-soft`, so its one consumer — `.chat-composer-shell-delta:focus-within` — painted a companion ring on top of the accent border swap. That is the second focus affordance the shared `:focus-visible` treatment is written to prevent (GATES Gate 3). The composer now uses `outline: 2px solid var(--focus)` at `outline-offset: 2px`, and both theme declarations of the token are deleted. Focus no longer overrides `box-shadow`. The retired token carried `--shadow-soft` as its second layer, so leaving the resting elevation alone keeps the pill seated at the same height focused as at rest. Measured in Chromium: light `solid 2px rgb(29, 111, 184)`, dark `solid 2px rgb(116, 189, 240)`, box-shadow byte-identical resting vs focused in both themes. Corrects the premise inherited from HANDOVER-2026-08-07 A2: this is not a visible production focus change. `chatComposerShell` is imported only by `calculators/search-detail.tsx` and its mockup twin; production `/calculators` renders `chatComposerShellBase` + `answer-footer-search-pill`, and `CalculatorSearchHome` is reached only from two unrouted mockup exports. Probing all 37 static production routes in Chromium found zero renders of the class; the single live render is `/mockups/calculators-search`, where the look was taken. The inherited note was right that a `--include=*.tsx` grep misses the consumer (it is in CSS) but wrong about its reach. Corrections recorded in the handover's own "Measured wrong so far" list, per that file's convention. Guard: design-token-contract.test.ts rejects both a `--shadow-focus:` declaration and a `var(--shadow-focus)` consumer, across globals.css and the v2 layer, and is mutation-verified against both. Deliberately not the whole-file substring check used for `--shadow-tight`, because the composer rule names the retired token in a comment on purpose. legacyShadowAliases 127 -> 125 (soft 71 -> 69), globals.css per-path pin tightened 3 -> 1: the deleted declarations' VALUE ended in `var(--shadow-soft)`, so they scored as two `soft` aliases — the indirection GATES documents. Left un-ratcheted as pre-existing slack unrelated to this diff: rawPaddingLiterals 67 -> 65, rawGapLiterals 34 -> 32, layoutTransitionExceptions 12 -> 11. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012spLo9ry4zjoDyZi7j89kT
15 tasks
BigSimmo
pushed a commit
that referenced
this pull request
Aug 12, 2026
…system rows Archived as verified-delivered or duplicate: #303, #284 (dup of #296), #149, #159, #286, #287, #288, #256, #261, #291. Re-scoped with re-measured evidence: #210 (gate was never missing; the defect is the .next/dev types include), #262 (aliases 228 -> 193), #266 (counts moved, 23 unadopted holds), #275 (premise 'only one implementation' is false — the values leaked to five files). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017paT42ZVMf8jaLtkjFxdy5
BigSimmo
pushed a commit
that referenced
this pull request
Aug 12, 2026
docs/outstanding-issues.md has no merge driver by design, so this conflicted in seven hunks. Resolved by taking main's file as the base — it carries main's own archives (#207, #226, #230, #261, #284, #296) — then re-applying all 23 of this branch's changes through scripts/outstanding-issues.mjs: 15 archives and 8 detail rewrites. Verified afterwards that every one landed and that the guard reports no ids deleted from base. Two rows are deliberately NOT resurrected. This branch's #302 (style-contract line-break artifacts) and #303 (issues:next-id sync) no longer exist anywhere on main under any id — main has since reused both numbers for entirely different live rows. Both of this branch's rows were verified-delivered trivia, so nothing actionable is lost, but the disappearance is itself evidence for #156/#168: a main-side merge dropped rows, which is the hazard those rows describe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017paT42ZVMf8jaLtkjFxdy5
BigSimmo
added a commit
that referenced
this pull request
Aug 18, 2026
* feat(ui): one category-identity registry for card glyphs and accents Icons and category colour were spread across ten independent maps and two of them disagreed, so the same tool rendered differently depending on which screen reached it. - `launcherIconById` (applications-launcher-page.tsx) carried 13 tool ids; `iconByToolId` (tools-search-results-page.tsx) carried 8 with a different fallback, so `guidelines`, `care-plans`, `safety-plan`, `calculators` and `monitoring` showed a real glyph on the launcher and a generic `Grid2X2` in search results. - Colour diverged the same way: the launcher tinted by tool area, the results page painted every tile `--type-source`, so one list read as a single purple family while the other grouped the same tools into five. - `ShieldCheck` was assigned to `guidelines`, to `risk-safety`, and to the "Source-backed" status chip — three unrelated meanings, one glyph, reachable on a single card. - `appIconTone` overrode the area map per id, routing `differentials` and `forms` to a tone key named `differentials`, so the advertised "category colour" was not a category colour. `src/lib/category-identity.ts` is now the single source of truth. It is framework-free (string glyph keys, no lucide) following the `semantic-tone.ts` precedent, so data and server modules can name a glyph without the render layer; `category-identity-icons.ts` is the only place that binds keys to components, resolving through `createElement` as `factsheets-icons.ts` does to satisfy `react-hooks/static-components`. `ToolCatalogRecord.id` is narrowed from `string` to a `ToolCatalogId` union, so `Record<ToolCatalogId, …>` cannot be under-filled: adding a tool without choosing a glyph is now a type error rather than a silent runtime fallback. `appModeIcons` keeps its name and shape but is derived rather than hand-maintained, so its "keep in sync" comment is now a property of the type. Accent delivery is `data-category-accent` → `--cat-accent`/`--cat-soft`/ `--cat-border` in globals.css rather than interpolated class names, which Tailwind's scanner cannot see, and rather than inline styles, which bypass the theme contract. Every accent aliases an existing non-semantic triad (`--type-*`, `--tone-*`), so light, dark and forced-colors need no new declarations. `risk-safety` loses its permanent danger-red tile: red asserted caution about a route rather than about a patient, spending the loudest colour in the system on a navigation target. Safety is carried by the now-unique shield glyph and by the danger-toned selected state, which is a real state. Gates: typecheck, lint, `npm run test` (643 files, 6882 passed / 4 skipped), check:design-system-contract, check:icon-scale, check:type-scale — all green. No provider-backed check was run and none is required; no RAG surface touched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XGhewT2mmRoRTynjWfF1Vn * fix(factsheets): stop painting content categories in semantic colours `categoryTheme()` drew two of its four category accents from the SEMANTIC palette: Therapies on `--success-text`/`--success-bg` and Tests & procedures on `--warning-text`/`--warning-bg`. Those tokens carry meaning. `src/lib/semantic-tone.ts` defines six tones where the colour IS the claim — warning means "pause, check, adjust, review", success means a check passed — and `docs/clinical-badge-system-guide.md` states the rule as "meaning drives the colour, never the other way round". Applying warning-amber to an entire category of patient handouts asserted caution about content that nothing had reviewed, and it did so on the largest surface the factsheet has: the hero band. It also spent a colour the badge system needs, so a genuine caution badge had to compete with its own page chrome. All four categories now sit on non-semantic identity triads, sourced from `FACTSHEET_CATEGORY_IDENTITY`: Medications --clinical-accent -> --type-form Conditions --tone-indigo -> --type-source Therapies --success-text -> --type-service Tests & procedures --warning-text -> --type-table Medications moves too, for a different reason: it was the same blue as every selection state, focus ring and evidence marker on the page, so the biggest category was the one with no identity of its own. `FactsheetTheme`'s shape is unchanged, so the ~20 call sites passing these as inline style values are untouched. `FactsheetCategory` is now a re-export of the registry's union, so the accent map and the content model cannot disagree about what the categories are. Three guards added to tests/design-token-contract.test.ts, each mutation-verified: - no `[data-category-accent]` rule may reference a semantic token (verified: pointing "table" at --warning-text fails the test) - `categoryTheme` must stay derived via `categoryAccentVars` and return no semantic token (verified: reinstating the old --warning-* return fails it) - `CategoryAccent` may not declare a semantic member, which is what makes the mistake unrepresentable at every call site rather than caught per site Gates: typecheck, lint, `npm run test` (643 files, 6885 passed / 4 skipped), check:design-system-contract — all green. No provider-backed check run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XGhewT2mmRoRTynjWfF1Vn * refactor(ui): add the shared card recipe and absorb the two private forks Four cards that sit side by side in the same shell had drifted on every axis: ToolCard rounded-lg --shadow-card p-4 border + tint + hover lift ServiceCard rounded-xl --shadow-inset p-3 sm:p-4 border + ring/35 CalculatorCard rounded-lg --shadow-inset p-4 border + --shadow-soft Factsheet card rounded-xl --shadow-card - inline-style border-t-[3px] Two radii, three resting elevations, and four different "this one is selected" encodings, three of those expressed as fractional opacity on a token colour — which is unreviewable, because the contrast an alpha lands on depends on whatever surface happens to sit behind it in each theme. `src/components/card-recipes.ts` holds the shared definitions: `cardSurface`, `cardInteractive`, `cardSelected`, `cardAccentEdge`, `cardPadding`, and one exported `focusRing` (that string is currently redeclared as a local const in a dozen files and inline in dozens more). Recipes rather than a registered component: COMPONENTS.md §0.4 measures 157 production importers of ui-primitives.tsx against 31 product imports across the whole 54-component registry, and ledger #266 says adoption is demand-driven, "never a race to 54/54". A function also sidesteps element polymorphism — these cards are variously <article>, <button> and <Link>. A new module rather than growing ui-primitives.tsx, which §0.4 already lists as over-budget and slated to split. Two deliberate departures from what the four cards did: - `--shadow-inset` is dropped as a card elevation. It is the design-system bevel, and SPEC §4.7 says an inset well uses a border or inset shading, not both; pairing it with a border is why the services and calculator cards read flatter than the tool cards beside them. Resting is border + --e1. - The recipes name `--e1`/`--e2`/`--e3` directly rather than the `--shadow-card` / `--shadow-soft` / `--shadow-hover` role aliases. TOKENS.md schedules those for retirement "inside the recipes first", and the contract ratchet counts every use — a new consolidating module reaching for one would move the count the wrong way. Caught by the gate on the first attempt (114 -> 115); now 113, unchanged from baseline. `specifierCard` and `formulationCard` were byte-identical copies of the same string; both now name the shared recipe. This moves those two modes' cards from `--surface` to `--surface-raised`, which is the SPEC §177 correction (true-white cards against the near-white page) and is a visible, intended change. Consumers for `cardInteractive`/`cardSelected`/`cardAccentEdge` land in the following commit. Gates: typecheck, lint, `npm run test` (643 files, 6885 passed / 4 skipped), check:design-system-contract, check:knip — all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XGhewT2mmRoRTynjWfF1Vn * feat(tools): elevate the tool cards and merge the phone/desktop pair The launcher rendered two components for the same content — `ToolCard` and `MobileToolRow` — and they had already drifted: different resting elevation (--shadow-card vs --shadow-inset), different selected tint (/50 vs /55), and a hover lift on one but not the other. They are now one component with a `density` prop. Both test ids are kept: `application-card-*` and `application-row-*` are each asserted by ui-tools and ui-smoke, and ui-smoke is blocking at zero retries. Verified in Chromium at 390px that the row renders visible and the card hidden, with all 13 of each still in the DOM. Craft changes, launcher and tools search results: - The fake button is gone. `Details` was a <span> painted as a solid accent button INSIDE the card's own <button>: it read as a nested control, was announced as nothing, was the loudest element on the card, and — being identical on every card — distinguished nothing. The card is the control; a chevron on the decoration tier says so, taking the category accent on hover so the affordance points at the card's own family. - On the search results page the same button is real (that card is an <article> and not itself clickable), so it stays — but as `floatingControl` rather than a filled accent. Thirteen filled primaries down one list were thirteen primary actions, none of them the page's actual primary action. - Titles move from `text-base font-extrabold` to `text-lg font-semibold`. At extrabold they matched the section heading above them, so a grid of cards read as a wall of headings. Size carries the hierarchy; weight stops trying to. SPEC §4.6 puts card titles at --text-lg. - "Best for:" was a bold inline run inside the body copy, giving a label the same emphasis as the clinical text it labels. It is a kicker, so it uses the shared `eyebrowText` recipe. - The magnifier beside "Best for" on the results page is dropped: "Best for" is not a search, and it spent an accent-coloured glyph on a label. - The selected rail on a results row takes the tool's own category accent rather than the product blue, so it agrees with the tile beside it. - `min-h-[9.25rem]` and `min-h-[5.25rem]` are replaced by content height with a `min-h-tap` floor. Production tap targets stay at min-h-12. - The local `focusRing` const in both files now imports the shared one. `risk-safety` keeps a danger-toned SELECTED state via the new `cardSelectedDanger` — selection is a real state, unlike the permanent red tile retired earlier in this branch. `legacyShadowAliases` fell 113 -> 111 as the cards moved off --shadow-card and --shadow-inset onto the --e ladder. Gates: typecheck, lint, `npm run test` (643 files, 6885 passed / 4 skipped), check:design-system-contract, check:icon-scale, check:type-scale — all green. Chromium: check:playwright-browser-revision was failing on the known #255 drift (1194 installed against the pinned 1234); the pinned revision was installed, the check now reports OK, and ui-tools + ui-hydration + the ui-smoke tools assertions were run locally against it. Five ui-tools failures were investigated and are pre-existing: all four reproduce on origin/main with this work stashed (two /services/13yarn composer cases, two service-detail cases, and the tools mobile detail-sheet case), and the tools one passes when driven manually, so it is environmental rather than a regression. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XGhewT2mmRoRTynjWfF1Vn * feat(ui): adopt the card recipe and category accents on factsheets, calculators and services Factsheets - The three inline `style` objects per card are gone. An inline value cannot be remapped by the dark or forced-colors blocks, so the old cards carried their light-mode tint into both. Verified in Chromium: the four accents now remap correctly in dark, and under forced-colors they flatten to Canvas/CanvasText as they should — identity colour is decoration, and the glyph and category chip carry the meaning in high contrast. - The category browse pills take the same accents, so a pill and the cards it filters to now agree. - Card titles move to `text-lg font-semibold`, and hover tints the title with the card's own category accent rather than the product blue. Calculators - The directory tile was grey until a card opened, so a closed directory showed five domains rendered identically and the domain was findable only by reading the chip. It now carries the domain accent at rest — which is what the chip beside it has always said in words. - `CALCULATOR_DOMAIN_ACCENT` deliberately gives `risk` (suicide risk) an identity accent, not `--danger`. The label already says "Suicide risk", and an instrument is not itself a warning; a red tile on a directory row would claim urgency about a tool rather than about a patient. - Open/closed states move onto `cardSelected` and the --e ladder. Services - Adopts `cardSurface` + `cardSelected`, retiring the fourth "this one is selected" encoding (`ring-1 …/35` — an alpha on a token colour, so what it contrasted against depended on whatever surface sat behind it per theme). - The leading tile deliberately stays a RANK rather than becoming a category glyph: this is a ranked referral list, the number is what the "Best fit" pill refers to, and it doubles as the shortlist checkmark. Services has no single category axis either — records carry facets — so there would be nothing honest to put there. Ratchets moved the right way: legacyShadowAliases 111 -> 107, edge conflicts 19 -> 18. Deferred, unchanged: therapy-compass/therapy-card.tsx (own SVG icon set, own control recipes, own IconTile, and the open rawPadding/rawGap debt from #261), the differentials-home card family, and the forms detail cards — those are detail-panel compositions rather than category-bearing list items. Gates: typecheck, lint, `npm run test` (643 files, 6885 passed / 4 skipped), check:design-system-contract — all green. Chromium inspection at 390/1440 in light, dark and forced-colors against the pinned revision 1234. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XGhewT2mmRoRTynjWfF1Vn --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
data/services-snapshot.json, with catalog mapper, registry fixtures, andcatalog_payloadmigration.services.ts/ registry seeding so signed-in users load owner-scoped records from Supabase instead of hardcoded fixtures.Verification
josh@stoicable.com:/api/registry/records?kind=servicereturns 200 with 222 owner records (includes 13yarn);/servicesrenders catalogue UI.tests/services-catalog.test.ts,tests/services.test.ts,tests/registry-records-route.test.ts,tests/supabase-schema.test.ts(55 tests passed).4f1b3c19-3c39-4597-b9df-168c8e6007ff.npm run verify:cheap(not run in this session)Test plan
/?mode=services— confirm 219 catalogue records and search (e.g. 13YARN).npm run registry:seed -- --kind service --write --confirm --owner-id <uid>on a fresh owner if needed.20260705030000_registry_catalog_payload.sqland20260705120000_differential_records.sqlif remote is behind.npm run verify:cheapbefore merge.