ai-config-design-ssot
Section titled “ai-config-design-ssot”Background
Section titled “Background”- 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\
- websites (monorepo):
- 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, wasinvestment-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.
Context
Section titled “Context”SSOT: [repo path] — see AGENTS.md for full project context. Portal: ai-config
Claude Response — 2026-08-29
Section titled “Claude Response — 2026-08-29”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.
Your three decisions this session
Section titled “Your three decisions this session”- 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
Summary
Section titled “Summary”- 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 ofSoftware 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. NamedDesign-Apps, notDESIGN-APPS.md, to avoid colliding with SMTM’s reservedDESIGN.mdmeaning. -
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: noVOICE.mdwas created.brands.md:10-13already 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.mdand 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 staleCore/Glossary/F.A.S.T.links (deleted 2026-07-09) repointed. -
Software Dev/UI-UX/UI-UX.mdreduced to a pointer;Processes.mdindex 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%).
Not done — deliberately, and why
Section titled “Not done — deliberately, and why”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.
Post-review fixes (same session)
Section titled “Post-review fixes (same session)”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.
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Read
Design-Principles.mdandDesign-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.
- Design-Principles
- Approve Phase 5 (the
design-contextskill +deploy.sh+AGENTS.mdbullet) — 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 inc3e497cbut is still listed, so the/task-startrock 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.
Talbot Response
Section titled “Talbot Response”- correct
Core/Processes/Website Dev/FluidDesignSpec.mdvault↔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
Claude Response — 2026-08-29 (2)
Section titled “Claude Response — 2026-08-29 (2)”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.
Your corrections, applied
Section titled “Your corrections, applied”- §§3-4 moved out of
Design-Principles.mdintoDesign-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-appis now on the token SSOT —@brandalias added to its Vite config (mirroring what sites do),app.cssimports the generated brand tokens, and--primary/--ringderive from--primary-8, the Treasury Emerald anchor#004425. - Verified, not assumed —
pnpm buildpasses; in a real browser--primaryresolves to153 100% 13%; the old hardcoded triplet is absent from the built CSS; screenshot confirms it renders on-brand. -
monorepo/docs/design/apps.mdwritten — the app surface page, with the wiring steps proven above rather than prescribed.
Two gaps found and documented rather than papered over:
- The color generator cannot target
apps/*.generate-color-system.mjsresolves its output root assites/<name>, so--site sd-appwould write to a directory that doesn’t exist. Apps can import brand scales but cannot receive generatedthemes/layers — so app neutrals (--background,--card,--border…) stay hand-declared until the generator takes an output path. - 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 tofrontend-design/artifact-design/datavizfor craft, with your constraints explicitly overriding them. -
deploy.shgeneratesreferences/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 isLESSONS.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 theAGENTS.mdbullet and a new Design section on the Skills Dashboard. - Verified by
lson 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-29stamped.
Commits
Section titled “Commits”KB 4d0c09b/88d3b95 + this round · monorepo 1c51fc5/281f8ce · ai-config 1b36e4a
On the Rocks
Section titled “On the Rocks”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.
Fixes after a review pass
Section titled “Fixes after a review pass”-
Design-Apps.mdwas 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.shrunsset -e; piping it intoheadSIGPIPEs the next echo and aborts mid-fan-out, leaving AntiGravity stale with no error. Re-run bare, all four re-verified. Lesson recorded — ai-config0d66713. -
_active.mdandsdc-sdapp-deploy-miniapp.mdupdated — the latter now carries a/design-context apppointer and, importantly, tells a fresh session not to redo or revert the token wiring that landed here in code it owns.
Next Steps for Talbot
Section titled “Next Steps for Talbot”- Rock #2 is unblocked —
/task-start sdc-sdapp-deploy-miniappis the natural next move. It’sstatus: 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-appdark-mode green — which primary scale step should it be? Nothing matches#3fc46etoday, 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: 3vs 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
Talbot Response
Section titled “Talbot Response”- OK to /clear and /model sonnet?
Claude Response — 2026-08-29 (3)
Section titled “Claude Response — 2026-08-29 (3)”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
| Option | Colour | vs #171717 | On the SSOT? |
|---|---|---|---|
| Today (hand-declared) | #41C377 vivid | 7.94:1 | ❌ off-scale |
--primary-2 | #9EC2A9 | 9.17:1 | ✅ |
--primary-3 | #86AC93 | 7.12:1 | ✅ closest to today’s contrast |
--primary-4 | #6A9579 | 5.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-miniappfrontmatter saidrock: 3against your new DASHBOARD ordering; corrected torock: 1, and this task torock: 1too. - Obsidian render confirmed by you — that closes the one verification gap I’d flagged as unmet.
On /clear and /model sonnet — yes, safe
Section titled “On /clear and /model sonnet — yes, safe”Nothing is held in this session’s context:
- All work is committed — KB
4d0c09b/88d3b95/6999e06/eb1aa40, monorepo1c51fc5/281f8ce, ai-config1b36e4a/0d66713. - The design context now travels by skill, not by conversation. A fresh Sonnet session runs
/design-context appand gets the L0-L3 ladder and the core-inputs rule from its own bundledreferences/— that was the entire point of Phase 5. sdc-sdapp-deploy-miniapp.mdcarries its own briefing — the/design-context apppointer, 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 sonnetmatches 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.
Next Steps for Talbot
Section titled “Next Steps for Talbot”-
--primary-3for sd-app dark mode? One line incolors.oklch.json(movedark:primaryfrom 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 *
Talbot Response
Section titled “Talbot Response”Claude Response — 2026-08-29 (4)
Section titled “Claude Response — 2026-08-29 (4)”--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.jsonnow 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.cssdark--primary/--ringderive fromvar(--primary-3), with your reasoning recorded in the file. - Light mode re-verified on the real app:
--primaryresolves to153 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:
| Variable | Hand-fixed | Reverts to |
|---|---|---|
--muted-foreground (light) | 28 8% 32% | 28 8% 44% |
--muted-foreground (dark) | 28 7% 63% | 28 7% 36% |
--destructive | 0 84.2% 40% | 0 84.2% 60.2% |
--destructive-foreground | 0 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.
A correction to round 2
Section titled “A correction to round 2”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.
Next Steps for Talbot
Section titled “Next Steps for Talbot”- 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-completespins 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
.darkblock is simpler than wiring a toggle — and makes--primary-3moot * -
[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 *