/* ─────────────────────────────────────────────────────────────────────────
   site.css - the public marketing layer. Loaded ONLY by the public pages
   (Site::cssLinks), never by the portal. var(--token) only; brand primitives
   live in theme.css. Every class is namespaced .site-* so it can never collide
   with the tool's styles.

   Direction is "the press sheet" (see theme.css). The signature element is a
   crop-mark bracket, drawn with ::before/::after on .site-crop, repeated on the
   hero panel and every section head.

   Section SHAPES deliberately differ - asymmetric hero, ruled spec list, ruled
   index, offset two-column, full band. A page where every section is the same
   three-card row is the tell.
   ───────────────────────────────────────────────────────────────────────── */

/* ── Global overflow safety net ───────────────────────────────────────────── */
html, body { overflow-x: clip; }
img, svg, video { max-width: 100%; height: auto; }
/* The hidden attribute must beat every component display: rule (buttons, the
   submit row, the file list). Without this, el.hidden = true sets the attribute
   but a .site-btn{display:inline-flex} keeps it on screen - which left Next
   visible on the review step. */
[hidden] { display: none !important; }

body.site {
  /* On card stock the slate muted grey drops to 2.4:1; this one holds 4.5 on
     both the card and the deeper paper. */
  --text-muted: #4f5969;
  background: var(--brand-paper);
  color: var(--text);
  font-family: var(--font-body);
}

:root { --section-y: clamp(28px, 3vw, 56px); }

.site-container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.site-skip-link {
  position: absolute; left: var(--space-3); top: calc(-1 * var(--space-8)); z-index: 60;
  padding: var(--space-2) var(--space-3);
  background: var(--brand-primary); color: #fff; border-radius: 2px;
  transition: top var(--transition);
}
.site-skip-link:focus { top: var(--space-3); }

.site-section { padding-block: var(--section-y); }
[id] { scroll-margin-top: 88px; }

/* ── Type ─────────────────────────────────────────────────────────────────── */
.site h1, .site h2, .site h3 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.01em; line-height: 1.06; }
.site-display {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -0.012em; line-height: 1.02;
  font-size: clamp(2.3rem, 1.2rem + 4.6vw, 4.3rem);
  text-wrap: balance;
}
.site-h2 { font-size: clamp(1.6rem, 1.1rem + 2vw, 2.6rem); }
.site-lede { font-size: clamp(1.05rem, 1rem + .45vw, 1.3rem); line-height: 1.5; max-width: 58ch; }

/* No eyebrows. Every page had an uppercase label sitting above its own heading -
   "SERVICES / What we print", "OUR STORY / A Hickory print shop", "PRINT REQUEST /
   Send us the job." The heading always carried it, and the label above it is the
   loudest generated-page tell there is. The class is gone with its markup.
*/
.site-section-head { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-5); }
.site-section-head .site-h2 { max-width: 30ch; }

/* ── Signature: crop marks ────────────────────────────────────────────────── */
.site-crop { position: relative; }
.site-crop::before, .site-crop::after {
  content: ""; position: absolute; width: var(--crop-size); height: var(--crop-size);
  pointer-events: none;
}
/* Outside the trim edge, not on it. Sitting on the border they read as a
   rendering glitch; offset, they read as what they are - the marks a printer
   trims to. */
.site-crop::before {
  top: calc(-1 * var(--crop-gap)); left: calc(-1 * var(--crop-gap));
  border-top: 1px solid var(--brand-accent-bright); border-left: 1px solid var(--brand-accent-bright);
}
.site-crop::after {
  bottom: calc(-1 * var(--crop-gap)); right: calc(-1 * var(--crop-gap));
  border-bottom: 1px solid var(--brand-accent-bright); border-right: 1px solid var(--brand-accent-bright);
}

/* ── Header ───────────────────────────────────────────────────────────────── */
/* The header sits on WHITE, the hero on the grey paper. Tim, 2026-09-02: "the
   header bar and the hero section should be a different colour or there should
   be a contrast there... right now it looks like the grey just kind of runs
   down." Paper-on-paper with a hairline between was exactly that. White also
   happens to be the only ground their dark lockup wants. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--brand-card) 94%, transparent);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--brand-ink-20);
}
.site-header-inner {
  display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between;
  gap: var(--space-4); min-height: 68px;
}
@media (min-width: 601px) { .site-header-inner { min-height: 80px; } }
/* The client's own lockup. It is 404x90 with a transparent ground, so it sits on
   the paper background and is never boxed, tinted or filtered. */
.site-brand { display: inline-flex; align-items: center; flex: none; color: var(--text); text-decoration: none; }
.site-brand:hover { text-decoration: none; }
.site-brand img { display: block; flex: none; width: auto; height: 44px; }
@media (min-width: 601px) { .site-brand img { height: 56px; } }

/* Type-set wordmark. Used where the lockup cannot go - the footer's dark ground
   and the drawer head - because there is no reversed lockup yet and a CSS filter
   turns the steel grey muddy. */
.site-brand-name {
  font-family: var(--font-display); font-weight: 700; font-size: 1.18rem; letter-spacing: -.01em;
  line-height: 1;
}
.site-brand-sub {
  display: block; font-family: var(--font-body); font-weight: 500; font-size: .58rem;
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-muted); margin-top: 3px;
}

.site-nav ul { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-5); list-style: none; margin: 0; padding: 0; }
.site-nav a { white-space: nowrap; }
.site-nav a {
  display: inline-flex; align-items: center; min-height: var(--tap-min);
  color: var(--brand-ink-80); font-size: var(--fs-sm); font-weight: 700;
  letter-spacing: .02em; text-decoration: none;
}
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--brand-accent); text-decoration: none; }
/* A button that happens to live in the nav keeps the button's own colours.
   `.site-nav a` is class+element and outranks the plain `.site-btn-*` class, so
   without this the CTA renders its label in the nav's ink - which on the red
   fill is red on red. */
.site-nav a.site-btn-primary,
.site-nav a.site-btn-primary:hover { color: var(--brand-on-accent); }
.site-nav a.site-btn { padding-block: var(--space-2); min-height: 40px; }

.site-nav-toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--control-min); padding: 0 var(--space-3);
  background: transparent; border: 1px solid var(--brand-ink-20); border-radius: 2px;
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-sm); color: var(--text);
  cursor: pointer;
}
.site-nav-toggle[hidden] { display: none; }

/* Drawer: below the measured fit width the nav becomes a sheet. */
.site-drawer {
  position: fixed; inset: 0; z-index: 55; display: none;
  background: var(--brand-paper);
  padding: var(--space-5) var(--space-4);
  overflow-y: auto;
}
.site-drawer.is-open { display: block; }
.site-drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-6); }
.site-drawer nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-drawer nav a {
  display: block; padding: var(--space-3) 0; border-bottom: 1px solid var(--brand-ink-20);
  font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; color: var(--text); text-decoration: none;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.site-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--control-min); padding: var(--space-3) var(--space-5);
  border: 2px solid transparent; border-radius: 2px;
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-md); line-height: 1.1;
  text-decoration: none; cursor: pointer;
  transition: transform 90ms ease, background var(--transition), color var(--transition);
}
.site-btn:hover { text-decoration: none; }
.site-btn:active { transform: translateY(1px); }
.site-btn-primary { background: var(--brand-accent); color: #fff; border-color: var(--brand-accent); }
.site-btn-primary:hover { background: var(--brand-accent-deep); border-color: var(--brand-accent-deep); color: #fff; }
.site-btn-ghost { background: transparent; color: currentColor; border-color: currentColor; }
/* Not background:currentColor - color changes in this same rule, so the fill
   became the new (paper) colour and the button vanished on hover. */
.site-btn-ghost:hover { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }
.site-btn-dark { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }
.site-btn-dark:hover { background: #000; color: #fff; }
.site-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* ── FAMILY 1: hero, asymmetric split with a spec panel ───────────────────── */
/* Bottom padding is the DEFAULT. Only the home hero zeroes it, because only the
   home hero has the walk-in bar butted onto its bottom edge; the landing pages
   reuse this family without a bar, and were running their buttons straight into
   the next section. */
.site-hero { position: relative; overflow: hidden; background: var(--brand-paper);
  padding-block: clamp(36px, 6vw, 72px) clamp(32px, 5vw, 64px); }
.site-hero--bar { padding-bottom: 0; }
.site-hero::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(var(--brand-ink-20) 1.5px, transparent 1.7px);
  background-size: 20px 20px;
  -webkit-mask-image: radial-gradient(120% 90% at 100% 0%, #000 0%, transparent 55%);
  mask-image: radial-gradient(120% 90% at 100% 0%, #000 0%, transparent 55%);
  opacity: .7;
}
.site-hero > .site-container { position: relative; z-index: 1; }
.site-hero-grid { display: grid; gap: var(--space-6); align-items: end; }
.site-hero h1 { color: var(--brand-primary); }
.site-hero .site-lede { color: var(--brand-ink-80); margin-top: var(--space-4); }
.site-hero .site-actions { margin-top: var(--space-5); }
.site-hero-grid { padding-bottom: clamp(28px, 4vw, 52px); }

/* The spec panel - the press-sheet block. Ruled label/value, never a card grid. */
@media (min-width: 900px) {
  .site-hero-grid { grid-template-columns: minmax(0, 1.55fr) minmax(280px, .9fr); gap: var(--space-8); }
  .site-spec .row { grid-template-columns: 1fr; }
}

/* ── FAMILY 3: offset two-column (the advice band) ────────────────────────── */
.site-advice { background: var(--brand-paper); color: var(--text); }
.site-advice .site-h2 { color: var(--brand-primary); max-width: 16ch; }
.site-advice p { color: var(--brand-ink-80); max-width: 56ch; }
.site-advice-grid { display: grid; gap: var(--space-5); }
.site-checks { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: grid; gap: var(--space-3); }
.site-checks li {
  display: grid; grid-template-columns: 20px 1fr; gap: var(--space-3); align-items: start;
  color: var(--text); font-size: var(--fs-md);
}
.site-checks li::before {
  content: ""; width: 12px; height: 12px; margin-top: 6px;
  background: var(--brand-accent);
}
@media (min-width: 860px) {
  .site-advice-grid { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: var(--space-8); align-items: start; }
}

/* ── FAMILY 4: full band CTA ──────────────────────────────────────────────── */
.site-band { background: var(--brand-accent); color: #fff; }
.site-band .site-h2 { color: #fff; max-width: 18ch; }
.site-band p { color: rgba(255,255,255,.9); max-width: 52ch; margin-top: var(--space-3); }
.site-band .site-actions { margin-top: var(--space-5); }
.site-band .site-btn-dark:hover { background: #fff; color: var(--brand-primary); border-color: #fff; }

/* ── FAMILY 5: grouped service lists ──────────────────────────────────────── */
.site-group + .site-group { margin-top: var(--space-7); }
.site-group-head { display: grid; gap: var(--space-2); margin-bottom: var(--space-4); }
.site-group-head h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.9rem); }
.site-group-head p { color: var(--text-soft); max-width: 60ch; }
/* ── FAMILY 6: the client / logo wall ─────────────────────────────────────
   On the light ground, like the rest of the site - a stark white grid on black
   read as a foreign block. Cells are the paper ground with hairline dividers;
   logos greyscale to unify a mixed set and warm to colour on hover. */
.site-roll { background: var(--brand-card); color: var(--text);
  border-top: 1px solid var(--brand-ink-20); border-bottom: 1px solid var(--brand-ink-20); }
.site-roll .site-h2 { color: var(--brand-primary); }
.site-roll p { color: var(--text-soft); max-width: 54ch; }
/* Logo wall: uniform white tiles on the ink band so a real logo of any colour
   reads; logos greyscale by default (unifies a mismatched set) and warm to full
   colour on hover. The client's NAME is the honest fallback for any tile without
   a logo file yet - drop one into assets/img/clients/ and it replaces the name. */
/* The hairlines are drawn by each CELL, with collapsing negative margins - NOT by
   a grey container background showing through a 1px gap. That trick paints the
   unfilled tail of the last row as a solid grey block, which is what it did here.
   A row that does not fill now ends in nothing at all. */
/* 2026-10-06: no cells. The logos sit straight on the card stock in one balanced
   band - the page sets --cols so the rows split evenly (7 logos = one row of 7),
   and a narrower screen wraps them with the short row centred, never an orphan
   in a corner. White logo backgrounds multiply away into the card, so a JPEG or
   a portal upload with a white box reads like a transparent mark. */
.site-logowall {
  --gap: var(--space-5);
  list-style: none; margin: var(--space-6) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: var(--space-5) var(--gap);
}
.site-logowall li {
  flex: 0 0 calc((100% - (var(--cols, 4) - 1) * var(--gap)) / var(--cols, 4));
  min-width: 120px; height: 84px;
  display: grid; place-items: center; text-align: center;
}
.site-logowall img {
  max-height: 52px; max-width: 100%; width: auto; object-fit: contain;
  mix-blend-mode: multiply;
  transition: transform var(--transition);
}
.site-logowall a { display: grid; place-items: center; width: 100%; height: 100%; }
.site-logowall li:hover img { transform: scale(1.04); }
/* Phones: two across, the odd one centred under them. */
@media (max-width: 559px) {
  .site-logowall { --gap: var(--space-4); }
  .site-logowall li { flex-basis: calc((100% - var(--gap)) / 2); height: 72px; }
  .site-logowall img { max-height: 44px; }
}

/* Credentials: facts on a line, each behind a short accent rule. Not badges. */
.site-creds {
  list-style: none; margin: var(--space-5) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
}
.site-creds li {
  display: flex; align-items: center; gap: var(--space-3);
  color: var(--text-soft); font-size: var(--fs-sm); font-weight: 600;
}
.site-creds li::before {
  content: ""; flex: none; width: 26px; height: 2px; background: var(--brand-accent);
}

/* An award is one line of fact, set like a stamp - not a badge graphic. */
/* A credential, not a control - a boxed border read as a clickable button. Now a
   short accent rule + muted text, like an editorial byline. */
.site-award {
  display: inline-flex; align-items: center; gap: var(--space-3);
  margin-top: var(--space-5); padding: 0; border: 0;
  color: var(--text-soft); font-size: var(--fs-sm); font-weight: 600; letter-spacing: .01em;
}
.site-award::before {
  content: ""; flex: none; width: 26px; height: 2px; background: var(--brand-accent);
}

/* ── About values (still used on the services page) ───────────────────────── */
.site-values { display: grid; gap: var(--space-5); margin-top: var(--space-7); }
.site-value { border-top: 3px solid var(--brand-primary); padding-top: var(--space-3); }
.site-value h3 { font-size: 1.15rem; margin-bottom: var(--space-2); }
.site-value p { color: var(--text-soft); }
@media (min-width: 760px) { .site-values { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); } }

/* ── Facts: a ruled label/value list, never a grid of tiles ───────────────── */
.site-facts { margin: 0; }
.site-facts .row {
  display: grid; grid-template-columns: 1fr; gap: 2px;
  padding: var(--space-3) 0; border-bottom: 1px solid var(--brand-ink-20);
}
.site-facts .row:first-child { border-top: 1px solid var(--brand-ink-20); }
.site-facts dt { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.site-facts dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }
.site-facts a { color: var(--brand-accent); }
@media (min-width: 601px) { .site-facts .row { grid-template-columns: 148px minmax(0, 1fr); gap: var(--space-4); align-items: baseline; } }

/* ── Forms (request + contact) ────────────────────────────────────────────── */
.site-form-grid { display: grid; gap: var(--space-6); align-items: start; }
@media (min-width: 960px) { .site-form-grid { grid-template-columns: minmax(0, 1.4fr) minmax(260px, .8fr); gap: var(--space-8); } }

.site-form { background: #fff; border: 1px solid var(--brand-ink-20); padding: clamp(16px, 3vw, 32px); }
.site-fieldset { border: 0; margin: 0; padding: 0; }
.site-fieldset + .site-fieldset { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--brand-ink-20); }
.site-fieldset legend {
  padding: 0; margin-bottom: var(--space-4);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-xs);
  letter-spacing: .16em; text-transform: uppercase; color: var(--brand-accent);
}
.site-field { display: grid; gap: var(--space-2); margin-bottom: var(--space-4); }
.site-field > label { font-weight: 700; font-size: var(--fs-sm); color: var(--brand-ink-80); }
.site-field .opt { font-weight: 500; color: var(--text-muted); }
.site-field input, .site-field select, .site-field textarea {
  border: 1px solid var(--brand-ink-20); border-radius: 2px; background: #fff;
}
.site-field input:focus, .site-field select:focus, .site-field textarea:focus { border-color: var(--brand-accent); outline-color: var(--brand-accent); }
.site-field .help { font-size: var(--fs-xs); color: var(--text-muted); }
.site-row { display: grid; gap: var(--space-4); }
@media (min-width: 601px) { .site-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } .site-row.three { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.site-drop {
  position: relative; display: grid; gap: var(--space-1); place-items: center; text-align: center;
  min-height: 8rem; padding: var(--space-5);
  border: 2px dashed var(--brand-ink-20); background: var(--brand-paper);
  transition: border-color var(--transition), background var(--transition);
}
.site-drop:focus-within, .site-drop.drag-over { border-color: var(--brand-accent); background: #fff; }
.site-drop input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.site-drop strong { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; }
.site-drop .hint { font-size: var(--fs-xs); color: var(--text-muted); }
.site-filelist { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: grid; gap: var(--space-1); }
.site-filelist li { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--fs-sm); padding-block: var(--space-1); border-bottom: 1px solid var(--brand-ink-20); }
.site-filelist .size { color: var(--text-muted); white-space: nowrap; }

.site-errors { border-left: 3px solid var(--brand-accent); background: #fff; padding: var(--space-3) var(--space-4); margin-bottom: var(--space-5); }
.site-errors ul { margin: 0; padding-left: var(--space-4); }
.site-errors li { font-size: var(--fs-sm); }
.site-errors p { font-weight: 700; margin: 0 0 var(--space-2); }

.site-submit { margin-top: var(--space-6); display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.site-submit .note { font-size: var(--fs-xs); color: var(--text-muted); max-width: 42ch; }

/* Explainer prose collapses; it never stands on the page. */
.site-details { border-top: 1px solid var(--brand-ink-20); padding-top: var(--space-3); margin-top: var(--space-4); }
.site-details summary { cursor: pointer; font-weight: 700; font-size: var(--fs-sm); }
.site-details p { margin-top: var(--space-2); color: var(--text-soft); font-size: var(--fs-sm); max-width: 62ch; }

/* Confirmation */
.site-receipt { display: inline-flex; align-items: baseline; gap: var(--space-3); margin-top: var(--space-5); padding: var(--space-4) var(--space-5); background: var(--brand-primary); color: #fff; }
.site-receipt .k { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: rgba(255,255,255,.6); }
.site-receipt .v { font-family: var(--font-display); font-weight: 700; font-size: 1.7rem; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
.site-footer { background: var(--brand-primary); color: rgba(255,255,255,.72); padding-block: var(--space-7) var(--space-5); font-size: var(--fs-sm); }
.site-footer a { color: rgba(255,255,255,.9); }
.site-footer a:hover { color: #fff; }
.site-footer .site-brand-name { color: #fff; }
.site-footer-inner { display: grid; gap: var(--space-6) var(--space-5); grid-template-columns: 1fr; }
.site-footer-brand p { margin-top: var(--space-2); max-width: 34ch; }
.site-footer-col h2 { font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: rgba(255,255,255,.5); margin: 0 0 var(--space-3); }
.site-footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-footer-contact a { display: inline-flex; align-items: center; gap: var(--space-2); }
.site-footer-contact svg { flex: none; opacity: .7; }
.site-footer-legal { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: space-between; margin-top: var(--space-6); padding-top: var(--space-4); border-top: 1px solid rgba(255,255,255,.16); color: rgba(255,255,255,.55); }
@media (min-width: 640px)  { .site-footer-inner { grid-template-columns: 1.5fr 1fr 1fr 1.1fr; } }

/* sr-only - self-contained; utilities.css is not loaded on public pages. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* One orchestrated page-load, not scattered micro-animations. */
@media (prefers-reduced-motion: no-preference) {
  .site-hero .site-display, .site-hero .site-lede, .site-hero .site-actions, .site-hero .site-spec {
    animation: site-rise 520ms cubic-bezier(.2, .7, .2, 1) both;
  }
  .site-hero .site-lede    { animation-delay: 70ms; }
  .site-hero .site-actions { animation-delay: 140ms; }
  .site-hero .site-spec    { animation-delay: 210ms; }
}
@keyframes site-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ── Landing-page FAQ: a ruled Q/A list, never an accordion widget ─────────── */
.site-faq { margin: 0; max-width: 68ch; }
.site-faq-item { padding: var(--space-4) 0; border-bottom: 1px solid var(--brand-ink-20); }
.site-faq-item:first-child { border-top: 1px solid var(--brand-ink-20); }
.site-faq dt { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--brand-primary); }
.site-faq dd { margin: var(--space-2) 0 0; color: var(--brand-ink-80); }


/* ── Typographic widows: never strand a lone last word ─────────────────────
   Short captions use `balance` (evens the lines, so a 2-line note never leaves
   one word alone); long prose uses `pretty` (avoids an orphan without balancing
   a whole paragraph). Putting short notes under `pretty` was not enough - a
   single trailing word still dropped to its own line. */
.site h1, .site h2, .site h3, .site-display, .site-h2, .site-section-head .site-h2,
.site-submit .note, .site-field .help, .site .help, .site-list .note,
.site-index .note, .site-drop .hint, .site-footer p, .site-aside li { text-wrap: balance; }
.site p, .site-lede, .site-facts dd, .site-aside p { text-wrap: pretty; }

/* ── Contact: shop left, map right, form below ─────────────────────────────── */
/* Explicit 1fr column so the map is viewport-width-constrained on phones - an
   auto grid column + aspect-ratio + min-height would size the map to its
   aspect width (400px) and overflow a 320-390px screen. */
.site-contact-grid { display: grid; gap: var(--space-6); grid-template-columns: minmax(0, 1fr); }
.site-contact-grid > * { min-width: 0; }
.site-contact-grid .site-h2 { margin-bottom: var(--space-4); }
.site-map { width: 100%; border: 1px solid var(--brand-ink-20); background: var(--brand-paper-2);
  aspect-ratio: 4 / 3; overflow: hidden; }
.site-map iframe { width: 100%; height: 100%; border: 0; display: block; }
.site-map-wrap { display: flex; flex-direction: column; gap: var(--space-3); }
.site-map-dir { align-self: start; }
@media (min-width: 820px) {
  .site-contact-grid { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); align-items: stretch; }
  .site-map-wrap { height: 100%; }
  .site-map { flex: 1; aspect-ratio: auto; min-height: 320px; }
}
.site-form-narrow { max-width: 720px; }

/* ── Services filter (search + category chips) ─────────────────────────────── */
.site-filter { display: grid; gap: var(--space-4); margin-bottom: var(--space-6); }
.site-search-field { display: flex; align-items: center; gap: var(--space-2);
  border: 1px solid var(--brand-ink-20); background: #fff; padding: 0 var(--space-3); }
.site-search-field svg { color: var(--steel); flex: none; }
.site-search-field input { border: 0; outline: 0; background: transparent; padding: var(--space-3) 0; min-height: 44px; }
.site-cat { border: 1px solid var(--brand-ink-20); background: transparent; color: var(--brand-ink-80);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-sm); letter-spacing: .01em;
  padding: 8px 14px; min-height: 40px; cursor: pointer; transition: background var(--transition), color var(--transition), border-color var(--transition); }
.site-cat:hover { border-color: var(--brand-primary); }
.site-cat.is-active { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }

.site-groups .site-group + .site-group { margin-top: var(--space-6); }
.site-noresults { padding: var(--space-5) 0; color: var(--text-soft); }
@media (min-width: 601px) { .site-search-field { max-width: 460px; } }

/* ── Hero walk-in bar: phone / address / email, for the local walk-in trade ───
   Most of this shop's customers walk in, so the three ways to reach it sit
   across the bottom of the hero. Rewritten 2026-09-03: it was a three-cell grid
   of stacked uppercase-label-over-value with dividers between, which read as a
   table of contents. It is three facts - an icon and the fact, one line each. */
.site-herobar { position: relative; z-index: 1; background: var(--brand-primary); color: #fff; }
.site-herobar-inner {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3) var(--space-7);
  padding-block: var(--space-4);
}
.site-herobar-item {
  display: inline-flex; align-items: center; gap: var(--space-3);
  color: #fff; text-decoration: none; min-height: var(--tap-min);
  font-weight: 600; font-size: 1.02rem; letter-spacing: .01em; overflow-wrap: anywhere;
}
.site-herobar-item svg { flex: none; color: var(--brand-accent-bright); }
.site-herobar-item:hover { color: #fff; text-decoration: none; }
.site-herobar-item:hover .v { text-decoration: underline; text-underline-offset: 3px; }
.site-herobar-item .k { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (min-width: 900px) { .site-herobar-inner { flex-wrap: nowrap; justify-content: space-between; } }

/* ── Flattened CTA bar (review: not a tall section) ────────────────────────── */
.site-band--flat { padding-block: clamp(20px, 3vw, 34px); }
.site-band-flat-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4) var(--space-6); }
.site-band--flat .site-h2 { margin: 0; }
.site-band--flat p { margin: var(--space-1) 0 0; }
.site-band--flat .site-actions { margin: 0; }

/* ── Bigger supporting text (review: older audience, easy to read) ─────────── */
.site-advice-body { font-size: clamp(1.05rem, 1rem + .5vw, 1.28rem); line-height: 1.55; }
.site-checks li { font-size: clamp(1rem, .96rem + .3vw, 1.14rem); }

/* ── Services card grid (review: cards with a colour icon, not a plain list) ── */
.site-cards { list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--space-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px) { .site-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 980px) { .site-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.site-card {
  display: flex; flex-direction: column; gap: var(--space-3); height: 100%;
  padding: var(--space-4); background: var(--brand-card); border: 1px solid var(--brand-ink-20);
  color: var(--text); text-decoration: none;
  transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.site-card:hover { border-color: var(--brand-primary); transform: translateY(-2px);
  box-shadow: 0 10px 26px -18px rgba(35,31,32,.6); text-decoration: none; }
.site-card-icon { width: 38px; height: 38px; }
.site-card-icon svg { width: 100%; height: 100%; display: block; }
.site-card-name { font-weight: 700; font-size: 1.02rem; line-height: 1.2; }
.site-card-go { margin-top: auto; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand-accent); opacity: 0; transition: opacity var(--transition); }
.site-card:hover .site-card-go, .site-card:focus-visible .site-card-go { opacity: 1; }
.site-card-go::after { content: " \2192"; }

/* ── Contact: info left, form right, big centered map below (review) ───────── */
.site-contact-top { display: grid; gap: var(--space-6); }
.site-contact-info .site-h2 { margin-bottom: var(--space-4); }
@media (min-width: 820px) {
  .site-contact-top { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: start; gap: var(--space-8); }
}
.site-map-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
  flex-wrap: wrap; margin-bottom: var(--space-4); }
.site-map-head .site-h2 { margin: 0; }
.site-map--wide { aspect-ratio: 16 / 9; min-height: 340px; max-width: 1000px; margin-inline: auto; }

/* ── Footer logo chip (the lockup is dark, so it sits on a white chip on the
   dark footer until a reversed logo exists) ─────────────────────────────────── */
.site-footer-logo { display: inline-block; background: #fff; padding: var(--space-2) var(--space-3);
  border-radius: 2px; }
.site-footer-logo img { display: block; height: 40px; width: auto; }
.site-footer-brand p { margin-top: var(--space-3); }


/* ═══════════════════════════════════════════════════════════════════════════
   2026-09-03 revision. Photography lands on the site, and the two families that
   were doing the least work (the ruled index, the recycled icon card) are
   replaced. See docs/plans/design-review-2026-09-03-spec.md.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Hero: type left, the shop right ──────────────────────────────────────────
   The panel that was here listed four specs in a dark box. It told a stranger
   nothing, and on a phone it stacked straight onto the dark walk-in bar as a
   second identical slab. A photograph of the counter answers "are these people
   real" in one look, and it breaks the two dark blocks apart. */
.site-hero-photo { margin: 0; position: relative; }
.site-hero-photo picture { display: block; }
.site-hero-photo img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  aspect-ratio: 4 / 3; background: var(--brand-paper-2);
}
.site-hero-photo figcaption {
  margin-top: var(--space-3);
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted);
}
@media (min-width: 1000px) {
  .site-hero-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); align-items: center; }
  .site-hero-photo img { aspect-ratio: 5 / 4; }
}

/* ── The press sheet ──────────────────────────────────────────────────────────
   A gang run: several different jobs imposed on one sheet and trimmed apart
   after. That is why the tiles are deliberately unequal - it is the shape of
   the client's own working artifact, and it is the answer to "make that more
   imagery based" that eight identical cards would not have been. */
.site-sheet { background: var(--brand-paper-2); border-block: 1px solid var(--brand-ink-20); }
.site-sheet-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5);
}
.site-sheet-head .site-h2 { margin: 0; }
.site-sheet-all {
  font-size: var(--fs-sm); font-weight: 700; color: var(--brand-accent); white-space: nowrap;
}
.site-sheet-all::after { content: " \2192"; }

.site-imposition { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }

/* The tile IS the photograph. A caption block underneath turned every tile into
   a card and stole a third of the picture; the label now sits on the image,
   inside a thin white inset rule - the white margin a mounted print carries, and
   the trim line this whole site is built on. */
.site-imp a {
  position: relative; display: block; height: 100%; overflow: hidden;
  background: var(--brand-primary); color: #fff; text-decoration: none;
}
/* z-index is load-bearing here. A transformed <img> is painted in the same layer
   as positioned descendants, AFTER them in DOM order - so the moment the hover
   scale kicked in, the image rose above the ::before scrim and the white label
   sat on bare photograph until the transition finished. Layering it explicitly
   keeps the scrim under the type and over the picture at every frame. */
.site-imp picture, .site-imp .site-imp-img { display: block; height: 100%; position: relative; z-index: 0; }
.site-imp-img img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform 450ms cubic-bezier(.2, .7, .2, 1);
}
.site-imp a:hover .site-imp-img img { transform: scale(1.04); }

/* The scrim is only under the type, and it is a gradient so the photograph is
   untouched above it. */
.site-imp a::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 62%;
  background: linear-gradient(to top,
    rgba(20, 17, 18, .9) 0%, rgba(20, 17, 18, .72) 34%, rgba(20, 17, 18, 0) 100%);
  pointer-events: none; z-index: 1;
}
/* The thin white box inside the picture. */
.site-imp a::after {
  content: ""; position: absolute; inset: 10px; border: 1px solid rgba(255, 255, 255, .5);
  pointer-events: none; transition: border-color var(--transition); z-index: 3;
}
.site-imp a:hover::after { border-color: rgba(255, 255, 255, .9); }

.site-imp-text {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: var(--space-5) var(--space-5) var(--space-5);
}
.site-imp-label {
  display: block; font-family: var(--font-display); font-weight: 600; color: #fff;
  font-size: 1.15rem; line-height: 1.14; text-wrap: balance;
  text-shadow: 0 1px 12px rgba(20, 17, 18, .5);
}
.site-imp-sub {
  display: block; margin-top: 5px; font-size: var(--fs-xs);
  color: rgba(255, 255, 255, .82); text-wrap: balance;
}
.site-imp.is-lg .site-imp-label { font-size: clamp(1.35rem, 1.05rem + 1.2vw, 1.95rem); }

/* Phones: one column. Tall enough that the picture is the point. */
.site-imp a { min-height: 230px; }
.site-imp.is-lg a { min-height: 300px; }
@media (min-width: 640px) {
  .site-imposition { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 235px; }
  .site-imp a, .site-imp.is-lg a { min-height: 0; }
  .site-imp.is-lg   { grid-column: span 4; grid-row: span 2; }
  .site-imp.is-wide { grid-column: span 2; }
  .site-imp.is-sm   { grid-column: span 2; }
}
@media (min-width: 1000px) {
  .site-imposition { grid-template-columns: repeat(6, minmax(0, 1fr)); grid-auto-rows: 230px; }
  .site-imp.is-lg   { grid-column: span 3; grid-row: span 2; }
  .site-imp.is-wide { grid-column: span 3; }
  .site-imp.is-sm   { grid-column: span 2; }
}

/* ── Advice band: the shop floor beside the argument ──────────────────────── */
.site-advice-photo { margin: 0; }
.site-advice-photo img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  aspect-ratio: 4 / 3; background: var(--brand-paper-2);
}
@media (min-width: 860px) {
  .site-advice-grid {
    grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
    align-items: center; gap: var(--space-8);
  }
}

/* ── Service cards: the mark is drawn at the product's own proportion ────────
   Fixed HEIGHT, automatic width. That is the whole trick: a business card mark
   comes out wide and short, a poster mark tall and narrow, a banner a long
   strip - so the grid reads as thirty different things instead of one icon
   used thirty times. */
.site-card-mark {
  display: flex; align-items: flex-end; height: 58px; margin-bottom: var(--space-2);
}
.site-card-mark svg { height: 100%; width: auto; max-width: 100%; display: block; }
.site-card-size {
  font-size: var(--fs-xs); color: var(--text-muted);
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.site-card { gap: 0; padding: var(--space-4) var(--space-4) var(--space-3); }
.site-card-name { margin-top: auto; font-size: 1rem; }
.site-card-size { margin-top: 2px; }
.site-card-go { margin-top: var(--space-3); }
.site-cards { gap: var(--space-2); }

/* No heading block above the search field - the nav already said Services. */
.site-services-top { padding-top: clamp(20px, 2.4vw, 30px); }


/* ── Chips: internal links that are not navigation ────────────────────────── */
.site-popular { border-top: 1px solid var(--brand-ink-20); }
.site-popular-title {
  font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted);
  margin: 0 0 var(--space-4);
}
.site-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.site-chips a {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 var(--space-4);
  border: 1px solid var(--brand-ink-20); background: var(--brand-card);
  font-size: var(--fs-sm); font-weight: 600; color: var(--brand-ink-80); text-decoration: none;
  transition: border-color var(--transition), color var(--transition);
}
.site-chips a:hover { border-color: var(--brand-accent); color: var(--brand-accent); text-decoration: none; }

/* ── About: the dates, then the photographs ──────────────────────────────────
   Four grey paragraphs made the reader do the arithmetic on a shop that has
   been open since 1987. */
.site-timeline { list-style: none; margin: var(--space-6) 0 0; padding: 0; display: grid; }
.site-timeline li {
  display: grid; gap: 2px var(--space-5); padding: var(--space-4) 0;
  border-top: 1px solid var(--brand-ink-20);
}
.site-timeline li:last-child { border-bottom: 1px solid var(--brand-ink-20); }
.site-timeline .y {
  font-family: var(--font-display); font-weight: 700; font-size: 1.35rem;
  color: var(--brand-accent); font-variant-numeric: tabular-nums; line-height: 1.1;
}
.site-timeline .t { color: var(--brand-ink-80); max-width: 60ch; }
@media (min-width: 601px) {
  .site-timeline li { grid-template-columns: 6.5rem minmax(0, 1fr); align-items: baseline; }
}

.site-photos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-5); }
.site-photos figure { margin: 0; }
.site-photos img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--brand-ink-20); background: var(--brand-paper-2);
}
.site-photos figcaption { margin-top: var(--space-2); font-size: var(--fs-sm); color: var(--text-muted); }
@media (min-width: 760px) { .site-photos { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* A pulled quote in the client's own words, set as a quote and not as prose. */
.site-pullquote {
  margin: var(--space-6) 0 0; padding-left: var(--space-5);
  border-left: 2px solid var(--brand-accent);
  font-family: var(--font-display); font-size: clamp(1.15rem, 1rem + .8vw, 1.5rem);
  line-height: 1.35; color: var(--brand-primary); max-width: 52ch; text-wrap: pretty;
}
.site-pullquote cite {
  display: block; margin-top: var(--space-3); font-family: var(--font-body);
  font-size: var(--fs-xs); font-style: normal; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted);
}

/* ── Landing pages ──────────────────────────────────────────────────────────
   Points were rendered as a ruled label/value row, so every sentence wrapped
   inside a narrow first column against a full-width rule. They are sentences;
   set them as sentences. */
/* A rule over every sentence turned four plain statements into a wireframe. Same
   mark the home page's list already uses: a small ink square, and the sentence. */
.site-points { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.site-points li {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3);
  align-items: start;
  color: var(--brand-ink-80); font-size: 1.02rem; line-height: 1.55; max-width: 52ch;
  text-wrap: pretty;
}
.site-points li::before {
  content: ""; width: 9px; height: 9px; margin-top: .48em; background: var(--brand-accent);
}
@media (min-width: 720px) { .site-points { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4) var(--space-7); } }

.site-lp-grid { display: grid; gap: var(--space-6); align-items: center; }
.site-lp-photo { margin: 0; }
.site-lp-photo img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  aspect-ratio: 4 / 3; background: var(--brand-paper-2);
}
@media (min-width: 900px) {
  .site-lp-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: var(--space-8); }
}

/* ── Widows ──────────────────────────────────────────────────────────────────
   A FAQ answer ending "...and we will price / it." is the same defect the rest
   of the site already guards against; the rule just never covered dd. */
.site-faq dd, .site-points li, .site-imp-sub, .site-timeline .t { text-wrap: pretty; }

/* ── Footer lockup ──────────────────────────────────────────────────────────
   Still a white chip (there is no reversed lockup, and filtering theirs turns
   the steel muddy) but sized and set like a printed label rather than a sticker
   dropped on the footer. */
.site-footer-logo { padding: var(--space-3) var(--space-4); box-shadow: 0 2px 10px -6px rgba(0,0,0,.6); }
.site-footer-logo img { height: 36px; }

/* The hero headline is set against a photograph now, in a narrower column. Cap
   the measure so it always breaks two lines rather than three ragged ones, and
   pull the tracking in at display size the way a serif this large wants. */
.site-hero .site-display { max-width: 15ch; letter-spacing: -.02em; }
.site-hero .site-lede { max-width: 46ch; }
.site-request-top { background: var(--brand-paper-2); border-top: 1px solid var(--brand-ink-20); }

/* ── Hero start strip ───────────────────────────────────────────────────────
   Borrowed shape, not borrowed look: a configurator strip across the foot of
   the hero, so somebody who already knows they want 250 business cards can
   start without reading the page. It hands off to the real request form with
   the job type and quantity already set - it is a shortcut into the existing
   flow, never a second flow. */
.site-startstrip { position: relative; z-index: 2; background: var(--brand-card);
  border-top: 1px solid var(--brand-ink-20); }
.site-startstrip-inner {
  display: grid; gap: var(--space-4); align-items: end;
  padding-block: var(--space-5);
}
.site-startstrip-field { display: grid; gap: var(--space-2); min-width: 0; }
.site-startstrip-field label {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted);
}
.site-startstrip-field select,
.site-startstrip-field input {
  width: 100%; min-height: var(--control-min); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--brand-ink-20); border-radius: 2px; background: var(--brand-card);
  font-family: var(--font-body); font-size: 1rem; color: var(--text);
}
.site-startstrip-field select:focus,
.site-startstrip-field input:focus { border-color: var(--brand-accent); outline-color: var(--brand-accent); }
.site-startstrip .site-btn { min-height: var(--control-min); white-space: nowrap; }
@media (min-width: 760px) {
  .site-startstrip-inner { grid-template-columns: minmax(0, 2fr) minmax(0, .8fr) auto; }
}

/* Desktop: the photograph runs off the right edge of the viewport instead of
   stopping at the container, so the hero reads as a place rather than a picture
   of one. The container is centred at --maxw with --space-4 of padding, so the
   gap from its content edge to the viewport edge is exactly (100vw - maxw)/2
   plus that padding. html{overflow-x:clip} is the safety net. */
.site-hero--bar { padding-top: clamp(24px, 3.5vw, 52px); }

/* ── Category bar: the product strip pinned under the header ─────────────────
   Browsing a print shop starts with "what am I even buying". The strip carries
   the five families and the search, sits directly under the header, and sticks
   there so the choice is always one click away while you scroll the grid. */
.site-catbar {
  position: sticky; top: var(--site-header-h, 67px); z-index: 40;
  background: var(--brand-primary); color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.site-catbar-inner {
  display: flex; align-items: center; gap: var(--space-3) var(--space-5);
  min-height: 72px; padding-block: var(--space-2); flex-wrap: wrap;
}
.site-cats {
  /* nowrap is load-bearing: an earlier .site-cats rule set flex-wrap: wrap for
     the old chip row, and inherited here it stacked the five categories into
     three rows of chrome above the grid on a phone. One scrolling row. */
  display: flex; flex-wrap: nowrap; align-items: center; gap: 0; flex: 1 1 auto;
  min-width: 0; overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.site-cats::-webkit-scrollbar { display: none; }
.site-cat {
  flex: none; border: 0; background: transparent; color: rgba(255, 255, 255, .74);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-sm);
  letter-spacing: .01em; white-space: nowrap; cursor: pointer;
  padding: var(--space-3) var(--space-4); min-height: var(--tap-min);
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.site-cat:first-child { padding-left: 0; }
.site-cat:hover { color: #fff; }
.site-cat.is-active { color: #fff; border-bottom-color: var(--brand-accent-bright); background: transparent; }
.site-catbar .site-search-field {
  flex: 0 1 300px; background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .22); color: #fff;
}
.site-catbar .site-search-field svg { color: rgba(255, 255, 255, .6); }
.site-catbar .site-search-field input { color: #fff; }
.site-catbar .site-search-field input::placeholder { color: rgba(255, 255, 255, .6); }
.site-services-top [id] { scroll-margin-top: 140px; }

/* ── How ordering works ──────────────────────────────────────────────────────
   Three steps, in the shop's real sequence - there is no checkout here, the
   shop calls you back with a price, and saying so up front is the whole
   difference from the web printers. */
.site-how { background: var(--brand-card); border-block: 1px solid var(--brand-ink-20); }
.site-how-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-6); counter-reset: step; }
/* The rule is the top edge of the column and the number sits on the heading
   line. Previously the number floated above a full-width rule that lined up with
   nothing, and the bold heading started below both. */
.site-how-list li {
  counter-increment: step; display: grid; gap: var(--space-2);
  padding-top: var(--space-3); border-top: 2px solid var(--brand-primary);
}
.site-how-list h3 { font-size: 1.18rem; line-height: 1.2; }
.site-how-list h3::before {
  content: counter(step) ".";
  margin-right: .5em; color: var(--brand-accent); font-variant-numeric: tabular-nums;
}
.site-how-list p { color: var(--text-soft); max-width: 42ch; text-wrap: pretty; }
@media (min-width: 760px) { .site-how-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); } }

/* ── Header: the What we print panel ────────────────────────────────────────── */
.site-navdrop { position: relative; }
.site-navdrop > button {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap-min);
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-sm);
  letter-spacing: .02em; color: var(--brand-ink-80);
}
.site-navdrop > button:hover, .site-navdrop > button[aria-expanded="true"] { color: var(--brand-accent); }
.site-navdrop > button svg { transition: transform var(--transition); }
.site-navdrop > button[aria-expanded="true"] svg { transform: rotate(180deg); }
.site-navpanel {
  position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%);
  min-width: min(760px, 92vw); padding: var(--space-5);
  background: var(--brand-card); border: 1px solid var(--brand-ink-20);
  box-shadow: 0 26px 60px -30px rgba(35, 31, 32, .55);
  display: grid; gap: var(--space-5) var(--space-6);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.site-navpanel[hidden] { display: none; }
.site-navpanel h3 {
  font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: var(--space-2);
}
.site-navpanel ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.site-navpanel a {
  display: block; padding: 5px 0; font-size: var(--fs-sm); font-weight: 500;
  color: var(--brand-ink-80); text-decoration: none;
}
.site-navpanel a:hover { color: var(--brand-accent); text-decoration: none; }
.site-navpanel-all { grid-column: 1 / -1; padding-top: var(--space-4); border-top: 1px solid var(--brand-ink-20); }

/* ── Product detail pages ───────────────────────────────────────────────────── */
.site-crumbs {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  margin-bottom: var(--space-4);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted);
}
.site-crumbs a { color: var(--brand-accent); }
.site-crumbs span[aria-hidden] { color: var(--brand-ink-20); }

/* Two or three facts about the product. A ruled label/value pair, the same
   shape the contact facts use - not a grid of tiles for two rows of data. */
.site-spec-inline { margin: var(--space-5) 0 0; display: grid; gap: 0; }
.site-spec-inline > div {
  display: grid; gap: 2px; padding: var(--space-3) 0;
  border-top: 1px solid var(--brand-ink-20);
}
.site-spec-inline > div:last-child { border-bottom: 1px solid var(--brand-ink-20); }
.site-spec-inline dt {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted);
}
.site-spec-inline dd { margin: 0; font-weight: 500; }
@media (min-width: 601px) {
  .site-spec-inline > div { grid-template-columns: 140px minmax(0, 1fr); gap: var(--space-4); align-items: baseline; }
}

.site-section--tight { padding-block: clamp(18px, 2vw, 28px); }
.site-details--card {
  border: 1px solid var(--brand-ink-20); border-top: 1px solid var(--brand-ink-20);
  background: var(--brand-card); padding: var(--space-4) var(--space-5); margin: 0;
}
.site-details--card summary { font-size: 1rem; }
.site-details--card[open] summary { margin-bottom: var(--space-4); }
.site-details--card .site-points li { font-size: var(--fs-sm); }

/* ── Full-bleed hero ─────────────────────────────────────────────────────────
   The photograph is the hero, edge to edge, with the headline on it and the
   start strip butted onto its bottom edge. A scrim from the left keeps the type
   at AA over a busy picture without flattening the whole image into grey. */
.site-hero--cover {
  position: relative; isolation: isolate; overflow: hidden;
  padding: 0; background: var(--brand-primary);
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: clamp(400px, 58vh, 620px);
}
.site-hero-bg { position: absolute; inset: 0; z-index: 0; }
.site-hero-bg picture, .site-hero-bg img {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 42%;
}
.site-hero--cover::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to right, rgba(18, 15, 16, .88) 0%, rgba(18, 15, 16, .72) 42%, rgba(18, 15, 16, .34) 72%, rgba(18, 15, 16, .22) 100%),
    linear-gradient(to top, rgba(18, 15, 16, .55) 0%, rgba(18, 15, 16, 0) 45%);
}
.site-hero--cover .site-hero-copy {
  position: relative; z-index: 2;
  padding-block: clamp(48px, 9vw, 104px);
}
.site-hero--cover .site-display { color: #fff; max-width: 17ch; }
.site-hero--cover .site-lede { color: rgba(255, 255, 255, .88); margin-top: var(--space-4); max-width: 46ch; }
.site-hero--cover .site-actions { margin-top: var(--space-5); }
.site-hero--cover .site-btn-ghost { color: #fff; border-color: rgba(255, 255, 255, .7); }
.site-hero--cover .site-btn-ghost:hover { background: #fff; color: var(--brand-primary); border-color: #fff; }
/* The strip is a solid white shelf across the foot of the picture. */
.site-hero--cover .site-startstrip { position: relative; z-index: 3; border-top: 0; }
.site-hero--nophoto { background: var(--brand-paper); }
.site-hero--nophoto .site-display { color: var(--brand-primary); }
.site-hero--nophoto::after { content: none; }
@media (min-width: 1000px) {
  .site-hero--cover .site-display { max-width: 15ch; font-size: clamp(2.6rem, 1.4rem + 3vw, 4rem); }
}

/* ── About: the story, told in beats ─────────────────────────────────────────
   Each paragraph sits beside its own picture and the sides alternate, instead
   of one narrow column of prose with half the page empty next to it. A beat
   with no picture (the paragraph about Sandy's illness) runs on its own, wider
   and quieter - that one should not be illustrated. */

/* The cover hero's scrim spans the whole section, so the walk-in bar sitting
   inside it needs to come up through the same stack the start strip does -
   otherwise its type renders through a 55% wash and misses contrast. */
.site-hero--cover .site-herobar { position: relative; z-index: 3; }

/* ── Cover hero, light plate ─────────────────────────────────────────────────
   The building is drawn in one ink on paper, so the dark scrim that a
   photograph needs would bury it. Here the scrim is paper, the headline stays
   in ink, and the drawing reads as what it is: something this shop printed. */
.site-hero--cover.is-light { background: var(--brand-paper); }
.site-hero--cover.is-light::after {
  background:
    linear-gradient(to right,
      rgba(238, 242, 248, .9) 0%, rgba(238, 242, 248, .78) 36%,
      rgba(238, 242, 248, .3) 68%, rgba(238, 242, 248, .1) 100%),
    linear-gradient(to bottom, rgba(238, 242, 248, .75) 0%, rgba(238, 242, 248, 0) 38%);
}
.site-hero--cover.is-light .site-display { color: var(--brand-primary); }
.site-hero--cover.is-light .site-lede { color: var(--brand-ink-80); }
.site-hero--cover.is-light .site-btn-ghost { color: var(--brand-primary); border-color: var(--brand-primary); }
.site-hero--cover.is-light .site-btn-ghost:hover { background: var(--brand-primary); color: #fff; }
/* The building and its sign sit in the lower half of the drawing, so a centred
   crop cuts the shopfront off. Hold the bottom of the picture. */
.site-hero--cover.is-light .site-hero-bg img { object-position: center 30%; }

/* The nav toggle is a hamburger, not the word "Menu" in a box, which read as a
   stray button rather than a control. The label stays for screen readers. */
.site-nav-toggle { width: var(--control-min); padding: 0; }
.site-nav-toggle svg { display: block; }

/* ── Cover hero on a phone ───────────────────────────────────────────────────
   The building is drawn wide - about 2.4:1 - so behind a tall portrait hero it
   cropped to a band of treetops with the building out of frame. Below 760px the
   hero stacks instead: the headline on paper, then the whole drawing at its own
   proportion, then the start strip. Nothing is cropped and nothing is guessed. */
@media (max-width: 759px) {
  .site-hero--cover { display: block; min-height: 0; background: var(--brand-paper); }
  .site-hero--cover::after { content: none; }
  .site-hero--cover .site-hero-bg { position: static; }
  .site-hero--cover .site-hero-bg img { aspect-ratio: 24 / 10; object-position: center 55%; }
  .site-hero--cover .site-hero-copy { padding-block: clamp(28px, 7vw, 44px) clamp(20px, 5vw, 32px); }
  .site-hero--cover .site-display { color: var(--brand-primary); max-width: 18ch; }
  .site-hero--cover .site-lede { color: var(--brand-ink-80); }
  .site-hero--cover .site-btn-ghost { color: var(--brand-primary); border-color: var(--brand-primary); }
}

/* ── About: one dated spine ──────────────────────────────────────────────────
   Every row is the same shape - year, then the chapter, then a photograph
   cropped to the same band - so the page has a rhythm instead of four
   differently-sized blocks starting at four different heights. The rule down
   the left is the timeline; the year sits on it. */
.site-about-top { background: var(--brand-paper); }
.site-story { background: var(--brand-paper-2); border-top: 1px solid var(--brand-ink-20); }

.site-chapters { list-style: none; margin: 0; padding: 0; }
.site-chapter {
  display: grid; gap: var(--space-3);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--brand-ink-20);
}
.site-chapter:first-child { border-top: 0; padding-top: var(--space-2); }
.site-chapter-year {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); line-height: 1;
  color: var(--brand-accent); font-variant-numeric: tabular-nums;
}
.site-chapter-body h3 {
  font-size: clamp(1.15rem, 1rem + .6vw, 1.45rem); line-height: 1.2;
  margin-bottom: var(--space-2); text-wrap: balance;
}
.site-chapter-body p {
  color: var(--brand-ink-80); font-size: 1.05rem; line-height: 1.65;
  max-width: 46ch; text-wrap: pretty;
}
.site-chapter-photo { margin: 0; }
.site-chapter-photo img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 2; object-fit: cover;
  border: 1px solid var(--brand-ink-20); background: var(--brand-paper);
}

@media (min-width: 900px) {
  /* year | chapter | photograph. A row with no photograph lets the chapter run
     into the third column rather than leaving a hole where a picture is not. */
  .site-chapter {
    grid-template-columns: 7rem minmax(0, 1fr) minmax(0, .95fr);
    gap: var(--space-6);
    align-items: start;
  }
  .site-chapter.is-solo { grid-template-columns: 7rem minmax(0, 1fr); }
  .site-chapter.is-solo .site-chapter-body p { max-width: 62ch; }
  .site-chapter-year { padding-top: .18em; }
}

/* The award reads as the footnote it is, under the quote. */
.site-story .site-pullquote { margin-top: var(--space-7); }
.site-story .site-award { margin-top: var(--space-5); }

/* The building drawing is wider than the 3:2 band, and its pole sign sits at the
   far right - a centred crop cuts the sign off, which is the one thing in that
   picture worth keeping. `data-pos` moves the crop window. */
.site-chapter-photo[data-pos="right"] img { object-position: right center; }
.site-chapter-photo[data-pos="left"] img  { object-position: left center; }
/* A portrait photo (an ad, a flyer) keeps its own 2:3 and shows whole. */
.site-chapter-photo[data-shape="tall"] { max-width: 20rem; }
.site-chapter-photo[data-shape="tall"] img { aspect-ratio: 2 / 3; object-fit: contain; }


/* ══════════════════════════════════════════════════════════════════════════════
   REQUEST FLOW - artwork first, bureaucracy last
   ═════════════════════════════════════════════════════════════════════════════
   The form used to open on "Who you are". It now opens on what is being printed
   (or, when the URL already told us, on the artwork), so the first thing that
   happens is the customer seeing their own file - not filling in a name. */

/* The shop-design panel. The label is the control, full width, so a 50+ thumb
   is not aiming at a 13px box. */
.site-artpanel {
  margin-bottom: var(--space-4); padding: var(--space-4);
  background: var(--brand-paper); border: 1px solid var(--brand-ink-20);
}
.site-check {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 44px; margin-bottom: var(--space-3); cursor: pointer;
  font-weight: 700; font-size: var(--fs-sm);
}
.site-check input { width: 22px; height: 22px; flex: none; accent-color: var(--brand-accent); }
.site-artpanel .site-field:last-child { margin-bottom: 0; }

/* ── The file list, with a thumbnail of what was actually attached ─────────── */
/* Overrides the plain two-column echo above: "5 files" told a customer nothing
   about whether the right one made it in. */
.site-filelist li {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center; gap: var(--space-3);
  padding-block: var(--space-2);
}
.site-filelist .name { overflow-wrap: anywhere; }
.site-filethumb {
  width: 48px; height: 48px; display: grid; place-items: center;
  background: var(--brand-paper-2); border: 1px solid var(--brand-ink-20); overflow: hidden;
}
.site-filethumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.site-filethumb.is-mark { color: var(--brand-steel); }
.site-filethumb svg { width: 22px; height: 28px; display: block; }

/* ── The proof: the image at the real trim, with the guides over it ────────── */
/* Page size is the only signal a file gives, and it is ambiguous - so we never
   read the product off it. Once the product IS known, though, the customer
   should see their picture at that size before we print it, because the reprint
   this shop eats is a small logo blown up to a four-foot banner. */
/* Two proofs side by side once there is room: the schematic (trim/bleed/safe -
   "does it fit") and the photoreal mockup (a card on the counter - "what does it
   look like"). Stacked on a phone so neither is squeezed to nothing. */
.site-proofs { display: grid; gap: var(--space-4); }
@media (min-width: 760px) { .site-proofs:has(.site-proof--mockup:not([hidden])) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.site-proof { margin-top: var(--space-4); }
.site-proofs .site-proof { margin-top: 0; }
.site-proof-sheet {
  padding: var(--space-4); background: var(--brand-paper-2);
  border: 1px solid var(--brand-ink-20);
}
.site-proof-sheet canvas {
  display: block; margin-inline: auto;
  max-width: 100%; max-height: 300px; width: auto; height: auto;
}
.site-proof-cap { margin-top: var(--space-3); font-size: var(--fs-xs); color: var(--text-muted); text-wrap: pretty; }
.site-proof-ok { margin-top: var(--space-2); font-size: var(--fs-sm); color: var(--text-soft); }
.site-proof-warn {
  margin-top: var(--space-3); padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--brand-accent); background: #fff;
  font-size: var(--fs-sm); color: var(--brand-ink-80); text-wrap: pretty;
}

/* ── The design handed back from the editor, when the browser refuses it ───── */
/* A design that cannot be attached must never be a design that is lost. */
.site-handoff {
  display: grid; gap: var(--space-2); justify-items: start;
  margin-bottom: var(--space-4); padding: var(--space-4);
  border: 1px solid var(--brand-accent); background: #fff;
}
.site-handoff strong { font-family: var(--font-display); font-size: 1.05rem; }
.site-handoff p { font-size: var(--fs-sm); color: var(--text-soft); text-wrap: pretty; }
.site-handoff .site-btn { margin-top: var(--space-2); }

/* Phones: the audience is 50+, so nothing here gets smaller than a thumb. */
@media (max-width: 600px) {
  .site-proof-sheet { padding: var(--space-3); }
  .site-proof-sheet canvas { max-height: 220px; }
}

/* ── /start: the ordering flow's two steps ───────────────────────────────────
   The review asked for a modal. This behaves like one - a focused sheet with a
   close button and nothing competing for attention - but it is a real page,
   because a modal has no address: it cannot be linked to, the back button does
   not close it, and a customer told "start here" over the phone has nothing to
   type. */
.site-sheetpage { background: var(--brand-card); padding-block: clamp(24px, 4vw, 48px) clamp(40px, 6vw, 72px); min-height: 60vh; }
.site-sheetpage-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-6);
  padding-bottom: var(--space-4); border-bottom: 1px solid var(--brand-ink-20);
}
.site-step-of {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--brand-accent); margin-bottom: var(--space-2);
}
.site-sheetpage-head .site-h2 { margin: 0; max-width: 22ch; }
.site-sheetpage-sub { margin-top: var(--space-3); color: var(--text-soft); font-weight: 600; }
.site-sheetpage-sub a { margin-left: var(--space-3); font-size: var(--fs-sm); color: var(--brand-accent); }
.site-sheetpage-close {
  flex: none; display: inline-flex; align-items: center; min-height: var(--tap-min);
  padding: 0 var(--space-3); font-size: var(--fs-sm); font-weight: 700; color: var(--text-muted);
}
.site-sheetpage-close:hover { color: var(--brand-accent); text-decoration: none; }
.site-startpick-filter { margin-bottom: var(--space-6); }
.site-startpick-filter .site-search-field { max-width: 460px; }

/* Step 2: how the artwork gets handled. Three routes, and the third one is a
   service on the shop's own line card, not a courtesy option. */
.site-fork { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.site-fork > li { display: flex; }
.site-fork a {
  display: flex; flex-direction: column; gap: var(--space-3); width: 100%;
  padding: var(--space-6) var(--space-5);
  background: var(--brand-card); border: 1px solid var(--brand-ink-20);
  color: var(--text); text-decoration: none;
  transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.site-fork a:hover {
  border-color: var(--brand-primary); text-decoration: none; transform: translateY(-2px);
  box-shadow: 0 14px 32px -22px rgba(35, 31, 32, .7);
}
.site-fork-mark { width: 42px; height: 42px; color: var(--brand-accent); }
.site-fork-mark svg { width: 100%; height: 100%; display: block; }
.site-fork h2 { font-size: 1.3rem; line-height: 1.2; }
.site-fork p { color: var(--text-soft); font-size: var(--fs-sm); line-height: 1.55; text-wrap: pretty; }
.site-fork-go {
  margin-top: auto; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand-accent);
}
.site-fork-go::after { content: " \2192"; }
.site-fork-note { margin-top: var(--space-6); color: var(--text-soft); font-size: var(--fs-sm); }
.site-fork-note a { color: var(--brand-accent); font-weight: 700; }
@media (min-width: 820px) { .site-fork { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); } }

/* A 68ch column of questions in a 1200px container left half the band empty.
   Heading on the left, the questions beside it. */
.site-faq-grid { display: grid; gap: var(--space-5); }
.site-faq-grid .site-section-head { margin-bottom: 0; }
@media (min-width: 860px) {
  .site-faq-grid { grid-template-columns: minmax(0, .5fr) minmax(0, 1fr); gap: var(--space-8); align-items: start; }
  .site-faq-grid .site-faq { max-width: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   site.css - the public marketing layer. Loaded ONLY by the public pages
   (Site::cssLinks), never by the portal. var(--token) only; brand primitives
   live in theme.css. Every class is namespaced .site-* so it can never collide
   with the tool's styles.

   Direction is "the press sheet" (see theme.css). The signature element is a
   crop-mark bracket, drawn with ::before/::after on .site-crop, repeated on the
   hero panel and every section head.

   Section SHAPES deliberately differ - asymmetric hero, ruled spec list, ruled
   index, offset two-column, full band. A page where every section is the same
   three-card row is the tell.
   ───────────────────────────────────────────────────────────────────────── */

/* ── Global overflow safety net ───────────────────────────────────────────── */
/* The hidden attribute must beat every component display: rule (buttons, the
   submit row, the file list). Without this, el.hidden = true sets the attribute
   but a .site-btn{display:inline-flex} keeps it on screen - which left Next
   visible on the review step. */

/* ── Type ─────────────────────────────────────────────────────────────────── */

/* No eyebrows. Every page had an uppercase label sitting above its own heading -
   "SERVICES / What we print", "OUR STORY / A Hickory print shop", "PRINT REQUEST /
   Send us the job." The heading always carried it, and the label above it is the
   loudest generated-page tell there is. The class is gone with its markup.
*/

/* ── Signature: crop marks ────────────────────────────────────────────────── */
/* Outside the trim edge, not on it. Sitting on the border they read as a
   rendering glitch; offset, they read as what they are - the marks a printer
   trims to. */

/* ── Header ───────────────────────────────────────────────────────────────── */
/* The header sits on WHITE, the hero on the grey paper. Tim, 2026-09-02: "the
   header bar and the hero section should be a different colour or there should
   be a contrast there... right now it looks like the grey just kind of runs
   down." Paper-on-paper with a hairline between was exactly that. White also
   happens to be the only ground their dark lockup wants. */
/* The client's own lockup. It is 404x90 with a transparent ground, so it sits on
   the paper background and is never boxed, tinted or filtered. */

/* Type-set wordmark. Used where the lockup cannot go - the footer's dark ground
   and the drawer head - because there is no reversed lockup yet and a CSS filter
   turns the steel grey muddy. */
/* A button that happens to live in the nav keeps the button's own colours.
   `.site-nav a` is class+element and outranks the plain `.site-btn-*` class, so
   without this the CTA renders its label in the nav's ink - which on the red
   fill is red on red. */

/* Drawer: below the measured fit width the nav becomes a sheet. */

/* ── Buttons ──────────────────────────────────────────────────────────────── */

/* ── FAMILY 1: hero, asymmetric split with a spec panel ───────────────────── */
/* Bottom padding is the DEFAULT. Only the home hero zeroes it, because only the
   home hero has the walk-in bar butted onto its bottom edge; the landing pages
   reuse this family without a bar, and were running their buttons straight into
   the next section. */

/* The spec panel - the press-sheet block. Ruled label/value, never a card grid. */

/* ── FAMILY 3: offset two-column (the advice band) ────────────────────────── */

/* ── FAMILY 4: full band CTA ──────────────────────────────────────────────── */

/* ── FAMILY 5: grouped service lists ──────────────────────────────────────── */
/* ── FAMILY 6: the client / logo wall ─────────────────────────────────────
   On the light ground, like the rest of the site - a stark white grid on black
   read as a foreign block. Cells are the paper ground with hairline dividers;
   logos greyscale to unify a mixed set and warm to colour on hover. */
/* Logo wall: uniform white tiles on the ink band so a real logo of any colour
   reads; logos greyscale by default (unifies a mismatched set) and warm to full
   colour on hover. The client's NAME is the honest fallback for any tile without
   a logo file yet - drop one into assets/img/clients/ and it replaces the name. */
/* The hairlines are drawn by each CELL, with collapsing negative margins - NOT by
   a grey container background showing through a 1px gap. That trick paints the
   unfilled tail of the last row as a solid grey block, which is what it did here.
   A row that does not fill now ends in nothing at all. */

/* Credentials: facts on a line, each behind a short accent rule. Not badges. */

/* An award is one line of fact, set like a stamp - not a badge graphic. */
/* A credential, not a control - a boxed border read as a clickable button. Now a
   short accent rule + muted text, like an editorial byline. */

/* ── About values (still used on the services page) ───────────────────────── */

/* ── Facts: a ruled label/value list, never a grid of tiles ───────────────── */

/* ── Forms (request + contact) ────────────────────────────────────────────── */

/* Aside beside a form: what happens next, in a ruled block. */

/* Explainer prose collapses; it never stands on the page. */

/* Confirmation */

/* ── Footer ───────────────────────────────────────────────────────────────── */

/* sr-only - self-contained; utilities.css is not loaded on public pages. */

/* One orchestrated page-load, not scattered micro-animations. */

/* ── Landing-page FAQ: a ruled Q/A list, never an accordion widget ─────────── */


/* ── Typographic widows: never strand a lone last word ─────────────────────
   Short captions use `balance` (evens the lines, so a 2-line note never leaves
   one word alone); long prose uses `pretty` (avoids an orphan without balancing
   a whole paragraph). Putting short notes under `pretty` was not enough - a
   single trailing word still dropped to its own line. */

/* ── Contact: shop left, map right, form below ─────────────────────────────── */
/* Explicit 1fr column so the map is viewport-width-constrained on phones - an
   auto grid column + aspect-ratio + min-height would size the map to its
   aspect width (400px) and overflow a 320-390px screen. */

/* ── Services filter (search + category chips) ─────────────────────────────── */

/* ── Request form: stepper (only when JS adds .is-stepped) ─────────────────── */

/* Review step */


/* ── Hero walk-in bar: phone / address / email, for the local walk-in trade ───
   Most of this shop's customers walk in, so the three ways to reach it sit
   across the bottom of the hero. Rewritten 2026-09-03: it was a three-cell grid
   of stacked uppercase-label-over-value with dividers between, which read as a
   table of contents. It is three facts - an icon and the fact, one line each. */

/* ── Flattened CTA bar (review: not a tall section) ────────────────────────── */

/* ── Bigger supporting text (review: older audience, easy to read) ─────────── */

/* ── Services card grid (review: cards with a colour icon, not a plain list) ── */

/* ── Contact: info left, form right, big centered map below (review) ───────── */

/* ── Footer logo chip (the lockup is dark, so it sits on a white chip on the
   dark footer until a reversed logo exists) ─────────────────────────────────── */


/* ═══════════════════════════════════════════════════════════════════════════
   2026-09-03 revision. Photography lands on the site, and the two families that
   were doing the least work (the ruled index, the recycled icon card) are
   replaced. See docs/plans/design-review-2026-09-03-spec.md.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Hero: type left, the shop right ──────────────────────────────────────────
   The panel that was here listed four specs in a dark box. It told a stranger
   nothing, and on a phone it stacked straight onto the dark walk-in bar as a
   second identical slab. A photograph of the counter answers "are these people
   real" in one look, and it breaks the two dark blocks apart. */

/* ── The press sheet ──────────────────────────────────────────────────────────
   A gang run: several different jobs imposed on one sheet and trimmed apart
   after. That is why the tiles are deliberately unequal - it is the shape of
   the client's own working artifact, and it is the answer to "make that more
   imagery based" that eight identical cards would not have been. */

/* The tile IS the photograph. A caption block underneath turned every tile into
   a card and stole a third of the picture; the label now sits on the image,
   inside a thin white inset rule - the white margin a mounted print carries, and
   the trim line this whole site is built on. */
/* z-index is load-bearing here. A transformed <img> is painted in the same layer
   as positioned descendants, AFTER them in DOM order - so the moment the hover
   scale kicked in, the image rose above the ::before scrim and the white label
   sat on bare photograph until the transition finished. Layering it explicitly
   keeps the scrim under the type and over the picture at every frame. */

/* The scrim is only under the type, and it is a gradient so the photograph is
   untouched above it. */
/* The thin white box inside the picture. */

/* Phones: one column. Tall enough that the picture is the point. */

/* ── Advice band: the shop floor beside the argument ──────────────────────── */

/* ── Service cards: the mark is drawn at the product's own proportion ────────
   Fixed HEIGHT, automatic width. That is the whole trick: a business card mark
   comes out wide and short, a poster mark tall and narrow, a banner a long
   strip - so the grid reads as thirty different things instead of one icon
   used thirty times. */

/* No heading block above the search field - the nav already said Services. */


/* ── Chips: internal links that are not navigation ────────────────────────── */

/* ── About: the dates, then the photographs ──────────────────────────────────
   Four grey paragraphs made the reader do the arithmetic on a shop that has
   been open since 1987. */

/* A pulled quote in the client's own words, set as a quote and not as prose. */

/* ── Landing pages ──────────────────────────────────────────────────────────
   Points were rendered as a ruled label/value row, so every sentence wrapped
   inside a narrow first column against a full-width rule. They are sentences;
   set them as sentences. */
/* A rule over every sentence turned four plain statements into a wireframe. Same
   mark the home page's list already uses: a small ink square, and the sentence. */

/* ── Widows ──────────────────────────────────────────────────────────────────
   A FAQ answer ending "...and we will price / it." is the same defect the rest
   of the site already guards against; the rule just never covered dd. */

/* ── Footer lockup ──────────────────────────────────────────────────────────
   Still a white chip (there is no reversed lockup, and filtering theirs turns
   the steel muddy) but sized and set like a printed label rather than a sticker
   dropped on the footer. */

/* The hero headline is set against a photograph now, in a narrower column. Cap
   the measure so it always breaks two lines rather than three ragged ones, and
   pull the tracking in at display size the way a serif this large wants. */

/* ── Hero start strip ───────────────────────────────────────────────────────
   Borrowed shape, not borrowed look: a configurator strip across the foot of
   the hero, so somebody who already knows they want 250 business cards can
   start without reading the page. It hands off to the real request form with
   the job type and quantity already set - it is a shortcut into the existing
   flow, never a second flow. */

/* Desktop: the photograph runs off the right edge of the viewport instead of
   stopping at the container, so the hero reads as a place rather than a picture
   of one. The container is centred at --maxw with --space-4 of padding, so the
   gap from its content edge to the viewport edge is exactly (100vw - maxw)/2
   plus that padding. html{overflow-x:clip} is the safety net. */

/* ── Category bar: the product strip pinned under the header ─────────────────
   Browsing a print shop starts with "what am I even buying". The strip carries
   the five families and the search, sits directly under the header, and sticks
   there so the choice is always one click away while you scroll the grid. */

/* ── How ordering works ──────────────────────────────────────────────────────
   Three steps, in the shop's real sequence - there is no checkout here, the
   shop calls you back with a price, and saying so up front is the whole
   difference from the web printers. */
/* The rule is the top edge of the column and the number sits on the heading
   line. Previously the number floated above a full-width rule that lined up with
   nothing, and the bold heading started below both. */

/* ── Header: the What we print panel ────────────────────────────────────────── */

/* ── Product detail pages ───────────────────────────────────────────────────── */

/* Two or three facts about the product. A ruled label/value pair, the same
   shape the contact facts use - not a grid of tiles for two rows of data. */

/* ── Full-bleed hero ─────────────────────────────────────────────────────────
   The photograph is the hero, edge to edge, with the headline on it and the
   start strip butted onto its bottom edge. A scrim from the left keeps the type
   at AA over a busy picture without flattening the whole image into grey. */
/* The strip is a solid white shelf across the foot of the picture. */

/* ── About: the story, told in beats ─────────────────────────────────────────
   Each paragraph sits beside its own picture and the sides alternate, instead
   of one narrow column of prose with half the page empty next to it. A beat
   with no picture (the paragraph about Sandy's illness) runs on its own, wider
   and quieter - that one should not be illustrated. */

/* The cover hero's scrim spans the whole section, so the walk-in bar sitting
   inside it needs to come up through the same stack the start strip does -
   otherwise its type renders through a 55% wash and misses contrast. */

/* ── Cover hero, light plate ─────────────────────────────────────────────────
   The building is drawn in one ink on paper, so the dark scrim that a
   photograph needs would bury it. Here the scrim is paper, the headline stays
   in ink, and the drawing reads as what it is: something this shop printed. */
/* The building and its sign sit in the lower half of the drawing, so a centred
   crop cuts the shopfront off. Hold the bottom of the picture. */

/* The nav toggle is a hamburger, not the word "Menu" in a box, which read as a
   stray button rather than a control. The label stays for screen readers. */

/* ── Cover hero on a phone ───────────────────────────────────────────────────
   The building is drawn wide - about 2.4:1 - so behind a tall portrait hero it
   cropped to a band of treetops with the building out of frame. Below 760px the
   hero stacks instead: the headline on paper, then the whole drawing at its own
   proportion, then the start strip. Nothing is cropped and nothing is guessed. */

/* ── About: one dated spine ──────────────────────────────────────────────────
   Every row is the same shape - year, then the chapter, then a photograph
   cropped to the same band - so the page has a rhythm instead of four
   differently-sized blocks starting at four different heights. The rule down
   the left is the timeline; the year sits on it. */

/* The award reads as the footnote it is, under the quote. */

/* The building drawing is wider than the 3:2 band, and its pole sign sits at the
   far right - a centred crop cuts the sign off, which is the one thing in that
   picture worth keeping. `data-pos` moves the crop window. */


/* ══════════════════════════════════════════════════════════════════════════════
   REQUEST FLOW - artwork first, bureaucracy last
   ═════════════════════════════════════════════════════════════════════════════
   The form used to open on "Who you are". It now opens on what is being printed
   (or, when the URL already told us, on the artwork), so the first thing that
   happens is the customer seeing their own file - not filling in a name. */

/* The confirmed product, above every step. It is the one decision the rest of
   the form is quoting against, so it never scrolls out of the argument. */

/* ── Step 1: the picker ────────────────────────────────────────────────────── */
/* Denser than the services grid: this one sits inside a form column, and thirty
   products at the full card height is a page of scrolling before the customer
   has done anything. */

/* ── The artwork fork: three routes, inline ────────────────────────────────── */

/* The shop-design panel. The label is the control, full width, so a 50+ thumb
   is not aiming at a 13px box. */

/* ── The file list, with a thumbnail of what was actually attached ─────────── */
/* Overrides the plain two-column echo above: "5 files" told a customer nothing
   about whether the right one made it in. */

/* ── The proof: the image at the real trim, with the guides over it ────────── */
/* Page size is the only signal a file gives, and it is ambiguous - so we never
   read the product off it. Once the product IS known, though, the customer
   should see their picture at that size before we print it, because the reprint
   this shop eats is a small logo blown up to a four-foot banner. */

/* ── The design handed back from the editor, when the browser refuses it ───── */
/* A design that cannot be attached must never be a design that is lost. */

/* Phones: the audience is 50+, so nothing here gets smaller than a thumb. */

/* ── /start: the ordering flow's two steps ───────────────────────────────────
   The review asked for a modal. This behaves like one - a focused sheet with a
   close button and nothing competing for attention - but it is a real page,
   because a modal has no address: it cannot be linked to, the back button does
   not close it, and a customer told "start here" over the phone has nothing to
   type. */

/* Step 2: how the artwork gets handled. Three routes, and the third one is a
   service on the shop's own line card, not a courtesy option. */

/* A 68ch column of questions in a 1200px container left half the band empty.
   Heading on the left, the questions beside it. */


/* Contact: the shop facts read as a panel, the same weight as the form beside
   them. Left as bare text they looked like a caption that had lost its picture,
   and the height difference between the two columns read as a hole. */
.site-contact-info {
  background: var(--brand-card); border: 1px solid var(--brand-ink-20);
  padding: clamp(16px, 3vw, 32px); align-self: start;
}
.site-contact-info .site-h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.9rem); }
.site-contact-info .site-facts .row:first-child { border-top: 0; padding-top: 0; }
.site-contact-info .site-facts .row:last-child { border-bottom: 0; padding-bottom: 0; }

/* ── The hero is exactly the drawing ─────────────────────────────────────────
   The start strip and the walk-in bar used to sit INSIDE this section, so they
   covered the bottom 180px of the picture and the shopfront was always cut off
   however the crop was tuned. They are siblings now, and the section takes the
   image's own proportion, so the whole building - roof to base, and the sign
   above it - is in frame at every width. */
@media (min-width: 760px) {
  .site-hero--cover {
    /* width:100% is load-bearing. With an auto width, `aspect-ratio` plus
       `max-height` makes the browser resolve the height first, hit the cap, and
       then SHRINK THE WIDTH to preserve the ratio - which left a 170px band of
       page showing past the right-hand edge of the hero on a wide screen. A
       definite width means max-height only ever crops. */
    width: 100%;
    min-height: 0;
    aspect-ratio: 1600 / 684;
    max-height: 76vh;
  }
  .site-hero--cover .site-hero-copy { padding-block: clamp(40px, 6vw, 76px); }
}

/* The request form runs one column now. It used to sit in a two-column grid with
   a "what happens next" aside, which pushed the artwork preview - the one thing
   the customer actually wants to look at - below the fold. */
.site-form-single { max-width: 860px; margin-inline: auto; }
.site-form-single .site-form { background: var(--brand-card); }

/* ── The reel: "off the press" (2026-10-06) ──────────────────────────────────
   The hero is a press sheet. The shop's footage is printed on a white sheet -
   crop marks outside its corners and a registration target in the margin - lying on a stack in the output tray. The ground is their blue at
   press density with a halftone field over it: Jimmy's "bubbles", made the way
   a printer makes them, heaviest behind the sheet and gone behind the headline
   so the type sits on flat colour. The colour control strip every press sheet
   carries IS the slideshow control: one process-ink patch per clip, filling
   as it runs. Nothing but the strip touches the footage. */
.site-hero--reel {
  position: relative; overflow: hidden; isolation: isolate; color: #fff;
  background:
    url("../img/halftone.svg") center / cover no-repeat,
    radial-gradient(ellipse 70% 90% at 78% 55%, var(--brand-accent) 0%, var(--brand-navy) 68%);
  background-color: var(--brand-navy);
  padding: 0;
}
.site-hero--reel::before { content: none; }
.site-reel-stage {
  display: grid; gap: clamp(36px, 6vw, 56px); align-items: center;
  padding-block: clamp(36px, 8vw, 56px) clamp(52px, 10vw, 72px);
  --cm: 16px;                       /* how far the crop marks sit outside the trim */
}
.site-reel-copy .site-display {
  color: #fff; max-width: 13ch;
  font-size: clamp(2.5rem, 1rem + 5.2vw, 5.1rem); line-height: .98; letter-spacing: -.025em;
  animation: site-rise 700ms cubic-bezier(.2, .7, .2, 1) both;
}
/* "since 1987." in the bright blue: 7:1 on the navy. */
.site-reel-mark { color: #a9c6f2; }
.site-reel-copy::before {
  content: ""; display: block; width: 56px; height: 4px; margin-bottom: var(--space-5);
  background: var(--brand-accent-bright);
}
.site-reel-copy .site-lede { color: rgba(255, 255, 255, .86); margin-top: var(--space-4); }

/* The output tray: two sheets already on the stack, the live one on top. */
.site-reel-tray { position: relative; margin-inline: calc(var(--cm) + 6px); }
.site-reel-tray::before, .site-reel-tray::after {
  content: ""; position: absolute; inset: 0; background: #e9eef6;
  box-shadow: 0 18px 40px -18px rgba(5, 14, 34, .6);
}
.site-reel-tray::before { transform: rotate(3.2deg) translate(10px, 6px); background: #dfe6f1; }
.site-reel-tray::after  { transform: rotate(-3.4deg) translate(-8px, 10px); }

.site-reel {
  position: relative; z-index: 1; background: #fff; color: var(--brand-primary);
  padding: 12px 12px 0;
  transform: rotate(-1.1deg);
  box-shadow: 0 34px 70px -24px rgba(5, 14, 34, .75), 0 1px 0 rgba(255, 255, 255, .6) inset;
}
.site-reel-window { position: relative; aspect-ratio: 1 / 1; overflow: hidden; background: #0d1a33; }
.site-reel-slide { position: absolute; inset: 0; margin: 0; visibility: hidden; }
.site-reel-slide.is-active { visibility: visible; z-index: 1; }
.site-reel-slide picture, .site-reel-slide img, .site-reel-slide video {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover;
}
/* A new clip FEEDS in from the top edge, the way a sheet comes through the press. */
.site-reel-slide.is-feeding { visibility: visible; z-index: 2; animation: site-feed 760ms cubic-bezier(.65, 0, .25, 1) both; }
@keyframes site-feed { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
/* The poster stays underneath; the clip fades up only once frames are playing,
   so a slow connection never shows a black box. */
.site-reel-slide video { opacity: 0; transition: opacity 400ms ease; }
.site-reel-slide video.is-playing { opacity: 1; }

/* Crop marks, outside the trim, collinear with its edges. */
.site-reel-crop {
  position: absolute; width: calc(var(--cm) + 10px); height: calc(var(--cm) + 10px);
  color: rgba(255, 255, 255, .78); pointer-events: none;
  background:
    linear-gradient(currentColor, currentColor) no-repeat,
    linear-gradient(currentColor, currentColor) no-repeat;
  background-size: 1px var(--cm), var(--cm) 1px;
}
.site-reel-crop.is-tl { top: calc(-1 * (var(--cm) + 10px)); left: calc(-1 * (var(--cm) + 10px)); background-position: 100% 0, 0 100%; }
.site-reel-crop.is-tr { top: calc(-1 * (var(--cm) + 10px)); right: calc(-1 * (var(--cm) + 10px)); background-position: 0 0, 100% 100%; }
.site-reel-crop.is-bl { bottom: calc(-1 * (var(--cm) + 10px)); left: calc(-1 * (var(--cm) + 10px)); background-position: 100% 100%, 0 0; }
.site-reel-crop.is-br { bottom: calc(-1 * (var(--cm) + 10px)); right: calc(-1 * (var(--cm) + 10px)); background-position: 0 100%, 100% 0; }

/* The sheet's margin: colour bar, slug, registration target. */
.site-reel-margin { display: flex; align-items: center; gap: var(--space-3); padding: 10px 0 12px; min-height: 52px; }
.site-reel-bar { display: flex; gap: 3px; flex: none; }
.site-reel-pause, .site-reel-patch {
  position: relative; width: 28px; height: 28px; padding: 0; border-radius: 0; cursor: pointer;
  display: grid; place-items: center;
}
.site-reel-pause { border: 1px solid var(--brand-primary); background: #fff; color: var(--brand-primary); margin-right: 4px; }
.site-reel-pause:hover { background: var(--brand-primary); color: #fff; }
.site-reel-pause .i-play { display: none; }
.site-reel.is-paused .site-reel-pause .i-play { display: block; }
.site-reel.is-paused .site-reel-pause .i-pause { display: none; }
/* A patch is its ink at a 20% tint; the playing clip's patch fills to solid. */
.site-reel-patch { border: 0; background: color-mix(in srgb, var(--ink) 22%, #fff); overflow: hidden; }
.site-reel-patch span {
  position: absolute; inset: 0; background: var(--ink);
  transform-origin: left; transform: scaleX(var(--p, 0));
}
.site-reel-patch[aria-current="true"] { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
.site-reel-patch.is-done span { transform: scaleX(1); }
.site-reel-patch.is-cyan    { --ink: #009ad8; }
.site-reel-patch.is-magenta { --ink: #c8007a; }
.site-reel-patch.is-yellow  { --ink: #f0bf00; }
.site-reel-patch.is-key     { --ink: #231f20; }
.site-reel-pause:focus-visible, .site-reel-patch:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; }
.site-reel-reg { flex: none; margin-left: auto; color: var(--brand-primary); opacity: .8; }

/* Load: the stack is there, the live sheet drops onto it. */
.site-reel { animation: site-sheet-land 900ms cubic-bezier(.2, .8, .2, 1) 120ms both; }
@keyframes site-sheet-land {
  from { opacity: 0; transform: translateY(-36px) rotate(-5deg); }
  to   { opacity: 1; transform: rotate(-1.1deg); }
}

@media (min-width: 900px) {
  .site-reel-stage {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(48px, 5vw, 80px);
    padding-block: clamp(56px, 6vw, 92px) clamp(64px, 7vw, 104px);
    --cm: 24px;
  }
  .site-reel-window { aspect-ratio: 4 / 3; }
  .site-reel { padding: 16px 16px 0; }
  .site-reel-margin { padding: 12px 0 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .site-reel, .site-reel-copy .site-display, .site-reel-slide.is-feeding { animation: none; }
  .site-reel-slide video { transition: none; }
}

/* The job ticket: the start form inside the reel hero, white on the navy like
   the sheet beside it. Job across the top; quantity and Start share a row. */
.site-reel-ticket {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3) var(--space-3);
  align-items: end; margin-top: clamp(24px, 4vw, 36px); max-width: 480px;
  padding: var(--space-5); background: #fff; color: var(--text);
  box-shadow: 0 24px 50px -24px rgba(5, 14, 34, .7);
  animation: site-rise 700ms cubic-bezier(.2, .7, .2, 1) 160ms both;
}
.site-reel-ticket .is-job { grid-column: 1 / -1; }
.site-reel-ticket .site-startstrip-field select,
.site-reel-ticket .site-startstrip-field input { background: var(--brand-card); }
.site-reel-ticket .site-btn { min-height: var(--control-min); padding-inline: var(--space-6); }
@media (prefers-reduced-motion: reduce) { .site-reel-ticket { animation: none; } }

/* The walk-in bar is the foot of the navy hero, not a separate black slab. */
.site-hero--reel + .site-herobar {
  background: #0c1f42; border-top: 1px solid rgba(255, 255, 255, .12);
}
.site-hero--reel + .site-herobar .site-herobar-item svg { color: #a9c6f2; }

/* Phone/tablet: the headline takes the full measure (the 13ch cap is for sitting
   beside the sheet), and the ticket's question reads as the call to action -
   ink, sentence weight, not a small grey caps label. */
@media (max-width: 899px) {
  .site-reel-copy .site-display { max-width: none; font-size: clamp(2.6rem, 1.1rem + 6.4vw, 3.6rem); }
  .site-reel-ticket { max-width: none; padding: var(--space-4); }
}
.site-reel-ticket .site-startstrip-field label {
  font-size: 1.05rem; font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--brand-primary);
}
.site-reel-ticket .is-qty label { font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); }
/* Phones: the footage leads, then the headline, then the ticket (2026-10-06).
   Visual order only - the source stays headline-first for screen readers. */
@media (max-width: 899px) {
  .site-reel-tray { order: -1; }
  .site-reel-stage { padding-top: clamp(40px, 10vw, 56px); gap: clamp(40px, 9vw, 52px); }
}

/* ── Header, two rows (2026-10-06) ────────────────────────────────────────────
   Top: logo, the product finder, account and cart. Under it, the category row
   that opens the visual services panel. Replaces the single measured nav row;
   the old .site-header-inner / .site-nav / .site-navdrop rules are now unused. */
.site-header-top {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: var(--space-3) clamp(16px, 3vw, 40px); padding-block: var(--space-3);
}
.site-header-top .site-brand img { height: 44px; }
@media (min-width: 900px) { .site-header-top { padding-block: var(--space-4); } .site-header-top .site-brand img { height: 52px; } }

.site-search { position: relative; display: flex; align-items: center; }
.site-search input {
  width: 100%; height: 48px; padding: 0 56px 0 var(--space-5);
  border: 1.5px solid var(--brand-ink-20); border-radius: 999px; background: #fff;
  font-family: var(--font-body); font-size: 1rem; color: var(--text);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.site-search input::placeholder { color: var(--text-muted); }
.site-search input:focus { outline: none; border-color: var(--brand-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-accent) 18%, transparent); }
.site-search input::-webkit-search-cancel-button { display: none; }
.site-search > button {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 999px; border: 0; cursor: pointer;
  display: grid; place-items: center; background: var(--brand-accent); color: #fff;
}
.site-search > button svg { width: 18px; height: 18px; }
.site-search > button:hover { background: var(--brand-accent-deep); }
.site-search-list {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 60;
  margin: 0; padding: 6px; list-style: none; background: #fff;
  border: 1px solid var(--brand-ink-20); border-radius: 14px;
  box-shadow: 0 24px 50px -24px rgba(19, 47, 96, .45);
}
.site-search-list a {
  display: grid; grid-template-columns: 48px minmax(0, 1fr); align-items: center; gap: var(--space-3);
  padding: 6px 8px; border-radius: 10px; color: var(--text); text-decoration: none;
}
.site-search-list a[aria-selected="true"], .site-search-list a:hover { background: var(--brand-card); text-decoration: none; }
.site-search-list .thumb { width: 48px; height: 36px; border-radius: 6px; overflow: hidden; background: var(--brand-paper); }
.site-search-list .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.site-search-list b { display: block; font-weight: 700; font-size: .98rem; }
.site-search-list small { display: block; color: var(--text-muted); font-size: var(--fs-xs); }
.site-search-list mark { background: none; color: var(--brand-accent); }
.site-search-empty { padding: var(--space-3) var(--space-4); color: var(--text-soft); font-size: var(--fs-sm); }

.site-header-icons { display: flex; align-items: center; gap: var(--space-2); }
.site-iconbtn {
  position: relative; display: grid; place-items: center; width: 48px; height: 48px; flex: none;
  border: 1.5px solid var(--brand-ink-20); border-radius: 999px; background: #fff;
  color: var(--brand-primary); cursor: pointer; text-decoration: none;
  transition: border-color var(--transition), color var(--transition);
}
.site-iconbtn:hover { border-color: var(--brand-accent); color: var(--brand-accent); text-decoration: none; }
.site-iconbtn-count {
  position: absolute; top: -3px; right: -3px; min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 999px; background: var(--brand-accent); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 20px; text-align: center;
}
.site-header .site-nav-toggle { display: none; }

/* Category row. */
.site-navrow { position: relative; border-top: 1px solid var(--brand-ink-20); }
.site-navrow-inner { display: flex; align-items: stretch; justify-content: space-between; gap: var(--space-5); }
.site-navrow-inner > ul { display: flex; align-items: stretch; list-style: none; margin: 0; padding: 0; }
.site-navrow-cats { gap: 2px; }
.site-navrow-pages { gap: var(--space-5); align-items: center; }
.site-cattab {
  position: relative; display: inline-flex; align-items: center; gap: 6px; height: 50px; padding: 0 var(--space-3);
  border: 0; background: transparent; cursor: pointer; white-space: nowrap;
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 500; color: var(--brand-ink-80);
}
.site-cattab.is-all { font-weight: 700; color: var(--brand-primary); padding-left: 0; }
.site-cattab svg { width: 14px; height: 14px; transition: transform var(--transition); }
.site-cattab::after {
  content: ""; position: absolute; left: var(--space-3); right: var(--space-3); bottom: -1px; height: 3px;
  background: var(--brand-accent); transform: scaleX(0); transition: transform 200ms ease;
}
.site-cattab.is-all::after { left: 0; }
.site-cattab:hover, .site-cattab[aria-expanded="true"] { color: var(--brand-accent); }
.site-cattab[aria-expanded="true"]::after { transform: scaleX(1); }
.site-cattab.is-all[aria-expanded="true"] svg { transform: rotate(180deg); }
.site-navrow-pages a {
  font-size: var(--fs-sm); font-weight: 700; color: var(--brand-ink-80); text-decoration: none; white-space: nowrap;
}
.site-navrow-pages a:hover, .site-navrow-pages a[aria-current="page"] { color: var(--brand-accent); }
.site-navrow-pages a.site-navrow-cta { color: var(--brand-accent); }
.site-navrow-pages a.site-navrow-cta::after { content: " \2192"; }

/* The services panel: categories down the left, photo tiles on the right. */
.site-mega {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 49;
  background: #fff; border-top: 1px solid var(--brand-ink-20);
  box-shadow: 0 40px 70px -40px rgba(19, 47, 96, .55);
}
.site-mega-inner {
  display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: clamp(24px, 3vw, 48px);
  padding-block: var(--space-6) var(--space-7);
}
.site-mega-cats { list-style: none; margin: 0; padding: 0; display: grid; align-content: start; gap: 2px; }
.site-mega-cats button {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: 12px 14px; border: 0; border-radius: 10px; background: transparent; cursor: pointer; text-align: left;
  font-family: var(--font-body); font-size: 1rem; font-weight: 600; color: var(--brand-ink-80);
}
.site-mega-cats button svg { width: 16px; height: 16px; opacity: 0; transition: opacity var(--transition), transform var(--transition); }
.site-mega-cats button:hover, .site-mega-cats button[aria-current="true"] { background: var(--brand-card); color: var(--brand-accent); }
.site-mega-cats button[aria-current="true"] svg { opacity: 1; transform: translateX(2px); }
.site-mega-all { margin-top: var(--space-4); padding: var(--space-4) 14px 0; border-top: 1px solid var(--brand-ink-20); }
.site-mega-all a { font-weight: 700; color: var(--brand-primary); text-decoration: underline; text-underline-offset: 4px; }
.site-mega-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-4); }
.site-mega-head h3 { font-family: var(--font-display); font-size: 1.6rem; font-weight: 600; color: var(--brand-primary); }
.site-mega-head a { font-weight: 700; font-size: var(--fs-sm); color: var(--brand-accent); }
.site-mega-tiles {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-4);
}
.site-mega-tiles a { display: grid; gap: var(--space-2); color: var(--text); text-decoration: none; }
.site-mega-img { display: block; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 10px; background: var(--brand-card); }
.site-mega-img img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 400ms cubic-bezier(.2, .7, .2, 1); }
.site-mega-tiles a:hover .site-mega-img img { transform: scale(1.05); }
.site-mega-label { font-weight: 600; font-size: .95rem; }
.site-mega-tiles a:hover .site-mega-label { color: var(--brand-accent); }
.site-mega-pane { animation: site-rise 260ms ease both; }
@media (prefers-reduced-motion: reduce) { .site-mega-pane { animation: none; } .site-mega-img img { transition: none; } }

/* Below 1100px the category row no longer fits: search drops to its own row,
   the hamburger appears, and the drawer carries the categories. */
@media (max-width: 1099px) {
  .site-navrow { display: none; }
  .site-header .site-nav-toggle { display: grid; }
}
@media (max-width: 759px) {
  .site-header-top { grid-template-columns: auto 1fr; }
  .site-header-top .site-search { grid-column: 1 / -1; grid-row: 2; }
  .site-header-icons { justify-self: end; }
  .site-iconbtn { width: 44px; height: 44px; }
  .site-search input { height: 46px; }
}

/* Drawer: categories as expanding groups, then the pages. */
.site-drawer-group { border-bottom: 1px solid var(--brand-ink-20); }
.site-drawer-group summary {
  list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center;
  padding: var(--space-4) 0; font-family: var(--font-display); font-weight: 600; font-size: 1.35rem; color: var(--text);
}
.site-drawer-group summary::-webkit-details-marker { display: none; }
.site-drawer-group summary::after { content: "+"; font-family: var(--font-body); font-weight: 400; font-size: 1.6rem; color: var(--brand-accent); }
.site-drawer-group[open] summary::after { content: "\2212"; }
.site-drawer-group ul { list-style: none; margin: 0; padding: 0 0 var(--space-4); display: grid; gap: 2px; }
.site-drawer nav .site-drawer-group a { display: block; border: 0; font-family: var(--font-body); font-size: 1rem; padding: 8px 0; color: var(--brand-ink-80); font-weight: 500; text-decoration: none; }
.site-drawer .site-drawer-pages { margin-top: var(--space-5); }
.site-drawer nav .site-drawer-pages a { font-size: 1.15rem; font-family: var(--font-body); font-weight: 700; }
.site-drawer-cta { width: 100%; margin-top: var(--space-6); justify-content: center; }

/* ── The ask + how it works: one section (2026-10-06) ───────────────────────── */
.site-order { background: var(--brand-paper); padding-block: clamp(56px, 8vw, 104px); }
.site-order-inner { display: grid; gap: clamp(40px, 6vw, 72px); align-items: center; }
.site-order-ask .site-h2 { font-size: clamp(2.2rem, 1.2rem + 3vw, 3.4rem); color: var(--brand-primary); }
.site-order-ask .site-lede { color: var(--brand-ink-80); margin-top: var(--space-4); max-width: 40ch; }
.site-order-ask .site-actions { margin-top: var(--space-6); }
/* The ticket: white stock, crop marks (the site's signature), ruled rows. */
.site-order-ticket { background: #fff; padding: clamp(24px, 3.5vw, 40px); box-shadow: 0 30px 60px -36px rgba(19, 47, 96, .45); }
.site-order-ticket-title {
  font-family: var(--brand-font-mono); font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--brand-accent);
  padding-bottom: var(--space-4); border-bottom: 2px solid var(--brand-primary);
}
.site-order-steps { list-style: none; margin: 0; padding: 0; }
.site-order-steps li {
  display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: var(--space-4);
  padding-block: var(--space-5); border-bottom: 1px dashed var(--brand-ink-20);
}
.site-order-steps li:last-child { border-bottom: 0; padding-bottom: 0; }
.site-order-steps .n {
  font-family: var(--font-display); font-size: 2.6rem; font-weight: 600; line-height: .9; color: var(--brand-accent);
  font-variant-numeric: tabular-nums;
}
.site-order-steps h4 { font-family: var(--font-display); font-size: 1.3rem; font-weight: 600; color: var(--brand-primary); }
.site-order-steps p { margin-top: var(--space-2); color: var(--text-soft); max-width: 46ch; }
@media (min-width: 900px) { .site-order-inner { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }

/* The footer closes on the hero's navy, not a third dark. */
.site-footer { background: #0c1f42; }

/* Hero: a way in for someone who does not know what to pick yet. */
.site-reel-start {
  display: inline-block; margin-top: var(--space-4); color: #fff; font-weight: 700;
  text-decoration: underline; text-decoration-color: rgba(255, 255, 255, .45); text-underline-offset: 4px;
}
.site-reel-start::after { content: " \2192"; }
.site-reel-start:hover { color: #fff; text-decoration-color: #fff; }

/* Product page: what we need, as a checklist under the actions. */
.site-needs { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--brand-ink-20); max-width: 52ch; }
.site-needs-title {
  font-family: var(--brand-font-mono); font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--brand-accent); margin-bottom: var(--space-3);
}
.site-needs ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-needs li { position: relative; padding-left: 28px; color: var(--brand-ink-80); line-height: 1.5; }
.site-needs li::before {
  content: ""; position: absolute; left: 2px; top: .3em; width: 16px; height: 16px; border-radius: 999px;
  background: var(--brand-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12 4 4 8-8'/%3E%3C/svg%3E") center / 11px no-repeat;
}

/* Services panel, text only (2026-10-06: photos read less professional). */
.site-mega-list {
  list-style: none; margin: 0; padding: 0;
  columns: 3 180px; column-gap: var(--space-6);
}
.site-mega-list li { break-inside: avoid; }
.site-mega-list a {
  display: block; padding: 9px 0; border-bottom: 1px solid var(--brand-card);
  color: var(--brand-ink-80); font-weight: 500; text-decoration: none;
}
.site-mega-list a:hover { color: var(--brand-accent); text-decoration: none; }
.site-mega-list a::after { content: " \2192"; opacity: 0; transition: opacity var(--transition); }
.site-mega-list a:hover::after { opacity: 1; }
.site-navrow-inner > .site-navrow-pages { align-items: center; gap: var(--space-5); }
.site-navrow-inner > .site-navrow-cats { gap: 2px; }
.site-navrow-inner > .site-navrow-pages { align-items: center; gap: var(--space-5); }
.site-navrow-inner > .site-navrow-cats { gap: 2px; }

/* Drawer (2026-10-06): the real lockup on top, ONE type voice for every row
   (the categories were in the display serif and the pages in the sans), and
   the CTA keeps button colours - the drawer's link rule was painting it ink. */
.site-drawer { background: var(--brand-card); }
.site-drawer-head .site-brand img { height: 40px; width: auto; display: block; }
.site-drawer nav .site-drawer-group summary,
.site-drawer nav .site-drawer-pages a {
  font-family: var(--font-body); font-size: 1.12rem; font-weight: 700; color: var(--brand-primary);
  padding: var(--space-4) 0;
}
.site-drawer nav .site-drawer-pages { margin-top: 0; }
.site-drawer nav .site-drawer-pages a { border-bottom: 1px solid var(--brand-ink-20); }
.site-drawer nav .site-drawer-group a { color: var(--brand-ink-80); font-weight: 500; padding: 10px 0 10px var(--space-3); }
.site-drawer nav a.site-drawer-cta {
  display: flex; justify-content: center; align-items: center; width: 100%; margin-top: var(--space-6);
  min-height: 52px; padding: 0 var(--space-5); border: 0;
  background: var(--brand-accent); color: #fff;
  font-family: var(--font-body); font-size: 1.05rem; font-weight: 700;
}
.site-drawer nav a.site-drawer-cta:hover { background: var(--brand-accent-deep); color: #fff; }

/* Delivery: ZIP check on /print/delivery. */
.site-zipcheck {
  margin-top: var(--space-6); padding: var(--space-5); max-width: 460px;
  background: #fff; border-left: 4px solid var(--brand-accent);
}
.site-zipcheck label { display: block; font-weight: 700; font-size: 1.1rem; color: var(--brand-primary); margin-bottom: var(--space-3); }
.site-zipcheck-row { display: flex; gap: var(--space-2); }
.site-zipcheck input {
  flex: 1; min-width: 0; min-height: var(--control-min); padding: 0 var(--space-3);
  border: 1px solid var(--brand-ink-20); border-radius: 2px; background: var(--brand-card);
  font-family: var(--font-body); font-size: 1.1rem; letter-spacing: .08em;
}
.site-zipcheck input:focus { border-color: var(--brand-accent); outline-color: var(--brand-accent); }
.site-zipcheck .site-btn { min-height: var(--control-min); }
.site-zipcheck-answer { margin: var(--space-3) 0 0; font-weight: 600; color: var(--brand-ink-80); min-height: 1.5em; }
.site-zipcheck-answer.is-free { color: #1d6b45; }
.site-zipcheck-answer:empty { display: none; }

/* ── Services: the catalogue (2026-10-06) ─────────────────────────────────────
   Category title on the left, its products as compact rows on the right. Each
   row keeps its product-shaped mark, small. */
.site-catalog { padding-block: clamp(32px, 5vw, 64px); }
.site-catalog-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-6); }
.site-catalog-head .site-h2 { color: var(--brand-primary); }
.site-catalog-q { margin: 0; color: var(--text-soft); }
.site-catalog-q a { margin-left: var(--space-3); font-weight: 700; }
.site-catalog-group {
  display: grid; gap: var(--space-4);
  padding-block: var(--space-6); border-top: 2px solid var(--brand-primary);
}
.site-catalog-title { font-family: var(--font-display); font-size: 1.5rem; font-weight: 600; color: var(--brand-primary); }
.site-catalog-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0 var(--space-6); }
.site-catalog-list a {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: var(--space-4);
  padding: 14px var(--space-3); margin-inline: calc(-1 * var(--space-3));
  border-bottom: 1px solid var(--brand-ink-20); color: var(--text); text-decoration: none;
  transition: background var(--transition);
}
.site-catalog-list a:hover { background: #fff; text-decoration: none; }
.site-catalog-mark { display: flex; align-items: center; justify-content: center; height: 32px; }
.site-catalog-mark svg { height: 100%; width: auto; max-width: 56px; }
.site-catalog-name { display: block; font-weight: 700; font-size: 1.05rem; color: var(--brand-primary); }
.site-catalog-meta { display: block; margin-top: 2px; font-size: var(--fs-sm); color: var(--text-muted); }
.site-catalog-go { color: var(--brand-accent); opacity: .35; transition: opacity var(--transition), transform var(--transition); }
.site-catalog-list a:hover .site-catalog-go { opacity: 1; transform: translateX(3px); }
@media (min-width: 700px) { .site-catalog-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) {
  .site-catalog-group { grid-template-columns: 260px minmax(0, 1fr); gap: var(--space-7); }
  .site-catalog-title { position: sticky; top: calc(var(--site-header-h, 80px) + 16px); align-self: start; }
}
.site-catalog-more { padding-block: 0 clamp(40px, 6vw, 80px); }
.site-catalog-more-inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5) var(--space-6); background: #fff; border-left: 4px solid var(--brand-accent);
}
.site-catalog-more p { margin: 0; font-family: var(--font-display); font-size: 1.3rem; font-weight: 600; color: var(--brand-primary); }
.site-catalog-more .site-actions { margin: 0; }

/* Contact: the map under the details, filling the column beside the form. */
.site-contact-left { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.site-contact-map { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.site-contact-map .site-map { flex: 1; min-height: 240px; aspect-ratio: auto; }
.site-contact-dir { align-self: flex-start; font-weight: 700; }
.site-contact-dir::after { content: " \2192"; }
@media (min-width: 900px) {
  .site-contact-top { align-items: stretch; }
  .site-contact-map .site-map { min-height: 280px; }
}

/* Contact rows: tappable actions, white on the card blue. */
.site-contact-info { background: transparent; border: 0; padding: 0; align-self: stretch; }
.site-contact-info .site-h2 { font-size: clamp(2rem, 1.3rem + 2.4vw, 3rem); color: var(--brand-primary); margin-bottom: var(--space-5); }
.site-contact-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-contact-rows a, .site-contact-rows li > div {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: var(--space-4);
  padding: 14px var(--space-4); background: #fff; color: var(--text); text-decoration: none;
  border: 1px solid transparent; transition: border-color var(--transition);
}
.site-contact-rows li > div { background: transparent; padding-block: 10px; }
.site-contact-rows a::after { content: "\203A"; font-size: 1.6rem; line-height: 1; color: var(--brand-accent); }
.site-contact-rows a:hover { border-color: var(--brand-accent); text-decoration: none; }
.site-contact-rows .ic {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 999px;
  background: color-mix(in srgb, var(--brand-accent) 12%, #fff); color: var(--brand-accent);
}
.site-contact-rows li > div .ic { background: transparent; }
.site-contact-rows .t { min-width: 0; }
.site-contact-rows b { display: block; font-size: 1.05rem; color: var(--brand-primary); }
.site-contact-rows .t span { display: block; color: var(--text-soft); overflow-wrap: anywhere; }
.site-contact-rows a .t span { color: var(--brand-accent); font-weight: 600; }
.site-contact-dir { display: none; }
/* ══════════════════════════════════════════════════════════════════════════════
   REQUEST BASKET + CUSTOMER ACCOUNT (2026-10-06, docs/plans/customer-accounts-spec.md)
   ══════════════════════════════════════════════════════════════════════════════
   /request is one page now: numbered sections a customer reads top to bottom,
   only the chosen artwork option's fields open, contact details at /cart. The
   six-step wizard, the icon-grid picker and the "Printing: X" banner are gone. */

/* ── /request: numbered sections ──────────────────────────────────────────── */
.site-reqstep + .site-reqstep { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 1px solid var(--brand-ink-20); }
.site-reqstep-h {
  display: flex; align-items: center; gap: var(--space-3); margin: 0 0 var(--space-3);
  font-family: var(--font-display); font-weight: 700; line-height: 1.2;
  font-size: clamp(1.3rem, 1.15rem + .6vw, 1.55rem); color: var(--brand-primary);
}
.site-reqstep-h .n {
  display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 999px;
  background: var(--brand-accent); color: var(--brand-on-accent);
  font-family: var(--font-body); font-size: 1rem; font-variant-numeric: tabular-nums;
}
.site-reqstep-h label { font: inherit; color: inherit; cursor: pointer; }
.site-reqstep > select {
  width: 100%; min-height: 52px; font-size: 1.1rem;
  border: 1px solid var(--brand-ink-20); border-radius: 2px; background: #fff;
}
.site-reqstep > select:focus { border-color: var(--brand-accent); outline-color: var(--brand-accent); }
.site-reqstep .site-qty { margin: var(--space-4) 0 0; max-width: 16rem; }

/* ── The job jacket's questions: tap-to-pick chips ───────────────────────────
   Each group is a real radio (or checkbox) set styled as pills, so it works
   with JS off and on a phone it is a thumb-sized target, never a dropdown.
   Radio groups open on "Not sure"; the one hint above them says what that
   means. The pills wrap, so a 13-stock group is rows of pills at 375px, not a
   sideways scroll. */
.site-jq-hint { margin: 0; color: var(--text-muted); font-size: var(--fs-sm); }
/* Space above each group, not below: a hidden NCR/envelope group at the end
   then leaves no gap behind it. */
.site-jq { border: 0; margin: var(--space-5) 0 0; padding: 0; min-width: 0; }
.site-jq-h { padding: 0; margin: 0 0 var(--space-2); font-weight: 700; font-size: var(--fs-sm); color: var(--brand-ink-80); }
.site-picks { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.site-pick { position: relative; display: inline-flex; min-width: 0; }
.site-pick input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; min-height: 0; }
.site-pick span {
  display: inline-flex; align-items: center; min-height: var(--control-min, 44px); padding: 0 var(--space-4);
  border: 1px solid var(--brand-ink-20); border-radius: 999px; background: #fff;
  font-weight: 600; line-height: 1.2; cursor: pointer; user-select: none;
}
.site-pick span:hover { border-color: var(--brand-primary); }
.site-pick input:focus-visible + span { outline: 3px solid var(--brand-accent-bright); outline-offset: 2px; }
.site-pick input:checked + span { background: var(--brand-accent); border-color: var(--brand-accent); color: var(--brand-on-accent); }
/* A ticked finishing shows a tick, not only a colour. */
.site-pick input[type="checkbox"]:checked + span::before {
  content: ""; width: 6px; height: 11px; margin: -3px var(--space-2) 0 0; flex: none;
  border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.site-jq .site-field { margin: var(--space-3) 0 0; max-width: 24rem; }

/* "Other": its text box opens when Other is picked. Without :has it simply
   shows, and typing into it is enough (JobForm::composeSpec). */
.site-pick-other { display: none; }
@supports selector(:has(a)) {
  .site-jq:has(input[value="other"]:checked) .site-pick-other { display: grid; }
}
@supports not selector(:has(a)) {
  .site-pick-other { display: grid; }
}

/* NCR parts and envelopes only for the products they apply to. The server
   writes data-kind for the product the page opened with and site.js keeps it
   current; with :has the chosen option's data-kinds is the only truth. */
.site-jobform [data-kind-panel] { display: none; }
.site-jobform[data-kind~="ncr"] [data-kind-panel="ncr"],
.site-jobform[data-kind~="envelope"] [data-kind-panel="envelope"] { display: block; }
@supports selector(:has(a)) {
  .site-jobform[data-kind] [data-kind-panel] { display: none; }
  .site-jobform:has([data-job-select] option[data-kinds~="ncr"]:checked) [data-kind-panel="ncr"],
  .site-jobform:has([data-job-select] option[data-kinds~="envelope"]:checked) [data-kind-panel="envelope"] { display: block; }
}

/* ── The artwork choice: three plain, equal cards ────────────────────────────
   One big label each, an icon, and a tick when chosen. The grid flows by
   column so a hidden "Design it myself online" leaves two equal cards, not a
   gap. */
.site-artfork { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
@media (min-width: 640px) { .site-artfork { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); } }
.site-artfork > li { display: flex; }
.site-artfork-card {
  position: relative; display: flex; align-items: center; gap: var(--space-3); width: 100%;
  min-height: 76px; padding: var(--space-3) var(--space-6) var(--space-3) var(--space-4);
  border: 2px solid var(--brand-ink-20); background: #fff; color: var(--brand-primary); text-decoration: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.site-artfork-card { cursor: pointer; }
.site-artfork-card:hover { border-color: var(--brand-primary); text-decoration: none; }
/* The radio is the control; the card is its label. Visually hidden, still
   focusable and announced, so keyboard and screen-reader users choose the same way. */
.site-artfork-input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.site-artfork-card:has(.site-artfork-input:focus-visible) { outline: 3px solid var(--brand-accent-bright); outline-offset: 2px; }
.site-artfork-card:has(.site-artfork-input:checked) { border-color: var(--brand-accent); box-shadow: 0 0 0 1px var(--brand-accent); }
.site-artfork-card:has(.site-artfork-input:checked) .site-artfork-tick { border-color: var(--brand-accent); background: var(--brand-accent); }
.site-artfork-card:has(.site-artfork-input:checked) .site-artfork-tick::after {
  content: ""; position: absolute; left: 5px; top: 1px; width: 6px; height: 11px;
  border: solid #fff; border-width: 0 2.5px 2.5px 0; transform: rotate(45deg);
}
.site-artfork-mark { color: var(--brand-accent); flex: none; }
.site-artfork-mark svg { width: 32px; height: 32px; display: block; }
.site-artfork-h { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.3rem, 1.2rem + .4vw, 1.5rem); line-height: 1.15; }
.site-artfork-tick {
  position: absolute; top: 8px; right: 8px; width: 22px; height: 22px;
  border: 2px solid var(--brand-ink-20); border-radius: 999px; background: #fff;
}

/* Only the chosen option's fields show. :has reads the checked radio with no
   script; data-route (server-rendered, kept in step by site.js) covers browsers
   without :has. data-panel lists the options a block belongs to. */
.site-reqstep--art { border: 0; margin: 0; padding: 0; min-width: 0; }
.site-reqstep--art legend { padding: 0; }
.site-jobform [data-panel] { display: none; }
.site-jobform[data-route="have"] [data-panel~="have"],
.site-jobform[data-route="design"] [data-panel~="design"],
.site-jobform[data-route="shop"] [data-panel~="shop"],
.site-jobform[data-route="bring"] [data-panel~="bring"],
.site-jobform:has(input[name="art_route"][value="bring"]:checked) [data-panel~="bring"],
.site-jobform:has(input[name="art_route"][value="have"]:checked) [data-panel~="have"],
.site-jobform:has(input[name="art_route"][value="design"]:checked) [data-panel~="design"],
.site-jobform:has(input[name="art_route"][value="shop"]:checked) [data-panel~="shop"] { display: block; }
/* With :has available the radio is the only truth - a stale data-route must not
   keep the previous option's fields open. */
@supports selector(:has(a)) {
  .site-jobform[data-route] [data-panel] { display: none; }
  .site-jobform:has(input[name="art_route"][value="have"]:checked) [data-panel~="have"],
  .site-jobform:has(input[name="art_route"][value="design"]:checked) [data-panel~="design"],
  .site-jobform:has(input[name="art_route"][value="shop"]:checked) [data-panel~="shop"],
  .site-jobform:has(input[name="art_route"][value="bring"]:checked) [data-panel~="bring"] { display: block; }
}

/* The chosen option's fields, directly under the cards - no boxed panel. */
.site-reqform .site-artpanel, .site-jobform .site-artpanel { margin: var(--space-4) 0 0; padding: 0; background: none; border: 0; }
.site-uppanel { margin-top: var(--space-4); }

/* Upload as one row: a button and the accepted formats. Not a tall dashed box. */
.site-drop--row {
  min-height: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start;
  gap: var(--space-2) var(--space-4); padding: var(--space-3); text-align: left;
  border: 1px dashed var(--brand-ink-20); background: #fff;
}
.site-drop--row .site-drop-btn {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--space-5);
  background: var(--brand-primary); color: #fff;
  font-family: var(--font-body); font-size: 1rem; font-weight: 700;
}
.site-drop--row:focus-within .site-drop-btn, .site-drop--row.drag-over .site-drop-btn { background: var(--brand-accent); }
.site-drop--row .hint { font-size: var(--fs-sm); }

/* "File too big to upload?" and "Add size, paper or finishing": a small link
   that opens its field. */
.site-linkfield { margin-top: var(--space-2); }
.site-linkfield summary {
  display: inline-flex; align-items: center; min-height: 44px; cursor: pointer;
  font-size: var(--fs-sm); font-weight: 700; color: var(--brand-accent);
}
.site-linkfield[open] summary { margin-bottom: var(--space-2); }
.site-linkfield .site-row { margin-bottom: 0; }

.site-filelist--kept { margin: 0 0 var(--space-3); }
.site-filelist--kept li { grid-template-columns: minmax(0, 1fr) auto auto; }
.site-check--sm { margin: 0; min-height: 44px; font-size: var(--fs-sm); }

.site-trap { position: absolute; left: -9999px; }

.site-reqbar { margin: 0; font-size: var(--fs-sm); color: var(--text-soft); }
.site-reqbar a { font-weight: 700; color: var(--brand-accent); }

/* ── Flash messages on the public pages ───────────────────────────────────── */
.site-flashes { display: grid; gap: var(--space-2); margin-bottom: var(--space-4); }
.site-flash {
  margin: 0 0 var(--space-3); padding: var(--space-3) var(--space-4); background: #fff;
  border-left: 3px solid var(--brand-accent); font-size: var(--fs-sm); color: var(--brand-ink-80);
}
.site-flashes .site-flash { margin: 0; }
.site-flash--error { border-left-color: var(--ink-red); }
.site-flash a { font-weight: 700; color: var(--brand-accent); }

/* ── /cart ─────────────────────────────────────────────────────────────────── */
.site-cart-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-4);
}
.site-cart-items { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.site-cart-item { display: grid; gap: var(--space-3); padding: var(--space-4); background: #fff; border: 1px solid var(--brand-ink-20); }
.site-cart-item-name { margin: 0 0 var(--space-2); font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; line-height: 1.2; }
.site-cart-facts { margin: 0; display: grid; gap: var(--space-1); }
.site-cart-facts > div { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: var(--space-3); font-size: var(--fs-sm); }
.site-cart-facts dt { color: var(--text-muted); font-weight: 600; }
.site-cart-facts dd { margin: 0; overflow-wrap: anywhere; }
.site-cart-clip { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-line; }
.site-cart-item-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.site-linkbtn {
  min-height: 44px; padding: 0 var(--space-3); background: none; border: 0; cursor: pointer;
  font: inherit; font-weight: 700; color: var(--ink-red); text-decoration: underline;
}
.site-cart-signed { margin: 0 0 var(--space-4); font-size: var(--fs-sm); color: var(--text-soft); }
.site-cart-signed a { font-weight: 700; color: var(--brand-accent); }
.site-cart-empty .site-actions { margin-top: var(--space-4); }

/* ── /account ──────────────────────────────────────────────────────────────── */
.site-acct-card {
  max-width: 460px; margin-inline: auto; padding: clamp(20px, 4vw, 32px);
  background: #fff; border: 1px solid var(--brand-ink-20);
}
.site-acct-card .site-h2 { font-size: var(--fs-h2); margin-bottom: var(--space-2); }
.site-acct-tabs { display: grid; grid-template-columns: 1fr 1fr; margin-bottom: var(--space-5); border-bottom: 1px solid var(--brand-ink-20); }
.site-acct-tabs a {
  display: flex; align-items: center; justify-content: center; min-height: 48px; margin-bottom: -1px;
  border-bottom: 3px solid transparent; font-weight: 700; color: var(--text-soft); text-decoration: none;
}
.site-acct-tabs a[aria-selected="true"] { color: var(--brand-primary); border-bottom-color: var(--brand-accent); }
.site-btn-block { width: 100%; justify-content: center; }
.site-acct-alt { margin: var(--space-3) 0 0; font-size: var(--fs-sm); color: var(--text-soft); }
.site-acct-alt a { font-weight: 700; color: var(--brand-accent); }
.site-acct-guest { text-align: center; }

.site-acct-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
.site-acct-who { margin: var(--space-1) 0 0; font-size: var(--fs-sm); color: var(--text-soft); overflow-wrap: anywhere; }
.site-acct-verify {
  display: grid; gap: var(--space-3); margin-bottom: var(--space-4); padding: var(--space-4);
  background: #fff; border-left: 3px solid var(--ink-yellow); font-size: var(--fs-sm);
}
.site-acct-verify p { margin: 0; }
.site-acct-verify a { font-weight: 700; color: var(--brand-accent); }
.site-acct-none { color: var(--text-soft); }

.site-acct-reqs { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-acct-req {
  display: grid; gap: var(--space-2); padding: var(--space-4); background: #fff;
  border: 1px solid var(--brand-ink-20); color: inherit; text-decoration: none;
  transition: border-color var(--transition);
}
.site-acct-req:hover { border-color: var(--brand-accent); text-decoration: none; }
.site-acct-req-date { font-size: var(--fs-sm); font-weight: 700; color: var(--text-soft); }
.site-acct-req-jobs { display: grid; gap: var(--space-2); }
.site-acct-job, .site-acct-jobhead { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.site-acct-job .ref, .site-acct-jobhead .ref { font-family: var(--brand-font-mono); font-size: var(--fs-sm); color: var(--text-soft); }
.site-acct-job .what { font-weight: 700; }
.site-acct-jobhead .site-cart-item-name { margin: 0; }

/* The status the shop set, in the shop's own words (PrintJobs::STATUSES).
   An outline, so it never reads as a button. Inks from the drawer, AA-checked. */
.site-status {
  display: inline-flex; align-items: center; padding: 2px 10px; border: 1px solid currentColor; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .02em; white-space: nowrap;
}
.site-status--wait  { color: var(--brand-ink-80); }
.site-status--act   { color: var(--ink-yellow); }
.site-status--go    { color: var(--ink-blue); }
.site-status--ready { color: var(--ink-green); }
.site-status--done  { color: var(--text-soft); }

.site-acct-h2 { font-size: var(--fs-h2); margin-bottom: var(--space-4); }
.site-acct-panels { display: grid; gap: var(--space-4); }
@media (min-width: 760px) { .site-acct-panels { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.site-form-single .site-acct-panels .site-form { background: #fff; }
.site-acct-label { font-size: var(--fs-sm); font-weight: 700; color: var(--brand-ink-80); }
.site-acct-fixed { overflow-wrap: anywhere; }
.site-acct-signout { margin-top: var(--space-5); }
.site-acct-offer { display: grid; gap: var(--space-3); justify-items: start; max-width: 640px; }
.site-acct-offer p { margin: 0; color: var(--text-soft); }

.site-acct-jobs { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: grid; gap: var(--space-3); }
.site-acct-jobcard { display: grid; gap: var(--space-3); padding: var(--space-4); background: #fff; border: 1px solid var(--brand-ink-20); }
.site-acct-timeline {
  list-style: none; margin: 0; padding: var(--space-3) 0 0; border-top: 1px solid var(--brand-ink-20);
  display: grid; gap: var(--space-2); font-size: var(--fs-sm);
}
.site-acct-timeline li { display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: var(--space-3); }
.site-acct-timeline .when { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.site-acct-tz { margin-top: var(--space-3); font-size: var(--fs-xs); color: var(--text-muted); }

@media (max-width: 600px) {
  .site-cart-facts > div, .site-acct-timeline li { grid-template-columns: 1fr; gap: 0; }
  .site-artfork-card { min-height: 64px; }
  .site-cart-head .site-btn, .site-acct-head .site-btn { width: 100%; justify-content: center; }
}

/* ── /cart: two ways in, one list ──────────────────────────────────────────── */
.site-cart-added {
  display: grid; gap: var(--space-3); margin-bottom: var(--space-5); padding: var(--space-4);
  background: #fff; border-left: 3px solid var(--ink-green);
}
.site-cart-added p { margin: 0; font-size: 1.05rem; }
.site-cart-added .site-actions { margin: 0; }
.site-cart-item-top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.site-cart-item-top .site-cart-item-name { margin: 0; }
.site-cart-item-top .site-cart-item-actions { margin-left: auto; }
.site-cart-needs {
  display: inline-flex; align-items: center; padding: 2px 10px; border-radius: 999px;
  background: var(--ink-red); color: #fff; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .02em;
}
.site-cart-item.is-incomplete { border-color: var(--ink-red); border-left-width: 3px; }
.site-cart-editor { display: grid; gap: var(--space-4); }
.site-cart-editor .site-errors { margin: 0; }
.site-cart-editor .site-reqstep-h { font-size: 1.15rem; }
.site-cart-editor .site-reqstep-h .n { width: 26px; height: 26px; font-size: .9rem; }
.site-cart-editor .site-submit { margin-top: 0; }
.site-cart-blocked { color: var(--ink-red); font-weight: 700; }
.site-submit .site-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Quick add: a button beside the product card (never inside its link). */
.site-quickadd { margin: 0; }
.site-cards > li:has(.site-quickadd) { display: grid; grid-template-rows: 1fr auto; }
.site-quickadd-btn {
  width: 100%; min-height: 44px; padding: 0 var(--space-3); cursor: pointer;
  border: 1px solid var(--brand-ink-20); border-top: 0; background: #fff;
  font: inherit; font-size: var(--fs-sm); font-weight: 700; color: var(--brand-accent);
  transition: background var(--transition), color var(--transition);
}
.site-quickadd-btn:hover, .site-quickadd-btn:focus-visible { background: var(--brand-accent); color: var(--brand-on-accent); }

/* Catalogue row + its quick add (merge 2026-10-06): the row opens the product,
   the small button drops it straight into the request as "needs details". */
.site-catalog-list li { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; border-bottom: 1px solid var(--brand-ink-20); }
.site-catalog-list li > a { border-bottom: 0; }
.site-catalog-list .site-quickadd { margin: 0 0 0 var(--space-2); }
.site-catalog-add {
  min-height: 36px; padding: 0 var(--space-3); border: 1.5px solid var(--brand-accent); border-radius: 999px;
  background: transparent; color: var(--brand-accent); font-family: var(--font-body); font-weight: 700; font-size: var(--fs-sm); cursor: pointer;
}
.site-catalog-add { display: inline-flex; align-items: center; margin-left: var(--space-2); text-decoration: none; }
.site-catalog-add:hover { background: var(--brand-accent); color: #fff; text-decoration: none; }

/* ── Account, signed in (redesign 2026-10-06) ─────────────────────────────────
   Profile rail left, content right; on a phone the rail is a header strip. */
.site-acct { padding-block: clamp(28px, 5vw, 64px); }
.site-acct-layout { display: grid; gap: clamp(24px, 4vw, 48px); align-items: start; }
.site-acct-rail { display: grid; gap: var(--space-4); }
.site-acct-me { display: flex; align-items: center; gap: var(--space-3); }
.site-acct-avatar {
  display: grid; place-items: center; width: 52px; height: 52px; flex: none; border-radius: 999px;
  background: var(--brand-accent); color: #fff; font-weight: 700; font-size: 1.1rem; letter-spacing: .02em;
}
.site-acct-me .n { margin: 0; font-weight: 700; color: var(--brand-primary); font-size: 1.05rem; }
.site-acct-me .e { margin: 0; color: var(--text-soft); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.site-acct-nav { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.site-acct-nav a {
  padding: 8px 14px; border-radius: 999px; background: #fff; color: var(--brand-primary);
  font-weight: 600; font-size: var(--fs-sm); text-decoration: none;
}
.site-acct-nav a:hover { background: var(--brand-accent); color: #fff; }
.site-acct-signout { margin: 0; }
.site-acct-signout .site-linkbtn, .site-acct-verify .site-linkbtn {
  min-height: 0; padding: 0; color: var(--brand-accent); font-weight: 700;
}
@media (min-width: 900px) {
  .site-acct-layout { grid-template-columns: 260px minmax(0, 1fr); }
  .site-acct-rail { position: sticky; top: calc(var(--site-header-h, 80px) + 24px); }
  .site-acct-me { flex-direction: column; align-items: flex-start; }
  .site-acct-avatar { width: 64px; height: 64px; font-size: 1.3rem; }
  .site-acct-nav { flex-direction: column; gap: 2px; padding-block: var(--space-3); border-block: 1px solid var(--brand-ink-20); }
  .site-acct-nav a { background: transparent; padding: 10px 12px; border-radius: 8px; font-size: 1rem; }
  .site-acct-nav a:hover { background: #fff; color: var(--brand-accent); }
}

.site-acct-main { display: grid; gap: var(--space-6); min-width: 0; }
.site-acct-main .site-acct-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
.site-acct-main .site-acct-head .site-h2 { color: var(--brand-primary); }
.site-acct-main .site-acct-verify {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4); padding: 12px var(--space-4);
  background: #fff7e6; border: 1px solid #f0d9a8; border-left: 4px solid #b7791f;
}
.site-acct-main .site-acct-verify p { margin: 0; color: var(--brand-ink-80); }
.site-acct-main .site-acct-verify form { margin: 0; }
.site-acct-empty {
  display: grid; justify-items: center; gap: var(--space-2); text-align: center;
  padding: clamp(32px, 6vw, 56px) var(--space-5); background: #fff; color: var(--text-soft);
}
.site-acct-empty svg { color: var(--brand-accent); }
.site-acct-empty .t { margin: var(--space-2) 0 0; font-family: var(--font-display); font-size: 1.4rem; font-weight: 600; color: var(--brand-primary); }
.site-acct-empty p { margin: 0; max-width: 40ch; }

.site-acct-main .site-acct-card { max-width: none; margin: 0; border: 0; background: #fff; padding: clamp(20px, 3vw, 32px); }
.site-acct-h { font-family: var(--font-display); font-size: 1.35rem; font-weight: 600; color: var(--brand-primary); margin-bottom: var(--space-4); }
.site-acct-grid { display: grid; gap: var(--space-4); margin-bottom: var(--space-5); }
@media (min-width: 700px) { .site-acct-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.site-acct-card .site-field { margin: 0; }
.site-acct-card input { font-family: var(--font-body); background: var(--brand-card); }
.site-acct-card input:focus { background: #fff; }
.site-acct-card .site-acct-fixed { display: flex; align-items: center; min-height: var(--control-min); color: var(--text-soft); }
input[type="tel"] { font-family: var(--font-body); }
.site-acct-nav a[aria-current="page"] { background: var(--brand-accent); color: #fff; }
@media (min-width: 900px) {
  .site-acct-nav a[aria-current="page"] { background: #fff; color: var(--brand-accent); box-shadow: inset 3px 0 0 var(--brand-accent); }
}
.site-acct-main h1.site-acct-h { font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.2rem); }

/* ── Cart rows + the job wizard (2026-10-06) ──────────────────────────────── */
.site-cart-title { color: var(--brand-primary); margin-bottom: var(--space-5); }
.site-cart-toast {
  display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4);
  padding: 10px var(--space-4); background: #e9f6ee; color: #1d6b45; border-radius: 8px; font-weight: 500;
}
.site-cart-items { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-cart-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3) var(--space-5);
  padding: var(--space-4) var(--space-5); background: #fff; border-left: 4px solid #1d6b45;
}
.site-cart-row.is-incomplete { border-left-color: #b7791f; }
.site-cart-row-main { display: grid; grid-template-columns: auto auto; justify-content: start; align-items: center; gap: 4px var(--space-3); min-width: 0; }
.site-cart-row .site-cart-item-name { margin: 0; font-size: 1.25rem; color: var(--brand-primary); }
.site-cart-summary { grid-column: 1 / -1; margin: 0; color: var(--text-soft); overflow-wrap: anywhere; }
.site-chip { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.site-chip.is-needs { background: #fff3db; color: #8a5a00; }
.site-chip.is-ready { background: #e3f3e9; color: #1d6b45; }
.site-cart-row-actions { display: flex; align-items: center; gap: var(--space-3); }
.site-cart-row-actions form { margin: 0; }
.site-cart-remove { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: var(--fs-sm); color: var(--text-muted); text-decoration: underline; }
.site-cart-remove:hover { color: #a71000; }
.site-cart-addrow a {
  display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-4);
  border: 2px dashed var(--brand-ink-20); color: var(--brand-accent); font-weight: 700; text-decoration: none;
}
.site-cart-addrow a:hover { border-color: var(--brand-accent); background: #fff; }
.site-cart-addrow span { font-size: 1.3rem; line-height: 1; }

/* The modal. */
.site-modal {
  width: min(720px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); padding: 0; border: 0; border-radius: 14px;
  background: #fff; color: var(--text); box-shadow: 0 40px 90px -30px rgba(12, 31, 66, .6);
}
.site-modal::backdrop { background: rgba(12, 31, 66, .55); }
.site-modal-form { display: flex; flex-direction: column; max-height: calc(100dvh - 24px); }
.site-modal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--brand-card); }
.site-modal-head h2 { margin: 0; font-family: var(--font-display); font-size: 1.4rem; color: var(--brand-primary); }
.site-modal-x { display: grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: 999px; background: var(--brand-card); color: var(--brand-primary); cursor: pointer; }
.site-modal-body { padding: var(--space-5); overflow-y: auto; flex: 1; }
.site-modal-foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-4) var(--space-5); border-top: 1px solid var(--brand-card); }
.site-modal-foot [data-wiz-back] { margin-right: auto; }
.site-modal .site-wiz-steps { margin: 0; padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--brand-card); }

/* The tracker: numbered steps joined by a line; done steps are buttons back. */
.site-wiz-steps { list-style: none; display: flex; gap: 0; margin: 0 0 var(--space-5); padding: 0; }
.site-wiz-steps li { flex: 1; position: relative; }
.site-wiz-steps li + li::before {
  content: ""; position: absolute; top: 16px; right: 50%; width: 100%; height: 2px; background: var(--brand-ink-20); z-index: 0;
}
.site-wiz-steps li.is-done + li::before, .site-wiz-steps li.is-current::before { background: var(--brand-accent); }
.site-wiz-steps button {
  position: relative; z-index: 1; display: grid; justify-items: center; gap: 6px; width: 100%;
  border: 0; background: none; padding: 0; cursor: pointer; font: inherit; font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted);
}
.site-wiz-steps button:disabled { cursor: default; }
.site-wiz-steps .n {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 999px;
  background: #fff; border: 2px solid var(--brand-ink-20); color: var(--text-muted); font-weight: 700;
}
.site-wiz-steps .is-current button { color: var(--brand-primary); }
.site-wiz-steps .is-current .n { background: var(--brand-accent); border-color: var(--brand-accent); color: #fff; }
.site-wiz-steps .is-done button { color: var(--brand-accent); }
.site-wiz-steps .is-done .n { background: #fff; border-color: var(--brand-accent); color: var(--brand-accent); }
.site-wiz-steps .is-done button:hover .n { background: var(--brand-card); }

/* One step on screen: no step numbers in the headings (the tracker has them). */
.is-wizard .site-reqstep-h .n { display: none; }
.is-wizard .site-reqstep { margin: 0; }
.is-wizard .site-submit:empty { display: none; }
.site-wiz-nav { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-6); }
.site-wiz-nav [data-wiz-back] { margin-right: auto; }
.site-wiz-msg { margin: 0 0 var(--space-3); padding: 10px var(--space-4); background: #fff3db; color: #8a5a00; border-radius: 8px; font-weight: 600; }
@media (max-width: 599px) {
  .site-cart-row-actions { width: 100%; }
  .site-cart-row-actions .site-btn { flex: 1; justify-content: center; }
  .site-modal { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; margin: 0; }
  .site-modal-form { max-height: 100dvh; height: 100%; }
}
/* The reset zeroes every margin, which pinned the dialog to the top-left. */
.site-modal { margin: auto; inset: 0; }
.is-wizard .site-reqstep { border-top: 0; padding-top: 0; }
.is-wizard .site-reqstep + .site-reqstep { margin-top: 0; }

/* Checkout: how do you want it (2026-10-06). */
.site-deliv { margin: var(--space-5) 0; padding: 0; border: 0; }
.site-deliv legend { font-weight: 700; font-size: 1.05rem; color: var(--brand-primary); margin-bottom: var(--space-3); }
.site-deliv-opts { display: grid; gap: var(--space-2); }
@media (min-width: 600px) { .site-deliv-opts { grid-template-columns: 1fr 1fr; } }
.site-deliv-opt {
  display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4);
  background: #fff; border: 2px solid var(--brand-ink-20); border-radius: 10px; cursor: pointer;
}
.site-deliv-opt:has(input:checked) { border-color: var(--brand-accent); background: color-mix(in srgb, var(--brand-accent) 5%, #fff); }
.site-deliv-opt input { margin-top: 3px; accent-color: var(--brand-accent); }
.site-deliv-opt b { display: block; color: var(--brand-primary); }
.site-deliv-opt small { display: block; color: var(--text-soft); font-size: var(--fs-sm); }
.site-deliv-addr { margin-top: var(--space-4); }
/* ZIP first, its delivery cost right beside it (stacks on a phone). */
.site-deliv-zipline { display: grid; gap: var(--space-3); margin-bottom: var(--space-4); align-items: end; }
@media (min-width: 600px) { .site-deliv-zipline { grid-template-columns: minmax(10rem, 14rem) 1fr; } }
.site-deliv-zipline .site-field { margin-bottom: 0; }
.site-deliv-quote {
  margin: 0; min-height: 52px; padding: 8px var(--space-4); display: flex; flex-direction: column; justify-content: center;
  border: 1px dashed var(--brand-ink-20); border-radius: 2px; background: var(--brand-card);
}
.site-deliv-quote-k { font-size: .72rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--brand-steel); }
.site-deliv-quote-v { font-weight: 600; color: var(--text-soft); }
.site-deliv-quote.is-free, .site-deliv-quote.is-fee, .site-deliv-quote.is-ask { border-style: solid; background: #fff; }
.site-deliv-quote.is-free { border-color: #1d6b45; }
.site-deliv-quote.is-free .site-deliv-quote-v { color: #1d6b45; font-size: 1.15rem; }
.site-deliv-quote.is-fee { border-color: var(--brand-accent); }
.site-deliv-quote.is-fee .site-deliv-quote-v { color: var(--brand-accent); font-size: 1.15rem; }
.site-deliv-quote.is-ask .site-deliv-quote-v { color: var(--brand-ink-80); }
.site-thanks-deliv { margin: var(--space-3) 0 0; padding: 10px var(--space-4); background: #fff; border-left: 4px solid var(--brand-accent); font-weight: 600; color: var(--brand-primary); }

/* ── Cart: list + one Checkout (2026-10-06) ───────────────────────────────── */
.site-cart-wrap { display: grid; gap: var(--space-5); align-items: start; }
@media (min-width: 960px) { .site-cart-wrap { grid-template-columns: minmax(0, 1fr) 300px; } }
.site-cart-main { min-width: 0; }
.site-cart-side {
  display: grid; gap: var(--space-3); padding: var(--space-5); background: #fff; border-radius: 12px;
  box-shadow: 0 24px 50px -34px rgba(19, 47, 96, .45);
}
@media (min-width: 960px) { .site-cart-side { position: sticky; top: calc(var(--site-header-h, 120px) + 16px); margin-top: 72px; } }
.site-cart-count { margin: 0; font-family: var(--font-display); font-size: 1.25rem; font-weight: 600; color: var(--brand-primary); }
.site-cart-side .site-btn { justify-content: center; min-height: 52px; font-size: 1.05rem; }
.site-btn.is-disabled { opacity: .45; pointer-events: none; }
.site-cart-side-note { margin: 0; font-size: var(--fs-sm); color: var(--text-soft); }
.site-btn-block { width: 100%; display: flex; }

/* ── Checkout: numbered sections that fold away ──────────────────────────── */
.site-checkout-grid { display: grid; gap: var(--space-6); align-items: start; }
@media (min-width: 960px) { .site-checkout-grid { grid-template-columns: minmax(0, 1fr) 320px; } }
.site-co-back { display: inline-block; margin-bottom: var(--space-3); font-weight: 600; color: var(--brand-accent); }
.site-checkout-main .site-h2 { color: var(--brand-primary); margin-bottom: var(--space-5); }
.site-co-form { display: grid; gap: var(--space-3); }
.site-co-step { background: #fff; border-radius: 12px; overflow: hidden; }
.site-co-head { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 2px var(--space-3); padding: var(--space-4) var(--space-5); }
.site-co-head .n {
  grid-row: span 2; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 999px;
  border: 2px solid var(--brand-ink-20); color: var(--text-muted); font-weight: 700;
}
.site-co-head h2 { margin: 0; font-family: var(--font-body); font-size: 1.15rem; font-weight: 700; color: var(--brand-primary); }
.site-co-sum { grid-column: 2; margin: 0; color: var(--text-soft); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.site-co-sum:empty { display: none; }
.site-co-change { grid-column: 3; grid-row: 1 / span 2; background: none; border: 0; padding: 0; font: inherit; font-weight: 700; color: var(--brand-accent); text-decoration: underline; cursor: pointer; }
.site-co-body { padding: 0 var(--space-5) var(--space-5) calc(var(--space-5) + 48px); display: grid; gap: var(--space-4); }
.site-co-body > .site-btn { justify-self: start; min-width: 160px; justify-content: center; }
.site-co-body .site-deliv { margin: 0; }
.site-co-step.is-open .n { background: var(--brand-accent); border-color: var(--brand-accent); color: #fff; }
.site-co-step.is-done .n { background: #e3f3e9; border-color: #1d6b45; color: #1d6b45; }
.site-co-step.is-done .n { font-size: 0; }
.site-co-step.is-done .n::after { content: "\2713"; font-size: 1rem; }
.is-stepped .site-co-step:not(.is-open) .site-co-body { display: none; }
.is-stepped .site-co-step.is-later { opacity: .6; }
.site-co-signin { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--brand-card); border-radius: 10px; }
.site-co-signin span { color: var(--text-soft); }
.site-co-who { margin: 0; color: var(--text-soft); }
.site-co-send { min-height: 54px; font-size: 1.1rem; }
@media (max-width: 599px) { .site-co-body { padding-left: var(--space-5); } .site-co-body > .site-btn { width: 100%; } }

.site-co-summary { background: #fff; border-radius: 12px; padding: var(--space-5); }
@media (min-width: 960px) { .site-co-summary { position: sticky; top: calc(var(--site-header-h, 120px) + 16px); margin-top: 96px; } }
.site-co-summary-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-3); }
.site-co-summary-head h2 { margin: 0; font-family: var(--font-display); font-size: 1.2rem; color: var(--brand-primary); }
.site-co-summary-head a { font-weight: 700; font-size: var(--fs-sm); }
.site-co-summary ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.site-co-summary li { padding-bottom: var(--space-3); border-bottom: 1px solid var(--brand-card); }
.site-co-summary li:last-child { border-bottom: 0; padding-bottom: 0; }
.site-co-summary b { display: block; color: var(--brand-primary); }
.site-co-summary span { color: var(--text-soft); font-size: var(--fs-sm); }

/* Toasts: bottom-centre on phones, bottom-right on desktop, leave by themselves. */
.site-toasts { position: fixed; z-index: 90; left: 16px; right: 16px; bottom: 16px; display: grid; gap: 8px; justify-items: center; pointer-events: none; }
@media (min-width: 700px) { .site-toasts { left: auto; right: 24px; bottom: 24px; justify-items: end; } }
.site-toast {
  pointer-events: auto; margin: 0; max-width: 420px; padding: 12px 18px 12px 44px; position: relative;
  background: var(--brand-navy); color: #fff; border-radius: 10px; font-weight: 500; cursor: pointer;
  box-shadow: 0 18px 40px -18px rgba(12, 31, 66, .7); animation: site-toast-in 240ms cubic-bezier(.2, .8, .2, 1) both;
}
.site-toast::before {
  content: "\2713"; position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; border-radius: 999px; background: #3fb07a; color: #fff;
  display: grid; place-items: center; font-size: 11px; font-weight: 700;
}
.site-toast.is-leaving { transition: opacity 280ms ease, transform 280ms ease; opacity: 0; transform: translateY(8px); }
@keyframes site-toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .site-toast { animation: none; } .site-toast.is-leaving { transition: none; } }
/* Before JS moves it, a toast is not a full-width bar in the page. */
main .site-toast { display: inline-block; }

/* Cart rows: picture, name, one quiet line, icon actions. */
.site-cart-row { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; align-items: center; gap: var(--space-4); padding: var(--space-3); border-left: 0; border-radius: 12px; }
.site-cart-row.is-incomplete { box-shadow: inset 3px 0 0 #b7791f; }
.site-cart-thumb { width: 96px; height: 72px; border-radius: 8px; overflow: hidden; background: var(--brand-card); display: block; }
.site-cart-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.site-cart-row-main { display: block; }
.site-cart-row .site-cart-item-name { font-size: 1.15rem; }
.site-cart-row .site-cart-summary { margin: 2px 0 0; font-size: var(--fs-sm); }
.site-cart-needs { margin: 2px 0 0; font-size: var(--fs-sm); font-weight: 600; color: #8a5a00; }
.site-cart-row-actions { gap: var(--space-1); }
.site-cart-icon {
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 999px; border: 0;
  background: transparent; color: var(--brand-ink-80); cursor: pointer; text-decoration: none;
}
.site-cart-icon:hover { background: var(--brand-card); color: var(--brand-accent); }
.site-cart-icon.is-remove:hover { color: #a71000; background: #fbeceb; }
.site-cart-fix { min-height: 40px; padding-inline: var(--space-4); }
@media (max-width: 599px) {
  .site-cart-row { grid-template-columns: 72px minmax(0, 1fr); }
  .site-cart-thumb { width: 72px; height: 56px; }
  .site-cart-row-actions { grid-column: 1 / -1; width: auto; justify-content: flex-end; }
  .site-cart-row-actions .site-btn { flex: 0 0 auto; }
}
/* Sign-in offer at checkout: one quiet line, not a box. */
.site-co-signin { display: block; margin: 0; padding: 0; background: none; border-radius: 0; color: var(--text-soft); font-size: var(--fs-sm); }
.site-co-signin a { font-weight: 700; color: var(--brand-accent); }
/* Checkout as one page: plain headed sections, no step numbers. */
.site-co-step { padding: var(--space-5); }
.site-co-h { margin: 0 0 var(--space-4); font-family: var(--font-body); font-size: 1.15rem; font-weight: 700; color: var(--brand-primary); }
.site-co-step .site-co-body { padding: 0; }
.site-co-final .site-co-body { gap: var(--space-4); }
.site-co-send { width: 100%; justify-content: center; }
@media (min-width: 600px) { .site-co-send { width: auto; min-width: 260px; } }

/* ── Job form on one page (2026-10-06) ───────────────────────────────────────
   Three sections with one rhythm: 40px between sections, 12px inside. */
.site-jobform { display: grid; gap: 40px; }
.site-jobform .site-reqstep { display: grid; gap: 12px; margin: 0; padding: 0; border: 0; }
.site-jobform .site-reqstep-h { margin: 0; font-family: var(--font-display); font-size: 1.5rem; font-weight: 600; color: var(--brand-primary); line-height: 1.2; }
.site-jobform .site-reqstep-h .n { display: none; }
.site-jobform legend.site-reqstep-h { padding: 0; margin-bottom: 12px; }
.site-jobform .site-reqstep--art .site-artfork { margin: 0; }
/* Artwork cards: equal, compact, icon above a clear label. */
.site-artfork { list-style: none; padding: 0; display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.site-artfork > li[hidden] { display: none; }
.site-artfork-card {
  position: relative; display: grid; align-content: start; gap: 10px; height: 100%; min-height: 0;
  padding: 18px 20px; background: #fff; border: 2px solid var(--brand-ink-20); border-radius: 12px; cursor: pointer;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.site-artfork-card:hover { border-color: var(--brand-accent); }
.site-artfork-card:has(input:checked) { border-color: var(--brand-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-accent) 18%, transparent); }
.site-artfork-mark { color: var(--brand-accent); }
.site-artfork-mark svg { width: 28px; height: 28px; }
.site-artfork-h { font-family: var(--font-body); font-size: 1.1rem; font-weight: 700; line-height: 1.3; color: var(--brand-primary); }
.site-artfork-tick { position: absolute; top: 14px; right: 14px; }
/* The attached line under the cards. */
.site-artsum { margin: 4px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--brand-ink-80); }
.site-artsum[hidden] { display: none; }
.site-artsum .ok { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 999px; background: #e3f3e9; color: #1d6b45; font-size: 12px; font-weight: 700; }
.site-artsum.is-done span:not(.ok) { font-weight: 600; }
.site-artsum button:not(.site-btn) { background: none; border: 0; padding: 0; font: inherit; font-weight: 700; color: var(--brand-accent); text-decoration: underline; cursor: pointer; }
.site-jobform .site-artpanel { margin-top: 4px; }
/* Upload popup. */
.site-upmodal { width: min(560px, calc(100vw - 24px)); }
.site-upmodal .site-modal-body { display: grid; gap: 12px; }
.site-upmodal .site-modal-foot { justify-content: flex-end; }
.site-uppanel.is-in-modal { margin: 0; padding: 0; border: 0; background: none; }
/* The page's form: one button, right-aligned on desktop, full width on phones. */
.site-reqform .site-submit { margin-top: 40px; display: flex; justify-content: flex-end; }
.site-reqform .site-submit .site-btn { min-width: 220px; justify-content: center; min-height: 52px; font-size: 1.05rem; }
@media (max-width: 599px) { .site-reqform .site-submit .site-btn { width: 100%; } }
.site-reqform { padding: clamp(24px, 4vw, 48px); background: #fff; border-radius: 14px; }

/* Catalogue row with its quick add (fix 2026-10-06): the row, not the link,
   carries the hover; the link no longer bleeds into the margin under the
   button; the arrow goes - the row is the link and "+ Add" is the action. */
.site-catalog-list li { gap: var(--space-3); padding-right: var(--space-2); border-radius: 8px; transition: background var(--transition); }
.site-catalog-list li:hover { background: #fff; }
.site-catalog-list li > a { margin-inline: 0; padding-inline: var(--space-2); background: none; }
.site-catalog-list li > a:hover { background: none; }
.site-catalog-list li .site-catalog-go { display: none; }
.site-catalog-list .site-quickadd { margin: 0; flex: none; }
.site-catalog-add { white-space: nowrap; }

/* Confirm popup (replaces the browser's confirm box). */
.site-confirm { width: min(420px, calc(100vw - 32px)); }
.site-confirm-body { padding: var(--space-5) var(--space-5) var(--space-2); }
.site-confirm-body h2 { margin: 0 0 var(--space-2); font-family: var(--font-display); font-size: 1.35rem; color: var(--brand-primary); }
.site-confirm-body p { margin: 0; color: var(--text-soft); }
.site-confirm .site-modal-foot { border-top: 0; padding-top: var(--space-4); }
.site-btn.is-danger { background: #b3261e; border-color: #b3261e; color: #fff; }
.site-btn.is-danger:hover { background: #8f1d17; border-color: #8f1d17; }
/* Touch screens keep :hover after a tap - only real pointers get the hover outline. */
@media (hover: none) { .site-artfork-card:hover { border-color: var(--brand-ink-20); } .site-artfork-card:has(input:checked) { border-color: var(--brand-accent); } }
/* Phones: what you are sending sits above the form, not after the Send button. */
@media (max-width: 959px) { .site-co-summary { order: -1; } .site-checkout-grid { display: flex; flex-direction: column; } }

/* The footer sits at the bottom of the window even on a short page. */
body.site { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
body.site > main { flex: 1 0 auto; }
body.site > .site-footer { flex-shrink: 0; }

/* Empty cart: one centred card, then popular quick starts. */
.site-cart-emptywrap { padding-block: clamp(40px, 7vw, 88px) var(--space-5); }
.site-cart-emptycard {
  max-width: 520px; margin-inline: auto; display: grid; justify-items: center; gap: var(--space-3); text-align: center;
  padding: clamp(32px, 5vw, 48px) var(--space-5); background: #fff; border-radius: 16px;
  box-shadow: 0 30px 60px -40px rgba(19, 47, 96, .5);
}
.site-cart-emptyicon { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 999px; background: var(--brand-card); color: var(--brand-accent); }
.site-cart-emptycard .site-h2 { margin: var(--space-2) 0 0; color: var(--brand-primary); }
.site-cart-emptycard > p { margin: 0; color: var(--text-soft); }
.site-cart-emptycard .site-btn { margin-top: var(--space-3); min-width: 240px; justify-content: center; min-height: 50px; }
.site-cart-emptyalt { font-weight: 600; font-size: var(--fs-sm); color: var(--brand-accent); }
.site-cart-emptysign { margin-top: var(--space-4) !important; padding-top: var(--space-4); border-top: 1px solid var(--brand-card); width: 100%; font-size: var(--fs-sm); }
.site-cart-emptysign a { font-weight: 700; }
.site-cart-popular { padding-block: var(--space-5) clamp(48px, 7vw, 96px); }
.site-cart-popular-h { margin: 0 auto var(--space-3); max-width: 880px; font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); text-align: center; }
.site-cart-popular ul { list-style: none; margin: 0 auto; padding: 0; max-width: 880px; display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
.site-cart-popular a { display: grid; gap: 6px; padding: 8px; background: #fff; border-radius: 12px; color: var(--brand-primary); text-decoration: none; font-weight: 600; font-size: var(--fs-sm); text-align: center; transition: box-shadow var(--transition); }
.site-cart-popular a:hover { box-shadow: 0 0 0 2px var(--brand-accent); }
.site-cart-popular .ph { display: block; aspect-ratio: 4 / 3; border-radius: 8px; overflow: hidden; background: var(--brand-card); }
.site-cart-popular img { width: 100%; height: 100%; object-fit: cover; display: block; }
.site .site-cart-popular .site-cart-popular-h { font-family: var(--font-body); font-size: var(--fs-xs); letter-spacing: .12em; }

/* ── Job editor: "More details" - the jacket's optional questions in a modal ──
   Rendered <dialog open> so it reads inline with JS off; site.js closes it on
   load and opens it as a modal from the button. */
.site-more-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; }
.site-more-sum { margin: 0; color: var(--text-soft, #555); font-size: .95rem; }
.site-more-sum:empty { display: none; }
.site-more { position: static; width: 100%; max-width: none; margin: 0; padding: 0; border: 0; background: transparent; color: inherit; }
.site-more[data-modal] {
  position: fixed; width: min(720px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); margin: auto;
  padding: 0; border: 0; border-radius: 14px; background: var(--site-card, #fff); box-shadow: 0 24px 60px rgba(0,0,0,.28);
  display: flex; flex-direction: column; overflow: hidden;
}
.site-more[data-modal]:not([open]) { display: none; }
.site-more[data-modal]::backdrop { background: rgba(10, 20, 40, .55); }
.site-more-head { padding: 1.25rem 1.5rem .5rem; }
.site-more-head .site-reqstep-h { margin: 0; }
.site-more-body { padding: .5rem 1.5rem 1rem; overflow-y: auto; }
.site-more:not([data-modal]) .site-more-foot { display: none; }
.site-more-foot { display: flex; justify-content: flex-end; padding: .75rem 1.5rem 1.25rem; border-top: 1px solid rgba(0,0,0,.08); }
.site-wide-size { display: flex; align-items: flex-end; gap: .75rem; }
.site-wide-size .site-field { flex: 1 1 0; margin: 0; }
.site-wide-size .site-field > span { display: block; font-size: .9rem; margin-bottom: .25rem; }
.site-wide-x { padding-bottom: .65rem; font-size: 1.2rem; }
.site-jq-note { margin: 0 0 .5rem; font-size: .9rem; color: var(--text-soft, #555); }

/* Wide-format and blueprint products ask their own size; paper questions step aside. */
.site-jobform[data-kind~="blueprint"] [data-kind-panel="blueprint"],
.site-jobform[data-kind~="wide"] [data-kind-panel="wide"] { display: block; }
.site-jobform[data-kind~="blueprint"] [data-kind-hide~="blueprint"],
.site-jobform[data-kind~="wide"] [data-kind-hide~="wide"] { display: none; }
@supports selector(:has(*)) {
  .site-jobform:has([data-job-select] option[data-kinds~="blueprint"]:checked) [data-kind-panel="blueprint"],
  .site-jobform:has([data-job-select] option[data-kinds~="wide"]:checked) [data-kind-panel="wide"] { display: block; }
  .site-jobform:has([data-job-select] option[data-kinds~="blueprint"]:checked) [data-kind-hide~="blueprint"],
  .site-jobform:has([data-job-select] option[data-kinds~="wide"]:checked) [data-kind-hide~="wide"] { display: none; }
}

/* ── Job editor: each product asks only its own questions (products.options,
   Jackets::optionsFor). The editor carries data-opts for the product; site.js
   keeps it current, and :has reads the chosen option directly. */
.site-jobform [data-opt] { display: none; }
.site-jobform[data-opts~="size"] [data-opt="size"],
.site-jobform[data-opts~="sides"] [data-opt="sides"],
.site-jobform[data-opts~="ink"] [data-opt="ink"],
.site-jobform[data-opts~="stock"] [data-opt="stock"],
.site-jobform[data-opts~="bindery"] [data-opt="bindery"],
.site-jobform[data-opts~="run"] [data-opt="run"],
.site-jobform[data-opts~="ncr"] [data-opt="ncr"],
.site-jobform[data-opts~="envelope"] [data-opt="envelope"],
.site-jobform[data-opts~="blueprint"] [data-opt="blueprint"],
.site-jobform[data-opts~="wide"] [data-opt="wide"],
.site-jobform[data-opts~="machines"] [data-opt="machines"],
.site-jobform[data-opts~="pages"] [data-opt="pages"] { display: block; }
@supports selector(:has(*)) {
  .site-jobform:has([data-job-select] option[data-opts~="size"]:checked) [data-opt="size"],
  .site-jobform:has([data-job-select] option[data-opts~="sides"]:checked) [data-opt="sides"],
  .site-jobform:has([data-job-select] option[data-opts~="ink"]:checked) [data-opt="ink"],
  .site-jobform:has([data-job-select] option[data-opts~="stock"]:checked) [data-opt="stock"],
  .site-jobform:has([data-job-select] option[data-opts~="bindery"]:checked) [data-opt="bindery"],
  .site-jobform:has([data-job-select] option[data-opts~="run"]:checked) [data-opt="run"],
  .site-jobform:has([data-job-select] option[data-opts~="ncr"]:checked) [data-opt="ncr"],
  .site-jobform:has([data-job-select] option[data-opts~="envelope"]:checked) [data-opt="envelope"],
  .site-jobform:has([data-job-select] option[data-opts~="blueprint"]:checked) [data-opt="blueprint"],
  .site-jobform:has([data-job-select] option[data-opts~="wide"]:checked) [data-opt="wide"],
  .site-jobform:has([data-job-select] option[data-opts~="machines"]:checked) [data-opt="machines"],
  .site-jobform:has([data-job-select] option[data-opts~="pages"]:checked) [data-opt="pages"] { display: block; }
}

/* "Still needed: ..." on a cart job - readable: dark amber on a pale amber
   pill (was olive text on a dark red ground). */
.site-cart-needs {
  display: inline-block; margin: 4px 0 0; padding: 3px 12px; border-radius: 999px;
  background: #fdf1d8; color: #6b4400; border: 1px solid #e8c77a;
  font-size: var(--fs-sm); font-weight: 600; line-height: 1.5;
}

/* ── Product search (site.js initCombo) ────────────────────────────────────
   The select stays in the form (it posts and drives the :has() rules) but
   sits under the search box. */
.site-combo { position: relative; }
.site-combo-native {
  position: absolute !important; width: 1px !important; height: 1px !important; min-height: 0 !important;
  padding: 0 !important; margin: -1px !important; overflow: hidden; clip: rect(0 0 0 0); border: 0 !important; opacity: 0;
}
.site-combo-input {
  box-sizing: border-box; width: 100%; min-height: 52px; padding: 0 var(--space-4); font: inherit; font-size: 1.1rem; color: var(--brand-primary);
  border: 1px solid var(--brand-ink-20); border-radius: 2px; background: #fff;
}
.site-combo-input:focus { border-color: var(--brand-accent); outline: 2px solid var(--brand-accent); outline-offset: -1px; }
.site-combo-input::placeholder { color: var(--text-muted); }
.site-combo-list {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 4px);
  max-height: min(22rem, 60vh); overflow-y: auto; margin: 0; padding: 6px 0; list-style: none;
  background: #fff; border: 1px solid var(--brand-ink-20); border-radius: 2px;
  box-shadow: 0 12px 28px rgba(19, 47, 96, .16);
}
.site-combo-group {
  padding: 10px var(--space-4) 4px; font-size: .72rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--brand-steel);
}
.site-combo-opt { padding: 10px var(--space-4); font-size: 1.02rem; color: var(--brand-primary); cursor: pointer; }
.site-combo-opt.is-active, .site-combo-opt:hover { background: var(--brand-card); }
.site-combo-none { padding: 10px var(--space-4) 4px; font-size: var(--fs-sm); color: var(--text-muted); }
.site-combo-send {
  margin-top: 4px; border-top: 1px solid var(--brand-ink-20); padding-top: 12px;
  font-weight: 700; color: var(--brand-accent);
}

/* ── Request received (pages/request_thanks.php) ───────────────────────────
   One column, one left edge. The ticket is a white sheet on the card stock:
   heading, the facts as label/value rows, the three steps, the actions. The
   account offer below is the same width, so every edge lines up. */
.site-thanks-col { max-width: 44rem; }
.site-ticket { box-sizing: border-box; background: #fff; border: 1px solid var(--brand-ink-20); border-radius: 2px; }
.site-ticket *, .site-ticket-offer { box-sizing: border-box; }
.site-ticket > * { padding: var(--space-5) var(--space-6); }
.site-ticket > * + * { border-top: 1px solid var(--brand-ink-20); }
.site-ticket-eyebrow, .site-ticket h2.site-ticket-k, .site-ticket-facts dt {
  margin: 0; font-family: var(--brand-font-body); font-size: .74rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--brand-steel);
}
.site-ticket-eyebrow { color: var(--brand-accent); }
.site-ticket-title {
  margin: var(--space-2) 0 0; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2rem, 5vw, 2.75rem); line-height: 1.05; letter-spacing: -.01em; color: var(--brand-primary);
}
.site-ticket-body { margin: var(--space-3) 0 0; font-size: 1.1rem; color: var(--brand-ink-80); }
.site-ticket-facts { margin: 0; display: grid; gap: var(--space-3); }
.site-ticket-facts > div { display: grid; grid-template-columns: 11rem 1fr; gap: var(--space-4); align-items: baseline; }
.site-ticket-facts dd { margin: 0; font-weight: 600; color: var(--brand-primary); overflow-wrap: anywhere; }
.site-ticket-facts .is-ref dd { font-family: var(--font-display); font-size: 1.6rem; font-weight: 700; line-height: 1; }
.site-ticket-steps { margin: var(--space-3) 0 0; padding: 0; list-style: none; counter-reset: step; display: grid; gap: var(--space-3); }
.site-ticket-steps li { counter-increment: step; display: grid; grid-template-columns: 2rem 1fr; column-gap: var(--space-3); }
.site-ticket-steps li::before {
  content: counter(step); grid-row: span 2; width: 2rem; height: 2rem; display: grid; place-items: center;
  border: 1.5px solid var(--brand-accent); border-radius: 50%; font-weight: 700; color: var(--brand-accent);
}
.site-ticket-steps b { color: var(--brand-primary); }
.site-ticket-steps span { color: var(--text-soft); }
.site-ticket-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); background: var(--bg-sunken, #f4f4f2); }
.site-ticket-actions .site-btn { margin: 0; }
.site-ticket-offer {
  max-width: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5) var(--space-6); background: #fff; border: 1px solid var(--brand-ink-20); border-radius: 2px;
}
.site-ticket-offer > div { flex: 1 1 18rem; }
.site-ticket-offer h2 { margin: 0; font-family: var(--font-display); font-size: 1.35rem; color: var(--brand-primary); }
.site-ticket-offer p { margin: var(--space-1) 0 0; }
.site-thanks-acct { padding-top: 0; }
@media (max-width: 599px) {
  .site-ticket > *, .site-ticket-offer { padding: var(--space-4); }
  .site-ticket-facts > div { grid-template-columns: 1fr; gap: 2px; }
  .site-ticket-actions .site-btn, .site-ticket-offer .site-btn { flex: 1 1 100%; justify-content: center; text-align: center; }
}

/* ── One request in the account (pages/account_request.php) ────────────────
   The ticket from Request received, inside the account layout. Each job is a
   band of the ticket; its history is one more fact row. */
.site-acct-back { display: inline-flex; gap: 6px; margin-bottom: var(--space-3); font-weight: 700; color: var(--brand-accent); text-decoration: none; }
.site-acct-back:hover { text-decoration: underline; }
.site-acct-ticket .site-ticket-title { font-size: clamp(1.75rem, 4vw, 2.25rem); }
.site-ticket-jobhead { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin-bottom: var(--space-3); }
.site-ticket-jobhead h2 { margin: 0; font-family: var(--font-display); font-size: 1.4rem; color: var(--brand-primary); }
.site-ticket-jobhead .ref { font-family: var(--brand-font-mono); font-size: .9rem; color: var(--brand-steel); }
.site-ticket-hist { margin: 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.site-ticket-hist .what { font-weight: 600; color: var(--brand-primary); }
.site-ticket-hist .when { font-weight: 400; color: var(--text-soft); margin-left: var(--space-2); }
.site-ticket-change { align-items: center; justify-content: space-between; }
.site-ticket-change p { margin: 0; flex: 1 1 16rem; color: var(--brand-ink-80); }
.site-acct-main .site-acct-tz { margin-top: var(--space-3); font-size: var(--fs-sm); color: var(--text-soft); }

/* ── Artwork upload: refusals beside the input, progress beside the send ──── */
.site-upload-errors { margin: var(--space-3) 0 0; }
.site-upload-errors[hidden] { display: none; }
.site-upprog { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3);
  margin: var(--space-4) 0 0; font-size: var(--fs-sm); }
.site-upprog[hidden] { display: none; }
.site-upprog progress { flex: 1 1 100%; width: 100%; height: 8px; accent-color: var(--brand-accent); }
.site-upprog-t { flex: 1 1 auto; color: var(--brand-ink-80); }
.site-upprog-x { background: none; border: 0; padding: 0; color: var(--brand-accent); text-decoration: underline; cursor: pointer; font: inherit; }
.site-upprog-x[hidden] { display: none; }
.site-upprog.is-error { border-left: 3px solid var(--brand-accent); background: #fff; padding: var(--space-3) var(--space-4); }
.site-upprog.is-error .site-upprog-t { color: inherit; font-weight: 600; }

/* The reel's other posters stay out of the layout (so their lazy images do not
   load) until site.js marks a slide as next or feeds it in - the hero costs
   one poster and one clip, not seven of each. */
.site-reel-slide:not(.is-active):not(.is-feeding):not(.is-next) picture { display: none; }

/* A phone number that is not 10 digits yet - marked on leaving the field, focus never pulled back. */
input[data-phone].is-invalid { border-color: var(--st-danger-fg); box-shadow: 0 0 0 1px var(--st-danger-fg); }

/* The product's own line under the artwork choices (Products > Online ordering). */
.site-artnote { margin: var(--space-2) 0 0; color: var(--text-soft); }

/* "I'll bring it in": where and when, in one line under the cards. */
.site-bringpanel p { margin: 0; color: var(--text-soft); }

/* ── Every public form, compact, with each field's name inside its box at
   the top left (owner, 2026-10-09: "apply this everywhere"). One rule: a
   .site-field whose label is followed directly by its input / select /
   textarea - the order form, checkout, contact, the account pages. ─────── */
.site-jobform { gap: 24px; }
.site-jobform .site-reqstep { gap: 10px; }
.site-jobform .site-reqstep-h { font-size: 1.25rem; }
.site-jobform legend.site-reqstep-h { margin-bottom: 10px; }
.site-field { margin-bottom: 12px; }
.site-row { gap: 12px; }
.site-field:has(> label + :is(input, select, textarea)) { position: relative; gap: 0; }
.site-field:has(> label + :is(input, select, textarea)) > label {
  position: absolute; z-index: 1; top: 7px; left: 13px; right: 13px;
  font-size: .78rem; font-weight: 600; line-height: 1.2; color: var(--brand-ink-80);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
}
.site-field:has(> label + :is(input, select, textarea)) > label .opt { font-weight: 500; }
.site-field > label + :is(input, select, textarea) {
  box-sizing: border-box; width: 100%; min-height: 52px;
  padding: 25px 13px 7px; font-size: 1rem; line-height: 1.3;
}
.site-field > label + textarea { padding-top: 27px; resize: vertical; }
.site-field > label + select { padding-right: 36px; }
.site-jobform .site-field { margin-bottom: 0; }
/* The product search (the step's own heading names it) matches the boxes. */
.site-jobform .site-combo-input { min-height: 52px; font-size: 1rem; }

/* ── "More details" window: compact, and clearly scrollable ─────────────── */
.site-more[data-modal] .site-more-head { padding: 1rem 1.5rem .25rem; }
.site-more[data-modal] .site-more-body { padding: .25rem 1.5rem 1.25rem; }
.site-more[data-modal] .site-jq { margin-top: 1rem; }
.site-more[data-modal] .site-jq:first-child { margin-top: .25rem; }
.site-more[data-modal] .site-jq-h { margin-bottom: .4rem; font-size: .9rem; }
.site-more[data-modal] .site-picks { gap: 6px; }
.site-more[data-modal] .site-pick span { min-height: 36px; padding: 0 14px; font-size: .95rem; }
/* More below the fold: the list fades out at the bottom edge and the footer
   lifts, with a "More below" button beside Done. */
.site-more.has-more .site-more-body { -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent); }
.site-more.has-more .site-more-foot { box-shadow: 0 -10px 18px -10px rgba(0, 0, 0, .18); }
.site-more-foot { justify-content: space-between; align-items: center; gap: 1rem; }
.site-more-foot > :only-child, .site-more-foot .site-more-down[hidden] + .site-btn { margin-left: auto; }
.site-more-down { background: none; border: 0; padding: .4rem 0; font: inherit; font-weight: 700; color: var(--brand-accent); cursor: pointer; }
.site-more-down[hidden] { display: none; }
.site-more-down:hover { text-decoration: underline; }

/* How many + pages, side by side; a chip this product does not offer is hidden. */
.site-qtyrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 12px; }
.site-qtyrow > [hidden] { display: none !important; }
.site-pick[hidden], .site-more-row[hidden] { display: none; }
.site-qtyrow .site-qty { margin: 0; max-width: none; }

/* Cart row: the description, typed in place. */
.site-cart-notes { margin: 10px 0 0; max-width: 44rem; }
.site-cart-notes .site-field { margin: 0; }
.site-cart-notes textarea { min-height: 64px; }
.site-cart-notes-state { display: block; min-height: 1.2em; margin-top: 4px; font-size: var(--fs-xs); color: var(--text-soft); }
.site-cart-row { align-items: start; }

/* ── Order form, one compact block (owner, 2026-10-09) ───────────────────
   Product, then how many / pages / when on one row, the description, the one
   files box, More details. Sections run together; no extra headings. */
.site-jobform { gap: 16px; }
.site-jobform .site-reqstep { gap: 8px; }
.site-qtyrow { grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 8px; }
.site-describe textarea { min-height: 84px; }
/* Files: one row - drop or pick anything; link and options under it. */
.site-files { display: grid; gap: 8px; }
.site-files .site-uppanel { margin: 0; display: grid; gap: 8px; }
.site-files .site-uppanel[hidden] { display: none; }
.site-files .site-drop--row {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin: 0;
  border: 1.5px dashed var(--brand-ink-20); border-radius: 10px; background: #fff; cursor: pointer;
}
.site-files .site-drop--row:hover, .site-files .site-drop--row:focus-within { border-color: var(--brand-accent); }
.site-files .site-drop--row input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.site-drop-text { display: grid; gap: 2px; }
.site-drop-text strong { color: var(--brand-primary); }
.site-drop-text .hint { font-size: var(--fs-xs); color: var(--text-soft); }
.site-files-ways { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; }
.site-files-ways > [hidden] { display: none; }
.site-designlink { font-weight: 700; color: var(--brand-accent); }
.site-bringpanel { margin: 0; color: var(--text-soft); }
.site-bringpanel[hidden] { display: none; }
/* The product page's order window: the whole form, scrolling inside. */
.site-order-actions { margin-top: var(--space-5); }
.site-order-modal { width: min(720px, calc(100vw - 24px)); }
.site-order-modal .site-modal-body { max-height: calc(100dvh - 180px); overflow-y: auto; }
/* On the product's own page the product is already chosen: no picker in its window. */
.site-order-modal .site-jobform > .site-reqstep:first-child > .site-reqstep-h,
.site-order-modal .site-jobform .site-combo { display: none; }

/* Cart row: how many + the description side by side, the row opens the editor. */
.site-cart-row[data-cart-row] { cursor: pointer; }
.site-cart-row[data-cart-row] :is(input, textarea, select, button, a, label) { cursor: auto; }
.site-cart-row[data-cart-row] :is(button, a, select, label) { cursor: pointer; }
.site-cart-notes { display: grid; grid-template-columns: minmax(9rem, 13rem) minmax(0, 1fr); gap: 8px; align-items: start; cursor: auto; }
.site-cart-notes:not(:has(.site-cart-qty)) { grid-template-columns: 1fr; }
.site-cart-qty select { width: 100%; }
.site-cart-qty input[data-cart-qty-other] { margin-top: 6px; width: 100%; min-height: 40px; padding: 6px 10px; border: 1px solid var(--brand-ink-20); border-radius: 2px; }
.site-cart-notes-foot { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.site-cart-notes-foot .site-cart-notes-state { margin: 0; }
.site-cart-more { font-weight: 700; font-size: var(--fs-sm); color: var(--brand-accent); }
@media (max-width: 640px) { .site-cart-notes { grid-template-columns: 1fr; } }

/* ══ Cart, compact (owner, 2026-10-09: "beautiful and compact") ═══════════
   One card per job: a small picture; the name with one quiet line beside it;
   quantity and description side by side at one height; two small actions.
   Every size on one scale: 14 / 15 / 16px text, 8 / 12 / 16px space. */
.site-cart-title { font-size: clamp(1.6rem, 1.3rem + 1vw, 2.1rem); margin: 0 0 16px; }
.site-cart-items { gap: 10px; }
.site-cart-row {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto;
  grid-template-areas: "thumb head actions" "thumb form form";
  align-items: start; gap: 8px 14px; padding: 14px 16px;
  background: #fff; border: 1px solid rgba(19, 47, 96, .08); border-radius: 12px;
  box-shadow: 0 1px 2px rgba(19, 47, 96, .06);
}
.site-cart-row.is-incomplete { box-shadow: 0 1px 2px rgba(19, 47, 96, .06); border-left: 1px solid rgba(19, 47, 96, .08); }
.site-cart-thumb { grid-area: thumb; width: 56px; height: 56px; border-radius: 8px; }
.site-cart-row-head { grid-area: head; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; padding-top: 2px; }
.site-cart-row .site-cart-item-name { margin: 0; font-family: var(--font-display); font-size: 1.12rem; font-weight: 600; line-height: 1.25; color: var(--brand-primary); }
.site-cart-row-head .site-cart-summary { margin: 0; font-size: .875rem; color: var(--text-soft); }
.site-cart-need { font-size: .8rem; font-weight: 600; color: #8a5a00; }
.site-cart-need::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 6px 1px 0; border-radius: 50%; background: #d4920b; vertical-align: middle; }
.site-cart-row-actions { grid-area: actions; display: flex; align-items: center; gap: 4px; }
.site-cart-edit { padding: 4px 10px; border-radius: 999px; font-size: .85rem; font-weight: 600; color: var(--brand-accent); text-decoration: none; white-space: nowrap; }
.site-cart-edit:hover { background: var(--brand-card); text-decoration: none; }
.site-cart-row .site-cart-icon { width: 32px; height: 32px; display: inline-grid; place-items: center; border-radius: 999px; color: var(--text-soft); }
.site-cart-row .site-cart-icon:hover { background: var(--brand-card); color: #a71000; }
.site-cart-row .site-cart-icon svg { width: 16px; height: 16px; }
/* The fields: one row, one height, labels inside. */
.site-cart-notes { grid-area: form; margin: 0; max-width: none; display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 8px; align-items: start; }
.site-cart-notes:not(:has(.site-cart-qty)) { grid-template-columns: minmax(0, 1fr); }
.site-cart-notes .site-field { margin: 0; }
.site-cart-notes .site-field > label { top: 6px; left: 11px; font-size: .7rem; }
.site-cart-notes .site-field > label + :is(select, textarea) { min-height: 46px; padding: 21px 11px 5px; font-size: .95rem; border-radius: 8px; border-color: rgba(19, 47, 96, .16); }
.site-cart-notes textarea { resize: none; overflow: hidden; line-height: 1.35; }
.site-cart-qty input[data-cart-qty-other] { margin-top: 6px; min-height: 38px; border-radius: 8px; }
.site-cart-notes-state { grid-column: 1 / -1; min-height: 0; margin: -2px 0 0; font-size: .75rem; color: var(--text-soft); }
.site-cart-notes-state:empty { display: none; }
/* The order summary card beside the list. */
@media (min-width: 960px) { .site-cart-side { margin-top: 56px; } }
.site-cart-side { padding: 18px; border-radius: 12px; gap: 12px; }
.site-cart-count { font-size: 1.05rem; }
.site-cart-side .site-btn { min-height: 46px; font-size: 1rem; }
.site-cart-addrow a { min-height: 52px; border-radius: 12px; font-size: .95rem; }
@media (max-width: 640px) {
  .site-cart-row { grid-template-columns: 48px minmax(0, 1fr); grid-template-areas: "thumb head" "form form" "actions actions"; padding: 12px; }
  .site-cart-thumb { width: 48px; height: 48px; }
  .site-cart-notes { grid-template-columns: 1fr; }
  .site-cart-row-actions { justify-content: flex-end; }
}
.site-cart-notes .site-field > label + textarea { resize: none; }
@media (max-width: 640px) {
  .site-cart-row { grid-template-columns: 44px minmax(0, 1fr) auto; grid-template-areas: "thumb head actions" "form form form"; }
  .site-cart-thumb { width: 44px; height: 44px; }
  .site-cart-row-actions { justify-content: flex-end; }
}
