/* system.css — the winner's COMPONENT LAYER, copied into the shop for B3's pilot cut (PLAN row 6b, 2026-10-05) from
   product-design/site-style/system.css at 6c8a9e20, unchanged: it reads only the token names (tokens.css), never a value. The rig's
   rules are the specification (site-style README §11.5, §11.10, §16); this copy is what ships, and the race page v2 (row 8) and
   B6 (row 10a) build on it — fix the shop's copy, and say so in the rig's README. The builder's own glue is builder.css. */
/* posterzap — the component layer of the style session (2026-09-23).
   Reads ONLY the token names in candidates/<x>/tokens.css; a candidate is its
   values. Structure is the wireframes' (site round 4 · builder round 15);
   every control obeys the text-length rule (builder-design §4: +45 % per
   line, ×2.5 per single word, wrap never clip — no control is sized to its
   English text). Class names are the components' names in the brief. */

/* ============================== base ============================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
p, li, td, .lede, .note, .hint, .cap { hyphens: auto; hyphenate-limit-chars: 10 4 4; }   /* only long words (German compounds) hyphenate; never "sepa-rate" */   /* long words hyphenate in running text (German compounds); never inside a control, a heading or a summary */
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font: 400 var(--body)/var(--lh-body) var(--font-ui);
  letter-spacing: 0.002em;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--link); text-decoration: underline; text-decoration-color: var(--link-underline); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { text-decoration-color: currentColor; }
a.quiet { color: inherit; text-decoration: none; }
a.quiet:hover { text-decoration: underline; }
b, strong { font-weight: 600; }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
main { padding: 32px 0 64px; }

hr { border: 0; border-top: 1px solid var(--hairline); margin: var(--section) 0; }
.mark, mark.x { background: var(--mark-bg); color: inherit; padding: 0 2px; border-radius: 2px; white-space: nowrap; }
.nowrap { white-space: nowrap; }
.hide { display: none !important; }

/* ============================== type ============================== */
h1, .h1 {
  font: var(--display-weight) var(--h1)/var(--display-lh) var(--font-display);
  letter-spacing: var(--display-tracking); margin: 0 0 12px; overflow-wrap: break-word;
}
h2, .h2 {
  font: var(--h2-weight) var(--h2)/1.2 var(--font-display);
  letter-spacing: var(--h2-tracking); margin: var(--section) 0 14px;
}
h3, .h3 { font: 600 var(--h3)/1.35 var(--font-ui); margin: 28px 0 6px; letter-spacing: -0.005em; }
h2 + p, h2 + .kv, h2 + .faq, h3 + p { margin-top: 0; }
.lede { font-size: var(--lede); line-height: 1.5; color: var(--ink-2); max-width: 640px; margin: 0 0 10px; }
.measure { max-width: 640px; }
.kicker {
  font: 600 var(--kicker-size)/1.3 var(--font-ui); letter-spacing: var(--kicker-tracking);
  text-transform: uppercase; color: var(--kicker); margin: 0 0 8px;
}
.prose p.kicker { color: var(--kicker); }   /* session 4 (2026-09-29): the reading pages' page label keeps the kicker colour (the prose paragraph rule outranked .kicker) */
.facts { font-size: 15px; color: var(--soft); margin: 4px 0 0; }
.note, .hint { font-size: var(--small); color: var(--soft); line-height: 1.45; }
.hint { margin: 6px 0 0; }
.micro { font-size: var(--micro); color: var(--soft); }
.price { font-size: var(--price); font-weight: var(--price-weight); letter-spacing: -0.02em; line-height: 1.1; }
.crumb { font-size: 13.5px; color: var(--soft); margin: 0 0 22px; }
.crumb a { color: var(--soft); text-decoration: none; }
.crumb a:hover { color: var(--ink); text-decoration: underline; }
.crumb b { color: var(--ink); font-weight: 500; }
p { margin: 0 0 12px; }
.ticks { font-size: 15px; color: var(--ink-2); margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 6px 22px; }
.ticks span::before { content: "✓ "; }

/* ============================== header / nav ============================== */
/* The header stays at the top as the page scrolls, on a phone and a computer (his look at 10h's preview, 2026-10-29: "like
   allbirds"; the builder's and the checkout's own headers apart); --header-h its height, the room an in-page link leaves for it */
:root { --header-h: 75px; }
@media (max-width: 730px) { :root { --header-h: 57px; } }
html:has(> body > header.site) { scroll-padding-top: var(--header-h); }   /* only where the header is: the builder's and the checkout's own scrolls untouched */
header.site { position: sticky; top: 0; z-index: 45; border-bottom: 1px solid var(--hairline); background: var(--ground); }
header.site .wrap { display: flex; align-items: center; gap: 28px; padding-top: 16px; padding-bottom: 14px; flex-wrap: wrap; }
.wordmark { font: 700 20px/1 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); text-decoration: none; }
nav.site { display: flex; gap: 4px; flex-wrap: wrap; align-items: baseline; }
nav.site a { font-size: 14.5px; font-weight: 500; color: var(--soft); padding: 10px 8px; text-decoration: none; }
nav.site a:hover, nav.site a[aria-current="page"] { color: var(--ink); }
/* Row 10h (his picks 2026-10-29, chrome/10h-record.md): a computer's bar is the wordmark, the nav's two words and the cart at the
   right; a phone's is ☰ and the search at the left (.hl — none on a computer), the wordmark centred, the cart at the right. */
header.site .hl { display: none; }
.nav-toggle, .nav-search { border: 0; background: none; color: var(--ink); width: var(--target); height: var(--target); display: inline-grid; place-items: center; cursor: pointer; padding: 0; flex: none; }
/* the cart: the bag and its number alone (his picks 3 A, 4 A) — a disc on the bag's corner, a ring of the page's colour between
   them; none while the cart is empty (the number [hidden] until site-chrome.js counts) */
.cart { position: relative; margin-left: auto; display: inline-grid; place-items: center; width: var(--target); height: var(--target); color: var(--ink); text-decoration: none; flex: none; }
.cart:hover { color: var(--ink); text-decoration: none; }
/* its left edge fixed, so a second digit grows it rightwards, away from the bag (the visual seat: at "12" its ring cut the corner) */
.cart .n { position: absolute; top: 3px; left: 28px; min-width: 17px; height: 17px; padding: 0 4px; box-sizing: border-box; border-radius: 9px; background: var(--ink); color: var(--ground); font: 700 10.5px/17px var(--font-ui); text-align: center; box-shadow: 0 0 0 2px var(--ground); }
@media (max-width: 730px) {
  .wrap { padding-left: var(--gutter-phone); padding-right: var(--gutter-phone); }
  header.site .wrap { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0; padding-top: 6px; padding-bottom: 6px; }
  header.site .hl { display: flex; align-items: center; justify-self: start; margin-left: -10px; }
  nav.site { display: none; }
  header.site .cart { justify-self: end; margin: 0 -3px 0 0; }
}
/* the builder's own header: back link + save */
header.tool .wrap { display: flex; align-items: center; gap: 18px; padding-top: 12px; padding-bottom: 12px; flex-wrap: nowrap; }
header.tool .wrap > * { flex: none; }
header.tool .back { font-size: 14px; }   /* a link like every other (6l, his pick 2 B 2026-10-19: it was grey, not seen as one) */
header.tool .save { margin-left: auto; }
header.tool .note { margin-left: auto; flex: 1 1 auto; min-width: 0; text-align: right; }
@media (max-width: 600px) { header.tool .wrap { flex-wrap: wrap; gap: 8px 12px; } header.tool .back { margin-left: auto; } header.tool .save { margin-left: auto; } }   /* the way back on the wordmark's line, at the right (6l 2 B) */

/* ============================== buttons ============================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: 46px; background: var(--btn-bg); color: var(--btn-fg);
  font: 600 15.5px/1.3 var(--font-ui); padding: 10px 22px; text-align: center;
  border-radius: var(--radius); border: 1px solid transparent; cursor: pointer; text-decoration: none;
  min-width: 0; max-width: 100%; overflow-wrap: anywhere;
}
.btn:hover { background: var(--btn-hover); color: var(--btn-fg); text-decoration: none; }
.btn.ghost { background: transparent; color: var(--ghost-fg); border-color: var(--ghost-border); }
.btn.ghost:hover { background: transparent; color: var(--ghost-fg); text-decoration: underline; }
.btn.block { display: flex; width: 100%; }
.btn.small { font-size: 14px; padding: 7px 14px; min-height: 38px; }
.btn.pill { border-radius: 999px; }
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible, .option:has(input:focus-visible), .sw:has(input:focus-visible), .sw:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
/* a chip's focus: a ring further out than its chosen ring (6b5 (f)), so a focused chip never looks chosen */
.chip:has(input:focus-visible) { box-shadow: 0 0 0 5px var(--ground), 0 0 0 7px var(--focus-ring); }   /* 5–7 px: clear of the next chip's border, 8 px away (the visual seat's NIT) */
input:focus-visible, select:focus-visible, textarea:focus-visible { outline-offset: 1px; border-color: var(--control-border-hover); }
legend { padding: 0; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin: 18px 0 0; }
.link-btn { background: none; border: 0; padding: 0; font: inherit; color: var(--link); text-decoration: underline; text-decoration-color: var(--link-underline); text-underline-offset: 3px; cursor: pointer; }

/* ============================== chips ============================== */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 12px; }
/* RESET: a chip is the SHORT SINGLE CHOICE (a year, a day, the times' three ways). Its boundary is a control border
   (≥ 3:1), never the decorative rule; 40 px tall. As a label it holds a real radio. The selected state is the page's selection
   idiom — a ring with a gap, as the chosen style and frame colour — on a light grey (6b5 (f), his pick A 2026-10-09: the ink
   fill fought the step's primary button for importance; solid ink is the one primary action of a step) */
.chip {
  position: relative; display: inline-flex; align-items: center; gap: 8px; min-height: 40px;
  font: 500 15px/1.3 var(--font-ui); color: var(--chip-fg); background: var(--chip-bg);
  border: 1px solid var(--control-border); border-radius: var(--radius-chip); padding: 8px 16px;
  cursor: pointer; text-decoration: none; overflow-wrap: anywhere; text-align: left;
}
.chip:hover { border-color: var(--control-border-hover); }
.chip.on, .chip:has(input:checked) { background: var(--chip-on-bg); color: var(--chip-on-fg); border-color: var(--chip-on-border); outline: 2px solid var(--chip-on-ring); outline-offset: 2px; }
/* forced colours draw no box-shadow: the focus a dashed ring further out — after the chosen rule, which it must win (focus in a
   radio group sits on the chosen chip; the code seat's LOW-5, the re-check's LOW-1) */
@media (forced-colors: active) { .chip:has(input:focus-visible) { outline: 2px dashed CanvasText; outline-offset: 6px; } }
.chip input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.chip.off { color: var(--text-disabled); border-color: var(--rule); cursor: not-allowed; }
.chip.off::after { content: " · unavailable"; font-size: 13px; }
/* the DISCLOSURE ("Earlier years", "Part of a relay team?"): a solid boundary, the ink, a chevron — never dashed */
.chip.soft, .disclose {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 8px 14px; font: 500 15px/1.3 var(--font-ui);
  color: var(--text); background: transparent; border: 1px solid var(--control-border); border-radius: var(--radius-chip); cursor: pointer; text-decoration: none;
}
.chip.soft, .disclose { border-radius: var(--radius); }
.chip.soft::after, .disclose::after { content: "▾"; font-size: 19px; line-height: 0.8; }
.disclose.link::after { text-decoration: none; display: inline-block; margin-left: 2px; }
.disclose[aria-expanded=true]::after { content: "▴"; }
.disclose.link { border: 0; padding: 6px 0; min-height: 32px; color: var(--link); text-decoration: underline; text-decoration-color: var(--link-underline); text-underline-offset: 3px; }   /* the combined pass: a text action takes the link colour like every other (his notes 2026-09-29) */
.chip.count b { font-weight: 500; }

/* ============================== fields ============================== */
.field { margin: 0 0 16px; }
.field label, .label { display: block; font-size: 14.5px; font-weight: 500; margin: 0 0 6px; }
.label.q { color: var(--ink-2); font-weight: 400; }   /* the builder's questions: "Which year?" */
.hint + .label, .chips + .label { margin-top: 14px; }
input[type=text], input[type=email], input[type=search], input[type=url], input[type=date], input[type=number], select, textarea {
  width: 100%; padding: 10px 12px; font: inherit; font-size: 16px; color: var(--ink);
  border: 1px solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); min-height: var(--target);
}
input[readonly], input.ro { background: var(--surface-2); border-color: var(--rule); color: var(--text-2); }
input:disabled, select:disabled { color: var(--text-disabled); background: var(--surface-2); border-color: var(--rule); cursor: not-allowed; }
textarea { min-height: 88px; resize: vertical; }
select { appearance: none; -webkit-appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%; background-size: 5px 5px; background-repeat: no-repeat; }
.search { position: relative; }
.search input { padding-left: 38px; }
.search::before { content: "⌕"; position: absolute; left: 14px; top: 50%; transform: translateY(-52%); color: var(--soft); font-size: 17px; }
.fits { font-size: 13.5px; color: var(--trust); margin: 4px 0 0; }
.check { display: flex; width: fit-content; gap: 10px; align-items: flex-start; font-size: 14px; margin: 12px 0; }   /* likewise */
.check input { margin-top: 3px; width: 18px; height: 18px; flex: none; }
/* the combined pass (his notes 2026-09-29): an independent yes/no setting is a checkbox — "No name on the poster" under its field, at the right; the label tappable; the fit line keeps its own room above */
/* round 3 (his decision 2026-09-29): the name field's label IS the checkbox — "Include a name on the poster", default on; the whole label
   comfortably tappable (--target); the box on the group's left edge with the field; the text input keeps its own accessible name (aria-label).
   Unticked: the field stays visible and disabled with its value kept, its fit line hidden; ticking restores it. The row it replaces
   ("No name on the poster" on the fit line's row) stays as the rig switch ?noname=row, the record of what he chose from. */
.field .labelcheck { display: flex; width: fit-content; gap: 10px; align-items: center; min-height: var(--target); margin: 2px 0 2px; font-size: 14.5px; font-weight: 500; color: var(--text); cursor: pointer; }   /* its words' width: a click beside them is not a tick (his look 2026-10-09 — the shop's fix, noted in the rig's README) */
.field .labelcheck input { width: 18px; height: 18px; margin: 0; flex: none; }
.field.single > label[for=name] { display: none; }
.field .with > .check.noname { display: none; flex: 0 0 auto; order: 3; margin: 4px 0 0 auto; align-items: center; gap: 10px; min-height: 22px; font-size: 14.5px; font-weight: 400; color: var(--text); cursor: pointer; }
html[data-nonamevariant=row] .field .labelcheck { display: none; }
html[data-nonamevariant=row] .field.single > label[for=name] { display: block; }
html[data-nonamevariant=row] .field .with > .check.noname { display: flex; }
.field .with > .check.noname input { margin: 0; width: 18px; height: 18px; flex: none; }
input[type=checkbox], input[type=radio] { accent-color: var(--ink); }   /* the combined pass (QA 2026-09-29): a native check or radio takes the ink, never the browser's blue */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mini { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 96px), 1fr)); gap: 10px; align-items: end; }   /* a wrapped label never drops its field below its neighbours */  /* Swim · Bike · Run — sizes to content with a ceiling: grows to more rows, never past the container */
.mini .field { margin: 0; }
@media (max-width: 600px) { .grid-2 { grid-template-columns: 1fr; } }

/* ============================== swatches (frame colour) ============================== */
.swatches { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 8px 0; }
.swatches .label { margin: 0; display: inline; }
.sw { width: var(--target); height: var(--target); display: inline-grid; place-items: center; background: none; border: 0; padding: 0; cursor: pointer; border-radius: 50%; }
.sw::before { content: ""; width: 28px; height: 28px; border-radius: 50%; background: var(--sw); box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); }
.sw[data-frame=black] { --sw: var(--frame-black); }
.sw[data-frame=brown] { --sw: var(--frame-brown); }
.sw[data-frame=natural] { --sw: var(--frame-natural); }
.sw[data-frame=white] { --sw: var(--frame-white); }
.sw.on::before, .sw:has(input:checked)::before { box-shadow: inset 0 0 0 1px rgba(0,0,0,.18), 0 0 0 2px var(--ground), 0 0 0 4px var(--ink); }
.sw input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.swatches { gap: 4px; }
.swatches .label { margin-right: 6px; }
.swatches .name { font-size: 14.5px; color: var(--ink-2); }
.swatches + .btn { margin-top: 14px; }

/* ============================== the poster + the frame ============================== */
/* .poster is a container; .framed draws the moulding as padding on .sheet, a share of the poster's width, so the
   frame keeps its proportion from a 120 px tile to a 420 px hero. The rebate (the lip) is a 1 px line on ::after. */
.poster { container-type: inline-size; width: 100%; position: relative; }
.poster img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.poster.unframed img { box-shadow: 0 0 0 1px var(--sheet-edge), var(--shadow-sheet); }
.poster.unframed .zoom { right: 10px; top: 10px; }
.poster.framed .sheet { position: relative; padding: var(--frame-w); box-shadow: 0 0 0 1px var(--frame-outline), var(--shadow-frame); }
.poster.framed .sheet::after { content: ""; position: absolute; inset: var(--frame-w); pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.18), 0 0 0 1px var(--frame-lip-light); }
.poster.framed[data-frame=black] .sheet { background: var(--frame-black); }
.poster.framed[data-frame=brown] .sheet { background: var(--frame-brown); }
.poster.framed[data-frame=natural] .sheet { background: var(--frame-natural); }
.poster.framed[data-frame=white] .sheet { background: var(--frame-white); }
.poster.framed[data-frame=black] .sheet::after, .poster.framed[data-frame=brown] .sheet::after { box-shadow: inset 0 0 0 1px rgba(0,0,0,.35), 0 0 0 1px var(--frame-lip-dark); }
/* the moulding as Prodigi's Classic frame — as poster-preview.css draws it (PLAN row 7b (d), his picks 2026-10-20) */
.poster.framed .sheet::before { content: ""; position: absolute; inset: 0; pointer-events: none; border-image: var(--frame-img) 5% / var(--frame-w) stretch; }
.poster.framed[data-frame=black] { --frame-img: url("/assets/img/frames/black.svg?v=9036496e"); }
.poster.framed[data-frame=brown] { --frame-img: url("/assets/img/frames/brown.webp?v=f69c386c"); }
.poster.framed[data-frame=natural] { --frame-img: url("/assets/img/frames/natural.webp?v=0ff1b575"); }
.poster.framed[data-frame=white] { --frame-img: url("/assets/img/frames/white.svg?v=eb269e3c"); }
/* a control drawn on the placed photo (founder 2026-09-22): "Edit photo" */
.poster .onphoto { position: absolute; display: inline-flex; align-items: center; min-height: clamp(24px, 9cqw, 36px); font: 500 clamp(10px, 3.6cqw, 13px)/1 var(--font-ui); color: #fff; background: rgba(0,0,0,.66); padding: 0.45em 0.85em; border-radius: 999px; text-decoration: none; white-space: nowrap; }   /* sized with the poster (cqw): on a 200 px poster it stays inside the photo */
.poster .zoom { position: absolute; right: calc(var(--frame-w) + 10px); top: calc(var(--frame-w) + 10px);   /* the map's corner, never the footer's stats */ font: 500 12.5px/1 var(--font-ui); color: var(--ink); background: rgba(255,255,255,.88); border: 1px solid var(--rule); padding: 6px 9px; border-radius: var(--radius); text-decoration: none; }
/* the honest mock (undrawn / own race): dashed panels on the paper */
.poster .mockpanel { position: absolute; border: 1px dashed rgba(0,0,0,.25); display: grid; place-items: center; font-size: 11px; color: rgba(0,0,0,.45); text-align: center; padding: 6px; }
/* the stage — the wall panel a poster hangs on (a candidate may set it transparent with no padding) */
.stage { background: transparent; padding: 0; }   /* 2026-09-28: no block per poster — a product AREA is the block (see BACKGROUNDS) */
.stage.hero { background: var(--ground-product); }   /* the product stage (its padding and corners: BACKGROUNDS) */
.stage > .poster { margin: 0 auto; }

/* the style rail (four thumbs) and the carousel (dots + names) */
.grouplabel { font: 600 12px/1.3 var(--font-ui); letter-spacing: 0.1em; text-transform: uppercase; color: var(--soft); margin: 18px 0 8px; }
.rail { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start; }
.rail a { text-decoration: none; color: var(--soft); font-size: 13px; text-align: center; min-width: 60px; max-width: 96px; overflow-wrap: anywhere; }
.rail .poster { width: 56px; margin: 0 auto 6px; }
.rail .poster.framed .sheet { box-shadow: 0 0 0 1px var(--frame-outline), 0 1px 3px rgba(0,0,0,.18); }
.rail .poster.framed .sheet::after { box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); }
.rail a.on { color: var(--ink); font-weight: 600; }
.rail a.on .poster { box-shadow: 0 0 0 3px var(--ink); border-radius: 1px; }
.carousel { text-align: center; margin-top: 12px; }
.dots { display: flex; gap: 8px; justify-content: center; margin: 0 0 10px; }
.dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--rule); display: block; }
.dots i.on { background: var(--ink); }
.names { display: flex; gap: 18px; justify-content: center; font-size: 15px; color: var(--soft); flex-wrap: wrap; }
.names span.on { color: var(--ink); font-weight: 600; text-decoration: underline; text-underline-offset: 5px; }
.cap { font-size: var(--small); color: var(--soft); margin: 8px 0 0; line-height: 1.45; }
.cap.body { font-size: var(--body); color: var(--ink); }     /* the undrawn page's caption at body size */
.stage + .cap.body { margin-top: 22px; }   /* clear of the frame's shadow */
.cap.center { text-align: center; }

/* ============================== the purchase box ============================== */
.box { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius-card); padding: 22px 22px 18px; box-shadow: var(--shadow-card); }
.box .btn { margin-bottom: 14px; }
.box p { margin: 0 0 10px; }
.box .prices { font-size: 16.5px; margin: 6px 0 2px; }
.box .prices b { font-weight: 600; }
.box .prices .pr, .bar .bp .pr { white-space: nowrap; }
.box .prices .sep { padding: 0 2px; }
.box .sep { color: var(--soft); padding: 0 4px; }
.box .size { color: var(--soft); font-size: 14.5px; margin: 0 0 10px; }
.box .sign { font-size: 15px; margin: 8px 0 0; }
@media (max-width: 600px) { .box { padding: 16px; } .box .btn { display: block; width: 100%; } }

/* ============================== the race hero ============================== */
/* RESET: the race hero is three parts — .ident (kicker · h1 · lede · facts) · .art (the poster, its rail or carousel,
   the caption, the tick line) · .buy (the formats, the button, the assurance, the signposts). Desktop: the art left,
   ident over buy on the right. Phone, drawn race: art · ident · buy (poster first, callout 17); undrawn: ident · art · buy
   (name first, callout 25). Two treatments of the summary: A "integrated" (default) — a column of the page, hairlines
   between its parts; B "surface" (html[data-summary=surface]) — ident + buy on one surface. */
.hero { display: grid; grid-template-columns: 1fr; gap: 22px 56px; align-items: start; position: relative; }
.hero > * { min-width: 0; position: relative; z-index: 1; }
.hero .art { order: 1; } .hero .ident { order: 2; } .hero .buy { order: 3; }
.hero.undrawn .ident { order: 1; } .hero.undrawn .art { order: 2; } .hero.undrawn .buy { order: 3; }
.hero .offerbg { display: none; }
.hero .art .poster { max-width: 100%; }
@media (min-width: 960px) {
  .hero { grid-template-columns: minmax(300px, 500px) 1fr; grid-template-rows: auto 1fr; }
  .hero .art, .hero .ident, .hero .buy { order: 0; }
  .hero .art { grid-column: 1; grid-row: 1 / 3; }
  .hero .ident { grid-column: 2; grid-row: 1; }
  .hero .buy { grid-column: 2; grid-row: 2; }
  .hero .art .poster { max-width: 420px; }
}
.home-hero { display: grid; grid-template-columns: 1fr; gap: 32px; align-items: center; }
.home-hero > * { min-width: 0; }
.home-hero .art .poster { max-width: 360px; }
@media (min-width: 960px) { .home-hero { grid-template-columns: minmax(300px, 460px) 1fr; gap: 64px; } }

/* ============================== the sticky bar (the race page; the homepage and the gifts page since 10h) ============================== */
/* RESET: the bar is FIXED to the viewport (no viewport-width margin, so no horizontal overflow beside a scrollbar), phone
   only, and has the wireframes' three states — hidden while one of the page's own buttons it names (data-pz-watch) is on
   screen (data-state=hero), shown once they have left (shown), hidden over the footer (footer). site-chrome.js sets the state
   from two observers. */
.bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; background: var(--bar-bg); border-top: 1px solid var(--hairline); box-shadow: var(--shadow-strip); transform: translateY(110%); visibility: hidden; transition: transform .18s ease, visibility 0s linear .18s; }
.bar[data-state=shown] { transform: none; visibility: visible; transition-delay: 0s; }
.bar .wrap { display: flex; align-items: center; gap: 12px; padding-top: 10px; padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
@media (min-width: 960px) { .bar { display: none; } }
@media (prefers-reduced-motion: reduce) { .bar { transition: none; } }
.bar .bp { font-size: 14.5px; color: var(--ink-2); flex: 1 1 auto; min-width: 0; }
.bar .btn { flex: none; }
.bar .btn:only-child { flex: 1 1 auto; }   /* without prices (10h: the homepage's and the gifts page's bar) the button the bar's width */
@media (max-width: 600px) { .bar .bp { font-size: 13.5px; } .bar .bp .pr { display: block; } .bar .bp .sep { display: none; } .bar .btn { padding: 11px 16px; font-size: 14.5px; } }


/* ============================== cards, tiles, the gallery ============================== */
.card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-card); padding: 20px; box-shadow: var(--shadow-card); }
/* format cards — Framed print · Unframed print · Digital file (a choice) */
.pcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin: 8px 0 12px; }
.pcard { display: block; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius); padding: 12px 14px; cursor: pointer; color: var(--ink); text-decoration: none; }
.pcard b { display: block; font-weight: 600; }
.pcard small { display: block; color: var(--soft); font-size: 13px; margin-top: 2px; }
.pcard .p { display: block; font-weight: 600; margin-top: 6px; }
.pcard.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
/* the gallery wall: six drawn races, each in its style's matched frame — the gallery-wall test */
.wall { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0 24px; margin: 24px 0 0; }
.wall.six { grid-template-columns: repeat(6, 1fr); }
.wall a { text-decoration: none; color: var(--ink); min-width: 0; display: grid; grid-template-rows: subgrid; grid-row: span 4; align-content: start; }   /* CORRECTION 2026-09-25: the rows align across the wall as on the finder */
.wall a > * { min-width: 0; }
.wall b { display: block; font-weight: 600; font-size: 14.5px; margin-top: 12px; line-height: 1.3; }
.wall small { display: block; color: var(--soft); font-size: 13px; line-height: 1.35; }
.wall .sty { display: block; color: var(--soft); font-size: 13px; margin-top: 2px; margin-bottom: 28px; }
.wall + .note, .tiles + .note { margin-top: 22px; }
@media (max-width: 959px) { .wall.six { grid-template-columns: repeat(3, 1fr); gap: 0 14px; } }
@media (max-width: 600px) { .wall.six { grid-template-columns: repeat(2, 1fr); gap: 0 14px; } }
/* the finder tile (the grid) and the finder row (the list) */
/* CORRECTION 2026-09-25 (the whole-shop review, 1): the frame and its left-aligned caption share one content edge — the poster
   fills the tile's width (the quiet block = the stage; its padding, where a candidate has one, insets the frame inside the block whose
   edge the caption keeps) — and the tile's rows (poster · title · place · price) are SUBGRID rows of the grid, so every tile in a row
   shares the title, place and price baselines, sized by the longest content; a three-line title moves the whole row. */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 0 24px; margin: 24px 0 0; }   /* no row gap: a subgrid tile would inherit it between ITS rows; the space between tile rows is the last row's margin */
@media (max-width: 699px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; } }
.tile { text-decoration: none; color: var(--ink); min-width: 0; display: grid; grid-template-rows: subgrid; grid-row: span 4; align-content: start; }
.tile .stage .poster { width: 100%; margin: 0; }
.tile > * { min-width: 0; }
.tiles.three-row .tile { grid-row: span 3; }   /* a tile without a place line (Gifts) */
.tile b { display: block; font-weight: 600; font-size: 14.5px; margin-top: 12px; line-height: 1.3; }
.tile small { display: block; color: var(--soft); font-size: 13px; }
.tile .from { display: block; color: var(--ink-2); font-size: 13px; margin-top: 3px; margin-bottom: 32px; }   /* the space to the next row of tiles */
.rows { margin: 16px 0 0; border-top: 1px solid var(--hairline); }
.rowi { display: flex; gap: 14px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--hairline); text-decoration: none; color: var(--ink); }
.rowi .poster { width: 44px; flex: none; }
.rowi .rt { flex: 1 1 auto; min-width: 0; }
.rowi b { display: block; font-weight: 600; font-size: 15px; }
.rowi small { color: var(--soft); font-size: 13px; }
.rowi .from { font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.rowi .go { display: none; }
.rowi:hover .go { display: inline-block; }
.own { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; border: 1px solid var(--rule); border-radius: var(--radius-card); padding: 18px 20px; margin: 36px 0 0; background: var(--surface); }
.own b { display: block; font-size: 16px; }
.own p { margin: 0; color: var(--ink-2); }

/* ============================== the thumbnail rail (order page: the other three styles) ============================== */
.thumbs { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.thumbs .poster { width: 64px; }

/* ============================== notices, found lines, kv, tables, steps, faq ============================== */
.notice { border-left: 3px solid var(--notice-border); background: var(--notice-bg); padding: 10px 14px; margin: 10px 0 14px; border-radius: 0 var(--radius) var(--radius) 0; }
.notice b { display: block; }
.notice p, .notice .row { margin: 4px 0 0; }
.found { border-left: 3px solid var(--trust); padding: 8px 14px; margin: 12px 0; }
.found b { display: block; }
.found small { color: var(--soft); font-size: 13.5px; display: block; }
.found .row { margin-top: 4px; font-size: 14.5px; }
.ok { color: var(--trust); }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 10px 26px; margin: 12px 0; align-items: baseline; }
.kv > span:nth-child(odd) { color: var(--text-3); font-size: 14.5px; }
.kv > span:nth-child(even) { max-width: var(--measure); min-width: 0; }
.kv.lines > span { padding: 12px 0; border-top: 1px solid var(--hairline); }
.kv.lines > span:nth-child(odd) { color: var(--ink); font-weight: 600; font-size: 15px; }
.kv.lines > span:nth-child(-n+2) { border-top: 0; }
@media (max-width: 600px) { .kv.lines { grid-template-columns: 1fr; gap: 0; } .kv.lines > span { border-top: 0; padding: 4px 0; } .kv.lines > span:nth-child(odd) { padding-top: 14px; border-top: 1px solid var(--hairline); } .kv.lines > span:nth-child(1) { border-top: 0; } }
table.plain { border-collapse: collapse; width: 100%; font-size: 15px; }
table.plain td, table.plain th { text-align: left; padding: 10px 14px 10px 0; border-top: 1px solid var(--hairline); vertical-align: top; }
table.plain th { font-weight: 600; }
table.plain tr:first-child td, table.plain tr:first-child th { border-top: 0; }
table.plain thead + tbody > tr:first-child > td { border-top: 1px solid var(--rule); }
.steps3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin: 18px 0 0; }
.steps3 .num { display: block; font: 600 14px/1 var(--font-ui); color: var(--num); margin-bottom: 8px; }
.steps3 b { display: block; font-weight: 600; margin-bottom: 4px; }
@media (max-width: 700px) { .steps3 { grid-template-columns: 1fr; gap: 18px; } }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
.three { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
@media (max-width: 700px) { .two, .three { grid-template-columns: 1fr; gap: 24px; } }
.faq { border-top: 1px solid var(--hairline); margin: 14px 0 0; }
.faq details { border-bottom: 1px solid var(--hairline); }
.faq summary { cursor: pointer; list-style: none; padding: 14px 0; display: flex; justify-content: space-between; gap: 16px; font-size: 15.5px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--soft); flex: none; }
.faq details[open] summary::after { content: "−"; }
.faq details p { margin: 0 0 16px; color: var(--text-2); font-size: 15px; max-width: var(--measure); }
.trust { display: flex; gap: 18px; align-items: center; padding: 22px 0; border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); margin: 40px 0; }
.trust .face { width: 56px; height: 56px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--hairline); flex: none; }
/* a draft's poster waits (8a, his look 2026-10-21: the default poster flashed before his): draft-early.js marks the page before
   the first paint; race-page.mjs and builder.mjs show the poster once it is the draft's — or, whatever happens, after 4 s
   — the fallback for a page whose script never runs; once it runs (pz-draft-js) the script alone shows the poster, so a slow
   line never shows the stand-in face (the visual seat; the re-check's 5). The format rows wait too, so "(pictured)" never
   moves in sight; the closing band's poster waits on a started poster's page until it is his (the re-check's 1) */
.pz-draft-wait :is(.hero .art .pp-mount, .hero .art .cap, .hero .buy > .btn, .hero .buy .formats, #poster) { visibility: hidden; animation: pz-draft-show 0s 4s forwards; }
.pz-started .final .cl-art .pp-mount:not(.pz-shown) { visibility: hidden; animation: pz-draft-show 0s 4s forwards; }
.pz-draft-js.pz-draft-wait :is(.hero .art .pp-mount, .hero .art .cap, .hero .buy > .btn, .hero .buy .formats, #poster), .pz-draft-js.pz-started .final .cl-art .pp-mount:not(.pz-shown) { animation: none; }
@keyframes pz-draft-show { to { visibility: visible; } }
.trust .face { overflow: hidden; } .trust .face img { display: block; width: 100%; height: 100%; object-fit: cover; }   /* his portrait (8a, IMG_8807): the photo fills the circle */
.feat { display: grid; grid-template-columns: minmax(200px, 300px) 1fr; gap: 32px; align-items: center; margin-top: 12px; }
.feat > * { min-width: 0; }
@media (max-width: 700px) { .feat { grid-template-columns: 1fr; gap: 12px; } }
.pers { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 16px; }
.pers figure { margin: 0; min-width: 0; }
.pers figure .stage { margin-bottom: 12px; }
.pers figure img.crop { width: 100%; height: auto; border-radius: var(--radius-card); box-shadow: 0 0 0 1px var(--sheet-edge); }
.pers { align-items: stretch; }
.pers figure { display: flex; flex-direction: column; }
.pers figure .stage { display: grid; place-items: center; }
.pers figure .stage > img.crop { width: 86%; }
.pers.three figure > img.crop { aspect-ratio: 16 / 10; object-fit: contain; background: transparent; padding: 4%; }
.pers b { display: block; font-weight: 600; }
.pers small { display: block; color: var(--soft); font-size: 13.5px; margin-top: 2px; }
@media (max-width: 700px) { .pers { grid-template-columns: 1fr; } }
.pers.three { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 700px) { .pers.three { grid-template-columns: 1fr; } }
.tband { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; padding: 28px 0; border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); margin: var(--section) 0 0; font-size: 15px; }
.tband b { display: block; margin-bottom: 4px; }
@media (max-width: 700px) { .tband { grid-template-columns: 1fr; gap: 18px; } }
.final { text-align: center; padding: 40px 0 0; }

/* ============================== the builder ============================== */
.builder { display: grid; grid-template-columns: 1fr; gap: 32px; align-items: start; }
.builder > * { min-width: 0; }
@media (min-width: 960px) { .builder { grid-template-columns: minmax(320px, 440px) 1fr; gap: 56px; } }
.look .poster { max-width: 440px; }
.look .cap { margin-top: 10px; }
.groups { margin: 0; }
.group { border-top: 1px solid var(--hairline); padding: 18px 0 6px; }
.group:first-child { border-top: 0; padding-top: 0; }
/* RESET: a stage heading in sentence case at h3 size with a status mark before it — a filled dot = the current group,
   ✓ = done (its summary row follows), a hollow dot = still to come, and the optional group carries its toggle. */
.ghead { display: flex; align-items: center; gap: 10px 12px; flex-wrap: wrap; font: 600 17px/1.3 var(--font-ui); letter-spacing: -0.005em; text-transform: none; color: var(--text); margin: 0 0 12px; }
.ghead::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); flex: none; }
.group.closed, .group.next, .group.off { padding: 14px 0; }
.group.done { border-top: 0; padding: 0; }
.group.closed .ghead, .group.next .ghead, .group.off .ghead { color: var(--text-3); font-weight: 500; margin-bottom: 0; }
.group.closed .ghead::before, .group.next .ghead::before, .group.off .ghead::before { background: transparent; box-shadow: inset 0 0 0 1.5px var(--control-border); }
.group.done .ghead { color: var(--text); font-weight: 500; margin-bottom: 0; }
.group.done .ghead::before { content: "✓"; width: auto; height: auto; background: none; color: var(--trust); font-size: 15px; font-weight: 700; line-height: 1; }
.ghead .opt { font: 400 14px/1.3 var(--font-ui); letter-spacing: 0; text-transform: none; color: var(--text-3); }
.ghead .chip { text-transform: none; letter-spacing: 0; font-weight: 500; }
.groups > .hint, .groups > p { margin-bottom: 18px; }
.groups .h3 a { margin-left: 12px; font-weight: 400; font-size: 14.5px; }
/* the summary row: heading · summary · Edit — a flex row; the summary drops under the heading when short of room, Edit keeps the right */
.sum { display: grid; grid-template-columns: minmax(110px, 150px) minmax(0, 1fr) auto; gap: 4px 16px; align-items: baseline; margin: 0; padding: 12px 0; border-top: 1px solid var(--rule-deco); }
.sum + .sum { padding-top: 12px; }
@media (max-width: 600px) { .sum { grid-template-columns: 1fr auto; } .sum .ss { grid-column: 1 / -1; grid-row: 2; } .sum .ed { grid-row: 1; grid-column: 2; } }
.sum .sh { font: 500 14.5px/1.4 var(--font-ui); letter-spacing: 0; text-transform: none; color: var(--text-3); }
.sum .sh::before { content: "✓ "; color: var(--trust); font-weight: 700; }
.sum .ss { min-width: 0; font-size: 15px; color: var(--text); }
.sum .ss b { font-weight: 600; }
.sum .ed { white-space: nowrap; justify-self: end; font-size: 14.5px; padding: 6px 2px; margin: -6px -2px; }   /* a 32 px tall target around the word */
.course { border-left: 3px solid var(--ink); padding: 6px 14px; margin: 6px 0 14px; }
.course b { display: block; font-weight: 600; }
.course .row { margin-top: 4px; font-size: 14.5px; }
.course .row small { color: var(--soft); }
div.done { margin: 18px 0 8px; }   /* the Done — next button's row (never the strip's "done" segments) */
/* the phone's sticky strip: maps · footer-only · full · collapsed */
.strip { position: sticky; top: 0; z-index: 30; background: var(--strip-bg); border-bottom: 1px solid var(--strip-border); box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.strip .segbar { display: flex; align-items: center; gap: 10px; padding: 8px var(--gutter-phone) 6px; font-size: 14px; }
.strip .segbar b { font-weight: 600; }
.strip .segbar { flex-wrap: nowrap; }
.strip .segbar .segs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; flex: 1 1 auto; min-width: 100px; align-self: center; }
.strip .segbar .segs i { height: 3px; margin: 0; background: var(--hairline); border-radius: 2px; display: block; }
.strip .segbar .segs i.on { background: var(--ink); }
.strip .segbar .segs i.done { background: var(--rule); }
.strip .stage { border-radius: 0; }
.strip .full { padding: 10px var(--gutter-phone) 6px; }
.strip .full .poster { max-width: 100%; }
.strip .footer-only { overflow: hidden; height: 150px; position: relative; }
.strip .footer-only img { width: 100%; position: absolute; left: 0; bottom: 0; }
.strip .maps { padding: 0; }
.strip .maps img { width: 100%; aspect-ratio: 3 / 2.8; object-fit: cover; object-position: top; }  /* the field alone: everything above the panels-end line (281 of 400 mm) */
.truth { display: flex; align-items: center; gap: 12px; padding: 8px var(--gutter-phone); font-size: 13.5px; color: var(--ink-2); border-top: 1px solid var(--hairline); }
.truth .t { flex: 1 1 auto; min-width: 0; }
.truth a { white-space: nowrap; }
.strip.collapsed .truth { border-top: 0; }
/* the phone's product cards (M5) */
.pcards.stack { grid-template-columns: 1fr; }
.pcard.row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.pcard.row > span:first-child { flex: 1 1 auto; min-width: 0; }
.pcard.row b, .pcard.row small { display: inline; }
.pcard.row b { margin-right: 6px; }
.pcard.row .p { margin: 0; flex: none; }

/* ============================== the order page ============================== */
.phases { display: flex; border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; margin: 0 0 20px; }
.phases span { flex: 1 1 0; display: flex; align-items: center; justify-content: center; text-align: center; padding: 10px 8px; font-size: 14px; color: var(--soft); border-left: 1px solid var(--rule); }
.phases span:first-child { border-left: 0; }
.phases span.done { color: var(--ink-2); }
.phases span.on { background: var(--ink); color: #fff; font-weight: 600; }
.order { display: grid; grid-template-columns: 1fr; gap: 28px; align-items: start; }
.order > * { min-width: 0; }
@media (min-width: 960px) { .order { grid-template-columns: minmax(320px, 440px) 1fr; gap: 56px; } }
.order .art .poster { max-width: 440px; }
.status { font-size: 17px; margin: 0 0 6px; }
.todo { list-style: none; padding: 0; margin: 12px 0; }
.todo li { padding: 6px 0; color: var(--ink-2); }
.todo li.done { color: var(--ink); }
.history { font-size: 14px; color: var(--soft); margin-top: 18px; }

/* ============================== footers ============================== */
footer.site { border-top: 1px solid var(--hairline); padding: 36px 0 44px; margin-top: var(--section); font-size: 13.5px; color: var(--text-3); }
footer.site .cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; margin-bottom: 28px; }
footer.site .cols b { display: block; font: 600 11.5px/1.3 var(--font-ui); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); margin-bottom: 10px; }
footer.site .cols a { display: block; color: var(--text-3); text-decoration: none; padding: 5px 0; font-size: 14px; }
footer.site .cols a:hover { color: var(--ink); text-decoration: underline; }
footer.site .marks { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
footer.site .marks i { font: 600 9px/1 var(--font-ui); letter-spacing: 0.06em; color: var(--soft); border: 1px solid var(--rule); border-radius: 3px; padding: 5px 6px; font-style: normal; background: var(--surface); }
footer.site p { margin: 0 0 6px; line-height: 1.5; }
@media (max-width: 700px) { footer.site .cols { grid-template-columns: 1fr 1fr; } }
footer.legal { border-top: 1px solid var(--hairline); padding: 18px 0 28px; margin-top: 40px; font-size: 13px; color: var(--soft); }
footer.legal a { color: var(--soft); }
footer.legal p { margin: 6px 0 0; }
.site-lite { display: flex; gap: 6px 18px; flex-wrap: wrap; font-size: 13px; color: var(--soft); border-top: 1px solid var(--hairline); padding: 18px 0 28px; margin-top: 48px; }
.site-lite a { color: var(--soft); text-decoration: none; }

/* ====================================================================================================== */
/* ============================== RESET 2026-09-24 — the components the review asked for ============================== */
/* ====================================================================================================== */

/* ------------------------------ text roles (read these, not the colours) ------------------------------ */
.note, .hint, .cap, .facts, .crumb, .grouplabel, .micro, nav.site a, .rail a, .names, .tile small, .wall small, .pcard small,
.found small, .course .row small, .phases span, .history, footer.legal, .site-lite { color: var(--text-3); }
.micro { font-size: 13px; }
.hint { font-size: var(--small); line-height: 1.45; }
.prose, .measure, .lede { max-width: var(--measure); }
p.reading { max-width: var(--measure); }

/* ------------------------------ the product summary (.ident + .buy) ------------------------------ */
.ident .facts { margin-top: 6px; }
.formats { margin: 20px 0 0; border-top: 1px solid var(--rule-deco); }
.fmt { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 18px; align-items: baseline; padding: 11px 0; border-bottom: 1px solid var(--rule-deco); }
.fmt .fn { font-size: 15.5px; color: var(--text); }
.fmt .fn .tag { display: inline; font: 400 13px/1.3 var(--font-ui); color: var(--text-3); margin-left: 6px; white-space: nowrap; }   /* the combined pass (his notes 2026-09-29): "pictured" is information, not a control — plain secondary text in parentheses, no container */
.fmt .fn .tag::before { content: "("; } .fmt .fn .tag::after { content: ")"; }
.fmt .fp { font-weight: 600; font-size: 16px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.fmt.shown .fn { font-weight: 600; }
.fmt.shown .fp { font-size: var(--price-hero); font-weight: var(--price-weight); letter-spacing: -0.02em; line-height: 1; }
.buy .size { color: var(--text-3); font-size: var(--small); margin: 8px 0 0; }
.buy > .btn { margin: 18px 0 0; min-width: 260px; }
.buy .assure { margin: 12px 0 0; font-size: 15px; color: var(--text-2); max-width: 46ch; text-wrap: balance; }   /* the combined pass: two even lines, no stranded "approve." */
main p, main li, .hint, .note { text-wrap: pretty; }   /* the combined pass: running text avoids a one-word last line (Type C's wider setting) */
.buy .signs { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--rule-deco); }
.buy .sign { font-size: 15px; margin: 6px 0 0; }
@media (max-width: 599px) { .buy > .btn { display: flex; width: 100%; } }
/* variant B — the surface: on desktop one panel behind ident + buy (.offerbg spans both rows); on the phone the two parts
   carry it themselves — joined on a drawn page (art · ident · buy), separate on an undrawn page (ident · art · buy) */
[data-summary=surface] .hero .ident, [data-summary=surface] .hero .buy { background: var(--offer-bg); border: 1px solid var(--offer-border); padding: 22px 20px; }
[data-summary=surface] .hero:not(.undrawn) .ident { border-bottom: 0; border-radius: var(--radius-card) var(--radius-card) 0 0; padding-bottom: 0; }
[data-summary=surface] .hero:not(.undrawn) .buy { border-top: 0; border-radius: 0 0 var(--radius-card) var(--radius-card); }
[data-summary=surface] .hero:not(.undrawn) .ident + .buy, [data-summary=surface] .hero:not(.undrawn) .art + .ident + .buy { margin-top: -22px; }
[data-summary=surface] .hero.undrawn .ident, [data-summary=surface] .hero.undrawn .buy { border-radius: var(--radius-card); }
@media (max-width: 959px) { [data-summary=surface] .hero.undrawn .ident { background: transparent; border: 0; padding: 0; } }
[data-summary=surface] .hero .formats { border-top-color: var(--rule); }
@media (min-width: 960px) {
  [data-summary=surface] .hero .offerbg { display: block; grid-column: 2; grid-row: 1 / 3; align-self: stretch; z-index: 0; background: var(--offer-bg); border: 1px solid var(--offer-border); border-radius: var(--radius-card); }
  [data-summary=surface] .hero .ident, [data-summary=surface] .hero .buy { background: transparent; border: 0; border-radius: 0; margin: 0; padding: 26px 28px 0; }
  [data-summary=surface] .hero .buy { padding: 0 28px 24px; }
  [data-summary=surface] .hero .art { grid-row: 1 / 3; }
  [data-summary=surface] .hero.undrawn .ident, [data-summary=surface] .hero.undrawn .buy { border-radius: 0; }
}
[data-summary=surface] .hero { gap: 0 56px; }
[data-summary=surface] .hero h1 { font-size: clamp(32px, 3.6vw, 42px); }
[data-summary=surface] .hero > .art { margin-bottom: 22px; }
[data-summary=surface] .hero.undrawn > .art { margin: 0 0 22px; }
[data-summary=surface] .hero.undrawn > .ident { margin-bottom: 22px; }
@media (min-width: 960px) { [data-summary=surface] .hero > .art, [data-summary=surface] .hero.undrawn > .art, [data-summary=surface] .hero.undrawn > .ident { margin: 0; } }

/* ------------------------------ the DETAILED choice (a course, a format): label · detail · price ------------------------------ */
.options { display: grid; gap: 8px; margin: 6px 0 14px; max-width: 560px; }
.option { position: relative; display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 2px 12px; align-items: start; padding: 11px 14px; min-height: var(--target);
  border: 1px solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); cursor: pointer; color: var(--text); text-decoration: none; }
.option:hover { border-color: var(--control-border-hover); }
.option input { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 2px 0 0; padding: 0; border: 1.5px solid var(--control-border); border-radius: 50%; background: var(--control-bg); display: grid; place-items: center; cursor: pointer; }
.option input::after { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink); transform: scale(0); }
.option input:checked { border-color: var(--ink); }
.option input:checked::after { transform: scale(1); }
.option b { font-weight: 600; font-size: 15.5px; line-height: 1.35; }
.option small { grid-column: 2; display: block; color: var(--text-3); font-size: var(--small); line-height: 1.4; }
.option .p { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; line-height: 1.35; }
.option.on, .option:has(input:checked) { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.option.off { color: var(--text-disabled); cursor: not-allowed; border-style: dashed; border-color: var(--rule); }
.option.off input { border-color: var(--rule); }
.option.off small { color: var(--text-disabled); }

/* ------------------------------ field states: invalid · required · supplied ------------------------------ */
.field label .req { color: var(--text-3); font-weight: 400; }
.field.invalid input:not([type=checkbox]):not([type=radio]), .field.invalid select, .field.invalid textarea { border-color: var(--error); box-shadow: inset 0 0 0 1px var(--error); }   /* round 2 QA: the field's error styling never reaches a checkbox inside it */
.err { display: flex; gap: 8px; align-items: flex-start; font-size: var(--small); color: var(--error); margin: 6px 0 0; line-height: 1.45; max-width: var(--measure); }
.err::before { content: "!"; flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--error); color: #fff; font: 700 12px/18px var(--font-ui); text-align: center; margin-top: 1px; }
.err a { color: inherit; }
.fits { display: flex; gap: 6px; align-items: baseline; }
.field .with { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; }
.field .with > input { flex: 1 1 100%; width: auto; }   /* round 2: the field takes its row; the fit line and the checkbox share the row under it (the chip that once sat beside the field is gone) */
.field .with > .chip { flex: none; }
.field .with > .fits, .field .with > .err { flex: 1 1 auto; min-width: 0; order: 3; margin: 5px 0 0; }   /* round 2 (his review 2026-09-29): the fit line shares its row with the checkbox when short ("Fits ✓"); a correction that does not fit takes the row and the checkbox drops below it */
@media (max-width: 599px) { .field .with > .chip { order: 4; } }
.promise { border-left: 3px solid var(--ink); padding: 8px 14px; margin: 12px 0 14px; max-width: 560px; }
.promise b { display: block; font-weight: 600; }
.promise p, .promise .row { margin: 4px 0 0; font-size: 14.5px; color: var(--text-2); }
.recover { border-left: 3px solid var(--error); padding: 8px 14px; margin: 12px 0 14px; max-width: 560px; }
.recover b { display: block; font-weight: 600; }
.recover .row { margin-top: 6px; font-size: 14.5px; }
.busy { display: inline-flex; gap: 10px; align-items: center; font-size: 14.5px; color: var(--text-2); }
.busy::before { content: ""; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--rule); border-top-color: var(--ink); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .busy::before { animation: none; } }
.progress { height: 6px; background: var(--rule-deco); border-radius: 3px; overflow: hidden; max-width: 320px; margin: 8px 0; }
.progress i { display: block; height: 100%; background: var(--ink); width: var(--v, 40%); }
.legs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 110px), 1fr)); gap: 10px; align-items: start; max-width: 560px; }   /* start: an error under one leg must not drop the others */
.legs .field { margin: 0; }
.legs .field label { font-weight: 500; }
.legs .field label small { color: var(--text-3); font-weight: 400; }
/* the time field (review of session 1, correction 2): the digits typed become a time; a clear control inside the field, 44 px */
.field.time { position: relative; }
.field.time input { padding-right: 44px; font-variant-numeric: tabular-nums; }
.field.time .clear { position: absolute; right: 0; top: 24px; width: var(--target); height: var(--target); display: grid; place-items: center; background: none; border: 0; color: var(--text-3); font-size: 20px; line-height: 1; cursor: pointer; border-radius: var(--radius); }
.field.time .clear:hover { color: var(--text); }
.field.time.empty .clear { display: none; }
.legs + .hint, .total + .hint { margin-top: 6px; }
.total { max-width: 240px; }
div.done .btn { min-width: 260px; }
@media (max-width: 599px) { div.done .btn { display: flex; width: 100%; } }

/* ------------------------------ the live footer (an HTML mock of B2's composed footer, on the face's footer band) ------------------------------ */
/* The face's raster footer is covered by a paper-coloured band carrying the title, the line under it (NAME · Class · Date,
   the L3 ladder), and the times band, so a typed name, a fit failure and "no times" show in context. Sizes in cqw of the
   poster; the family is Inter (the poster's own grotesk is not loaded here). */
.poster .lf { position: absolute; left: 0; right: 0; bottom: 0; height: 33.5%; overflow: hidden; background: var(--paper-warm); color: var(--paper-ink); padding: 0 8%;
  display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; gap: 1.6cqw; font-family: "Inter", var(--font-ui); text-align: left; }
.poster .lf > * { min-width: 0; }
.poster.framed .lf { left: var(--frame-w); right: var(--frame-w); bottom: var(--frame-w); height: calc((100% - 2 * var(--frame-w)) * 0.335); }
.lf .t { font-weight: 800; font-size: 6.9cqw; line-height: 1.2; letter-spacing: -0.02em; text-transform: uppercase; white-space: nowrap; overflow: hidden; }   /* 1.2: a diaeresis on a capital (KÖLN) must not clip */
.lf .s { font-weight: 400; font-size: 2.5cqw; line-height: 1.2; color: #5F5750; white-space: nowrap; overflow: visible; }
.lf .s.over { color: var(--error); text-decoration: underline; text-decoration-color: var(--error); }
/* session 4 addendum (2026-09-29, ?look=): the mock's paper follows the poster's style — Warm's cream (the default), Engrave's and Plate's white, Night's dark */
.poster[data-style=engrave] .lf, .poster[data-style=plate] .lf { background: var(--paper-white); }
.poster[data-style=night] .lf { background: var(--paper-night); color: #F1EEE7; }
.poster[data-style=night] .lf .s { color: #B9B5AD; }
.poster[data-style=night] .lf .band .k { color: #A5A198; }
.poster[data-style=night] .lf .band .k.swim { color: #7FA6E6; } .poster[data-style=night] .lf .band .k.bike { color: #EC8E52; } .poster[data-style=night] .lf .band .k.run { color: #6DBA7C; }
.poster[data-style=night] .lf .band .p { color: #8F8B83; }
html[data-format=unframed] .order .swatches, html[data-format=digital] .order .swatches { display: none; }   /* no frame colour for an unframed or digital order */
html[data-look-style]:not([data-look-style=warm]) .order .onphoto { display: none; }   /* the photo band exists only in the Warm fixture */
.lf .band { display: grid; grid-template-columns: 1.25fr 1fr 1fr 1fr; gap: 0 3cqw; align-items: end; margin-top: 0.8cqw; }
.lf .band .k { display: block; font-weight: 700; font-size: 2.2cqw; letter-spacing: 0.06em; color: #6A6459; text-transform: uppercase; }
.lf .band .k.swim { color: #2456A8; } .lf .band .k.bike { color: #C8611D; } .lf .band .k.run { color: #2E7D3E; }
.lf .band .v { display: block; font-weight: 800; font-size: 5.2cqw; line-height: 1.05; letter-spacing: -0.02em; margin-top: 0.6cqw; font-variant-numeric: tabular-nums; }
.lf .band .d { display: block; font-weight: 700; font-size: 3.4cqw; line-height: 1.05; margin-top: 0.6cqw; }
.lf .band .p { display: block; font-weight: 500; font-size: 1.85cqw; color: #7A7266; margin-top: 0.8cqw; letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; }
.lf .band .d, .lf .band .k { white-space: nowrap; overflow: hidden; }
.lf .band .v.ph, .lf .band .p.ph, .lf .s .ph { color: #A39C90; }   /* YOUR TIME · YOUR NAME: the builder's placeholders, greyed (L1 · L10) */
.lf .band.notimes .v { display: none; }
.lf .band.notimes > span:first-child { display: none; }   /* no TOTAL label without a total */

/* the phone strip's readback: what the line under the title will print, and whether it fits (a PROPOSED behaviour) */
/* the readback (his proposal, review of session 1): the label "Subtitle" and the poster's verdict above, the line below in full —
   wrapping here is this box's business, "Fits" is the poster's */
.strip .readback { display: grid; grid-template-columns: 1fr; gap: 1px 0; padding: 5px var(--gutter-phone) 6px; font-size: 13.5px; color: var(--text-2); border-top: 1px solid var(--rule-deco); }
.strip .readback .k { color: var(--text-3); font-size: 12.5px; }
.strip .readback .k::after { content: " · "; }
.strip .readback .v { min-width: 0; overflow-wrap: anywhere; }
.strip .readback .ok { color: var(--trust); white-space: nowrap; font-size: 12.5px; }
.strip .readback .bad { color: var(--error); white-space: nowrap; font-size: 12.5px; }
.strip .readback .v .ph { color: var(--text-3); }
.strip .footer-only { height: auto; overflow: visible; }
.strip .footer-only .poster { max-width: 100%; }
.strip .footer-only .poster img { display: none; }
.strip .footer-only .poster .lf { position: static; height: auto; padding: 2.5cqw 6% 2.2cqw; }
.strip[data-fold] .truth { display: none; }   /* while typing, the style · price line folds — the footer and the readback stay (a proposed rule). The fold is set on focus and cleared at the next mode change or user scroll, NEVER on blur alone: unfolding on blur grows the strip under the finger that just tapped a control below it (found twice in the headless runs) */

/* ------------------------------ reading pages (support content) ------------------------------ */
body.reading { background: var(--ground-reading); }
.page-head { max-width: var(--measure); margin: 6px 0 26px; }
.page-head h1 { margin-bottom: 10px; }
.page-head .lede { margin: 0; }
.prose h2 { font-size: calc(var(--h2) - 2px); margin: 44px 0 10px; }
.prose h3 { margin: 26px 0 6px; }
.prose p { color: var(--text); }
.prose ul, .prose ol { padding-left: 1.25em; margin: 0 0 12px; }
.prose li { margin: 0 0 6px; }
.prose .hint { max-width: var(--measure); }
.stages, .prose ol.stages { list-style: none; margin: 16px 0 0; padding: 0; max-width: var(--measure); }
.stages li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 2px 14px; padding: 14px 0; border-top: 1px solid var(--rule-deco); position: relative; }
.stages li::before { content: ""; width: 10px; height: 10px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--ink); background: var(--ground-reading); margin-top: 6px; position: relative; z-index: 1; }
.stages { position: relative; }
.stages::before { content: ""; position: absolute; left: 4.5px; top: 22px; bottom: 22px; width: 1px; background: var(--rule); z-index: 1; }   /* the timeline: one line OVER the row rules, under the dots */
.stages li::before { z-index: 2; }
.stages li:last-child::after { content: ""; position: absolute; left: 0; width: 10px; top: 26px; bottom: 0; background: var(--ground-reading); z-index: 1; }   /* the line ends at the last dot */
html[data-reading=ground] .stages li:last-child::after { background: var(--ground); }
.stages b { display: block; font-weight: 600; font-size: 16px; }
.stages .d { display: block; color: var(--text-2); font-size: 15px; margin-top: 2px; grid-column: 2; }
.stages .n { display: block; color: var(--text-3); font-size: var(--small); margin-top: 4px; grid-column: 2; line-height: 1.45; }
.stages .who { display: inline-block; font: 500 12.5px/1.3 var(--font-ui); color: var(--text-3); border: 1px solid var(--rule); border-radius: 999px; padding: 1px 8px; margin-left: 8px; vertical-align: 1px; }
.aside { border-left: 3px solid var(--rule); padding: 8px 16px; margin: 20px 0; max-width: var(--measure); color: var(--text-2); font-size: 15px; }
.aside b { color: var(--text); }
.related { margin: 40px 0 0; padding-top: 16px; border-top: 1px solid var(--rule-deco); font-size: 15px; display: flex; gap: 8px 24px; flex-wrap: wrap; max-width: var(--measure); }
.related b { flex-basis: 100%; font-weight: 600; }
table.plain caption { text-align: left; font-weight: 600; padding: 0 0 8px; caption-side: top; }
table.plain td.num, table.plain td.n { font-variant-numeric: tabular-nums; white-space: nowrap; }
table.plain th { white-space: nowrap; }
table.plain th { color: var(--text-3); font-weight: 500; font-size: var(--small); padding-top: 0; }
.tablewrap { overflow-x: auto; }
@media (max-width: 599px) {
  table.stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.stack, table.stack tbody, table.stack tr, table.stack td { display: block; }
  table.stack tr { padding: 12px 0; border-top: 1px solid var(--rule-deco); }
  table.stack td { border: 0; padding: 3px 0; display: grid; grid-template-columns: 8.5em minmax(0, 1fr); gap: 12px; white-space: normal; }
  table.stack td > .v { min-width: 0; overflow-wrap: anywhere; }
  table.stack td > .v mark.x { white-space: normal; }   /* CORRECTION 2026-09-25 (3): a parked sentence in a stacked cell wraps — the table never scrolls sideways */
  table.stack td::before { content: attr(data-th); color: var(--text-3); font-size: var(--small); line-height: 1.5; }
  table.stack td:first-child { display: block; font-weight: 600; padding-bottom: 4px; }
  table.stack td:first-child::before { display: none; }
  table.stack td[colspan] { display: block; }
  table.stack td[colspan]::before { display: none; }
  table.stack thead + tbody > tr:first-child > td { border-top: 0; }   /* one rule per destination (the plain table's first-row rule would double it) */
  table.stack thead + tbody > tr:first-child { border-top: 0; }
}

/* ------------------------------ the controls sheet's scaffolding (states side by side) ------------------------------ */
.states { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 22px 28px; margin: 12px 0 8px; align-items: start; }
.states > div { min-width: 0; }
.states .lab { font: 500 12.5px/1.3 var(--font-ui); letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); margin: 0 0 8px; }
.sheet-note { max-width: var(--measure); color: var(--text-2); font-size: 15px; }

/* ====================================================================================================== */
/* ============================== RESET 2026-09-24 · SESSION 2 — the builder's remaining groups, the cart, the order page's phases, the strip's four modes ============================== */
/* ====================================================================================================== */

/* ------------------------------ the placed photo (W2c frame 2 · M4 placed): a thumb · the file with its size check · the actions UNDER it ------------------------------ */
.photo { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 2px 16px; align-items: start; margin: 4px 0 16px; max-width: 560px; }
.photo .th { grid-row: 1 / 4; width: 96px; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius); box-shadow: 0 0 0 1px var(--sheet-edge); }
.photo .fn { font-weight: 600; font-size: 15.5px; overflow-wrap: anywhere; line-height: 1.35; }
.photo .fn .ok { margin-left: 4px; }
.photo .st { font-size: 14.5px; color: var(--text-2); line-height: 1.4; }
.photo .st .ok { font-weight: 600; }
.photo .acts { grid-column: 2; display: flex; gap: 4px 16px; flex-wrap: wrap; font-size: 14.5px; margin-top: 2px; }
.photo .acts a, .photo .acts .link-btn { display: inline-flex; align-items: center; min-height: 32px; padding: 6px 0; margin: -6px 0; }   /* a 32 px target around each word */
@media (max-width: 599px) { .photo { grid-template-columns: 72px minmax(0, 1fr); gap: 2px 14px; } .photo .th { width: 72px; } }
/* the upload in flight, and a problem the buyer can recover from */
.upload { max-width: 560px; margin: 4px 0 16px; }
.upload .busy { font-weight: 500; color: var(--text); }
.upload .progress { max-width: none; margin: 10px 0 8px; }
.upload .row { font-size: 14.5px; }
.recover p { margin: 4px 0 0; font-size: 14.5px; color: var(--text-2); }

/* ------------------------------ the crop editor ("Edit photo"): a clear boundary, confirm and return, 44 px tools, a keyboard path ------------------------------ */
.cropper-back { position: fixed; inset: 0; z-index: 59; background: rgba(0, 0, 0, .45); }
.cropper { position: fixed; inset: 0; z-index: 60; background: var(--ground); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
@media (min-width: 700px) {
  .cropper { inset: auto; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(760px, calc(100vw - 48px)); height: min(640px, calc(100vh - 48px)); border-radius: var(--radius-card); box-shadow: var(--shadow-menu); border: 1px solid var(--hairline); overflow: hidden; }
}
.cropper .head { display: flex; align-items: center; gap: 12px; padding: 10px var(--gutter-phone); border-bottom: 1px solid var(--hairline); background: var(--strip-bg); }
.cropper .head h2 { font: 600 17px/1.3 var(--font-ui); letter-spacing: 0; margin: 0; flex: 1 1 auto; min-width: 0; }
.cropper .head .hint { flex-basis: 100%; margin: 0; }
.cropper .work { position: relative; overflow: hidden; background: #26262A; touch-action: none; cursor: grab; }
.cropper .work:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -3px; }
.cropper .work img { position: absolute; left: 50%; top: 50%; width: var(--iw); max-width: none; transform: translate(-50%, -50%) translate(var(--dx, 0px), var(--dy, 0px)) scale(var(--z, 1)); user-select: none; -webkit-user-drag: none; pointer-events: none; }
.cropper .frame { position: absolute; left: 50%; top: 50%; width: var(--cw); height: var(--ch); transform: translate(-50%, -50%); box-shadow: 0 0 0 9999px rgba(0, 0, 0, .58); outline: 2px solid #fff; outline-offset: -2px; pointer-events: none; }
.cropper .frame::before, .cropper .frame::after { content: ""; position: absolute; pointer-events: none; }   /* thirds, a light guide */
.cropper .frame::before { inset: 33.33% 0; border-top: 1px solid rgba(255, 255, 255, .35); border-bottom: 1px solid rgba(255, 255, 255, .35); }
.cropper .frame::after { inset: 0 33.33%; border-left: 1px solid rgba(255, 255, 255, .35); border-right: 1px solid rgba(255, 255, 255, .35); }
.cropper .frame i { position: absolute; left: 0; right: 0; top: -22px; text-align: left; font: 500 12px/1 var(--font-ui); color: rgba(255, 255, 255, .85); font-style: normal; letter-spacing: .04em; }
.cropper .tools { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; padding: 10px var(--gutter-phone) calc(10px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--hairline); background: var(--strip-bg); }
.cropper .zoom { display: inline-flex; align-items: center; gap: 4px; }
.cropper .zbtn { width: var(--target); height: var(--target); display: grid; place-items: center; border: 1px solid var(--control-border); border-radius: 50%; background: var(--control-bg); color: var(--text); font: 500 22px/1 var(--font-ui); cursor: pointer; padding: 0; }
.cropper .zbtn:hover { border-color: var(--control-border-hover); }
.cropper input[type=range] { width: 110px; height: 28px; accent-color: var(--ink); margin: 0 4px; }   /* the slider is the secondary zoom control (the 44 px buttons are the primary); 28 px tall so its thumb is not the only target */
.cropper .sp { flex: 1 1 auto; }
.cropper .tools .btn { min-height: var(--target); }
.cropper .tools .link-btn { min-height: var(--target); padding: 0 6px; }
@media (max-width: 599px) { .cropper .tools .actions { flex: 1 1 100%; display: flex; gap: 10px; margin: 0; } .cropper .tools .actions .btn { flex: 1 1 0; } }

/* ------------------------------ the undrawn and own-race builders: the stand-in preview (W3 · W4) ------------------------------ */
.poster .mock { position: absolute; inset: 0; background: var(--paper-warm); }
.poster.framed .mock { inset: var(--frame-w); }
.poster .mock .mockpanel { font: 500 2.6cqw/1.3 var(--font-ui); color: rgba(0, 0, 0, .5); border-color: rgba(0, 0, 0, .28); }
.look .example { margin-top: 18px; }
.look .example .grouplabel { margin-top: 0; }
.look .example .rail { align-items: flex-start; }
.look .example .cap { margin-top: 6px; }
.look .rail .poster { width: 64px; }
/* a required input that blocks Done (the own race's route recording), distinct from an informational line (.course) */
.reqblock { border: 1px solid var(--control-border); border-radius: var(--radius); padding: 14px 16px; margin: 6px 0 16px; max-width: 560px; background: var(--control-bg); }
.reqblock .lab { display: block; font-size: 14.5px; font-weight: 500; margin: 0 0 4px; }
.reqblock .lab .req { color: var(--text-3); font-weight: 400; }
.reqblock p { margin: 0 0 10px; font-size: 14.5px; color: var(--text-2); }
.reqblock .actions { margin: 0; gap: 8px 12px; }
.reqblock .actions small { flex-basis: 100%; color: var(--text-3); font-size: 13.5px; }
.reqblock.invalid { border-color: var(--error); box-shadow: inset 0 0 0 1px var(--error); }
.reqblock .got { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; font-weight: 600; }
.reqblock .got .ok { font-weight: 700; }
.reqblock .got a { font-weight: 400; font-size: 14.5px; }
.btn[aria-disabled=true], .btn:disabled { background: var(--surface-2); color: var(--text-disabled); border-color: var(--rule); cursor: not-allowed; }
.done .why { display: block; font-size: 13.5px; color: var(--text-3); margin-top: 8px; }

/* ------------------------------ the gift (W5 · M6): the arrival line, a date, a dated verdict, one parcel line ------------------------------ */
.arrive { display: flex; gap: 10px; align-items: baseline; font-weight: 600; font-size: 16px; margin: 0 0 20px; padding: 4px 14px; border-left: 3px solid var(--ink); }
.field.date { max-width: 260px; }
.verdict { max-width: 560px; margin: 0 0 14px; font-size: 15.5px; line-height: 1.5; }
.verdict b { font-weight: 600; }
.verdict.tight, .verdict.late { border-left: 3px solid var(--ink); padding: 8px 14px; }
.verdict .row { margin-top: 6px; font-size: 14.5px; }
mark.x { background: var(--mark-bg); color: inherit; padding: 0 2px; border-radius: 2px; white-space: nowrap; }
.fixture { font-size: 12.5px; color: var(--text-3); }

/* the page to show on the day (view only): the poster, three lines, nothing to operate */
body.giftpage main { padding-top: 40px; }
.giftpage .show { max-width: 520px; margin: 0 auto; text-align: center; }
.giftpage .show .kicker { margin-bottom: 10px; }
.giftpage .show h1 { font-size: clamp(26px, 3.4vw, 36px); margin: 0 0 24px; text-wrap: balance; }
.giftpage .show .poster { max-width: 340px; margin: 0 auto; }
.giftpage .show .way { margin: 26px 0 0; font-size: 16px; color: var(--text-2); }   /* not .line — that is the cart's */

/* ------------------------------ Review your order (W6 · M7): the collapsed groups ARE the summary; under them Style · Frame colour · Format · Price ------------------------------ */
.rev { margin-top: 4px; }
.rev .sum .sh::before { content: none; }
.rev .sum.price .ss { font-weight: 600; font-size: 17px; }
.rev .sum .ss.ro { color: var(--text); }
.review-copy { margin: 20px 0 0; max-width: 560px; }
.review-copy .promise { margin-top: 0; }
.review-copy p { margin: 0 0 8px; }
.commit { display: flex; gap: 12px 20px; align-items: center; flex-wrap: wrap; margin: 20px 0 0; }
.commit .btn { min-width: 260px; }
@media (max-width: 599px) { .commit { flex-direction: column; align-items: stretch; } .commit .btn { display: flex; width: 100%; } .commit a:not(.btn) { text-align: center; padding: 8px 0; } }

/* ------------------------------ the cart (W7 · M8): lines with Edit · Remove UNDER the description, totals, the market's legal layer ------------------------------ */
.checkout { max-width: 720px; }
.topline { font-size: 14.5px; color: var(--text-3); padding: 10px 0 12px; border-bottom: 1px solid var(--rule-deco); margin: 0 0 24px; line-height: 1.5; }
.checkout h2 { font-size: 21px; margin: 32px 0 8px; }
.checkout h2:first-of-type { margin-top: 0; }
.line { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: 2px 16px; padding: 16px 0; border-top: 1px solid var(--rule-deco); align-items: start; }
.line .poster { width: 64px; grid-row: 1 / 4; }
.line b { font-weight: 600; font-size: 15.5px; line-height: 1.35; }
.line .desc { grid-column: 2; color: var(--text-2); font-size: 14.5px; line-height: 1.45; }
.line .pr { grid-column: 3; grid-row: 1; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.line .acts { grid-column: 2; display: flex; gap: 4px 16px; flex-wrap: wrap; font-size: 14.5px; margin-top: 4px; }
.line .acts a { display: inline-flex; align-items: center; min-height: 32px; padding: 6px 0; margin: -6px 0; }
.line .acts:has(.q) { align-items: center; }
.line .acts .q { color: var(--text); flex-basis: 100%; }   /* "Remove this poster?" asked in place (10h, his look): on its own line, Remove · Keep under it */
.addline { display: inline-flex; align-items: center; min-height: var(--target); padding: 8px 0; font-size: 15px; margin: 4px 0 0; }
.started-line { margin: 14px 0 0; font-size: 15px; color: var(--text-2); } .started-line b { color: var(--text); font-weight: 600; } .started-line a { white-space: nowrap; }   /* a started poster named at the checkout (8a) */
.totals { border-top: 1px solid var(--rule); padding-top: 10px; margin-top: 4px; }
.totals .kv { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 24px; margin: 0; }
.totals .kv > span:nth-child(odd) { color: var(--text-2); font-size: 15px; }
.totals .kv > span:nth-child(even) { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.totals .kv .tot { font-weight: 600; font-size: 17px; color: var(--text); }
.totals .kv .tot + span { font-weight: 600; font-size: 17px; }
.checkout .field { max-width: 560px; }
.element { border: 1px solid var(--control-border); border-radius: var(--radius); padding: 14px; background: var(--control-bg); max-width: 560px; }
.element .tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.element .tabs > span { border: 1px solid var(--control-border); border-radius: var(--radius); padding: 8px 12px; font-size: 14px; min-height: 40px; display: inline-flex; align-items: center; }
.element .tabs > span.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.element .fake { height: var(--target); border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface-2); margin-top: 8px; }
.element .note { margin: 10px 0 0; font-size: 13.5px; }
.legalnote { font-size: 14.5px; line-height: 1.5; color: var(--text); margin: 20px 0 0; padding: 14px 16px; border: 1px solid var(--rule); border-radius: var(--radius); max-width: 560px; }
.legalnote p { margin: 0 0 10px; }
.legalnote .check { margin: 0; }
.giftline { margin: 16px 0 0; font-size: 15px; max-width: 560px; }
.binding { border: 1px solid var(--control-border); border-radius: var(--radius); padding: 14px 16px; margin: 16px 0 0; max-width: 560px; background: var(--control-bg); }
.binding h3 { margin: 0 0 8px; font-size: 16px; }
.binding .kv { margin: 0; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 16px; }
.binding .kv > span:nth-child(odd) { color: var(--text); font-size: 15px; line-height: 1.4; }
.binding .kv > span:nth-child(even) { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.binding .kv .tot, .binding .kv .tot + span { font-weight: 600; }
.binding .lead { margin: 10px 0 0; font-size: 14.5px; color: var(--text-2); }
.binding ~ .btn { display: flex; width: 100%; max-width: 560px; margin-top: 12px; }   /* NOTHING between the order information and the button (§ 312j Abs. 2 + 3); the button spans the block */
.gloss { font-size: 14.5px; color: var(--text-2); margin: 10px 0 0; max-width: 60ch; line-height: 1.5; }

/* ------------------------------ the order page's phases (W11): who acts next is the sentence's subject, and the actions ------------------------------ */
.phases span.done::before { content: "✓ "; color: var(--trust); font-weight: 700; }
.phases span.on::before { content: none; }
.status { font-size: 19px; line-height: 1.4; margin: 0 0 8px; max-width: 44ch; }
.status b { font-weight: 600; white-space: nowrap; }   /* a date never splits */
.todo li { display: flex; gap: 10px; align-items: baseline; padding: 5px 0; color: var(--text-2); }
.todo li::before { content: "○"; flex: none; width: 1.1em; color: var(--text-3); }
.todo li.done { color: var(--text); }
.todo li.done::before { content: "✓"; color: var(--trust); font-weight: 700; }
.order .copy > p { max-width: 560px; }
.order .copy .actions { margin-top: 0; }
.order .copy .actions + .hint { margin-top: 12px; }
.dl { margin: 14px 0 18px; }
.dl .hint { margin-top: 8px; }

/* ------------------------------ the phone strip's FOUR modes (§4 Mobile · W8): maps · footer-only · full · collapsed ------------------------------ */
.strip[data-mode] .view > * { display: none; }
.strip[data-mode=maps] .view > .maps, .strip[data-mode=footer] .view > .footer-only, .strip[data-mode=full] .view > .full { display: block; }
.strip[data-mode] .readback { display: none; }
.strip[data-mode=footer] .readback { display: grid; }
.strip .view { overflow: hidden; }
body:has(.strip[data-mode]) { overflow-anchor: none; }   /* the strip's own scroll compensation is the only one (Chrome's scroll anchoring would add the delta a second time; Safari has none) */
.strip .view.anim { transition: height .22s ease; }
@media (prefers-reduced-motion: reduce) { .strip .view.anim { transition: none; } }
/* maps: the field alone above the panels-end line (24–276 × 22–281 mm), no frame, no footer; capped so the strip stays under ~45 % of a short phone */
.strip .maps { display: grid; place-items: center; padding: 8px var(--gutter-phone) 6px; }
/* the field alone: the sheet's 24–276 × 22–281 mm window (84 % of the width from 5.5 % down), clipped — no margins, no title, no footer */
.strip .maps .field { width: min(320px, 33vh, 100%); aspect-ratio: 252 / 259; overflow: hidden; box-shadow: 0 0 0 1px var(--sheet-edge); }
.strip .maps .field img { display: block; width: 119.05%; max-width: none; aspect-ratio: 3 / 4; margin: -8.73% 0 0 -9.52%; }
/* full: the framed poster at a fixed height (≈ 270 px, W8 note 10), its width from the frame's proportion */
.strip .full { display: grid; place-items: center; padding: 8px var(--gutter-phone) 6px; }
.strip .full .poster { width: calc(min(270px, 34vh) / 1.297); max-width: 100%; }
.strip[data-mode=collapsed] .truth { border-top: 0; }
.strip .truth a { min-height: 28px; display: inline-flex; align-items: center; padding: 3px 0; margin: -3px 0; }
/* the readback's two variants for the height decision (session 2): always = at rest and while typing any field;
   subtitle = hidden while a TIME field has focus (the band is the feedback then) */
/* (the readback's hiding while a time or the title is edited moved to the controller: .strip[data-hidereadback] below) */
/* the journey page: an open group shows its body; a done group its summary row; a group not yet reached its heading alone */
.groups .group[data-mode] .sum { display: none; }
.groups .group[data-mode].done .sum { display: grid; }
.groups .group[data-mode].done .ghead, .groups .group[data-mode].done .body { display: none; }
.groups .group[data-mode].next .body, .groups .group[data-mode].off .body { display: none; }
.strip .segbar .segs i[data-go] { height: 3px; box-sizing: content-box; padding: 10px 0; background-clip: content-box; cursor: pointer; }   /* a 23 px hit area under a 3 px mark (the shorthand above would reset the clip at lower specificity) */
@media (max-width: 599px) { .hide-phone { display: none; } }

/* ====================================================================================================== */
/* ============================== SESSION 2 — THE CORRECTION PASS (his review + the iPhone 13 mini test, 2026-09-24) ============================== */
/* ====================================================================================================== */
/* the buyer's photo drawn ON the poster with its confirmed crop: an overlay in the band's photo space — a FIXTURE rect measured
   from the Blenheim band face (7.8 % from the left, 56.1 % down, 25 × 13.9 % of the sheet; a 1.35 : 1 space). B2's manifest supplies the real rect. */
.poster .pov { position: absolute; overflow: hidden; left: 7.8cqw; top: 74.8cqw; width: 25cqw; height: 18.53cqw; background: #8A8680; display: none; }   /* .pov, NOT .ph — .ph is the footer's placeholder span (the re-review's A) */
.poster.framed .pov { left: 12.44cqw; top: 72.07cqw; width: 22.25cqw; height: 16.5cqw; }
.poster .pov img { position: absolute; left: 50%; top: 50%; width: var(--iw, 100%); max-width: none; aspect-ratio: auto; height: auto; transform: translate(-50%, -50%) translate(var(--dx, 0px), var(--dy, 0px)) rotate(var(--rot, 0deg)) scale(var(--z, 1)); }
[data-photo=placed] .poster .pov, [data-state=placed] .poster .pov, [data-state=crop] .poster .pov { display: block; }
/* the gift as a quiet checkbox in the builder's introductory area (founder 2026-09-24): it applies to the whole purchase */
.gifttop { display: inline-flex; gap: 10px; align-items: center; font-size: 15px; margin: 0 0 16px; min-height: var(--target); cursor: pointer; }
.gifttop input { width: 18px; height: 18px; margin: 0; accent-color: var(--ink); }
/* the segment bar's segments are real buttons: focusable, activable, the current one exposed */
.strip .segbar .segs .seg { display: block; height: 3px; padding: 10px 0; box-sizing: content-box; border: 0; background: var(--hairline); background-clip: content-box; border-radius: 2px; cursor: pointer; min-width: 0; }
.strip .segbar .segs .seg.on, .strip .segbar .segs .seg[aria-current] { background-color: var(--ink); }
.strip .segbar .segs .seg.done { background-color: var(--rule); }
.strip .segbar .segs .seg:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 0; }
/* the strip pinned to the VISUAL viewport while the keyboard is up: iOS pans the visual viewport, a sticky element sticks to the layout one */
.strip { top: var(--vv-top, 0px); }
.strip[data-kbd] .segbar { display: none; }   /* while typing, navigation folds with the truth bar — the field and its preview get the space */
.strip[data-hidereadback] .readback { display: none; }   /* while a TIME or the TITLE is edited the subtitle is not the feedback (founder 2026-09-24) */
/* a preview that did not load: say so, and offer the retry */
.poster .imgfail { position: absolute; inset: var(--frame-w); display: grid; place-items: center; text-align: center; padding: 10%; background: var(--surface-2); color: var(--text-2); font-size: clamp(11px, 3.6cqw, 14px); line-height: 1.45; }
.poster.unframed .imgfail { inset: 0; }
.poster .imgfail b { display: block; color: var(--text); font-weight: 600; margin-bottom: 4px; }
.poster .imgfail a { color: var(--text); }
/* the crop editor's rotate control (W2c: pan, pinch, rotate, Confirm — built, founder 2026-09-24) */
.cropper .rot { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; color: var(--text-2); }
.cropper .rot input[type=range] { width: 100px; }
.cropper .rot .v { min-width: 3.4em; font-variant-numeric: tabular-nums; text-align: right; }
@media (max-width: 599px) { .cropper .rot { flex: 1 1 100%; justify-content: space-between; } .cropper .rot input[type=range] { flex: 1 1 auto; } }

/* ====================================================================================================== */
/* ============================== RESET 2026-09-24 · SESSION 3 — the whole shop: support pages, Gifts, navigation and utility states, the finder's exits ============================== */
/* ====================================================================================================== */

/* ------------------------------ the phone navigation drawer (S12 callout 7): the five words large, a secondary row, one action ------------------------------ */
/* _nav.js builds it from the header's nav and wires the toggle. html[data-nav=open] shows it; the page behind is inert. */
.drawer { position: fixed; inset: 0; z-index: 50; background: var(--ground); display: none; flex-direction: column; overflow: auto; }
html[data-nav=open] .drawer { display: flex; }
html[data-nav=open] { overflow: hidden; }
/* its head mirrors the header (10h, his pick 1 A): ✕ where ☰ is — the same tap closes it — the wordmark centred, the cart */
.drawer .dhead { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 6px var(--gutter-phone); border-bottom: 1px solid var(--hairline); }
.drawer .dhead .cart { justify-self: end; margin: 0 -3px 0 0; }
.drawer .close { justify-self: start; margin-left: -10px; width: var(--target); height: var(--target); display: inline-grid; place-items: center; border: 0; background: none; color: var(--ink); font-size: 22px; cursor: pointer; padding: 0; }
.drawer .dmain { padding: 18px var(--gutter-phone) 28px; display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
.drawer .dmain > a:not(.btn) { display: flex; align-items: center; min-height: 52px; font: 600 24px/1.2 var(--font-display); letter-spacing: -0.015em; color: var(--ink); text-decoration: none; padding: 8px 0; border-bottom: 1px solid var(--rule-deco); }
.drawer .dmain > a:not(.btn)[aria-current=page] { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; }
/* the smaller row in two even columns (10h: with How it works and Pricing in it a wrapping row left one word alone; room for
   German's longer words and About to come) */
.drawer .dsec { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; margin: 18px 0 0; }
.drawer .dsec a { display: inline-flex; align-items: center; min-height: var(--target); font-size: 15.5px; color: var(--text-3); text-decoration: none; padding: 6px 0; }
.drawer .dsec a:hover { color: var(--ink); text-decoration: underline; }
.drawer .dsec a[aria-current=page] { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
.drawer .dmain .btn { margin-top: auto; align-self: stretch; display: flex; }
@media (min-width: 731px) { .drawer { display: none !important; } }
/* the states sheet shows the drawer inside a phone-width frame: .compact forces the phone chrome whatever the viewport */
.phoneframe { width: 390px; max-width: calc(100% - 32px); margin: 0 auto; border: 1px solid var(--rule); border-radius: 14px; overflow: hidden; background: var(--ground); position: relative; }
.phoneframe header.site .wrap { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0; padding: 6px var(--gutter-phone); }
.phoneframe header.site nav.site { display: none; }
.phoneframe header.site .hl { display: flex; align-items: center; justify-self: start; margin-left: -10px; }
.phoneframe header.site .cart { justify-self: end; margin: 0 -3px 0 0; }
.phoneframe .drawer { position: absolute; display: flex !important; }
.phoneframe:has(.drawer) { min-height: 720px; }

/* ------------------------------ the market's lines in the footer (S12 callouts 6 · 14) and the slim legal footer (W11 note 9): DE default, GB the twin ------------------------------ */
.mk-de, .mk-gb { display: none; }
html[data-market=de] .mk-de, html:not([data-market]) .mk-de, html[data-market=gb] .mk-gb { display: block; }
html[data-market=de] span.mk-de, html:not([data-market]) span.mk-de, html[data-market=gb] span.mk-gb, html[data-market=de] a.mk-de, html:not([data-market]) a.mk-de, html[data-market=gb] a.mk-gb { display: inline; }
footer.site .cols a.mk-gb, footer.site .cols a.mk-de { display: none; }
html[data-market=gb] footer.site .cols a.mk-gb, html[data-market=de] footer.site .cols a.mk-de, html:not([data-market]) footer.site .cols a.mk-de { display: block; }
footer.legal .links > span { display: none; gap: 2px 16px; flex-wrap: wrap; align-items: center; }
html[data-market=de] footer.legal .links > span.mk-de, html:not([data-market]) footer.legal .links > span.mk-de, html[data-market=gb] footer.legal .links > span.mk-gb { display: flex; }
footer.legal .links a { min-height: 32px; display: inline-flex; align-items: center; padding: 4px 0; white-space: nowrap; }
footer.legal .links i { display: none; }   /* the separators are the gap */
footer.legal p { max-width: var(--measure); }

/* ------------------------------ the support pages (S6 · S8 · S4 · Contact) on the reading system ------------------------------ */
html[data-reading=ground] body.reading { background: var(--ground); }   /* the comparison: one ground everywhere (the open choice, README §9) */
html[data-reading=ground] .stages li::before { background: var(--ground); }
/* the market switch on Cancellation & refunds: a short single choice — real radios, the chip role; the page's content follows */
.mswitch { margin: 4px 0 18px; }
.mswitch .chips { margin: 0; }
.mswitch + h2, .mswitch + .prose > h2:first-child { margin-top: 36px; }
.mk-de-only, .mk-gb-only { display: none; }
html[data-market=de] .mk-de-only, html:not([data-market]) .mk-de-only, html[data-market=gb] .mk-gb-only { display: block; }
/* a labelled sub-answer inside a section (S6 callout 8: "Changes" under "Before you approve") */
.sub { margin: 14px 0 0; padding-left: 16px; border-left: 2px solid var(--rule); max-width: var(--measure); }
.sub b { display: block; font-weight: 600; font-size: 15px; margin-bottom: 2px; }
.sub p { margin: 0 0 8px; font-size: 15px; color: var(--text-2); }
/* the longer German disclosure: a disclosure block, closed by default, its summary the control */
details.disclosure { border: 1px solid var(--control-border); border-radius: var(--radius); margin: 18px 0; max-width: var(--measure); background: var(--control-bg); }
details.disclosure summary { cursor: pointer; list-style: none; padding: 12px 16px; font-weight: 600; font-size: 15.5px; display: flex; justify-content: space-between; gap: 16px; align-items: center; min-height: var(--target); }
details.disclosure summary::-webkit-details-marker { display: none; }
details.disclosure summary::after { content: "▾"; font-size: 19px; line-height: 0.8; color: var(--text-3); flex: none; }
details.disclosure[open] summary::after { content: "▴"; }
details.disclosure[open] summary { border-bottom: 1px solid var(--rule-deco); }
details.disclosure .body { padding: 12px 16px 6px; font-size: 15px; color: var(--text-2); }
details.disclosure .body p { color: var(--text-2); }
details.disclosure .body h3 { font-size: 15.5px; margin: 14px 0 4px; }
details.disclosure .body ul { padding-left: 1.2em; }
/* the legal position, in full (S6 callout 6): the same text role as the body, its heading smaller — the law is read, not skimmed */
.legal-full p { font-size: 15px; color: var(--text-2); }
.legal-full { margin-bottom: 28px; }
.closing { margin-top: 28px; }
/* the FAQ's topic navigation (S8 callout 1): five chips that jump — links, the chip's boundary, wrapping */
.topics { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 8px; }
.topics a { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 16px; font: 500 15px/1.3 var(--font-ui); color: var(--chip-fg); border: 1px solid var(--control-border); border-radius: var(--radius-chip); text-decoration: none; }
.topics a:hover { border-color: var(--control-border-hover); }
.topics a[aria-current=true] { background: var(--chip-on-bg); color: var(--chip-on-fg); border-color: var(--chip-on-border); }
.faq h2 { scroll-margin-top: 28px; }
.faq summary::after { font-size: 22px; line-height: 1; color: var(--text-2); font-weight: 300; }
.prose .faq { border-top: 0; margin: 0; }
.prose .faq h2 { margin: 40px 0 6px; padding-bottom: 8px; border-bottom: 1px solid var(--rule); font-size: 21px; }
.faq details p, .faq details ul, .faq details .kv { max-width: var(--measure); }
.faq details ul { margin: 0 0 16px; padding-left: 1.2em; color: var(--text-2); font-size: 15px; }
.faq details li { margin: 0 0 4px; }
.faq details .kv { margin: 0 0 16px; font-size: 15px; }   /* the format comparison: a labelled list, never a table on the phone */
.faq details .kv > span:nth-child(odd) { color: var(--text); font-weight: 600; font-size: 15px; }
.faq details .kv > span:nth-child(even) { color: var(--text-2); }
@media (max-width: 599px) { .faq details .kv { grid-template-columns: 1fr; gap: 2px 0; } .faq details .kv > span:nth-child(even) { margin-bottom: 8px; } }
.faq details .also { font-size: 14.5px; margin: -8px 0 16px; }
/* a question this round has no fact to answer (S8 callout 4): the question stays closed, a flag names what is missing — not an answer, not an error */
.faq .waits summary { color: var(--text-2); cursor: default; }
.faq .waits summary::after { content: none; }
.faq .waits details { border-bottom: 0; }
.faq .waits { border-bottom: 1px solid var(--hairline); }
.faq .waits .flag { display: block; font-size: 13.5px; color: var(--text-3); margin: -6px 0 12px; max-width: var(--measure); }
.faq .waits .flag::before { content: "answer waits on: "; }
.faq summary { min-height: var(--target); align-items: center; }
/* Prints and frames (S4): the facts as a labelled list; the swatch row with the names printed; three photograph slots with captions */
.facts-kv { margin: 8px 0 4px; }
.facts-kv > span:nth-child(odd) { color: var(--text); font-weight: 600; font-size: 15px; }
.swrow { display: flex; gap: 12px 18px; flex-wrap: wrap; margin: 14px 0 6px; }
@media (max-width: 420px) { .swrow { display: grid; grid-template-columns: 1fr 1fr; } }
.swrow span { display: inline-flex; align-items: center; gap: 8px; font-size: 14.5px; color: var(--text-2); }
.swrow span::before { content: ""; width: 28px; height: 28px; border-radius: 50%; background: var(--sw); box-shadow: inset 0 0 0 1px rgba(0,0,0,.18); }
.swrow [data-frame=black] { --sw: var(--frame-black); } .swrow [data-frame=brown] { --sw: var(--frame-brown); } .swrow [data-frame=natural] { --sw: var(--frame-natural); } .swrow [data-frame=white] { --sw: var(--frame-white); }
.photos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin: 16px 0 0; align-items: start; }
.photos figure { margin: 0; min-width: 0; }
.photos .slot { aspect-ratio: 4 / 3; background: var(--surface-2); border: 1px dashed var(--control-border); border-radius: var(--radius-card); display: grid; place-items: center; text-align: center; padding: 16px; color: var(--text-2); font-size: 14px; line-height: 1.45; }
.photos .slot b { display: block; font: 600 11px/1.3 var(--font-ui); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); margin-bottom: 6px; white-space: nowrap; }
.photos figcaption { font-size: var(--small); color: var(--text-3); margin-top: 8px; line-height: 1.45; }
.photos figure:first-child .slot { aspect-ratio: 4 / 3; }
@media (max-width: 700px) { .photos { grid-template-columns: repeat(2, minmax(0, 1fr)); } .photos figure:first-child { grid-column: 1 / -1; } .photos .slot b { white-space: normal; } }   /* a half-width slot: the label wraps (Inter is wider than Instrument Sans — 1 px of overflow at 360 in A and C otherwise) */
/* Contact: the support treatment, one address, no form */
.contact-line { font-size: 22px; font-weight: 600; margin: 8px 0 12px; letter-spacing: -0.01em; }
.contact-line a { color: var(--ink); }

/* ------------------------------ the Gifts landing page (S9): the hero, the reassurance, the photo, a labelled search that hands over to the finder ------------------------------ */
.gift-hero { display: grid; grid-template-columns: 1fr; gap: 24px 56px; align-items: start; }
.gift-hero > * { min-width: 0; }
.gift-hero .art { order: 2; } .gift-hero .copy { order: 1; }
.gift-hero .art .poster { max-width: 420px; }
.gift-hero .pricelines { margin-top: 18px; font-size: 15.5px; }
.gift-hero .pricelines .size { color: var(--text-3); font-size: var(--small); margin: 4px 0 0; }
.gift-hero .copy .btn { margin-top: 18px; min-width: 260px; }
.gift-hero .copy .sign { margin-top: 14px; font-size: 15px; color: var(--text-2); max-width: 48ch; }
@media (max-width: 599px) { .gift-hero .copy .btn { display: flex; width: 100%; } }
@media (min-width: 960px) { .gift-hero { grid-template-columns: 1fr minmax(300px, 460px); } .gift-hero .art, .gift-hero .copy { order: 0; } }
.steps-inline { counter-reset: st; list-style: none; padding: 0; margin: 14px 0 0; max-width: var(--measure); display: grid; gap: 10px; }
.steps-inline li { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 12px; align-items: baseline; }
.steps-inline li::before { counter-increment: st; content: counter(st); font: 600 14px/1 var(--font-ui); color: var(--num); }
.steps-inline b { font-weight: 600; }
.steps-inline b { grid-column: 2; }
.steps-inline span { display: block; color: var(--text-2); font-size: 15px; grid-column: 2; }
.gsearch { margin: 8px 0 0; max-width: 640px; }
.gsearch .field { margin-bottom: 12px; }
.gsearch .actions { margin: 0; }
.gsearch .btn { min-width: 200px; }
@media (max-width: 599px) { .gsearch .actions { flex-direction: column; align-items: stretch; } .gsearch .btn { display: flex; width: 100%; } }
.tiles.six { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0 16px; }
.tiles.six .tile .from { margin-bottom: 0; }
@media (max-width: 959px) { .tiles.six { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* the phone's swipe row is a scrolling GRID (not a flex row), so the subgrid rows still align every tile's title and price */
@media (max-width: 599px) { .tiles.six { grid-auto-flow: column; grid-auto-columns: 150px; grid-template-columns: none; overflow-x: auto; scroll-snap-type: x mandatory; gap: 0 14px; padding-bottom: 8px; margin-left: calc(-1 * var(--gutter-phone)); margin-right: calc(-1 * var(--gutter-phone)); padding-left: var(--gutter-phone); padding-right: var(--gutter-phone); scroll-padding-left: var(--gutter-phone); } .tiles.six .tile { scroll-snap-align: start; } }
.feat .stage .poster { max-width: 300px; }

/* ------------------------------ the message/action layout (S12: the empty cart, the saved draft, /order/success, /order/cancelled, /404) — one shape, a small set of states ------------------------------ */
.msg { max-width: 560px; margin: 8px 0 0; }
.msg h1 { font-size: clamp(28px, 3.4vw, 36px); margin-bottom: 8px; }
.msg .status { font-size: 17px; color: var(--text); margin: 0 0 10px; }
.msg p { color: var(--text-2); }
.msg .actions { margin-top: 20px; }
.msg .actions .btn { min-width: 220px; }
.msg .steps { list-style: none; padding: 0; margin: 18px 0 0; counter-reset: st; display: grid; gap: 10px; }
.msg .steps li { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 0 12px; align-items: baseline; }
.msg .steps li::before { counter-increment: st; content: counter(st); font: 600 14px/1 var(--font-ui); color: var(--num); }
.msg .steps b { font-weight: 600; }
.msg .steps b { grid-column: 2; }
.msg .steps span { display: block; color: var(--text-2); font-size: 15px; grid-column: 2; }
.msg .code { font-size: 14.5px; color: var(--text-3); margin: 0 0 6px; }
@media (max-width: 599px) { .msg .actions { flex-direction: column; align-items: stretch; } .msg .actions .btn { display: flex; width: 100%; } .msg .actions a:not(.btn) { text-align: center; padding: 8px 0; } }
.msg.centre { margin: 40px auto 0; text-align: center; }
.msg.centre .actions { justify-content: center; }
/* the states sheet: each state in its own labelled frame; ?state=x isolates one */
.sheet .scene { border: 1px solid var(--rule); border-radius: var(--radius-card); overflow: hidden; margin: 12px 0 36px; background: var(--ground); }
.sheet .scene > .lab { font: 500 12.5px/1.3 var(--font-ui); letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); padding: 8px 14px; border-bottom: 1px solid var(--rule-deco); background: var(--surface); }
.sheet .scene main { padding: 24px 0 40px; }
.sheet .scene footer.legal { margin-top: 24px; }
.sheet .scene footer.site { margin-top: 32px; padding-bottom: 28px; }
html[data-state] .sheet .scene { border: 0; border-radius: 0; margin: 0; }
html[data-state] .sheet .scene > .lab, html[data-state] .sheet .page-head, html[data-state] .sheet > .intro { display: none; }
html[data-state] .sheet .scene main { padding: 32px 0 64px; }
html[data-state] body.reading { background: var(--ground); }
html[data-state] .sheet .scene { min-height: 100vh; display: flex; flex-direction: column; }
html[data-state] .sheet .scene main { flex: 1 1 auto; }

/* ------------------------------ the finder's three own-race treatments (W1 notes 5 · 6 · 11 · 12) and its phone bar ------------------------------ */
/* at rest: the quiet line under the search + the box at the end (the existing .own); ≤ 3 results: the exit joins the grid as a tile; none: the exit is the page */
.tile.exit { display: flex; flex-direction: column; justify-content: center; gap: 8px; grid-row: span 4; border: 1px solid var(--control-border); border-radius: var(--radius-card); padding: 18px 16px; background: var(--surface); min-height: 100%; }
.tile.exit b { margin: 0; font-size: 15.5px; }
.tile.exit p { margin: 0; color: var(--text-2); font-size: 14.5px; }
.tile.exit .btn { margin-top: 6px; align-self: flex-start; }
.tile.exit .btn.small { min-height: 40px; }
@media (max-width: 699px) { .tile.exit .btn { align-self: stretch; display: flex; } }
.noresult { border: 1px solid var(--control-border); border-radius: var(--radius-card); padding: 24px 22px; margin: 24px 0 0; max-width: 640px; background: var(--surface); }
.noresult h2 { margin: 0 0 6px; font-size: 22px; overflow-wrap: anywhere; }
.noresult p { color: var(--text-2); margin: 0 0 8px; }
.noresult .btn { margin-top: 12px; }
.noresult .btn q, .noresult h2 q { quotes: "‘" "’"; }
.noresult .alt { margin-top: 14px; font-size: 14.5px; }
html[data-results=none] .tiles, html[data-results=none] .own, html[data-results=none] .row { display: none; }
html:not([data-results=none]) .noresult { display: none; }
html:not([data-results=few]) .tile.exit { display: none; }
html[data-results=few] .own { display: none; }   /* PROPOSED: the tile is the exit; the box would be a third one on a phone screen */
@media (min-width: 731px) { html[data-results=few] .tile.exit { grid-column: span 2; } }   /* the combined pass (his notes 2026-09-29): with few results the helper spans two columns on desktop, so its sentence and button stop breaking into short lines; the grey stays continuous. Not on the phone's two-column grid: a full-width tile would drop below the result and the fold (QA) — there the sticky bar is the exit */
@media (max-width: 959px) { body:has(.bar.finder-bar) main { padding-bottom: 96px; } }
.finder-bar .bp { font-size: 14.5px; color: var(--text-2); }
/* the tick line: text, never links; "(shown)" as an informational marker in the secondary role */
.ticks span i { font-style: normal; color: var(--text-3); }
.ticks[hidden] { display: none; }
.ticks { gap: 6px 18px; }
@media (max-width: 599px) { .ticks { font-size: 13.5px; gap: 6px 12px; } }   /* three races on one line at 358 px in all three sets (S1 callout 35; measured: 355 of 358 in A and C); six wrap to two */
/* a long parked sentence wraps (the short figures stay on one line) */
mark.x.long { white-space: normal; }
.email, a[href^="mailto:"] { hyphens: none; -webkit-hyphens: none; overflow-wrap: anywhere; }

/* ------------------------------ the consistency pass: one header, one cart, the same roles ------------------------------ */
.crumb a { min-height: 24px; }

/* ------------------------------ CORRECTION 2026-09-25 (the whole-shop review, 2): the shared photo-example treatment ------------------------------ */
/* The heading (the page's own words), a short explanation under it, then TWO equal Eifel posters — the same face, the same frame, a
   landscape photograph in its slot beside a portrait photograph in its slot — each with its caption attached; one line identifies both.
   Side by side on desktop; on a narrow phone they stack at a useful size (two half-width posters would make the photographs too small
   to read). Used on Gifts and on the drawn and undrawn race pages; not a layout selector. */
.photoex { margin-top: 0; }
.photoex > p { max-width: var(--measure); margin: 0 0 18px; }
.photoex .pair { display: grid; grid-template-columns: repeat(2, minmax(0, 300px)); gap: 28px 32px; align-items: start; }
.photoex .pair figure { margin: 0; min-width: 0; }
.photoex .pair figure .stage { margin: 0; }
.photoex .pair figure .poster { max-width: 300px; margin: 0; }   /* left-aligned: the poster and its caption share one edge (as the tiles do) */
.photoex .pair figcaption { font-size: 15px; color: var(--text); margin-top: 12px; font-weight: 500; }
.photoex .ident { margin: 14px 0 0; }
@media (max-width: 599px) { .photoex .pair { grid-template-columns: minmax(0, 1fr); gap: 28px; } .photoex .pair figure .poster { max-width: 320px; } }

/* COPY REVIEW 2026-09-27 (row 21): the keyboard help beside the crop editor's main help, desktop only */
@media (max-width: 699px) { .cropper .kbd-help { display: none; } }

/* ============================== BACKGROUNDS — the dedicated session (2026-09-28) + HIS CORRECTIONS (the same day) ==============================
   THE RULE (his corrections, notes/site_style_feedback/background_session/background_feedback.md): grey holds the product AND
   whatever changes it; a hero that makes one statement is one piece; reading sections alternate as full-width bands; the header,
   the footer and the working chrome stay white. Roles, valued per candidate (tokens.css "BACKGROUNDS"):
     --ground          the PAGE: header, footer, explanation, forms, purchase information, the phone builder's working area
     --ground-product  the PRODUCT GROUND: the poster with its choices (the race page's art column with the style rail; the builder's
                       poster with its style, format and frame colour), a one-piece hero (home, Gifts), a gallery section, a
                       photo-example section, the whole finder, the phone strip's poster mode
     --ground-band     the ALTERNATE READING BAND (new): every other reading section, so the sections don't run together
                       (?bands=grey paints them with the product ground instead — the comparison)
     --bar-bg          the WORKING CHROME: the sticky bars, the phone strip (footer, maps and collapsed modes; its style · price
                       line in every mode), the crop editor's head and tools
     --ground-reading  the support pages (= the page)
   GEOMETRY (?geom — his pick pending): bleed (the default) — every area is a full-width band, a product page's hero splits (the
   grey column reaches the viewport's edge, the purchase column stays white); panel — the product areas are bounded panels (the
   first pass's geometry) grown to hold the choices. The reading bands are full width in both; on a phone every area is a band.
   PAINT: a band (class .zone — never .band, which is the live footer's times row) paints its colour past the wrap to the viewport's edges with a border-image outset (ink overflow: no horizontal
   scroll, no wrapper markup); bands touch — the space between sections is their own padding. One hard edge at every join. */
html[data-bands=grey] { --ground-band: var(--ground-product); }
.wrap { --gx: var(--gutter); --band-pad: clamp(36px, 5vw, 60px); }   /* --gx: the wrap's current gutter (a panel bleeds by it) */
@media (max-width: 730px) { .wrap { --gx: var(--gutter-phone); } }

/* ---- the band ---- */
.zone { --zone: transparent; margin: 0; padding-block: var(--band-pad); }
.zone.zone-product { --zone: var(--ground-product); }
.zone.zone-alt { --zone: var(--ground-band); }
.zone.zone-product, .zone.zone-alt { border-image: linear-gradient(var(--zone) 0 0) fill 0 // 0 100vw; }
.zone > :first-child { margin-top: 0; }
.zone > :last-child { margin-bottom: 0; }
.zone.zone-product + .zone.zone-product, .zone.zone-alt + .zone.zone-alt { padding-top: 8px; }   /* two sections that belong together run on one ground; the heading separates them */
main:has(> .wrap > .zone:first-child) { padding-top: 0; }           /* a band under the header meets it: one edge */
main:has(> .wrap > .zone:last-child) { padding-bottom: 0; }          /* the page ends on a band: its own padding is the space above the footer */
body:has(> main > .wrap > :is(.zone-alt, .zone-product):last-child) > footer.site { margin-top: 0; }   /* a painted last band meets the footer's edge (no orphan strip of page) */
/* the race pages below the hero (his reply to the sheet, 2026-09-28): the trust line directly under the hero, so what separates the
   hero's grey column from the next band is a section with content, never an empty sliver; ?seq= the sequence below it — rule (the
   default: the photo examples on the product grey, then page · tint · page) · a (page first: trust page, the examples tint, …) · b
   (tint first: trust tint, the examples page, …) */
.hero ~ .zone { border-image: linear-gradient(var(--zone) 0 0) fill 0 // 0 100vw; }   /* every band below the hero can take a tone */
@media (max-width: 959px) { .hero { padding-bottom: 28px; } }       /* the purchase information's last line clear of the band below */
html[data-seq=rule] .hero ~ :is(#example, #pers, .pers-held) { --zone: var(--ground-product); }   /* his pick is a (the markup's default); rule and b = the record */
html[data-seq=b] .hero ~ :is(.trust, .two, #questions) { --zone: var(--ground-band); }
html[data-seq=b] .hero ~ :is(#example, #pers, .pers-held, #what) { --zone: transparent; }
.trust.zone { display: block; border-top: 0; border-bottom: 0; margin: 0; padding-block: 28px; border-image: linear-gradient(to bottom, var(--rule-deco) 0 1px, var(--zone) 1px) fill 0 // 0 100vw; }   /* round 2 (his review 2026-09-29): a single full-width rule above the strip, drawn by the band's own paint (no overflow); the tint below bounds it; never the "border" shorthand on a band */
.trust .tin { display: flex; gap: 20px; align-items: center; justify-content: center; }
.trust .tin .tx { text-align: left; min-width: 0; max-width: 560px; }
.trust .say { margin: 0; font: 400 clamp(18px, 1.5vw, 20px)/1.4 var(--font-display); color: var(--text); text-wrap: balance; }   /* the message in the display face: a personal line, smaller than a section heading */
.trust .who { margin: 4px 0 0; font-size: var(--small); color: var(--text-3); }
@media (max-width: 730px) { .trust.zone { padding-block: 26px; } .trust .tin { align-items: flex-start; justify-content: flex-start; } .trust .tin .face { margin-top: 2px; } }
.tband.zone { border-top: 0; border-bottom: 0; margin: 0; }
.final { padding-bottom: 0; }

/* ---- a stage inside a product area sits on the area (the area is the block) ---- */
.stage.hero { display: block; background: var(--ground-product); padding: clamp(16px, 6%, 40px); border-radius: var(--radius-card); }   /* a stage that IS the area (the order page, the gift page) */
.stage.hero > .cap { margin: 14px 0 0; text-align: center; }
.stage.hero > .cap.body { margin-top: 18px; }
.stage.hero > .carousel { margin-top: 14px; }
.stage.hero > .carousel + .cap { margin-top: 10px; }
.stage.hero + .rail { margin-top: 14px; }
.look .stage.hero > .cap { margin-top: 12px; }
@media (max-width: 959px) { .stage.hero { margin-inline: calc(-1 * var(--gx)); border-radius: 0; padding: 20px var(--gx) 18px; } }
.hero .art .stage.hero, .look .stage.hero, .order > .art .stage.hero, .home-hero .stage.hero, .gift-hero .stage.hero, .fin .stage.hero { background: none; padding: 0; border-radius: 0; margin-block: 0; margin-inline: auto; }   /* auto: a stage narrower than its column centres (note 11) */
.zone.zone-product .sw:has(input:checked)::before, .look .sw:has(input:checked)::before, .order > .art .sw:has(input:checked)::before { box-shadow: inset 0 0 0 1px rgba(0,0,0,.18), 0 0 0 2px var(--ground-product), 0 0 0 4px var(--ink); }

/* ---- a product page's hero (the race pages, drawn and undrawn): the art column is the product area — the poster, its caption,
   the tick line, the style rail (desktop) or the dots (phone); the ident and the purchase information stay on the page ---- */
@media (max-width: 959px) {
  .hero .art { padding: 20px 0 18px; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 100vw; }
  main:has(> .wrap > .hero:not(.undrawn):first-child) { padding-top: 0; }   /* the drawn page opens on the poster band */
  .hero .art .carousel { margin-top: 14px; }
}
@media (min-width: 960px) {
  main:has(> .wrap > .hero:first-child) { padding-top: 0; }
  .hero .art { align-self: stretch; padding: 40px 0; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 28px 0 100vw; }   /* bleed: to the viewport's edge, half the column gap on the inside */
  .hero .ident { padding-top: 40px; }
  .hero .buy { padding-bottom: 40px; }
}

/* ---- the product column's content, desktop (his note 11): the poster, its caption and the style rail share ONE block the poster's
   width (the rail starts at the frame's edge); in the bleed geometry that content is centred in the GREY, not in its column — the grey
   runs from the window's edge to 28 px past the column, so the content moves left by half the extra bleed (40 px at 1280, none at 960) ---- */
@media (min-width: 960px) {
  .hero .art > * { max-width: 420px; margin-inline: auto; }
  :is(.hero .art, .builder > .look, .order > .art) { --bleedL: calc(max(0px, (100vw - var(--maxw)) / 2) + var(--gutter)); }
  html:not([data-geom=panel]) :is(.hero .art, .builder > .look, .order > .art) > * { position: relative; left: calc((28px - var(--bleedL)) / 2); }
}

/* ---- the builder (desktop): the poster with style, format and frame colour — one product column; the questions on the page ---- */
@media (max-width: 959px) {
  .order > .art { padding: 20px 0 22px; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 100vw; }
  .builder > .look { padding: 20px 0 22px; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 100vw; }
  main:has(> .wrap > .builder:first-child > .look:first-child) { padding-top: 0; }
}
@media (min-width: 960px) {
  main:has(> .wrap > .builder:first-child) { padding-top: 0; }
  .builder > .look { align-self: stretch; padding: 32px 0 40px; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 28px 0 100vw; }
  .builder > .groups { padding-top: 32px; }
  .order > .art { align-self: stretch; padding: 32px 0 40px; border-image: linear-gradient(var(--ground-product) 0 0) fill 0 // 0 28px 0 100vw; }   /* the order page's preview column = the builder's (his review, 4) */
  .order > .copy { padding-top: 32px; }
}

/* ---- galleries and photo examples: transparent on their band ---- */
.tiles, .wall { background: none; }
.tile.exit { min-height: 0; margin-bottom: 32px; }                 /* stretched to its rows, ending where the captions' row ends */
.photoex > h2 { margin-top: 0; }
.home-hero.zone { padding-block: 40px 44px; }
.home-hero + .zone.zone-product { padding-top: 0; }                      /* ?homejoin=together (the default): the hero and the gallery on one ground */
html[data-homejoin=break] .home-hero + .zone.zone-product { margin-top: var(--band-pad); padding-top: var(--band-pad); }

/* ---- the finder: the whole section is the product ground — the search and the filters change the results, so they sit with them;
   the ground never changes under the user while they type (no results keeps it); header and footer on the page ---- */
body.finder { min-height: 100vh; display: flex; flex-direction: column; }
body.finder > main { flex: 1 0 auto; background: var(--ground-product); }
body.finder > footer.site { margin-top: 0; }

/* ---- GEOMETRY = panel (?geom=panel, desktop): the first pass's bounded panels, grown to hold the choices ---- */
@media (min-width: 960px) {
  html[data-geom=panel] .zone.zone-product { border-image: none; background: var(--ground-product); border-radius: var(--radius-card); margin: var(--band-pad) calc(-1 * var(--gx)); padding: 32px var(--gx) 36px; }   /* white around a panel: its corners never sit on a neighbouring band */
  html[data-geom=panel] .zone.zone-product + .zone.zone-product { margin-top: var(--band-pad); padding-top: 32px; }
  html[data-geom=panel] main:has(> .wrap > .zone:first-child) { padding-top: 32px; }
  html[data-geom=panel] .zone.zone-product:first-child { margin-top: 0; }
  html[data-geom=panel] .photoex.zone.zone-product { width: fit-content; max-width: calc(100% + 2 * var(--gx)); box-sizing: border-box; }
  html[data-geom=panel] .home-hero.zone { padding: 40px var(--gx); }
  html[data-geom=panel] .home-hero + .zone.zone-product { padding-top: 32px; }
  html[data-geom=panel] main:has(> .wrap > .hero:first-child), html[data-geom=panel] main:has(> .wrap > .builder:first-child) { padding-top: 32px; }
  html[data-geom=panel] .hero .art, html[data-geom=panel] .builder > .look, html[data-geom=panel] .order > .art { align-self: start; border-image: none; background: var(--ground-product); border-radius: var(--radius-card); padding: 28px; margin-left: calc(-1 * var(--gx)); }   /* symmetric padding: the poster centred in the panel (note 11) */
  html[data-geom=panel] .hero + .zone { margin-top: var(--band-pad); }   /* white under the art panel's corners */
  html[data-geom=panel] .hero .ident { padding-top: 0; }
  html[data-geom=panel] .hero .buy { padding-bottom: 0; }
  html[data-geom=panel] .builder > .groups, html[data-geom=panel] .order > .copy { padding-top: 0; }
}

/* ---- the phone strip: WORKING CHROME (white) — the grey comes and goes with the poster: in poster mode the step bar and the framed
   poster are one grey block (?stepbar=white keeps the step bar white); the style · price line is white in every mode; the strip's
   bottom edge and its lift are back (white over the white working area) ---- */
.strip { background: var(--bar-bg); border-bottom: 1px solid var(--hairline); box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.strip[data-mode=full] .segbar, .strip[data-mode=full] .view { background: var(--ground-product); }
html[data-stepbar=white] .strip[data-mode=full] .segbar { background: none; }
.strip .segbar .segs i, .strip .segbar .segs .seg { background-color: var(--strip-border); }
.strip .segbar .segs i.on, .strip .segbar .segs .seg.on, .strip .segbar .segs .seg[aria-current] { background-color: var(--ink); }
.strip .segbar .segs i.done, .strip .segbar .segs .seg.done { background-color: var(--rule); }
.strip .readback { border-top: 0; }                                /* the paper's edge above it is the separator */
.truth { border-top: 1px solid var(--hairline); }
.strip[data-mode=full] .truth { border-top: 0; }                   /* the grey's edge is the separator */
.strip .footer-only { padding: 2px 0 6px; }
.strip .footer-only .poster .lf { box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 0 0 1px var(--sheet-edge); }   /* the footer preview: the poster's own paper, full width, its edge on the white */
/* the crop editor: a distinct image-editing mode — white working chrome around the dark image area */
.cropper .head, .cropper .tools { background: var(--bar-bg); }
/* the reading ground: = the page now; ?reading=surface shows the pure-white alternative (the open value, session 4's Ground card) */
html[data-reading=surface] body.reading { background: var(--surface); }
html[data-reading=surface] .stages li::before, html[data-reading=surface] .stages li:last-child::after { background: var(--surface); }

/* ---- the frame colour lives in the Framed print card (founder 2026-09-28, background corrections note 12 — his call of record, as
   builder-round acceptance row J9i and VOICE.md rule 6 already said): one card holds the format option and, while Framed print is
   chosen, its frame colour; Unframed print and Digital file hide it (the chosen colour is kept for a switch back) ---- */
.option-card { border: 1px solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); }
.option-card:hover { border-color: var(--control-border-hover); }
.option-card > .option, .option-card > .option:has(input:checked) { border: 0; background: none; box-shadow: none; }   /* the card carries the selected outline — never the option inside it too */
.option-card:has(> .option input:checked) { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.option-card > .swatches { margin: -4px 0 0; padding: 0 14px 8px 46px; gap: 6px 10px; }   /* under the option's text column (14 + 20 + 12) */
.option-card:not(:has(> .option input:checked)) > .swatches { display: none; }
@media (max-width: 599px) { .option-card > .swatches { gap: 2px 6px; } .option-card > .swatches > .label { flex-basis: 100%; } }   /* a phone: the label on its own line, the four colours and the name on one */
.option-card .sw:has(input:checked)::before { box-shadow: inset 0 0 0 1px rgba(0,0,0,.18), 0 0 0 2px var(--control-bg), 0 0 0 4px var(--ink); }

/* ---- the photo examples, recomposed (his review 2026-09-28, 1): on desktop the explanation in one column and the two examples beside
   it; on a phone ONE large example with Landscape photo / Portrait photo choices (two near-identical full-size posters made a simple point
   take a lot of scrolling). The same component on the race pages and Gifts. ---- */
.photoex { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px 56px; }
.photoex .px-text > h2 { margin-top: 0; }
.photoex .px-text > p { max-width: var(--measure); margin: 0; }
.photoex .px-pick { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
@media (min-width: 960px) {
  .photoex { grid-template-columns: minmax(240px, 1fr) auto; align-items: center; }
  .photoex .px-pick { display: none; }
}
@media (max-width: 959px) {
  .photoex .pair { grid-template-columns: minmax(0, 1fr); }
  .photoex .pair figure .poster { max-width: min(100%, 420px); }
  .photoex .pair figcaption { display: none; }                      /* the choice names the example */
  .photoex:has(.px-pick label:first-child input:checked) .pair figure:nth-child(2),
  .photoex:has(.px-pick label:last-child input:checked) .pair figure:first-child { display: none; }
}

/* ---- home's "Personalise your poster", recomposed (his review 2026-09-28, 2): a text-and-detail column beside the photo, so the short
   detail and the tall framed photo no longer leave an empty quarter ---- */
.pcompose { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; }
@media (min-width: 800px) { .pcompose { grid-template-columns: minmax(0, 1fr) minmax(260px, 380px); gap: 56px; align-items: center; } }
.pcompose .pc-text > h2 { margin-top: 0; }
.pcompose figure { margin: 0; min-width: 0; }
.pcompose .pc-detail img.crop { width: 100%; max-width: 480px; height: auto; border-radius: var(--radius-card); box-shadow: 0 0 0 1px var(--sheet-edge); }
.pcompose b { display: block; font-weight: 600; margin-top: 12px; }
.pcompose small { display: block; color: var(--text-3); font-size: 13.5px; margin-top: 2px; }
.pcompose .pc-photo { margin-top: 32px; }
.pcompose .pc-photo p { margin: 2px 0 0; max-width: var(--measure); }
.pcompose .pc-poster .poster { max-width: 380px; margin: 0; }
.pcompose .pc-poster small { margin-top: 12px; }

/* ---- the final QA seat's small fixes (2026-09-28): the tick line centred under the centred caption in the product column; the "What you
   get" rows' rules one continuous line (no column gap in the rule, tops aligned); "More questions?" clear of the last question's rule ---- */
.hero .art .ticks { justify-content: center; }
.kv.lines { column-gap: 0; align-items: start; }
.kv.lines > span:nth-child(odd) { padding-right: 26px; }
.faq + .note { margin-top: 16px; }

/* ---- the undrawn page's supporting examples (his re-review 2026-09-28): the finished-example row and the photo row share ONE column
   grid — the heading, explanation and link on the left, vertically centred; the artwork on the right, on the same left edge — on one
   continuous tint, separated by spacing ---- */
.fin { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px 56px; }
.fin > * { min-width: 0; }
.fin .px-text > h2 { margin-top: 0; }
.fin .px-text > p { max-width: var(--measure); }
.fin .px-text > p:last-child { margin-bottom: 0; }
.fin .fin-art { max-width: 300px; }
@media (max-width: 959px) { .fin .fin-art { max-width: min(100%, 420px); } }
@media (min-width: 960px) { .fin, .photoex { grid-template-columns: minmax(220px, 1fr) minmax(0, 632px); align-items: center; } }

/* ---- the order page (his re-review): a quiet jump to the style and frame colour, which sit with the preview and can be out of view on
   desktop; the phone's source order (preview · choices · approval) needs none ---- */
.order .jump { margin: 12px 0 0; font-size: 15px; }
@media (max-width: 959px) { .order .jump { display: none; } }
.order .art .ph.look { scroll-margin-top: 24px; }

/* ---- the London detail crop (the recorded margin polish): the asset's ink starts 7 px under its top edge against 72 px at the left —
   the missing top margin added as the same paper (#F8F2E4, the Warm paper the crop is cut from) ---- */
img.crop[src$="detail-footer-london.png"] { aspect-ratio: 900 / 359; object-fit: contain; object-position: center bottom; background: #F8F2E4; }

/* ---- the race page's product column on a SHORT desktop window (his re-review 2026-09-28): the poster yields a little height so the
   whole style rail and its labels stay above the fold — a viewport adjustment, not a smaller poster site-wide (420 px from ≈ 890 px tall;
   the frame is 1.2976 × its width tall; 324 px = the 308 px from the window's top to the rail's labels without the poster, measured, + 16 px clear) ---- */
@media (min-width: 960px) { .hero:not(.undrawn) .art > * { max-width: clamp(300px, calc((100vh - 324px) / 1.2976), 420px); } }

/* The language link (EN · DE) in the header and the footer, and the offer line above an English page for a browser that
   prefers German (his pick 2 at row 10e; row 10e2): the Worker fills their slots only once a second language has its words
   (words-html.mjs languageChrome) — until 10f nothing here shows. The page's language plain and current, the other a link. */
nav.lang, p.lang { font-size: 13.5px; color: var(--soft); white-space: nowrap; }
.lang a { color: var(--soft); text-decoration: none; display: inline-block; padding: 6px 2px; }
.lang a:hover { color: var(--ink); text-decoration: underline; }
.lang a[aria-current] { color: var(--ink); font-weight: 600; }
/* in the header only where it fits beside the nav and the cart, with German's longer nav words (the visual seat: below
   1024 px it pushed the cart or the menu button onto a second row, or squeezed the button) — the footer's line always */
header.site nav.lang, header.tool nav.lang { display: none; }
@media (min-width: 1024px) {
  header.site nav.lang { display: block; margin-left: auto; }
  header.site nav.lang ~ .cart { margin-left: 0; }
  header.tool nav.lang { display: block; margin-left: auto; }
  header.tool nav.lang ~ .save { margin-left: 0; }
  header.tool nav.lang a { padding-top: 0; padding-bottom: 0; }
}
footer.site p.lang, footer.legal p.lang { margin-top: 10px; }
.lang-offer { margin: 0; padding: 8px 16px; display: flex; gap: 12px; align-items: center; justify-content: center; background: var(--surface); border-bottom: 1px solid var(--hairline); font-size: var(--small); }
.lang-offer[hidden] { display: none; }
.lang-offer a { color: var(--ink); font-weight: 600; }
.lang-offer .close { background: none; border: 0; color: var(--soft); font: inherit; cursor: pointer; min-width: 44px; min-height: 44px; }
