Draw it. Don’t configure it.
HS-X illustrations are hand-authored SVG. Every figure is the exact shape it needs to be — no <Funnel stages={[…]} /> shortcut, no generic chart component. This page is the cookbook: tokens, patterns, and copy-paste recipes that share the same visual language across blog, guides, and docs.
The shared vocabulary.
Reach for these variables — paper/ink for surfaces, status-* for compare tints, orange-* for emphasis, mono for labels.
0.5px ink-15 borders or 1px ink-50 SVG strokes. Animated dashed strokes use stroke-dasharray: 4 4 with the fig-flow keyframe.--font-sans (Geist) for titles + body, --font-mono (Geist Mono) for bracketed mono labels.2px for inner cards, 4px for outer frames. No pills, no soft radii.The editorial chrome.
Every illustration sits inside <Figure>. It provides the tag pill, bold title, caption, and the outer paper-raised frame. Author the inside freely.
Use the app like a customer.
Click through, find odd parts, fix and repeat.
<Figure
tag="Frontend loop"
title="Use the app like a customer."
caption="Click through, find odd parts, fix and repeat."
>
{/* your illustration here */}
</Figure>Trapezoidal stages with dashed callouts.
One inline SVG. Each stage is a polygon with explicit corner coordinates. Tweak the inset (e.g. 12px) to control how aggressively it tapers. Dashed leader lines pull annotations out to the right.
<svg viewBox="0 0 800 360" width="100%">
<defs>
<style>{`
.name { font: 600 14px var(--font-sans); fill: var(--fig-ink); }
.pct { font: 500 13px var(--font-mono); fill: var(--ink-60); }
.dash { stroke: var(--ink-40); stroke-dasharray: 4 4; fill: none; }
`}</style>
</defs>
{/* one stage: tone class drives --fig-tint / --fig-edge / --fig-ink */}
<g className="fig-tone-info">
<text className="pct" x="64" y="32" textAnchor="end">100%</text>
{/* trapezoid: top wider than bottom by inset on each side */}
<polygon
points="120,0 640,0 630,56 130,56"
fill="var(--fig-tint)"
stroke="var(--fig-edge)"
vectorEffect="non-scaling-stroke"
/>
<text className="name" x="380" y="33" textAnchor="middle">Fetched</text>
{/* dashed leader + annotation */}
<path className="dash" d="M 646 28 H 660" />
<text x="668" y="26">API budget</text>
<text x="668" y="42" className="sub">rate-limit, page size</text>
</g>
{/* repeat for each stage; narrow the trapezoid width per row */}
</svg>A 2×2 decision grid.
Layout-only — pure CSS grid. Each cell is a paper card with a tone-tinted left rail. The rail color comes from --fig-ink via the .fig-tone-* class. Row and column headers sit on dashed paper to read as axes.
<div className="matrix">
<div /> {/* corner, intentionally empty */}
<div className="matrix-col">Low volume</div>
<div className="matrix-col">High volume</div>
<div className="matrix-row">Near-real-time</div>
<div className="matrix-cell tone-success">
<span className="matrix-cell-tag">Hook-driven</span>
<strong>Few records, fresh on change</strong>
<span>Subscribe to webhooks; Worker writes the diff…</span>
</div>
<div className="matrix-cell">
{/* … */}
</div>
{/* repeat for second row */}
</div>
/* CSS:
.matrix is grid-template-columns: 132px 1fr 1fr.
.matrix-col / .matrix-row are mono-uppercase eyebrow labels —
no panel chrome, just the axis vocabulary.
.matrix-cell is paper-raised with a hairline border.
Tone signal lives inside the cell on <Figure.Chip>, not on the cell. */Good vs bad, side by side.
Two tone-tinted divs sharing a grid. Status glyph + title in each header. Inside, mix whatever primitives — cards, inline SVG, dots, icons — that the story needs.
<div className="compare">
<div className="compare-side fig-tone-danger">
<header>
<Figure.Status kind="cross" tone="danger" />
<span>Cowboy deploys</span>
</header>
{/* fan-out: an envelope rect at top, six dashed lines to dots below */}
<svg viewBox="0 0 200 120" width="100%">
<rect x="78" y="6" width="44" height="32" rx="2"
fill="var(--paper-raised)" stroke="var(--status-fail)" />
<path d="M82 18 L100 28 L118 18" stroke="var(--status-fail)" fill="none" />
{[28,60,92,124,156,172].map((x,i)=>(
<line key={i} x1="100" y1="40" x2={x} y2="90"
stroke="var(--status-fail)" strokeDasharray="3 3" opacity="0.7" />
))}
{/* …terminal dots */}
</svg>
</div>
<div className="compare-side fig-tone-success">
{/* Stage 1..4: grid of small cards with envelope icon + dots */}
</div>
</div>
/* CSS: .compare is grid-template-columns: 1fr 1fr.
.compare-side uses var(--fig-tint) / var(--fig-edge) background+border. */A dashed leader pointing at something.
A 1px dashed segment + a small L-bend, then a sans label. Use it anywhere you’d otherwise reach for a tooltip — beside a funnel stage, a diagram node, a step card.
<div className="callout">
<div className="target">{/* the thing being annotated */}</div>
<svg viewBox="0 0 160 60" width="160" height="60">
{/* horizontal leader + small L-bend up */}
<path d="M 0 30 L 50 30 L 50 20"
fill="none"
stroke="var(--ink-40)"
stroke-dasharray="4 4" />
</svg>
<div className="body">
<strong>One change at a time.</strong>
<span>Ship the smallest improvement before grading the next.</span>
</div>
</div>Status circles, dot counts, and inline icons.
These are the only pre-built atoms — small enough to stay flexible. <Figure.Status>, <Figure.Dots>, and <Figure.Icon> all honor the fig-tone-* vocabulary.
<Figure.Status kind="check" tone="success" />
<Figure.Status kind="cross" tone="danger" />
<Figure.Status kind="dot" tone="warning" />
<Figure.Dots count={3} tone="warning" />
<Figure.Dots count={5} tone="emphasis" />
<Figure.Icon name="envelope" tone="emphasis" />
<Figure.Icon name="target" tone="info" />
<Figure.Icon name="alert" tone="danger" />A numbered process with a loop-back.
<Figure.Row> distributes Step cards evenly. <Figure.Arrow> threads dashed connectors between them. <Figure.Loop> draws the return curve underneath; tone='emphasis' fills the final step with ink.
<Figure.Row gap="md">
<Figure.Step n={1} title="test the app" caption="click through the real flow" />
<Figure.Arrow />
<Figure.Step n={2} title="find odd parts" caption="confusing copy, dead ends" />
<Figure.Arrow />
<Figure.Step n={3} title="fix and repeat" caption="ship the smallest improvement" tone="emphasis" />
</Figure.Row>
<Figure.Loop label="repeat the flow" />