refactor: decompose ClinicalDashboard monolith (AuthPanel + answer-content, move-only) - #202
Merged
Merged
Conversation
Adds scripts/capture-chrome-parity.ts: drives Playwright against the dev server with the smoke suite's demo API mocks and dumps getComputedStyle (incl. ::placeholder/::after) for the header + composer chrome across 16 states (home/answer/focus/document x mobile/desktop x light/dark). Selectors are refactor-stable (testids/aria/structure), never the chrome class names being migrated. --compare diffs two snapshots and exits nonzero on any difference, proving the @layer migration is pixel-identical. Snapshots write to the git-ignored scratch/ dir (machine-specific). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The "purple" mode-home pill tone (Youth service pathway dot) used a raw Tailwind palette color, the only non-token color introduced by #171. It did not adapt to dark mode or forced-colors like the surrounding tokens. Add --tone-purple (light #7c3aed == violet-600 so light mode is unchanged; brighter #a78bfa on dark; CanvasText under forced-colors) and reference it via bg-[color:var(--tone-purple)]. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cal) The header + mode pill was the source of the recurring overlap/shadow bugs. Move edge-glass-header (+ responsive padding), universal-header, universal-header-mode-button, and universal-header-icon-control into @layer components so Tailwind utilities on those elements now win instead of silently losing to the unlayered class. Reconciled the three shadow conflicts so rendered output is unchanged: drop the dead shadow-[var(--shadow-tight)] on the two edge-glass-header headers (class already sets box-shadow:none), and drop shadow-[var(--shadow-inset)] on the mode button and the New-chat icon control so the layered class supplies its shadow directly (avoids Tailwind's shadow utility injecting transparent ring-placeholder layers). Verified byte-identical computed styles across 16 states (home/answer/focus/document x mobile/desktop x light/dark) with scripts/capture-chrome-parity.ts. The frosted COMPOSER chrome stays unlayered (deferred): PR #171 pushed it to ~92 conflicts in shared ui-primitives constants; tracked in docs/process-hardening.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…aya-beb836 # Conflicts: # scripts/capture-chrome-parity.ts
…anel Move-only: AuthPanel plus its solely-consumed auth-email snapshot helpers (subscribeAuthEmail/getAuthEmailSnapshot/getServerAuthEmailSnapshot and the authEmailChangeEvent const) out of the ClinicalDashboard monolith into a self-contained module. No closure over main-component state; testid/aria strings unchanged (sha1 identical); pinned AST/rendered-text guards green. First step of the approved move-map decomposition (docs/redesign/04-deferred). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… into claude/kind-visvesvaraya-beb836
BigSimmo
enabled auto-merge (squash)
July 2, 2026 17:05
BigSimmo
disabled auto-merge
July 2, 2026 17:09
BigSimmo
enabled auto-merge
July 2, 2026 17:11
… into claude/kind-visvesvaraya-beb836
This was referenced Jul 2, 2026
Merged
BigSimmo
added a commit
that referenced
this pull request
Aug 5, 2026
Add #237–#239 from the fastest-wins planning session, repair mislabeled queue rows (#201/#202 vs #183/#185), remove archived #182 from the queue, and enqueue every previously open-but-unqueued item including P1s #207, #226, and #231. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.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.
What
Move-only decomposition of
src/components/ClinicalDashboard.tsxintosrc/components/clinical-dashboard/*, landing two modules so far.1.
auth-panel.tsxExtracted
AuthPanel+ its auth-email snapshot helpers verbatim. The isolated leaf of the map — no closure over main-component state, helpers solely consumed by it.2.
answer-content.tsxExtracted the answer render family (
SourceImage,ScopeAndGovernanceNotice, the answer/source formatters,SourcePreviewContent,NaturalLanguageAnswer,UserQuestionBubble,KeyClinicalItems) against the current (post-drift) monolith. The block moved verbatim — the original source range diffs empty against the new module body.Two monolith-internal helpers used by both the moved block and the code that stays behind went to clean shared homes instead of a monolith↔module import cycle:
useMobilePreviewSheet(+ its media-query snapshot helpers) → newclinical-dashboard/use-mobile-preview-sheet.ts(matches theuse-theme.tshook pattern)comparableAnswerText→clinical-dashboard/display-text.ts(the shared text-helper module)Move fidelity
data-testid/aria-labelstrings byte-identical acrossClinicalDashboard.tsx+clinical-dashboard/*.tsx(sha1 checksum unchanged before/after each move).Pinned guards — retargeted, not weakened
tests/clinical-dashboard-merge-artifacts.test.ts:findFunctionDeclarationnow scans ascannedFilesarray (monolith +answer-content.tsx); theNaturalLanguageAnswerpin resolves in the module,ClinicalOutputPanelstill in the monolith, and theclinicalOutputModeCopy/PrimaryAnswerContentabsence checks now cover both files.tests/rendered-text-formatting.test.ts: negative raw-render regexes now scan the monolith+module corpus (verified the module trips none); positivetoContainassertions stay pinned to the monolith where those strings remain.Gates (green)
npm run typechecknpm run lint— 0 errorsnpm run format:checknpm run verify:cheap— 903/906 (the one failure is an unrelatedrag-cache-invalidation15s timeout under parallel load; passes in isolation in ~6s)Deferred
Remaining modules (ordered hand-off in
docs/process-hardening.mdPhase 3):evidence-panels.tsx(clinical-detail helper family — must land before output-panel),output-panel.tsx(AST-pinnedClinicalOutputPanel),visual-evidence.tsx,document-results.tsx.🤖 Generated with Claude Code