Visual Design
You are helping the user re-skin an existing artifact with a distinct aesthetic. This is a post-step skill: something else produced the artifact; your job is to make it feel like something, not a generic template.
The skill supports two modes based on the input file:
- HTML mode (
.htmlinput) — 6-step flow: Tradition → Composition → Color → Type → Mood → Signature Flourish. Rewrites the<style>block, including CSS-only layout art direction. - SVG mode (
.svginput) — 3-step flow: Tradition → Stroke → Color. Rewrites stroke/fill attributes on paths. For icons, logos, and illustrations.
The skill ships with shared design DNA in references/ (synced from the repo's shared/design-dna/ — edit there, not here):
references/banned-defaults.md— the "never do" list every output must passreferences/font-pool.md— the characterful font supply and uniqueness rulesreferences/composition-signatures.md— eight CSS-only layout signaturesreferences/critique-gate.md— the render-and-critique gate run before any output shipsreferences/traditions.md+references/flourishes.md— the libraries (formerly inline)
The user invokes /visual-design [optional path to .html or .svg]. Original is preserved; a new <name>.styled.html or <name>.styled.svg is written alongside, and .visual-design/tokens.json captures the decisions for reuse in the project.
Core principles:
- Write in plain English. Talk like a designer who cares, not a form-builder.
- Each decision presents exactly 4 options except Tradition (top 3 matched + 20+ catalog) and Flourish (top 3 curated + library) — those use name-based picking.
- Always include a recommendation.
- Show, don't just tell — every option renders a preview using the actual tradition's tokens.
- Nothing banned ships. Every output passes the checks in
references/banned-defaults.mdand the critique gate inreferences/critique-gate.mdbefore the user sees it. - The skill's job ends when the styled file and
tokens.jsonare on disk, the critique gate has passed, and the result is opened for the user.
AUTO-MODE OVERRIDE (applies if /autodecide was used)
Detection: Auto-mode applies if EITHER:
$ARGUMENTScontains a[Auto directive: ...]block (injected by the/autodecideorchestrator), OR$ARGUMENTSstarts with/autodecide(direct invocation modifier — the user typed/visual-design /autodecide [path])
In the second case, strip /autodecide from the args before treating the rest as the path/argument for the skill. Note: visual-design has a fixed decision count per mode (6 for HTML, 3 for SVG), so depth modifiers (/overdecide, /underdecide) don't apply here — strip them if present and ignore.
If auto-mode is triggered, your behavior changes for this entire run — apply the rules below across every phase.
What changes:
Per-decision pauses are skipped. For each aesthetic decision in your flow (HTML mode: Tradition → Composition → Color → Type → Mood → Flourish; SVG mode: Tradition → Stroke → Color): generate the full HTML decision page exactly as normal — option previews using the actual tradition's tokens, recommendation, comparison. Save it. Record the decision in
.decisions/decisions.json(or your equivalent decision log) withstatus: "auto-picked"andchosenset to the recommended option (capture the recommendation reasoning in thereasoningfield, prefixed with "Auto-picked: "). Do NOTopenthe file. Do NOT pause. Immediately proceed to the next decision.Generate
.decisions/auto-review.htmlafter all aesthetic decisions are picked. This is the ONE pause point in auto mode. A single page listing every auto-picked aesthetic decision in a scannable layout. For each row, show: decision number, decision title (e.g. "Tradition", "Color"), the chosen option (label + summary or token preview), the other options as one-line summaries, and the AI's reasoning. Use the same dark-theme styling as per-decision pages (background#0a0a0f, accent#6c63ffpurple,#fbbf24yellow for "auto-picked",#4ade80green for "confirmed"). Footer must surface the override syntax:For decision-N I want Yand an "Approve all" path. Open it withopen .decisions/auto-review.html.Tell the user. Output: "Auto-picked all N aesthetic decisions. Review at .decisions/auto-review.html. Confirm with 'looks good' or override with 'For decision-N I want Y'."
Wait for the user's response. This is the only pause in auto mode.
On user response:
- "Looks good" / "Confirm" / "Approved" / similar → Transition every
auto-pickeddecision tostatus: "chosen". Update the auto-review page rows to the green "confirmed" state. Then proceed to the styled-file generation step normally — apply all chosen tokens, write<name>.styled.htmlor<name>.styled.svgandtokens.json, and open the result. - "For decision-N I want Y" → Update that decision: change
chosento option Y, setstatus: "chosen", capture reasoning if given, add ahistoryentry recording the change from auto-pick to user choice. Regenerateauto-review.html. Re-prompt for confirmation of the remaining auto-picks. Repeat until the user confirms. - "Redo decision N" (or "redo N" / "interactive N") → Drop just decision N back to interactive mode: open its HTML, run the standard interaction. After they pick, return to the auto-review pause for the rest.
- Custom answer → Standard custom-answer handling: generate a custom option card (or use the user's named tradition/color/etc.), regenerate auto-review.
Note on Tradition and Flourish: these decisions don't follow the strict 4-option pattern (they use top-3-matched + catalog/library). In auto mode, auto-pick the top match (the highest-ranked recommendation) for each. The user can still override to any catalog item via the standard syntax.
Note on depth directives: visual-design has a fixed decision count per mode (6 for HTML, 3 for SVG), so any [Depth directive: ...] from /overdecide or /underdecide does not apply here — auto-mode runs the standard count.
Schema: auto-picked is a third valid value for the status field, alongside pending and chosen. The styled file must not be written until every aesthetic decision has transitioned from auto-picked to chosen.
Critical invariant: Do NOT write the styled file (.styled.html/.styled.svg) or tokens.json until every decision has transitioned from auto-picked to chosen. The batch-review pause is the gate.
PHASE 1 — Invocation
Step 1a — Parse the argument + detect mode
The user invokes /visual-design [path] where [path] is optional.
If a path is provided:
- Verify the file exists.
- Branch on extension:
.html→ setMODE = "html",TARGET = path, proceed to Phase 2..svg→ setMODE = "svg",TARGET = path, proceed to Phase 2..png/.jpg/.jpeg/.webp→ tell the user rasters aren't supported (the skill rewrites vector/style, not pixels). Suggest they convert to SVG or provide an HTML wrapper. Stop.- Any other extension → tell the user and fall through to the picker path below.
If no path is provided:
- Glob for recent styleable artifacts in priority order:
.decisions/*.html(most common — decision-kit outputs)*.{html,svg}in cwd**/*.{html,svg}up to 2 levels deep (excludingnode_modules,dist,.git)
- Sort results by modification time (newest first).
- If 0 matches: tell the user no artifacts found, suggest running a thinking skill first or passing a path. Stop.
- If 1 match: use it, but confirm with user first:
"Found [filename] (modified [time ago]). Re-skin this one? Reply
yesor pass a different path." - If 2+ matches: show the top 5 with the newest marked ✓:
"Found these artifacts. Which one do you want to re-skin?
- ✓ strategy-brief.html (2 min ago)
- icon-download.svg (1 hr ago)
- proposal.html (yesterday) Reply with a number, a filename, or paste a different path."
Once confirmed, set MODE from the extension. Wait for confirmation before proceeding.
Step 1b — Check for project memory
Once TARGET is set, check for .visual-design/tokens.json at the project root (walk up from the target file to find the nearest one).
- If present: parse it. Note the previous tradition + flourish. On the Phase 3 starting screen, surface this as suggestion #1 in the top 3 with the label "your project aesthetic."
- If absent: normal flow — skill will create the
.visual-design/directory later.
Step 1c — Create .decisions/ working directory for this run
Create .decisions/visual-design/ at the project root. Per-step decision pages for this invocation go here.
HTML mode output:
01-tradition.html02-composition.html03-color.html04-type.html05-mood.html06-flourish.htmlindex.html(run summary)
SVG mode output:
01-tradition.html02-stroke.html03-color.htmlindex.html(run summary)
These let the user revisit their aesthetic decisions later.
PHASE 2 — Artifact Analysis
Analysis branches on MODE.
Phase 2 — HTML mode
Read the target HTML file. Extract:
- Structural selectors — every class and ID used on elements. Note the semantic regions (
header,footer,nav,main,section, etc.). - Current style block — the contents of
<style>...</style>if present. Note what tokens it already defines (e.g.,:root { --ink: ... }). - Artifact type hints:
- Word count (rough estimate from stripped body text)
- Heading structure (h1-h6 count)
- Presence of tables, lists, code blocks, forms
- Inline font stacks used
- Infer artifact type — one of:
brief— word-heavy, 1-3 headings, long prose paragraphslanding— short hero text, multiple sections, CTAsdoc— many headings, tables, code blocksproposal— mixed — hero + sections + tables + CTAsdashboard— low text, many small cardsslide/one-pager— small body, large display text
Keep this as a data structure you reference throughout the run. Example:
{
"target": ".decisions/strategy-brief.html",
"mode": "html",
"type": "brief",
"wordCount": 2400,
"headings": { "h1": 1, "h2": 6, "h3": 3 },
"hasTables": true,
"hasCode": false,
"selectors": [".page", ".option", ".footer", ".research", "h1.title", ".deck", "..."]
}
Phase 2 — SVG mode
Read the target SVG file. Extract:
- ViewBox and dimensions —
viewBox,width,heightattributes on the root<svg>element. - Shape inventory — count of
<path>,<circle>,<rect>,<line>,<polygon>,<polyline>,<ellipse>. Note which primitives dominate. - Current styling:
- Existing
strokeandfillattributes on shapes (and inside inlinestyle="...") - Existing
stroke-widthvalues - Any embedded
<style>tag inside the SVG - Any
<defs>(gradients, filters, patterns) that will need to be updated or preserved
- Existing
- Color count — how many distinct colors are used? (1 = single-color, 2-3 = duotone/limited, 4+ = multi-color illustration)
- Infer asset type — one of:
icon— small viewBox (≤64), 1-2 colors, outline-style (no fill or single fill)logo— small-medium viewBox, branded colors, mixed stroke/fillillustration— larger viewBox, 4+ colors, complex shapesglyph— path-only, single color, no stroke (text-like)
Example:
{
"target": "icons/download.svg",
"mode": "svg",
"type": "icon",
"viewBox": "0 0 24 24",
"shapes": { "path": 3, "circle": 0, "rect": 0 },
"colorCount": 1,
"currentStroke": "currentColor",
"currentFill": "none",
"currentStrokeWidth": "2"
}
Warn the user if type === "illustration" and they've picked a tradition with single-color rules — multi-color illustrations may lose detail when flattened to a tradition's palette.
PHASE 3 — Tradition Selection (Decision 1)
This is the first and biggest decision. The catalog holds 20-30+ traditions; the starting screen gives the user a fast path (top 3 matches) and a surf path (the whole catalog, flat).
Step 3a — Score the traditions for this artifact
For each tradition in the library (see AESTHETIC TRADITIONS LIBRARY below), compute a fit score from the artifact type:
| Artifact type | Tradition affinities (highest fit first) |
|---|---|
brief (HTML) |
Editorial Print, Warm Minimal, Academic, Newsprint, Japandi, Neo-Classical, Botanical Herbarium, Swiss Modern |
landing (HTML) |
Neo-Brutalist, Kinetic Modern, Glassmorphic, Playful Maximalist, Y2K Maximalist, Memphis Revival, Retro Futurism, Swiss Modern |
doc (HTML) |
Technical Documentary, Swiss Modern, Monochrome, Academic, Dashboard Operator, Newsprint |
proposal (HTML) |
Editorial Print, Neo-Classical, Swiss Modern, Warm Minimal, Luxury Serif, Midnight Marine, Art Deco |
dashboard (HTML) |
Swiss Modern, Technical Documentary, Dashboard Operator, Kinetic Modern, Monochrome, Neon Terminal |
slide (HTML) |
Editorial Print, Neo-Brutalist, Luxury Serif, Kinetic Modern, Art Deco, Bauhaus Grid, Zine |
icon (SVG) |
Swiss Modern, Monochrome, Neo-Brutalist, Technical Documentary, Neon Terminal, Cyberpunk Neon, Dashboard Operator, Bauhaus Grid |
logo (SVG) |
Swiss Modern, Neo-Brutalist, Art Deco, Luxury Serif, Bauhaus Grid, Retro Futurism, Monochrome |
illustration (SVG) |
Warm Handmade, Sketchbook, Botanical Herbarium, Editorial Print, Memphis Revival, Kraft Paper, Playful Maximalist |
glyph (SVG) |
Monochrome, Swiss Modern, Neo-Brutalist, Art Deco, Luxury Serif, Academic |
SVG-incompatible traditions (warn user if they pick one for an SVG):
- Glassmorphic — requires backdrop-filter + layered translucency, meaningless on single-shape icons
- Playful Maximalist — gradients-as-default need careful per-shape handling, best for illustrations only
- Anti-Design — clashing-font premise doesn't apply to vectors without text
If the user picks one of these in SVG mode, offer a gentle "are you sure? here's what will change" note rather than blocking. The tradition will still resolve (color palette at least).
Top 3 scores become the featured matches. If project memory exists, slot the previous tradition as suggestion #1 regardless of score (with the "your project aesthetic" label).
Step 3b — Render the tradition decision page
Write .decisions/visual-design/01-tradition.html following the HTML TEMPLATE REFERENCE below. The page has two sections:
- Matched for your artifact (3 large tiles, rendered with each tradition's real tokens — type-forward thumbnail style, see below)
- Browse all (flat grid of remaining traditions, ~48px tiles)
Each tile renders the tradition's name using the tradition's own headline font, primary text color, and base background. This is the "type-forward thumbnail" pattern — one word in the tradition's voice. Readable at small sizes, conveys feel instantly.
Open the file with open .decisions/visual-design/01-tradition.html and wait for the user's response.
Step 3c — Handle the user's pick
User's response shapes:
- Name:
Editorial,Editorial Print,warm minimal,Swiss,neo-brutal→ fuzzy-match the library (case-insensitive, partial prefix match). - Shortcut:
top pick/first/best match/A/B/C→ resolves to the 1st, 2nd, or 3rd matched tile. recommended→ resolves to the highest-scored tradition (usually match #1).more/more options→ expand the Browse All grid (if you showed a partial subset initially).surprise me/skill's pick→ pick the highest-scored tradition, move on.
If input is ambiguous (multiple traditions match), list the candidates numbered:
"Could be: 1) Editorial Print, 2) Academic (editorial typeface), 3) Neo-Classical. Reply with a number or a more specific name."
Once locked: set TRADITION in state, proceed to Step 3d.
Step 3d — Calibrate with current references (optional but recommended)
Traditions are a stable grammar. The web has current examples. Combining the two gives you a library that never ages.
After TRADITION locks (and before presenting the Color/Type steps), fire 1-2 WebSearch queries targeting current real-world examples of this tradition. Good patterns:
"<tradition name> web design 2026 examples""<tradition name> <artifact type> current trends"(e.g., "editorial landing page current trends", "neo-brutalist SaaS site 2026")- For SVG mode:
"<tradition> icon set current"or"<tradition> icons 2026"
From the results, extract 1-3 concrete calibration signals:
- Shifted accent hue — is the current wave of this tradition trending warmer/cooler/more saturated? Capture 1-2 specific hex values from the examples.
- Updated font weight or pairing — did current examples swap the library's default for something fresher (e.g., Fraunces variable axis set to 144 instead of 96, or paired with Inter Tight instead of Inter)?
- Trending treatment — a new signature move the tradition is doing right now (e.g., current Editorial Print examples using big italic pull quotes; current Neo-Brutalist adding subtle grain behind offset shadows).
Store these as CALIBRATION in state alongside TRADITION. They'll show up in downstream decisions as a "2026 current" variant.
Skip this step if:
- Web is unavailable (offline, tool error)
- User said
use library defaultsorskip calibrationat any prior step - The tradition is intentionally era-specific and shouldn't track trends (Art Deco, Academic, Neon Terminal — these are stable by definition)
Don't let this step add more than ~5 seconds of latency. One search, extract, move on. If the search returns nothing useful, skip silently — the library defaults are still fine.
PHASE 4 — Remaining Steps
The flow branches on MODE:
- HTML mode → 5 remaining steps (Composition, Color, Type, Mood, Signature Flourish), all A/B/C/D
- SVG mode → 2 remaining steps (Stroke, Color), all A/B/C/D
PHASE 4 (HTML mode) — Steps 2-6
All five of these steps use the A/B/C/D pattern (standard thinking-skill convention). Each step:
- Generates a decision HTML page with 4 options
- Opens it in the browser
- Waits for a letter-based response
Step 2 — Composition
The bones decision — load references/composition-signatures.md. Sameness in layout survives any re-paint; this step is where the artifact stops being the default centered column. Everything here is CSS-only: grid-template-areas, spans, offsets on the artifact's existing semantic regions. Never restructure the DOM.
Given TRADITION and the artifact analysis from Phase 2, offer 4 options:
- Option A: Tradition signature — the tradition's default signature from the library table (recommended).
- Option B: Monolith — the deliberate single column: oversized display headline, extreme vertical rhythm. For when content should dominate.
- Option C: Contrast pick — the signature that most opposes A, for users who want friction.
- Option D: Density shift — A's signature with density inverted (gutters, measure, rhythm one step tighter or looser).
Render each option as a miniature wireframe — gray blocks in the actual grid proportions of that signature, using the tradition's bg/ink — so the user sees the bones before any paint.
Fitness guard: if the artifact has fewer than 3 distinct semantic regions, or is dominated by wide tables (dashboard/doc with heavy tables), grey out signatures the library marks as unfit and note why. If nothing but monolith fits, say so and pre-pick B.
Write .decisions/visual-design/02-composition.html. Open. Wait.
Step 3 — Color
Given TRADITION (and optionally CALIBRATION from Step 3d), offer 4 color variants:
- Option A: Faithful — the tradition's default ramp + accent as specified by the library.
- Option B: 2026 current (when
CALIBRATIONhas color signal) — the tradition's ramp with the calibration's shifted accent hue applied. Label this option explicitly: "Pulled from current [tradition] examples on the web." Fall back to "Warmer" (shift accents toward wood/brick/amber) if no calibration was gathered. - Option C: Cooler — shift accents toward cooler hues (navy, forest, slate). Always available.
- Option D: Higher contrast — pump the contrast between text and background one step. Always available.
Render each option as a mini-frame with the tradition's structure (browser chrome, header, hero headline, CTA button) using the shifted palette. Write .decisions/visual-design/03-color.html. Open. Wait.
Step 4 — Type
Given TRADITION + COLOR (and optionally CALIBRATION), offer 4 type treatments:
- Option A: Tradition default — the headline + body pair specified by the tradition (recommended when no calibration).
- Option B: 2026 current (when
CALIBRATIONhas type signal) — updated font weight / pairing pulled from current examples of this tradition. Label: "Pulled from current [tradition] examples on the web." Fall back to "Bigger headlines" (same fonts, one scale step up on h1/h2) if no calibration. - Option C: Alternate pair — the tradition's alternate typeface suggestion (e.g., for Editorial, swap Fraunces display for Source Serif display).
- Option D: Mono everything — replace body with a monospace stack (good for technical feel).
All four options must clear references/banned-defaults.md — no banned face may be offered, including in Option D's mono stack (use the tradition's own mono from references/font-pool.md).
Each preview shows a styled headline + two lines of body text at realistic sizes. Write .decisions/visual-design/04-type.html, open, wait.
Step 5 — Mood
Given prior choices, offer 4 mood combos (shape × shadow bundled):
- Option A: Sharp + flat — tight radius, no shadows
- Option B: Sharp + elevated — tight radius, strong shadows
- Option C: Soft + flat — generous radius, no shadows
- Option D: Soft + elevated — generous radius, soft shadows
Each preview shows a CTA button + a card + a divider to demonstrate the combo. The values come from the tradition's tokens; this step picks which combination dominates the artifact.
Step 6 — Signature Flourish
Given prior choices, load the flourish candidates from the tradition's picks in references/flourishes.md.
- Top 3 curated — the 3 flourishes that fit this tradition best (per the table in the flourish library). Surface with the label "✦ fits [tradition] best."
- Full library below — all 8-10 flourishes available. Browse flat.
This is the novel step — the anti-generic move. Use name-based picking like Tradition:
- Name:
Drop Cap,Pull Quote,Grain, etc. A/B/Chits the top 3 tilesnone/skipis a valid choice (no flourish)
Each flourish preview renders the flourish rendered inside a small paragraph using the chosen tradition.
Write .decisions/visual-design/06-flourish.html. Open. Wait.
PHASE 4 (SVG mode) — Steps 2-3
Two remaining steps after Tradition. Both use A/B/C/D.
Step 2 — Stroke Weight
Pull the tradition's default stroke weight preference and offer 4 options calibrated around it. For a tradition whose rule specifies "1.5px stroke" (Swiss), the range might be 1 / 1.5 / 2 / 3. For Neo-Brutalist, 2 / 3 / 4 / 6.
General pattern:
- Option A: Thin — hairline, precise. Good for dense icon sets and reading-context icons.
- Option B: Regular — the tradition's default stroke width (recommended).
- Option C: Bold — stepped up one level, more presence.
- Option D: Very Bold — aggressive, chunky. Sets the icon apart. Default for Neo-Brutalist, Y2K, Anti-Design.
Render each option as a small grid of 3-4 icon primitives (chevron, plus, check, circle) drawn in the tradition's colors at that stroke width. User sees how each weight reads at typical icon size.
Also apply the tradition's stroke-linecap and stroke-linejoin preference:
- Most traditions →
roundfor linecap + linejoin - Swiss Modern, Bauhaus, Monochrome, Technical, Dashboard →
square/miter - Neo-Brutalist →
square+ thick miter join - Neon Terminal, Cyberpunk →
squarewith glow filter
Write .decisions/visual-design/02-stroke.html. Open. Wait.
Step 3 — Color
Given TRADITION + STROKE, offer 4 color treatments:
- Option A: Faithful palette — apply the tradition's accent color as stroke/fill (e.g., Editorial's
#9a3412brick, Cyberpunk's#ff006eneon). - Option B: Monochrome — single color, typically the tradition's ink (e.g., Editorial's
#1f1611, Swiss's#0f172a). Most versatile for icon sets — inherits from surrounding text color if set tocurrentColor. - Option C: Single accent — stroke in the tradition's brightest accent, with no fill. Best for call-to-action icons.
- Option D: Duotone — two colors on different paths/shapes. Stroke in accent, fill in a secondary tone. Requires 2+ shapes in the SVG to make sense — if the SVG has only 1 path, grey out this option.
Each preview renders the same test icon with each color treatment applied so the user can see the difference directly.
Special case — SVG uses currentColor: If the input SVG already uses currentColor for stroke (common in icon libraries like Lucide, Heroicons), Option B should preserve that. Include a 5th-line note: "Detected currentColor — Option B keeps it inheritable."
Write .decisions/visual-design/03-color.html. Open. Wait.
PHASE 5 — Rewrite & Output
Branches on MODE.
HTML mode — Steps 5a–5e below (existing flow). SVG mode — Steps 5s-a through 5s-d (new, after the HTML section).
Phase 5 (HTML mode)
Once all 6 decisions are locked, you have:
TRADITION— tokens + aesthetic rulesCOMPOSITION— the layout signature + density variantCOLOR— palette shift applied to rampTYPE— headline + body pair + scaleMOOD— shape + shadow comboFLOURISH— the signature element to add
Step 5a — Resolve final tokens
Combine everything into a single tokens object:
{
"tradition": "Editorial Print",
"variant": {
"composition": "editorial-spread",
"color": "faithful",
"type": "tradition-default",
"mood": "sharp-flat",
"flourish": "drop-cap"
},
"tokens": {
"color": {
"ramp": ["#fdf6e3", "#f5ecd0", "#e7d7b8", "...", "#1f1611"],
"accent": "#9a3412",
"ink": "#1f1611",
"bg": "#fdf6e3"
},
"type": {
"headline": { "family": "'Iowan Old Style', Georgia, serif", "weights": [400, 600, 700] },
"body": { "family": "'Source Serif 4', Georgia, serif", "weights": [400, 600] },
"mono": { "family": "'JetBrains Mono', ui-monospace, monospace" },
"scale": [12, 14, 18, 22, 32, 52]
},
"spacing": [4, 8, 12, 16, 24, 32, 48, 72, 104],
"radius": [2, 4, 6, 10],
"shadow": { "l1": "...", "l2": "...", "l3": "...", "l4": "..." },
"motion": { "ease": "cubic-bezier(.2,.8,.2,1)", "duration": [140, 240, 400] }
},
"rules": [
"Always use Iowan Old Style display at larger sizes.",
"Italics are expressive tools for kickers and captions.",
"No gradients — solid warm paper + ink.",
"..."
],
"flourish": {
"type": "drop-cap",
"css": ".drop { float: left; font-family: var(--headline); font-size: 3.5em; line-height: 0.85; padding: 0.1em 0.1em 0 0; color: var(--accent); }",
"htmlHook": "add <span class=\"drop\">[first letter]</span> to the first paragraph after each h1"
}
}
Step 5b — Generate the new <style> block
Using the artifact's selectors (from Phase 2) and the resolved tokens, compose a complete CSS stylesheet:
- Add Google Fonts
<link>if needed (check the tradition's type stack) - Add
:root { --... }with the resolved tokens - For each selector in the artifact, write rules that:
- Apply tradition's aesthetic rules (e.g., offset-solid shadows for Neo-Brutalist, italic kickers for Editorial)
- Use the resolved tokens for color, spacing, radius, type
- Preserve the DOM and its semantics — composition changes come from CSS, never restructuring
- Apply the chosen composition signature's CSS (from
references/composition-signatures.md) to the artifact's semantic regions — grid-template-areas, spans, offsets — including its under-720px single-column collapse - Append the flourish CSS
- Responsive breakpoints mirror the original where the signature doesn't supersede them (never lose the artifact's mobile usability)
- Run the self-check from
references/banned-defaults.mdagainst the stylesheet before writing it — banned faces and hexes must not survive into the output
Step 5c — Write output files
- Copy the original artifact HTML structure (body, semantics) into a new file named
<original-name-without-ext>.styled.htmlin the same directory as the original. - Replace its
<style>...</style>block with the freshly generated CSS. - If
FLOURISH.htmlHookspecifies DOM insertions (e.g., drop caps, pull quotes), apply them minimally — just enough to manifest the flourish. - Ensure the
<head>has the needed Google Fonts<link>tags.
Step 5d — Write tokens sidecar
Write the resolved tokens object (from Step 5a) to .visual-design/tokens.json at the project root. Also write .visual-design/run.json with the invocation metadata (timestamp, target file, all 5 decisions).
If .gitignore exists and doesn't include .visual-design/, append a line:
# visual-design skill state
.visual-design/
Step 5e — Run the critique gate
Before the user sees anything, run the gate in references/critique-gate.md against the styled file: deterministic checks (ban scan, contrast, composition proof, font delivery), then render via headless Chrome (or available browser tooling) and answer the binary rubric against the screenshot — falling back to the CSS self-review variant if no renderer exists. Fix failures, maximum two loops. Keep what the gate found for the report.
Step 5f — Open + report
Open both files side by side (so user can compare):
open <original>
open <original-basename>.styled.html
Report:
"Re-skinned! [basename].styled.html is open alongside the original.
Applied [Tradition] with [Composition] and [Flourish]. Decisions saved to
.visual-design/tokens.json— next run in this project will surface this aesthetic as suggestion #1.[One short paragraph: what the critique gate checked, caught, and fixed — one sentence if everything passed.]
Reply:
love it→ nothing to do, doneredo→ rerun the flow from scratchchange [tradition|composition|color|type|mood|flourish]→ rerun just that stepdifferent flourish→ return to step 6more contrast/warmer/ etc → I'll interpret and adjust"
Phase 5 (SVG mode)
Once all 3 decisions are locked, you have:
TRADITION— aesthetic rules (stroke-linecap, linejoin, filter needs)STROKE— stroke-width valueCOLOR— resolved stroke + fill values (faithful / mono / accent / duotone)
Step 5s-a — Resolve SVG attributes
Derive the exact attribute values to apply to each shape:
{
"mode": "svg",
"tradition": "Editorial Print",
"variant": { "stroke": "regular", "color": "monochrome" },
"svg": {
"strokeWidth": "1.5",
"stroke": "#1f1611",
"fill": "none",
"strokeLinecap": "round",
"strokeLinejoin": "round",
"filter": null
},
"rootAttributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"stroke": "currentColor",
"stroke-width": "1.5",
"stroke-linecap": "round",
"stroke-linejoin": "round"
}
}
For traditions with a signature filter (Cyberpunk Neon, Neon Terminal), generate an SVG <filter> element to embed under <defs>. Example for Neon Terminal's phosphor glow:
<defs>
<filter id="vd-glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="1.5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
Then apply filter="url(#vd-glow)" to grouped shapes.
Step 5s-b — Rewrite the SVG
The strategy: hoist common attributes to the root <svg> element, then remove redundant per-shape attributes. This keeps the output clean and makes the SVG easy to re-theme later.
Set root attributes on
<svg>itself:stroke,fill,stroke-width,stroke-linecap,stroke-linejoin- Keep existing
viewBox,width,height - Preserve
xmlns
Strip old styling from every shape (
<path>,<circle>, etc.):- Remove
style="..."attributes - Remove per-shape
stroke,fill,stroke-widthUNLESS the color treatment isduotoneand this shape is the "accent" layer — then keep its override.
- Remove
Duotone handling:
- For multi-shape SVGs with duotone: the first half of shapes (or all "filled" shapes) get
fill="var(--accent)"+stroke="none"; the second half getstroke="var(--ink)"+fill="none". Tune per SVG inspection. - Single-path SVGs can't express duotone — fall back to accent.
- For multi-shape SVGs with duotone: the first half of shapes (or all "filled" shapes) get
Filter injection (if tradition requires one):
- Add
<defs>with the filter after<svg>opening - Add
filter="url(#vd-glow)"to either the root<g>wrapper OR individual shapes
- Add
Add a CSS comment header inside
<svg>as a text annotation for discoverability:<!-- /visual-design · Editorial Print · 1.5px · monochrome -->Preserve everything else untouched —
<title>,<desc>,<metadata>, comments, id attributes, aria attributes.
Step 5s-c — Write output files
- Write the rewritten SVG to
<original-basename>.styled.svgin the same directory as the original. - Write tokens to
.visual-design/tokens.jsonat the project root (shared with HTML mode — same file, tokens now may include ansvgfield alongside the usual ones). - Write run metadata to
.visual-design/run.json(target, mode, decisions, timestamp). - Add
.visual-design/to.gitignoreif missing.
Step 5s-d — Critique gate + open + report
Run the lightweight SVG variant of references/critique-gate.md first: ban scan on any embedded style, then render the styled SVG (headless Chrome screenshots SVG files directly) and check — strokes legible at 24px? duotone layers distinct? filter (if any) visible without blowing out shapes? Fix and re-check once, then open both files side by side (browsers render SVGs directly):
open <original>
open <original-basename>.styled.svg
Report:
"Re-skinned! [basename].styled.svg is open alongside the original.
Applied [Tradition] at [Stroke]px in [Color treatment]. Decisions saved to
.visual-design/tokens.json.Reply:
love it→ doneredo→ rerun the flowchange [tradition|stroke|color]→ rerun just that stepmore stroke weight/different color→ I'll interpret and adjustapply to other SVGs in this folder→ batch-apply the same aesthetic to sibling .svg files"
Batch mode (bonus): if the user invokes /visual-design again in the same project and another .svg is detected, default to applying the project's saved tokens directly (skip the flow) unless they say otherwise. This makes consistent icon sets trivial.
RESPONSE PARSING — How Users Pick
The six steps don't all have 4 options, so input parsing varies per step:
Steps 2, 3, 4, 5 (Composition, Color, Type, Mood) — standard A/B/C/D
- Exactly 4 options each. Respond like any thinking skill.
- Accept:
Option A,A,the first one,Option B because [reason],Option A but [modification],more options.
Steps 1 and 6 (Tradition, Flourish) — name-based picking
- 10-30+ options, letters don't scale. Pick by name.
- Primary:
Editorial,Warm Minimal,Neo-Brutalist,Drop Cap,Rule Line, etc. - Fuzzy: case-insensitive, partial prefix match (
brutal→ Neo-Brutalist,warm→ Warm Minimal). - Top-3 shortcuts:
A/B/Chit the top 3 tiles. Also:top pick,first,best match. - Disambiguate: if input matches >1 tradition, echo candidates numbered, ask for a pick.
- Recommended: the highest-scored tradition earns a ★. User can say
recommendedto pick it.
Catalog-wide commands (any step)
more/more options— expand visible set.surprise me/skill's pick— take the highest-scored option, move on.back/previous— step back without rerunning.skip— at step 6, valid meaning "no flourish." At other steps, use recommended.
Match input against (a) letter regex ^([A-Za-z])\b at steps 2-5, (b) shortcut keywords, (c) fuzzy name match at steps 1 and 6. Show numbered candidates when ambiguous.
AESTHETIC TRADITIONS LIBRARY
The 30-tradition library lives in references/traditions.md — load it when you reach Phase 3 (Tradition selection) and again at Phase 5 (rewrite). Each entry provides tokens (color ramp, type stack, spacing, radius, shadow, motion), aesthetic rules, flourish picks, and a default composition signature.
Two library-wide guarantees (do not violate when adding or editing traditions):
- No two traditions share a display face. Body and mono faces may repeat at most twice across the catalog.
- Nothing in the library uses a banned default — see
references/banned-defaults.md.
SIGNATURE FLOURISH LIBRARY
The ten flourish types (CSS + insertion hooks + tradition fit) live in references/flourishes.md — load it at Step 6 (Flourish) and at Phase 5 when applying the chosen flourish.
HTML DECISION PAGE TEMPLATE
Each step generates a decision HTML file. Use a consistent shell with per-step variations.
Shell skeleton (applies to all 6 step pages)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Visual Design · Step [N] · [StepName]</title>
<style>
:root {
--page-bg: #faf8f4;
--page-ink: #1a1714;
--page-ink-2: #4a433b;
--page-ink-3: #7a7066;
--page-rule: #d8cfbf;
--page-accent: #9a3412;
--page-accent-soft: #fef3e8;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Inter", sans-serif; background: var(--page-bg); color: var(--page-ink); padding: 48px 32px; line-height: 1.6; }
.page { max-width: 1100px; margin: 0 auto; }
.eyebrow { font-family: ui-monospace, "SF Mono", monospace; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--page-accent); margin-bottom: 20px; }
h1 { font-family: "Iowan Old Style", Palatino, Georgia, serif; font-size: 44px; font-weight: 400; letter-spacing: -0.015em; margin-bottom: 16px; }
.deck { font-family: "Iowan Old Style", Palatino, Georgia, serif; font-style: italic; font-size: 18px; color: var(--page-ink-2); max-width: 720px; margin-bottom: 40px; }
/* Step-specific styles follow here */
</style>
</head>
<body>
<div class="page">
<div class="eyebrow">Step [N] of 6 · [StepName]</div>
<h1>[Decision question]</h1>
<p class="deck">[Plain-English framing — 1 sentence]</p>
[STEP-SPECIFIC CONTENT]
<div class="footer">[instruction on how to respond]</div>
</div>
</body>
</html>
Step 1 (Tradition) — structure
- Section A: "Matched for your artifact" — 3 large tiles (160px × 100px each), horizontal row. Each renders the tradition name in the tradition's own type + color + bg.
- Section B: "Browse all" — flat grid, 5 columns × N rows of small tiles (56-64px). Each tile = name in the tradition's type-forward thumbnail style.
- Footer: "Repl
…(truncated)