mirror of
https://github.com/kbenestad/mdcms.git
synced 2026-06-18 15:24:32 +00:00
Separates sidebar header colours from nav link colours. The three new keys control the site name, site description, and dark/light toggle independently, each cascading from the nearest nav variable (nav-sitename → nav-link, nav-description and nav-toggle → nav-section-heading) so existing themes are unaffected. Enables Claude Design to fine-tune sidebar header legibility on saturated or bold nav backgrounds without having to override the nav link colours, and vice versa. CSS selectors and applyThemeYml() updated; app/theme.yml, CLAUDE.md, and docs/claude-design.md updated with full key reference and pattern examples. https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
228 lines
8.5 KiB
Markdown
228 lines
8.5 KiB
Markdown
# mdcms theme authoring guide for Claude Design
|
|
|
|
This document explains the `theme.yml` format so that Claude Design can produce
|
|
complete, correct theme files that render well in all nav configurations and in
|
|
both light and dark mode.
|
|
|
|
---
|
|
|
|
## Full theme.yml structure
|
|
|
|
```yaml
|
|
# mdcms v0.4 | DO NOT REMOVE THIS COMMENT
|
|
# mdcms theme — <theme name>
|
|
|
|
# ──────────────────────────────────
|
|
# Colours
|
|
# ──────────────────────────────────
|
|
light:
|
|
accent: "#2563EB" # brand colour; used for links, active nav border, accents
|
|
background: "#FFFFFF" # main content area background
|
|
nav-background: "#F8FAFC" # sidebar/nav panel background
|
|
text: "#1E293B" # body text
|
|
text-muted: "#64748B" # secondary text, captions
|
|
nav-link: "#1E293B" # inactive nav link text
|
|
nav-link-active: "#2563EB" # active (current page) nav link text
|
|
nav-section-heading: "#64748B" # nav section label text (uppercase, small)
|
|
nav-sitename: "#1E293B" # site name in sidebar header
|
|
nav-description: "#64748B" # site description below the site name
|
|
nav-toggle: "#64748B" # dark/light mode toggle button
|
|
# divider: "#CBD5E1" # omit to auto-derive via color-mix(background, text)
|
|
|
|
dark:
|
|
accent: "#60A5FA"
|
|
background: "#0F172A"
|
|
nav-background: "#1E293B"
|
|
text: "#F1F5F9"
|
|
text-muted: "#94A3B8"
|
|
nav-link: "#E2E8F0"
|
|
nav-link-active: "#60A5FA"
|
|
nav-section-heading: "#94A3B8"
|
|
nav-sitename: "#E2E8F0"
|
|
nav-description: "#94A3B8"
|
|
nav-toggle: "#94A3B8"
|
|
# divider: "#334155" # omit to auto-derive via color-mix(background, text)
|
|
|
|
# ──────────────────────────────────
|
|
# Semantic colours
|
|
# colours-semantic applies to both modes.
|
|
# colours-semantic-dark overrides for dark mode only.
|
|
# ──────────────────────────────────
|
|
colours-semantic:
|
|
info: "#2563EB"
|
|
warning: "#D97706"
|
|
success: "#16A34A"
|
|
error: "#DC2626"
|
|
|
|
colours-semantic-dark:
|
|
info: "#60A5FA"
|
|
warning: "#F59E0B"
|
|
success: "#34D399"
|
|
error: "#F87171"
|
|
|
|
# ──────────────────────────────────
|
|
# Callout defaults
|
|
# primary-colour → left border and icon
|
|
# background-colour → tinted background (rendered at ~8% opacity)
|
|
# ──────────────────────────────────
|
|
callouts:
|
|
info:
|
|
icon: info
|
|
primary-colour: "#2563EB"
|
|
background-colour: "#2563EB"
|
|
warning:
|
|
icon: warning
|
|
primary-colour: "#D97706"
|
|
background-colour: "#D97706"
|
|
success:
|
|
icon: success
|
|
primary-colour: "#16A34A"
|
|
background-colour: "#16A34A"
|
|
error:
|
|
icon: error
|
|
primary-colour: "#DC2626"
|
|
background-colour: "#DC2626"
|
|
|
|
# ──────────────────────────────────
|
|
# Typography
|
|
# Format: "provider:Font Name:weight" (provider: bunny | google)
|
|
# ──────────────────────────────────
|
|
font-body: "bunny:IBM Plex Sans:400"
|
|
font-heading: "bunny:IBM Plex Sans:700"
|
|
font-size: 1.0 # unitless multiplier (1.0 = 16px base)
|
|
line-height: 1.7 # unitless multiplier
|
|
|
|
# ──────────────────────────────────
|
|
# Layout
|
|
# ──────────────────────────────────
|
|
main-width: 80em
|
|
nav-width: 20em
|
|
```
|
|
|
|
---
|
|
|
|
## Nav colour keys: when to set them
|
|
|
|
There are six nav colour keys divided into two groups:
|
|
|
|
**Nav links and labels** — control the navigation list itself:
|
|
- `nav-link` — inactive link text (defaults to `text`)
|
|
- `nav-link-active` — active/current page link text (defaults to `accent`)
|
|
- `nav-section-heading` — uppercase section labels (defaults to `text-muted`)
|
|
|
|
**Sidebar header elements** — control the branding area above the nav list:
|
|
- `nav-sitename` — site name (defaults to `nav-link`)
|
|
- `nav-description` — subtitle below the site name (defaults to `nav-section-heading`)
|
|
- `nav-toggle` — dark/light mode toggle button (defaults to `nav-section-heading`)
|
|
|
|
### When the defaults are fine
|
|
|
|
On themes where `nav-background` is a neutral near-white (light mode) or
|
|
near-black (dark mode), `text` and `text-muted` read well against the nav
|
|
background. All six keys can be omitted and the fallback chain works correctly.
|
|
|
|
### When to set the keys explicitly
|
|
|
|
Set all six keys whenever `nav-background` is anything other than a neutral:
|
|
any saturated brand colour (red, navy, forest green, teal), any noticeably
|
|
dark sidebar in an otherwise light design, or any light-but-tinted background.
|
|
|
|
The two groups can be set independently. On a subtly tinted nav where the
|
|
link defaults look fine but the site name needs slightly more weight or a
|
|
different shade, set only the header keys (`nav-sitename`, `nav-description`,
|
|
`nav-toggle`) and leave the nav link keys to their defaults.
|
|
|
|
**Rule of thumb:** if `nav-background` has saturation above ~20 % or lightness
|
|
below 30 % (dark sidebar) or differs from `background` by more than a slight
|
|
tint, set all six explicitly for that mode.
|
|
|
|
### Pattern: accent-coloured nav (e.g. brand red, navy, forest green)
|
|
|
|
```yaml
|
|
light:
|
|
accent: "#D00C33"
|
|
nav-background: "#D00C33" # same as accent — all nav keys must be set
|
|
nav-link: "#FFFFFF"
|
|
nav-link-active: "#FFFFFF"
|
|
nav-section-heading: "rgba(255,255,255,0.65)"
|
|
nav-sitename: "#FFFFFF"
|
|
nav-description: "rgba(255,255,255,0.65)"
|
|
nav-toggle: "rgba(255,255,255,0.65)"
|
|
|
|
dark:
|
|
accent: "#D00C33"
|
|
nav-background: "#000000"
|
|
nav-link: "#E2E2E2"
|
|
nav-link-active: "#FFFFFF"
|
|
nav-section-heading: "#888888"
|
|
nav-sitename: "#FFFFFF"
|
|
nav-description: "#888888"
|
|
nav-toggle: "#888888"
|
|
```
|
|
|
|
### Pattern: dark nav in light mode (sidebar darker than content)
|
|
|
|
```yaml
|
|
light:
|
|
nav-background: "#1E293B"
|
|
nav-link: "#CBD5E1"
|
|
nav-link-active: "#FFFFFF"
|
|
nav-section-heading: "#64748B"
|
|
nav-sitename: "#FFFFFF"
|
|
nav-description: "#64748B"
|
|
nav-toggle: "#64748B"
|
|
```
|
|
|
|
### Pattern: transparent / very light nav (default behaviour)
|
|
|
|
When `nav-background` is a light neutral, the defaults work fine.
|
|
You can omit `nav-link`, `nav-link-active`, and `nav-section-heading`
|
|
and the renderer will fall back to `text`, `accent`, and `text-muted`.
|
|
|
|
---
|
|
|
|
## Semantic colours and dark mode
|
|
|
|
`colours-semantic` values are applied globally (both modes). The callout
|
|
background is rendered at ~8% opacity, so a colour that looks fine on white
|
|
can wash out on a dark background — or conversely, a colour bright enough for
|
|
dark mode may be too vivid on white.
|
|
|
|
The solution is `colours-semantic-dark`: it overrides semantic colours in dark
|
|
mode only. Typical approach:
|
|
|
|
- **`colours-semantic`** — choose saturated but not neon values that work on white
|
|
- **`colours-semantic-dark`** — use lighter, more luminous variants of the same hues
|
|
|
|
```yaml
|
|
colours-semantic:
|
|
info: "#1D4ED8" # deep blue — strong on white
|
|
warning: "#B45309" # amber — strong on white
|
|
success: "#15803D" # green — strong on white
|
|
error: "#B91C1C" # red — strong on white
|
|
|
|
colours-semantic-dark:
|
|
info: "#93C5FD" # light blue — visible on dark background
|
|
warning: "#FCD34D" # light amber
|
|
success: "#6EE7B7" # light green
|
|
error: "#FCA5A5" # light red/pink
|
|
```
|
|
|
|
Match `callouts` `primary-colour` / `background-colour` values to
|
|
`colours-semantic` (light mode callout values), since the callout block
|
|
uses its own per-callout colour settings rather than the semantic variables.
|
|
|
|
---
|
|
|
|
## Checklist before finalising a theme
|
|
|
|
- [ ] All six nav colour keys (`nav-link`, `nav-link-active`, `nav-section-heading`,
|
|
`nav-sitename`, `nav-description`, `nav-toggle`) set for both `light` and
|
|
`dark` whenever `nav-background` is non-neutral
|
|
- [ ] All nav colours contrast against `nav-background` (WCAG AA minimum)
|
|
- [ ] `colours-semantic-dark` provided with lighter variants of each colour
|
|
- [ ] `callouts` `primary-colour` matches `colours-semantic` values for consistency
|
|
- [ ] `divider` omitted unless the auto-derived value looks wrong (check hr and table borders)
|
|
- [ ] Dark mode `background` is not pure `#000000` unless intentional (use `#0A0A0A`+)
|
|
- [ ] `font-size` between `0.85` and `1.15`; `line-height` between `1.5` and `1.9`
|
|
- [ ] Version comment on line 1: `# mdcms v0.4 | DO NOT REMOVE THIS COMMENT`
|