Foundations

Twelve focused cards, one concern each

Each card links ../colors_and_type.css and renders the real tokens, real components and real preserved asset files — no screenshots, no redrawn marks. Start with the dark canvas if you are new to the system; it explains why everything else looks the way it does. Full rules live in DESIGN.md.

Tokens & assets

The foundation: what the colours, type, spacing and radii are, and the real asset files that ship with them.

Color 1/3

Primary & the brand ramp

The action violet, the reserved cyan, all 24 ramp steps and the error ramp, each labelled with its job.

colors-primary.html
Color 2/3

The dark canvas

Four surface steps one hair apart, the foreground ramp with contrast ratios, and cards in situ. The system’s defining decision.

colors-theme-dark.html
Color 3/3

Light-surface exceptions

The three — and only three — light surfaces that exist, plus why no light theme may be derived.

colors-theme-light.html
Typography

Satoshi specimens

Real cuts from fonts/, the nine-step scale at true size, and the eyebrow signature with a counter-example.

typography-specimens.html
Spacing 1/3

Gutters & rhythm

Container gutters, the asymmetric 200/120 section rhythm, bottom-heavy card padding and the two control heights.

spacing-tokens.html
Spacing 2/3

Radius census

Eight steps at true size, the measured homepage census, and what the same card looks like at 4px.

spacing-radius.html
Spacing 3/3

The inverted glow

Violet light thrown upward, side by side with the conventional drop shadow that destroys it. Plus the CTA and input halos.

spacing-shadows.html
Assets

Brand assets

Every wordmark, glyph, favicon and app icon loaded from the real preserved files in build/ and assets/.

brand-assets.html
Imagery

Decorative art

The line-and-glow layer — seven stroke-only section backgrounds, the opacity ladder that makes the falloff, and the two ramp steps they were hiding.

brand-imagery.html

CSS components

The class layer that sits on those tokens — .btn, .field, .checkbox, .chip, .rule and the rest, all defined directly in ../colors_and_type.css. You write these as plain HTML: <button class="btn btn-primary">, one stylesheet, nothing to import and no framework. Primitives, further down this page, is the same design delivered a second way — as Vue components. Why both exist is explained where the two halves meet.

Components 1/3

Buttons

Eight variants with rest, hover, active, focus and disabled shown together, and the one sanctioned CTA pairing.

components-buttons.html
Components 2/3

Inputs

Floating-label field in five states, textarea, both checkbox variants, and the assembled consultation form.

components-inputs.html
Components 3/3

Rule & progress

The gradient line carried forward from the previous docs site — as a masthead accent, as a determinate bar, and three ways to break it.

components-progress.html

Two deliveries of one design

Everything above is CSS. Everything below is Vue. They are not two levels of one stack and neither is built on the other — they are the same design shipped twice, for two kinds of consumer, and they meet at the tokens and nowhere above them.

 CSS componentsPrimitives
What you write <button class="btn btn-primary"> <Button variant="primary" />
Where it is defined colors_and_type.css — one stylesheet .vue sources, compiled into the package
What it needs a <link>, and nothing else Vue 3, plus Tailwind told to scan the package
What it can express appearance and the states CSS can reach: :hover, :focus-visible, :disabled, :checked all of that, plus props, slots, v-model, the <a>-or-<button> decision, and a glow that follows the cursor
Where it works anywhere HTML does — an email, a Rails or Django template, a CMS theme, a static page a Vue application

They meet at the tokens, and only there. <Button> does not render .btn. It emits Tailwind utilities — bg-primary-500, min-h-12, rounded-full — which resolve through theme.css to the same custom properties .btn reads. Change a token and both move. Change .btn and only the CSS layer moves.

That independence is the point rather than an oversight. A Vue component that rendered .btn would drag the whole stylesheet into every consumer’s bundle, and a class layer that needed Vue would be useless in an email — which is exactly where two of the six artifacts live.

The cost is drift, and it is worth knowing before you edit either one. Because nothing connects them above the token layer, a fix applied to one does not reach the other, and nothing fails when they disagree. GlowButton is that showing: it renders a 44px control against the 48px --control-height every button in the CSS layer uses. If you change a control’s shape, check the other delivery.

Which to use. In a Vue application, the primitive — it carries behaviour the class layer cannot. Anywhere else, the class. Do not put both on one element: the utilities and .btn are all single-class selectors, so which wins comes down to stylesheet order, and neither layer promises one.

Both surfaces prove parts. ../examples/ proves they compose — a pitch deck, a contact form, two emails, a landing page and a print poster, each a single self-contained file carrying real density.

Open the examples

Live components

13 components, extracted from codecave.pro

Twelve of the thirteen stories mount the real components — the verbatim .vue sources compiled by tools/build-storybook.mjs and rendered by the vendored Vue and GSAP runtimes against the site's own Tailwind theme (docs/tailwind.css, compiled per page by Vite). The thumbnails below are those same mounts, miniaturized. The one .astro component is a hand-translated HTML port, and every gap between this storybook and production is written down on its page.

12 live Vue mounts 1 Astro port (HTML) Astro 7 · Vue 3.5 · Tailwind 4.1

Primitives

The reusable controls, as Vue. Everything else on the site is built from these — and each has a counterpart in CSS components above, which is the same design without the framework. Two deliveries of one design explains why both ship.

Content

Cards and blocks. Each takes the fields it reads as a prop, so the content can come from any CMS — or from nothing at all.

Compositions

Not primitives — assemblies worth documenting because they define styling that lives nowhere else.

What this storybook found

54 findings across the thirteen components — 28 flagged as defects, 26 as design observations — each recorded on its own story page. The four that would change behavior in production:

Two components animate against a variable they never define. Checkbox.vue:75 and Radio.vue:61 both declare transition: var(--default-transition-duration) transform ease-in-out;, and --default-transition-duration appears nowhere in the project's own code. It resolves anyway — to 150ms from Tailwind's default theme, which the build emits because transition-colors is in use. Lift either component out of a Tailwind build and the shorthand collapses, snapping the indicator instead of easing it.

Button's isDisabled does not disable anything. It sets opacity and a cursor. The disabled attribute is never bound, so the control stays clickable and keyboard-reachable — and as a link it still navigates.

TextField syncs its model on change, not input. The parent's v-model only updates on blur, while InputText in the same form updates per keystroke.

Two dead styles. Radio's secondary hover needs a group ancestor that nothing renders, and Button's type prop is declared but never bound.