/* Self-hosted. Generated by scripts/fetch-fonts.mjs — do not edit by hand. */
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:400 800;font-display:swap;src:url('/fonts/bricolage-grotesque-latin-ext-400-800.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:400 800;font-display:swap;src:url('/fonts/bricolage-grotesque-latin-400-800.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400 700;font-display:swap;src:url('/fonts/instrument-sans-latin-ext-400-700.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400 700;font-display:swap;src:url('/fonts/instrument-sans-latin-400-700.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/space-mono-latin-ext-400.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/space-mono-latin-400.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:700;font-display:swap;src:url('/fonts/space-mono-latin-ext-700.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:700;font-display:swap;src:url('/fonts/space-mono-latin-700.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}


/* ===========================================================================
   Atrium — daylight paper editorial
   ---------------------------------------------------------------------------
   The upstream product is a dark near-black page with a lime accent, a pixel
   display face and rendered 3D mascots. This system is the other pole: warm
   paper, ink linework, one clay accent, flat drawings, and print furniture
   (hairline rules, mono micro-type, ledger columns) instead of glow.

   Nothing here may be duplicated into a page as an inline style: the site is
   served under a CSP whose style-src is 'self' with no 'unsafe-inline', so an
   inline rule is parsed and then declined, and the element silently keeps its
   default. Every visual decision lives in this file.
   =========================================================================== */

:root {
  /* Paper */
  --paper:    #f6f2e9;
  --paper-2:  #ede7da;
  --paper-3:  #e3dbc9;

  /* Ink */
  --ink:      #171512;
  --ink-2:    #3b3630;
  --slate:    #6b6459;   /* 4.75:1 on --paper */
  --rule:     #cfc6b3;
  --rule-2:   #ded6c4;

  /* Accents, used sparingly */
  --clay:     #d2542a;   /* 4.75:1 on --paper */
  --clay-ink: #a83e1b;
  --pine:     #1f5b4e;   /* 7.15:1 on --paper */
  --sun:      #e8b647;

  /* Type */
  --display: "Bricolage Grotesque", "Instrument Sans", system-ui, sans-serif;
  --body:    "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Measure */
  --gutter:  clamp(20px, 5vw, 56px);
  --shell:   min(1240px, 100% - (var(--gutter) * 2));
  --reading:  68ch;

  /* Rhythm */
  --step:    clamp(56px, 7vw, 104px);
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-width: 320px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* A page must never scroll sideways at 390. */
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--clay); color: var(--paper); }

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

.shell { width: var(--shell); margin-inline: auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--paper);
  padding: 10px 16px; font-family: var(--mono); font-size: 12px;
}
.skip:focus { left: 12px; top: 12px; }

/* ---------------------------------------------------------------- type ---- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.028em;
  line-height: 1.02;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: clamp(40px, 7.4vw, 92px); font-weight: 800; letter-spacing: -0.036em; }
h2 { font-size: clamp(29px, 4.2vw, 52px); }
h3 { font-size: clamp(19px, 1.7vw, 23px); letter-spacing: -0.018em; }
h4 { font-size: 16px; letter-spacing: -0.01em; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: clamp(17px, 1.55vw, 21px);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 46ch;
}

.prose { max-width: var(--reading); }
.prose p { color: var(--ink-2); }
.prose a { color: var(--clay-ink); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--ink); }

/* Mono micro-type is the site's connective tissue: kickers, labels, figures,
   addresses, and the whole navigation. */
.kicker {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--clay-ink);
  margin-bottom: 18px;
}

.micro {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--slate);
}

.figure {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* ------------------------------------------------------------- chrome ----- */

.chrome {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}

.chrome__bar {
  width: var(--shell);
  margin-inline: auto;
  min-height: 60px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex: 0 0 auto;
  margin-right: auto;
}
.mark svg { width: 28px; height: 28px; }
.mark span {
  font-family: var(--display);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.04em;
}

/* The checker asserts nav links render at 13px or less in a mono face, because a
   header whose classes match nothing still renders — as a run of body prose. */
.chrome__links {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.9vw, 28px);
}

.chrome__links a {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
  white-space: nowrap;
}
.chrome__links a:hover { color: var(--ink); border-bottom-color: var(--clay); }
.chrome__links a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); }

.chrome__links a.chrome__app {
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-bottom-color: var(--ink);
  padding: 7px 13px;
}
.chrome__links a.chrome__app:hover { background: var(--clay-ink); border-color: var(--clay-ink); }

@media (max-width: 860px) {
  .chrome__bar { min-height: 54px; flex-wrap: wrap; gap: 0 16px; }
  .mark { padding: 10px 0; }
  .chrome__links {
    order: 3;
    width: 100%;
    gap: 14px;
    overflow-x: auto;
    padding-bottom: 9px;
    scrollbar-width: none;
  }
  .chrome__links::-webkit-scrollbar { display: none; }
  .chrome__links a { font-size: 11px; }
}

/* ------------------------------------------------------------ opening ----- */

/* Rule 2: every route opens with its own animated drawing, full bleed to the
   content column, landscape, above the fold and never taller than 0.9 screens. */
.opening {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1200 / 620;
  background: var(--paper-2);
  border-bottom: 1px solid var(--rule);
}

/* The box keeps the drawing's own 1200x620 at every width, so xMidYMid slice never actually
   slices. Cropping it taller on a phone looked better in the abstract and cut the first and
   last station off the four step drawing, which is the whole of what that picture says. */

/* --------------------------------------------------------------- hero ----- */

.hero {
  border-bottom: 1px solid var(--rule);
  padding: clamp(34px, 5vw, 60px) 0 clamp(38px, 5vw, 66px);
}

.hero__grid {
  display: grid;
  gap: clamp(26px, 3.4vw, 48px);
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); align-items: end; }
}

.hero h1 { margin-bottom: 22px; }
.hero h1 em { font-style: normal; color: var(--clay); }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 11px;
  margin-top: 28px;
}

.hero__aside {
  border-top: 2px solid var(--ink);
  padding-top: 16px;
}

.hero__facts { list-style: none; margin: 0; padding: 0; }
.hero__facts li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--rule-2);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}
.hero__facts li:last-child { border-bottom: 0; }
.hero__facts b { font-weight: 700; color: var(--ink); }
.hero__facts span { color: var(--slate); text-transform: uppercase; letter-spacing: 0.1em; font-size: 11px; }

/* -------------------------------------------------------------- button ---- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 46px;
  padding: 0 20px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn:hover { background: var(--ink); color: var(--paper); }

/* Paper on --clay measures 3.73:1, under the 4.5 the standard asks for. --clay-ink is the same
   hue one step down and measures 5.58:1, so every surface that carries paper-coloured text uses
   it and --clay is kept for rules, marks and display type. */
.btn--solid { background: var(--clay-ink); border-color: var(--clay-ink); color: var(--paper); }
.btn--solid:hover { background: #8e3315; border-color: #8e3315; color: var(--paper); }

.btn--quiet { border-color: var(--rule); color: var(--ink-2); }
.btn--quiet:hover { background: transparent; border-color: var(--ink); color: var(--ink); }

.btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* ------------------------------------------------------------- address ---- */

.address {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 22px;
  padding: 10px 13px;
  border: 1px dashed var(--rule);
  background: var(--paper-2);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--slate);
  width: fit-content;
  max-width: 100%;
}
.address b { color: var(--ink); letter-spacing: 0.08em; }
.address code {
  font-family: var(--mono);
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------- band ----- */

.band { padding: var(--step) 0; border-bottom: 1px solid var(--rule); }
.band--tint { background: var(--paper-2); }
.band--ink { background: var(--ink); color: var(--paper); border-bottom-color: var(--ink); }
.band--ink .kicker { color: var(--sun); }
.band--ink p { color: color-mix(in srgb, var(--paper) 76%, var(--ink)); }
.band--ink .lede { color: color-mix(in srgb, var(--paper) 82%, var(--ink)); }

.band__head { margin-bottom: clamp(30px, 3.6vw, 52px); }

@media (min-width: 900px) {
  .band__head {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: clamp(28px, 4vw, 72px);
    align-items: end;
  }
  .band__head .lede { max-width: 40ch; }
}

/* --- layout family A: a ruled ledger list ---------------------------------- */

.ledger { border-top: 2px solid var(--ink); }
.band--ink .ledger { border-top-color: var(--paper); }

.ledger__row {
  display: grid;
  gap: 6px 28px;
  padding: 22px 0;
  border-bottom: 1px solid var(--rule-2);
  align-items: baseline;
}
.band--ink .ledger__row { border-bottom-color: color-mix(in srgb, var(--paper) 22%, transparent); }

@media (min-width: 760px) {
  .ledger__row { grid-template-columns: 26px minmax(0, 1fr) minmax(0, 1.5fr); }
}

.ledger__mark { font-family: var(--mono); font-size: 12px; color: var(--clay-ink); }
.band--ink .ledger__mark { color: var(--sun); }
.ledger__row p { color: var(--slate); margin: 0; font-size: 15.5px; }
.band--ink .ledger__row p { color: color-mix(in srgb, var(--paper) 70%, var(--ink)); }

/* --- layout family B: plates in an asymmetric grid -------------------------
   The default track is auto-fit so a group of three, four or six always fills its row.
   .plates--feature is the deliberate asymmetric case, and it is used on one page only. */

.plates {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}

@media (min-width: 1080px) {
  .plates--feature { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .plates--feature .plate { grid-column: span 2; }
  .plates--feature .plate--wide { grid-column: span 4; }
  .plates--feature .plate--lead { grid-column: span 4; }
}

.plate {
  background: var(--paper);
  padding: clamp(22px, 2.4vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
}
.plate p { color: var(--slate); font-size: 15.5px; margin: 0; }
.plate h3 { margin: 0; }

/* The icon is a mark, not an illustration. Without a size it inherits the 256 unit viewBox
   and fills the card, which is exactly what it did. */
.plate__no {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--clay-ink);
  text-transform: uppercase;
  display: block;
}
.plate__no svg { width: 22px; height: 22px; }

a.plate:hover { background: var(--paper-2); }
a.plate:hover h3 { color: var(--clay-ink); }

.plate--lead { background: var(--pine); color: var(--paper); }
.plate--lead p { color: color-mix(in srgb, var(--paper) 82%, var(--pine)); }
.plate--lead .plate__no { color: var(--sun); }
a.plate--lead:hover { background: #1a4d42; }
a.plate--lead:hover h3 { color: var(--sun); }

/* --- layout family C: a stepped sequence ---------------------------------- */

.steps { display: grid; gap: 0; counter-reset: step; }

@media (min-width: 980px) { .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.step {
  padding: 26px 0 26px;
  border-top: 1px solid var(--rule);
  position: relative;
}
@media (min-width: 980px) {
  .step { padding: 26px clamp(16px, 1.6vw, 26px) 8px 0; border-top: 2px solid var(--ink); }
}
.step__no {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.15em;
  color: var(--clay-ink);
  display: block;
  margin-bottom: 14px;
}
.step h3 { margin-bottom: 9px; }
.step p { color: var(--slate); font-size: 15px; margin: 0; }

/* --- layout family D: the ticker board ------------------------------------ */

.board {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tile {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 9px 13px;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
}
.tile small {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate);
  font-weight: 400;
}
.tile--soon { border-style: dashed; border-color: var(--rule); color: var(--slate); background: transparent; }
.tile--pick { background: var(--clay-ink); border-color: var(--clay-ink); color: var(--paper); }
.tile--pick small { color: color-mix(in srgb, var(--paper) 93%, var(--clay-ink)); }

/* --- layout family E: the room index -------------------------------------- */

.index { border-top: 2px solid var(--ink); }

.index__row {
  display: grid;
  gap: 4px 20px;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule-2);
  text-decoration: none;
  align-items: baseline;
}

@media (min-width: 860px) {
  .index__row { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.9fr) 130px; align-items: center; }
}

.index__row:hover { background: var(--paper-2); }
.index__name {
  font-family: var(--display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em;
  display: inline-flex; align-items: center; gap: 7px;
}
.index__seal { width: 15px; height: 15px; color: var(--pine); flex: 0 0 auto; }
.index__desc { color: var(--slate); font-size: 15px; margin: 0; }
.index__tag {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--clay-ink);
  justify-self: start;
}

@media (min-width: 860px) { .index__tag { justify-self: end; } }

/* --- layout family F: a split feature ------------------------------------- */

.split { display: grid; gap: clamp(26px, 3.6vw, 60px); }

@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
  .split--wide { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
}

.checks { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 10px; }
.checks li {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  font-size: 15.5px;
  color: var(--ink-2);
}
.checks svg { width: 16px; height: 16px; margin-top: 3px; color: var(--pine); }
.band--ink .checks li { color: color-mix(in srgb, var(--paper) 78%, var(--ink)); }
.band--ink .checks svg { color: var(--sun); }

/* ---------------------------------------------------------------- docs ---- */

.doc { display: grid; gap: clamp(28px, 4vw, 56px); padding: var(--step) 0; }

@media (min-width: 1000px) {
  .doc { grid-template-columns: 210px minmax(0, 1fr); align-items: start; }
}

.doc { min-width: 0; }
.doc > * { min-width: 0; }
.doc__nav { position: sticky; top: 84px; align-self: start; min-width: 0; }
.doc__nav ol { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.doc__nav li { border-bottom: 1px solid var(--rule); }
.doc__nav a {
  display: block;
  padding: 9px 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--slate);
  text-decoration: none;
}
.doc__nav a:hover { color: var(--clay-ink); }

@media (max-width: 999px) {
  .doc__nav { position: static; }
    .doc__nav ol { display: flex; flex-wrap: wrap; gap: 0 18px; border-top: 0; max-width: 100%; }
  .doc__nav a { white-space: normal; overflow-wrap: anywhere; }
  .doc__nav li { border-bottom: 0; }
}

.doc__section { padding-bottom: clamp(34px, 4vw, 58px); scroll-margin-top: 84px; }
.doc__section + .doc__section { border-top: 1px solid var(--rule); padding-top: clamp(34px, 4vw, 58px); }
.doc__section h2 { margin-bottom: 18px; }
.doc__section > p, .doc__section > ul { max-width: var(--reading); }
.doc__section ul { color: var(--ink-2); padding-left: 1.1em; margin: 0 0 1.1em; }
.doc__section li { margin-bottom: 7px; }

.note {
  border-left: 3px solid var(--pine);
  background: var(--paper-2);
  padding: 16px 20px;
  margin: 22px 0;
  max-width: var(--reading);
}
.note h4 { margin-bottom: 6px; }
.note p { color: var(--ink-2); font-size: 15.5px; }
.note--warn { border-left-color: var(--clay); }

.table-scroll { overflow-x: auto; margin: 22px 0; border: 1px solid var(--rule); }
table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: 14.5px; }
th, td { text-align: left; padding: 11px 15px; border-bottom: 1px solid var(--rule-2); vertical-align: top; }
th {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  background: var(--paper-2);
  white-space: nowrap;
}
td { color: var(--ink-2); }
tr:last-child td { border-bottom: 0; }

pre {
  overflow-x: auto;
  background: var(--ink);
  color: var(--paper);
  padding: 18px 20px;
  margin: 22px 0;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.7;
}
code { font-family: var(--mono); font-size: 0.92em; }

.kv { border-top: 1px solid var(--rule); margin: 22px 0; }
.kv__row {
  display: grid;
  gap: 4px 20px;
  padding: 13px 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 700px) { .kv__row { grid-template-columns: 190px minmax(0, 1fr); } }
.kv__row dt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--slate); }
.kv__row dd { margin: 0; overflow-wrap: anywhere; }
.kv__row dd.figure { font-size: 13px; }

.faq { border-top: 2px solid var(--ink); margin-top: 8px; }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  cursor: pointer;
  padding: 16px 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.015em;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 18px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--mono); color: var(--clay); flex: 0 0 auto; }
.faq details[open] summary::after { content: "\2212"; }
.faq details > p { padding-bottom: 18px; color: var(--slate); max-width: var(--reading); margin: 0; }

/* ----------------------------------------------------------------- cta ---- */

.cta { padding: var(--step) 0; background: var(--ink); color: var(--paper); }
.cta h2 { margin-bottom: 16px; }
.cta p { color: color-mix(in srgb, var(--paper) 74%, var(--ink)); max-width: 44ch; }
.cta .btn { border-color: var(--paper); color: var(--paper); }
.cta .btn:hover { background: var(--paper); color: var(--ink); }
.cta .btn--solid { background: var(--clay-ink); border-color: var(--clay-ink); }
.cta .btn--solid:hover { background: var(--sun); border-color: var(--sun); color: var(--ink); }
.cta__actions { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 28px; }

/* -------------------------------------------------------------- footer ---- */

.foot { padding: clamp(40px, 5vw, 68px) 0 34px; background: var(--paper-2); }

.foot__grid { display: grid; gap: 34px; }
@media (min-width: 860px) { .foot__grid { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); gap: 40px; } }

.foot__blurb { color: var(--slate); font-size: 15px; max-width: 34ch; margin: 16px 0 0; }
.foot__col h4 {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 14px;
}
.foot__col a { display: block; padding: 5px 0; font-size: 15px; color: var(--ink-2); text-decoration: none; }
.foot__col a:hover { color: var(--clay-ink); }

.foot__rule {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
  margin-top: 40px;
  padding-top: 18px;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--slate);
}

/* ------------------------------------------------------------ utilities --- */

.stack > * + * { margin-top: 18px; }
.mt-l { margin-top: clamp(28px, 3.4vw, 44px); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}


/* --- drawing: atrium (/) --- */
/* / — the atrium.
   Every class is prefixed d-atrium- so it cannot collide with another drawing.

   Entrance, about 1.2s: the roof glazing lights pane by pane from the left eave to
   the right, and the two shafts of daylight fall the full height of the void behind
   it. Loop: the motes drift down the shafts and fade out, and one doorway at a time
   takes a slow warm glow, four doorways to a twenty second round.

   Nothing here may move into the SVG as an inline style: the site is served under a
   CSP whose style-src is 'self' with no 'unsafe-inline'. */

.d-atrium-pane {
  animation: d-atrium-pane-light 0.6s ease-out both;
}

.d-atrium-pane-0 { animation-delay: 0.06s; }
.d-atrium-pane-1 { animation-delay: 0.11s; }
.d-atrium-pane-2 { animation-delay: 0.16s; }
.d-atrium-pane-3 { animation-delay: 0.21s; }
.d-atrium-pane-4 { animation-delay: 0.26s; }
.d-atrium-pane-5 { animation-delay: 0.31s; }
.d-atrium-pane-6 { animation-delay: 0.36s; }
.d-atrium-pane-7 { animation-delay: 0.41s; }
.d-atrium-pane-8 { animation-delay: 0.46s; }
.d-atrium-pane-9 { animation-delay: 0.51s; }
.d-atrium-pane-10 { animation-delay: 0.56s; }
.d-atrium-pane-11 { animation-delay: 0.61s; }

.d-atrium-shaft {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  animation: d-atrium-shaft-fall 0.86s cubic-bezier(0.22, 0.61, 0.36, 1) both,
             d-atrium-shaft-breathe 17s ease-in-out infinite;
}

.d-atrium-shaft-0 { animation-delay: 0.34s, 1.6s; }
.d-atrium-shaft-1 { animation-delay: 0.46s, 3.2s; }

.d-atrium-glow {
  animation: d-atrium-glow-warm 20s ease-in-out infinite;
}

.d-atrium-glow-0 { animation-delay: 1.4s; }
.d-atrium-glow-1 { animation-delay: 6.4s; }
.d-atrium-glow-2 { animation-delay: 11.4s; }
.d-atrium-glow-3 { animation-delay: 16.4s; }

.d-atrium-mote {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: d-atrium-mote-fall 16s linear infinite;
}

.d-atrium-mote-0 { animation-duration: 16s; animation-delay: -2.4s; }
.d-atrium-mote-1 { animation-duration: 19s; animation-delay: -9.1s; }
.d-atrium-mote-2 { animation-duration: 14.5s; animation-delay: -5.6s; }
.d-atrium-mote-3 { animation-duration: 21s; animation-delay: -13.2s; }
.d-atrium-mote-4 { animation-duration: 17.5s; animation-delay: -0.9s; }
.d-atrium-mote-5 { animation-duration: 15s; animation-delay: -7.3s; }
.d-atrium-mote-6 { animation-duration: 20s; animation-delay: -16.4s; }
.d-atrium-mote-7 { animation-duration: 18s; animation-delay: -11.8s; }
.d-atrium-mote-8 { animation-duration: 16.5s; animation-delay: -4.2s; }
.d-atrium-mote-9 { animation-duration: 19.5s; animation-delay: -14.9s; }

/* ---------------------------------------------------------------- entrance */

/* A pane catches the light, then settles back to the tint it rests at. */
@keyframes d-atrium-pane-light {
  0%   { opacity: 0; }
  55%  { opacity: 0.76; }
  100% { opacity: 0.3; }
}

/* The shaft is a sliver under the ridge, then it reaches the floor. */
@keyframes d-atrium-shaft-fall {
  0%   { opacity: 0.06; transform: scaleY(0.04); }
  100% { opacity: 0.18; transform: scaleY(1); }
}

/* -------------------------------------------------------------------- loop */

@keyframes d-atrium-shaft-breathe {
  0%, 100% { opacity: 0.18; }
  50%      { opacity: 0.1; }
}

/* A doorway warms for about four seconds in every twenty, and the four starts are
   five seconds apart, so only one room is ever lit. */
@keyframes d-atrium-glow-warm {
  0%, 100% { opacity: 0.1; }
  7%, 18%  { opacity: 0.52; }
  27%      { opacity: 0.1; }
}

@keyframes d-atrium-mote-fall {
  0%   { opacity: 0; transform: translateY(-24px); }
  18%  { opacity: 0.62; }
  72%  { opacity: 0.44; }
  100% { opacity: 0; transform: translateY(96px); }
}

/* ---------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  .d-atrium-pane { animation: none !important; }
  .d-atrium-pane-0 { animation: none !important; }
  .d-atrium-pane-1 { animation: none !important; }
  .d-atrium-pane-2 { animation: none !important; }
  .d-atrium-pane-3 { animation: none !important; }
  .d-atrium-pane-4 { animation: none !important; }
  .d-atrium-pane-5 { animation: none !important; }
  .d-atrium-pane-6 { animation: none !important; }
  .d-atrium-pane-7 { animation: none !important; }
  .d-atrium-pane-8 { animation: none !important; }
  .d-atrium-pane-9 { animation: none !important; }
  .d-atrium-pane-10 { animation: none !important; }
  .d-atrium-pane-11 { animation: none !important; }
  .d-atrium-shaft { animation: none !important; }
  .d-atrium-shaft-0 { animation: none !important; }
  .d-atrium-shaft-1 { animation: none !important; }
  .d-atrium-glow { animation: none !important; }
  .d-atrium-glow-0 { animation: none !important; }
  .d-atrium-glow-1 { animation: none !important; }
  .d-atrium-glow-2 { animation: none !important; }
  .d-atrium-glow-3 { animation: none !important; }
  .d-atrium-mote { animation: none !important; }
  .d-atrium-mote-0 { animation: none !important; }
  .d-atrium-mote-1 { animation: none !important; }
  .d-atrium-mote-2 { animation: none !important; }
  .d-atrium-mote-3 { animation: none !important; }
  .d-atrium-mote-4 { animation: none !important; }
  .d-atrium-mote-5 { animation: none !important; }
  .d-atrium-mote-6 { animation: none !important; }
  .d-atrium-mote-7 { animation: none !important; }
  .d-atrium-mote-8 { animation: none !important; }
  .d-atrium-mote-9 { animation: none !important; }
}

/* --- drawing: rooms (/rooms) --- */
/* ===========================================================================
   Atrium — opening drawing for /rooms: THE FLOOR PLAN.

   The SVG carries no style attribute and no <style> element, because the page
   is served with style-src 'self' and no 'unsafe-inline'. Every moving part is
   driven from here. The still frame — this file with all animation removed —
   is already the finished picture: walls solid, doors drawn open the way an
   architect draws them, rooms carrying their resting floor tint.
   =========================================================================== */

/* --------------------------------------------------- entrance: the walls ---
   Each wall path declares pathLength="1000", so one dash of 1000 covers the
   whole run whatever its true length, and the offset draws it in.            */

.d-rooms-wall,
.d-rooms-wall-v,
.d-rooms-wall-h {
  stroke-dasharray: 1000;
  stroke-dashoffset: 0;
}

.d-rooms-wall {
  animation: d-rooms-draw 620ms cubic-bezier(0.33, 0, 0.15, 1) 0ms both;
}

.d-rooms-wall-v {
  animation: d-rooms-draw 540ms cubic-bezier(0.33, 0, 0.15, 1) 260ms both;
}

.d-rooms-wall-h {
  animation: d-rooms-draw 540ms cubic-bezier(0.33, 0, 0.15, 1) 380ms both;
}

/* ------------------------------------------- entrance: the swing markings --
   The quarter circle each door sweeps. They arrive after the walls that hold
   them, one just behind the next.                                           */

.d-rooms-arcs > path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 0;
  animation: d-rooms-draw 420ms ease-out both;
}

.d-rooms-arcs > path:nth-child(1) { animation-delay: 500ms; }
.d-rooms-arcs > path:nth-child(2) { animation-delay: 532ms; }
.d-rooms-arcs > path:nth-child(3) { animation-delay: 564ms; }
.d-rooms-arcs > path:nth-child(4) { animation-delay: 596ms; }
.d-rooms-arcs > path:nth-child(5) { animation-delay: 628ms; }
.d-rooms-arcs > path:nth-child(6) { animation-delay: 660ms; }
.d-rooms-arcs > path:nth-child(7) { animation-delay: 692ms; }
.d-rooms-arcs > path:nth-child(8) { animation-delay: 724ms; }
.d-rooms-arcs > path:nth-child(9) { animation-delay: 756ms; }

/* ------------------------------------------------ the doors: entrance+loop -
   Each leaf is drawn in the SVG already open, perpendicular to its wall, so
   the motionless picture is the correct architectural one. A leaf carries the
   thickness of the wall it closes into — 4 for the outer wall, 3 for the
   interior ones — so shutting it completes the wall instead of swelling it.
   The entrance runs it back to rotate(-90deg) — flat in the wall opening —
   and swings it out.
   The loop then closes and reopens it once per period, and the periods are
   deliberately unequal (16s to 22s) so the nine doors drift apart instead of
   breathing in unison.                                                       */

.d-rooms-leaves > rect {
  transform-box: fill-box;
  animation:
    d-rooms-swing 460ms cubic-bezier(0.2, 0.7, 0.3, 1) 560ms both,
    d-rooms-door  19s   cubic-bezier(0.45, 0, 0.55, 1) 2.2s infinite;
}

.d-rooms-leaves > rect:nth-child(1) {
  transform-origin: 50% 100%;
  animation-delay: 560ms, 2.2s;
  animation-duration: 460ms, 19s;
}
.d-rooms-leaves > rect:nth-child(2) {
  transform-origin: 100% 50%;
  animation-delay: 602ms, 4.6s;
  animation-duration: 460ms, 17s;
}
.d-rooms-leaves > rect:nth-child(3) {
  transform-origin: 50% 0%;
  animation-delay: 644ms, 6.3s;
  animation-duration: 460ms, 21s;
}
.d-rooms-leaves > rect:nth-child(4) {
  transform-origin: 50% 100%;
  animation-delay: 686ms, 3.4s;
  animation-duration: 460ms, 16s;
}
.d-rooms-leaves > rect:nth-child(5) {
  transform-origin: 0% 50%;
  animation-delay: 728ms, 8s;
  animation-duration: 460ms, 22s;
}
.d-rooms-leaves > rect:nth-child(6) {
  transform-origin: 0% 50%;
  animation-delay: 770ms, 5.5s;
  animation-duration: 460ms, 18s;
}
.d-rooms-leaves > rect:nth-child(7) {
  transform-origin: 0% 50%;
  animation-delay: 812ms, 2.9s;
  animation-duration: 460ms, 20s;
}
.d-rooms-leaves > rect:nth-child(8) {
  transform-origin: 50% 0%;
  animation-delay: 854ms, 8.8s;
  animation-duration: 460ms, 17.5s;
}
.d-rooms-leaves > rect:nth-child(9) {
  transform-origin: 100% 50%;
  animation-delay: 896ms, 7.1s;
  animation-duration: 460ms, 19.5s;
}

/* ---------------------------------------------------- the loop: the tints --
   Every room keeps a faint resting wash — that is the 0% frame too, so nothing
   pops when a long delay finally starts. The eight delays are 2.5s apart over a
   20s round, so the lit window has to stay under 2.5s or two rooms are always up
   together and an adjacent pair reads as one block: 3%-14% of 20s is 2.2s, and
   the delays hop around the plan rather than sweeping it left to right.        */

.d-rooms-tints > rect {
  animation: d-rooms-tint 20s ease-in-out 0s infinite both;
}

.d-rooms-tints > rect:nth-child(1) { animation-delay: 0s; }
.d-rooms-tints > rect:nth-child(2) { animation-delay: 12.5s; }
.d-rooms-tints > rect:nth-child(3) { animation-delay: 5s; }
.d-rooms-tints > rect:nth-child(4) { animation-name: d-rooms-tint-sun; animation-delay: 17.5s; }
.d-rooms-tints > rect:nth-child(5) { animation-delay: 2.5s; }
.d-rooms-tints > rect:nth-child(6) { animation-delay: 15s; }
.d-rooms-tints > rect:nth-child(7) { animation-delay: 7.5s; }
.d-rooms-tints > rect:nth-child(8) { animation-delay: 10s; }

/* ----------------------------------------------- entrance: the small print */

.d-rooms-keys > g {
  animation: d-rooms-fade 400ms ease-out both;
}

.d-rooms-keys > g:nth-child(1) { animation-delay: 700ms; }
.d-rooms-keys > g:nth-child(2) { animation-delay: 738ms; }
.d-rooms-keys > g:nth-child(3) { animation-delay: 776ms; }
.d-rooms-keys > g:nth-child(4) { animation-delay: 814ms; }
.d-rooms-keys > g:nth-child(5) { animation-delay: 852ms; }
.d-rooms-keys > g:nth-child(6) { animation-delay: 890ms; }
.d-rooms-keys > g:nth-child(7) { animation-delay: 928ms; }
.d-rooms-keys > g:nth-child(8) { animation-delay: 966ms; }

.d-rooms-dim {
  animation: d-rooms-fade 600ms ease-out 300ms both;
}

.d-rooms-step {
  animation: d-rooms-fade 420ms ease-out 900ms both;
}

/* ------------------------------------------------------------ keyframes --- */

@keyframes d-rooms-draw {
  from { stroke-dashoffset: 1000; }
  to   { stroke-dashoffset: 0; }
}

@keyframes d-rooms-swing {
  0%   { opacity: 0; transform: rotate(-90deg); }
  30%  { opacity: 1; }
  100% { opacity: 1; transform: rotate(0deg); }
}

@keyframes d-rooms-door {
  0%,  30%  { transform: rotate(0deg); }
  40%, 52%  { transform: rotate(-90deg); }
  62%, 100% { transform: rotate(0deg); }
}

@keyframes d-rooms-tint {
  0%,  3%   { opacity: 0.08; }
  6%,  11%  { opacity: 0.27; }
  14%, 100% { opacity: 0.08; }
}

@keyframes d-rooms-tint-sun {
  0%,  3%   { opacity: 0.12; }
  6%,  11%  { opacity: 0.40; }
  14%, 100% { opacity: 0.12; }
}

@keyframes d-rooms-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ------------------------------------------------------- reduced motion ---
   Written out one selector at a time. With every animation removed the
   picture is already complete: nothing here is the only thing making an
   element visible.                                                           */

@media (prefers-reduced-motion: reduce) {
  .d-rooms-wall            { animation: none !important; }
  .d-rooms-wall-v          { animation: none !important; }
  .d-rooms-wall-h          { animation: none !important; }
  .d-rooms-arcs > path     { animation: none !important; }
  .d-rooms-leaves > rect   { animation: none !important; }
  .d-rooms-tints > rect    { animation: none !important; }
  .d-rooms-keys > g        { animation: none !important; }
  .d-rooms-dim             { animation: none !important; }
  .d-rooms-step            { animation: none !important; }
}

/* --- drawing: how (/how-it-works) --- */
/* --- how-it-works: the four-step line -------------------------------------
   One master clock. The token walks the rule in 18s and every station performs
   its own move in the window the token is standing in front of it, so the
   picture is read left to right rather than all at once.

     token at station 1   14% - 19%     beam is set, plumb rings out
     token at station 2   33% - 38%     ticker plate is lifted and slotted in
     token at station 3   52% - 57%     ram strikes the bed
     token at station 4   71% - 76%     the pool fills

   Amplitudes are in viewBox units and the drawing is 1200 wide, so a 390px
   phone renders them at 0.325x. Anything under ~30 units here is under 10 CSS
   pixels there, which is not motion a reader can see. Every station move is
   sized against that, not against how it looks at 1200. */

.d-how-rule {
  stroke-dasharray: 1000;
  stroke-dashoffset: 0;
  animation: d-how-draw 0.95s cubic-bezier(0.22, 0.72, 0.2, 1) both;
}

.d-how-s1,
.d-how-s2,
.d-how-s3,
.d-how-s4 {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation-name: d-how-pop;
  animation-duration: 0.48s;
  animation-timing-function: cubic-bezier(0.2, 0.75, 0.25, 1);
  animation-fill-mode: both;
}

.d-how-s1 { animation-delay: 0.15s; }
.d-how-s2 { animation-delay: 0.34s; }
.d-how-s3 { animation-delay: 0.53s; }
.d-how-s4 { animation-delay: 0.72s; }

.d-how-token {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: d-how-travel 18s linear 1.05s infinite backwards;
}

.d-how-beam {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: d-how-set 18s ease-in-out 1.05s infinite;
}

.d-how-plumb {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  animation: d-how-swing 18s ease-in-out 1.05s infinite;
}

.d-how-plate {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: d-how-slot 18s ease-in-out 1.05s infinite;
}

.d-how-ram {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: d-how-press 18s ease-in-out 1.05s infinite;
}

.d-how-water {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: d-how-fill 18s ease-in-out 1.05s infinite;
}

@keyframes d-how-draw {
  from { stroke-dashoffset: 1000; }
  to   { stroke-dashoffset: 0; }
}

@keyframes d-how-pop {
  from { opacity: 0; transform: translateY(16px) scale(0.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes d-how-travel {
  0%   { transform: translateX(0px);   opacity: 0; }
  4%   { transform: translateX(26px);  opacity: 1; }
  14%  { transform: translateX(175px); }
  19%  { transform: translateX(175px); }
  33%  { transform: translateX(385px); }
  38%  { transform: translateX(385px); }
  52%  { transform: translateX(595px); }
  57%  { transform: translateX(595px); }
  71%  { transform: translateX(805px); }
  76%  { transform: translateX(805px); }
  94%  { transform: translateX(980px); opacity: 1; }
  100% { transform: translateX(980px); opacity: 0; }
}

/* Station 1. The head beam is lifted off the posts and set back down on them as
   the token arrives: 46 units of travel, which is the largest move in the
   drawing because it is the one that says "framed up". */
@keyframes d-how-set {
  0%   { transform: translateY(0px); }
  8%   { transform: translateY(0px); }
  11%  { transform: translateY(-46px); }
  16%  { transform: translateY(2px); }
  19%  { transform: translateY(0px); }
  100% { transform: translateY(0px); }
}

/* The plumb line rings out under the beam landing and settles true. It rests at
   0deg, which is exactly where the SVG's own attributes put it, so the loop's
   resting frame and the reduced-motion still frame are the same picture. */
@keyframes d-how-swing {
  0%   { transform: rotate(0deg); }
  15%  { transform: rotate(0deg); }
  17%  { transform: rotate(-8deg); }
  20%  { transform: rotate(5.5deg); }
  23%  { transform: rotate(-3deg); }
  26%  { transform: rotate(1.4deg); }
  30%  { transform: rotate(0deg); }
  100% { transform: rotate(0deg); }
}

/* Station 2. Lifted clear of the roof, then seated into it with a little
   bed-in. 39 units end to end. */
@keyframes d-how-slot {
  0%   { transform: translateY(0px); }
  27%  { transform: translateY(0px); }
  30%  { transform: translateY(-34px); }
  36%  { transform: translateY(5px); }
  40%  { transform: translateY(0px); }
  100% { transform: translateY(0px); }
}

/* Station 3. Raised, then driven down 18 units so the ram's face lands on the
   top edge of the bed at y=241 instead of stopping short of it in mid air. */
@keyframes d-how-press {
  0%   { transform: translateY(0px); }
  46%  { transform: translateY(0px); }
  50%  { transform: translateY(-20px); }
  55%  { transform: translateY(18px); }
  59%  { transform: translateY(-6px); }
  64%  { transform: translateY(0px); }
  100% { transform: translateY(0px); }
}

/* Station 4. The pool roughly doubles in depth. The rise is centred on 73%, the
   middle of the token's dwell, because ease-in-out puts its steepest travel at
   the midpoint of a segment and that is the part a reader actually catches. 29
   units up from the resting line still leaves the crest clear of the basin clip
   at y=305. */
@keyframes d-how-fill {
  0%   { transform: translateY(0px); }
  68%  { transform: translateY(0px); }
  78%  { transform: translateY(-29px); }
  88%  { transform: translateY(-23px); }
  100% { transform: translateY(0px); }
}

@media (prefers-reduced-motion: reduce) {
  .d-how-rule   { animation: none !important; }
  .d-how-s1     { animation: none !important; }
  .d-how-s2     { animation: none !important; }
  .d-how-s3     { animation: none !important; }
  .d-how-s4     { animation: none !important; }
  .d-how-token  { animation: none !important; }
  .d-how-beam   { animation: none !important; }
  .d-how-plumb  { animation: none !important; }
  .d-how-plate  { animation: none !important; }
  .d-how-ram    { animation: none !important; }
  .d-how-water  { animation: none !important; }
}

/* --- drawing: rewards (/rewards) --- */
/* /rewards — the split-flap board.
   Every class is prefixed d-rewards- so it cannot collide with another drawing. */

.d-rewards-tile {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: d-rewards-drop 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.d-rewards-in-0 { animation-delay: 0.04s; }
.d-rewards-in-1 { animation-delay: 0.06s; }
.d-rewards-in-2 { animation-delay: 0.08s; }
.d-rewards-in-3 { animation-delay: 0.09s; }
.d-rewards-in-4 { animation-delay: 0.11s; }
.d-rewards-in-5 { animation-delay: 0.13s; }
.d-rewards-in-6 { animation-delay: 0.15s; }
.d-rewards-in-7 { animation-delay: 0.17s; }
.d-rewards-in-8 { animation-delay: 0.19s; }
.d-rewards-in-9 { animation-delay: 0.21s; }
.d-rewards-in-10 { animation-delay: 0.22s; }
.d-rewards-in-11 { animation-delay: 0.24s; }
.d-rewards-in-12 { animation-delay: 0.26s; }
.d-rewards-in-13 { animation-delay: 0.28s; }
.d-rewards-in-14 { animation-delay: 0.3s; }
.d-rewards-in-15 { animation-delay: 0.32s; }
.d-rewards-in-16 { animation-delay: 0.34s; }
.d-rewards-in-17 { animation-delay: 0.35s; }
.d-rewards-in-18 { animation-delay: 0.37s; }
.d-rewards-in-19 { animation-delay: 0.39s; }
.d-rewards-in-20 { animation-delay: 0.41s; }
.d-rewards-in-21 { animation-delay: 0.43s; }
.d-rewards-in-22 { animation-delay: 0.45s; }
.d-rewards-in-23 { animation-delay: 0.47s; }
.d-rewards-in-24 { animation-delay: 0.48s; }
.d-rewards-in-25 { animation-delay: 0.5s; }
.d-rewards-in-26 { animation-delay: 0.52s; }
.d-rewards-in-27 { animation-delay: 0.54s; }

/* Eight of the twenty-eight flaps turn over on their own. The cycle lengths are all different
   and none divides another, so the board never falls into step and the sequence never repeats
   inside a visit. The first two delays are negative: at load those animations are already part
   way through a cycle, which puts the first flap over at 1.6s, a third of a second after the
   entrance settles. Measured before this: the drawing did not change by one pixel between 1.3s
   and 7.5s, so the one gesture that says "split-flap" was invisible for the first six seconds. */

.d-rewards-flip-a,
.d-rewards-flip-b,
.d-rewards-flip-c,
.d-rewards-flip-d,
.d-rewards-flip-e,
.d-rewards-flip-f,
.d-rewards-flip-g,
.d-rewards-flip-h {
  transform-box: fill-box;
  transform-origin: 50% 50%;
}

.d-rewards-flip-a { animation: d-rewards-clatter 11s    ease-in-out -1.26s infinite; }
.d-rewards-flip-b { animation: d-rewards-clatter 12.5s  ease-in-out -0.3s  infinite; }
.d-rewards-flip-c { animation: d-rewards-clatter 13.5s  ease-in-out 0.79s  infinite; }
.d-rewards-flip-d { animation: d-rewards-clatter 10.5s  ease-in-out 2.92s  infinite; }
.d-rewards-flip-e { animation: d-rewards-clatter 14.5s  ease-in-out 3.23s  infinite; }
.d-rewards-flip-f { animation: d-rewards-clatter 12s    ease-in-out 5.23s  infinite; }
.d-rewards-flip-g { animation: d-rewards-clatter 15.5s  ease-in-out 5.67s  infinite; }
.d-rewards-flip-h { animation: d-rewards-clatter 11.5s  ease-in-out 8.06s  infinite; }

.d-rewards-glow {
  animation: d-rewards-breathe 9s ease-in-out infinite;
}

.d-rewards-lamp {
  animation: d-rewards-lamp 1.24s ease-out both;
}

.d-rewards-pick {
  animation: d-rewards-fade 0.26s ease-out 0.78s both;
}

.d-rewards-lead {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  animation: d-rewards-lead 0.28s ease-out 0.82s both;
}

.d-rewards-dot {
  animation: d-rewards-fade 0.22s ease-out 1.02s both;
}

/* ---------------------------------------------------------------- entrance */

@keyframes d-rewards-drop {
  0%   { transform: scaleY(0.04); }
  68%  { transform: scaleY(1.04); }
  86%  { transform: scaleY(0.98); }
  100% { transform: scaleY(1); }
}

@keyframes d-rewards-lamp {
  0%, 62% { opacity: 0; }
  100%    { opacity: 1; }
}

@keyframes d-rewards-lead {
  0%   { transform: scaleY(0); }
  100% { transform: scaleY(1); }
}

@keyframes d-rewards-fade {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

/* -------------------------------------------------------------------- loop */

/* One flap turns over: the tile collapses on its own centre line and opens again.
   The turn takes about 0.8s out of a 16-22s cycle, so the board clatters rarely. */
@keyframes d-rewards-clatter {
  0%, 26%  { transform: scaleY(1); }
  28.5%    { transform: scaleY(0.06); }
  31%, 100%{ transform: scaleY(1); }
}

@keyframes d-rewards-breathe {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 0.40; }
}

/* ---------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  .d-rewards-tile { animation: none !important; }
  .d-rewards-in-0 { animation: none !important; }
  .d-rewards-in-1 { animation: none !important; }
  .d-rewards-in-2 { animation: none !important; }
  .d-rewards-in-3 { animation: none !important; }
  .d-rewards-in-4 { animation: none !important; }
  .d-rewards-in-5 { animation: none !important; }
  .d-rewards-in-6 { animation: none !important; }
  .d-rewards-in-7 { animation: none !important; }
  .d-rewards-in-8 { animation: none !important; }
  .d-rewards-in-9 { animation: none !important; }
  .d-rewards-in-10 { animation: none !important; }
  .d-rewards-in-11 { animation: none !important; }
  .d-rewards-in-12 { animation: none !important; }
  .d-rewards-in-13 { animation: none !important; }
  .d-rewards-in-14 { animation: none !important; }
  .d-rewards-in-15 { animation: none !important; }
  .d-rewards-in-16 { animation: none !important; }
  .d-rewards-in-17 { animation: none !important; }
  .d-rewards-in-18 { animation: none !important; }
  .d-rewards-in-19 { animation: none !important; }
  .d-rewards-in-20 { animation: none !important; }
  .d-rewards-in-21 { animation: none !important; }
  .d-rewards-in-22 { animation: none !important; }
  .d-rewards-in-23 { animation: none !important; }
  .d-rewards-in-24 { animation: none !important; }
  .d-rewards-in-25 { animation: none !important; }
  .d-rewards-in-26 { animation: none !important; }
  .d-rewards-in-27 { animation: none !important; }
  .d-rewards-flip-a { animation: none !important; }
  .d-rewards-flip-b { animation: none !important; }
  .d-rewards-flip-c { animation: none !important; }
  .d-rewards-flip-d { animation: none !important; }
  .d-rewards-flip-e { animation: none !important; }
  .d-rewards-flip-f { animation: none !important; }
  .d-rewards-flip-g { animation: none !important; }
  .d-rewards-flip-h { animation: none !important; }
  .d-rewards-glow { animation: none !important; }
  .d-rewards-lamp { animation: none !important; }
  .d-rewards-pick { animation: none !important; }
  .d-rewards-lead { animation: none !important; }
  .d-rewards-dot { animation: none !important; }
}

/* --- drawing: docs (/docs) --- */
/* ===========================================================================
   Atrium — opening drawing for /docs: THE OPEN MANUAL
   Entrance (~1.2s): the right-hand page turns over into place from the gutter,
   then the four leader lines draw out to their margin notes one by one.
   Loop: a slow highlight travels down the body rules on the left page (16s),
   and the margin notes fade gently in and out in sequence (18s).
   Every resting state is already correct with no animation applied.
   =========================================================================== */

/* --- entrance: the right page swings over onto the gutter ---------------- */

.d-docs-page {
  transform-box: fill-box;
  transform-origin: left center;
  animation: d-docs-turn 1.05s cubic-bezier(0.22, 0.72, 0.24, 1) both;
}

@keyframes d-docs-turn {
  from { transform: scaleX(0.05); opacity: 0.5; }
  55%  { opacity: 1; }
  to   { transform: scaleX(1); opacity: 1; }
}

/* --- entrance: leader lines draw out, one by one ------------------------- */

.d-docs-lead1,
.d-docs-lead2,
.d-docs-lead3,
.d-docs-lead4 {
  stroke-dasharray: 200;
  stroke-dashoffset: 0;
  animation: d-docs-draw 0.42s ease-out backwards;
}

.d-docs-lead1 { animation-delay: 0.66s; }
.d-docs-lead2 { animation-delay: 0.78s; }
.d-docs-lead3 { animation-delay: 0.90s; }
.d-docs-lead4 { animation-delay: 1.02s; }

@keyframes d-docs-draw {
  from { stroke-dashoffset: 200; }
  to   { stroke-dashoffset: 0; }
}

/* --- loop: the reading highlight travels down the column ------------------
   The band is one line tall and clipped to the column (y 186-470 in the
   drawing), so it is invisible above the first rule and below the last one and
   the wrap is never seen. No opacity animation, so nothing blinks.          */

.d-docs-hl {
  transform-box: fill-box;
  transform-origin: center;
  animation: d-docs-read 16s linear 1.25s infinite backwards;
}

@keyframes d-docs-read {
  from { transform: translateY(-34px); }
  to   { transform: translateY(286px); }
}

/* --- loop: the margin notes breathe in sequence -------------------------- */

.d-docs-note1,
.d-docs-note2,
.d-docs-note3,
.d-docs-note4 {
  animation: d-docs-breathe 18s ease-in-out infinite;
}

.d-docs-note1 { animation-delay: 1.6s; }
.d-docs-note2 { animation-delay: 6.1s; }
.d-docs-note3 { animation-delay: 10.6s; }
.d-docs-note4 { animation-delay: 15.1s; }

@keyframes d-docs-breathe {
  0%   { opacity: 1; }
  9%   { opacity: 0.26; }
  22%  { opacity: 1; }
  100% { opacity: 1; }
}

/* --- reduced motion: the still frame is already the finished picture ----- */

@media (prefers-reduced-motion: reduce) {
  .d-docs-page  { animation: none !important; }
  .d-docs-lead1 { animation: none !important; }
  .d-docs-lead2 { animation: none !important; }
  .d-docs-lead3 { animation: none !important; }
  .d-docs-lead4 { animation: none !important; }
  .d-docs-hl    { animation: none !important; }
  .d-docs-note1 { animation: none !important; }
  .d-docs-note2 { animation: none !important; }
  .d-docs-note3 { animation: none !important; }
  .d-docs-note4 { animation: none !important; }
}

/* --- drawing: stamp (/verify) --- */
/* /verify — the stamp.
   Entrance: the press comes down, prints its mark, and lifts. Loop: the press breathes against
   the page while the loupe travels down the column of addresses, one row at a time. */

.d-stamp-press {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: d-stamp-press-in 1.15s cubic-bezier(0.2, 0.8, 0.3, 1) backwards,
             d-stamp-breathe 9s ease-in-out 1.15s infinite;
}
@keyframes d-stamp-press-in {
  0%   { transform: translateY(-190px); }
  62%  { transform: translateY(14px); }
  100% { transform: translateY(0); }
}
@keyframes d-stamp-breathe {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(7px); }
}

/* The mark is on the page from the start, so the still frame is a stamped document rather
   than a press hovering over nothing. The entrance only darkens it as the press lands. */
.d-stamp-mark { animation: d-stamp-ink 1.15s ease-out backwards; }
@keyframes d-stamp-ink {
  0%, 52% { opacity: 0.12; }
  70%     { opacity: 1; }
  100%    { opacity: 1; }
}

/* The column of addresses arrives just before the press lands on it. */
.d-stamp-rows { animation: d-stamp-rows-in 0.8s ease-out backwards; }
@keyframes d-stamp-rows-in { from { opacity: 0; } to { opacity: 1; } }

.d-stamp-loupe {
  transform-box: fill-box;
  transform: translate(452px, 204px);
  animation: d-stamp-read 20s ease-in-out infinite;
}
@keyframes d-stamp-read {
  0%,  14% { transform: translate(452px, 204px); }
  22%, 34% { transform: translate(452px, 270px); }
  42%, 54% { transform: translate(452px, 336px); }
  62%, 74% { transform: translate(452px, 402px); }
  82%, 94% { transform: translate(452px, 468px); }
  100%     { transform: translate(452px, 204px); }
}

/* The row under the loupe reads a shade darker as it is checked. */
.d-stamp-row { animation: d-stamp-row-read 20s ease-in-out infinite; }
.d-stamp-row-1 { animation-delay: 0s; }
.d-stamp-row-2 { animation-delay: -16s; }
.d-stamp-row-3 { animation-delay: -12s; }
.d-stamp-row-4 { animation-delay: -8s; }
.d-stamp-row-5 { animation-delay: -4s; }
@keyframes d-stamp-row-read {
  0%, 10%   { opacity: 1; }
  16%, 20%  { opacity: 0.55; }
  26%, 100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .d-stamp-press,
  .d-stamp-mark,
  .d-stamp-rows,
  .d-stamp-loupe,
  .d-stamp-row { animation: none !important; }
  .d-stamp-mark { opacity: 1; }
  .d-stamp-row { opacity: 1; }
}

/* --- drawing: club (/app) --- */
/* Opening drawing — /app — "the clubhouse, inside" */

.d-club-lamp-1,
.d-club-lamp-2,
.d-club-lamp-3,
.d-club-lamp-4,
.d-club-lamp-5 {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  animation-name: d-club-sway;
  animation-timing-function: cubic-bezier(.45, 0, .55, 1);
  animation-iteration-count: infinite;
}
.d-club-lamp-1 { animation-duration: 15s; animation-delay: -2.5s; }
.d-club-lamp-2 { animation-duration: 18s; animation-delay: -9s; }
.d-club-lamp-3 { animation-duration: 13s; animation-delay: -5s; }
.d-club-lamp-4 { animation-duration: 20s; animation-delay: -14s; }
.d-club-lamp-5 { animation-duration: 16s; animation-delay: -7s; }

.d-club-glow-1,
.d-club-glow-2,
.d-club-glow-3,
.d-club-glow-4,
.d-club-glow-5 {
  animation-name: d-club-lightup;
  animation-duration: .45s;
  animation-timing-function: ease-out;
  animation-fill-mode: both;
}
.d-club-glow-1 { animation-delay: .10s; }
.d-club-glow-2 { animation-delay: .26s; }
.d-club-glow-3 { animation-delay: .42s; }
.d-club-glow-4 { animation-delay: .58s; }
.d-club-glow-5 { animation-delay: .74s; }

.d-club-seat-1,
.d-club-seat-2,
.d-club-seat-3,
.d-club-seat-4,
.d-club-seat-5,
.d-club-seat-6,
.d-club-seat-7,
.d-club-cups,
.d-club-fore-1,
.d-club-fore-2 {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation-name: d-club-rise;
  animation-duration: .75s;
  animation-timing-function: cubic-bezier(.22, .72, .2, 1);
  animation-fill-mode: both;
}
.d-club-seat-1 { animation-delay: .05s; }
.d-club-seat-2 { animation-delay: .12s; }
.d-club-seat-3 { animation-delay: .19s; }
.d-club-seat-4 { animation-delay: .26s; }
.d-club-seat-5 { animation-delay: .33s; }
.d-club-seat-6 { animation-delay: .40s; }
.d-club-seat-7 { animation-delay: .47s; }
.d-club-cups   { animation-delay: .30s; }
.d-club-fore-1 { animation-delay: .02s; }
.d-club-fore-2 { animation-delay: .10s; }

.d-club-lean-1,
.d-club-lean-2,
.d-club-lean-3,
.d-club-lean-4 {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation-timing-function: cubic-bezier(.45, 0, .55, 1);
  animation-iteration-count: infinite;
}
.d-club-lean-1 { animation-name: d-club-lean; animation-duration: 19s; animation-delay: 2s; }
.d-club-lean-2 { animation-name: d-club-lean-b; animation-duration: 22s; animation-delay: 9s; }
.d-club-lean-3 { animation-name: d-club-lean; animation-duration: 18s; animation-delay: 15s; }
.d-club-lean-4 { animation-name: d-club-lean-b; animation-duration: 21s; animation-delay: 5s; }

.d-club-chart {
  stroke-dasharray: 400;   /* the path measures 375.3, so one dash covers it whole */
  stroke-dashoffset: 0;
  animation: d-club-draw .9s cubic-bezier(.4, 0, .2, 1) .3s both;
}

.d-club-tip {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: d-club-fade .3s ease-out 1.05s both,
             d-club-pulse 5s ease-in-out 1.5s infinite;
}

@keyframes d-club-sway {
  0%, 100% { transform: rotate(-2.4deg); }
  50%      { transform: rotate(2.4deg); }
}

@keyframes d-club-lightup {
  from { opacity: 0; }
}

@keyframes d-club-rise {
  from { opacity: 0; transform: translateY(28px); }
}

@keyframes d-club-lean {
  0%, 66%, 100% { transform: translateY(0) rotate(0deg); }
  76%, 86%      { transform: translateY(7px) rotate(1.8deg); }
}

@keyframes d-club-lean-b {
  0%, 66%, 100% { transform: translateY(0) rotate(0deg); }
  76%, 86%      { transform: translateY(7px) rotate(-1.8deg); }
}

@keyframes d-club-draw {
  from { stroke-dashoffset: 400; }
}

@keyframes d-club-fade {
  from { opacity: 0; }
}

@keyframes d-club-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.16); }
}

@media (prefers-reduced-motion: reduce) {
  .d-club-lamp-1,
  .d-club-lamp-2,
  .d-club-lamp-3,
  .d-club-lamp-4,
  .d-club-lamp-5,
  .d-club-glow-1,
  .d-club-glow-2,
  .d-club-glow-3,
  .d-club-glow-4,
  .d-club-glow-5,
  .d-club-seat-1,
  .d-club-seat-2,
  .d-club-seat-3,
  .d-club-seat-4,
  .d-club-seat-5,
  .d-club-seat-6,
  .d-club-seat-7,
  .d-club-cups,
  .d-club-fore-1,
  .d-club-fore-2,
  .d-club-lean-1,
  .d-club-lean-2,
  .d-club-lean-3,
  .d-club-lean-4,
  .d-club-chart,
  .d-club-tip { animation: none !important; }
}