{
  "id": "v1-tm-1111",
  "long_id": "v1.terminal.landing.s01.p01.t01.u01",
  "name": "Terminal, a command-line tool's home page",
  "era": {
    "slug": "terminal",
    "code": "tm",
    "name": "Terminal",
    "years": [
      2015,
      2026
    ],
    "description": "The text-terminal look of 2015 to 2026: a monospace face for everything, bright text on a dark screen, boxes and rules drawn with borders like character frames, prompts and cursors, status lines and key hints instead of buttons with chrome."
  },
  "archetype": "landing",
  "mode": "pure",
  "viewport": {
    "width": 1280,
    "fluid": false
  },
  "summary": "This is the home page of a command-line program as its authors built it between 2015 and 2026: the page dresses as the terminal the program runs in. One monospace face sets everything, bright text stands on a dark screen, boxes are drawn with one-cell lines whose titles are cut into the top edge, and the product is shown as a typed session with a prompt and a block cursor instead of a screenshot. It was the look of project pages for shell tools, terminal emulators and text-mode libraries, of text-only front ends, and of the personal sites of the people who wrote them.",
  "url": "https://chrono.skin/s/v1-tm-1111",
  "preview_url": "https://chrono.skin/s/v1-tm-1111/specimen.html",
  "files": {
    "STYLE.md": "# Terminal, a command-line tool's home page\n\n## Summary\n\nThis is the home page of a command-line program as its authors built it between 2015 and 2026: the page dresses as the terminal the program runs in. One monospace face sets everything, bright text stands on a dark screen, boxes are drawn with one-cell lines whose titles are cut into the top edge, and the product is shown as a typed session with a prompt and a block cursor instead of a screenshot. It was the look of project pages for shell tools, terminal emulators and text-mode libraries, of text-only front ends, and of the personal sites of the people who wrote them.\n\n## Layout\n\n- The page is designed for a 1280px window and does not stretch: `.ds-wrap` is one centred column of at most `--size-page` (1080px) on `--color-canvas`, between two faint upright rules in `--color-border-muted`, with `3ch` of side padding. It holds the header, the views and the footer and is at least as tall as the window, so the footer rests at the foot.\n- `.ds-nav` is one line on the canvas with a rule below: the `.ds-brand` at the left and `.ds-nav__list` at the right, whose `.ds-nav__link` items are words in brackets; the current one is inverse video. `.ds-nav__version` is a muted last item. There is no sidebar on the home view.\n- The home view stacks, top to bottom: `.ds-hero`, two columns (5 to 6): the claim, a lead, the install line and two buttons at the left, and `.ds-term`, a framed terminal window with a typed session, at the right; then `.ds-section` blocks `--space-4` (40px) apart, each opened by a `.ds-section__title` rule: the framed `.ds-stats` row, the framed table of commands, the `.ds-grid` of four cells, and `.ds-cols` (3 to 2) with the news list beside a panel.\n- Inner pages have no hero. They open with the `.ds-breadcrumb` as a path, then `.ds-page-header`; the work follows in `.ds-cols`: `--side` puts a `--size-side` (240px) column of sidebar frames at the left of the text (the manual), the plain form is 3 to 2 (changelog, download), `--even` is two equal columns. `.ds-stack` piles frames `--space-3` apart in a column. Tabs sit directly above what they switch, inside the main column.\n- Views. The specimen is one small site with four views, one showing at a time; header and footer are written once around them. `home` is the landing page. `docs` is a page of the manual: contents at the left, notices, running text, tabs over an install listing, see-also links, pagination. `changelog` is the table of releases under tabs with its pagination, beside the legend of badges, the empty state of the unreleased part and a note on upgrading. `download` is the framed table of files, the release-mail form with its error and its four buttons, the confirmation dialog and build notes. A view is `<section class=\"ds-view\" id=\"...\">`; links between views are plain `href=\"#id\"`.\n- Spacing scale, in quarters and multiples of one 20px text line: `--space-1` 5px is the vertical padding of buttons, inputs, table cells and tabs; `--space-2` 10px the padding above the text in a frame, the gap between a rule and what follows, between list rows and between buttons that wrap; `--space-3` 20px the gap between paragraphs, between frames in a stack and under a page header; `--space-4` 40px the gap between sections and above the footer; `--space-5` 60px is kept for a break larger than a section. Horizontal steps are character cells written in `ch`.\n- Fixed sizes: `--size-label` 150px the label column of a form, `--size-field` 420px a text input, `--size-date` 100px the date column of the list, `--size-dialog` 440px a dialog.\n- Below 720px there is one column: the hero's terminal goes under its text and scrolls sideways inside itself, columns stack with the sidebar first, the stats row and the grid become two by two, form labels sit above their fields, list dates sit above their entries, and table cells marked `.ds-table__extra` are left out. The page never scrolls sideways.\n\n## Typography and colour roles\n\n- One face for everything: `--font-body`, `--font-heading`, `--font-ui` and `--font-mono` are the same monospace stack (\"JetBrains Mono\", \"Fira Code\", \"DejaVu Sans Mono\", Menlo, Consolas, monospace). Weights are `--weight-body` 400 and bold 700 for headings, typed commands and the brand; the references used JetBrains Mono, Menlo and other system monospace faces. Nothing is tracked: `--heading-tracking` and `--display-tracking` are 0.\n- Sizes stay close to one size, as on a screen of character cells: `--text-base` 15px with `--line-body` 1.4 is all running text, `--text-ui` 15px navigation, buttons, inputs, tabs and pagination, `--text-small` 13px meta lines, hints, badges, code blocks and the status line, `--text-large` 17px the hero's lead and the brand name. Headings are told apart by weight and colour more than by size: `--text-display` 30px is the hero title only, `--text-h1` 22px a page title and the first heading of running text, `--text-h2` 15px section rules and second headings, `--text-h3` 15px frame titles, grid titles and third headings. `--heading-transform` is uppercase, `--ui-transform` is none.\n- A green phosphor screen: every colour is a step of one green, with a yellow-green for accents; only errors and warnings leave the family.\n- The screen: `--color-page` #000000 is the window, `--color-canvas` #030a05 the sheet the text stands on, `--color-surface` #061208 the inside of frames and table rows, `--color-surface-alt` #0a1a0d alternate rows, code blocks and the install line, `--color-surface-strong` #0f2614 group rows and inline code. `--color-text` #38c85a is running text, `--color-text-muted` #2a8f44 dates, counts, hints and the brackets of fields, `--color-heading` #9df5ae headings, typed commands and figures, `--color-heading-alt` #d7ff5f frame titles, third headings and tags.\n- Links: `--color-link` #9df5ae, `--color-link-quiet` #38c85a for navigation, breadcrumb, tabs and sidebar links, `--color-link-visited` #5fa87a, `--color-link-hover` #e8f0e8, `--color-link-active` #d7ff5f. `--link-decoration` is underline for links in text and titles, `--link-decoration-quiet` none for navigation, and every link takes `--link-decoration-hover` (underline) when hovered. A link may also be marked by brackets (`.ds-link--bracket`).\n- Bars: `--color-bar` #38c85a with `--color-bar-text` #000000 is the head row of a table and, where a layout has one, the menu line and the labels of the key bar. `--color-bar-alt` #0f2614 with `--color-bar-alt-text` #6fe38a is the status line at the foot. `--color-inverse` #9df5ae with `--color-inverse-text` #000000 is inverse video: the current navigation link, tab, page number and sidebar link, the selected table row, a text selection.\n- Lines: `--color-border` #1f6b33 at `--border-width` 1px `--border-style` solid draws every frame and rule; `--color-border-strong` #38c85a at `--border-width-strong` 2px is the rule under a page header, the left edge of a notice and the frame of a dialog; `--color-border-muted` #12401f parts rows inside a frame and boxes the empty state.\n- Accents: `--color-accent` #d7ff5f with `--color-accent-text` #000000 is the count badge; `--color-accent-alt` #5fd7af is the prompt sign and flag letters. `--color-fill-1` to `--color-fill-4` (#061208, #0a1a0d, #0f2614, #0a1a0d) are the four grid cells. Status words are text in brackets: `--color-success` #5fff00, `--color-warning` #ffd75f, `--color-danger` #ff5f5f; meters use the first two.\n- Controls: the primary button is `--color-button` #38c85a with `--color-button-text` #000000; the secondary button is `--fill-button-secondary` with `--color-button-secondary-text` #9df5ae and a frame in `--color-border`; fields are `--fill-input` with `--color-input-text` #9df5ae and a line in `--color-input-border` #1f6b33; disabled is `--color-disabled` #0a1a0d with `--color-disabled-text` #1f6b33. The notice is `--color-notice` #0a1a0d with `--color-notice-text` #9df5ae, the error notice `--color-danger-surface` #1a0505 with `--color-danger`. `--color-overlay` #0a1a0d is the block a dialog stands on; `--color-focus` #d7ff5f is the focus outline.\n- Surface: `--fill-button-secondary` and `--fill-input` are transparent, so secondary buttons and fields are drawn on whatever they stand on; `--fill-button-hover` lightens the button (70% of it over white); `--fill-panel` is `--color-surface`. There is no box shadow at all (`--shadow-panel`, `--shadow-control` and its hover and pressed forms and `--shadow-dialog` are none). `--shadow-text` is the phosphor glow, a 4px bloom of the accent colour at 30%, used on the hero title, page titles, figures, typed commands and the brand name; keep it this faint. All four radii are 0 and `--backdrop-blur` is 0px. `--focus-ring` is 1px solid var(--color-focus); `--transition` is none: states change at once. The only motion is the blinking `.ds-cursor`, and only under `prefers-reduced-motion: no-preference`.\n- The era's rule for which text stands on which fill (all three layouts keep it, so any palette works with any layout): `--color-text`, `--color-text-muted`, the two heading colours, every link colour and the three status colours stand on `--fill-page`, `--color-canvas`, the three surfaces, `--fill-panel` and the four fills, and on nothing else. `--color-bar-text` only on `--fill-bar`; `--color-bar-alt-text` only on `--fill-bar-alt`; `--color-inverse-text` only on `--fill-inverse`; `--color-accent-text` only on `--fill-accent`; `--color-button-text` and `--color-button-hover-text` only on `--fill-button` and its hover; `--color-notice-text` only on `--color-notice`; `--color-danger` also on `--color-danger-surface`; `--color-disabled-text` on `--color-disabled`. Two tokens must read in two places, because a surface set may leave a control unfilled: `--color-button-secondary-text` on `--fill-button-secondary` and on the canvas and surfaces, `--color-input-text` on `--fill-input` and on the canvas and surfaces. Where the navigation stands on `--fill-bar`, its current item is a hole in the bar: `--color-canvas` with `--color-heading`. Nothing but a button, a badge or a key label stands on a bar or an inverse block.\n- One-off sizes written with `calc()` or `ch`: a frame title is lifted by half of `--text-h3` times `--line-body` so that the frame's top line runs through it; the brand tile is one text line square (`--text-base` times `--line-body`); horizontal paddings and column gaps are whole character cells (`1ch`, `2ch`, `3ch`, `4ch`); the checkbox is `2ch` square.\n\n## Components\n\n- `.ds-page` on `<body>`: page fill and base type, no margin. `.ds-wrap` is the centred column; `.ds-cols` (`--side`, `--even`) are its column pairs, `.ds-stack` a pile of frames, `.ds-main` a column that may shrink, `.ds-section` a block of the page.\n- `.ds-nav`: the header line. `.ds-nav__list` holds `.ds-nav__link` items in brackets and the muted `.ds-nav__version`. The stylesheet marks the link whose `href` names the view that is showing (one selector per view, and the home link when the address names none); on a page of its own give the link `is-current`.\n- `.ds-hero`: the opening of the home view. `.ds-hero__text` holds `.ds-hero__title` (`--text-display`), `.ds-hero__lead`, `.ds-hero__install` (the install command on `--color-surface-alt` in a frame, with a `[copy]` bracket link at its right), a `.ds-buttons` row and a small `.ds-hero__note`. Beside it `.ds-term` is the terminal window: a frame with `.ds-term__title` cut into its top line and `--shadow-dialog`, holding `.ds-term__screen`, a `<pre>` at `--text-small` whose lines are marked `.ds-term__in` (typed, bold), `.ds-term__dim`, `.ds-term__ok`, `.ds-term__warn` and `.ds-term__head` (a head row on the bar fill), and which ends in the `.ds-cursor`.\n- `.ds-footer`: a status line on `--fill-bar-alt`: `.ds-footer__keys`, a list of `.ds-key` hints each holding a `.ds-footer__link`, and a `.ds-footer__text` at the right.\n- `.ds-brand`: the site's mark and name, a link to the home view, first thing in the header. `.ds-brand__mark` is a tile one text line square, dressed like the primary button (`--fill-button`, `--color-button-text`, the button's frame, `--radius-control`, `--shadow-control`); `.ds-brand__name` is bold at `--text-large`. The name `chronoskin` and the mark are placeholders for the installing project's own name and logo.\n- `.ds-breadcrumb`: a path: `.ds-breadcrumb__link` items with `.ds-breadcrumb__sep` (`/`) between them, ending in a bold `.ds-breadcrumb__current`.\n- `.ds-page-header`: the head of an inner page: `.ds-page-header__main` with `.ds-page-header__title` (`--text-h1`) and one muted `.ds-page-header__text` line; `.ds-page-header__action` at the right holds one button. A rule of `--border-width-strong` closes it.\n- `.ds-prose`: running text, at most 78 characters wide: h1, h2, h3, paragraphs, lists whose bullet is a typed dash, `code` on `--color-surface-strong`, `strong` in the heading colour. Anything typed literally goes in `.ds-code`, a `<pre>` at `--text-small` on `--color-surface-alt` in a frame; it scrolls sideways inside itself.\n- `.ds-link`: text link with `is-visited`, `is-hover`, `is-active`, `is-focus`. `.ds-link--quiet` for meta and tool links, `.ds-link--bracket` for a link written as a word in brackets (`[copy]`, `[get]`). `.ds-links` sets several in a wrapping line.\n- `.ds-button`: a `<button>`, or an `<a>` when it only leads to another view. It is a word in square brackets, which the stylesheet adds: `[ download ]`. The primary one is a block of `--fill-button`; `.ds-button--secondary` is a frame in `--color-border`; `.ds-button--danger` is the destructive action in `--color-danger` on `--color-danger-surface`; `disabled` or `is-disabled` is greyed. `is-hover`, `is-active` and `is-focus` show the states. Group with `.ds-buttons`.\n- `.ds-form`: rows (`.ds-form__row`) of a `.ds-form__label` ending in a colon and a `.ds-form__field`. Controls take `.ds-form__input` (`--wide` for the full width, `--auto` for selects). `is-invalid` plus a bold `.ds-form__error` marks a validation error, `.ds-form__hint` is help text, `.ds-form__check` holds a `.ds-form__checkbox` (one empty cell, a filled block when set), and `.ds-form__actions` lines the buttons up with the fields.\n- `.ds-table`: aligned columns under a head row on `--fill-bar`. `.ds-table__num` right-aligns a numeric column, `.ds-table__code` is a bold first column, `.ds-table__date` a muted one, `tr.is-alt` an alternate row, `.ds-table__group` a group row, `tr.is-selected` the row under the cursor in inverse video, `tr.is-unread` a bold row, `.ds-table__title` the link in a row, `.ds-table__extra` cells a phone leaves out. `.ds-table--framed` gives every cell its four lines, as a table drawn in box characters.\n- `.ds-list`: dated entries. Each `.ds-list__item` is a muted `.ds-list__date` in a `--size-date` column and a `.ds-list__main` with a bold `.ds-list__title` link, a `.ds-list__excerpt` and a small `.ds-list__meta` line; faint rules part the items.\n- `.ds-panel`: a frame with its `.ds-panel__title` cut into the top line, and a `.ds-panel__body` of `.ds-panel__text` paragraphs. The title row draws the top line itself (a one-cell rule, the title, a rule to the corner), so the frame works on any fill and with any border style; a panel always has a title.\n- `.ds-stat`: one figure: a `.ds-stat__value` at `--text-h1` over a small muted `.ds-stat__label`. `.ds-stats` is the row: one frame of four cells parted by upright rules.\n- `.ds-grid`: four `.ds-grid__cell` boxes (four across, two by two on a phone), each a frame on `--color-fill-1` (`--2`, `--3`, `--4` select the other fills), with a `.ds-grid__title`, `.ds-grid__text` and an optional muted `.ds-grid__label`.\n- `.ds-tabs`: a row of words on a rule; each `.ds-tabs__tab` is a link, the current one a `<span class=\"ds-tabs__tab is-current\">` in inverse video. Each tab is written in brackets. Content goes in `.ds-tabs__body`.\n- `.ds-badge`: a count: bold `--text-small` on `--fill-accent`. `.ds-badge--tag` is a word after a `#` in `--color-heading-alt`. Status labels are `.ds-badge--success`, `.ds-badge--warning` and `.ds-badge--danger`: a word in brackets in the status colour, with no fill and no frame. `.ds-badges` sets several in a line.\n- `.ds-sidebar`: the contents column of the manual, at the left of an inner page. Each `.ds-sidebar__block` is a frame with a `.ds-sidebar__title` cut into its top line and a `.ds-sidebar__list` of `.ds-sidebar__link` items (`is-current` in inverse video) with optional `.ds-sidebar__count`; `.ds-sidebar__text` is a small muted paragraph.\n- `.ds-notice`: a sentence in a frame of `--color-border-strong` with a heavy left edge, starting with a bold `.ds-notice__title`. `.ds-notice--error` uses `--color-danger` on `--color-danger-surface`. Stack several in `.ds-notices`.\n- `.ds-pagination`: a line of `.ds-pagination__link` items: previous, numbers, next. The current page is a `<span>` with `is-current` in inverse video; `is-disabled` is muted.\n- `.ds-dialog`: a frame in `--color-border-strong`, `--size-dialog` wide, with `--shadow-dialog`. It sits in the page flow on `.ds-dialog__backdrop`, a flat block of `--color-overlay`; it has a `.ds-dialog__title`, a `.ds-dialog__body`, `.ds-dialog__text` and `.ds-dialog__actions`. No dimming of the page, no blur.\n- `.ds-empty`: a faint frame with a centred muted `.ds-empty__text` sentence and one secondary button.\n- Text-mode pieces: `.ds-prompt` is a typed command line (`.ds-prompt__sign` the `$`, `.ds-prompt__path` the directory); `.ds-cursor` is the block cursor, a `<span>` holding one no-break space; `.ds-key` is a key hint whose `.ds-key__cap` is set in brackets (`[q] quit`); `.ds-meter` is a progress bar typed in block characters, the filled part in `.ds-meter__on` (`--warning` for the amber one); `.ds-section__title` is a heading followed by a rule to the right edge; `.ds-note` is a small muted line under a block.\n\n## Never\n\n- `font-families <= 1`: one monospace face sets everything, headings and buttons included.\n- `font-size <= 30px`: the largest text is the hero title; everything else is within a few pixels of the body size.\n- `font-size >= 13px`: small text is the meta size; nothing is set smaller.\n- `letter-spacing <= 0px`: the grid of the typeface is never stretched.\n- `line-height <= 1.6`: lines sit as close as a terminal sets them.\n- `border-radius <= 0px`: a character cell has no round corner; every box, button and field is square.\n- `box-shadow-blur <= 0px`: nothing is soft and nothing floats; where a set has a shadow at all it is a hard offset block.\n- `gradient-fills <= 0%`: every fill is one flat colour.\n- `border-width <= 2px`: lines are one weight, with one heavier rule.\n- `transition = none`: states change at once, as a screen redraws.\n\n## Extending\n\nDerive a new component from the nearest one in the specimen. A boxed thing copies `.ds-panel`: a frame of `--border-width` in `--color-border` with its title cut into the top line and `--space-2` and `2ch` of padding. A row type copies a `.ds-table` row or a `.ds-list__item`. A set of choices copies `.ds-tabs`, and whatever is current or selected is inverse video (`--fill-inverse` with `--color-inverse-text`). A status is a word in brackets in its status colour; a quantity is a `.ds-meter` of block characters; an action is a word dressed as `.ds-button`, with its key given as a `.ds-key`. Use only the tokens of `tokens.css` and the `--size-*` and `--space-*` tokens of `components.css`, write horizontal steps in `ch`, and pair each text token with its own fill as listed above. When in doubt do less: text before a box, a rule before a fill, a typed character before an icon, and never a radius, a soft shadow, a gradient, a picture or a second typeface.\n",
    "components.css": "/* Layout tokens (structure part). Vertical steps are quarters, halves and\n   multiples of one 20px text line; horizontal steps are written in ch. */\n:root {\n  --size-page: 1080px;\n  --size-side: 240px;\n  --size-label: 150px;\n  --size-field: 420px;\n  --size-dialog: 440px;\n  --size-date: 100px;\n  --space-1: 5px;\n  --space-2: 10px;\n  --space-3: 20px;\n  --space-4: 40px;\n  --space-5: 60px;\n}\n\n/* ---------- shell: one face, one size, a screen of text ---------- */\n.ds-page {\n  margin: 0;\n  padding: 0;\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/* Selection is inverse video. */\n.ds-page ::selection {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n}\n/* ---------- views: one screen of the example site 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/* ---------- frames: a box of 1-cell lines with its title cut into the top edge.\n   The top edge is drawn by the title row (a short rule, the title, a long rule),\n   so it works on any fill and with any border style. ---------- */\n.ds-panel,\n.ds-dialog,\n.ds-sidebar__block,\n.ds-term {\n  position: relative;\n  display: flow-root;\n  box-sizing: border-box;\n  min-width: 0;\n  margin: calc(var(--text-h3) * var(--line-body) * 0.5) 0 0;\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-top: 0;\n  border-radius: var(--radius-panel);\n  background: var(--fill-panel);\n  box-shadow: var(--shadow-panel);\n}\n.ds-panel__title,\n.ds-dialog__title,\n.ds-sidebar__title,\n.ds-term__title {\n  display: flex;\n  align-items: center;\n  gap: 1ch;\n  margin: calc(var(--text-h3) * var(--line-body) * -0.5) calc(var(--border-width) * -1) 0;\n  padding: 0;\n  overflow: hidden;\n  white-space: nowrap;\n  color: var(--color-heading-alt);\n  font-family: var(--font-heading);\n  font-size: var(--text-h3);\n  font-weight: var(--weight-heading);\n  line-height: var(--line-body);\n  letter-spacing: var(--heading-tracking);\n  text-transform: var(--heading-transform);\n}\n.ds-panel__title::before,\n.ds-dialog__title::before,\n.ds-sidebar__title::before,\n.ds-term__title::before {\n  content: \"\";\n  flex: none;\n  width: 1ch;\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-panel__title::after,\n.ds-dialog__title::after,\n.ds-sidebar__title::after,\n.ds-term__title::after {\n  content: \"\";\n  flex: 1;\n  min-width: 1ch;\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-panel__body {\n  padding: var(--space-2) 2ch var(--space-3);\n}\n.ds-panel__text {\n  margin: 0 0 var(--space-2);\n}\n.ds-panel__text:last-child {\n  margin-bottom: 0;\n}\n\n/* ---------- a section rule: the name, then a line to the right edge ---------- */\n.ds-section {\n  margin: 0 0 var(--space-4);\n}\n.ds-section__title {\n  display: flex;\n  align-items: center;\n  gap: 1ch;\n  margin: var(--space-3) 0 var(--space-2);\n  color: var(--color-heading);\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}\n.ds-section__title:first-child {\n  margin-top: 0;\n}\n.ds-section__title::after {\n  content: \"\";\n  flex: 1;\n  border-top: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-note:last-child {\n  margin-bottom: 0;\n}\n.ds-note {\n  margin: var(--space-2) 0 var(--space-3);\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n\n/* ---------- prompt, cursor, key hints, meters ---------- */\n.ds-prompt {\n  margin: 0 0 var(--space-2);\n  color: var(--color-heading);\n  font-family: var(--font-mono);\n  font-weight: var(--weight-bold);\n  overflow-wrap: anywhere;\n}\n.ds-prompt__sign {\n  color: var(--color-accent-alt);\n}\n.ds-prompt__path {\n  color: var(--color-heading-alt);\n}\n/* The block cursor: one cell of inverse video. It holds a no-break space. */\n.ds-cursor {\n  background: currentColor;\n}\n@media (prefers-reduced-motion: no-preference) {\n  .ds-cursor {\n    animation: ds-blink 1.2s steps(1) infinite;\n  }\n}\n@keyframes ds-blink {\n  0% { opacity: 1; }\n  50% { opacity: 0; }\n  100% { opacity: 0; }\n}\n.ds-key {\n  white-space: nowrap;\n}\n.ds-key__cap {\n  font-weight: var(--weight-bold);\n}\n.ds-key__cap::before {\n  content: \"[\";\n}\n.ds-key__cap::after {\n  content: \"]\";\n}\n/* A progress bar typed in block characters. */\n.ds-meter {\n  color: var(--color-border);\n  white-space: nowrap;\n}\n.ds-meter__on {\n  color: var(--color-success);\n}\n.ds-meter__on--warning {\n  color: var(--color-warning);\n}\n.ds-code {\n  box-sizing: border-box;\n  max-width: 100%;\n  margin: 0 0 var(--space-3);\n  padding: var(--space-2) 2ch;\n  overflow-x: auto;\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-panel);\n  background: var(--color-surface-alt);\n  color: var(--color-text);\n  font-family: var(--font-mono);\n  font-size: var(--text-small);\n  line-height: var(--line-body);\n  white-space: pre;\n}\n.ds-code:last-child {\n  margin-bottom: 0;\n}\n\n/* ---------- links ---------- */\n.ds-link {\n  color: var(--color-link);\n  text-decoration: var(--link-decoration);\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}\n.ds-link:active,\n.ds-link.is-active {\n  color: var(--color-link-active);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-link:focus-visible,\n.ds-link.is-focus {\n  outline: var(--focus-ring);\n}\n.ds-link--quiet,\n.ds-link--quiet:visited,\n.ds-link--quiet.is-visited {\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-link--quiet:hover,\n.ds-link--quiet.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n/* A link marked by brackets instead of an underline: [copy]. */\n.ds-link--bracket,\n.ds-link--bracket:visited {\n  color: var(--color-link);\n  text-decoration: none;\n  white-space: nowrap;\n}\n.ds-link--bracket::before {\n  content: \"[\";\n}\n.ds-link--bracket::after {\n  content: \"]\";\n}\n.ds-links {\n  display: flex;\n  flex-wrap: wrap;\n  gap: var(--space-1) 3ch;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n\n/* ---------- brand: the mark on a one-line tile dressed like the primary button ---------- */\n.ds-brand {\n  display: inline-flex;\n  align-items: center;\n  gap: 1ch;\n  color: var(--color-heading);\n  text-decoration: none;\n}\n.ds-brand__mark {\n  flex: none;\n  display: block;\n  box-sizing: border-box;\n  width: calc(var(--text-base) * var(--line-body));\n  height: calc(var(--text-base) * var(--line-body));\n  border: var(--border-width) var(--border-style) var(--color-button);\n  border-radius: var(--radius-control);\n  background: var(--fill-button);\n  box-shadow: var(--shadow-control);\n  color: var(--color-button-text);\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-large);\n  font-weight: var(--weight-display);\n  line-height: var(--line-heading);\n  letter-spacing: var(--display-tracking);\n  text-shadow: var(--shadow-text);\n}\n.ds-brand:hover .ds-brand__name,\n.ds-brand.is-hover .ds-brand__name {\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-brand:focus-visible,\n.ds-brand.is-focus {\n  outline: var(--focus-ring);\n}\n\n/* ---------- breadcrumb: a path ---------- */\n.ds-breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 0 1ch;\n  margin: 0 0 var(--space-2);\n  padding: 0;\n  list-style: none;\n}\n.ds-breadcrumb__link {\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-breadcrumb__link:hover,\n.ds-breadcrumb__link.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-breadcrumb__sep {\n  color: var(--color-text-muted);\n}\n.ds-breadcrumb__current {\n  color: var(--color-heading);\n  font-weight: var(--weight-bold);\n}\n\n/* ---------- page header: title, one line, an action at the right, a heavy rule ---------- */\n.ds-page-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: flex-end;\n  gap: var(--space-2) 2ch;\n  margin: 0 0 var(--space-3);\n  padding: 0 0 var(--space-2);\n  border-bottom: var(--border-width-strong) var(--border-style) var(--color-border-strong);\n}\n.ds-page-header__main {\n  min-width: 0;\n}\n.ds-page-header__title {\n  margin: 0;\n  color: var(--color-heading);\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  text-shadow: var(--shadow-text);\n}\n.ds-page-header__text {\n  margin: var(--space-1) 0 0;\n  color: var(--color-text-muted);\n}\n.ds-page-header__action {\n  flex: none;\n}\n\n/* ---------- stats ---------- */\n.ds-stats {\n  display: grid;\n  grid-template-columns: repeat(4, minmax(0, 1fr));\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-stat {\n  min-width: 0;\n}\n.ds-stat__value {\n  color: var(--color-heading);\n  font-family: var(--font-heading);\n  font-weight: var(--weight-display);\n}\n.ds-stat__label {\n  color: var(--color-text-muted);\n}\n\n/* ---------- prose ---------- */\n.ds-prose {\n  max-width: 78ch;\n}\n.ds-prose h1,\n.ds-prose h2,\n.ds-prose h3 {\n  margin: 0 0 var(--space-2);\n  color: var(--color-heading);\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}\n.ds-prose h1 {\n  font-size: var(--text-h1);\n}\n.ds-prose h2 {\n  margin-top: var(--space-4);\n  font-size: var(--text-h2);\n}\n.ds-prose h3 {\n  margin-top: var(--space-3);\n  font-size: var(--text-h3);\n  color: var(--color-heading-alt);\n}\n.ds-prose p {\n  margin: 0 0 var(--space-3);\n}\n.ds-prose ul,\n.ds-prose ol {\n  margin: 0 0 var(--space-3);\n  padding: 0 0 0 3ch;\n}\n.ds-prose ul {\n  list-style-type: \"- \";\n  padding-left: 2ch;\n}\n.ds-prose code {\n  padding: 0 0.5ch;\n  background: var(--color-surface-strong);\n  color: var(--color-heading);\n  font-family: var(--font-mono);\n}\n.ds-prose strong {\n  color: var(--color-heading);\n  font-weight: var(--weight-bold);\n}\n.ds-prose > :first-child {\n  margin-top: 0;\n}\n.ds-prose > :last-child {\n  margin-bottom: 0;\n}\n\n/* ---------- buttons: a word in brackets, the primary one in inverse video ---------- */\n.ds-buttons {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-2) 2ch;\n}\n.ds-button {\n  display: inline-block;\n  box-sizing: border-box;\n  margin: 0;\n  padding: var(--space-1) 1ch;\n  border: var(--border-width) var(--border-style) var(--color-button);\n  border-radius: var(--radius-control);\n  background: var(--fill-button);\n  box-shadow: var(--shadow-control);\n  color: var(--color-button-text);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  line-height: var(--line-body);\n  text-transform: var(--ui-transform);\n  text-decoration: none;\n  white-space: nowrap;\n  transition: var(--transition);\n  cursor: pointer;\n}\n.ds-button::before {\n  content: \"[ \";\n}\n.ds-button::after {\n  content: \" ]\";\n}\n.ds-button:hover,\n.ds-button.is-hover {\n  background: var(--fill-button-hover);\n  box-shadow: var(--shadow-control-hover);\n  color: var(--color-button-hover-text);\n}\n.ds-button:active,\n.ds-button.is-active {\n  box-shadow: var(--shadow-control-pressed);\n}\n.ds-button:focus-visible,\n.ds-button.is-focus {\n  outline: var(--focus-ring);\n}\n.ds-button--secondary,\n.ds-button--secondary:hover,\n.ds-button--secondary.is-hover {\n  border-color: var(--color-border);\n  background: var(--fill-button-secondary);\n  color: var(--color-button-secondary-text);\n}\n.ds-button--secondary:hover,\n.ds-button--secondary.is-hover {\n  border-color: var(--color-border-strong);\n}\n.ds-button--danger,\n.ds-button--danger:hover,\n.ds-button--danger.is-hover {\n  border-color: var(--color-danger);\n  background: var(--color-danger-surface);\n  color: var(--color-danger);\n}\n.ds-button:disabled,\n.ds-button.is-disabled {\n  border-color: var(--color-border-muted);\n  background: var(--color-disabled);\n  box-shadow: none;\n  color: var(--color-disabled-text);\n  cursor: default;\n}\n\n/* ---------- form ---------- */\n.ds-form {\n  margin: 0;\n}\n.ds-form__row {\n  display: grid;\n  grid-template-columns: var(--size-label) minmax(0, 1fr);\n  gap: 0 2ch;\n  align-items: start;\n  margin: 0 0 var(--space-2);\n}\n.ds-form__label {\n  padding: var(--space-1) 0;\n  color: var(--color-heading);\n}\n.ds-form__field {\n  min-width: 0;\n}\n.ds-form__input {\n  box-sizing: border-box;\n  width: 100%;\n  max-width: var(--size-field);\n  margin: 0;\n  padding: var(--space-1) 1ch;\n  border: var(--border-width) var(--border-style) var(--color-input-border);\n  border-radius: var(--radius-control);\n  background: var(--fill-input);\n  box-shadow: var(--shadow-control);\n  color: var(--color-input-text);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  line-height: var(--line-body);\n  transition: var(--transition);\n}\n.ds-form__input--wide {\n  max-width: none;\n}\n.ds-form__input--auto {\n  width: auto;\n}\n.ds-form__input:focus-visible,\n.ds-form__input.is-focus {\n  outline: var(--focus-ring);\n}\n.ds-form__input:disabled,\n.ds-form__input.is-disabled {\n  background: var(--color-disabled);\n  color: var(--color-disabled-text);\n}\n.ds-form__input.is-invalid {\n  border-color: var(--color-danger);\n}\n.ds-form__error {\n  margin: var(--space-1) 0 0;\n  color: var(--color-danger);\n  font-weight: var(--weight-bold);\n}\n.ds-form__hint {\n  margin: var(--space-1) 0 0;\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n.ds-form__check {\n  display: flex;\n  align-items: center;\n  gap: 1ch;\n  padding: var(--space-1) 0;\n}\n/* A checkbox is one cell: an empty box, or a filled block when set. */\n.ds-form__checkbox {\n  appearance: none;\n  flex: none;\n  box-sizing: border-box;\n  width: 2ch;\n  height: 2ch;\n  margin: 0;\n  border: var(--border-width) var(--border-style) var(--color-input-border);\n  border-radius: var(--radius-control);\n  background: var(--fill-input);\n}\n.ds-form__checkbox:checked {\n  border-style: solid;\n  background: var(--color-input-text);\n}\n.ds-form__checkbox:focus-visible {\n  outline: var(--focus-ring);\n}\n.ds-form__actions {\n  display: flex;\n  flex-wrap: wrap;\n  gap: var(--space-2) 2ch;\n  margin: var(--space-3) 0 0;\n  padding-left: calc(var(--size-label) + 2ch);\n}\n\n/* ---------- table: aligned columns under a head line in the bar colours ---------- */\n.ds-table {\n  width: 100%;\n  border-collapse: collapse;\n  border-radius: var(--radius-panel);\n}\n.ds-table th,\n.ds-table td {\n  padding: var(--space-1) 1ch;\n  border-style: var(--border-style);\n  border-color: var(--color-border-muted);\n  border-width: 0 0 var(--border-width);\n  text-align: left;\n  vertical-align: top;\n}\n.ds-table th {\n  background: var(--fill-bar);\n  color: var(--color-bar-text);\n  border-color: var(--color-border);\n  font-family: var(--font-heading);\n  font-weight: var(--weight-bold);\n  text-transform: var(--heading-transform);\n  white-space: nowrap;\n}\n.ds-table td {\n  background: var(--color-surface);\n}\n.ds-table tr.is-alt td,\n.ds-table__row--alt td {\n  background: var(--color-surface-alt);\n}\n.ds-table th.ds-table__num,\n.ds-table td.ds-table__num {\n  text-align: right;\n  white-space: nowrap;\n}\n.ds-table td.ds-table__code {\n  color: var(--color-heading);\n  font-family: var(--font-mono);\n  font-weight: var(--weight-bold);\n  white-space: nowrap;\n}\n.ds-table td.ds-table__date {\n  color: var(--color-text-muted);\n  white-space: nowrap;\n}\n.ds-table__group td {\n  background: var(--color-surface-strong);\n  color: var(--color-heading-alt);\n  font-weight: var(--weight-bold);\n}\n/* The row under the cursor: inverse video. */\n.ds-table tr.is-selected td {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n}\n.ds-table tr.is-selected .ds-table__title {\n  color: var(--color-inverse-text);\n}\n.ds-table tr.is-unread td {\n  font-weight: var(--weight-bold);\n}\n.ds-table__title {\n  color: var(--color-link);\n  text-decoration: var(--link-decoration);\n}\n.ds-table__title:visited,\n.ds-table__title.is-visited {\n  color: var(--color-link-visited);\n}\n.ds-table__title:hover,\n.ds-table__title.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n\n/* ---------- list ---------- */\n.ds-list {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-list__item {\n  display: grid;\n  grid-template-columns: var(--size-date) minmax(0, 1fr);\n  gap: 0 2ch;\n  padding: var(--space-2) 0;\n  border-bottom: var(--border-width) var(--border-style) var(--color-border-muted);\n}\n.ds-list__item:first-child {\n  padding-top: 0;\n}\n.ds-list__item:last-child {\n  padding-bottom: 0;\n  border-bottom: 0;\n}\n.ds-list__date {\n  color: var(--color-text-muted);\n  white-space: nowrap;\n}\n.ds-list__main {\n  min-width: 0;\n}\n.ds-list__title {\n  color: var(--color-link);\n  font-weight: var(--weight-bold);\n  text-decoration: var(--link-decoration);\n}\n.ds-list__title:visited,\n.ds-list__title.is-visited {\n  color: var(--color-link-visited);\n}\n.ds-list__title:hover,\n.ds-list__title.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-list__excerpt {\n  margin: 0;\n}\n.ds-list__meta {\n  margin: 0;\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n\n/* ---------- grid: four framed cells on the block fills ---------- */\n.ds-grid {\n  display: grid;\n  grid-template-columns: repeat(4, minmax(0, 1fr));\n  gap: var(--space-2) 2ch;\n}\n.ds-grid__cell {\n  min-width: 0;\n  padding: var(--space-2) 2ch var(--space-3);\n  border: var(--border-width) var(--border-style) var(--color-border);\n  border-radius: var(--radius-page);\n  background: var(--color-fill-1);\n}\n.ds-grid__cell--2 {\n  background: var(--color-fill-2);\n}\n.ds-grid__cell--3 {\n  background: var(--color-fill-3);\n}\n.ds-grid__cell--4 {\n  background: var(--color-fill-4);\n}\n.ds-grid__label {\n  margin: 0;\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n.ds-grid__title {\n  margin: 0 0 var(--space-1);\n  color: var(--color-heading);\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  text-transform: var(--heading-transform);\n}\n.ds-grid__text {\n  margin: 0;\n}\n\n/* ---------- tabs: words on a rule, the current one in inverse video ---------- */\n.ds-tabs {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 0 1ch;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n  text-transform: var(--ui-transform);\n}\n.ds-tabs__tab {\n  display: block;\n  padding: var(--space-1) 1ch;\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-tabs__tab:hover,\n.ds-tabs__tab.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-tabs__tab:focus-visible,\n.ds-tabs__tab.is-focus {\n  outline: var(--focus-ring);\n}\n.ds-tabs__tab.is-current {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n  font-weight: var(--weight-bold);\n  text-decoration: none;\n}\n.ds-tabs__body {\n  padding: var(--space-2) 0 var(--space-3);\n}\n\n/* ---------- badge: a count on the accent fill; a tag; a status word in brackets ---------- */\n.ds-prose + .ds-links {\n  margin-top: var(--space-3);\n}\n.ds-badges {\n  margin: 0 0 var(--space-2);\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-1) 2ch;\n}\n.ds-badge {\n  display: inline-block;\n  padding: 0 1ch;\n  border-radius: var(--radius-pill);\n  background: var(--fill-accent);\n  color: var(--color-accent-text);\n  font-family: var(--font-ui);\n  font-size: var(--text-small);\n  font-weight: var(--weight-bold);\n  line-height: var(--line-body);\n  white-space: nowrap;\n}\n.ds-badge--tag,\n.ds-badge--success,\n.ds-badge--warning,\n.ds-badge--danger {\n  padding: 0;\n  background: transparent;\n  font-weight: var(--weight-body);\n}\n.ds-badge--tag {\n  color: var(--color-heading-alt);\n}\n.ds-badge--tag::before {\n  content: \"#\";\n}\n.ds-badge--success::before,\n.ds-badge--warning::before,\n.ds-badge--danger::before {\n  content: \"[\";\n}\n.ds-badge--success::after,\n.ds-badge--warning::after,\n.ds-badge--danger::after {\n  content: \"]\";\n}\n.ds-badge--success {\n  color: var(--color-success);\n}\n.ds-badge--warning {\n  color: var(--color-warning);\n}\n.ds-badge--danger {\n  color: var(--color-danger);\n}\n\n/* ---------- sidebar: framed blocks of links ---------- */\n.ds-sidebar {\n  display: grid;\n  gap: var(--space-2);\n  align-content: start;\n  min-width: 0;\n}\n.ds-sidebar__list {\n  margin: 0;\n  padding: var(--space-1) 1ch var(--space-2);\n  list-style: none;\n}\n.ds-sidebar__list li {\n  display: flex;\n  justify-content: space-between;\n  gap: 1ch;\n}\n.ds-sidebar__link {\n  flex: 1;\n  min-width: 0;\n  padding: 0 1ch;\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-sidebar__link:hover,\n.ds-sidebar__link.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-sidebar__link.is-current {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n  font-weight: var(--weight-bold);\n  text-decoration: none;\n}\n.ds-sidebar__count {\n  flex: none;\n  padding: 0 1ch 0 0;\n  color: var(--color-text-muted);\n}\n.ds-sidebar__text {\n  margin: 0;\n  padding: var(--space-1) 2ch var(--space-2);\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n\n/* ---------- notice: a box with a heavy left edge ---------- */\n.ds-notices {\n  display: grid;\n  gap: var(--space-2);\n  margin: 0 0 var(--space-3);\n}\n.ds-notice {\n  margin: 0;\n  padding: var(--space-2) 2ch;\n  border: var(--border-width) var(--border-style) var(--color-border-strong);\n  border-left-width: var(--border-width-strong);\n  border-radius: var(--radius-panel);\n  background: var(--color-notice);\n  color: var(--color-notice-text);\n}\n.ds-notice__title {\n  font-weight: var(--weight-bold);\n  text-transform: var(--heading-transform);\n}\n.ds-notice--error {\n  border-color: var(--color-danger);\n  background: var(--color-danger-surface);\n  color: var(--color-danger);\n}\n\n/* ---------- pagination ---------- */\n.ds-pagination {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--space-1) 1ch;\n  margin: var(--space-3) 0 0;\n  padding: 0;\n  list-style: none;\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n}\n.ds-pagination__link {\n  display: block;\n  padding: 0 1ch;\n  color: var(--color-link);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-pagination__link:hover,\n.ds-pagination__link.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-pagination__link:focus-visible,\n.ds-pagination__link.is-focus {\n  outline: var(--focus-ring);\n}\n.ds-pagination__link.is-current {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n  font-weight: var(--weight-bold);\n  text-decoration: none;\n}\n.ds-pagination__link.is-disabled {\n  color: var(--color-text-muted);\n  text-decoration: none;\n}\n\n/* ---------- dialog: a framed box on a block of the overlay colour, in the page flow ---------- */\n.ds-dialog__backdrop {\n  box-sizing: border-box;\n  padding: var(--space-3) 2ch;\n  border-radius: var(--radius-panel);\n  background: var(--color-overlay);\n}\n.ds-dialog {\n  max-width: var(--size-dialog);\n  margin-left: auto;\n  margin-right: auto;\n  border-color: var(--color-border-strong);\n  box-shadow: var(--shadow-dialog);\n}\n.ds-dialog__title::before,\n.ds-dialog__title::after {\n  border-color: var(--color-border-strong);\n}\n.ds-dialog__body {\n  padding: var(--space-2) 2ch var(--space-3);\n}\n.ds-dialog__text {\n  margin: 0 0 var(--space-3);\n}\n.ds-dialog__actions {\n  display: flex;\n  flex-wrap: wrap;\n  gap: var(--space-2) 2ch;\n}\n\n/* ---------- empty ---------- */\n.ds-empty {\n  padding: var(--space-3) 2ch;\n  border: var(--border-width) var(--border-style) var(--color-border-muted);\n  border-radius: var(--radius-panel);\n  text-align: center;\n}\n.ds-empty__text {\n  margin: 0 0 var(--space-2);\n  color: var(--color-text-muted);\n}\n.ds-note code,\n.ds-notice code,\n.ds-panel__text code {\n  color: var(--color-heading);\n  font-family: var(--font-mono);\n}\n.ds-notice code {\n  color: inherit;\n  font-weight: var(--weight-bold);\n}\n\n/* ---------- layout 1: one centred column between two faint side rules ---------- */\n.ds-wrap {\n  display: flex;\n  flex-direction: column;\n  box-sizing: border-box;\n  max-width: var(--size-page);\n  min-height: 100vh;\n  margin: 0 auto;\n  padding: 0 3ch var(--space-3);\n  border-style: var(--border-style);\n  border-color: var(--color-border-muted);\n  border-width: 0 var(--border-width);\n  border-radius: var(--radius-page);\n  background: var(--color-canvas);\n}\n.ds-cols {\n  display: grid;\n  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);\n  gap: var(--space-3) 4ch;\n  align-items: start;\n}\n.ds-cols--side {\n  grid-template-columns: var(--size-side) minmax(0, 1fr);\n}\n.ds-cols--even {\n  grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.ds-stack {\n  display: grid;\n  gap: var(--space-3);\n  min-width: 0;\n}\n.ds-main {\n  min-width: 0;\n}\n.ds-wrap > .ds-view {\n  padding-bottom: var(--space-4);\n}\n\n/* nav: the name at the left, the pages as bracketed words at the right */\n.ds-nav {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  gap: var(--space-1) 3ch;\n  margin: 0 0 var(--space-3);\n  padding: var(--space-2) 0;\n  border-bottom: var(--border-width) var(--border-style) var(--color-border);\n  font-family: var(--font-ui);\n  font-size: var(--text-ui);\n  font-weight: var(--weight-ui);\n}\n.ds-nav__list {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 0 2ch;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-nav__link {\n  display: block;\n  color: var(--color-link-quiet);\n  text-decoration: var(--link-decoration-quiet);\n  text-transform: var(--ui-transform);\n}\n.ds-nav__link::before {\n  content: \"[\";\n}\n.ds-nav__link::after {\n  content: \"]\";\n}\n.ds-nav__link:hover,\n.ds-nav__link.is-hover {\n  color: var(--color-link-hover);\n  text-decoration: var(--link-decoration-hover);\n}\n.ds-nav__link:focus-visible,\n.ds-nav__link.is-focus {\n  outline: var(--focus-ring);\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(#docs:target) .ds-nav__link[href=\"#docs\"],\n.ds-page:has(#changelog:target) .ds-nav__link[href=\"#changelog\"],\n.ds-page:has(#download:target) .ds-nav__link[href=\"#download\"] {\n  background: var(--fill-inverse);\n  color: var(--color-inverse-text);\n  font-weight: var(--weight-bold);\n  text-decoration: none;\n}\n.ds-nav__version {\n  color: var(--color-text-muted);\n}\n\n/* hero: the claim and the install line beside a terminal window with a typed session */\n.ds-hero {\n  display: grid;\n  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);\n  gap: var(--space-3) 4ch;\n  align-items: start;\n  margin: 0 0 var(--space-4);\n  padding: var(--space-3) 0 0;\n}\n.ds-hero__text {\n  min-width: 0;\n}\n.ds-hero__title {\n  margin: 0 0 var(--space-3);\n  color: var(--color-heading);\n  font-family: var(--font-heading);\n  font-size: var(--text-display);\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  text-shadow: var(--shadow-text);\n}\n.ds-hero__lead {\n  margin: 0 0 var(--space-3);\n  font-size: var(--text-large);\n}\n.ds-hero__install {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: space-between;\n  gap: 0 2ch;\n  margin: 0 0 var(--space-3);\n  padding: var(--space-2) 2ch;\n  border: var(--border-width) var(--border-style) var(--color-border);\n  background: var(--color-surface-alt);\n  color: var(--color-heading);\n  font-family: var(--font-mono);\n}\n.ds-hero__note {\n  margin: var(--space-2) 0 0;\n  color: var(--color-text-muted);\n  font-size: var(--text-small);\n}\n.ds-term {\n  box-shadow: var(--shadow-dialog);\n}\n.ds-term__title {\n  color: var(--color-text-muted);\n}\n.ds-term__screen {\n  margin: 0;\n  padding: var(--space-2) 2ch var(--space-3);\n  overflow-x: auto;\n  color: var(--color-text);\n  font-family: var(--font-mono);\n  font-size: var(--text-small);\n  line-height: var(--line-body);\n  white-space: pre;\n}\n.ds-term__in {\n  color: var(--color-heading);\n  font-weight: var(--weight-bold);\n  text-shadow: var(--shadow-text);\n}\n.ds-term__dim {\n  color: var(--color-text-muted);\n}\n.ds-term__ok {\n  color: var(--color-success);\n}\n.ds-term__warn {\n  color: var(--color-warning);\n}\n.ds-term__head {\n  background: var(--fill-bar);\n  color: var(--color-bar-text);\n  font-weight: var(--weight-bold);\n}\n\n/* stats: four cells of one framed row, parted by upright rules */\n.ds-stats {\n  border: var(--border-width) var(--border-style) var(--color-border);\n  background: var(--fill-panel);\n}\n.ds-stat {\n  padding: var(--space-2) 2ch;\n  border-left: var(--border-width) var(--border-style) var(--color-border);\n}\n.ds-stat:first-child {\n  border-left: 0;\n}\n.ds-stat__value {\n  display: block;\n  font-size: var(--text-h1);\n  line-height: var(--line-heading);\n  text-shadow: var(--shadow-text);\n}\n.ds-stat__label {\n  display: block;\n  font-size: var(--text-small);\n}\n\n/* the feature table is framed: every cell has its four lines */\n.ds-table--framed th,\n.ds-table--framed td {\n  border-width: var(--border-width);\n  border-color: var(--color-border);\n}\n.ds-tabs__tab::before {\n  content: \"[\";\n}\n.ds-tabs__tab::after {\n  content: \"]\";\n}\n\n/* footer: a status line with key hints */\n.ds-footer {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: space-between;\n  gap: var(--space-1) 3ch;\n  margin: auto 0 0;\n  padding: var(--space-1) 2ch;\n  background: var(--fill-bar-alt);\n  color: var(--color-bar-alt-text);\n  font-size: var(--text-small);\n}\n.ds-footer__keys {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 0 2ch;\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.ds-footer__text {\n  margin: 0;\n}\n.ds-footer__link {\n  color: var(--color-bar-alt-text);\n  text-decoration: var(--link-decoration-quiet);\n}\n.ds-footer__link:hover,\n.ds-footer__link.is-hover {\n  text-decoration: var(--link-decoration-hover);\n}\n\n/* ---------- narrow windows: one column, nothing scrolls sideways but code ---------- */\n@media (max-width: 720px) {\n  .ds-page-header {\n    flex-direction: column;\n    align-items: flex-start;\n  }\n  .ds-stats,\n  .ds-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n  .ds-form__row {\n    grid-template-columns: minmax(0, 1fr);\n  }\n  .ds-form__label {\n    padding: 0;\n  }\n  .ds-form__actions {\n    padding-left: 0;\n  }\n  .ds-table__extra {\n    display: none;\n  }\n  .ds-dialog__backdrop {\n    padding: var(--space-3) 1ch;\n  }\n  .ds-button {\n    white-space: normal;\n  }\n  .ds-table td.ds-table__code {\n    white-space: normal;\n    overflow-wrap: anywhere;\n  }\n\n  .ds-wrap {\n    padding: 0 2ch var(--space-3);\n    border-width: 0;\n  }\n  .ds-hero,\n  .ds-cols,\n  .ds-cols--side,\n  .ds-cols--even {\n    grid-template-columns: minmax(0, 1fr);\n  }\n  .ds-hero__title {\n    font-size: var(--text-h1);\n  }\n  .ds-stat:nth-child(odd) {\n    border-left: 0;\n  }\n  .ds-stat:nth-child(n + 3) {\n    border-top: var(--border-width) var(--border-style) var(--color-border);\n  }\n  .ds-list__item {\n    grid-template-columns: minmax(0, 1fr);\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: time tracking from the command line. Terminal, 2015 to 2026: specimen</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<div class=\"ds-wrap\">\n\n<header class=\"ds-nav\" data-component=\"nav\">\n  <a class=\"ds-brand\" data-component=\"brand\" href=\"#home\"><span class=\"ds-brand__mark\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"square\" aria-hidden=\"true\"><path d=\"M12 3a9 9 0 1 1-9 9\"/><path d=\"M12 17a5 5 0 1 1 5-5\"/><circle cx=\"12\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/></svg></span><span class=\"ds-brand__name\">chronoskin</span></a>\n  <ul class=\"ds-nav__list\">\n    <li><a class=\"ds-nav__link\" href=\"#home\">home</a></li>\n    <li><a class=\"ds-nav__link\" href=\"#docs\">docs</a></li>\n    <li><a class=\"ds-nav__link\" href=\"#changelog\">changelog</a></li>\n    <li><a class=\"ds-nav__link\" href=\"#download\">download</a></li>\n    <li class=\"ds-nav__version\">v3.2.0</li>\n  </ul>\n</header>\n\n<!-- View 1, the home page: the claim, a typed session, figures, commands, uses, news. -->\n<section class=\"ds-view ds-view--home\" id=\"home\">\n  <section class=\"ds-hero\" data-component=\"hero\">\n    <div class=\"ds-hero__text\">\n      <h1 class=\"ds-hero__title\">Track your hours without leaving the prompt.</h1>\n      <p class=\"ds-hero__lead\">chronoskin is a time tracker that lives in your shell. Start a task, stop it, and print the week as text you can read, pipe or paste into an invoice.</p>\n      <p class=\"ds-hero__install\"><span><span class=\"ds-prompt__sign\">$</span> brew install chronoskin</span> <a class=\"ds-link ds-link--bracket\" href=\"#download\">copy</a></p>\n      <div class=\"ds-buttons\">\n        <a class=\"ds-button\" href=\"#download\">download 3.2.0</a>\n        <a class=\"ds-button ds-button--secondary is-hover\" href=\"#docs\">read the docs</a>\n      </div>\n      <p class=\"ds-hero__note\">One binary of 3.1 MB for Linux, macOS and Windows. No account, no daemon, no network.</p>\n    </div>\n    <div class=\"ds-term\">\n      <p class=\"ds-term__title\">~/work: chronoskin, 60x17</p>\n<pre class=\"ds-term__screen\"><span class=\"ds-term__in\"><span class=\"ds-prompt__sign\">$</span> chronoskin start \"write the parser\" -t compiler</span>\nstarted 09:12  write the parser  <span class=\"ds-term__dim\">#compiler</span>\n<span class=\"ds-term__in\"><span class=\"ds-prompt__sign\">$</span> chronoskin status</span>\n<span class=\"ds-term__ok\">running</span>  write the parser             00:47:13\n<span class=\"ds-term__in\"><span class=\"ds-prompt__sign\">$</span> chronoskin report --week</span>\n<span class=\"ds-term__head\"> day    hours   tracked of 8 h                  </span>\n mon      6.5   <span class=\"ds-meter\"><span class=\"ds-meter__on\">████████████████</span>░░░░</span>\n tue      7.2   <span class=\"ds-meter\"><span class=\"ds-meter__on\">██████████████████</span>░░</span>\n wed      4.1   <span class=\"ds-meter\"><span class=\"ds-meter__on\">██████████</span>░░░░░░░░░░</span>\n thu      0.8   <span class=\"ds-meter\"><span class=\"ds-meter__on ds-meter__on--warning\">██</span>░░░░░░░░░░░░░░░░░░</span>\n<span class=\"ds-term__dim\"> ------------------------------------------</span>\n total   18.6 h in 3 projects, 11 tasks\n<span class=\"ds-term__warn\">note: thursday is still running</span>\n<span class=\"ds-term__in\"><span class=\"ds-prompt__sign\">$</span> <span class=\"ds-cursor\">&nbsp;</span></span></pre>\n    </div>\n  </section>\n\n  <section class=\"ds-section\">\n    <ul class=\"ds-stats\" data-component=\"stats\">\n      <li class=\"ds-stat\"><span class=\"ds-stat__value\">12 ms</span><span class=\"ds-stat__label\">to start, cold</span></li>\n      <li class=\"ds-stat\"><span class=\"ds-stat__value\">3.1 MB</span><span class=\"ds-stat__label\">one static binary</span></li>\n      <li class=\"ds-stat\"><span class=\"ds-stat__value\">0</span><span class=\"ds-stat__label\">libraries it needs</span></li>\n      <li class=\"ds-stat\"><span class=\"ds-stat__value\">41</span><span class=\"ds-stat__label\">releases since 2019</span></li>\n    </ul>\n  </section>\n\n  <section class=\"ds-section\">\n    <h2 class=\"ds-section__title\">commands</h2>\n    <table class=\"ds-table ds-table--framed\" data-component=\"table\">\n      <thead>\n        <tr><th>command</th><th>what it does</th><th class=\"ds-table__extra\">since</th><th class=\"ds-table__num\">runs in</th></tr>\n      </thead>\n      <tbody>\n        <tr><td class=\"ds-table__code\">start</td><td>Begins a task, and stops the one that was running.</td><td class=\"ds-table__extra ds-table__date\">1.0</td><td class=\"ds-table__num\">4 ms</td></tr>\n        <tr class=\"is-alt\"><td class=\"ds-table__code\">stop</td><td>Ends the running task and writes one line to the log.</td><td class=\"ds-table__extra ds-table__date\">1.0</td><td class=\"ds-table__num\">4 ms</td></tr>\n        <tr><td class=\"ds-table__code\">status</td><td>Prints what is running and for how long. Made for a prompt.</td><td class=\"ds-table__extra ds-table__date\">1.2</td><td class=\"ds-table__num\">3 ms</td></tr>\n        <tr class=\"is-alt\"><td class=\"ds-table__code\">report</td><td>A day, a week or a month as aligned columns, CSV or JSON.</td><td class=\"ds-table__extra ds-table__date\">2.0</td><td class=\"ds-table__num\">12 ms</td></tr>\n        <tr><td class=\"ds-table__code\">edit</td><td>Opens the log in your editor. It is a text file; fix it by hand.</td><td class=\"ds-table__extra ds-table__date\">2.4</td><td class=\"ds-table__num\">6 ms</td></tr>\n      </tbody>\n    </table>\n    <p class=\"ds-note\">Every command takes <span class=\"ds-key\"><span class=\"ds-key__cap\">-h</span> help</span> and exits with 0 when it did what you asked. <a class=\"ds-link\" href=\"#docs\">The full reference</a> has all fourteen.</p>\n  </section>\n\n  <section class=\"ds-section\">\n    <h2 class=\"ds-section__title\">where it fits</h2>\n    <div class=\"ds-grid\" data-component=\"grid\">\n      <div class=\"ds-grid__cell\">\n        <p class=\"ds-grid__label\">01 prompt</p>\n        <h3 class=\"ds-grid__title\">In your shell</h3>\n        <p class=\"ds-grid__text\">A status segment for bash, zsh and fish shows the running task beside your path.</p>\n      </div>\n      <div class=\"ds-grid__cell ds-grid__cell--2\">\n        <p class=\"ds-grid__label\">02 editor</p>\n        <h3 class=\"ds-grid__title\">In your editor</h3>\n        <p class=\"ds-grid__text\">The log is plain text, one line a task. Any editor can open, sort and repair it.</p>\n      </div>\n      <div class=\"ds-grid__cell ds-grid__cell--3\">\n        <p class=\"ds-grid__label\">03 pipe</p>\n        <h3 class=\"ds-grid__title\">In a pipeline</h3>\n        <p class=\"ds-grid__text\">Reports come as CSV or JSON on standard output, ready for the next program.</p>\n      </div>\n      <div class=\"ds-grid__cell ds-grid__cell--4\">\n        <p class=\"ds-grid__label\">04 sync</p>\n        <h3 class=\"ds-grid__title\">In your repository</h3>\n        <p class=\"ds-grid__text\">Keep the log beside the code. It merges like any other text file.</p>\n      </div>\n    </div>\n  </section>\n\n  <section class=\"ds-section\">\n    <div class=\"ds-cols\">\n      <div class=\"ds-main\">\n        <h2 class=\"ds-section__title\">news</h2>\n        <ul class=\"ds-list\" data-component=\"list\">\n          <li class=\"ds-list__item\">\n            <span class=\"ds-list__date\">2026-03-02</span>\n            <div class=\"ds-list__main\">\n              <a class=\"ds-list__title\" href=\"#changelog\">3.2.0: reports by tag</a> <span class=\"ds-badge\">new</span>\n              <p class=\"ds-list__excerpt\">Group a report by tag instead of by project, and total across both.</p>\n              <p class=\"ds-list__meta\">release | 6 changes | 3.1 MB</p>\n            </div>\n          </li>\n          <li class=\"ds-list__item\">\n            <span class=\"ds-list__date\">2026-01-19</span>\n            <div class=\"ds-list__main\">\n              <a class=\"ds-list__title\" href=\"#docs\">The prompt segment is now documented</a>\n              <p class=\"ds-list__excerpt\">Three lines of configuration for each of the three shells.</p>\n              <p class=\"ds-list__meta\">docs | 1 new page</p>\n            </div>\n          </li>\n          <li class=\"ds-list__item\">\n            <span class=\"ds-list__date\">2025-11-30</span>\n            <div class=\"ds-list__main\">\n              <a class=\"ds-list__title is-visited\" href=\"#download\">Builds for ARM on Windows</a>\n              <p class=\"ds-list__excerpt\">The last platform people asked for. Checksums are on the download page.</p>\n              <p class=\"ds-list__meta\">download | 1 new file</p>\n            </div>\n          </li>\n        </ul>\n      </div>\n      <div class=\"ds-panel\" data-component=\"panel\">\n        <h2 class=\"ds-panel__title\">the log file</h2>\n        <div class=\"ds-panel__body\">\n          <p class=\"ds-panel__text\">Everything chronoskin knows is in one file you can read.</p>\n<pre class=\"ds-code\">03-02 09:12 10:41 write the parser\n03-02 10:55 12:30 review notes\n03-02 13:20 -     fix the lexer</pre>\n          <p class=\"ds-panel__text\">A dash means the task is still running. <a class=\"ds-link\" href=\"#docs\">The format</a> fits on one page.</p>\n        </div>\n      </div>\n    </div>\n  </section>\n</section>\n\n<!-- View 2, a page of the manual: contents at the left, the text, tabs for each system. -->\n<section class=\"ds-view\" id=\"docs\">\n  <ol class=\"ds-breadcrumb\" data-component=\"breadcrumb\">\n    <li><a class=\"ds-breadcrumb__link\" href=\"#home\">chronoskin</a></li>\n    <li class=\"ds-breadcrumb__sep\">/</li>\n    <li><a class=\"ds-breadcrumb__link\" href=\"#docs\">docs</a></li>\n    <li class=\"ds-breadcrumb__sep\">/</li>\n    <li class=\"ds-breadcrumb__current\">getting-started</li>\n  </ol>\n  <div class=\"ds-page-header\" data-component=\"page-header\">\n    <div class=\"ds-page-header__main\">\n      <h1 class=\"ds-page-header__title\">Getting started</h1>\n      <p class=\"ds-page-header__text\">Install it, track one task, print one report. Five minutes.</p>\n    </div>\n    <div class=\"ds-page-header__action\"><a class=\"ds-button ds-button--secondary\" href=\"#download\">get the binary</a></div>\n  </div>\n  <div class=\"ds-cols ds-cols--side\">\n    <aside class=\"ds-sidebar\" data-component=\"sidebar\">\n      <div class=\"ds-sidebar__block\">\n        <h2 class=\"ds-sidebar__title\">manual</h2>\n        <ul class=\"ds-sidebar__list\">\n          <li><a class=\"ds-sidebar__link is-current\" href=\"#docs\">Getting started</a></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">The log file</a></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">Reports</a></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">Tags and projects</a></li>\n          <li><a class=\"ds-sidebar__link is-hover\" href=\"#docs\">Prompt segment</a></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">Configuration</a></li>\n        </ul>\n      </div>\n      <div class=\"ds-sidebar__block\">\n        <h2 class=\"ds-sidebar__title\">reference</h2>\n        <ul class=\"ds-sidebar__list\">\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">Commands</a><span class=\"ds-sidebar__count\">14</span></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#docs\">Exit codes</a><span class=\"ds-sidebar__count\">5</span></li>\n          <li><a class=\"ds-sidebar__link\" href=\"#changelog\">Changelog</a><span class=\"ds-sidebar__count\">41</span></li>\n        </ul>\n      </div>\n      <div class=\"ds-sidebar__block\">\n        <h2 class=\"ds-sidebar__title\">keys</h2>\n        <p class=\"ds-sidebar__text\"><span class=\"ds-key\"><span class=\"ds-key__cap\">j</span> next page</span> <span class=\"ds-key\"><span class=\"ds-key__cap\">k</span> previous</span> <span class=\"ds-key\"><span class=\"ds-key__cap\">/</span> search</span></p>\n      </div>\n    </aside>\n    <div class=\"ds-main\">\n      <div class=\"ds-notices\" data-component=\"notice\">\n        <p class=\"ds-notice\"><span class=\"ds-notice__title\">note:</span> this page describes 3.2. Run <code>chronoskin --version</code> to see what you have.</p>\n        <p class=\"ds-notice ds-notice--error\"><span class=\"ds-notice__title\">error:</span> versions before 2.0 cannot read a log written by 3.x. Upgrade before you share a file.</p>\n      </div>\n      <div class=\"ds-prose\" data-component=\"typography\">\n        <h1>Your first tracked hour</h1>\n        <p>chronoskin keeps one text file, the <strong>log</strong>, and three commands do nearly all the work: <code>start</code>, <code>stop</code> and <code>report</code>. Nothing runs in the background; the clock is the difference between two times in the file.</p>\n        <h2>Install</h2>\n        <p>Pick your system. Each line puts one binary on your path and nothing else.</p>\n      </div>\n      <ul class=\"ds-tabs\" data-component=\"tabs\">\n        <li><span class=\"ds-tabs__tab is-current\">macos</span></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#docs\">linux</a></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#docs\">windows</a></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#docs\">from source</a></li>\n      </ul>\n      <div class=\"ds-tabs__body\">\n<pre class=\"ds-code\">$ brew install chronoskin\n$ chronoskin --version\nchronoskin 3.2.0</pre>\n      </div>\n      <div class=\"ds-prose\">\n        <h2>Track a task</h2>\n        <p>Say what you are doing. Starting a task stops the one before it, so you never have two clocks.</p>\n        <ul>\n          <li><code>chronoskin start \"name\"</code> begins a task now.</li>\n          <li><code>chronoskin start -a 09:00 \"name\"</code> begins it in the past.</li>\n          <li><code>chronoskin stop</code> ends it and prints how long it ran.</li>\n        </ul>\n        <h3>Tags</h3>\n        <p>A word after <code>-t</code> is a tag. A task may carry several; a report can group by any of them.</p>\n      </div>\n      <h2 class=\"ds-section__title\">see also</h2>\n      <ul class=\"ds-links\" data-component=\"links\">\n        <li><a class=\"ds-link\" href=\"#docs\">the log file</a></li>\n        <li><a class=\"ds-link is-visited\" href=\"#docs\">reports (visited)</a></li>\n        <li><a class=\"ds-link is-hover\" href=\"#docs\">tags (hover)</a></li>\n        <li><a class=\"ds-link is-active\" href=\"#docs\">configuration (active)</a></li>\n        <li><a class=\"ds-link ds-link--quiet\" href=\"#changelog\">changelog</a></li>\n      </ul>\n      <ul class=\"ds-pagination\" data-component=\"pagination\">\n        <li><span class=\"ds-pagination__link is-disabled\">&lt; prev</span></li>\n        <li><span class=\"ds-pagination__link is-current\">1</span></li>\n        <li><a class=\"ds-pagination__link\" href=\"#docs\">2</a></li>\n        <li><a class=\"ds-pagination__link\" href=\"#docs\">3</a></li>\n        <li><a class=\"ds-pagination__link\" href=\"#docs\">4</a></li>\n        <li><a class=\"ds-pagination__link\" href=\"#docs\">next &gt;</a></li>\n      </ul>\n    </div>\n  </div>\n</section>\n\n<!-- View 3, the changelog: releases newest first, what is not yet released. -->\n<section class=\"ds-view\" id=\"changelog\">\n  <ol class=\"ds-breadcrumb\">\n    <li><a class=\"ds-breadcrumb__link\" href=\"#home\">chronoskin</a></li>\n    <li class=\"ds-breadcrumb__sep\">/</li>\n    <li class=\"ds-breadcrumb__current\">changelog</li>\n  </ol>\n  <div class=\"ds-page-header\">\n    <div class=\"ds-page-header__main\">\n      <h1 class=\"ds-page-header__title\">Changelog</h1>\n      <p class=\"ds-page-header__text\">41 releases, newest first. Dates are the day the tag was pushed.</p>\n    </div>\n    <div class=\"ds-page-header__action\"><a class=\"ds-button\" href=\"#download\">download 3.2.0</a></div>\n  </div>\n  <div class=\"ds-cols\">\n    <div class=\"ds-main\">\n      <ul class=\"ds-tabs\">\n        <li><span class=\"ds-tabs__tab is-current\">all</span></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#changelog\">3.x</a></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#changelog\">2.x</a></li>\n        <li><a class=\"ds-tabs__tab\" href=\"#changelog\">1.x</a></li>\n      </ul>\n      <div class=\"ds-tabs__body\">\n        <table class=\"ds-table\">\n          <thead>\n            <tr><th>version</th><th class=\"ds-table__extra\">date</th><th>change</th><th>kind</th><th class=\"ds-table__num\">lines</th></tr>\n          </thead>\n          <tbody>\n            <tr class=\"ds-table__group\"><td colspan=\"5\">3.2.0, 2 March 2026</td></tr>\n            <tr><td class=\"ds-table__code\">3.2.0</td><td class=\"ds-table__extra ds-table__date\">03-02</td><td>report --by tag groups a report by tag.</td><td><span class=\"ds-badge ds-badge--success\">added</span></td><td class=\"ds-table__num\">+412</td></tr>\n            <tr class=\"is-alt\"><td class=\"ds-table__code\">3.2.0</td><td class=\"ds-table__extra ds-table__date\">03-02</td><td>A week that crosses a clock change no longer loses an hour.</td><td><span class=\"ds-badge ds-badge--warning\">fixed</span></td><td class=\"ds-table__num\">+38</td></tr>\n            <tr><td class=\"ds-table__code\">3.2.0</td><td class=\"ds-table__extra ds-table__date\">03-02</td><td>The --utc flag is gone. Set the zone in the config file.</td><td><span class=\"ds-badge ds-badge--danger\">removed</span></td><td class=\"ds-table__num\">-120</td></tr>\n            <tr class=\"ds-table__group\"><td colspan=\"5\">3.1.2, 11 January 2026</td></tr>\n            <tr><td class=\"ds-table__code\">3.1.2</td><td class=\"ds-table__extra ds-table__date\">01-11</td><td>status prints nothing, not an error, when no task runs.</td><td><span class=\"ds-badge ds-badge--warning\">fixed</span></td><td class=\"ds-table__num\">+9</td></tr>\n            <tr class=\"is-alt\"><td class=\"ds-table__code\">3.1.2</td><td class=\"ds-table__extra ds-table__date\">01-11</td><td>Shell completions for fish.</td><td><span class=\"ds-badge ds-badge--success\">added</span></td><td class=\"ds-table__num\">+164</td></tr>\n            <tr class=\"ds-table__group\"><td colspan=\"5\">3.1.0, 30 November 2025</td></tr>\n            <tr><td class=\"ds-table__code\">3.1.0</td><td class=\"ds-table__extra ds-table__date\">11-30</td><td>Builds for ARM on Windows.</td><td><span class=\"ds-badge ds-badge--success\">added</span></td><td class=\"ds-table__num\">+21</td></tr>\n          </tbody>\n        </table>\n        <ul class=\"ds-pagination\">\n          <li><span class=\"ds-pagination__link is-disabled\">&lt; newer</span></li>\n          <li><span class=\"ds-pagination__link is-current\">1</span></li>\n          <li><a class=\"ds-pagination__link\" href=\"#changelog\">2</a></li>\n          <li><a class=\"ds-pagination__link\" href=\"#changelog\">3</a></li>\n          <li><a class=\"ds-pagination__link\" href=\"#changelog\">older &gt;</a></li>\n        </ul>\n      </div>\n    </div>\n    <div class=\"ds-stack\">\n      <div class=\"ds-panel\">\n        <h2 class=\"ds-panel__title\">legend</h2>\n        <div class=\"ds-panel__body\">\n          <p class=\"ds-panel__text ds-badges\" data-component=\"badge\"><span class=\"ds-badge\">41</span> <span class=\"ds-badge ds-badge--success\">added</span> <span class=\"ds-badge ds-badge--warning\">fixed</span> <span class=\"ds-badge ds-badge--danger\">removed</span> <span class=\"ds-badge ds-badge--tag\">breaking</span></p>\n          <p class=\"ds-panel__text\">A count stands on the accent colour. A kind is a word in brackets. A tag marks a release you should read before upgrading.</p>\n        </div>\n      </div>\n      <div class=\"ds-panel\">\n        <h2 class=\"ds-panel__title\">unreleased</h2>\n        <div class=\"ds-panel__body\">\n          <div class=\"ds-empty\" data-component=\"empty\">\n            <p class=\"ds-empty__text\">Nothing has been merged since 3.2.0.</p>\n            <a class=\"ds-button ds-button--secondary\" href=\"#download\">propose a change</a>\n          </div>\n        </div>\n      </div>\n      <div class=\"ds-panel\">\n        <h2 class=\"ds-panel__title\">upgrade</h2>\n        <div class=\"ds-panel__body\">\n<pre class=\"ds-code\">$ chronoskin self-update\n3.1.2 -&gt; 3.2.0  <span class=\"ds-meter\"><span class=\"ds-meter__on\">████████████</span></span> ok</pre>\n          <p class=\"ds-panel__text\">The old binary is kept beside the new one until the next update.</p>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- View 4, download: the files, how to check one, the release mail. -->\n<section class=\"ds-view\" id=\"download\">\n  <ol class=\"ds-breadcrumb\">\n    <li><a class=\"ds-breadcrumb__link\" href=\"#home\">chronoskin</a></li>\n    <li class=\"ds-breadcrumb__sep\">/</li>\n    <li class=\"ds-breadcrumb__current\">download</li>\n  </ol>\n  <div class=\"ds-page-header\">\n    <div class=\"ds-page-header__main\">\n      <h1 class=\"ds-page-header__title\">Download 3.2.0</h1>\n      <p class=\"ds-page-header__text\">Six files and their checksums. Each archive holds one binary and the manual.</p>\n    </div>\n    <div class=\"ds-page-header__action\"><a class=\"ds-button ds-button--secondary\" href=\"#changelog\">what changed</a></div>\n  </div>\n  <table class=\"ds-table ds-table--framed\">\n    <thead>\n      <tr><th>file</th><th>system</th><th class=\"ds-table__extra\">sha256, first 16</th><th class=\"ds-table__num\">size</th><th></th></tr>\n    </thead>\n    <tbody>\n      <tr><td class=\"ds-table__code\">chronoskin-3.2.0-linux-x64.tar.gz</td><td>Linux, x86-64</td><td class=\"ds-table__extra ds-table__date\">9f2c41d07ab3e5c8</td><td class=\"ds-table__num\">3.1 MB</td><td><a class=\"ds-link ds-link--bracket\" href=\"#download\">get</a></td></tr>\n      <tr class=\"is-alt\"><td class=\"ds-table__code\">chronoskin-3.2.0-linux-arm64.tar.gz</td><td>Linux, ARM</td><td class=\"ds-table__extra ds-table__date\">27d0be6614f9a0c2</td><td class=\"ds-table__num\">2.9 MB</td><td><a class=\"ds-link ds-link--bracket\" href=\"#download\">get</a></td></tr>\n      <tr><td class=\"ds-table__code\">chronoskin-3.2.0-macos.tar.gz</td><td>macOS, universal</td><td class=\"ds-table__extra ds-table__date\">c48e19a2f07d3b55</td><td class=\"ds-table__num\">5.8 MB</td><td><a class=\"ds-link ds-link--bracket\" href=\"#download\">get</a></td></tr>\n      <tr class=\"is-alt\"><td class=\"ds-table__code\">chronoskin-3.2.0-windows-x64.zip</td><td>Windows, x86-64</td><td class=\"ds-table__extra ds-table__date\">510af3e7d92c6b18</td><td class=\"ds-table__num\">3.4 MB</td><td><a class=\"ds-link ds-link--bracket\" href=\"#download\">get</a></td></tr>\n      <tr><td class=\"ds-table__code\">chronoskin-3.2.0.tar.gz</td><td>source</td><td class=\"ds-table__extra ds-table__date\">e6b7204c1d8f93aa</td><td class=\"ds-table__num\">412 KB</td><td><a class=\"ds-link ds-link--bracket\" href=\"#download\">get</a></td></tr>\n    </tbody>\n  </table>\n  <p class=\"ds-note\">Check a file with <code>sha256sum -c chronoskin-3.2.0.sha256</code> before you run it.</p>\n\n  <div class=\"ds-cols ds-section\">\n    <div class=\"ds-main\">\n      <h2 class=\"ds-section__title\">release mail</h2>\n      <form class=\"ds-form\" data-component=\"form\" action=\"#download\">\n        <div class=\"ds-form__row\">\n          <label class=\"ds-form__label\" for=\"f-mail\">address:</label>\n          <div class=\"ds-form__field\">\n            <input class=\"ds-form__input is-invalid\" id=\"f-mail\" type=\"text\" value=\"dev@example\">\n            <p class=\"ds-form__error\">error: that address has no domain ending.</p>\n          </div>\n        </div>\n        <div class=\"ds-form__row\">\n          <label class=\"ds-form__label\" for=\"f-name\">name:</label>\n          <div class=\"ds-form__field\">\n            <input class=\"ds-form__input\" id=\"f-name\" type=\"text\" value=\"A. Reader\">\n          </div>\n        </div>\n        <div class=\"ds-form__row\">\n          <label class=\"ds-form__label\" for=\"f-kind\">send me:</label>\n          <div class=\"ds-form__field\">\n            <select class=\"ds-form__input ds-form__input--auto\" id=\"f-kind\"><option>every release</option><option>major releases only</option><option>security fixes only</option></select>\n            <p class=\"ds-form__hint\">About eight mails a year. Plain text, no tracking.</p>\n          </div>\n        </div>\n        <div class=\"ds-form__row\">\n          <label class=\"ds-form__label\" for=\"f-note\">note:</label>\n          <div class=\"ds-form__field\">\n            <textarea class=\"ds-form__input\" id=\"f-note\" rows=\"3\">I package chronoskin for a distribution.</textarea>\n          </div>\n        </div>\n        <div class=\"ds-form__row\">\n          <span class=\"ds-form__label\">format:</span>\n          <div class=\"ds-form__field\">\n            <label class=\"ds-form__check\"><input class=\"ds-form__checkbox\" type=\"checkbox\" checked> include the checksums in the mail</label>\n          </div>\n        </div>\n        <div class=\"ds-form__actions\" data-component=\"buttons\">\n          <button class=\"ds-button\" type=\"button\">subscribe</button>\n          <button class=\"ds-button ds-button--secondary\" type=\"button\">preview a mail</button>\n          <button class=\"ds-button ds-button--danger\" type=\"button\">unsubscribe</button>\n          <button class=\"ds-button\" type=\"button\" disabled>resend</button>\n        </div>\n      </form>\n    </div>\n    <div class=\"ds-stack\">\n      <div class=\"ds-dialog__backdrop\">\n        <div class=\"ds-dialog\" data-component=\"dialog\" role=\"dialog\" aria-labelledby=\"dlg-1\">\n          <h2 class=\"ds-dialog__title\" id=\"dlg-1\">unsubscribe?</h2>\n          <div class=\"ds-dialog__body\">\n            <p class=\"ds-dialog__text\">dev@example.org will get no more release mail. Security fixes are announced on this page too.</p>\n            <div class=\"ds-dialog__actions\">\n              <button class=\"ds-button ds-button--danger\" type=\"button\">unsubscribe</button>\n              <button class=\"ds-button ds-button--secondary\" type=\"button\">keep it</button>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div class=\"ds-panel\">\n        <h2 class=\"ds-panel__title\">build it yourself</h2>\n        <div class=\"ds-panel__body\">\n<pre class=\"ds-code\">$ tar xf chronoskin-3.2.0.tar.gz\n$ cd chronoskin-3.2.0 &amp;&amp; make\n$ ./chronoskin --version</pre>\n          <p class=\"ds-panel__text\">A C compiler and make are all it takes. <a class=\"ds-link\" href=\"#docs\">Build notes</a></p>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<footer class=\"ds-footer\" data-component=\"footer\">\n  <ul class=\"ds-footer__keys\">\n    <li class=\"ds-key\"><span class=\"ds-key__cap\">g</span> <a class=\"ds-footer__link\" href=\"#home\">home</a></li>\n    <li class=\"ds-key\"><span class=\"ds-key__cap\">d</span> <a class=\"ds-footer__link\" href=\"#docs\">docs</a></li>\n    <li class=\"ds-key\"><span class=\"ds-key__cap\">c</span> <a class=\"ds-footer__link\" href=\"#changelog\">changelog</a></li>\n    <li class=\"ds-key\"><span class=\"ds-key__cap\">i</span> <a class=\"ds-footer__link\" href=\"#download\">install</a></li>\n  </ul>\n  <p class=\"ds-footer__text\">chronoskin 3.2.0 | free software | no cookies, no scripts</p>\n</footer>\n\n</div>\n</body>\n</html>\n",
    "style.json": "{\n  \"id\": \"v1.terminal.landing.s01.p01.t01.u01\",\n  \"library\": \"2026.10.07-2111\",\n  \"era\": {\n    \"slug\": \"terminal\",\n    \"years\": [\n      2015,\n      2026\n    ]\n  },\n  \"archetype\": \"landing\",\n  \"mode\": \"pure\",\n  \"markup\": \"modern\",\n  \"viewport\": {\n    \"width\": 1280,\n    \"fluid\": false\n  },\n  \"source\": \"https://chrono.skin/s/v1-tm-1111\",\n  \"short\": \"v1-tm-1111\"\n}\n",
    "tokens.css": "/* @part palette */\n:root {\n  --color-page: #000000;\n  --color-canvas: #030a05;\n  --color-surface: #061208;\n  --color-surface-alt: #0a1a0d;\n  --color-surface-strong: #0f2614;\n  --color-bar: #38c85a;\n  --color-bar-text: #000000;\n  --color-bar-alt: #0f2614;\n  --color-bar-alt-text: #6fe38a;\n  --color-inverse: #9df5ae;\n  --color-inverse-text: #000000;\n  --color-text: #38c85a;\n  --color-text-muted: #2a8f44;\n  --color-heading: #9df5ae;\n  --color-heading-alt: #d7ff5f;\n  --color-link: #9df5ae;\n  --color-link-quiet: #38c85a;\n  --color-link-visited: #5fa87a;\n  --color-link-hover: #e8f0e8;\n  --color-link-active: #d7ff5f;\n  --color-border: #1f6b33;\n  --color-border-strong: #38c85a;\n  --color-border-muted: #12401f;\n  --color-accent: #d7ff5f;\n  --color-accent-text: #000000;\n  --color-accent-alt: #5fd7af;\n  --color-fill-1: #061208;\n  --color-fill-2: #0a1a0d;\n  --color-fill-3: #0f2614;\n  --color-fill-4: #0a1a0d;\n  --color-button: #38c85a;\n  --color-button-text: #000000;\n  --color-button-hover-text: #000000;\n  --color-button-secondary: #0a1a0d;\n  --color-button-secondary-text: #9df5ae;\n  --color-input: #000000;\n  --color-input-text: #9df5ae;\n  --color-input-border: #1f6b33;\n  --color-disabled: #0a1a0d;\n  --color-disabled-text: #1f6b33;\n  --color-danger: #ff5f5f;\n  --color-danger-surface: #1a0505;\n  --color-success: #5fff00;\n  --color-warning: #ffd75f;\n  --color-notice: #0a1a0d;\n  --color-notice-text: #9df5ae;\n  --color-focus: #d7ff5f;\n  --color-shadow: #000000;\n  --color-overlay: #0a1a0d;\n}\n\n/* @part type */\n:root {\n  --font-body: \"JetBrains Mono\", \"Fira Code\", \"DejaVu Sans Mono\", Menlo, Consolas, monospace;\n  --font-heading: \"JetBrains Mono\", \"Fira Code\", \"DejaVu Sans Mono\", Menlo, Consolas, monospace;\n  --font-ui: \"JetBrains Mono\", \"Fira Code\", \"DejaVu Sans Mono\", Menlo, Consolas, monospace;\n  --font-mono: \"JetBrains Mono\", \"Fira Code\", \"DejaVu Sans Mono\", Menlo, Consolas, monospace;\n  --text-base: 15px;\n  --text-small: 13px;\n  --text-ui: 15px;\n  --text-large: 17px;\n  --text-display: 30px;\n  --text-h1: 22px;\n  --text-h2: 15px;\n  --text-h3: 15px;\n  --line-body: 1.4;\n  --line-heading: 1.3;\n  --line-display: 1.2;\n  --weight-body: 400;\n  --weight-bold: 700;\n  --weight-heading: 700;\n  --weight-display: 700;\n  --weight-ui: 400;\n  --heading-transform: uppercase;\n  --heading-tracking: 0;\n  --display-tracking: 0;\n  --ui-transform: none;\n  --link-decoration: underline;\n  --link-decoration-hover: underline;\n  --link-decoration-quiet: none;\n}\n\n/* @part surface */\n:root {\n  --border-width: 1px;\n  --border-width-strong: 2px;\n  --border-style: solid;\n  --radius-control: 0;\n  --radius-panel: 0;\n  --radius-pill: 0;\n  --radius-page: 0;\n  --shadow-panel: none;\n  --shadow-control: none;\n  --shadow-control-hover: none;\n  --shadow-control-pressed: none;\n  --shadow-dialog: none;\n  --shadow-text: 0 0 4px color-mix(in srgb, var(--color-accent) 30%, transparent);\n  --fill-page: 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: color-mix(in srgb, var(--color-button) 70%, white);\n  --fill-button-secondary: transparent;\n  --fill-input: transparent;\n  --focus-ring: 1px solid var(--color-focus);\n  --transition: none;\n  --backdrop-blur: 0px;\n}\n"
  }
}
