{
  "id": "v1-nb-6535",
  "long_id": "v1.neubrutalism.blog.s06.p05.t03.u05",
  "name": "Neubrutalism personal page (2021 to 2026)",
  "era": {
    "slug": "neubrutalism",
    "code": "nb",
    "name": "Neubrutalism",
    "years": [
      2021,
      2026
    ],
    "description": "Loud and flat, 2021 to 2026: thick black outlines, hard offset shadows with no blur, saturated colour blocks and bold type."
  },
  "archetype": "blog",
  "mode": "mix",
  "viewport": {
    "width": 1440,
    "fluid": true,
    "responsive": true
  },
  "summary": "A creator's own page in the neubrutalist look: a centred masthead, a profile card with a tilted portrait, and a stack of big outlined link buttons, every box on a hard, unblurred shadow over a flat coloured page. It was common from about 2021 to 2026 for link-in-bio pages, portfolios of illustrators and developers and the small sites of one-person studios. Boxes stand free on the page colour in one centred column; nothing is full-bleed except the masthead and the footer.",
  "url": "https://chrono.skin/s/v1-nb-6535",
  "preview_url": "https://chrono.skin/s/v1-nb-6535/specimen.html",
  "files": {
    "STYLE.md": "# Neubrutalism personal page (2021 to 2026)\n\n## Summary\n\nA creator's own page in the neubrutalist look: a centred masthead, a profile card with a tilted portrait, and a stack of big outlined link buttons, every box on a hard, unblurred shadow over a flat coloured page. It was common from about 2021 to 2026 for link-in-bio pages, portfolios of illustrators and developers and the small sites of one-person studios. Boxes stand free on the page colour in one centred column; nothing is full-bleed except the masthead and the footer.\n\n## Layout\n\n- The page is fluid: `--size-page` is 100%, but the content is one centred column of `--size-content` (1080px) with `--space-gutter` (24px) at the sides. Designed at a 1440px viewport, where the page colour shows as wide margins left and right of the column.\n- The masthead (`.ds-nav`) is centred and stacked: a `--fill-bar-alt` announcement line, then on `--fill-bar` the brand (mark tilted 6 degrees, name at 28px) over a centred row of link chips, closed by a `--border-width-strong` rule. There is no button in the masthead.\n- The home page is a `.ds-home` grid: a `--size-profile` (384px) column with the profile card (`.ds-hero`) and the stat box under it, and a wide column with the `.ds-linkstack`, then two equal columns for a short list and a panel. Columns are `--space-7` (32px) apart, blocks inside a column `--space-6` (24px).\n- Inner pages keep the masthead and the footer and drop the profile card, the stats and the link stack. They start with a centred `.ds-page-header`: the breadcrumb, a 40px title, one line of description of at most `--size-measure` (600px) and at most one button, all centred. Below it, blocks stack `--space-7` apart in the same column: a gallery page has the `.ds-tabs` bar centred, the three-column `.ds-grid`, a key of labels and centred pagination; an article page is a `.ds-split` (the text on a `.ds-sheet`, a `--size-profile` side column with a `.ds-sidebar` and a panel); a form page is `.ds-split--even` with notices above it.\n- Spacing scale: `--space-1` 4px (underline offset, brand tile padding), `--space-2` 8px (badge padding, gap between masthead chips, label to control), `--space-3` 12px (gap between list rows, row padding, gap between stacked buttons), `--space-4` 16px (panel and card padding, gap between buttons and fields), `--space-5` 20px (gap between link buttons, sidebar padding), `--space-6` 24px (gap inside a column, profile card padding, grid column gap), `--space-7` 32px (gap between columns and between the blocks of a page, grid row gap, sheet and sign-up padding), `--space-8` 48px (top padding of the column, footer padding, overlay padding), `--space-9` 72px (bottom padding of the column).\n- Movement tokens: `--space-nudge` 2px (hover offset, focus outline offset) and `--space-press` 4px (pressed offset, offset of the red shadow under an invalid field). Hover and press move a control straight down, never sideways, so the movement is right whichever way the surface set throws its shadows.\n- Fixed sizes: `--size-control` 44px (buttons, inputs, tab segments), `--size-control-large` 54px (the main button of the profile card), `--size-control-small` 34px (masthead chips, small buttons, pagination), `--size-logo` 36px, `--size-icon` 44px (icon tile of a link button), `--size-link` 84px (least height of a link button), `--size-portrait` 152px, `--size-art` 148px (picture of a project card), `--size-check` 20px, `--size-dialog` 440px.\n- Below 900px every two-column arrangement stacks (profile card first, then the link stack) and the grid drops to two columns. Below 600px the grid and form rows are one column, masthead chips shrink and wrap, titles step down, the page header button fills the width, the tab bar fills the width and scrolls inside itself, the sign-up field and button stack, list rows and notices stack, and table columns marked `.ds-table__extra` are hidden so a table never scrolls sideways. On a phone (600px and below) the links `.ds-nav__links` are not shown; the \"Menu\" button `.ds-nav__fold` beside the brand opens a full-width list of every view as `.ds-menu__link--view` rows, the current one filled with the accent and barred on the left.\n- Views: the specimen is one example site, the page of a map illustrator, with five views switched by plain `#name` links. `home` is the link-in-bio page (profile card, three figures, four link buttons, recent news beside a \"now\" panel). `work` is the portfolio (page header with the breadcrumb, tabs, six project cards, the key of labels, pagination). `project` is one project (the story on a sheet with further links, a facts sidebar and a panel). `hire` is the rates and enquiry page (notices, the rates table and a confirmation dialog beside the enquiry form with its buttons). `letter` is the newsletter (sign-up box, past letters, an empty slot for this month). The masthead marks the current view through `:has()` rules in `components.css`, one per view; `is-current` on a link does the same by hand.\n\n## Typography and colour roles\n\nThis style combines the parts of different styles of one era. Where a note below names a value that differs from `tokens.css`, the tokens are right.\n\n- `--color-page` and `--color-canvas` are pale blue #dcebfe; `--color-surface` is white #ffffff for the rail, cards, stat tiles, tables, lists and the sheet. A plain card stage and even table rows take the pale blue.\n- `--color-button`, `--color-surface-strong` and `--color-bar-alt` are blue #5294ff with black text: the primary button, the brand mark, the title strips of cards and dialogs, the highlight behind a hovered link.\n- `--color-accent` is green #05e17a with black text: the current navigation item, rail link, filter chip and page, and the default badge. `--color-accent-alt` is yellow #facc00: the marked words of the intro title and \"new\" badges.\n- `--color-surface-alt` is sky #88c5ee: a hovered rail link, the empty state, the current table row, inline code.\n- `--color-fill-1` to `--color-fill-4` are blue #5294ff, green #05e17a, yellow #facc00 and lavender #b6ace4: the stages of demo cards whose content brings its own surface. Use each once before repeating.\n- Text, headings, every link colour, borders, focus and shadow are #000000; `--color-text-muted` #666666 (section notes, list meta, hints), `--color-border-muted` #b3b3b3 (the page grid). The navigation bar, the table head and the panel title (`--color-bar`) are white. The footer (`--color-inverse`) is black with white text.\n- Status: `--color-success` green #05e17a, `--color-warning` yellow #facc00, `--color-danger` red #dc341e, `--color-danger-surface` salmon #ee8888 behind an error notice, `--color-notice` lavender #b6ace4. All carry black text.\n- One grotesque sans for everything (`--font-body`, `--font-heading`, `--font-ui`: Public Sans, then DM Sans, Helvetica Neue); `--font-mono` for inline code, the command chip and class names in a table.\n- The whole page is heavy: `--weight-body` 500, `--weight-ui` 600 (navigation, rail links, chips, inputs, leads), `--weight-bold` 700 (buttons, labels, badges, the current rail link), `--weight-heading` 800 and `--weight-display` 900. Nothing is lighter than 500.\n- `--text-base` 16px at `--line-body` 1.5; `--text-small` 14px (rail headings, counts, notes, stat labels, table heads, list text, the footer); `--text-ui` 16px (navigation, rail links, chips, buttons, inputs); `--text-large` 24px for leads, the large button and the brand.\n- `--text-display` 72px at `--line-display` 1.1 for the intro title; `--text-h1` 48px (the inner page title, prose h1), `--text-h2` 36px (section titles, stat figures, prose h2), `--text-h3` 22px (card, panel, dialog and empty-state titles) at `--line-heading` 1.1. No tracking, no uppercase headings.\n- Uppercase is used only for the 12px `.ds-badge`. That size is `calc(var(--text-small) * 0.857)`; the vocabulary has no token for it.\n- Links in running text are underlined (`--link-decoration`) and lose the underline on hover (`--link-decoration-hover: none`), where the flat highlight replaces it; quiet links are never underlined.\n- `--border-width` is 3px on every box and rule; `--border-width-strong` 4px under the navigation.\n- All four radius tokens are 8px: buttons, inputs, cards, tiles, dialogs and badges share one rounded corner; badges are rounded rectangles, not pills.\n- Boxes that stand on the page sit on a second sheet, not a plain block: `--shadow-panel` is two hard shadows at the same `5px 5px` offset, a `--color-surface-strong` one on top and a `--color-shadow` one spread 3px behind it, so a filled, outlined copy of the box shows at its right and bottom edge like the next card in a stack. `--shadow-control` is the same at `4px 4px`, `--shadow-dialog` at `8px 8px`. No shadow is blurred. Filter chips and pagination squares carry the smaller `3px 3px` (`--shadow-control-hover`), as does a hovered button; a pressed one keeps `1px 1px` (`--shadow-control-pressed`). A box shown inside a card stage (the panel, the form box) has an outline but no shadow.\n- `--fill-page` draws a 70px grid of 1px lines (`--color-border-muted` at 50%) over the page colour; every other fill is flat.\n- `--focus-ring` is `3px solid` in `--color-focus`; `--transition` animates only `transform` and `box-shadow` over 0.2s.\n\n## Components\n\n- `.ds-page`: on `<body>`. Sets the flat page fill, the base font and colour. Its children are the `.ds-nav` masthead, `<main class=\"ds-main\">` and the `.ds-footer`; each view holds one `.ds-column`.\n- `.ds-brand`: the site's mark and name, centred at the top of the masthead and a link to the home page. `.ds-brand__mark` is a `--size-logo` tile dressed like the primary button (`--fill-button`, mark in `--color-button-text`, outline, `--radius-control`, `--shadow-control`) and tilted 6 degrees, so every palette and surface set reskins it. `.ds-brand__name` is the name in the heading font at `--text-h2`. The name `chronoskin` and its mark are placeholders for the installing project's own name and logo.\n- `.ds-nav`: the masthead. `.ds-nav__strip` is the announcement line with a `.ds-nav__strip-link`; `.ds-nav__bar` stacks the `.ds-brand` over `.ds-nav__links`, a centred wrapping row of `.ds-nav__link` chips. The current chip (`is-current`) is filled with the accent and outlined; `is-hover` shows the outline only.\n- `.ds-main`, `.ds-column`: the centred column and its stack of blocks. `.ds-home` is the home grid (profile column, wide column). `.ds-split` is a main column plus a 384px side column; `.ds-split--even` is two halves. `.ds-stack` stacks blocks 24px apart, `.ds-row` puts two things at the ends of a line, `.ds-label` is a 28px heading over a block without a title strip, `.ds-note` a muted small line.\n- `.ds-hero`: the profile card, one per site, on the home page: `.ds-hero__art` (a `--color-fill-1` field holding the `.ds-portrait`) over a rule, then `.ds-hero__text` with a status badge, `.ds-hero__title` at 32px, `.ds-hero__lead` and `.ds-hero__actions`, a column of one large primary button and one secondary button at full width. It stands on `--shadow-dialog`.\n- `.ds-portrait`: the avatar, drawn in CSS: a `--size-portrait` tile on `--color-accent-alt`, outlined, shadowed and tilted 5 degrees, with a `.ds-portrait__head` circle and a `.ds-portrait__body` shape on `--color-fill-3`. A project with a real photograph replaces the two inner spans with it and keeps the tile.\n- `.ds-stat`: the row of summary figures, one outlined, shadowed box of three `.ds-stat__cell` divided by vertical rules, each a 28px `.ds-stat__value` over a `.ds-stat__label`. It sits under the profile card.\n- `.ds-linkstack`: the stack of big link buttons, the main navigation of the home page. Each `.ds-linkstack__link` is an outlined, shadowed row at least `--size-link` tall, filled by `--1` to `--4` (white without a modifier): a round `.ds-linkstack__icon` tile with an inline SVG, `.ds-linkstack__main` with a `.ds-linkstack__title` and one `.ds-linkstack__text` line, and a `.ds-linkstack__arrow`. `is-hover` sinks it 2px and shortens its shadow. Four to six links; more belong on an inner page.\n- `.ds-page-header`: the centred head of an inner page: the `.ds-breadcrumb`, `.ds-page-header__title`, one `.ds-page-header__lead` and optionally `.ds-page-header__actions` with one button. No fill and no rule.\n- `.ds-grid`: project cards in three columns. Each `.ds-grid__cell` is an outlined, shadowed card: `.ds-grid__art` (a field `--size-art` tall, filled by `.ds-grid__cell--1` to `--4`, holding an inline SVG drawing in `currentColor`) over a rule, then `.ds-grid__body` with a `.ds-grid__title` link, a `.ds-grid__text` line and a `.ds-badges` row.\n- `.ds-prose`: long text: h1, h2, h3, p, ul, ol, strong, inline code (outlined, on `--color-surface-alt`) and links inside it are styled. On an article page it sits in a `.ds-sheet`, an outlined, shadowed card.\n- `.ds-link`: any link in content: underlined, weight 600. `.ds-link--quiet` removes the underline for titles and breadcrumbs. States `is-visited`, `is-hover`, `is-active`, `is-focus`. `.ds-links` lays several out in a wrapping row.\n- `.ds-button`: the primary button, a 44px pill, outlined, on `--shadow-control`. `.ds-button--secondary` is off-white. `.ds-button--danger` is the destructive action (clear a form): flat `--color-danger` with `--color-text`; use it once per view, at the end of a form's button row or as the confirming button of a dialog. `.ds-button--large` (54px, 19px text) for the profile card, `.ds-button--small` (34px, 13px text) inside panels and the empty state. `is-hover` sinks it 2px toward its shadow, `is-active` 4px with the pressed shadow, `is-disabled` is flat grey, `is-focus` adds the focus ring 2px away. `.ds-buttons` is a row of them.\n- `.ds-badge`: a small bold label in an outlined pill, on the accent by default. `.ds-badge--alt` yellow (new), `.ds-badge--plain` off-white (years, neutral facts). Status labels on project cards and in the sidebar: `.ds-badge--success` (prints available, open for commissions), `.ds-badge--warning` (few left), `.ds-badge--danger` (sold out), all with `--color-text`. No shadow. `.ds-badges` is a wrapping row; `.ds-badges--key` centres it as the key under a gallery.\n- `.ds-form`: stacked fields 16px apart; `.ds-form__row` puts two side by side. A `.ds-form__field` is a bold 13px `.ds-form__label` above a `.ds-form__control` (input, select; `.ds-form__control--area` for a textarea), then `.ds-form__hint` or `.ds-form__error`. Controls have the outline and no shadow at rest; `is-focus` adds `--shadow-control` and the focus ring, `is-invalid` turns the border to `--color-danger` and puts a red shadow straight under the field, `is-disabled` greys it. `.ds-form__check` wraps a `.ds-form__checkbox` and its text. `.ds-form__foot` is the button row over a rule.\n- `.ds-signup`: the newsletter box: outlined, on `--color-fill-2` and `--shadow-dialog`, a `.ds-label` and `.ds-signup__text` beside a `.ds-signup__form` whose `.ds-signup__line` holds one field and one button. One per page.\n- `.ds-table`: one outlined, shadowed box with a head row on `--color-surface-alt` and rows divided by rules; `is-current` on a row puts it on `--color-surface-strong` in bold. `.ds-table__num` right-aligns numbers; a cell with `.ds-table__extra` is dropped below 600px. Inside a `.ds-panel--flush` it loses its own outline and shadow and the panel is its frame.\n- `.ds-list`: separate rows, each `.ds-list__item` an outlined card on `--shadow-control`, 12px apart: a `.ds-list__main` block (bold `.ds-list__title`, a `.ds-list__text` line) and a muted `.ds-list__meta` on the right. For news and past letters.\n- `.ds-panel`: an outlined, shadowed box with a `.ds-panel__title` strip on `--color-surface-strong` over a rule and a `.ds-panel__body`. `.ds-panel--plain` puts the strip on `--fill-bar` with `--color-bar-text`; `.ds-panel--flush` removes the body padding for a table.\n- `.ds-tabs`: one outlined pill bar on `--shadow-control`, cut into segments by rules: each `.ds-tabs__item` holds a `.ds-tabs__tab`; the current one (`is-current`) is filled with the accent and bold, `is-hover` is on `--color-surface-alt`. Centred under the page header; two to five segments.\n- `.ds-sidebar`: an outlined, shadowed block beside an article: a `.ds-sidebar__title` and a `.ds-sidebar__list` of `.ds-sidebar__item` rows divided by faint rules, each a fact with its value at the right, or a link.\n- `.ds-notice`: a one-line message in an outlined box on `--shadow-control`, with a bold `.ds-notice__title` and `.ds-notice__text`, on `--color-notice`. `.ds-notice--error` is on `--color-danger-surface` with `--color-text`.\n- `.ds-pagination`: a centred row of 34px outlined pills (`.ds-pagination__link`) on `--shadow-control-hover`; the current page (`is-current`) is on the accent, `is-disabled` is grey and flat, `is-hover` sinks into its shadow.\n- `.ds-breadcrumb`: a centred 13px trail of `.ds-breadcrumb__item` separated by a muted slash; the last has `is-current` and is bold. It is the first line of the page header.\n- `.ds-dialog`: a 440px outlined box on `--shadow-dialog`, with a `.ds-dialog__bar` on `--color-surface-strong` (holding `.ds-dialog__title` and a round `.ds-dialog__close`), a `.ds-dialog__body`, and a `.ds-dialog__actions` strip on `--color-canvas` over a rule with the buttons right-aligned. In the page flow it sits on a `.ds-overlay` block, an outlined area filled with `--color-overlay`.\n- `.ds-empty`: an outlined, shadowed box on `--color-surface-alt`, centred: `.ds-empty__title`, `.ds-empty__text` and one small button.\n- `.ds-footer`: one inverse block, centred, closed above by a thick rule: `.ds-footer__brand`, a `.ds-footer__list` of underlined `.ds-footer__link` in a line and `.ds-footer__legal`.\n- `.ds-menu`: a chunky drop-down, a `<details>` whose `<summary>` is the `.ds-menu__trigger` (a small secondary button that ends in a plus sign). `.ds-menu__list` is an outlined, shadowed box of `.ds-menu__item` rows divided by rules, each a `.ds-menu__link`. Use it for a short list of pages under one button.\n- `.ds-nav__fold`: the `.ds-menu` that stands in for the bar's links at 600px and below: a \"Menu\" button beside the brand that lists every view as a `.ds-menu__link--view` (the current one filled with the accent and barred on the left) and the actions the phone bar has no room for. It is hidden on wider screens, where the links show.\n- `.ds-carousel`: a row of quotes of which one shows, in one outlined, shadowed box. `.ds-carousel__track` scrolls sideways with scroll snap; each `.ds-carousel__slide` holds a `.ds-carousel__quote` and a `.ds-carousel__who` line with a `.ds-avatar`. `.ds-carousel__controls` is the strip below with two `.ds-carousel__arrow` buttons and the `.ds-carousel__dots` (the current `.ds-carousel__dot` is wider and filled). Use it for what customers say, on the home page.\n- `.ds-avatar`: a person as initials on a filled, outlined circle (`--2`, `--3` change the fill). Use it beside a name.\n- `.ds-progress`: how far something is: a `.ds-progress__label` line (what, and the figures) over a thick outlined `.ds-progress__track` holding a `.ds-progress__bar` (50% wide; `--25` and `--70` set other widths).\n- `.ds-switch`: an on and off control: a `<label>` holding a hidden `.ds-switch__input` checkbox, the `.ds-switch__track` and the text. On, the track is filled with the accent and takes a small hard shadow. `.ds-switch-row` puts a `.ds-tooltip` at the end of its line. Use it for a setting that applies at once.\n- `.ds-tooltip`: a hint like a sticker. `.ds-tooltip__trigger` is a small round button with a question mark; `.ds-tooltip__tip` is an inverted, outlined box that shows above it on hover or focus (`is-open` on the wrapper shows it by hand). One or two lines of text.\n- `.ds-accordion`: questions that open and close, one outlined, shadowed box of `<details class=\"ds-accordion__item\">` divided by rules. `.ds-accordion__head` is the `<summary>` with a square plus sign; open, it becomes a `--color-surface-strong` strip with a minus sign over `.ds-accordion__body`. Use it for frequently asked questions.\n- `.ds-follow`: on a block that comes after another in a column that has no gap of its own; it adds the space above.\n\n## Never\n\n- `row-gap <= 20px`: table rows touch; list rows are separate cards 12px apart and link buttons 20px.\n- `content-width <= 80%`: the page is one centred column of 1080px; the page colour always shows at the sides.\n- `font-weight >= 500`: no regular or light text; the page is set in medium and heavier.\n- `font-size <= 72px`: the intro title is the largest text.\n- `font-size >= 12px`: badge labels are the smallest text.\n- `font-families <= 2`: one sans and a monospace for code.\n- `line-height <= 1.5`: body text is set at 1.5.\n- `letter-spacing = 0px`: nothing is tracked.\n- `uppercase-text <= 5%`: only 12px badges are uppercase.\n- `underlined-links <= 20%`: only links in running text are underlined.\n- `box-shadow-blur <= 0px`: every shadow is a hard offset block; a blurred shadow breaks the style at once.\n- `border-radius <= 20px`: 10px on controls, 14px on boxes, 20px on the largest cards; badges and meters are pills.\n- `border-width >= 2px`: every outline and rule is 2px or the 4px thick rule; no hairlines.\n- `border-width <= 4px`: nothing heavier than the 4px rule.\n- `text-shadow = none`: no text shadow in any reference.\n- `gradient-fills <= 1%`: fills are flat; the only gradient is the dot pattern drawn on the page background.\n- `animation = none`: nothing moves on its own; only hover and press shift a control.\n\n## Extending\n\nDerive a new component from the nearest one in the specimen and use tokens only. Anything new is a free-standing box in the centred column: a `--border-width` `--color-border` outline, the `--radius-panel` corner and the `--shadow-panel` hard shadow; the one or two most important boxes of a page (the profile card, the sign-up box, a dialog) take `--shadow-dialog` instead, and small things inside a column (list rows, notices) take `--shadow-control`. Anything clickable gets `--radius-control`, so controls read as pills against square boxes, and sinks `--space-nudge` on hover and `--space-press` when pressed, straight down. Colour a box with one flat `--color-fill-*` or surface token and put `--color-text` on it; never tint, fade or blur. A new destination on the home page is another `.ds-linkstack__link`; a new kind of work is another `.ds-grid__cell` with a drawing in `currentColor`. Only the portrait and the brand tile are tilted; do not rotate text or whole cards. A new page keeps the masthead, starts with the centred page header and stacks its blocks `--space-7` apart. For a size the vocabulary lacks, use `calc()` over an existing token, as the badge text does.\n",
    "components.css": "/* Layout tokens (structure part) */\n:root {\n  --size-page: 100%;\n  --size-content: 1080px;\n  --size-profile: 384px;\n  --size-measure: 600px;\n  --size-portrait: 152px;\n  --size-control: 44px;\n  --size-control-large: 54px;\n  --size-control-small: 34px;\n  --size-logo: 36px;\n  --size-icon: 44px;\n  --size-check: 20px;\n  --size-menu: 240px;\n  --size-avatar: 40px;\n  --size-tip: 220px;\n  --size-switch: 44px;\n  --size-bar: 16px;\n  --size-link: 84px;\n  --size-art: 148px;\n  --size-dialog: 440px;\n  --space-1: 4px;\n  --space-2: 8px;\n  --space-3: 12px;\n  --space-4: 16px;\n  --space-5: 20px;\n  --space-6: 24px;\n  --space-7: 32px;\n  --space-8: 48px;\n  --space-9: 72px;\n  --space-gutter: 24px;\n  --space-nudge: 2px;\n  --space-press: 4px;\n}\n\n/* shell: a centred masthead, one centred column of free-standing boxes, a centred footer */\n.ds-page {\n  margin: 0;\n  width: var(--size-page);\n  background: var(--fill-page);\n  color: var(--color-text);\n  font-family: var(--font-body);\n  font-size: var(--text-base);\n  font-weight: var(--weight-body);\n  line-height: var(--line-body);\n}\n.ds-page *,\n.ds-page *::before,\n.ds-page *::after {\n  box-sizing: border-box;\n}\n\n/* views: one screen shows at a time */\n.ds-view { display: none; }\n.ds-view:target, .ds-page:not(:has(.ds-view:target)) .ds-view--home { display: block; }\n.ds-view:target { scroll-margin-top: 100vh; }\n\n/* nav: a centred masthead. A filled announcement line, the brand, a row of link chips */\n.ds-nav {\n  color: var(--color-bar-text);\n  background: var(--fill-bar);\n  border-bottom: var(--border-width-strong) var(--border-style) var(--color-border-strong);\n}\n.ds-nav__strip {\n  margin: 0;\n  padding: var(--space-2) var(--space-gutter);\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-ui);\n  line-height: 1.4;\n  text-align: center;\n  color: var(--color-bar-alt-text);\n  background: var(--fill-bar-alt);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-nav__strip-link {\n  color: inherit;\n  font-weight: var(--weight-bold);\n  text-decoration: var(--link-decoration);\n  text-underline-offset: var(--space-1);\n}\n.ds-nav__bar {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: var(--space-4);\n  padding: var(--space-6) var(--space-gutter) var(--space-5);\n}\n.ds-brand {\n  display: inline-flex;\n  align-items: center;\n  gap: var(--space-3);\n  text-decoration: none;\n}\n.ds-brand__mark {\n  display: inline-flex;\n  flex: none;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-logo);\n  height: var(--size-logo);\n  padding: var(--space-1);\n  color: var(--color-button-text);\n  background: var(--fill-button);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control);\n  transform: rotate(-6deg);\n}\n.ds-brand__mark svg {\n  display: block;\n  width: 100%;\n  height: 100%;\n}\n.ds-brand__name {\n  font-family: var(--font-heading);\n  font-size: var(--text-h2);\n  font-weight: var(--weight-heading);\n  line-height: 1;\n  letter-spacing: var(--heading-tracking);\n  text-transform: var(--heading-transform);\n  color: var(--color-bar-text);\n}\n.ds-nav__links {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: var(--space-2);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-nav__link {\n  display: inline-flex;\n  align-items: center;\n  gap: var(--space-2);\n  min-height: var(--size-control-small);\n  padding: 0 var(--space-4);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  line-height: 1;\n  text-transform: var(--ui-transform);\n  text-decoration: var(--link-decoration-quiet);\n  color: var(--color-bar-text);\n  border: var(--border-width) var(--border-style) transparent;\n  border-radius: var(--radius-control);\n}\n.ds-nav__link:hover,\n.ds-nav__link.is-hover {\n  border-color: var(--color-border);\n}\n.ds-nav__link.is-current,\n.ds-page:not(:has(.ds-view:target)) .ds-nav__link[href=\"#home\"],\n.ds-page:has(#home:target) .ds-nav__link[href=\"#home\"],\n.ds-page:has(#work:target) .ds-nav__link[href=\"#work\"],\n.ds-page:has(#project:target) .ds-nav__link[href=\"#project\"],\n.ds-page:has(#hire:target) .ds-nav__link[href=\"#hire\"],\n.ds-page:has(#letter:target) .ds-nav__link[href=\"#letter\"] {\n  font-weight: var(--weight-bold);\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n  border-color: var(--color-border);\n  box-shadow: var(--shadow-control-hover);\n}\n.ds-nav__link:focus-visible,\n.ds-nav__link.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n\n/* column: everything below the masthead sits in one centred column */\n.ds-main {\n  display: block;\n  padding: var(--space-8) var(--space-gutter) var(--space-9);\n}\n.ds-column {\n  display: grid;\n  gap: var(--space-7);\n  align-content: start;\n  max-width: var(--size-content);\n  margin: 0 auto;\n}\n.ds-home {\n  display: grid;\n  grid-template-columns: var(--size-profile) minmax(0, 1fr);\n  gap: var(--space-7);\n  align-items: start;\n}\n.ds-split {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) var(--size-profile);\n  gap: var(--space-7);\n  align-items: start;\n}\n.ds-split--even {\n  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n}\n.ds-stack {\n  display: grid;\n  gap: var(--space-6);\n  align-content: start;\n  min-width: 0;\n}\n.ds-row {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-4);\n}\n.ds-label {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h2);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  text-transform: var(--heading-transform);\n  color: var(--color-heading);\n}\n.ds-note {\n  margin: 0;\n  font-size: var(--text-small);\n  line-height: 1.4;\n  color: var(--color-text-muted);\n}\n\n/* hero: the profile card. A filled top with a tilted portrait, then the introduction */\n.ds-hero {\n  display: flex;\n  flex-direction: column;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n  box-shadow: var(--shadow-dialog);\n  overflow: hidden;\n}\n.ds-hero__art {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: var(--space-7) var(--space-5);\n  background: var(--color-fill-1);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-hero__text {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  gap: var(--space-3);\n  padding: var(--space-6);\n}\n.ds-hero__title {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: calc(var(--text-h1) * 0.8);\n  font-weight: var(--weight-display);\n  line-height: var(--line-display);\n  letter-spacing: var(--display-tracking);\n  text-transform: var(--heading-transform);\n  color: var(--color-heading);\n}\n.ds-hero__lead {\n  margin: 0;\n  font-size: var(--text-base);\n  line-height: var(--line-body);\n}\n.ds-hero__actions {\n  display: grid;\n  gap: var(--space-3);\n  width: 100%;\n  margin-top: var(--space-2);\n}\n.ds-portrait {\n  position: relative;\n  display: block;\n  width: var(--size-portrait);\n  height: var(--size-portrait);\n  background: var(--color-accent-alt);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  transform: rotate(-5deg);\n  overflow: hidden;\n}\n.ds-portrait__head {\n  position: absolute;\n  top: 16%;\n  left: 31%;\n  width: 38%;\n  height: 38%;\n  background: var(--color-surface);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: 50%;\n}\n.ds-portrait__body {\n  position: absolute;\n  top: 60%;\n  left: 12%;\n  width: 76%;\n  height: 70%;\n  background: var(--color-fill-3);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: 50%;\n}\n\n/* stats: one outlined box of three cells divided by rules */\n.ds-stat {\n  display: grid;\n  grid-template-columns: repeat(3, minmax(0, 1fr));\n  margin: 0;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-stat__cell {\n  display: flex;\n  flex-direction: column-reverse;\n  align-items: center;\n  min-width: 0;\n  padding: var(--space-4) var(--space-2);\n  text-align: center;\n}\n.ds-stat__cell + .ds-stat__cell {\n  border-left: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-stat__value {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h2);\n  font-weight: var(--weight-display);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading);\n}\n.ds-stat__label {\n  margin: var(--space-1) 0 0;\n  font-size: var(--text-small);\n  line-height: 1.3;\n}\n\n/* link stack: big outlined buttons, one per destination */\n.ds-linkstack {\n  display: grid;\n  gap: var(--space-5);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-linkstack__link {\n  display: flex;\n  align-items: center;\n  gap: var(--space-4);\n  min-height: var(--size-link);\n  padding: var(--space-3) var(--space-5) var(--space-3) var(--space-4);\n  text-decoration: none;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  transition: var(--transition);\n}\n\n/* a block that moves down onto its shadow carries a strip above itself, so a pointer at its top edge stays on it */\n.ds-linkstack__link {\n  position: relative;\n}\n.ds-linkstack__link::before {\n  content: \"\";\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 100%;\n  height: calc(2 * var(--space-press));\n}\n.ds-linkstack__link--1 {\n  background: var(--color-fill-1);\n}\n.ds-linkstack__link--2 {\n  background: var(--color-fill-2);\n}\n.ds-linkstack__link--3 {\n  background: var(--color-fill-3);\n}\n.ds-linkstack__link--4 {\n  background: var(--color-fill-4);\n}\n.ds-linkstack__link:hover,\n.ds-linkstack__link.is-hover {\n  box-shadow: var(--shadow-control);\n  transform: translateY(var(--space-nudge));\n}\n.ds-linkstack__link:focus-visible,\n.ds-linkstack__link.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n.ds-linkstack__icon {\n  display: flex;\n  flex: none;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-icon);\n  height: var(--size-icon);\n  padding: var(--space-2);\n  color: var(--color-text);\n  background: var(--color-surface);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n}\n.ds-linkstack__icon svg {\n  display: block;\n  width: 100%;\n  height: 100%;\n}\n.ds-linkstack__main {\n  flex: 1;\n  min-width: 0;\n}\n.ds-linkstack__title {\n  display: block;\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n}\n.ds-linkstack__text {\n  display: block;\n  margin-top: var(--space-1);\n  font-size: var(--text-small);\n  line-height: 1.4;\n}\n.ds-linkstack__arrow {\n  flex: none;\n  font-family: var(--font-ui);\n  font-size: var(--text-large);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n}\n\n/* page header: the head of an inner page, centred like the masthead */\n.ds-page-header {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: var(--space-3);\n  text-align: center;\n  color: var(--color-text);\n}\n.ds-page-header__title {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h1);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  text-transform: var(--heading-transform);\n  color: var(--color-heading);\n}\n.ds-page-header__lead {\n  max-width: var(--size-measure);\n  margin: var(--space-2) 0 0;\n  font-size: var(--text-large);\n  line-height: 1.45;\n}\n.ds-page-header__actions {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: var(--space-4);\n  margin-top: var(--space-2);\n}\n\n/* grid: project cards, a filled picture over a caption */\n.ds-grid {\n  display: grid;\n  grid-template-columns: repeat(3, minmax(0, 1fr));\n  gap: var(--space-7) var(--space-6);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-grid__cell {\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-grid__art {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: var(--size-art);\n  padding: var(--space-4);\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-grid__art svg {\n  display: block;\n  height: 100%;\n}\n.ds-grid__cell--1 .ds-grid__art {\n  background: var(--color-fill-1);\n}\n.ds-grid__cell--2 .ds-grid__art {\n  background: var(--color-fill-2);\n}\n.ds-grid__cell--3 .ds-grid__art {\n  background: var(--color-fill-3);\n}\n.ds-grid__cell--4 .ds-grid__art {\n  background: var(--color-fill-4);\n}\n.ds-grid__body {\n  display: flex;\n  flex: 1;\n  flex-direction: column;\n  gap: var(--space-2);\n  padding: var(--space-4) var(--space-4) var(--space-5);\n}\n.ds-grid__title {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading-alt);\n}\n.ds-grid__title .ds-link {\n  font-weight: inherit;\n}\n.ds-grid__text {\n  flex: 1;\n  margin: 0;\n  font-size: var(--text-small);\n  line-height: 1.45;\n}\n\n/* typography */\n.ds-prose {\n  max-width: 64ch;\n  color: var(--color-text);\n}\n.ds-prose h1,\n.ds-prose h2,\n.ds-prose h3 {\n  font-family: var(--font-heading);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  text-transform: var(--heading-transform);\n  color: var(--color-heading);\n}\n.ds-prose h1 {\n  margin: 0 0 var(--space-4);\n  font-size: var(--text-h1);\n}\n.ds-prose h2 {\n  margin: var(--space-6) 0 var(--space-3);\n  font-size: var(--text-h2);\n}\n.ds-prose h3 {\n  margin: var(--space-5) 0 var(--space-2);\n  font-size: var(--text-h3);\n}\n.ds-prose p,\n.ds-prose ul,\n.ds-prose ol {\n  margin: 0 0 var(--space-4);\n}\n.ds-prose ul,\n.ds-prose ol {\n  padding-left: var(--space-6);\n}\n.ds-prose li {\n  margin-bottom: var(--space-1);\n}\n.ds-prose strong {\n  font-weight: var(--weight-bold);\n}\n.ds-prose code {\n  padding: 0 var(--space-1);\n  font-family: var(--font-mono);\n  font-size: var(--text-small);\n  white-space: nowrap;\n  background: var(--color-surface-alt);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n}\n.ds-prose a {\n  color: var(--color-link);\n  font-weight: var(--weight-ui);\n  text-decoration: var(--link-decoration);\n  text-underline-offset: var(--space-1);\n}\n.ds-prose a:hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n  background: var(--color-surface-strong);\n}\n.ds-sheet {\n  padding: var(--space-7) var(--space-7) var(--space-6);\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n  box-shadow: var(--shadow-panel);\n}\n\n/* links */\n.ds-link {\n  color: var(--color-link);\n  font-weight: var(--weight-ui);\n  text-decoration: var(--link-decoration);\n  text-decoration-thickness: var(--border-width);\n  text-underline-offset: var(--space-1);\n}\n.ds-link--quiet {\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-link:visited,\n.ds-link.is-visited {\n  color: var(--color-link-visited);\n}\n.ds-link:hover,\n.ds-link.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n  background: var(--color-surface-strong);\n}\n.ds-link:active,\n.ds-link.is-active {\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n}\n.ds-link:focus-visible,\n.ds-link.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n.ds-links {\n  display: flex;\n  flex-wrap: wrap;\n  gap: var(--space-2) var(--space-5);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n\n/* buttons: flat fill, outline, hard shadow; a pressed button sinks straight down */\n.ds-button {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  gap: var(--space-2);\n  min-height: var(--size-control);\n  margin: 0;\n  padding: 0 var(--space-5);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  text-transform: var(--ui-transform);\n  text-decoration: none;\n  text-shadow: var(--shadow-text);\n  white-space: nowrap;\n  cursor: pointer;\n  color: var(--color-button-text);\n  background: var(--fill-button);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control);\n  transition: var(--transition);\n}\n\n/* a block that moves down onto its shadow carries a strip above itself, so a pointer at its top edge stays on it */\n.ds-button {\n  position: relative;\n}\n.ds-button::before {\n  content: \"\";\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 100%;\n  height: calc(2 * var(--space-press));\n}\n.ds-button--secondary {\n  color: var(--color-button-secondary-text);\n  background: var(--fill-button-secondary);\n}\n.ds-button--danger {\n  color: var(--color-text);\n  background: var(--color-danger);\n}\n.ds-button--large {\n  min-height: var(--size-control-large);\n  padding: 0 var(--space-6);\n  font-size: var(--text-large);\n}\n.ds-button--small {\n  min-height: var(--size-control-small);\n  padding: 0 var(--space-3);\n  font-size: var(--text-small);\n}\n.ds-button:hover,\n.ds-button.is-hover {\n  color: var(--color-button-hover-text);\n  background: var(--fill-button-hover);\n  box-shadow: var(--shadow-control-hover);\n  transform: translateY(var(--space-nudge));\n}\n.ds-button--secondary:hover,\n.ds-button--secondary.is-hover {\n  color: var(--color-button-secondary-text);\n  background: var(--fill-button-secondary);\n}\n.ds-button--danger:hover,\n.ds-button--danger.is-hover {\n  color: var(--color-text);\n  background: var(--color-danger);\n}\n.ds-button:active,\n.ds-button.is-active {\n  box-shadow: var(--shadow-control-pressed);\n  transform: translateY(var(--space-press));\n}\n.ds-button:focus-visible,\n.ds-button.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n.ds-button:disabled,\n.ds-button.is-disabled {\n  color: var(--color-disabled-text);\n  background: var(--color-disabled);\n  box-shadow: var(--shadow-control-pressed);\n  transform: none;\n  cursor: not-allowed;\n}\n.ds-buttons {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-4);\n}\n\n/* badge */\n.ds-badge {\n  display: inline-flex;\n  align-items: center;\n  padding: 0 var(--space-2);\n  font-family: var(--font-ui);\n  font-size: calc(var(--text-small) * 0.9);\n  font-weight: var(--weight-bold);\n  line-height: 1.6;\n  white-space: nowrap;\n  vertical-align: middle;\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n}\n.ds-badge--alt {\n  color: var(--color-text);\n  background: var(--color-accent-alt);\n}\n.ds-badge--plain {\n  color: var(--color-text);\n  background: var(--color-surface);\n}\n.ds-badge--success {\n  color: var(--color-text);\n  background: var(--color-success);\n}\n.ds-badge--warning {\n  color: var(--color-text);\n  background: var(--color-warning);\n}\n.ds-badge--danger {\n  color: var(--color-text);\n  background: var(--color-danger);\n}\n.ds-badges {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-2);\n}\n\n.ds-badges--key {\n  justify-content: center;\n}\n\n/* form */\n.ds-form {\n  display: grid;\n  gap: var(--space-4);\n}\n.ds-form__row {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n  gap: var(--space-4);\n  align-items: start;\n}\n.ds-form__field {\n  display: grid;\n  gap: var(--space-2);\n  min-width: 0;\n}\n.ds-form__label {\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: 1.4;\n}\n.ds-form__control {\n  width: 100%;\n  min-height: var(--size-control);\n  margin: 0;\n  padding: var(--space-2) var(--space-3);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  line-height: 1.4;\n  color: var(--color-input-text);\n  background: var(--fill-input);\n  border: var(--border-width) var(--border-style) var(--color-input-border);\n  border-radius: var(--radius-control);\n  transition: var(--transition);\n}\n.ds-form__control--area {\n  min-height: calc(var(--size-control) * 2.2);\n  resize: vertical;\n}\n.ds-form__control:focus,\n.ds-form__control.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n  box-shadow: var(--shadow-control);\n}\n.ds-form__control:disabled,\n.ds-form__control.is-disabled {\n  color: var(--color-disabled-text);\n  background: var(--color-disabled);\n}\n.ds-form__control.is-invalid {\n  border-color: var(--color-danger);\n  box-shadow: 0 var(--space-press) 0 0 var(--color-danger);\n}\n.ds-form__error {\n  margin: var(--space-1) 0 0;\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: 1.4;\n  color: var(--color-danger);\n}\n.ds-form__hint {\n  margin: 0;\n  font-size: var(--text-small);\n  line-height: 1.4;\n  color: var(--color-text-muted);\n}\n.ds-form__check {\n  display: flex;\n  align-items: center;\n  gap: var(--space-3);\n  font-weight: var(--weight-ui);\n}\n.ds-form__checkbox {\n  appearance: none;\n  flex: none;\n  width: var(--size-check);\n  height: var(--size-check);\n  margin: 0;\n  background: var(--fill-input);\n  border: var(--border-width) var(--border-style) var(--color-input-border);\n  border-radius: min(var(--radius-control), var(--space-1));\n}\n.ds-form__checkbox:checked,\n.ds-form__checkbox.is-checked {\n  background: var(--color-text);\n  box-shadow: inset 0 0 0 var(--space-nudge) var(--color-input);\n}\n.ds-form__checkbox:focus-visible,\n.ds-form__checkbox.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n.ds-form__foot {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-4);\n  margin-top: var(--space-2);\n  padding-top: var(--space-4);\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n\n/* notice */\n.ds-notice {\n  display: flex;\n  align-items: baseline;\n  gap: var(--space-3);\n  padding: var(--space-3) var(--space-4);\n  color: var(--color-notice-text);\n  background: var(--color-notice);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-control);\n}\n.ds-notice__title {\n  flex: none;\n  font-weight: var(--weight-bold);\n}\n.ds-notice__text {\n  margin: 0;\n}\n.ds-notice--error {\n  color: var(--color-text);\n  background: var(--color-danger-surface);\n}\n\n/* pagination */\n.ds-pagination {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: center;\n  gap: var(--space-2);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-pagination__link {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  min-width: var(--size-control-small);\n  min-height: var(--size-control-small);\n  padding: 0 var(--space-3);\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  text-decoration: none;\n  color: var(--color-button-secondary-text);\n  background: var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control-hover);\n  transition: var(--transition);\n}\n.ds-pagination__link:hover,\n.ds-pagination__link.is-hover {\n  box-shadow: var(--shadow-control-pressed);\n}\n.ds-pagination__link.is-current {\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n}\n.ds-pagination__link.is-disabled {\n  color: var(--color-disabled-text);\n  background: var(--color-disabled);\n  box-shadow: var(--shadow-control-pressed);\n}\n\n/* breadcrumb */\n.ds-breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: center;\n  gap: var(--space-2);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-ui);\n  line-height: 1.4;\n}\n.ds-breadcrumb__item + .ds-breadcrumb__item::before {\n  content: \"/\";\n  margin-right: var(--space-2);\n  color: var(--color-text-muted);\n}\n.ds-breadcrumb__item.is-current {\n  font-weight: var(--weight-bold);\n}\n\n/* empty state */\n.ds-empty {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  gap: var(--space-2);\n  padding: var(--space-6) var(--space-4);\n  text-align: center;\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n}\n.ds-empty__title {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  color: var(--color-text);\n}\n.ds-empty__text {\n  margin: 0 0 var(--space-2);\n  font-size: var(--text-small);\n  line-height: 1.4;\n}\n\n/* table: one outlined, shadowed box; rows divided by rules */\n.ds-table {\n  width: 100%;\n  border-collapse: separate;\n  border-spacing: 0;\n  font-size: var(--text-base);\n  color: var(--color-text);\n  background: var(--color-surface);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-table th,\n.ds-table td {\n  padding: var(--space-3) var(--space-4);\n  text-align: left;\n  vertical-align: middle;\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-table th {\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n}\n.ds-table tbody tr:last-child td {\n  border-bottom: 0;\n}\n.ds-table tbody tr.is-current td {\n  background: var(--color-surface-strong);\n  font-weight: var(--weight-bold);\n}\n.ds-table .ds-table__num {\n  text-align: right;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n/* list: separate outlined rows, each a small card */\n.ds-list {\n  display: grid;\n  gap: var(--space-3);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-list__item {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-4);\n  padding: var(--space-3) var(--space-4);\n  color: var(--color-text);\n  background: var(--color-surface);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-control);\n}\n.ds-list__main {\n  min-width: 0;\n}\n.ds-list__title {\n  margin: 0;\n  font-size: var(--text-base);\n  font-weight: var(--weight-bold);\n  line-height: 1.35;\n}\n.ds-list__title .ds-link {\n  font-weight: inherit;\n}\n.ds-list__text {\n  margin: 0;\n  font-size: var(--text-small);\n  line-height: 1.45;\n}\n.ds-list__meta {\n  flex: none;\n  font-size: var(--text-small);\n  line-height: 1.4;\n  color: var(--color-text-muted);\n}\n\n/* panel: outlined box with a filled title strip */\n.ds-panel {\n  min-width: 0;\n  background: var(--fill-panel);\n  color: var(--color-text);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-panel__title {\n  margin: 0;\n  padding: var(--space-3) var(--space-4);\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading-alt);\n  background: var(--color-surface-strong);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-panel__body {\n  padding: var(--space-4);\n}\n.ds-panel__body p {\n  margin: 0 0 var(--space-3);\n}\n.ds-panel--plain .ds-panel__title {\n  color: var(--color-bar-text);\n  background: var(--fill-bar);\n}\n.ds-panel--flush .ds-panel__body {\n  padding: 0;\n}\n.ds-panel--flush .ds-table {\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n/* sign-up: a filled box with one field and one button on a line */\n.ds-signup {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n  gap: var(--space-5) var(--space-7);\n  align-items: center;\n  padding: var(--space-7);\n  color: var(--color-text);\n  background: var(--color-fill-2);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n  box-shadow: var(--shadow-dialog);\n}\n.ds-signup__text {\n  margin: var(--space-2) 0 0;\n}\n.ds-signup__form {\n  display: grid;\n  gap: var(--space-2);\n}\n.ds-signup__line {\n  display: flex;\n  gap: var(--space-3);\n}\n\n/* tabs: one outlined bar cut into segments; the current one is filled */\n.ds-tabs {\n  display: inline-flex;\n  max-width: 100%;\n  margin: 0 auto;\n  padding: 0;\n  list-style: none;\n  background: var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control);\n  overflow: hidden;\n}\n.ds-tabs__item + .ds-tabs__item {\n  border-left: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-tabs__tab {\n  display: flex;\n  align-items: center;\n  gap: var(--space-2);\n  min-height: var(--size-control);\n  padding: 0 var(--space-5);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  line-height: 1;\n  text-transform: var(--ui-transform);\n  text-decoration: none;\n  white-space: nowrap;\n  color: var(--color-button-secondary-text);\n}\n.ds-tabs__tab:hover,\n.ds-tabs__tab.is-hover {\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n}\n.ds-tabs__tab.is-current {\n  font-weight: var(--weight-bold);\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n}\n.ds-tabs__tab:focus-visible,\n.ds-tabs__tab.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: calc(-1 * var(--space-press));\n}\n\n/* sidebar: an outlined block of facts and links beside an article */\n.ds-sidebar {\n  padding: var(--space-5);\n  color: var(--color-text);\n  background: var(--color-surface);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n}\n.ds-sidebar__title {\n  margin: 0 0 var(--space-3);\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading-alt);\n}\n.ds-sidebar__list {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-sidebar__item {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-3);\n  padding: var(--space-2) 0;\n  border-top: var(--border-width) var(--border-style) var(--color-border-muted);\n}\n\n/* dialog: an outlined box with a title strip, on a filled backdrop block */\n.ds-overlay {\n  padding: var(--space-8) var(--space-5);\n  background: var(--color-overlay);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n}\n.ds-dialog {\n  max-width: var(--size-dialog);\n  margin: 0 auto;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border-strong);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-dialog);\n  overflow: hidden;\n}\n.ds-dialog__bar {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-4);\n  padding: var(--space-3) var(--space-4);\n  background: var(--color-surface-strong);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-dialog__title {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading-alt);\n}\n.ds-dialog__close {\n  display: inline-flex;\n  flex: none;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-control-small);\n  height: var(--size-control-small);\n  padding: 0;\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  text-decoration: none;\n  cursor: pointer;\n  color: var(--color-button-secondary-text);\n  background: var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control-hover);\n}\n.ds-dialog__body {\n  padding: var(--space-5) var(--space-4);\n}\n.ds-dialog__body p {\n  margin: 0;\n}\n.ds-dialog__actions {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-end;\n  gap: var(--space-4);\n  padding: var(--space-4);\n  background: var(--color-canvas);\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n\n/* footer: one inverted block, centred */\n.ds-footer {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: var(--space-4);\n  padding: var(--space-8) var(--space-gutter) var(--space-7);\n  font-size: var(--text-small);\n  line-height: 1.45;\n  text-align: center;\n  color: var(--color-inverse-text);\n  background: var(--fill-inverse);\n  border-top: var(--border-width-strong) var(--border-style) var(--color-border-strong);\n}\n.ds-footer__brand {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h2);\n  font-weight: var(--weight-heading);\n  line-height: 1;\n  letter-spacing: var(--heading-tracking);\n}\n.ds-footer__list {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: var(--space-2) var(--space-5);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-footer__link {\n  font-weight: var(--weight-ui);\n  color: var(--color-inverse-text);\n  text-decoration: var(--link-decoration);\n  text-underline-offset: var(--space-1);\n}\n.ds-footer__link:hover,\n.ds-footer__link.is-hover {\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-footer__legal {\n  margin: 0;\n}\n\n/* menu: a chunky drop-down, a details element whose summary is the trigger */\n.ds-menu {\n  position: relative;\n}\n.ds-menu__trigger {\n  list-style: none;\n  cursor: pointer;\n}\n.ds-menu__trigger::-webkit-details-marker {\n  display: none;\n}\n.ds-menu__trigger::after {\n  content: \"+\";\n  margin-left: var(--space-2);\n  font-weight: var(--weight-bold);\n}\n.ds-menu[open] .ds-menu__trigger::after {\n  content: \"-\";\n}\n.ds-menu__list {\n  position: absolute;\n  top: calc(100% + var(--space-2));\n  left: 0;\n  z-index: 3;\n  width: var(--size-menu);\n  max-width: 80vw;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-menu__item + .ds-menu__item {\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-menu__link {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-3);\n  padding: var(--space-2) var(--space-4);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  text-decoration: none;\n  color: var(--color-text);\n}\n.ds-menu__link:hover,\n.ds-menu__link.is-hover {\n  background: var(--color-surface-alt);\n}\n\n/* avatar: a person as initials on a filled, outlined circle */\n.ds-avatar {\n  display: inline-flex;\n  flex: none;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-avatar);\n  height: var(--size-avatar);\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  color: var(--color-text);\n  background: var(--color-accent-alt);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n}\n.ds-avatar--2 {\n  background: var(--color-fill-2);\n}\n.ds-avatar--3 {\n  background: var(--color-fill-4);\n}\n\n/* follow: a block that comes after another in a plain column */\n.ds-follow {\n  margin-top: var(--space-5);\n}\n/* carousel: one quote showing, the rest a swipe away */\n.ds-carousel {\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-carousel__track {\n  display: flex;\n  flex: 1;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  overflow-x: auto;\n  scroll-snap-type: x mandatory;\n  scrollbar-width: none;\n}\n.ds-carousel__slide {\n  display: flex;\n  flex: 0 0 100%;\n  flex-direction: column;\n  justify-content: space-between;\n  gap: var(--space-4);\n  min-width: 0;\n  padding: var(--space-5);\n  scroll-snap-align: start;\n}\n.ds-carousel__quote {\n  margin: 0;\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  color: var(--color-heading-alt);\n}\n.ds-carousel__who {\n  display: flex;\n  align-items: center;\n  gap: var(--space-3);\n  margin: 0;\n  font-size: var(--text-small);\n  font-weight: var(--weight-ui);\n  line-height: 1.3;\n}\n.ds-carousel__controls {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-4);\n  padding: var(--space-2) var(--space-4);\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-carousel__arrow {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-control-small);\n  height: var(--size-control-small);\n  margin: 0;\n  padding: 0;\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  cursor: pointer;\n  color: var(--color-button-secondary-text);\n  background: var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-shadow: var(--shadow-control-hover);\n  transition: var(--transition);\n}\n.ds-carousel__arrow:hover,\n.ds-carousel__arrow.is-hover {\n  box-shadow: var(--shadow-control-pressed);\n}\n.ds-carousel__dots {\n  display: flex;\n  align-items: center;\n  gap: var(--space-2);\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-carousel__dot {\n  display: block;\n  width: var(--space-4);\n  height: var(--space-4);\n  background: var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n}\n.ds-carousel__dot.is-current {\n  width: var(--space-6);\n  background: var(--fill-accent);\n}\n/* progress: a thick outlined track with a filled bar */\n.ds-progress {\n  display: grid;\n  gap: var(--space-2);\n}\n.ds-progress__label {\n  display: flex;\n  justify-content: space-between;\n  gap: var(--space-3);\n  margin: 0;\n  font-size: var(--text-small);\n  font-weight: var(--weight-ui);\n  line-height: 1.3;\n}\n.ds-progress__track {\n  display: block;\n  height: var(--size-bar);\n  background: var(--fill-input);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n  overflow: hidden;\n}\n.ds-progress__bar {\n  display: block;\n  width: 50%;\n  height: 100%;\n  background: var(--fill-accent);\n  border-right: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-progress__bar--70 {\n  width: 70%;\n}\n/* switch: an on and off control drawn over a checkbox */\n.ds-switch-row {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-3);\n}\n.ds-switch {\n  position: relative;\n  display: flex;\n  align-items: center;\n  gap: var(--space-3);\n  font-weight: var(--weight-ui);\n  line-height: 1.3;\n  cursor: pointer;\n}\n.ds-switch__input {\n  position: absolute;\n  width: var(--size-check);\n  height: var(--size-check);\n  margin: 0;\n  opacity: 0;\n}\n.ds-switch__track {\n  position: relative;\n  display: block;\n  flex: none;\n  width: var(--size-switch);\n  height: calc(var(--size-check) + 2 * var(--border-width));\n  background: var(--fill-input);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n  transition: var(--transition);\n}\n.ds-switch__track::before {\n  content: \"\";\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: var(--size-check);\n  height: var(--size-check);\n  background: var(--color-text);\n  border-radius: var(--radius-pill);\n  transform: scale(0.64);\n  transition: var(--transition);\n}\n.ds-switch__input:checked + .ds-switch__track,\n.ds-switch__track.is-on {\n  background: var(--fill-accent);\n  box-shadow: var(--shadow-control-hover);\n}\n.ds-switch__input:checked + .ds-switch__track::before,\n.ds-switch__track.is-on::before {\n  left: calc(100% - var(--size-check));\n  background: var(--color-accent-text);\n}\n.ds-switch__input:focus-visible + .ds-switch__track,\n.ds-switch__track.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: var(--space-nudge);\n}\n/* tooltip: a sticker of a hint over its trigger, on hover or focus */\n.ds-tooltip {\n  position: relative;\n  display: inline-flex;\n  align-items: center;\n}\n.ds-tooltip__trigger {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: var(--size-check);\n  height: var(--size-check);\n  margin: 0;\n  padding: 0;\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: 1;\n  cursor: help;\n  color: var(--color-text);\n  background: var(--color-accent-alt);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-pill);\n  box-sizing: content-box;\n}\n.ds-tooltip__tip {\n  position: absolute;\n  bottom: calc(100% + var(--space-2));\n  right: 0;\n  z-index: 2;\n  width: var(--size-tip);\n  max-width: 70vw;\n  padding: var(--space-2) var(--space-3);\n  font-size: var(--text-small);\n  font-weight: var(--weight-ui);\n  line-height: 1.35;\n  text-align: left;\n  color: var(--color-inverse-text);\n  background: var(--fill-inverse);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: min(var(--radius-control), var(--space-4));\n  box-shadow: var(--shadow-control-hover);\n  visibility: hidden;\n}\n.ds-tooltip:hover .ds-tooltip__tip,\n.ds-tooltip:focus-within .ds-tooltip__tip,\n.ds-tooltip.is-open .ds-tooltip__tip {\n  visibility: visible;\n}\n/* accordion: questions that open and close, one outlined box, a big plus sign */\n.ds-accordion {\n  color: var(--color-text);\n  background: var(--fill-panel);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  box-shadow: var(--shadow-panel);\n  overflow: hidden;\n}\n.ds-accordion__item + .ds-accordion__item {\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-accordion__head {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-4);\n  padding: var(--space-3) var(--space-4);\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-heading);\n  letter-spacing: var(--heading-tracking);\n  list-style: none;\n  cursor: pointer;\n  color: var(--color-heading-alt);\n}\n.ds-accordion__head::-webkit-details-marker {\n  display: none;\n}\n.ds-accordion__head::after {\n  content: \"\";\n  display: block;\n  flex: none;\n  width: var(--size-check);\n  height: var(--size-check);\n  color: var(--color-button-secondary-text);\n  background: linear-gradient(currentColor, currentColor) center / calc(var(--space-1) * 2.5) calc(var(--space-1) / 2) no-repeat,\n    linear-gradient(currentColor, currentColor) center / calc(var(--space-1) / 2) calc(var(--space-1) * 2.5) no-repeat,\n    var(--fill-button-secondary);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-control);\n  box-sizing: content-box;\n}\n.ds-accordion__head:hover,\n.ds-accordion__head.is-hover {\n  color: var(--color-text);\n  background: var(--color-surface-alt);\n}\n.ds-accordion__head:focus-visible,\n.ds-accordion__head.is-focus {\n  outline: var(--focus-ring);\n  outline-offset: calc(-1 * var(--space-press));\n}\n.ds-accordion__item[open] .ds-accordion__head {\n  color: var(--color-heading-alt);\n  background: var(--color-surface-strong);\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-accordion__item[open] .ds-accordion__head::after {\n  background: linear-gradient(currentColor, currentColor) center / calc(var(--space-1) * 2.5) calc(var(--space-1) / 2) no-repeat,\n    var(--fill-button-secondary);\n}\n.ds-accordion__body {\n  padding: var(--space-4);\n}\n.ds-accordion__body p {\n  margin: 0;\n}\n\n/* nav fold: on a phone the bar's links fold into a menu behind one button */\n.ds-nav__fold {\n  display: none;\n}\n.ds-menu__link.is-current,\n.ds-page:not(:has(.ds-view:target)) .ds-menu__link--view[href=\"#home\"],\n.ds-page:has(#home:target) .ds-menu__link--view[href=\"#home\"],\n.ds-page:has(#work:target) .ds-menu__link--view[href=\"#work\"],\n.ds-page:has(#project:target) .ds-menu__link--view[href=\"#project\"],\n.ds-page:has(#hire:target) .ds-menu__link--view[href=\"#hire\"],\n.ds-page:has(#letter:target) .ds-menu__link--view[href=\"#letter\"] {\n  font-weight: var(--weight-bold);\n  color: var(--color-accent-text);\n  background: var(--fill-accent);\n  border-left: var(--space-2) var(--border-style) var(--color-border);\n}\n\n@media (max-width: 900px) {\n  .ds-home,\n  .ds-split,\n  .ds-split--even,\n  .ds-signup {\n    grid-template-columns: minmax(0, 1fr);\n  }\n  .ds-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n  .ds-main {\n    padding: var(--space-7) var(--space-4) var(--space-8);\n  }\n}\n\n@media (max-width: 600px) {\n  .ds-nav__bar {\n    gap: var(--space-3);\n    padding: var(--space-4) var(--space-3) var(--space-3);\n  }\n  .ds-nav__links {\n    gap: var(--space-1);\n  }\n  .ds-nav__link {\n    padding: 0 var(--space-2);\n    font-size: var(--text-small);\n  }\n  .ds-column {\n    gap: var(--space-6);\n  }\n  .ds-page-header__title,\n  .ds-prose h1 {\n    font-size: calc(var(--text-h1) * 0.8);\n  }\n  .ds-hero__title {\n    font-size: calc(var(--text-h1) * 0.7);\n  }\n  .ds-page-header__lead {\n    font-size: var(--text-base);\n  }\n  .ds-page-header__actions,\n  .ds-page-header__actions .ds-button {\n    width: 100%;\n  }\n  .ds-grid,\n  .ds-form__row {\n    grid-template-columns: minmax(0, 1fr);\n  }\n  .ds-linkstack__link {\n    gap: var(--space-3);\n    padding: var(--space-3);\n  }\n  .ds-signup,\n  .ds-sheet {\n    padding: var(--space-5) var(--space-4);\n  }\n  .ds-signup__line {\n    flex-direction: column;\n  }\n  .ds-tabs {\n    display: flex;\n    overflow-x: auto;\n  }\n  .ds-tabs__tab {\n    padding: 0 var(--space-3);\n    font-size: var(--text-small);\n  }\n  .ds-table {\n    font-size: var(--text-small);\n  }\n  .ds-table th,\n  .ds-table td {\n    padding: var(--space-2) var(--space-3);\n  }\n  .ds-table .ds-table__extra {\n    display: none;\n  }\n  .ds-notice,\n  .ds-list__item {\n    flex-direction: column;\n    align-items: flex-start;\n    gap: var(--space-1);\n  }\n  .ds-overlay {\n    padding: var(--space-6) var(--space-3);\n  }\n  .ds-footer {\n    padding: var(--space-7) var(--space-4) var(--space-6);\n  }\n}\n@media (max-width: 600px) {\n  /* the brand gives way before the menu button leaves the bar */\n  .ds-brand {\n    min-width: 0;\n  }\n  .ds-brand__name {\n    font-size: min(var(--text-h2), 7vw);\n  }\n  .ds-nav {\n    position: relative;\n  }\n  .ds-nav .ds-nav__links {\n    display: none;\n  }\n  .ds-nav__fold {\n    display: block;\n    position: static;\n    margin-left: auto;\n  }\n  .ds-nav__fold .ds-menu__list {\n    top: 100%;\n    left: var(--space-3);\n    right: var(--space-3);\n    width: auto;\n    max-width: none;\n  }\n  .ds-nav__bar {\n    flex-direction: row;\n    justify-content: space-between;\n  }\n}\n",
    "specimen.html": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>chronoskin: neubrutalism personal page specimen, link stack layout</title>\n<link rel=\"stylesheet\" href=\"tokens.css\">\n<link rel=\"stylesheet\" href=\"components.css\">\n</head>\n<body class=\"ds-page\" data-component=\"shell\">\n\n<header class=\"ds-nav\" data-component=\"nav\">\n  <p class=\"ds-nav__strip\">Two commission slots are open for the autumn. <a class=\"ds-nav__strip-link\" href=\"#hire\">Ask for one</a></p>\n  <nav class=\"ds-nav__bar\" aria-label=\"Main\">\n    <a class=\"ds-brand\" data-component=\"brand\" href=\"#home\">\n      <span class=\"ds-brand__mark\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linejoin=\"miter\" aria-hidden=\"true\"><polygon points=\"16.9,6.85 20,6.5 21.5,20 8,21.5 7.6,17.65 18,16.5\" fill=\"currentColor\" stroke=\"none\"/><polygon points=\"3,4.5 16.5,3 18,16.5 4.5,18\"/><circle cx=\"10.5\" cy=\"10.7\" r=\"2.5\" fill=\"currentColor\" stroke=\"none\"/></svg></span>\n      <span class=\"ds-brand__name\">chronoskin</span>\n    </a>\n<details class=\"ds-menu ds-nav__fold\" data-component=\"menu\">\n<summary class=\"ds-button ds-button--secondary ds-button--small ds-menu__trigger\">Menu</summary>\n<ul class=\"ds-menu__list\">\n<li class=\"ds-menu__item\"><a class=\"ds-menu__link ds-menu__link--view\" href=\"#home\">Hello</a></li>\n<li class=\"ds-menu__item\"><a class=\"ds-menu__link ds-menu__link--view\" href=\"#work\">Work</a></li>\n<li class=\"ds-menu__item\"><a class=\"ds-menu__link ds-menu__link--view\" href=\"#project\">Latest map</a></li>\n<li class=\"ds-menu__item\"><a class=\"ds-menu__link ds-menu__link--view\" href=\"#hire\">Hire me</a></li>\n<li class=\"ds-menu__item\"><a class=\"ds-menu__link ds-menu__link--view\" href=\"#letter\">Field notes</a></li>\n</ul>\n</details>\n    <ul class=\"ds-nav__links\">\n      <li><a class=\"ds-nav__link\" href=\"#home\">Hello</a></li>\n      <li><a class=\"ds-nav__link\" href=\"#work\">Work</a></li>\n      <li><a class=\"ds-nav__link\" href=\"#project\">Latest map</a></li>\n      <li><a class=\"ds-nav__link\" href=\"#hire\">Hire me</a></li>\n      <li><a class=\"ds-nav__link\" href=\"#letter\">Field notes</a></li>\n    </ul>\n  </nav>\n</header>\n\n<main class=\"ds-main\">\n<section class=\"ds-view ds-view--home\" id=\"home\">\n<div class=\"ds-column\">\n  <div class=\"ds-home\">\n    <div class=\"ds-stack\">\n      <section class=\"ds-hero\" data-component=\"hero\">\n        <div class=\"ds-hero__art\">\n          <span class=\"ds-portrait\" aria-hidden=\"true\"><span class=\"ds-portrait__head\"></span><span class=\"ds-portrait__body\"></span></span>\n        </div>\n        <div class=\"ds-hero__text\">\n          <span class=\"ds-badge ds-badge--success\">Open for commissions</span>\n          <h1 class=\"ds-hero__title\">Hand-drawn maps for people who like getting lost.</h1>\n          <p class=\"ds-hero__lead\">chronoskin is a one-person studio. I walk a place, then draw it with ink and too many colours, for festivals, trail clubs and small magazines.</p>\n          <div class=\"ds-hero__actions\">\n            <a class=\"ds-button ds-button--large\" href=\"#hire\">Commission a map &rarr;</a>\n            <a class=\"ds-button ds-button--secondary\" href=\"#work\">See the work</a>\n          </div>\n        </div>\n      </section>\n      <dl class=\"ds-stat\" data-component=\"stats\">\n        <div class=\"ds-stat__cell\">\n          <dt class=\"ds-stat__label\">Maps drawn</dt>\n          <dd class=\"ds-stat__value\">143</dd>\n        </div>\n        <div class=\"ds-stat__cell\">\n          <dt class=\"ds-stat__label\">Years at it</dt>\n          <dd class=\"ds-stat__value\">12</dd>\n        </div>\n        <div class=\"ds-stat__cell\">\n          <dt class=\"ds-stat__label\">Countries</dt>\n          <dd class=\"ds-stat__value\">9</dd>\n        </div>\n      </dl>\n    </div>\n\n    <div class=\"ds-stack\">\n      <ul class=\"ds-linkstack\">\n        <li><a class=\"ds-linkstack__link ds-linkstack__link--1\" href=\"#work\">\n          <span class=\"ds-linkstack__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" aria-hidden=\"true\"><path d=\"M3 6l6-2 6 2 6-2v14l-6 2-6-2-6 2z\"/><path d=\"M9 4v14M15 6v14\"/></svg></span>\n          <span class=\"ds-linkstack__main\"><span class=\"ds-linkstack__title\">The portfolio</span><span class=\"ds-linkstack__text\">Thirty-six maps, from one street to a whole coast.</span></span>\n          <span class=\"ds-linkstack__arrow\">&rarr;</span>\n        </a></li>\n        <li><a class=\"ds-linkstack__link ds-linkstack__link--2\" href=\"#project\">\n          <span class=\"ds-linkstack__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" aria-hidden=\"true\"><path d=\"M3 17c3 2 6 2 9 0s6-2 9 0\"/><path d=\"M5 13l1-6h12l1 6M12 7V3\"/></svg></span>\n          <span class=\"ds-linkstack__main\"><span class=\"ds-linkstack__title\">Latest: the island ferry map</span><span class=\"ds-linkstack__text\">Seven piers, four boats and one very patient harbour master.</span></span>\n          <span class=\"ds-linkstack__arrow\">&rarr;</span>\n        </a></li>\n        <li><a class=\"ds-linkstack__link ds-linkstack__link--3\" href=\"#hire\">\n          <span class=\"ds-linkstack__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" aria-hidden=\"true\"><path d=\"M4 20l4-1 11-11-3-3L5 16z\"/><path d=\"M14 7l3 3\"/></svg></span>\n          <span class=\"ds-linkstack__main\"><span class=\"ds-linkstack__title\">Commission a map</span><span class=\"ds-linkstack__text\">Rates, how long it takes and a short form.</span></span>\n          <span class=\"ds-linkstack__arrow\">&rarr;</span>\n        </a></li>\n        <li><a class=\"ds-linkstack__link ds-linkstack__link--4\" href=\"#letter\">\n          <span class=\"ds-linkstack__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\"/><path d=\"M3 6l9 7 9-7\"/></svg></span>\n          <span class=\"ds-linkstack__main\"><span class=\"ds-linkstack__title\">Field notes, a monthly letter</span><span class=\"ds-linkstack__text\">One sketch, one wrong turn, one place worth the detour.</span></span>\n          <span class=\"ds-linkstack__arrow\">&rarr;</span>\n        </a></li>\n      </ul>\n      <div class=\"ds-split ds-split--even\">\n        <div class=\"ds-stack\">\n          <h2 class=\"ds-label\">Lately</h2>\n          <ul class=\"ds-list\" data-component=\"list\">\n            <li class=\"ds-list__item\">\n              <div class=\"ds-list__main\">\n                <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">Ferry map goes to print</a></h3>\n                <p class=\"ds-list__text\">Four colours, 2,000 copies.</p>\n              </div>\n              <span class=\"ds-list__meta\">3 days ago</span>\n            </li>\n            <li class=\"ds-list__item\">\n              <div class=\"ds-list__main\">\n                <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#letter\">Field notes no. 31</a></h3>\n                <p class=\"ds-list__text\">On drawing fog.</p>\n              </div>\n              <span class=\"ds-list__meta\">Last week</span>\n            </li>\n            <li class=\"ds-list__item\">\n              <div class=\"ds-list__main\">\n                <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">Orchard trail, redrawn</a></h3>\n                <p class=\"ds-list__text\">The bridge moved, so did the map.</p>\n              </div>\n              <span class=\"ds-list__meta\">In March</span>\n            </li>\n          </ul>\n<div class=\"ds-carousel\" data-component=\"carousel\">\n<ul class=\"ds-carousel__track\">\n<li class=\"ds-carousel__slide\"><blockquote class=\"ds-carousel__quote\">\"People stop at the map before they stop at the stalls.\"</blockquote><p class=\"ds-carousel__who\"><span class=\"ds-avatar\" data-component=\"avatar\">NA</span> Noor A., festival office</p></li>\n<li class=\"ds-carousel__slide\"><blockquote class=\"ds-carousel__quote\">\"The only trail map nobody has folded wrong.\"</blockquote><p class=\"ds-carousel__who\"><span class=\"ds-avatar ds-avatar--2\" data-component=\"avatar\">JB</span> Jonas B., walking club</p></li>\n<li class=\"ds-carousel__slide\"><blockquote class=\"ds-carousel__quote\">\"We framed the proof.\"</blockquote><p class=\"ds-carousel__who\"><span class=\"ds-avatar ds-avatar--3\" data-component=\"avatar\">PC</span> Petra C., harbour office</p></li>\n</ul>\n<div class=\"ds-carousel__controls\"><button class=\"ds-carousel__arrow\" type=\"button\" aria-label=\"Previous\">&larr;</button><ol class=\"ds-carousel__dots\" aria-label=\"Quote 1 of 3\"><li class=\"ds-carousel__dot is-current\"></li><li class=\"ds-carousel__dot\"></li><li class=\"ds-carousel__dot\"></li></ol><button class=\"ds-carousel__arrow\" type=\"button\" aria-label=\"Next\">&rarr;</button></div>\n</div>\n        </div>\n        <div class=\"ds-stack\">\n          <h2 class=\"ds-label\">Now</h2>\n          <section class=\"ds-panel\" data-component=\"panel\">\n            <h3 class=\"ds-panel__title\">On the drawing table</h3>\n            <div class=\"ds-panel__body\">\n              <p>A walking map of a market town for its summer fair: forty stalls, three bandstands and a duck pond that insists on being in the middle.</p>\n              <p>Next free slot is in September.</p>\n              <a class=\"ds-link\" href=\"#hire\">How a commission works</a>\n            </div>\n          </section>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n</section>\n\n<section class=\"ds-view\" id=\"work\">\n<div class=\"ds-column\">\n  <section class=\"ds-page-header\" data-component=\"page-header\">\n    <ol class=\"ds-breadcrumb\" data-component=\"breadcrumb\" aria-label=\"Breadcrumb\">\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#home\">Hello</a></li>\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">Work</a></li>\n      <li class=\"ds-breadcrumb__item is-current\" aria-current=\"page\">All maps</li>\n    </ol>\n    <h1 class=\"ds-page-header__title\">Work</h1>\n    <p class=\"ds-page-header__lead\">Thirty-six maps I would still put my name on. Six to a page.</p>\n    <div class=\"ds-page-header__actions\">\n      <a class=\"ds-button\" href=\"#hire\">Commission one</a>\n    </div>\n  </section>\n  <ul class=\"ds-tabs\" data-component=\"tabs\" role=\"tablist\">\n    <li class=\"ds-tabs__item\"><a class=\"ds-tabs__tab is-current\" href=\"#work\" role=\"tab\" aria-selected=\"true\">All</a></li>\n    <li class=\"ds-tabs__item\"><a class=\"ds-tabs__tab\" href=\"#work\" role=\"tab\">Towns</a></li>\n    <li class=\"ds-tabs__item\"><a class=\"ds-tabs__tab\" href=\"#work\" role=\"tab\">Trails</a></li>\n    <li class=\"ds-tabs__item\"><a class=\"ds-tabs__tab\" href=\"#work\" role=\"tab\">Print</a></li>\n  </ul>\n  <ul class=\"ds-grid\" data-component=\"grid\">\n    <li class=\"ds-grid__cell ds-grid__cell--1\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><path d=\"M4 70c20-14 34 10 54-2s30-30 50-22 28 20 48 8\"/><path d=\"M40 20h24v18H40zM104 62h22v16h-22z\"/><circle cx=\"84\" cy=\"30\" r=\"7\" fill=\"currentColor\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">The island ferry map</a></h2>\n        <p class=\"ds-grid__text\">Seven piers and the four boats between them, for the harbour office.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge ds-badge--alt\">New</span><span class=\"ds-badge ds-badge--plain\">2025</span></div>\n      </div>\n    </li>\n    <li class=\"ds-grid__cell ds-grid__cell--2\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><path d=\"M10 90V40l30-24 30 24v50M90 90V54h56v36\"/><path d=\"M4 90h152M32 90V66h16v24M104 68h10M126 68h10\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">Market town, summer fair</a></h2>\n        <p class=\"ds-grid__text\">Forty stalls, three bandstands and a duck pond in the middle.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge\">On the table</span><span class=\"ds-badge ds-badge--plain\">2025</span></div>\n      </div>\n    </li>\n    <li class=\"ds-grid__cell ds-grid__cell--3\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><path d=\"M6 86l34-52 22 30 20-44 30 48 16-20 26 38z\"/><path d=\"M20 96c30-8 90-8 120 0\" stroke-dasharray=\"6 8\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">Three passes in four days</a></h2>\n        <p class=\"ds-grid__text\">A trail map for a walking club, with every hut and every bad idea.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge ds-badge--success\">Prints available</span><span class=\"ds-badge ds-badge--plain\">2024</span></div>\n      </div>\n    </li>\n    <li class=\"ds-grid__cell ds-grid__cell--4\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><circle cx=\"80\" cy=\"50\" r=\"38\"/><path d=\"M80 12v76M42 50h76M54 24c14 12 38 12 52 0M54 76c14-12 38-12 52 0\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">Where the oranges go</a></h2>\n        <p class=\"ds-grid__text\">An editorial map of one crate's journey, for a food magazine.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge ds-badge--warning\">Few prints left</span><span class=\"ds-badge ds-badge--plain\">2024</span></div>\n      </div>\n    </li>\n    <li class=\"ds-grid__cell ds-grid__cell--2\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><path d=\"M8 20h144v60H8z\"/><path d=\"M8 50h50v30M58 50V20M100 20v36h52M100 56v24\"/><circle cx=\"126\" cy=\"38\" r=\"6\" fill=\"currentColor\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">One street, every door</a></h2>\n        <p class=\"ds-grid__text\">Sixty-two front doors drawn in order, for a neighbourhood festival.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge ds-badge--danger\">Sold out</span><span class=\"ds-badge ds-badge--plain\">2023</span></div>\n      </div>\n    </li>\n    <li class=\"ds-grid__cell ds-grid__cell--1\">\n      <div class=\"ds-grid__art\"><svg viewBox=\"0 0 160 100\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" aria-hidden=\"true\"><path d=\"M6 30c16-12 28 12 44 0s28 12 44 0 28 12 44 0 12-6 16-6M6 56c16-12 28 12 44 0s28 12 44 0 28 12 44 0 12-6 16-6M6 82c16-12 28 12 44 0s28 12 44 0 28 12 44 0 12-6 16-6\"/></svg></div>\n      <div class=\"ds-grid__body\">\n        <h2 class=\"ds-grid__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">Tide table, drawn</a></h2>\n        <p class=\"ds-grid__text\">A year of high water as one long picture for a sailing school.</p>\n        <div class=\"ds-badges\"><span class=\"ds-badge ds-badge--success\">Prints available</span><span class=\"ds-badge ds-badge--plain\">2023</span></div>\n      </div>\n    </li>\n  </ul>\n  <div class=\"ds-badges ds-badges--key\" data-component=\"badge\">\n    <span class=\"ds-note\">On the cards:</span>\n    <span class=\"ds-badge\">On the table</span>\n    <span class=\"ds-badge ds-badge--alt\">New</span>\n    <span class=\"ds-badge ds-badge--plain\">Year</span>\n    <span class=\"ds-badge ds-badge--success\">Prints available</span>\n    <span class=\"ds-badge ds-badge--warning\">Few prints left</span>\n    <span class=\"ds-badge ds-badge--danger\">Sold out</span>\n  </div>\n  <ul class=\"ds-pagination\" data-component=\"pagination\" aria-label=\"Pages\">\n    <li><a class=\"ds-pagination__link is-disabled\" href=\"#work\" aria-disabled=\"true\">&larr; Newer</a></li>\n    <li><a class=\"ds-pagination__link is-current\" href=\"#work\" aria-current=\"page\">1</a></li>\n    <li><a class=\"ds-pagination__link\" href=\"#work\">2</a></li>\n    <li><a class=\"ds-pagination__link\" href=\"#work\">3</a></li>\n    <li><a class=\"ds-pagination__link\" href=\"#work\">6</a></li>\n    <li><a class=\"ds-pagination__link\" href=\"#work\">Older &rarr;</a></li>\n  </ul>\n</div>\n</section>\n\n<section class=\"ds-view\" id=\"project\">\n<div class=\"ds-column\">\n  <section class=\"ds-page-header\">\n    <ol class=\"ds-breadcrumb\" aria-label=\"Breadcrumb\">\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#home\">Hello</a></li>\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">Work</a></li>\n      <li class=\"ds-breadcrumb__item is-current\" aria-current=\"page\">The island ferry map</li>\n    </ol>\n    <h1 class=\"ds-page-header__title\">The island ferry map</h1>\n    <p class=\"ds-page-header__lead\">Seven piers, four boats and a timetable that only makes sense as a picture.</p>\n  </section>\n  <div class=\"ds-split\">\n    <div class=\"ds-stack\">\n      <div class=\"ds-sheet\">\n        <article class=\"ds-prose\" data-component=\"typography\">\n          <h1>How it was drawn</h1>\n          <p>The harbour office wanted one sheet a visitor could read on a windy pier. I rode every boat twice, once looking forward and once looking back.</p>\n          <h2>What went on the sheet</h2>\n          <p>Each pier gets its own colour and each boat a line in that colour. The file that keeps them apart is called <code>piers.txt</code>, and it is the most useful thing I made all year.</p>\n          <ul>\n            <li>North is where the big crane is, not where the compass says</li>\n            <li>Crossing times are drawn as distance, so a slow boat looks far</li>\n            <li>The cafe that sells tickets is marked twice, on purpose</li>\n          </ul>\n          <h3>What stayed off</h3>\n          <p>Depths, buoys and anything a sailor needs. <strong>This is a map for people with ice cream</strong>, and it says so in the corner.</p>\n        </article>\n      </div>\n      <div class=\"ds-stack\">\n        <h2 class=\"ds-label\">More like this</h2>\n        <ul class=\"ds-links\" data-component=\"links\">\n          <li><a class=\"ds-link\" href=\"#work\">Tide table, drawn</a></li>\n          <li><a class=\"ds-link is-visited\" href=\"#work\">Three passes in four days</a></li>\n          <li><a class=\"ds-link is-hover\" href=\"#work\">One street, every door</a></li>\n          <li><a class=\"ds-link is-active\" href=\"#hire\">Commission your own</a></li>\n        </ul>\n      </div>\n    </div>\n    <div class=\"ds-stack\">\n      <aside class=\"ds-sidebar\" data-component=\"sidebar\">\n        <h2 class=\"ds-sidebar__title\">About this map</h2>\n        <ul class=\"ds-sidebar__list\">\n          <li class=\"ds-sidebar__item\">For <span>The harbour office</span></li>\n          <li class=\"ds-sidebar__item\">Size <span>60 by 40 cm, folded</span></li>\n          <li class=\"ds-sidebar__item\">Drawn in <span>Five weeks</span></li>\n          <li class=\"ds-sidebar__item\">Prints <span class=\"ds-badge ds-badge--success\">Available</span></li>\n          <li class=\"ds-sidebar__item\"><a class=\"ds-link\" href=\"#work\">All town maps</a></li>\n          <li class=\"ds-sidebar__item\"><a class=\"ds-link\" href=\"#letter\">The field note about it</a></li>\n        </ul>\n      </aside>\n      <section class=\"ds-panel\">\n        <h2 class=\"ds-panel__title\">Want one of your place?</h2>\n        <div class=\"ds-panel__body\">\n          <p>A map like this takes four to six weeks and starts with a walk.</p>\n          <a class=\"ds-button ds-button--small\" href=\"#hire\">See the rates</a>\n<div class=\"ds-progress ds-follow\" data-component=\"progress\"><p class=\"ds-progress__label\"><span>Autumn slots taken</span><span>4 of 6</span></p><span class=\"ds-progress__track\"><span class=\"ds-progress__bar ds-progress__bar--70\"></span></span></div>\n        </div>\n      </section>\n    </div>\n  </div>\n</div>\n</section>\n\n<section class=\"ds-view\" id=\"hire\">\n<div class=\"ds-column\">\n  <section class=\"ds-page-header\">\n    <ol class=\"ds-breadcrumb\" aria-label=\"Breadcrumb\">\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#home\">Hello</a></li>\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#hire\">Hire me</a></li>\n      <li class=\"ds-breadcrumb__item is-current\" aria-current=\"page\">Rates and enquiry</li>\n    </ol>\n    <h1 class=\"ds-page-header__title\">Hire me</h1>\n    <p class=\"ds-page-header__lead\">What a map costs, how long it takes, and a form that goes straight to my desk.</p>\n  </section>\n  <div class=\"ds-stack\" data-component=\"notice\">\n    <div class=\"ds-notice\" role=\"status\">\n      <strong class=\"ds-notice__title\">Booked until August</strong>\n      <p class=\"ds-notice__text\">Two slots are open from September. Small maps can sometimes jump the queue.</p>\n    </div>\n    <div class=\"ds-notice ds-notice--error\" role=\"alert\">\n      <strong class=\"ds-notice__title\">Not sent yet</strong>\n      <p class=\"ds-notice__text\">Your enquiry is missing a deadline. Add one below and send it again.</p>\n    </div>\n  </div>\n  <div class=\"ds-split ds-split--even\">\n    <div class=\"ds-stack\">\n      <section class=\"ds-panel ds-panel--flush\">\n        <h2 class=\"ds-panel__title\">Rates</h2>\n        <div class=\"ds-panel__body\">\n          <table class=\"ds-table\" data-component=\"table\">\n            <thead>\n              <tr><th>Kind of map</th><th class=\"ds-table__extra\">Takes</th><th class=\"ds-table__num\">From</th></tr>\n            </thead>\n            <tbody>\n              <tr><td>One street or square</td><td class=\"ds-table__extra\">2 weeks</td><td class=\"ds-table__num\">900</td></tr>\n              <tr><td>Festival or fair site</td><td class=\"ds-table__extra\">3 weeks</td><td class=\"ds-table__num\">1,600</td></tr>\n              <tr class=\"is-current\"><td>Town or island</td><td class=\"ds-table__extra\">5 weeks</td><td class=\"ds-table__num\">2,800</td></tr>\n              <tr><td>Trail, up to four days</td><td class=\"ds-table__extra\">6 weeks</td><td class=\"ds-table__num\">3,400</td></tr>\n              <tr><td>Editorial, one page</td><td class=\"ds-table__extra\">1 week</td><td class=\"ds-table__num\">650</td></tr>\n            </tbody>\n          </table>\n        </div>\n      </section>\n      <p class=\"ds-note\">Prices include one round of changes and the right to print the map as often as you like. The walk is charged at cost.</p>\n      <div class=\"ds-overlay\">\n        <div class=\"ds-dialog\" data-component=\"dialog\" role=\"dialog\" aria-labelledby=\"dlg-title\">\n          <div class=\"ds-dialog__bar\">\n            <h2 class=\"ds-dialog__title\" id=\"dlg-title\">Clear the form?</h2>\n            <a class=\"ds-dialog__close\" href=\"#hire\" aria-label=\"Close\">&times;</a>\n          </div>\n          <div class=\"ds-dialog__body\">\n            <p>Everything you typed goes, including the draft saved on this device.</p>\n          </div>\n          <div class=\"ds-dialog__actions\">\n            <a class=\"ds-button ds-button--secondary\" href=\"#hire\">Keep writing</a>\n            <button class=\"ds-button ds-button--danger\" type=\"button\">Clear it</button>\n          </div>\n        </div>\n      </div>\n<div class=\"ds-accordion\" data-component=\"accordion\">\n<details class=\"ds-accordion__item\" open><summary class=\"ds-accordion__head\">Do you visit the place?</summary><div class=\"ds-accordion__body\"><p>Always. I walk it at least twice before I draw.</p></div></details>\n<details class=\"ds-accordion__item\"><summary class=\"ds-accordion__head\">Who owns the map?</summary><div class=\"ds-accordion__body\"><p>You may print it as often as you like. I keep the drawing.</p></div></details>\n<details class=\"ds-accordion__item\"><summary class=\"ds-accordion__head\">Can it be changed later?</summary><div class=\"ds-accordion__body\"><p>One round of changes is in the price.</p></div></details>\n</div>\n    </div>\n    <section class=\"ds-panel ds-panel--plain\">\n      <h2 class=\"ds-panel__title\">Tell me about the place</h2>\n      <div class=\"ds-panel__body\">\n        <form class=\"ds-form\" data-component=\"form\">\n          <div class=\"ds-form__field\">\n            <label class=\"ds-form__label\" for=\"f-name\">Your name</label>\n            <input class=\"ds-form__control\" id=\"f-name\" type=\"text\" value=\"Ines Carvalho\">\n          </div>\n          <div class=\"ds-form__field\">\n            <label class=\"ds-form__label\" for=\"f-kind\">Kind of map</label>\n            <select class=\"ds-form__control\" id=\"f-kind\">\n              <option>Town or island</option>\n              <option>Festival or fair site</option>\n              <option>Trail, up to four days</option>\n            </select>\n          </div>\n          <div class=\"ds-form__field\">\n            <label class=\"ds-form__label\" for=\"f-date\">Needed by</label>\n            <input class=\"ds-form__control is-invalid\" id=\"f-date\" type=\"text\" value=\"soon\" aria-invalid=\"true\" aria-describedby=\"f-date-err\">\n            <p class=\"ds-form__error\" id=\"f-date-err\">Give a month and a year, such as October 2025.</p>\n          </div>\n          <div class=\"ds-form__field\">\n            <label class=\"ds-form__label\" for=\"f-note\">The place, in a few lines</label>\n            <textarea class=\"ds-form__control ds-form__control--area\" id=\"f-note\">A fishing village with one road in, a chapel on the hill and a regatta every August.</textarea>\n            <p class=\"ds-form__hint\">What should a stranger not miss?</p>\n          </div>\n          <label class=\"ds-form__check\"><input class=\"ds-form__checkbox\" type=\"checkbox\" checked> Send me the field notes too</label>\n<div class=\"ds-switch-row\"><label class=\"ds-switch\" data-component=\"switch\"><input class=\"ds-switch__input\" type=\"checkbox\" checked><span class=\"ds-switch__track\"></span><span>I need it printed too</span></label><span class=\"ds-tooltip\" data-component=\"tooltip\"><button class=\"ds-tooltip__trigger\" type=\"button\" aria-describedby=\"tip-1\">?</button><span class=\"ds-tooltip__tip\" id=\"tip-1\" role=\"tooltip\">Printing is quoted apart, by the sheet.</span></span></div>\n          <div class=\"ds-form__foot\" data-component=\"buttons\">\n            <button class=\"ds-button\" type=\"button\">Send enquiry</button>\n            <button class=\"ds-button ds-button--secondary\" type=\"button\">Save draft</button>\n            <button class=\"ds-button ds-button--danger\" type=\"button\">Clear form</button>\n            <button class=\"ds-button\" type=\"button\" disabled>Attach a sketch</button>\n          </div>\n        </form>\n      </div>\n    </section>\n  </div>\n</div>\n</section>\n\n<section class=\"ds-view\" id=\"letter\">\n<div class=\"ds-column\">\n  <section class=\"ds-page-header\">\n    <ol class=\"ds-breadcrumb\" aria-label=\"Breadcrumb\">\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#home\">Hello</a></li>\n      <li class=\"ds-breadcrumb__item\"><a class=\"ds-link ds-link--quiet\" href=\"#letter\">Field notes</a></li>\n      <li class=\"ds-breadcrumb__item is-current\" aria-current=\"page\">Sign up</li>\n    </ol>\n    <h1 class=\"ds-page-header__title\">Field notes</h1>\n    <p class=\"ds-page-header__lead\">A letter on the first Sunday of the month. One sketch, one wrong turn, one place worth the detour.</p>\n  </section>\n  <section class=\"ds-signup\">\n    <div>\n      <h2 class=\"ds-label\">Get the next one</h2>\n      <p class=\"ds-signup__text\">1,840 people read it. Nobody has ever been sold anything in it except, twice, a tea towel.</p>\n    </div>\n    <form class=\"ds-signup__form\">\n      <label class=\"ds-form__label\" for=\"f-mail\">Your email address</label>\n      <div class=\"ds-signup__line\">\n        <input class=\"ds-form__control\" id=\"f-mail\" type=\"email\" placeholder=\"you@example.org\">\n        <button class=\"ds-button\" type=\"button\">Sign me up</button>\n      </div>\n      <p class=\"ds-form__hint\">One letter a month. Leaving takes one click.</p>\n    </form>\n  </section>\n  <div class=\"ds-split\">\n    <div class=\"ds-stack\">\n      <h2 class=\"ds-label\">Past letters</h2>\n      <ul class=\"ds-list\">\n        <li class=\"ds-list__item\">\n          <div class=\"ds-list__main\">\n            <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#project\">No. 31: On drawing fog</a></h3>\n            <p class=\"ds-list__text\">How to show a harbour you could not see.</p>\n          </div>\n          <span class=\"ds-list__meta\">April</span>\n        </li>\n        <li class=\"ds-list__item\">\n          <div class=\"ds-list__main\">\n            <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">No. 30: The bridge that moved</a></h3>\n            <p class=\"ds-list__text\">Redrawing a trail after the river changed its mind.</p>\n          </div>\n          <span class=\"ds-list__meta\">March</span>\n        </li>\n        <li class=\"ds-list__item\">\n          <div class=\"ds-list__main\">\n            <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">No. 29: Sixty-two doors</a></h3>\n            <p class=\"ds-list__text\">A street, a folding stool and a lot of tea.</p>\n          </div>\n          <span class=\"ds-list__meta\">February</span>\n        </li>\n        <li class=\"ds-list__item\">\n          <div class=\"ds-list__main\">\n            <h3 class=\"ds-list__title\"><a class=\"ds-link ds-link--quiet\" href=\"#work\">No. 28: North is a suggestion</a></h3>\n            <p class=\"ds-list__text\">Why most of my maps point at something else.</p>\n          </div>\n          <span class=\"ds-list__meta\">January</span>\n        </li>\n      </ul>\n    </div>\n    <div class=\"ds-stack\">\n      <h2 class=\"ds-label\">This month</h2>\n      <div class=\"ds-empty\" data-component=\"empty\">\n        <h3 class=\"ds-empty__title\">No letter yet</h3>\n        <p class=\"ds-empty__text\">May's field note is still out walking. It lands on the first Sunday.</p>\n        <a class=\"ds-button ds-button--small\" href=\"#project\">Read the latest map story</a>\n      </div>\n    </div>\n  </div>\n</div>\n</section>\n</main>\n\n<footer class=\"ds-footer\" data-component=\"footer\">\n  <p class=\"ds-footer__brand\">chronoskin</p>\n  <ul class=\"ds-footer__list\">\n    <li><a class=\"ds-footer__link\" href=\"#work\">Work</a></li>\n    <li><a class=\"ds-footer__link\" href=\"#hire\">Hire me</a></li>\n    <li><a class=\"ds-footer__link\" href=\"#letter\">Field notes</a></li>\n    <li><a class=\"ds-footer__link\" href=\"#home\">Back to the top</a></li>\n  </ul>\n  <p class=\"ds-footer__legal\">Specimen page. All names and figures are placeholders.</p>\n</footer>\n\n</body>\n</html>\n",
    "style.json": "{\n  \"id\": \"v1.neubrutalism.blog.s06.p05.t03.u05\",\n  \"library\": \"2026.10.09-1346\",\n  \"era\": {\n    \"slug\": \"neubrutalism\",\n    \"years\": [\n      2021,\n      2026\n    ]\n  },\n  \"archetype\": \"blog\",\n  \"mode\": \"mix\",\n  \"markup\": \"modern\",\n  \"viewport\": {\n    \"width\": 1440,\n    \"fluid\": true,\n    \"responsive\": true\n  },\n  \"source\": \"https://chrono.skin/s/v1-nb-6535\",\n  \"short\": \"v1-nb-6535\"\n}\n",
    "tokens.css": "/* @part palette */\n:root {\n  --color-page: #f0eefc;\n  --color-canvas: #f0eefc;\n  --color-surface: #ffffff;\n  --color-surface-alt: #feecfb;\n  --color-surface-strong: #c084fc;\n  --color-bar: #ffffff;\n  --color-bar-text: #020617;\n  --color-bar-alt: #581c87;\n  --color-bar-alt-text: #ffffff;\n  --color-inverse: #020617;\n  --color-inverse-text: #f0eefc;\n  --color-text: #020617;\n  --color-text-muted: #5c5c66;\n  --color-heading: #020617;\n  --color-heading-alt: #020617;\n  --color-link: #581c87;\n  --color-link-quiet: #020617;\n  --color-link-visited: #581c87;\n  --color-link-hover: #020617;\n  --color-link-active: #020617;\n  --color-border: #020617;\n  --color-border-strong: #020617;\n  --color-border-muted: #b6ace4;\n  --color-accent: #22d3ee;\n  --color-accent-text: #020617;\n  --color-accent-alt: #facc15;\n  --color-fill-1: #c084fc;\n  --color-fill-2: #22d3ee;\n  --color-fill-3: #fbb1c4;\n  --color-fill-4: #facc15;\n  --color-button: #5423e7;\n  --color-button-text: #ffffff;\n  --color-button-hover-text: #ffffff;\n  --color-button-secondary: #ffffff;\n  --color-button-secondary-text: #020617;\n  --color-input: #ffffff;\n  --color-input-text: #020617;\n  --color-input-border: #020617;\n  --color-disabled: #e7e7e4;\n  --color-disabled-text: #5c5c66;\n  --color-danger: #f53d6b;\n  --color-danger-surface: #fbb1c4;\n  --color-success: #22c55e;\n  --color-warning: #ff9500;\n  --color-notice: #b6ace4;\n  --color-notice-text: #020617;\n  --color-focus: #5423e7;\n  --color-shadow: #020617;\n  --color-overlay: rgb(88 28 135 / 0.8);\n}\n\n/* @part type */\n:root {\n  --font-body: \"Public Sans\", \"DM Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  --font-heading: \"Public Sans\", \"DM Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  --font-ui: \"Public Sans\", \"DM Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  --text-base: 16px;\n  --text-small: 14px;\n  --text-ui: 16px;\n  --text-large: 24px;\n  --text-display: 72px;\n  --text-h1: 48px;\n  --text-h2: 36px;\n  --text-h3: 22px;\n  --line-body: 1.5;\n  --line-heading: 1.1;\n  --line-display: 1.1;\n  --weight-body: 500;\n  --weight-bold: 700;\n  --weight-heading: 800;\n  --weight-display: 900;\n  --weight-ui: 600;\n  --heading-transform: none;\n  --heading-tracking: 0;\n  --display-tracking: 0;\n  --figure-shift: 0em;\n  --ui-transform: none;\n  --link-decoration: underline;\n  --link-decoration-hover: none;\n  --link-decoration-quiet: none;\n}\n\n/* @part surface */\n:root {\n  --border-width: 2px;\n  --border-width-strong: 4px;\n  --border-style: solid;\n  --radius-control: 10px;\n  --radius-panel: 14px;\n  --radius-pill: 9999px;\n  --radius-page: 20px;\n  --shadow-panel: 6px 6px 0 0 var(--color-shadow);\n  --shadow-control: 3px 3px 0 0 var(--color-shadow);\n  --shadow-control-hover: 1px 1px 0 0 var(--color-shadow);\n  --shadow-control-pressed: 0 0 0 0 var(--color-shadow);\n  --shadow-dialog: 10px 10px 0 0 var(--color-shadow);\n  --shadow-text: none;\n  --fill-page:\n    radial-gradient(circle, var(--color-border-muted) 1.5px, transparent 2px) 0 0 / 24px 24px,\n    var(--color-page);\n  --fill-bar: var(--color-bar);\n  --fill-bar-alt: var(--color-bar-alt);\n  --fill-inverse: var(--color-inverse);\n  --fill-accent: var(--color-accent);\n  --fill-panel: var(--color-surface);\n  --fill-button: var(--color-button);\n  --fill-button-hover: var(--color-button);\n  --fill-button-secondary: var(--color-button-secondary);\n  --fill-input: var(--color-input);\n  --focus-ring: 3px solid var(--color-focus);\n  --transition: transform 0.12s ease, box-shadow 0.12s ease;\n  --backdrop-blur: 0px;\n}\n"
  }
}
