UI/UX: one enforced design system across every public surface#66
Merged
Conversation
…parity enforcement Root cause of the UI drift: brand.json/brand.js called themselves "the single source of the brand" but held zero colors. The ember/warm-black palette was hand-duplicated across landing/index.html and build-pages.mjs under *two different naming schemes* for the same hexes (--ink/--surface/--ember vs --bg/--panel/--brand), so the two "one" palettes could — and did — fork. - brand.json: add a `colors` block (full dark + light palettes) as the one source of hexes, plus `fonts` and `site`. - src/brand.js: add `cssVars(scheme)` + `rootTokensCss()` pure helpers that emit the :root token block and a prefers-color-scheme:light override. - build-pages.mjs: status page now injects tokens from brand.json via rootTokensCss() (gains light mode; was dark-only) and uses the one naming scheme everywhere (--ink→--bg, --surface→--panel, --fg→--text, --ember→--brand). - landing/index.html: redefine --brand-2/--ok for light mode so peach/mint accents meet AA contrast on light backgrounds. - test/pages.test.js: enforce FULL-palette parity (every dark AND light hex in brand.json.colors must appear on both public pages) — change one hex there and this fails until every surface updates. That is what makes brand.json the source of truth. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
… chrome Rebuild landing/index.html on a Stat-Led structure (modern-minimal genre) so it reads as made, not generated. The redesign removes the AI-slop tells the old page carried and embeds the real shipped artwork instead of a weaker redrawn hero. Killed: - The fake terminal window (three identical traffic-light dots + mock title bar wrapping a <pre>) — replaced with an honestly-labelled code <figure>. - Placeholder digit-icons 01-06 and the glyph "icons" — replaced with real inline stroke SVG icons that mean something (layers, shield-check, radar, reuse-loop, lock-check, git-branch; dashed-node graph + gauge for the limits). - The uniform 3x2 bordered icon-tile grid — capabilities now sit in a hairline-divided two-column list, breaking the card-in-card rhythm. - The faux-live "pulse" dot (styled with a glow ring but static) — now a plain honest status marker. Added / fixed: - The real hero diagram (docs/assets/hero-*.svg) is embedded, inlined so it resolves both in local preview and at the deployed site root (the Pages deploy copies only index.html, not docs/assets). Dark and light variants toggle by prefers-color-scheme. - Metrics kept but sourced (118 ms / 0.43 ms from reports/benchmarks.md, 62.1% from the white-paper prototype, 0 deps from package.json) — no invented numbers. - overflow-x: clip on html+body, minmax(0,1fr) grids, eyebrow stacked above the heading, instant focus-visible rings, compositor-light nav blur (8px). - Verified via headless Chromium at 320/375/768/1280 in dark+light: no horizontal scroll at any width, hero fits, real SVG renders. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
Landing set twitter:card=summary_large_image but shipped no og:image, so social cards rendered blank; neither page had a favicon; the status page had no OG / canonical / JSON-LD at all. - Author a 1200x630 brand card (docs/assets/og.svg -> og.png, rasterized once via the pre-installed Chromium — a committed author artifact, not a runtime dep) and an ember "F" favicon (favicon.svg) + apple-touch-icon.png. - Landing head: add og:image/twitter:image (absolute), og:image:width/height/alt, twitter:title/description, favicon + apple-touch-icon links, og:site_name. - Status page (build-pages render): add canonical, full Open Graph, Twitter card, favicon/apple-touch-icon, and a SoftwareApplication JSON-LD — all derived from the single brand.json site.url (new SITE base), so canonical == og:url. - static.yml: copy og.png + favicon.svg + apple-touch-icon.png to the Pages root so the absolute URLs resolve on the deployed project site. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
forge uicheck design + a WCAG pass flagged sub-4.5:1 supplementary text and six ad-hoc border-radius levels on the redesigned landing page. - Contrast: bump --faint (dark 3.9->4.6, light 4.0->4.6), light --brand (kicker 4.3->4.6) and light --ok (3.7->4.6) at the single brand.json source, so every accent/label pair on both schemes clears 4.5:1. Landing's mirrored token blocks updated to match (parity test stays green); the status page inherits the new values via brand.json automatically. - Radius: collapse the literal border-radii onto --radius-sm / --radius / pill so uicheck's radius-levels reads 3 (was 6). var() radii aren't counted, so routing small elements through --radius-sm is the deliberate 3-level scale. uicheck design now passes spacing-scale, radius-levels, shadow-levels with slop distance 0.42 (>=0.25). palette-size stays advisory-only: a dark+light token system declares ~21 hexes before the embedded hero illustration, so the <=8 single-theme heuristic can't apply — not CI-gated. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
…d status page Three freshness/drift bugs where the "no mock data" promise wasn't actually held. - build-pages: the impact/saved regexes no longer matched the current README, so those "repo-sourced" numbers were silently the hardcoded fallbacks (0.43 ms / 62.1%). Fix the regexes to parse the README and make a non-match a hard build error (mustMatch) — the number is sourced or the build fails, never a stale default. Remove the dead `claim` field. - public/index.html is a generated artifact (CI rebuilds it at deploy), so it was going stale in git (old version) and leaking the dev branch name into a visible chip — and it shipped in the npm tarball. Gitignore it, untrack it, and drop "public" from package.json files. npm pack now contains zero public/ entries. - Landing's Status link pointed at ./status/, dead in local file preview; now the absolute Pages URL, which resolves everywhere. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
global/statusline.sh used nearest xterm-256 indices (#209 ember, #245/#247 greys) instead of the real brand tokens. Move to 24-bit truecolor from a named palette block so the ember and warm-taupe greys are the exact brand.json hexes (#f26430, #7d7263, #a99e90, #67e8a5), with a 256-color fallback when COLORTERM isn't truecolor/24-bit so it degrades instead of mis-rendering. Keep the subtle ember ctx>200k warning, the cache-hit meter, and the jq-absent fallback. New test/statusline.test.js drives the script the way Claude Code does (sample JSON on stdin) and asserts every segment renders, the exact truecolor hexes are emitted, the 256-color fallback kicks in without COLORTERM, and minimal input never leaks a literal "null". Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
…t nav blur Lock in the UI/metadata work so it can't silently regress: both public pages must ship an absolute og:image + twitter:image and a favicon/apple-touch-icon; canonical must equal og:url on each; the landing page must state the current package.json version (not a stale hardcode); backdrop blur must stay <=8px; and public/ must not reappear in the npm files list. Extends the existing single-source parity suite. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
…ickstart
- checkDiagrams: a `%%{init` block must now carry the brand's actual color values
(ember #f26430 + warm-black #171310 from brand.json), not merely a theme directive
— a diagram can no longer declare a theme yet render off-brand. New docs_check test
covers both the branded-pass and missing-values-flagged cases.
- ARCHITECTURE.md: document brand.json.colors as the single color source both public
pages derive from, and the parity/diagram guards that keep it honest.
- README: lead with a "Start in 60 seconds" block so the first screen is actionable,
linking to the full quickstart and command reference.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
CodeWithJuber
marked this pull request as ready for review
July 16, 2026 20:24
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 & why
The brand called itself "one source of truth" but
brand.json/brand.jsheld zero colors — the ember/warm-black palette was hand-duplicated across the landing page and the status page under two different naming schemes, so the "one" palette forked. The landing page also carried classic AI-slop tells (fake terminal chrome,01–06digit-icons,↯/%glyph icons, a uniform card grid, a faux-live pulse dot), the real hero art was never used, social cards were blank, and the "repo-sourced" status metrics were silently hardcoded fallbacks.This makes the design system one enforced source and ships every fix with a guard so it can't rot (the repo's fix-and-enforce pattern). Eight focused commits:
brand.json= single color source (full dark + light palettes) emitted bysrc/brand.jsrootTokensCss(); the status page gains light mode;test/pages.test.jsenforces full-palette parity across both surfaces.og:image+twitter:image(rasterized once via Chromium — a committed author artifact, not a runtime dep), favicon + apple-touch-icon,canonical == og:url, full OG/Twitter/SoftwareApplicationJSON-LD on the status page.impact/savedmetric regexes now actually parse the README, a non-match is a hard build error (no silent fallback);public/index.htmlis gitignored + dropped from the npm tarball (CI regenerates it, killing the stale-version + dev-branch-leak bugs).checkDiagramsnow validates mermaid theme values (brand hexes), not just the%%{initdirective; README leads with a 60-second quickstart; ARCHITECTURE documents the single color source.Zero runtime dependencies preserved (system-font stack; the OG PNG is a committed asset). Verified with headless Chromium at 320/375/768/1280/1920 in light + dark — no horizontal scroll, hero fits, real SVG renders.
Checklist
npm testpasses (717 tests, 715 pass / 2 integration-skip)npm run checkpasses (Biome lint + format)cssVars/rootTokensCss, statusline, metadata guards)feat:/fix:/test:/docs:)CHANGELOG.mdupdated under## [Unreleased]ARCHITECTURE.md, README,docs checkgreen)Risk & rollback
public/becoming a build artifact is the only non-code change — CI regenerates it on deploy regardless.Extra checks (tick if applicable)
npm run typecheckpasses🤖 Generated with Claude Code
https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
Generated by Claude Code