/* ═══ THE BENCH — the board as one working surface ═════════════════════════════
   The default look, laid over css/style.css and keyed off html[data-look="bench"]
   (js/appearance.js). Every rule here is scoped to that attribute, so RETRO — the
   board as it was, panels, chips and pips — is style.css untouched.

   The idea: each object on the bench IS the information it carries.
     · The composing stick is the groove, and it is a ruler. The measure — the
       length multiplier — is cut along its edge (renderRule in js/render.js),
       so how far a word reaches is read off the scale, and the steel knee
       closes on the word's end.
     · The manuscript sheet is the status: chapter, folio, quota and the words
       of the page on ruled lines, the word pips as the lines' bullets.
     · The proof strip is the readout, above the stick: Points × the measure
       and the paints as stamps = the total, read the way the sum is done. A
       stamp is struck blind while it is ×1 and inked in its colour when it
       applies. What each PATRON adds stays on its own card, in the order the
       seats speak. On a Deadline the editor's slab is the strip's header.
     · The type case is the hand, one socket per place, so a wider hand is more
       sockets. The bag and the hellbox stand either side.
     · The last row is three parts: the workbench at the left in the buttons'
       wood, the three verbs on the board's centre line, Print at the right.
       A sundry is the same gesture as a discard — arm it, then tap the tiles.
     · The sheet stands beside the shelf and the proof row and is ruled to
       their foot, so the desk is retro's column with the page beside it and
       no object ever sits beside a hole.
     · One surface, one red ink. Small capitals from the printed page (IM Fell)
       for labels; Fraunces for numerals and tiles, as before.
     · A lamp: a pool of candlelight over the bench that follows the pointer.
   The rooms tint the bench top; the Deadline still pulls it to ember. The
   tiles, the paints and the trims keep their colours, because they mean
   things. The full-screen sheets — the Market, the alley, the Colophon, the
   book, the rest — are css/bench-sheets.css, scoped the same way. */

html[data-look="bench"] {
  --bn-bench:      #3d2b20;
  --bn-bench-hi:   #4c372a;
  --bn-bench-edge: #241811;
  --bn-paper:      #ede3c9;
  --bn-paper-2:    #dfd2b0;
  --bn-ivory:      #f6efdc;
  --bn-ink:        #221c16;
  --bn-dim:        #6d5c45;
  --bn-rule:       rgba(60, 42, 22, 0.24);
  --bn-red:        #b23a1e;
  --bn-red-dk:     #7d2711;
  --bn-brass:      #cba15a;
  --bn-brass-hi:   #ebc989;
  --bn-steel:      #a3abb3;
  --bn-steel-dk:   #5f6870;
  --bn-cream:      rgba(237, 227, 201, 0.7);

  --bn-fell:    'IM Fell English', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --bn-fell-sc: 'IM Fell English SC', 'IM Fell English', 'Iowan Old Style', Georgia, serif;

  --bn-paper-face:
    repeating-linear-gradient(0deg, rgba(120, 95, 60, 0.05) 0 1px, transparent 1px 3px),
    linear-gradient(170deg, var(--bn-ivory) 0%, var(--bn-paper) 45%, var(--bn-paper-2) 100%);
  --bn-paper-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.5),
    0 1px 2px rgba(0, 0, 0, 0.35),
    0 14px 28px -10px rgba(0, 0, 0, 0.65);

  /* The bench top, in the room's own wood: the game's page tokens, re-pointed. */
  --page-bg:
    radial-gradient(1200px 700px at 50% -10%, rgba(255, 214, 150, 0.10), transparent 60%),
    radial-gradient(900px 500px at 50% 110%, rgba(0, 0, 0, 0.35), transparent 60%),
    repeating-linear-gradient(92deg, rgba(255, 226, 180, 0.035) 0 2px, transparent 2px 9px, rgba(0, 0, 0, 0.06) 9px 11px, transparent 11px 23px),
    linear-gradient(180deg, var(--bn-bench-hi), var(--bn-bench) 40%, #34241a);
  --page-bg-deadline:
    radial-gradient(1200px 700px at 50% -10%, rgba(255, 120, 90, 0.14), transparent 60%),
    radial-gradient(900px 500px at 50% 110%, rgba(0, 0, 0, 0.45), transparent 60%),
    repeating-linear-gradient(92deg, rgba(255, 200, 170, 0.03) 0 2px, transparent 2px 9px, rgba(0, 0, 0, 0.07) 9px 11px, transparent 11px 23px),
    linear-gradient(180deg, #4a2a22, #38201a 40%, #26150f);
  --vignette: inset 0 0 calc(18 * var(--vmu)) rgba(0, 0, 0, 0.5);
  --vignette-deadline:
    inset 0 0 calc(24 * var(--vmu)) rgba(10, 2, 4, 0.7),
    inset 0 0 0 1px rgba(255, 130, 115, 0.12);
}

/* ── The rooms tint the bench top ─────────────────────────────────────────── */
html[data-look="bench"][data-theme="foolscap"] {
  --bn-bench: #8c6a4a; --bn-bench-hi: #a07c58; --bn-bench-edge: #4e3722; --bn-cream: rgba(255, 246, 228, 0.85);
  --page-bg:
    radial-gradient(1200px 700px at 50% -10%, rgba(255, 250, 230, 0.28), transparent 60%),
    repeating-linear-gradient(92deg, rgba(255, 240, 210, 0.05) 0 2px, transparent 2px 9px, rgba(0, 0, 0, 0.05) 9px 11px, transparent 11px 23px),
    linear-gradient(180deg, var(--bn-bench-hi), var(--bn-bench) 40%, #7a5a3e);
}
html[data-look="bench"][data-theme="hellbox"] {
  --bn-bench: #2a1512; --bn-bench-hi: #3a1d18; --bn-bench-edge: #14090a;
  --page-bg:
    radial-gradient(1200px 700px at 50% -10%, rgba(255, 138, 94, 0.14), transparent 60%),
    radial-gradient(900px 500px at 50% 110%, rgba(0, 0, 0, 0.5), transparent 60%),
    repeating-linear-gradient(92deg, rgba(255, 180, 150, 0.03) 0 2px, transparent 2px 9px, rgba(0, 0, 0, 0.08) 9px 11px, transparent 11px 23px),
    linear-gradient(180deg, var(--bn-bench-hi), var(--bn-bench) 40%, #1a0c0a);
}
html[data-look="bench"][data-theme="moonstone"] {
  --bn-bench: #1e2433; --bn-bench-hi: #2a3145; --bn-bench-edge: #0f131e;
  --page-bg:
    radial-gradient(1200px 700px at 50% -10%, rgba(159, 194, 255, 0.10), transparent 60%),
    radial-gradient(900px 500px at 50% 110%, rgba(0, 0, 0, 0.45), transparent 60%),
    repeating-linear-gradient(92deg, rgba(200, 220, 255, 0.03) 0 2px, transparent 2px 9px, rgba(0, 0, 0, 0.07) 9px 11px, transparent 11px 23px),
    linear-gradient(180deg, var(--bn-bench-hi), var(--bn-bench) 40%, #141a28);
}
html[data-look="bench"][data-theme="baize"] {
  --bn-bench: #1f4a36; --bn-bench-hi: #2a5c44; --bn-bench-edge: #10261c;
  --page-bg:
    radial-gradient(1200px 700px at 50% -10%, rgba(255, 240, 200, 0.10), transparent 60%),
    radial-gradient(900px 500px at 50% 110%, rgba(0, 0, 0, 0.45), transparent 60%),
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.02) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, var(--bn-bench-hi), var(--bn-bench) 40%, #163527);
}

/* ── The room itself ──────────────────────────────────────────────────────── */
html[data-look="bench"] body {
  font-family: var(--bn-fell);
  color: var(--bn-paper);
}
/* No watermark: the wood is the ground. Retro's glyph is body::before, so the
   bench hangs its lamp there instead — a pool of candlelight that follows the
   pointer (initLamp in js/appearance.js writes --lx and --ly as viewport
   percentages, which the body's zoom cannot skew). It lies over the board
   (z-index 5) and under the sheets, the FX and the banner (200+), so the
   brass of the stick and the paper catch it and a Market never does.
   Soft-light leaves the wood nearly alone and lifts the bright things. */
html[data-look="bench"] body::before {
  content: '';
  position: fixed; inset: 0;
  right: 0; bottom: 0;
  z-index: 10;
  font-size: 0;
  transform: none;
  pointer-events: none;
  background: radial-gradient(farthest-side circle at var(--lx, 50%) var(--ly, 28%),
    rgba(255, 214, 150, 0.22), rgba(255, 214, 150, 0.07) 45%, transparent 75%);
  mix-blend-mode: soft-light;
}

/* ── The shop sign ────────────────────────────────────────────────────────── */
html[data-look="bench"] header { max-width: 1240px; padding: 12px 22px 4px; }
html[data-look="bench"] .logo {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 27px;
  letter-spacing: 2px;
  color: #f4ead2;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
}
html[data-look="bench"] .coin-purse {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 4px 8px;
  color: var(--bn-brass-hi);
}
html[data-look="bench"] .btn-icon {
  background: rgba(0, 0, 0, 0.22);
  border-color: rgba(255, 230, 190, 0.2);
}

/* ── The desk ─────────────────────────────────────────────────────────────────
   Retro's column, with the manuscript sheet standing beside its top: the
   patrons' shelf across the whole press, then the proof strip, then the
   stick, the case, and the buttons with the workbench at their left, all at
   the desk's full width. The sheet spans the shelf and the proof row and is
   STRETCHED to them — a sheet of paper is ruled to its foot, so the slack
   lives inside the paper as empty lines rather than beside it as a hole in
   the bench. The shelf keeps its whole width whatever the seat count (seven,
   at most), and the stick and the case keep theirs whatever the hand (twelve
   places, at most); the workbench (four slots, at most) leads the button row
   from the desk's left edge, where nothing competes with it for width.

   On a Deadline the editor's slab is the proof strip's header: a row of its
   own only in the grid, joined flush to the strip's top by eating the row
   gap, so the editor reads the proof and the spike strikes the total right
   beneath. On an ordinary page that row is not there at all — an empty auto
   row would still cost a gap — so the areas are switched on the slab's own
   `hidden`, as :has() already makes the shelf room for the graveyard door
   (style.css). Every wrapper is dissolved (display: contents) and each object
   placed by area, so the DOM is retro's, untouched. */
/* The bench centres the board as a flex column with auto margins rather than
   with retro's min-height, so the grid is exactly as tall as what is on it. */
html[data-look="bench"] body { display: flex; flex-direction: column; }
html[data-look="bench"] header { flex: none; width: 100%; }
html[data-look="bench"] .table {
  flex: none;            /* never squeezed to the room's height: a tall board scrolls */
  width: 100%;
  max-width: 1240px;
  min-height: 0;
  margin: auto;
  align-content: start;
  padding: 6px 22px 36px;
  grid-template-columns: minmax(270px, 320px) auto minmax(0, 1fr);
  grid-template-rows: none;
  grid-template-areas:
    "sheet  shelf  shelf"
    "sheet  boss   boss"
    "sheet  proof  proof"
    "stick  stick  stick"
    "case   case   case"
    "action action action"
    "log    log    log";
  gap: 16px 20px;
  align-items: start;
}
html[data-look="bench"] .table:has(.boss-bar.hidden) {
  grid-template-areas:
    "sheet  shelf  shelf"
    "sheet  proof  proof"
    "stick  stick  stick"
    "case   case   case"
    "action action action"
    "log    log    log";
}
html[data-look="bench"] .rail,
html[data-look="bench"] .board,
html[data-look="bench"] .shelf-row   { display: contents; position: static; }
html[data-look="bench"] .status-row  { grid-area: sheet; align-self: stretch; }
html[data-look="bench"] .shelf-wrap  { grid-area: shelf; }
/* The workbench shares the last row with the buttons: a sundry is the same
   gesture as a discard — arm it, then tap the tiles — so the tools and those
   buttons are one family, off the sum above and off the bag → case → hellbox
   line. Where each of them stands is under "The last row, in three parts".

   The tray never outgrows the sheet's column, however many slots the Colophon
   adds: the slots give way to 52px before the tray would, and four of them sit
   inside that width at about 68px each. (The board's bench by id, here and
   below: the Market's is .sundries--market, on a trestle, at its own size.) */
html[data-look="bench"] #sundries {
  width: fit-content;
  max-width: 100%;
  grid-template-columns: repeat(var(--slot-count, 2), minmax(52px, 74px));
}
html[data-look="bench"] .boss-bar    { grid-area: boss; }
html[data-look="bench"] .readout     { grid-area: proof; align-self: stretch; }
html[data-look="bench"] .groove-wrap { grid-area: stick; }
html[data-look="bench"] .rack-row    { grid-area: case; }
html[data-look="bench"] .action-row  { grid-area: action; align-self: center; }
html[data-look="bench"] .log         { grid-area: log; }

/* ── The manuscript sheet: the page you are filling ───────────────────────── */
/* Head, lines, and the quota with the discards beside it at the foot. The lines
   track is the flexible one: the sheet is stretched to the rows beside it, and
   whatever height that gives it beyond its words is more ruled paper. */
html[data-look="bench"] .status-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "head head" "lines lines" "quota pips";
  gap: 0;
  align-items: start;
  padding: 14px 18px 12px;
  color: var(--bn-ink);
  background: var(--bn-paper-face);
  box-shadow: var(--bn-paper-shadow);
  transform: rotate(-0.6deg);
}
html[data-look="bench"] .status-row::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 6px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.08), transparent);
  pointer-events: none;
}
html[data-look="bench"] .status-card {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
  min-width: 0;
}
html[data-look="bench"] .chapter-card {
  grid-area: head;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "label page" "name name";
  align-items: baseline;
  gap: 2px 10px;
  border-bottom: 1px solid var(--bn-ink);
  padding-bottom: 6px;
}
html[data-look="bench"] .chapter-label {
  grid-area: label;
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: 1px;
  text-transform: none;
  color: var(--bn-ink);
}
html[data-look="bench"] .chapter-name {
  grid-area: name;
  font-family: var(--bn-fell);
  font-style: italic;
  font-weight: 400;
  font-size: 14.5px;
  color: var(--bn-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
html[data-look="bench"] .page-label {
  grid-area: page;
  font-family: var(--bn-fell);
  font-style: italic;
  font-weight: 400;
  font-size: 14px;
  color: var(--bn-dim);
  text-align: right;
}
html[data-look="bench"] .page-of { opacity: 1; }
html[data-look="bench"] .deadline-tag {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-style: normal;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: none;
  color: var(--bn-red);
  background: none;
  border: 1px solid var(--bn-red);
  border-radius: 2px;
  padding: 1px 7px;
}

/* The lines: one per word of the page, the pips as their bullets. The rules
   are the box's background at the lines' own pitch, so they run on below the
   last word to the sheet's foot; the lines themselves carry no border. */
html[data-look="bench"] .page-lines {
  --bn-line: 24px;
  grid-area: lines;
  align-self: stretch;
  display: grid;
  align-content: start;
  padding: 2px 0 0;
  /* Two pixels at half strength rather than one at full: the sheet is tilted,
     and a one-pixel rule rasterised at 0.6° steps between pixel rows every
     hundred pixels and reads as dashes. */
  background:
    repeating-linear-gradient(180deg,
      transparent 0 calc(var(--bn-line) - 2px),
      rgba(60, 42, 22, 0.13) calc(var(--bn-line) - 2px) var(--bn-line));
  background-origin: content-box;
  background-clip: content-box;
}
html[data-look="bench"] .page-line {
  position: relative;
  height: var(--bn-line);
  display: flex;
  align-items: flex-end;
  gap: 9px;
  padding-bottom: 4px;
  border: 0;
  font-family: var(--bn-fell-sc);
  font-size: 17px;
  letter-spacing: 1.2px;
  line-height: 1;
  white-space: nowrap;
  min-width: 0;
}
html[data-look="bench"] .page-line .pip { flex: none; margin-bottom: 2px; }
html[data-look="bench"] .page-word {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
html[data-look="bench"] .page-line--bold .page-word { font-weight: 700; }
html[data-look="bench"] .page-score {
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--bn-dim);
  font-variant-numeric: tabular-nums;
}
html[data-look="bench"] .page-line--next::after {
  content: '';
  position: absolute; left: 20px; bottom: 6px;
  width: 8px; height: 14px;
  border-left: 2px solid var(--bn-red);
  opacity: 0.55;
  animation: bnCaret calc(1.2s / var(--aspd)) steps(1) infinite;
}
@keyframes bnCaret { 50% { opacity: 0; } }
html[data-look="bench"] .page-line--fresh .page-word {
  animation: bnInk calc(0.55s / var(--aspd)) cubic-bezier(.2, 1.1, .4, 1) both;
}
@keyframes bnInk {
  0%   { opacity: 0; transform: translateY(4px); filter: blur(1.5px); }
  100% { opacity: 1; transform: none; filter: none; }
}

/* The pips, as ink: a dot still to be spent is filled, a spent one is a ring. */
html[data-look="bench"] .pip {
  width: 10px; height: 10px;
  border: 1.5px solid var(--bn-dim);
  background: transparent;
  box-shadow: none;
}
html[data-look="bench"] .pip--word.pip--on { background: #c9932e; border-color: #8a5f1d; box-shadow: none; }
html[data-look="bench"] .pip--swap.pip--on { background: var(--azure); border-color: #2e5f95; box-shadow: none; }

html[data-look="bench"] .quota-card {
  grid-area: quota;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-content: stretch;    /* retro centres its flex column; a grid would centre its track */
  gap: 4px;
  margin-top: 8px;
}
html[data-look="bench"] .quota-card--deadline { border: 0; }
html[data-look="bench"] .quota-top { align-items: baseline; }
html[data-look="bench"] .quota-word {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: none;
  color: var(--bn-ink);
}
html[data-look="bench"] .quota-nums { font-size: 15px; font-weight: 700; color: var(--bn-ink); }
html[data-look="bench"] .quota-nums b { color: var(--bn-red); }
html[data-look="bench"] .quota-bar {
  height: 6px;
  border-radius: 0;
  background: rgba(255, 255, 255, 0.35);
  border: 1px solid rgba(40, 30, 15, 0.5);
  box-shadow: none;
}
html[data-look="bench"] .quota-fill { border-radius: 0; background: var(--bn-ink); box-shadow: none; }
html[data-look="bench"] .quota-fill--done { background: var(--bn-red); box-shadow: none; }

html[data-look="bench"] .pips-card {
  grid-area: pips;
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-self: end;
  margin: 8px 0 0 14px;
  gap: 0;
}
/* The word pips are on the lines now; only the discards keep their row. */
html[data-look="bench"] .pips-row:has(#wordPips) { display: none; }
html[data-look="bench"] .pips-label {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: 1px;
  text-transform: none;
  color: var(--bn-dim);
}

/* ── The editor's slab ────────────────────────────────────────────────────────
   Everything else on the bench is paper, brass and wood; the editor is a block
   of black ink with a red edge, lit from within. It is the proof strip's
   header: set down flush on the strip's top — the negative margin eats the
   grid's row gap and the extra padding runs on under the slip — its lines
   centred, and it does not tilt, so the slip squares up to meet it. */
html[data-look="bench"] .boss-bar {
  position: relative;
  z-index: 0;
  align-content: center;
  gap: 12px;
  row-gap: 4px;
  margin-bottom: -16px;
  padding: 10px 16px 27px 18px;
  border-radius: 2px 2px 0 0;
  color: #e6d6b8;
  background:
    radial-gradient(120% 140% at 0% 50%, rgba(178, 58, 30, 0.28), transparent 55%),
    radial-gradient(60% 100% at 100% 100%, rgba(120, 20, 10, 0.35), transparent 60%),
    linear-gradient(170deg, #241012 0%, #150809 55%, #0c0405 100%);
  border: 1px solid rgba(178, 58, 30, 0.75);
  border-left: 5px solid var(--bn-red);
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.7),
    inset 0 0 28px rgba(0, 0, 0, 0.6),
    0 1px 0 rgba(255, 120, 90, 0.12),
    0 16px 30px -10px rgba(0, 0, 0, 0.9);
  transform: none;
}
html[data-look="bench"] .boss-bar--warn {
  border-color: #e0553a;
  border-left-color: #e0553a;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.7),
    inset 0 0 28px rgba(178, 58, 30, 0.45),
    0 0 22px rgba(178, 58, 30, 0.4),
    0 16px 30px -10px rgba(0, 0, 0, 0.9);
}
html[data-look="bench"] .boss-emoji {
  font-size: 24px;
  filter: grayscale(0.35) contrast(1.15) drop-shadow(0 0 8px rgba(178, 58, 30, 0.7)) drop-shadow(0 3px 3px rgba(0, 0, 0, 0.8));
}
html[data-look="bench"] .boss-name {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 17px;
  letter-spacing: 2.5px;
  text-transform: none;
  color: #ff7a5c;
  text-shadow: 0 0 10px rgba(178, 58, 30, 0.6), 0 1px 0 #000;
}
html[data-look="bench"] .boss-rule {
  font-family: var(--bn-fell);
  font-size: 14.5px;
  color: #e6d6b8;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.8);
}
html[data-look="bench"] .boss-verdict {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.5px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.45);
}
html[data-look="bench"] .boss-verdict--ok  { color: #9fdcb0; border: 1px solid rgba(159, 220, 176, 0.45); }
html[data-look="bench"] .boss-verdict--bad { color: #ff8f78; border: 1px solid rgba(255, 143, 120, 0.7); background: rgba(120, 20, 10, 0.5); }
html[data-look="bench"] .boss-mark { border-color: rgba(230, 214, 184, 0.25); background: rgba(0, 0, 0, 0.45); }
html[data-look="bench"] .boss-mark--passed { color: #9fdcb0; background: rgba(0, 0, 0, 0.45); border-color: rgba(159, 220, 176, 0.45); }
html[data-look="bench"] .boss-mark--spiked { color: #ff8f78; background: rgba(120, 20, 10, 0.55); border-color: rgba(255, 143, 120, 0.6); }

/* ── The letter rack: calling cards in their slots ────────────────────────── */
html[data-look="bench"] .shelf-row { gap: 10px; }
html[data-look="bench"] .shelf,
html[data-look="bench"] .sundries {
  gap: 10px;
  padding: 10px 10px 12px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  background: linear-gradient(180deg, #2b1d14, var(--bn-bench-edge));
  box-shadow:
    inset 0 3px 10px rgba(0, 0, 0, 0.7),
    inset 0 -1px 0 rgba(255, 220, 170, 0.12),
    0 1px 0 rgba(255, 220, 170, 0.08);
}
/* The tray sits with the buttons, so it is cut from their wood — raised, with
   their lip — and only its slots are recessed. (Beside the shelf on a narrow
   bench it goes back to the shelf's finish, below.) It stands about as tall
   as Print, which is as close to the verbs as a box of tools can come: a slot
   holds a glyph and a name and nothing else now that the ratchet asks for its
   step in a popover rather than on the bench. */
html[data-look="bench"] #sundries {
  padding: 5px 8px 6px;
  border-radius: 3px;
  border: 1px solid rgba(255, 230, 190, 0.18);
  background: linear-gradient(180deg, #5b3f2c, #3d2a1c);
  box-shadow: 0 3px 0 #1d120b, 0 6px 12px rgba(0, 0, 0, 0.45);
}
html[data-look="bench"] #sundries .sundry {
  min-height: 44px;
  gap: 3px;
  padding: 5px 5px 4px;
}
html[data-look="bench"] #sundries .sundry-glyph { font-size: 19px; }
/* The card is a small grid, so everything it says has a cell of its own and
   nothing lies over anything else: the portrait heads the first row, and the
   card's honours — the guild pin, the letters after the name, the laurels —
   sit at that row's far end. Only the take-stamp (a stamp, laid over the
   corner on purpose) and the ✕ stay absolute. Pseudo-elements are grid items
   too, so the pin (.patron::before, retro's absolute enamel) takes a cell. */
html[data-look="bench"] .patron {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-rows: auto auto minmax(0, 1fr);
  grid-template-areas:
    "emoji .    laurel silk"
    "name  name name   name"
    "desc  desc desc   desc";
  align-items: start;
  align-content: start;
  min-height: 108px;
  padding: 8px 8px 7px;
  border-radius: 3px;
  text-align: left;
  gap: 3px 4px;
}
html[data-look="bench"] .patron-emoji { grid-area: emoji; }
html[data-look="bench"] .patron-name  { grid-area: name; }
html[data-look="bench"] .patron-desc  { grid-area: desc; }
/* The guild, in the Market's silk rather than retro's enamel: a ribbon over the
   card's top edge at its right, a shorter second one bound in beside it for a
   dual livery. The strip is the last cell of the honours row, so it reserves
   its own width and the badges settle to its left; the ribbons then overflow
   that cell upward, which is what puts them over the edge without the row (and
   the name under it) growing to their height. They ride the card's tilt, and
   take no pointer: the tap belongs to the card. */
html[data-look="bench"] .patron[class*="patron--g-"]::before { content: none; }
html[data-look="bench"] .patron-liveries {
  grid-area: silk;
  display: flex;
  align-items: flex-start;
  gap: 2px;
  height: 22px;                /* the emoji's row: the silk hangs out of it */
  align-self: start;
  pointer-events: none;
}
html[data-look="bench"] .patron-livery {
  flex: none;
  width: 13px;
  margin-top: -11px;           /* the card's 8px of padding, and 3px past the edge */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 80%, 0 100%);
  box-shadow: 0 2px 3px rgba(60, 40, 15, 0.35);
}
html[data-look="bench"] .patron-livery--first {
  height: 30px;
  background: linear-gradient(175deg, var(--livery-brt) -45%, var(--livery) 60%);
}
html[data-look="bench"] .patron-livery--second {
  height: 24px;
  background: linear-gradient(175deg, var(--livery2-brt) -45%, var(--livery2) 60%);
  order: -1;                   /* the primary silk keeps the outside */
}
/* The seat's name already reads "Dr Assayer, PhD" (patronShelf in js/patrons.js),
   so the gilt tab would only say it twice. The foil and the gilt name still
   mark the seat as lettered, and the ×Mult those letters carry is in the
   popover's tally. Retro keeps the tab: its name is one ellipsised line, which
   a long enough patron truncates before the letters ever show. */
html[data-look="bench"] .patron-postnom { display: none; }
html[data-look="bench"] .patron-laurel {
  grid-area: laurel;
  position: static;
  bottom: auto; right: auto;
  align-self: center;
}
/* The ✕ hangs off the corner past the badges; it only shows on hover. */
html[data-look="bench"] .patron-x { top: -8px; right: -8px; }
html[data-look="bench"] .patron--ubiquitous,
html[data-look="bench"] .patron--common,
html[data-look="bench"] .patron--uncommon,
html[data-look="bench"] .patron--rare {
  background: linear-gradient(170deg, var(--bn-ivory) 0%, var(--bn-paper) 60%, var(--bn-paper-2) 100%);
  color: var(--bn-ink);
  border: 1px solid rgba(138, 95, 29, 0.45);
  box-shadow:
    inset 0 0 0 3px rgba(255, 252, 240, 0.9),
    inset 0 0 0 4px var(--ring),
    0 3px 8px rgba(0, 0, 0, 0.45);
  transform: rotate(-0.8deg);
}
html[data-look="bench"] .shelf .patron:nth-child(even) { transform: rotate(0.7deg); }
html[data-look="bench"] .patron-emoji { font-size: 22px; }
html[data-look="bench"] .patron-name {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.5px;
  line-height: 1.15;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
html[data-look="bench"] .patron-desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-family: var(--bn-fell);
  font-size: 11px;
  line-height: 1.25;
  color: var(--bn-dim);
  text-align: left;
  position: relative;
  z-index: 1;
}
html[data-look="bench"] .patron--empty {
  display: flex;
  border: 0;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.35);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.6);
  color: rgba(237, 227, 201, 0.18);
  align-items: center;
  justify-content: center;
  font-size: 18px;
  transform: none;
}
html[data-look="bench"] .patron--empty::after { content: none; }
/* Armed: the card lifts, and the take is stamped on its corner in ink. */
html[data-look="bench"] .patron--armed {
  animation: none;
  border-color: rgba(138, 95, 29, 0.45);
  transform: translateY(-6px) rotate(-0.8deg);
  box-shadow:
    inset 0 0 0 3px rgba(255, 252, 240, 0.9),
    inset 0 0 0 4px var(--ring),
    0 10px 18px rgba(0, 0, 0, 0.55);
}
html[data-look="bench"] .shelf .patron--armed:nth-child(even) { transform: translateY(-6px) rotate(0.7deg); }
html[data-look="bench"] .patron--armed::after { display: none; }
html[data-look="bench"] .patron--just-armed { animation: bnRise calc(0.42s / var(--aspd)) ease-out; }
@keyframes bnRise {
  0%   { transform: translateY(1px); }
  60%  { transform: translateY(-9px); }
  100% { transform: translateY(-6px); }
}
html[data-look="bench"] .patron-take {
  top: auto; bottom: -8px; left: -8px;
  padding: 2px 7px 3px;
  border-radius: 3px;
  font-family: var(--serif);
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0;
  color: var(--bn-red);
  background: rgba(255, 255, 255, 0.6);
  border: 2px solid currentColor;
  box-shadow: none;
  transform: rotate(-8deg);
  mix-blend-mode: multiply;
}
html[data-look="bench"] .patron--just-armed .patron-take {
  animation: bnStamp calc(0.42s / var(--aspd)) cubic-bezier(0.2, 1.4, 0.4, 1);
}
@keyframes bnStamp {
  0%   { transform: scale(0)    rotate(-22deg); }
  65%  { transform: scale(1.22) rotate(-4deg); }
  100% { transform: scale(1)    rotate(-8deg); }
}
html[data-look="bench"] .patron-take--bump { animation: bnStampBump calc(0.36s / var(--aspd)) ease; }
@keyframes bnStampBump {
  0%   { transform: scale(1)    rotate(-8deg); }
  45%  { transform: scale(1.32) rotate(-8deg); }
  100% { transform: scale(1)    rotate(-8deg); }
}
html[data-look="bench"] .patron-take--points        { color: #2f4f8a; background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--mult          { color: var(--bn-red); background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--coins         { color: #8a5f1d; background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--paint-amber   { color: #a87010; background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--paint-jade    { color: #2d8a5c; background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--paint-crimson { color: #b23a2e; background: rgba(255, 255, 255, 0.6); }
html[data-look="bench"] .patron-take--paint-azure   { color: #2e6fb2; background: rgba(255, 255, 255, 0.6); }

html[data-look="bench"] .sundry--empty {
  border: 0;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.35);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.6);
  color: rgba(237, 227, 201, 0.18);
}
html[data-look="bench"] .sundry--empty::after { display: none; }
html[data-look="bench"] .sundry-name {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  letter-spacing: 0.5px;
  text-transform: none;
}

/* ── The graveyard door: a tab on the shelf's edge ────────────────────────── */
/* The door is not a column here but a tab that slides out from under the
   shelf's right edge when the first ghost turns up, and stays as the handle
   of the drawer. It emerges by its `right` offset, not a transform, so the
   hover nudge and the vertical centring are left alone. */
html[data-look="bench"] .shelf-wrap { display: block; }
html[data-look="bench"] .shelf-clip { z-index: 1; }
html[data-look="bench"] .ghost-btn {
  position: absolute;
  top: 50%;
  right: -18px;
  z-index: 0;
  width: 36px;
  height: 68px;
  padding: 0 0 0 6px;
  gap: 3px;
  border-radius: 0 7px 7px 0;
  border: 1px solid rgba(0, 0, 0, 0.6);
  border-left: 0;
  background: linear-gradient(90deg, #1b2438, #2b3550 55%, #1a2136);
  box-shadow:
    inset 0 1px 0 rgba(170, 200, 245, 0.2),
    inset -2px 0 4px rgba(0, 0, 0, 0.35),
    3px 3px 8px rgba(0, 0, 0, 0.5);
  transform: translate(0, -50%);
  animation: bnNub calc(0.45s / var(--aspd)) cubic-bezier(0.2, 0.9, 0.3, 1.15) both;
}
@keyframes bnNub { from { right: 12px; } to { right: -18px; } }
html[data-look="bench"] .ghost-btn:hover { transform: translate(3px, -50%); }
html[data-look="bench"] .ghost-btn-mark { font-size: 17px; }
html[data-look="bench"] .ghost-btn-count {
  font-family: var(--serif);
  font-size: 11px;
  font-weight: 900;
  color: #c3d3ef;
}
html[data-look="bench"] .ghost-btn--open {
  background: linear-gradient(90deg, #121a2c, #1c2439 55%, #121828);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.65), 3px 3px 8px rgba(0, 0, 0, 0.5);
}
html[data-look="bench"] .ghost-drawer { border-radius: 6px; }
/* The shop's table is the same furniture in a smaller room: its cards are half
   the height of the board's, so the tab and the drawer's cheek come down to
   match, and the tab keeps inside the sheet's own padding rather than hanging
   into its scroll. */
html[data-look="bench"] .shelf-wrap--market > .ghost-btn { right: -20px; width: 32px; height: 54px; }
html[data-look="bench"] .shelf-wrap--market .ghost-drawer-head { max-width: 96px; padding: 6px 10px; }
html[data-look="bench"] .shelf-wrap--market .ghost-drawer-tally { font-size: 15px; }
html[data-look="bench"] .shelf-wrap--market .ghost-drawer-note { display: none; }
@keyframes bnNubMarket { from { right: 10px; } to { right: -20px; } }
html[data-look="bench"] .shelf-wrap--market > .ghost-btn { animation-name: bnNubMarket; }
html[data-look="bench"] .ghost-drawer-title {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 1.5px;
  text-transform: none;
}
html[data-look="bench"] .ghost-drawer-note { font-family: var(--bn-fell); font-style: italic; font-size: 11.5px; }
html[data-look="bench"] .ghost-drawer .shelf { background: none; border: 0; box-shadow: none; }

/* A ghost's card is the parchment's negative — slate under moonlight, light
   ink — in the drawer and in the Market's sheet alike. Retro says so already
   (style.css); the bench's ivory outranks it, hence the repetition. */
html[data-look="bench"] .patron--ghost.patron--ubiquitous,
html[data-look="bench"] .patron--ghost.patron--common,
html[data-look="bench"] .patron--ghost.patron--uncommon,
html[data-look="bench"] .patron--ghost.patron--rare {
  background:
    radial-gradient(125% 80% at 50% -12%, rgba(126, 178, 240, 0.22), transparent 72%),
    linear-gradient(170deg, #1a2338 0%, #0d1322 100%);
  color: #d3e3fb;
  border: 1px dashed rgba(178, 214, 255, 0.5);
  box-shadow:
    inset 0 0 0 2px rgba(150, 195, 250, 0.12),
    inset 0 0 20px rgba(96, 148, 214, 0.22),
    0 4px 16px rgba(0, 0, 0, 0.65),
    0 0 20px rgba(122, 172, 236, 0.25);
}
html[data-look="bench"] .patron--ghost .patron-name { color: #d3e3fb; }
html[data-look="bench"] .patron--ghost .patron-desc { color: #9fb8d8; }
html[data-look="bench"] .patron--ghost.patron--empty {
  background: rgba(0, 0, 0, 0.45);
  color: rgba(180, 205, 240, 0.3);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.7);
}

/* ── The composing stick ──────────────────────────────────────────────────── */
html[data-look="bench"] .groove-wrap {
  display: block;
  position: relative;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--bn-brass-hi) 0%, var(--bn-brass) 12%, #b78a3c 55%, #8f6828 100%);
  box-shadow:
    inset 0 2px 0 rgba(255, 245, 210, 0.55),
    inset 0 -3px 0 rgba(60, 38, 8, 0.55),
    0 12px 22px -8px rgba(0, 0, 0, 0.7);
  overflow: hidden;
}
/* The stick is as deep as the hand could fill it — one course of type on a
   desk, two on a phone — and it is that deep from the first frame, so a word
   never grows it under the player's fingers. Its height is built of the same
   rows the channel is milled around (--word-rows, set in reserveHandHeight),
   never of the raw pixels, so the two can't disagree and leave a course of
   bare brass over the scale. */
html[data-look="bench"] .word-groove {
  --bn-stick-top: 8px;      /* the shoulder above the channel */
  --bn-stick-scale: 40px;   /* the scale cut along the foot (.rule-bar) */
  --bn-stick-gap: 8px;      /* between courses of type */
  --bn-stick-channel: calc(var(--word-rows, 1) * var(--tile-h)
                         + (var(--word-rows, 1) - 1) * var(--bn-stick-gap) + 8px);
  min-height: calc(var(--bn-stick-top) + var(--bn-stick-channel)
                 + var(--bn-stick-scale) + 6px);
  padding: 12px 18px 42px;
  gap: 8px;
  justify-content: flex-start;
  align-content: flex-start;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
html[data-look="bench"] .word-groove:has(.tile) { border: 0; box-shadow: none; }
/* Sorts set to the measure. A word too long for the stick is set in a smaller
   size rather than turned onto a second line (fitWord in js/render.js hands
   down the size and the factor), so the stick stays one course deep. The
   details below are drawn in fixed pixels in css/style.css — the letter at
   30px and its 2/3/4-letter variants, the corner figure at 11px, the nick's
   bite at 9px — so each is taken down by the same factor: a smaller sort, not
   a squashed one. */
html[data-look="bench"] .word-groove .tile {
  width: var(--word-tile-w, var(--tile-w));
  height: var(--word-tile-h, var(--tile-h));
  border-radius: calc(9px * var(--word-fit, 1));
  --nick-r: calc(9px * var(--word-fit, 1));
}
html[data-look="bench"] .word-groove .tile--wide { width: calc(var(--word-tile-w, var(--tile-w)) * 2); }
html[data-look="bench"] .word-groove .tile-letter { font-size: calc(30px * var(--word-fit, 1)); }
html[data-look="bench"] .word-groove .tile-letter[data-len='2'] { font-size: calc(21px * var(--word-fit, 1)); }
html[data-look="bench"] .word-groove .tile-letter[data-len='3'] { font-size: calc(16px * var(--word-fit, 1)); }
html[data-look="bench"] .word-groove .tile-letter[data-len='4'],
html[data-look="bench"] .word-groove .tile-letter[data-len='5'] { font-size: calc(24px * var(--word-fit, 1)); }
html[data-look="bench"] .word-groove .tile-pts {
  font-size: calc(11px * var(--word-fit, 1));
  right: calc(5px * var(--word-fit, 1));
  bottom: calc(4px * var(--word-fit, 1));
}

/* The set line: a channel milled into the stick, the sorts sitting in it. */
html[data-look="bench"] .word-groove::before {
  content: '';
  position: absolute; left: 0; right: 0; top: var(--bn-stick-top);
  height: var(--bn-stick-channel);
  /* A milled line where one course of type ends and the next begins, tiled
     every course from the first sort's head — so a stick deep enough for two
     lines reads as two lines rather than as one slot with brass to spare. A
     stick only one course deep puts its first line past its own foot, where
     there is nothing to draw it on. */
  background:
    linear-gradient(180deg, transparent calc(100% - 1px), rgba(52, 34, 6, 0.4) calc(100% - 1px))
      0 4px / 100% calc(var(--tile-h) + var(--bn-stick-gap)) repeat-y,
    linear-gradient(180deg, #6a4a1a, #8a6528 30%, #7a5820);
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.55), inset 0 -1px 0 rgba(255, 230, 170, 0.25);
  pointer-events: none;
}
html[data-look="bench"] .word-groove[data-placeholder]:not([data-placeholder=''])::after {
  inset: 8px 0 auto 0;
  height: calc(var(--tile-h) + 8px);
  place-items: center start;
  padding-left: 44px;          /* clear of the knee, which rests at the stick's head */
  font-family: var(--bn-fell);
  font-size: 16px;
  color: rgba(255, 240, 210, 0.45);
}
/* The scale, cut by renderRule — a tick per sort, the measure from the sixth. */
html[data-look="bench"] .rule-bar {
  display: block;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 40px;
  pointer-events: none;
}
html[data-look="bench"] .tick {
  position: absolute;
  bottom: 9px;
  width: 1px;
  height: 8px;
  background: rgba(50, 32, 4, 0.5);
}
html[data-look="bench"] .tick--major { width: 2px; height: 13px; }
html[data-look="bench"] .tick--on { background: var(--bn-ink); }
html[data-look="bench"] .tick-label {
  position: absolute;
  bottom: 23px;
  transform: translateX(-50%);
  font-family: var(--serif);
  font-weight: 700;
  font-size: 12px;
  color: var(--bn-red-dk);
  opacity: 0.8;
  white-space: nowrap;
  transition: transform calc(0.2s / var(--aspd)) ease, opacity calc(0.2s / var(--aspd)) ease;
}
html[data-look="bench"] .tick-label.tick--here {
  transform: translateX(-50%) scale(1.35);
  opacity: 1;
  color: var(--bn-red);
  text-shadow: 0 0 6px rgba(255, 245, 210, 0.6);
}
/* The knee: a steel block that closes on the word's end. */
html[data-look="bench"] .knee {
  display: block;
  position: absolute;
  top: 5px;
  width: 18px;
  height: calc(var(--tile-h) + 14px);
  border-radius: 2px;
  background: linear-gradient(90deg, #c8cfd6, var(--bn-steel) 45%, var(--bn-steel-dk));
  box-shadow: 0 0 0 1px rgba(30, 30, 30, 0.6), 2px 3px 8px rgba(0, 0, 0, 0.5);
  transition: left calc(0.22s / var(--aspd)) cubic-bezier(.2, .8, .3, 1);
  pointer-events: none;
  z-index: 2;
}
/* A word wrapped to a second row has no end for the knee to close on. */
html[data-look="bench"] .knee--off { display: none; }
html[data-look="bench"] .knee::after {
  content: '';
  position: absolute; left: 5px; top: 8px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff, #7a828a 70%);
}

/* ── The proof strip ──────────────────────────────────────────────────────────
   Retro's three tracks, on paper: Points at the left, the stamps in the
   middle, the total at the right, read the way the sum is done. It stands
   above the stick beside the workbench, as tall as the row. */
html[data-look="bench"] .readout {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "in chips out";
  height: auto;
  min-height: 84px;
  padding: 8px 18px;
  gap: 12px;
  align-items: center;
  justify-content: stretch;
  border: 0;
  border-radius: 0;
  color: var(--bn-ink);
  background: var(--bn-paper-face);
  box-shadow: var(--bn-paper-shadow);
  transform: rotate(0.4deg);
  opacity: 1;
}
/* With the editor's slab on its top the slip is set square, so the two meet. */
html[data-look="bench"] .table:not(:has(.boss-bar.hidden)) .readout { transform: none; }
html[data-look="bench"] .readout::before {
  /* the clip holding the slip to the bench */
  content: '';
  position: absolute; left: 50%; top: -9px;
  width: 34px; height: 18px;
  margin-left: -17px;
  border: 3px solid var(--bn-steel-dk);
  border-radius: 9px;
  background: linear-gradient(180deg, #d5dbe0, var(--bn-steel));
}
html[data-look="bench"] .table:not(:has(.boss-bar.hidden)) .readout::before { display: none; }
html[data-look="bench"] .readout--idle { opacity: 1; }
html[data-look="bench"] .readout--idle .ro-side,
html[data-look="bench"] .readout--idle .ro-chips { opacity: 0.45; }
html[data-look="bench"] .ro-op {
  display: inline;
  font-family: var(--bn-fell);
  font-size: 22px;
  color: var(--bn-dim);
}
html[data-look="bench"] .ro-side--in {
  grid-area: in;
  justify-content: flex-end;
  align-items: baseline;
  gap: 10px;
}
html[data-look="bench"] .slab {
  flex-direction: row;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
html[data-look="bench"] .slab--points { background: none; }
html[data-look="bench"] .slab-num { font-size: 27px; color: var(--bn-ink); text-shadow: none; }
html[data-look="bench"] .slab-label {
  order: 2;
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: none;
  color: var(--bn-dim);
  opacity: 1;
}
/* The multipliers, as stamps. The measure and the four paints are always on
   the slip — struck blind while they are ×1, the way retro keeps its chips dim,
   so the eye knows what could light — and a track that applies is inked solid
   in its own colour. No labels: the colour is the label. The rarer tracks
   (purple, cursed, a squib, bold, primed) appear only when they have
   something to say, as before. When the print reaches a track its stamp pops
   and the ink blooms — a darker halo under multiply, wet ink spreading into
   the paper and drying back — which is retro's glow in a medium that cannot
   glow. */
html[data-look="bench"] .ro-chips {
  grid-area: chips;
  justify-content: center;
  flex-wrap: wrap;
  gap: 5px 6px;
  min-height: 0;
  padding: 0;
}
html[data-look="bench"] .chip {
  --stamp: var(--bn-ink);
  min-width: 0;
  padding: 2px 8px 3px;
  border-radius: 3px;
  font-family: var(--serif);
  font-weight: 900;
  font-size: 15px;
  opacity: 1;
  color: var(--stamp);
  background: none;
  border: 2px solid var(--stamp);
  box-shadow: none;
  mix-blend-mode: multiply;
  transition: color calc(0.2s / var(--aspd)), background-color calc(0.2s / var(--aspd)),
              border-color calc(0.2s / var(--aspd)), text-shadow calc(0.2s / var(--aspd));
}
/* Blind: the figure pressed into the paper without ink (the same relief as a
   Blind-emboss sort's letter, style.css), the border a faint deboss. */
html[data-look="bench"] .chip:not(.chip--on) {
  color: transparent;
  border-color: rgba(60, 42, 22, 0.16);
  text-shadow: 0 1px 0 rgba(255, 255, 250, 0.9), 0 -1px 1px rgba(86, 82, 64, 0.5);
}
html[data-look="bench"] .chip--purple:not(.chip--on),
html[data-look="bench"] .chip--cursed:not(.chip--on),
html[data-look="bench"] .chip--explosive:not(.chip--on),
html[data-look="bench"] .chip--bold:not(.chip--on),
html[data-look="bench"] .chip--primed:not(.chip--on) { display: none; }
html[data-look="bench"] .chip--length    { --stamp: var(--bn-red-dk); background: none; }
html[data-look="bench"] .chip--crimson   { --stamp: #b23a2e; background: none; }
html[data-look="bench"] .chip--azure     { --stamp: #2e6fb2; background: none; }
html[data-look="bench"] .chip--jade      { --stamp: #2d8a5c; background: none; }
html[data-look="bench"] .chip--amber     { --stamp: #a87010; background: none; }
html[data-look="bench"] .chip--purple    { --stamp: #7040a0; background: none; }
html[data-look="bench"] .chip--cursed    { --stamp: #6d1a15; background: none; }
html[data-look="bench"] .chip--explosive { --stamp: #9a4210; background: none; }
html[data-look="bench"] .chip--bold      { --stamp: var(--bn-ink); background: none; }
html[data-look="bench"] .chip--primed    { --stamp: #2f6357; background: none; }
/* Due: the stamp is set in its colour but not yet struck — the outline is
   there, waiting for the print to reach it. The transition on .chip is what
   inks it, so a counted track fills rather than appears. */
html[data-look="bench"] .chip--on.chip--due {
  color: var(--stamp);
  background: none;
  border-color: var(--stamp);
  text-shadow: none;
}
/* Inked: solid in the track's colour, the figure in paper. */
html[data-look="bench"] .chip--on {
  color: var(--bn-ivory);
  background: var(--stamp);
  border-color: var(--stamp);
  box-shadow: none;
  text-shadow: none;
}
html[data-look="bench"] .chip--pop {
  animation: bnInkBloom calc(0.5s / var(--aspd)) cubic-bezier(.3, 1.5, .5, 1);
}
@keyframes bnInkBloom {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 var(--stamp); }
  40%  { transform: scale(1.32); box-shadow: 0 0 16px 4px var(--stamp); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0 transparent; }
}
html[data-look="bench"] .ro-side--out {
  grid-area: out;
  justify-content: flex-start;
  align-items: baseline;
  gap: 10px;
}
html[data-look="bench"] .ro-total-wrap { min-width: 72px; text-align: right; }
html[data-look="bench"] .ro-total {
  font-size: 40px;
  letter-spacing: -1px;
  color: var(--bn-ink);
  text-shadow: none;
  font-variation-settings: 'opsz' 144;
}
html[data-look="bench"] .ro-total.ro-total--struck { font-size: 22px; color: #9a8a70; text-shadow: none; }

/* ── The type case, the bag and the hellbox ───────────────────────────────── */
html[data-look="bench"] .rack-row {
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
}
/* One socket per place the hand holds (--places, set in renderRack): the
   sockets are a stripe pattern one em wide on the case's content box, so a
   sort sits in its socket and an empty place shows the recess. Its width is
   the hand's, centred in the row; a hand too wide for a phone wraps.

   The width has to be exact, because auto-fill cuts a column only where a
   whole one fits: two pixels short and the last place drops to a second row
   with the space for it still showing. Everything on the page is border-box,
   so the figure must carry the padding AND the border, and the two pixels of
   slack are for the sub-pixel rounding the UI zoom introduces — spare width
   is harmless here, since the columns are fixed and packed from the start. */
html[data-look="bench"] .rack {
  --bn-case-gap: 7px;
  --bn-case-pad: 11px;    /* the case's own side walls */
  --bn-case-pad-y: 10px;  /* the head; the foot takes 2px more, for the lip */
  --bn-slot: calc(var(--tile-w) + var(--bn-case-gap));
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--tile-w));
  grid-auto-rows: calc(var(--tile-h) + 6px);
  justify-content: start;
  align-content: start;
  align-items: center;
  justify-items: center;
  --bn-case-gap-y: 10px;
  gap: var(--bn-case-gap-y) var(--bn-case-gap);
  width: min(100%, calc(var(--places, 10) * var(--bn-slot) - var(--bn-case-gap)
                        + 2 * var(--bn-case-pad) + 2px + 2px));
  justify-self: center;
  /* An empty case still shows its sockets, so the deal has somewhere to land
     and the board doesn't jump as the last sort leaves the hand — and it holds
     every row the hand needs (--rack-rows), not just the one, so playing a
     sort into the stick can't collapse a two-row case to one. */
  min-height: calc(var(--rack-rows, 1) * (var(--tile-h) + 6px)
                 + (var(--rack-rows, 1) - 1) * var(--bn-case-gap-y)
                 + 2 * var(--bn-case-pad-y) + 4px);
  padding: var(--bn-case-pad-y) var(--bn-case-pad) calc(var(--bn-case-pad-y) + 2px);
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.6);
  background-image:
    repeating-linear-gradient(90deg,
      rgba(0, 0, 0, 0.34) 0 calc(var(--tile-w) + 6px),
      transparent calc(var(--tile-w) + 6px) var(--bn-slot)),
    linear-gradient(180deg, #7a5537 0%, #5b3d27 20%, #3e2919 100%);
  background-origin: content-box, border-box;
  background-clip: padding-box, border-box;
  background-position: -3px 0, 0 0;
  background-repeat: repeat-x, no-repeat;
  background-size: auto 100%, auto;
  box-shadow:
    inset 0 2px 0 rgba(255, 220, 170, 0.18),
    inset 0 -6px 12px rgba(0, 0, 0, 0.45),
    0 10px 22px -8px rgba(0, 0, 0, 0.7);
}
html[data-look="bench"] .pouch-label {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: none;
  color: var(--bn-cream);
}
html[data-look="bench"] .pouch-count {
  font-family: var(--serif);
  background: var(--bn-brass);
  color: var(--bn-ink);
  border-color: rgba(60, 40, 8, 0.5);
}

/* ── The press, and the lesser controls ───────────────────────────────────── */
html[data-look="bench"] .btn {
  font-family: var(--bn-fell-sc);
  font-weight: 400;
  font-size: 15px;
  letter-spacing: 1.5px;
  text-transform: none;
  border-radius: 3px;
  padding: 9px 16px 10px;
  color: #ede3c9;
  background: linear-gradient(180deg, #5b3f2c, #3d2a1c);
  border: 1px solid rgba(255, 230, 190, 0.18);
  box-shadow: 0 3px 0 #1d120b, 0 6px 12px rgba(0, 0, 0, 0.45);
}
/* Nobody needs telling what Discard and Shuffle mean, and a shortcut printed
   on every button is four captions of furniture in the one place the eye has
   real work to do. The keys are listed in Settings instead; the buttons keep
   their tooltips. (The one caption that was guidance rather than a shortcut —
   "tap tiles, then confirm" — is already said in the status bar the moment a
   discard is armed: LOG_TEXT.discardArmed in js/text.js.) */
html[data-look="bench"] .btn kbd { display: none; }
html[data-look="bench"] .btn-quiet { background: linear-gradient(180deg, #5b3f2c, #3d2a1c); }
html[data-look="bench"] .btn-discard {
  color: #dbe6f4;
  background: linear-gradient(180deg, #4a5f7a, #2e3d52);
  border-color: rgba(141, 184, 255, 0.3);
  box-shadow: 0 3px 0 #16202e, 0 6px 12px rgba(0, 0, 0, 0.45);
}
html[data-look="bench"] .btn-discard--armed {
  color: #ffe0d6;
  background: linear-gradient(180deg, #8a3a26, #5e2314);
  border-color: rgba(255, 160, 130, 0.35);
  box-shadow: 0 3px 0 #2e0d06, 0 6px 12px rgba(0, 0, 0, 0.45);
}
html[data-look="bench"] .btn-print {
  padding: 13px 34px 14px;
  font-size: 22px;
  letter-spacing: 4px;
  color: #f6efdc;
  background: linear-gradient(180deg, #c8462a 0%, var(--bn-red) 40%, #8d2c14 100%);
  border: 1px solid rgba(60, 10, 0, 0.7);
  box-shadow: 0 5px 0 #4d1608, 0 10px 22px rgba(178, 58, 30, 0.35);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
html[data-look="bench"] .btn-print kbd { color: rgba(255, 230, 210, 0.75); opacity: 1; }
html[data-look="bench"] .btn-print:hover:not(:disabled) { filter: brightness(1.08); box-shadow: 0 5px 0 #4d1608, 0 10px 26px rgba(178, 58, 30, 0.5); }
html[data-look="bench"] .btn-print:active:not(:disabled) { transform: translateY(4px); box-shadow: 0 1px 0 #4d1608; }

html[data-look="bench"] .log {
  font-family: var(--bn-fell);
  font-style: italic;
  color: rgba(237, 227, 201, 0.62);
}

/* ── The last row, in three parts ─────────────────────────────────────────────
   The tray at the desk's left edge, the three verbs on the board's centre line
   — the type case's line, directly above them — and Print holding the right
   edge. All of it belongs to the wide desk: below 880px the row is retro's own
   again, and the tray goes back to the shelf's side, so nothing here needs
   undoing there.

   The row spans the whole desk, which is what puts the verbs on its centre;
   the tray is placed on that row's own grid lines beside them. Two things
   follow from the row being that wide. Its box covers the tray's corner and
   paints later in the DOM, so the tray is lifted into a layer of its own or
   its slots stop taking taps. And Print has to leave the flow to hold the
   right edge — otherwise it counts toward what is being centred and pulls the
   verbs left — which means restating the nudge it makes when pressed, since
   that is a transform too. */
@media (min-width: 881px) {
  /* #sundries, not .sundries: the Market keeps a workbench of its own wearing
     the same class, and the board's grid lines mean nothing to it. */
  html[data-look="bench"] #sundries {
    grid-row: action-start / action-end;
    grid-column: 1 / 2;
    justify-self: start;
    align-self: center;
    position: relative;
    z-index: 1;
  }
  html[data-look="bench"] .action-row    { position: relative; justify-content: center; }
  html[data-look="bench"] .action-spacer { display: none; }
  /* The board's Print, named through the row it belongs to: .btn-print is a
     LOOK, worn by the Market's "Next page", the Chamber's "Begin the run",
     every sheet's confirm. Pinning the class pinned all of them, against
     whatever happened to be positioned near them. .action-row is the board's
     alone. */
  html[data-look="bench"] .action-row .btn-print {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
  }
  html[data-look="bench"] .action-row .btn-print:active:not(:disabled) {
    transform: translateY(calc(-50% + 4px));
  }
}

/* ── Narrow benches ───────────────────────────────────────────────────────── */
/* Beside the sheet on a desk under ~1160px the proof row is narrow and, on a
   Deadline, the editor's demand wraps to three lines: the strip and its stamps
   come in a size so the five stamps keep one line and a 1024×768 window keeps
   the whole desk without a scrollbar. */
@media (min-width: 881px) and (max-width: 1160px) {
  html[data-look="bench"] .table { padding-bottom: 10px; }
  html[data-look="bench"] .readout { min-height: 72px; padding: 6px 12px; gap: 8px; }
  html[data-look="bench"] .ro-chips { gap: 4px; }
  html[data-look="bench"] .chip { padding: 1px 6px 2px; font-size: 13px; }
  html[data-look="bench"] .ro-op { font-size: 18px; }
  html[data-look="bench"] .ro-total { font-size: 34px; }
  html[data-look="bench"] .ro-total-wrap { min-width: 56px; }
  html[data-look="bench"] .boss-bar { padding: 8px 12px 24px 14px; }
  html[data-look="bench"] .boss-rule { font-size: 13px; }
}
@media (max-width: 880px) {
  html[data-look="bench"] .table,
  html[data-look="bench"] .table:has(.boss-bar.hidden) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-template-areas: "shelf" "sheet" "boss" "proof" "stick" "case" "action" "log";
  }
  /* On its own selector: paired with the :has() twin above it would outrank
     the narrower bench's gap below, which is a phone's to set. */
  html[data-look="bench"] .table { gap: 10px; }
  /* One column: the shelf, the door and the bench share a row again, the sheet
     is its own height, and the editor's slab is a bar of its own. */
  html[data-look="bench"] .shelf-row { display: grid; grid-area: shelf; }
  html[data-look="bench"] .shelf-wrap,
  html[data-look="bench"] #sundries { grid-area: auto; align-self: auto; }
  html[data-look="bench"] #sundries {
    justify-self: auto;
    width: auto;
    max-width: none;
    /* Retro's own phone sizing again, which the wide desk's flexible slots
       would otherwise outrank from a higher-specificity selector. */
    grid-template-columns: repeat(var(--slot-count, 2), 52px);
    padding: 10px 10px 12px;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.6);
    background: linear-gradient(180deg, #2b1d14, var(--bn-bench-edge));
    box-shadow:
      inset 0 3px 10px rgba(0, 0, 0, 0.7),
      inset 0 -1px 0 rgba(255, 220, 170, 0.12),
      0 1px 0 rgba(255, 220, 170, 0.08);
  }
  html[data-look="bench"] .status-row { align-self: auto; }
  html[data-look="bench"] .readout { align-self: auto; }
  html[data-look="bench"] .boss-bar { z-index: auto; margin-bottom: 0; border-radius: 2px; }
  /* The tab rides the shelf's own edge, over it rather than out from under
     it, clear of the workbench beside it. */
  html[data-look="bench"] .ghost-btn { right: -6px; width: 30px; height: 60px; z-index: 2; border-radius: 6px; border-left: 1px solid rgba(0, 0, 0, 0.6); }
  @keyframes bnNub { from { right: 12px; } to { right: -6px; } }
  html[data-look="bench"] .status-row { transform: none; padding: 10px 12px 9px; }
  html[data-look="bench"] .page-lines { --bn-line: 24px; }
  html[data-look="bench"] .page-line { font-size: 14px; }
  html[data-look="bench"] .boss-bar { align-self: auto; padding: 8px 12px 9px 14px; }
  html[data-look="bench"] .boss-name { font-size: 14px; letter-spacing: 1.5px; }
  html[data-look="bench"] .patron-laurel { display: none; }
  html[data-look="bench"] .patron-liveries { height: 19px; }
  html[data-look="bench"] .patron-livery { width: 10px; margin-top: -8px; }
  html[data-look="bench"] .patron-livery--first  { height: 24px; }
  html[data-look="bench"] .patron-livery--second { height: 19px; }
  html[data-look="bench"] .patron { min-height: 76px; padding: 5px 4px 4px; gap: 2px; }
  html[data-look="bench"] .patron-emoji { font-size: 19px; }
  html[data-look="bench"] .patron-name { display: block; font-size: 9px; letter-spacing: 0; overflow-wrap: anywhere; }
  html[data-look="bench"] .patron-desc { display: none; }
  html[data-look="bench"] .patron-take { font-size: 10px; padding: 1px 5px 2px; left: -6px; bottom: -7px; }
  html[data-look="bench"] .readout {
    transform: none;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "in chips out";
    align-items: center;
    min-height: 0;
    padding: 8px 12px 10px;
    column-gap: 8px;
  }
  html[data-look="bench"] .readout::before { display: none; }
  html[data-look="bench"] .ro-op { font-size: 18px; }
  html[data-look="bench"] .ro-total { font-size: 30px; }
  html[data-look="bench"] .rack { width: 100%; }
  html[data-look="bench"] .btn-print { font-size: 18px; letter-spacing: 3px; padding: 12px 20px; }
}

@media (max-width: 600px) {
  html[data-look="bench"] header { padding: 6px 12px 0; }
  html[data-look="bench"] .logo { font-size: 19px; letter-spacing: 1px; }
  /* The desk takes the room the phone actually has and spends it BETWEEN its
     rows: centring it left a band of bare bench under the sign and squeezed
     everything below into 6px. A grid can never be pressed below its own
     content, so a short phone still simply scrolls. */
  html[data-look="bench"] .table {
    flex: 1 1 auto;
    margin: 0 auto;
    align-content: space-between;
    padding: 2px 10px calc(8px + env(safe-area-inset-bottom));
    gap: 10px;
  }
  html[data-look="bench"] .chapter-label { font-size: 14px; }
  html[data-look="bench"] .page-lines { --bn-line: 22px; }
  html[data-look="bench"] .page-line { font-size: 13px; }
  html[data-look="bench"] .quota-card { margin-top: 5px; }
  html[data-look="bench"] .shelf, html[data-look="bench"] .sundries { padding: 6px 6px 7px; gap: 5px; }
  html[data-look="bench"] #sundries { grid-template-columns: repeat(var(--slot-count, 2), 40px); }
  html[data-look="bench"] .ghost-btn { right: -4px; width: 24px; height: 52px; padding-left: 3px; }
  html[data-look="bench"] .ghost-btn-mark { font-size: 14px; }
  html[data-look="bench"] .ghost-drawer-head { max-width: 64px; padding: 4px 8px; gap: 1px; }
  html[data-look="bench"] .ghost-drawer-tally { font-size: 15px; }
  html[data-look="bench"] .ghost-drawer-note { display: none; }
  html[data-look="bench"] .patron { min-height: 60px; padding: 4px 3px 3px; }
  html[data-look="bench"] .patron-emoji { font-size: 17px; }
  html[data-look="bench"] .patron-name { font-size: 8px; }
  html[data-look="bench"] .patron-liveries { height: 17px; }
  html[data-look="bench"] .patron-livery { width: 8px; margin-top: -7px; }
  html[data-look="bench"] .patron-livery--first  { height: 20px; }
  html[data-look="bench"] .patron-livery--second { height: 16px; }
  html[data-look="bench"] .word-groove {
    --bn-stick-top: 6px;
    --bn-stick-scale: 36px;
    --bn-stick-gap: 6px;
    min-height: calc(var(--bn-stick-top) + var(--bn-stick-channel)
                   + var(--bn-stick-scale) + 2px);
    padding: 10px 10px 36px;
    gap: 6px;
  }
  html[data-look="bench"] .knee { top: 3px; width: 12px; }
  html[data-look="bench"] .knee::after { left: 3px; width: 6px; height: 6px; }
  html[data-look="bench"] .rule-bar { height: 36px; }
  html[data-look="bench"] .tick-label { font-size: 10.5px; bottom: 20px; }
  html[data-look="bench"] .rack-row { grid-template-columns: 1fr 1fr; gap: 6px; }
  html[data-look="bench"] .rack {
    --bn-case-gap: 5px;
    --bn-case-pad: 8px;
    --bn-case-pad-y: 7px;
    --bn-case-gap-y: 8px;
    grid-column: 1 / -1;
    grid-row: 1;
    gap: var(--bn-case-gap-y) var(--bn-case-gap);
  }
  html[data-look="bench"] .btn { padding: 9px 6px; font-size: 13px; letter-spacing: 1px; }
  html[data-look="bench"] .btn kbd { display: none; }
  /* Print stands at the end of the verbs' row rather than taking a row of its
     own: the stick is two courses deep on a phone, and the press is no use
     under the fold. The spacer between them (retro's) does the pushing. */
  html[data-look="bench"] .action-row { display: flex; gap: 6px; flex-wrap: nowrap; }
  /* Hard right, on its own: retro hides the row's spacer at this width
     (css/style.css), so there is nothing to push Print over with. */
  html[data-look="bench"] .btn-print { grid-column: auto; margin-left: auto; padding: 11px 14px; font-size: 16px; letter-spacing: 2px; }
  html[data-look="bench"] .ro-total { font-size: 26px; }
  html[data-look="bench"] .slab-num { font-size: 19px; }
}

@media (prefers-reduced-motion: reduce) {
  html[data-look="bench"] .page-line--next::after,
  html[data-look="bench"] .page-line--fresh .page-word,
  html[data-look="bench"] .patron--just-armed,
  html[data-look="bench"] .patron--just-armed .patron-take,
  html[data-look="bench"] .patron-take--bump { animation: none; }
  html[data-look="bench"] .knee, html[data-look="bench"] .tick-label { transition: none; }
  html[data-look="bench"] .ghost-btn { animation: none; }
  /* The stamp still pops (retro's chipPop); only the bloom is stilled. */
  html[data-look="bench"] .chip--pop { animation-name: chipPop; }
}
