Avatar

256 × 256 viewBox. Metaphorical glyph; reads at favicon and avatar scale.

project one-line tagline a one-line summary of the output a half-line of meta

Hero

1200 × 430 viewBox. Big title left, embedded metaphor below it, four fact tiles right.

PROJECT · ONE-LINE TAGLINE YEAR project first line of tagline; what the project is or does in one breath. second line of tagline; the trade-off you're taking on. one tagline, used here and on the avatar. FLOW DISCIPLINE IN big phrase subtitle that grounds the big word SPEC LINE · ONE OR TWO TERMS POSTURE big word how the project behaves A NEGATION OR GUARANTEE OUT big word what comes out SHAPE OR FORMAT OF THE OUTPUT LIFETIME big word how it stays good over time A STABILITY GUARANTEE TERRITORY · TAG · TAG · TAG · TAG LICENSE · GITLAB.COM/DUNN.DEV/PROJECT

Skill language

The rules, stated tersely. Lift the templates, replace the placeholders, keep the rest.

Two artifacts, two voices

Avatar answers what is this like? with a metaphor. Hero answers what does this promise? with principles. Don't mix: a flow diagram in the avatar or a metaphorical hero is the failure mode.

The metaphor goes in both

GitHub strips the repo avatar, so the hero embeds an elaborated version of the same glyph beneath the title. The hero version has more endpoints, more lines, more density; it's the avatar with room to breathe.

One tagline, two surfaces

The italic line on the hero (under the title) and the muted tagline on the avatar (under the title) are the same phrase. It's a tagline, not a stage direction — evocative about the project's posture, not a literal description of the visual ("a basket catching the day's photographs as they fall from the feed" is the failure mode; "collected moments of early learning" is the right register).

One phrase across both artifacts keeps the brand coherent on the two surfaces a viewer hits (avatar in the repo header, hero in the README). Pick a phrase that fits the avatar's narrower budget — the hero has more room than it'll ever need.

Character budgets

The viewBoxes are fixed; SVG text doesn't wrap. Overflow looks unprofessional and hides content. Treat these as the worst-they-still-fit ceilings:

FieldWhereBudget
titleavatar + hero~10 chars (one short word)
taglineavatar + hero italic~36 chars
title sub-linehero, two lines~70 chars per line
top metadatahero, mono caps~58 chars
tile big wordhero, font-size 34~12 chars
tile subtitlehero, font-size 11~46 chars
tile spec linehero, mono caps~30 chars
territory tagshero bottom-left~38 chars
output lineavatar, font-size 9~50 chars

Always render the SVG at canvas size (avatar 256, hero 1200) before shipping, and look for text that crosses a tile edge or runs into a divider line. Then look at it as a 3× PNG (avatar 768, hero 3600) — the PNG is what social cards and external embeds will actually display, and some overflow is only obvious there.

Glyph stays in its band

The hero metaphor mark sits in y 230-380 (150 actual units; ~75 local at the template's scale(2)). The bottom rule line at y 386 is hard — a glyph that overlaps it looks like a layout bug. If a glyph won't fit at scale(2), drop a row of elements before scaling down: a less-full layout reads as "the project's still small / still growing," which is usually on-brand. Scaling below 1.7 makes the strokes too thin against the canvas.

The avatar glyph sits in y 90-200 (110 units) at scale(1). Similar discipline: photo + caption + a binding line beats four photos crammed in.

Token whitelist

Every fill and stroke comes from a published semantic token. The hero uses --surface for its canvas so white tile fills pop; the avatar uses --bg for cool-white card framing.

TokenHexUse
--bg#ffffffavatar canvas, hero tile fill
--surface#f4f4f4hero canvas, renderer-circle fill on hero
--border#e0e0e0avatar outer border, hero dividers and tile borders
--text-muted#707070mono small caps, captions, subtitles, response lines
--text-2#404040body copy, taglines
--text#0a0a0aglyph strokes, output line
--accent#4a6741title, big tile word, primary stroke

Type

Avatar uses the system stack (Helvetica, Arial, sans-serif) so the SVG renders the same in terminals, GitLab repo headers, and social cards where IBM Plex isn't loaded. Hero uses IBM Plex Sans, Helvetica, Arial, sans-serif with mono (IBM Plex Mono, Menlo, monospace) for small-caps headers and spec lines. Plex renders where it's loaded; system falls in everywhere else.

Lines start and end at edges

Connecting lines start at the conductor's edge and end at the renderer's edge — never pass through circle centres. When the metaphor has both call and response, draw them as parallel lanes (perpendicular offset, same magnitude on both ends), not converging on the same point.

Tile content

Each of the four hero tiles carries four layers: a small-caps mono label, a big bold moss word, a body subtitle that grounds the word, and a small mono spec line at the bottom. Top row covers flow (in / out), bottom row covers discipline (posture / lifetime). The pattern is fixed; the labels can vary per project.

Territory tags

The bottom-left dotted line carries territory tags: stable concepts that say what kind of project this is. Domain words (audio, auth), form words (cli, library), protocol names when they're stable and central (UPnP, OAuth).

What doesn't go here: language names, library names, framework names, version numbers, LOC counts, file counts, CLI flag names. Anything that might be renamed or swapped is a maintenance detail and lives in the repo's badge row, not in the brand.

Required attributes

  • role="img" on the <svg> root.
  • Non-empty aria-label describing the diagram in a sentence.
  • Outer <rect> filling the canvas with paper (avatar) or paper-warm (hero), so the artwork carries its own background.
  • font-family set on both the <svg> and the wrapping <g> so it inherits everywhere.
  • <defs> marker IDs prefixed with the repo slug to avoid collisions when SVGs are inlined together.

Generation

avatar.png is derived from avatar.svg via rsvg-convert -w 256 -h 256. brand.png is derived by stacking the avatar (rendered at 800×800, padded to 1600×800 on a surface canvas) above the hero (rendered at 1600×573), with a 24px surface border around the whole thing. The hero stays SVG-only; GitHub renders SVG natively.

Each repo's Makefile adds a brand target that regenerates both PNGs. Run it after editing either SVG.

Files

Lift, rename, replace placeholders.