design-system
Every site in the estate that renders HTML consumes the
@dunn.dev/reference package for its visual tokens and page chrome.
Vendoring is the failure mode this standard closes: a copied
tokens.css drifts the moment the published one moves, and the estate
stops reading as one body of work.
The package is published from gitlab.com/dunn.dev/reference; see its
package.json exports field for the current set of importable paths.
What the tokens contain and the visual language they carry live on the
design pages: Foundation,
Colors, Typography,
Diagrams, Talks, Lessons,
Repository.
What this standard checks
Generated from ./check.sh, in the order the check
runs them.
| assertion | target | pattern or value | note |
|---|---|---|---|
| applies at all, or stops the run | astro.config.* or global.css or site.css or index.html |
a repo with no web surface has no chrome to import tokens into, and a hand-written waiver per assertion says the wrong thing for a repo shape that repeats across the estate; governs repos that render a web surface | |
| some file matches | global.css |
^([^/]|/[^*])*@import.*@?dunn\.dev/reference/tokens |
a vendored copy of the palette stops tracking the estate the moment a token changes; a talk imports them from its talk.css, through the package copied to dunn.dev/reference/, a Vite lesson from src/styles.css; any file of that name in the repo, or matching talk.css or styles.css; build dirs skipped |
| some file matches | package.json |
"@dunn\.dev/reference" |
an import with no dependency behind it builds from a stale local tree and breaks in CI; any file of that name in the repo, build dirs skipped |
How to satisfy
Three edits anywhere in the project. The check is layout-agnostic: put
them where the build picks them up, whether web sources sit at the repo
root, under site/, or under web/.
Add the dep to
package.json:"@dunn.dev/reference": "X.Y.Z"And add an
.npmrcbeside it pointing at GitLab's project npm registry forgitlab.com/dunn.dev/reference(project ID82110648):@dunn.dev:registry=https://gitlab.com/api/v4/projects/82110648/packages/npm/The URL must use the numeric project ID. The URL-encoded path form (
dunn.dev%2Freference) works for most GitLab REST calls and 404s on/packages/npm/<name>specifically. The registry serves anonymous reads, so no token is needed fornpm install, in CI or locally.Import the tokens from whichever
global.cssis the project's primary stylesheet, creating one and importing it from the Astro layout if there isn't one yet:@import '@dunn.dev/reference/tokens/index.css';A project site must import the chrome too (canonical header, footer, page and hero patterns):
@import '@dunn.dev/reference/site.css';site.cssowns the layout: header, page and footer share one frame (--frame) and one inline padding (--pad), and the page is a single track that width. A row is a.split(prose capped at--measure, a visual beside it), a.flowof balanced prose columns, or a full-track grid. Do not cap prose with a localmax-width, redefine these tokens, or copy a sidebar grid. The mark lives in the header only;.herocarries none. An Astro site takes that markup from@dunn.dev/reference/chrome/*(ProjectLayoutand the row components) instead of writing its own layout. Scroll motion is CSS only:.scroll-progress, and.diagram-trackstepping a figure's marks by opacity, inside@supportsfor scroll timelines andprefers-reduced-motion: no-preference.A lesson site, a Vite app with a single
styles.css, imports the tokens there and@dunn.dev/reference/lesson/lesson.cssafter them instead ofsite.css; see Lessons.Caution on
site.css: it styles.hero,.brand-name,.section-prose,.site-header,.eyebrow, markdown inside.page articleand other generic class names. A site that already styles those classes with different semantics gets collisions. Rename the local classes. A bespoke site that brings its own chrome records a reasoned deviation in.deviations.yaml.Caution on Astro's default HTML compression: it collapses the whitespace before an inline element, so a sentence built as
via the<code>x</code>loses its space in the rendered page. SetcompressHTML: falseinastro.config.*for any prose that mixes plain text with inline tags this way.Delete any
:root { --bg: ...; ... }block the tokens now provide. A vendoredtokens.cssis the pattern this standard exists to close. Delete that file outright once the import is in place; every rule that referenced its variables resolves against the package's../templates/global.cssis the minimum pattern.A talk, a plain
index.htmlwith no Astro, links the talk chrome and imports the motion tokens from its owntalk.css, which the check reads in place ofglobal.css. The install step copies the package todunn.dev/reference/, dropping only the@:@import "./dunn.dev/reference/tokens/motion.css";Audit the rest of
global.css. Any rule redefining a token the package publishes should be deleted. Site-specific patterns (a.skill-zoneclass, a curriculum layout grid) stay.
Verification
A touched page is done when it shows none of these at 1280px and at 375px:
- Text-on-text overlap.
- Text-on-line overlap, worst near arrowheads.
- Geometric overlap: a path routing through a box.
- A stray
<p>beside a diagram, which is the markdown processor breaking the SVG. - Nav clipping at 375px.
- At 1280px, the header inner, the footer inner and every row under
.page-contentend within 1px of each other on the right, and in each.splitthe aside ends at the track edge. Prose lines stay at or under 75 characters. - At 1280px and 375px, with
prefers-reduced-motion: reduce, everydata-stepmark in a.diagramis at opacity 1 and everydata-untilmark at 0. - A
layout-shiftobserver sums to 0 over a full scripted scroll at both widths. - At 375px, horizontal scroll.
Deviations
A project with no web surface is not applicable: a pure Go CLI ships
no Astro config, no global.css, no site.css and no index.html,
and the contract exits N/A before either assertion runs. No deviation
entry needed. A deviation is for a project the contract does govern
that legitimately fails one of its assertions anyway; see
Deviations for the format.
What this standard does NOT cover
- Token-by-token enforcement. The assertions are that the imports
exist, not that every CSS value resolves to a published token. A
--my-bespoke-color: #ff0000in acolor:rule still passes. - The visual language itself. Palette, type, diagram conventions, brand artifacts and the stack's traps are on the design pages linked above. This standard asserts only that a site consumes them from the package rather than keeping its own copy.
See ./check.sh for the executable assertions.
curl https://reference.dunn.dev/standards/design-system/index.md
check conformance
just -f ~/gitlab.com/dunn.dev/reference/justfile check