/* ============================================================
   Shared chrome — masthead, rail, table, panel.
   Every page draws from this so the system stays one system.
   ============================================================ */

/* ── Backdrop ─────────────────────────────────────────────────
   Fixed behind everything, heavily knocked back, under a scrim that
   pulls the paper colour back over the top and bottom edges. The art is
   dark, so the light theme takes far less of it than the dark one.
   ───────────────────────────────────────────────────────────── */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--shot);
  background-size: cover;
  background-position: center 30%;
  opacity: 0.09;
}

.backdrop::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, var(--paper) 0%, transparent 22%, transparent 68%, var(--paper) 100%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .backdrop { opacity: 0.3; }
}
:root[data-theme='dark'] .backdrop { opacity: 0.3; }

/* The body must stay transparent or it paints over the backdrop; the
   colour moves to the root instead. */
:root { background: var(--paper); }
body:has(.backdrop) { background: transparent; }

/* ── Picker ──────────────────────────────────────────────────
   Shared by the builder and the compare board. These used to live only
   in builder.html, so compare.html rendered a .picker with no position,
   no size and no z-index — a zero-height element that could never take
   a backdrop click. Define it once.
   ───────────────────────────────────────────────────────────── */

.picker {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s4);
  z-index: 40;
}
.picker.open { display: flex; }
.pick {
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  width: min(660px, 100%);
  max-height: min(74vh, 640px);
  display: flex;
  flex-direction: column;
  border-radius: var(--radius);
}
.pick header { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); border-bottom: 1px solid var(--rule); }
.pick header h2 { font-size: var(--t-md); }
.pick header .n { font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }
.pick header .x { margin-left: auto; background: none; border: 0; color: var(--ink-muted); font-size: var(--t-md); padding: 2px 6px; }
.pick header .x:hover { color: var(--flag); }
.pick .filter { padding: var(--s3) var(--s4) 0; }
.pick .list { overflow-y: auto; padding: var(--s2) var(--s4) var(--s4); }

.opt {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  padding: var(--s2);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  text-align: left;
}
.opt:hover { background: var(--paper-raised); }
.opt .t { flex: 1; min-width: 0; }
.opt .t b { display: block; font-size: var(--t-sm); font-weight: 500; color: var(--ink); }
.opt .t span { font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }
.opt .p { font-family: var(--f-data); font-size: var(--t-sm); color: var(--ink); font-variant-numeric: tabular-nums; }
.opt.clear { color: var(--flag); justify-content: center; border-bottom: 0; }

/* ── Reading surface ──────────────────────────────────────────
   Pages whose content is prose and rows rather than an opaque table
   need something under them, or the type competes with the backdrop.
   One continuous sheet rather than a box per group — this is a ledger,
   and a ledger is a long page, not a stack of cards.
   ───────────────────────────────────────────────────────────── */

.paper {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: var(--s5);
}
.paper > :first-child { margin-top: 0; }
.paper > :last-child { margin-bottom: 0; }

@media (max-width: 720px) {
  .paper { padding: var(--s4); }
}

/* ── Masthead ─────────────────────────────────────────────── */

/* Three tracks so the nav sits on the true centre of the viewport — the
   flanking columns are equal width, so an uneven wordmark and stamp can't
   drag it off centre. */
.masthead {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s4);
  padding: 0 var(--s5);
  height: 52px;
  background: var(--paper-raised);
  border-bottom: 1px solid var(--rule);
}

.wordmark {
  justify-self: start;
  font-family: var(--f-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-transform: uppercase;
  white-space: nowrap;
  text-decoration: none;
}
.wordmark i { font-style: normal; color: var(--ink-muted); font-weight: 400; }

.nav { justify-self: center; display: flex; gap: var(--s5); }
.nav a {
  font-family: var(--f-display);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--ink-muted);
  text-decoration: none;
  padding: 2px 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current] { color: var(--ink); border-bottom-color: var(--money); }

.mastright { justify-self: end; display: flex; align-items: center; gap: var(--s3); min-width: 0; }

.build-stamp {
  font-family: var(--f-data);
  font-size: var(--t-label);
  color: var(--ink-muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* ── Search launcher ──────────────────────────────────────── */

.findbtn {
  display: flex;
  align-items: center;
  gap: var(--s2);
  background: var(--paper-sunk);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 4px 6px 4px 10px;
  color: var(--ink-muted);
  font-family: var(--f-ui);
  font-size: var(--t-xs);
}
.findbtn:hover { border-color: var(--money); color: var(--ink); }
.findbtn kbd {
  font-family: var(--f-data);
  font-size: 10px;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0 4px;
  color: var(--ink-muted);
}

.finder {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 10vh var(--s4) var(--s4);
  z-index: 90;
}
.finder.open { display: flex; }

.findbox {
  width: min(620px, 100%);
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  max-height: 70vh;
}
.findbox #findq {
  font-family: var(--f-ui);
  font-size: var(--t-md);
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: var(--s3) var(--s4);
  outline: none;
}
.findbox #findq::placeholder { color: var(--ink-muted); }

.findlist { overflow-y: auto; padding: var(--s2); }
.findempty { padding: var(--s5); text-align: center; color: var(--ink-muted); font-size: var(--t-xs); margin: 0; }

.findrow {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  padding: var(--s2);
  background: none;
  border: 0;
  border-radius: var(--radius);
  text-align: left;
}
.findrow:hover { background: var(--paper-raised); }
.findrow[aria-selected] { background: var(--money-wash); box-shadow: inset 2px 0 0 var(--money); }
.findrow .t { flex: 1; min-width: 0; }
.findrow .t b { display: block; font-size: var(--t-sm); font-weight: 500; color: var(--ink); }
.findrow .t span { font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }
.findrow .p { font-family: var(--f-data); font-size: var(--t-sm); color: var(--ink); font-variant-numeric: tabular-nums; }

.findfoot {
  border-top: 1px solid var(--rule);
  padding: 6px var(--s4);
  font-size: var(--t-label);
  color: var(--ink-muted);
  display: flex;
  gap: 5px;
  align-items: center;
}
.findfoot kbd {
  font-family: var(--f-data);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0 4px;
}

@media (max-width: 720px) {
  .findbtn .q { display: none; }
  .findbtn kbd { display: none; }
  .findbtn::after { content: '⌕'; font-size: 15px; }
  .finder { padding: 0; }
  .findbox { max-height: 100%; height: 100%; border: 0; border-radius: 0; }
}

/* ── Two-column workbench (rail + content) ────────────────── */

.bench {
  display: grid;
  grid-template-columns: 186px minmax(0, 1fr);
  height: calc(100vh - 52px);
}

.rail {
  border-right: 1px solid var(--rule);
  background: var(--paper-raised);
  overflow-y: auto;
  padding: var(--s4) 0 var(--s6);
}
.rail h2 { padding: 0 var(--s4) var(--s2); }

.railitem {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  width: 100%;
  padding: 7px var(--s4);
  background: none;
  border: 0;
  border-left: 2px solid transparent;
  text-align: left;
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  color: var(--ink-2);
  text-decoration: none;
}
.railitem:hover { background: var(--paper-sunk); color: var(--ink); }
.railitem[aria-pressed='true'] {
  border-left-color: var(--money);
  color: var(--ink);
  font-weight: 600;
  background: var(--paper-sunk);
}
.railitem .n {
  margin-left: auto;
  font-family: var(--f-data);
  font-size: var(--t-label);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.railitem[aria-pressed='true'] .n { color: var(--money); }
.railitem.empty { opacity: 0.45; pointer-events: none; }

/* ── Page body ────────────────────────────────────────────── */

.sheet { overflow-y: auto; padding: var(--s4) var(--s5) var(--s7); }

.sheet-head {
  display: flex;
  align-items: flex-end;
  gap: var(--s4);
  flex-wrap: wrap;
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--rule-strong);
  margin-bottom: var(--s4);
}
.sheet-head h1 { font-size: var(--t-lg); }
.sheet-head .sub { font-size: var(--t-xs); color: var(--ink-muted); margin-top: 2px; }
.sheet-head .tools { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }

/* ── Search ───────────────────────────────────────────────── */

.search {
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  color: var(--ink);
  background: var(--paper-sunk);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 6px 10px;
  width: 190px;
}
.search::placeholder { color: var(--ink-muted); }
.search:focus { border-color: var(--money); outline: none; }

/* ── Data table. The reference view — dense, aligned, scannable ── */

.tablewrap { overflow-x: auto; border: 1px solid var(--rule); background: var(--paper-raised); }

table.data {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--t-sm);
}

table.data thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--paper-sunk);
  border-bottom: 1px solid var(--rule-strong);
  font-family: var(--f-display);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-muted);
  text-align: left;
  padding: 8px var(--s3);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
table.data thead th:hover { color: var(--ink); }
table.data thead th[aria-sort] { color: var(--money); }
table.data thead th.r, table.data td.r { text-align: right; }

table.data tbody td {
  padding: 7px var(--s3);
  border-bottom: 1px solid var(--rule);
  vertical-align: middle;
  color: var(--ink-2);
  white-space: nowrap;
}
table.data tbody tr:hover td { background: var(--paper-sunk); }
table.data tbody tr[data-href] { cursor: pointer; }
table.data tbody tr[data-href]:focus-visible { outline: 2px solid var(--money); outline-offset: -2px; }

table.data th.art-cell, table.data td.art-cell {
  width: 92px;
  padding: 4px var(--s2) 4px var(--s3);
  cursor: default;
}
table.data th.art-cell:hover { color: inherit; }

/* ── Card view ─────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(184px, 1fr));
  gap: var(--s3);
}

.card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  border-radius: var(--radius);
  padding: var(--s2);
  text-align: left;
  color: inherit;
  gap: var(--s2);
}
.card:hover { border-color: var(--money); }
.card:focus-visible { outline: 2px solid var(--money); outline-offset: 2px; }
.card .art { background: var(--paper-sunk); border-color: var(--rule); }

.card .nm {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.25;
  display: flex;
  align-items: baseline;
  gap: var(--s1);
  flex-wrap: wrap;
}
.card .sub {
  font-family: var(--f-data);
  font-size: var(--t-label);
  color: var(--ink-muted);
  line-height: 1.4;
}
.card .foot {
  margin-top: auto;
  padding-top: var(--s2);
  border-top: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2);
}
.card .foot .p {
  font-family: var(--f-data);
  font-size: var(--t-sm);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.card .foot .x { font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }

/* ── View toggle ───────────────────────────────────────────── */

.viewtoggle { display: flex; border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; }
.viewtoggle button {
  background: none;
  border: 0;
  padding: 5px 11px;
  font-family: var(--f-display);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.viewtoggle button + button { border-left: 1px solid var(--rule); }
.viewtoggle button:hover { color: var(--ink); }
.viewtoggle button[aria-pressed='true'] { background: var(--money); color: var(--paper-raised); }

.wiptoggle {
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 5px 10px;
  font-family: var(--f-display);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
}
.wiptoggle:hover { color: var(--ink); border-color: var(--rule-strong); }
.wiptoggle .n { font-family: var(--f-data); opacity: 0.75; }
.wiptoggle[aria-pressed='true'] { color: var(--caution); border-color: var(--caution); }

/* Chunked rendering sentinel */
.moreRow {
  text-align: center;
  padding: var(--s3);
  font-family: var(--f-data);
  font-size: var(--t-label);
  color: var(--ink-muted);
}
.cards .moreRow { grid-column: 1 / -1; }

table.data td.name {
  color: var(--ink);
  font-weight: 500;
  white-space: normal;
  min-width: 190px;
}
table.data td.num {
  font-family: var(--f-data);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
table.data td.dim { color: var(--ink-muted); }
table.data .rowbtn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  width: 100%;
}

/* ── Chips ────────────────────────────────────────────────── */

.chip {
  display: inline-block;
  font-family: var(--f-display);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: var(--radius);
  border: 1px solid var(--rule-strong);
  color: var(--ink-muted);
  white-space: nowrap;
}
.chip.wip { color: var(--caution); border-color: var(--caution); }
.chip.free { color: var(--money); border-color: var(--money); }
.chip.tracer { color: var(--caution); border-color: var(--caution); opacity: 0.85; }
.chip.amb { color: var(--ink-muted); border-style: dashed; }

/* ── Detail panel ─────────────────────────────────────────── */

.panel {
  position: fixed;
  top: 52px;
  right: 0;
  bottom: 0;
  width: 340px;
  background: var(--paper-raised);
  border-left: 1px solid var(--rule-strong);
  overflow-y: auto;
  padding: var(--s4);
  display: none;
}
.panel.open { display: block; }

/* The panel is fixed, so the sheet must yield room or the right-hand
   columns sit underneath it. */
body.panelopen .sheet { padding-right: calc(340px + var(--s5)); }
.panel .close {
  float: right;
  background: none;
  border: 0;
  color: var(--ink-muted);
  font-size: var(--t-md);
  line-height: 1;
  padding: 2px 4px;
}
.panel .close:hover { color: var(--flag); }
.panel h2 { font-size: var(--t-lg); margin-bottom: 2px; }
.panel .kicker { font-size: var(--t-xs); color: var(--ink-muted); margin-bottom: var(--s4); }

.spec {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  padding: 5px 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--t-xs);
}
.spec .k { color: var(--ink-muted); }
.spec .v { font-family: var(--f-data); color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; }

.panel .blurb {
  font-size: var(--t-xs);
  color: var(--ink-2);
  white-space: pre-line;
  margin: var(--s4) 0 0;
  padding: var(--s3);
  background: var(--paper-sunk);
  border-left: 2px solid var(--rule-strong);
  line-height: 1.55;
}

.effect { display: flex; align-items: baseline; gap: var(--s2); font-size: var(--t-xs); padding: 4px 0; }
.effect .dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--money); }
.effect.bad .dot { background: var(--flag); }
.effect .mag { margin-left: auto; font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }

/* ── Item art ─────────────────────────────────────────────────
   Icons are datamined game art. They are deliberately git-ignored and
   served from the CDN, so until they are uploaded every <img> 404s.
   The frame holds its space and falls back to the grid footprint, so a
   missing icon reads as "not yet" rather than as a broken page.
   ───────────────────────────────────────────────────────────── */

.art {
  position: relative;
  display: grid;
  place-items: center;
  background: var(--paper-sunk);
  border: 1px solid var(--rule);
  overflow: hidden;
  flex: none;
}
/* The image is stacked over the fallback and starts transparent rather than
   display:none — a display:none image is never near the viewport, so
   loading="lazy" would never fetch it at all.

   Inset rather than padding: an absolutely positioned child is laid out
   against the parent's padding box, so padding alone would do nothing. The
   inset is what keeps art off the frame edges. */
.art img {
  position: absolute;
  inset: 5px;
  width: calc(100% - 10px);
  height: calc(100% - 10px);
  object-fit: contain;
  opacity: 0;
}
.art.loaded img { opacity: 1; }
.art.loaded .fallback { display: none; }
.art .fallback {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 4px;
}

/* Source art runs from 5.86:1 (rifles) to 0.45:1 (magazines), so frames are
   wide enough that a long weapon still reads at a glance. */
/* Sizes are `sm` / `md` / `lg` — never reuse a component name here. An
   `.art.card` class would also match the `.card` component and inherit its
   flex/border/padding rules. */
.art.sm { width: 92px; height: 50px; }
.art.md { width: 100%; height: 104px; }
.art.md img { inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); }
.art.lg { width: 100%; aspect-ratio: 3 / 2; }
.art.lg img { inset: 14px; width: calc(100% - 28px); height: calc(100% - 28px); }

/* ── Footprint (shared with builder) ──────────────────────── */

.footprint {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  justify-self: start;
}
.footprint span { background: var(--paper-sunk); }

/* ── Item detail: shared by item.html and the items-list modal ── */

/* On the standalone item page the detail is the whole page, so it needs its
   own surface. Inside the items-list modal it already sits on .sheetbox. */
.page .detail {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: var(--s5);
}

.detail .top { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--s5); align-items: start; margin-bottom: var(--s5); }
.detail .identity h1 { font-size: clamp(24px, 3.4vw, 34px); margin-bottom: var(--s2); }
.detail .kicker { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; margin-bottom: var(--s3); }
.detail .flav { font-size: var(--t-md); color: var(--ink-2); max-width: 58ch; margin: 0 0 var(--s4); line-height: 1.55; }

.detail .headline { display: flex; gap: var(--s5); flex-wrap: wrap; padding-top: var(--s3); border-top: 1px solid var(--rule); }
.detail .headline .fig .v {
  font-family: var(--f-data);
  font-size: 27px;
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  display: block;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.detail .headline .fig .v.money { color: var(--money); }
.detail .headline .fig .k { display: block; margin-top: 3px; }

.detail .cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); gap: var(--s5); align-items: start; }
.detail .block h2 { font-size: var(--t-md); padding-bottom: 6px; border-bottom: 1px solid var(--rule-strong); margin-bottom: var(--s2); }

.detail .blurb {
  font-size: var(--t-sm);
  color: var(--ink-2);
  white-space: pre-line;
  padding: var(--s3);
  background: var(--paper-sunk);
  border-left: 2px solid var(--rule-strong);
  line-height: 1.6;
  margin: 0;
}
.detail .fits { display: flex; flex-wrap: wrap; gap: var(--s1); }

.detail .related { margin-top: var(--s6); }
.detail .related h2 { font-size: var(--t-md); padding-bottom: 6px; border-bottom: 1px solid var(--rule-strong); margin-bottom: var(--s3); }
.detail .rel-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: var(--s2); }
.detail .rel {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2);
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  text-decoration: none;
  border-radius: var(--radius);
}
.detail .rel:hover { border-color: var(--money); }
.detail .rel .t { min-width: 0; }
.detail .rel .t b { display: block; font-size: var(--t-sm); font-weight: 500; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail .rel .t span { font-family: var(--f-data); font-size: var(--t-label); color: var(--ink-muted); }

@media (max-width: 720px) {
  .detail .top { grid-template-columns: 1fr; gap: var(--s3); }
  .detail .art.lg { max-width: 220px; }
}

/* ── Modal ─────────────────────────────────────────────────── */

.modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: var(--s5) var(--s4);
  overflow-y: auto;
  z-index: 50;
}
.modal.open { display: flex; }

.sheetbox {
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  width: min(940px, 100%);
  margin: auto;
  position: relative;
}
.sheetbox .bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--s3) var(--s2) var(--s4);
  background: var(--paper-raised);
  border-bottom: 1px solid var(--rule);
}
.sheetbox .bar .crumb { font-size: var(--t-xs); color: var(--ink-muted); }
.sheetbox .bar .spacer { flex: 1; }
.sheetbox .bar a.full {
  font-family: var(--f-display);
  font-size: var(--t-label);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-muted);
  text-decoration: none;
}
.sheetbox .bar a.full:hover { color: var(--money); }
.sheetbox .bar .x { background: none; border: 0; color: var(--ink-muted); font-size: var(--t-md); line-height: 1; padding: 4px 8px; }
.sheetbox .bar .x:hover { color: var(--flag); }
.sheetbox .detail { padding: var(--s5); }

@media (max-width: 720px) {
  .modal { padding: 0; }
  .sheetbox { border: 0; min-height: 100%; }
  .sheetbox .detail { padding: var(--s4); }
}

/* Visually hidden, still read by screen readers and crawlers. Tool pages
   carry no visible page title by design, but every page still needs one h1. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Empty / stub states ──────────────────────────────────── */

.stub {
  max-width: 60ch;
  margin: var(--s7) auto;
  text-align: center;
  padding: 0 var(--s4);
}
.stub h1 { font-size: var(--t-mega); margin-bottom: var(--s3); }
.stub p { font-size: var(--t-md); color: var(--ink-2); margin: 0 0 var(--s3); }
.stub .label { display: block; margin-bottom: var(--s2); }
.stub .lede { color: var(--ink-muted); font-size: var(--t-sm); }

.noresult { padding: var(--s6); text-align: center; color: var(--ink-muted); font-size: var(--t-sm); }

/* ── Responsive ───────────────────────────────────────────── */

/* A centred nav needs both flanking tracks as wide as the widest of them.
   Below this the build stamp no longer fits beside the search launcher, and
   it is the most expendable thing in the bar. */
@media (max-width: 1300px) {
  .build-stamp { display: none; }
}

@media (max-width: 1080px) {
  .bench { grid-template-columns: 160px minmax(0, 1fr); }
  .panel { width: 300px; }
  body.panelopen .sheet { padding-right: calc(300px + var(--s4)); }
}

@media (max-width: 860px) {
  .bench { grid-template-columns: 1fr; height: auto; }
  .rail {
    display: flex;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    padding: var(--s2) var(--s3);
    gap: var(--s1);
  }
  .rail h2 { display: none; }
  .railitem {
    width: auto;
    white-space: nowrap;
    border-left: 0;
    border-bottom: 2px solid transparent;
    padding: 5px var(--s3);
  }
  .railitem[aria-pressed='true'] { border-left: 0; border-bottom-color: var(--money); }
  .panel { top: auto; left: 0; width: 100%; height: 62vh; border-left: 0; border-top: 1px solid var(--rule-strong); }
  body.panelopen .sheet { padding-right: var(--s4); padding-bottom: 64vh; }
}

/* The nav drops to its own row well before phone widths: with six links,
   a wordmark and the search launcher, a centred nav stops fitting on one
   line at about 940px. */
@media (max-width: 940px) {
  .masthead {
    height: auto;
    grid-template-columns: 1fr auto;
    gap: var(--s2) var(--s3);
    padding: var(--s3) var(--s4);
  }
  .nav {
    grid-column: 1 / -1;
    justify-self: stretch;
    width: 100%;
    gap: var(--s4);
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  .nav::-webkit-scrollbar { display: none; }
  .sheet { padding: var(--s4) var(--s4) var(--s6); }
  /* Search takes the slack; the toggle keeps its intrinsic width or its
     labels get clipped by the group's overflow:hidden. */
  .sheet-head .tools { width: 100%; margin-left: 0; flex-wrap: wrap; }
  .search { flex: 1 1 140px; min-width: 0; width: auto; }
  .viewtoggle { flex: none; }
}

/* ── Site footer ──────────────────────────────────────────────────────
   Injected by nav.js on every page that does not size itself to the
   viewport. Quiet by design: it is provenance and a disclaimer, not
   navigation, and it should never compete with the data above it. */
.sitefoot {
  max-width: 1040px;
  margin: var(--s7) auto 0;
  padding: var(--s4) var(--s5) var(--s6);
  border-top: 1px solid var(--rule);
  font-size: var(--t-xs);
  color: var(--ink-muted);
  line-height: 1.6;
}
.sitefoot p { margin: 0 0 4px; max-width: 78ch; }
.sitefoot a { color: var(--ink-muted); }
.sitefoot a:hover { color: var(--money); }
