Monorepo Design + Brand Review — 2026-06-25
Section titled “Monorepo Design + Brand Review — 2026-06-25”Verdict
Section titled “Verdict”Strong forward progress. The single highest-leverage finding from the prior review —
mBR bypassing the OKLCH token pipeline (Critical #1) — is fully resolved: mBR now has
src/brand/mbr/colors.oklch.json, tokens.css, generated themes/{base,light,dark}.css, a
complete Tailwind theme config, and zero hardcoded hex values in global.css (was 30+).
The rates dashboard (Phase C) is almost entirely token-driven. Several prior minor items are
also fixed (Card #ececec default removed, Button stale ring: block removed).
The just-landed brand-animation SSOT refactor (342db93) is a genuine SSOT — verified below. The new Tooltip component is clean and accessible.
The remaining issues cluster around one theme: the two SvelteKit-style PWA focus pages
(sites/mbr/src/pages/focus.astro, sites/sdc/src/pages/focus.astro) live outside the design
system — they hardcode brand hex, and they carry a third tooltip implementation (.ft) that
duplicates the canonical Tooltip.astro (.tt). One concrete latent bug: SDC injects .ft
tooltip spans with no matching CSS, so the first Glossary() term added to SDC focus content
will dump its definition inline, unstyled. Dark-mode tokens for mBR fail WCAG badly, but dark
mode is currently unreachable (no toggle), so that is latent, not shipping.
Severity counts: Critical 0 · High 1 · Medium 5 · Low 4
[HIGH] [effort: 1h] SDC focus page injects .ft tooltip spans with no matching CSS — latent inline-text leak
Section titled “[HIGH] [effort: 1h] SDC focus page injects .ft tooltip spans with no matching CSS — latent inline-text leak”sites/sdc/src/utils/load-focus-content.ts:68-72 runs injectGlossaryTooltips() and emits
<span class="ft" tabindex="0">{term}<span class="ft-tip" role="tooltip">{def}</span></span>.
But sites/sdc/src/pages/focus.astro contains no .ft / .ft-tip CSS and no positioning JS
(grep for .ft-tip / positionTooltip / initTooltips returns nothing — confirmed). The mBR
focus page has all of it (sites/mbr/src/pages/focus.astro:212-281 CSS, :297-334 JS); SDC does
not.
Consequence: an unstyled .ft-tip span has no visibility:hidden, so the definition text renders
permanently inline inside the body copy. SDC focus content currently has no Glossary() terms
(confirmed via 2026-06-23_Glossary-Tooltip-Syntax.md and SDC/_WorkingOn/Focus.md:31), so this
is latent — but the commit message for a741aa2 claims “Same infrastructure added to SDC” and the
author docs explicitly invite SDC authors to use Glossary(Term). The day someone does, the page
breaks silently.
Recommendation: This is the SSOT smell behind the symptom. Don’t copy the .ft CSS into SDC.
Instead, extract the .ft tooltip CSS + positioning JS into a shared partial (or better — render
through the canonical Tooltip.astro .tt component, see Medium #1) so any page that imports the
focus-content pipeline gets working tooltips automatically. Minimum fix: extract .ft CSS/JS to a
shared focus-tooltip.css + script imported by both focus pages.
Medium
Section titled “Medium”[MEDIUM] [effort: 3h] Three parallel tooltip implementations — .tt (canonical) vs .ft (duplicated in two focus pages)
Section titled “[MEDIUM] [effort: 3h] Three parallel tooltip implementations — .tt (canonical) vs .ft (duplicated in two focus pages)”A canonical Tooltip.astro was just added (packages/components/src/ui/Tooltip.astro) with a
.tt class, token-driven colors (hsl(var(--foreground)) / hsl(var(--background))), 4-way
smart repositioning, and proper role="tooltip". Good component.
But the focus pages do not use it. The build-time glossary injector
(sites/mbr/src/utils/load-focus-content.ts:77,226,230 and the SDC twin) emits a different
.ft markup, styled by a hand-rolled .ft/.ft-tip block duplicated inline in
sites/mbr/src/pages/focus.astro:212-281 (and missing entirely in SDC, see High #1). The .ft
version hardcodes --brand-primary: #004425 for the bubble background and only does vertical-flip
- horizontal-clamp, where
.ttdoes full 4-way fit. So the repo now maintains two tooltip behaviours, two CSS blocks, and two positioning algorithms for the same UX.
Recommendation: Make Tooltip.astro (.tt) the single tooltip. Have the glossary injector
emit .tt markup (or a class the component’s CSS already covers), delete the per-page .ft CSS.
One tooltip, one positioning algorithm, token-driven colors that also work if focus pages ever
adopt tokens.
[MEDIUM] [effort: 4h] Both focus PWA pages live entirely outside the OKLCH token system — hardcoded brand hex
Section titled “[MEDIUM] [effort: 4h] Both focus PWA pages live entirely outside the OKLCH token system — hardcoded brand hex”sites/mbr/src/pages/focus.astro:29-30 and sites/sdc/src/pages/focus.astro:28-29 both define
--brand-primary: #004425; --brand-gold: #D5B038; as raw hex, then drive the entire page off them
(focus.astro:38 color:#222, :54 background:#ececec, :90 rgba(0,69,38,.7) h2 banner,
:139 #fffbe6, :156 #e0a200, :233 #fff). These are standalone Astro pages that do not import
@brand/mbr/tokens.css or the generated themes. This is the same opt-out problem the prior
review flagged for the main mBR site (Critical #1) — now resolved for the site, but the PWA focus
pages were never brought onto the pipeline.
Note #004425 is correct for both brands (SDC primary is also Treasury Emerald, per
src/brand/sd/index.ts:20), so this is not a wrong-color bug — it’s a token-adherence /
maintainability bug. A brand color change now requires editing these two pages by hand.
Recommendation: Import the generated theme CSS (or at least @brand/{mbr,sd}/tokens.css) into
the focus pages and replace --brand-primary / --brand-gold / the ad-hoc hexes with
hsl(var(--primary)), hsl(var(--muted)), etc. This also unlocks dark mode and fixes Medium #1
(tokenized tooltips) in one move.
[MEDIUM] [effort: 2h] mBR dark-mode tokens fail WCAG AA — but dark mode is unreachable (latent)
Section titled “[MEDIUM] [effort: 2h] mBR dark-mode tokens fail WCAG AA — but dark mode is unreachable (latent)”sites/mbr/src/styles/themes/dark.css defines (measured against --background: 24 15% 13%):
--muted-foreground: 28 7% 36%→ 2.42:1 (needs 4.5:1) — secondary text, captions, table notes, chip labels all use this (rates.astro:461,475,479,516,518,533,534,549,564).--primary: 146 45% 24%→ 1.95:1 against the dark bg — anycolor: hsl(var(--primary))text (rate values, links, headings) would be nearly invisible.
These are generated by the OKLCH pipeline, so the anchor parameters / dark semantic mappings in
src/brand/mbr/colors.oklch.json need adjusting (lift dark primary lightness, lift
muted-foreground to ~55-60% L).
Why only Medium: dark mode is currently unreachable — dark.css activates on
[data-theme='dark'] (themes/dark.css:12) but there is no theme toggle and no
prefers-color-scheme handler that sets the attribute anywhere in sites/mbr/src/ (only a favicon
swaps on prefers-color-scheme, BaseLayout.astro:22). So the broken contrast does not ship
today. The day a toggle is added, it ships broken. Either (a) fix the dark anchors now, or
(b) explicitly remove the dark theme from mBR (as was done for TS in ce6d9dd) until it’s needed —
don’t keep a broken-contrast theme one toggle away from production.
[MEDIUM] [effort: 1h] Rates dashboard debt/invest accent colors are hardcoded HSL, not tokens
Section titled “[MEDIUM] [effort: 1h] Rates dashboard debt/invest accent colors are hardcoded HSL, not tokens”sites/mbr/src/pages/rates.astro is otherwise a model citizen (token-driven), but the
debt (amber) and invest (blue) accent families are raw HSL literals, not token scale positions:
:473,477amber chiphsl(46 65% 53%)/hsl(45 51% 45%):497debt bannerhsl(38 55% 38%),:501invest bannerhsl(220 60% 38%):537debt ratehsl(38 55% 38%),:538,555,559invest bluehsl(220 60% 42%)
These repeat across ~10 sites; a tweak to “debt amber” means editing every line. They also have no relationship to the OKLCH palette, so they won’t shift correctly in dark mode (compounding Medium #3).
Contrast (measured, on white): debt amber hsl(38 55% 38%) = 4.55:1 (passes AA normal, thin
margin); invest blue hsl(220 60% 42%) = 6.97:1 (good); amber chip value hsl(45 51% 45%) =
3.07:1 — passes only as large/bold text (it is 1.4rem/700 at :476-477, so it qualifies, but
it’s right at the line).
Recommendation: Add accent-debt / accent-invest (or a tertiary/quaternary) to the OKLCH
palette in colors.oklch.json and reference hsl(var(--accent-debt)) etc. Single source for the
two non-primary semantic accent families.
[MEDIUM] [effort: 1h] Rates banner white text on amber is at the WCAG floor (4.55:1)
Section titled “[MEDIUM] [effort: 1h] Rates banner white text on amber is at the WCAG floor (4.55:1)”sites/mbr/src/pages/rates.astro:497-498 — debt banner background: hsl(38 55% 38%); color:#fff.
Measured 4.55:1, just clearing AA for normal text but with no margin; banner text at
:493-510 looks to be normal-weight section headers. Any future darkening of the amber, or use at
smaller sizes, drops it below AA. The blue banner (:501-502, 7.97:1) and emerald are fine.
Recommendation: Darken the amber banner ~5-8% L (e.g. hsl(38 55% 32%)) for headroom, or bump
banner text to 600 weight. Fold into the tokenization in Medium #4.
[LOW] [effort: 0.5h] Tooltip.astro uses role="group" on the trigger — non-standard; prefer aria-describedby
Section titled “[LOW] [effort: 0.5h] Tooltip.astro uses role="group" on the trigger — non-standard; prefer aria-describedby”packages/components/src/ui/Tooltip.astro:12-17 puts role="group" + tabindex="0" on the
trigger and role="tooltip" on the bubble, but the two are not linked via aria-describedby.
Screen readers won’t reliably announce the tooltip as the description of the trigger. The
build-time .ft injector has the same gap (load-focus-content.ts:77).
Recommendation: Give the bubble an id and the trigger aria-describedby="{id}"; drop the
role="group" (a tooltip trigger is not a group). Low because the visible text is still readable
and tabindex="0" makes it focusable; this is a refinement, not a blocker.
[LOW] [effort: 0.5h] Tooltip is hover/focus only — no touch/tap dismissal path
Section titled “[LOW] [effort: 0.5h] Tooltip is hover/focus only — no touch/tap dismissal path”Both .tt (Tooltip.astro:114-119) and .ft rely on :hover / :focus-within. On touch
devices a tap focuses the element (so it can open) but there is no documented tap-again-to-dismiss
or tap-outside-to-close behaviour, and cursor:help is meaningless on touch. For glossary terms
this is mostly acceptable (tap shows it, tap elsewhere blurs it), but worth a deliberate decision +
a test on a real touch viewport.
Recommendation: Confirm tap-to-open / tap-outside-to-dismiss works on iOS Safari and Android Chrome (Playwright touch emulation), and note the supported interaction in the component docstring.
[LOW] [effort: 0.5h] Card.astro docstring still advertises #ececec as an example background
Section titled “[LOW] [effort: 0.5h] Card.astro docstring still advertises #ececec as an example background”The hardcoded #ececec default from prior review #7 is correctly removed (component now uses
hsl(var(--card)), :54). But the docstring example still reads
custom color (e.g., "#ececec") (packages/components/src/ui/Card.astro:9), inviting callers to
pass raw hex and re-introduce the anti-pattern.
Recommendation: Change the example to a token, e.g. hsl(var(--muted)).
[LOW] [effort: 0.5h] Button retains default + primary variant aliases (prior #9, unresolved)
Section titled “[LOW] [effort: 0.5h] Button retains default + primary variant aliases (prior #9, unresolved)”packages/components/src/ui/Button.astro:27 still lists both 'default' | 'primary' mapping to
identical styles. The stale ring: <style> block (prior #10) is fixed — only this alias remains.
Recommendation: Pick default (shadcn convention), drop primary, or document primary as a
deliberate alias. Minor drift risk.
Verified strong (no action)
Section titled “Verified strong (no action)”- Brand-animation SSOT (342db93) is real.
sites/mbr/src/pages/focus.astro:3imports@monorepo/components/brand/MyBetterRates.css; the page has zero inline@keyframes/animation:for the brand text (confirmed by grep). The previously-frozen inline copy is gone.MyBetterRates.astroimports the same CSS (:69) and adds only theme-aware color overrides. One source formbr-wm-bar, one for--mbr-wm-cycle. The intentional logo/text timing divergence (logos brief-flash at 93.75%, text 50/50) is documented in the CSS and the commit. - Reduced-motion is handled everywhere it matters:
MyBetterRates.css:70-75,BrandLogo.astro(sd-dot-pulseguard added in 342db93),Tooltip.astro:121-125,focus.astro:279-281,global.css:442-446. Consistentprefers-reduced-motion: reduce. - mBR token pipeline (prior Critical #1) fully resolved:
colors.oklch.json+tokens.css+ generated themes + full Tailwind config;global.csshardcoded-hex count = 0. Tooltip.astrorepositioning (:138-159) is well-built: preferred → opposite → remaining, usesgetBoundingClientRect()on the hidden bubble (correctly relies on layout being forced), GAP=6 viewport clamping. The horizontal-clamp + caret-tracking on.ft(focus.astro:323-334) is also a nice touch.mbr-reversevariant (MyBetterRates.astro:88-94) cleanly handles white-on-dark-banner brand text for the inverted h2 banners — good brand consistency call.