/* ============================================================
   SVRV — page architecture (demo)
   Extends svrv.css. Built Live grammar carries across every page:
   measure → structure → content → contact. Nothing fades.
   ============================================================ */

:root{ --cal:1; }                      /* screen calibration for true-size marks */

/* subpages have no hero, so the docked header needs real clearance */
/* SUBPAGES ONLY. This ran on the homepage too, whose hero is min-height:100svh —
   so the hero ended a full main-padding below the fold and the visitor landed on
   "Built to hold." with the paragraph, the Request Access button, the scroll cue
   and the index all off-screen. Measured at -106px on desktop, -114px on mobile. */
body.sub main{ padding-top:clamp(6rem,14vh,10rem); }
header.docked{ background:linear-gradient(180deg,rgba(26,3,3,.92),rgba(26,3,3,0)); }
.nav-on{ color:var(--on-field)!important; }

/* ---------- THE COLLECTION — a procession, not a grid -------------------- */
.coll-head{ padding-bottom:clamp(2rem,6vh,4rem); }
/* H1 family: ref .coll-head 48/128, step 0.8 -> .piece-hero 0.8x (38.4/102.4),
   .doc h1 0.64x (30.4/81.6). No token: each of the three covers one selector. */
.coll-head h1{ font-family:var(--serif); font-weight:400; line-height:.94;
  font-size:clamp(3rem,11vw,8rem); color:var(--on-field-2); letter-spacing:-.015em; }
.coll-head p{ margin-top:1.6rem; max-width:34ch; color:var(--type-dim); }

.procession{ padding-bottom:clamp(4rem,12vh,9rem); }
.row{ position:relative; display:grid; align-items:baseline; gap:1.2rem;
  /* the name column is CAPPED, not 1fr — annotations sit beside what they annotate,
     and the trailing 1fr carries the affordance to the edge without stranding the data */
  grid-template-columns:4.5rem minmax(0,26rem) 11rem 1fr;
  padding:calc(2.1rem * var(--p,1)) 0; color:inherit; text-decoration:none; }
/* the measured rule: line and marks drawn as ONE element, one scaleX */
.row::before{ content:""; position:absolute; left:0; top:0; width:100%; height:6px; z-index:1;
  background-image:linear-gradient(90deg,var(--hairline),var(--hairline)),
    repeating-linear-gradient(90deg,var(--hairline) 0 1px,transparent 1px 60px);
  background-size:100% 1px,100% 5px; background-position:0 0,0 1px; background-repeat:no-repeat;
  transform:scaleX(0); transform-origin:left;
  transition:transform .62s var(--blade); transition-delay:calc(var(--i,0) * 140ms); }
.row.in::before{ transform:scaleX(1); }
.js .row.rv{ transition-delay:calc(.18s + var(--i,0) * 140ms); }
.row:last-child{ border-bottom:1px solid var(--hairline); }

.row-num{ align-self:start; padding-top:.55rem; font-family:var(--serif); font-size:var(--text-numeral);
  text-align:right; padding-right:.4rem; color:var(--on-field-2); letter-spacing:.1em; }
.row-name{ font-family:var(--serif); font-size:calc(clamp(2.1rem,6vw,4.4rem) * var(--s,.55)); line-height:1;
  color:var(--on-field-2); transition:transform .55s var(--ease); }
.row-cloth{ color:var(--on-field-2); }
.row-go{ justify-self:end; color:var(--on-field-2); transition:transform .5s var(--ease); }
@media(hover:hover){
  .row:hover .row-name{ transform:translateX(10px); color:var(--on-field); }
  .row:hover .row-go{ transform:translateX(8px); color:var(--on-field-2); }
}
@media(max-width:900px){
  .row{ grid-template-columns:2.6rem minmax(0,1fr) auto;
    grid-template-areas:"num name name" "num cloth cloth" "num go go"; row-gap:.5rem; }
  .row-num{grid-area:num} .row-name{grid-area:name} .row-cloth{grid-area:cloth}
  .row-go{grid-area:go; justify-self:start}
  .row-name{ font-size:calc(clamp(1.9rem,7.4vw,2.9rem) * max(var(--s,.55),.62)); }
}

/* ---------- PIECE PAGE --------------------------------------------------- */
.piece-hero h1{ font-family:var(--serif); font-weight:400; line-height:.94;
  font-size:clamp(2.4rem,9vw,6.4rem); color:var(--on-field-2); letter-spacing:-.015em; }
.piece-cloth{ margin-top:1.8rem; color:var(--on-field-2); }
.piece-cloth .label{ margin-right:.9rem; color:var(--on-field-2); }
.piece-note{ margin-top:1.2rem; max-width:46ch; color:var(--type-dim); line-height:1.7; }

/* ---------- IMAGE SLOTS — in-world, never a grey box --------------------- */
.plates{ padding-block:clamp(3rem,9vh,6rem); }
.plates .wrap{ display:grid; gap:clamp(1rem,2.5vw,1.8rem);
  grid-template-columns:1fr 1fr; }
.slot{ position:relative; margin:0; border:1px solid var(--hairline); overflow:hidden;
  background:var(--field-slot); }
/* stand-in imagery — see the SLOTS comment in build_site.py: generic/licensed, not the
   shoot. The measure-grid stays ON TOP (z-index) so a real photo still reads as a plate
   under construction, not a finished product shot. */
.slot-img{ position:absolute; inset:0; z-index:0; width:100%; height:100%; object-fit:cover;
  opacity:.9; }
.slot::before{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background-image:repeating-linear-gradient(90deg,var(--hairline) 0 1px,transparent 1px 48px),
    repeating-linear-gradient(180deg,var(--hairline) 0 1px,transparent 1px 48px);
  opacity:.28; }
.slot::after{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(0deg,rgba(26,3,3,.86) 0%,rgba(26,3,3,.35) 42%,transparent 68%); }
/* max-height fought aspect-ratio: capping the HEIGHT made the box shrink its WIDTH
   to keep 4:5, so the largest plate on every piece page rendered 472px wide inside a
   939px column and aligned with nothing. The ratio wins; the cap is gone. */
.slot--full{ grid-column:1 / -1; aspect-ratio:4/5; }

/* honeypot: off-screen rather than display:none — a bot that skips hidden inputs
   would sail past display:none, and this must be filled to be useful */
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.slot--detail{ aspect-ratio:1/1; }
.slot--macro{ grid-column:1 / -1; aspect-ratio:4/3; }
.slot-in{ position:absolute; inset:0; z-index:2; display:flex; flex-direction:column;
  justify-content:flex-end; gap:.5rem; padding:clamp(1.1rem,3vw,2rem); }
.slot-kind{ color:var(--on-field-2); }
/* .slot-spec removed 2026-08-13 with the markup it styled — the shoot's pixel
   dimensions stopped rendering on customer-facing piece pages. The data itself is
   still in SLOTS in build_site.py; only the span is gone. */
.slot-brief{ max-width:44ch; font-family:var(--sans); font-size:var(--text-spec); line-height:1.65;
  color:var(--type-dim); }
@media(max-width:700px){ .plates .wrap{ grid-template-columns:1fr } .slot--detail{aspect-ratio:4/5} }

/* ---------- THE MARK AT TRUE SIZE ---------------------------------------- */
.truesize{ padding-block:clamp(3.5rem,10vh,7rem); border-top:1px solid var(--hairline); }
.truesize h2{ font-family:var(--serif); font-weight:400; font-size:var(--text-h2-util);
  color:var(--on-field-2); margin-top:.6rem; }
.tbc{ font-family:var(--sans); font-size:.62rem; /* held: shares .field label's value by coincidence, not independently argued — a --text-label candidate for a future pass, not tested this round */ font-weight:500; letter-spacing:.24em;
  text-transform:uppercase; color:var(--alert); border:1px solid var(--alert);
  padding:.25rem .5rem; vertical-align:middle; margin-left:.9rem; }
.ts-stage{ margin-top:2.4rem; padding:clamp(1.6rem,5vw,3rem) 0;
  border-top:1px solid var(--hairline); border-bottom:1px solid var(--hairline); overflow-x:auto; }
.ts-mark{ width:calc(var(--w) * var(--cal)); max-width:none; }
/* THE MARK IS STRUCK, NOT COLOURED. The spec printed beneath it says the mark reads by
   relief and sheen, never by colour — so it must be debossed here too: warm highlight
   offset DOWN, dark shadow offset UP. Same physics as the threshold and the footer. */
.ts-mark img{ display:block; width:100%; height:auto; opacity:.94;
  filter:brightness(0)
    drop-shadow(0 .055em 0 rgba(255,228,220,.30))
    drop-shadow(0 -.045em 0 rgba(0,0,0,.85)); }
/* the calibration state must never be silent — an idea whose equity is verifiable
   honesty cannot be silently unverifiable */
.cal-state{ margin-top:1rem; font-family:var(--sans); font-size:var(--text-spec); font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; }
.cal-state[data-state="true"]{ color:var(--on-field-2); }
.cal-state[data-state="nominal"]{ color:var(--alert); }
.doc .err,.field .err,.err{ margin-top:.5rem; font-family:var(--sans); font-size:.74rem;
  color:var(--alert); }   /* specificity must beat .doc p, and #A51E22 is 2.4:1 on crimson */
.field input[aria-invalid],.field select[aria-invalid]{ border-bottom-color:var(--alert); }
.confirm-inline{ margin-top:2rem; }
.confirm-inline h2{ font-family:var(--serif); font-weight:400; font-size:clamp(1.8rem,4vw,2.8rem); color:var(--on-field-2); }
.confirm-inline p{ margin-top:.9rem; max-width:44ch; font-family:var(--sans); font-size:.9rem;
  line-height:1.7; color:var(--type-dim); }
.confirm-inline .fallback a{ color:var(--on-field-2); border-bottom:1px solid var(--hairline); }
.ts-none{ padding:1.4rem 0; }
.ts-ok,.ts-warn{ margin-top:1rem; }
.ts-ok{ color:var(--on-field-2); }
.ts-warn{ color:var(--alert); }   /* directive red fails on crimson; lift for legibility */
.ts-note{ margin-top:1.4rem; max-width:52ch; font-family:var(--sans); font-size:var(--text-spec);
  line-height:1.7; color:var(--type-dim); }
.cal-open{ margin-top:1.8rem; font-family:var(--sans); font-size:var(--text-action); letter-spacing:.18em;
  text-transform:uppercase; }

/* ---------- SPEC FIELDS (not swatches) ----------------------------------- */
.spec{ margin-top:2rem; display:grid; gap:0; }
.spec > div{ display:grid; grid-template-columns:12rem 1fr; gap:1.5rem; align-items:baseline;
  padding:1rem 0; border-top:1px solid var(--hairline); }
.spec dt{ color:var(--on-field-2); }
.spec dd{ margin:0; color:var(--on-field-2); font-family:var(--sans); font-size:var(--text-body); }
.colourways{ padding-block:clamp(3rem,8vh,5rem); border-top:1px solid var(--hairline); }
@media(max-width:640px){ .spec > div{ grid-template-columns:1fr; gap:.35rem } }

/* ---------- CALIBRATION -------------------------------------------------- */
.cal{ position:fixed; inset:0; z-index:120; display:none; align-items:center; justify-content:center;
  background:rgba(10,2,2,.86); padding:1.4rem; }
.cal.open{ display:flex; }
.cal-panel{ width:min(560px,100%); background:var(--panel); border:1px solid var(--hairline);
  padding:clamp(1.6rem,4vw,2.6rem); }
.cal-panel h3{ font-family:var(--serif); font-weight:400; font-size:1.8rem; color:var(--on-field-2); }
.cal-panel p{ margin-top:.9rem; font-size:.85rem; line-height:1.65; color:var(--type-dim); max-width:44ch; }
.cal{ overflow:auto; }
.cal-card{ margin:1.8rem 0 1rem; width:calc(85.6mm * var(--cal)); height:calc(53.98mm * var(--cal));
  border:1px solid var(--on-field-2); position:relative; }
.cal-card::after{ content:"85.60 × 53.98 mm"; position:absolute; left:.6rem; bottom:.5rem;
  font-family:var(--sans); font-size:var(--text-spec); letter-spacing:.2em; text-transform:uppercase; color:var(--on-field-2); }
.cal input[type=range]{ width:100%; accent-color:var(--on-field-2); }
.cal-actions{ display:flex; gap:1.4rem; margin-top:1.6rem; align-items:center; }

/* below ~420px the card cannot fit landscape — calibrate on its short edge instead */
@media(max-width:420px){
  .cal-card{ width:calc(53.98mm * var(--cal)); height:calc(85.6mm * var(--cal)); }
  .cal-card::after{ content:"53.98 × 85.60 mm"; }
}
/* a 180 mm mark overflows a phone; the pan must be reachable without a mouse */
.ts-stage{ scrollbar-width:thin; }
.ts-stage:focus-visible{ outline:1px solid var(--on-field-2); outline-offset:3px; }

/* ---------- LEGAL / ATELIER ---------------------------------------------- */
.doc{ padding-bottom:clamp(4rem,12vh,8rem); }
.doc h1{ font-family:var(--serif); font-weight:400; font-size:clamp(1.9rem,7vw,5.1rem);
  color:var(--on-field-2); line-height:1; }
.doc h2{ margin-top:2.6rem; font-family:var(--sans); font-size:var(--text-label); font-weight:500;
  letter-spacing:.26em; text-transform:uppercase; color:var(--on-field-2); }
.doc p{ margin-top:.8rem; max-width:60ch; font-family:var(--sans); font-size:var(--text-body);
  line-height:1.75; color:var(--type-dim); }
.doc .wrap > .label.incise{ display:block; }

/* ---------- DEMO FLAG ---------------------------------------------------- */
.demo-flag{ position:fixed; left:0; right:0; bottom:0; z-index:200;
  background:var(--directive); color:#fff; text-align:center;
  font-family:var(--sans); font-size:.6rem; font-weight:500; letter-spacing:.28em;
  text-transform:uppercase; padding:.5rem; }
body{ padding-bottom:2rem; }

@media(prefers-reduced-motion:reduce){
  .row::before{ transform:none; transition:none }
  header{ transition:none } header.hidden{ transform:none }
  .slot,.truesize,.colourways{ transition:none }
  .row:hover .row-name,.row:hover .row-go{ transform:none }
}

/* ---------- THE REGISTER -------------------------------------------------
   Real scarcity, set as type. A pending state is a statement, not a gap. */
.register{ padding-bottom:clamp(3rem,9vh,6rem); }
.reg-row{ position:relative; display:grid; align-items:baseline; gap:1.2rem;
  /* the figure sits BESIDE the piece, not exiled to the edge — the trailing 1fr is
     deliberate margin, not a stranded column */
  /* name column widened 17rem -> 26rem when the quantity column came out; at 17rem
     "The Statement Tee" wrapped to two lines with empty space beside it. */
  grid-template-columns:4.5rem minmax(0,26rem) 6rem 1fr;
  grid-template-areas:"num name mark gap";
  padding:2rem 0; }
.reg-row::before{ content:""; position:absolute; left:0; top:0; width:100%; height:6px;
  background-image:linear-gradient(90deg,var(--hairline),var(--hairline)),
    repeating-linear-gradient(90deg,var(--hairline) 0 1px,transparent 1px 60px);
  background-size:100% 1px,100% 5px; background-position:0 0,0 1px; background-repeat:no-repeat;
  transform:scaleX(0); transform-origin:left;
  transition:transform .62s var(--blade); transition-delay:calc(var(--i,0) * 120ms); }
.reg-row.in::before{ transform:scaleX(1); }
.reg-num{ grid-area:num; align-self:start; padding-top:.5rem; font-family:var(--serif);
  font-size:var(--text-numeral); text-align:right; padding-right:.4rem; color:var(--on-field-2); letter-spacing:.1em; }
.reg-name{ grid-area:name; font-family:var(--serif); font-size:clamp(1.5rem,3vw,2.2rem);
  line-height:1; color:var(--on-field-2); }
.reg-mark{ grid-area:mark; color:var(--on-field-2); }
/* .reg-qty / .q-num / .q-unit / .q-total / .reg-note removed 2026-08-12 with the
   per-SKU quantities they styled. .q-pending survives: still used by "Date pending"
   on the Samples row, which is an honest label — it says what is pending. */
/* Was #E86A62 — the form-ERROR colour, on a data state. It read as a developer error
   token, and the register's whole authority is precision. Oat, quiet, bordered. */
.q-pending{ color:var(--on-field-2); border:1px solid var(--hairline);
  padding:.3rem .6rem; display:inline-block; }
.release{ padding-block:clamp(3rem,9vh,6rem); border-top:1px solid var(--hairline); }
.release h2{ font-family:var(--serif); font-weight:400; font-size:var(--text-h2-util);
  color:var(--on-field-2); margin-top:.6rem; }
.release .spec dd a{ color:var(--on-field-2); border-bottom:1px solid var(--hairline); }
.coll-head p strong{ font-weight:400; color:var(--on-field); }
.register-head p{ max-width:52ch; }
@media(max-width:820px){
  .reg-row{ grid-template-columns:2.6rem minmax(0,1fr) auto;
    grid-template-areas:"num name mark"; row-gap:.6rem; }
}
@media(prefers-reduced-motion:reduce){ .reg-row::before{ transform:none; transition:none } }

/* the send button must show it is working, and must not be pressable twice */
.send.sending{ opacity:.5; pointer-events:none; }
.confirm-inline strong{ font-weight:400; color:var(--on-field); }

/* The row IS the link — the ledger stays a ledger, no furniture added. */
a.reg-row{ text-decoration:none; color:inherit; display:grid; }
a.reg-row:hover .reg-name,a.reg-row:focus-visible .reg-name{ color:var(--on-field); }
a.reg-row:focus-visible{ outline:1px solid var(--on-field-2); outline-offset:4px; }

.reg-foot{ margin-top:clamp(2.5rem,6vw,4rem); max-width:46ch;
  color:var(--type-dim-threshold); font-size:var(--text-body); line-height:1.75; }
.reg-foot a{ color:var(--on-field); text-decoration:none; border-bottom:1px solid rgba(245,241,233,.3);
  padding-bottom:.05em; }
.reg-foot a:hover{ border-bottom-color:var(--on-field); }
