How to Create Dark Mode Variants Using the Diagram-Design Skin System

Create dark mode variants by defining light tokens in style-guide.md and running the skin linter, which automatically applies the inversion rule to generate *-dark.html files.

The cathrynlavery/diagram-design repository uses a token-based skin system that eliminates manual dark mode editing. This guide explains how to create dark mode variants using the skin system's automatic inversion pipeline.

How the Skin System Handles Dark Mode

The Diagram-Design skill treats dark mode as a derived output, not a parallel design. All visual tokens—colors, typography, and spacing—live in a single file: skills/diagram-design/references/style-guide.md. When you modify these tokens, the skin system can regenerate both light and dark variants deterministically.

This approach guarantees visual consistency. Every diagram template and example consumes the same token definitions, so a single change propagates everywhere.

Step 1: Define Light Mode Tokens in style-guide.md

Open skills/diagram-design/references/style-guide.md and edit the core color tokens. These define your light (default) skin:

Token Purpose Example Value
paper Background color rgba(245,245,245,1)
ink Primary text color rgba(30,30,30,1)
accent Highlight/branding color rgba(0,112,243,1)
muted Secondary text rgba(120,120,120,1)
link Interactive elements rgba(0,112,243,1)

The skin system treats these as your canonical definitions. Dark mode colors are computed from them, never hand-authored.

Step 2: Apply the Automatic Inversion Rule

The inversion rule, documented in skills/diagram-design/references/onboarding.md, transforms light tokens into dark equivalents:

  • Paper inverts to ink — the background becomes the text color
  • Ink inverts to paper — text becomes the background color
  • Accent, muted, and link swap but preserve relative luminance

For example, a light paper value of rgba(245,245,245,1) (white-smoke) becomes rgba(ink-rgb, 1) in dark mode—using the actual RGB value defined for your ink token. This ensures perfect contrast regardless of your custom brand colors.

Step 3: Regenerate Dark HTML with the Skin Linter

The scripts/lint-skin.py tool validates your tokens and produces paired HTML outputs.

Regenerate all examples:

python3 scripts/lint-skin.py --all --baseline

Regenerate a single example:

python3 scripts/lint-skin.py skills/diagram-design/assets/example-process.html

The linter performs two critical functions:

  1. Validation — confirms that tokens follow the skin contract (required fields, valid color formats, accessible contrast ratios)
  2. Generation — outputs both example-<type>.html and example-<type>-dark.html for each diagram type

Dark files are suffixed with -dark and placed in skills/diagram-design/assets/.

Step 4: Use Dark Variants in Your Application

Reference the generated dark files directly, or let the browser select based on user preference.

Embedding with prefers-color-scheme:

<link rel="stylesheet" href="style.css">

<!-- Light variant -->
<link rel="stylesheet" href="skills/diagram-design/assets/example-process.html" media="(prefers-color-scheme: light)">

<!-- Dark variant -->
<link rel="stylesheet" href="skills/diagram-design/assets/example-process-dark.html" media="(prefers-color-scheme: dark)">

Direct linking:

<!-- Force dark mode regardless of system preference -->
<iframe src="skills/diagram-design/assets/example-process-dark.html"></iframe>

Type-specific reference docs like skills/diagram-design/references/type-process.md list the available dark variants for each diagram category.

Key Files in the Dark Mode Pipeline

File Role
skills/diagram-design/references/style-guide.md Single source of truth for all skin tokens
skills/diagram-design/references/onboarding.md Documents the inversion rule transformation
scripts/lint-skin.py Validates tokens and generates paired light/dark HTML
skills/diagram-design/references/type-<type>.md Indexes generated *-dark.html files
skills/diagram-design/assets/*-dark.html Final dark mode diagram outputs

Modifying the Inversion Rule

The inversion logic lives in scripts/lint-skin.py. While the default behavior swaps paper↔ink and preserves accent, advanced users can pass --invert-strategy flags to customize:

  • luminance-preserve — maintains perceptual brightness (default)
  • hue-rotate — shifts complementary colors
  • custom-map — uses explicit token mappings defined in skin.config.json

Run python3 scripts/lint-skin.py --help for available options.

Summary

  • Edit style-guide.md to set light mode tokens—dark mode derives automatically from the inversion rule
  • Run lint-skin.py to validate and regenerate both variants; never hand-edit *-dark.html files
  • Embed dark variants using prefers-color-scheme media queries or direct file references
  • Trust the pipeline: any token change propagates to all diagram types instantly

Frequently Asked Questions

Can I override dark mode colors manually without changing light tokens?

No. The skin system enforces derivation from light tokens to guarantee accessibility and consistency. To change dark mode appearance, modify the source tokens in style-guide.md or adjust the inversion strategy in lint-skin.py.

What happens if my light mode colors fail accessibility contrast checks?

The skin linter fails with a descriptive error before generating any HTML. Fix the contrast ratio in style-guide.md—the dark variant will inherit the correction automatically.

Does the skin system support more than two color schemes?

The current implementation generates exactly two variants: light and dark. For additional schemes (sepia, high-contrast), fork lint-skin.py and extend the --all flag to accept custom transformation profiles.

How do I preview dark mode during local development?

Run python3 scripts/lint-skin.py --watch to regenerate on file changes, then open skills/diagram-design/assets/example-<type>-dark.html directly in your browser or use DevTools to force prefers-color-scheme: dark.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →