/* reset.css - minimal modern reset. Copied from the nick-leoni site-v2
   reference at C0. One adaptation: the focus-outline color rides a neutral
   token with a currentColor fallback, because tokens.css is empty until C1
   (nick's rule referenced his --ember brand token, which does not exist
   here; an undefined var() would silently kill the focus outline). */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
/* min-height, NOT height: a fixed body height clamps the sticky header's
   containing block to one viewport, so position:sticky dies after the first
   screenful of scroll. min-height lets body grow with content. */
html { height: 100%; }
body { min-height: 100%; }
body {
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
table { border-collapse: collapse; border-spacing: 0; }
/* Focus outline: --focus-ring is assigned at C1 (receipt-tagged in
   tokens.css); currentColor keeps focus visible meanwhile. */
:focus-visible { outline: 2px solid var(--focus-ring, currentColor); outline-offset: 2px; }

/* ============================================================
   LA ROSA TATTOO - design tokens (C1, 2026-08-15)
   A custom mood on the Aurochs DS-4.0 spine: identity tokens
   overridden, architecture/scales/motion/a11y inherited.
   Spine: C:/Work Work/Aurochs/MCP Workspace/Aurochs/docs/design-system-v4.0.html

   RECEIPT TAGS: every identity value cites its extraction source.
   [1221] storefront photo (facade, neon, A-frame, flash windows)
   [1196/1198] door-sign wordmark (white + gold colorways)
   [1202/1261] LR emblems (floral white variant, thorn black variant)
   [1191/1214/1220] flash sheets on paper (interior)
   [reviews] GT §6 corpus ("clean and bright", "beautiful shop")
   SAMPLED values are eyeball-derived from CDN-capped photos and
   are flagged; exact fills upgrade from the vector door PDFs /
   originals at State B. Model-taste entries are flagged [taste]
   and sit at the D12 gate.
   DEFAULT DIRECTION CHANGED 2026-08-30 (Stefan): the shipped default is now
   OXBLOOD, not Flash Paper. `:root` below carries Oxblood's values, so a
   production build with no attribute and no JavaScript ships Oxblood. The
   original extracted Flash Paper values, with their receipt tags intact, moved
   to styles/palettes.css as `[data-palette="flashpaper"]` and remain fully
   available. Their red (#CE3A28), press shade and sign gold are UNCHANGED and
   still carry their [1221]/[1196] receipts: only the grounds, the ink, the
   structural colour, the type and the measure differ between directions.
   ============================================================ */

:root {
  /* -- Grounds: flash-paper cream, not gallery white -------------
     Their windows are a wall of flash drawn on warm paper [1221],
     gold-paper flash inside [1191]; the room reads bright and warm
     [reviews, 1215/1219]. SAMPLED. */
  --bg: #F6EFE8;            /* OXBLOOD ground: warm paper that carries a little of
                               the structure's red so the page reads as one temperature */
  --bg-warm: #EFE5DC;       /* deeper paper for alternating bands */
  --bg-card: #FCF7F2;       /* raised card/paper sheet */

  /* -- Ink ------------------------------------------------------
     Their linework, sign shadows, window lettering are near-black
     ink, not pure #000 [1196 drop shadows, 1214/1220 flash line]. */
  --fg: #1F1714;            /* warm near-black, never #000. 15.48:1 on --bg */
  --fg-dim: #5C4F49;        /* 6.90:1 on --bg, 6.33 on --bg-warm, 7.39 on card */
  --fg-faint: #6E5F58;      /* captions/meta */

  /* -- Structure: facade navy ----------------------------------
     The painted Victorian storefront is a deep blue-charcoal
     [1221]. Used for the footer band, dark structural surfaces,
     and the header on scroll - the site wears their paint. */
  --facade: #5C1913;        /* THE STRUCTURE. Derived, not sampled: THEIR neon #CE3A28
                               darkened to structural weight. DEEPENED 2026-08-31
                               (Stefan: darker, more appropriate) from #6E2018.
                               Cream on it 11.33:1, gold 4.22:1 (was 9.65 / 3.59),
                               so both improved. Held at this depth deliberately:
                               one step further (#4B1410) it stops reading as red
                               and becomes near-black, which is the dark-parlor
                               anti-reference PRODUCT.md rules out. Saturation is
                               unchanged at 0.79, hue unchanged at ~5deg, so it is
                               still their red, just deeper. */
  --facade-deep: #4A1310;   /* darker oxblood for depth [derived]. Followed the
                               facade down; at the old #571913 it would have been
                               LIGHTER than the new facade and inverted the depth. */
  --facade-deepest: #3B100B; /* DEEPEST STRUCTURAL GROUND, added 2026-09-03 (Stefan,
                               via impeccable live accept 73e2a769 at ground 0.65).
                               Used by ONE band, .band--visit, and deliberately not
                               by --facade itself.
                               The note on --facade above says a step this deep
                               "stops reading as red and becomes near-black", the
                               dark-parlor anti-reference. That warning is why this
                               is a separate token and not a change to --facade: the
                               footer, the header on scroll and every other
                               structural surface hold at #5C1913, so at most one
                               band ever sits this deep and the page keeps its red
                               structure. Measured rather than asserted: channels are
                               R59 G16 B11, red still 3.7x green, oklab hue unchanged
                               at ~31deg, chroma 0.079 against the facade's 0.117, so
                               it is a darker red and not a neutral. Cream on it
                               14.36:1, gold 5.34:1 (large text only, which is where
                               gold is used).
                               Derivation, so the other palettes can follow: the
                               palette's own --facade mixed 24.3% toward black in
                               oklab, which scales L and chroma together and stays in
                               gamut. Reducing oklab L alone clips oxblood to #440101,
                               a pure primary, which is why that rule was rejected. */
  --on-facade: #F4EEE1;     /* cream text on facade == --bg [contrast 9.6:1 approx] */

  /* -- Action: their red ----------------------------------------
     The neon "LA ROSA TATTOO" and the TATTOO A-frame are the
     shop's own action color [1221]. ONE action color, used for
     [data-cta-primary] and data-channel-action surfaces only. */
  --accent: #A82C1A;        /* DEEPENED 2026-08-31 (Stefan: darker, more appropriate).
                               Their literal neon is #CE3A28 [1221; sampled] and is kept
                               exactly, receipts intact, in the Flash Paper direction. In
                               OXBLOOD the structure is already their red darkened, so a
                               bright neon action beside a deep oxblood structure read as
                               two unrelated reds. This is the same hue at action depth:
                               one red story at two weights. White on it 6.91:1 (was 4.93). */
  --accent-press: #8A2415;  /* link text + pressed. 7.86:1 on --bg (was 5.49). This token
                               is the TEXT shade, not just a pressed state (DESIGN.md). */
  --on-accent: #FFFFFF;     /* white letters on red, exactly their A-frame [1221] */

  /* -- Fine accent: sign gold -----------------------------------
     The gold colorway of their own wordmark [1196 lower variant].
     Rules, small ornaments, hover glints. Never a text color on
     cream (contrast fails); always decorative or on facade. */
  --gold: #B08D4C;          /* sign-gold [1196; sampled] */
  --gold-dim: rgba(176, 141, 76, 0.40);

  /* -- Proof green (used sparingly for open/walk-in signals) ----
     [taste] flagged: the plants in every window/room frame [1221,
     1215, 1219] justify a leaf tone if C2 wants an "open now"
     tick; NOT part of the core scheme. */
  --leaf: #4A6B4F;          /* [taste, D12; plants in 1221/1215] */

  /* -- Type -----------------------------------------------------
     D14: self-hosted woff2, max 2 families, full ES diacritics.
     EXTRACTED [live-computed 08-15]: the live site's loaded type
     identity is Playfair Display (400/600/700; the LA ROSA TATTOO
     heading renders 52px/700) + DM Sans 400 body. Adopted per the
     extraction-first law after Stefan caught the earlier
     Besley/Archivo pairing as taste asserted over an unchecked
     live surface (the SFFM slop-cause-1 class; correction CD17).
     The wordmark itself always renders as their extracted art
     [1196/1199], never re-typeset. */
  --font-display: "Playfair Display", Georgia, serif;   /* SWAPPED 2026-08-31 */
  --font-body: "DM Sans", system-ui, sans-serif;
  --font-ui: var(--font-body);

  /* -- Scales: inherited from the DS-4.0 spine ------------------ */
  /* -- Type scale. Every step clears 1.25x; the 12-19px pile-up that made
        nothing rankable is gone. Map declarations onto these, never invent. */
  --t-xs:   0.8rem;    /* 12.8px  micro-labels, captions */
  --t-sm:   0.875rem;  /* 14px    meta, hours, credits */
  --t-base: 1rem;      /* 16px    body */
  --t-md:   1.125rem;  /* 18px    lede / standfirst */
  --t-lg:   1.25rem;   /* 20px    sub-headings */
  --t-xl:   1.5rem;    /* 24px    minor headings */
  --t-2xl:  clamp(1.7rem, 3.2vw, 2.2rem);   /* band h2 */
  --t-3xl:  clamp(2.3rem, 3.6vw, 3.2rem);   /* page h1 */

  --header-h: 88px;
  /* -- Measure scale (2026-08-25) ------------------------------
     Replaces eleven ad-hoc `ch` caps (22/26/30/32/40/42/46/52/54/
     56/62ch) that had accreted across six stylesheets. Measured
     symptom: on /how-it-works/ at 1440px the same 16px body text
     rendered 503px in one band and 613px in the next, under h2s
     running the full 1165px, so every band stopped at a different
     place and the right edge read as ragged.

     Expressed in REM, not ch, on purpose: `ch` resolves against
     each element's OWN font size, so a heading capped at Nch and
     its paragraph capped at Nch never share a right edge. A rem
     measure lets the heading and the prose it heads occupy one
     column. Each palette may retune --measure for its own font
     width; that is the correct per-palette knob. */
  --measure-tight: 26rem;   /* measures follow the FACE, so they swapped too */
  --measure: 32rem;         /* ~46ch in DM Sans */
  --measure-wide: 40rem;    /* lists and dense reference blocks */

  --container-max: 1100px;
  --container-padding: clamp(16px, 4vw, 80px);
  /* Wider body-content tiers (Stefan 2026-08-16): the container steps up at
     1440 and 2560 so big screens use their width; prose stays capped by its
     ch measure, so reading lines never stretch with the layout. */
  --space-4: 4px;  --space-8: 8px;  --space-12: 12px; --space-16: 16px;
  --space-20: 20px; --space-24: 24px; --space-32: 32px; --space-40: 40px;
  --space-48: 48px; --space-64: 64px; --space-80: 80px; --space-120: 120px;

  /* Radius: trad flash sheets and their framed walls are square
     [1214/1220]; soft app-radii would fight the register. Spine
     values, small end only. */
  --radius-none: 0px;
  --radius-sm: 2px;
  --radius-md: 3px;

  /* Shadows: paper-weight, not app-glow [spine] */
  --shadow-sm: 0 1px 3px rgba(26, 22, 19, 0.12);
  --shadow-md: 0 2px 12px rgba(26, 22, 19, 0.16);

  /* Motion: spine defaults; street shop, not tech demo (plan §5).
     Reveals only, ease-out, reduced-motion kills all (site.js). */
  --ease-out: cubic-bezier(0.33, 1, 0.68, 1);
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 350ms;

  /* A11y */
  --focus-ring: var(--accent);
}

/* Body-content width tiers (2026-08-16): larger screens get a wider
   container. 1280px from 1440 viewports, 1680px from 2560. */
@media (min-width: 1440px) {
  :root { --container-max: 1280px; }
}
@media (min-width: 2560px) {
  :root { --container-max: 1680px; }
}

/* global.css - C1 (S4 direction) base layer on tokens.css.
   Receipts + flagged decisions: styles/tokens.css header + docs/direction-2026-08-15.md */

/* -- Self-hosted fonts (D14; latin subset covers ES diacritics + inverted marks) -- */
@font-face {
  font-family: "Playfair Display";
  src: url("/fonts/playfair-display-var-latin.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "DM Sans";
  src: url("/fonts/dm-sans-var-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* -- Ground -- */
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* -- Display voice: Playfair Display carries headings (CD17: extracted from
      the live site, which self-hosts PlayfairDisplay + DMSans - re-verified
      2026-08-15); the wordmark itself is always
      their extracted art, never re-typeset (plan row 17 / D16 dead) -- */
h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
h1 { font-weight: 700; }
h2, h3 { font-weight: 700; }

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-padding);
}

a { color: inherit; }
a:hover { color: var(--accent-press); }

:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* -- The one action color: their neon/A-frame red (row 7 ranked channels).
      White-on-red uppercase echoes the TATTOO A-frame [1221]. -- */
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  width: fit-content;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 14px 22px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  transition: background var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.btn-primary:hover { background: var(--accent-press); color: var(--on-accent); }
.btn-primary:active { transform: scale(0.97); }

/* Skip link: visually hidden until keyboard focus (mechanics, not design). */
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.skip-link:focus {
  position: fixed;
  top: 0;
  left: 0;
  width: auto;
  height: auto;
  clip-path: none;
  z-index: 999;
  background: var(--bg-card);
  color: var(--fg);
  padding: var(--space-12) var(--space-16);
}

@media (prefers-reduced-motion: reduce) {
  .btn-primary { transition: none; }
}

/* -- Band base rhythm (C2) -- */
.band { padding-block: var(--space-64); }
.band > .container > h2,
.band__h {
  font-size: var(--t-2xl);
  margin-block-end: var(--space-24);
}
/* The subordinate step. Without this every sub-heading rendered at h2 size
   (measured ratio 1.00), which is the mechanical cause of the flat, "busy"
   read across the whole site. */
.how-triad__h,
.aftercare-steps__h {
  font-size: var(--t-lg);
  margin-block-end: var(--space-8);
}
.band__more a {
  font-weight: 600;
  color: var(--accent-press);
  text-underline-offset: 4px;
}

/* C6 (eyes-on catch): prose links must LOOK like links; components opt out. */
main a:not(.btn-primary):not(.rail-card--link) {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

/* -- Reading rhythm (2026-08-15) ---------------------------------------
   Body copy was running the full container width with no vertical rhythm,
   which reads as unset type on a page rather than designed content. Cap the
   measure at the house 65-75ch and give stacked prose consistent spacing.
   Grids, rails and strips opt out: they are layout, not prose. */
.band p,
.band ul,
.band ol {
  /* Was 46ch. The ch value was right for a paragraph in isolation (1ch, the
     "0" glyph, is ~1.54x an average prose character in DM Sans, so the
     earlier 68ch rendered ~95-105 characters). It was wrong as a SYSTEM:
     ch resolves per element font-size, so headings never aligned with the
     prose under them. --measure is the rem equivalent and is shared. */
  max-width: var(--measure);
}
.band p + p { margin-block-start: var(--space-16); }
.band h2 + p,
.band h3 + p { margin-block-start: var(--space-12); }
.band li + li { margin-block-start: var(--space-8); }
.band h3 { margin-block-start: var(--space-24); }
/* Was 40ch here and 52ch in comp-inner-hero.css: two rules, same selector,
   different measures, so which one won depended on stylesheet order. One
   rule now, one value. */
.inner-hero__lede { max-width: var(--measure-tight); font-size: var(--t-md); }

/* Layout containers keep their own width. */
.work-gallery p, .flash-row p, .crew-strip p, .shop-strip p,
.rail p, .how-triad p, .bench p, .channels p { max-width: none; }

body { background: var(--bg); }



/* -- The prose column (2026-08-25) -------------------------------------
   THE fix for the ragged-measure problem. A band that carries only prose
   narrows its CONTAINER to the measure, so the heading and the paragraphs
   under it occupy one column with one right edge. A band that carries a
   grid, gallery, rail, strip or form keeps the full container: those are
   layout, and layout wants the width.

   Done with :has() rather than by tagging 104 band instances across 42
   page files by hand. The band's background still spans the full viewport;
   only the text column narrows. */
/* .glance added 2026-09-04: the /reports/ hub is a LAYOUT band (its levers table
   needs the full container); its prose keeps its own 46ch measure via the
   .glance__* max-widths, so exempting the container widens the table, not the text. */
.band > .container:not(:has(.bench, .glance, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid)) {
  max-width: calc(var(--measure) + 2 * var(--container-padding));
}

/* The companion rule. A LAYOUT band keeps its wide container (the grid wants
   the width), but its heading and its intro prose still share one column, so
   their right edges agree. Without this a band like band--clean rendered a
   1165px h2 directly over a 512px paragraph, a 2.3x mismatch that read as
   the heading having come loose from its own text. --measure-wide rather
   than --measure: an intro standing above a full-width strip can carry more
   width than a pure prose band. */
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > h2,
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > .band__h,
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > h3,
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > p,
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > ul,
.band > .container:has(.bench, .booking-form, .channels, .clean-strip, .crew-strip, .flash-row, .flash-strip, .hero-grid, .how-triad, .merch-strip, .proof-track, .q-export, .rail, .rail--hub, .shop-strip, .work-gallery, .work-grid) > ol {
  max-width: var(--measure-wide);
}

/* The ranked channel band (row 7). */
.band--cta { background: var(--bg-warm); }
.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-16) var(--space-24);
}
.cta-band__dm { font-weight: 600; text-underline-offset: 4px; }
.cta-band__walkin {
  margin-block-start: var(--space-16);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* comp-footer.css - site footer.
   LEDGER LOCKED IN 2026-08-30 (Stefan). The three-variant flip is over.

   What was here: three arrangements of the same five groups (Signboard,
   Window, Ledger) selectable with data-footer, so the direction could be
   chosen by looking rather than by argument. Ledger won, so it is now the
   only footer and it renders with no attribute set. Signboard and Window are
   deleted rather than left as dead selectors, and the footer control is gone
   from the preview switcher for the same reason: a decided question should
   stop offering itself.

   Why Ledger, recorded for whoever reads this next: it is the arrangement
   that scales. The shop's facts live in a real three-column grid on gold
   rules, so hours, a second location, or a flash-day link can join later
   without a redesign. The other two were compositions; this one is a table.

   THE EMBLEM. The shipped file was a 1600x1600 canvas whose artwork occupied
   only 320x329 of it, 20%, offset 395px left and 134px above centre, so a
   128px box rendered a ~26px mark. footer.py now points at a trimmed
   derivative in which the art fills 97% of the frame. */

/* ── Shell ─────────────────────────────────────────────────────────────── */

.site-footer {
  background: var(--facade);
  color: var(--on-facade);
  margin-top: 0;                    /* was 80px of empty cream above the footer */
}
.site-footer a { color: var(--on-facade); }
.site-footer a:hover { color: #C9A867; }  /* gold at 3.68:1 fails AA on facade at body size */

.footer-inner {
  padding-block: var(--space-48) var(--space-32);
  display: grid;
  gap: var(--space-24);
  font-size: 0.9rem;
}

.footer-emblem {
  width: 88px;
  height: auto;
  display: block;
}

.footer-bilingual {
  /* Their own sentence, so it gets display type and the one gold use the
     token rules allow on facade: large text only, never body size. */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.28rem;
  line-height: 1.25;
  color: var(--gold);
  margin: 0;
  max-width: 22ch;
}

.footer-facts p { margin: 0; }
.footer-address { color: rgba(244, 238, 225, 0.9); }
.footer-phone { margin-block-start: var(--space-4) !important; }
.footer-phone a { text-decoration-thickness: 1px; }

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-20);
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8) var(--space-20);
  align-items: baseline;
}
.footer-base p { margin: 0; }
.footer-legal { color: rgba(244, 238, 225, 0.72); }
.kicker {
  font-family: var(--font-ui);
  font-size: 0.8rem;
  color: rgba(244, 238, 225, 0.72);
}

/* ── The Ledger, from 880px up ─────────────────────────────────────────── */

@media (min-width: 880px) {
  .footer-inner {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "say   say   say"
      "rule  rule  rule"
      "facts nav   base";
    column-gap: var(--space-40);
    row-gap: var(--space-16);
    align-items: start;
    padding-block: var(--space-48) var(--space-32);
  }

  /* The mark rides inline with their sentence rather than owning a column,
     which is what keeps the three fact columns equal. */
  .footer-mark {
    grid-area: say;
    align-self: center;
    justify-self: start;
  }
  .footer-say {
    grid-area: say;
    justify-self: start;
    align-self: center;
    padding-inline-start: calc(56px + var(--space-20));
  }
  .footer-facts { grid-area: facts; }
  .footer-nav   { grid-area: nav; }
  .footer-base  { grid-area: base; }

  .footer-emblem { width: 56px; }
  .footer-bilingual { font-size: 1.32rem; max-width: none; }

  /* the gold rule under the statement */
  .footer-inner::before {
    content: "";
    grid-area: rule;
    height: 1px;
    background: var(--gold-dim);
    margin-block: var(--space-12);
  }

  .footer-nav .footer-links { flex-direction: column; gap: var(--space-8); }
  .footer-base { flex-direction: column; gap: var(--space-8); }

  /* vertical gold hairlines between the three columns */
  .footer-nav,
  .footer-base {
    border-inline-start: 1px solid var(--gold-dim);
    padding-inline-start: var(--space-24);
  }
}

/* ── Mobile: one stacked column ────────────────────────────────────────── */

@media (max-width: 879px) {
  .footer-inner { grid-template-columns: minmax(0, 1fr); }
  .footer-bilingual { font-size: 1.34rem; max-width: 24ch; }
  .footer-nav {
    padding-block-start: var(--space-8);
    border-block-start: 1px solid var(--gold-dim);
  }
  .footer-nav .footer-links { padding-block-start: var(--space-16); }
}

@media (prefers-reduced-motion: reduce) {
  .site-footer * { transition: none !important; }
}

/* Booking fallback form (row 12). */
.booking-form { max-width: 560px; display: flex; flex-direction: column; gap: var(--space-16); }
.booking-form__row { display: grid; gap: var(--space-16); }
@media (min-width: 640px) { .booking-form__row { grid-template-columns: 1fr 1fr; } }
.field { display: flex; flex-direction: column; gap: var(--space-4); }
.field__label { font-weight: 600; font-size: 0.95rem; }
.field__es { font-weight: 400; color: var(--fg-faint); }
.field__req { color: var(--accent-press); }
.field__control {
  font: inherit;
  padding: 10px 12px;
  background: var(--bg-card);
  border: 1px solid rgba(26, 22, 19, 0.25);
  border-radius: var(--radius-sm);
  color: var(--fg);
}
.field__control:focus-visible { border-color: var(--accent); }
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; }
.booking-form__status.is-error { color: var(--accent-press); font-weight: 600; }
.booking-form__note, .booking-form__sent { font-size: 0.9rem; color: var(--fg-dim); }

/* -- Form v2 (change-plan row 3, ratified G-C1 2026-08-24) -------------
   The triage placeholders carry the T7 guidance, so they read as prompts,
   not ghosts; the select joins the .field__control system. */
.field__control::placeholder { color: var(--fg-faint); opacity: 1; }
select.field__control { cursor: pointer; }

/* comp-header.css - header + mobile drawer. STUB: visual design lands at C1.

   The rules below are the MECHANICS CONTRACT of /js/site.js mobileDrawer()
   only: visibility states plus a transition, because the close path waits on
   transitionend (reduced-motion closes immediately, matching the media query
   below). Colors use CSS system colors (Canvas/CanvasText) so no brand
   decision is made here; C1 replaces them with tokens. */

/* Hamburger toggle: without dimensions the button collapses to 0x0 and the
   drawer can never open (found at the C0 dev-serve proof). Bars ride
   currentColor; sizes are generic tap-target mechanics. The 881px breakpoint
   is site.js's own mobileDrawer() constant, mirrored here. */
.menu-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 12px;
}
.menu-toggle__bar {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
}
@media (min-width: 881px) {
  .menu-toggle { display: none; }
}
@media (max-width: 880px) {
  .primary-nav { display: none; }
}

.drawer-overlay {
  position: fixed;
  inset: 0;
  opacity: 0;
  transition: opacity 160ms linear;
}
.drawer-overlay.is-open { opacity: 1; }

.mobile-nav {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(20rem, 100%);
  background: Canvas;
  color: CanvasText;
  opacity: 0;
  transition: opacity 160ms linear;
  z-index: 10;
}
.mobile-nav.is-open { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .drawer-overlay,
  .mobile-nav { transition: none; }
}

/* -- C1 paint (tokens; receipts in tokens.css) ------------------------- */
/* The header had the SAME ground as the body, so it read as nothing at all.
   Give it its own lighter paper, a real edge, and enough height for the
   mark to be a mark rather than a favicon. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 8;  /* under .text-bar (9) and the drawer (10) */
  background: var(--bg-card);
  border-bottom: 1px solid rgba(26, 22, 19, 0.22);
  box-shadow: 0 1px 0 rgba(26, 22, 19, 0.05), 0 6px 18px -14px rgba(26, 22, 19, 0.5);
}
/* ACCEPTED VARIANT 1, impeccable live 2026-08-31 (Stefan: "clean this up,
   make it look more professional"). Chosen axis: HIERARCHY.

   What it replaces: a flex row where the mark, the nav, the language toggle
   and the burger all sat at one weight with space-between deciding the
   rhythm, so nothing led. Now a three-cell grid, and the left cell is a
   composed lockup: the mark at 72px with the shop name and the city set
   beside it. The nav drops to --fg-dim at 0.9rem, which is what makes the
   lockup read as the anchor rather than as one more item in a row. */
.site-header__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-40);
}
.site-header__wordmark {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: auto auto;
  column-gap: var(--space-12);
  align-items: center;
  text-decoration: none;
}
.site-header__wordmark img {
  display: block;
  grid-row: span 2;
  width: 72px;
  height: 72px;
}
.site-header__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.22rem;
  letter-spacing: 0.01em;
  line-height: 1;
  color: var(--facade);
  align-self: end;
}
.site-header__place {
  font-family: var(--font-ui);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-dim);
  align-self: start;
  margin-block-start: 4px;
}
.site-header__right { display: flex; align-items: center; gap: var(--space-16); }
.site-header__inner { padding-block: var(--space-8); }
.primary-nav a {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 0.9rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--fg-dim);            /* recedes; the lockup leads */
  padding: var(--space-8) var(--space-4);
}
.primary-nav a:hover { color: var(--facade); }
.primary-nav a.is-current {
  color: var(--accent-press);
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-thickness: 2px;
}
.primary-nav ul {
  display: flex;
  gap: var(--space-24);
  list-style: none;
  margin: 0;
  padding: 0;
}
.mobile-nav {
  background: var(--bg);
  color: var(--fg);
}
.mobile-nav__nav a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.6rem;
  text-decoration: none;
}
.mobile-nav__nav a:hover, .mobile-nav__nav a.is-current { color: var(--accent-press); }

.nav__lang-note { font-size: 0.65em; font-weight: 600; letter-spacing: 0.06em; color: var(--fg-faint); vertical-align: super; }

/* -- EN / ES toggle. The shop is bilingual by identity, so the language
      choice belongs in the header as a control, not buried as a link in
      hero copy. Current language is inert text; only the other side is a
      link. -- */
.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  margin-inline-start: var(--space-24);
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: var(--space-4) var(--space-8);
  border: 1px solid rgba(26, 22, 19, 0.28);
  border-radius: var(--radius-sm);
}
.lang-toggle__on { color: var(--accent-press); }
.lang-toggle__off { color: var(--fg-dim); text-decoration: none; }
.lang-toggle__off:hover { color: var(--fg); }
.lang-toggle__sep { color: var(--fg-faint); }
@media (max-width: 880px) { .lang-toggle { margin-inline-start: auto; margin-inline-end: var(--space-12); } }

/* Over the hero photograph on the homepage. */
.page-home .site-header .lang-toggle__off,


/* Everything except the mark floats right (Stefan 2026-08-15): the mark
   anchors the left edge, the nav, language toggle and menu button group
   together on the right. */
/* Superseded by the grid above: with three explicit cells the auto margins
   have nothing left to do. The nav right-aligns inside its own cell. */
.primary-nav ul { justify-content: flex-end; gap: var(--space-32); }

/* The drawer's close control shipped with no rules at all. */
.mobile-nav__head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-20) var(--space-24); }
.mobile-nav__close { min-width: 44px; min-height: 44px; border: 0; background: transparent; font-size: 1.6rem; line-height: 1; color: var(--fg); cursor: pointer; }
.mobile-nav__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 17x19px is below even the 24px WCAG 2.5.8 floor, on a primary control. */
.lang-toggle__off, .lang-toggle__on { display: inline-flex; align-items: center; min-height: 44px; padding-inline: var(--space-4); }


/* Below the nav breakpoint the grid collapses to mark | right, and the city
   line is dropped: at that width it is noise beside a 72px mark. */
@media (max-width: 880px) {
  .site-header__inner { grid-template-columns: auto auto; justify-content: space-between; gap: var(--space-16); }
  .site-header__wordmark img { width: 52px; height: 52px; }
  .site-header__name { font-size: 1.02rem; }
  .site-header__place { display: none; }
}

/* Inner-page opening band (booking, result pages; C3/C4 pages inherit). */
.inner-hero { padding-block: var(--space-48) var(--space-24); }
.inner-hero h1 { font-size: clamp(2.2rem, 6vw, 3rem); margin-block-end: var(--space-12); }
/* max-width moved to global.css (it was fighting a 40ch rule on the same
   selector). Colour and size stay here. */
.inner-hero__lede { font-size: 1.1rem; color: var(--fg-dim); }

/* comp-preview-switcher.css - the staging-only style switcher (2026-08-25).

   Renders only on preview builds. Deliberately NOT dressed in the site's own
   tokens: it is a tool sitting on top of the work, not part of it, so it uses
   fixed values and reads the same whichever of the three directions is
   active. If it inherited --bg and --fg it would restate whichever direction
   is switched on, which is exactly what a control for comparing directions
   must not do. Fixed values keep it neutral in all three.

   Placement: bottom-right on desktop. Below 880px the site has a fixed
   bottom text bar, so the control lifts above it rather than covering the
   one persistent action on the page. */

.pv {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 900;                 /* under a focused skip link, over content */
  font-family: ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  font-size: 13px;
  line-height: 1.35;
  color: #F2F0EC;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  max-width: min(320px, calc(100vw - 32px));
}

@media (max-width: 879px) {
  /* clear of the fixed text bar */
  .pv { bottom: 76px; right: 12px; }
}

.pv__toggle {
  appearance: none;
  border: 1px solid rgba(242, 240, 236, 0.28);
  background: #1C1F26;
  color: #F2F0EC;
  font: inherit;
  padding: 8px 14px;
  border-radius: 2px;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
.pv__toggle:hover { background: #262A33; }
.pv__toggle:focus-visible { outline: 2px solid #7FB2FF; outline-offset: 2px; }

.pv__panel {
  background: #1C1F26;
  border: 1px solid rgba(242, 240, 236, 0.22);
  border-radius: 2px;
  padding: 14px 16px 12px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
  display: grid;
  gap: 16px;
  width: min(320px, calc(100vw - 32px));
  max-height: min(70vh, 620px);
  overflow-y: auto;
}
.pv__panel[hidden] { display: none; }

.pv__group { border: 0; margin: 0; padding: 0; display: grid; gap: 6px; }
.pv__group legend {
  padding: 0 0 4px;
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(242, 240, 236, 0.6);
}

.pv__opt {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 8px;
  align-items: baseline;
  padding: 6px 8px;
  border-radius: 2px;
  cursor: pointer;
}
.pv__opt:hover { background: rgba(242, 240, 236, 0.07); }
.pv__opt input { grid-row: span 2; margin: 2px 0 0; accent-color: #7FB2FF; }
.pv__opt-name { font-weight: 600; }
.pv__opt-note {
  grid-column: 2;
  font-size: 11.5px;
  color: rgba(242, 240, 236, 0.62);
}
.pv__opt:focus-within { outline: 2px solid #7FB2FF; outline-offset: 1px; }

.pv__note {
  margin: 0;
  padding-block-start: 10px;
  border-block-start: 1px solid rgba(242, 240, 236, 0.16);
  font-size: 11.5px;
  color: rgba(242, 240, 236, 0.55);
}

@media print { .pv { display: none; } }

/* comp-textbar.css - the D11 mobile text bar (plan section 2, R5 easy path).

   Mobile-only: the ceiling matches the drawer breakpoint (880px, site.js's
   own constant). Fixed to the viewport bottom; body compensates with
   padding so the footer's last line never hides beneath it. Safe-area
   padded for notched phones. Contrast: on-accent on accent, the shipped
   btn-primary AA pair; the ES sub-line repeats the booking CTA's explicit
   on-accent + weight rule (the IMP-2/axe lesson, never opacity-faded).
   z-index 9 sits UNDER the mobile drawer (10), so the open drawer covers
   the bar. */

.text-bar { display: none; }

@media (max-width: 880px) {
  body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }

  .text-bar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 9;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 56px;
    padding: var(--space-8) var(--space-16);
    padding-bottom: calc(var(--space-8) + env(safe-area-inset-bottom, 0px));
    background: var(--accent);
    color: var(--on-accent);
    text-decoration: none;
    text-align: center;
    font-family: var(--font-ui);
    box-shadow: 0 -1px 0 rgba(26, 22, 19, 0.18);
  }
  .text-bar:active { background: var(--accent-press); }

  .text-bar__main {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.01em;
  }
  .text-bar__sub {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--on-accent);
    opacity: 1;
  }
}


/* Hidden while the hero's own CTA is visible: the two are the same action,
   and the bar was sitting directly on top of the button. site.js adds
   .text-bar--armed once the hero CTA scrolls away. No JS means the bar
   simply shows, which is the safe default. */
@media (max-width: 880px) {
  html:not(.no-js) .text-bar { opacity: 0; pointer-events: none; transform: translateY(100%); transition: opacity 220ms var(--ease-out), transform 260ms var(--ease-out); }
  html:not(.no-js) .text-bar--armed { opacity: 1; pointer-events: auto; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  html:not(.no-js) .text-bar { transition: none; }
}

/* Booking page bands. */
.band--channels { padding-block-start: 0; }
.channels { display: flex; flex-direction: column; gap: var(--space-16); align-items: flex-start; }
.channels__sub { font-weight: 400; opacity: 0.85; }
.channels__dm { font-weight: 600; text-underline-offset: 4px; }
.channels__artist-note { color: var(--fg-dim); font-size: 0.95rem; }
.band--walkin { background: var(--bg-warm); }
.walkin__hours { font-weight: 600; }
.walkin__address a { color: var(--accent-press); }
.walkin__note {
  font-size: 0.85rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--fg-faint);
}
.band--next { background: var(--bg-warm); }
.band--next p { max-width: var(--measure); color: var(--fg-dim); }

/* Dual-language primary: EN leads, ES stacks under (C2 eyes-on fix). */
.channels__text { flex-direction: column; align-items: flex-start; gap: 2px; }
.channels__text .channels__sub { font-size: 0.8em; letter-spacing: 0.04em; }

.walkin__phone a { color: var(--accent-press); }

/* S7 axe fix: any dual-language sublabel INSIDE a red action surface renders white */
.btn-primary .field__es, .btn-primary .channels__sub { color: var(--on-accent); }

/* S7 definitive: the ES sublabel inside the red primary is full-white, 600,
   opacity 1 (12px/400 at reduced opacity failed axe AA). */
a.btn-primary .channels__sub { color: var(--on-accent); font-weight: 600; opacity: 1; }

/* pages-home.css - C1: the hero band (row 23 composition budget).
   Mobile-first at the 390x844 receipt viewport: photo >= 50svh leads,
   the cream panel below carries exactly the four content elements.
   Composition language: photograph over flash-paper, like their windows. */

/* HERO: Matt Frederick's gallery-walk pattern (hero--v5), columns SWAPPED
   so the photographs lead on the left and the type sits on the right. The
   focus card carries a two-layer shadow; its neighbours step back in
   perspective. Type sits on the page's own paper: no card, no tint. */
/* Flush bottom edge (impeccable live accept 988c0e68, 2026-08-16): the hero
   meets the proof band with no slack. */
.hero--walk { padding-block: 0; overflow-x: clip; }
.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-24);
  align-items: center;
}
@media (min-width: 881px) {
  .hero-grid { grid-template-columns: minmax(0, 66%) minmax(0, 34%); gap: var(--space-64); align-items: center; }
  /* Text column keeps a reading inset; the image column stays flush to the
     viewport edge, which is the point of taking the hero out of .container. */
  .hero-text { padding-inline-end: var(--container-padding); max-width: 100%; }
}

.hero-walk {
  position: relative;
  width: 100%;
  height: clamp(430px, 122vw, 510px);
  overflow: hidden;
}
/* Desktop: fill the fold below the header (accepted knobs: hero-h=1.0,
   photo split 66%), capped so ultra-tall monitors don't stretch the crop. */
@media (min-width: 881px) { .hero-walk { height: min(calc(100svh - var(--header-h)), 860px); } }

/* One image at a time, filling the whole 60% column. Slides stack and
   crossfade; no neighbours, no mat, no offsets. Opacity only (never
   visibility) so the outgoing frame fades instead of cutting. */
.walk-card {
  position: absolute;
  inset: 0;
  opacity: 0;
  z-index: 0;
  transition: opacity 1200ms var(--ease-out);
  will-change: opacity;
}
.walk-card.is-center { opacity: 1; z-index: 1; }
.walk-card.is-prev,
.walk-card.is-next,
.walk-card.is-far { opacity: 0; z-index: 0; }
.walk-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The landscape storefront slide: bias the crop toward the lit 693 door so
   the tall mobile crop keeps the neon and the open doorway in frame. */
.walk-card--wide img { object-position: 55% center; }

.walk-dots {
  position: absolute;
  inset-block-end: var(--space-16);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  gap: var(--space-8);
}
.walk-dot {
  width: 26px; height: 26px; padding: 0; border: 0;
  background: transparent; cursor: pointer; display: grid; place-items: center;
}
.walk-dot::before {
  content: "";
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(244, 238, 225, 0.65);
  transition: background var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
}
.walk-dot.is-active::before { background: var(--accent); transform: scale(1.35); }
.walk-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.hero-text {
  display: flex; flex-direction: column;
  align-items: flex-start; gap: var(--space-16);
  padding-inline: var(--container-padding);
  min-width: 0;
}
.hero-eyebrow {
  font-family: var(--font-ui); font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent-press);
}
.hero-headline {
  margin: 0; color: var(--fg);
  font-size: clamp(2.3rem, 3.6vw, 3.2rem); line-height: 1.0;
  overflow-wrap: break-word;
}
.hero__welcome { margin: 0; max-width: 30ch; font-size: 1.02rem; color: var(--fg-dim); }
.hero__welcome a {
  color: var(--accent-press); text-decoration: underline; text-underline-offset: 3px;
}
.hero__hours {
  margin: 0; font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-dim);
}

@media (prefers-reduced-motion: reduce) { .walk-card { transition: none; } }

/* -- Bands 2-6 (C2) -- */
/* Proof: dark stepping carousel (impeccable live accept 0e529ee6,
   2026-08-16; accepted knobs baked: 4s per step, no per-quote rules).
   Six verbatim slices ride a track; three visible on desktop, one on
   mobile. CSS-only: hover pauses, reduced-motion and no-JS collapse to a
   static stacked list. --proof-dwell stays a var for future tuning. */
.band--proof { background: var(--facade); --proof-dwell: 4s; }
.band--proof .proof__rating {
  color: var(--on-facade);
  display: flex; align-items: baseline; gap: var(--space-16);
  font-size: var(--t-md);
  margin-block-end: var(--space-40);
}
.band--proof .proof__rating strong {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2.6rem, 4.5vw, 3.8rem); line-height: 1; color: #FFF6EC;
  text-shadow: 0 0 12px rgba(206, 58, 40, 0.75), 0 0 28px rgba(206, 58, 40, 0.4);
}
.band--proof .proof__rating::after { content: ""; flex: 1; height: 1px; background: var(--gold-dim); }
.proof-win { overflow: hidden; }
.proof-track { display: flex; width: 600%; }
.proof-track .proof__quote { margin: 0; flex: 0 0 calc(100% / 6); padding-inline-end: var(--space-48); box-sizing: border-box; }
@media (min-width: 881px) { .proof-track { width: 200%; } }
.band--proof .proof__quote blockquote { color: var(--on-facade); font-size: var(--t-md); line-height: 1.55; }
.band--proof .proof__quote figcaption {
  margin-block-start: var(--space-12); color: #C9A867;
  letter-spacing: 0.08em; text-transform: uppercase; font-size: var(--t-sm);
}
@keyframes proofStep6 {
  0%, 22% { transform: translateX(0); }
  25%, 47% { transform: translateX(-16.667%); }
  50%, 72% { transform: translateX(-33.333%); }
  75%, 97% { transform: translateX(-50%); }
  100% { transform: translateX(0); }
}
@media (prefers-reduced-motion: no-preference) {
  html:not(.no-js) .proof-track { animation: proofStep6 calc(var(--proof-dwell) * 6) var(--ease-out) infinite; }
  html:not(.no-js) .proof-win:hover .proof-track { animation-play-state: paused; }
}
@media (prefers-reduced-motion: reduce) {
  .proof-track { flex-wrap: wrap; width: auto; }
  .proof-track .proof__quote { flex-basis: 100%; margin-block-end: var(--space-20); }
}
html.no-js .proof-track { flex-wrap: wrap; width: auto; }
html.no-js .proof-track .proof__quote { flex-basis: 100%; margin-block-end: var(--space-20); }
.proof__quote blockquote {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.15rem;
  line-height: 1.35;
  margin: 0 0 var(--space-8);
}
.proof__quote figcaption { color: var(--fg-faint); font-size: 0.9rem; }

.rail { display: grid; gap: var(--space-24); }
@media (min-width: 880px) { .rail { grid-template-columns: repeat(2, 1fr); gap: var(--space-32); } }
/* Home rail: three columns - two artist cards + the crew card (live accept
   85ae6df7; accepted knobs baked: navy tone, name scale 1.15). */
@media (min-width: 881px) { .rail--trio { grid-template-columns: repeat(3, 1fr); } }
.rail--trio .rail-card img { aspect-ratio: 3 / 2.6; }
.crew-card {
  --crew-name-scale: 1.15;
  background: var(--facade);
  color: var(--on-facade);
  padding: var(--space-32);
  display: flex;
  flex-direction: column;
}
.crew-card__title {
  font-family: var(--font-display);
  font-size: calc(var(--t-xl) * var(--crew-name-scale));
  margin: 0 0 var(--space-16);
}
.crew-card__list { list-style: none; margin: 0; padding: 0; flex: 1; }
.crew-card__list li {
  padding-block: var(--space-8);
  font-family: var(--font-display);
  font-size: calc(var(--t-lg) * var(--crew-name-scale));
}
.crew-card__list span {
  font-family: var(--font-body);
  font-size: var(--t-sm);
  opacity: 0.75;
  margin-inline-start: var(--space-8);
}
.crew-card__guest { margin: var(--space-16) 0 0; font-size: var(--t-sm); opacity: 0.8; }
.rail-card { margin: 0; }
/* Rail cards mix source aspects: portrait shop photos and square flash
   sheets. Pin the box so a square sheet cannot run the card to full height
   (caught eyes-on 2026-08-15 when Omar's flash joined the rail). */
.rail-card img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  height: auto;
  display: block;
}
.rail-card figcaption { padding-block-start: var(--space-12); }
.rail-card figcaption strong { font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; display: block; }
.rail-card__style { color: var(--fg-dim); }

/* How-it-works teaser: deep-navy hairline band (live accept 413ec5e3;
   accepted knobs baked: red separators, air 2). Scoped under .band--how so
   the /how-it-works/ page's own triad keeps its cream form. */
.band--how {
  background: var(--facade-deep);
  color: var(--on-facade);
  border-block: 1px solid rgba(201, 168, 103, 0.3);
}
.band--how h2 { color: var(--on-facade); }
.how-triad { display: grid; gap: var(--space-24); }
@media (min-width: 880px) { .how-triad { grid-template-columns: repeat(3, 1fr); gap: var(--space-32); } }
.how-triad__item h3 { font-size: 1.15rem; margin-block-end: var(--space-8); }
.how-triad__item p { color: var(--fg-dim); margin: 0; }
.band--how .how-triad__item { padding-block: var(--space-16); }
@media (min-width: 880px) {
  .band--how .how-triad { gap: 0; }
  .band--how .how-triad__item { padding-inline: var(--space-40); border-inline-start: 1px solid rgba(206, 58, 40, 0.5); }
  .band--how .how-triad__item:first-child { border-inline-start: none; padding-inline-start: 0; }
}
.band--how .how-triad__item h3 { color: var(--on-facade); font-size: var(--t-lg); display: inline-block; }
.band--how .how-triad__item h3::after {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  background: var(--accent);
  margin-block-start: var(--space-8);
}
.band--how .how-triad__item p { color: rgba(244, 238, 225, 0.82); }
/* /es/ reuses this band with in-copy links and the superscript EN note;
   both need on-navy colors (the note's fg-faint was 1.9:1 - axe caught it). */
.band--how a { color: #C9A867; }
.band--how .nav__lang-note { color: rgba(244, 238, 225, 0.75); }

/* The visit band, asymmetric edge layout (impeccable live accept 73e2a769,
   2026-09-03; chosen params ground 0.65, weight 0.5, bleed left).
   What it replaced and why: a 1fr 1fr grid holding a 4-up bordered image strip
   beside SIX sibling paragraphs at near-identical weight. Eleven competing
   objects and no entry point, which is the "feels very busy" Stefan picked it
   for. Here the flash bleeds to the left edge at full height and every word
   sits in one measure-wide column on the right. */
/* padding:0 is load-bearing, not tidy-up: the base .band supplies 64px block
   padding, which insets the flash and defeats the whole point of an edge
   bleed. The accepted variant killed it; this port dropped the line and the
   probe caught the images floating 64px off the band's top and bottom edge.
   The text column carries its own padding instead. */
/* padding:0 is load-bearing, not tidy-up: the base .band supplies block
   padding that insets the flash and defeats an edge bleed. The accepted
   variant killed it, this port dropped the line, and the probe caught the
   images floating off the band's top and bottom edge. The text column
   carries its own padding instead. The phone case needed a second fix: see
   the opt-out list in pages-inner.css. */
.band--visit { background: var(--facade-deepest); color: var(--on-facade); padding: 0; }
.band--visit a { color: var(--on-facade); text-underline-offset: 4px; }
.band--visit a:hover { color: var(--gold); }
.visit-edge { display: grid; align-items: center; }
.visit-edge__col {
  display: grid;
  gap: var(--space-12);
  max-width: var(--measure);
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-40) var(--container-padding);
}
.visit-edge__media { display: grid; grid-template-columns: 1fr 1fr; align-self: stretch; }
.visit-edge__media img {
  width: 100%; height: 100%; display: block; object-fit: cover; aspect-ratio: 1 / 1;
}
/* The flash line keeps its h2 so the document outline is unchanged; only its
   visual weight drops. Demoting it to a <p> would have looked identical and
   quietly removed a heading from the page. */
.visit-edge__flash {
  margin: 0; font-family: var(--font-body); font-size: 0.95rem;
  font-weight: 400; opacity: 0.9;
}
@media (min-width: 880px) {
  .visit-edge { grid-template-columns: 1fr 50%; }
  .visit-edge__media { grid-column: 1; grid-row: 1; }
  .visit-edge__col {
    grid-column: 2; grid-row: 1; justify-self: start; padding-block: var(--space-64);
  }
}
.visit__neighborhood { color: var(--gold); font-size: 1.17rem; font-weight: 700; }
.visit__ada { font-size: 0.85rem; opacity: 0.8; }

/* -- C3: linked cards + hub/bench/work-grid -- */
.rail-card--link { text-decoration: none; color: inherit; display: block; }
.rail-card--link:hover { color: inherit; }
.rail-card--link:hover figcaption strong { color: var(--accent); }
.rail--hub { margin-block-start: var(--space-24); }
.band--bench { background: var(--bg-warm); }
.bench { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-12); }
.bench a { color: var(--accent-press); text-underline-offset: 3px; }
.bench__note { margin-block-start: var(--space-16); color: var(--fg-faint); font-size: 0.9rem; }
.work-grid { display: grid; gap: var(--space-16); }
@media (min-width: 640px) { .work-grid { grid-template-columns: repeat(3, 1fr); } }
.work-grid__item { margin: 0; }
.work-grid__item img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 5; display: block; }
.work-grid__more { margin-block-start: var(--space-16); }
.work-grid__more a { color: var(--accent-press); }
.band--route { background: var(--bg-warm); }
.route__note { margin-block-start: var(--space-12); color: var(--fg-dim); }

.visit__phone a { color: var(--on-facade); text-underline-offset: 4px; }

/* -- C6 React Bits pass (native reimplementations; kills logged in the
      plan's C6 part 3). All of it dies under prefers-reduced-motion. -- */

/* 1. Hero word-rise: Split Text, reimagined as a once-only CSS mask rise. */
.hero-rise__w { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .hero-rise { overflow: hidden; }
  .hero-rise__w {
    transform: translateY(0.7em);
    opacity: 0;
    animation: hero-rise 640ms var(--ease-out) forwards;
  }
  .hero-rise__w:nth-child(2) { animation-delay: 90ms; }
  .hero-rise__w:nth-child(3) { animation-delay: 180ms; }
  @keyframes hero-rise { to { transform: translateY(0); opacity: 1; } }

  /* 4. One-time neon-catch sheen on the hero primary (Shiny Text energy,
     once, never looping - a loop is the SaaS tell). */
  .hero [data-cta-primary] { position: relative; overflow: hidden; }
  .hero [data-cta-primary]::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-130%) skewX(-18deg);
    background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,0.16) 50%, transparent 70%);
    animation: cta-sheen 900ms var(--ease-out) 700ms 1 forwards;
  }
  @keyframes cta-sheen { to { transform: translateX(130%) skewX(-18deg); } }

  /* 3. Reveal stagger on repeated children (Animated List energy on the
     existing scrollReveal; transition-delay only). */
  .rail-card:nth-child(2) { transition-delay: 70ms; }
  .rail-card:nth-child(3) { transition-delay: 140ms; }
  .work-grid__item:nth-child(2) { transition-delay: 70ms; }
  .work-grid__item:nth-child(3) { transition-delay: 140ms; }
  .how-triad__item:nth-child(2) { transition-delay: 70ms; }
  .how-triad__item:nth-child(3) { transition-delay: 140ms; }
}

/* 2. Framed-glass glare on their flash imagery (Glare Hover, toned to a
   slow museum-glass sheen; their walls ARE art under glass - file 1214).
   Hover-only surfaces; no touch cost. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .work-grid__item, .rail-card figure { position: relative; overflow: hidden; }
  .work-grid__item::after, .rail-card--link figure::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    transform: translateX(-140%) skewX(-14deg);
    background: linear-gradient(105deg, transparent 35%, rgba(251,248,240,0.14) 50%, transparent 65%);
    transition: transform 700ms var(--ease-out);
  }
  .work-grid__item:hover::after, .rail-card--link:hover figure::after {
    transform: translateX(140%) skewX(-14deg);
  }
}

/* .flash-strip retired 2026-09-03 with the visit-band rebuild. Its only user
   was that band; the images now live in .visit-edge__media, edge to edge with
   no hairline. The four 1px borders were themselves part of the busyness. */

/* "Inside the shop": the room a walk-in is deciding to enter. */
.band--shop-inside { background: var(--bg-card); }
.shop-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-12);
}
.shop-strip figure { margin: 0; }
.shop-strip img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.18);
}
.shop-strip figcaption {
  font-size: 0.8rem;
  color: var(--fg-dim);
  padding-block-start: var(--space-8);
}
@media (max-width: 700px) { .shop-strip { grid-template-columns: repeat(2, 1fr); } }

/* "Wear the shop": the merch dimension (eyes-on hero pass 2026-08-16). */
.band--merch { background: var(--bg-warm); }
.merch-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-16);
}
.merch-strip figure { margin: 0; }
.merch-strip img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.18);
}
.merch-strip figcaption {
  font-size: 0.8rem;
  color: var(--fg-dim);
  padding-block-start: var(--space-8);
}
@media (max-width: 700px) {
  .merch-strip { grid-template-columns: 1fr; gap: var(--space-20); }
  .merch-strip img { aspect-ratio: 4 / 4; }
}

/* -- Hero carousel (auto-rotating; Stefan 2026-08-15) -------------------
   Slides stack; only .is-active is visible. Without JS the first slide
   keeps its is-active class from the markup, so the hero still renders a
   full photograph and the row-23 composition contract holds. */
/* The container owns the height (.hero__media 56svh / 100% at desktop), so
   EVERY slide is absolute. Letting the first slide sit in flow made the box
   take the image's intrinsic height and blew the desktop hero to 1.25x the
   viewport, the exact regression the pinned height fixed earlier. */
/* NB: .hero-carousel IS the .hero__media element. Declaring position OR
   height here overrides the stage geometry set above and collapses the hero
   to zero (done twice now: height first, then position). This rule
   intentionally sets NEITHER. */
.hero-carousel { display: block; }
.hero-slide {
  margin: 0;
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1600ms var(--ease-out);
  will-change: opacity;
}
.hero-slide.is-active { opacity: 1; z-index: 1; }
/* House pattern: the drift is SLOWER than the 5.2s dwell so it never
   completes, which is what stops the freeze-then-lurch on each change. */
@media (prefers-reduced-motion: no-preference) {
  .hero-slide.is-active img { animation: heroKenBurns 16s linear forwards; }
  @keyframes heroKenBurns { from { transform: scale(1.02); } to { transform: scale(1.10); } }
}
.hero-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-dots {
  z-index: 3;
  position: absolute;
  inset-block-end: var(--space-12);
  inset-inline-end: var(--space-12);
  display: flex;
  gap: var(--space-8);
  z-index: 2;
}
.hero-dot {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.hero-dot::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(244, 238, 225, 0.55);
  box-shadow: 0 0 0 1px rgba(26, 22, 19, 0.35);
  transition: background var(--duration-fast) var(--ease-out);
}
.hero-dot.is-active::before { background: var(--accent); }
.hero-dot:focus-visible { outline: 2px solid var(--on-facade); outline-offset: -4px; }

@media (prefers-reduced-motion: reduce) {
  .hero-slide { transition: none; }
}

/* Dot progress: the auto-advance now shows its own clock, so the rotation
   is legible rather than something that just happens to you. The ring
   fills over one interval and resets on change. Never runs under
   reduced-motion (where rotation is off anyway). */
.hero-dot::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  border: 1.5px solid transparent;
}
@media (prefers-reduced-motion: no-preference) {
  .hero-dot.is-active::after {
    border-color: rgba(244, 238, 225, 0.9);
    clip-path: inset(0 0 0 0);
    animation: dot-clock 5200ms linear both;
  }
  @keyframes dot-clock {
    from { clip-path: inset(0 100% 0 0); }
    to   { clip-path: inset(0 0 0 0); }
  }
}
.hero-dots { inset-block-end: var(--space-16); inset-inline-end: var(--space-16); }
@media (min-width: 881px) {
  /* Dots belong on the photograph, not on the solid panel. */
  .hero-dots { inset-inline-end: calc(40% + var(--space-16)); }
}

/* The hero card now sits on the solid facade panel, so its type must be the
   on-facade pair. Declared LAST because earlier C1 rules set fg-dim/press-red
   for the old cream-ground hero and were still winning (axe caught all three
   as contrast failures against the navy). */
.hero__panel .hero__welcome,
.hero__panel .hero__hours { color: var(--on-facade); }
.hero__panel .hero__welcome a {
  color: var(--on-facade);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.hero__panel .hero__welcome a:hover { color: var(--gold); }

/* -- P-1 proof verifiability (ratified 2026-08-24): platform-of-record
   links on the facade band; gold hover matches the footer's AA step. */
.band--proof a { color: var(--on-facade); text-decoration-thickness: 1px; }
.band--proof a:hover { color: #C9A867; }  /* the AA-cleared gold step (comp-footer precedent) */
.proof__source { margin-block: var(--space-16) 0; font-size: 0.9rem; color: rgba(244, 238, 225, 0.85); }
/* C-9 (2026-08-24): the visit band's dates pointer. */
.visit__dates { margin-block: var(--space-4) 0; }

/* pages-inner.css - inner-page overrides. STUB: C2-C4 fill this on the C1
   token spine. */

/* -- C4: first-timer page, aftercare, prose -- */
.how-triad--page { margin-block-start: var(--space-24); }
.how-triad__h { font-size: 1.2rem; margin-block-end: var(--space-8); }
.band--first { background: var(--bg-warm); }
.first-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-16); max-width: var(--measure-wide); }
.band--clean .proof__quote { margin-block-start: var(--space-24); }
.band--pricing p { max-width: var(--measure); color: var(--fg-dim); }
.aftercare__provenance {
  font-size: 0.85rem; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--fg-faint);
}
.aftercare-steps { margin: 0; padding-inline-start: 1.2em; display: flex; flex-direction: column; gap: var(--space-24); max-width: var(--measure-wide); }
.aftercare-steps__h { font-size: 1.15rem; margin-block-end: var(--space-4); }
.aftercare-call { margin-block-start: var(--space-40); padding: var(--space-24); background: var(--bg-card); border: 1px solid rgba(26, 22, 19, 0.2); max-width: var(--measure-wide); }
.aftercare-call h2 { font-size: 1.15rem; margin-block-end: var(--space-8); color: var(--accent-press); }
/* Kept as a named container, now measure-driven so it sits in the same
   family as the automatic prose column in global.css. */
.container--prose { max-width: calc(var(--measure-wide) + 2 * var(--container-padding)); }
.container--prose h2 { font-size: 1.25rem; margin-block: var(--space-32) var(--space-8); }

@media print {
  .site-header, .site-footer, .band--cta, .menu-toggle { display: none !important; }
  .band { padding-block: 12pt; }
  body { background: white; color: black; }
}

/* C6: the scaffold stub class gets real padding (404 sat unstyled - IMP minor) */
.stub { padding-block: var(--space-64); }
.stub h1 { margin-block-end: var(--space-12); }

/* -- /walk-ins/ (M10, G-E2 ratified 2026-08-15) ------------------------- */
/* The storefront is portrait 1600x2407: crop it to a wide arrival frame so
   the page reads landing, not photo dump. Framed-flash squareness kept. */
.walkins__hours { font-weight: 600; margin-block-start: var(--space-8); }
.walkins__storefront { margin: var(--space-24) 0 0; }
.walkins__storefront img {
  width: 100%;
  height: auto;
  max-height: 62vh;
  object-fit: cover;
  object-position: center 62%;
  border: 1px solid rgba(26, 22, 19, 0.2);
}
.walkins__storefront figcaption {
  font-size: 0.85rem;
  color: var(--fg-dim);
  padding-block-start: var(--space-8);
}

/* -- G-E1 enrichment strips (2026-08-15) --------------------------------
   Two-up figure rows inside existing bands. Square-cornered per the
   framed-flash law; captions in dim ink. Single column on phones. */
.clean-strip, .craft-strip {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-16);
  margin-block-start: var(--space-24);
}
.clean-strip figure, .craft-strip figure { margin: 0; }
.clean-strip img, .craft-strip img {
  width: 100%;
  height: 100%;
  max-height: 44vh;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.2);
}
.clean-strip figcaption, .craft-strip figcaption, .first-figure figcaption {
  font-size: 0.85rem;
  color: var(--fg-dim);
  padding-block-start: var(--space-8);
}
.first-figure { margin: var(--space-24) 0 0; }
.first-figure img {
  width: 100%;
  height: auto;
  max-height: 58vh;
  object-fit: cover;
  object-position: center 35%;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.2);
}
.work-grid__note {
  margin-block-start: var(--space-16);
  color: var(--fg-dim);
}
@media (max-width: 640px) {
  .clean-strip, .craft-strip { grid-template-columns: 1fr; }
}

/* -- Recent work gallery (/artists/, ig-rip curation 2026-08-15) --------- */
.band--work-gallery { background: var(--bg-warm); }
.work-gallery__lede { color: var(--fg-dim); margin-block-end: var(--space-24); }
.work-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-12);
}
.work-gallery figure { margin: 0; }
.work-gallery img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.2);
}
.work-gallery__note { margin-block-start: var(--space-20); color: var(--fg-dim); }

/* -- Full-bleed photographic band for inner pages (2026-08-15) ----------
   The site is a tattoo shop's; every page should show work, not just
   describe it. Bleeds past the container on purpose: this is the one
   element allowed to break the reading column. */
.band--page-hero { padding-block: 0; }
.page-hero { margin: 0; position: relative; }
.page-hero img {
  width: 100%;
  height: clamp(240px, 42vh, 460px);
  object-fit: cover;
  object-position: center 45%;
  display: block;
  border-block: 1px solid rgba(26, 22, 19, 0.2);
}
.page-hero__cap {
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: 0;
  background: rgba(51, 58, 71, 0.88);
  color: var(--on-facade);
  font-family: var(--font-ui);
  font-size: 0.82rem;
  letter-spacing: 0.01em;
  padding: var(--space-8) var(--space-16);
}

/* Flash row inside the work-gallery band (square sheets, not skin). */
.flash-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-12);
  margin-block-start: var(--space-16);
}
.flash-row figure { margin: 0; }
.flash-row img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.2);
  background: var(--bg-card);
}
.flash-row figcaption {
  font-size: 0.78rem;
  color: var(--fg-dim);
  padding-block-start: var(--space-4);
}
.work-gallery__sub {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-block-start: var(--space-32);
}

/* "The crew at work": more hands than the pages above. Nobody is named. */
.band--crew { background: var(--bg-card); }
.crew__lede { color: var(--fg-dim); margin-block-end: var(--space-24); }
.crew-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-16);
}
.crew-strip figure { margin: 0; }
.crew-strip img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  border: 1px solid rgba(26, 22, 19, 0.18);
}
@media (max-width: 700px) { .crew-strip { grid-template-columns: 1fr 1fr; } }


/* P0: the medical-escalation block was the smallest heading on /aftercare/,
   an accident of specificity. It is the most consequential copy on the site
   and now reads that way. Full border: a coloured side-stripe is banned. */
.aftercare-call {
  border: 2px solid var(--accent);
  background: var(--bg-card);
  padding: var(--space-24);
}
.aftercare-call h2 {
  font-size: clamp(1.35rem, 2vw, 1.6rem);
  color: var(--accent-press);
}

/* Rhythm: every band shipped 64/64 with no step-down, so nothing could
   matter more than anything else. */
.band--tight { padding-block: var(--space-40); }
.band--loose { padding-block: var(--space-80); }
/* Mobile step-down, but never flatten the variants: an unscoped copy of
   this rule in another stylesheet was loading last and defeating
   .band--tight / .band--loose / .band--page-hero / .inner-hero entirely. */
@media (max-width: 600px) {
  .band:not(.band--tight):not(.band--loose):not(.band--page-hero):not(.inner-hero):not(.band--visit) {
    /* .band--visit added 2026-09-03: it is a full-bleed edge layout that
       carries its own padding on the text column only. This rule is an
       opt-out list by design, so joining it is the fix; raising the other
       selector's specificity would have left the list lying about scope. */
    padding-block: var(--space-40);
  }
}


/* -- .page-open: the shared inner-page opening (impeccable spec) ---------
   Replaces .inner-hero + a sibling .band--page-hero. The panel OVERLAPS the
   photograph so title and image compose as one unit rather than stacking as
   two unrelated sections, and it carries the page's one action above the
   fold. Counts as one band: it replaces two. */
.page-open { display: flex; flex-direction: column; }

.page-open__media { position: relative; margin: 0; }
.page-open__media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  height: auto;
  object-fit: cover;
  object-position: center 42%;
  display: block;
}
.page-open__cap {
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: 0;
  background: rgba(51, 58, 71, 0.88);
  color: var(--on-facade);
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  padding: var(--space-8) var(--space-16);
}

.page-open__panel {
  position: relative;
  z-index: 1;
  background: var(--facade);
  color: var(--on-facade);
  padding: var(--space-32) var(--container-padding) var(--space-40);
  margin-block-start: -24px;          /* the overlap: one unit, not two blocks */
  margin-inline: var(--space-16);
}
.page-open__eyebrow {
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #C9A867;                     /* gold at 3.68:1 fails body; this clears AA */
  padding-block-end: var(--space-12);
  border-block-end: 1px solid var(--gold-dim);
  margin-block-end: var(--space-16);
  max-width: 32ch;
}
.page-open h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-3xl);
  line-height: 1.02;
  letter-spacing: -0.01em;
  margin-block-end: var(--space-12);
}
.page-open__lede {
  font-size: var(--t-md);
  line-height: 1.5;
  color: rgba(244, 238, 225, 0.86);   /* 7.9:1 on facade */
  max-width: var(--measure-tight);
  margin-block-end: var(--space-24);
}
.page-open .btn-primary { flex-direction: column; align-items: flex-start; gap: 2px; }
.page-open .channels__sub {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--on-accent);
  opacity: 1;
  text-transform: none;
  letter-spacing: 0.01em;
}

@media (min-width: 881px) {
  .page-open {
    display: grid;
    grid-template-columns: minmax(380px, 42%) 1fr;
    align-items: stretch;
    min-height: 460px;
  }
  .page-open__media { grid-column: 2; height: 100%; }
  .page-open__media img { aspect-ratio: auto; height: 100%; min-height: 460px; }
  .page-open__panel {
    grid-column: 1;
    grid-row: 1;
    margin: 0;
    padding: var(--space-64) var(--space-48) var(--space-64) var(--container-padding);
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .page-open__cap { inset-block-end: var(--space-16); }
}


/* The healing timeline is an <ol> whose markers were killed by the reset and
   by display:flex. Sequence is the entire point of the page. */
.aftercare-steps { counter-reset: step; padding-inline-start: 0; }
.aftercare-steps > li { counter-increment: step; position: relative; padding-inline-start: 44px; }
.aftercare-steps > li::before {
  content: counter(step);
  position: absolute; inset-inline-start: 0; top: 2px;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: var(--t-base);
  background: var(--facade); color: var(--on-facade);
  border-radius: var(--radius-sm);
}

/* 28 uncaptioned tiles on the page whose job is choosing an artist. */
.work-gallery { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

/* -- C-9 events surface (change-plan rows 6/7, ratified 2026-08-24) ---- */
.events-block { margin-block-start: var(--space-24); }
.events-block__h { font-family: var(--font-display); font-size: var(--t-lg); margin-block-end: var(--space-12); }
.events-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-8); }
.events-list li { display: flex; gap: var(--space-16); align-items: baseline; background: var(--bg-card); border: 1px solid var(--bg-warm); padding: var(--space-8) var(--space-12); }
.events-list__date { font-family: var(--font-display); font-weight: 700; min-width: 4.5em; }
.events-empty { background: var(--bg-card); border: 1px dashed var(--fg-faint); padding: var(--space-12) var(--space-16); color: var(--fg-dim); }

/* -- C-4 cover-up subsection (2026-08-24) ------------------------------ */
.pricing__sub { margin-block-start: var(--space-24); font-size: var(--t-lg); }

/* -- C-9 booking dates pointer (2026-08-24) ---------------------------- */
.walkin__dates { margin-block-start: var(--space-8); }

/* -- C-7 aftercare take-with-you + review-ask (rows 10/11, 2026-08-24) - */
.aftercare-take { margin-block-start: var(--space-32); }
.aftercare-ask { margin-block-start: var(--space-32); padding: var(--space-16); background: var(--bg-card); border: 1px solid var(--bg-warm); }
.aftercare-ask__qr { display: block; margin-block-start: var(--space-12); width: 132px; height: 132px; background: #FFFFFF; padding: var(--space-8); border: 1px solid var(--bg-warm); }

/* .mr-fine moved here 2026-09-04 from the retired pages-market-research.css:
   /questions/ still uses it for its small print. */
.mr-fine { font-size: var(--t-sm); color: var(--fg-faint); }

/* /questions/ - fillable W6 batch. Reuses .field/.field__control from
   comp-forms; adds grouping, hints, progress, and the export bar. */

.q-meta {
  display: flex;
  gap: var(--space-16);
  align-items: baseline;
  font-size: var(--t-sm);
  color: var(--fg-dim);
}
/* --accent-press, not --accent: the surface shade is 3.7:1 on cream at
   this size and fails AA. Caught 2026-08-25 when /questions/ was added
   to the axe sweep, having never been in it. This one was live. */
#q-progress { font-weight: 600; color: var(--accent-press); }
.q-status { color: var(--fg-faint); }

.q-form { display: flex; flex-direction: column; gap: var(--space-32); }

.q-group {
  border: 1px solid var(--gold-dim);
  background: var(--bg-card);
  padding: var(--space-20) var(--space-24) var(--space-24);
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  margin: 0;
}
.q-group legend {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  color: var(--fg);
  padding: 0 var(--space-8);
}

.q-hint { font-size: var(--t-sm); color: var(--fg-faint); margin: 0; }
.q-area { min-height: 4.5rem; resize: vertical; }

.q-export {
  border-top: 2px solid var(--gold);
  padding-top: var(--space-24);
}
.q-export__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
  margin-top: var(--space-16);
}
.q-btn {
  font-family: var(--font-ui);
  font-size: var(--t-base);
  padding: 0.65rem 1.1rem;
  border: 1px solid var(--fg-dim);
  background: var(--bg-card);
  color: var(--fg);
  cursor: pointer;
}
.q-btn:hover { border-color: var(--fg); }
.q-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}
.q-btn--primary:hover { background: var(--accent-press); border-color: var(--accent-press); }
.q-btn--quiet { border-color: transparent; color: var(--fg-faint); }

/* pages-rationale.css - /rationale/ (S8, PIPELINE 4.8 deliverable).

   Register: the site's own paper system carrying a document. Expandable
   cards are native details/summary (keyboard-accessible, no JS, honors
   reduced motion by having no motion). Full hairline borders throughout;
   the side-stripe ban applies here like everywhere. */

.rationale-provenance {
  margin-block-start: var(--space-24);
  padding: var(--space-16) var(--space-20);
  background: var(--bg-card);
  border: 1px solid rgba(26, 22, 19, 0.14);
  font-size: 0.95rem;
  color: var(--fg-dim);
}

.band--method { background: var(--bg-warm); }

/* -- Layer cards -------------------------------------------------------- */
.layer-card {
  border: 1px solid rgba(26, 22, 19, 0.16);
  background: var(--bg);
  margin-block-start: var(--space-12);
}
.layer-card summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  cursor: pointer;
  list-style: none;
}
.layer-card summary::-webkit-details-marker { display: none; }
.layer-card summary::after {
  content: "+";
  margin-inline-start: auto;
  font-family: var(--font-display);
  font-size: 1.2rem;
  color: var(--accent-press);
}
.layer-card[open] summary::after { content: "\2212"; }
.layer-card__tag {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--accent-press);
}
.layer-card__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}
.layer-card__goal {
  font-size: 0.9rem;
  color: var(--fg-dim);
}
.layer-card__body { padding: 0 var(--space-16) var(--space-16); }
.layer-card__here { color: var(--fg-dim); }
.method-foot {
  margin-block-start: var(--space-20);
  font-size: 0.85rem;
  color: var(--fg-faint);
}

/* Citations: subtle, never load-bearing for layout. */
.cite {
  font-size: 0.8em;
  color: var(--fg-faint);
  white-space: nowrap;
}

/* -- ADR clusters ------------------------------------------------------- */
.adr {
  border: 1px solid rgba(26, 22, 19, 0.16);
  background: var(--bg-card);
  margin-block-start: var(--space-12);
}
.adr summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  cursor: pointer;
  list-style: none;
}
.adr summary::-webkit-details-marker { display: none; }
.adr summary::after {
  content: "+";
  margin-inline-start: auto;
  font-family: var(--font-display);
  font-size: 1.2rem;
  color: var(--accent-press);
}
.adr[open] summary::after { content: "\2212"; }
/* Contrast law (axe catch at S8): gold-dim is a surface tone, not a text
   tone; small labels take the press red or dim ink, both AA on the paper. */
.adr__num {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--accent-press);
}
.adr__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}
.adr__layers {
  font-size: 0.8rem;
  color: var(--fg-faint);
  white-space: nowrap;
}
.adr__body { padding: 0 var(--space-16) var(--space-16); }
.adr__body h3 {
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-block-start: var(--space-16);
}
.adr__body ul { padding-inline-start: 1.2em; }
.adr__body li { margin-block-start: var(--space-4); }
.adr__paste {
  margin-block-start: var(--space-16);
  padding: var(--space-12) var(--space-16);
  background: var(--bg-warm);
  border: 1px solid rgba(176, 141, 76, 0.45);
  font-family: var(--font-display);
  font-size: 1.02rem;
}
.adr__paste-label {
  display: block;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-block-end: var(--space-4);
}

/* -- Kept / arc / choices ---------------------------------------------- */
.band--kept { background: var(--bg-warm); }

.band--arc {
  background: var(--facade);
  color: var(--on-facade);
}
.band--arc h2 { color: var(--on-facade); }
/* One signal per view: the build is the primary action (btn-primary, the
   underline-law opt-out class); the old site is a quiet inherited link
   (on-facade color by inheritance, underlined by the global prose rule). */
.arc-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-24);
  margin-block-start: var(--space-24);
}

.choice-list { padding-inline-start: 1.2em; }
.choice-list li { margin-block-start: var(--space-12); }

.band--deferred ul { padding-inline-start: 1.2em; }
.band--deferred li { margin-block-start: var(--space-8); }

.band--ask { background: var(--bg-warm); }

/* pages-reports.css - the client report reading surface (/reports/).
   SPEC: docs/plans/2026-08-24-client-report-surface-spec.md v1.1 (post-loop).

   Register: brand / long-form content. Color strategy: COMMITTED, INHERITED -
   flash-paper ground, facade blue-charcoal structure, one red action, gold as
   the fine rule. No new palette decisions; every value below is an existing
   token or a tint of one.

   Impeccable laws honored explicitly here:
   - no side-stripe borders (the earlier local hub used border-left 3px on
     quotes; that is an absolute ban). Quotations get a full-bordered well.
   - no boxed identity card: the masthead is typographic and ruled.
   - no identical card grid: the hub groups are ranked and weighted differently.
   - measure is 46ch, NOT impeccable's raw 65-75ch, because global.css already
     proved with glyph metrics that 1ch in DM Sans is ~1.54x an average prose
     character, so 46ch renders ~70 real characters. Same law, right number.
   - heading steps below clear 1.25x, which the base token scale does not.
   ============================================================ */

.page-reports {
  --report-measure: 46ch;
  --report-h2: 1.6rem;    /* 1.28x over h3 */
  --report-h3: 1.25rem;   /* 1.25x over h4 */
  --report-h4: 1rem;
  --tint-settled: rgba(74, 107, 79, 0.14);   /* --leaf */
  --tint-open:    rgba(176, 141, 76, 0.18);  /* --gold */
  --tint-working: rgba(51, 58, 71, 0.10);    /* --facade */
  --tint-action:  rgba(206, 58, 40, 0.10);   /* --accent */
}

/* ---- masthead (R2: the first screen states what this is) ---------------- */
.rpt-masthead { padding-block: var(--space-32) var(--space-24); }
.rpt-masthead__eyebrow {
  font-size: var(--t-sm); text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--fg-faint); margin: 0 0 var(--space-8);
}
.rpt-masthead h1 {
  font-family: var(--font-display); font-weight: 700; line-height: 1.1;
  font-size: clamp(1.9rem, 4.4vw, 2.6rem); margin: 0;
  max-width: 22ch;
}
.rpt-masthead__lede {
  font-size: var(--t-md); line-height: 1.5; color: var(--fg);
  max-width: var(--report-measure); margin: var(--space-16) 0 0;
}
.rpt-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-8) var(--space-16);
  align-items: center; margin-top: var(--space-20);
  padding-top: var(--space-16); border-top: 2px solid var(--gold);
  font-size: var(--t-sm); color: var(--fg-dim);
}
.rpt-badge {
  font-weight: 600; padding: 3px 10px; border: 1px solid rgba(26, 22, 19, 0.2);
  border-radius: var(--radius-sm); color: var(--fg);
}
.rpt-badge[data-stance="settled"] { background: var(--tint-settled); }
.rpt-badge[data-stance="open"]    { background: var(--tint-open); }
.rpt-badge[data-stance="working"] { background: var(--tint-working); }
.rpt-badge[data-stance="action"]  { background: var(--tint-action); }
.rpt-meta__audience { flex-basis: 100%; color: var(--fg-faint); }

/* ---- the reading column + spine ---------------------------------------- */
.rpt-layout { display: block; padding-bottom: var(--space-64); }
.rpt-toc { margin-block: var(--space-24); }
.rpt-toc summary {
  cursor: pointer; font-weight: 600; padding: var(--space-12) var(--space-16);
  background: var(--bg-card); border: 1px solid var(--bg-warm);
}
.rpt-toc ol { list-style: none; margin: 0; padding: var(--space-12) var(--space-16); }
.rpt-toc li { margin-block: 2px; }
.rpt-toc a { color: var(--fg-dim); text-decoration: none; font-size: var(--t-sm); }
.rpt-toc a:hover, .rpt-toc a:focus-visible { color: var(--fg); text-decoration: underline; }
.rpt-toc li[data-level="3"] { padding-inline-start: var(--space-16); }
.rpt-toc li[data-level="4"] { padding-inline-start: var(--space-32); }
.rpt-toc a.is-current { color: var(--accent-press); font-weight: 600; }

@media (min-width: 1100px) {
  .rpt-layout {
    display: grid; grid-template-columns: 1fr minmax(0, 62ch);
    gap: var(--space-48); align-items: start;
  }
  .rpt-toc {
    position: sticky; top: calc(var(--header-h) + var(--space-16));
    max-height: calc(100vh - var(--header-h) - var(--space-48));
    overflow-y: auto; margin: 0; grid-column: 1; justify-self: end;
    max-width: 26ch;
  }
  .rpt-toc summary { display: none; }
  .rpt-toc[open] ol, .rpt-toc ol { display: block; padding-inline: 0; }
  .rpt-doc { grid-column: 2; }
}

/* ---- the document body ------------------------------------------------- */
.rpt-doc > p, .rpt-doc > ul, .rpt-doc > ol, .rpt-doc > blockquote {
  max-width: var(--report-measure);
}
.rpt-doc p { margin-block: 0 var(--space-16); line-height: 1.62; }
.rpt-doc h2 {
  font-family: var(--font-display); font-size: var(--report-h2); line-height: 1.2;
  margin-block: var(--space-48) var(--space-12); scroll-margin-top: 96px;
  padding-bottom: var(--space-8); border-bottom: 1px solid var(--gold-dim);
}
.rpt-doc h3 {
  font-size: var(--report-h3); font-weight: 600; line-height: 1.3;
  margin-block: var(--space-32) var(--space-8); scroll-margin-top: 96px;
}
.rpt-doc h4 {
  font-size: var(--report-h4); font-weight: 600; color: var(--fg-dim);
  margin-block: var(--space-24) var(--space-8); scroll-margin-top: 96px;
}
.rpt-doc ul, .rpt-doc ol { padding-inline-start: 1.2em; margin-block: 0 var(--space-16); }
.rpt-doc li { margin-block: var(--space-4); line-height: 1.55; }
.rpt-doc hr { border: 0; border-top: 1px solid var(--gold-dim); margin-block: var(--space-32); }
.rpt-doc code {
  font-size: 0.85em; background: var(--bg-warm); padding: 1px 5px;
  border-radius: var(--radius-sm); word-break: break-word;
}
.rpt-doc pre {
  background: var(--bg-card); border: 1px solid var(--bg-warm);
  padding: var(--space-16); overflow-x: auto; font-size: var(--t-sm);
}
/* Quotation wells: FULL border, never a side stripe (impeccable absolute ban). */
.rpt-doc blockquote {
  margin: var(--space-16) 0; padding: var(--space-12) var(--space-16);
  background: var(--bg-card); border: 1px solid var(--bg-warm);
  color: var(--fg-dim);
}
.rpt-doc blockquote p:last-child { margin-bottom: 0; }
.rpt-doc a { color: var(--accent-press); }

/* ---- tables that survive a phone (R1) ---------------------------------- */
.tw {
  overflow-x: auto; margin-block: var(--space-16) var(--space-24);
  border: 1px solid var(--bg-warm); background: var(--bg-card);
  scrollbar-gutter: stable;
}
.tw:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tw table { border-collapse: collapse; width: 100%; font-size: var(--t-sm); }
.tw th, .tw td {
  border-bottom: 1px solid var(--bg-warm); padding: var(--space-8) var(--space-12);
  text-align: left; vertical-align: top; min-width: 9rem;
}
.tw thead th { background: var(--bg-warm); font-weight: 600; position: sticky; top: 0; }
.tw tbody tr:last-child td { border-bottom: 0; }
.tw td:first-child, .tw th:first-child {
  position: sticky; left: 0; background: var(--bg-card); font-weight: 600;
  border-inline-end: 1px solid var(--bg-warm);
}
.tw thead th:first-child { background: var(--bg-warm); }

/* ---- glossary (R1/R4: first occurrence per document) ------------------- */
.gloss {
  font: inherit; color: inherit; background: none; border: 0; padding: 0;
  border-bottom: 1px dotted var(--fg-faint); cursor: help; position: relative;
}
.gloss:hover, .gloss:focus-visible { border-bottom-color: var(--accent); }
/* display:none while hidden, NOT visibility:hidden. Measured in the pane:
   hidden popovers still occupied layout and pushed the document to 768px wide
   inside a 564px viewport. A definition popping in instantly is also the right
   motion answer here. The flip class is set by site.js when the default
   left anchor would cross the right edge. */
.gloss__pop {
  display: none; position: absolute; left: 0; top: calc(100% + 6px); z-index: 20;
  width: max-content; max-width: min(30ch, 68vw); text-align: left;
  background: var(--facade); color: var(--on-facade); padding: 8px 10px;
  font-size: var(--t-sm); line-height: 1.4; font-weight: 400;
  box-shadow: var(--shadow-md); overflow-wrap: anywhere;
}
.gloss__pop--flip { left: auto; right: 0; }
.gloss:hover .gloss__pop, .gloss:focus .gloss__pop,
.gloss:focus-visible .gloss__pop { display: block; }

/* ---- withheld markers (visible, never silent) -------------------------- */
.redaction {
  background: var(--tint-working); border: 1px dashed var(--fg-faint);
  padding: 0 6px; font-size: 0.92em; color: var(--fg-dim);
}
.rpt-notes { margin-top: var(--space-32); max-width: var(--report-measure); }
.rpt-notes h2 { font-size: var(--report-h3); }
.rpt-notes ol { font-size: var(--t-sm); color: var(--fg-dim); }

/* ---- document metadata (the frontmatter, kept not dropped) ------------- */
.docmeta { margin-top: var(--space-32); max-width: var(--report-measure); }
.docmeta summary { cursor: pointer; font-size: var(--t-sm); color: var(--fg-faint); }
.docmeta__pre {
  white-space: pre-wrap; font-size: var(--t-xs); color: var(--fg-dim);
  background: var(--bg-card); border: 1px solid var(--bg-warm);
  padding: var(--space-12); margin-top: var(--space-8);
}

/* ---- the closing ask (R5, identical on all sixteen) -------------------- */
.rpt-ask {
  margin-top: var(--space-48); padding: var(--space-24);
  background: var(--facade); color: var(--on-facade);
}
.rpt-ask h2 {
  font-family: var(--font-display); font-size: var(--report-h2); margin: 0 0 var(--space-8);
  border: 0; color: var(--on-facade);
}
.rpt-ask p { max-width: var(--measure); margin-block: 0 var(--space-16); }
.rpt-ask a:not(.btn-primary) { color: #C9A867; }

/* ---- the hub ----------------------------------------------------------- */
.rpt-intro { max-width: var(--report-measure); }
.rpt-howto {
  margin-block: var(--space-32); padding: var(--space-24);
  background: var(--bg-card); border: 1px solid var(--bg-warm);
}
.rpt-howto h2 { font-family: var(--font-display); font-size: var(--report-h2); margin-top: 0; }
.rpt-howto dl { margin: 0; }
.rpt-howto dt { font-weight: 600; margin-top: var(--space-12); }
.rpt-howto dd { margin: 2px 0 0; color: var(--fg-dim); max-width: var(--measure-wide); }

.rpt-group { margin-block: var(--space-48); }
.rpt-group__h {
  font-family: var(--font-display); font-size: var(--report-h2);
  margin: 0 0 var(--space-4); padding-bottom: var(--space-8);
  border-bottom: 2px solid var(--gold);
}
.rpt-group__note { color: var(--fg-dim); max-width: var(--measure-wide); margin-block: 0 var(--space-20); }
.rpt-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-12); }
.rpt-item {
  display: block; padding: var(--space-16); background: var(--bg-card);
  border: 1px solid var(--bg-warm); text-decoration: none; color: var(--fg);
}
.rpt-item:hover, .rpt-item:focus-visible { border-color: var(--gold); background: var(--bg); }
.rpt-item__t { font-weight: 600; font-size: var(--t-md); display: block; }
.rpt-item__o { color: var(--fg-dim); margin: var(--space-4) 0 var(--space-8); max-width: var(--measure-wide); }
.rpt-item__m {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--fg-faint);
}
/* The one thing that needs the reader: deliberately heavier than the rest. */
.rpt-item--action {
  background: var(--facade); color: var(--on-facade); border-color: var(--facade-deep);
  padding: var(--space-24);
}
.rpt-item--action .rpt-item__t { font-family: var(--font-display); font-size: var(--t-xl); }
.rpt-item--action .rpt-item__o { color: rgba(244, 238, 225, 0.86); }
.rpt-item--action .rpt-item__m { color: #C9A867; }
.rpt-item--action:hover, .rpt-item--action:focus-visible { background: var(--facade-deep); }
/* The working-document group is quieter by design. */
.rpt-group--method .rpt-item { background: transparent; }


/* ==== At a glance (2026-09-04): the executive layer above the shelf =========
   SPEC: docs/plans/2026-09-04-reports-executive-synthesis.md (PFD Mode 2).
   Same laws as the rest of this file: no boxed identity card (the masthead is
   typographic), no side stripes (the repeat line is a full-bordered well), no
   new hues (marks are the existing tints; "wrong" is solid ink because red is
   action-only and the "Needs you" badge already owns the red tint).
   R2 is measured, not assumed: scripts/probe-glance.mjs asserts the fourth
   question sits above the 844px fold at 390px. Keep the title to one clause
   and the lede to ~30 words or that probe will tell you. */
.glance { padding-block: var(--space-24) 0; }
.glance__mast { padding-block: var(--space-16) 0; }
.glance__title {
  font-family: var(--font-display); font-weight: 700; line-height: 1.08;
  font-size: clamp(2rem, 5.2vw, 3rem); margin: 0; max-width: 16ch;
}
.glance__lede {
  font-size: var(--t-md); line-height: 1.5; max-width: var(--report-measure);
  margin: var(--space-16) 0 0;
}
.glance__jump { margin-top: var(--space-20); max-width: var(--report-measure); }
.glance__jump ol { list-style: none; margin: 0; padding: 0; }
.glance__jump a {
  display: flex; gap: var(--space-12); align-items: baseline;
  padding: var(--space-8) 0; border-top: 1px solid var(--gold-dim);
  color: var(--fg); text-decoration: none; font-weight: 600; line-height: 1.35;
}
.glance__jump li:last-child a { border-bottom: 1px solid var(--gold-dim); }
.glance__jump a:hover, .glance__jump a:focus-visible { color: var(--accent-press); }
.glance__n { font-family: var(--font-display); color: var(--gold); min-width: 1.3em; }
.glance__legend {
  margin: var(--space-16) 0 0; font-size: var(--t-sm); line-height: 1.9;
  color: var(--fg-dim); max-width: var(--report-measure);
}

/* the four-mark vocabulary */
.glance-mark {
  display: inline-block; font-weight: 600; font-size: var(--t-sm); line-height: 1.3;
  padding: 2px 8px; border: 1px solid rgba(26, 22, 19, 0.2);
  border-radius: var(--radius-sm); color: var(--fg); white-space: nowrap;
}
.glance-mark[data-mark="held"]     { background: var(--tint-settled); }
.glance-mark[data-mark="narrowed"] { background: var(--tint-open); }
.glance-mark[data-mark="open"]     { background: var(--tint-working); }
.glance-mark[data-mark="wrong"]    { background: var(--fg); color: var(--on-facade); border-color: var(--fg); }

/* one question, one grammar (R3) */
.glance__q, .glance__levers, .glance__method {
  margin-block: var(--space-48) 0; max-width: var(--report-measure);
  scroll-margin-top: calc(var(--header-h) + var(--space-16));
}
.glance__levers { max-width: none; }
.glance__q h2, .glance__levers h2, .glance__method h2 {
  font-family: var(--font-display); font-size: var(--report-h2); line-height: 1.15;
  margin: 0 0 var(--space-12); padding-bottom: var(--space-8);
  border-bottom: 2px solid var(--gold);
}
.glance__verdict {
  display: flex; flex-wrap: wrap; gap: var(--space-8) var(--space-12); align-items: baseline;
  font-size: var(--t-md); line-height: 1.5; margin: 0 0 var(--space-12);
}
.glance__verdict .glance-mark { flex: none; white-space: normal; }
.glance__found h3 {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--fg-faint); margin: var(--space-16) 0 var(--space-8); font-weight: 600;
}
.glance__q p, .glance__levers p, .glance__method p { margin: 0 0 var(--space-12); line-height: 1.6; }
.glance__asof { display: block; font-size: var(--t-xs); color: var(--fg-faint); margin: 0 0 var(--space-12); }
.glance__cell strong { font-weight: 600; }
.glance__repeat {
  margin-top: var(--space-16); padding: var(--space-12) var(--space-16);
  background: var(--bg-card); border: 1px solid var(--bg-warm);
}
.glance__intro { max-width: var(--report-measure); }
/* The levers table is a LAYOUT element, not prose: it breaks out of the 46ch
   measure to the full container, the same law the site uses for layout bands
   (heading and intro capped, the grid full width). The first version capped
   the scroll well at the prose measure, so an 817px table scrolled inside a
   503px box beside 600px of empty margin (Stefan, 2026-09-04: "make the table
   wider, not x-overflow"). Measured after: no horizontal scroll at 1280 or
   wider; the phone still scrolls the well with the first column sticky, which
   is the spec's own table law. Scoped to this table; the documents' tables
   keep the spec section 4.6 treatment. */
.glance__levers .tw { margin-block: var(--space-20) var(--space-24); max-width: none; width: 100%; }
.glance__levers .tw table { width: 100%; table-layout: auto; font-size: var(--t-base); }
.glance__levers .tw th, .glance__levers .tw td { padding: var(--space-12) var(--space-16); vertical-align: top; line-height: 1.45; }
.glance__levers .tw th { white-space: nowrap; }
/* No minimum column widths: they forced 1049px against the 981px available at
   1280 and the well scrolled again (measured 2026-09-04). table-layout:auto
   distributes the container and cells wrap; only the mark keeps from breaking. */
.glance__levers .tw td:nth-child(1) { width: 2.5rem; color: var(--fg-faint); font-family: var(--font-display); }
.glance__levers .tw td:nth-child(2) { font-weight: 600; }
.glance__levers .tw td:nth-child(3) .glance-mark { white-space: normal; }
.glance__levers .tw td:nth-child(5) { color: var(--fg-dim); }
.glance__levers .glance__cell { max-width: var(--report-measure); }

/* the ask inherits .rpt-ask (the facade band); only the list is new */
.glance__need { margin-top: var(--space-48); }
.glance__need ol { margin: 0 0 var(--space-16); padding-inline-start: 1.3em; max-width: var(--measure-wide); }
.glance__need li { margin-block: var(--space-8); line-height: 1.55; }
.glance__need li strong { font-weight: 600; }
.glance__need a:not(.btn-primary) { color: #C9A867; }

/* the shelf: the old masthead, demoted under the verdicts */
.rpt-masthead--shelf {
  margin-top: var(--space-64); padding-top: var(--space-40);
  border-top: 1px solid var(--gold-dim);
}
/* With the container no longer narrowed (global.css, 2026-09-04) the shelf
   would stretch its cards to 1100px. Hold the shelf at its reading width. */
.rpt-masthead--shelf, .page-reports .rpt-howto, .page-reports .rpt-group { max-width: var(--measure-wide); }
.page-reports .page-hero { max-width: none; }
.rpt-masthead--shelf .rpt-masthead__title {
  font-family: var(--font-display); font-weight: 700; line-height: 1.1;
  font-size: clamp(1.5rem, 3vw, 2rem); margin: 0; max-width: 22ch;
}

/* palettes.css - three flippable directions (2026-08-25).
   AUTHORITY: Stefan, "create 3 style sheet options to flip through with
   different colors and fonts". Brief answer: one faithful, two departures.

   HOW IT WORKS. Every identity value in tokens.css is a custom property, so a
   direction is a token override and nothing else; no component CSS is forked.
   Pick with `data-palette` on <html>. No attribute is Flash Paper, so the
   shipped direction stays the default and a production build that never sets
   the attribute is byte-identical in behaviour to today.

   Selectors are written `:root[data-palette=...]` (0,2,0) rather than
   `[data-palette=...]` (0,1,0) so they beat `:root` in tokens.css regardless
   of the order the builder concatenates stylesheets in.

   THE THREE, and what each one is arguing:

   1. FLASH PAPER   (default, no attribute)  their extracted palette and type.
      Every value carries a receipt to a real surface of the shop: the cream
      is their flash-paper windows, the navy is their painted facade, the red
      is their own neon and A-frame, the gold is their door sign, and Playfair
      is the display face their live site already loads. Nothing here needs a
      new argument to Julian, because it is a description of his shop.

   2. DAYLIGHT      departure. Pushes the anti-intimidating axis, which is the
      one PRODUCT.md names as the hard conversion: the anxious first-timer.
      Brighter paper, and the structural colour moves from facade navy to the
      botanical green already sitting in every window and room photo. Their
      red is KEPT, because the neon is the single most recognisable thing they
      own and a direction that drops it stops being their shop.
      PFD L1: the 50ms gate reads colour, density and image quality, not
      sentences, so a higher-luminance ground with one warm saturated accent
      resolves as "open, clean, safe" before any copy is processed.
      PFD L2: one type family across display and body removes a whole voice
      from the page, which is a fluency gain on a phone at arm's length.

   3. OXBLOOD       departure. Same architecture as the other two, third
      structural colour. Where Flash Paper's structure is their facade blue
      and Daylight's is the botanical green, this one darkens THEIR OWN neon
      red to structural weight: #6E2018 carries cream at 9.65:1, which is the
      same structural weight the blue (9.89) and the green (9.54) carry, so
      the three read as one system with three temperatures rather than as
      three different sites.
      PFD L1: the 50ms gate reads colour before it reads anything else, and
      red is the shop's own pre-attentive signal. Putting it in the STRUCTURE
      rather than only in the buttons means the first fixation lands on their
      colour instead of on a neutral.
      PFD L3: a red that appears both as the ground of a band and as the
      colour of the one action is a perceptual conflict, because the same hue
      cannot mean "surface" and "do this" at once. Resolved below by inverting
      the button on oxblood bands rather than by adding a second red.
      REPLACED the earlier After Dark direction (Stefan, 2026-08-25): that one
      inverted the whole site to a dark ground, which was adjacent to the
      dark-parlor anti-reference. This keeps the light ground the brand
      actually argues for.

   TYPE. Playfair Display and DM Sans both appear on the impeccable
   reflex-reject list, but that list explicitly does not govern identity
   preservation, only greenfield and departure choices. So Flash Paper keeps
   them (they are extracted, not chosen) while the two departures had to look
   elsewhere. Both replacements are self-hosted latin-subset variable woff2,
   consistent with the DESIGN.md rule that no build ever requests a font from
   a third-party host. (That rule is enforced by qa row-16, which greps the
   built stylesheet for the host name; this comment originally spelled the
   host out and tripped its own gate, which is the gate working.) */

/* ── Departure faces, self-hosted ──────────────────────────────────────── */

@font-face {
  /* Bricolage Grotesque: a humanist grotesque with a real optical-size axis
     and slightly irregular joins. Physical reference is municipal signage
     that someone cared about, which is the Daylight argument in a typeface. */
  font-family: "Bricolage Grotesque";
  src: url("/fonts/bricolage-grotesque-var-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  /* Archivo: a signage grotesque with a width axis, drawn in the lineage of
     trade gothic shop plates. The expanded cut carries display; the normal
     cut carries body. One family, two very different jobs. */
  font-family: "Archivo";
  src: url("/fonts/archivo-var-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── 2. DAYLIGHT ───────────────────────────────────────────────────────── */

:root[data-palette="daylight"] {
  --bg: #FBF6EC;
  --bg-warm: #F4EDDF;
  --bg-card: #FDFAF4;

  --fg: #241E19;            /* 15.29:1 on --bg */
  --fg-dim: #5C544A;        /*  6.91:1 on --bg */
  --fg-faint: #6E6457;

  --facade: #2F4034;        /* botanical green: the plants in 1215/1219/1221 */
  --facade-deep: #243128;
  --facade-deepest: #1D2921; /* 2026-09-03: daylight's own facade taken 24.3% toward
                                black in oklab, the same operation that produced the
                                shipped oxblood --facade-deepest. Cream 13.05:1. */
  --on-facade: #F4EEE1;     /*  9.54:1 on --facade */

  --accent: #CE3A28;        /* THEIR neon red, kept on purpose */
  --accent-press: #B23122;  /*  5.81:1 as a link colour on --bg */
  --on-accent: #FFFFFF;     /*  4.93:1 on --accent */

  --gold: #C79A4F;          /*  4.29:1 on --facade, large text only */
  --gold-dim: rgba(199, 154, 79, 0.38);

  --font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
  --font-body: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
  --font-ui: var(--font-body);

  /* Bricolage sets a little wider than DM Sans, so the rem measure is nudged
     to hold the same characters per line. */
  --measure-tight: 27rem;
  --measure: 33rem;
  --measure-wide: 41rem;
}

/* Display type in this direction wants weight, not size, to do the work. */
:root[data-palette="daylight"] h1,
:root[data-palette="daylight"] h2,
:root[data-palette="daylight"] .band__h {
  font-weight: 700;
  letter-spacing: -0.02em;
}
:root[data-palette="daylight"] .footer-bilingual { letter-spacing: -0.015em; }

/* ── 1. FLASH PAPER ── their extracted direction, now an OPTION ──────────
   Was the default until 2026-08-30. Every value here carries its extraction
   receipt to a real surface of the shop, which is why it is kept intact and
   selectable rather than deleted: it is the only direction that is a
   description of the building rather than a derivation from it. */

:root[data-palette="flashpaper"] {
  --bg: #F4EEE1;            /* flash-paper cream [1221 windows, 1191; sampled] */
  --bg-warm: #EFE7D6;       /* deeper paper tone for alternating bands [sampled] */
  --bg-card: #FBF8F0;       /* raised card/paper sheet [sampled] */

  --fg: #1A1613;            /* ink black [1196 shadow, flash linework; sampled] */
  --fg-dim: #5C544A;        /* softened ink for secondary text [derived from --fg] */
  --fg-faint: #6E6457;      /* captions/meta [darkened C6 for AA 4.5+ on cream] */

  --facade: #333A47;        /* facade blue-charcoal [1221; sampled] */
  --facade-deep: #272D38;   /* darker facade shade for depth [derived] */
  --facade-deepest: #20252E; /* 2026-09-03: same 24.3% oklab darkening as the shipped
                                oxblood --facade-deepest, along this palette's own
                                blue. Cream 13.30:1. */
  --on-facade: #F4EEE1;     /* cream on facade, 9.89:1 */

  --accent: #CE3A28;        /* neon/A-frame red [1221; sampled] */
  --accent-press: #B23122;  /* 5.41:1 as link text on --bg */
  --on-accent: #FFFFFF;     /* white letters on red, exactly their A-frame [1221] */

  --gold: #B08D4C;          /* sign-gold [1196; sampled] */
  --gold-dim: rgba(176, 141, 76, 0.35);

  /* SWAPPED 2026-08-31 (Stefan): this direction now carries Archivo and
     Oxblood carries their extracted Playfair/DM Sans. The extraction
     receipts on the COLOURS here are untouched; only the faces moved. */
  --font-display: "Archivo", "Segoe UI", system-ui, sans-serif;
  --font-body: "Archivo", "Segoe UI", system-ui, sans-serif;
  --font-ui: var(--font-body);

  --measure-tight: 25rem;   /* Archivo sets narrower */
  --measure: 30rem;
  --measure-wide: 38rem;
}

/* ── 3. OXBLOOD ── now the DEFAULT, see tokens.css ──────────────────────
   Its token values live in tokens.css `:root`, so a production build with no
   attribute ships Oxblood. What remains here are its COMPONENT rules, which
   must apply by default and must NOT apply under the other two directions.
   Hence the `:not()` scoping rather than a `[data-palette="oxblood"]` prefix:
   it covers both the no-attribute default and an explicit oxblood selection,
   while Flash Paper and Daylight opt out. */

/* The width axis is why Archivo is here: display goes expanded, body stays
   normal, so one family carries two clearly different voices. On a light
   ground this reads as a painted shop plate rather than a lit sign. */
/* The width axis belongs to Archivo, which now lives in Flash Paper, so this
   rule moved with the face. Playfair has no width axis; applying font-stretch
   to it would be inert at best and a lie in the source at worst. */
:root[data-palette="flashpaper"] h1,
:root[data-palette="flashpaper"] h2,
:root[data-palette="flashpaper"] .band__h,
:root[data-palette="flashpaper"] .footer-bilingual {
  font-stretch: 116%;
  font-weight: 700;
  letter-spacing: 0.004em;
}

/* THE ONE REAL CONFLICT IN THIS DIRECTION, and its fix.
   On the other two palettes the structure and the action are different hues,
   so a red button on a structural band separates by colour. Here they are the
   same hue: their #CE3A28 on the #6E2018 structure measures 2.26:1, under the
   3.0 a UI component needs, and it would also be saying "surface" and "do
   this" in one colour. So on structural bands the button INVERTS to a cream
   surface with oxblood text: 9.79:1 both as a surface against the band and as
   text on itself. Everywhere else the button stays their red.

   NOTE FOR ANYONE MEASURING THIS: .btn-primary carries `transition: background
   120ms` and `color` is NOT in that transition list, so immediately after a
   palette switch getComputedStyle reports a pair that never actually renders
   (oxblood text on red). Measure at least 150ms after the switch;
   scripts/axe.mjs settles 200ms for exactly this reason. */
:root:not([data-palette="flashpaper"]):not([data-palette="daylight"]) :is(
  .page-open__panel, .band--visit, .band--proof, .band--arc, .band--how,
  .crew-card, .rpt-ask, .site-footer
) .btn-primary {
  background: var(--bg);
  color: var(--facade);
  border-color: var(--bg);
}
:root:not([data-palette="flashpaper"]):not([data-palette="daylight"]) :is(
  .page-open__panel, .band--visit, .band--proof, .band--arc, .band--how,
  .crew-card, .rpt-ask, .site-footer
) .btn-primary:hover {
  background: #FFFFFF;
  color: var(--facade-deep);
}
/* the sub-line inside a two-line button inherits the inverted colour too */
:root:not([data-palette="flashpaper"]):not([data-palette="daylight"]) :is(.page-open__panel, .rpt-ask, .band--visit)
  .btn-primary :is(.field__es, .channels__sub) {
  color: var(--facade);
}


