/* ---- /uses: the periodic table of the tools on Jason's screen ----
   One issue a month, written by scripts/build-uses.mjs from
   content/uses/<YYYY-MM>.json (DESIGN.md, "Uses"; specs/uses.md). From
   Paper's "A · Periodic table" in "Portfolio v3", page "Uses · 2026-10-03".
   From 1280px each family is a column, its cells stacked on its label and
   the columns bottom-aligned, so the table's outline rises where a family
   holds more tools. Below 1280px each family is a row that scrolls sideways.
   Counts are measured; the notes say only what the record shows. */

/* A menu-bar strip is 28 of a tile's 100 (scripts/paint-uses.py STRIP), so
   its text sits on the line of a tile's corner figures. */
.uses { --uses-cell-w: 130px; --uses-cell-h: 100px; --uses-strip-h: calc(var(--uses-cell-h) * 0.28); }

/* The head: the title, with every issue right under it, oldest first, the
   one shown in plain ink and the rest links (2026-11-02; the list sat at the
   foot of the page, newest first, and the head linked /uses/ to its own
   copy). */
.uses-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-8);
  padding-bottom: var(--space-20);
}
.uses-issues ol { display: flex; flex-wrap: wrap; gap: 0 var(--space-24); list-style: none; }
.uses-issues :is(a, span) { display: inline-flex; align-items: center; min-height: 44px; margin-block: calc(-1 * var(--hit-slop)); }
.uses-issues a { color: var(--ink-soft); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.uses-issues [aria-current] { color: var(--ink); }
.uses-issues a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .uses-issues a:hover { color: var(--ink); text-decoration-thickness: 2px; }
}

/* No orphans anywhere on the page (2026-11-01): short lines balance, running
   text breaks pretty. */
.uses :is(h1, h2, h3, .uses-move__name, .uses-row__label p, .uses-row__empty) { text-wrap: balance; }
.uses :is(p, li) { text-wrap: pretty; }
.uses :is(.uses-row__label p, .uses-row__empty) { text-wrap: balance; }

/* ---- The table ---- */

.uses-table { position: relative; padding-top: var(--space-64); }

.uses-family { display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.uses-family__cells { display: flex; flex-direction: column; gap: var(--space-6); list-style: none; }

/* From 1280px, layout A (Jason, 2026-10-14): a periodic table. Each family is
   a block on the grid, placed by scripts/build-uses.mjs (--col, --row, --w,
   --h), and each tool a slot in its block (--c, --r). The blocks share the
   grid's 6px gap, so their cells line up across families. */
@media (width >= 1280px) {
  .uses-grid {
    display: grid;
    /* The columns share the width, so the table meets both edges. */
    grid-template-columns: repeat(var(--uses-cols), minmax(0, 1fr));
    grid-template-rows: var(--uses-rows);
    gap: var(--space-6);
  }
  .uses-grid > .uses-family { display: block; grid-column: var(--col) / span var(--w); grid-row: var(--row) / span var(--h); }
  .uses-grid .uses-family__cells {
    display: grid;
    grid-template-columns: repeat(var(--w), minmax(0, 1fr));
    grid-template-rows: repeat(var(--h), var(--uses-cell-h));
    gap: var(--space-6);
  }
  .uses-grid .uses-family__cells > li { grid-column: var(--c); grid-row: var(--r); }
}
/* From 1280px a family has no label or rule under it (Jason, 2026-10-14):
   the label stays in the markup, first, for a screen reader, and shows
   again over each row below 1280px. */
.uses-family__name { font-weight: 400; line-height: var(--text-micro-line); }
@media (width >= 1280px) {
  .uses-family .uses-family__name {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}
.uses-family__count { display: none; color: var(--ink-soft); }

/* A cell is an element tile, painted (Jason, 2026-10-14; DESIGN.md,
   "Uses"): a watercolour wash in its family's pigment, as deep as its days,
   under a pencil outline, both from scripts/paint-uses.py. Days seen at the
   top left like an atomic number, the days agents ran it at the top right,
   and the symbol and name centred, all in ink. The paint is the cell's
   ::before, one cell of the issue's sprite set in percentages, so it fits
   the tile at any size; it runs 8px past the 130 by 100 tile, so a pool or
   a stroke can cross the edge. */
.uses { --paint: var(--paint-light); }
@media (prefers-color-scheme: dark) { .uses { --paint: var(--paint-dark); } }
.uses-cell {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  grid-template-areas: "days headless" "symbol symbol" "name name" "last last";
  width: 100%;
  height: var(--uses-cell-h);
  padding: 7px 10px 12px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.uses-cell::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* 8px of 100 and of 130: the sprite cell's margin around its tile. */
  inset: -8% -6.1538%;
  background: var(--paint) var(--paint-x) var(--paint-y) / calc(var(--paint-cols) * 100%) calc(var(--paint-rows) * 100%) no-repeat;
  pointer-events: none;
}
/* The paint goes on as the page loads (2026-10-17): each wash blooms out
   from a point inside its tile, wet at the edge, and dries sharp, in a
   loose sweep from the left that uses.js times per cell. The soft edge is
   the mask's falloff; a blur on every tile cost frames and added nothing
   (2026-11-02). The ink type is there from the first frame; only the
   paint, and the pencil in
   the same sprite, arrive. Until uses.js marks the table live the paint
   holds back, for 2s at most, so a script that never loads still shows it.
   With reduced motion the paint is simply there. */
@property --bloom { syntax: "<percentage>"; inherits: false; initial-value: 160%; }
@media (prefers-reduced-motion: no-preference) {
  .js [data-uses-table]:not(.uses-live) .uses-cell::before { animation: uses-paint-wait 0s 2s backwards; }
  .uses-live .uses-cell::before {
    --bloom-edge: calc(var(--bloom) - 45%);
    -webkit-mask-image: radial-gradient(farthest-corner at var(--bloom-x, 50%) var(--bloom-y, 50%), #000 var(--bloom-edge), transparent var(--bloom));
    mask-image: radial-gradient(farthest-corner at var(--bloom-x, 50%) var(--bloom-y, 50%), #000 var(--bloom-edge), transparent var(--bloom));
    animation: uses-paint-in 1100ms cubic-bezier(0.22, 0.7, 0.25, 1) var(--bloom-delay, 0ms) backwards;
  }
  /* Dry: uses.js marks a cell once its wash has bloomed, and the mask goes. */
  .uses-live .uses-cell--dry::before { -webkit-mask-image: none; mask-image: none; animation: none; }
}
@keyframes uses-paint-wait { from { opacity: 0; } }
@keyframes uses-paint-in {
  from { --bloom: 0%; opacity: 0; }
  30% { opacity: 1; }
  to { --bloom: 160%; opacity: 1; }
}
.uses-cell__symbol {
  grid-area: symbol;
  align-self: center;
  justify-self: center;
  font-family: var(--display);
  font-weight: 400;
  font-size: 30px;
  line-height: 30px;
  letter-spacing: -0.01em;
}
/* Days seen, in the mono 11px; of how many is in its tooltip. */
.uses-cell__days {
  grid-area: days;
  justify-self: start;
  font-family: var(--mono);
  font-size: var(--text-micro);
  font-weight: 400;
  line-height: var(--text-micro-line);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}
/* A name never wraps (2026-10-18): one that is too long overflows, and
   uses.js steps it down until it fits, so the symbol keeps its line. A long
   domain (gemini.google.com) starts a size down. */
.uses-cell__name {
  grid-area: name;
  font-size: 13px;
  font-weight: 500;
  line-height: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.uses-cell__name--long { font-size: 11.5px; letter-spacing: -0.01em; }

/* The days agents ran it, at the top right and never added to days seen.
   Its place says what it is (2026-10-14), so it has no mark. */
.uses-cell__headless {
  grid-area: headless;
  justify-self: end;
  font-family: var(--mono);
  font-size: var(--text-micro);
  font-weight: 400;
  line-height: var(--text-micro-line);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}

/* A command-line tool: its name as the command, at a prompt, with no
   cursor (Jason, 2026-10-14). */
.uses-cell__command { font-family: var(--mono); font-size: var(--text-micro); letter-spacing: 0; white-space: nowrap; }

/* Faceless: a pool of paint with no outline, so its figures sit in from the
   corners, on the paint, 16px down and 22px in, both on one line. */
.uses-cell--faceless .uses-cell__days { margin: 9px 0 0 12px; }
.uses-cell--faceless .uses-cell__headless { margin: 9px 12px 0 0; }

/* Menu bar: always on, rarely open. A painted strip at the top of its slot,
   in its own pencil outline, holds the days around at the left and the
   name; the rest of the slot is bare paper (2026-11-01: an outline round the
   whole slot read as a missing tile). No symbol: "Menu bar" is in the
   cell's name and on its card. */
.uses-cell--ambient {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: var(--uses-strip-h);
  grid-template-areas: "days name";
  align-items: center;
  column-gap: 7px;
  padding: 0 var(--space-8) var(--space-12);
  text-align: left;
}
.uses-cell--ambient .uses-cell__symbol { display: none; }
/* A note on the card: the tile's lower right corner folds over, a small ink
   triangle drawn on the cell's own box, so it never reflows the type
   (2026-11-01). */
.uses-cell--noted { --fold: 10px; }
.uses-cell__fold {
  position: absolute;
  right: 0;
  bottom: 0;
  width: var(--fold);
  height: var(--fold);
  background: var(--ink);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  pointer-events: none;
}
/* A menu bar tile is the strip at the top of its slot, so its corner folds there. */
.uses-cell--ambient .uses-cell__fold { bottom: auto; top: calc(var(--uses-strip-h) - var(--fold)); }
@media (width < 600px) { .uses-cell--noted { --fold: 8px; } }
.uses-cell--ambient .uses-cell__name { font-size: 11px; line-height: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }

/* Left: a pencil outline alone, struck, in soft ink, with the day it was
   last seen under the name. */
.uses-cell__last { grid-area: last; margin-top: var(--space-2); line-height: var(--text-micro-line); }

/* The open cell takes a 2px ink frame over its paint, and the card's notch
   from 1280px; the focus ring sits 3px further out. The frame is the cell's
   ::after, above the paint: drawn on the cell itself it sat under the wash
   and all but vanished on a deep tile (2026-10-17). A border, not a shadow,
   so forced colours keep it. A strip's frame is the strip's alone. */
.uses-cell:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.uses-cell[aria-expanded="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--ink);
  pointer-events: none;
}
.uses-cell--ambient[aria-expanded="true"]::after { bottom: auto; height: var(--uses-strip-h); }

/* A pressed cell, chip or Close gives as the site's other buttons do, and touch
   draws no grey flash over the cell's own open frame. */
.uses-cell, .uses-note__close { -webkit-tap-highlight-color: transparent; }
.uses-cell, .uses-note__close { transition: scale 150ms var(--ease-out); }
.uses-cell:active, .uses-note__close:active { scale: 0.96; }
@media (prefers-reduced-motion: reduce) {
  .uses-cell, .uses-note__close { transition: none; }
}

@media (hover: hover) and (pointer: fine) {
  .uses-cell:hover .uses-cell__name { text-decoration-line: underline; text-underline-offset: 3px; }
}

/* ---- A tool's card ----
   Without uses.js every card shows, in a list under the table, and each cell
   links to its card. uses.js turns the cells into buttons and shows one card
   at a time: over the table from 1280px, pointing at its cell, and under the
   cell's row below that. */

.uses-notes { padding-top: var(--space-64); }
.uses-notes__title {
  padding-bottom: var(--space-16);
  margin-bottom: var(--space-20);
  border-bottom: 1px solid var(--ink);
  font-family: var(--display);
  font-weight: 400;
  font-size: 26px;
  line-height: 30px;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.uses-notes__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 400px), 1fr));
  gap: var(--space-20);
  list-style: none;
}

/* Three groups, 24px apart and 24px in from the edge (2026-11-01): the
   head, the month, and the note with its link. */
.uses-note {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
  padding: var(--space-24);
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
}
/* Scrolled in, a card stops above the fixed back-to-home square: its 22px
   offset, 44px and 16px to spare. */
.uses-note[data-open] { max-width: 540px; scroll-margin-block-end: 82px; }
.uses-note:focus { outline: none; }
/* Focus thickens the card's own edge rather than drawing a second frame
   outside it. */
.uses-note:focus-visible { outline: 1px solid var(--ink); outline-offset: -2px; }
/* The name on its own line with Close across from it, and the family and
   tag under the name, so a long name never squeezes them (2026-11-01). */
.uses-note__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name close" "family family";
  align-items: baseline;
  column-gap: var(--space-14);
  row-gap: var(--space-6);
}
.uses-note__name { grid-area: name; }
.uses-note__family { grid-area: family; }
.uses-note__close { grid-area: close; }
.uses-note__name {
  font-family: var(--display);
  font-weight: 400;
  font-size: 26px;
  line-height: 30px;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.uses-note__family { color: var(--ink-soft); }
.uses-note__close {
  display: inline-flex;
  margin-inline-start: auto;
  align-items: center;
  gap: var(--space-4);
  min-height: 44px;
  margin-block: calc(-1 * var(--hit-slop));
  padding: 0 0 0 var(--space-8);
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.uses-note__close[hidden] { display: none; }
.uses-note__close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .uses-note__close:hover { text-decoration: underline; text-underline-offset: 3px; }
}
/* The month: a strip of days, then one caption. A filled square is a day
   on screen (or around, for a menu bar tool); a tick under it, a day agents
   ran it; an open square, a day with no record. 8px from strip to caption. */
.uses-note__data, .uses-move__data { display: flex; flex-direction: column; gap: var(--space-8); }
.uses-move__data { margin-block: var(--space-4) var(--space-2); }
/* Every recap strip spans its column, so they all share one edge. */
.uses-move__data .uses-strip { width: 100%; }
.uses-strip { display: flex; gap: 2px; }
.uses-strip--agents { padding-bottom: 5px; }
.uses-strip > span {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  max-width: 14px;
  height: 12px;
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}
.uses-strip > .is-on { background: var(--ink); }
.uses-strip > .is-gap { background: none; box-shadow: inset 0 0 0 1px var(--line); }
.uses-strip > .is-agent::after {
  content: "";
  position: absolute;
  inset: auto 0 -5px;
  height: 2px;
  background: var(--ink-soft);
}
/* A tooltip for a strip square or a cell's corner figure: date in ink over
   what the day shows (or the figure's meaning alone), in a small
   paper box with a hairline, drawn by uses.js on hover. */
.uses-tip {
  position: fixed;
  z-index: 50;
  display: flex;
  flex-direction: column;
  padding: var(--space-4) var(--space-8);
  background: var(--paper);
  border: 1px solid var(--ink);
  color: var(--ink-soft);
  line-height: var(--text-micro-line);
  white-space: nowrap;
  text-transform: none;
  letter-spacing: 0;
  pointer-events: none;
}
.uses-tip[hidden] { display: none; }
.uses-tip strong { color: var(--ink); font-weight: inherit; }
.uses-strip > span { cursor: default; }
.uses-note__data-caption, .uses-move__data-caption { color: var(--ink-soft); line-height: var(--text-micro-line); text-transform: none; letter-spacing: 0; }
/* The note and the tool's site, as one group. */
.uses-note__body { display: flex; flex-direction: column; gap: var(--space-8); }
/* His note: plain serif in ink, a touch larger than the counts, with no
   rule or name (2026-11-01). */
.uses-note__note {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 27px;
  font-synthesis: none;
  text-wrap: pretty;
}
.uses-note__link,
.uses-move__link {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: calc(-1 * var(--hit-slop));
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  /* A long label (github.com/owner/repo) wraps on a narrow phone. */
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}
.uses-note__link:focus-visible,
.uses-move__link:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* With uses.js: one card at a time, and the list stays out of sight. */
.uses-live .uses-notes { display: none; }
.uses-note--float {
  position: absolute;
  z-index: 2;
  width: min(540px, 100%);
}
/* Floating, uses.js sizes it to whole columns. */
.uses-note--float[data-open] { max-width: none; }
/* The notch: a 6px ink tick from the card's edge to its cell. */
.uses-note--float::after {
  content: "";
  position: absolute;
  left: var(--notch, 50%);
  height: 6px;
  /* A border, so forced colours draw it rather than a gap in the card. */
  border-left: 1px solid var(--ink);
}
.uses-note--float[data-side="above"]::after { top: 100%; }
.uses-note--float[data-side="below"]::after { bottom: 100%; }

/* ---- The issue's recap ----
   What joined, what left, the top of the table, the notes, and the issues.
   Rows on About's columns, between hairlines. */

.uses-recap { padding-top: var(--space-96); }
.uses-recap__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-8) var(--space-24);
  padding-bottom: var(--space-16);
  border-bottom: 1px solid var(--ink);
}
.uses-recap__head .micro { color: var(--ink-soft); }
.uses-recap__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: 26px;
  line-height: 30px;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.uses-row {
  display: grid;
  grid-template-columns: var(--column) minmax(0, 1fr);
  gap: var(--space-12) var(--column-gap);
  padding: var(--space-24) 0 var(--space-28);
  border-bottom: 1px solid var(--line);
  border-image: linear-gradient(to top, var(--line) var(--hairline), transparent 0) 1;
}
.uses-row__label { display: flex; flex-direction: column; gap: var(--space-10); padding-top: var(--space-4); }
.uses-row__label h3 { font-weight: 400; line-height: var(--text-micro-line); }
.uses-row__label p { max-width: 340px; color: var(--ink-soft); font-size: 16px; line-height: 24px; text-wrap: pretty; }
.uses-row__body { max-width: 760px; }
.uses-row__empty,
.uses-recap__notes p,
.uses-method p {
  max-width: 580px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 27px;
  font-synthesis: none;
  text-wrap: pretty;
}
.uses-row__empty { color: var(--ink-soft); }
.uses-recap__notes { list-style: none; }
/* How this is counted: a row of the month like the others (2026-11-01), in
   the notes' serif, open, so the counts have their reading beside them. */
.uses-method { display: flex; flex-direction: column; gap: var(--space-12); }
.uses-recap__notes li + li { margin-top: var(--space-12); }

.uses-moves { list-style: none; display: flex; flex-direction: column; gap: var(--space-16); }
.uses-move { display: flex; align-items: flex-start; gap: var(--space-16); }
.uses-move__body { display: flex; flex-direction: column; gap: var(--space-6); flex: 1; min-width: 0; max-width: 580px; }
/* A recap name is the board's: sans 16, medium. With a card it is a 44px
   link that opens the card under its line (2026-11-01). */
.uses-move__name { font-size: 16px; font-weight: 500; line-height: 24px; }
a.uses-move__name {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: -10px;
  color: inherit;
  text-decoration: none;
}
a.uses-move__name:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  a.uses-move__name:hover { text-decoration: underline; text-underline-offset: 3px; }
}
/* Every recap entry, from 1280px: the chip and name at the left, and to
   their right the month as a strip across the column, then any note and
   link (Jason, 2026-11-01; the caption under the strip went 2026-11-02). Below 1280px they stack. */
.uses-move__detail { display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
@media (width >= 1280px) {
  .uses-move__body { display: grid; grid-template-columns: 144px minmax(0, 1fr); column-gap: var(--space-24); align-items: start; }
  .uses-move__name { grid-column: 1; }
  /* With no caption under it, the strip stands taller: 16px, centred on
     the name's 24px line (2026-11-02). */
  .uses-move__detail { grid-column: 2; padding-top: 4px; }
  .uses-move__data { gap: var(--space-4); margin: 0; }
  .uses-move .uses-strip > span { max-width: none; height: 16px; }
}
.uses-moves__also { margin-top: var(--space-16); color: var(--ink-soft); font-size: 16px; line-height: 24px; }
.uses-move__open { list-style: none; }
/* The site ends the row, 4px clear of the note above its 44px target. */
.uses-move__link { margin-top: -11px; }
.uses-move__note {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 27px;
  font-synthesis: none;
  text-wrap: pretty;
}

/* A symbol as a chip: a label beside a recap row's tool, and in a board row
   (2026-10-18). Its case is the symbol's. */
.uses-chip {
  position: relative;
  flex: none;
  display: inline-block;
  min-width: 34px;
  padding: 4px 7px;
  border: 1px solid var(--line-strong);
  line-height: var(--text-micro-line);
  text-align: center;
  text-transform: none;
  text-decoration: none;
  color: var(--ink);
}

/* A painted chip: its tile's paint, scaled down to the chip, inside the
   chip's own hairline (2026-11-01), which stands in for the pencil that
   is lost at this size. The paint is the sprite cell as on a tile, 8px of
   margin round it, clipped to the chip; a faceless pool has no edge. */
.uses-chip--painted {
  isolation: isolate;
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 26px;
  padding: 0;
  overflow: hidden;
}
.uses-chip--painted::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -8% -6.1538%;
  background: var(--paint) var(--paint-x) var(--paint-y) / calc(var(--paint-cols) * 100%) calc(var(--paint-rows) * 100%) no-repeat;
  pointer-events: none;
}
.uses-chip--faceless { border: 0; overflow: visible; }

/* Separate borders, since a collapsed table ignores border-image and would
   draw its rules a full 1px rather than as the site's hairline. */
.uses-board { width: 100%; border-collapse: separate; border-spacing: 0; font-variant-numeric: tabular-nums; }
.uses-board th,
.uses-board td { padding: var(--space-8) 0; border-bottom: 1px solid var(--line); border-image: linear-gradient(to top, var(--line) var(--hairline), transparent 0) 1; text-align: right; font-weight: 400; }
.uses-board thead th { padding-top: 0; color: var(--ink-soft); line-height: var(--text-micro-line); }
.uses-board th:nth-child(2),
.uses-board td:nth-child(2) { text-align: left; }
.uses-board :is(th, td):first-child { width: 56px; text-align: left; }
/* A gutter between columns, so right-aligned headers never run into the
   next one ("…of 1,291" and "Share" read as one at 320). */
.uses-board :is(th, td) + :is(th, td) { padding-inline-start: var(--space-12); }
.uses-board tbody th { text-align: left; font-size: 16px; font-weight: 500; line-height: 20px; }
/* Each row is a 44px target (2026-11-01: they were 28px); the row's own
   padding goes, so the board keeps its height. */
.uses-board tbody :is(th, td) { padding-block: 0; height: 44px; vertical-align: middle; }
.uses-board tbody tr:last-child :is(th, td) { border-bottom: 0; }
/* A board row's card opens in a row of its own under it. */
.uses-board .uses-board__open td { padding: var(--space-12) 0 var(--space-20); text-align: left; font-family: inherit; font-size: inherit; }
.uses-board__tool { display: inline-flex; align-items: center; gap: var(--space-12); min-height: 44px; text-decoration: none; }
.uses-board__tool:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  /* The name underlines, never the symbol's chip beside it (Jason, 2026-10-18). */
  .uses-board__tool:hover .uses-board__name { text-decoration: underline; text-underline-offset: 3px; }
}


/* From 1280px the month's rows stand on the table's columns (2026-11-01):
   the label takes the first two, the body the next four, so a chip lines up
   with a tile's edge and every note, strip and table ends on one line. */
@media (width >= 1280px) {
  .uses-row { grid-template-columns: repeat(var(--uses-cols), minmax(0, 1fr)); column-gap: var(--space-6); }
  .uses-row__label { grid-column: 1 / span 2; }
  .uses-row__body { grid-column: 3 / span 4; max-width: none; }
  .uses-move__body { flex: 1; max-width: none; }
  .uses-row__empty, .uses-recap__notes p, .uses-method p { max-width: none; }
  /* Rank and the 12px gutter after it take a chip's width and its gap, so a
     board's chips start where a row's names do. */
  .uses-board :is(th, td):first-child { width: 38px; }
}

/* ---- Narrower: the intro stacks, lede first ---- */
@media (width < 1100px) {
  .uses-row { grid-template-columns: minmax(0, var(--column)) minmax(0, 1fr); }
}

/* ---- Below 1280px each family is a row ---- */
@media (width < 1280px) {
  .uses-table { padding-top: var(--space-40); }
  .uses-grid { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-24); }
  .uses-family__name {
    order: 0;
    display: flex;
    justify-content: space-between;
    padding-top: 0;
    border-top: 0;
  }
  .uses-family__count { display: inline; }
  /* The row runs off the right edge and scrolls; the page never does. */
  .uses-family__cells {
    flex-direction: row;
    overflow-x: auto;
    /* A swipe past the row's end stays in the row, never goes Back. */
    overscroll-behavior-x: contain;
    margin-right: calc(-1 * var(--gutter));
    padding-right: var(--gutter);
    /* Room for the 2px focus ring 3px out, so the scroller never clips it. */
    padding-block: var(--space-6);
    margin-block: calc(-1 * var(--space-6));
    padding-left: var(--space-6);
    margin-left: calc(-1 * var(--space-6));
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
  }
  .uses-family__cells > li { flex: none; width: var(--uses-cell-w); }
  .uses-note--float { position: static; }
}

@media (width < 800px) {
  .uses-row { grid-template-columns: minmax(0, 1fr); padding: var(--space-20) 0 var(--space-24); }
  .uses-row__label p { max-width: none; }
  .uses-recap { padding-top: var(--space-64); }
  .uses-notes { padding-top: var(--space-48); }
}

@media (width < 600px) {
  /* Three cells and part of a fourth at any phone width, so a row always
     shows it scrolls: 84px at 320, 96px from about 360. */
  .uses { --uses-cell-w: clamp(84px, calc((100vw - var(--gutter)) / 3.4 - 6px), 96px); --uses-cell-h: 72px; }
  .uses-cell { padding: 7px 7px 9px; }
  .uses-cell__symbol { font-size: 22px; line-height: 24px; letter-spacing: 0; }
  .uses-cell--faceless .uses-cell__days { margin: 3px 0 0 7px; }
  .uses-cell--faceless .uses-cell__headless { margin: 3px 7px 0 0; }
  /* One line, 11.5px, never smaller. From 360px uses.js widens the cell of
     a name too long for it; below that it ends in an ellipsis, and the
     accessible name and card keep it whole. */
  .uses-cell__name { font-size: 11.5px; line-height: 15px; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* A left tool's date goes; the card keeps it. */
  /* The strip is 28% of a 72px slot: its name and days stay on it. */
  .uses-cell--ambient { padding: 0 var(--space-6) var(--space-8); column-gap: 5px; }
  .uses-note { padding: var(--space-16); gap: var(--space-20); }
  .uses-note__name { font-size: 22px; line-height: 26px; }
  .uses-recap__title { font-size: 22px; line-height: 26px; }
  .uses-board :is(th, td):first-child { width: 40px; }
  .uses-board__tool .uses-chip { display: none; }
}

/* The holder of a card opened in place: a one-row grid, so its row can
   open from nothing. Ahead of the motion below, whose starting style must
   come later in the file to win. */
.uses-open__reveal { display: grid; grid-template-rows: 1fr; }
.uses-open__reveal > div { min-height: 0; overflow: hidden; }

/* ---- Motion beyond the paint-in (2026-11-02) ----
   All of it is off with reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  /* A floating card grows out of its cell: from the notch, 97% to whole,
     with a quick fade. Moving to another cell's card, and closing, stay
     instant. */
  .uses-note[data-open] { transition: opacity 180ms var(--ease-out), scale 220ms var(--ease-out); }
  .uses-note--float[data-side="above"] { transform-origin: var(--notch, 50%) 100%; }
  .uses-note--float[data-side="below"] { transform-origin: var(--notch, 50%) 0; }
  @starting-style {
    .uses-note[data-open] { opacity: 0; }
    .uses-note--float[data-open] { scale: 0.97; }
  }

  /* A card opened in place, under a recap line or a Most used row, opens
     the space it needs rather than shoving the page down at once. */
  .uses-open__reveal { transition: grid-template-rows 240ms cubic-bezier(0.65, 0, 0.35, 1); }
  @starting-style { .uses-open__reveal { grid-template-rows: 0fr; } }

  /* The month fills in, day by day, as a card opens: every square, the
     empty days too (Jason, 2026-11-02), about 30 in under half a second.
     uses.js numbers the squares. */
  .uses-note[data-open] .uses-strip > span { animation: uses-day 160ms var(--ease-out) calc(var(--i, 0) * 9ms) backwards; }

  /* On a tile under the pointer, the wash deepens, as if the brush went
     over it again, and a noted tile's corner lifts a little more. */
  @media (hover: hover) and (pointer: fine) {
    .uses-cell::before { transition: filter 150ms ease; }
    .uses-cell:hover::before { filter: saturate(1.35) contrast(1.04); }
    .uses-cell__fold { transform-origin: 100% 100%; transition: scale 150ms var(--ease-out); }
    .uses-cell:hover .uses-cell__fold { scale: 1.5; }
  }

  /* From one issue to another, each tool that is in both glides from its
     old place to its new one and its paint turns to the new month's; a tool
     in one only fades. A move across the page, so it eases in and out. */
  .uses-cell { view-transition-class: uses-tile; }
  ::view-transition-group(*.uses-tile),
  ::view-transition-old(*.uses-tile),
  ::view-transition-new(*.uses-tile) {
    animation-duration: 420ms;
    animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  }
}
@keyframes uses-day { from { opacity: 0; } }

/* Arrived by the view transition from another issue: the paint is already
   on and the page holds still, so the tiles can glide. Placed last to beat
   the paint-in's wait and bloom. */
:root.uses-arrive [data-uses-table] .uses-cell::before { animation: none; -webkit-mask-image: none; mask-image: none; }
:root.uses-arrive .page-main > * { animation: none; }
