/* The nav, on every page of the lab (round 6, iteration 23, 2026-10-13;
   owner, of the bible's nav: "can we make it so it persist with the
   pages as well? at the end of the day its all one system"): the index,
   the column of the system's sections, pages and tools that nav.js
   builds where it stands; the Proof grid it turns on; the Export drawer
   it opens; the page's offset they all stand by. Moved out of ds.css as
   they were, in their order, so the bible draws as it did, and loaded
   before each page's own sheet (ds.css, side/side.css,
   playground/playground.css), which may place the page around it.
   Tokens or cells only: the lab's chrome, never exported. */

/* ---- the chrome's clock and curve, every page's ----------------------
   The tool's own (the still page zeroes the system's clock, and the
   chrome is frozen to the page before any edit, lib/chrome.js), so
   literals, said once here for every page (iteration 24's audit: 320 ms
   and the curve were written three times, on the bible alone, so a side
   page had no chrome clock): the index's mark and entrance, the Global
   dock's drawer, the Scheme's cross-fade and the task's recede
   (components/task.js) read them. Reduced motion lands each where it
   is used */
:root {
  --chrome-clock: 320ms;
  --chrome-ease: cubic-bezier(0.6, 0, 0, 1);
}

/* ---- the page's geometry, said once for every page ---------------------
   (iteration 24's audit: the bar's 48, the column's 288, the stage's
   1056 and their cap were written as cells in four sheets and as
   numbers in two scripts, so a change in one left the others standing
   wrong). The nav's bar below 1200 and its column from it; the stage at
   its widest and the composition's cap (the stage and the nav's
   column); the index's track in the row (none under 1200, the column
   from it); the stage's least beside the inspector, which the sash
   leaves it; the margin after the inspector's cards, 32 (lib/split.js
   writes the viewer's) and its least, 8. The sash's rule (nav.js
   window.DSSash) reads these as lengths before the first paint, so
   those of them that are cells are registered, as the cap is (the
   review of iteration 24: the rule wrote 32, 8, 480 and 408 again as
   numbers). side/side.css and playground/playground.css stand their
   pages by the same names */
@property --index-w {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
@property --page-cap {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
@property --stage-least {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
@property --rail-margin {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
:root {
  --nav-bar-h: calc(var(--ds-grid-cell) * 12);
  --nav-w: calc(var(--ds-grid-cell) * 72);
  --stage-max: calc(var(--ds-grid-cell) * 264);
  --page-cap: calc(var(--stage-max) + var(--nav-w));
  --index-w: 0px;
  --stage-least: calc(var(--ds-grid-cell) * 120);
  --rail-margin: calc(var(--ds-grid-cell) * 8);
  --rail-margin-least: var(--ds-space-8);
}
@media (min-width: 1200px) {
  :root {
    --index-w: var(--nav-w);
  }
}

/* ---- the page's offset: the bible's composition centred once the window
        is wider than its cap (the stage's 1056, the index's 288 and the
        inspector's track, --side-w, which lib/split.js writes from the
        stored margin and nav.js before the first paint), so the nav
        stands at one x on every page ---------------------------------- */
/* one scrollbar's room on every page, so a page that does not scroll (a
   short page) has the width the others have and the offset with it (the
   review of iteration 23: 80 on the bible, 96 on the Playground, at 1920
   under a classic bar). A page that gives the room back (the
   Playground's field, which never scrolls, runs to the window's edge:
   in the room nothing but the root's colour is drawn, so its grid
   stopped 15 short) takes the bar's width off its own width instead,
   for every length read from it (nav.js measures it: --gutter-w, 0
   where the room is kept or the bar takes none) */
html {
  scrollbar-gutter: stable;
  --gutter-w: 0px;
}
@property --side-w {
  syntax: "<length>";
  inherits: true;
  initial-value: 384px;
}
html {
  --side-w: calc(var(--ds-grid-cell) * 96);
  /* the page's offset once the window is wider than the page's cap (the
     stage's 1056, the index's 288 and the rail): half of what is left,
     on the cell, so the composition stands centred, 48 from either edge
     at the least (round 3, 2026-10-09: "refine layou itself"). A
     custom property's 100% is its user's: the sheet's padding reads the
     page's width, a fixed box's left the window's less its scrollbar,
     the page's rounded width either way. While the sash is dragged it
     stands still, written on <html> as it was (lib/split.js), and
     centres again once the hand lets go */
  /* on the 16 lattice (round 6, iteration 19; the visual audit: on
     the cell alone, a wide window's offset of 88 set the whole page 8
     off the proof grid) */
  --page-x: max(
    0px,
    round(
      down,
      calc(
        (
            round(down, 100% - var(--gutter-w), var(--ds-space-16)) -
              var(--page-cap) - var(--side-w)
          ) /
          2
      ),
      var(--ds-space-16)
    )
  );
  /* the inspector's track: its x, the page's offset and what the
     page's rounded width leaves the inspector's width, at most the cap
     (the stage and the nav's column), which the bible's rail, the
     Export drawer and the Playground's composer beside it stand by (the
     review of iteration 24: the one length was written in three
     sheets). Unregistered, as the offset is, so its 100% is its user's */
  --side-x: calc(
    var(--page-x) +
      min(
        calc(
          round(down, 100% - var(--gutter-w), var(--ds-space-16)) -
            var(--side-w)
        ),
        var(--page-cap)
      )
  );
  /* where the inspector's cards end (its track less the margin after
     them), the composition's right edge, which a side page's card ends
     on too (side/side.css; the refinement of iteration 24) */
  --cards-end: calc(var(--side-x) + var(--side-w) - var(--rail-margin));
}
/* the offset's way back to the centre after a sash's drag (lib/split.js
   animates it, on the chrome's clock) */
@property --page-glide {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

/* the chrome density: one density for every window of the lab's chrome
   (owner, 2026-10-08: "Give some more spacing, currently it feels like
   it's only cramped up"). A head of 48 (the module's line), a row of 32
   and 8 between rows (the system's own "between"), 16 in, cards 16
   apart. Read by the panes' cards, the Global card and its stubs, the
   swatch folders' summaries (figures/swatches.css) and the drawer's
   head; the drawer stands outside the page, so it declares them too.
   Tokens or cells only, never exported: a tool's interface */
.page,
.drawer {
  --chrome-row: calc(var(--ds-grid-cell) * 8);
  /* 12 between rows and 24 between cards since round 6, iteration 10
     (owner: "add a bit more spacing into our system UIs") */
  --chrome-gap: calc(var(--ds-grid-cell) * 3);
  --chrome-head: calc(var(--ds-grid-cell) * 12);
  --chrome-pad: var(--ds-space-16);
  --chrome-card-gap: calc(var(--ds-grid-cell) * 6);
  /* the line stepped toward the ink: a selection's edge and a swatch's
     inner hair (round 6, iteration 16: never the full ink, which read
     as a stray black line in light) */
  --line-strong: color-mix(
    in srgb,
    var(--ds-color-line),
    var(--ds-color-ink) 28%
  );
}
/* words for a reader alone (a page's h1 where the nav names the page,
   the live region): one rule for every page (iteration 24's audit: the
   bible and the Playground each said it their own way, and the side
   pages, which loaded neither, styled their live region inline) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* the nav's and the drawer's buttons bare, at no specificity, on every
   page (the bible's own reset reaches only its .page) */
:where(.toc, .drawer) :where(button) {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

/* ---- the index ------------------------------------------------------
   Below 1200 a sticky bar: the brand, the sections inline (the one in
   view ink, the reading rail along the bar's foot), the pages, Inspect,
   Export and the Proof grid. */
.toc {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  --toc-gap: var(--ds-space-16);
  gap: var(--toc-gap);
  box-sizing: border-box;
  height: var(--nav-bar-h);
  --toc-pad: calc(var(--ds-grid-cell) * 12);
  padding-inline: var(--toc-pad);
  background: var(--ds-color-canvas);
  box-shadow: inset 0 calc(var(--rule) * -1) 0 var(--ds-color-line);
}
/* a module and a half (144, three halves of 96), so the list beside it
   starts on the module's line */
.toc__brand {
  flex: none;
  width: calc(var(--ds-grid-cell) * 36);
  margin: 0;
  color: var(--ds-color-ink);
  font-weight: 500;
  white-space: nowrap;
}
.toc__list {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* the lab's other pages (round 6, iteration 6): the builder, the icons,
   the type ramp, a block of links after the sections; in the bar a run
   of them */
.toc__pages {
  display: flex;
  /* the links' own room (8 a side) makes their words 16 apart, as the
     sections' are (round 6, iteration 17's review: a gap more made 24) */
  gap: 0;
}
/* a section's link, and the link to the lab's other page (the
   playground), which reads the same */
.toc__link,
.toc__page {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  height: var(--nav-bar-h);
  padding-inline: var(--ds-space-8);
  color: var(--ds-color-dim);
  text-decoration: none;
  white-space: nowrap;
}
/* the section in view: its ink swaps at once (a state change is never a
   fade, 2026-09-07); only the mark moves */
.toc__link[aria-current="true"] {
  color: var(--ds-color-ink);
}
/* the rail and its mark (lib/toc.js; round 6, iteration 16's
   follow-up, 2026-10-12; owner: "This menu is still very glitchy,
   redesign it again"): a hairline track beside the section links in the
   column (at their left edge) and along the bar's foot below 1200, and
   on it one mark of ink as long as the current link's words (--v0 to
   --v1). It moves only when the current section changes: each end is a
   length of its own, registered, so each eases on its own, the leading
   end a third of the index's clock and the trailing end the whole
   (data-way: on is down the column and along the bar), so the mark
   stretches toward the new link and gathers itself there. The index
   keeps a clock of its own (the still page zeroes the system's);
   reduced motion zeroes every transition (the end of this sheet) */
@property --v0 {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
@property --v1 {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
.toc {
  /* the index's own clock and curve (round 6, 2026-10-11; owner: "add
     cool motion to this sidebar"): the still page zeroes the system's
     clock, so the index keeps one of its own for its mark and its
     entrance; reduced motion zeroes it at the end of this sheet */
  --toc-clock: var(--chrome-clock);
  --toc-ease: var(--chrome-ease);
  --toc-lead: calc(var(--toc-clock) / 3);
  transition:
    --v0 var(--toc-clock) var(--toc-ease),
    --v1 var(--toc-lead) var(--toc-ease);
}
.toc[data-way="back"] {
  transition:
    --v0 var(--toc-lead) var(--toc-ease),
    --v1 var(--toc-clock) var(--toc-ease);
}
/* the first place, and a place measured again (a resize), are set
   still: the mark lands, it does not travel */
.toc[data-rail-still] {
  transition: none;
}
/* the rail: a hairline of the ink at 6 %, two px, round at its ends;
   the bar's along its foot */
.toc__rail {
  position: absolute;
  top: var(--rail-y, 0px);
  left: var(--rail-x, 0px);
  width: 2px;
  height: var(--rail-len, 0px);
  border-radius: 1px;
  background: color-mix(in srgb, var(--ds-color-ink) 6%, transparent);
  pointer-events: none;
}
.toc[data-axis="x"] .toc__rail {
  top: calc(var(--rail-y, 0px) - 2px);
  width: var(--rail-len, 0px);
  height: 2px;
}
/* the mark, in ink, beside the current link's words */
.toc__view {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--v0);
  height: max(0px, calc(var(--v1) - var(--v0)));
  border-radius: inherit;
  background: var(--ds-color-ink);
  pointer-events: none;
}
.toc[data-axis="x"] .toc__view {
  top: 0;
  bottom: 0;
  left: var(--v0);
  width: max(0px, calc(var(--v1) - var(--v0)));
  height: auto;
}
/* no section current yet (before the index first asks): no mark */
.toc:not(:has(.toc__link[aria-current])) .toc__view {
  visibility: hidden;
}
/* a link's glyph (lib/icons.js): 16, dim, the ink with its words under
   the hand or current, at once with them (a state's colour is never a
   fade, above; iteration 24's audit: the glyph inked over 320 ms after
   its words); in the bar the words alone */
.toc__icon {
  display: none;
  flex: none;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
  color: var(--ds-color-dim);
}
.toc__icon svg {
  width: 100%;
  height: 100%;
}
.toc__link[aria-current="true"] .toc__icon {
  color: var(--ds-color-ink);
}
@media (hover: hover) {
  .toc__link:hover .toc__icon,
  .toc__page:hover .toc__icon {
    color: var(--ds-color-ink);
  }
}
.toc__word {
  min-width: 0;
}
@keyframes toc-in {
  from {
    opacity: 0;
    transform: translateX(calc(var(--ds-space-8) * -1));
  }
}
/* the links stand over the rail and its mark (the index's box is their
   containing block in both forms) */
.toc__list,
.toc__pages,
.toc__page,
.toc__tools,
.toc__brand {
  position: relative;
  z-index: 1;
}
/* the index's tools (Inspect, Export, the Proof grid) at its end: text
   buttons, pressed in ink; in the bar a run of them */
.toc__tools {
  display: flex;
  align-items: center;
  gap: 0;
  margin-left: auto;
}
/* a tool: the links' room either side, so every word of the bar stands
   16 from the next (they stood 8) */
.toc__tool {
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  height: var(--nav-bar-h);
  padding-inline: var(--ds-space-8);
  color: var(--ds-color-dim);
  white-space: nowrap;
}
/* a pressed tool: the system's chosen rung, the fill and the page's
   words (components/button.css: "chosen ... a pressed toggle"), the one
   look for on in the tool's chrome as on the canvas, so pressed never
   reads as the hand's ink alone (the refinement of iteration 24, the
   owner's "refine", open call 1 of the round: a pressed Inspect drew as
   a hovered one). At the merge of the refinement the nav, the side bars
   and the inspector drew on two ways: the line ground in ink at 500
   here and on the side bars, the fill in the inspector; the line ground
   stood 5 levels off the system's Hover rung, so chosen read as the hand
   on it (the shell's critique, C1), and the chrome takes the fill (the
   owner, 2026-09-12: "all active states have same visual states and
   same semantics"). The weight holds, so a press moves nothing */
.toc__tool[aria-pressed="true"] {
  background: var(--ds-color-active);
  color: var(--ds-color-page);
}
.toc__key {
  display: none;
  color: inherit;
  font: inherit;
}
/* the bar's Tools (nav.js): its word and the dropdown's chevron after
   it, as it opens a list as a dropdown does (the review of the
   refinement: a word alone read as a page's link), in ink while its
   popup is open, and on the pressed rung while a tool in it is on
   (lib/nav.js data-on; the review: with Inspect and the Proof grid on,
   the bar showed neither). Drawn under the column form only (below) */
.toc__more {
  display: none;
}
.toc__more[aria-expanded="true"] {
  color: var(--ds-color-ink);
}
.toc__more[data-on] {
  background: var(--ds-color-active);
  color: var(--ds-color-page);
}
.toc__chev {
  display: flex;
  flex: none;
}
.toc__chev svg {
  width: var(--ds-space-16);
  height: var(--ds-space-16);
}
/* the skip link (nav.js): out of sight until a key brings the focus to
   it, then over the nav's corner, its words on the brand's word edge
   (48 in), a row of 32 in the chrome's 14 on 20, the measure ring
   inside, on the canvas's ground, over the bar and the column */
.toc__skip {
  position: fixed;
  top: var(--ds-space-8);
  left: calc(var(--page-x) + var(--ds-grid-cell) * 8);
  z-index: 50;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  height: calc(var(--ds-grid-cell) * 8);
  padding-inline: var(--ds-space-16);
  background: var(--ds-color-canvas);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
  color: var(--ds-color-ink);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-decoration: none;
  white-space: nowrap;
  outline: none;
}
.toc__skip:not(:focus) {
  clip-path: inset(50%);
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
}
/* what it takes the focus to draws no ring for it (a box of the page,
   not a control) */
[data-skip-to]:focus {
  outline: none;
}
@media (hover: hover) {
  .toc__link:hover,
  .toc__page:hover,
  .toc__tool:not([aria-pressed="true"], [data-on]):hover {
    color: var(--ds-color-ink);
  }
  /* chosen under the hand: the fill tinted toward the text, the page's
     words kept (components/button.css, chosen hover) */
  :is(.toc__tool[aria-pressed="true"], .toc__more[data-on]):hover {
    background: color-mix(
      in srgb,
      var(--ds-color-active),
      var(--ds-color-text) var(--ds-state-hover)
    );
  }
}
/* a key's focus on the lab's chrome: the measure ring inside, a rule
   wide, as an inset shadow (an outline is a whole CSS px in Chromium,
   components/surface.css: at 125 % a full device pixel and a quarter),
   over the index's current line, which lies under it (so said a step
   more surely than the column's line; forced colours keep their
   outline, ds.css below). A ring only where the keys brought the focus
   (owner, 2026-10-08: "make sure we never use this hover stroke unless
   its very clearly designed this way!!"): every ring rule of both
   pages, this sheet's and the components', is gated on html[data-kbd]
   (lib/core.js: a navigation key, Enter or Space sets it, a pointerdown
   clears it), so a click draws none and a Tab or an arrow draws one;
   :focus-visible stays inside the gate as the engine's own test, and
   the flag alone carries a focus WebKit drops it for (an arrow in a
   radio row) */
.toc__link:focus-visible,
.toc__page:focus-visible,
.toc__tool:focus-visible {
  outline: none;
}
html[data-kbd] .toc :is(.toc__link, .toc__page, .toc__tool):focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}

/* from 1200: a bare column fixed to the window at the page's left
   (round 5, 2026-10-10, the brief's §1: "The nav on the left keeps
   today's sections"; from round 2 to round 4 it stood between the
   sections and the rail, "[content][MENU][debug/controls]"). Its x is
   the page's offset once the page is centred (--page-x), its words 48
   in, on the title's gutter; the sheet gives it its 288 (--index-w,
   ds.css .sheet). One rhythm on the lattice:
   the brand a head of 48, its line on the sections' titles and on the
   card's head (all three centred on 72 at the page's top); then rows of
   40: the sections, the rail's mark beside the current one; the pages
   and the tools follow the list, each block 32 under the last, parted
   by a hairline, its first row 8 under the line. Its words take the
   track's first 208, its gutter on the rail's side */
@media (min-width: 1200px) {
  .toc {
    position: fixed;
    top: 0;
    bottom: 0;
    left: var(--page-x);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    /* 288 (round 6, iterations 10 and 13; owner: "make table of contents menu
       more spacious and add more width"): the words 48 in, rows of 216,
       24 to the track's end (1344 with the stage, on the 48) */
    width: var(--nav-w);
    height: auto;
    /* the rows 208, ending 32 before the track's end (round 6, iteration
       18: on the 16 lattice, where 24 set every row's end and every
       hairline 8 off it) */
    padding: calc(var(--ds-grid-cell) * 12) calc(var(--ds-grid-cell) * 8)
      calc(var(--ds-grid-cell) * 6) calc(var(--ds-grid-cell) * 12);
    background: none;
    box-shadow: none;
    /* the current link's step and the mark never make a bar */
    overflow-x: hidden;
    overflow-y: auto;
    /* its box is the track, a fixed layer over the sheet: the hand
       passes through its ground and its gutter to what stands there
       (the sash's band at the rail's edge); its words and its tools
       take the hand as before */
    pointer-events: none;
  }
  .toc > * {
    pointer-events: auto;
  }
  .toc__brand {
    display: flex;
    align-items: center;
    width: auto;
    height: calc(var(--ds-grid-cell) * 12);
  }
  /* 16 under the brand (iteration 18: the list on the lattice) */
  .toc__list {
    flex-direction: column;
    margin-top: var(--ds-space-16);
  }
  /* a link: a row of 40 (its words on a 24 line, 8 above and below;
     round 6, iteration 10: "more spacious"), 8 in from the rail, its
     glyph before its words; the rail's mark beside the current one
     (lib/toc.js), the hand inking a link's words alone */
  .toc__link {
    height: auto;
    /* a row of 40 (iteration 13; owner: "vertical can be slightly less"
       than the 48 of iteration 12): the words on 24, 8 above and below */
    padding: var(--ds-space-8);
  }
  .toc__icon {
    display: flex;
  }
  /* the list's entrance, once a visit (nav.js data-in, on the visit's
     first page that shows the column, gone once it has played): each
     link fades in from 8 to its left, a beat after the last */
  .toc[data-in] .toc__list > li {
    animation: toc-in var(--toc-clock) var(--toc-ease) both;
  }
  .toc[data-in] .toc__list > li:nth-child(2) {
    animation-delay: calc(var(--toc-clock) / 8);
  }
  .toc[data-in] .toc__list > li:nth-child(3) {
    animation-delay: calc(var(--toc-clock) / 4);
  }
  .toc[data-in] .toc__list > li:nth-child(4) {
    animation-delay: calc(var(--toc-clock) * 3 / 8);
  }
  .toc[data-in] .toc__list > li:nth-child(n + 5) {
    animation-delay: calc(var(--toc-clock) / 2);
  }
  /* the other page and the tools: blocks of their own under the list,
     each 16 under the last, a hairline on its top edge, its first row 8
     under the line; at the index's edge as a group's name (no spine, so
     no indent) */
  .toc__pages,
  .toc__tools {
    /* 32 apart (iteration 18: on the lattice; 24 set them 8 off it) */
    margin-top: calc(var(--ds-grid-cell) * 8);
    box-shadow: inset 0 var(--rule) 0 var(--ds-color-line);
  }
  /* the pages and the tools, columns of rows of 40 under their
     hairline, the first 8 under it; the blocks 24 apart */
  .toc__pages,
  .toc__tools {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-left: 0;
    padding-top: var(--ds-space-8);
  }
  .toc__page,
  .toc__tool {
    height: auto;
    margin-left: 0;
    padding: var(--ds-space-8);
  }
  /* a tool's words on the links' word column (their glyph and its gap
     before them), the tools having no glyph (round 6, iteration 17's
     review) */
  .toc__tool {
    padding-left: calc(var(--ds-space-8) * 2 + var(--ds-space-16));
  }
  /* a key at its row's end (the column's edge), so it stands on the
     lattice: after the words it stood where they ended, its hair
     between two device pixels at 125 % */
  .toc__key {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--ds-space-16);
    height: var(--ds-space-16);
    margin-left: auto;
    padding: 0 var(--ds-space-4);
    box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-14);
    line-height: var(--ds-space-16);
  }
}

/* away from the bible (round 6, iteration 23): the brand is the way back
   to it, a link in the brand's words; the page you are on is current as
   a section is on the bible, in ink, the rail's mark beside it
   (lib/toc.js) */
a.toc__brand {
  text-decoration: none;
}
.toc__page[aria-current="page"],
.toc__page[aria-current="page"] .toc__icon {
  color: var(--ds-color-ink);
}
/* the rail is the bible's sections' (lib/toc.js); away from it the page
   you are on carries the mark itself, from the first paint: a 2 px line
   of ink as long as its words, at its left edge in the column and at its
   foot in the bar, as the bible's mark stands */
.toc:not([data-here="bible"]) .toc__rail {
  display: none;
}
.toc__page[aria-current="page"]::before {
  content: "";
  position: absolute;
  right: var(--ds-space-8);
  bottom: 0;
  left: var(--ds-space-8);
  height: 2px;
  border-radius: 1px;
  background: var(--ds-color-ink);
}
@media (min-width: 1200px) {
  .toc__page[aria-current="page"]::before {
    top: var(--ds-space-8);
    right: auto;
    bottom: var(--ds-space-8);
    left: 0;
    width: 2px;
    height: auto;
  }
}
/* a tool this page cannot use (Inspect off the bible): greyed as the
   inspector's off rows are (ds.css .tp-v-disabled, 0.65), its key not
   drawn, its words dim under the hand too; a press opens the popup
   that says where it works (lib/nav.js; the owner's "refine": it drew as a
   working tool and its refusal went to a live region alone) */
.toc__tool[aria-disabled="true"] {
  opacity: 0.65;
  cursor: default;
}
.toc__tool[aria-disabled="true"] .toc__key {
  visibility: hidden;
}
@media (hover: hover) {
  .toc__tool[aria-disabled="true"]:hover {
    color: var(--ds-color-dim);
  }
}
.toc__brand:focus-visible {
  outline: none;
}
html[data-kbd] .toc .toc__brand:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}

/* the Export drawer's body: one line of words, then the block in the
   mono, as copied */
.export__words {
  margin: 0 0 var(--ds-space-16);
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-wrap: pretty;
}
.export__css {
  margin: 0;
  color: var(--ds-color-ink);
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  tab-size: 2;
  /* a long line wraps in the drawer, never under a sideways bar (the
     visual audit, 2026-10-12: 1268 of code in a box of 337, cut) */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.export__css:focus-visible {
  outline: none;
}
html[data-kbd] .export__css:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}

/* ---- the Export drawer (lib/export.js; round 5's Tokens drawer, renamed
        in round 6), every page's: the lab's chrome (square, a hairline,
        the canvas ground), its own scroll. From 960 it stands on the
        controls column's track, at the column's x and width (fixed: the
        page's offset and what the page leaves the column, at most the
        cap, as the rail reads it), and the bible's column it covers
        leaves paint and the Tab order (ds.css), so nothing fixed ever
        stands over a control but this; under 1200 it covers more than a
        column (an under section's stage from 960, the one-column page
        below it), so the page's main is inert while it is open
        (lib/export.js); under 960 at the page's rounded right edge. Its
        chrome the family's: a head of 48 (the title, Copy CSS, the close
        a 32-box in the action column), a hair of line under it, as the
        Global card's; under it one line of words and the system's CSS
        as one block, 16 in; the foot band's instance at its scrolling
        body's foot ----------------------------------------------- */
/* its right edge the page's rounded width, never the window's: a page
   scrollbar leaves an odd width (1425 at 1440), and a box anchored to
   the window's right then stood off the lattice (x 1041; lane D's
   finding, round 2), so it is placed from the left, as the column's
   track is (round 2's integration, 2026-10-09) */
.drawer {
  /* the page's rounded width (a fixed box's 100% is the window's less
     its scrollbar), and the drawer's own, 96 cells */
  --page-edge: round(down, 100% - var(--gutter-w), var(--ds-grid-cell));
  --drawer-w: min(calc(var(--ds-grid-cell) * 96), 100%);
  position: fixed;
  top: 0;
  bottom: 0;
  left: max(0px, calc(var(--page-edge) - var(--drawer-w)));
  z-index: 45;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: var(--drawer-w);
  background: var(--ds-color-canvas);
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-line);
}
@supports not (width: round(down, 1px, 1px)) {
  .drawer {
    left: auto;
    right: 0;
  }
}
.drawer[hidden] {
  display: none;
}
/* under 1200 the index is a bar over the page's top: the drawer stands
   under it, so the bar (its Inspect among it) stays in sight and in
   reach while the page is inert (lib/export.js) */
@media (max-width: 1199px) {
  .drawer {
    top: var(--nav-bar-h);
  }
}
/* from 960 it stands where the bible's inspector does, on its track (the
   page's offset and the stored width, --side-w), on every page alike */
@media (min-width: 960px) {
  .drawer {
    left: var(--side-x);
    width: var(--side-w);
  }
}
.drawer__head {
  display: flex;
  flex: none;
  align-items: stretch;
  height: var(--chrome-head);
  box-shadow: inset 0 calc(var(--rule) * -1) 0 var(--ds-color-line);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
}
/* the title takes the focus when the drawer opens (a heading, not a
   control: no ring of its own) */
.drawer__title {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  margin: 0;
  padding-left: var(--chrome-pad);
  color: var(--ds-color-ink);
  font-size: inherit;
  font-weight: 500;
  line-height: inherit;
}
.drawer__title:focus {
  outline: none;
}
.drawer__copy,
.drawer__close {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ds-color-dim);
  white-space: nowrap;
}
.drawer__copy {
  padding-inline: var(--ds-space-8);
}
/* the close: a 32-box in the action column, 8 from the edge */
.drawer__close {
  flex: none;
  align-self: center;
  box-sizing: border-box;
  width: calc(var(--ds-grid-cell) * 8);
  height: calc(var(--ds-grid-cell) * 8);
  margin-right: var(--ds-space-8);
}
.drawer__icon {
  display: flex;
  width: var(--ds-space-16);
  height: var(--ds-space-16);
}
.drawer__icon svg {
  width: 100%;
  height: 100%;
}
@media (hover: hover) {
  .drawer__copy:hover,
  .drawer__close:hover {
    color: var(--ds-color-ink);
  }
}
.drawer__copy:focus-visible,
.drawer__close:focus-visible {
  outline: none;
}
html[data-kbd] .drawer__copy:focus-visible,
html[data-kbd] .drawer__close:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.drawer__body {
  flex: 1 1 auto;
  display: grid;
  align-content: start;
  min-height: 0;
  padding: var(--ds-space-16);
  overflow: auto;
  overscroll-behavior: contain;
  container-type: inline-size;
  /* no bar, as the controls columns have none: a classic bar took 15
     of its 384 and put its rows off the lattice (1024 x 768); its foot
     band says more lies below */
  scrollbar-width: none;
}
.drawer__body::-webkit-scrollbar {
  display: none;
}

/* ---- the page's popup (lib/popup.js; the compact Colour picker in it,
        lib/pickpop.js): one module on every page, so its rules are this
        sheet's, every page's (iteration 24's audit: ds.css and
        side/side.css each held the same copy). A window of the system
        on the level above (L3), under the half whose colour it edits
        (round 5, 2026-10-10): a window's own corner and inset
        (components/surface.css), so it is the system's, not the lab's
        chrome; its content 56 cells whatever the inset (256 at the
        default 16); the list's edge, the inactive stroke, so it parts
        from the ground it stands over. Above the Inspect strip, under
        the drawer (the z ladder, ds.css) ----------------------------- */
.pickpop {
  position: absolute;
  z-index: 35;
  width: calc(var(--ds-grid-cell) * 56 + var(--space) * 2);
  box-shadow: inset 0 0 0 var(--stroke-inactive-w) var(--ds-stroke-inactive);
}
.pickpop[hidden] {
  display: none;
}
/* a panel on the level above, as a dropdown's list is: the control's
   corner, not a window's (its corner and inset), and what it holds
   nested by the inward law, the corner less the inset, at least 0, so
   square at the defaults (iteration 21; owner, of the colour popup's
   20: "make our color picker square like all the system components") */
.pickpop[data-surface] {
  --pop-corner: var(--control-corner, var(--ds-radius-corner));
  border-radius: var(--pop-corner);
}
/* taller than the window: its content scrolls inside (lib/popup.js) */
.pickpop[data-scrolls] {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.pickpop > * {
  --control-corner: max(0px, var(--pop-corner) - var(--space));
}
/* the nav's own popups (lib/nav.js): the bar's Tools, its three as rows
   of 32 in the chrome's 14 on 20, each on the nav's ladder (dim, ink
   under the hand, pressed on the system's chosen fill, greyed
   where the page cannot use it), its key at the row's end; and the
   note a tool's refusal gives, its words and the way to where it
   works */
.popmenu {
  display: grid;
}
.popmenu__item {
  display: flex;
  align-items: center;
  gap: var(--ds-space-8);
  box-sizing: border-box;
  height: calc(var(--ds-grid-cell) * 8);
  margin: 0;
  padding: 0 var(--ds-space-8);
  border: 0;
  background: none;
  color: var(--ds-color-dim);
  font: inherit;
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.popmenu__item[aria-pressed="true"] {
  background: var(--ds-color-active);
  color: var(--ds-color-page);
}
.popmenu__item[aria-disabled="true"] {
  opacity: 0.65;
  cursor: default;
}
.popmenu__key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--ds-space-16);
  height: var(--ds-space-16);
  margin-left: auto;
  padding: 0 var(--ds-space-4);
  box-shadow: inset 0 0 0 var(--rule) var(--line-strong, var(--ds-color-line));
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-14);
  font-weight: 400;
  line-height: var(--ds-space-16);
}
.popmenu__item[aria-disabled="true"] .popmenu__key {
  visibility: hidden;
}
@media (hover: hover) {
  .popmenu__item:not([aria-disabled="true"], [aria-pressed="true"]):hover {
    color: var(--ds-color-ink);
  }
  .popmenu__item[aria-pressed="true"]:hover {
    background: color-mix(
      in srgb,
      var(--ds-color-active),
      var(--ds-color-text) var(--ds-state-hover)
    );
  }
}
.popmenu__item:focus-visible,
.popnote__go:focus-visible {
  outline: none;
}
html[data-kbd] .popmenu__item:focus-visible,
html[data-kbd] .popnote__go:focus-visible {
  box-shadow: inset 0 0 0 var(--rule) var(--ds-color-measure);
}
.popnote {
  margin: 0 0 var(--ds-space-8);
  color: var(--ds-color-dim);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-wrap: pretty;
}
.popnote__go {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--ds-grid-cell) * 6);
  color: var(--ds-color-ink);
  font-size: var(--ds-text-14);
  line-height: calc(var(--ds-grid-cell) * 5);
  text-decoration: underline;
  text-underline-offset: calc(var(--ds-grid-cell) * 0.75);
}
/* a pressed tool's key on the fill keeps an edge, in its words' colour */
.toc__tool[aria-pressed="true"] .toc__key {
  box-shadow: inset 0 0 0 var(--rule) currentColor;
}

/* ---- the occlusion band's instances that are the nav's and the
        drawer's (ds.css says the rule and keeps the window's foot) --- */
:root {
  --fade-band: calc(var(--ds-grid-cell) * 12);
}
.toc::before,
.toc::after,
.drawer__body::after {
  background: linear-gradient(
    to var(--fade-to),
    transparent,
    var(--ds-color-canvas)
  );
  pointer-events: none;
}
/* the drawer's foot: a sticky band at its body's end, taking no row */
.drawer__body::after {
  content: "";
  position: sticky;
  bottom: 0;
  z-index: 1;
  height: var(--fade-band);
  margin-top: calc(var(--fade-band) * -1);
  --fade-to: bottom;
}

/* ---- the Proof grid: the whole document on the cell lattice ------- */
/* round 6, iteration 10 (owner: "refine proof grid, its entirely
   busted ... a bit larger, maybe each 16px ... behind everything and
   subtle"): the grid is the page's own ground while html[data-proof]
   (lib/nav.js), under every card and word, never over them (the overlay of
   round 4 blended over the page and dithered its words): a line every
   16 at 5 % of the ink, every module (96) at 10 %, both transparent
   mixes, so they read on either scheme. The .proof box keeps only the
   strip of what is left past the page's edge */
html[data-proof] .page,
html[data-proof] .side {
  --proof-cell: color-mix(in srgb, var(--ds-color-ink) 5%, transparent);
  --proof-major: color-mix(in srgb, var(--ds-color-ink) 10%, transparent);
  background:
    repeating-linear-gradient(
      to right,
      var(--proof-major) 0 var(--ds-hair),
      transparent 0 calc(var(--ds-grid-cell) * 24)
    ),
    repeating-linear-gradient(
      to bottom,
      var(--proof-major) 0 var(--ds-hair),
      transparent 0 calc(var(--ds-grid-cell) * 24)
    ),
    repeating-linear-gradient(
      to right,
      var(--proof-cell) 0 var(--ds-hair),
      transparent 0 calc(var(--ds-grid-cell) * 4)
    ),
    repeating-linear-gradient(
      to bottom,
      var(--proof-cell) 0 var(--ds-hair),
      transparent 0 calc(var(--ds-grid-cell) * 4)
    );
}
.proof {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: clip;
  pointer-events: none;
}
.proof[hidden] {
  display: none;
}
.proof__left {
  position: absolute;
  top: 0;
  bottom: 0;
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--ds-color-off) 45%, transparent) 0 1px,
    transparent 0 var(--ds-grid-cell)
  );
}
/* the strip is 0 to 3 px wide: its label stands just inside the page */
.proof__label {
  position: sticky;
  top: var(--nav-bar-h);
  display: block;
  width: max-content;
  padding: var(--ds-space-4) 0;
  transform: translateX(-100%);
  color: var(--ds-color-off);
  font-family: var(--ds-font-mono);
  font-size: var(--ds-text-15);
  writing-mode: vertical-rl;
}

/* ---- below 1200 the index is a bar: one that holds more than its width
        scrolls sideways (the Colour picker's link made it run past 1024;
        without the Style it holds its run at 1024)
        -------------------------------------------------------------- */
@media (max-width: 1199px) {
  /* no gap between its blocks: the links' own room (8 a side) and the
     rules' (below) part them, so every word of the bar stands 16 from
     the next, and the run fits a window of 1000 (the owner's "refine") */
  .toc {
    --toc-gap: 0px;
  }
  /* the brand at its words' width and the links' room after it (the
     column's 144 left 39 of bar after its words) */
  .toc__brand {
    width: auto;
    padding-right: var(--ds-space-8);
  }
  /* a bar holding more than its width: it scrolls sideways, quietly,
     and keeps the one in view in view (lib/toc.js) */
  .toc {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    /* the index's follow (lib/toc.js) brings its item a fade's width
       clear of either end the bar continues past, by the least scroll */
    scroll-padding-inline: var(--fade-band);
  }
  /* the three tools stand in the popup of the bar's one Tools
     (lib/nav.js), so the bar's run fits from 1000 (the owner's "refine":
     at 1000 Export was cut at "Expo" and the Proof grid off the
     window) */
  .toc__tool:not(.toc__more) {
    display: none;
  }
  .toc__more {
    display: flex;
  }
  /* the column's hairlines between its blocks, in the bar a rule of 24
     before the sections, the pages and the tools, 4 from the links' own
     room either side, so two words across a rule stand 25 apart, 16
     within a block (the room the Tools chevron takes: at 8 a side the
     bar's run was 24 past a window of 1000) */
  .toc__list::before,
  .toc__pages::before,
  .toc__tools::before {
    content: "";
    flex: none;
    align-self: center;
    width: var(--rule);
    height: calc(var(--ds-grid-cell) * 6);
    margin-inline: var(--ds-space-4);
    background: var(--ds-color-line);
  }
  .toc::-webkit-scrollbar {
    display: none;
  }
  /* where the bar continues past either edge, a fade in the bar's own
     ground lies over the words (the occlusion rule's instances, above):
     an overlay, never a mask, so the bar's ground and hairline stay
     whole and nothing shows through. Each takes no room (its negative
     margin gives back its width and the gap) */
  .toc::before,
  .toc::after {
    content: "";
    position: sticky;
    /* over the list and the brand (each a layer of 1, after it in the
       page: at 1 the fade lay under the words it should dissolve) */
    z-index: 2;
    flex: none;
    align-self: stretch;
    width: var(--fade-band);
    opacity: 0;
  }
  /* a sticky box keeps inside the bar's padding: the fades are held
     past it, to the window's edge, so no word shows cut there */
  /* the start's fade reaches the first whole word (lib/toc.js
     --fade-before): a word the bar's start cuts dissolves under it to its
     end, never read as a fragment ("ystem" of the brand), and the band's
     48 dissolve at its inner edge, solid before it */
  .toc::before {
    --fade-to: left;
    left: calc(var(--toc-pad) * -1);
    width: var(--fade-before, var(--fade-band));
    margin-right: calc(
      var(--fade-before, var(--fade-band)) * -1 - var(--toc-gap)
    );
    background: linear-gradient(
      to left,
      transparent,
      var(--ds-color-canvas) min(100%, var(--fade-band))
    );
  }
  .toc::after {
    --fade-to: right;
    right: calc(var(--toc-pad) * -1);
    margin-left: calc(var(--fade-band) * -1 - var(--toc-gap));
  }
  .toc[data-before]::before,
  .toc[data-more]::after {
    opacity: 1;
  }
  .toc > * {
    flex: none;
  }
}
/* from 768 to 1199 the bar's Tools stands still at its end, and the
   bar's run scrolls under it, so the three tools are in reach at any
   width a mouse has (the review of the refinement: under 1000 the run
   ran past the window again, Tools off its end, reachable only
   sideways). Its ground is the bar's, hairline and all, to the window's
   edge (its room there the bar's end room), and where the bar continues
   past it the end's fade stands before it, not at the window's edge */
@media (min-width: 768px) and (max-width: 1199px) {
  .toc {
    padding-inline-end: 0;
  }
  .toc__tools {
    position: sticky;
    right: 0;
    z-index: 2;
    padding-right: var(--toc-pad);
    background: var(--ds-color-canvas);
    box-shadow: inset 0 calc(var(--rule) * -1) 0 var(--ds-color-line);
  }
  .toc::after {
    display: none;
  }
  .toc__tools::after {
    content: "";
    position: absolute;
    top: 0;
    right: 100%;
    bottom: var(--rule);
    width: var(--fade-band);
    background: linear-gradient(to right, transparent, var(--ds-color-canvas));
    opacity: 0;
    pointer-events: none;
  }
  .toc[data-more] .toc__tools::after {
    opacity: 1;
  }
}
/* a phone: the 16 gutter; the lab's debug chrome hidden
   (data-chrome="debug": the bible's brand, the tools, the drawer), one
   rule for every page; the bible keeps its section links, then its
   rule and the pages (the refinement of iteration 24, the owner's "refine":
   with its links alone the bible was a dead end, none of the four other
   pages in reach, against the owner's "its all one system"), another
   page its way back and the pages, the one you are on marked */
@media (max-width: 767px) {
  .toc__tools {
    display: none;
  }
  /* the bible draws no brand there, so no rule before its sections; on
     another page the brand and the pages, no rule between them, so the
     run fits 390 to its last page but one (with it the Type page's own
     link stood under the fade) */
  .toc[data-here="bible"] .toc__list::before,
  .toc:not([data-here="bible"]) .toc__pages::before {
    display: none;
  }
  .toc {
    --toc-pad: var(--ds-space-16);
  }
  [data-chrome~="debug"] {
    display: none !important;
  }
  /* the Proof grid is one of the tools, which are for a wider window: a
     phone draws none, whatever the visit kept (lib/nav.js refuses it
     there, as it refuses Inspect and Export) */
  html[data-proof] .page,
  html[data-proof] .side {
    background: none;
  }
  .toc:not([data-here="bible"]) .toc__list {
    display: none;
  }
}

/* a finger: every target the touch unit, 48 */
@media (pointer: coarse) {
  .toc__link,
  .toc__page {
    justify-content: center;
    min-width: calc(var(--ds-grid-cell) * 12);
    box-sizing: border-box;
  }
  .toc__tool {
    min-height: calc(var(--ds-grid-cell) * 12);
  }
  /* the drawer's close 48, as the Global card's boxes */
  .drawer__close {
    width: calc(var(--ds-grid-cell) * 12);
    height: calc(var(--ds-grid-cell) * 12);
    margin-right: 0;
  }
}
@media (pointer: coarse) and (min-width: 1200px) {
  .toc__link,
  .toc__page {
    justify-content: flex-start;
    padding-block: calc(var(--ds-grid-cell) * 3);
  }
}

/* reduced motion: the nav and the drawer still (each page's sheet stills
   the rest) */
@media (prefers-reduced-motion: reduce) {
  .toc,
  .toc *,
  .toc::before,
  .toc::after,
  .toc *::before,
  .toc *::after,
  .drawer,
  .drawer * {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation: none !important;
  }
}
/* forced colours: the mark and the current in the system's text, a
   pressed tool in Highlight, the drawer outlined, every ring Highlight */
@media (forced-colors: active) {
  .toc__view {
    forced-color-adjust: none;
    background: CanvasText;
  }
  .toc__link[aria-current="true"] {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .toc__page[aria-current="page"] {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .toc__page[aria-current="page"]::before {
    forced-color-adjust: none;
    background: CanvasText;
  }
  .toc__tool[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }
  .drawer {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  /* the refinement's parts (iteration 24): a pressed tool in the bar's
     Tools in Highlight as the column's; a tool the page cannot use in
     the system's grey; the bar's rules in the text colour; the skip
     link and the nav's popups' rings an outline */
  /* the page's popup keeps an edge (its stroke is a shadow, dropped
     here): the Tools menu stood edgeless over the Global card */
  .pickpop {
    outline: 1px solid CanvasText;
    outline-offset: -1px;
  }
  .popmenu__item[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }
  .toc__tool[aria-disabled="true"],
  .popmenu__item[aria-disabled="true"] {
    opacity: 1;
    color: GrayText;
  }
  .toc__list::before,
  .toc__pages::before,
  .toc__tools::before {
    forced-color-adjust: none;
    background: CanvasText;
  }
  .toc__skip {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  html[data-kbd] .popmenu__item:focus-visible,
  html[data-kbd] .popnote__go:focus-visible {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  html[data-kbd] .toc__brand:focus-visible,
  html[data-kbd] .toc__link:focus-visible,
  html[data-kbd] .toc__page:focus-visible,
  html[data-kbd] .toc__tool:focus-visible,
  html[data-kbd] .drawer__copy:focus-visible,
  html[data-kbd] .drawer__close:focus-visible {
    outline: 2px solid Highlight;
    outline-offset: 2px;
  }
}
