Esoteric Fish

Sofia Yang

Reading Time
6 min
Date
May 2026
Technical Writeup

Building a Document Design System as an Agent Skill

From color mockups to installable SKILL.md — a constraint-first approach

The Problem

AI agents produce documents that look different every time. Same prompt, same model, wildly different typography, spacing, and color choices. The output is functional but never consistent — and never something you'd want to ship to a stakeholder.

Existing solutions like Kami solve this with a fixed aesthetic (parchment + ink blue + serif), but that locks you into one visual identity. What if you want a different palette? A different font system? You'd need to fork the entire skill and rewrite the constraints.

1
Accent Color
2
Font Families
9
DESIGN.md Sections
Core insight: A document design system is not a template — it's a set of constraints. The agent fills in content; the constraints ensure visual consistency. Fewer constraints that are strictly enforced beats many constraints that are loosely followed.

Constraint-First Design

Instead of designing a template and extracting rules, we worked backwards: define the constraints first, then build components that satisfy them. This meant making design decisions as a series of eliminations.

What we eliminated

  • Multiple accent colors — three competing accents drew the eye away from text. One accent (Copper) keeps the hierarchy clean.
  • Colored status badges — green/red/yellow badges create visual noise. Neutral zinc badges with copper for active-only is sufficient.
  • Monospace body text — JetBrains Mono for body felt too "terminal." DM Sans for body reads as a proper document.
  • Warm backgrounds — parchment tones (`#f5f4ed`) felt editorial but clashed with technical content. Cool `#fafafa` is neutral ground.
  • Uppercase section labels — micro-labels (SUMMARY, KEY CHANGES) read like a dashboard. Proper H2/H3 hierarchy reads like a document.

What we kept

  • Doppelrand page shell — outer tray + inner core creates physical depth on screen, strips cleanly in print
  • H2 copper bottom-border — the single strongest visual anchor, creates clear section breaks
  • 65ch body width — optimal reading line length, non-negotiable
  • Film-grain noise overlay — subtle texture at 2% opacity, adds warmth without color

Key Design Decisions

DecisionOptions ConsideredChosenRationale
Accent colorTerracotta, Teal, Violet, Gold, CopperCopper #B0652EWarm on cool base, distinctive, not "AI purple"
Heading fontPlus Jakarta Sans, DM Sans, GeistDM SansRounder, more formal than Jakarta, less niche than Geist
Body fontJetBrains Mono, DM Sans, Source SerifDM SansMono felt like a terminal, serif felt like a law firm
BackgroundWarm parchment, pure white, Zinc-50#fafafa (Zinc-50)Cool neutral, doesn't compete with warm accent
Section structureUppercase micro-labels, H1/H2/H3H1/H2/H3Proper hierarchy for formal documents
Status colorsSemantic (green/red), Neutral zincNeutral + copper activeFewer colors = less noise = content-first

Skill Architecture

The skill follows the Stitch DESIGN.md format — a 9-section specification that any AI agent can consume. The skill itself is a lightweight SKILL.md that references the full design system.

flowchart TB
    subgraph Skill["SKILL.md (Agent reads this)"]
        A[When to activate]
        B[Document types]
        C[Design tokens]
        D[HTML structure template]
        E[Critical rules]
    end
    subgraph Ref["DESIGN.md (Full reference)"]
        F[Visual Theme]
        G[Color Palette]
        H[Typography]
        I[Components]
        J[Layout]
        K[Do's & Don'ts]
    end
    subgraph Out["Output"]
        L[Styled HTML]
        M[PDF via print]
    end
    Skill --> Ref
    Skill --> Out
      
Figure 1 — SKILL.md is the entry point; DESIGN.md is the full reference
file structure
copper-docs/
├── skills/copper-docs/
│   ├── SKILL.md              # What agents read
│   └── references/
│       └── DESIGN.md          # Full 9-section spec
├── templates/
│   ├── rfc-template.html      # Complete RFC example
│   └── example-writeup.html   # This document
└── renderer/
    ├── index.html             # Markdown → styled preview
    └── generate-pdf.js        # Playwright PDF export

Rendering Pipeline

Documents can be produced through three paths, each serving a different workflow.

flowchart LR
    A["Agent generates HTML"] --> B["Browser renders"]
    B --> C["User reviews"]
    C --> D["Export PDF"]

    E["User writes Markdown"] --> F["Renderer (marked.js)"]
    F --> B

    G["Playwright script"] --> H["Headless render"]
    H --> D
      
Figure 2 — Three rendering paths: agent-generated HTML, markdown editor, or headless CLI

Path 1: Agent generates HTML directly

The agent reads SKILL.md, generates a complete HTML document following the design system, and writes it to disk. The user opens it in a browser and exports to PDF. Best for one-shot document generation.

Path 2: Markdown renderer

The user writes markdown in the split-pane editor. marked.js converts it to HTML, and the design system CSS is applied automatically. Mermaid code blocks render as diagrams. Best for iterative writing.

Path 3: Headless PDF generation

A Playwright script navigates to the document URL, waits for Mermaid diagrams to render, and exports to PDF with print styles applied. Best for CI/CD or batch generation.

Lessons Learned

  1. Mono-accent is enough. We started with three accent colors (Copper, Sage, Blue) and it was too noisy. One accent + neutral zinc scale handles every use case — status, emphasis, links, callouts — without visual competition.
  2. Body font matters more than heading font. You spend 90% of reading time in body text. Swapping from JetBrains Mono to DM Sans for body had more impact than any heading change.
  3. Mermaid theming is fragile. Theme variables don't reliably propagate to sequence diagrams. CSS !important overrides on SVG elements are the only reliable approach.
  4. Print CSS is easy to forget. The Doppelrand shell looks great on screen but terrible on paper. @media print must strip it completely — no border-radius, no shadows, no noise overlay.
  5. Constraints beat templates. A well-specified DESIGN.md produces more consistent output than a rigid HTML template, because the agent can adapt the structure to the content while respecting the visual rules.
A design system for agents isn't about making things pretty — it's about making things predictable. The agent should never need to make an aesthetic decision. Every visual choice should already be answered by the constraints.
design-system agent-skills document-generation copper-docs