Skip to content

Align Courts and every Explore page with the register's design system - #78

Merged
l0cka merged 9 commits into
mainfrom
feat/explore-ui-consistency
Aug 7, 2026
Merged

Align Courts and every Explore page with the register's design system#78
l0cka merged 9 commits into
mainfrom
feat/explore-ui-consistency

Conversation

@l0cka

@l0cka l0cka commented Aug 7, 2026

Copy link
Copy Markdown
Owner

The register, developments and policy-detail pages set the design system; the Courts page and the Explore pages had drifted. Three review groups brought them into line, a fresh-eyes reviewer judged the whole surface at once, and a fix wave closed what it found. Net −167 lines: consistency here meant deleting bespoke styling, not adding it.

What changed

  • Courts / Agencies / Timeline — 22 divergences: ad-hoc heading sizes → the four heading classes; bordered metric grids → hairline bands; ad-hoc status/jurisdiction markup → the shared components. StatusPill and JurisdictionMark are now exported from policy-table.tsx and reused everywhere; SourceState accepts a bare verification status.
  • Map / Network — panels and sidebar adopted the register's chrome (eyebrow labels, hairline rules, StatusPill); three spots misusing --trust decoratively moved to --primary; design-tokens.ts and jurisdiction-colors.ts deleted — dead hardcoded-hex helpers once their callers moved onto tokens.
  • Framework — the worst offender: shadcn Cards/Badges/Buttons with rounded-none band-aids, bg-gray-* fallbacks and dark: classes that never tracked the site's theme toggle, all flattened to token-driven bordered chrome; view toggle now matches the register's.
  • Blogprose-slate → token-driven prose. This fixed a real dark-mode bug the screenshots caught: Typography's own layer beat an @layer base override, leaving post headings near-invisible in dark mode.
  • Two rendering bugs found by screenshot, not inspection: content-visibility intrinsic-size underestimation blanked sections on /timeline and /developments (the latter pre-existing on the reference page itself). Both fixed.

Verification

All on Argus: 442/442 tests, typecheck, lint, next build; 30-screenshot sweep (10 pages × light/dark 1440 full-page + mobile 390) — zero horizontal overflow; final cross-page review verdict MERGE-READY with no regressions on register/developments from the shared-component refactor; network graph confirmed rendering (9 nodes/6 edges) with proper settle time.

Deliberately left

  • Framework pillar titles are Title Case from dta-ai-policy-framework.json — data content, not presentation; flag if you want the data edited.

🤖 Generated with Claude Code

l0cka and others added 9 commits August 7, 2026 16:41
…design system

Courts: heavy rule and row borders were ad-hoc (border-foreground,
border-border/30) instead of tokens; status shown as plain coloured text
instead of the StatusPill used everywhere else; jurisdiction section
headers had no accent dot and used an ad-hoc font size instead of
.page-eyebrow; rows had no ink-rail hover spine.

Agencies: search input used a per-element focus colour instead of the
global focus-visible convention; jurisdiction column was plain text with
no accent dot; statement status was ad-hoc coloured text instead of the
CheckCircle2/CircleAlert language used elsewhere; mobile view kept the
desktop table (columns cropped, required horizontal scroll) instead of
switching to cards like PolicyTable; a stats sentence duplicated the new
MetricStrip.

Timeline: filters/legend lived in shadcn Card boxes (register uses a
plain border-l sidebar); event colours were hardcoded Tailwind classes
(bg-green-500 etc, not theme-aware) with no legend entry for the
"superseded" type; event rows used oversized circular year avatars and
shadcn Badges instead of the developments-browser feed pattern.

Extracted StatusPill, JurisdictionMark and a now-reusable SourceState
(takes a verification object rather than a full Policy) from
policy-table.tsx so all three pages share the exact same status/
jurisdiction/verification presentation as the register.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
content-auto (content-visibility:auto + a 72px intrinsic-size guess) is
fine for the register's flat rows, but on the timeline's deeper per-event
grid it produced enormous blank gaps between year sections in the
full-page screenshot capture. The performance win isn't worth a broken
layout here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Shared: SourceState now accepts just a verification status (Pick<...,
'status'>) so pages without the full RecordVerification object can still
use it. Deleted design-tokens.ts (STATUS_COLORS/STATUS_BG_COLORS) and
network/jurisdiction-colors.ts, both dead-ending hardcoded-hex helpers
once their only two callers were moved onto the token system.

/map: policy status now renders via StatusPill instead of hardcoded
STATUS_COLORS text; jurisdiction eyebrow label and panel heading moved
onto .page-eyebrow/.section-title; policy list rows gained the
register's ink-rail + --row-hover hover treatment; ad-hoc shadow-xl/
shadow-lg and `rounded` radii swapped for --shadow-lift and rounded-md.

/network: sidebar's status/type/jurisdiction/verified chips now use
StatusPill, JurisdictionMark and SourceState; heading sizes moved onto
.page-eyebrow/.section-title; three spots that reused --trust purely as
a decorative accent (selected-theme chip, shared-theme tags, numbered
connection badge) switched to --primary/--accent; the metrics band lost
its internal grid-line borders in favour of a single hairline; sidebar's
ad-hoc box-shadow moved to --shadow-lift.
Flatten shadcn Card/CardHeader/CardTitle/Badge/Button/Separator to the
register's bordered-section chrome. Drop the unique "Back to Policies"
breadcrumb (no other Explore page has one; /framework is reached via
header nav like the rest). Replace ad-hoc text-2xl/text-xl/text-lg
headings with the contract's page-title/section-title/page-eyebrow
scale. Replace per-record hardcoded pillar/aim hex colours (baked into
the framework JSON, inconsistent with light-dark theming) with neutral
bordered icon chips. Replace requirement-type badges'
dark:bg-red-950-style Tailwind dark: classes -- which never respond to
the site's data-theme toggle, only prefers-color-scheme -- with a
token-free emphasis scale (bold/plain/muted) so severity reads without
repurposing --trust/--caution/--alarm. Overview/Detailed switch now
matches the register's ViewToggle instead of default shadcn Buttons.
Sentence-case headings throughout.
Blog index: row title used ad-hoc font-display text-2xl (a heading-scale
violation); switched to the sans font-semibold weight used by every
other feed row (developments-browser, PolicyCard) since a listing row
is not a page/section heading.

Blog post page: replaced the ArrowLeft "Back to Blog" breadcrumb -- a
pattern that exists nowhere else in the app -- with the same mono
trail nav used on the policy detail page. Aligned the post date format
(dd MMMM yyyy) with the blog index, which used the opposite day/month
order. Dropped prose-slate: it hardcodes a fixed palette with no
dark:prose-invert wired up (and dark: doesn't track the site's
data-theme toggle anyway), so dark-mode readers got light-mode prose
colours. Added a light-dark()-aware --tw-prose-* override block in
globals.css so the typography plugin follows the same tokens as
everything else, in both themes, with no invert variant needed.
The dl already spaces its children with space-y-4; a leftover mt-4 on
the first item pushed it further from the heading than the second
item's gap from the first. No visual system change, just a tidy-up
found while auditing the page (already aligned from an earlier pass).
Left over from removing the section-header icon on "Principles and
requirements" when the heading dropped to page-eyebrow.
The --tw-prose-* override lived in @layer base, but @tailwindcss/typography
injects its own .prose reset into a higher-priority layer. CSS layer
order beats source order, so the plugin's fixed (light-only) heading/body
colours were winning regardless -- confirmed by screenshot: headings and
paragraphs past the first block rendered near-invisible dark-on-dark on
/blog/welcome-to-policai in dark mode, while the same page was fine in
light mode (the plugin's hardcoded dark text happened to look right on
a light background). Moved the override out of any @layer so it wins
unconditionally, per the CSS spec (unlayered beats layered).
content-auto (content-visibility:auto + a 72px intrinsic-size guess)
underestimates the developments browser's variable-height article rows,
same as the timeline bug in 62a5e31 — offscreen month sections rendered
only their headers with blank space below until scroll/resize forced a
repaint. Also swap back-to-top's hardcoded shadow-lg/xl for the
--shadow-raise/--shadow-lift tokens to match the design system.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@l0cka
l0cka merged commit 8c5d375 into main Aug 7, 2026
3 checks passed
@l0cka
l0cka deleted the feat/explore-ui-consistency branch August 7, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant