Skip to content
  • In today’s digital world, the effectiveness of UI/UX is critical, itself a KSF, especially for a strategy expert and thought leader, and creator of apps.
    • F.A.S.T. is my behaviour approach to make it easier to learn + ACT (address knowing-doing gap); Core/Misc/Glossary
  • I have a monorepo for websites, apps, and more, with an existing SSOT for brand entities and decisions.
    • websites (monorepo): \\wsl$\Ubuntu-24.04\home\ta\projects\monorepo\
    • apps, micro-apps: \\wsl$\Ubuntu-24.04\home\ta\projects\monorepo\apps\sd-app\
  • other side dev projects created, with more to come
    • \\wsl$\Ubuntu-24.04\home\ta\projects\asset-history\
    • SKILL, for investment analysis
      • \\wsl$\Ubuntu-24.04\home\ta\.claude\skills\financial-dashboard\SKILL.md (renamed 2026-09-26, was investment-analysis-historical)
      • didn’t use any Design context, but could have (if a suitable one was available)
  • There are multiple KB-OS docs that reference “DESIGN.md”. The need for one was rejected a few months ago. Should review and extract usable ideas.
  • Decide if this issue belongs to Core/IT, ai-config, or both
  • Different design guidelines/rules should apply to different targets/artifacts: websites vs apps vs books/booklets/pamphlets vs reports vs decks, etc.
    • How? Some guidelines overlap scopes and should apply to multiple targets. Separate files for different roles? @includes?
    • Define how to integrate with related guides, like VOICE.md (defining brand voice, for writing vs websites, as an example). Links (to related notes)?
    • Decide how to address the (more important) F.A.S.T. principles
    • Apps are probably the most involved and deserve special treatment, perhaps DESIGN-APPS.md?
      • many ideas to include from KB and Dynalist, starting with “start simple, minimal, then progressive”
      • I found this SDC/_WorkingOn/Projects/SD-App/archive/DESIGN.md. Many others.
  • Create a standard Design System artifact, showcasing the traditional design properties (colors, fonts, logos/favicons, spacing, etc.), for each monorepo brand (sdc, ts, mbr)
  • PLAN Mode only, initially. Importance warrants Opus. Detail a system that addresses these goals and issues.

SSOT: [repo path] — see AGENTS.md for full project context. Portal: ai-config


Plan approved, and Phases 1-2 shipped. Full plan: ~/.claude/plans/d-fss-kb-core-it-tasks-ai-config-design-vectorized-mochi.md.

One premise in the task was false — worth knowing before reading anything else

Section titled “One premise in the task was false — worth knowing before reading anything else”

Line 28 says a DESIGN.md “was rejected a few months ago.” No rejection verdict exists in the vault. What happened was a placement reversal (KB-OS-re-focus-sdc.md:132, executed in c3e497c, 2026-08-28): dev design docs moved into repos. DESIGN.md’s taxation half went with them; its UI/UX half was left homeless — and was blocking Rock #2, per SDC/Logs/Dev/2026-08-28_LevPro-sd-math-M5-M6-RRSP.md. So this task was a hard dependency of Rock #2, not off-rock; frontmatter now reads rock: 2. The /task-start gate fired before that evidence surfaced and was answered “proceed anyway” — noting it so the focus ledger isn’t polluted.

Second correction: a real design system already exists — monorepo/docs/design/, 1,556 lines across 7 docs — and its brands.md:3-14 explicitly forbids forking a per-site DESIGN.md. So the answer to the task was never “write DESIGN.md.” It was an authority structure that extends what exists.

  • SSOT split — repo owns implementation, vault owns principles
  • F.A.S.T.’s A = Adaptable (progressive-disclosure sense)
  • Design System artifact = Astro showcase route in sites/template
  • The boundary rule, which answers task item 1 (Core/IT vs ai-config vs both): repo-side owns anything a build step reads or generates; vault-side owns anything only a human or an agent’s judgment reads. Ownership is both, split by kind — content is IT, delivery is AI. It predicts every existing placement correctly and mispredicts exactly one file, which turned out to be a real defect (below).
  • Core/Processes/Design/ created — a sibling of Software Dev/, deliberately not inside it, because books, reports and decks are not software.
    • Design-Principles.md — rescues the orphaned UI/UX content verbatim: 80/20 BIG Rocks, Simplified Inputs/Outputs (the “as Steve Jobs would design it” core-inputs rule), Highest Impact Analysis. F.A.S.T. leads, with your CEO directive stated plainly: where a design convention and F.A.S.T. conflict, F.A.S.T. wins.
    • Targets/Design-Apps.md — task item 5, the substantive one. The L0-L3 progression ladder (Snapshot → Core+“See all” → Full → Highest Impact), defaults-are-the-product, normalization as a simplification device. This is what LevPro consumes. Named Design-Apps, not DESIGN-APPS.md, to avoid colliding with SMTM’s reserved DESIGN.md meaning.
    • Targets/Design-Web.md — thin router into the repo docs, plus the one web-only rule not in the repo (content before design system)
    • Voice.md — task item 3’s answer: no VOICE.md was created. brands.md:10-13 already routes voice to Strategy docs; a new file would fork it. This is the 7-slot schema plus the per-brand router, which surfaces that SDC’s voice doc is a stub and TS has none.
    • Targets/Design-{Print,Decks,Reports}.md — question lists containing no declarative guidance. Nothing exists in the vault on non-web targets, so per NEVER GUESS these ask rather than assert.
  • LevPro unblocked — SD-App/PORTAL.md and the LevPro dev log both updated in the same commit, so neither starts lying.
  • F.A.S.T. reconciled. Behavioural-Solutions.md §6 asserted “canonically Fast, Adaptive…” while citing the Glossary as SSOT — a word the Glossary does not use, mapped to a different meaning (EAST Timely, an individual’s threshold). Annotated to record Adaptable as canonical and to name the timing idea as a separate principle rather than annexing the A to it. Two stale Core/Glossary/F.A.S.T. links (deleted 2026-07-09) repointed.
  • Software Dev/UI-UX/UI-UX.md reduced to a pointer; Processes.md index updated.

Answer to “how?” (task item 2 — the overlap/@includes question)

Section titled “Answer to “how?” (task item 2 — the overlap/@includes question)”

There is no include mechanism. deploy.sh offers exactly three: whole-file concatenation (Claude Code only), a vault pointer (LESSONS.md:16-18 — “the tool won’t follow the pointer”), and skill-bundled references/ (all four surfaces, no vault mount needed). The plan’s answer is a design-context skill whose references/ are copied from the vault at deploy time — the same move LESSONS.md already prescribes, so no fork. That is Phase 5 and it is CEO-gated, since it touches AGENTS.md and deploy.sh.

Defect found while testing the boundary rule

Section titled “Defect found while testing the boundary rule”

Core/Processes/Website Dev/FluidDesignSpec.md declares scope: Monorepo Frontend and specifies a 62.5% base font, while sites/template/src/styles/design-tokens.css:13 ships 100%. A live vault↔repo contradiction on a build-read fact. Disposition is Phase 4 (move the normative content repo-side, resolve in favour of the shipped 100%).

Phases 3-6 remain. Phase 3 (repo docs) and 4 (the Astro showcase) are IT execution; Phase 5 (the skill + deploy.sh + AGENTS.md) is a globally-deploying change and needs your approval. Also spun out rather than fixed: the three competing SmartDebt greens (#004425 vs #005c2e/#3fc46e vs 155 100% 18%), sites/sdc being off the design system entirely, the favicon dual-writer conflict, and filling in SDC/TS brand voice.

Design.md claimed the boundary rule was already stated in two repo docs — it wasn’t yet, so those two one-line edits were shipped rather than leaving the sentence false (monorepo docs/design/README.md + brands.md). Design-Apps.md’s forward reference to a not-yet-written monorepo/docs/design/apps.md now says so and names what to read instead. A markdownlint pass caught one genuine Obsidian render break — unescaped | inside wikilink aliases in a table row — now escaped; remaining lint hits are tab-indent and stacked callouts, both vault convention. No headless Obsidian render check was possible: the CLI isn’t installed (that’s [Obsidian-Upgrades-Phase2-Verification](/core/processes/projects/kb-os/tasks/obsidian-upgrades-phase2-verification/)), so the callouts and tables have not been eyeballed in the app.

  • Read Design-Principles.md and Design-Apps.md — these are your words lifted verbatim; confirm the L0-L3 ladder matches what you meant by “start simple, minimal, then progressive”
    • Design-Principles
      • Sections 3 and 4 are Design-Apps guidelines, not global.
      • L0-L3 ladder looks good.
  • Approve Phase 5 (the design-context skill + deploy.sh + AGENTS.md bullet) — globally-deploying, so it waits on you
    • go
  • Design-Principles.md §5 has one > [!todo] — what counts as Tailored beyond User Profiles, inferred region, and progressive personalization? The archived source said only “define more later”, so it wasn’t guessed
    • done
  • Core/DASHBOARD.md’s Biggest Rocks table is stale — Rock #1 (LevPro port) closed in c3e497c but is still listed, so the /task-start rock gate ran off a stale table this session. Re-ranking is your call, not mine
    • Rocks 1 & 2 are waiting for this design system, so on task. It’s also part of KB-OS upgrading.
  • Optional now, needed eventually: answer the Print/Decks/Reports question lists — the two that gate everything are print colour authority (anchors are screen-gamut OKLCH, no CMYK anywhere) and deck authoring tool (decides whether tokens can apply at all)
    • Other artifacts will get design guidelines when needed. Probably can find (borrow > build) frameworks/templates/skills to do this well.
  • correct Core/Processes/Website Dev/FluidDesignSpec.md vault↔repo contradiction; resolve in favour of the shipped 100%
  • fast track the design-app functionality to unblock the top rock SDC/IT/Tasks/sdc-sdapp-deploy-miniapp

Both your asks are done, and Rock #2’s design blocker turned out to be a real code defect — now fixed and verified in a browser.

  • §§3-4 moved out of Design-Principles.md into Design-Apps.md — you were right, they were app guidelines wearing global clothes. Principles is now F.A.S.T. → 80/20 → Personalized → Accessibility → Voice → Provenance, with a short “note on scope” recording why the move happened. A page or a pamphlet has no inputs to simplify.
  • §5 Tailored — you’d already answered it in the file (stored/retrieved personalization settings, respecting privacy regulations). Left your wording as the fourth device and dropped the [!todo].
  • Print/Decks/Reports — added your borrow > build rule to all three: find an existing framework/template/skill first, answer the questions against that baseline rather than in the abstract.

FluidDesignSpec.md — fixed, and it was worse than the one contradiction

Section titled “FluidDesignSpec.md — fixed, and it was worse than the one contradiction”

Resolved in favour of the shipped 100% (1rem = 16px) as you directed. Two more defects found in the same file while fixing it: its example clamp() values were illustrative fictions, now replaced with the values the repo actually ships (read from design-tokens.conservative.css); and the file ended mid-code-block with an unclosed fence, so everything after it rendered as code. Added a section naming monorepo/docs/design/typography.md as the SSOT, so if the two ever diverge again the repo wins.

Fast-tracking Rock #2 — the blocker was real, not documentation

Section titled “Fast-tracking Rock #2 — the blocker was real, not documentation”

sd-app hand-declared its primary as 155 100% 18% (#005c2e) and imported no brand token file at all — matching no anchor. It was off the design system entirely, which is exactly the drift brands.md exists to prevent. A mini-app built on that would have shipped off-brand.

  • sd-app is now on the token SSOT — @brand alias added to its Vite config (mirroring what sites do), app.css imports the generated brand tokens, and --primary/--ring derive from --primary-8, the Treasury Emerald anchor #004425.
  • Verified, not assumed — pnpm build passes; in a real browser --primary resolves to 153 100% 13%; the old hardcoded triplet is absent from the built CSS; screenshot confirms it renders on-brand.
  • monorepo/docs/design/apps.md written — the app surface page, with the wiring steps proven above rather than prescribed.

Two gaps found and documented rather than papered over:

  1. The color generator cannot target apps/*. generate-color-system.mjs resolves its output root as sites/<name>, so --site sd-app would write to a directory that doesn’t exist. Apps can import brand scales but cannot receive generated themes/ layers — so app neutrals (--background, --card, --border…) stay hand-declared until the generator takes an output path.
  2. No scale step matches sd-app’s dark-mode green 145 52% 51% (nearest is --primary-3, far more muted). Left hand-declared and flagged in the CSS — picking the step is a design decision, not a mechanical substitution.

Phase 5 shipped — design-context skill, live on all four surfaces

Section titled “Phase 5 shipped — design-context skill, live on all four surfaces”
  • skills/design-context/SKILL.md — F.A.S.T. and the 80/20 rule inline (the two things that must survive if nothing else is read), then a target router, then a repo router, then handoff to frontend-design / artifact-design / dataviz for craft, with your constraints explicitly overriding them.
  • deploy.sh generates references/ from the vault at deploy time — so the vault only needs to be mounted here, on your machine, never at use time on any surface. That is LESSONS.md:16-18’s prescribed fix, and this is its second occurrence, which promotes it from “awaiting a second occurrence”.
  • Added to USER_SKILLS (a skill dir alone silently doesn’t deploy while the script still echoes success), plus the AGENTS.md bullet and a new Design section on the Skills Dashboard.
  • Verified by ls on all four targets, not the deploy echo — WSL, Windows, AntiGravity global, monorepo workspace: SKILL.md + 7 references each, generated headers intact, L0-L3 ladder survived the copy.
  • Security review run (/skill-security-review) — PASS. 8 files, all markdown, zero scripts, no network, no injection patterns. One honest note: the skill’s “F.A.S.T. outranks conventional design convention” is override language by design, scoped to design advice only. security-tested: 2026-08-29 stamped.

KB 4d0c09b/88d3b95 + this round · monorepo 1c51fc5/281f8ce · ai-config 1b36e4a

You said Rocks 1 & 2 are waiting on this, so it’s on task — agreed for #2. But Rock #1 (LevPro port) is complete, closed in c3e497c, and the DASHBOARD table still lists it. Separately, sdc-sdapp-deploy-miniapp’s own frontmatter says rock: 3 while the DASHBOARD calls it #2. Two stale numbers pointing at the same task; your call, not mine.

  • Design-Apps.md was stating four facts twice — the verbatim lift duplicated my own earlier restatements of the same content (User Profiles, region auto-detect, the 10-year default, per-$100/mn). SSOT violated inside the file whose whole job is to be the SSOT, and it was already bundled to four surfaces. Rewritten so Talbot’s words are the single home; only the two genuinely new corollaries survive.
  • Two callouts in that file went false the moment this round shipped (apps.md “not yet written”, sd-app “known drift”) — both corrected.
  • A re-deploy had silently reached only 2 of 4 surfaces. deploy.sh runs set -e; piping it into head SIGPIPEs the next echo and aborts mid-fan-out, leaving AntiGravity stale with no error. Re-run bare, all four re-verified. Lesson recorded — ai-config 0d66713.
  • _active.md and sdc-sdapp-deploy-miniapp.md updated — the latter now carries a /design-context app pointer and, importantly, tells a fresh session not to redo or revert the token wiring that landed here in code it owns.
  • Rock #2 is unblocked — /task-start sdc-sdapp-deploy-miniapp is the natural next move. It’s status: ready, model: sonnet, and now has both an SSOT to design against (/design-context app) and a working token path. Only its Cloudflare Pages project creation needs you
    • started
  • sd-app dark-mode green — which primary scale step should it be? Nothing matches #3fc46e today, so it stays hand-declared until you pick
    • unclear of decision required, provide more specific context
  • DASHBOARD Rocks table — Rock #1 closed but still listed; mini-app task says rock: 3 vs DASHBOARD’s #2
    • cleaned up, renumbered Rocks
  • Optional: the design docs still haven’t been eyeballed in Obsidian — callouts and tables are lint-clean but unrendered here (no Obsidian CLI; that’s [Obsidian-Upgrades-Phase2-Verification](/core/processes/projects/kb-os/tasks/obsidian-upgrades-phase2-verification/))
    • done; look good
  • OK to /clear and /model sonnet?


Yes — /clear and /model sonnet are both safe. Details at the end. First, the dark-mode context you asked for, because investigating it changed the answer.

The dark-mode decision — it’s smaller than I made it sound

Section titled “The dark-mode decision — it’s smaller than I made it sound”

I framed this as “pick a scale step”. That was incomplete. The real finding: the brand SSOT already declares a dark-mode primary, and it’s unusable.

src/brand/sd/colors.oklch.json maps step 8 to both light and dark:

"semanticMappings": { "8": ["light:primary", "dark:primary", ...] }

Step 8 is Treasury Emerald #004425. On the app’s #171717 dark background that is 1.54:1 — effectively invisible. So the mechanism to put dark mode on the SSOT already exists and is simply pointed at the wrong step; no generator change is needed, just a different number in that JSON. That’s why sd-app hand-declared its own green in the first place.

It is latent, not live: sites/sdc and sites/mbr are light-only by decision, and sd-app overrides it, so nothing renders that 1.54:1 today.

What the choice actually costs — measured, on the app’s real background

Section titled “What the choice actually costs — measured, on the app’s real background”

!sd-app-dark-primary-options.png

OptionColourvs #171717On the SSOT?
Today (hand-declared)#41C377 vivid7.94:1❌ off-scale
--primary-2#9EC2A99.17:1✅
--primary-3#86AC937.12:1✅ closest to today’s contrast
--primary-4#6A95795.28:1✅

All pass WCAG AA comfortably; contrast is not the deciding factor. Appearance is: every scale step reads as a muted sage-green, while today’s is a vivid money-green. That’s not an accident — "chromaCurve": "bell" in the brand JSON deliberately drops chroma at the light end, so the generated scale contains no vivid step at any position. Going on-SSOT means accepting a duller dark mode, unless the chroma curve itself changes (a much bigger change affecting every brand surface).

My recommendation: --primary-3, and it’s a small, reversible call. Dark mode is sd-app-only — both sites are light-only, and the debt-first mini-app embeds into light educational content, so this affects one surface you can flip back in one line.

  • Rock renumbering picked up — sdc-sdapp-deploy-miniapp frontmatter said rock: 3 against your new DASHBOARD ordering; corrected to rock: 1, and this task to rock: 1 too.
  • Obsidian render confirmed by you — that closes the one verification gap I’d flagged as unmet.

Nothing is held in this session’s context:

  • All work is committed — KB 4d0c09b/88d3b95/6999e06/eb1aa40, monorepo 1c51fc5/281f8ce, ai-config 1b36e4a/0d66713.
  • The design context now travels by skill, not by conversation. A fresh Sonnet session runs /design-context app and gets the L0-L3 ladder and the core-inputs rule from its own bundled references/ — that was the entire point of Phase 5.
  • sdc-sdapp-deploy-miniapp.md carries its own briefing — the /design-context app pointer, and an explicit do not redo or revert note on the token wiring, so a fresh session can’t undo it.
  • Its frontmatter is model: sonnet, so /model sonnet matches what its own model-check gate expects.

The only thing not written down is the dark-mode reasoning above — which is now in this file.

  • --primary-3 for sd-app dark mode? One line in colors.oklch.json (move dark:primary from step 8 to 3), regenerate, drop the hand-declared override. Say go and I’ll do it — or say keep the vivid green and I’ll leave it hand-declared with the reason recorded
    • yes
  • Otherwise this task is done. Phases 1-5 shipped; only the Phase 4 Astro design-system showcase route (brands.astro + Color/Type/Spacing panels) remains, and it is independent of Rock #1. Say the word and I’ll close with /task-complete, spinning the showcase out as its own task *
  • Not urgent: "chromaCurve": "bell" means no generated step is vivid, on any brand. If you ever want a punchier accent anywhere, that curve is the lever — worth knowing before it surprises you on another surface *


--primary-3 is in, but applying it uncovered two problems that matter more than the colour did. Both are now contained; neither is fixed here.

  • src/brand/sd/colors.oklch.json now maps "3": ["dark:primary"], split out of step 8. That corrects the latent defect — step 8 was mapped to both light and dark primary, and it’s #004425, 1.54:1 on the app’s dark background.
  • apps/sd-app/src/app.css dark --primary/--ring derive from var(--primary-3), with your reasoning recorded in the file.
  • Light mode re-verified on the real app: --primary resolves to 153 100% 13%, the Treasury Emerald anchor.

🚩 pnpm colors is unsafe to run — caught by diffing, not by luck

Section titled “🚩 pnpm colors is unsafe to run — caught by diffing, not by luck”

I regenerated to apply the mapping, diffed before staging, and discarded the output. It would have done two unrelated kinds of damage:

1. It reverts hand-applied WCAG AA fixes. The generated theme files carry “DO NOT EDIT MANUALLY” headers and were edited anyway — five accessibility values across light.css and dark.css, each with a comment explaining the contrast fix:

VariableHand-fixedReverts to
--muted-foreground (light)28 8% 32%28 8% 44%
--muted-foreground (dark)28 7% 63%28 7% 36%
--destructive0 84.2% 40%0 84.2% 60.2%
--destructive-foreground0 0% 100%210 40% 98%
--primary (light)215 69% 32%215 69% 45%

Anyone running pnpm colors silently breaks accessibility compliance. This is exactly the AGENTS.md “deploy-from-source configs — diff before you deploy” pattern: the generated copy drifted ahead of its generator.

2. sites/template was last generated with the ts brand. Its themes are Professional Blue. Running colors:sd — the obvious command when working on SmartDebt — rebrands the entire template site green as a side effect. Nothing in the repo records which brand a site was built from.

Spun out: monorepo-color-generator-safety (status: ready, model: sonnet), plus a [!danger] callout in docs/design/apps.md. The app needed no regeneration anyway — it reads --primary-3 straight from the :root scales.

🚩 sd-app’s dark mode does not render at all

Section titled “🚩 sd-app’s dark mode does not render at all”

Not caused by this change, and worth knowing before anyone builds against it: nothing ever adds the .dark class — no toggle, no prefers-color-scheme listener. On top of that, Tailwind tree-shakes the entire @layer base { .dark { … } } block out of the build, because @layer contents are purged against content and a bare .dark selector appears in no component. grep -c 'dark{' on the built CSS returns 0.

The dark: utility variants in the calculator tables do survive (they compile to :is(.dark *)), which makes the app look half-wired while being entirely unreachable. Your --primary-3 choice is correct and recorded; it becomes visible the moment a toggle exists.

I reported the light-mode token “verified in a real browser”. That verification was sound, but a re-check this round initially hit an unrelated Astro dev server on port 4321 and returned a different value, which I nearly reported as a regression. Re-run against sd-app on a known-free port, light mode is correct. Worth naming because “verified in a browser” is only as good as knowing which server answered.

  • Close this task? Everything you asked for is shipped. Only the Phase 4 showcase route remains and it’s independent — say the word and /task-complete spins it out *
  • Does sd-app actually need dark mode? Both sites are light-only by decision, and the debt-first mini-app embeds into light content. If dark mode isn’t wanted, deleting the dead .dark block is simpler than wiring a toggle — and makes --primary-3 moot *
  • [monorepo-color-generator-safety](/core/it/tasks/monorepo-color-generator-safety/) is ready to run whenever — it blocks any future colour work, but nothing today *