mdcms/docs/claude-design.md
Claude f2bc729e40
Derive --divider via color-mix; add explicit divider key as escape hatch
--divider in both light and dark modes now auto-derives from the theme's
background and text colours using color-mix(in srgb, bg 85%, text), so
accent-coloured or custom-background themes get a correct divider without
any extra config. An explicit `divider` key in theme.yml overrides this
for the rare cases where exact control is needed.

docs/claude-design.md and CLAUDE.md updated accordingly.

https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
2026-05-18 11:09:06 +00:00

6.6 KiB

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

# 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)
  # 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"
  # 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

Critical rule: nav contrast

The renderer defaults nav-link-active to accent and nav-link to text. When nav-background and accent share the same hue (or are very close), active nav links become invisible — the coloured text disappears into a coloured background.

Always set all three nav colour keys explicitly whenever nav-background is anything other than a neutral near-white (light) or near-black (dark).

Pattern: accent-coloured nav (e.g. brand red, navy, forest green)

light:
  accent: "#D00C33"
  nav-background: "#D00C33"   # same as accent — nav links MUST be overridden
  nav-link: "#FFFFFF"
  nav-link-active: "#FFFFFF"
  nav-section-heading: "rgba(255,255,255,0.65)"

dark:
  accent: "#D00C33"
  nav-background: "#000000"
  nav-link: "#E2E2E2"
  nav-link-active: "#FFFFFF"
  nav-section-heading: "#888888"

Pattern: dark nav in light mode (sidebar darker than content)

light:
  nav-background: "#1E293B"
  nav-link: "#CBD5E1"
  nav-link-active: "#FFFFFF"
  nav-section-heading: "#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
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

  • nav-link, nav-link-active, nav-section-heading specified for both light and dark whenever nav-background is non-neutral
  • All three nav link 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