/* ==========================================================================
   backdash.gg: site.css, the Project Backdash design system (direction v2.4)

   One file for every page. Page stylesheets in /assets/css/pages/ are optional
   and only add layout for one page. Fonts come from /assets/css/fonts.css,
   linked before this file by the head include.

   Contents
     1. Tokens (palette, dark default, light theme, surfaces that stay dark)
     2. Base and type
     3. App bar, drawer, page list, status strip, skip link, lockup
     4. Layouts: bands; pages with a sidebar and a reading column
     5. Shared pieces: headline and highlight box, label box, download block, links
     6. Buttons: the crimson primary, outline secondary
     7. Content: notices, tables, figures, details, lists, code, input strip
     8. Footer
     9. Utilities, motion, forced colours, print

   resurrection.css, linked after this file, sets the launcher's palette on every
   page and adds its touches: the red field, the gold mark on the current page,
   the label tab, the link rows and the centred footer.

   Rules the file keeps (and check.mjs enforces): no italics, no skew, no
   gradients except the hard-stop progress fill, no glows or shadows used as
   light, no chevrons on buttons. PBD crimson (the --verm-* tokens) only on the
   primary button and the logo's lit down-back.
   ========================================================================== */

/* 1. Tokens ================================================================ */

:root {
  /* @palette: fixed colours, the same in both themes */
  --petrol-950: #0B0304;
  --petrol-900: #1D0609;
  --petrol-800: #2A0B11;
  --petrol-700: #5A0E18;
  --petrol-300: #F4B63F;
  --graphite-900: #14191B;
  --graphite-850: #1A2023;
  --graphite-800: #222A2D;
  --mist-50: #F4F7F6;
  --mist-100: #E6EBEA;
  --mist-200: #D5DDDC;
  /* PBD crimson, the one loud colour (direction v2.4; the --verm-* names are kept from the vermilion it replaced).
     Ink on crimson is 4.05:1, so the primary label is 19 px or more in the heavy display face (large text). */
  --verm-400: #EB5470;      /* PBD crimson, hover (label 5.09:1) */
  --verm-500: #E3304F;      /* PBD crimson (label 4.05:1) */
  --verm-600: #D02846;      /* PBD crimson, pressed (label 3.44:1); the logo's lit tile on light surfaces (4.28:1 on mist-100) */
  --on-verm: #14191B;
  --ink: #132024;
  --track: #D5DDDC;
  --dk-text-1: #E9EEED;
  --dk-text-2: #AEBDBD;
  --dk-text-3: #8A9C9C;
  --dk-focus: #E6EBEA;
  --lt-focus: #5A0E18;
  /* @end */

  /* Type */
  --font-display: "PBD Display", "Barlow", "Segoe UI", system-ui, sans-serif;  /* our own caps-only face, one weight */
  --font-ui: "Barlow", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", Consolas, Menlo, monospace;
  --fs-hero: clamp(2.125rem, 1.741rem + 1.577vw, 2.75rem);   /* 34 -> 44 px */
  --fs-title: clamp(1.75rem, 1.596rem + 0.631vw, 2rem);      /* 28 -> 32 px */
  --fs-sub: clamp(1.125rem, 0.971rem + 0.631vw, 1.375rem);   /* 18 -> 22 px */
  --fs-lead: clamp(1.125rem, 1.086rem + 0.158vw, 1.1875rem); /* 18 -> 19 px */
  --fs-body: clamp(1.0625rem, 1.024rem + 0.158vw, 1.125rem); /* 17 -> 18 px */
  --fs-h2: 1.375rem;     /* 22 */
  --fs-label: 1.25rem;   /* 20 */
  --fs-h3: 1.125rem;     /* 18 */
  --fs-small: 0.875rem;  /* 14 */
  --lh-body: 1.556;      /* 28/18, 26.4/17 */

  /* Space (4 px grid), radii, motion, layers */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px;
  --s-8: 32px; --s-10: 40px; --s-12: 48px; --s-16: 64px; --s-20: 80px;
  --r-slab: 3px;
  --r-control: 4px;
  --r-box: 8px;
  --t-fast: 90ms;
  --t-press: 60ms;
  --t-drawer: 200ms;
  --ease-out: cubic-bezier(.2, 0, 0, 1);
  --z-bar: 50;
  --z-skip: 100;

  /* Layout */
  --bar-h: 56px;
  --col: 704px;           /* home column */
  --read: 760px;          /* inner-page reading column */
  --side: 240px;          /* inner-page sidebar */
  --pad-l: 44px;          /* home band padding; the spine lives in the left one */
  --pad-r: 20px;
  --spine-x: -26px;       /* spine line, from the column's left edge (phones: 18 px from the screen edge) */
  --band-pt: 48px;
  --band-pb: 48px;

  color-scheme: dark;
}

/* Dark theme (default, the brand look) */
:root,
:root[data-theme="dark"] {
  /* @dark */
  --bg: #1A2023;            /* graphite-850: page under the bands, inner pages */
  --band: #14191B;          /* graphite-900: neutral bands, the app bar, status strip, sidebar and drawer */
  --surface: #222A2D;       /* graphite-800: figure frames, boxes on the page */
  --text-1: #E9EEED;
  --text-2: #AEBDBD;
  --text-3: #8A9C9C;
  --link: #F4B63F;
  --focus: #E6EBEA;
  --control-edge: #8A9C9C;  /* outline buttons, the theme switch */
  --selected-edge: #E3304F; /* inset edge of the petrol-700 "you are here" slab (3:1 against the surface) */
  --good: #3CC47E;
  --warn: #F4B63F;
  --bad: #FF9470;           /* coral, kept apart from the crimson accent (the rose #FF8FA3 had its hue) */
  --text-info: #F4B63F;
  --notice-info: #2A0B11;
  --notice-good: #123524;
  --notice-warn: #3A2E12;
  --notice-bad: #3B1F17;
  /* @end */
  --line: rgba(233, 238, 237, 0.12);
  --hover: rgba(233, 238, 237, 0.07);
  --press: rgba(233, 238, 237, 0.12);
  --code-bg: rgba(233, 238, 237, 0.08);
  --mark-lit: var(--verm-500);  /* the logo's lit tile */
  color-scheme: dark;
}

/* Light theme: follows the system unless the visitor chose dark */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #F7F3F3;
    --band: #EDE5E6;
    --surface: #EDE5E6;
    --text-1: #1A0A0D;
    --text-2: #5A4549;
    --text-3: #6A5559;
    --link: #A01F38;
    --focus: #5A0E18;
    --control-edge: #6A5559;
    --selected-edge: #A01F38;
    --good: #1C7447;
    --warn: #8A5800;
    --bad: #A8360C;
    --text-info: #8A1C30;
    --notice-info: #FBE6EA;
    --notice-good: #DDF0E4;
    --notice-warn: #FBF0D9;
    --notice-bad: #FCE8E0;
    --line: rgba(26, 10, 13, 0.14);
    --hover: rgba(26, 10, 13, 0.06);
    --press: rgba(26, 10, 13, 0.11);
    --code-bg: rgba(26, 10, 13, 0.07);
    --mark-lit: var(--verm-600);
    color-scheme: light;
  }
}

/* Light theme, chosen in the footer or with ?theme=light */
:root[data-theme="light"] {
  /* @light */
  --bg: #F7F3F3;            /* mist-50 */
  --band: #EDE5E6;          /* mist-100 */
  --surface: #EDE5E6;       /* mist-100 */
  --text-1: #1A0A0D;
  --text-2: #5A4549;
  --text-3: #6A5559;
  --link: #A01F38;
  --focus: #5A0E18;
  --control-edge: #6A5559;
  --selected-edge: #A01F38;
  --good: #1C7447;
  --warn: #8A5800;
  --bad: #A8360C;
  --text-info: #8A1C30;
  --notice-info: #FBE6EA;
  --notice-good: #DDF0E4;
  --notice-warn: #FBF0D9;
  --notice-bad: #FCE8E0;
  /* @end */
  --line: rgba(26, 10, 13, 0.14);
  --hover: rgba(26, 10, 13, 0.06);
  --press: rgba(26, 10, 13, 0.11);
  --code-bg: rgba(26, 10, 13, 0.07);
  --mark-lit: var(--verm-600);
  color-scheme: light;
}

/* Surfaces that keep their dark colours in both themes: the hero band (the
   coming-soon shell and the replay link page). `.on-petrol` does the same for
   anything an author puts on petrol. */
.band-hero,
.on-petrol {
  --text-1: var(--dk-text-1);
  --text-2: var(--dk-text-2);
  --text-3: var(--dk-text-3);
  --link: var(--petrol-300);
  --focus: var(--dk-focus);
  --control-edge: var(--dk-text-3);
  --selected-edge: var(--petrol-300);
  --text-info: var(--petrol-300);
  --line: rgba(233, 238, 237, 0.12);
  --hover: rgba(233, 238, 237, 0.07);
  --press: rgba(233, 238, 237, 0.12);
  --code-bg: rgba(233, 238, 237, 0.08);
  --mark-lit: var(--verm-500);
  color-scheme: dark;
  color: var(--text-1);
}

@media (min-width: 720px) {
  :root {
    --bar-h: 64px;
    --pad-l: 56px;
    --pad-r: 56px;
    --spine-x: -36px;
    --band-pt: 56px;
    --band-pb: 56px;
  }
}

/* 2. Base and type ========================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--bar-h) + 16px);
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text-1);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-body);
  font-synthesis: none;
  font-variant-numeric: lining-nums;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

body > main,
body > .page {
  flex: 1 0 auto;
}

main:focus {
  outline: none;
}

h1,
h2,
h3,
h4 {
  color: var(--text-1);
  text-wrap: balance;
}

h1,
.page-title {
  margin: 0 0 var(--s-3);
  font-family: var(--font-display);
  font-stretch: 112%;
  font-weight: 700;
  font-size: var(--fs-title);
  line-height: 1.25;
  letter-spacing: -0.005em;
}

/* Under 360 px the longest one-word title, "Requirements", is 296 px at 28 px
   and the reading column is 280 px at 320, so it broke inside the word. At
   26 px it is 275 px and stays on one line. */
@media (max-width: 359.98px) {
  h1,
  .page-title {
    font-size: 1.625rem;
  }
}

h2,
.h2 {
  margin: var(--s-10) 0 var(--s-3);
  font-family: var(--font-display);
  font-stretch: 100%;
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.3;
}

h3,
.h3 {
  margin: var(--s-8) 0 var(--s-2);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.4;
}

h4 {
  margin: var(--s-6) 0 var(--s-1);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.45;
}

p,
ul,
ol,
dl {
  margin: 0 0 var(--s-4);
}

/* No one-word last lines. */
p,
li,
dd,
figcaption {
  text-wrap: pretty;
}

ul,
ol {
  padding-left: 1.3em;
}

li + li {
  margin-top: var(--s-1);
}

li::marker {
  color: var(--text-3);
}

strong,
b {
  font-weight: 600;
  color: var(--text-1);
}

/* No italics anywhere: emphasis is weight. */
em,
i,
cite,
dfn,
var,
address {
  font-style: normal;
}

em {
  font-weight: 600;
}

small,
.fine {
  font-size: var(--fs-small);
  line-height: 1.43;
}

.lead {
  margin: 0 0 var(--s-4);
  max-width: 62ch;
  color: var(--text-2);
  font-size: var(--fs-lead);
  line-height: 1.5;
}

.muted,
.text-2 {
  color: var(--text-2);
}

.text-3 {
  color: var(--text-3);
}

.num,
.tabular {
  font-variant-numeric: tabular-nums;
}

hr {
  height: 1px;
  margin: var(--s-10) 0;
  border: 0;
  background: var(--line);
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

::selection {
  background: var(--petrol-700);
  color: var(--dk-text-1);
}

/* Links: always underlined, one colour. */
a {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* 3. App bar, drawer, page list, status strip, skip link ================== */

/* The skip link: a black slab, light text and the gold focus ring, as in the
   launcher. */
.skip-link {
  position: absolute;
  top: -200px;
  left: var(--s-3);
  z-index: var(--z-skip);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-control);
  background: #0B0304;
  color: #E9EEED;
  font-weight: 600;
}

.skip-link:focus {
  top: var(--s-2);
  outline: 2px solid #F4B63F;
  outline-offset: 2px;
}

/* The bar on every page, on the band colour (the launcher's black): the menu
   button at the left, the lockup in the middle, How it works at the right.
   Sticky, so the page list is always one tap away. */
.app-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-bar);
  background: var(--band);
  border-bottom: 1px solid var(--line);
}

.app-bar-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: var(--bar-h);
  padding: 0 var(--s-3) 0 var(--s-2);
}

/* The bar is sticky at the top, so what sits in it never needs scrolling into
   view. The page's scroll-padding-top (which keeps focused content clear of
   the bar) made focusing the menu button, the lockup or the button scroll the
   page (600 px down jumped to 142); a negative margin of the same size cancels
   it for them. */
.app-bar-inner > :not(.drawer),
.drawer > summary {
  scroll-margin-top: calc(-1 * (var(--bar-h) + 16px));
}

.app-bar-inner > .drawer {
  grid-column: 1;
  justify-self: start;
}

.app-bar-inner > .lockup {
  grid-column: 2;
}

.app-bar-inner > .app-bar-action {
  grid-column: 3;
  justify-self: end;
}

.app-bar .app-bar-action {
  display: none;
}

@media (min-width: 600px) {
  .app-bar .app-bar-action {
    display: inline-flex;
  }
}

/* The button never links to the page you are on, and on pages with a sidebar
   (from 1024 px) the sidebar already has the row. `visibility` keeps the
   1fr/auto/1fr grid, so the lockup stays centred. */
.app-bar .app-bar-action[aria-current="page"] {
  visibility: hidden;
}

@media (min-width: 1024px) {
  body:has(.sidebar) .app-bar .app-bar-action {
    visibility: hidden;
  }
}

/* The lockup: the mark, a gap of one cap height, the one-line wordmark. The
   mark is 2 caps tall, 26 px at the 13 px bar cap, and 6.15 caps wide; the
   wordmark is the PBD Display outlines, 19.14 caps wide. */
.lockup {
  --cap: 11px;
  display: inline-flex;
  align-items: center;
  gap: var(--cap);
  min-height: 44px;
  padding: 0 var(--s-1);
  color: var(--text-1);
  text-decoration: none;
  border-radius: var(--r-control);
}

.lockup .mark {
  display: block;
  flex: none;
  width: auto;
  height: calc(var(--cap) * 2);
}

/* The middle arrow is the same back arrow turned 45 degrees, with a bare crimson fill. */
.mark .mark-lit.mark-solid {
  fill: var(--mark-lit, var(--verm-500));
  stroke: none;
}

.lockup .wordmark {
  display: block;
  flex: none;
  width: auto;
  height: var(--cap);
}

@media (min-width: 720px) {
  .app-bar .lockup {
    --cap: 13px;
  }
}

/* Phones: the lockup sits at the left and the menu button at the right. The
   lockup (26.29 caps and 8 px wide: the 6.15-cap mark, a one-cap gap and the
   19.14-cap wordmark) no longer fits centred between the button and an equal
   right column, and a back arrow right after the burger reads as Back.
   The "How it works" button is hidden here anyway. Below 360 px the cap
   shrinks so at least 12 px stay between the wordmark and the button. The
   drawer then opens from the right, and its close button lands where the
   menu button was. */
@media (max-width: 599.98px) {
  .app-bar-inner {
    grid-template-columns: minmax(0, 1fr) auto;
    padding: 0 var(--s-2) 0 var(--s-3);
  }

  .app-bar-inner > .lockup {
    grid-column: 1;
    grid-row: 1;
    justify-self: start;
  }

  .app-bar-inner > .drawer {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .app-bar .lockup {
    --cap: min(11px, calc((100vw - 84px) / 26.30));
  }
}

/* The game the site is for, as a second line under the bar's wordmark: plain
   text in small capitals, never the game's own lettering. It shows from
   720 px, where the cap is 13 px: the wordmark (13 px), a 3 px gap and the
   11 px line together are as tall as the mark, which spans both lines. On
   narrower bars the lockup is the plain one-line version; the link's name
   says the game at every width. */
.lockup-for {
  display: none;
}

@media (min-width: 720px) {
  .lockup-game {
    display: inline-grid;
    grid-template-columns: auto auto;
    align-items: center;
    gap: 3px var(--cap);
  }

  .lockup-game .mark {
    grid-row: 1 / 3;
  }

  .lockup-game .wordmark {
    grid-column: 2;
    grid-row: 1;
    align-self: end;
  }

  .lockup-for {
    display: block;
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    color: var(--text-2);
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.6875rem;
    line-height: 1;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    white-space: nowrap;
  }
}

/* The mark (the `mark` partial): back, down-back, back, every arrow the same
   size. Its parts are filled shapes (.mark-solid). The two backs (.mark-arrow)
   take the surface's text-1; the down-back (.mark-lit, above) is PBD crimson,
   the logo's only colour. */
.mark {
  color: var(--text-1);
  overflow: visible;
}

.mark .mark-arrow.mark-solid {
  fill: currentColor;
  stroke: none;
}

/* Wordmark: the first word in text-2, the second in text-1. */
.wordmark {
  color: var(--text-1);
  fill: currentColor;
}

.wordmark .wordmark-project {
  fill: var(--text-2);
}

.wordmark-text {
  font-family: var(--font-display);
  font-stretch: 112%;
  font-weight: 800;
  font-size: calc(var(--cap, 12px) * 1.43);
  line-height: 1;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Drawer: a <details> element, so it opens and closes without JavaScript.
   Open, a panel slides in over the page from the side the menu button is on
   (the left; on phones, where the button is at the right, the right). It
   spans the full height, the app bar's row included: a header row as tall as
   the bar holds the lockup and the close button, and the page list sits
   under it. A scrim dims everything else, the app bar included.
   The summary does all the closing: its ::before is the scrim, and its
   .drawer-button (the burger, drawn as an X while open) moves into the
   header row. So the X, a click on the scrim, and Enter or Space on the
   button close the drawer with or without site.js; site.js adds Escape,
   closes it when a link is chosen, moves focus into the panel and keeps it
   there, and locks the page's scroll (.drawer-locked).
   The panel is the bar's band colour, with the bar's hairline under its
   header row. */
.drawer {
  /* 360 px, and at least 56 px of dimmed page stays in view on phones. */
  --drawer-w: min(360px, calc(100vw - 56px));
}

.drawer > summary {
  display: block;
  width: 44px;
  height: 44px;
  color: var(--text-1);
  cursor: pointer;
  list-style: none;
  -webkit-tap-highlight-color: transparent;
}

.drawer > summary::-webkit-details-marker {
  display: none;
}

/* What you see of the summary, 44 x 44 px: in the bar while the drawer is
   closed, in the panel's header row while it is open. The focus ring is drawn
   here too, so it follows the button. */
.drawer-button {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-control);
}

/* Pointers that hover only: on a phone the X lands under the finger that
   tapped the burger, and a hover state would stick to it. */
@media (hover: hover) {
  .drawer-button:hover {
    background: var(--hover);
  }
}

.drawer > summary:focus-visible {
  outline: none;
}

.drawer > summary:focus-visible .drawer-button {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.burger,
.burger::before,
.burger::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  transition: transform var(--t-fast) var(--ease-out), background-color var(--t-fast) linear;
}

.burger {
  position: relative;
}

.burger::before,
.burger::after {
  content: "";
  position: absolute;
  left: 0;
}

.burger::before {
  top: -6px;
}

.burger::after {
  top: 6px;
}

.drawer[open] .burger {
  background: transparent;
}

.drawer[open] .burger::before {
  transform: translateY(6px) rotate(45deg);
}

.drawer[open] .burger::after {
  transform: translateY(-6px) rotate(-45deg);
}

/* Layers inside the app bar (z-index 50, above the whole page): the scrim 1,
   the panel 2, the close button 3. The bar's own lockup and button stay
   under the scrim, which darkens the red field towards the launcher's black. */
.drawer[open] > summary::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  background: rgba(11, 3, 4, 0.66);
  cursor: default;
  transition: opacity var(--t-drawer) linear;
}

.drawer-panel {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  width: var(--drawer-w);
  background: var(--band);
  transition: transform var(--t-drawer) var(--ease-out);
}

/* The header row: the bar's height and its bottom line, so both lines meet. */
.drawer-head {
  display: flex;
  flex: none;
  align-items: center;
  height: calc(var(--bar-h) + 1px);
  padding: 0 calc(44px + 2 * var(--s-2)) 0 var(--s-3);
  background: var(--band);
  border-bottom: 1px solid var(--line);
}

/* The lockup at 10 px caps (the bar's is 13), smaller where the panel is
   narrower: it is 26.29 caps and 8 px wide (the .lockup rules), and the row
   keeps 12 px at the left and the close button with 8 px on each side at the
   right. 27.5 caps leaves room for every mark in the preview switcher.
   !important because the bar's lockup sizes (.app-bar .lockup, per width and
   per mark) are more specific and would reach this one too. */
.drawer-head .lockup {
  --cap: min(10px, calc((var(--drawer-w) - 84px) / 27.5)) !important;
}

.drawer-nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-4) 0 var(--s-8);
  background: var(--band);
}

/* The close button, over the panel's header row at its right end. */
.drawer[open] .drawer-button {
  position: fixed;
  top: calc((var(--bar-h) - 44px) / 2);
  left: calc(var(--drawer-w) - 44px - var(--s-2));
  z-index: 3;
  transition: transform var(--t-drawer) var(--ease-out);
}

/* Sliding in: the panel and its close button move together; the scrim fades
   in. Closing is instant, and with prefers-reduced-motion so is opening (the
   rule after the phone rules). */
@starting-style {
  .drawer[open] > summary::before {
    opacity: 0;
  }

  .drawer[open] .drawer-panel {
    transform: translateX(-100%);
  }

  .drawer[open] .drawer-button {
    transform: translateX(calc(-1 * var(--drawer-w)));
  }
}

/* Phones: the menu button is at the right (see the lockup rules), so the
   drawer opens from the right, and the close button lands where the menu
   button was. (--drawer-gutter is the scrollbar's width, which site.js adds
   back while it locks the page's scroll; 0 on phones.) */
@media (max-width: 599.98px) {
  .drawer-panel {
    left: auto;
    right: 0;
  }

  .drawer[open] .drawer-button {
    left: auto;
    right: calc(var(--s-2) + var(--drawer-gutter, 0px));
  }

  @starting-style {
    .drawer[open] .drawer-panel {
      transform: translateX(100%);
    }

    .drawer[open] .drawer-button {
      transform: translateX(var(--drawer-w));
    }
  }
}

/* Reduced motion: no slide and no fade. Without a transition the starting
   styles above never apply, so the drawer is simply there. (The general rule
   in section 9 only shortens transitions; a test showed the panel still at
   its starting offset two frames after opening.) */
@media (prefers-reduced-motion: reduce) {
  .drawer[open] > summary::before,
  .drawer-panel,
  .drawer[open] .drawer-button {
    transition: none;
  }
}

/* site.js locks the page's scroll while the drawer is open and pads the body
   by the scrollbar's width, so nothing under the scrim moves sideways. */
:root.drawer-locked {
  overflow: hidden;
}

:root.drawer-locked body {
  padding-right: var(--drawer-gutter, 0px);
}

/* Without JavaScript nothing keeps keyboard focus inside the open drawer. Once
   focus moves on (into the page, or to the lockup or button in the app bar
   under the scrim), stop covering it (WCAG 2.4.11): the panel and scrim go
   and the button, still an X, goes back into the bar. With site.js the Tab
   trap keeps focus in the drawer, so this never matches. */
body:has(.drawer[open]):has(:is(main, .sidebar, .site-footer) :focus-visible, .app-bar-inner > :not(.drawer):focus-visible) .drawer[open] > .drawer-panel,
body:has(.drawer[open]):has(:is(main, .sidebar, .site-footer) :focus-visible, .app-bar-inner > :not(.drawer):focus-visible) .drawer[open] > summary::before {
  display: none;
}

body:has(.drawer[open]):has(:is(main, .sidebar, .site-footer) :focus-visible, .app-bar-inner > :not(.drawer):focus-visible) .drawer[open] .drawer-button {
  position: static;
  transform: none;
}

/* The page list (the `nav` partial), in the drawer and the sidebar: one row
   per page, 48 px tall. The current page is marked in resurrection.css (the
   launcher's gold edge and wash); here it is a slab with the selected edge. */
.nav-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-list li + li {
  margin-top: 2px;
}

.nav-list a {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px var(--s-3);
  min-height: 48px;
  margin: 0 var(--s-3);
  padding: var(--s-1) var(--s-4);
  border-radius: var(--r-slab);
  color: var(--text-2);
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.3;
  text-decoration: none;
}

.nav-list a:hover {
  background: var(--hover);
  color: var(--text-1);
}

.nav-list a[aria-current="page"] {
  background: var(--petrol-700);
  box-shadow: inset 0 0 0 1.5px var(--selected-edge);
  color: var(--dk-text-1);
  font-weight: 600;
}

/* A state on a row (the Coming soon pill) sits at its right end. */
.nav-list .pill {
  margin-left: auto;
}

/* Download, while there is no public release: not a link, so nothing to
   focus or press. The launcher's disabled look, as on Home's download block:
   a faint light fill and edge, the arrow and label in text-3 (never crimson),
   and the reason under the label in gold capitals. */
.nav-download {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 56px;
  margin: var(--s-4) var(--s-3) 0;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-control);
  background: rgba(233, 238, 237, 0.06);
  box-shadow: inset 0 0 0 1px rgba(233, 238, 237, 0.08);
  color: #8A9C9C;
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.3;
}

.nav-download-arrow {
  flex: none;
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.nav-download-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.nav-download .nav-state {
  color: var(--link);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-transform: uppercase;
}

/* Source and Privacy close the list in small type, over a hairline. */
.nav-fine {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s-5);
  margin: var(--s-6) var(--s-3) 0;
  padding: var(--s-1) var(--s-4) 0;
  border-top: 1px solid var(--line);
  list-style: none;
}

.nav-fine li + li {
  margin-top: 0;
}

.nav-fine a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-2);
  font-size: var(--fs-small);
  font-weight: 500;
  text-decoration: none;
}

.nav-fine a:hover {
  color: var(--text-1);
  text-decoration: underline;
}

.nav-fine a[aria-current="page"] {
  color: var(--link);
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

/* 4. Layouts =============================================================== */

/* A full-width band (the coming-soon shell and the replay link page). */
.band {
  --band-bg: var(--band);
  position: relative;
  overflow: hidden;
  background: var(--band-bg);
  color: var(--text-1);
}

.band-hero {
  --band-bg: var(--petrol-900);
}

/* Pages with a sidebar: from 1024 px the page list stands on the band at the
   left, beside the page (one reading column on inner pages, Home's own column
   on Home); narrower, the drawer holds the list. resurrection.css sets the
   reading column's width. */
.page {
  display: block;
}

.sidebar {
  display: none;
}

.page-main {
  padding: var(--s-10) var(--s-4) var(--s-16);
}

.page-col {
  max-width: var(--read);
  margin: 0 auto;
}

@media (min-width: 720px) {
  .page-main {
    padding: var(--s-12) var(--s-10) var(--s-20);
  }
}

@media (min-width: 1024px) {
  .page {
    display: grid;
    grid-template-columns: var(--side) minmax(0, 1fr);
  }

  .sidebar {
    display: block;
    background: var(--band);
    border-right: 1px solid var(--line);
  }

  .sidebar-inner {
    position: sticky;
    top: var(--bar-h);
    max-height: calc(100vh - var(--bar-h));
    overflow-y: auto;
    padding: var(--s-6) 0;
  }

  /* Pages with a sidebar do not need the drawer on wide screens. */
  body:has(.sidebar) .drawer {
    display: none;
  }
}

.page-head {
  margin: 0 0 var(--s-10);
}

/* A quiet line under the lead (a date, a scope). */
.page-meta {
  margin: var(--s-3) 0 0;
  color: var(--text-2);
  font-size: 1rem;
  line-height: 1.5;
}

/* End-of-page links row (holds a ul.links). */
.page-next {
  margin-top: var(--s-12);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

.section {
  margin-top: var(--s-12);
}

.section > :first-child {
  margin-top: 0;
}

/* 5. Shared pieces ========================================================= */

/* Headline (the coming-soon shell): PBD Display in the mist highlight box, one box per line. */
.headline {
  --node-y: calc(var(--fs-hero) * 0.65);
  margin: 0;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 800;
  font-size: var(--fs-hero);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;
}

/* mist-200 rather than mist-100: the box is the largest light field in the dark
   theme, and a step down glares less at night (ink on it 12.1:1, box on petrol 10.2:1). */
.hl {
  padding: 0.02em 0.2em 0.06em;
  background: var(--mist-200);
  color: var(--ink);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Wide screens: PBD Display sets about 30 % wider than Saira did at the same
   size, which pushed the headline box into the hero drawing's 60 px clearance.
   The headline is capped at 579 px (60 px or more clear of the drawing at every
   width from 1024 px) and set 14 % smaller: it takes three lines. */
@media (min-width: 1024px) {
  .band-hero .headline {
    font-size: calc(var(--fs-hero) * 0.86);
    max-width: 579px;
  }
}

.hero-sub {
  margin: var(--s-5) 0 0;
  max-width: 32ch;
  color: var(--text-1);
  font-weight: 500;
  font-size: var(--fs-sub);
  line-height: 1.36;
}

.hero-compat {
  margin: var(--s-3) 0 0;
  max-width: 46ch;
  color: var(--text-2);
}

@media (min-width: 1024px) {
  .hero-sub,
  .hero-compat {
    max-width: min(46ch, 56%);
  }
}

/* Section label (the replay link page): a box over its heading. */
.label-box {
  display: block;
  width: fit-content;
  margin: 0 0 var(--s-6);
  padding: 1px 10px 3px;
  background: var(--petrol-700);
  color: var(--dk-text-1);
  font-family: var(--font-display);
  font-stretch: 112%;
  font-weight: 700;
  font-size: var(--fs-label);
  line-height: 1.35;
}

.icon {
  display: inline-block;
  flex: none;
  width: 24px;
  height: 24px;
  vertical-align: middle;
  color: var(--text-1);
}

svg.icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The download block: the primary, then one sentence under it. */
.download {
  margin: 0 0 var(--s-4);
}

.download-note {
  margin: var(--s-3) 0 0;
  color: var(--text-2);
  font-size: 1rem;
  line-height: 1.5;
}

/* The download arrow inside the primary: the same block arrow as the logo's, in the label's ink. */
.dl-arrow {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.links li + li {
  margin-top: 0;
}

.links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* 6. Buttons =============================================================== */

/* The primary, as in the launcher: one plain crimson rectangle per screen, the
   label in PBD Display at 20 px in ink. Ink on crimson is 4.05:1, so the label
   never gets smaller (it is declared bold, which the one-weight face draws as
   is, so it counts as large text). Pressed, it steps 2 px left for 60 ms. */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-3);
  min-height: 48px;
  min-width: 0;
  margin: 0;
  padding: 6px 22px;
  border: 0;
  border-radius: var(--r-control);
  background: var(--verm-500);
  color: var(--on-verm);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  line-height: 1.1;
  letter-spacing: 0.1em;
  text-align: left;
  text-transform: uppercase;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--t-fast) linear, transform var(--t-press) linear;
}

.btn-primary:hover {
  background: var(--verm-400);
  color: var(--on-verm);
}

.btn-primary:active {
  background: var(--verm-600);
  transform: translateX(-2px);
}

.btn-primary:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.btn-lg {
  min-height: 56px;
  padding: 6px 28px;
}

.btn-block {
  display: flex;
  width: 100%;
}

/* Disabled, as in the launcher: never crimson. A faint light edge and fill, the
   label in text-3; say why next to it. Use <button disabled>,
   aria-disabled="true", or a <span> with .is-disabled. */
.btn-primary:is(:disabled, [aria-disabled="true"], .is-disabled) {
  background: rgba(233, 238, 237, 0.06);
  box-shadow: inset 0 0 0 1px rgba(233, 238, 237, 0.08);
  color: #8A9C9C;
  cursor: not-allowed;
  transform: none;
}

span.btn-primary.is-disabled {
  cursor: default;
}

/* Progress: a hard-stop fill runs left to right. Set style="--progress: 42%". */
.btn-primary.is-progress {
  background-image: linear-gradient(90deg, var(--verm-500) var(--progress, 0%), rgba(233, 238, 237, 0.1) var(--progress, 0%));
  color: var(--on-verm);
  cursor: progress;
  transform: none;
}

/* Outline secondary. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 44px;
  margin: 0;
  padding: 0 var(--s-4);
  border: 1.5px solid var(--control-edge);
  border-radius: var(--r-control);
  background: transparent;
  color: var(--text-1);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--t-fast) linear, border-color var(--t-fast) linear;
}

.btn:hover {
  border-color: var(--text-1);
  background: var(--hover);
  color: var(--text-1);
}

.btn:active {
  background: var(--press);
}

.btn:is(:disabled, [aria-disabled="true"]) {
  border-style: dashed;
  background: transparent;
  color: var(--text-2);
  cursor: not-allowed;
}

/* Small outline button (app bar): 36 px to look at, 44 px to hit. */
.btn-sm {
  min-height: 36px;
  padding: 0 var(--s-3);
  font-size: 0.9375rem;
}

.btn-sm::before {
  content: "";
  position: absolute;
  inset: -5px -2px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-4);
  margin: var(--s-6) 0;
}

/* 7. Content =============================================================== */

/* Notices: a full-tint box with an icon and words. No side stripe.
   The icon is drawn by the stylesheet; put an .icon first to use your own. */
.notice {
  --notice-bg: var(--notice-info);
  --notice-fg: var(--text-info);
  --notice-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M12%2011v5.5M12%207.6v.01%22%2F%3E%3C%2Fsvg%3E");
  position: relative;
  margin: var(--s-6) 0;
  padding: var(--s-4) var(--s-5) var(--s-4) 52px;
  border-radius: var(--r-box);
  background: var(--notice-bg);
  color: var(--text-1);
  font-size: 1rem;
  line-height: 1.55;
}

.notice::before {
  content: "";
  position: absolute;
  left: var(--s-4);
  top: 18px;
  width: 22px;
  height: 22px;
  background-color: var(--notice-fg);
  -webkit-mask: var(--notice-icon) center / contain no-repeat;
  mask: var(--notice-icon) center / contain no-repeat;
}

.notice:has(> .icon:first-child)::before {
  display: none;
}

.notice > .icon:first-child {
  position: absolute;
  left: var(--s-4);
  top: 17px;
  color: var(--notice-fg);
}

.notice > :last-child {
  margin-bottom: 0;
}

.notice-title {
  margin: 0 0 var(--s-1);
  font-weight: 600;
  color: var(--text-1);
}

.notice-good {
  --notice-bg: var(--notice-good);
  --notice-fg: var(--good);
  --notice-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M8.2%2012.4l2.6%202.6%205-5.4%22%2F%3E%3C%2Fsvg%3E");
}

.notice-warn {
  --notice-bg: var(--notice-warn);
  --notice-fg: var(--warn);
  --notice-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M12%203.8L21%2019.6H3z%22%2F%3E%3Cpath%20d%3D%22M12%2010v4.2M12%2016.9v.01%22%2F%3E%3C%2Fsvg%3E");
}

.notice-bad {
  --notice-bg: var(--notice-bad);
  --notice-fg: var(--bad);
  --notice-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M9.2%209.2l5.6%205.6M14.8%209.2l-5.6%205.6%22%2F%3E%3C%2Fsvg%3E");
}

.text-good {
  color: var(--good);
}

.text-warn {
  color: var(--warn);
}

.text-bad {
  color: var(--bad);
}

/* Tables: always inside a focusable scroll wrapper, so the table scrolls, not the page.
   <div class="table-wrap" tabindex="0" role="region" aria-labelledby="CAPTION-ID"> */
.table-wrap {
  margin: var(--s-6) 0;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-box);
}

.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 1rem;
  line-height: 1.45;
}

.data-wide {
  min-width: 640px;
}

.data caption {
  padding: var(--s-3) var(--s-4) var(--s-2);
  caption-side: top;
  color: var(--text-1);
  font-weight: 600;
  text-align: left;
}

.data th,
.data td {
  padding: 10px var(--s-4);
  border-top: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.data thead th {
  color: var(--text-2);
  font-weight: 600;
  font-size: 0.9375rem;
  white-space: nowrap;
}

.data tbody th {
  color: var(--text-1);
  font-weight: 600;
}

.data td {
  color: var(--text-1);
}

.data .num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Phones: header cells may wrap and cells sit a little tighter, so short tables
   fit a 320 px screen. `.data-wide` tables still scroll inside their box. */
@media (max-width: 479.98px) {
  .data thead th,
  .data thead th.num {
    white-space: normal;
  }

  .data caption,
  .data th,
  .data td {
    padding-left: var(--s-3);
    padding-right: var(--s-3);
  }
}

/* Paragraphs inside cells, and a quieter caveat line (`.cell-note`). */
.data td > p {
  margin: 0;
}

.data td > p + p {
  margin-top: var(--s-2);
}

.cell-note {
  color: var(--text-2);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.cell-note strong {
  color: var(--text-1);
}

/* A link that is the whole content of a cell: a 44 px target. */
.data td > a:only-child {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: -10px;
}

/* `.data-kv`: a two-column label/value table. On phones each row stacks, the
   label above its value, so it fits 320 px without scrolling. Give the table
   explicit ARIA table roles (role="table", "rowgroup", "row", "rowheader",
   "cell") so screen readers keep it a table when the display type changes. */
.data-kv tbody th {
  width: 36%;
}

@media (min-width: 720px) {
  .data-kv tbody th {
    width: 12rem;
  }
}

@media (max-width: 599.98px) {
  .data-kv,
  .data-kv caption,
  .data-kv tbody,
  .data-kv tr,
  .data-kv th,
  .data-kv td {
    display: block;
  }

  .data-kv tbody th {
    width: auto;
    padding: var(--s-3) var(--s-4) 2px;
  }

  .data-kv td {
    padding: 0 var(--s-4) var(--s-3);
    border-top: 0;
    overflow-wrap: anywhere;
  }
}

.notes {
  margin: calc(var(--s-6) * -1 + var(--s-2)) 0 var(--s-6);
  color: var(--text-2);
  font-size: var(--fs-small);
  line-height: 1.5;
}

/* A one-line note right under a table. */
.table-wrap + .fine {
  margin-top: calc(var(--s-2) - var(--s-6));
}

/* Numbered steps: a ringed number (like a round button) beside each step.
   <ol class="steps"><li><h3>Title</h3><p>Text</p></li>...</ol> */
.steps {
  margin: var(--s-6) 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.steps > li {
  position: relative;
  min-height: 36px;
  margin: 0;
  padding-left: 52px;
  counter-increment: step;
}

.steps > li + li {
  margin-top: var(--s-6);
}

.steps > li::before {
  content: counter(step);
  position: absolute;
  top: -2px;
  left: 0;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--control-edge);
  border-radius: 50%;
  color: var(--text-1);
  /* Barlow, not the display face: PBD Display's 1 has a flag and no foot, and
     at 16 px in a ring it reads as a 7. */
  font-family: var(--font-ui);
  font-stretch: 100%;
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.steps h3 {
  margin: 0 0 var(--s-1);
  font-size: var(--fs-h3);
  line-height: 1.5;
}

.steps li > p {
  margin: 0;
}

.steps li > p + p {
  margin-top: var(--s-2);
}

/* Term and description rows. */
.dl {
  margin: var(--s-6) 0;
  border-top: 1px solid var(--line);
}

.dl > div {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}

.dl dt {
  color: var(--text-1);
  font-weight: 600;
}

.dl dd {
  margin: var(--s-1) 0 0;
  color: var(--text-1);
}

.dl dd > :last-child {
  margin-bottom: 0;
}

@media (min-width: 720px) {
  .dl > div {
    display: grid;
    grid-template-columns: 12rem minmax(0, 1fr);
    gap: var(--s-6);
  }

  .dl dd {
    margin: 0;
  }
}

/* Figures and captions. */
.figure {
  margin: var(--s-8) 0;
}

.figure-frame {
  overflow: auto;
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-box);
  background: var(--surface);
}

.figure figcaption {
  margin-top: var(--s-2);
  color: var(--text-3);
  font-size: var(--fs-small);
  line-height: 1.43;
}

/* Details and summary. */
.disclosure {
  border-bottom: 1px solid var(--line);
}

.disclosure:first-of-type {
  border-top: 1px solid var(--line);
}

.disclosure > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 52px;
  padding: var(--s-3) var(--s-1);
  color: var(--text-1);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.disclosure > summary::-webkit-details-marker {
  display: none;
}

.disclosure > summary:hover {
  background: var(--hover);
}

.disclosure > summary::after {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  background-color: var(--text-2);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%3E%3Cpath%20d%3D%22M2.5%208h11M8%202.5v11%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%3E%3Cpath%20d%3D%22M2.5%208h11M8%202.5v11%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
}

.disclosure[open] > summary::after {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%3E%3Cpath%20d%3D%22M2.5%208h11%22%2F%3E%3C%2Fsvg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.75%22%20stroke-linecap%3D%22round%22%3E%3Cpath%20d%3D%22M2.5%208h11%22%2F%3E%3C%2Fsvg%3E");
}

.disclosure-body {
  padding: 0 var(--s-1) var(--s-4);
  color: var(--text-1);
}

.disclosure-body > :last-child {
  margin-bottom: 0;
}

/* Code and file names. */
code,
kbd,
samp,
pre {
  font-family: var(--font-mono);
  font-size: 0.875em;
}

code {
  padding: 0.1em 0.35em;
  border-radius: 3px;
  background: var(--code-bg);
  color: var(--text-1);
}

pre {
  overflow-x: auto;
  margin: 0 0 var(--s-4);
  padding: var(--s-4);
  border-radius: var(--r-box);
  background: var(--code-bg);
  line-height: 1.5;
}

pre code {
  padding: 0;
  background: none;
}

.hash {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  overflow-wrap: anywhere;
}

/* An address or file name that is not a link (repositories that are not public
   yet, host names). Monospace, no box, wraps anywhere. */
.addr {
  font-family: var(--font-mono);
  font-size: 0.875em;
  overflow-wrap: anywhere;
}

/* The input strip (the input-strip partial): our arrows in the b, n, b, d/b
   rhythm, at low contrast with one arrow lit. "Why the name" and the style
   guide only. */
.strip {
  display: block;
  color: var(--text-3);
}

.strip .input-strip {
  display: block;
  width: 100%;
  max-width: 376px;
  height: auto;
}

/* The lit arrow is brighter, never crimson (crimson is kept for the primary
   button and the logo's lit tile, which draws the same cancel). */
.strip .lit {
  color: var(--text-1);
}

/* Guide pieces: Download, Install, FAQ and Troubleshooting ----------------
   Short, scannable help for players who are not technical. Every colour is a
   token, so the contrast pairs in contrast.mjs already cover them.
     .tag          a status word (Ready, Preview, Coming soon, Not active yet)
     .ui           the name of an on-screen button, as the player sees it
     .checklist    "have these ready" items with a tick
     .jump         a grid of problem links at the top of a long help page
     .versions     version rows: a name, its status tags, one sentence
     .win-sketch   a plain drawing of the Windows warning (no screenshot)  */

.tag {
  display: inline-block;
  padding: 1px 8px 2px;
  border: 1px solid currentColor;
  border-radius: 3px;
  color: var(--text-2);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.45;
  vertical-align: 0.08em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.tag-ready {
  color: var(--good);
}

.tag-preview {
  color: var(--warn);
}

/* An on-screen button name: a thin outline like a launcher control. */
.ui {
  display: inline-block;
  padding: 0 6px 1px;
  border: 1px solid var(--control-edge);
  border-radius: 3px;
  color: var(--text-1);
  font-weight: 600;
  line-height: 1.4;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* A one-line command the reader copies: wraps instead of scrolling, so it
   stays readable at 320 px and with enlarged text. */
.pre-wrap {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Things to have ready, each with a tick. */
.checklist {
  margin: var(--s-5) 0 var(--s-6);
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.checklist > li {
  position: relative;
  margin: 0;
  padding: var(--s-3) 0 var(--s-3) 36px;
  border-bottom: 1px solid var(--line);
}

.checklist > li + li {
  margin-top: 0;
}

.checklist > li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: calc(var(--s-3) + 3px);
  width: 20px;
  height: 20px;
  background-color: var(--warn);
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M5%2012.5l4.5%204.5L19%207.5%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M5%2012.5l4.5%204.5L19%207.5%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
}

.checklist strong {
  color: var(--text-1);
}

.checklist .hint {
  display: block;
  color: var(--text-2);
  font-size: 1rem;
  line-height: 1.5;
}

/* Problem links at the top of a help page: one column on phones, two from 600 px. */
.jump {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-2);
  margin: var(--s-5) 0 0;
  padding: 0;
  list-style: none;
}

.jump > li + li {
  margin-top: 0;
}

@media (min-width: 600px) {
  .jump {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.jump a {
  display: block;
  height: 100%;
  min-height: 44px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-box);
  background: var(--surface);
  color: var(--text-1);
  text-decoration: none;
}

.jump a:hover {
  border-color: var(--selected-edge);
  background: var(--hover);
}

.jump-title {
  display: block;
  color: var(--link);
  font-weight: 600;
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.jump-hint {
  display: block;
  margin-top: 2px;
  color: var(--text-2);
  font-size: 0.9375rem;
  line-height: 1.45;
}

/* Version rows: name, tags, then one sentence. */
.versions {
  margin: var(--s-5) 0 var(--s-6);
  border-top: 1px solid var(--line);
}

.versions > div {
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line);
}

.versions dt {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-3);
  color: var(--text-1);
  font-weight: 600;
}

.versions dt .tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  font-weight: 400;
}

.versions dd {
  margin: var(--s-2) 0 0;
  color: var(--text-1);
}

/* A plain drawing of the Windows warning: words and two outlined buttons with
   numbered markers. Hidden from screen readers; the caption says the same. */
.win-sketch {
  max-width: 460px;
  padding: var(--s-5) var(--s-5) var(--s-4);
  border: 1px solid var(--control-edge);
  border-radius: 4px;
  background: var(--band);
  color: var(--text-1);
  font-size: 1rem;
  line-height: 1.5;
}

.win-sketch p {
  margin: 0 0 var(--s-3);
}

.win-sketch-title {
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.3;
}

.win-sketch-fine {
  color: var(--text-2);
}

.win-sketch-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

.win-sketch-buttons {
  justify-content: flex-end;
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

.win-sketch .ui-link {
  padding: 0;
  border: 0;
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.win-sketch .ui {
  padding: 4px 14px 5px;
}

.win-sketch .ui.is-target {
  border: 2px solid var(--warn);
}

/* The numbered marker beside the control to press, ringed like a step. */
.win-sketch .pick {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 2px solid var(--warn);
  border-radius: 50%;
  color: var(--warn);
  font-weight: 700;
  font-size: 0.9375rem;
  line-height: 1;
}

@media (forced-colors: active) {
  .tag,
  .ui,
  .jump a,
  .win-sketch {
    border: 1px solid CanvasText;
  }

  .checklist > li::before {
    forced-color-adjust: none;
    background-color: CanvasText;
  }
}

/* 8. Footer ================================================================ */

.site-footer {
  flex: none;
  color: var(--text-2);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.footer-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s-5);
  margin: 0 0 var(--s-4);
  padding: 0;
  list-style: none;
}

.footer-nav li + li {
  margin-top: 0;
}

.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  color: var(--text-1);
}

.footer-nav a[aria-current="page"] {
  text-decoration-thickness: 2px;
}

/* Project Backdash elsewhere (src/_partials/social.html): one-colour icon links, as on most project sites. */
.social-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--s-5);
  /* Pull the row left by the tap padding so the first icon lines up with the text above and below it. */
  margin: 0 0 var(--s-4) -10px;
  padding: 0;
  list-style: none;
}

.social-links li + li {
  margin-top: 0;
}

/* At least 44 x 44 px to hit, with the 24 px icon centred in it. */
.social-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  color: var(--text-1);
}

/* Icon links: one-colour brand marks at 24 px inside 44 px targets; they dim on hover like the other quiet links. */
.social-links .social-icon {
  transition: color var(--t-fast) linear;
}

.social-links .social-icon:hover {
  color: var(--text-2);
}

.social-links .social-icon svg {
  display: block;
  width: 24px;
  height: 24px;
}

.site-footer p {
  margin: 0 0 var(--s-2);
}

.footer-free {
  color: var(--text-1);
  font-weight: 500;
}

/* One line of fine print: independence and the trademark. */
.footer-fine {
  max-width: 72ch;
  color: var(--text-3);
  font-size: var(--fs-small);
  line-height: 1.5;
}

/* 9. Utilities, motion, forced colours, print ============================= */

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.nowrap {
  white-space: nowrap;
}

.mt-0 {
  margin-top: 0 !important;
}

.mb-0 {
  margin-bottom: 0 !important;
}

/* A forced line break that only applies on phones (hero headline). */
@media (min-width: 600px) {
  .br-phone {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .btn-primary:active {
    transform: none;
  }
}

@media (forced-colors: active) {
  .btn-primary {
    border: 2px solid ButtonText;
    forced-color-adjust: auto;
  }

  .hl,
  .label-box {
    border: 1px solid CanvasText;
  }

  /* The logo in one colour: every arrow in CanvasText. */
  .mark {
    forced-color-adjust: none;
  }

  .mark .mark-arrow.mark-solid,
  .mark .mark-lit.mark-solid {
    fill: CanvasText;
  }

  /* The wordmark sets its own colour, so forced colours would keep its fills
     (text-1 and text-2), which vanish on a light high-contrast Canvas. */
  .wordmark,
  .wordmark .wordmark-project,
  .wordmark .wordmark-main {
    forced-color-adjust: none;
    fill: CanvasText;
  }

  .notice {
    border: 1px solid CanvasText;
  }

  /* Shapes drawn with background colours would become Canvas and vanish: the
     hamburger, the notice and disclosure icons. */
  .burger,
  .burger::before,
  .burger::after,
  .notice::before,
  .disclosure > summary::after {
    forced-color-adjust: none;
    background-color: CanvasText;
  }

  .drawer[open] .burger {
    background-color: transparent;
  }

  .drawer-panel {
    border-right: 1px solid CanvasText;
  }

  .nav-list a[aria-current="page"],
  .nav-download {
    border: 2px solid CanvasText;
  }
}

@media (forced-colors: active) and (max-width: 599.98px) {
  .drawer-panel {
    border-right: 0;
    border-left: 1px solid CanvasText;
  }
}

@media print {
  .app-bar,
  .sidebar,
  .skip-link {
    display: none !important;
  }

  .band,
  body {
    background: #fff;
    color: #000;
  }
}
