Labs · SVG cookbook

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.

Tokens

The shared vocabulary.

Reach for these variables — paper/ink for surfaces, status-* for compare tints, orange-* for emphasis, mono for labels.

--paperMain canvas
--paper-raisedCards on paper
--paper-darkerSubtle wells
--inkPrimary text / fills
--ink-60Body copy
--ink-15Hairline borders
--orange-500Brand emphasis
--orange-50Emphasis tint
--status-healthyGood
--status-warnCaution
--status-failBad
--status-infoNeutral signal
Stroke. Hairlines are 0.5px ink-15 borders or 1px ink-50 SVG strokes. Animated dashed strokes use stroke-dasharray: 4 4 with the fig-flow keyframe.
Type. --font-sans (Geist) for titles + body, --font-mono (Geist Mono) for bracketed mono labels.
Corners. Near-square: 2px for inner cards, 4px for outer frames. No pills, no soft radii.
Frame

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.

Frontend loop

Use the app like a customer.

Click through, find odd parts, fix and repeat.

your illustration here
<Figure
  tag="Frontend loop"
  title="Use the app like a customer."
  caption="Click through, find odd parts, fix and repeat."
>
  {/* your illustration here */}
</Figure>
Funnel

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.

100%FetchedAPI budgetrate-limit, page size98%Parsed94%ValidatedSchema driftunknown fields, nulls60%Diffed92%UpsertedWrite contentionconcurrent hooks99%AckedCheckpoint healthresume safety
<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>
Matrix

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.

Low volume
High volume
Near-real-time
Hook-drivenFew records, fresh on changeSubscribe to webhooks; Worker writes the diff straight to your store.
Hook + queueMany records, fresh on changeHooks fan into a Queue; consumer applies updates idempotently.
Batch / nightly
Cron syncFew records, OK to lagScheduled Worker pulls a delta; small enough to fit in one run.
Cursor syncMany records, OK to lagResumable cursor + Durable Object for backpressure; chunked writes.
<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. */
Compare

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.

Cowboy deploys
Untracked bundle.Local CLI → prod. No artifact, no rollback, no diff.
Promotion gates
Stage 1
Dev test account
Stage 2
Shared staging
Stage 3
Canary portal
Stage 4
Production
Attested artifact.Signed bundle promoted across portals. One rollback target.
<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. */
Callout

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.

Step 3fix and repeat
One change at a time.Ship the smallest useful improvement before grading the next one.
<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>
Badges

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" />
Steps

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.

01
test the app
click through the real flow
02
find odd parts
confusing copy, dead ends
03
fix and repeat
ship the smallest useful improvement
repeat the flow
<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" />