Reference

Styleguide

Contrast ratios are measured against the page colour of the scheme they belong to, light first. Nothing here should ever need a value outside the scales.

The page is cream, never white. Pure white next to #FDF9F3 reads as a rendering bug, so the surface token resolves to cream in the light scheme and to ink in the dark one. Body text is ink on cream at 12.9:1, which clears AAA with room to spare, and the column is capped at 720px so a line lands between 68 and 72 characters at the desktop body size.

Editorial layout, generous whitespace, one column of readable text. No cards-in-cards, no gradients, no shadow deeper than a hairline.

Colour

Body links use the darkened signal blue at 5.4:1, never the raw brand blue, which measures 4.1:1 and fails. They are underlined as well as coloured, because colour alone is not an affordance. Raw orange is a fill, never text on cream.

The home hero lays the page colour over the mascot artwork at--scrim-opacity — 72% in the light scheme, 86% in the dark one. Measured against composited output across viewport widths, body text stays above 6.5:1 in both schemes.

Type scale

  • Two families: Inter for everything, the platform mono for code.
  • Body 18px on mobile, 20px from 768px up.
  • Line height 1.65 for body, 1.2 for headings.
  • One breakpoint, declared in em so it survives page zoom.

Spacing scale

Vertical space comes from one scale: 4, 8, 12, 16, 24, 32, 48, 64, 96. Paragraphs are separated by 24px, a heading opens with 64px above it, and the footer sits 96px below the last block. Nothing is nudged by an odd pixel.

States

Buttons

PrimaryGhost

Tab to each. Hover each. The primary label is ink on raw pulse at 4.2:1, which holds because it is never smaller than 25px — large text at any weight, 3:1 floor. Weight is not part of the guarantee: before the webfont arrives the label renders in whatever bold face the reader's machine has, or in none. Hover darkens the fill to --pulse-700 and flips the label to cream at 5.1:1.

Links

A default link, and the same link after you hover it. Tab through this paragraph to see the focus ring: 2px solid --focusat 2px offset, which clears the 3:1 non-text floor on both the page and the sunken surface.

Components

TagPill

astro design-systems 4 postsaccessibility TypeScriptMarkdown

Link, link with count, aria-current="page", then two static chips. Hover and tab each. Both forms share one box, so a stack badge and a tag link never differ in size. The count is announced as "design-systems 4 posts".

PostCard

6 min read

A post with tags

The card is an editorial entry, not a box: one hairline above it and nothing else.

ProjectCard

In progress

An in-progress project

Status, title, one-line pitch, stack badges. Only the title is interactive.

  • Astro
  • TypeScript
  • CSS

Shipped

A shipped project

A longer pitch, here to show that the badges still land on the same baseline as the card beside it.

  • Markdown

Pagination

A missing neighbour omits its cell rather than greying out a link. At one page the component renders nothing at all, which is why there is no fourth example.

Breadcrumb

Prose

Inline code such as --space-24 sits on a sunken surface at 11.6:1. A block runs to the gutter edges below the breakpoint rather than squeezing an already narrow column, and scrolls horizontally when it has to.

A second-level heading

Body copy at the current breakpoint's size, 1.65 line height, capped at the 720px column so the measure stays readable.

A third-level heading

  • List item with a --token in it.
  • A second item, 8px below the first.

A quote, marked by a 3px rule in the signal blue.

--space-24: 1.5rem;