Help us improve
Share bugs, ideas, or general feedback.
From markdown-html-skills
Captures the user's brand identity once via a 10-question onboarding wizard (primary/accent HEX + heading + body Google Fonts + design style editorial/technical/minimal/playful + default output directory + syntax theme + TOC behavior + optional logo/company), validates body-text and link contrast against WCAG 2.2 AA, derives 12 CSS custom properties in HSL space, and stores the result for every markdown-html converter to consume. Use before any markdown-html conversion. Triggers on first-run onboarding ("set up the brand", "configure markdown-html", "run onboarding"), on explicit reset ("reset the design system", "re-onboard"), and is checked by every converter via config_loader.py before rendering. Refuses to save if body-text contrast fails AA 4.5:1 or the output dir isn't writable. Precedence: project (./.markdown-html/) > global (~/.config/markdown-html/) > built-in defaults; MARKDOWN_HTML_NO_CONFIG=1 bypasses.
npx claudepluginhub kruxshnx/claude-skills-devin --plugin markdown-html-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/markdown-html-skills:design-systemThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The design-system skill is the **shared brand owner** for the markdown-html plugin. Run its onboarding once. Every converter (`md-document`, `md-review`, `md-slides`) reads the resulting config via `config_loader.py` and applies the same 12 CSS custom properties to its output. Without this, conversions render with placeholder defaults — technically functional but unbranded.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
The design-system skill is the shared brand owner for the markdown-html plugin. Run its onboarding once. Every converter (md-document, md-review, md-slides) reads the resulting config via config_loader.py and applies the same 12 CSS custom properties to its output. Without this, conversions render with placeholder defaults — technically functional but unbranded.
This skill ships exactly three Python tools:
onboard.py — interactive (or --defaults / --set / --show / --reset) wizard.config_loader.py — importable customization loader with project > global > defaults precedence and MARKDOWN_HTML_NO_CONFIG=1 bypass.brand_palette_validator.py — WCAG-AA contrast checker + HSL palette deriver.All three are stdlib-only and contain no LLM calls (deterministic per Path-B discipline).
| Symptom | Action |
|---|---|
| User says "convert this markdown to HTML" for the first time in this workspace | Run python3 markdown-html/skills/design-system/scripts/onboard.py |
~/.config/markdown-html/design-system.json doesn't exist OR setup_completed_at is null | Refuse conversion, surface onboarding |
| User wants per-repo brand override | python3 .../onboard.py --scope project |
| User wants to change a single field non-interactively | python3 .../onboard.py --set brand.primary=#FF6B35 |
| User wants to reset and re-onboard | python3 .../onboard.py --reset then re-run |
| User wants zero-touch defaults (CI, ephemeral session) | python3 .../onboard.py --defaults |
| Headless / containerized run that should ignore saved config | MARKDOWN_HTML_NO_CONFIG=1 ... |
| # | Key | Choices / Validator | Default |
|---|---|---|---|
| 1 | default_output_dir | path; os.access(parent, os.W_OK) | ./markdown-html-out/ |
| 2 | brand.primary | HEX ^#?[0-9a-fA-F]{6}$ | #0A1628 |
| 3 | brand.accent | HEX or blank (auto-derive) | derive from primary |
| 4 | typography.heading_font | Google Font name (12 safe defaults) | Inter |
| 5 | typography.body_font | Google Font name | Inter |
| 6 | design_style | editorial / technical / minimal / playful | technical |
| 7 | code_theme | light / dark / auto | auto |
| 8 | toc.behavior | sticky-sidebar / collapsible-top / inline / none | sticky-sidebar |
| 9 | company_name | string (may be empty) | "" |
| 10 | logo_url | URL or empty (base64-embedded at render) | "" |
brand_palette_validator.validate() runs after every change. Body text on bg must reach 4.5:1; link on bg must reach 4.5:1. If either fails, onboard.py refuses to save (exit code 4) and tells the user to pick a darker primary, blank brand.bg/brand.text to let derivation pick a safe pair, or override brand.text directly. Canon: WCAG 2.2 §1.4.3.onboard.py walks up the path to find an existing ancestor and checks os.W_OK. Empty or unwritable path → exit code 3. The orchestrator's output_path_resolver.py honors the same rule per-conversion.design_style, brand.primary, code_theme, or toc.behavior. Decorative-only fields fail the design discipline.brand.primary in a project config without losing typography.heading_font from global).MARKDOWN_HTML_NO_CONFIG=1 is for headless CI, ephemeral test containers, and the autoresearch-style evaluator loops. Never set it silently for an interactive user.Once the user's brand is captured, brand_palette_validator.derive_palette() produces 12 CSS custom properties stored under derived_palette in the same config file. Every converter inlines these into its <style> block.
| Token | Purpose | Derivation |
|---|---|---|
--md-bg | Document background | Primary if dark, near-neutral if vibrant |
--md-surface | Card / callout / blockquote background | Bg ± 4-6% luminance |
--md-border | Hairline dividers, table borders | Bg ± 8-12% luminance |
--md-text | Body text | Off-white on dark bg, near-black on light bg |
--md-text-muted | Captions, metadata, footers | rgba(text, 0.68) |
--md-accent | Primary CTA, callout headers, link emphasis | Primary if vibrant, hue-shifted lighter if dark |
--md-accent-soft | Accent backgrounds, hover states | rgba(accent, 0.14) |
--md-code-bg | Inline code, fenced block bg | Bg ± 4-5% luminance |
--md-link | Hyperlinks | Iteratively walked to reach 4.5:1 contrast on bg |
--md-link-hover | Hover state | Link ± 6-8% luminance |
--md-success | OK / approved / passed | Green anchored, luminance-matched |
--md-warn | Caution / nit / TODO | Amber anchored, luminance-matched |
One question per turn, recommended answer, canon citation.
technical for engineering specs/reports, editorial for long-read narratives, minimal for sparse reference docs, playful for marketing/landing content. Canon: Ellen Lupton, Thinking with Type (style serves the rhetorical purpose).sticky-sidebar for documents over 800 words, inline for short reads. Canon: Nielsen-Norman, Table of Contents Best Practices (2023).--scope project only when this repo has a different brand. Canon: research-ops onboarding pattern, research-ops/CLAUDE.md §8.# First-run onboarding (interactive, walks all 10 questions)
python3 markdown-html/skills/design-system/scripts/onboard.py
# Zero-touch defaults for CI / first-test
python3 .../onboard.py --defaults
# Change just the primary color and design style
python3 .../onboard.py --set brand.primary=#FF6B35 --set design_style=editorial
# Per-repo override
python3 .../onboard.py --scope project --set design_style=minimal
# Reset and re-onboard
python3 .../onboard.py --reset
python3 .../onboard.py
# Inspect the effective config (project > global > defaults)
python3 .../config_loader.py --show
python3 .../config_loader.py --status
# Bypass saved config (returns DEFAULTS only)
MARKDOWN_HTML_NO_CONFIG=1 python3 .../config_loader.py --show
# Spot-check WCAG contrast before committing to a brand
python3 .../brand_palette_validator.py --primary "#FF6B35" --accent "#00D4AA"
code_theme: auto handles the prefers-color-scheme case for syntax highlighting; layout palette is single-mode per onboarding.marketing/landing/skills/landing/scripts/brand_palette_validator.py — that script's derive_palette() produces 8 tokens shaped for hero-page rendering (--navy, --teal, --card-bg, --card-border). This script produces 12 tokens shaped for document rendering (sticky surface, hairline border, code bg, link, link-hover, success, warn). Same WCAG + HSL math, different token taxonomy.research-ops/skills/clinical-research/scripts/onboard.py — same pattern (interactive + --defaults/--set/--show/--reset/--scope), different question set (clinical alpha/power/dropout vs. brand palette/typography/layout).~/.config/markdown-html/design-system.json (global) or ./.markdown-html/design-system.json (project). JSON schema lives at assets/design_system_schema.json.
brand.bg directly (low text contrast). Use it as accent instead.MARKDOWN_HTML_NO_CONFIG=1 silently for an interactive user — they'll wonder why their tokens disappeared.derived_palette outside the 12-token taxonomy. Add a new token only with a deliberate name + purpose + derivation rule.research-ops/CLAUDE.md §8marketing/landing/skills/landing/scripts/brand_palette_validator.py