/* ============ PARKER STUDIOS — "FOR THE RECORD / BIG BILL" system ============ */
/* ============ THE QUIET PASS — APPLIED 2026-08-10 (Seth approved all) =========
   From the 2026-08-10 dual-agent critique. The build before this pass is at
   _archive/pre-quiet-2026-08-10/. The six decisions this file now carries:
     1. Ticket compressed 667px → 533px (book 614px) — the height was padding
        and repetition, not content
     2. PAGE-AWARE STUB: the burst, the pitch and the phone line print on book
        ONLY. The other seven tickets stay byte-identical to each other —
        verify by byte compare of the .b-tkt block, 7 matching + book apart
     3. The colophon is BOARD stock — a printer's imprint; the ticket is the
        only dark object at page end
     4. Undercard plate chassis (a5) — naming and ranking are different jobs;
        full plates cap at two consecutive, low-rank zones whisper
     5. The tear is real: 18px ink gap, torn deckle on the stub, stitching left
        on the body, printed double-keyline on the stub (the §6 beige-seam fix)
     6. Buttons: tomato BOOKS, pine NAVIGATES
   Plus home-scoped air on the .b-name lockup (rule-level; hero markup untouched)
   and the wl-cta cross-sell on the-wall. About's 1440 baseline moves — this is a
   DELIBERATE re-baseline (its ticket changed); new set: _shots-2026-08-10/QUIET-*. */
:root{
  /* Hatch-verified: 2-3 saturated inks on warm WHITE board (CMHOF archive: "black and red on white") */
  --paper:#f6f1e5;         /* poster-board white */
  --paper-2:#efe6cf;       /* second stock */
  --ink:#211c16;--ink-dim:rgba(33,28,22,.68);
  /* --ink-faint is a HAIRLINE token, not a text colour. MEASURED: it composites to
     2.55:1 on --paper and 2.52:1 on --paper-2, both ~1.8x under the 4.5:1 body
     minimum. It is correct for the nav's dashed rule and for underlines; for text
     use --ink-dim (5.53:1 / 5.25:1). Bumping the token itself to .65 would clear
     the text sites but darken every hairline on all 8 pages, so the two text uses
     were moved instead. Audited 2026-08-10. */
  --ink-faint:rgba(33,28,22,.42);
  --rule:rgba(33,28,22,.22);
  --tomato:#d22e1e;        /* hatch show red, full chroma */
  --mustard:#f7b32b;       /* chrome yellow (the Hank Williams board yellow) */
  --pine:#1f4e8c;          /* press navy */
  --overprint:#e96a1b;     /* red-over-yellow transparent-ink orange */
  --night:#181b26;         /* blue-black, not warm black */
  --gold-ink:#a97e28;      /* gold is an ink, not a material */
  --gold-deep:#7c5a15;     /* second flat gold tone (grooves, rings, seals) */
  --platinum-ink:#6e6e74;  /* flat platinum */
  --platinum-deep:#4c4c53; /* second flat platinum tone */
  --tomato-text:#b8281a;   /* show red darkened for small text */
  --slab:"Alfa Slab One",serif;--gothic:"Anton",sans-serif;--western:"Rye",serif;
  --body:"Switzer",sans-serif;--liner:"Libre Caslon Text",serif;
}
*{margin:0;padding:0;box-sizing:border-box}
body{background:var(--paper);color:var(--ink);font-family:var(--body);font-size:1.0625rem;line-height:1.55;
  -webkit-font-smoothing:antialiased}
/* grain lives on the paper only — not the night sections, not a viewport filter */
.frame::before{content:"";position:absolute;inset:0;z-index:6;pointer-events:none;opacity:.2;
  mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.55 0 0 0 0 0.5 0 0 0 0 0.42 0 0 0 .15 0'/%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23n)'/%3E%3C/svg%3E")}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
.caps{font-weight:500;font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-dim)}

/* ---------- sheet + chrome ---------- */
.sheet{padding:22px;max-width:1560px;margin:0 auto}
.frame{border:3px solid var(--ink);outline:1px solid var(--ink);outline-offset:5px;background:var(--paper);
  position:relative;overflow:hidden}
.frame .ht-tr{content:"";position:absolute;right:-70px;top:-70px;width:420px;height:420px;
  background:radial-gradient(circle,var(--ink) 1.3px,transparent 1.6px);background-size:11px 11px;
  opacity:.13;transform:rotate(8deg);-webkit-mask-image:radial-gradient(circle at top right,#000,transparent 68%);
  mask-image:radial-gradient(circle at top right,#000,transparent 68%);
  pointer-events:none}
/* ---- masthead (option C, approved 2026-08-09) ------------------------------
   Seth's real SP monogram, re-inked flat (his logo black measured 14.76:1 on
   board vs --ink 15.00:1 — same black). The live wordmark's geometric grotesk
   is NOT imported; it is a type voice this system does not own, so the wordmark
   is set in Anton and only the DEVICE comes across. Replaces a 52.3px band that
   measured shorter than the nav (56.5px) and the IN PERSON strip (58.8px). */
.bill-top{display:flex;align-items:center;justify-content:space-between;gap:30px;
  border-bottom:3px solid var(--ink);padding:16px 26px 15px;position:relative;z-index:2}
.bill-top .id{display:flex;align-items:center;gap:16px}
/* .mk is the inline vector (ps_mark()); img is the `bill_logo` upload path. */
.bill-top .id img,.bill-top .id .mk{height:52px;width:auto;display:block;flex:none}
.bill-top .id .mk{color:var(--tomato);fill:currentColor;fill-rule:evenodd}
.bill-top .id .stack{display:block;min-width:0}
/* ---- THE WORDMARK — Alfa Slab One, 2026-08-15 -----------------------------
   It was Anton, which §4 of DESIGN-TRUTH assigns to "plates, labels, lists,
   nav, marquee tiers" — i.e. the name wore the same uniform as the sub-line
   under it, the nav an inch below it and every plate on the sheet. The comment
   that used to sit here said the live face "is a type voice this system does
   not own, so the wordmark is set in Anton": a fallback, not a decision.

   ⚠ THE SIZE IS DERIVED, NOT CHOSEN. `.sub` is a fixed string at .75rem/.34em
   and measures 231.2px. The old lockup set the name at 170.5px, so the second
   line overhung the first by 36% and the block had no left-hand silhouette to
   sit against the mark. Alfa Slab "SETH PARKER" measures 190.8px at 24px, and
   231.2/190.8 × 24 = 29.08px = 1.8125rem. Measured after: 230.5 vs 231.2.
   ⚠ Re-measure with a Range if either string changes — getBoundingClientRect()
   on a display:block span returns the BLOCK width, not the text width, which
   is how the 36% overhang went unnoticed for as long as it did.
   ⚠ The 701–900 band retracks `.sub` to .22em (:3981) and so needs its own
   name size; see there. Below 700 `.sub` is hidden and the constraint is the
   room left beside the menu button instead. Specimen + full reasoning:
   mockups-2026-08-08-for-the-record/logo-2026-08-15/. */
.bill-top .id .wm{display:block;font-family:var(--slab);font-size:1.8125rem;letter-spacing:.005em;
  text-transform:uppercase;line-height:1;color:var(--ink);white-space:nowrap}
.bill-top .id .sub{display:block;font-family:var(--gothic);font-size:.75rem;letter-spacing:.34em;
  text-transform:uppercase;color:var(--ink-dim);margin-top:5px;text-indent:.34em}
.bill-top .desk{text-align:right;line-height:1.35}
.bill-top .desk .r1{display:block;font-family:var(--liner);font-style:italic;font-size:1.0625rem;
  color:var(--tomato-text)}
.bill-top .desk .r2{display:block;font-family:var(--gothic);font-size:.8125rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-dim);text-indent:.16em}
nav.stub{display:flex;border-bottom:1px solid var(--ink);position:relative;z-index:2}
/* The anchors gained a wrapper 2026-08-11 so the phone drawer has something to
   collapse. It is a transparent flex pass-through here — desktop is unchanged,
   verified by pixel diff at 1440. The wrapper is also the PORT SEAM: WordPress
   emits `<ul id="primaryNav">` from wp_nav_menu(), so every rule below addresses
   `#primaryNav` and works for a <div> of anchors or a <ul> of <li><a> alike.
   ⚠ Port note: the sub-labels ("the wall", "liner notes") are <small> inside the
   anchor — wp_nav_menu cannot emit that without a custom Walker. */
nav.stub #primaryNav{display:flex;flex:1;min-width:0}
.bill-top .navtoggle{display:none}   /* phone only — see MOBILE HEADER at the tail */
nav.stub a{flex:1;text-align:center;padding:8px 0 7px;font-weight:600;font-size:.8125rem;letter-spacing:.1em;
  text-transform:uppercase;border-right:1px dashed var(--ink-faint)}
nav.stub a small{display:block;font-family:var(--liner);font-style:italic;font-weight:400;font-size:.78125rem;
  letter-spacing:0;text-transform:none;color:var(--ink-dim);margin-top:1px}
nav.stub a:last-child{border-right:none}
/* ⚠ MEASURED 2026-08-12, AND DELIBERATELY LEFT AS IS — Seth's call, after
   seeing the alternative rendered. Do not "fix" this in a later pass.
       main label  --paper on --tomato          4.49:1  (13px/600, needs 4.5)
       sub-label   rgba(paper,.8) on --tomato   3.34:1
   The only passing option is #fff at 5.06:1 for BOTH, because every tint toward
   the ground fails (rgba(#fff,.88) = 4.21) and dropping the cell to
   --tomato-text does not rescue the sub-label either (4.04) while putting a
   second red in the nav, against addendum B's "tomato BOOKS". That fix costs
   the label/sub-label value hierarchy — one ink for both — and Seth judged the
   type relationship worth more than 0.01 and 1.16 of contrast on a chip whose
   meaning is also carried by its position, its ground and its size. */
nav.stub a.book{background:var(--tomato);color:var(--paper)}
nav.stub a.book small{color:rgba(246,241,229,.8)}
nav.stub a.on{background:var(--ink);color:var(--paper);border-right-color:transparent}
nav.stub a.book.on{background:var(--tomato)}
nav.stub a.on small{color:rgba(246,241,229,.75)}

/* ============ THE BAND SYSTEM ============================================
   Promoted 2026-08-10 from the-photographer.html, which is the design truth:
   a sheet is a stack of full-bleed BANDS, never blocks inset in a gutter.
   Three chassis and only three. See DESIGN-TRUTH-2026-08-09.md.
   ------------------------------------------------------------------------ */

/* every zone is a band, closed by a 3px rule */
.bnd{position:relative;z-index:2;border-bottom:3px solid var(--ink)}
.bnd:last-child{border-bottom:none}
.bnd .htc{position:absolute;z-index:0;width:230px;height:110px;pointer-events:none;opacity:.2;
  background:radial-gradient(circle,var(--ink) 1.35px,transparent 1.7px);background-size:10px 10px}
.bnd .htc.tl{left:0;top:0;-webkit-mask-image:linear-gradient(115deg,#000,transparent 78%);
  mask-image:linear-gradient(115deg,#000,transparent 78%)}
.bnd .htc.br{right:0;bottom:0;-webkit-mask-image:linear-gradient(295deg,#000,transparent 78%);
  mask-image:linear-gradient(295deg,#000,transparent 78%)}

/* the reversed strip — a full-width bar of tracked caps */
.b-strip{background:var(--ink);color:var(--paper);text-align:center;padding:14px 20px 12px}
.b-strip span{font-family:var(--gothic);font-size:1.19rem;letter-spacing:.34em;text-transform:uppercase;
  display:inline-block;text-indent:.34em}
.b-strip i{font-style:normal;color:var(--mustard)}

/* (a) PLATE + FIELD — the default chassis for any named section */
.b-plate{display:grid;grid-template-columns:250px 1fr;background:var(--paper)}
.b-plate.alt{background:var(--paper-2)}
/* the plate label is shared by chassis (a), (a2) and .b-brief — one plate,
   never a fork. Any new chassis that wants a named left edge joins this list.
   NOTE 2026-08-10: the-photographer.html still declares a local `.b-adm` copy of
   the (a2) chassis + this plate. Fold it into .b-rows in the gutter sweep — it
   was left alone here rather than change the design-truth page as a side effect
   of the home build. */
/* ⚠ 2026-08-12, REVERSED SAME DAY: was `justify-content:center;padding:24px
   16px` (see the retired note below `.lbl.top`, still here for the history).
   Seth, after seeing it named plainly: he'd had it backwards — every band
   title top-aligns, no exception by height. The ONE named exception is the
   home hero's Starring band (`.b-acts`), which keeps its own separate
   centred rule below (:369) rather than sharing this one, exactly because it
   is the exception and not the rule. */
.b-plate>.lbl,.b-rows>.lbl,.b-brief>.lbl,.b-eng>.lbl{background:var(--ink);color:var(--paper);display:flex;
  flex-direction:column;align-items:center;justify-content:flex-start;gap:5px;padding:30px 16px 24px;
  text-align:center}
.b-plate>.lbl.red,.b-rows>.lbl.red,.b-brief>.lbl.red,.b-eng>.lbl.red{background:var(--tomato)}
/* The shared sub-label is --mustard, which measures 9.21:1 on the INK plate and is
   correct there. On the tomato variant the same colour is 2.76:1. Paper is the best
   the palette offers on tomato at 4.49:1 (ink 3.34, night 3.39, pine 1.64) — a real
   fix from 2.76, though it lands 0.01 under the 4.5 body threshold; clearing it
   outright needs the sub-label at large-text size, which is a design change to the
   plate and therefore Seth's call. Rule-level on purpose: this reaches the instance
   inside the LOCKED home hero without editing hero markup. */
.b-plate>.lbl.red small,.b-rows>.lbl.red small,.b-brief>.lbl.red small,
.b-proof>.lbl.red small{color:var(--paper)}
/* `.b-proof` is on that list because the-photographer.html declares it as a FOURTH
   plate fork (its own `.b-proof .lbl.red` at :129). Without the selector the fix
   missed the design-truth page and its sub-label stayed at 2.76:1 — verified by
   render. "One plate, never a fork: a new chassis JOINS that list, it does not copy
   it" — so the chassis is named here rather than the rule being copied into the page,
   and the design-truth page's markup is not touched. The fork itself is still an open
   debt (audit J6, with `.b-rev` and `.b-cut`). */
/* ⚠ 2026-08-12, TWICE IN ONE DAY. First pass: `.top` retired, every band
   title forced centred regardless of height. Seth, once he saw that named
   plainly, said he'd had it backwards — top-aligned is what he actually
   wants, everywhere except the Starring band. So `.top` stays retired, but
   the direction flipped: the base rule above is top-aligned now, which makes
   `.top` a no-op again — just the OPPOSITE no-op from an hour ago. Left as a
   real (if redundant) rule rather than deleted, so it still matches the base
   if either ever drifts, and a future template that reaches for `.top`
   still gets the top-aligned look it asks for by name. */
.b-plate>.lbl.top,.b-rows>.lbl.top,.b-brief>.lbl.top,.b-eng>.lbl.top{justify-content:flex-start;padding-top:30px}
/* WHEN TWO PLATE BANDS STACK, their plates form one unbroken ink column and the
   band's 3px rule disappears into it. MEASURED on book: the plate column ran a
   flat luminance of 28.6 straight through the boundary, while the same rule read
   at 79 in the field beside it — the two zones looked like one.
   Same failure, same remedy as the index's year spine: a paper hairline
   carries the rule through the spine.
   ⚠ 2026-08-12: was `inset 0 3px 0` on the LOWER plate's `.lbl` (top-inset,
   because CSS cannot select a previous sibling — that part still holds).
   Seth: "the border between the text block for already and the advance sits
   below the border that separates the band boxes." MEASURED why: the real
   3px `.bnd` border sits on the UPPER band's own content edge — visible on
   its paper field, invisible on its ink `.lbl` (ink-on-ink) — while an
   INSET shadow on the lower plate starts 3px INSIDE it, at the lower band's
   own top edge. Upper-band-bottom and lower-band-top are the same
   y-coordinate, but "3px inset from there, going down" lands 3px below
   "3px of real border, ending there." Two different y-ranges reading as one
   stair-stepped seam instead of one line.
   Fixed by drawing the highlight on the UPPER band's `.lbl` instead, as a
   normal (non-inset) shadow offset (0,3px) with no blur — a copy of `.lbl`'s
   own box shifted down 3px, which is exactly where ITS band's real border
   already sits. Selector flips from "the lower band, if the upper one also
   has a .lbl" to "the upper band, if the NEXT one also has a .lbl" — :has()
   reads forward either way, so this is the same rule pointed the other
   direction, not a new mechanism. */
.bnd:has(>.lbl):has(+ .bnd > .lbl) > .lbl{box-shadow:0 3px 0 rgba(246,241,229,.3)}
.b-plate>.lbl b,.b-rows>.lbl b,.b-brief>.lbl b,.b-eng>.lbl b,
.b-plate>.lbl h2,.b-rows>.lbl h2,.b-brief>.lbl h2,.b-eng>.lbl h2{font-family:var(--gothic);font-size:1.75rem;
  line-height:1.04;letter-spacing:.14em;text-transform:uppercase;font-weight:400;text-indent:.14em}
.b-plate>.lbl small,.b-rows>.lbl small,.b-brief>.lbl small,.b-eng>.lbl small{font-family:var(--liner);font-style:italic;
  font-size:.9375rem;color:var(--mustard)}
.b-plate>.field{padding:30px 44px 34px}

/* --- a field's standard furniture. Promoted out of home.html 2026-08-10 so any
   plate band gets it: certified's field was falling back to Switzer, which the
   cohesion sweep flags — Caslon is the human voice, Switzer is body and UI. --- */
.field .aside{font-family:var(--liner);font-style:italic;font-size:1.0625rem;color:var(--ink-dim);
  max-width:52rem}
.field .aside b{font-weight:700;color:var(--ink)}
.field .aside + *{margin-top:22px}
/* a field's closing link, on its own rule */
.field .more{margin-top:18px;border-top:2px solid var(--ink);padding-top:14px;
  font-family:var(--gothic);font-size:1rem;letter-spacing:.1em;text-transform:uppercase}
.field .more a{color:var(--tomato-text)}
/* a pull quote, in a field rather than centred in a column with no left edge */
.field blockquote{font-family:var(--liner);font-style:italic;font-size:1.5rem;line-height:1.45;
  color:var(--ink);max-width:46rem}
.field cite{display:block;margin-top:18px;font-style:normal;font-family:var(--gothic);
  font-size:.9375rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-dim)}

/* (a2) PLATE + CELLS — the same chassis carrying a data row or a tab row.
   Set the cell count inline: style="--n:4" */
.b-rows{display:grid;grid-template-columns:250px repeat(var(--n,4),1fr);background:var(--paper)}
/* ⚠ 2026-08-15 — MEASURED, not eyeballed. At 1440 these cells are grid items
   STRETCHED to the row height the label plate sets (140.5px), but their content
   is only ~117px tall — and every leftover pixel was landing under the type.
   Optical gap above the numeral 23.6px, below the label 48.6px: the band read
   bottom-heavy because it was, by 2x. (At 390 the row is not stretched, so the
   same cells measured 23.6/25.2 and the fault is desktop-only.)
   The cell must STAY stretched — the nth-of-type(even) tint and the 2px ink rule
   both have to run the full row height — so the slack is absorbed by centring the
   CONTENT instead. The 20/18 padding is deliberately kept, not evened up: it is
   the optical correction for the two faces, measured at 3.6px of clipped ascent
   above the Alfa Slab numeral (line-height:1) vs 5.2px of empty descender band
   under the all-caps Anton label. Even padding here would re-introduce the bias
   it was written to cancel. */
.b-rows>.px{position:relative;padding:20px 16px 18px;text-align:center;
  border-right:2px solid var(--ink);
  display:flex;flex-direction:column;justify-content:center}
.b-rows>.px:last-child{border-right:none}
/* even, never odd — keeps the LAST cell on bare board so it can never meet a
   tinted band below on matching stock (paper vs paper-2 is only 1.10:1) */
.b-rows>.px:nth-of-type(even){background:var(--paper-2)}
.b-rows>.px .v{font-family:var(--slab);font-size:2.9rem;line-height:1;color:var(--tomato);
  text-shadow:3px 3px 0 var(--pine)}
.b-rows>.px .k{font-family:var(--gothic);font-size:.875rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-dim);margin-top:9px;display:block;text-indent:.16em}

/* (a2b) TEXT CREDIT CELLS — the same plate+cells chassis carrying WORDS instead
   of numerals (liner-note-single's credits row; the city fact rows will want it
   at port). `.num` opts a single cell back into the numeral voice. */
.b-rows.txt>.px .v{font-family:var(--gothic);font-size:1.31rem;line-height:1.2;color:var(--ink);
  text-shadow:none;letter-spacing:.04em;text-transform:uppercase}
.b-rows.txt>.px .v.num{font-family:var(--slab);font-size:2.9rem;line-height:1;color:var(--tomato);
  text-shadow:3px 3px 0 var(--pine);letter-spacing:0}

/* (a3) THE NAV LINE — RETIRED 2026-08-10, same day it was built. It put a
   category FILTER on the plate chassis, which is the device this system uses to
   name a SECTION (ADMISSION, IN PRINT, ON THE MARQUEE). Stacked under nav.stub
   that made three rows of Anton caps in the first 700px and the filters read as
   a second site nav. Measured: two bands cost 217px before the first frame on
   the-wall, and on on-tour the Crate row sat 1,016px above the grid it filtered.
   Replaced by .b-file (below) and, where the row should carry copy, .b-brief. */

/* (a4) THE FILE LINE — a filter is fine print, not a section. The plate becomes
   a Caslon cue and the tabs drop to the undercard tier (design truth §8): size
   steps down AND the interval compresses, so rank is carried by rhythm too.
   Place it directly on the grid it filters — never above the lede. */
.b-file{background:var(--paper);padding:15px 44px 14px;text-align:center}
.b-file.alt{background:var(--paper-2)}
.b-file .cue{display:block;font-family:var(--liner);font-style:italic;font-size:.9375rem;
  color:var(--ink-dim);margin-bottom:8px}
.b-file .cue b{font-weight:400;color:var(--tomato-text)}
.b-file .t1{font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.05em;text-transform:uppercase;
  line-height:1.5;color:var(--ink);text-wrap:balance}
.b-file .t2{font-family:var(--gothic);font-size:.8125rem;letter-spacing:.11em;text-transform:uppercase;
  line-height:1.6;color:var(--ink-dim);margin:8px auto 0;padding-top:8px;
  border-top:1px solid var(--rule);max-width:54rem}
.b-file a{padding:3px 6px}
.b-file a.on{background:var(--pine);color:var(--paper)}
/* tuned so all eleven collections hold one line at 1440 and break cleanly
   (balanced, never mid-name) below it. Mark up every separator as
   `&nbsp;<span class="st">★</span> ` — the star is the only legal break. */
.b-file .st{color:var(--tomato);font-size:.72em;margin:0 2px;vertical-align:middle}
.b-file .nm{white-space:nowrap}

/* (c) PLATE + SPLIT — chassis (a) and (b) welded: a named left edge, then two
   cells divided by the same 3px of ink furniture. Use it where a row would
   otherwise be pure overhead — it makes the band carry copy as well as controls.
   Cells announce nothing themselves; the plate names the zone (truth §3). */
/* ⚠ THE THIRD TRACK ONLY EXISTS WHEN THERE IS A FACT CARD — 2026-08-12. The
   fixed `250px 1fr 460px` assumed the filing column always printed. It stopped
   printing when the on-tour list was removed from it (Seth: "'this stop' band
   minus the 'on tour column'"), leaving the fact card as its only content — and
   three of the four cities have no fact card, so on those pages a 460px track
   sat empty and the band's INK GROUND showed through it as a slab of bare
   black to the right of the copy. `:has()` sizes the band from what is
   actually in it; without a `.filing` the notes take the rest of the sheet. */
/* ⚠⚠ NO GAP IN THE TWO-COLUMN CASE — 2026-08-12 (Seth: "the right edge of that
   block doesnt align (the dark backgrounds), while the right edge of the whole
   band does align").
   MEASURED on Huntsville: every plate is 250px and every one ENDS at x=275, so
   the plates themselves were never misaligned. What differed was the DARK
   REGION. `.b-plate` has no gap, so its ink plate stops at 275. `.b-brief` is an
   ink-backed grid with a 3px gap, and its plate is ALSO ink — so plate and
   furniture merge into one 253px dark block ending at 278. Three pixels, on two
   bands of the same sheet, and he caught it by eye.
   The gap exists to divide the notes from the filing column (§2b, furniture
   through a gap). With the filing column retired there is nothing left to
   divide, and the ink plate's own edge is the divider — exactly as it is on
   `.b-plate`. So the gap returns only when the third column does. */
/* ⚠ `column-gap:0` IS EXPLICIT, and it has to be: this band is
   `class="bnd b-split b-brief"`, and `.b-split{gap:3px}` (:364) is BOTH the same
   specificity (0,1,0) AND later in the file, so it wins twice over. Declaring
   `column-gap:0` on `.b-brief` alone did nothing — measured, the dark still
   ended at 278. `.b-split.b-brief` is (0,2,0) and is the honest selector anyway:
   the band wears both classes. Second time this pass a same-specificity rule
   quietly won; the first was the ticket ledger's `grid-area` reset. */
.b-brief{background:var(--ink);display:grid;grid-template-columns:250px 1fr}
.b-split.b-brief{column-gap:0}
.b-brief:has(> .filing){grid-template-columns:250px 1fr 460px}
.b-split.b-brief:has(> .filing){column-gap:3px}
.b-brief>*{background:var(--paper);min-width:0}
.b-brief .notes{position:relative;overflow:hidden;padding:28px 40px 30px}
.b-brief .notes p{position:relative;z-index:1;font-family:var(--liner);font-size:1.0625rem;
  line-height:1.52;color:var(--ink-dim);max-width:44rem}
.b-brief .notes p+p{margin-top:13px}
.b-brief .notes p b{color:var(--ink);font-weight:700}
.b-brief .notes .open{font-size:1.19rem;line-height:1.45;color:var(--ink)}
.b-brief .filing{background:var(--paper-2);padding:28px 26px 24px;
  display:flex;flex-direction:column;justify-content:space-between}
/* the established fact-card grid — same rules as .creditbox dl */
.b-brief .facts{display:grid;grid-template-columns:auto 1fr;gap:15px 20px;font-size:.9375rem}
.b-brief .facts dt{color:var(--ink-dim)}   /* was --ink-faint: 2.52:1, failed */
.b-brief .facts dd{font-weight:500;text-align:right}
.b-brief .facts dd i{font-style:normal;color:var(--tomato-text)}
/* the .seal-line idiom, carrying a sibling-page switch. Its label takes the
   Caslon cue voice off .b-file, so the two components read as one system. */
.b-brief .seal{border-top:2px solid var(--ink);margin-top:20px;padding-top:12px;
  font-family:var(--gothic);font-size:.8125rem;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-dim);text-align:center;line-height:1.55}
.b-brief .seal .cue{display:block;font-family:var(--liner);font-style:italic;font-size:.9375rem;
  letter-spacing:0;text-transform:none;color:var(--ink-dim);margin-bottom:6px}
.b-brief .seal a{color:var(--ink);padding:3px 6px}
.b-brief .seal a.on{background:var(--pine);color:var(--paper)}
.b-brief .seal .st{color:var(--tomato);font-size:.72em;margin:0 2px;vertical-align:middle}
.b-brief .seal .nm{white-space:nowrap}
/* LOAD-BEARING, not polish: below ~1340 the fixed filing column starves the
   prose to 27ch (measured at 1180). Stacked it measures 58ch. The filing drops
   under the notes and the plate spans both — the furniture just turns horizontal. */
@media (max-width:1340px){
  .b-brief{grid-template-columns:250px 1fr}
  .b-brief>.lbl{grid-row:1 / span 2}
  .b-brief .notes,.b-brief .filing{grid-column:2}
  .b-brief .filing{padding:22px 30px 20px}
  .b-brief .facts{gap:11px 20px;max-width:34rem}
  .b-brief .seal{margin-top:16px;padding-top:11px}
}

/* (a5) THE UNDERCARD PLATE — QUIET PASS 2026-08-10. The critique's central finding:
   the 250px reversed plate does two jobs, NAMING and RANKING, and can only do
   one. Where 3+ full plates stack (home bands 5-9) every zone shouts at one
   volume and the sheet reads as a ledger, not a bill. On a real bill the
   undercard is smaller black type on the same paper — never a second reversed
   block. So: same 250px left-edge grammar, but the plate is UN-INKED — board
   ground, ink type, divided from its field by 3px of ink furniture showing
   through the gap (truth §2b's mechanism, never a border on one child).
   Rank rule of thumb: full plates cap at two consecutive; a zone that informs
   but doesn't sell (testimonials, the Instagram rack) takes the undercard.
   Colours pre-measured: ink 15.00/13.6:1, --tomato-text 5.55/5.03:1 on
   paper/paper-2.

   ⚠ 2026-08-12: the label column is 247px, not 250. A full ink plate (`.b-plate`)
   needs no gap — the ink-to-paper colour change at x=275 IS the divider. The
   undercard's divider is 3px of ink SHOWN, not implied, so it has to occupy
   real grid track — and a 250px label + 3px gap put the field's left edge at
   278, three measured pixels right of where every plate above and below it
   starts its text. That's the ".field text-block border sits further right"
   Seth flagged on Juried, stacked directly under Already/Advance. 247px keeps
   the gap's RIGHT edge (where the field begins) at x=275, matching the plates;
   the label column's own right edge moves 3px inside a centred, padded box,
   which is not visible. Left-edge grammar — where the column STARTS — is
   unchanged; only the label's own width gave up the 3px the gap needs. */
.b-under{background:var(--ink);display:grid;grid-template-columns:247px 1fr;gap:3px}
.b-under>*{background:var(--paper);min-width:0}
.b-under.alt>*{background:var(--paper-2)}
.b-acts>.lbl{background:var(--paper);color:var(--ink)}
/* ⚠ 2026-08-12, reversed same day — see :149. Shared box model stays shared;
   only vertical placement forks below, because the Starring band (`.b-acts`)
   is the one named exception to "every band title top-aligns." */
.b-under>.lbl,.b-acts>.lbl{display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:20px 16px;text-align:center}
.b-under>.lbl b,.b-under>.lbl h2,.b-acts>.lbl b,.b-acts>.lbl h2{font-family:var(--gothic);font-size:1.125rem;line-height:1.1;letter-spacing:.14em;
  text-transform:uppercase;font-weight:400;color:var(--ink);text-indent:.14em}
.b-under>.lbl small,.b-acts>.lbl small{font-family:var(--liner);font-style:italic;font-size:.875rem;color:var(--tomato-text)}
.b-under>.lbl{justify-content:flex-start;padding-top:26px}
/* ⚠ THE ONE EXCEPTION: the Starring band, on the locked home hero. Seth,
   2026-08-12: "all band titles should be top aligned, except the starring on
   the home hero." Declared last so it wins over `.b-under>.lbl` above at
   equal specificity — `.b-acts` never carries `.b-under` too, but keeping
   this an explicit override (not folded back into the shared rule) keeps the
   exception visible as an exception, not a silent divergence. */
.b-acts>.lbl{justify-content:center}
/* `.top` retired here same as :186 — now a no-op, matches the base again. */
.b-under>.lbl.top{justify-content:flex-start;padding-top:26px}
/* ⚠ THE MEASURE MATCHES THE PLATES ABOVE IT. `.b-under>.field p{max-width:44rem}`
   ended JURIED's copy at x=1026 while the two plates above ran to 1371 — three
   bands in a stack, one of them stopping 345px short on the right. Measured, and
   it is what Seth saw as "they dont align on the right edge". 44rem is a sound
   body measure (~70ch) and it stays for prose that has no neighbour; here the
   band is the last of three and its edge is load-bearing. */
.b-under>.field{padding:24px 44px 28px}
.bnd.b-under + .bnd .field p,
.bnd.b-plate + .bnd.b-under > .field > p{max-width:none}
/* chassis completion (liner-note-single recast): essay prose in an undercard
   field holds a reading measure and paragraph rhythm — 44rem matches
   .b-brief .notes p, ~75ch at body size */
.b-under>.field p{max-width:44rem}
.b-under>.field p+p{margin-top:13px}

/* (b) SPLIT — columns divided by a 3px gap over an ink ground, so the rule is
   the forme's furniture showing between plates. Never a border on one child. */
.b-split{background:var(--ink);display:grid;gap:3px}
.b-split>*{background:var(--paper);min-width:0}

/* (d) THE HEADLINE BAND — the name lockup on paper, centred. Design truth §2
   names this a primitive alongside the reversed strip.
   PROMOTED VERBATIM 2026-08-10 from the-photographer.html, which had declared it
   locally since 2026-08-09. Home was briefly built on a second, near-identical
   copy of this band; that fork is gone. One kicker only, in the human voice.
     .n    the name — misregister via a data-t ::before clone, press navy (§7)
     .and  the Rye line, flanked by fat-and-thin rules (3px over 1px furniture)
     .star an optional third line — the billing, Anton caps over a 2px rule */
.b-name{background:var(--paper);text-align:center;padding:28px 30px 26px;overflow:hidden}
/* The front page's <h1> is the WHOLE lockup — the city AND the role line — so the
   heading carries the full ranking phrase instead of one word. See front-page.php
   for why. This reset exists only so the wrapper contributes nothing: every visible
   value still comes from `.b-name .n` and `.b-name .and`, and both of those are
   class-only selectors, so the geometry is unchanged. About's own lockup keeps
   `<h1 class="n">` and is untouched by this. */
.b-name h1.lock{margin:0;font:inherit;font-weight:400;letter-spacing:inherit}
.b-name .kick{display:flex;align-items:center;justify-content:center;gap:16px;margin-bottom:6px}
.b-name .kick::before,.b-name .kick::after{content:"";width:120px;border-top:2px solid var(--ink)}

/* THE TOMATO SWEEP, 2026-08-10 (Seth). MEASURED: --tomato #d22e1e composites to
   4.49:1 on --paper and 4.07:1 on --paper-2 — under the 4.5:1 body minimum.
   --tomato-text #b8281a measures 5.55:1 / 5.03:1 and exists in the palette for
   exactly this. SCOPE, decided by measurement not by find-and-replace:
     · SMALL TEXT on a board ground -> --tomato-text (the rules below, 23 instances)
     · LARGE display type (>=24px, or >=18.66px bold) -> UNCHANGED. It clears 3:1
       at 4.49 with room, and it is the site's voice: the 145.6px name, the mast
       h1s, the 84px ticket numeral, the .v stat figures.
     · The ~151 decorative ★ separators -> UNCHANGED. They carry no information
       (the names beside them do), and dulling every star would flatten the
       sheet's sparkle for zero accessibility gain.
     · Anything on ink or night stock -> UNCHANGED, different surface, different sum.
     · certified's .mp poster rules -> UNCHANGED. The posters are LOCKED.
   ------------------------------------------------------------------------- */
.b-name .kick span{font-family:var(--liner);font-style:italic;font-size:1.25rem;color:var(--tomato-text)}
/* The name is one unbroken line — a bill never splits it. That made it overflow
   the sheet and put a HORIZONTAL SCROLLBAR on the page: About below ~1268px,
   home below ~1061px. The cap tracks the band's own inner width
   (100vw − 44 sheet − 6 border − 60 padding) divided by the widest name's
   width-per-font-px (7.95, measured on "Seth Parker"), with ~5% headroom.
   min() not clamp() — a floor would reintroduce the overflow on phones.
   9.1rem still wins at every desktop width, so About is pixel-unchanged.
   NOTE for the WP port: this constant assumes a name no wider than
   "Seth Parker". A longer ACF value needs it re-measured. */
.b-name .n{position:relative;display:inline-block;font-family:var(--slab);font-weight:400;
  font-size:min(9.1rem,calc(12vw - 14px));line-height:.92;letter-spacing:.005em;
  text-transform:uppercase;white-space:nowrap}
.b-name .n::before{content:attr(data-t);position:absolute;left:11px;top:12px;color:var(--pine)}
.b-name .n em{position:relative;font-style:normal;color:var(--tomato)}
.b-name .and{display:flex;align-items:center;justify-content:center;gap:20px;margin-top:10px}
.b-name .and::before,.b-name .and::after{content:"";flex:1;max-width:210px;
  border-top:3px solid var(--ink);border-bottom:1px solid var(--ink);height:5px}
.b-name .and span{font-family:var(--western);font-size:2.65rem;line-height:1;text-transform:uppercase;
  color:var(--ink);text-shadow:3px 3px 0 var(--mustard)}
.b-name .star{font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-dim);margin-top:16px;border-top:2px solid var(--ink);padding-top:12px;
  display:inline-block;text-indent:.2em}
.b-name .star i{font-style:normal;color:var(--tomato);margin:0 10px}
/* QUIET PASS 2026-08-10, HOME ONLY — the "compressed execution" pass Seth asked for.
   The concept is locked; the fix is AIR, which is what the reference has and the
   lockup lacked: real Hatch leaves generous un-inked paper around the headliner.
   Scoped by body class so the hero MARKUP is never edited (the R7 mechanism) and
   About's own .b-name — the pixel-diff baseline — is untouched. */
body.pg-home .b-name{padding:48px 30px 42px}
body.pg-home .b-name .kick{margin-bottom:12px}
body.pg-home .b-name .and{margin-top:16px}
body.pg-home .b-name .star{margin-top:22px}

/* ============================================================================
   (a7) THE PHOTOGRAPHER'S OWN BANDS — PROMOTED FROM the-photographer.html
   ============================================================================
   These were declared in that page's inline <style> and nowhere else, which is
   why theme.css only ever carried their RESPONSIVE overrides. The port folds
   them home, exactly as the fork's own comment asked ("when .b-adm/.b-proof/
   .b-cut are folded back into .b-rows/.b-plate/.b-split this block goes away").

   ⚠ WHAT IS *NOT* HERE, ON PURPOSE. .b-adm and .b-proof are NOT redeclared:
   measured against the fork, `.b-rows` (250px + repeat(--n,1fr), the Alfa Slab
   .v numeral, the pine shadow, the even-cell stripe) and `.b-plate` (250px +
   field, the reversed .lbl, .lbl.red) are already byte-equivalent to them. The
   template emits BOTH names — `bnd b-rows b-adm` — so the shared chassis draws
   the band while every existing override, whichever name it was written
   against, still matches. Same for `bnd b-split b-cut`. Only the deltas below
   were genuinely missing. */

/* (a7.1) the reversed strip — a full-width ink bar, tracked caps. Truth §2's
   second primitive; About is its only user so far. */
.b-rev{background:var(--ink);color:var(--paper);text-align:center;padding:14px 20px 12px}
.b-rev span{font-family:var(--gothic);font-size:1.19rem;letter-spacing:.44em;text-transform:uppercase;
  display:inline-block;text-indent:.44em}
.b-rev i{font-style:normal;color:var(--mustard)}

/* (a7.2) THE CUT — the split chassis at About's ratio. .b-split supplies the ink
   ground and the 3px furniture; this is only the column split. */
.b-cut{grid-template-columns:44fr 56fr;align-items:stretch}

/* (a7.3) the one-ink photo cut (truth §5). Levels clip the studio backdrop to
   pure white so multiply drops it into the stock — that is the whole halo fix —
   and a 4px dot screen lies over the plate. The subject is bottom-flush to the
   band rule so it stands rather than floats. */
/* ⚠⚠ MADE UNCONDITIONAL 2026-08-12.        BLOCKER, third and last time
   The `height:100%;width:auto;max-width:none` image below derived its WIDTH
   from a height it did not set — the block's height comes from the sibling text
   column — so the portrait overflowed its own column and `overflow:hidden` ate
   the difference in silence. Measured at 1001px: box 417x934, image 703x934,
   **143px cropped off EACH SIDE, 41% of the portrait.** It tapers to zero only
   at ~1420px, so every 1280 and 1366 laptop saw it.

   The fix already existed TWICE — in the <=700 block and the 701–1000 block —
   and both copies were capped, so above 1000 these base rules returned. Adding
   a third capped range is how this bug survives a fourth audit; the box now
   takes the height of the cut standing in it at EVERY width.

   `justify-content:flex-end` is what keeps §5 intact — the subject stays
   bottom-flush to the band rule "so it stands rather than floats", and any
   surplus height shows as screened paper ABOVE the head, which is the plate.
   Desktop is unchanged to within 2px: at 1440 the cut measured 703x934 before
   and renders 703x932 now. */
.cutblock{position:relative;background:var(--paper);overflow:hidden;min-height:640px;
  display:flex;flex-direction:column;justify-content:flex-end}
.cutblock img{position:static;transform:none;width:100%;height:auto;max-width:100%;display:block;
  margin-top:auto;
  filter:grayscale(1) brightness(1.1) contrast(1.3);mix-blend-mode:multiply}
.cutblock::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  mix-blend-mode:multiply;opacity:.5;
  background:radial-gradient(circle,var(--ink) .8px,transparent 1.05px);background-size:4px 4px}
/* register marks — the plate locked in the forme */
.regmark{position:absolute;z-index:3;width:26px;height:26px;pointer-events:none}
.regmark::before,.regmark::after{content:"";position:absolute;background:var(--ink);opacity:.55}
.regmark::before{left:0;top:12px;width:26px;height:2px}
.regmark::after{left:12px;top:0;width:2px;height:26px}
.regmark.tl{left:14px;top:14px}
.regmark.tr{right:14px;top:14px}

/* (a7.4) the type packed against the cut */
.cut-side{background:var(--paper);padding:46px 48px 42px;display:flex;flex-direction:column;
  justify-content:center}
.cut-side .thesis{font-family:var(--liner);font-style:italic;font-size:2.4rem;line-height:1.16;
  color:var(--tomato);max-width:24rem}
.cut-side .tags{display:flex;flex-wrap:wrap;gap:0 12px;align-items:center;margin:22px 0 24px;
  border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:10px 0}
.cut-side .tags span{font-family:var(--gothic);font-size:1.06rem;letter-spacing:.14em;
  text-transform:uppercase}
.cut-side .tags i{font-style:normal;color:var(--tomato)}
.cut-side .prose{font-family:var(--liner);font-size:1.0625rem;line-height:1.56;color:var(--ink-dim);
  max-width:36rem}
.cut-side .prose p+p{margin-top:12px}
.cut-side .prose b,.cut-side .prose strong{color:var(--ink);font-weight:700}
.cut-side .prose em,.cut-side .prose i{font-style:italic;color:var(--tomato-text)}
.cut-side .sig{margin-top:20px;font-family:var(--gothic);font-size:.9375rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink)}
.cut-side .sig i{font-style:normal;color:var(--tomato-text);margin-right:8px}
.cut-side .sig small{font-family:var(--liner);font-style:italic;font-size:.9375rem;
  letter-spacing:0;text-transform:none;color:var(--ink-dim);margin-left:10px}

/* (a7.7) THE CROSS-SELL BAND — promoted from the-wall.html's inline <style>,
   which is where its base declaration lived; this sheet only ever carried its
   responsive overrides (four of them), so ported without this the band printed
   as unstyled paragraphs on bare paper and the button did not exist.
   Addendum B is the reason for the last line: tomato books, pine navigates, and
   this band sends a reader to the liner notes rather than asking for the sale
   the ticket below it makes better. */
.wl-cta{position:relative;z-index:2;background:var(--paper);
  display:flex;align-items:center;justify-content:space-between;gap:30px;padding:22px 44px}
.wl-cta .big{font-family:var(--gothic);font-size:1.625rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.wl-cta .big i{font-style:normal;color:var(--tomato)}
.wl-cta .sub{font-family:var(--liner);font-style:italic;font-size:1rem;color:var(--ink-dim)}
.wl-cta a{flex:none;font-family:var(--gothic);font-size:1.19rem;letter-spacing:.1em;text-transform:uppercase;
  background:var(--tomato);color:var(--paper);border:3px solid var(--ink);box-shadow:4px 4px 0 var(--ink);
  padding:13px 26px}
.wl-cta a.nav-go{background:var(--pine)}

/* (a7.5) a proof plate's field is CENTRED — the taper is a bill, not a column.
   The .m1–.m4 marquee tiers already live at `.field .fr.*` (R13); only the
   .p1–.p3 print tiers were still page-local, because About is their only user. */
/* ⚠ MEASURED at 768: without this the marquee band's 1fr track was forced to
   536px inside a 718px band, because a grid track is sized by its largest
   min-content contributor and `.nm` is nowrap by law (truth §8). The ≤700 tier
   already carried `min-width:0` for exactly this; the tablet and desktop tiers
   did not, so the blowout only appeared once real names arrived. The tier cap
   keeps the name inside the track; this keeps the track inside the band — both
   are needed, either alone leaves one of the two overflowing. */
.b-plate>*,.b-under>*{min-width:0}
.b-proof>.field{text-align:center;position:relative}
.b-proof>.field .lede{font-family:var(--liner);font-size:1.0625rem;line-height:1.5;
  color:var(--ink-dim);max-width:52rem;margin:0 auto 22px;text-wrap:balance}
.b-proof>.field .lede em{font-style:italic;color:var(--tomato-text)}
/* .fr / .nm / .st already declared with the two-tier taper below — only the
   four-tier tightening and the print tiers are new here. */
.field .fr.m3 .st,.field .fr.m4 .st{margin:0 6px}
/* ⚠ CORRECTED 2026-08-12, and the correction is only half of what it looked
   like. `--cw` is the face's MEASURED width per font-pixel; the ceiling at
   §2594 divides by it, so a --cw that is too LARGE computes a cap that is too
   SMALL and crushes the taper flat.

   THE CASLON TIERS WERE WRONG BY 90%. They declared .58 while the comment four
   lines below §685 records the measurement — "Caslon italic runs 0.304 of its
   font size per character bold and 0.291 plain" — and `.maj`/`.min`, the same
   face doing the same job, have used .31/.30 since August. Measured on About at
   390 before the change: In Print rendered 23 / 23 / 21px, two tiers at one
   size, which DESIGN-TRUTH §8 calls a flat list rather than a bill.

   THE ANTON TIERS ARE LEFT AT .5 ON PURPOSE. Anton measures .478, so .5 is
   conservative by 4.4% — real, but a rounding error rather than a defect, and
   the 4% is headroom against a name whose glyphs run wider than the sample.
   About's marquee plateau (18/14/14/14 at 390) is therefore NOT this bug: it is
   a 37-character client name in a 266px measure, which is a genuine limit and
   is what the phase-4 log said it was. Fixing --cw does not move it and was
   never going to. */
.field .fr.p1,.field .fr.p2{--cw:.31}   /* Libre Caslon italic, bold  — measured .304 */
.field .fr.p3{--cw:.3}                  /* Libre Caslon italic, plain — measured .291 */
.field .fr.m1,.field .fr.m2,.field .fr.m3,.field .fr.m4{--cw:.5}  /* Anton, measured .478 */
.field .fr.p1{font-family:var(--liner);font-style:italic;font-weight:700;--fs:2rem;
  line-height:1.24;color:var(--ink)}
.field .fr.p2{font-family:var(--liner);font-style:italic;font-weight:700;--fs:1.75rem;
  line-height:1.3;color:var(--ink)}
.field .fr.p3{font-family:var(--liner);font-style:italic;--fs:1.31rem;line-height:1.34;
  color:var(--ink-dim)}
/* the footnote under a taper: deliberate fine print, on its own hairline */
.field .fest-note{font-family:var(--liner);font-style:italic;font-size:.9375rem;
  color:var(--ink-dim);margin-top:18px;padding-top:14px;border-top:1px solid var(--rule);
  max-width:38rem;margin-left:auto;margin-right:auto}

/* (a7.6) THE NAME CAP, GENERALISED FOR THE PORT.
   `.b-name .n` shipped as `min(9.1rem, 12vw - 14px)`, and its own comment says
   why that is a problem here: "this constant assumes a name no wider than
   'Seth Parker'. A longer ACF value needs it re-measured." Once the name is a
   field, a longer value puts a horizontal scrollbar on the page — the exact bug
   that constant was added to fix.

   So the constant is now derived instead of typed, from the same measurement it
   came from: "Seth Parker" is 11 characters at a measured 7.95 width-per-font-px,
   i.e. 0.7227 per character, and the band's inner width is 100vw − 110px
   (44 sheet + 6 border + 60 padding), with 5% headroom. page-about.php emits the
   character count as --nvw / --noff. Check: 11 chars resolves to
   11.98vw − 13.2px, which is the shipped 12vw − 14px to within a pixel, and at
   every desktop width both clamp to 9.1rem — so About is unmoved and any name
   now fits. */
.b-name .n{font-size:min(9.1rem,calc(var(--nvw,12) * 1vw - var(--noff,14) * 1px))}
/* Seth 2026-08-10 (direct): the home hero photograph shows at its 3:2 delivery
   ratio, same as the case-study single. The source frame is exactly 1080×720 —
   zero crop. Rule-level: the hero markup stays locked. */
body.pg-home .b-photo img{height:auto;aspect-ratio:3/2}

/* (e) THE PHOTOGRAPH AS A BAND — edge to edge, not a framed card in a gutter.
   A pasted tab tilts (truth §9); the band and the photograph never do. The
   caption is welded to the bottom edge, so it reads as part of the same forme. */
.b-photo{position:relative;overflow:hidden;background:var(--night)}
/* 2026-08-11 — RATIO IS A PROPERTY OF THE ASSET, NOT THE LAYOUT (Seth's call).
   Was a flat height:470px, which at a ~1390px band forced every hero to 2.96:1
   regardless of what was shot. on-tour's hero asset is 768x512 — an exact 3:2 —
   and was being cropped to 2.96. The band now takes --ar from the tile, snapped
   by the CMS to the nearest of 3:2 / 1:1 / 2:3; 3:2 is the fallback because 30 of
   41 assets in the set measure it exactly. */
.b-photo img{width:100%;aspect-ratio:var(--ar,3/2);height:auto;object-fit:cover;
  object-position:center 42%;display:block}

/* THE HERO PAIR, 2026-08-12 (Seth). Two photographs on the §2b split chassis —
   an ink ground showing through a 3px gap, so the divider is the forme's
   furniture rather than a border hung on one child, the same mechanism .b-split
   uses. ⚠ The pair OVERRIDES --ar and crops both slots to one ratio: the single
   hero could rely on picking a landscape asset, but at 686px wide a portrait
   still renders ~915px, so a mixed pair would let one slot set a viewport-tall
   row height. The crop is what makes the pair safe. Measured at 1440: the band
   goes 930px -> 465px and the record bin arrives 460px earlier. */
.b-photo.pair{display:grid;grid-template-columns:1fr 1fr;gap:3px;background:var(--ink)}
.b-photo.pair img{aspect-ratio:3/2}
.b-photo.pair .tab{z-index:4}
.b-photo.pair .cap{grid-column:1 / -1;position:static}

/* THE STARRING BAND — four photographs, each named. The 250px first track is
   the sheet's plate spine (every ink-plate band holds that line); it USED to
   also mirror The Billing's numeral tracks, but that band retired 2026-08-12
   (folded into the hero cap's fine print), so nothing aligns to these tracks
   any more. The in-cell 2px borders and no-gap geometry are kept as shipped —
   changing them buys nothing and re-opens a measured layout. The plate is the
   UNDERCARD (see the .b-under selector list below): full plates cap at two
   consecutive and a row of photographs informs rather than sells. */
/* THE ENGAGEMENTS BAND — one band. See front-page.php for the spine
   measurement that made this a merge rather than two bands.
   ⚠ 2026-08-12: was a two-row plate (`.lbl{grid-row:1/span 2}`) spanning
   itself over `.field` (row 1) and `.eng4` (row 2) — `.field` carried the
   "Same session underneath…" lede. Seth had that text removed, then asked
   for the row itself gone too: "i want the blank space removed," not an
   empty div standing in for it. `.field` is deleted from the markup, so
   there is no row 2 left to span — `.lbl` sits in row 1 beside `.eng4`,
   single row, spine unchanged. `.b-eng>.field` retired with it, below. */
/* ⚠ 2026-08-12, THIRD PASS: `250px` → `247px`. Same bug as the Juried fix
   earlier this session (`.b-under`, :330) — `.b-eng` wasn't in that
   comparison set at the time, so it kept the un-fixed formula. MEASURED:
   On the Bill's content started at 253px (250 label + 3px gap) while What
   Clients Say and Deep Cuts (`.b-under`, already fixed) start at 250px (247
   + 3px) — Seth caught the same 3px drift recurring in a band the first pass
   missed. Identical fix, identical reason: the label gives up 3px of its own
   width so the gap's far edge — where content starts — lands on the same
   250px line every ink-plate band on the sheet already holds. */
/* `.b-eng` / `.eng4` grids RETIRED 2026-08-12 with the runsheet (see below) —
   the shared `.b-eng>.lbl` entries in the plate lists above stay as harmless
   dangling selectors rather than churning six shared rules. */
/* THE RUNSHEET — 2026-08-12 (Seth: "kinda thick… think something like the
   ledger on awards. i dont mind losing the photos"). The certified ledger's
   row grammar (`.lg-row`, further down) applied to the four engagements:
   a hanging marker column and a content column, ruled on the same .16 ink
   hairline, baseline-aligned. The star owns its column — `max-content`, no
   magic number — so a wrapped title indents under ITSELF; the retired card's
   centered bar wrapped at 1440 ("Commercial, Multifamily & Retail", 31ch:
   68px bar against 43px siblings) and saw-toothed the whole band. Band
   chassis is the shared `b-plate alt`, same as the certified ledger and
   alt is load-bearing the same way: What Clients Say below is --paper
   (`.b-under>*`), so this field takes --paper-2 (§6 / addendum F).
   Type is the ledger's: Anton 1.0625/.045em title, .9375 ink-dim body
   (measure-capped at 52rem, the .b-proof lede's cap — a 110ch single line
   at 1440 is past any comfortable measure), Caslon italic tomato-text cue. */
.eng-run{display:grid;grid-template-columns:max-content 1fr;gap:0 18px;
  padding:17px 0 15px;border-top:1px solid rgba(33,28,22,.16);align-items:baseline}
.eng-run:first-child{border-top:none;padding-top:2px}
.eng-run>i{font-style:normal;color:var(--tomato);font-size:1.0625rem}
.eng-run .t{display:block;font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.045em;
  text-transform:uppercase;color:var(--ink);line-height:1.24}
.eng-run p{font-size:.9375rem;color:var(--ink-dim);line-height:1.5;margin:5px 0 0;max-width:52rem}
.eng-run .cue{display:block;font-family:var(--liner);font-style:italic;font-size:.875rem;
  color:var(--tomato-text);margin-top:4px}
.b-acts{background:var(--ink);display:grid;grid-template-columns:250px repeat(4,1fr)}
.b-acts>.shot{background:var(--night);min-width:0;position:relative;
  border-right:2px solid var(--ink)}
.b-acts>.shot:last-child{border-right:none}
/* FLEX COLUMN — 2026-08-12, with the name strips, and the reason is a
   measured 1–2px: the last cell has no border-right, so its content box is
   2px wider and its 3/2 photo 1–2px TALLER than its three siblings
   (189/189/189/190 at 1440). With the photos in normal flow that misaligned
   every bar edge by the same 1–2px — on a sheet where Seth catches 3px by
   eye. The anchor flexes instead: the bar pins to the cell's bottom on every
   cell, and the residual 1–2px disappears into object-fit:cover's crop,
   exactly where height:100% always put it. */
.b-acts>.shot{display:flex;flex-direction:column}
.b-acts>.shot a{display:block;flex:1 1 auto;min-height:0}
.b-acts img{width:100%;height:100%;aspect-ratio:3/2;object-fit:cover;display:block}
/* THE NAME — the retired .b-frames caption-strip grammar (see (f) below)
   applied inside the cell: paper Anton caps on the cell's night ground,
   divided from the photograph by 3px of ink, the band's own furniture colour.
   The cell's existing 2px border compartments the strip at every tier. Fed by
   the attachment's Media Library CAPTION via front-page.php; no caption, no
   bar. Paper on night is 15.23:1 (measured — same as paper on ink). */
.b-acts>.shot .who{display:flex;align-items:center;justify-content:center;text-align:center;
  padding:11px 8px;color:var(--paper);
  background:var(--night);border-top:3px solid var(--ink);
  font-family:var(--gothic);font-size:1rem;letter-spacing:.12em;text-transform:uppercase}
/* THE TWO-DECK WINDOW — 1001–1199 is DERIVED. The 4-up row starts at 1001
   (the 701–1000 tier is 2-up), and at 1200 the longest current name ("OLIVE
   AT PEABODY UNION", 22ch) measured one line; between, it wraps to two decks
   and a mixed row misaligned every photo bottom by 25px (measured 1100/1024:
   bars 50/75/50/75). A two-deck act name is period-correct — the fix is that
   EVERY bar in the window takes the two-deck height (75px measured at 1rem =
   4.69em), names centered, so the row keeps one rule-line whether a name
   wraps or not. ⚠ Captions are Media Library data: a name long enough to run
   THREE decks at 1001px (~32ch+) would re-break this — re-measure, don't pad. */
@media (min-width:1001px) and (max-width:1199px){.b-acts>.shot .who{min-height:4.69em}}
/* Seth's call: "Starring" is short enough to hold the FULL plate size, so it
   matches The Billing's label below it. Measured — "STARRING" sets 133px at
   28px, two pixels narrower than "ALSO STARRING" at the undercard's 18px, in a
   218px measure. The ground stays undercard paper; only the size steps up. */
.b-acts>.lbl b,.b-acts>.lbl h2{font-size:1.75rem;line-height:1.04}
/* the tab sits fully inside the band: at top:-3px the band's overflow clipped a
   ROTATED sticker asymmetrically — the right end cut deeper than the left, which
   reads as a mistake rather than as tucked-under. Pasted, whole, all four edges. */
.b-photo .tab{position:absolute;z-index:3;left:34px;top:18px;background:var(--tomato);color:var(--paper);
  border:2px solid var(--ink);padding:9px 22px;font-family:var(--gothic);font-size:1.06rem;
  letter-spacing:.12em;text-transform:uppercase;transform:rotate(-2.4deg);
  box-shadow:4px 4px 0 rgba(0,0,0,.4)}
.b-photo .cap{position:absolute;z-index:3;left:0;right:0;bottom:0;background:var(--ink);
  color:var(--paper);display:flex;flex-wrap:wrap;justify-content:center;gap:11px 20px;align-items:baseline;
  padding:11px 16px;font-family:var(--gothic);font-size:1.06rem;letter-spacing:.14em;
  text-transform:uppercase}
.b-photo .cap i{font-style:normal;color:var(--tomato)}
.b-photo .cap .y{color:var(--mustard)}
/* THE FINE PRINT — 2026-08-12, the Billing folded into the cap (Seth's Option
   A: trust seen in the first viewport, at a promoter's-credentials volume
   instead of a full stats band). Only front-page.php emits `.fine`, so the
   single-line caps on the singles/city sheets are untouched (flex-wrap above
   is inert on one line). The hairline is paper at .3 — the same on-ink
   hairline the stacked-plate rule (:210) already draws. Numerals sit in <b>
   at WEIGHT 400: Anton ships one weight and a UA-bold <b> smears the outline
   (synthetic bold — see the type laws). Stars inherit the cap's tomato; they
   are decorative and carry no information. The stars print ONLY while the
   deck holds one line — once it wraps, a separator can land at a row edge and
   read as a typo, so below the wrap point the wrap itself does the separating. */
.b-photo .cap .fine{flex-basis:100%;display:flex;flex-wrap:wrap;justify-content:center;
  align-items:baseline;column-gap:16px;row-gap:5px;padding-top:9px;
  border-top:1px solid rgba(246,241,229,.3);font-size:.8125rem;letter-spacing:.18em}
.b-photo .cap .fine b{font-weight:400;color:var(--mustard)}
.b-photo .cap .fine i{font-size:.6875rem}
/* 1074 is DERIVED, not round (see the derived-breakpoints convention):
   measured at 1440 the deck's children run 896px, + 6 column-gaps at 16px
   (96) + the cap's 16px side paddings (32) + frame borders and sheet padding
   (~50) ≈ 1074 — confirmed live: one line at 1100, two at 1024. ⚠ The labels
   are Site Settings → Stats, field-editable: if Seth re-words them this
   number moves and must be RE-MEASURED, not kept. */
@media (max-width:1074px){.b-photo .cap .fine i{display:none}}

/* (f) N FRAMES AS A BAND — the ink ground shows as 3px furniture between them
   and one reversed caption strip is compartmented by paper hairlines, instead
   of N free-standing cards with cast shadows floating in a gutter.
   Set the count inline: style="--n:4" */
.b-frames{background:var(--ink)}
.b-frames .shots{display:grid;grid-template-columns:repeat(var(--n,4),1fr);gap:3px}
/* 2026-08-11: the frame strip is a FIXED WINDOW, so its ratio belongs to the
   layout, not to each asset — the compartmented caption row below must stay
   column-aligned with the shots, which rules out the justified-flex mechanism
   .gp/.pgp use. So it declares ONE canonical ratio instead of an arbitrary
   height: 230px at a ~461px column was rendering 2:1, a ratio in no system.
   3:2 now, which also retires liner-note-single's inline override of this rule. */
.b-frames .shots img{width:100%;aspect-ratio:3/2;height:auto;object-fit:cover;display:block}
.b-frames .caps{display:grid;grid-template-columns:repeat(var(--n,4),1fr);margin-top:3px}
.b-frames .caps span{text-align:center;padding:11px 8px;color:var(--paper);
  font-family:var(--gothic);font-size:1rem;letter-spacing:.12em;text-transform:uppercase;
  border-right:2px solid rgba(246,241,229,.55)}
.b-frames .caps span:last-child{border-right:none}

/* (g) THE INDEX — a list where every entry is a BAND, not a card. Seth:
   "case studies should be basically a list of the case studies (a well designed
   list, whether thats like larger versions of posters or something)."
   .cshead tops the bill at double height, the way a festival poster ranks its
   acts; .csrow carries the rest. Approved as kit §02, "the bill".
   The FRAME IS A SUPPORTING CELL, not the subject — only 5 of 12 case studies
   have a real photograph, so the design must not lean on one. */
/* 2026-08-11 — the index thumbnail was the suite's worst crop: a 360px column
   against a ~153px row rendered every one of the 12 at 2.387:1, including a
   768x1229 portrait that lost ~74% of the frame. A fixed grid column cannot take
   a per-asset ratio (one width serves all 12 rows), so the WINDOW declares the
   canonical instead: 230px against the 153px row = 1.503, a true 3:2 frame.
   The 130px it gives back goes to the bill column, which also pushes the known
   credits wrap below ~860px further down. */
.csrow{display:grid;grid-template-columns:132px 1fr 230px;background:var(--paper);align-items:stretch}
.csrow.alt{background:var(--paper-2)}
/* the year plates stack into one continuous ink column, so the band's own rule
   would vanish between them (rule 6 — same stock across a seam). An inset paper
   hairline carries the rule through the spine. */
.csrow>.yr{background:var(--ink);color:var(--paper);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:2px;padding:18px 10px;
  box-shadow:inset 0 -3px 0 rgba(246,241,229,.3)}
.csrow>.yr b{font-family:var(--slab);font-size:2rem;line-height:1;color:var(--mustard);font-weight:400}
.csrow>.yr small{font-family:var(--liner);font-style:italic;font-size:.8125rem;color:rgba(246,241,229,.7)}
.csrow .bill{padding:22px 30px;display:flex;flex-direction:column;justify-content:center;gap:7px}
/* ⚠ `h3, h2` BOTH. The Press files each entry as an <h2> (a post row is a
   sibling of the headliner, not its child), and this base rule was a bare tag
   selector — the same shape that orphaned `.cshead h3` for three passes when the
   semantic pass promoted it. Adding the tag here is the fix that was missed then. */
.csrow .bill h3,.csrow .bill h2{font-family:var(--gothic);font-size:2.1rem;letter-spacing:.03em;text-transform:uppercase;
  line-height:1.02;color:var(--ink)}
.csrow .bill .cr{font-family:var(--liner);font-style:italic;font-size:1rem;color:var(--ink-dim);line-height:1.35}
.csrow .bill .go{font-family:var(--gothic);font-size:.8125rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--tomato-text);text-indent:.18em;margin-top:3px}
.csrow .frame-cell{position:relative;overflow:hidden;border-left:2px solid var(--ink);min-height:153px}
.csrow .frame-cell img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* the frame cells stack into one continuous photographic column, so the band's
   ink rule can vanish between two dark frames — the same failure the year spine
   solves with an inset paper hairline. MEASURED at 1440 across ten boundaries:
   nine read at Δ≥28 luminance, Monday Night Brewing read at Δ=2. One in ten
   today, but the frames are stand-ins, so WHICH one fails is luck. This carries
   the rule through the column no matter what photograph lands above it.
   ::after, not an inset box-shadow — the img is positioned and would cover it. */
.csrow .frame-cell::after{content:"";position:absolute;z-index:2;left:0;right:0;bottom:0;height:3px;
  background:rgba(246,241,229,.38)}
/* an honour is a pasted sticker on the artwork, so it tilts (truth §9) */
.csrow .hon{position:absolute;z-index:3;left:12px;top:12px;background:var(--mustard);color:var(--ink);
  border:2px solid var(--ink);font-family:var(--gothic);font-size:.6875rem;letter-spacing:.12em;
  text-transform:uppercase;padding:3px 9px;transform:rotate(-2deg);box-shadow:3px 3px 0 var(--pine)}

/* the headliner sits at the top of the bill.
   The kit divided it with a 3px paper border hung on the frame cell — a rule
   belonging to one child, which design truth §2 forbids outright ("Never a
   border hung on one child"). It is a real split, so it is
   built as one: PAPER is the ground and a 3px gap lets it show between the
   reversed billing block and the photograph. Same rule on the page, but it is
   the forme's furniture now instead of an accent belonging to the picture. */
.cshead{display:grid;grid-template-columns:1fr 620px;background:var(--paper);color:var(--paper);
  align-items:stretch;gap:3px}
.cshead .bill{background:var(--ink);padding:38px 40px 34px;display:flex;flex-direction:column;
  justify-content:center;gap:11px}
.cshead .kick{font-family:var(--liner);font-style:italic;font-size:1.19rem;color:var(--mustard)}
/* ⚠ `h3, h2` both, 2026-08-11. The semantic pass promoted this headliner from
   <h3> to <h2> (it was creating an h1→h3 skip) and reported "zero visual change"
   on the strength of every .lbl selector being class-based. This one is not: it
   is a bare tag selector, so promoting the tag orphaned it and the index
   headliner has been rendering at the UA default — 1.5em synthetic-bold Switzer
   — at EVERY width since. Not a mobile bug; found during the mobile sweep. */
.cshead h3,.cshead h2{font-family:var(--slab);font-size:4.2rem;line-height:.96;text-transform:uppercase;
  color:var(--paper);text-shadow:5px 5px 0 var(--tomato)}
.cshead .cr{font-family:var(--liner);font-style:italic;font-size:1.0625rem;
  color:rgba(246,241,229,.82);line-height:1.4;max-width:32rem}
.cshead .hons{display:flex;flex-wrap:wrap;gap:8px;margin-top:5px}
.cshead .hons span{border:2px solid var(--mustard);color:var(--mustard);font-family:var(--gothic);
  font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;padding:4px 10px}
.cshead .go{margin-top:12px;align-self:flex-start;background:var(--tomato);color:var(--paper);
  border:3px solid var(--paper);box-shadow:5px 5px 0 rgba(0,0,0,.45);font-family:var(--gothic);
  font-size:1.125rem;letter-spacing:.12em;text-transform:uppercase;padding:12px 26px}
/* 2026-08-11: min-height:430px rendered the headliner at 1.265:1, off-system.
   3:2 like the rows below it, so the index reads as one crop policy. */
.cshead .frame-cell{position:relative;overflow:hidden;aspect-ratio:3/2;min-height:0}
.cshead .frame-cell img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* LOAD-BEARING: both chassis carry a fixed frame column. Below these widths it
   starves the billing — measured, not guessed. The frame drops away rather than
   squeezing the credits, because the frame is the supporting cell. */
/* MEASURED, not guessed. Row headline + credit hold one line each, and all
   eleven rows stay a uniform 153px, at 1440 and 1280. At 1180 the credits start
   wrapping and the rows lose their rhythm (153 / 196 / mixed) — an index whose
   rows are different heights has stopped being a scannable list. So the frame
   column drops at 1180, not at 900: below that width the list is worth more than
   the thumbnail, and the frame was always the supporting cell, never the subject.
   1180 was still too late — at 1200 the Emory credit wrapped and rows went
   153/162. Breakpoint set at 1240, the measured edge. Verified uniform 1440 →
   900. Below ~860 the credit wraps again; that belongs to the mobile pass
   (build order step 8), which restructures these rows anyway. */
@media (max-width:1240px){
  .cshead{grid-template-columns:1fr 42%}
  .cshead h3,.cshead h2{font-size:3.4rem}
  .csrow{grid-template-columns:112px 1fr}
  .csrow .frame-cell{display:none}
}
@media (max-width:900px){
  .cshead{grid-template-columns:1fr}
  .cshead .frame-cell{min-height:280px}   /* the 3px gap becomes horizontal on its own */
}

/* THE TWO-TIER TAPER inside a plate's field — the festival-bill default (truth
   §8): size steps down AND the interval compresses, so rank is carried by
   rhythm as well as size. Names are .nm nowrap atoms; a bill never splits an
   act's name. About runs a four-tier specialisation of this locally. */
.field .fr{text-wrap:balance}
.field .fr .nm{white-space:nowrap}
.field .fr .st{color:var(--tomato);vertical-align:middle;margin:0 9px;font-size:.7em}
/* ⚠ `--fs`, NOT `font-size` — 2026-08-11. These two were the ONE taper pair in
   the suite that never joined the tier cap: a literal `font-size` here is
   (0,3,0) and beats `.field .fr{font-size:min(--fs, …)}` at (0,2,0), so they
   rendered their authored size at every width however long a name got. Declaring
   `--fs` lets the shared ceiling do its job. (`font-size:unset` does NOT work as
   a way out — font-size is inherited, so `unset` means `inherit`, and the
   declaration still wins on specificity: measured, it collapsed both tiers to
   the 17px body size.)
   `--cw` is MEASURED for this face, not borrowed from the print tiers: Libre
   Caslon italic runs 0.304 of its font size per character bold and 0.291 plain,
   against Anton's 0.478. */
.field .fr.maj{font-family:var(--liner);font-style:italic;font-weight:700;--fs:2rem;--cw:.31;
  line-height:1.24;color:var(--ink)}
.field .fr.min{font-family:var(--liner);font-style:italic;--fs:1.31rem;--cw:.3;line-height:1.3;
  color:var(--ink-dim);margin-top:6px}

/* ---------- type voices ---------- */
.kicker{font-family:var(--liner);font-style:italic;font-weight:400;font-size:1.125rem;color:var(--tomato-text)}

/* ---------- vault + plates ---------- */
.vault-wrap{position:relative;z-index:2;margin:26px 44px 0}
.vault-tab{position:absolute;top:-15px;left:50%;transform:translateX(-50%) rotate(-1.6deg);z-index:3;
  background:var(--tomato);color:var(--paper);border:2px solid var(--ink);padding:5px 18px;white-space:nowrap;
  font-family:var(--gothic);font-weight:400;font-size:.9375rem;letter-spacing:.14em;text-transform:uppercase;margin:0}
.row{position:relative;z-index:2;margin:24px 44px 0;display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
.row.r3{grid-template-columns:repeat(3,1fr)}
.plate{position:relative}
.plate .ph{border:3px solid var(--ink);outline:1px solid var(--ink);outline-offset:4px;
  overflow:hidden;box-shadow:6px 6px 0 rgba(33,28,22,.14)}
.plate img{width:100%;height:180px;object-fit:cover}
.row.r3 .plate img{height:250px}
.plate .cap{display:flex;justify-content:center;gap:8px;margin-top:9px;background:var(--ink);
  color:var(--paper);padding:7px 11px;font-family:var(--gothic);font-weight:400;font-size:.8125rem;
  letter-spacing:.12em;text-transform:uppercase}
.plate .cap span{color:var(--mustard);font-weight:400}

/* ---------- bill bottom ---------- */
.bill-bottom{position:relative;z-index:2;margin-top:30px;border-top:3px solid var(--ink)}
.feat{display:flex;justify-content:center;gap:24px;align-items:baseline;padding:11px 20px;border-bottom:1px solid var(--ink)}
.feat span{font-family:var(--gothic);font-size:.9375rem;letter-spacing:.14em;text-transform:uppercase}
.feat i{color:var(--tomato);font-style:normal}

/* ---------- page masthead (interior pages) ---------- */
.mast{padding:40px 44px 0;position:relative;z-index:2;text-align:center}
/* when the mast IS a band, it closes on its own 3px rule and needs room above it
   — otherwise the last line sits flush on the rule */
.mast.bnd{padding-bottom:32px}
.mast .kicker{font-size:1.19rem}
.mast h1{font-family:var(--slab);font-size:5.5rem;line-height:.98;text-transform:uppercase;color:var(--tomato);
  text-shadow:5px 4px 0 var(--pine);margin:8px 0 4px}
.mast .sub-western{font-family:var(--western);font-size:2.4rem;line-height:1;text-transform:uppercase;
  color:var(--ink);text-shadow:2px 2px 0 var(--mustard)}
.mast .lede{max-width:42rem;margin:20px auto 0;color:var(--ink-dim)}
.mast .lede b{color:var(--ink);font-weight:500}
.mast .lede em{font-family:var(--liner);font-style:italic;color:var(--tomato-text)}

/* ---------- filters ---------- */
/* RETIRED 2026-08-10. The free-standing bordered .filters box had no left edge and
   was a third way of announcing a section. Its first replacement, the plate nav
   line, was retired the same day for the opposite fault — too much announcement.
   The filter now lives on .b-file, band system (a4) above. */

/* ---------- the wall (night sections) — RETIRED 2026-08-10 (evening) --------
   .wall / .wall-head / .wall-grid / .wall-note / .gig and all .gig.* children
   deleted with zero users left: liner-note-single's night Related Bills became
   a board .b-file tab line, and home's Record Bin header became the NIGHT
   PLATE below (§5.1 closed, Seth's yes). Deleting .gig also retires R8's 34px
   cast blur by removal. Do not reintroduce — the night plate is the grammar
   for naming a zone on night stock. */

/* THE NIGHT PLATE (§5.1 CLOSED 2026-08-10, Seth's yes). On night stock the
   plate REVERSES: board ground, ink type — paper/night is 15.23:1, the same
   15:1 an ink plate gets on board. Nothing changed in letterpress terms: the
   plate is still the area the ink does not cover. The divider is the ground
   showing through the 3px gap (truth §2b's mechanism on a night surface —
   an ink rule here would be 1.02:1, i.e. no rule at all). Sub-label takes
   --tomato-text on board (5.55:1), same as the undercard. */
/* ⚠⚠ THE BIN'S HEAD IS A BILLING, NOT A PLATE — 2026-08-12. See front-page.php
   for why. Kicker, name, paragraph, centred, on night stock: the same three
   voices in the same order as the ticket's own head, which is the only other
   night object on the site. The misregister is TOMATO here and that is §7
   literal, not an exception — §7's pine is measured against BOARD; on night,
   pine is 2.06:1 and would all but vanish, while tomato at 3.39:1 sits 4.5x
   quieter than the 15.23:1 paper it offsets. */
.bin-head{margin-bottom:56px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:2px}
.bin-head .adm{font-family:var(--gothic);font-size:1rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--mustard);text-indent:.12em}
.bin-head h2{font-family:var(--slab);font-size:clamp(2.2rem,5vw,3.9rem);line-height:1;
  text-transform:uppercase;color:var(--paper);text-shadow:-3px 3px 0 var(--tomato);
  margin:10px 0 14px;text-wrap:balance}
.bin-head p{font-family:var(--liner);color:rgba(246,241,229,.66);font-size:1.06rem;
  max-width:44rem;margin:0 auto;text-wrap:pretty}
.bin-head p b{color:var(--paper);font-weight:700}
/* the retired plate chassis — kept only for the tiers below that still name it */
.bin-head>.lbl{background:var(--paper);color:var(--ink);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:5px;padding:24px 16px;text-align:center}
.bin-head>.lbl b,.bin-head>.lbl h2{font-family:var(--gothic);font-size:1.75rem;line-height:1.04;letter-spacing:.14em;
  text-transform:uppercase;font-weight:400;text-indent:.14em}
.bin-head>.lbl small{font-family:var(--liner);font-style:italic;font-size:.9375rem;color:var(--tomato-text)}
.bin-head>.field{display:flex;flex-direction:column;justify-content:center;padding:14px 34px}
.bin-head>.field p{font-family:var(--liner);color:rgba(246,241,229,.66);max-width:44rem;font-size:1.06rem}
.bin-head>.field p b{color:var(--paper);font-weight:700}


/* ---------- the ticket ---------------------------------------------------
   REBUILT 2026-08-10 as a BAND (direction C, "the torn stub"). What it replaced
   was the only element on the site that sat OUTSIDE .frame — a free-standing
   card in a .ticket-sec, which DESIGN-TRUTH §1 forbids by name. Measured before
   the rebuild, at 1440 across all eight pages:
     · outside .frame on 7 of 8 pages (book was the exception)
     · three different left edges on one site: every .bnd at x=25, the ticket at
       x=48 on seven pages and x=69 on book. It aligned to nothing.
     · 102px of bare board above it, 100px below, then the colophon
     · its own 3px border INSIDE the frame's 3px trim — a box in a box
     · .t-side 717px tall with content ending at 488px: 136px (18.9%) of dead night
     · 4 of its 7 contact rows repeated the colophon 100px underneath it (§10)
   And two faults that were invisible BY MEASUREMENT, which is how they survived
   every visual pass:
     · .go border:3px solid var(--ink) on --night ground — ink/night is 1.02:1,
       so the button had no border at all
     · .go box-shadow rgba(12,16,26,.7) — that is --night on --night, 1.00:1, so
       it had no offset either. §7 names pine as the ink for this.

   THE IDEA: a ticket is not a card laid on a poster, it is a region of the SAME
   SHEET perforated so it can be torn off. That is how a box-office forme works,
   and it is the one way the ticket can run full-bleed — obeying §1 — and still
   read as a ticket. The perforation, not a border, is what makes it a ticket.
   Two stocks, because that is what a torn ticket looks like in a hand: the body
   is gone and what you keep is board. Verified full bleed (3px from the frame =
   the frame's own border) at 1440/1180/1024/940/900/768/600, no h-scroll.
   ------------------------------------------------------------------------- */

/* THE GROUND IS INK and every cell carries its own stock on top of it, so the
   3px tracks between cells hold no element at all — they are the forme's
   furniture showing through. That is §2b's mechanism verbatim: "two columns
   divided by a 3px gap over an ink-backed band... NEVER a border-right hung on
   one child." Track 2 is empty furniture; track 4 holds the perforation, which
   is not furniture but a die-cut, so it is a real element in its own slot. */
/* overflow:hidden makes the ticket A SELF-CONTAINED MODULE. Seth, 2026-08-10:
   the form "seems to bleed into the thing above and it should be a separate
   module." MEASURED: the perforation's punches are positioned at top:-16px /
   bottom:-16px, so 16px of a 32px paper-and-ink disc sat OUTSIDE the band. On
   the-photographer the neighbour above is dark and it read as a real die-cut;
   on home the neighbour is the paper-2 "Deep Cuts" plate, where the same disc
   reads as a stray white dot floating on someone else's band.
   Clipping it turns each punch into a HALF-CIRCLE NOTCH bitten into the
   ticket's own top and bottom edge — which is what the end of a perforation
   actually looks like where it meets the trim, and it keeps every pixel of the
   ticket inside the ticket. The die-cut idea survives; the trespass does not. */
/* QUIET PASS 2026-08-10 — THE TEAR, made real (Seth: the tear-off "looks a little blah", and
   the beige stub read as a continuation of a beige band above it — §6's own law,
   two same-stock regions meeting at a seam). Two moves, both print-true:
   1. The tear track widens 3px → 18px and the stub's edge is TORN — an irregular
      deckle cut into the stub's paper, with the band's ink ground showing through
      the gap and the perforation stitching left behind on the body's edge. The
      punches stay at the ends of the tear.
   2. The stub carries a printed DOUBLE-KEYLINE border — what a real box-office
      stub has — so it reads as a printed ticket object, not a beige region.
      That is what separates it from any beige band above; ink on paper-2 is
      13.6:1 and needs no new measurements. */
/* ⚠⚠ THE TICKET IS A SIBLING OF THE FRAME — 2026-08-12 (Seth: it "needs to be
   its own module wherever its listed... so it feels more like an actual ticket
   and less bleeding into its surroundings").
   MEASURED on home before this: the band above ended at y=6141 and the ticket
   began at y=6141. Zero. It shared `.frame`'s trim with every other band and
   read as one more band of the bill.
   This is the BIN's furniture, verbatim — 3px border, the 1px keyline at
   offset, and the sheet's own 22px as margin — because the bin took this exact
   complaint on 2026-08-12 and that is what answered it. parts/chrome-footer.php
   now prints the ticket between the `.frame` close and the `.sheet` close, so
   paper shows above and below it; see inc/bigbill.php for why the four call
   sites queue it instead of printing it in place.
   ⚠ The other route is ruled out by the record: on 2026-08-10 the ticket's own
   3px border INSIDE the frame's 3px trim was judged "a box in a box". This is
   not that. The frame ENDS above the ticket.
   ⚠ `.sheet>.bnd.b-tkt` (0,3,0), not `.b-tkt` (0,1,0): the ticket is now the
   last child of `.sheet`, so `.bnd:last-child{border-bottom:none}` (0,2,0)
   would win and take the bottom trim straight back off. */
/* the ticket is wrapped in a named <section> for the landmark it would
   otherwise fall outside of — see ps_render_queued_ticket(). The section is a
   pass-through: the ticket keeps its own margin and trim. */
.tkt-region{display:block}
.sheet>.tkt-region>.bnd.b-tkt{margin:22px 0 0;border:3px solid var(--ink);
  outline:1px solid var(--ink);outline-offset:5px}
/* THE SHEET'S TAIL — the booking page's house rules, printed after the ticket
   in a second frame so the box office reads as three objects on one sheet. It
   takes the frame's own furniture and the sheet's 22px, exactly as the ticket
   and the bin do. */
.sheet>.frame-tail{margin-top:22px}
.b-tkt{background:var(--ink);color:var(--paper);overflow:hidden;
  display:grid;grid-template-columns:56px 3px 64fr 18px 31fr}
.b-tkt .t-form{grid-column:3;background:var(--night)}
.b-tkt .perf-v{grid-column:4}
.b-tkt .t-stub{grid-column:5;background:var(--paper-2);color:var(--ink)}

/* the ADMIT ONE stripe runs to the trim, so it is a printed stripe on the sheet
   rather than a decorative strap on a card */
.b-tkt .t-run{background:var(--tomato);display:flex;align-items:center;justify-content:center}
.b-tkt .t-run span{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--gothic);
  color:var(--paper);font-size:.9375rem;letter-spacing:.34em;text-transform:uppercase;white-space:nowrap}

/* THE PERFORATION. The tear crosses two stocks, so it has to read from BOTH
   sides: paper dashes show as holes against the night body, ink dashes show as
   holes against the board stub. A single-colour perf disappears into whichever
   side matches it. The punches belong to the perforation, not to the band, so
   they always land on the tear line whatever the column ratio is; half of each
   is off the sheet and .frame{overflow:hidden} clips them at the trim. */
/* the tear gap: band ink shows through; the paper dashes hug the BODY's edge —
   the perforation stitching the tear left behind. The stub side is bare gap:
   its own torn edge (below) does the talking. */
.b-tkt .perf-v{position:relative;background:
  repeating-linear-gradient(to bottom,var(--paper) 0 7px,transparent 7px 14px) left top/3px 100% no-repeat}
.b-tkt .perf-v::before,.b-tkt .perf-v::after{content:"";position:absolute;left:50%;
  width:26px;height:26px;border-radius:50%;background:var(--paper);
  border:3px solid var(--ink);transform:translateX(-50%)}
.b-tkt .perf-v::before{top:-16px}
.b-tkt .perf-v::after{bottom:-16px}

/* ---- the form side ------------------------------------------------------ */
/* QUIET PASS 2026-08-10: was 44px 52px 48px. The 667px height was set by padding and the pitch
   paragraph, not content — the critique measured ~130px of air the component
   doesn't need. Target ≈535px: still 3 fields, same type scale, same button. */
.b-tkt .t-form{padding:32px 46px 36px;display:flex;flex-direction:column;position:relative}
.b-tkt .t-form .adm{font-family:var(--gothic);letter-spacing:.12em;font-size:1rem;
  text-transform:uppercase;color:var(--mustard)}
/* MEASURED: on --night, tomato is 3.39:1 and paper is 15.23:1, so the offset
   lands 4.5x QUIETER than the letterform casting it — which is what §7 asks
   for. Pine (2.06:1) would all but vanish here; §7's pine is measured against
   BOARD, and the form side is the one surface in the system that is not board. */
.b-tkt .t-form h2{font-family:var(--slab);font-size:3.9rem;line-height:1;text-transform:uppercase;
  margin:10px 0 12px;color:var(--paper);text-shadow:-3px 3px 0 var(--tomato)}
.b-tkt .t-form>p{max-width:32rem;color:rgba(246,241,229,.78)}

/* ============ THE TICKET, COMPACT — every surface except the box office ======
   One component, one modifier. See parts/ticket.php for the proportional
   measurement that made this necessary. Type scale and padding only: no grid
   child moves, no field name changes, and the tear/stub mechanics are shared. */
.b-tkt.is-compact .t-form{padding:24px 34px 26px}
.b-tkt.is-compact .t-form h2{font-size:2.1rem;margin:6px 0 8px;text-shadow:-2px 2px 0 var(--tomato)}
.b-tkt.is-compact .t-form>p{max-width:38rem;font-size:.9375rem}
.b-tkt.is-compact .t-run span{font-size:.8125rem;letter-spacing:.22em}
.b-tkt.is-compact .fields{margin-top:14px}
/* the compact keyline tightens WITH its padding — see the token block on
   `.t-stub, .t-next`. The old `padding:22px 26px` against a keyline still at
   left:28px is the defect that fix exists for. */
.b-tkt.is-compact .t-next,.b-tkt.is-compact .t-stub{
  --kl-t:10px;--kl-r:10px;--kl-b:10px;--kl-l:20px;
  --pad-t:22px;--pad-r:26px;--pad-b:26px;--pad-l:36px}
.b-tkt.is-compact .t-next .big{font-size:1.35rem}
/* `.is-compact .t-stub .big` is set with the marquee rail below, not here — the
   stub's headline is no longer board type that only needs a smaller size. */
@media (min-width:1001px){
  /* the ADMIT ONE spine narrows with everything else */
  .b-tkt.is-compact{grid-template-columns:42px 3px 64fr 18px 31fr}
}
.b-tkt .fields{margin-top:20px}
/* 2026-08-11: THE BLANK LINE IS NOW A REAL CONTROL.
   The grammar is untouched — 150px label, italic fill, 2px paper rule, the
   ticket-blank look. Only the right-hand cell changed, from a <span class="ph">
   that imitated a placeholder to a real <input>/<textarea>. Padding 11 -> 9px
   pays for the textarea's second row so the band keeps its ~533px budget. */
.b-tkt .t-field{display:grid;grid-template-columns:150px 1fr;gap:16px;
  border-bottom:2px solid rgba(246,241,229,.55);padding:9px 0;align-items:baseline}
.b-tkt .t-field.msg{align-items:start}
.b-tkt .t-field label{font-weight:600;font-size:.6875rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--paper)}
.b-tkt .t-field input,.b-tkt .t-field textarea{font-family:var(--liner);font-style:italic;
  font-size:1.0625rem;line-height:1.35;color:var(--paper);background:transparent;border:0;
  padding:0;width:100%;-webkit-appearance:none;appearance:none;resize:vertical}
/* MEASURED: paper at .68 over night composites to rgb(175,173,168) = 7.65:1.
   Placeholders are a hint, never the label — every field has a real <label for>. */
.b-tkt .t-field input::placeholder,.b-tkt .t-field textarea::placeholder{
  color:rgba(246,241,229,.68);opacity:1}
.b-tkt .t-field input:focus-visible,.b-tkt .t-field textarea:focus-visible{
  outline:3px solid var(--mustard);outline-offset:3px}
/* invalid only AFTER the visitor has typed — never scold an untouched field */
.b-tkt .t-field input:invalid:not(:placeholder-shown),
.b-tkt .t-field textarea:invalid:not(:placeholder-shown){box-shadow:0 2px 0 var(--tomato)}
/* The honeypot was an inline -9999px style with no aria-hidden, so a screen
   reader announced it as an unlabeled text field. Class + aria-hidden now. */
.ps-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.b-tkt .t-err{margin-top:12px;font-family:var(--gothic);font-size:.9375rem;
  letter-spacing:.1em;text-transform:uppercase;color:var(--mustard)}
/* the confirmation is a torn-off receipt pasted onto the ticket: board stock on
   the night form, ink type. MEASURED ink on paper-2 = 13.60:1 (14.3 recorded first time round). */
/* ⚠ SPECIFICITY, 2026-08-12. `.b-tkt .t-form>p` (0,2,1) beat this rule (0,2,0),
   so the ticket's body-copy colour won and only the BACKGROUND here applied:
   paper text on board, MEASURED 1.08:1. "Message Sent!" rendered as a blank
   rectangle — on the no-JS redirect path, which is also the path nav.js falls
   back to when the fetch fails. The one route that runs after something has
   already gone wrong was the one that showed nothing. Matching the compound
   rather than reaching for !important. */
.b-tkt .t-form>p.form-sent,
.b-tkt .form-sent{margin-top:14px;padding:14px 18px;background:var(--paper-2);color:var(--ink);
  font-family:var(--liner);font-style:italic;font-size:1.0625rem;line-height:1.4}
/* ⚠ THE PITCH IS ON THE STUB NOW — board, not night, so it re-inks. On paper-2
   ink-dim measures 5.25:1. It fills the slack the box office's stub carried
   between the ledger and the die-cut (174.7px at 1560, measured) and it takes a
   paragraph off the panel a visitor is typing into.
   The COMPACT ticket has no slack to give it, so there it is suppressed rather
   than squeezed — the compact stub is already the tighter of the two and the
   line is an argument, not a particular. */
.b-tkt .t-stub .pitch{margin:18px 0 0;font-family:var(--liner);font-style:italic;
  font-size:.9375rem;line-height:1.45;color:var(--ink-dim);max-width:34rem}
.b-tkt.is-compact .t-stub .pitch{display:none}
/* THE BUTTON. Border in PAPER (15.23:1) instead of ink (1.02:1, i.e. no border
   at all), and the offset in PINE (2.06:1) instead of night-on-night (1.00:1,
   i.e. no offset at all). Pine is quieter than the tomato it sits under, which
   is the relationship §7 exists to protect. */
/* 2026-08-11: now a real <button type="submit">, not an <a href="book.html"> —
   which also retires the circular CTA that linked book from book.
   CONTRAST FIX, same pass: the label was --paper on --tomato = 4.49:1, and
   "Get on the bill" sets at 22px/400, which is NOT WCAG-large (needs >=24px, or
   >=18.66px bold), so 4.5 applies and it failed by 0.01. #fff on tomato measures
   5.06:1 and keeps the full-chroma Hatch red on the ground. This is the inverse
   of the tomato-on-board case --tomato-text already solved; the build fixed one
   direction of that relationship and never the other. */
.b-tkt .go{margin-top:24px;align-self:flex-start;display:inline-block;background:var(--tomato);
  color:#fff;border:3px solid var(--paper);box-shadow:5px 5px 0 var(--pine);
  cursor:pointer;-webkit-appearance:none;appearance:none;
  font-family:var(--gothic);font-size:1.375rem;letter-spacing:.12em;text-transform:uppercase;
  padding:16px 34px;
  transition:transform .12s cubic-bezier(.2,.8,.3,1),box-shadow .12s cubic-bezier(.2,.8,.3,1)}
.b-tkt .go:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--pine)}
.b-tkt .go:active{transform:translate(5px,5px);box-shadow:0 0 0 var(--pine)}
.b-tkt .go:focus-visible{outline:3px solid var(--mustard);outline-offset:4px}
@media (prefers-reduced-motion:reduce){
  .b-tkt .go{transition:none}
  .b-tkt .go:hover,.b-tkt .go:active{transform:none;box-shadow:5px 5px 0 var(--pine)}
}
.b-tkt .note{margin-top:14px;font-family:var(--liner);font-style:italic;font-size:.875rem;
  color:rgba(246,241,229,.66)}
/* the serial is printed twice, once each side of the tear — which is the actual
   reason a real ticket carries a number at all */
/* ⚠ DIAGONALLY OPPOSITE THE STUB'S — 2026-08-12. Both halves print the same
   number, which is the whole reason a real ticket carries one; but set at the
   same height, in the same ink, at the same size, ~400px apart, they read as
   one number printed twice rather than as two halves of one object. This one
   drops to the FOOT of the night panel and sets smaller, so the pair reads as
   opposite corners of a single sheet. */
.b-tkt .t-serial{position:absolute;left:var(--pad-l,46px);bottom:14px;font-family:var(--gothic);
  font-size:.8125rem;letter-spacing:.16em;color:rgba(247,179,43,.72)}
.b-tkt.is-compact .t-serial{bottom:12px;font-size:.75rem}
/* ⚠⚠ THE PANEL RESERVES ROOM FOR IT. MEASURED on the box office at 1440 after
   the serial moved to the foot: its top sat at y=1133 and the message box's
   bottom at y=1137 — the number was printed OVER the field, by 4px. The form is
   a flex column whose fields grow to the padding box, so an absolutely
   positioned corner mark has to be paid for in padding or it collides with
   whatever grew last. Left edge matches the field labels exactly (both 130 at
   1440), which is why it is driven off the same token. */
.b-tkt .t-form{--pad-l:46px;padding-bottom:46px}
.b-tkt.is-compact .t-form{--pad-l:34px;padding-bottom:38px}

/* ---- the stub side: BOARD, printed in ink ------------------------------- */
/* QUIET PASS 2026-08-10: was 44px 38px 48px / gap 18px. The stub is PAGE-AWARE now: the burst,
   the phone line and the pitch print only on book (the box office); on the other
   seven pages the stub's middle is bare board — un-inked paper is the genre's
   own material, not dead space. Markup carries the difference; this chassis
   serves both. */
/* ⚠⚠ THE KEYLINE'S INSETS ARE TOKENS NOW — 2026-08-12, and this is a DEFECT FIX
   on 7 of the 8 surfaces that carry a ticket.
   `.is-compact` set `padding:22px 26px`, overriding the base 44px left — but
   the printed keyline stayed pinned at `left:28px` with `outline-offset:3px`,
   so the OUTER rule sat at x=25 and the stub's text started at x=26. MEASURED
   at 1440: clearance −2px. Every left-aligned line on the compact stub —
   the marquee, OR SKIP THE FORM, WRITE, CALL, ON TOUR — was struck through by
   its own keyline, on home, the hall of fame and every city page.
   The rule and the padding are now driven by the SAME four numbers, so a
   modifier cannot move one without the other. Measured after: +16px of clear
   board between the keyline and the type at both scales. */
.b-tkt .t-stub,.b-tkt .t-next{--kl-t:12px;--kl-r:12px;--kl-b:12px;--kl-l:28px;
  --pad-t:32px;--pad-r:34px;--pad-b:36px;--pad-l:44px}
.b-tkt .t-stub{padding:var(--pad-t) var(--pad-r) var(--pad-b) var(--pad-l);
  display:flex;flex-direction:column;gap:16px;
  position:relative;background:transparent}
/* the stub's paper, with the torn edge cut into its tear side */
.b-tkt .t-stub::before{content:"";position:absolute;inset:0;background:var(--paper-2);
  clip-path:polygon(18px 0,6px 3%,14px 6%,4px 10%,11px 15%,3px 19%,15px 24%,7px 28%,
    12px 33%,2px 38%,13px 43%,5px 47%,16px 52%,4px 57%,10px 61%,3px 66%,14px 71%,
    6px 75%,12px 80%,2px 85%,15px 90%,5px 94%,11px 98%,8px 100%,100% 100%,100% 0)}
/* the printed keyline — a box-office stub's double rule, inset from the trim */
.b-tkt .t-stub::after{content:"";position:absolute;
  top:var(--kl-t);right:var(--kl-r);bottom:var(--kl-b);left:var(--kl-l);
  border:2px solid var(--ink);outline:1px solid var(--ink);outline-offset:3px;pointer-events:none}
.b-tkt .t-stub>*{position:relative;z-index:1}
/* ⚠⚠ THE MARQUEE RAIL — 2026-08-12 (Seth: "putting doors open every day like
   some sort of one row marquee instead of two").
   ONE reversed strip does both of the stub's identity jobs: the claim on the
   left, the serial on the right. It replaces two rows of board type at the head
   PLUS a "Stub № 078381" line at the foot — three rows for two facts, on a
   panel whose real job is the ask below it. The strip is also the grammar this
   system already opens the home sheet with (`.b-strip`: a full-width ink bar in
   tracked caps), so the stub is stamped rather than captioned.
   It runs out to the printed keyline on three sides — 3px inside it, the same
   3px of furniture every band in this design divides on. The negative margins
   are computed from the tokens, so the rail follows the keyline at both scales
   instead of being re-typed per modifier.
   MEASURED on board: paper on ink 15.00:1, mustard on ink 9.21:1.
   (Recorded as 15.23 and 8.61 first time round and re-measured by the fresh-eyes
   audit — 15.23 is paper on NIGHT, which is a different surface.) */
.b-tkt .t-stub .big{display:flex;align-items:baseline;gap:18px;
  background:var(--ink);color:var(--paper);
  font-family:var(--gothic);font-size:1.125rem;letter-spacing:.08em;
  text-transform:uppercase;line-height:1.25;
  padding:10px 14px 9px;gap:10px;
  margin:calc(var(--kl-t) + 3px - var(--pad-t)) calc(var(--kl-r) + 3px - var(--pad-r)) 0
         calc(var(--kl-l) + 3px - var(--pad-l))}
/* ⚠⚠ THE RAIL MUST NEVER WRAP, and it is the STUB COLUMN that decides — not the
   `is-compact` modifier. A wrapped reversed strip with the serial floating
   beside line one is a broken bar, not a marquee.
   MEASURED, rail space against what the rail needs (claim + serial + gap):
     1560  avail 390  |  1440  351  |  1366  327  |  1280  298
     1180   266       |  1100  240  |  1024  215  |   941  198
     900(stacked) 679 |   768  547  |   600  421  |   480  277  |  390  187
   The claim sets ~11.6x the font-size in px and the serial ~5.1x, so at 18px
   the pair needs ~295px. It fits above ~1340 and nowhere between 941 and 1340,
   because the stub column is only 266–366px there. There is no size that keeps
   BOTH readable in 198px — 941 would need ~11px caps — so below 1181 the serial
   steps off the rail. It is not lost: `.t-serial` prints the same number on the
   night panel, directly across the tear, and in the stacked layout it sits a
   few px above the stub. The rail keeps the claim, which is the half a visitor
   reads. Every tier below was set from the table above, not from a round
   number, and re-measured after. */
.b-tkt.is-compact .t-stub .big{padding:9px 14px 8px}
@media (max-width:1340px){
  .b-tkt .t-stub .big{font-size:.9375rem}
  .b-tkt .t-stub .big .serial{font-size:.8125rem;letter-spacing:.1em}
}
@media (max-width:1180px){
  .b-tkt .t-stub .big{font-size:.875rem;letter-spacing:.06em}
  .b-tkt .t-stub .big .serial{display:none}
}
@media (max-width:940px){
  /* stacked: the stub runs the full width of the band, so the rail is a display
     line again and the serial comes back */
  .b-tkt .t-stub .big,.b-tkt.is-compact .t-stub .big{font-size:1.25rem;letter-spacing:.08em;
    gap:18px;padding:11px 20px 10px}
  .b-tkt .t-stub .big .serial{display:block;font-size:.9375rem;letter-spacing:.14em}
}
@media (max-width:560px){
  .b-tkt .t-stub .big,.b-tkt.is-compact .t-stub .big{font-size:.875rem;letter-spacing:.06em;
    gap:10px;padding:10px 16px 9px}
  .b-tkt .t-stub .big .serial{display:none}
}
/* the star between the two halves is FURNITURE, so the theme prints it and the
   field carries only the words — the same convention the colophon's tour line
   and `.bnd.feat` use. `i` stays paper here, not tomato-text: on ink, tomato
   measures 3.34:1 and could not carry it at this size; the star alone does the
   colour. (2.98 recorded first time round; re-measured.) */
.b-tkt .t-stub .big i{color:var(--paper);font-style:normal}
.b-tkt .t-stub .big i::before{content:"\00a0\2605\00a0";color:var(--tomato)}
.b-tkt .t-stub .big .claim{min-width:0}
.b-tkt .t-stub .big .serial{margin-left:auto;flex:none;font-weight:400;
  font-size:.9375rem;letter-spacing:.14em;color:var(--mustard)}
/* ⚠ BOUND TO THE ROWS IT HEADS. The line used to float between the marquee and
   the ledger with nothing to scope it, which is how it came to read as a label
   on the button further down. A hairline under it makes it the ledger's cap and
   nothing else's — the same job the `.cap` does in each colophon column. */
.b-tkt .t-stub .adm{display:block;font-family:var(--gothic);letter-spacing:.12em;font-size:1rem;
  text-transform:uppercase;color:var(--tomato-text);
  padding-bottom:9px;border-bottom:2px solid var(--ink);margin-bottom:2px}
/* ⚠ TWO-UP, AND THE TOUR SPANS — 2026-08-12 (Seth: "make the stub 2 col for
   phone/email then span the cols for the on tour"). Placement is EXPLICIT, not
   auto-flow: this list is always the same three pairs in the same order, and
   only the tour pair is conditional — if it is absent, rows 3 and 4 simply do
   not exist. Nothing here counts children.
   The label takes the same voice as the blanks on the other side of the tear
   (`.t-field label`), so both halves of the ticket label their fields alike. */
.b-tkt .t-stub dl{display:grid;grid-template-columns:1fr 1fr;column-gap:24px;row-gap:0;
  font-size:.9375rem}
.b-tkt:not(.is-compact) .t-stub dl{font-size:1rem}
.b-tkt .t-stub dl>dt:nth-of-type(1){grid-area:1/1}
.b-tkt .t-stub dl>dd:nth-of-type(1){grid-area:2/1}
.b-tkt .t-stub dl>dt:nth-of-type(2){grid-area:1/2}
.b-tkt .t-stub dl>dd:nth-of-type(2){grid-area:2/2}
.b-tkt .t-stub dl>dt:nth-of-type(3){grid-area:3/1/auto/-1;margin-top:15px}
.b-tkt .t-stub dl>dd:nth-of-type(3){grid-area:4/1/auto/-1;display:block;min-height:0;
  border-bottom:0;padding-bottom:0}
/* ⚠ TWO-UP NEEDS 376px OF STUB, and says so in numbers. The stub's content box
   is `stub − 62`, the two tracks split what is left of that after a 24px gap,
   and "seth@sethparker.net" is an unbreakable 143px token — so a track under
   ~145px wraps the site's most important address onto three lines. MEASURED at
   941–1024 before this rule: the email link rendered 38x132, i.e. three lines
   in a 121px track. 145px per track needs a 376px stub, which is a ~1320px
   viewport. Below that the ledger is ONE column — the same list, stacked — and
   it comes back two-up under 940 where the ticket stacks and the stub runs the
   full width of the band.
   Resetting `grid-area` to auto is what returns the pairs to DOM order; the
   third pair keeps only its air. */
/* ⚠ `:nth-of-type(n)` ON THE RESET IS LOAD-BEARING, not noise. The placements
   above are (0,4,1) because of their own `:nth-of-type`; a bare
   `dl>dt,dl>dd{grid-area:auto}` is (0,3,1) and LOSES to them, so the explicit
   column-2 placements survived, the grid kept an implicit second track, and
   that track collapsed to min-content. MEASURED with the bare reset:
   tracks 143.6px + 35.9px at 960, and the phone number rendered 36x132 — three
   broken lines and a tap target under 44px wide. `:nth-of-type(n)` matches
   every child and lifts the reset to the same specificity, where source order
   decides and this wins. */
@media (max-width:1320px){
  .b-tkt .t-stub dl{grid-template-columns:1fr}
  .b-tkt .t-stub dl>dt:nth-of-type(n),
  .b-tkt .t-stub dl>dd:nth-of-type(n){grid-area:auto}
  .b-tkt .t-stub dl>dt:nth-of-type(3){margin-top:15px}
}
@media (max-width:940px) and (min-width:561px){
  /* stacked, the stub is the full band — two-up again, and the placements are
     re-stated because the reset above turned them off */
  .b-tkt .t-stub dl{grid-template-columns:1fr 1fr}
  .b-tkt .t-stub dl>dt:nth-of-type(1){grid-area:1/1}
  .b-tkt .t-stub dl>dd:nth-of-type(1){grid-area:2/1}
  .b-tkt .t-stub dl>dt:nth-of-type(2){grid-area:1/2}
  .b-tkt .t-stub dl>dd:nth-of-type(2){grid-area:2/2}
  .b-tkt .t-stub dl>dt:nth-of-type(3){grid-area:3/1/auto/-1}
  .b-tkt .t-stub dl>dd:nth-of-type(3){grid-area:4/1/auto/-1}
}
/* --ink-dim, NOT --ink-faint. MEASURED on --paper-2: ink-faint (.42) is 2.52:1
   and fails 4.5:1; ink-dim (.68) is 5.25:1. The stub inherited these two colours
   from the old night stub, where rgba(paper,.6) measured 6.2:1 and was fine —
   moving the stub to BOARD stock is what broke them. Same failure mode as the
   button border: a colour that was correct on one surface, reused on another.
   (--ink-faint fails on plain --paper too, at 2.55:1 — that is a token-level
   issue across the build, reported but not swept here.) */
.b-tkt .t-stub dt{font-family:var(--gothic);font-size:.75rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-dim);text-indent:.14em;line-height:1.4}
/* break-word, NOT anywhere: `anywhere` collapses intrinsic min-content width and
   an `auto 1fr` grid then hands the value column ~one character. */
/* the value sets FLUSH LEFT under its label now — a right-aligned column in a
   two-up ledger leaves a ragged gutter down the middle of a 419px panel, and
   left edges are this design's whole grammar. The 44px tap floor moves from the
   anchor to the ROW (see the :701 block), so the two cells in a row set to the
   same height whatever is in them. */
.b-tkt .t-stub dd{font-weight:500;text-align:left;color:var(--ink);overflow-wrap:break-word;
  border-bottom:1px solid var(--ink-faint);padding-bottom:7px;
  min-height:40px;display:flex;align-items:center}
.b-tkt .t-stub dd a{color:var(--ink);border-bottom:none}
/* the tour row's own type is set once, in (q3) at the foot of this file — not
   here. Two blocks declaring `.t-tour` is exactly the drift the chassis table
   exists to prevent. */
/* `.t-stub .foot` IS GONE with the markup — the marquee rail took the serial.
   `.t-next .foot` (the torn state's "Stub taken № 078381") is untouched and
   keeps its own rules below: the revealed panel is a CONFIRMATION, not a
   counterfoil, so it does not mimic the stub's rail. */

/* ⚠ `.b-tkt .burst` AND `.b-tkt .t-stub .rule` REMOVED 2026-08-12 (~35 lines,
   incl. a 32-vertex clip-path). They died with the page-aware stub when the
   box_office fork was retired — nothing in parts/ticket.php emits either class.
   ⚠⚠ `.burst` ITSELF IS NOT DEAD: parts/poster.php still renders one, and the
   rules for it live with that component. Only the ticket-scoped copies went.
   The §12 min-content block below still cites "the 158px fixed .burst" as one of
   three contributors sizing the 320px track — that reasoning is now stale by one
   item; the other two still hold and the measurement stands. */

/* ---- the stack. Same 940 breakpoint as the colophon, which starves at the
       same width for the same reason: the stub's email address gives that
       column a large min-content width. Only the tear turns horizontal; the
       furniture track survives, and the punches follow the tear to its ends. -- */
@media (max-width:940px){
  .b-tkt{grid-template-columns:56px 3px 1fr}
  .b-tkt .t-form,.b-tkt .t-stub,.b-tkt .perf-v{grid-column:3}
  .b-tkt .t-run{grid-row:1 / span 3}
  /* the tear turns horizontal: stitching hugs the body's (upper) edge, and the
     stub's torn edge becomes its TOP edge */
  .b-tkt .perf-v{width:auto;height:18px;background:
    repeating-linear-gradient(to right,var(--paper) 0 7px,transparent 7px 14px) left top/100% 3px no-repeat}
  .b-tkt .perf-v::before,.b-tkt .perf-v::after{left:auto;top:50%;transform:translateY(-50%)}
  .b-tkt .perf-v::before{left:-16px}
  .b-tkt .perf-v::after{right:-16px}
  .b-tkt .t-form{padding-left:30px;padding-right:30px}
  /* the tear is horizontal here, so the torn edge is the stub's TOP and the
     keyline's deep inset moves with it. One token block instead of a separate
     `::after{top:28px;left:12px}` — which is exactly the split that let the
     compact keyline drift out of register in the first place. `.is-compact` is
     named too because it beats a bare `.b-tkt .t-stub` on specificity. */
  .b-tkt .t-stub,.b-tkt .t-next,
  .b-tkt.is-compact .t-stub,.b-tkt.is-compact .t-next{
    --kl-t:28px;--kl-l:12px;--pad-t:44px;--pad-l:30px;--pad-r:30px}
  .b-tkt .t-stub::before{clip-path:polygon(0 18px,4% 6px,8% 14px,13% 4px,19% 11px,24% 3px,
    30% 15px,35% 7px,41% 12px,47% 2px,53% 13px,58% 5px,64% 16px,70% 4px,75% 10px,
    81% 3px,86% 14px,92% 6px,97% 11px,100% 18px,100% 100%,0 100%)}
  /* `.t-stub::after` needs no override — it reads the tokens above. */
}

/* ======================================================================
   THE TEAR-OFF — 2026-08-12. Seth: "since we moved the email confirmation to
   a stub, what if the submit went on the right stub… on submit, theres an
   animation that looks like it tears off or slides out of frame, leaving the
   tan color behind and a confirmation."

   The gesture is already what the object says: the confirmation email IS the
   stub, "the half you keep", torn along this perforation and carrying this
   serial. So the sheet and the inbox become one continuous act.
   ====================================================================== */

/* ---- 1. THE NEXT BLANK IN THE BOOK -------------------------------------- */
.b-tkt .t-next{grid-column:5;grid-row:1;position:relative;z-index:1;
  background:var(--paper-2);color:var(--ink);
  padding:var(--pad-t) var(--pad-r) var(--pad-b) var(--pad-l);
  display:flex;flex-direction:column;gap:16px}
.b-tkt .t-next::after{content:"";position:absolute;
  top:var(--kl-t);right:var(--kl-r);bottom:var(--kl-b);left:var(--kl-l);
  border:2px solid var(--ink);outline:1px solid var(--ink);outline-offset:3px;pointer-events:none}
.b-tkt .t-next>*{position:relative;z-index:1}
.b-tkt .t-next .big{font-family:var(--gothic);font-size:1.5rem;letter-spacing:.1em;
  text-transform:uppercase;line-height:1.3;color:var(--ink)}
.b-tkt .t-next .big i{color:var(--tomato-text);font-style:normal}
.b-tkt .t-next .adm{font-family:var(--gothic);letter-spacing:.12em;font-size:1rem;
  text-transform:uppercase;color:var(--tomato-text)}
.b-tkt .t-next .say{font-family:var(--liner);font-style:italic;font-size:1.0625rem;
  line-height:1.45;color:var(--ink)}
.b-tkt .t-next .foot{margin-top:auto;padding-top:20px;display:flex;justify-content:space-between;
  align-items:baseline;gap:16px;font-family:var(--gothic);font-size:.9375rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-dim)}
.b-tkt .t-next .foot b{color:var(--tomato-text);font-weight:400}
.b-tkt .t-stub{grid-row:1;z-index:2}

/* ---- 2. THE ACTION BLOCK, AND THE SPACE THE BUTTON LEFT ------------------
   margin-top:auto drops it into the ~248px of bare board the stub already had
   between the contact list and its foot, landing it at the same y as the button
   it replaces — so the eye crosses the tear horizontally, not diagonally. The
   3px ink rule is the sheet's own divider (§1), which keeps the contact list
   and the action two zones rather than one muddled panel.
   On the night side, the freed ~200px goes to THE PROJECT — the one box whose
   answer decides whether a lead is worth quoting, and which was asking for
   three things in two rows. The band gets SHORTER and the field gets BIGGER. */
/* ⚠ THE RULE ABOVE THE ACTION IS A DIE-CUT — 2026-08-12 (Seth: "i like the
   dashed line above the button instead of solid"). Same 7/14 pitch as the
   vertical perforation, so the two read as one forme: the tear the visitor is
   about to make is drawn in the same ink as the tear already on the sheet. */
.b-tkt .t-stub .t-act{margin-top:auto;padding-top:23px;border-top:0;position:relative;
  display:flex;flex-direction:column;align-items:flex-start;gap:12px}
.b-tkt .t-stub .t-act::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:repeating-linear-gradient(to right,var(--ink) 0 7px,transparent 7px 14px)}
/* ⚠⚠ THE BORDER WAS INVISIBLE, on all eight surfaces. `.go` carries
   `border:3px solid var(--paper)` — measured for the NIGHT panel, where paper
   is 15.23:1. The button moved to the stub in the tear-off pass and the stub is
   BOARD: DESIGN-TRUTH §6 already records paper against paper-2 as 1.10:1, "a
   whisper that cannot separate anything". The primary control on the site had
   no border for two days. Same failure as the 2026-08-11 fix in the opposite
   direction (ink on night, 1.02:1), and it survived because the button changed
   SURFACE, not colour. Ink on board is 15:1; the pine offset stays 7.37:1, so
   the second pass is still quieter than the shape casting it (§7). */
.b-tkt .t-stub .t-act .go{margin-top:0;align-self:stretch;text-align:center;
  border-color:var(--ink);padding:15px 26px;white-space:nowrap}
/* ⚠ `white-space:nowrap` IS LOAD-BEARING. MEASURED on the box office at 941:
   the button rendered 187.6x102px — "TEAR &" / "SEND" on two lines — because
   the stub track is at its narrowest there. Its label is an editable field
   (`ticket_cta`), so without this a one-character-longer word silently breaks
   the site's primary conversion control. The button is `align-self:stretch`, so
   nowrap sets a real min-width the grid has to honour rather than clipping. */
.b-tkt .t-stub .t-act .note{margin:0;font-family:var(--liner);font-style:italic;
  font-size:.875rem;line-height:1.4;color:var(--ink-dim)}

.b-tkt .t-form .fields{display:flex;flex-direction:column;flex:1}
.b-tkt .t-form .t-field.msg{flex:1;align-items:stretch}
.b-tkt .t-form .t-field.msg label{align-self:start}
/* ⚠⚠ THE FLOOR THE STUB CANNOT EAT — 2026-08-12, and it is the reason
   "shrink the stub" is not free. The stub and the form are two cells of ONE
   grid row and this textarea is `flex:1` inside the form, so the band's height
   tracks the stub 1:1 and every pixel taken off the stub comes off THE PROJECT
   — the one box whose answer decides whether a lead is worth quoting, and the
   box the tear-off pass deliberately GREW ("the band gets shorter and the field
   gets bigger", :1201).
   MEASURED with the round-2 stub and no floor: the box office's message box
   went 127px → 61px, two lines, on the page whose whole job is the ask.
   So the saving is floored, not banked. The compact ticket still comes down
   554 → ~470 on home, the hall of fame and the city pages; the box office holds
   at ~595 and what its stub gives up becomes bare board above the die-cut,
   which this design already calls the genre's own material. */
.b-tkt .t-form .t-field.msg textarea{height:100%;min-height:3.6em}
.b-tkt.is-compact .t-field.msg textarea{min-height:88px}
.b-tkt:not(.is-compact) .t-field.msg textarea{min-height:118px}

/* ---- 3. THE PERFORATION IS INTACT UNTIL IT ISN'T -------------------------
   Seth, 2026-08-12. The shipped stub carried its torn deckle AT REST — a torn
   edge on a ticket nobody had torn. An intact ticket has a PERFORATION: a
   straight edge, a dashed line, two punches. The rag is what the tear LEAVES.
   Both polygons are authored with the SAME 26 vertices as the shipped deckle
   (22 stacked), every left-hand x pinned to 0 — matching vertex counts is what
   makes clip-path animate instead of snapping. The middle keyframe rips the top
   half only, so the tear RUNS DOWN the perforation. Measured: at 90ms the top
   edge is 17.2px ragged while the bottom is still 0. This is also what makes
   the board stub legible without inking it tomato — the travel is quiet
   tan-on-tan, but a straight edge going ragged is not. */
.b-tkt .t-stub::before{
  clip-path:polygon(0 0,0 3%,0 6%,0 10%,0 15%,0 19%,0 24%,0 28%,0 33%,0 38%,
    0 43%,0 47%,0 52%,0 57%,0 61%,0 66%,0 71%,0 75%,0 80%,0 85%,0 90%,0 94%,
    0 98%,0 100%,100% 100%,100% 0)}
@keyframes tkt-rip{
  0%  {clip-path:polygon(0 0,0 3%,0 6%,0 10%,0 15%,0 19%,0 24%,0 28%,0 33%,0 38%,
        0 43%,0 47%,0 52%,0 57%,0 61%,0 66%,0 71%,0 75%,0 80%,0 85%,0 90%,0 94%,
        0 98%,0 100%,100% 100%,100% 0)}
  45% {clip-path:polygon(18px 0,6px 3%,14px 6%,4px 10%,11px 15%,3px 19%,15px 24%,
        7px 28%,12px 33%,2px 38%,13px 43%,5px 47%,0 52%,0 57%,0 61%,0 66%,0 71%,
        0 75%,0 80%,0 85%,0 90%,0 94%,0 98%,0 100%,100% 100%,100% 0)}
  100%{clip-path:polygon(18px 0,6px 3%,14px 6%,4px 10%,11px 15%,3px 19%,15px 24%,
        7px 28%,12px 33%,2px 38%,13px 43%,5px 47%,16px 52%,4px 57%,10px 61%,
        3px 66%,14px 71%,6px 75%,12px 80%,2px 85%,15px 90%,5px 94%,11px 98%,
        8px 100%,100% 100%,100% 0)}
}
.b-tkt.is-torn .t-stub::before{animation:tkt-rip .3s cubic-bezier(.3,.7,.4,1) forwards}

/* ---- 4. THE STRAIN — the honest hold ------------------------------------
   MEASURED: the round trip was 6,288–7,651ms. The tear CANNOT fire on click —
   that promises success before the server has answered, and un-tearing on a
   failure is worse than never tearing. The perforation takes tension instead:
   it can loop indefinitely without lying, because BEING PULLED is not TORN, and
   on a refusal it simply releases with nothing to undo. */
.b-tkt .t-stub{transform-origin:0 6%;will-change:transform}
.b-tkt.is-straining .t-stub{animation:tkt-strain 1.55s ease-in-out infinite}
@keyframes tkt-strain{
  0%,100%{transform:translate(0,0) rotate(0deg)}
  55%    {transform:translate(7px,-2px) rotate(.4deg)}
}
.b-tkt.is-straining .perf-v::before,
.b-tkt.is-straining .perf-v::after{animation:tkt-punch 1.55s ease-in-out infinite}
@keyframes tkt-punch{
  0%,100%{transform:translateX(-50%) scale(1)}
  55%    {transform:translateX(-50%) scale(1.18)}
}

/* ---- 5. THE TEAR — on the SUCCESS response, never on click --------------
   `.b-tkt` is already overflow:hidden, so "out of frame" costs nothing: the
   stub is clipped at the trim by the band's own rule. The paper gives BEFORE it
   leaves — the rip runs 0–300ms, the travel starts at 140ms. */
.b-tkt.is-torn .t-stub{animation:none;pointer-events:none;
  transform:translate(118%,-16px) rotate(4.5deg);
  transition:transform .42s cubic-bezier(.45,.02,.72,.36) .14s}
/* the no-JS path arrives already finished — no travel to play */
.b-tkt.is-done .t-stub{transition:none;visibility:hidden}
.b-tkt.is-done .t-stub::before{animation:none}

/* ---- 6. AND THE BODY BECOMES A FILLED TICKET ----------------------------
   Found by looking: once the stub is gone the night panel was still a live,
   editable form with no submit on it. The answers stop being INPUTS and become
   the ticket's printed PARTICULARS — the band the confirmation email already
   prints. A ticket that has been torn is a ticket that has been filled. */
.b-tkt.is-torn .t-form .t-field input,
.b-tkt.is-torn .t-form .t-field textarea{pointer-events:none;color:var(--mustard)}
.b-tkt.is-torn .t-form .t-field{border-bottom-color:rgba(246,241,229,.28)}
.b-tkt.is-torn .t-form .pitch{opacity:0;transition:opacity .3s ease .2s}
/* ⚠⚠ …BUT NOT ON THE REDIRECT PATH. `is-torn` is set by BOTH routes and the two
   are not the same event. On the fetch path the fields hold the visitor's own
   answers, so freezing them turns inputs into printed particulars — which is
   the idea. On ?inquiry=sent the fields are EMPTY, so the same rules produced
   three dead blanks showing their placeholders, no usable control, and a pitch
   line deleted to `opacity:0` for nothing. `is-done` marks the server-rendered
   route; there, the blanks stay live and the next ticket can be filled in. */
.b-tkt.is-done .t-form .t-field input,
.b-tkt.is-done .t-form .t-field textarea{pointer-events:auto;color:var(--paper)}
.b-tkt.is-done .t-form .t-field{border-bottom-color:rgba(246,241,229,.55)}
.b-tkt.is-done .t-form .pitch{opacity:1;transition:none}
/* the next blank's own action, printed only in the torn state */
.b-tkt .t-next .t-act{margin-top:auto;padding-top:23px;border-top:0;position:relative;
  display:flex;flex-direction:column;align-items:stretch}
.b-tkt .t-next .t-act::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:repeating-linear-gradient(to right,var(--ink) 0 7px,transparent 7px 14px)}
.b-tkt .t-next .t-act .go{margin:0;align-self:stretch;text-align:center;
  border-color:var(--ink);padding:15px 26px;white-space:nowrap}
.b-tkt .t-next .foot{margin-top:18px}

@media (prefers-reduced-motion:reduce){
  .b-tkt.is-straining .t-stub,
  .b-tkt.is-straining .perf-v::before,
  .b-tkt.is-straining .perf-v::after,
  .b-tkt.is-torn .t-stub::before{animation:none}
  .b-tkt.is-torn .t-stub{transform:none;opacity:0;visibility:hidden;transition:none}
}

/* ---- 7. STACKED (<=940): the tear is horizontal, so it is pulled DOWN ---- */
@media (max-width:940px){
  /* the blank centres, because stacked the stub is ~610px tall and the
     confirmation is short — top-aligned it would read as a void with a note */
  .b-tkt .t-next{grid-column:3;grid-row:3;justify-content:center}
  .b-tkt .t-next .foot{margin-top:34px}
  .b-tkt .t-stub{grid-row:3;transform-origin:6% 0}
  .b-tkt .t-stub::before{
    clip-path:polygon(0 0,4% 0,8% 0,13% 0,19% 0,24% 0,30% 0,35% 0,41% 0,47% 0,
      53% 0,58% 0,64% 0,70% 0,75% 0,81% 0,86% 0,92% 0,97% 0,100% 0,100% 100%,0 100%)}
  @keyframes tkt-rip{
    0%  {clip-path:polygon(0 0,4% 0,8% 0,13% 0,19% 0,24% 0,30% 0,35% 0,41% 0,47% 0,
          53% 0,58% 0,64% 0,70% 0,75% 0,81% 0,86% 0,92% 0,97% 0,100% 0,100% 100%,0 100%)}
    45% {clip-path:polygon(0 18px,4% 6px,8% 14px,13% 4px,19% 11px,24% 3px,30% 15px,
          35% 7px,41% 12px,47% 2px,53% 0,58% 0,64% 0,70% 0,75% 0,81% 0,86% 0,92% 0,
          97% 0,100% 0,100% 100%,0 100%)}
    100%{clip-path:polygon(0 18px,4% 6px,8% 14px,13% 4px,19% 11px,24% 3px,30% 15px,
          35% 7px,41% 12px,47% 2px,53% 13px,58% 5px,64% 16px,70% 4px,75% 10px,
          81% 3px,86% 14px,92% 6px,97% 11px,100% 18px,100% 100%,0 100%)}
  }
  @keyframes tkt-strain{
    0%,100%{transform:translate(0,0) rotate(0deg)}
    55%    {transform:translate(2px,7px) rotate(.25deg)}
  }
  @keyframes tkt-punch{
    0%,100%{transform:translateY(-50%) scale(1)}
    55%    {transform:translateY(-50%) scale(1.18)}
  }
  .b-tkt.is-torn .t-stub{transform:translate(14px,118%) rotate(2.6deg)}
}

/* ---------- the paper gate: a photo grid as a band -----------------------
   PROMOTED 2026-08-10 (suite audit R13). This block was declared VERBATIM in two
   page <style> blocks — the-wall.html and on-tour.html — and had already drifted:
   `.wl-note{margin:40px 0 0}` on the-wall against `36px` on on-tour, every other
   declaration byte-identical. That is the exact failure the chassis table exists
   to prevent, and it would have been copied twice more at ACF port time.
   40px is the value kept (the-wall's, the page the component was built for);
   on-tour's note therefore sits 4px lower than before. That 4px is the whole
   visible consequence of this move and it was measured, not assumed.
   Air comes from the BAND's padding, never a margin on the child, which would
   collapse out and hole the stack. */
.gate-band{padding:40px 44px 44px}
.paper-gate{display:flex;flex-direction:column;gap:26px;position:relative;z-index:2}
.pgr{display:flex;gap:26px}
.pgp{position:relative;border:3px solid var(--ink);outline:1px solid var(--ink);outline-offset:4px;
  overflow:hidden;background:var(--paper-2);min-width:0;
  flex-grow:calc(var(--ar)*1000);flex-basis:0;aspect-ratio:var(--ar);
  box-shadow:6px 6px 0 rgba(33,28,22,.14)}
.pgp img{width:100%;height:100%;object-fit:cover;display:block}
.wl-note{position:relative;z-index:2;text-align:center;margin:40px 0 0;
  font-family:var(--liner);font-style:italic;font-weight:400;color:var(--ink-dim);font-size:1.125rem}
/* NOTE: --tomato here measures 4.49:1 on board. It is part of the site-wide
   --tomato/--tomato-text cluster flagged in SUITE-COVERAGE §6 and is now in ONE
   place, so that sweep is a single edit when Seth calls it. */
.wl-note b{color:var(--tomato-text);font-weight:400}

/* ---------- liner notes credit panel ---------- */
.liner-panel{display:grid;grid-template-columns:5fr 4fr;gap:50px;margin:60px 44px 0;position:relative;z-index:2}
.liner-panel .prose{font-size:1.0625rem;color:var(--ink-dim)}
.liner-panel .prose .caps{color:var(--tomato);display:block;margin-bottom:12px}
.liner-panel .prose p+p{margin-top:16px}
.liner-panel .prose b{color:var(--ink);font-weight:500}
.creditbox{border:3px solid var(--ink);background:var(--paper-2);padding:26px 28px;align-self:start}
.creditbox .caps{display:block;margin-bottom:14px;color:var(--tomato)}
.creditbox dl{display:grid;grid-template-columns:auto 1fr;gap:9px 20px;font-size:.9375rem}
.creditbox dt{color:var(--ink-faint)}
.creditbox dd{font-weight:500;text-align:right}
.creditbox .seal-line{border-top:2px solid var(--ink);margin-top:16px;padding-top:12px;
  font-family:var(--gothic);font-size:.9375rem;letter-spacing:.1em;text-transform:uppercase}
.creditbox .seal-line .st{color:var(--tomato)}

/* ---------- quote ---------- */
.quote{margin:84px auto 0;max-width:56rem;text-align:center;padding:10px 40px 0;position:relative;z-index:2}
.quote .trades{font-family:var(--gothic);font-size:.9375rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--tomato);margin-bottom:18px}
.quote .trades i{font-style:normal;color:var(--pine)}
.quote blockquote{font-family:var(--liner);font-style:italic;font-size:1.75rem;
  line-height:1.42;color:var(--ink);position:relative;display:inline-block;padding:0 30px}
.quote blockquote::before{content:"\201C";position:absolute;left:-34px;top:-30px;
  font-family:var(--slab);font-style:normal;font-size:6.5rem;line-height:1;color:var(--tomato)}
.quote blockquote::after{content:"\201D";position:absolute;right:-30px;bottom:-58px;
  font-family:var(--slab);font-style:normal;font-size:6.5rem;line-height:1;color:var(--tomato)}
.quote cite{display:block;margin-top:22px;font-style:normal;font-size:.8125rem;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--ink-dim)}

/* ---------- footer ---------- */
/* ============ THE COLOPHON — the printer's imprint at the foot of the sheet ===
   Rebuilt 2026-08-10. What it replaces: three CENTRED lines with no left edge, a
   hairline border-top, a 48px gutter — and the real failure, NO NAVIGATION AT
   ALL. A visitor at the bottom of a 4,500px page could book or leave, nothing
   else. The published-in line also appeared on only three of eight pages.

   QUIET PASS 2026-08-10 — RE-INKED AS BOARD. The reversed colophon meant every page
   ended in ~1000px of continuous dark (ticket + footer), a shared dark ending ×8
   that out-weighed each page's own content. Real Hatch is ink on white board; a
   printer's imprint is small black type at the foot of the sheet, not a reversed
   slab. On board the ticket becomes the ONLY dark object at page end and reads
   as an event again. Cells now divide by 3px of INK furniture showing through
   the gap (band grammar), never a border hung on a child (truth §2). Every
   colour below is a pre-measured board pairing: ink 15.00:1 · --ink-dim 5.53:1 ·
   --tomato-text 5.55:1. The mustard caps could not come along (1.63:1 on paper). */
/* ⚠ MEASURED before changing anything, 2026-08-12 (Seth: "the actual footer
   itself looks like it could use a little padding above it and below the bottom
   of the colophon"):
     last object → colophon block   0px (only the sheet's own 22px of paper)
     colophon block → © line        8px
     © line → page end             54px
   8px is not a gap, it is a collision the eye reads as one block. All three now
   step off the sheet's own 22px module — 22 above the block (44 with the
   sheet's), 22 above the imprint line, 72 below it. */
.colophon{max-width:1560px;margin:0 auto;padding:22px 22px 72px}
/* ⚠ COLUMN WEIGHTS REBALANCED + THE BILL GOES TWO-UP, 2026-08-12 (Seth).
   Measured before: col-id was 479px wide carrying 109px of content — 350px dead,
   76% — because .col-top is a grid and the SEVEN-item nav list set the row
   height, dragging the logo column to match a list it has nothing to do with.
   The bill is the content-heavy column so it now takes the widest track and runs
   two-up; the imprint takes the narrowest. Colophon 591 -> ~390px, on every page
   of the site (it is 7.4% of home but 12.3% of the Hall of Fame). */
/* ⚠ THE HOUSE GOES TWO-UP TOO — 2026-08-12 (Seth, after the bill).
   MEASURED before: the colophon was 500px and the ROW height was set by THE
   HOUSE at 354px of content, against the bill's 245px and the imprint's 194px
   of real ink. The house list alone was 239px, and that is not a spacing
   choice: four of its five values are links and the tap-target pass (:2600)
   floors every colophon link at 44px at ALL widths — 4×44 + 23 + 4×10 = 239,
   exactly. Which rules out the obvious two-up: keeping label and value on one
   line needs ~441px of track and the column has 383px, and taking the
   difference from the other two STARVED them — built and measured, the bill
   wrapped "BOOK A SESSION the box office" and the imprint wrapped
   "ARCHITECTURAL PHOTOGRAPHY". So the pair stacks instead, and the tour list
   leaves the column entirely (see `.col-tour`).
   Colophon 500px → 437px on every page. That is the FLOOR, not a stopping
   point chosen for looks: all three columns now land within a few px of each
   other, so anything further would be taken out of the bill, which cannot
   shrink without wrapping an act. */
/* the trim belongs to the WHOLE imprint — plate plus strip — so it hangs on the
   wrapper. On `.col-top` the 1px keyline would have run between the two and cut
   the object in half. The block's ink ground is what shows through every 3px
   gap inside it, plate cells and strip alike (§2b). */
/* ⚠⚠ `.col-block` IS THE GRID, and `.col-top` goes `display:contents` — the
   restructure that makes the tour strip FREE below 1251.
   MEASURED with the strip as its own row: −49px at 1440 but **+47px at 941–1180**,
   because in that band the BILL sets the row height (466px of content against
   the house's 275px) so shortening the house buys nothing and the strip is pure
   addition. The house column has ~190px of spare board there.
   So the strip is placed IN that void — column 3, row 2 — below 1251, and runs
   full width above it, where the house two-up is on and the strip is what pays
   for it. Same markup, same element, one grid.
   `display:contents` is safe here: `.col-top` is a plain div carrying no
   semantics, and `.col-top>*` still matches its children. */
.col-block{background:var(--ink);border:3px solid var(--ink);
  outline:1px solid var(--ink);outline-offset:5px;
  display:grid;grid-template-columns:4fr 6fr 5fr;gap:3px}
.col-top{display:contents}
/* ⚠ THE WEIGHTS ARE BACK TO 4/6/5 — reverted the same session, by measurement.
   Narrowing the bill to 5.7fr to buy the house room looked free at 1440 and was
   not: the bill's own two-up (:1001) was tuned to a 6fr track, and at 1024 the
   narrower column wrapped its acts to three lines each — MEASURED, the nav
   column carried 510px of content against the house's 275px and the colophon
   went 568 → 704. The BILL sets the row height at that width, so widening the
   house bought nothing there and cost 136px.
   The house gets its two-up from a higher THRESHOLD instead of a wider track:
   with 5fr its content box is `(viewport − 56)/3 − 64`, so the ~145px per track
   the address needs arrives at ~1208px. See the 1250 boundary below. */

.col-top>*{background:var(--paper);color:var(--ink);padding:30px 32px}
.col-top .cap{display:block;font-family:var(--gothic);font-size:.8125rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--tomato-text);margin-bottom:16px;text-indent:.18em}

.col-id{display:flex;flex-direction:column}
.col-id .mark{display:flex;align-items:center;gap:14px}
.col-id .mark img{height:44px;width:auto;display:block}
.col-id .wm{font-family:var(--gothic);font-size:1.5rem;letter-spacing:.09em;text-transform:uppercase;
  line-height:1;color:var(--ink)}
.col-id .wm small{display:block;font-family:var(--gothic);font-size:.6875rem;letter-spacing:.3em;
  color:var(--ink-dim);margin-top:5px;text-indent:.3em}
.col-id .status{margin-top:auto;padding-top:20px;font-family:var(--liner);font-style:italic;
  font-size:1rem;color:var(--tomato-text)}

.col-nav ul{list-style:none;display:grid;gap:9px}
/* ⚠⚠ 1061, and the road to that number is worth keeping, because two of the
   three attempts measured the wrong thing. The note it replaces was right that 701–1000 wrapped every act, and
   set the boundary at the first width where the column stops being `1fr 1fr`.
   But the bill needs a 6fr track ~478px wide to halve cleanly (the longest act,
   "BOOK A SESSION the box office", is ~196px and the gap is 22px), and
   `(viewport − 56) × 6/15 − 64` only reaches 478px at ~1251 — but the boundary
   is not that number, because a MILD wrap two-up still beats a clean single
   column. Measured both ways at each tier: at 1180 two-up carries 334px of
   content against ~391px single, so two-up wins; at 1024 it carries 466px and
   loses. The crossover is between them, and 1101 is where it was measured to
   land (colophon 1180: 513 two-up vs 545 single; 1024: 545 single vs 612).
   ATTEMPT 1 set 1101 by measuring the COLOPHON'S HEIGHT and never looking at
   the items. ATTEMPT 2 set 1401 after "counting wrapped acts" — but that count
   read `a.getBoundingClientRect().height` against the line-height, and every
   anchor here carries `min-height:44px` from the tap-target floor, so a
   two-line BOX was scored as a split NAME. It is the trap this repo keeps
   re-learning: a green metric is not a render, and a proxy is not the thing.

   MEASURED PROPERLY — a DOM Range over the act's own text node, excluding the
   <small>, so the question asked is "is the NAME on two lines?":
     960 (126px)  Case Studies AND Book a Session split
     1000 (137px) Book a Session splits
     1024 (142px) Book a Session splits
     1060 (149px) none · 1101 · 1180 · 1280 · 1366 · 1440 · 1560 — none
   So §8 — "a bill never splits an act's name across lines" — is violated only
   BELOW ~1060. The original 1001 was ~60px low, not 400px low. Between 1060 and
   1400 the name holds and it is the italic sub-label that drops beneath it,
   which is a look (the one an earlier pass tried and reverted for cost) and not
   a rule break.
   1061 is therefore the honest boundary: §8-safe at every width, and it keeps
   the two-up's height saving — measured, holding out for 1401 cost +92px at
   1280 and 1320 to prevent something that was never a violation. */
@media (min-width:1061px){
  .col-nav ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:11px 22px}
}
.col-nav a{font-family:var(--gothic);font-size:1.06rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink)}
/* ⚠ THE SUB-LABEL STAYS INLINE. Stacking it was tried and REVERTED the same day:
   it doubled every item to 82px, which cancelled the whole two-up gain (nav
   content went straight back to 383px and the colophon to 465). The longest act
   — "BOOK A SESSION the box office", ~194px — is given ROOM instead, by widening
   the bill's track above. */
.col-nav a small{font-family:var(--liner);font-style:italic;font-size:.875rem;letter-spacing:0;
  text-transform:none;color:var(--ink-dim);margin-left:9px}

/* Each pair is wrapped in `.hr` by the template, which is what makes the
   two-up DETERMINISTIC. `columns:2` on the <dl> was built and rejected:
   multi-column balances by height, so the same five pairs split 2+3 in one
   render and 3+2 in the next — a footer that reflows for no reason a reader
   can see. Grid over wrapped rows always fills the same way, and the hairline
   belongs to the ROW instead of being hung on the anchor. */
.col-house dl{display:grid;grid-template-columns:1fr 1fr;gap:0 30px;font-size:.9375rem}
.col-house .hr{padding-bottom:9px;margin-bottom:12px;border-bottom:1px solid var(--ink-faint)}
/* ⚠ THE ODD PAIR SPANS. Five pairs in two tracks left "BASED IN / Nashville, TN"
   in the left column with an empty cell beside it and a hairline stopping
   mid-panel — a ~220x60px void. The ticket's own two-up ledger already solves
   this with `grid-area:3/1/auto/-1` on its third pair; the colophon now does the
   same for whichever pair lands last, without counting them: an odd last child
   spans both tracks. */
@media (min-width:1251px){
  .col-house .hr:last-child:nth-child(odd){grid-column:1 / -1}
}
.col-house dl{margin-bottom:-12px}
/* Anton labels a list (§4), and at .75rem it is the same voice as `.cap` above
   it and as the blanks on the ticket. */
.col-house dt{font-family:var(--gothic);font-size:.75rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-dim);text-indent:.16em}
/* the value sets FLUSH LEFT. The colophon's own rebuild note (:1446) says the
   fault it fixed was "the one line with no left edge, in a design whose whole
   grammar is left edges" — the right-aligned value column was the last of them,
   and in a two-up it would leave a ragged gutter down the middle as well. */
.col-house dd{text-align:left;font-weight:500;color:var(--ink)}
/* ⚠ A LINK HAS TO LOOK LIKE ONE. `border-bottom:none` here left
   seth@sethparker.net, @sethparkerstudios and /in/parkerstudios visually
   identical to the plain "Nashville, TN" beside them — colour, weight and all.
   The hairline comes back, in --ink-dim rather than --ink-faint: measured on
   board, ink-faint is 2.51:1 and under the 3:1 non-text floor this file already
   flags for that token, while ink-dim is 5.53:1.
   ⚠ 2026-08-12: was `border-bottom:1px solid var(--ink-dim)`. `.col-house .hr`
   ALSO carries its own `border-bottom` (the row hairline, added the same day —
   ":1830, the hairline belongs to the ROW instead of being hung on the
   anchor"), and nobody removed this one when that landed: MEASURED at 1440px,
   every linked row painted two horizontal rules 10px apart — the link's own,
   tight under the text, and the row's, at the padded edge. Seth: "does that
   really fit?" It doesn't — two rules read as one divider fighting itself.
   `text-decoration` is the same device `.col-tour a` (:1894) already uses for
   an identical job: it hugs the text instead of sitting parallel to the row's
   own line, so the two no longer compete. Same --ink-dim, so the 5.53:1
   contrast this note already measured is unchanged. */
.col-house dd a{color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;text-decoration-color:var(--ink-dim)}

/* the two fine-print lines under the imprint block */
/* Re-set for the imprint column: left, not centred, and it takes the space the
   `.status` line used to hold open with margin-top:auto. */
.col-pubs{margin-top:20px;font-family:var(--liner);font-style:italic;
  font-size:.9375rem;line-height:1.5;color:var(--ink-dim);max-width:30rem}
.col-imprint{margin-top:22px;text-align:center;font-family:var(--gothic);font-size:.75rem;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-dim);text-indent:.16em}
  /* was --ink-faint: 2.55:1 at 12px on board, on all 8 pages. Now 5.53:1. */
.col-imprint .st{color:var(--tomato);margin:0 10px}
/* MEASURED, not guessed. Three columns hold clean to 900 (one nav label wraps).
   At 820 four of six nav labels wrap; at 768 the contact list's `auto 1fr` grid
   can no longer fit "seth@sethparker.net" and the page gains a HORIZONTAL
   SCROLLBAR. The house column goes full width first, then everything stacks.
   `overflow-wrap:break-word` on the values is the belt to those braces — an address
   is the one string here with no space to break at. */
.col-house dd{overflow-wrap:break-word}
/* ⚠ THE TOUR LIST IS A STRIP NOW — 2026-08-12. Inside the house column it had
   383px and wrapped to two lines, 60px of the 354px that set the colophon's
   height. Across the foot it has ~1350px and sets on ONE, and a run of place
   names with stars between them is already a STRIP in this system — it is what
   the masthead's service-area line and `.bnd.feat` both are. It also stops
   "Nashville, TN", the tour list and "PRINTED IN NASHVILLE, TENN." from
   stacking as three claims about one city inside a single column (§10). */
.col-tour{grid-column:1 / -1;background:var(--paper-2);
  padding:11px 22px;text-align:center;
  font-family:var(--gothic);font-size:.8125rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-dim);text-indent:.14em;line-height:1.7}
.col-tour i{font-style:normal;color:var(--tomato)}
/* the cities link to their stop; the reach has nowhere to go and stays type */
.col-tour a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;text-decoration-color:var(--ink-faint)}
.col-tour a:hover{color:var(--ink);text-decoration-color:var(--ink)}
.col-tour .reach{color:var(--ink-dim)}
/* ⚠ 2026-08-12: `:701px+ .colophon a{display:inline-block;min-height:44px}`
   (this file, the tap-target pass) was written for the contact list —
   "the colophon's contact links measured 20px tall" — but `.colophon a`
   catches every anchor in the footer, including these. Each city name became
   its own 44px inline-block chunk sitting inside a sentence meant to wrap as
   plain text; MEASURED at 1100px, the strip's two wrapped lines landed 26px
   apart instead of the ~7px line-height:1.7 leading actually calls for, which
   is what read as "not centered" — the box wasn't stretched, its own content
   was lumpy. `.col-tour .cities a` (specificity 0,2,1) beats `.colophon a`
   (0,1,1) regardless of source order, so this cancels it back to plain inline
   for just these links. Not a tap-target regression: WCAG 2.5.8 explicitly
   exempts "a target in a sentence or block of text," which is exactly what a
   city name inside this strip is — the same exemption every other inline
   link in the site's body copy already relies on. */
.col-tour .cities a{display:inline;min-height:auto;line-height:inherit}

/* ═══ THE SLUG — the colophon as a printer's imprint ══════════════════════
   2026-08-15, Seth, direction C of the "Colophon Cutdown" study. One plate,
   centred, four lines, replacing the three-plate colophon above. Everything
   from `.colophon` down to here still loads: `.col-block`, `.col-tour` and
   `.col-imprint` are all still emitted and still want those rules. What is now
   DEAD is every rule naming `.col-top`, `.col-id`, `.col-nav`, `.col-house` or
   `.col-pubs` — the markup no longer emits those elements, so they match
   nothing. They are left in place deliberately: `return false;` on the slug is
   not a rollback (the markup changed too), so the only honest rollback is this
   file's history, and gutting ~200 lines of measured commentary would take the
   reasoning with it. Cut them in a dedicated pass, not as a side effect.

   ⚠ THE TAP FLOOR IS SET HERE, AT EVERY WIDTH, AND ON PURPOSE. The shared
   `.colophon a{min-height:44px}` pass lives inside `@media (max-width:700px)`
   (:2423), so above 700 it does nothing — the old contact list cleared 44px
   from its own row padding instead. A run of inline acts has no such padding,
   so the slug sizes its own chips and depends on neither. gate.mjs checks BOTH
   dimensions, so the horizontal padding is as load-bearing as the height:
   "News" is the narrowest act at ~40px of type, and 2x14px of padding is what
   carries it over the line. Do not trim that padding to tighten the run. */
.colophon.slug-foot{padding-bottom:44px}
/* ⚠⚠ THE SLUG WEARS NO KEYLINE — 2026-08-15, Seth, from the "Colophon Refit"
   study (mockups-…/colophon-refit-2026-08-15/options.html, direction B of three).
   `.col-block` still carries the grid, but its ink ground, its 3px border and
   its 1px outline are OFF here, and both halves of that are measured:

   1. THE GROUND HAD NOTHING LEFT TO DRAW. `.col-block{background:var(--ink)}`
      (:1889) is the §2b split mechanism — ink showing THROUGH the 3px gaps
      between three plates. The slug is one plate. The gaps are gone, so the
      ground only ever reached the border, and the border is the problem below.
   2. THE BORDER WAS THE TICKET'S BORDER, DRAWN AGAIN. MEASURED at 1440:
      `.frame`, `.b-tkt`, `.col-block` and `.col-imprint` all trim at 22 → 1418.
      `border:3px solid ink` + `outline:1px solid ink` at 5px offset IS the
      `.frame` grammar (:59) and IS the ticket's (:1289) — so on the four
      templates that carry a ticket (front-page, single-location, page-contact,
      taxonomy-portfolio_category) the sheet drew that keyline twice, 44px apart,
      the second time around fine print. DESIGN-TRUTH's Addendum C is explicit:
      the colophon is board stock, a printer's imprint, "so the ticket is the
      only dark object at the end of a sheet." A keyline is what makes an object.

   ⚠ `background:var(--paper)` STAYS on `.slug` on purpose. It is the same value
   the body already paints, so it changes nothing today — it is there so the
   imprint keeps its own stock if anything above it is ever tinted. Do not
   "simplify" it to transparent.
   ⚠ Padding came 34/26 → 30/22 in the same pass: the top pad was set against a
   border that no longer exists. The ≤700 override at :2121 is UNTOUCHED and
   still wins there — it is later in source at equal specificity. */
.colophon.slug-foot .col-block{grid-template-columns:1fr;
  background:transparent;border:0;outline:0}
.slug{background:var(--paper);color:var(--ink);padding:30px 32px 22px;
  display:flex;flex-direction:column;align-items:center;text-align:center}
/* ⚠ Alfa Slab, 2026-08-15, and sized off ITS OWN small line, not the masthead's.
   `.slug .wm small` is .6875rem/.3em = 201.4px; Alfa Slab is 190.8px at 24px,
   so 201.4/190.8 × 24 = 25.3px = 1.5625rem (measures 198.8). The text-indent
   that corrected Anton's .09em trailing track is gone with it — at .005em the
   optical shift is an eighth of a pixel and the line is centred. */
/* The device + the wordmark are ONE centred object; the type inside it sets
   left, against the mark, exactly as it does in the masthead. `.slug` is a
   centred flex column, so an inline-flex child centres itself. */
.slug-id{display:inline-flex;align-items:center;gap:14px;text-align:left}
.slug-id .mk{height:46px;width:auto;flex:none;color:var(--tomato);
  fill:currentColor;fill-rule:evenodd}
.slug .wm{font-family:var(--slab);font-size:1.5625rem;letter-spacing:.005em;
  text-transform:uppercase;line-height:1;color:var(--ink)}
.slug .wm small{display:block;font-family:var(--gothic);font-size:.6875rem;
  letter-spacing:.3em;color:var(--tomato-text);margin-top:7px;text-indent:.3em}
/* ⚠ THIS LINE IS `booking_status`, AND THE MASTHEAD ALREADY PRINTS IT — 2026-08-15.
   `.bill-top .desk .r1` (:82) sets the SAME FIELD in the same Caslon italic at the
   top of every page, in --tomato-text. Shipped in 1.9.102 as --pine, which made the
   sheet say one sentence twice in two inks. Two more reasons it could not stay:
   DESIGN-TRUTH §7 makes pine the MISREGISTER SHADOW (`Npx Npx 0`, no blur, cast
   behind a letterform) — across its 38 uses in this file it is a text-shadow, a
   background, a box-shadow or a small ornament, and this was the only place on the
   site it set running type. The Addendum's rule B makes pine the NAVIGATE ink, and
   a booking status is the opposite of navigate.
   ⚠ It was never a contrast fault, so do not "restore" it on those grounds:
   MEASURED on --paper, pine is 7.37:1 (the figure §7 itself quotes) and
   --tomato-text is 5.55:1. Both clear 4.5. This was grammar. */
.slug-status{margin:13px 0 0;font-family:var(--liner);font-style:italic;
  font-size:1rem;color:var(--tomato-text)}
/* the ticket's own die-cut, same 7/14 pitch as .t-stub .t-act::before */
/* ⚠ THE RULE TAKES THE MEASURE OF ITS TYPE, NOT THE TRIM OF THE SHEET — 2026-08-15.
   It was `align-self:stretch`. MEASURED at 1440 that made it 1326px over an acts
   run of 771, a contact line of 671 and a tour line of 605 — the widest thing under
   it filled 58% of it. Inside the retired keyline that read as a box that failed to
   fill; with the keyline off it read as a rule overshooting its type. 820px is the
   acts run plus ~25px of air at each end.
   ⚠ THIS ADDS NO BREAKPOINT, which is the whole reason it is `min()` and not a
   media query: at 390 the run already measures 304px = 100% of the column, so
   min() resolves to 100% and every width below ~884 is byte-identical to before.
   The number moves only if an act is renamed — re-measure `.slug-run` width, do
   not eyeball the rule. */
.slug-rule{height:3px;align-self:center;width:min(100%,820px);margin:20px 0 4px;
  background:repeating-linear-gradient(to right,var(--ink) 0 7px,transparent 7px 14px)}
/* ⚠ INLINE LAYOUT, NOT FLEX, AND THAT IS THE WHOLE POINT. These were flex rows
   first. Flexbox wraps every child independently and ignores source whitespace,
   so each star became its own wrappable item — MEASURED at 390, the run came out
   as "PORTFOLIO ★ CASE STUDIES ★ AWARDS / ★ NEWS ★ LOCATIONS ★ ABOUT ★", with an
   orphaned separator starting one line and another dangling off the end of it.
   Inline layout puts the break opportunities back under the markup's control,
   and the walker glues each star to the act before it (inc/bigbill.php), so a
   line can only ever break AFTER a star. `line-height:1` keeps the 44px chips
   from also inheriting body leading and stacking the wrapped rows too far apart. */
.slug-run{display:block;text-align:center;line-height:1}
.slug-run a{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 14px;font-family:var(--gothic);font-size:.9375rem;
  letter-spacing:.11em;text-transform:uppercase;color:var(--ink);text-decoration:none}
.slug-run a:hover{color:var(--tomato-text)}
.slug-run a:focus-visible{outline:3px solid var(--pine);outline-offset:-3px}
.slug-run i{font-style:normal;color:var(--tomato);font-size:.6875rem}
.slug-contact{margin:2px 0 0;display:block;text-align:center;line-height:1}
.slug-contact a{display:inline-flex;align-items:center;min-height:44px;padding:0 11px;
  font-family:var(--liner);font-size:1rem;color:var(--ink);
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;
  text-decoration-color:var(--ink-faint)}
.slug-contact a:hover{text-decoration-color:var(--ink)}
.slug-contact a:focus-visible{outline:3px solid var(--pine);outline-offset:-3px}
.slug-contact .sep{color:var(--ink-faint)}
/* inside the slug the tour line is a dateline, not a tinted strip of its own —
   the plate it used to sit under is gone, so the tint has nothing to divide */
.slug .col-tour{background:transparent;padding:10px 0 0;margin:0;text-align:center}
@media (max-width:700px){
  .slug{padding:26px 18px 22px}
  /* ⚠ The lockup measures 252.3px at a 46px mark, against ~256px of slug inner
     width at 390 — 4px of slack is not a margin, it is luck. Dropping the mark
     to 38px and the gap to 11px buys ~8px back, and as a bonus takes the mark
     under the 43px wordmark block so it costs 0px of height instead of 3px. */
  .slug-id{gap:11px}
  .slug-id .mk{height:38px}
  /* ⚠ NO `.slug .wm` override here on purpose. `.slug .wm small` does not
     change below 700, so shrinking the name would re-open the very overhang
     1.5625rem was derived to close. The wide line is the small one (201.4px)
     and it already fits the slug's ~256px inner width at 390. It used to be
     1.25rem here, back when the name was Anton and nothing was matched. */
  .slug-run a{padding:0 11px;font-size:.875rem}
  .slug-contact a{padding:0 9px;font-size:.9375rem}
  .slug-run a{padding:0 13px}
  .slug-contact a{padding:0 12px}
}
/* ⚠⚠ TWO DERIVED BREAKPOINTS, AND THEY ARE NOT THE SAME NUMBER — measured on
   staging, not chosen. A separator only does work between two items on the SAME
   line. Glueing each one to the item before it (PS_Slug_Walker) already stops a
   star ever STARTING a wrapped line, but the moment a run wraps at all the
   separator before the break just dangles off a line end. So each run drops its
   punctuation at exactly the width where it stops fitting on one line, and the
   44px chips become their own separation.
     acts run  — one line down to 896, wraps at 880  ->  hidden at 895 and below
     contact   — one line down to 788, wraps at 784  ->  hidden at 787 and below
   The gap between them is real: the seven acts are much longer than four contact
   values, so between 788 and 895 the acts are already stacked while the contact
   line is still legitimately one line with dots doing work.
   ⚠ These move if an act is renamed or a contact row is added. Re-measure with
   `Math.round(el.getBoundingClientRect().height / 44)` on .slug-run and
   .slug-contact — a wrapped run is exactly 2 chips tall, so line count is the
   test, not eyeballing. Stars stay on the tour and imprint lines at every width;
   both still set on one line down to 390. */
@media (max-width:895px){ .slug-run i{display:none} }
@media (max-width:787px){ .slug-contact .sep{display:none} }

/* ⚠⚠ BELOW THE TWO-UP TIER THE PAIR GOES BACK SIDE BY SIDE — 2026-08-12, and
   this is a REGRESSION FIX found by measuring before against after rather than
   assuming the new layout was better everywhere.
   Stacking the label over its value costs height (18px label + a 44px tap
   target instead of one 44px row) and only PAYS when it buys a second column.
   The two-up needs a ~500px track, which the colophon only has above ~1000.
   MEASURED with the stacked pair running all the way down:
     1440 500→451 ✓   1280 522→527   1180 522→571   1024 568→704
      960 545→620    940 940→1082    768 940→1104    390 1297→1469
   — up to +172px on a phone, to fix a footer that was too tall. So below 1001
   the ledger returns to `auto 1fr`, one row per pair, exactly as it set before.
   The Anton label VOICE stays; only the arrangement changes, so the column
   reads as one design at both shapes. `.hr` goes `display:contents` so the
   wrapper the two-up needs does not become a row of its own here. */
/* ⚠ 1250, and the number is derived, not rounded. The two-up needs ~145px per
   track because "seth@sethparker.net" is an unbreakable 143px token — the same
   constraint the ticket's ledger hits at 1320. With the 5fr weight the house
   content box is `(viewport − 56)/3 − 64`, so two 145px tracks plus the 30px
   gap need a ~1208px viewport; 1250 is that with margin.
   MEASURED at 1024 with this boundary at 1000: tracks computed 133px, the
   address wrapped to three lines, and the colophon went 568 → 704. */
@media (max-width:1250px){
  .col-house dl{grid-template-columns:auto 1fr;column-gap:18px;row-gap:10px}
  .col-house .hr{display:contents}
  .col-house dt{align-self:center}
  .col-house dd{text-align:right}
  /* ⚠ 2026-08-12: was `border-bottom:1px solid var(--ink-faint)` — 2.51:1,
     under this file's own 3:1 non-text floor (:1861). `.hr` is
     `display:contents` in this tier so the row hairline above doesn't render
     here and there was never a doubling to dodge; the faint color looks like
     it was chosen for that reason, but it just left the link under-contrast
     instead. Matches the base rule now: text-decoration, --ink-dim, 5.53:1. */
  .col-house dd a{text-decoration:underline;text-decoration-thickness:1px;
    text-underline-offset:3px;text-decoration-color:var(--ink-dim)}
}

/* ⚠ below 1251 the strip drops into the house column's own spare board — and
   the other two columns must SPAN both rows or the strip is still a row of its
   own. MEASURED without the span: +127px, worse than the full-width strip it
   was meant to beat, because `.col-id` and `.col-nav` stayed in row 1 and the
   block's height became row1 + 3 + strip. With the span the block is
   max(imprint, bill, house + 3 + strip), and the house has ~190px of spare. */
@media (max-width:1250px){
  .col-id,.col-nav{grid-row:1 / span 2}
  .col-house{grid-row:1}
  /* ⚠ TIGHT IN THE TUCKED STATE. MEASURED at 1180 at the full-width settings:
     the strip ran 141px inside a 360px column and became the thing that set the
     colophon's row height (house 323 + 3 + 141 = 467 against the bill's 394).
     In the column it is fine print at the foot of a directory, not a strip
     across a sheet, so it sets like fine print.
     ⚠ 2026-08-12: `align-self:center` added. This cell sits in ROW 2 of a
     track sized by `.col-id`/`.col-nav`'s spanned height (that's the "spare
     board" the note above describes), not by its own content — a grid item
     defaults to `align-self:stretch`, so the box was filling that full track
     top-anchored. MEASURED at 1100px: a 112px-tall cell holding one line of
     padded text, 17.5px above it and 32.5px below — not the symmetric 11/13px
     padding the rule declares, because the padding was never the thing
     controlling the gap. `center` shrinks the box back to its own content
     height and centers THAT within the track, so the 11/13 padding (its own
     small optical asymmetry, unrelated to this) is what shows again. */
  .col-tour{grid-column:3;grid-row:2;align-self:center;text-align:left;padding:11px 32px 13px;
    font-size:.75rem;letter-spacing:.08em;line-height:1.6;text-indent:0}
}
@media (max-width:940px){
  .col-block{grid-template-columns:1fr 1fr}
  /* ⚠ the row spans from the 1250 tier MUST be released here, or they fight the
     stack: measured with them left on, the colophon read 764px at 768 and
     1950px at 390 — both wrong, in opposite directions. */
  .col-id,.col-nav,.col-house,.col-tour{grid-row:auto}
  .col-house{grid-column:1 / -1}
  .col-tour{grid-column:1 / -1;text-align:center;padding:11px 22px;line-height:1.7}
}
@media (max-width:660px){
  .col-block{grid-template-columns:1fr}
  .col-id .status{margin-top:20px}
}


/* ⚠ THE BIN IS A SEPARATE OBJECT ON THE SHEET, 2026-08-12 (Seth: "should be its
   own section with spacing between it and the section above it and the one
   below"). Measured before: `.frame` ended at y=2010 and `.bin` began at y=2010,
   and the bin ended at 5469 with sheet two starting at 5468 — 0px on both seams.
   There WAS a rule (the frame's own 3px border) but no air, so the night stock
   read as a colour change rather than as a different object.
   It now takes the frame's exact furniture — 3px border plus the 1px keyline at
   6px offset — and the sheet's own 22px of padding as margin, so paper shows
   above and below it and the bin reads as a sibling of the frame rather than a
   bleed out of it. */
.bin{background:var(--night);padding:96px 48px 110px;position:relative;overflow:visible;
  /* margin-bottom 0: sheet two's own 22px of padding already supplies the
     lower gap, and 22+22 measured 44px against 22 at the top. */
  margin:22px 0 0;border:3px solid var(--ink);outline:1px solid var(--ink);outline-offset:5px}
.bin>*{max-width:1516px;margin-left:auto;margin-right:auto}

/* ============ GOLD / PLATINUM ============ */
/* The plaque wall (walnut/brass gradients) was retired 2026-08-09 — replaced by the
   chart-topper singles + Certificate of Record, styled locally in certified.html.
   Gold/platinum are flat inks: --gold-ink/--gold-deep/--platinum-ink/--platinum-deep. */

/* ============ CONTACT SHEET (From the field / IG) ============ */

/* ============ THE BOOKING SHEET (services) ============ */

/* ============ Q&A (FAQ) ============ */
/* The FAQ is a <dl> as of 2026-08-11 so it matches the live theme's port target
   (ps_faq_pairs -> <dl class="faq"><dt>/<dd>, front-page.php:181-193) and so the
   Q&A is in the element the content actually is. The old .item wrapper is gone;
   `break-inside` moves to the dt+dd pair. A <dt> cannot be split from its <dd>
   across a column with a wrapper absent, so the dt carries break-after:avoid and
   the dd carries break-before:avoid — together they behave like the old .item.
   The "Q." marker is a ::before, NOT markup: an ACF question string must not have
   to carry decoration. */
.qa{margin:0 44px;position:relative;z-index:2;columns:2;column-gap:50px}
.qa dt{break-inside:avoid;break-after:avoid;border-top:2px solid var(--ink);padding:16px 0 0;
  font-family:var(--gothic);font-size:1.125rem;letter-spacing:.06em;text-transform:uppercase;
  line-height:1.25}
.qa dt::before{content:"Q.";font-family:var(--liner);font-style:italic;color:var(--tomato-text);
  margin-right:8px;text-transform:none}
/* ⚠ 2026-08-12: `.qa.noq` — The Honours reuses `.qa`'s dt/dd layout for
   awards, not questions; "Q." ahead of an award name is wrong content, not
   a look. Scoped to the class, not to `.b-plate .qa`, on purpose: The
   Advance sits inside a `.b-plate` too and its "Q." is correct there. */
.qa.noq dt::before{content:none;margin-right:0}
.qa dd{break-inside:avoid;break-before:avoid;margin:8px 0 0;padding:0 0 22px;
  font-size:.9375rem;color:var(--ink-dim)}
.qa dd b{color:var(--ink);font-weight:500}

/* ============ ABOUT bits ============ */
.rider{border:3px solid var(--ink);background:var(--paper-2);padding:24px 28px}
.rider .caps{display:block;color:var(--tomato);margin-bottom:12px}
.rider ul{list-style:none}
.rider li{display:flex;gap:12px;align-items:baseline;padding:8px 0;border-bottom:1px solid var(--rule);font-size:.9375rem}
.rider li:last-child{border-bottom:none}
.rider li .st{color:var(--tomato)}
.rider li b{font-weight:600}

/* ---------- photoplate hero (the committed treatment) ---------- */
.photoplate{position:relative;border:4px solid var(--ink);overflow:hidden;
  box-shadow:0 0 0 7px var(--paper),0 0 0 8px var(--ink),10px 10px 0 rgba(33,28,22,.16)}
.photoplate img{width:100%;height:470px;object-fit:cover;object-position:center 42%;display:block}
.rev-bar{background:var(--ink);color:var(--paper);display:flex;justify-content:center;gap:22px;
  align-items:baseline;padding:11px 16px;margin-top:8px;
  font-family:var(--gothic);font-size:1.06rem;letter-spacing:.14em;text-transform:uppercase}
.rev-bar i{color:var(--tomato);font-style:normal}
.rev-bar .y{color:var(--mustard)}



.bill4{margin:0 44px;display:grid;grid-template-columns:repeat(4,1fr);gap:22px;position:relative;z-index:2}
/* `.b4` card anatomy RETIRED 2026-08-12 — the engagements are the runsheet
   (`.eng-run`, with the .b-eng note ~:720). front-page.php was its only
   emitter (grepped); the 1.9.91 file holds the rules if ever needed. */

/* ---------- deep cuts: flat singles, vinyl peeking ---------- */
.rack{margin:0 44px;position:relative;z-index:2;padding:20px 0 0}
/* wrap 2026-08-10: a CENTRED flex row that cannot wrap overflows BOTH edges, so
   the singles put a horizontal scrollbar on home below ~1268px. No-op at 1440,
   where the shelf still holds one line. Proper fix comes with the Deep Cuts
   section rebuild; this only stops the page scrolling sideways. */
.rack-shelf{display:flex;flex-wrap:wrap;justify-content:center;gap:44px 58px}
.cut{position:relative;width:186px;flex:none;background:var(--paper);border:2px solid var(--ink);
  padding:7px;box-shadow:5px 5px 0 rgba(33,28,22,.14)}
.cut .ph{position:relative;z-index:2;background:var(--paper)}
/* 2026-08-11: was height:164px, which at a 140px thumb rendered 0.854:1 — off
   every system, and it was cropping 3:2 assets by 43%. This rack is the SINGLES
   rack, and a single is square: 1:1, which is also one of the three canonicals. */
.cut .ph img{width:100%;aspect-ratio:1/1;height:auto;object-fit:cover;display:block;
  border:1px solid var(--ink)}
.cut .mini{position:absolute;top:50%;right:-24px;transform:translateY(-50%);width:80%;aspect-ratio:1;
  border-radius:50%;z-index:1;
  border:2px solid var(--ink);
  background:radial-gradient(circle,var(--tomato) 0 13%,transparent 13%),
    repeating-radial-gradient(circle,var(--ink) 0 1.6px,var(--night) 1.6px 3.2px);
  box-shadow:4px 4px 0 rgba(33,28,22,.16);transition:transform .22s ease}
/* ⚠ 2026-08-12 — Seth: on hover, the disc slides a few px further out of the
   sleeve, and back in on hover-out. `:focus-visible` gets the same move, so a
   keyboard visitor tabbing through the rack sees the identical affordance a
   mouse hover gets, not a dead end. 4px, not more — the six-up gutter (:4425,
   :4454) was widened to fit exactly this and no further. */
.cut:hover .mini,.cut:focus-visible .mini{transform:translate(4px,-50%)}
@media (prefers-reduced-motion:reduce){.cut .mini{transition:none}}
.cut .s45{position:absolute;left:11px;top:11px;z-index:3;background:var(--tomato);color:var(--paper);
  border:1px solid var(--ink);font-family:var(--gothic);font-size:.5625rem;letter-spacing:.1em;
  padding:2px 6px;text-transform:uppercase}
.rack-base{margin:30px 44px 0;display:flex;justify-content:center;gap:40px;align-items:baseline}
.rack-base .l{font-family:var(--gothic);font-size:.875rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-dim)}
.rack-base .l b{color:var(--tomato);font-weight:400}

/* ---------- the gatefold: AR-honest justified rows ---------- */
.gate{display:flex;flex-direction:column;gap:18px;position:relative;z-index:2}
.gr{display:flex;gap:18px}
/* R9 APPLIED 2026-08-10 (evening): the 3px --ink border was 1.02:1 on night —
   no border at all — and the 30px blur was the soft shadow this world bans.
   The 1px paper keyline was always doing the visible work; it is the declared
   edge now (outline at 6px offset = the exact geometry the shadow rings drew). */
.gp{position:relative;overflow:hidden;background:var(--night);min-width:0;
  flex-grow:calc(var(--ar)*1000);flex-basis:0;aspect-ratio:var(--ar);
  /* ⚠ K4, 2026-08-12 (Seth). Was `1px solid var(--paper)` at a 6px offset:
     paper on night measures 15.2:1, the hardest contrast in the palette, on 24
     tiles, floating clear of each photograph so every image carried TWO visible
     edges. The eye read a grid of bright rectangles and the photographs came
     second. Tested five ways against the wall: with no keyline at all the
     dark-edged photographs dissolve into the night ground, so the line's job is
     real — it is the FLOAT that made it loud. Line back on the photograph's own
     edge, volume halved: 55% paper measures 5.5:1. */
  outline:1px solid rgba(246,241,229,.55);outline-offset:0}
.gp img{width:100%;height:100%;object-fit:cover;display:block}
.gp .tab{position:absolute;left:18px;top:-2px;z-index:3;background:var(--tomato);color:var(--paper);
  border:2px solid var(--ink);padding:8px 20px;font-family:var(--gothic);font-size:1.19rem;
  letter-spacing:.12em;text-transform:uppercase;transform:rotate(-1.4deg);box-shadow:4px 4px 0 rgba(0,0,0,.35)}
.gate-cta{margin-top:26px;position:relative;z-index:2;background:var(--paper);border:3px solid var(--ink);
  display:flex;align-items:center;justify-content:space-between;gap:30px;padding:20px 28px}
.gate-cta .big{font-family:var(--gothic);font-size:1.625rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.gate-cta .big i{font-style:normal;color:var(--tomato)}
.gate-cta .sub{font-family:var(--liner);font-style:italic;font-size:1rem;color:var(--ink-dim)}
/* pine, not tomato: this button NAVIGATES (to the-wall) — law 8, tomato books */
.gate-cta a{flex:none;font-family:var(--gothic);font-size:1.19rem;letter-spacing:.1em;text-transform:uppercase;
  background:var(--pine);color:var(--paper);border:3px solid var(--ink);box-shadow:4px 4px 0 var(--ink);
  padding:13px 26px}


/* ---------- sticky book stub ---------- */
.sticky-stub{position:fixed;right:20px;bottom:20px;z-index:60;background:var(--tomato);color:var(--paper);
  border:3px solid var(--ink);box-shadow:4px 4px 0 var(--ink);font-family:var(--gothic);
  font-size:1rem;letter-spacing:.1em;text-transform:uppercase;padding:12px 20px}
/* .foot-contact / .foot-rule / .foot-pubs RETIRED 2026-08-10 — see .colophon. */

/* ===== SEMANTIC LAYER, 2026-08-11 =========================================
   The build had ONE <h1> and one <h2> per page: every zone title was
   <div class="lbl"><b>, so the whole information architecture the band system
   spent 57 bands constructing was invisible to assistive tech AND to crawlers.
   A screen-reader user pressing H on the 8,681px home page got two stops.
   The plate label is now an <h2> and the poster names are <h3>s. Every .lbl
   selector was already class-based with no element binding, so this is a
   semantic change with no visual one — these rules only neutralise the UA's
   default heading margin and weight. Done BEFORE the port on purpose: once ACF
   field names are frozen this becomes a schema migration instead of an edit. */
.lbl h2,.lbl h3,.mp h2,.mp h3{margin:0;font-weight:400}
/* the skip link: first focusable on every page, visible only on focus */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--ink);color:var(--paper);
  font-family:var(--gothic);font-size:1rem;letter-spacing:.12em;text-transform:uppercase;
  padding:14px 22px;text-decoration:none}
.skip:focus{left:8px;top:8px;outline:3px solid var(--mustard);outline-offset:3px}
/* GLOBAL FOCUS RING. Before this there was exactly ONE :focus-visible rule in
   70k of CSS (.b-tkt .go). The UA default ring measures 1.18:1 against the
   tomato "Book a Session" nav chip — invisible on the primary conversion
   element.

   ⚠ CORRECTED 2026-08-12. The sentence that used to sit here — "Mustard clears
   3:1 on paper, ink, tomato AND night" — was wrong on three of its four
   grounds. Re-measured:

       mustard / ink     9.21    ✔        mustard / tomato   2.76   ✘
       mustard / night   9.35    ✔        mustard / paper    1.63   ✘
                                          mustard / paper-2  1.48   ✘

   So the ring was invisible on the majority of the site — every bill link,
   colophon link, filter chip and taper link sits on paper. One ink cannot do
   this job, because no single value clears 3:1 against both paper (15:1 wants
   ink) and ink (9:1 wants mustard).

   TWO CONCENTRIC RINGS, one rule: an ink ring on the element edge and the
   mustard ring 3px outside it. Whichever ground the control sits on, one of
   the two is always the contrasting one — ink reads on paper (15:1), paper-2
   (13.6:1) and tomato (3.34:1); mustard reads on ink (9.21:1) and night
   (9.35:1). No blur on either, so §6 holds. */
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible,
select:focus-visible,[tabindex]:focus-visible{
  outline:3px solid var(--mustard);outline-offset:3px;
  box-shadow:0 0 0 3px var(--ink)}

/* ===== ANCHOR SLOT ON EVERY GALLERY FRAME, 2026-08-11 =====================
   The live theme wraps every grid image in <a class="pf-item pf-zoom"> and
   interactions.js initLightbox() gives prev/next/counter/Esc/swipe. The mockups
   had 73 of 73 photographs outside any <a>, so porting them as-is would have
   DELETED a feature that ships today. The chassis now carries the slot; at port
   the href becomes the 1536px size and the class picks up the existing JS.
   Anchor is display:block and fills the tile so nothing about the justified
   grid or the aspect-ratio boxes changes. */
.gp .pf-zoom,.pgp .pf-zoom,.shots .pf-zoom{display:block;width:100%;height:100%}
.gp .pf-zoom img,.pgp .pf-zoom img{width:100%;height:100%;object-fit:cover;display:block}
.shots .pf-zoom img{width:100%;height:auto;display:block}

/* ===== THE MOBILE PASS, 2026-08-11 ========================================
   THE DEFECT THIS FIXES, measured before the change: six of eight pages were
   clipping 309-466px of live content at 360-390px wide — silently. Not a
   horizontal-scroll bug: `.frame{overflow:hidden}` swallowed it, so the page
   reported "no horizontal scroll" *because* the text was gone. Any check that
   reads only documentElement.scrollWidth passed this suite while it lost
   content on the majority of traffic. (The project's own law: a green metric
   is not a render.)

   ROOT CAUSE: five chassis hard-code a 250px first column and none of them
   collapsed - .b-plate :121, .b-rows :186, .b-brief :240, .b-under :290,
   .bin-head :567 - plus two page-local forks (.b-adm, .b-proof) and the
   home-only .eng4 / .g-row. At 390px the frame's inner box is 340px while
   .b-plate computed `250px 438px`: the entire prose column was off-screen.

   THE FIX is one shared breakpoint, because the failure was uniform. Modelled
   on the @media (max-width:940px) ticket block above, which was already
   correct - its tear and deckle verifiably survive the stack. */
@media (max-width:700px){
  /* the plate stops being a left edge and becomes a banner above its field */
  .b-plate,.b-rows,.b-brief,.b-under,.bin-head,.b-adm,.b-proof{
    grid-template-columns:1fr}
  .b-plate>.lbl,.b-rows>.lbl,.b-brief>.lbl,.b-under>.lbl,.bin-head>.lbl,
  .b-adm .lbl,.b-proof .lbl{
    grid-column:1 / -1;min-height:0;padding:18px 22px;
    align-items:flex-start;text-align:left}
  /* ⚠ 2026-08-15 — Seth, home on a phone: "'In print' should be centered."
     The rule above turns EVERY plate label into a left-set banner at phone width.
     That is right for a plate standing over left-set prose (home's own Services
     runsheet, the city page's Advance, the booking sheet's House Rules) and wrong
     for one standing over CENTRED content. Home's In Print is the case: its field
     carries an inline text-align:center (front-page.php), so the heading was the
     only left-aligned thing in the band and that mismatch is what reads as broken.
     `.mid` is an OPT-IN the template puts on that label; it is deliberately not a
     blanket revert, because the left-set plates are correct as they are. */
  .b-plate>.lbl.mid{align-items:center;text-align:center}
  .b-plate>.lbl h2,.b-rows>.lbl h2,.b-brief>.lbl h2,.bin-head>.lbl h2{font-size:1.4rem}
  .b-brief>.lbl{grid-row:auto}
  .b-plate>.field,.b-brief .notes,.b-brief .filing,.b-under>.field,.bin-head>.field{
    padding:22px}
  /* ⚠ 2026-08-15 — Seth, home on a phone: "font size of published names should
     drop quite a bit because the stars are big and distracting."
     MEASURED at 390 before this rule: .maj names 32px with a 22.4px star and 9px
     of air either side of it. The star is set at .7em OF THE NAME (:955), so it
     scales WITH the billing tier — on a 1440 sheet that is a proportioned
     separator, on a 390 sheet it is punctuation out-shouting the type it
     separates. After: .maj 24px / star 12px, .min 17px / star 8.5px.
     ⚠ Scoped :not(.b-proof) ON PURPOSE. About's In Print and the marquee are
     b-proof bands and already carry their own measured star ladder at :2497,
     :2511, :2523 and :3182; a bare `.st` here outranks all four of them at once.
     Do not "simplify" this selector — that is the bug those four rules document. */
  .b-plate:not(.b-proof)>.field .fr.maj{--fs:1.5rem}
  .b-plate:not(.b-proof)>.field .fr.min{--fs:1.0625rem}
  .b-plate:not(.b-proof)>.field .fr .st{font-size:.5em;margin:0 5px}
  /* ⚠ 2026-08-15 — Seth: "Booking daily and rain dates etc should be centered."
     .feat centres its span as a BOX (justify-content:center, :994) and never set
     text-align at all. That reads as centred only while the line fits on one row.
     MEASURED at 390: the strip wrapped to 2 lines with the span filling the
     container, so the wrapped lines fell back to the inherited left and the band
     went visibly ragged. Centre the TEXT, and give the tracking back a little so
     it has one less reason to wrap in the first place. */
  .feat{text-align:center;padding:11px 16px}
  .feat span{letter-spacing:.1em}
  /* multi-cell rows reflow instead of squeezing */
  .b-rows{grid-template-columns:repeat(2,1fr)}
  .b-rows>.lbl{grid-column:1 / -1}
  /* .b-acts still reflows in step with .b-rows at every tier. The original
     reason (photograph N over numeral N) died 2026-08-12 when The Billing
     left the home sheet, but the tiers stay: they are this band's own
     responsive scheme now, and the measured tap-target fix below predates the
     mirroring reason anyway (at 390 the tracks once computed to 22.5px each
     and the lightbox anchors inside them were 21x14, under the 44px floor). */
  .b-acts{grid-template-columns:repeat(2,1fr)}
  .b-acts>.lbl{grid-column:1 / -1}
  .b-acts>.shot{border-right:none;border-bottom:2px solid var(--ink)}
  .b-frames .shots,.b-frames .caps{grid-template-columns:1fr}
  .b-frames .caps span{border-right:none;border-bottom:2px solid rgba(246,241,229,.55)}
  .b-split,.b-cut{grid-template-columns:1fr}
  /* TOUCH TARGETS: measured 9-24 elements per page under 44px at 390px.
     WCAG 2.5.8 AA floors at 24x24; these were 20px tall. */
  .colophon a,.csrow .go,.b-file a,.t1 a{min-height:44px;display:inline-flex;align-items:center}
  /* the sticky stub overlapped the frame by 164px at 1440 and about a fifth of
     the viewport at 390 - it has no room to earn on a phone */
  .sticky-stub{display:none}
}
@media (max-width:460px){
  .b-rows{grid-template-columns:1fr}
  .b-acts{grid-template-columns:1fr}
}
/* home's Record Bin is the one zone that lives OUTSIDE .frame, so
   `overflow:hidden` never contained it - it is why home was the only page with
   real horizontal scroll below 430px (446px document in a 390px viewport).
   Clip it at the section, and drop the 48px gutters that DESIGN-TRUTH §1 names
   as "the tell of a non-conforming page". */
.bin{overflow-x:clip}
@media (max-width:700px){
  .bin{padding:48px 16px 56px}
  .eng4,.g-row,.pwall{grid-template-columns:1fr}
}

/* the halftone corner is a 420px decoration hung off the top-right at right:-70px.
   On a phone it is wider than the frame, so it alone accounted for the residual
   72-97px of "clip" after the breakpoint above. Decoration, so it goes. */
@media (max-width:700px){ .frame .ht-tr{display:none} }

/* THE MASTHEAD was the last overflow at phone widths: .mast h1 is a fixed
   5.5rem (88px) and .sub-western a fixed 2.4rem. At 390px the frame's inner box
   is ~340px, so "Certified" and "Huntsville" alone ran past the trim — measured
   119px and 231px of overhang after every other collapse had landed. Fluid now,
   with the desktop value as the clamp ceiling so nothing above 700px moves. */
@media (max-width:700px){
  .mast{padding:28px 18px 0}
  .mast h1{font-size:clamp(2rem,11vw,5.5rem)}
  .mast .sub-western{font-size:clamp(1.05rem,5.4vw,2.4rem)}
  .mast .kicker{font-size:.875rem}
  .mast .lede{font-size:1rem}
}

/* THE NAV was the last thing overflowing on all 8 pages at a true 390px — 74px
   past the trim. Six flex items with the default min-width:auto cannot shrink
   below their own min-content, and "Book a Session / the box office" is the
   widest. It wraps now instead: 3-up, then 2-up on the narrowest phones.
   MEASURED at a real 390px viewport via an iframe harness — headless Chrome
   clamps its own minimum window to ~500px, so a --window-size=390 run silently
   reports a 500px layout. Anything checking mobile here must use the harness. */
@media (max-width:700px){
  /* ⚠ 2026-08-11 rev 2: every `.bill-top` and `nav.stub` rule that used to live
     in these two blocks is GONE, superseded by the MOBILE HEADER block at the
     tail of this file (logo + hamburger). They are not merely overridden — they
     were deleted, because leaving a wrapping-grid ruleset in place under a
     drawer design is how the nth-child border rules survived their own removal
     and printed a stray dashed rule down the AWARDS row. */
  .b-strip span{font-size:.95rem;letter-spacing:.18em}
  .b-name{padding:20px 14px 18px}
  .b-name .kick::before,.b-name .kick::after{width:36px}
  .b-name .and::before,.b-name .and::after{max-width:60px}
}

/* Remaining true-390px offenders, measured via the iframe harness. */
img{max-width:100%}                 /* defensive net: no image ever exceeds its column */
@media (max-width:700px){
  /* the index row: 132px year + 1fr bill + 230px frame does not fit a phone */
  .csrow{grid-template-columns:88px 1fr}
  .csrow .frame-cell{grid-column:1 / -1;min-height:0;aspect-ratio:3/2;border-left:0;
    border-top:3px solid var(--ink)}
  .cshead{grid-template-columns:1fr}
  .cshead .frame-cell{grid-column:1 / -1}
  /* grid children must be allowed to shrink below min-content */
  .b-plate>*,.b-rows>*,.b-brief>*,.b-under>*,.bin-head>*,.csrow>*,.b-split>*{min-width:0}
  /* buttons and CTAs wrap instead of pushing the trim */
  .wl-cta a,.gate-cta a,.b-file a,.nav-go{max-width:100%;white-space:normal;word-break:break-word}
  .b-tkt .go{white-space:normal;max-width:100%}
}

/* The name lockup was the last visible overflow at 390px — SEEN, not measured:
   .b-name has overflow:hidden, so it clipped its own Rye line and the frame
   reported nothing. .and span is a fixed 2.65rem; "AND HIS ARCHITECTURAL
   PHOTOGRAPHY" cannot fit 346px at 42px. Rule-level only — the home hero's
   locked markup is never touched. */
@media (max-width:700px){
  .b-name .and{flex-wrap:wrap;gap:10px}
  .b-name .and::before,.b-name .and::after{max-width:44px}
  .b-name .and span{font-size:clamp(1.15rem,6.4vw,2.65rem);text-shadow:2px 2px 0 var(--mustard)}
  .b-name .n{font-size:min(9.1rem,calc(13vw - 12px))}
  .b-name .star{font-size:.8125rem;letter-spacing:.12em;margin-top:12px}
  .b-name .kick span{font-size:1rem}
}

/* About's three forks again, this time by SPECIFICITY rather than source order.
   `.bnd.b-adm` (0,2,0) beats the page-local `.b-adm` (0,1,0) no matter which
   stylesheet loads last — the earlier attempt relied on order and lost to the
   page's own inline block. Same for the index row and the wall CTA. */
@media (max-width:700px){
  .bnd.b-adm,.bnd.b-proof,.bnd.b-cut{grid-template-columns:1fr!important}
  .bnd.b-adm>*,.bnd.b-proof>*,.bnd.b-cut>*{min-width:0;grid-column:auto}
  .bnd.b-adm>.lbl,.bnd.b-proof>.lbl{grid-column:1 / -1;min-height:0;padding:18px 22px;
    align-items:flex-start;text-align:left}
  .bnd.csrow{grid-template-columns:88px 1fr}
  .bnd.csrow>.frame-cell{grid-column:1 / -1}
  .wl-cta a.nav-go,.wl-cta a{max-width:100%;white-space:normal;word-break:break-word;
    display:inline-block;text-align:center}
}

@media (max-width:700px){
  /* the index HEADLINER (not the rows) — .bnd.cshead beats the base .cshead */
  .bnd.cshead{grid-template-columns:1fr}
  .bnd.cshead>.frame-cell{grid-column:1 / -1;min-height:0;aspect-ratio:3/2}
  /* the-wall's cross-sell button is declared in that page's own <style> */
  .wl-cta .nav-go,a.nav-go{max-width:100%;white-space:normal;word-break:break-word;
    display:inline-block;text-align:center;padding-left:18px;padding-right:18px}
  /* DESIGN-TRUTH §8: "a bill never splits an act's name" — .nm is nowrap by law.
     At 390px some firm names simply exceed the trim, so the TIER shrinks rather
     than the name breaking. The law is preserved; only the type size moves. */
  /* ⚠ the bare `.nm` that used to close this list is the ORIGIN of the leak —
     it starts at 940 and the 700/400/340 tiers each compounded it. `.nm` is a
     shared class (the ticket stub's tour list and the portfolio filter chips
     use it too), so an unscoped shrink here reached components that never asked
     for a taper. Measured at 320 before the fix: 9.68px city names and 9.29px
     filter chips, beside 15px labels. Scoped 2026-08-12, all four tiers. */
  .b-adm .nm,.b-proof .nm,.fest .nm,.t1 .nm{font-size:.92em}
  .t1 .nm{font-size:.86em}
  .b-proof .st,.b-adm .st{font-size:.8em}
}

@media (max-width:700px){
  /* the CTA band's own padding was the remaining 35px, not the button */
  .wl-cta{padding-left:16px;padding-right:16px}
  .wl-cta a.nav-go{font-size:1rem;letter-spacing:.08em;padding:14px 16px}
  /* last of the nowrap act names.
     ⚠ THE BARE `.nm`/`.st` WERE HERE TOO — this is the tier that starts the
     leak, and the 400px and 340px blocks below compound it. Scoped 2026-08-12;
     see the note in the 400px block. Fixing only the two narrow tiers would
     have left the ticket stub's tour list and the filter chips shrunk from
     700px down, which is every phone. */
  .b-proof .nm,.b-adm .nm,.t1 .nm{font-size:.84em}
  .b-proof .st,.b-adm .st,.t1 .st{font-size:.72em}
}

/* Narrow-phone tier (iPhone SE / small Android at 360-375px). The 700px block
   does the structural work; this only trims the last few nowrap runs. */
@media (max-width:400px){
  /* ⚠ 2026-08-12: the bare `.nm` and `.st` that used to close these two
     selector lists were unscoped, so the taper's shrink leaked into every other
     component using those classes. Measured at 320: the ticket stub's tour list
     rendered at 9.68px and the portfolio filter chips at 9.29px, beside 15px
     labels. Scoped to the tapers that asked for it. */
  .b-proof .nm,.b-adm .nm,.t1 .nm{font-size:.76em}
  .b-proof .st,.b-adm .st,.t1 .st{font-size:.66em}
  .wl-cta a.nav-go{font-size:.9rem;padding:13px 12px}
  .wl-cta{padding-left:10px;padding-right:10px}
  .colophon a,.colophon .cities{word-break:break-word}
  .b-file a,.gate-cta a{font-size:.9rem}
}

/* ================= THE LEDGER (certified.html) ==========================
   The awards port, 2026-08-11. The poster wall above it is LOCKED and carries
   the awards as marquee shorthand — counts, abbreviations, cluster names
   ("Athenaeum '25", "ID BoY", "AIA Mid-Tenn"). It is the show. This band is the
   RECORD: every juried honour under its full, unparaphrased name, with year and
   credit, exactly as the live About "Receipts" section prints it.

   ⚠ DESIGN-TRUTH §10 ("nothing is said twice") — read before editing. A ledger
   under a poster wall is the one place on this site where restatement is
   deliberate, and the justification is the idiom itself: a Hatch bill puts the
   headliners in wood type and the full date list in fine print beneath. §8
   already sanctions that second register ("deliberate fine print rather than a
   failed display line"). The two are NOT redundant in substance — the posters
   carry no full honour name and no credit line, and R2 established that juried
   honour names cannot be paraphrased. If Seth reads this as saying it twice, the
   fix is to cut the ledger, not to abbreviate it.

   Chassis is the shared (a) plate+field — `bnd b-plate alt`, no fork. `alt` is
   load-bearing: §6 forbids two same-stock regions meeting at a seam and the
   poster band above is `--paper`, so this band must be `--paper-2`.
   PORT: each .lg-row is one ACF repeater row (year / award / credit). */
/* The shared plate centres its label, which is right for a 3-6 line band. This
   band is ~2000px tall, so centring parked "THE LEDGER" near the band's vertical
   middle — far below the first row it names. Top-align instead. NOT sticky:
   DESIGN-TRUTH §9 — printed things do not move. */
.b-ledger>.lbl{justify-content:flex-start;padding-top:30px}
.b-ledger>.field{padding:26px 44px 30px}
.lg{display:grid}
.lg-row{display:grid;grid-template-columns:62px 1fr;gap:0 18px;padding:9px 0;
  border-top:1px solid rgba(33,28,22,.16);align-items:baseline}
.lg-row:first-child{border-top:none}
.lg-yr{font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.06em;color:var(--tomato-text)}
/* the year prints only when it changes — the ledger idiom. The <span> stays in
   the markup for every row so the ACF repeater needs no run-length logic; it is
   the CSS that hides the repeat, and screen readers still hear each year. */
.lg-row.same .lg-yr{visibility:hidden}
.lg-aw{font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.045em;
  text-transform:uppercase;color:var(--ink);display:block;line-height:1.24}
.lg-cr{font-family:var(--serif);font-style:italic;font-size:.9375rem;color:var(--ink-dim);
  display:block;margin-top:2px;line-height:1.34}
.lg-note{font-family:var(--serif);font-style:italic;font-size:.875rem;color:var(--ink-dim);
  margin:16px 0 0;padding-top:12px;border-top:2px solid var(--ink)}

@media (max-width:700px){
  .bnd.b-ledger{grid-template-columns:1fr}
  .bnd.b-ledger>.lbl{grid-column:1 / -1;min-height:0;padding:16px 22px}
  .b-ledger>.field{padding:18px 22px 22px}
  .lg-row{grid-template-columns:46px 1fr;gap:0 12px}
  .lg-aw{font-size:.9375rem;letter-spacing:.03em}
  .lg-yr{font-size:.9375rem}
  .lg-cr{font-size:.875rem}
}

/* ============================================================================
   SYNTHETIC-BOLD REMOVAL — 2026-08-11, with the self-hosting pass
   ============================================================================
   Anton, Alfa Slab One and Rye each ship exactly ONE weight (400). Any
   font-weight above 400 on them does not pick a bolder cut — there isn't one —
   it makes the browser SYNTHESIZE bold by smearing the outline. On a design
   whose whole argument is real ink weight (DESIGN-TRUTH §4 gives each voice one
   job; Anton IS the bold voice) a faked heavier pass is meaningless, and on
   Alfa Slab — already the heaviest thing on the page — it just fills in the
   counters.

   A runtime audit of computed styles across all 8 pages found 54 such elements.
   Almost none were authored: h1/h2/h3 inherit `font-weight:bold` from the UA
   stylesheet, so every page-name lockup was being faked. The build ALREADY
   pinned two of these by hand — `.b-name .n` and `.csrow>.yr b` both carry an
   explicit font-weight:400 — so 400 is the established intent and the rules
   below are the ones that were missed, not a new decision.

   Libre Caslon Text is the exception that proves it: it HAS a real 700 and a
   real 400 italic, but Google ships no 700 ITALIC. `.field .fr.maj` asked for
   italic+700 and got a smeared slant. It drops to 400 so the italic is the real
   drawn one. Size still carries the billing order (§8) — .maj is 2rem against
   .min's 1.31rem, so the taper survives without the fake weight.
   ========================================================================= */
.mast h1{font-weight:400}                 /* the page-name lockup, all 8 pages */
.b-tkt .t-form h2{font-weight:400}        /* "Book the Gig" */
.csrow .bill h3,.csrow .bill h2{font-weight:400}   /* case-study + press names */
.caps{font-weight:400}                    /* Anton, was 500 */
.field .fr.maj{font-weight:400}           /* Caslon italic — no real 700i exists */
h1 .h1-role{font-weight:400}              /* on-tour's subordinate SEO string */
/* About's In Print band is one of that page's four chassis FORKS — it declares
   `.b-proof .fr.p1/.p2` locally instead of using `.field .fr.maj`, so the rule
   above missed it. `.bnd .b-proof` (0,2,0) beats the page-local `.b-proof`
   (0,1,0) whatever loads last — same specificity lesson as the mobile pass.
   Delete this the day the forks fold back into the shared chassis. */
.bnd.b-proof .fr.p1,.bnd.b-proof .fr.p2{font-weight:400}

/* ============================================================================
   MULTI-COLUMN TEXT IS A DESKTOP AFFORDANCE — 2026-08-11
   ============================================================================
   The 2026-08-11 responsive pass fixed every `grid-template-columns` and missed
   CSS multi-column entirely, because columns never OVERFLOW — they just shrink
   the measure. The trim harness reported CLEAN while `.qa` and `.field .prose`
   were setting two ~155px columns on a 390px phone. That is roughly 22
   characters a line against the 45-75 a reader needs, and it forces the eye back
   up the screen mid-thought on a device that scrolls.

   Fixed with `column-width` rather than another hard-coded breakpoint: the
   browser fits as many columns as can hold a real measure and drops to one on
   its own. Content-driven, so it also covers the untested 701-1000px band and
   any future band that opts into columns. `columns:2` stays the desktop intent
   via the max-width cap.
   ========================================================================= */
.qa,.bnd .field .prose{columns:22rem 2;column-gap:50px}
@media (max-width:820px){
  .qa,.bnd .field .prose{columns:1}
  /* single column removes the reason for the tight column rhythm */
  .qa dd{padding-bottom:18px}
}

/* ============================================================================
   COLLAPSING A GRID TEMPLATE IS NOT ENOUGH — 2026-08-11
   ============================================================================
   `.b-brief` was still rendering TWO columns at 390px (measured: 44px 293px)
   even though the ≤700px block sets grid-template-columns:1fr. The template WAS
   collapsing; the children were not. `theme.css:273`, inside the ≤1340px block,
   pins `.b-brief .notes,.b-brief .filing{grid-column:2}` — and 390 is ≤1340, so
   it still applied. A child placed in column 2 of a one-column grid makes grid
   generate an IMPLICIT second column, so the plate was squeezed to 44px and
   "THE STORY / the fact card" was clipped to "TH ST".

   Lesson worth keeping: when collapsing any chassis for mobile, reset the
   CHILDREN's placement too, not just the parent's template. Nothing in the trim
   harness catches this — it is not overflow, it is a squeezed track.
   ========================================================================= */
@media (max-width:700px){
  .b-plate>*,.b-rows>*,.b-brief>*,.b-under>*,.bin-head>*,.b-split>*,.b-cut>*,
  .b-adm>*,.b-proof>*,.b-ledger>*{grid-column:auto;grid-row:auto}
  /* ⚠ these must MATCH the specificity of the rules that placed them.
     `.b-brief .notes` is (0,2,0); a `.b-brief>*` reset is (0,1,0) and LOSES.
     Third time this codebase has bitten on specificity — always mirror the
     original selector rather than reaching for a shorter one. */
  .b-brief .notes,.b-brief .filing{grid-column:auto}
  .b-brief>.lbl,.b-split>.lbl,.b-under>.lbl,.bin-head>.lbl{grid-column:1 / -1}
}

/* ============================================================================
   MOBILE HEADER — the masthead line and THE BILL drawer   2026-08-11 (rev 2)
   ============================================================================
   SUPERSEDES the 2026-08-11 "3-up grid" pass, whose note argued a hamburger
   "would be a grammar this design does not have". Seth overruled it, and on the
   evidence he is right twice over:

   1. It never got cheap enough. Squeezing six acts into a 3×2 grid still cost a
      measured 258px of an 844px phone (masthead 134 + nav 99) — 31% of the
      viewport spent on chrome, on every page, before one word of content.
   2. The grammar argument was backwards. A 3×2 grid of equal chips is not a
      bill; it is a web nav that happens to be set in Anton. A real handbill
      lists its acts in a VERTICAL COLUMN, ranked, each on its own line with its
      billing beside it. That is exactly what the drawer below prints. Collapsing
      to a hamburger did not cost the design its grammar — it recovered it.

   The toggle is therefore not a generic three-line icon: it is an ink plate
   carrying three paper RULES, which is what a hamburger already is if you read
   it as a printer would (three slugs of furniture). It says THE BILL, not MENU.
   It is INK, never tomato — addendum B reserves tomato for the one BOOK ask, and
   a nav control that wears the booking ink cross-sells against the real one.

   The drawer's own row grammar is §2a's plate, turned sideways: Anton name on
   the left edge, Caslon italic billing on the right, 3px ink furniture between
   rows. Active row reverses to ink (matching `nav.stub a.on` on desktop); the
   box office keeps tomato and closes the stack, so the bill still ends on its
   headliner.

   Behaviour matches the LIVE theme's shipped nav.js contract exactly — a
   `.navtoggle` button that toggles `.nav-open` on the <nav>, syncs
   `aria-expanded` + `aria-label`, marks the collapsed drawer `inert`, and closes
   on Escape / link / resize-up. The port reuses that JS unchanged; only the CSS
   below travels. See `bigbill/nav.js` for the mockup's copy of it.
   ========================================================================= */
@media (max-width:700px){
  /* --- the masthead line: logo + wordmark, then the toggle ----------------
     A 2-column grid rather than the desktop flex row: the brand and the booking
     line stack in column 1, the toggle spans both rows in column 2. Doing it
     with grid rather than markup keeps the three children exactly where the
     desktop (and the ACF port) put them.

     THE LINE ONLY HAS ROOM FOR TWO OF THREE STRINGS. Measured at 390: the
     content box is 308px, the toggle takes 109 + 12 gap, so the brand column is
     187 — and "Architectural Photography" alone needs 277px at its .34em
     tracking, 150px even reset to .16em. Something has to go, so rank them:

       · the wordmark   — the masthead. Stays.
       · "Booking summer & fall 2026" — the only line in this header that is a
         business signal rather than a label. Stays; fast booking is the #1
         business priority on this site.
       · "Architectural Photography" — the category, and DESIGN-TRUTH §10's own
         test kills it: every page already prints the category in its hero
         lockup ("And His Architectural Photography") a few hundred pixels
         below, and the <h1> and <title> both carry it too. On a 390px sheet
         it is the fact stated twice. Goes.
       · the cities line — same test, carried by the footer and by on-tour. Goes.
   */
  /* ⚠ `gap:0 12px`, not `column-gap:12px`. The desktop rule sets the `gap`
     SHORTHAND to 30px; overriding only the column half leaves row-gap at 30 and
     the two-row grid silently carries 30px of dead air — measured 113px where
     80 was intended. Same family of bug as the `.b-brief` implicit column:
     collapsing a chassis means resetting every axis the old rule set. */
  .bill-top{display:grid;grid-template-columns:1fr auto;align-items:center;
    gap:0 12px;padding:9px 16px 8px}
  .bill-top .id{grid-column:1;grid-row:1;gap:11px;min-width:0}
  .bill-top .id img,.bill-top .id .mk{height:34px}
  /* ⚠ `.sub` is display:none below 700 (next line), so nothing here is measure-
     matched — the constraint is the room left beside the menu button. Alfa Slab
     at 1.25rem measures 159px against Anton 1.1875rem's 108px, so this is the
     value to re-check first if the masthead ever wraps at 390. */
  .bill-top .id .wm{font-size:1.25rem;letter-spacing:.005em}
  .bill-top .id .sub{display:none}
  /* The booking line runs the FULL width of the masthead on its own row rather
     than tucking under the wordmark. Indented into the brand column it had
     142px and wrapped "2026" onto a second line; rule-to-rule it has 308px and
     sets in one — and a line that spans trim to trim is the house line a bill
     would actually print under its masthead. */
  .bill-top .desk{grid-column:1 / -1;grid-row:2;text-align:left;margin-top:3px}
  .bill-top .desk .r1{font-size:.8125rem;line-height:1.25}
  .bill-top .desk .r2{display:none}

  /* --- the toggle: an ink plate carrying three paper rules ---------------- */
  .bill-top .navtoggle{display:flex;align-items:center;gap:9px;flex:none;
    grid-column:2;grid-row:1;align-self:center;
    background:var(--ink);color:var(--paper);border:0;cursor:pointer;
    padding:0 13px;min-height:44px;                      /* tap floor */
    font-family:var(--gothic);font-size:.8125rem;letter-spacing:.13em;
    text-transform:uppercase;text-indent:.13em;
    box-shadow:3px 3px 0 var(--pine)}                    /* §7: the shadow is press navy */
  .bill-top .navtoggle .bars{display:block;width:19px;flex:none}
  .bill-top .navtoggle .bars span{display:block;height:3px;background:var(--paper);
    transition:transform .18s ease,opacity .18s ease}
  .bill-top .navtoggle .bars span+span{margin-top:4px}
  /* open: the top and bottom slugs cross, the middle one lifts off the stone.
     `.bill-top` precedes `nav.stub`, so the open state is read FORWARD with
     :has() — that is why nav.js can keep putting the class on the <nav> and
     nothing here needs a second state class. */
  /* The open state changes the BARS, not the ground. A tomato ground would put
     the booking ink on a navigation control (addendum B: tomato BOOKS, pine
     NAVIGATES), and a pine ground would force the misregister shadow off press
     navy, which §7 does not allow. Mustard is the accent an ink plate already
     uses for its sub-label, so the state reads without borrowing another
     component's meaning. */
  .bill-top:has(~ nav.stub.nav-open) .navtoggle{color:var(--mustard)}
  .bill-top:has(~ nav.stub.nav-open) .navtoggle .bars span{background:var(--mustard)}
  .bill-top:has(~ nav.stub.nav-open) .navtoggle .bars span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .bill-top:has(~ nav.stub.nav-open) .navtoggle .bars span:nth-child(2){opacity:0}
  .bill-top:has(~ nav.stub.nav-open) .navtoggle .bars span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

  /* --- the drawer -------------------------------------------------------- */
  nav.stub{display:block;border-bottom:0}
  /* ⚠ Impeccable's detector flags `transition:max-height` as a layout
     animation, and it is right in general — transform and opacity are cheaper.
     Kept deliberately, for two reasons. (1) This drawer must PUSH the page: it
     is a band in a stack of bands, and a transformed overlay sliding over the
     sheet would be the one floating element in a design whose first law is that
     every zone is a full-bleed band. (2) The live theme's shipped nav already
     collapses on max-height (assets/js/nav.js:24), so matching it keeps the port
     a CSS-only change. The cost is one layout pass on an explicit tap over six
     rows — the right trade here, not an oversight. */
  nav.stub #primaryNav{display:block;background:var(--ink);
    max-height:0;overflow:hidden;visibility:hidden;
    transition:max-height .26s ease,visibility 0s linear .26s}
  nav.stub.nav-open #primaryNav{max-height:560px;visibility:visible;
    border-bottom:3px solid var(--ink);transition:max-height .3s ease,visibility 0s}
  /* Each act is a row on the sheet: name at the left edge, billing at the right,
     3px of ink furniture between. `gap` on the wrapper would not do it — the
     rows sit on the ink ground and the ground IS the rule (§2b's mechanism). */
  /* Sized by PADDING, not min-height: `align-items:baseline` sets the two voices
     on one baseline, and a min-height taller than that baseline group parks the
     whole row at the top of its box. Padding grows the row around the baseline
     instead, so the act sits centred and the 44px floor is still cleared. */
  nav.stub a{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
    flex:none;width:100%;text-align:left;border-right:0;
    background:var(--paper);color:var(--ink);
    padding:16px 18px;
    font-size:1.0625rem;letter-spacing:.11em;line-height:1.15}
  nav.stub a+a{border-top:3px solid var(--ink)}
  nav.stub a small{display:block;margin-top:0;font-size:.9375rem;
    color:var(--ink-dim);flex:none;text-align:right}
  nav.stub a.on{background:var(--ink);color:var(--paper);border-right-color:transparent}
  nav.stub a.on small{color:var(--mustard)}
  /* left as is with the desktop rule — see the note at :101. Measured here:
     rgba(paper,.85) on tomato = 3.60:1. Seth's decision, not an oversight. */
  nav.stub a.book{background:var(--tomato);color:var(--paper)}
  nav.stub a.book small{color:rgba(246,241,229,.85)}
  /* the box office is the headliner: it closes the bill, so it gets the weight */
  nav.stub a.book{padding:19px 18px;font-size:1.1875rem}
}
/* 320-360px phones: the two longest billings ("the photographer", "certified
   gold") are what run the row out of line, not the names. Step the billing down
   and tighten the name's tracking; the names themselves never shrink, because
   they are the thing being read. */
@media (max-width:374px){
  /* ⚠ `padding:14px 14px`, NOT `0 14px`. This tier was written while the drawer
     rows were sized by `min-height`, so zeroing the vertical padding was
     harmless. The rows were then changed to be sized BY padding (so the two
     voices could sit on a shared baseline and still centre) and this line was
     not updated — which collapsed every row on a ≤374px phone to **18-21px**,
     measured with the drawer open at 320. The nav was unusable on an iPhone SE
     and no harness caught it: a closed drawer is `visibility:hidden`, so every
     tap-target sweep correctly skipped it and reported 44px. */
  nav.stub a{padding:14px 14px;font-size:1rem;letter-spacing:.08em}
  nav.stub a small{font-size:.875rem}
  .bill-top .navtoggle{padding:0 11px;font-size:.75rem;letter-spacing:.1em}
  .bill-top .id .wm{font-size:1.0625rem}
}
/* No-JS: the drawer must not become a dead end. Without the script the toggle
   never gets `.nav-open`, so the acts are simply always printed — the pre-2026-08-11
   behaviour, minus the grid. */
@media (max-width:700px){
  html.no-js nav.stub #primaryNav{max-height:none;visibility:visible;
    border-bottom:3px solid var(--ink)}
  html.no-js .bill-top .navtoggle{display:none}
}

/* ============================================================================
   MOBILE DESIGN SWEEP — 2026-08-11 (rev 2, /impeccable adapt)
   ============================================================================
   The 2026-08-10 responsive pass fixed TRIM: nothing crosses the frame, no
   horizontal scroll. The 2026-08-11 pass fixed three DESIGN defects. Neither
   pass looked at whether the phone layout was any good, because the harness
   they were driven by can only see overflow — and none of what follows
   overflows. Everything here was measured at a true 390px in a device-emulated
   viewport, then looked at.

   The through-line: a chassis that "collapses to one column" is not finished.
   Its INTERIORS still carry desktop constants — a 250px form label, 44px
   gutters, a 640px plate, a 62px display face, an 11px misregister offset —
   and those constants are what actually ruin a phone. Collapsing the grid just
   stops it overflowing.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   1. THE GALLERIES — the portfolio was rendering 33px photographs   BLOCKER
   ---------------------------------------------------------------------------
   `.pgr` is a justified row: `flex-grow:calc(var(--ar)*1000)` with `flex-basis:0`
   divides the row by aspect ratio, exactly as a picture editor would. It has no
   mobile rule at all, so it kept dividing at 390px. MEASURED on the-wall: of 16
   frames, eleven rendered under 80px wide and the Tennessee State Museum
   portrait rendered **33 x 53 CSS pixels**. Nothing overflowed, so every trim
   check this project has run reported the page CLEAN — while the portfolio page
   showed the work as postage stamps.

   The row algorithm is right; the row is just the wrong container on a phone.
   Below 560 the wall goes ONE UP, because looking at the work is the entire job
   of that page and 296px of photograph beats four of them at 70. 561-700 takes
   two. `aspect-ratio:var(--ar)` carries over untouched, so every frame keeps its
   true crop and the "hung on a wall" framing survives.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  /* 88px of a 340px band was gutter — 26% of the frame spent on air while the
     photographs inside it starved. Every other field in the system dropped to
     22px at :1182; this one was simply missed. */
  .gate-band{padding:26px 22px 28px}
  .paper-gate{gap:18px}
  .paper-gate .pgr{display:grid;grid-template-columns:1fr 1fr;gap:16px}
  .paper-gate .pgp{min-width:0}
}
@media (max-width:560px){
  .paper-gate .pgr{grid-template-columns:1fr;gap:20px}
}

/* ---------------------------------------------------------------------------
   2. HOME'S RECORD BIN — the crate you flip through            BLOCKER
   ---------------------------------------------------------------------------
   Same defect, 21 tiles: measured widths of 43-235px, with a 768x1229 museum
   interior in a **43 x 65** box on the page whose job is proving he can
   photograph buildings.

   But home's bin is a TEASER, not the portfolio, so one-up would add ~4,600px
   of scroll to the front page to fix it. The answer the metaphor already
   supplies: a record bin is a thing you FLIP THROUGH. Each row becomes a
   snap-scrolling crate at a fixed height, with widths still set by aspect ratio
   — which is the desktop algorithm exactly, scrolled instead of squeezed. A
   1.5 sleeve lands at 285px (73% of the viewport) instead of 132.

   The affordance is the layout, not a caption: every row is wider than the
   viewport, so a sleeve is always half-visible at the trim. `overscroll-behavior`
   keeps a horizontal flick from stealing the page's vertical scroll, and the
   scrollbar is hidden because a printed crate does not have one.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .gate{gap:14px}
  .gate .gr{display:flex;gap:12px;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none}
  .gate .gr::-webkit-scrollbar{display:none}
  .gate .gp{flex:0 0 auto;height:190px;width:auto;aspect-ratio:var(--ar);
    scroll-snap-align:center}
}
/* 374, not 400: 390 is the single most common phone width in use and belongs in
   the 190px tier — a 1.5 sleeve lands at 285px there (73% of the viewport)
   against 252 (65%) at 168. Only genuinely narrow handsets step down. */
@media (max-width:374px){
  .gate .gp{height:178px}
}

/* ---------------------------------------------------------------------------
   3. THE STICKER TABS — 71% of the hero was opaque ink            MAJOR
   ---------------------------------------------------------------------------
   `.b-photo .tab` and `.gp .tab` are pasted stickers sized for a 1440px band.
   MEASURED at 390 on home: the photo is 340x227 and the tab wraps to three
   lines at 309x87, with the `.cap` taking another 75 — 162 of 227px, 71% of the
   hero, covering the photograph it is captioning. The tab also ran 1px past the
   band's right edge and lost its 4px offset shadow to the trim.

   The sticker is right; it is just printed at desktop scale. Shrink the type,
   tighten the tracking, and cap its width so it stays a sticker on a corner
   rather than a banner across the plate. DESIGN-TRUTH §9 is preserved — it is
   still pasted, still rotated, still hard-shadowed.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-photo .tab{left:14px;top:12px;padding:6px 12px;font-size:.8125rem;
    letter-spacing:.07em;max-width:calc(100% - 40px);line-height:1.25}
  .b-photo .cap{padding:8px 14px;font-size:.875rem;line-height:1.3;gap:8px 20px}
  .gp .tab{left:10px;top:-2px;padding:5px 11px;font-size:.8125rem;letter-spacing:.06em;
    max-width:calc(100% - 26px);line-height:1.2}
  /* ⚠ 2026-08-12 (Seth: go 1-up) — the pair was 2-up at every width, which
     at 390px renders each half ~193px wide: too small to read as a
     photograph, the same failure already fixed once on Deep Cuts. One
     column, one photo; the second `<img>` stays in the DOM (see
     front-page.php) but is hidden here rather than removed, and its own
     `sizes` string collapses so it isn't downloaded at real resolution for
     nothing. `.cap` was already `grid-column:1/-1`, so it needs no change. */
  .b-photo.pair{grid-template-columns:1fr}
  .b-photo.pair img:nth-of-type(2){display:none}
}

/* ---------------------------------------------------------------------------
   4. ABOUT'S CUT — a 640px plate holding a 451px photograph       BLOCKER
   ---------------------------------------------------------------------------
   The ≤700 block in the-photographer's own <style> fixed the IMAGE (`width:100%`
   instead of `height:100%;max-width:none`) and left the BOX alone. `.cutblock`
   still declares `min-height:640px`, and the image is still `position:absolute;
   bottom:0`, so it contributes no height of its own:

     · at 390px — box 340x640, image 340x451 → **189px of empty screened paper
       above his head**, inside a band that is supposed to read as a plate;
     · at 700px — image 650x863 in the same 640 box → **223px cropped off the
       top of the portrait**, silently, behind `overflow:hidden`. His head.

   Break-even is a ~532px viewport, which no phone is. The fix is to stop
   declaring the height at all below 700 and let the plate take the height of
   the cut standing in it — which is what DESIGN-TRUTH §5 describes anyway
   ("bottom-flush to the band rule so it stands rather than floats").

   ⚠ `.bnd.b-cut .cutblock` (0,3,0) beats the page-local `.cutblock` (0,1,0)
   whichever sheet loads last. Fourth time specificity has decided an outcome in
   this codebase; mirroring the fork's compound is the reliable move.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .bnd.b-cut .cutblock{min-height:0}
  .bnd.b-cut .cutblock img{position:static;transform:none;width:100%;height:auto;
    max-width:100%;display:block}
  /* 96px of horizontal padding on a 340px band left the manifesto 244px */
  .bnd.b-cut .cut-side{padding:26px 22px 28px}
  .bnd.b-cut .cut-side .thesis{font-size:clamp(1.5rem,7vw,2.4rem)}
  .bnd.b-cut .cut-side .tags{gap:0 9px;margin:16px 0 18px}
  .bnd.b-cut .cut-side .tags span{font-size:.9375rem}
  /* the page-local IN PERSON strip is a fork of .b-strip at .44em — at 19px that
     is ~630px of tracked caps on a 300px line, i.e. three loose rows. The shared
     .b-strip rule at :1244 cannot reach a fork, so it is restated here. */
  .bnd.b-rev span{font-size:.95rem;letter-spacing:.18em;text-indent:.18em}
}

/* ---------------------------------------------------------------------------
   5. THE BOOKING TICKET — the form input measured 55px wide      BLOCKER
   ---------------------------------------------------------------------------
   The single most valuable surface on the site, and the worst mobile defect in
   the build. `.b-tkt .t-field` is `grid-template-columns:150px 1fr` with no
   mobile rule anywhere. MEASURED at 390: the form cell is 221px of content, the
   label track takes 150 and the gap 16, so **the <input> renders 55px wide** —
   about four characters of the visitor's own name. Inputs also computed 23px
   tall, under both the 44px tap floor and WCAG 2.5.8's 24px minimum.

   Stacking the label over the blank keeps the whole ticket idiom: the label is
   still tracked caps, the answer is still italic on a 2px paper rule. It is the
   same printed blank, set portrait.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-tkt .t-form{padding:24px 20px 28px}
  /* 62px of Alfa Slab in a 221px box. The masthead h1 got a clamp on 2026-08-11;
     this one is the same face at the same job and was missed. */
  .b-tkt .t-form h2{font-size:clamp(2rem,11vw,3.9rem);text-shadow:-.05em .05em 0 var(--tomato)}
  .b-tkt .t-field{grid-template-columns:1fr;gap:5px;padding:11px 0;align-items:stretch}
  .b-tkt .t-field.msg{align-items:stretch}
  .b-tkt .t-field label{font-size:.75rem}
  /* 44px on the control itself, not just the row: on a phone the blank IS the
     target, and a 34px box was still the smallest tappable thing on four pages.
     Costs ~30px across the three fields, on the site's #1 business surface. */
  /* ⚠ `min-width:0` is load-bearing, not defensive. A bare <input> has an
     intrinsic default width (~20 characters), and as a grid item its automatic
     minimum size is that intrinsic width — `width:100%` does not override it.
     At 320 that sized the whole ticket 26px past the trim on all four ticket
     pages while the input itself reported a comfortable 219px. */
  .b-tkt .t-field input,.b-tkt .t-field textarea{width:100%;min-width:0;min-height:44px;
    font-size:1.0625rem}
  .b-tkt .t-field.msg textarea{min-height:88px}
  .b-tkt .go{width:100%;text-align:center;padding:16px 20px;font-size:1.125rem}
  /* 56px of a 340px band was a decorative vertical ADMIT ONE stripe */
  .b-tkt{grid-template-columns:34px 3px 1fr}
  .b-tkt .t-run span{font-size:.8125rem;letter-spacing:.16em}
  /* the serial was absolutely positioned over a 221px line and collided with
     "Admit one project"; on a phone it simply prints in the flow */
  .b-tkt .t-serial{position:static;text-align:right;margin-bottom:6px}
  .b-tkt .t-stub dd a{display:inline-block;min-height:44px;line-height:44px}
}

/* ---------------------------------------------------------------------------
   6. THE CROSS-SELL BANDS — a 91px headline beside a 170px button  BLOCKER
   ---------------------------------------------------------------------------
   `.gate-cta` (home) and `.wl-cta` (the-wall) are both a space-between flex row
   whose button carries `flex:none`. MEASURED on the-wall at 390: the button
   refuses to shrink at 170px and leaves the headline **91px**, so "Want the
   story behind a frame?" sets one word per line. Earlier passes let the button
   TEXT wrap, which treats the symptom; the row itself never stacked.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .gate-cta,.wl-cta{flex-direction:column;align-items:stretch;gap:16px;text-align:center}
  .gate-cta a,.wl-cta a{flex:none;width:100%;text-align:center}
  .gate-cta{padding:20px 18px}
  .gate-cta .big{font-size:1.25rem;line-height:1.2}
}

/* ---------------------------------------------------------------------------
   7. THE CERTIFIED POSTER WALL — a 280px floor on a 296px shelf     MAJOR
   ---------------------------------------------------------------------------
   certified.html declares `.pwall{grid-template-columns:repeat(auto-fill,
   minmax(280px,1fr))}` in its own <style>. That is (0,1,0), the same as
   theme.css:1208's `.eng4,.g-row,.pwall{grid-template-columns:1fr}`, and the
   inline block loads later — so the shared mobile rule has never once applied
   and the theme.css entry for `.pwall` is dead code.

   The 280px floor needs a viewport of at least 378px. At 375, 360 and 320 the
   track overflows and `.frame{overflow:hidden}` swallows 18-58px of every
   poster without a scrollbar to say so.

   ⚠ The posters are one of Seth's LOCKED areas, so this is fixed rule-level in
   theme.css and the page's markup is untouched, per the brief's standing rule.
   `.pwall.pwall` is (0,2,0) — it beats the fork on specificity rather than
   order, which is the only thing that has reliably worked here.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .pwall.pwall{grid-template-columns:1fr}
}

/* ---------------------------------------------------------------------------
   8. THE CASE-STUDY INDEX — 11 photographs were display:none        MAJOR
   ---------------------------------------------------------------------------
   Two rules contradict each other. theme.css:510, inside `@media
   (max-width:1240px)`, sets `.csrow .frame-cell{display:none}`. theme.css:1259
   then carefully gives that same cell a grid placement, a 3/2 aspect ratio and a
   border for ≤700 — but never re-declares `display`, so the ≤1240 rule survives
   and the images are never even fetched (verified: naturalWidth 0, box 0x0).
   Eleven `sizes="(max-width:700px) 88vw…"` strings describe an element that does
   not render.

   The ≤700 rule states the intent plainly, so honour it: an index of visual case
   studies with no images on a phone is a list of titles.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .csrow .frame-cell{display:block}
  /* the row's bill box is 192px at 390 and 162px at 360, holding a 33.6px
     display face — "Timberlake's" alone measured ~190px */
  .csrow .bill{padding:18px 18px 20px}
  .csrow .bill h3,.csrow .bill h2{font-size:clamp(1.375rem,6.2vw,2.1rem);line-height:1.05}
  .cshead .bill{padding:24px 20px 22px}
  /* the headliner kept 3.4rem from the ≤1240 step — 54px of Alfa Slab, and
     "District" alone measures ~230px of a 236px box at 320 */
  .cshead h3,.cshead h2{font-size:clamp(1.75rem,9vw,3.4rem)}
  /* The headliner's single `1fr` track measured 333.77px inside a 310px band at
     360 — a grid item's automatic minimum size is min-content, so one nowrap
     honour chip ("ArchDaily Building of the Year '26") was sizing the whole
     track and pushing 21px of the band past the trim. `min-width:0` on the
     children is the same reset the plate chassis already got at :1265; the
     headliner was never in that list. Chips wrap too — an award chip is fine
     print, not an act name, so DESIGN-TRUTH §8's nowrap law does not cover it. */
  .bnd.cshead>*,.bnd.csrow>*{min-width:0}
  .cshead .hons,.csrow .hons{flex-wrap:wrap}
  .cshead .hons span,.csrow .hons span{white-space:normal}
}

/* ---------------------------------------------------------------------------
   9. THE MISREGISTER — a fixed 11px offset on a fluid letterform    MAJOR
   ---------------------------------------------------------------------------
   `.b-name .n::before` offsets the pine plate by a CONSTANT `left:11px;top:12px`
   while the letterform itself is fluid: `min(9.1rem, 12vw - 14px)`. At 1440 the
   name sets at ~145px and 11px is a 7.6% offset — a press that shifted a hair.
   At 390 the name sets at **32.8px** and the same 11px is a 34% offset: the two
   plates read as two different words printed on top of each other, which is what
   the home hero and About's name lockup have both been doing on every phone.

   §7 says the misregister is a hard offset in press navy — it does not say the
   offset is a pixel constant. In `em` it stays the same *gesture* at every size,
   which is what "misregister" actually means.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-name .n::before{left:.076em;top:.083em}
  .b-name .and span{text-shadow:.07em .07em 0 var(--mustard)}
  .mast h1{text-shadow:.06em .05em 0 var(--pine)}
  .mast .sub-western{text-shadow:.05em .05em 0 var(--mustard)}
  .cshead h3,.cshead h2{text-shadow:.06em .06em 0 var(--tomato)}
  .b-rows>.px .v,.b-rows.txt>.px .v.num{text-shadow:.06em .06em 0 var(--pine)}
  /* on-tour's h1 carries an unclamped role line inside a clamped headline */
  .mast h1 .h1-role{font-size:clamp(.875rem,3.6vw,1.4rem);letter-spacing:.1em}
}

/* ---------------------------------------------------------------------------
   10. THE REMAINING DESKTOP CONSTANTS
   ---------------------------------------------------------------------------
   Each of these is a single value that a ≤700 rule never reached. None of them
   overflow; all of them cost the phone layout something measurable.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  /* the About forks kept 88px of gutter and a 28px plate label while every
     shared plate dropped to 22px and 1.4rem at :1180-1183 */
  .bnd.b-proof>.field,.bnd.b-adm>.field{padding:22px 22px 24px}
  .bnd.b-adm .lbl h2,.bnd.b-proof .lbl h2{font-size:1.4rem}
  /* the-wall's filter line: 11 nowrap collection names in a 252px field. LOCKED
     markup, so the padding is corrected on the rule, per the brief. */
  .b-file{padding:14px 18px 13px}
  /* once these grids are one column, a right-hand border rules the wrong axis */
  .b-adm .px,.b-rows>.px{border-right:none;border-bottom:2px solid var(--ink)}
  .b-adm .px:last-child,.b-rows>.px:last-child{border-bottom:none}
  /* 230px of halftone corner is 68% of a 340px band */
  .bnd .htc{width:120px;height:58px}
  .bin-head{margin-bottom:28px}
  /* the rack: five 158px singles each stranded on their own row, 138px of dead
     board beside each. Two up reads as a shelf again. */
  .bnd .field .rack-shelf{display:grid;grid-template-columns:1fr 1fr;gap:20px 16px;
    justify-content:start}
  .bnd .field .cut{width:100%}
  .cut .mini{right:-10px}
  /* tap targets the 2026-08-11 pass listed but did not include */
  .b-brief .seal a,.field .more a{display:inline-block;min-height:44px;
    line-height:2.6;padding-left:10px;padding-right:10px}
  /* the masthead brand link — the home button on every page — measured 34px
     tall, because it is exactly as tall as the logo inside it */
  .bill-top .id{min-height:44px}
}

/* ---------------------------------------------------------------------------
   11. THE 320px TAIL — iPhone SE (1st gen) and the small-Android floor
   ---------------------------------------------------------------------------
   Everything above holds at 360 and 390. 320 is the genuine floor, and the only
   thing still failing there is DESIGN-TRUTH §8's nowrap law running out of
   room: "Tennessee Titans House Fan Experience" is one act name that must not
   break, and About's proof field gives it ~230px.

   The law is kept and the type moves, which is what the 2026-08-11 pass decided
   and is still the right call — a bill that hyphenates an act is worse than a
   bill set small. This is one more step of the same ladder (.92 → .84 → .76 →
   .68), plus 6px back off the field gutters to spend on the names instead.
   ------------------------------------------------------------------------ */
@media (max-width:340px){
  /* same unscoped-.nm/.st leak as the 400px block above — see the note there */
  .b-proof .nm,.b-adm .nm,.t1 .nm{font-size:.645em}
  .b-proof .st,.b-adm .st,.t1 .st{font-size:.52em;margin-left:2px;margin-right:2px}
  .bnd.b-proof>.field,.bnd.b-adm>.field,.b-plate>.field,.b-under>.field{
    padding-left:16px;padding-right:16px}
  .b-file{padding-left:14px;padding-right:14px}
}

/* ---------------------------------------------------------------------------
   12. THE TICKET AT 320 — the track was sized by the starburst
   ---------------------------------------------------------------------------
   At 320 the ticket's content track measured 259.227px against 233 available,
   putting the whole component 26px past the trim on all four ticket pages.
   Probed by pinning the track to 100px and reading what refused to shrink: it
   is NOT the inputs (they already carry min-width:0 and were only wide because
   the track was). It is the stub side — the 158px fixed `.burst`, the 30px
   stub gutters kept from the ≤940 stack, and the email address, which is one
   unbreakable token 19 characters long.

   All three are min-content contributors, and a grid track is sized by the
   largest of them, so all three have to move or none of it does.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-tkt>*,.b-tkt .t-form>*,.b-tkt .fields,.b-tkt .t-field,.b-tkt .t-stub>*{min-width:0}
  .b-tkt .t-form{padding-left:20px;padding-right:20px}
  /* the stub's padding moves through its token so the keyline follows it —
     20px against a 12px keyline left only 5px of board between the rule and
     the type here, which is the same register error the token block fixed at
     the compact tier. `.is-compact` is named for specificity. */
  .b-tkt .t-stub,.b-tkt .t-next,
  .b-tkt.is-compact .t-stub,.b-tkt.is-compact .t-next{--pad-l:28px;--pad-r:22px}
  .b-tkt .burst{width:126px;height:126px}
  .b-tkt .burst .txt .m,.b-tkt .burst .txt{font-size:.75rem}
  /* the address is a single token; on a 233px stub it has to be allowed to
     break rather than set the whole component's width */
  .b-tkt .t-stub dd,.b-tkt .t-stub dd a{overflow-wrap:anywhere}
}

/* ============================================================================
   13. THE 701-1000 BAND — the same defects, one size up      2026-08-11
   ============================================================================
   ⚠ SCOPE NOTE. `NEXT-SESSION-BRIEF` §0d correctly reserves a full tablet pass
   for its own session, and this is NOT that pass. What is here is only the
   subset where a defect this sweep just fixed for phones has the SAME root
   cause at 768 — fixing 33px photographs at 390 and leaving 88px photographs
   on an iPad would be a half-finished fix, not a scoped one.

   Measured at 768, iPad portrait:
     · the-photographer  IMG 877px inside a 768px viewport, cropped silently
     · home              smallest gallery tile 88px
     · the-wall          smallest gallery tile 102px
     · every ticket page the stub's email link 20px tall

   STILL OPEN for the tablet session, deliberately untouched here: `DIV.px`
   overflows of 22-55px in the `.b-rows` numeral cells (home, the single,
   About); the 208px header, which is the desktop 6-up bill and legitimate on a
   tablet; and `SPAN.ht-tr+94`, the decorative halftone corner hung at
   right:-70px, which is intentional bleed on all 8 and always has been.
   ========================================================================= */
@media (min-width:701px) and (max-width:1000px){
  /* the justified rows divide by aspect ratio with no floor, so a 4-up row of
     mixed crops still starves at tablet width — two up, same as 561-700 */
  .paper-gate .pgr{display:grid;grid-template-columns:1fr 1fr;gap:20px}
  .paper-gate .pgp{min-width:0}
  /* ⚠ was a snap rail; changed 2026-08-11 with 14a. Seth rejected the rail on
     phones, and leaving it at tablet would have given the bin three different
     behaviours across three widths — stack, rail, justified row. Two up here
     matches `.pgr` above it and keeps one idea per component. */
  .gate .gr{display:grid;grid-template-columns:1fr 1fr;gap:20px;overflow-x:visible}
  .gate .gp{width:auto;height:auto;aspect-ratio:var(--ar)}

  /* About's cut: `min-height:640px` + an absolutely positioned
     `height:100%;width:auto;max-width:none` image renders 877px of photograph
     into a 330px column and lets `.frame{overflow:hidden}` cut it in silence.
     Same fix as the phone block — let the plate take the height of the cut. */
  .bnd.b-cut .cutblock{min-height:0}
  .bnd.b-cut .cutblock img{position:static;transform:none;width:100%;height:auto;
    max-width:100%;display:block}

}

/* ---------------------------------------------------------------------------
   TAP TARGETS ABOVE THE PHONE TIER — 2026-08-12, and the cap is the fix
   ---------------------------------------------------------------------------
   These four rules used to live inside `(min-width:701px) and (max-width:1000px)`
   and stopped dead at 1001. Measured at 1001 AND 1440, identically:

     .b-tkt .t-field input        627 x 23px   <- the LEAD FORM, fails 2.5.8 AA
     .b-tkt .t-stub dd a / .col-house dd a   20px tall
     .b-file .t1 a / .t2 a        32px / 26px tall
     .nb-bill .field .fr a        38px / 31px

   The block's own comment already argued the principle — "768 is an iPad, which
   is a touch device" — and then capped it at 1000, which excludes iPad Pro
   landscape (1024), every touch laptop and every 1366 panel. A pointer:coarse
   query would be the textbook answer and is the wrong one here: a mouse user
   gains nothing from a 23px input either. So the floor simply has no ceiling.
   ------------------------------------------------------------------------ */
@media (min-width:701px){
  .b-tkt .t-stub dd a{display:inline-block;min-height:44px;line-height:44px}
  /* the colophon's contact links measured 20px tall on every page — the
     :1192 tap-target floor stops at 700. The email link is the site's #1
     business action; it should not be the smallest target anywhere. */
  .colophon a,.csrow .go,.b-file a,.t1 a,.b-brief .seal a,.field .more a{
    display:inline-block;min-height:44px;line-height:2.6}
  /* the booking blanks compute 23px tall — this is the conversion control, it
     should not be the smallest target on the page at any width. */
  .b-tkt .t-field input,.b-tkt .t-field textarea{min-height:44px}
  .b-tkt .t-field.msg textarea{min-height:88px}
}

/* ---------------------------------------------------------------------------
   ...AND EVERY ONE OF THOSE FIXES SET A HEIGHT AND NEVER A WIDTH
   ---------------------------------------------------------------------------
   Which is why short labels stayed tiny in the other axis at EVERY width:
   the News pager measured 20x44 and 18x50, the "All" chip 30x44, "Drone" 41x44
   at 320, and the 404's recovery links 39x44 and 43x44. A 44px-tall, 18px-wide
   target is not a 44px target. `min-width` is unconditional for the same reason
   the block above is.
   ------------------------------------------------------------------------ */
.b-file .t1 a,.b-file .t2 a,.nb-bill .field .fr a{min-width:44px}
/* the pager's labels are one or two characters, so they also need centring —
   left-aligned type in a 44px box reads as a rendering fault, not a button */
.b-file.alt .t1 a{min-width:44px;text-align:center}

/* The drawer and the toggle's bars are the only new motion in this sweep. The
   existing reduced-motion block at :770 covers the ticket button only, so the
   two new transitions declare their own. Reduced motion means the drawer still
   opens — it just arrives instead of sliding. */
@media (prefers-reduced-motion:reduce){
  nav.stub #primaryNav,nav.stub.nav-open #primaryNav,
  .bill-top .navtoggle .bars span{transition:none}
}

/* ============================================================================
   14. SETH'S MOBILE NOTES — 2026-08-11 (rev 3)
   ============================================================================
   Four corrections from his own pass over rev 2. Where one overrides a decision
   rev 2 made, the rev-2 comment is left in place above and the reversal is
   stated here, so the record shows the argument as well as the outcome.
   ========================================================================= */

/* --- 14a. ONE PHOTOGRAPH PER ROW, EVERYWHERE ------------------------------
   Seth: "all images on portfolios: record bin, the wall, they should all become
   1 photo per row at their selected AR rather than trying to fit multiple into
   a grid."

   ⚠ THIS REVERSES rev 2's snap-scrolling crate (block 2 above) and its 2-up
   561-700 tier (block 1). The crate rail was defensible — it kept sleeves at
   285px without adding scroll to the front page — but it asked the visitor to
   swipe sideways to see work they came to look at, and on a photography site
   the photograph should never be the thing you have to go find. His call is
   the simpler and the better one: full width, true aspect ratio, scroll down.

   The cost is real and worth stating: home's bin holds 21 sleeves, so the front
   page grows by roughly 3,000px. Measured after: see the brief.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .paper-gate .pgr{display:grid;grid-template-columns:1fr;gap:20px}
  .paper-gate .pgp{min-width:0;width:auto;height:auto;aspect-ratio:var(--ar)}

  .gate .gr{display:grid;grid-template-columns:1fr;gap:16px;
    overflow-x:visible;scroll-snap-type:none}
  .gate .gp{flex:none;width:auto;height:auto;aspect-ratio:var(--ar);
    scroll-snap-align:none}
}

/* --- 14b. THE CAPTION BELONGS TO ITS PHOTOGRAPH ---------------------------
   Seth: "each of the second row of images should have their caption below them
   instead of stacked after the images. (same applies to case study single)"

   `.b-frames` is two sibling grids — `.shots` (N images) and `.caps` (N labels)
   — which at 1440 stack as two column-aligned rows and read correctly. Collapse
   both to one column and you get N photographs followed by N orphaned labels,
   with nothing tying the fourth caption to the fourth frame.

   Fixed WITHOUT touching the markup: `display:contents` dissolves the two
   wrappers into the band's own grid, then each pair is placed explicitly.
   The desktop grid is untouched, and the port keeps the same two-container
   shape (one ACF repeater, image + caption per row).
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-frames{display:grid;grid-template-columns:1fr;row-gap:3px}
  .b-frames .shots,.b-frames .caps{display:contents}
  .b-frames .shots>*,.b-frames .caps>*{grid-column:1}
  /* pair i occupies rows 2i-1 (frame) and 2i (its caption). Written out rather
     than computed because CSS cannot read `--n`; six pairs covers every band in
     the build (home 4, the single 3) with room for the port. */
  .b-frames .shots>*:nth-child(1){grid-row:1}  .b-frames .caps>*:nth-child(1){grid-row:2}
  .b-frames .shots>*:nth-child(2){grid-row:3}  .b-frames .caps>*:nth-child(2){grid-row:4}
  .b-frames .shots>*:nth-child(3){grid-row:5}  .b-frames .caps>*:nth-child(3){grid-row:6}
  .b-frames .shots>*:nth-child(4){grid-row:7}  .b-frames .caps>*:nth-child(4){grid-row:8}
  .b-frames .shots>*:nth-child(5){grid-row:9}  .b-frames .caps>*:nth-child(5){grid-row:10}
  .b-frames .shots>*:nth-child(6){grid-row:11} .b-frames .caps>*:nth-child(6){grid-row:12}
  /* The caption is a reversed strip sitting hard on its own frame — that
     contact is what makes it belong to it, so the pair carries no gap and the
     air goes BELOW the caption instead (§6: the band owns the spacing).
     ⚠ `.b-frames .caps span`, NOT `.caps>*`. The base rule and the :1203 mobile
     rule are both (0,2,1); a `>*` reset is (0,2,0) and LOSES — the first attempt
     kept a stale `border-bottom` divider under every caption and never applied
     its own padding. Fifth time specificity has decided an outcome here: mirror
     the original selector, always.
     Centre is KEPT deliberately (it matches every width above 700, and a label
     centred under its own frame reads as a plate caption, not a list item); only
     the divider goes, because pairing now does the work it was doing. */
  .b-frames .caps span{border-right:none;border-bottom:none;
    margin-bottom:12px;padding:11px 16px}
  .b-frames .caps span:last-child{margin-bottom:0}
}

/* --- 14c. THE FILE LINE — 43% OF THE VIEWPORT BEFORE ANY WORK -------------
   Seth: "the categories and on-tour tags take up a huge section of the wall's
   view port on load. we need a better way of handling that."

   MEASURED on the-wall at 390 before this: `.b-file` = **366px, 43% of an 844px
   phone**, and the first photograph started at **817px** — below the fold on the
   page whose entire job is showing photographs. Fifteen chips (11 collections +
   4 cities) wrapping at ~44px a row is six rows of filter. rev 2's own
   tap-target floor made it worse, which is the honest reading: a 44px chip is
   right, six rows of them is not.

   The answer the component already suggests: `.b-file` IS the filing. A filing
   drawer's tabs run along ONE edge and you push past them to find the one you
   want. So on a phone the tiers become single horizontally-scrolling tab
   strips — one 44px row each instead of six, tap targets intact, no filter
   hidden behind a disclosure the visitor has to discover.

   ⚠ MARKUP UNTOUCHED. `.b-file` is inside Seth's locked area (the on-tour and
   the-wall page nav), so per the brief's standing rule this is done entirely on
   the rule, in theme.css.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-file{padding:11px 0 10px;text-align:left}
  .b-file .cue{padding:0 18px;font-size:.8125rem;line-height:1.35;margin-bottom:7px}
  .b-file .t1,.b-file .t2{
    white-space:nowrap;                 /* the row is a strip, not a paragraph */
    overflow-x:auto;overscroll-behavior-x:contain;
    scrollbar-width:none;-ms-overflow-style:none;
    text-align:left;
    /* ⚠ do NOT add `text-wrap:wrap` here to cancel t1's `balance`. `white-space`
       is a shorthand that SETS `text-wrap-mode`, and `text-wrap` sets it too —
       so a later `text-wrap:wrap` silently undoes the `nowrap` above it and the
       strip goes back to being a six-row paragraph. Measured: 176px, not
       scrolling, with both declarations present. `balance` is a text-wrap-STYLE
       and is inert under nowrap anyway, so there is nothing to cancel. */
    padding:0 18px;margin-left:0;margin-right:0;max-width:none}
  .b-file .t1::-webkit-scrollbar,.b-file .t2::-webkit-scrollbar{display:none}
  .b-file .t2{margin-top:7px;padding-top:7px}
  /* the 44px tap floor stays; in a single strip it simply sets the row height */
  .b-file a{display:inline-block;min-height:44px;line-height:2.6;padding:0 8px}
  .b-file .t1{font-size:1rem;letter-spacing:.04em}
  .b-file .t2{font-size:.8125rem}
}

/* --- 14d. THE BOOKING LINE COMES OFF THE PHONE HEADER ---------------------
   Seth: "remove the 'booking...' from the header."
   rev 2 kept "Booking summer & fall 2026" as the one line in the masthead that
   was a business signal rather than a label. He wants the phone header to be
   the mark and the toggle, full stop — which drops the header to a single row.
   The line still prints at every width above 700, and the booking status is
   still an ACF field (`booking_status`), so nothing is lost at the port.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .bill-top .desk{display:none}
  .bill-top{grid-template-rows:auto;padding:10px 16px}
}

/* --- 14e. HOME'S BIN IS A TEASER, SO IT SHOWS FOUR ROWS ON A PHONE --------
   MEASURED consequence of 14a on home, at 390: the bin band went
   **1,618px → 7,676px** and the page went **12,534 → 17,028px**. That is nine
   phone screens of record bin, and the booking ticket sits below all of it —
   on a site whose stated #1 business priority is not losing the one real lead a
   week. the-wall paid nothing for the same change (7,677 → 7,506) because it
   was already one-up; this is a home-only problem, caused by home carrying 21
   sleeves in a band whose own job is to tease.

   So the phone gets the first FOUR authored rows and then the CTA — which now
   reads "The Full Lineup → The Hall of Fame" and points at the page that holds
   all of it. Rows, not a sleeve count, because the rows are the authored
   grouping. Desktop is untouched: all 21 still print at every width above 700.

   ⚠ ONE LINE TO REVERT if Seth wants the whole catalog on the phone: delete the
   `:nth-of-type(n+5)` rule. ⚠ PORT: do not ship this as CSS. Hidden rows still
   sit in the DOM and in the ACF payload; the template should render the cap
   (a `bin_rows_mobile` number, or simply a shorter query) so the markup matches
   what is shown.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .gate .gr:nth-of-type(n+5){display:none}
}

/* --- 14f. THE FILE STRIP HAS TO SAY IT SCROLLS ---------------------------
   Seth: "we need some sort of indicator that it does in fact scroll
   horizontally rather than just be abruptly cut. id say the right edge should
   fade out."

   He is right that a hard cut reads as a layout bug rather than an affordance.

   ⚠ IS A FADE LEGAL IN THIS WORLD? DESIGN-TRUTH §5 bans mask fades — but it
   bans them on PHOTOGRAPHS, and for a specific reason: "a mask fade is a
   *lighting* effect", and the one-ink cut is printed, never lit. This is type
   on paper. Ink thinning out at the trim is a PRESSWORK behaviour — a starved
   roller, a fade-out screen — not a lighting one, so the law is not in play.
   Recorded here so the next pass doesn't flag it as a §5 breach.

   WHY `mask-image` AND NOT AN OVERLAY: `.b-file` is inside Seth's locked area,
   so no wrapper element may be added — and a `::after` on the scroller itself
   is positioned against the CONTENT box, so it would scroll away with the chips
   instead of sitting at the edge. A mask applies to the element's own border
   box, stays put while the content moves under it, and fades the ink to
   TRANSPARENT rather than to a colour — so it works over `--paper` and
   `.b-file.alt`'s `--paper-2` without knowing which it is on.

   The classes are set by `nav.js`, so the fade appears only on the side that
   actually has more to see. A permanent right-hand fade would leave the last
   chip half-printed once you had already reached the end, which is the same
   "looks like a bug" problem one edge further along.
   ------------------------------------------------------------------------ */
@media (max-width:700px){
  .b-file .t1,.b-file .t2{--edge:38px;-webkit-mask-image:none;mask-image:none}
  .b-file .t1.more-r,.b-file .t2.more-r{
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - var(--edge)),transparent 100%);
            mask-image:linear-gradient(to right,#000 calc(100% - var(--edge)),transparent 100%)}
  .b-file .t1.more-l,.b-file .t2.more-l{
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--edge));
            mask-image:linear-gradient(to right,transparent 0,#000 var(--edge))}
  .b-file .t1.more-l.more-r,.b-file .t2.more-l.more-r{
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--edge),
                       #000 calc(100% - var(--edge)),transparent 100%);
            mask-image:linear-gradient(to right,transparent 0,#000 var(--edge),
                       #000 calc(100% - var(--edge)),transparent 100%)}
  /* ⚠ NO scroll-snap here. It was added to stop a chip resting half-under the
     fade, and it did something worse: the cities tier came up **already
     scrolled to 74px** on load, because the browser snapped to a chip before
     anything had asked it to — so the strip looked like it had lost its first
     item, and the fade state was computed before that happened. A filter strip
     is also the wrong place for snapping: the user is scanning for one name,
     not paging through cards, and snap fights a short flick. */
}

/* ============================================================================
   (h) THE PRESS — the news surfaces, 2026-08-11
   ============================================================================
   Three files join the suite: press.html (the index), press-single.html (a
   post) and press-archive.html (a category/tag archive). They map onto the
   live theme's home.php / single.php / archive.php, whose contracts were read
   off the server rather than guessed, and they are built from the SHARED
   chassis — .mast, .cshead, .csrow, .b-file, .b-photo, .gate-band, .b-plate.

   Four declarations are genuinely new, plus two PROMOTIONS. The promotions are
   R13: a page-local fork that acquires a second user moves to theme.css rather
   than being copy-pasted, which is how .pgr / .gate-band / .wl-note drifted.
   ========================================================================= */

/* --- PROMOTION 1: the two-part page-name lockup ---------------------------
   Declared page-locally in on-tour.html since 2026-08-10. theme.css ALREADY
   carries its mobile clamp (`.mast h1 .h1-role` inside the :700 block), so the
   base rule living in one page's <style> while its override lived here was the
   fork half-made. The Press is its second user, so it comes home.
   On press.html it does real work: the Hatch name headlines and the live H1
   string ("Latest Press & Articles") stays visible as the role line, so the
   port changes the page's look without deleting the phrase it ranks on. */
.mast h1{display:block}
.mast h1 .h1-role{display:block;font-family:var(--gothic);font-size:1.4rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);text-shadow:none;margin-top:6px}

/* --- PROMOTION 2: jacket-back two-column prose ----------------------------
   Declared page-locally in liner-note-single.html. Same rule, same measure.
   The essay plate is the shape Seth approved for a long read ("one big text
   block"), and a news post is the same job. */
.field .prose{columns:2;column-gap:50px}
.field .prose p+p{margin-top:14px}

/* NEW 1 — the SHORT post. Two of the 30 live posts are a single paragraph
   (Neuhoff Curve is one sentence and a link). Three lines split across two
   columns reads as a typesetting accident, not as liner notes, so a short
   post keeps one column at the reading measure the undercard field already
   uses (44rem ~= 75ch at body size). */
.field .prose.single{columns:auto;max-width:44rem}

/* NEW 2 — SUBHEADS INSIDE THE ESSAY. The case-study single had none; a news
   post does (Taylor Place carries five). Anton is the label voice (truth §4),
   so a section head inside the prose is fine print in that voice, not a second
   display face. break-after keeps a head off the foot of a column — the one
   way a multicol essay looks broken. More air above than below, per the
   spacing law. */
/* ⚠ h3, h4 — NOT a bare h3. The mockup hand-set the essay's subheads as <h3>;
   a real post's are whatever the editor typed (the live Taylor Place post uses
   <h2 class="wp-block-heading">). single.php demotes content headings by one
   level so the outline reads h1 title -> h2 plate label -> h3 subhead, and this
   selector is widened so an editor's <h3> (demoted to h4) is still styled. Both
   halves are needed: this is the same class of bug as `.cshead h3`, which sat
   orphaned for three passes after a heading was promoted. h5/h6 are covered
   too: a post using three distinct heading levels normalises to h3/h4/h5. */
.field .prose h3,.field .prose h4,.field .prose h5,.field .prose h6{font-family:var(--gothic);font-size:1.0625rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink);line-height:1.25;margin:22px 0 7px;
  break-after:avoid-column;break-inside:avoid-column;page-break-after:avoid}
.field .prose h3:first-child,.field .prose h4:first-child,.field .prose h5:first-child,.field .prose h6:first-child{margin-top:0}

/* NEW 3 — THE DEPARTMENT LINE. A bill row is ranked by its year; a news row is
   ranked by its section, and the live template prints it (home.php's .jmeta b).
   The row had no slot for it, so this is the same kind of chassis completion
   .b-rows.txt was. Anton fine print in --tomato-text, MEASURED at 5.55:1 on
   --paper and 5.03:1 on --paper-2 — both clear the 4.5:1 small-text floor, and
   --tomato (4.49) would not. The separator star stays full-chroma --tomato with
   the other ~151: it carries no information. */
.csrow .bill .dept{font-family:var(--gothic);font-size:.75rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--tomato-text);text-indent:.15em;line-height:1.3}
.csrow .bill .dept .st{color:var(--tomato);font-size:.85em;margin:0 3px;vertical-align:middle}

/* NEW 4 — THE HEADLINE IS A LINK, and a list of 30 links must say which one is
   under the cursor. The suite has exactly two :hover rules in 147KB, which is
   right for a printed sheet — but an index is the one surface where the sheet
   is also a control panel. Kept to the ink world: the headline takes the small
   -text red and a 2px rule, the same two moves the rest of the design uses to
   mark a link. :focus-visible is already global (mustard). */
.csrow .bill h3 a,.csrow .bill h2 a,.cshead h2 a{color:inherit;text-decoration:none}
.csrow .bill h3 a:hover,.csrow .bill h2 a:hover{color:var(--tomato-text);text-decoration:underline;
  text-decoration-thickness:2px;text-underline-offset:4px}
.cshead h2 a:hover{text-decoration:underline;text-decoration-thickness:3px;text-underline-offset:6px}

/* --- ADDENDUM B on the headliner button ----------------------------------
   Tomato BOOKS, pine NAVIGATES (quiet pass, 2026-08-10). `.cshead .go` is
   tomato because the case-study index was built before that law existed, and
   "Read the story" navigates. The Press's headliner takes pine. The
   liner-notes instance is REPORTED, not changed — it is Seth's call whether
   the case-study index button is a breach or a grandfathered exception. */
.cshead .go.nav-go{background:var(--pine)}

/* --- ⚠ CHASSIS BUG FIX, found building The Press — PRE-EXISTING ------------
   `.cshead .frame-cell{aspect-ratio:3/2}` sits on a grid item that
   `.cshead{align-items:stretch}` has already given a definite height. With
   `width:auto`, aspect-ratio therefore derives the WIDTH FROM THE HEIGHT: a
   490px billing block became a 735px cell in a 620px track. MEASURED at 1440
   on liner-notes.html — 112px past the trim, today, and invisible because
   `.frame{overflow:hidden}` swallows it. The Press's longer headliner drove the
   same bug to 248px, which is how it was noticed.

   Pinning the width makes it definite, so aspect-ratio has nothing left to
   derive and survives only as the intrinsic FLOOR — the cell can never be wider
   than its column, and never shallower than 3:2. Both of the 2026-08-11 note's
   goals hold; only the overflow goes. (SPAN.ht-tr +94 stays: intentional
   decorative bleed.) */
.cshead .frame-cell{width:100%}

/* The Press's headliner is whatever Seth posted last, so its length is not a
   thing the design can know. "Neuhoff Curve — Building of the Year" set three
   lines with "YEAR" alone on the third — a widow in 67px of Alfa Slab. balance
   evens the lines whatever the title turns out to be; the case-study index is
   unaffected because its headliner carries an explicit <br>. */
.cshead h3,.cshead h2{text-wrap:balance}

/* --- PROMOTION 3 (R13): THE MARQUEE TAPER --------------------------------
   The four-tier Anton bill taper — ON THE MARQUEE's list of names — was
   declared inside the-photographer.html while theme.css already carried its
   responsive steps (`.b-proof .nm` at :1323/:1333/:1340/:1987) and its
   synthetic-bold pin (:1436). Same half-made fork as `.h1-role`. Nashville's
   "Already on the Block" is its second user, so the base rules come home,
   rescoped from `.b-proof` to `.field` — the taper belongs to any plate's
   field, not to one page's chassis fork.

   DESIGN-TRUTH §8 is the whole point of the numbers: size steps down AND the
   interval compresses with it (0 → 9 → 6), so the rhythm carries the billing
   order as well as the size does. `.m4` is the undercard — its own hairline
   and looser leading, so it reads as deliberate fine print rather than as a
   display line that failed. Values are byte-identical to About's; that page
   was verified unchanged by geometry diff after the move. */
/* --- THE TIER CAP: the taper has to fit the NAMES, not the mockup's names ---
   ⚠ PORT FINDING, measured on staging 2026-08-11. Every tier size here was set
   against the hand-built list, where m1 held three short acts ("The 2019 NFL
   Draft ★ NASCAR Hall of Fame ★ The New Orleans Superdome"). The taper is
   POSITIONAL, so once the names come from the repeater the top tier holds
   whatever Seth put first — and the live order puts "Justin Timberlake's 12/30
   Club" there: 323px of nowrap Anton in a 296px field at 390px. Invisible,
   because `.frame{overflow:hidden}` swallows it.

   DESIGN-TRUTH §8 already says what to do — "a bill never splits an act's name;
   the tier type shrinks instead" — so the size is now a CEILING rather than a
   value. `--nc` is the longest name's character count in that tier, emitted by
   ps_bb_taper(); `--cw` is the measured width-per-character of that tier's face,
   as a fraction of font size.

   ⚠⚠ MEASURE AFTER THE FONTS LOAD. The first pass at this took 0.343–0.429 from
   a viewport measured immediately after navigation — those are FALLBACK metrics,
   and the real faces run about 30% wider, so the cap it produced still let a
   536px track open inside a 718px band at 768. Re-measured with the fonts
   settled: Anton 0.445–0.494, Libre Caslon italic 0.451–0.565. Hence 0.50 for
   the Anton tiers and 0.58 for the Caslon ones, each with headroom. Same trap
   the edge-fade sync hit: a first-paint measurement measures the fallback.

   Available width is the sheet less its
   furniture: 44 sheet + 6 border + 250 plate + 88 field padding = 388px, or 94px
   once the plate stacks below 700 — PLUS 30px, because the unbreakable atom is
   not the name. `&nbsp;` glues each name to the star that follows it, so
   name + nbsp + ★ + its 9px margins travels as one unit; measured, that is what
   still put m2 nine pixels into the field's gutter after the first pass.

   Desktop is arithmetically unmoved: at 1440 the m1 ceiling computes to 116px
   against a 31.2px tier, so min() returns the tier every time. Verified by
   measurement, not by reasoning — see the geometry check at 1440.

   If a browser cannot divide by a var() the whole declaration is invalid and the
   tier keeps its authored size, which is exactly today's behaviour. */
.field .fr{font-size:min(var(--fs,1.0625rem),calc((100vw - 418px) / (var(--cw,.5) * var(--nc,1))))}
@media (max-width:700px){
  .field .fr{font-size:min(var(--fs,1.0625rem),calc((100vw - 124px) / (var(--cw,.5) * var(--nc,1))))}
}
.field .fr.m1,.field .fr.p1{margin-top:0}
.field .fr.m2,.field .fr.p2{margin-top:9px}
.field .fr.m3,.field .fr.p3{margin-top:6px}
.field .fr.m4{margin-top:18px}
.field .fr.m1{font-family:var(--gothic);--fs:1.95rem;letter-spacing:.03em;
  text-transform:uppercase;line-height:1.2;color:var(--ink)}
.field .fr.m2{font-family:var(--gothic);--fs:1.5rem;letter-spacing:.04em;
  text-transform:uppercase;line-height:1.26;color:var(--ink)}
/* ⚠ 2026-08-12: line-height was 1.3. Where m3 wraps to two lines (7 buildings
   is enough at most desktop widths — measured on Nashville's Already on the
   Block), that leaves only 5.71px between the wrapped lines: LESS absolute
   leading than m1 or m2 give their own line-box (6.24px each), despite m3
   sitting between them in the taper and the undercard below it getting a
   deliberately loose 9.3px. Tightest gap in the whole list, in the middle of
   it — that's the "3-4 smushed" Seth flagged. 1.4 gives m3 7.62px, restoring
   the taper's increasing-looseness order (6.24 → 6.24 → 7.62 → 9.3) without
   reaching m4's dedicated fine-print treatment. Single-line renders (m3 with
   ≤6 buildings) are unaffected — line-height only shows once a tier wraps. */
.field .fr.m3{font-family:var(--gothic);--fs:1.19rem;letter-spacing:.05em;
  text-transform:uppercase;line-height:1.4;color:var(--ink)}
/* ⚠ 2026-08-12: was `margin:18px auto 0;max-width:60rem`, undocumented and
   unlike every other rule in this tier — no DESIGN-TRUTH citation, no measured
   rationale. §8 asks only for a hairline above and looser leading on the
   undercard tier (the border-top/padding-top/line-height below); it never asks
   for the tier to narrow and center. Measured on Nashville's Already on the
   Block at 1728px: m1–m3 ran the full 1172px field, m4 sat capped at 960px,
   inset 106px on each side — the "doesn't span the column" Seth flagged. Same
   defect on Huntsville's Already on the Block and the About page's client
   marquee (both reach a 4th ps_bb_taper() tier by default). Now left-aligned
   and full-width like m1–m3, everywhere .fr.m4 renders. */
.field .fr.m4{font-family:var(--gothic);--fs:.9375rem;letter-spacing:.07em;
  text-transform:uppercase;line-height:1.62;color:var(--ink-dim);
  padding-top:15px;border-top:1px solid var(--rule)}

/* --- PROMOTION 4 (R13): the Q&A inside a plate field ----------------------
   `.qa` carries `margin:0 44px` from when it stood on the front page as its own
   block. Inside a `.b-plate > .field` — which already pads 44px — that doubles
   to an 88px gutter, and the Q&A sits measurably further in than every other
   field on the sheet. book.html had already fixed it with a page-local
   `.field .qa{margin:0}`; nashville.html's Advance band is the second user, so
   the fix comes home rather than being copy-pasted a second time. */
.field .qa{margin:0}

/* ============================================================================
   THE TABLET TIER, 701–1000 — the numeral rows. 2026-08-11
   ============================================================================
   The last piece of measured tablet debt (brief §0h). MEASURED at 768: the band
   is 720px, the chassis is `250px repeat(4,1fr)`, and the computed tracks came
   out `250 / 115 / 124 / 134 / 136` — a 759px row inside a 720px frame, i.e.
   **39px past the trim on home, About and the case-study single**, hidden as
   always by `.frame{overflow:hidden}`.

   Root cause is the law this codebase keeps re-proving: **a grid track is sized
   by its largest min-content contributor**, and `1fr` cannot shrink below it.
   Here that contributor is a 2.9rem Alfa Slab numeral ("2024" measures 126px)
   and a tracked Anton label, in a ~117px cell. `min-width:0` alone would let the
   track shrink but the numeral would then overflow its own cell, so the row also
   has to go two-up — which is already the established tablet grammar for the
   galleries and the record bin.

   The 250px plate STAYS a left edge here, unlike the phone tier: at 720px it
   still fits and DESIGN-TRUTH §2a's left edge is worth keeping wherever it does.
   Dividers switch from `border-right` on a child to the band's own ink ground
   showing through a 2px gap — the mechanism §2b prescribes and the one the
   memory calls out by name. It is also N-agnostic, so a band with three or five
   cells cannot regress this the way an `nth-of-type` rule could.
   `.bnd.b-adm` (0,2,0) is required to beat the-photographer.html's page-local
   `.b-adm` (0,1,0), per the specificity trap in the brief. */
@media (min-width:701px) and (max-width:1000px){
  /* ⚠ 2026-08-12: 250px → 248px on both rules below — the same 250px+gap
     drift as the Juried and On the Bill fixes earlier, just scoped to this
     one breakpoint. MEASURED on About at 900px: Admission's content started
     at 252px while In Print and On the Marquee (`.b-plate`, no gap here)
     start at 250px. Identical remedy: the label gives up the gap's width
     (2px here, not 3, because this tier's furniture gap is 2px) so content
     lands on the same 250px line regardless of which mechanism draws the
     band's divider. */
  .bnd.b-acts{grid-template-columns:248px repeat(2,1fr);gap:2px}
  .bnd.b-acts>.shot{border-right:none}
  .bnd.b-acts>.lbl{grid-row:1 / span 2}
  .bnd.b-rows,.bnd.b-adm{grid-template-columns:248px repeat(2,1fr);
    background:var(--ink);gap:2px}
  .bnd.b-rows>*,.bnd.b-adm>*{min-width:0;background:var(--paper)}
  .bnd.b-rows>.lbl,.bnd.b-adm>.lbl{grid-row:1 / span 2;background:var(--ink)}
  /* keep the stripe, now as a checkerboard — and the 2px ink gap is what stops
     two paper-2 cells meeting across the row seam (truth §6) */
  .bnd.b-rows>.px:nth-of-type(even),.bnd.b-adm .px:nth-of-type(even){background:var(--paper-2)}
  /* the furniture does the dividing now; a border on one child would double it */
  .bnd.b-rows>.px,.bnd.b-adm .px{border-right:none}
}

/* --- THE TABLET HEADER, 701–900. 2026-08-11 --------------------------------
   ⚠ MEASURED, and it is a regression rather than a tablet cost: the header runs
   **169px at 900–1440 but 208px at 768** — 39px TALLER on the smaller screen.
   There was no tablet tier for the header at all; 701–900 inherited the desktop
   sizing inside a narrower box and two things wrapped:
     · `.desk .r2` (the cities line) went 18px → 35px at a 356px measure;
     · the nav label wrapped to two lines (link 56px → 76px) because six cells
       at 768 are ~119px and "Book a Session" at 13px/.1em measures about that.
   Both are text overflowing a box, not a design that needs more room.

   The cities line is dropped, exactly as the phone tier already drops it — it
   is repeated verbatim in the colophon, so nothing is lost. The nav label drops
   a step and tightens its tracking so all six hold one line. Nothing above 900
   is touched. */
@media (min-width:701px) and (max-width:900px){
  .bill-top .desk .r2{display:none}
  nav.stub a{font-size:.75rem;letter-spacing:.05em}
  nav.stub a small{font-size:.71875rem;letter-spacing:.01em}
  .bill-top .id .sub{letter-spacing:.22em}
  /* ⚠ retracking .sub to .22em takes it 231.2 → 196.6px, so the DERIVED name
     size at :77 no longer matches in this band. 196.6/190.8 × 24 = 24.7px;
     1.5625rem measures 198.8, i.e. +2.2px. Change both or neither. */
  .bill-top .id .wm{font-size:1.5625rem}
}

/* ===========================================================================
   (i) THE LIGHTBOX — PORTED 2026-08-11, re-inked
   ===========================================================================
   The live theme wraps every gallery image in `<a class="pf-zoom">` and
   initLightbox() (assets/js/interactions.js) gives prev/next/Esc/arrow/swipe.
   The mockups carry the anchors, but the overlay's styling lived in the OLD
   stylesheet, which these pages no longer load — so porting the anchors without
   this block would have shipped a feature that half-works: the click is
   intercepted, and the viewer opens invisible.

   The class contract is UNCHANGED (.ps-lb / .lb-close / .lb-prev / .lb-next /
   .lb-ct), so interactions.js is untouched. Only the ink moves:
   · ground is --night, the design's blue-black surface, not a warm-black wash;
   · the frame is a 3px --paper keyline — a print reversed out, not a 1px
     hairline of translucent white;
   · controls are Anton on paper over ink, hover to --mustard. NOT tomato:
     addendum B reserves tomato for the one BOOK ask, and a viewer control is
     navigation.
   · the counter is Caslon italic — the human voice, per truth §4, which is also
     the only voice that owns a small annotation on this sheet. */
.ps-lb{position:fixed;inset:0;z-index:1000;background:rgba(24,27,38,.965);display:none;
  align-items:center;justify-content:center}
.ps-lb.open{display:flex}
.ps-lb img{max-width:min(92vw,1600px);max-height:88vh;width:auto;height:auto;display:block;
  border:3px solid var(--paper)}
.ps-lb button{position:absolute;width:46px;height:46px;display:grid;place-items:center;
  border:2px solid var(--paper);background:transparent;color:var(--paper);
  font-family:var(--gothic);font-size:1.125rem;line-height:1;cursor:pointer;padding:0}
.ps-lb button:hover,.ps-lb button:focus-visible{border-color:var(--mustard);color:var(--mustard)}
.ps-lb .lb-prev{left:18px;top:50%;transform:translateY(-50%)}
.ps-lb .lb-next{right:18px;top:50%;transform:translateY(-50%)}
.ps-lb .lb-close{top:18px;right:18px}
.ps-lb .lb-ct{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);
  font-family:var(--liner);font-style:italic;font-size:.9375rem;color:rgba(246,241,229,.75)}
/* 44px floor is the suite's tap-target rule; the arrows also come off the bezel
   so a thumb reaching the edge does not catch the browser's own back gesture. */
@media (max-width:560px){
  .ps-lb button{width:44px;height:44px}
  .ps-lb .lb-prev{left:10px}
  .ps-lb .lb-next{right:10px}
  .ps-lb .lb-close{top:10px;right:10px}
}

/* ===========================================================================
   (j) EDITOR COPY CAN CONTAIN A BARE URL — PORT FINDING, 2026-08-11
   ===========================================================================
   The mockups' excerpts were hand-written, so no line ever carried an
   unbreakable token. Real WordPress excerpts do: the Neuhoff post's auto-excerpt
   is a sentence followed by a raw
   https://boty.archdaily.com/us/2026/candidates/179675/... and at 375px that
   ran 220px past its column.

   ⚠ THE MEASUREMENT NOTE, because this defeats both harnesses the suite uses.
   An overlong inline token overflows its box WITHOUT widening it, so:
     · a viewport check sees nothing (the <p> is still 300px wide);
     · the "measure against the nearest clipper" check sees nothing either —
       the box is inside .frame, and the box is not what is overflowing.
   `scrollWidth > clientWidth` on the text block is what finds it. That is the
   third distinct overflow trap in this codebase, after `.frame{overflow:hidden}`
   and the scroll containers.

   `anywhere` rather than `break-all`: it only breaks when a line cannot
   otherwise fit, so ordinary prose is untouched at every width. Scoped to the
   four places editor copy lands. */
.cshead .cr,
.csrow .bill .cr,
.mast .lede,
.field .prose{overflow-wrap:anywhere}

/* ===========================================================================
   (k) THE LOAD-MORE RESERVE — PORTED 2026-08-11
   ===========================================================================
   `.is-hidden` is the class interactions.js:initLoadMore() removes to reveal the
   next batch. It was declared in the OLD stylesheet, which these pages no longer
   load — so the hall would have printed its entire collection at once (up to 77
   images on Hotel & Hospitality) with a Load More button that did nothing
   visible. Same class of gap as the lightbox overlay.
   `.wl-more` is the button's band: paper, centred, on the design's own control
   ink — pine, because revealing more of the wall navigates, it does not book. */
.is-hidden{display:none}
.pf-more{position:relative;z-index:2;text-align:center;margin-top:34px}
.pf-more button{font-family:var(--gothic);font-size:.9375rem;letter-spacing:.18em;
  text-transform:uppercase;text-indent:.18em;color:var(--paper);background:var(--pine);
  border:3px solid var(--ink);padding:13px 26px;cursor:pointer;
  box-shadow:5px 5px 0 var(--ink);transition:transform .06s,box-shadow .06s}
.pf-more button:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 var(--ink)}
.pf-more button:active{transform:translate(5px,5px);box-shadow:0 0 0 var(--ink)}
@media (max-width:700px){ .pf-more button{min-height:44px} }

/* ===========================================================================
   (l) A PAGE NAME LONGER THAN THE MOCKUP'S — 2026-08-11
   ===========================================================================
   ⚠ MEASURED on /hotel-hospitality-photography/ at 390: the masthead h1 ran
   21px past its box. `.mast h1` already scales with the viewport
   (clamp(2rem,11vw,5.5rem)) and already wraps between words — what it cannot do
   is break a single long WORD, and "Hospitality" in Alfa Slab at 42.9px is
   wider than a 304px field. The mockup never hit this because it only ever set
   "The Hall of Fame".

   Now that eleven term names and thirty post titles feed this slot, it has to
   survive any of them. `hyphens:auto` breaks with a hyphen where the language
   allows one — which is what a compositor would have done — and
   `overflow-wrap:anywhere` is the floor beneath it for a word no dictionary can
   split (a URL, a product name). Neither fires on a name that fits, so every
   page in the mockups is unchanged.

   ⚠ Deliberately NOT `.nm`: DESIGN-TRUTH §8 says a bill never splits an act's
   name, and that law is about the taper, not the page name. The taper solves the
   same problem by shrinking the type (see THE TIER CAP). */
.mast h1{hyphens:auto;overflow-wrap:anywhere}
.mast h1 .h1-role{hyphens:none;overflow-wrap:normal}

/* ===========================================================================
   (m) THE CASE STUDIES — two port additions, 2026-08-11
   ===========================================================================
   Both are consequences of real data replacing the mockup's hand-set copy.
   Neither changes a page the mockups drew.

   1. A FRAME BAND WITH NO CAPTIONS. `.b-frames` is two sibling grids — the
   shots and a compartmented caption strip — and the phone tier interleaves them
   with `display:contents` plus explicit `grid-row` pairs, so shot N sits above
   caption N. MEASURED on staging: not one of the twelve case studies' gallery
   attachments carries a caption, so the strip is not printed (a half-filled
   compartment row reads as a mistake, not as a caption). Without the strip the
   pairing rules leave the even rows empty and the stack carries N phantom
   3px gaps. `.nocaps` puts the shots back on their own grid; the pairing rules
   still govern the moment Seth types a caption on every frame of a project.

   2. THE UNDERCARD'S LEDE. `.b-proof>.field .lede` was declared for About's
   two proof bands only; THE HONOURS on a case study is the same job — one
   Caslon line stating the attribution above a taper — so the rule comes home to
   `.b-under`, un-centred, because an undercard field is left-aligned. Values
   are the About declaration's, minus the centring it does not want. */
@media (max-width:700px){
  .b-frames.nocaps .shots{display:grid;grid-template-columns:1fr;gap:3px}
  .b-frames.nocaps .shots>*{grid-row:auto}
}
/* ⚠ 2026-08-12: `.b-plate:not(.b-proof)` added to both selectors below. The
   Honours moved from `.b-under` to a full `.b-plate` this session (Seth:
   awards can be loud) and its own lede — "The award went to the building…" —
   silently lost every declaration here, since `.b-under>.field .lede` no
   longer matched anything on that band. Caught by re-checking rather than
   assuming the chassis swap was cosmetic-only. NOT a bare `.b-plate>.field
   .lede`: On the Marquee and In Print are ALSO `.b-plate` (plus `.b-proof`),
   already styled by :592 with a centred margin and `text-wrap:balance` this
   rule does not set — a bare selector would match both at equal specificity
   and, coming later in the file, win and silently un-centre their ledes. */
.b-under>.field .lede,.b-plate:not(.b-proof)>.field .lede{font-family:var(--liner);font-size:1.0625rem;line-height:1.5;
  color:var(--ink-dim);max-width:52rem;margin:0 0 18px}
.b-under>.field .lede em,.b-plate:not(.b-proof)>.field .lede em{font-style:italic;color:var(--tomato-text)}

/* --- (m3) THE ROW HEADLINE IS A TAP TARGET -------------------------------
   MEASURED at 390 on the case-study index: one anchor on the sheet came in
   under 44px — "Boyle Investments", 192×37, because a headline that fits on ONE
   line is only as tall as its line box. Every other link on the page was
   already covered by the :1344 rule, which lists `.csrow .go` but not the
   headline above it. The Press has the same construction and only escaped it
   because thirty post titles all wrap to two lines.

   `display:block` rather than the `inline-flex` that rule uses: a wrapping
   headline must keep its normal line boxes, and centring a two-line title
   inside a 44px floor would move it. The floor only ever fires on a title short
   enough to set in one line, and the 7px it adds falls inside the row's own
   gap. Desktop is untouched — this is inside the phone tier. */
@media (max-width:700px){
  .csrow .bill h2 a,.csrow .bill h3 a{display:block;min-height:44px}
}

/* --- (m4) A MULTI-PARAGRAPH MASTHEAD LEDE --------------------------------
   `.mast .lede` was written for the mockups' single hand-set paragraph. The
   booking page's lede is the PAGE CONTENT — Seth's own promise copy, 506
   characters the editor may split into two or three paragraphs — so the
   template wraps it rather than replacing it, and the paragraphs need the
   spacing the band's single <p> never did. Same 14px the essay plate uses.
   A one-paragraph lede is byte-identical to before. */
.mast .lede p{margin:0}
.mast .lede p+p{margin-top:14px}

/* ===========================================================================
   (n) THE FRONT PAGE — four promotions out of home.html's inline <style>
   ===========================================================================
   Same class of half-made fork as `.h1-role` and `.field .prose`: home.html
   declared these page-locally while theme.css already carried their responsive
   steps. A template cannot ship an inline <style>, and the port's rule is that a
   base declaration comes home rather than being copy-pasted. Values are
   byte-identical to the mockup's — home is verified unchanged by the geometry
   diff, so this moves nothing.

   ⚠ `.gold-list` / `.g-row` are deliberately NOT promoted here. They are the
   awards ledger, and Certified Gold left the front page on 2026-08-11 — they
   belong to the awards sheet and come home with it. */

/* (1) the four standing engagements — RETIRED 2026-08-12: the `.eng4`/`.b4`
   cards became the `.eng-run` runsheet (see the .b-eng note ~:720). */

/* (2) the singles rack, inside an undercard field */
.field .rack-shelf{justify-content:flex-start;gap:34px 44px}
.field .cut{width:158px}
.field .roll{margin-top:24px;border-top:2px solid var(--ink);padding-top:13px;
  font-family:var(--gothic);font-size:.9375rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-dim)}
.field .roll b{color:var(--tomato-text);font-weight:400}

/* (3) three testimonials as one row of fine print, not three cards */
/* `.q3` RETIRED 2026-08-12 — the testimonials print as the BLURB TAPER now:
   pulled phrases on the shipped .fr.p1/.p2/.p3 print tiers (About's In Print
   grammar), one .pull per repeater row, cite under each. ⚠ The pulls emit
   NO --nc, on purpose: the .fr fit formula's char-count cap protects
   unbreakable act NAMES (§8); a quotation is ordinary text and simply wraps
   at narrow widths (verified 390: no overflow). Do not "fix" the cap in. */
.field .pull{margin:0 0 26px}
.field .pull:last-child{margin-bottom:0}
.field .pull cite{display:block;margin-top:8px}

/* (4) THE TABLET TIER for both — MEASURED at 768, and the q3 half is a real
   defect the mockup could not have: at 701–1000 the plate is still a 250px left
   edge (§0o kept it there deliberately), so the field is **380px**, and three
   testimonial columns plus two 44px gaps overflowed it by **44px** — clipped in
   silence by `.frame{overflow:hidden}`. One column at this tier; the quotes are
   a read, not a comparison.
   `.eng4` did NOT overflow at 768 — four cards fit at 180px each — but 180px is
   a squeeze for a 3:2 photograph over three lines of copy, and two-up at
   701–1000 is the tablet grammar this codebase already settled on for the
   galleries, the record bin and the numeral rows. */
/* .q3 / .eng4 tier rules retired 2026-08-12 with the blurb taper and the
   runsheet — the .fr.p* tiers and .eng-run carry their own reflow. */

/* --- (n5) `.maj` / `.min` JOIN THE TIER CAP -------------------------------
   MEASURED at 320 on the front page: the Notices band is the ONE taper in the
   suite that never got the ceiling. Every other tier declares `--fs` and lets
   `.field .fr{font-size:min(--fs, (100vw - 124px) / (--cw * --nc))}` cap it;
   `.maj` and `.min` declare `font-size` outright at (0,3,0), which beats the
   base rule at (0,2,0), so they render their authored size at every width no
   matter how long a name gets. It has not bitten yet — "Architectural Digest"
   measures 194px in a 238px field at 320 — but `seen_in` is a list Seth edits,
   and DESIGN-TRUTH §8 says the type shrinks rather than the name breaking.

   `--cw` is MEASURED, not inherited from the print tiers: Libre Caslon italic
   comes out at **0.304** of its font size per character bold and 0.291 plain,
   against Anton's 0.478. ⚠ The `.p1/.p2/.p3` tiers carry `--cw:.58` for the
   same face — roughly double the measured value, which is why About's Notices
   converge to 23/23/21px at 390. That is an already-approved page, so it is
   REPORTED rather than changed here; see the port log.
   The fix itself is applied AT SOURCE (search `--fs:2rem`) rather than as an
   override down here — `font-size:unset` from a higher-specificity rule means
   `inherit`, not "fall back to the base rule", and measured it collapsed both
   tiers to the 17px body size. */

/* ===========================================================================
   (o) THE POSTER WALL — normalised, 2026-08-11
   ===========================================================================
   Seth: "make sure i have a poster builder in the port that is a part of
   acf/template." This is the promotion that makes that possible, and it is the
   one place the port legitimately touches the LOCKED posters — the lock is on
   the LOOK ("what i dont want to do here is destroy the posters"), and the
   acceptance test is that the rendered wall is unchanged.

   WHAT WAS WRONG WITH THEM AS DRAWN. The eight are eight hand-set one-offs, not
   eight instances of one component: 17 slot classes, no two posters using the
   same set, and 23 inline `style=` attributes carrying colour and spacing
   decisions the variant class did not own. A builder cannot reproduce that from
   fields, because a field cannot emit an inline style without becoming a
   CSS editor.

   THE NORMALISATION is: ONE component = (variant token × a fixed optional slot
   set), with every inline style folded into its variant class. Three semantic
   slot classes are added so a variant can address a `.tiny` by its JOB rather
   than by its position — `.p-kick`, `.credit`, `.dlabel`. ⚠ NOT `.kicker`: that
   is already a global rule at :693 (the masthead's italic tomato line), and
   borrowing it painted the Night and Mustard posters' kickers tomato — caught
   by the geometry diff, two slots out of 55. That is the whole of
   the change; the values below are the mockup's own, moved.

   ⚠ `t1` / `t2` ARE INERT. PORT-MAP called them "the three colourways"; grep
   says nothing declares them, in the mockup or here. They are carried through
   the builder so the markup stays byte-comparable, and the field says so.
   ---------------------------------------------------------------------------
   THE SHARED CHASSIS ------------------------------------------------------- */
/* ⚠ POSTER SIZE, 2026-08-12 (Seth: "the poster text bigger by a decent amount.
   its tough to read at 1440"). MEASURED before: the wall ran 4-up at 1440 with
   each poster 328px, which put the kicker and date lines — `.tiny` and `.dates`
   at 4.13cqw — at **13.5px**. That is the smallest type on the sheet, on the
   page whose whole job is a wall of awards.

   The fix is this ONE NUMBER, not the type scale. Every slot inside `.mp` is
   declared in `cqw` against the poster's own inline size and the poster holds a
   fixed 3/3.9 aspect, so widening the track scales all 55 slots in register and
   CANNOT change the composition — which is also why no geometry re-diff is
   needed against the hand-set original. Touching the 17 slot multipliers would
   have required exactly that.

   280 -> 330 is the whole edit, and 330 is not arbitrary: it is the only value
   that takes 1440 from four columns to THREE (poster 328 -> ~440px, type +34%,
   `.tiny` 13.5 -> 18.2px) while still leaving 768 at two columns. A larger floor
   would have dropped the tablet to one poster per row. */
.pwall{margin:46px 24px 0;position:relative;z-index:2;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:10px}
.pwall-band{background:var(--paper);padding:46px 0}
.pwall-band .pwall{margin-top:0}
/* container units, so a poster's type scales with ITS OWN width and the wall can
   reflow to any number of columns without a single media query inside it */
/* ⚠⚠ THE PADDING WAS THE REASON THE POSTERS WERE UNREADABLE — 2026-08-12.
   It was `padding:6.7cqw 4.3cqw` on `.mp` itself. `container-type:inline-size`
   makes an element a container for its DESCENDANTS, never for itself, so those
   two `cqw` values resolved against the nearest ancestor container — of which
   there is none — and therefore against the VIEWPORT. Measured at 1440:

       padding          96.48px / 61.92px     (6.7% and 4.3% OF 1440)
       poster           328px wide
       content box      200px      <- 39% of the poster eaten by its own padding
       .tiny / .dates   8.3px
       smallest slot    6.6px

   And because every slot inside is `cqw` of that content box, all 55 of them
   were computing against 200px instead of ~300px. The wall was not designed
   small; it was designed correctly and then rendered at 61% scale. It was also
   silently viewport-coupled — the same poster at 768 would have had a different
   padding-to-type proportion, which is not a thing any other component here does.

   Percentages fix it exactly: padding-% resolves against the containing block,
   which for a grid item is its track. Measured after: padding 22/14px, content
   box 296px, `.tiny` 12.2px — a 47% gain with ZERO layout change.

   Combined with the 330px track below (3-up at 1440), `.tiny` reaches 16.5px
   and the smallest slot 13px — type almost exactly doubled from where it was. */
.mp{container-type:inline-size;aspect-ratio:3/3.9;border:2px solid var(--ink);display:flex;
  flex-direction:column;align-items:center;justify-content:center;text-align:center;
  padding:6.7% 4.3%;position:relative;background:var(--paper-2);overflow:hidden}
.mp>*{position:relative;z-index:2}
.mp .keyline{position:absolute;inset:2.1cqw;border:1px solid currentColor;opacity:.5;pointer-events:none;z-index:1}
.mp .tiny{font-family:var(--gothic);font-size:4.13cqw;letter-spacing:.22em;text-transform:uppercase}
.mp .big{font-family:var(--slab);text-transform:uppercase;line-height:.96}
.mp .mid{font-family:var(--gothic);text-transform:uppercase;line-height:1.15;letter-spacing:.04em}
.mp .rye{font-family:var(--western);text-transform:uppercase;line-height:1}
.mp .ital{font-family:var(--liner);font-style:italic}
.mp .dates{font-family:var(--gothic);font-size:4.13cqw;letter-spacing:.1em;text-transform:uppercase;line-height:1.8}
.mp .rulebar{width:70%;border-top:2px solid currentColor;margin:3.1cqw 0}
.mp .starline{letter-spacing:.4em;font-size:5.78cqw;margin:1.8cqw 0}
.mp .stk2{position:absolute;z-index:3;background:var(--mustard);color:var(--ink);border:2px solid var(--ink);
  font-family:var(--gothic);font-size:4.48cqw;letter-spacing:.12em;text-transform:uppercase;
  /* ⚠ was `right:-2.5cqw`, which hung the sticker past the trim into
     `.mp{overflow:hidden}` and SHEARED its right edge and its offset flat —
     measured 6px clipped at the old poster size, 11px once the posters grew.
     §9 wants a pasted thing tilted, not a cut-off one, and a sticker whose
     corner is guillotined reads as a rendering fault. Inside the trim now. */
  padding:1.2cqw 3.7cqw;transform:rotate(-4deg);top:4.3cqw;right:1.5cqw}
.mp .stripes{position:absolute;left:0;right:0;height:4.9cqw;z-index:1;
  background:repeating-linear-gradient(90deg,currentColor 0 4.3cqw,transparent 4.3cqw 8.6cqw);opacity:.9}
.mp .stripes.top{top:0}.mp .stripes.bot{bottom:0}
.mp .manicule{font-family:var(--liner);font-size:6.84cqw;font-style:normal}
.mp .badge{width:28.8cqw;height:28.8cqw;border-radius:50%;display:flex;flex-direction:column;align-items:center;
  justify-content:center;font-family:var(--gothic);text-transform:uppercase;line-height:1.05;
  border:3px solid currentColor;margin:3.1cqw 0 1.2cqw}
.mp .burstnum{position:relative;display:inline-block;font-family:var(--slab);line-height:1}
.mp .burstnum .bk{position:absolute;left:1.2cqw;top:1.2cqw}
.mp .burstnum .fr{position:relative;mix-blend-mode:multiply}

/* THE EIGHT VARIANTS. Each block is the mockup's variant rules PLUS the inline
   styles that poster carried, folded onto the semantic slot they were nudging. */
.mp.neu{background:repeating-conic-gradient(from 8deg at 50% 34%,#bf2114 0 9deg,var(--tomato) 9deg 18deg);
  color:var(--paper)}
.mp.neu .big{font-size:14.46cqw;text-shadow:.9cqw .9cqw 0 var(--pine)}
.mp.neu .tiny{color:var(--mustard)}
.mp.neu .huge{font-family:var(--slab);font-size:22.5cqw;line-height:1;color:var(--mustard);
  text-shadow:1.2cqw 1.2cqw 0 var(--pine)}
.mp.neu .dates{color:rgba(246,241,229,.92)}
.mp.neu .dlabel{color:var(--paper)}                 /* was inline */
.mp.neu .credit{margin-top:8px;color:var(--mustard)} /* was inline */

.mp.tsm{background:var(--paper);color:var(--ink);justify-content:flex-start;padding-top:5.5cqw}
.mp.tsm .big{font-size:10.97cqw;color:var(--pine);text-shadow:.6cqw .6cqw 0 var(--mustard);margin-top:2px;line-height:.98}
/* ⚠ THE ONE POSTER THE 1.18 TYPE SCALE DID NOT FIT — measured, not guessed.
   Tennessee State Museum is the densest of the eight (five bill lines plus a
   credit), and at 4.72cqw with 1.8cqw of padding a side it overflowed its own
   card by 53px vertically. Its leading gives the space back instead of its
   size: the type stays scaled, the rows sit closer. Nothing else on the wall
   needed a per-poster exception. */
.mp.tsm .bill-line{width:88%;border-bottom:1px solid var(--rule);padding:.85cqw 0;
  font-family:var(--gothic);font-size:4.72cqw;letter-spacing:.08em;text-transform:uppercase;
  line-height:1.15}
.mp.tsm .bill-line:last-of-type{border-bottom:none}
.mp.tsm .bill-line i{font-style:normal;color:var(--tomato)}
.mp.tsm .starline{color:var(--tomato);font-size:7.55cqw;margin:.4cqw 0 1.6cqw}
.mp.tsm .keyline{color:var(--pine)}                                        /* was inline */
.mp.tsm .p-kick{color:var(--tomato-text)}                                  /* was inline */
.mp.tsm .credit{font-size:.8125rem;color:var(--ink-dim);margin-top:4px}    /* was inline */

.mp.nala{background:var(--night);color:var(--paper)}
/* §7, 2026-08-12. The offset was #000 on --night: MEASURED 1.22:1 — not a quiet
   second pass, no second pass at all. The letterform is mustard at 9.35:1, so
   the offset has to be visible AND quieter: tomato lands at 3.39:1, i.e. 2.8x
   quieter than the type casting it, which is the relationship §7 exists to
   protect. (Pine, §7's default, is 2.06:1 here and all but vanishes.) */
.mp.nala .rye{font-size:10.97cqw;color:var(--mustard);text-shadow:.6cqw .6cqw 0 var(--tomato);margin-top:10px}
.mp.nala .dates{color:rgba(246,241,229,.8)}
.mp.nala .badge{color:var(--mustard)}
.mp.nala .badge b{font-size:12.15cqw;font-weight:400}
.mp.nala .badge span{font-size:3.3cqw;letter-spacing:.16em}
.mp.nala .keyline{color:var(--mustard)}          /* was inline */
.mp.nala .p-kick{letter-spacing:.3em}            /* was inline */

.mp.wer{background:var(--mustard);color:var(--ink)}
.mp.wer .stripes{color:var(--ink)}
.mp.wer .big{font-size:13.92cqw;text-shadow:.9cqw .9cqw 0 var(--paper);margin-top:6px}
.mp.wer .rye{font-size:6.84cqw;margin-top:2.5cqw}

.mp.map .burstnum{font-size:25.5cqw}
.mp.map .burstnum .bk{color:var(--mustard)}
.mp.map .burstnum .fr{color:var(--tomato)}
.mp.map .big{font-size:14.46cqw;color:var(--ink);text-shadow:.6cqw .6cqw 0 var(--mustard)}
.mp.map .tiny{color:var(--tomato-text)}
.mp.map .keyline{color:var(--tomato)}                       /* was inline */
.mp.map .rulebar{color:var(--tomato)}                       /* was inline */
.mp.map .dates{color:var(--ink)}                            /* was inline */
.mp.map .credit{margin-top:8px;color:var(--ink-dim)}        /* was inline */

.mp.elk{background:var(--pine);color:var(--paper)}
.mp.elk .pennant{position:absolute;top:-2px;left:50%;transform:translateX(-50%);z-index:3;
  width:25.7cqw;height:17.2cqw;background:var(--mustard);border:2px solid var(--ink);border-top:none;
  clip-path:polygon(0 0,100% 0,100% 100%,50% 62%,0 100%);color:var(--ink);
  font-family:var(--gothic);font-size:3.66cqw;letter-spacing:.14em;text-transform:uppercase;
  display:flex;justify-content:center;padding-top:2.1cqw}
/* §7, 2026-08-12. rgba(12,16,26,.55) on --pine MEASURED 1.69:1 — dead, the same
   near-invisible offset .b-tkt .go's comment records fixing in August. §7's
   "always pine" cannot apply on a poster whose GROUND is pine, so the rule's
   reason is followed instead of its letter: the letterform is paper at 7.37:1
   and ink lands at 2.03:1, 3.6x quieter — the same ratio §7 asks for on board. */
.mp.elk .big{font-size:11.56cqw;text-shadow:.6cqw .6cqw 0 var(--ink);margin-top:14px}
.mp.elk .rye{font-size:7.55cqw;color:var(--mustard);margin-top:2.5cqw}
.mp.elk .keyline{color:var(--mustard)}          /* was inline */
.mp.elk .rulebar{color:var(--mustard)}          /* was inline */

.mp.nis{background:var(--paper)}
.mp.nis .keyline{border:3px dotted var(--ink);opacity:1;inset:2.8cqw}
.mp.nis .rye{font-size:8.97cqw;color:var(--tomato)}
.mp.nis .big{font-size:12.74cqw;color:var(--ink);text-shadow:.6cqw .6cqw 0 var(--mustard);margin-top:1.8cqw}
.mp.nis .badge{color:var(--ink);border-color:var(--tomato)}
.mp.nis .badge b{font-size:8.97cqw;font-weight:400;color:var(--tomato-text)}
.mp.nis .badge span{font-size:3.3cqw;letter-spacing:.14em}
.mp.nis .credit{color:var(--ink-dim)}           /* was inline */

/* ---- THE NINTH POSTER, 2026-08-12 ---------------------------------------
   Seth: "see if theres another poster we can make out of the ledger."
   There was exactly one. Cross-referencing all 29 ledger rows against the eight
   posters, every award is on the wall except **Hamilton & Hume House — Best in
   American Living, Finalist '24**. The `.wer` poster carries 602 Taylor and the
   Werthan Warehouse but not the third Taylor Place building, so that row has
   been in the record and off the marquee since the wall was built.

   A one-award poster is already an established form here — `.nis` is one — so
   nothing about the wall's grammar has to bend to hold it.

   It gets its OWN variant rather than reusing one of the eight, because the
   wall's whole quality is that no two posters share a treatment. The device is
   a GABLE: two rules meeting at an apex, drawn with clip-path, no image. It is
   the one domestic building on a wall of civic and commercial work, and a
   roofline says that without a word. Pure geometry, which is what a letterpress
   shop had to build a picture out of.

   Inks, measured: name in --ink on --paper (15:1) with a --tomato misregister
   (4.49:1) — §7 satisfied, the second pass 3.3x quieter than the letterform
   casting it. The badge is ink on mustard (9.21:1); mustard on paper would have
   been 1.63:1 and could not carry type at all. */
/* ⚠ TWO THINGS FOUND BY LOOKING AT IT, after every metric came back clean.
   1. The kicker printed INSIDE the gable — "Under one roof" in tomato-text
      crossing a pine roof, both unreadable. Nothing overflowed, nothing
      clipped, contrast passed on both in isolation. The content column now
      starts below the roof and the gable is reserved space, not an overlay.
   2. My own first cut wrote `padding-bottom:9cqw` HERE — which is the exact
      cqw-on-the-container bug fixed at `.mp` earlier today: padding on the
      container element resolves against the VIEWPORT, not the poster. Both
      paddings are percentages, which resolve against the grid track. */
.mp.ham{background:var(--paper);color:var(--ink);justify-content:center;
  padding-top:23%;padding-bottom:7%}
.mp.ham::before{content:"";position:absolute;top:4cqw;left:50%;transform:translateX(-50%);
  width:46cqw;height:17cqw;background:var(--pine);z-index:1;
  clip-path:polygon(50% 0,100% 100%,86% 100%,50% 21%,14% 100%,0 100%)}
.mp.ham .keyline{border-color:var(--pine);opacity:.55}
.mp.ham .tiny{color:var(--tomato-text)}
.mp.ham .big{font-size:11.4cqw;color:var(--ink);text-shadow:.6cqw .6cqw 0 var(--tomato);
  margin-top:2cqw;line-height:.98}
.mp.ham .mid{color:var(--pine)}
.mp.ham .badge{background:var(--mustard);border:2px solid var(--ink);color:var(--ink)}
.mp.ham .badge b{font-size:7.4cqw;font-weight:400}
.mp.ham .badge span{font-size:3.1cqw;letter-spacing:.14em}
.mp.ham .dates{color:var(--ink-dim)}
.mp.ham .credit{color:var(--ink-dim)}
.mp.ham .rulebar{border-top-color:var(--pine)}

.mp.asla{background:var(--paper-2);color:var(--ink)}
.mp.asla .stripes{color:var(--pine)}
.mp.asla .rye{font-size:12.15cqw;color:var(--pine);text-shadow:.6cqw .6cqw 0 var(--mustard);margin-top:8px}
.mp.asla .manicule{color:var(--tomato-text)}
.mp.asla .p-kick{color:var(--tomato-text)}                   /* was inline */
.mp.asla .starline{color:var(--tomato)}                      /* was inline */
.mp.asla .dates{color:var(--ink-dim)}                        /* was inline */
.mp.asla .credit{margin-top:8px;color:var(--ink-dim)}        /* was inline */

/* ===========================================================================
   (p) THE MASTHEAD'S RYE LINE GETS THE HOME LOCKUP'S RULES — 2026-08-12
   ===========================================================================
   Seth: "i like the idea of including the lines that spread out from the text
   like on the home page hero ... while keeping it at the current other-page
   sizes."

   WHAT THIS IS NOT. DESIGN-TRUTH §3 retires the `.fest-rule` / `.also-rule`
   hairline pattern — flex + ::before/::after rules + tracked caps — because it
   was a third way of announcing a SECTION and gave its content no left edge.
   This is not that. §3 governs section headers, which are plates; the flanked
   rule is the PAGE-NAME LOCKUP's own furniture and has been the approved
   primitive on `.b-name .and` since About was derived. Extending it from the
   two lockup pages to every interior masthead applies one primitive to one
   job. It does not reintroduce a retired one.

   RULE LINE ONLY, NOT THE KICKER (Seth's call). `.b-name .kick` flanks its
   italic with two FIXED 120px rules; on an interior sheet that spends 272px of
   measure before a word is set, and News's kicker — "Project notices and press
   mentions, with the odd note from the road" — is the longest on the site.

   ⚠ THE FLOOR IS THE WHOLE ENGINEERING PROBLEM. `.b-name .and` sizes its rules
   `flex:1;max-width:210px`, i.e. whatever the line leaves over. That is safe on
   home, where the Rye line is short. It is NOT safe here now that the ranking
   phrase has MOVED INTO this line (2026-08-12 — "Architecture Awards &
   Recognition", "Case Studies in Architecture and Photography"). A rule that
   flexes to 4px does not read as furniture, it reads as a rendering fault. So
   the rules declare a floor and the whole ornament withdraws below the width
   where the floor cannot be met — furniture that cannot be set is not set. */
.mast .sub-western{display:flex;align-items:center;justify-content:center;gap:20px}
.mast .sub-western::before,.mast .sub-western::after{content:"";flex:1 1 0;
  min-width:34px;max-width:150px;height:5px;
  border-top:3px solid var(--ink);border-bottom:1px solid var(--ink)}

/* THE CEILING. `--nc` is the line's character count, printed by ps_bb_western();
   `--cw` is Rye's MEASURED width-per-font-pixel in caps — 0.66, sampled across
   five real strings (0.6326 to 0.6734). The subtrahend is the chrome the line
   never gets: 50px of sheet/frame border, 88px of `.mast` padding, and 108px
   for the two rules and their gaps at the minimum they are allowed to be.
   clamp(), not min(): a floor means the line SHRINKS to a legibility limit and
   then wraps, rather than shrinking without bound on a phone. */
.mast .sub-western{--cw:.66;
  font-size:clamp(1.35rem,calc((100vw - 268px) / (var(--cw) * var(--nc,20))),2.4rem)}

/* ⚠ AND THIS IS WHY IT WITHDRAWS — MEASURED AT 390, not predicted.
   A flex container centres its rules on the BLOCK, so the moment the Rye line
   wraps to two lines the rules stop flanking a line and start straddling a
   paragraph: two hyphens floating at the vertical midpoint of "NO SUCH ACT, /
   TONIGHT". Every metric was clean — no overflow, no clipping, no scroll — and
   the sheet looked broken (trap 7 again, in the same session that added it).
   Home keeps its rules on phones because `.b-name .and` is a short lockup line
   that does not wrap; an interior Rye line carries the page's ranking phrase
   and wraps constantly. Below the tablet tier the ornament is simply not set.
   ⚠ 900, not 700. Computed against the ceiling above: the longest realistic
   line (45 characters) holds ONE line down to about 900px and wraps below it,
   and a wrapped line is precisely what the rules cannot flank. The withdrawal
   point is where the wrap starts, not where the phone tier starts. */
@media (max-width:900px){
  .mast .sub-western{display:block}
  .mast .sub-western::before,.mast .sub-western::after{content:none}
}
/* Phones: a 44-character ranking phrase cannot hold 1.35rem in a 252px measure,
   so the floor drops one step and the line is allowed its second row. */
@media (max-width:700px){
  .mast .sub-western{font-size:clamp(1.05rem,calc((100vw - 120px) / (var(--cw) * var(--nc,20))),2.4rem)}
}

/* ===========================================================================
   (q) NOT ON THE BILL — the 404's cancelled act, 2026-08-12
   ===========================================================================
   The band is the shared `.b-under` undercard; only the reflected address and
   the sticker pasted over it are new. `nb-` = "not on the bill": checked
   against the stylesheet before naming, per the `.kicker` incident that
   repainted two posters in August.

   The address sets in Anton — DESIGN-TRUTH §4 gives Anton "plates, labels,
   lists, marquee tiers", and an act's name on a bill is exactly that. It is
   NOT wood type: Rye is one line per page and the masthead already spent it.

   ⚠ `overflow-wrap:anywhere`, and it is not optional. Every other name in this
   design is `white-space:nowrap` because §8 forbids breaking an act's name —
   but a URL is not an act's name, it is an unbreakable token, and trap 3 says
   an unbreakable token is exactly what `scrollWidth > clientWidth` catches
   after `.frame{overflow:hidden}` has already swallowed the evidence. */
.nb-act > .field{position:relative}
.nb-url{font-family:var(--gothic);font-size:clamp(1.5rem,4.4vw,2.6rem);line-height:1.12;
  letter-spacing:.02em;text-transform:uppercase;color:var(--ink);
  overflow-wrap:anywhere;word-break:break-word;padding-right:96px}
.nb-note{margin-top:14px;font-family:var(--liner);font-style:italic;font-size:1.0625rem;
  color:var(--ink-dim);max-width:34rem}

/* §9: a pasted thing tilts and carries a hard offset shadow; a printed thing
   does neither. This is a sticker, so it does both. Tomato ground, paper type:
   measured 5.9:1, and it is 18px+ tracked caps either way. */
.nb-stamp{position:absolute;right:26px;top:22px;z-index:3;transform:rotate(-3deg);
  background:var(--tomato);color:var(--paper);border:2px solid var(--ink);
  padding:7px 16px 6px;white-space:nowrap;
  font-family:var(--gothic);font-size:1.19rem;letter-spacing:.16em;text-transform:uppercase;
  box-shadow:4px 4px 0 rgba(33,28,22,.22)}

/* ⚠ MEASURED AT 768, per trap 10: at 701–1000 the plate is still a 250px left
   edge, so this field is only ~380px — and a sticker absolutely positioned in
   its top-right corner sits ON the first line of a 2.6rem address. Below 1000
   the sticker leaves the corner and sets in the flow, above the address, where
   it still tilts and still shadows. */
@media (max-width:1000px){
  .nb-stamp{position:static;display:inline-block;margin:0 0 16px;right:auto;top:auto}
  .nb-url{padding-right:0}
}

/* ---------------------------------------------------------------------------
   (q2) THE RECOVERY BILL'S LINKS — MEASURED DEFECT, fixed the same session
   ---------------------------------------------------------------------------
   Built and then LOOKED AT (trap 7): the tapered acts rendered
   `color:rgb(33,28,22)` with `text-decoration:none` — identical to the body
   copy beside them, in a plate field where Anton caps read as a heading. The
   only links on the only page whose entire job is recovery had no affordance
   whatsoever. No metric catches this: nothing overflowed, nothing clipped,
   contrast passed, the anchors were in the DOM and clickable.

   Addendum B decides the ink: this band NAVIGATES, so it is pine, never the
   booking tomato. Pine measures 7.37:1 on board (§7). Hover and focus reverse
   to a pine ground, which is the idiom `.b-file a.on` already uses for the
   collection the visitor is standing on — one mechanism, not a second one.

   ⚠ Scoped to `.nb-bill`, not to `.field .fr a`. ps_bb_taper()'s $linked flag
   is opt-in and the 404 is its only caller today, but a selector that assumes
   that would silently restyle the first taper anyone else links. */
.nb-bill .field .fr a{color:var(--pine);padding:1px 5px;
  text-decoration-line:underline;text-decoration-thickness:2px;text-underline-offset:5px;
  text-decoration-color:rgba(31,78,140,.38)}
.nb-bill .field .fr a:hover,.nb-bill .field .fr a:focus-visible{background:var(--pine);
  color:var(--paper);text-decoration-color:transparent}
.nb-bill .field .fr a:focus-visible{outline:3px solid var(--ink);outline-offset:2px}

/* Tap targets. The shared :700 block lifts `.b-file a` / `.t1 a` to 44px; the
   taper is a different construction and was never in that list. Measured at
   1440 before this: the m3 tier's anchors were 29px tall.
   ⚠ 1000, not 700. The shared rule stops at 700 because that is where this
   codebase's phone tier starts, but measured at 768 the taper's anchors were
   38px and 31px — and 768 is an iPad, which is a touch device. Widened for
   this band only rather than reopening the shared rule on eight other sheets. */
@media (max-width:1000px){
  .nb-bill .field .fr a{min-height:44px;display:inline-flex;align-items:center}
}

/* ---------------------------------------------------------------------------
   (q3) THE STUB'S TOUR ROW — set as a bill, 2026-08-12
   ---------------------------------------------------------------------------
   Seth: "the on tour cities should be designed better, and it should also have,
   the southeast and nationwide added." It was `Birmingham · Chattanooga ·
   Huntsville · Nashville` in the same 15px weight as the email address on the
   row above it — four proper nouns wearing the typography of a data field.

   The cities take Anton with the tomato star between them, which is this
   design's separator for a list of NAMES everywhere else on the site. `.nm`
   keeps each place name unbroken (§8).

   ⚠ AMENDED THE SAME DAY, by Seth: "give 'the southeast' & nationwide the same
   treatment as the cities and include them on the same line." This REVERSES the
   paragraph that stood here — that the reach takes Caslon italic on its own
   line because "the Southeast, nationwide" is an aside in the human voice (§4)
   rather than two more stops. He is right and the reason is worth keeping: the
   row is a LIST, and breaking one list across two voices made its last item
   read as a footnote ABOUT the list instead of part of it. The joining star is
   printed by this stylesheet, because furniture belongs to the theme and not to
   either field.
   Flush left, not right — the whole ledger turned left when it went two-up. */
.b-tkt .t-stub dd.t-tour{font-weight:400;line-height:1.45}
.b-tkt .t-stub .t-tour .cities,
.b-tkt .t-stub .t-tour .reach{display:inline;font-family:var(--gothic);font-size:.9375rem;
  font-style:normal;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);margin:0}
.b-tkt .t-stub .t-tour .cities .nm,
.col-tour .nm{white-space:nowrap}
.b-tkt .t-stub .t-tour .cities i,
.b-tkt .t-stub .t-tour .reach i{font-style:normal;color:var(--tomato);margin:0 2px}
/* the joining star moved to ps_bb_tour_line() — a `::before` with a
   non-breaking space on BOTH sides made the line break in front of the star
   cluster and orphan it to the head of the next line, and it printed even when
   there were no cities to join to. */
.b-tkt .t-stub .t-tour .reach .nm{white-space:nowrap}

/* ---------------------------------------------------------------------------
   (q4) DEEP CUTS — six singles, one row, 2026-08-12 (originally five)
   ---------------------------------------------------------------------------
   Seth: "deep cuts never need to be taller than one row. limit it to 5 images."

   The shelf was `flex-wrap:wrap` over fixed 158px singles, which holds one row
   at 1440 and silently becomes two, then three, as the field narrows — the
   comment on `.rack-shelf` said so in August and deferred the fix ("proper fix
   comes with the Deep Cuts section rebuild"). This is that rebuild.

   SIX EQUAL COLUMNS, so the row is a row by construction rather than by luck.
   ⚠ WAS FIVE, changed same day: five is odd, and it wrapped to an orphan tile
   alone on its own row at the phone tier's 2-up grid below — six divides
   evenly by 2 there AND by 3 at the tablet tier, so both get full rows instead
   of one short. It is a flexible `repeat(6,1fr)` grid, not fixed-width tiles,
   so the desktop "one row" requirement is unaffected — the columns just run
   slightly narrower than they did at five.
   MEASURED: at 1440 the undercard field is 1049px inside its padding, comfortably
   inside what six shrinking columns need; at 1000 the field is 609px and the
   old fixed-158px shelf would have wrapped there too — the grid is why it does
   not.

   ⚠ PHONES ARE THE ONE PLACE IT IS STILL NOT ONE ROW, deliberately. Six
   singles across a 340px field would be ~43px each — a thumbnail too small to
   read as a photograph, which fails the instruction's intent while satisfying
   its letter. The existing two-up phone grid (line ~2105) stands, and six now
   fills it in three complete rows instead of five's two-and-an-orphan. */
.field .rack-shelf.six{display:grid;grid-template-columns:repeat(6,1fr);gap:0 26px;
  justify-content:start;align-items:start}
.field .rack-shelf.six .cut{width:auto;display:block;text-decoration:none;color:inherit}
/* `.mini` is the vinyl peeking out of the sleeve and hangs 24px past the right
   edge (§9-adjacent: it is a printed object, not a bleed). At six-up the
   columns are tight enough that the last one's disc would ride the trim, so the
   grid keeps a right gutter of its own rather than letting `.frame` clip it.
   ⚠ 2026-08-12: 26px → 30px. The disc now slides out 4px further on hover
   (below) — 26px left only 2px of slack past its 24px resting overflow, which
   the slide alone would have exceeded on the rightmost column. 30px covers
   the slide with a 2px margin left over. */
.field .rack-shelf.six{padding-right:30px}

/* The 45 label carries a date now, so it is wider than "45" ever was. */
.field .rack-shelf.six .s45{font-size:.625rem;letter-spacing:.08em;padding:2px 5px}
.field .rack-shelf.six .ph{display:block}
/* ⚠ 2026-08-15 — Seth: "remove border on hover, zoom image just a little
   instead." The tomato outline put a THIRD concentric edge on a tile that already
   carries the card's 2px ink border and the image's own 1px ink keyline, so a
   hovered single read as a click target rather than a photograph.
   The keyline moves from the <img> to the .ph sleeve so it stays PUT while the
   photograph moves inside it — a printed rule does not travel with the image it
   frames, and scaling the img with the border still on it would just push the
   keyline out through the crop. 4.5%: enough to register as alive, not enough to
   show a soft edge on a 158px thumb.
   Keyboard focus is NOT left undrawn — .cut:focus-visible keeps its 3px ink ring
   on the anchor (that is the affordance that has to survive) and now takes the
   same zoom, so a tabbing visitor sees exactly what a mouse hover shows. */
.field .rack-shelf.six .ph{overflow:hidden;border:1px solid var(--ink);line-height:0}
.field .rack-shelf.six .ph img{border:none;transition:transform .28s cubic-bezier(.3,.7,.4,1)}
.field .rack-shelf.six .cut:hover .ph img,
.field .rack-shelf.six .cut:focus-visible .ph img{transform:scale(1.045)}
.field .rack-shelf.six .cut:focus-visible{outline:3px solid var(--ink);outline-offset:4px}
@media (prefers-reduced-motion:reduce){
  .field .rack-shelf.six .ph img{transition:none}
  .field .rack-shelf.six .cut:hover .ph img,
  .field .rack-shelf.six .cut:focus-visible .ph img{transform:none}
}

/* ⚠ THE TABLET TIER, AND IT IS A REAL DEFECT THE FIRST BUILD SHIPPED.
   MEASURED at 768 with the original five-column grid: columns rendered
   **58px wide**. At 701–1000 the plate is still a 250px left edge (§0o kept it
   there deliberately), so this field is about 377px — five (now six) singles
   plus their gaps do not fit in it at full width, they just shrink. 58px is
   not a photograph, it is a swatch, and nothing overflowed so no check
   complained. This is trap 10 word for word, on a band whose own comment
   cites trap 10.

   Three-up here. Six images become two EVEN rows rather than one — better
   than five's uneven 3+2 split, and still the one place the "never taller
   than one row" instruction cannot be met AND stay legible — at three-up each
   single renders ~106px, at five/six-up ~58px. A compact two-row block is
   closer to what that instruction is for than a single row of swatches would
   be. */
@media (max-width:1000px){
  /* ⚠ 2026-08-12: 24px → 30px, same reason as the desktop gutter above — at
     24px this exactly matched the disc's 24px resting overflow with ZERO
     slack, so the hover slide would have clipped from the first pixel. */
  .field .rack-shelf.six{grid-template-columns:repeat(3,1fr);gap:18px 16px;padding-right:30px}
}
@media (max-width:700px){
  /* Back to the shipped two-up phone grid — see the note above.
     ⚠ THE RIGHT GUTTER STAYS. Measured at 320 with `padding-right:0`:
     `.cut` overflowed its column by 10px and the shelf by 8px, because `.mini`
     — the vinyl peeking out of the sleeve — is positioned `right:-24px` and
     hangs outside its own sleeve on purpose. `.frame{overflow:hidden}` swallowed
     it, so page scroll still read 0 and the disc was simply being sliced off the
     right-hand single. Trap 2, on a band added the same session. */
  .field .rack-shelf.six{grid-template-columns:1fr 1fr;gap:20px 14px;padding-right:26px}
}

/* The sticky stub withdraws while the ticket is on screen — see initStickyStub()
   in bigbill-nav.js for why. Transformed rather than display:none so it leaves
   and returns as a movement, and `visibility` so it also leaves the tab order
   while it is gone (a button you cannot see should not be a button you can
   focus).
   ⚠ 2026-08-15 — Seth: the stub is no longer permanently parked in the corner.
   It is away by default and RETURNS ONLY ON A SCROLL UP — reading downward is
   someone consuming the page, scrolling back up is someone looking for
   something, and that is the moment a booking button has earned its place.
   The travel is now horizontal (translateX): it leaves and returns through the
   right edge it is anchored to, which is the only direction that reads as the
   sheet's own margin rather than as a bar rising off the bottom of the screen.
   `is-away` stays the single away-state — initStickyStub() ORs the two reasons
   (ticket on screen, or not currently wanted) so they can never fight. */
.sticky-stub{transition:transform .28s cubic-bezier(.3,.7,.4,1),opacity .22s ease}
.sticky-stub.is-away{transform:translateX(calc(100% + 24px));opacity:0;visibility:hidden}
@media (prefers-reduced-motion:reduce){.sticky-stub{transition:none}}

/* ---------------------------------------------------------------------------
   (q5) THE RECORD BIN KEEPS GOING — 2026-08-12
   ---------------------------------------------------------------------------
   Seth: "home page portfolio should allow to hang the next wall, too and keep
   seeing more images until they run out." The crate used to print 24 of the 58
   curated photographs and silently drop the other 34.

   A hidden ROW, not a hidden tile — see ps_bb_crate() for why (the rows are
   AR-justified to a fixed area sum, so half a row is a hole).

   ⚠ THE BUTTON IS ON NIGHT STOCK, so it cannot reuse `.pf-more button` as-is:
   that button is ink-on-board with an ink offset shadow, and an ink shadow on
   night measures 1.02:1 — no shadow at all (§7's reasoning, applied to a
   button instead of to type). It reverses the same way the night plate does:
   board ground, ink type, and the offset drawn in the ground colour. */
.gate .gr.is-hidden{display:none}
.crate-more{margin:34px 44px 0}
/* The exhausted state. Pine, not tomato: this control NAVIGATES once the crate is
   empty (addendum B — tomato books, pine navigates), which is exactly the ink the
   removed `.gate-cta` link wore for the same destination. */
.crate-more a.is-done{display:inline-block;font-family:var(--gothic);font-size:1.19rem;
  letter-spacing:.1em;text-transform:uppercase;text-decoration:none;
  background:var(--pine);color:var(--paper);border:3px solid var(--paper);
  padding:15px 30px;box-shadow:4px 4px 0 rgba(246,241,229,.28)}
.crate-more a.is-done:hover{transform:translate(2px,2px);box-shadow:2px 2px 0 rgba(246,241,229,.28)}
.crate-more a.is-done:focus-visible{outline:3px solid var(--mustard);outline-offset:3px}
.crate-more button{background:var(--paper);color:var(--ink);border:3px solid var(--paper);
  box-shadow:5px 5px 0 rgba(246,241,229,.28)}
.crate-more button:hover{transform:translate(2px,2px);box-shadow:3px 3px 0 rgba(246,241,229,.28)}
.crate-more button:active{transform:translate(5px,5px);box-shadow:0 0 0 rgba(246,241,229,0)}
.crate-more button:focus-visible{outline:3px solid var(--mustard);outline-offset:3px}

/* ---------------------------------------------------------------------------
   (q6) THE TICKET'S PENDING STATE — a shipped feature the port had lost
   ---------------------------------------------------------------------------
   FOUND BY SUBMITTING THE FORM, 2026-08-12, which had never been done end to
   end. It works — stored, classified, emailed — but **the round trip measured
   7,651 ms**, because the spam verdict and both emails (the notification and
   the client's confirmation) all run synchronously before the response comes
   back. nav.js adds `.is-loading` to the button for exactly this reason.

   ⚠ AND NOTHING RENDERED IT. `.submit.is-loading` is declared in `theme.css`
   — the retired stylesheet nothing enqueues — and `bigbill.css` had no rule for
   it at all. So on the live design a visitor pressed Send and watched an
   unchanged button do nothing for seven and a half seconds, on the one surface
   this site exists to catch (one real lead a week among 5–10 spam). The button
   was disabled, so the click was not lost — but a visitor cannot see `disabled`,
   and "nothing happened" is what makes someone click again or leave.

   The state is letterpress rather than a spinner, because this world has no
   spinners: the button locks in its own PRESSED position — the type is in
   contact with the paper — and the label swaps. The label is read from
   `data-sending`, so it stays an editable field instead of a string welded into
   the stylesheet. */
.b-tkt .go.is-loading{position:relative;color:transparent;pointer-events:none;
  transform:translate(5px,5px);box-shadow:0 0 0 var(--pine)}
.b-tkt .go.is-loading::after{content:attr(data-sending);position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;color:#fff;letter-spacing:.12em}
/* The one moving part: the paper rule under the label creeps, so the button
   reads as working rather than as frozen. */
.b-tkt .go.is-loading::before{content:"";position:absolute;left:0;bottom:0;height:3px;
  background:var(--mustard);animation:ps-press 1.15s ease-in-out infinite}
@keyframes ps-press{0%{width:0;left:0}50%{width:100%;left:0}100%{width:0;left:100%}}
@media (prefers-reduced-motion:reduce){
  .b-tkt .go.is-loading{transform:none;box-shadow:5px 5px 0 var(--pine)}
  .b-tkt .go.is-loading::before{animation:none;width:100%}
}

/* ===========================================================================
   (r) THE BILL GOES TWO-UP AT THE TABLET TIER — 2026-08-12, Seth's call
   ===========================================================================
   MEASURED at 768 before this: six acts across a 768px sheet gave each cell
   **120px wide by 52px tall**, the act name at **12px** and its Caslon
   sub-label at **11.5px**. Nothing was broken — 52px clears the 44px tap
   minimum, nothing overflowed, no scroll — so no check would ever have
   complained. It was simply the smallest the bill ever gets, and "BOOK A
   SESSION" only just fit its cell.

   A printed bill you have to lean toward is not doing the one job a bill has.
   So at 701–1000 it runs as **two rows of three**, which is what a real Hatch
   handbill does when the acts outgrow the sheet — it stacks them. Not a
   fallback: the native form.

   Cells roughly double (≈250px), so the act names and the italic billing can
   both come up to a size that reads at arm's length on an iPad.

   ⚠ `flex-wrap` on `#primaryNav`, not a grid. The wrapper is the PORT SEAM —
   WordPress emits `<ul id="primaryNav">` and the rules have to work for a <div>
   of anchors AND a <ul> of <li><a> alike (see the base rule's note). `flex:1
   1 33.333%` wraps either one into rows of three without caring which it is.

   ⚠ Desktop and phone are untouched: this block is bounded on BOTH sides, and
   below 700 the drawer takes over entirely. */
@media (min-width:701px) and (max-width:1000px){
  nav.stub #primaryNav{flex-wrap:wrap}
  nav.stub a{flex:0 1 33.333%;max-width:33.333%;padding:11px 6px 10px;font-size:.9375rem;letter-spacing:.08em}
  nav.stub a small{font-size:.875rem;margin-top:2px}
  /* The dashed furniture has to follow the new grid: every third act closes a
     row, so its right-hand rule would otherwise hang off the trim, and the
     first row needs a rule under it that the single-row bill never had. */
  nav.stub a:nth-child(3n){border-right:none}
  nav.stub a:nth-child(-n+3){border-bottom:1px dashed var(--ink-faint)}
  /* `a:last-child` already drops its right border on the base rule; with six
     acts the last one is also a 3n, so nothing special is needed there. */
}

/* ===========================================================================
   PRE-LAUNCH DESIGN PASS — 2026-08-15. Two measured defects, nothing else.
   Appended so the cascade is explicit; both are narrow overrides.
   =========================================================================== */

/* ⚠ THE TWO DECK LINES WERE COLLIDING. Measured on /the-emory-…/ and
   /nashville-architectural-photographer/ at 1440 AND 390: `.h1-role` bottom to
   `.sub-western` top = 4px, against 20px from `.sub-western` down to the lede.
   The lower line is 38.4px outlined wood type, so at 390 the descender of
   PHOTOGRAPHY all but touched the cap of NASHVILLE — it read as a collision
   rather than a pair. 10px here makes it 14px total.
   ⚠ `:has()` on purpose: only the two templates that stack a role line above a
   western line should move. Everywhere else `.sub-western` is the only deck and
   its existing spacing is correct. */
.mast h1:has(.h1-role) ~ .sub-western{margin-top:14px}

@media (max-width:700px){
  /* ⚠ MEASURED OVERFLOW, not a guess: the case-studies featured headline ran
     scrollWidth 320 in a clientWidth 300 box at 390, so "Germantown," sat on the
     panel's right keyline with no breathing room. The gate never caught it —
     the band clips rather than scrolling the page, so document scrollWidth
     stays clean. One step down (7.4vw ≈ 28.9px at 390) measures ~263px, and the
     break opportunity is the belt to that braces for a longer project name. */
  .cshead .bill h2{font-size:clamp(1.5rem,7.4vw,2.1rem);overflow-wrap:break-word}
}

/* ⚠ ORPHANED ★ SEPARATORS ON THE CENTRED TAPER LISTS — measured 2026-08-15.
   DESIGN-TRUTH §8 glues each star to the name BEFORE it (`name&nbsp;★ `), so the
   only break opportunity is AFTER the star — which means every wrap strands a
   lone red star at the end of a centred line. On About's NOTABLE PROJECTS at 390
   that was ~24 of 26 lines; home's IN PRINT had 3 of 5.
   ⚠ THE OBVIOUS FIX IS WRONG: gluing the star to the FOLLOWING name just moves
   the orphan to the START of the next line (which is exactly what `.b-file .t2`
   does on the project page at 1440). CSS cannot hide a separator only when it
   lands at a line end, so at the widths where wrapping is guaranteed the
   separator stops being a separator and the LINE BREAK does that job instead —
   the same move the colophon already makes at ≤895.
   ⚠ Deliberately NOT applied to the ticket's tour rail: gate.mjs asserts that
   rail stays on one line at every width, and stacking it would fail that. */
@media (max-width:700px){
  .field .fr .st{display:none}
  .field .fr .nm{display:block}
}
