/* =========================================================================
   The Flame Chicago — v2.css  (image-forward iteration)
   Loads AFTER global.css. Reuses tokens, header, footer, buttons, .reveal.
   Adds: cinematic photographic slot system (.shot) + image-led sections.
   Every .shot is a treated placeholder carrying its generation brief; drop a
   real <img class="shot-img"> inside to replace. Briefs map to IMAGE-PLAN.md.
   ========================================================================= */

/* ---------- live "open now" pill (header + visit) ---------- */
.live{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-weight:700;font-size:.8rem;letter-spacing:.02em;color:var(--green);background:rgba(121,227,154,.08);border:1px solid rgba(121,227,154,.34);border-radius:100px;padding:6px 13px}
.live::before{content:"";width:8px;height:8px;border-radius:100px;background:var(--green);box-shadow:0 0 0 0 rgba(121,227,154,.6);animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(121,227,154,.5)}70%{box-shadow:0 0 0 7px rgba(121,227,154,0)}100%{box-shadow:0 0 0 0 rgba(121,227,154,0)}}
@media(prefers-reduced-motion:reduce){.live::before{animation:none}}

/* section rhythm tightened — the stacked headers were leaving too much air */
.section{padding-block:clamp(48px,7vw,96px)}

/* =========================================================================
   WIDER CONTENT COLUMN + PILLAR COLOR ACCENTS (from the messaging deck)
   Amber stays the brand/CTA throughline; teal/magenta/violet punctuate.
   ========================================================================= */
:root{--maxw:1320px;
  /* HEADING SCALE — one source of truth so components snap to a step instead
     of inventing a size. At 1693px: h2 64 / h3 44 / h4 32.
     Before this, only h2 was real: h3's nominal 32px was a phantom (every
     consumer overrode it) and sizes were scattered from 22 to 62. */
  --fs-h2:clamp(2.3rem,5vw,4rem);
  --fs-h3:clamp(1.9rem,2.8vw,2.75rem);
  --fs-h4:clamp(1.4rem,2vw,2rem);
  /* PILLAR STROKE — one source of truth for the masked gradient edge now worn
     by the FAQ + ring, the submit button, the form fields and card, the step
     cards and their numerals, and the occasion photo. Snap new components to
     it rather than pasting the conic gradient an eighth time. */
  --stroke-grad:conic-gradient(from 210deg,var(--teal),var(--amber) 30%,var(--magenta) 62%,var(--violet) 88%,var(--teal));
  --stroke-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0)}

/* The ring itself. Draws a 1px gradient edge by masking out everything inside
   the padding box. Use as a child element wherever ::before/::after are already
   spoken for (.step, .btn-ring), or copy the three properties onto a free
   pseudo-element. Callers set opacity — that is the whole hierarchy:
   card .2 → content cards .3 → controls .5 at rest → controls 1 on focus. */
.gr-ring{
  position:absolute;inset:0;border-radius:inherit;padding:1px;pointer-events:none;
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}

/* header rides the SAME track as .wrap, so the wordmark's left edge
   lines up exactly with the hero/section content at every width. Background
   stays full-bleed (header is block) while .nav-wrap carries the gutter. */
.site-header{display:block;padding:15px 0}
/* 1fr auto 1fr, not space-between: the brand and the tools cluster are very
   different widths, so space-between parked the nav off-centre. The middle
   track centres on the viewport regardless of what flanks it. */
.nav-wrap{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:20px}
.nav-wrap .nav-tools{justify-self:end}

/* jump nav set in caps, and the sliding indicator that tracks the section
   you're actually looking at (positioned by global.js). */
.nav{position:relative}
.nav a.navlink{text-transform:uppercase;font-size:.92rem;letter-spacing:.13em}
.nav a.navlink.is-current{color:var(--paper)}
/* the per-link hover underline is retired — it sat exactly where the indicator
   does, so hovering an inactive link drew two bars */
.nav a.navlink::after{display:none}
.nav-ind{
  position:absolute;left:0;bottom:-8px;height:2px;width:0;opacity:0;
  background:var(--amber);border-radius:2px;pointer-events:none;
  box-shadow:0 0 12px rgba(255,182,74,.55);
  transition:transform .38s var(--ease),width .38s var(--ease),opacity .3s var(--ease);
}
.nav-ind.is-on{opacity:1}
@media(prefers-reduced-motion:reduce){.nav-ind{transition:opacity .3s var(--ease)}}
/* the drawer stacks the links vertically, so a horizontal slider has nothing
   to slide along — and it would be measured at 0 while .nav is display:none.
   .is-current still marks the section by colour in the drawer. */
@media(max-width:860px){.nav-ind{display:none}}
/* the header runs closer to the browser edge than the content column — half the
   gutter. This deliberately breaks the wordmark's alignment with .wrap below. */
.site-header .nav-wrap{padding-inline:35px}
@media(max-width:900px){.site-header .nav-wrap{padding-inline:20px}}
@media(max-width:560px){.site-header .nav-wrap{padding-inline:11px}}

/* content column = full width minus a FIXED 70px margin on each side
   (no max-width centering, so the margin is always exactly 70px on desktop) */
.wrap{max-width:none;margin-inline:0;padding-inline:70px}
@media(max-width:900px){.wrap{padding-inline:40px}}
@media(max-width:560px){.wrap{padding-inline:22px}}

/* section eyebrows carry a pillar hue per section */
.kicker.k-teal{color:var(--teal)}
.kicker.k-magenta{color:var(--magenta)}
.kicker.k-violet{color:var(--violet)}
.kicker.k-teal::before{background:var(--teal)}
.kicker.k-magenta::before{background:var(--magenta)}
.kicker.k-violet::before{background:var(--violet)}

/* amber-outlined button — clearer than a plain ghost. Used only on the two
   phone CTAs. Amber label by default (the nav one, against the photo hero);
   the footer's takes a white label below, where it sits on flat dark ground
   next to a lot of other amber and needs to read as text to act on. */
.btn-outline{background:transparent;color:var(--amber);border-color:var(--amber)}
.btn-outline:hover{background:var(--amber);color:#241300;border-color:var(--amber);transform:translateY(-2px)}

/* hairline framing system — a soft full-bleed rule marks every section seam,
   framing the page into distinct bands for first-time visitors. The reusable
   ".rule" line (fades at the far edges) is the recurring divider/framing motif. */
.firststeps,.occasions,.testimonials,.faqs,.invite{position:relative}
.firststeps::before,.occasions::before,.testimonials::before,.faqs::before,.invite::before,.footer-rich::before{
  content:"";position:absolute;top:0;left:0;right:0;height:1px;z-index:6;pointer-events:none;
  background:rgba(255,240,222,.16);
}

/* --- lit rule grid ------------------------------------------------------
   Borrowed from the cabinets' edge lighting: a bright hairline core with a
   soft coloured bloom spilling onto the dark band. The seam rules and the
   sections carry the same treatment so the lines read as one illuminated
   frame rather than a stack of unrelated dividers.

   Every rule runs the same four pillar colours, but each section ROTATES the
   ramp to lead with its own pillar (--r1). So the page walks the palette as
   you scroll instead of repeating the identical rainbow five times. The
   footer leads teal again, closing the loop the first section opened.

   All rules run the full width, edge to edge — no fade-out at the ends. */
.firststeps{--r1:var(--teal);   --r2:var(--amber);  --r3:var(--magenta);--r4:var(--violet); --rule-glow:rgba(69,214,208,.16)}
.occasions {--r1:var(--magenta);--r2:var(--violet); --r3:var(--teal);   --r4:var(--amber);  --rule-glow:rgba(255,92,146,.16)}
.testimonials{--r1:var(--violet); --r2:var(--teal);  --r3:var(--amber);  --r4:var(--magenta);--rule-glow:rgba(166,132,255,.16)}
.faqs      {--r1:var(--magenta);--r2:var(--amber);  --r3:var(--violet); --r4:var(--teal);   --rule-glow:rgba(255,92,146,.16)}
.invite    {--r1:var(--amber);  --r2:var(--magenta);--r3:var(--violet); --r4:var(--teal);   --rule-glow:rgba(255,182,74,.16)}

.firststeps::before,.occasions::before,.testimonials::before,.faqs::before,.invite::before{
  background:linear-gradient(90deg,
    var(--r1) 0%, var(--r2) 34%, var(--r3) 67%, var(--r4) 100%);
  opacity:.36;
  filter:saturate(.8) drop-shadow(0 0 4px var(--rule-glow)) drop-shadow(0 0 11px var(--rule-glow));
}

/* The footer rule closes the page rather than seaming two bands, so it is
   softened and darkened against the others, and carries no bloom. */
.footer-rich{--r1:var(--teal);--r2:var(--amber);--r3:var(--magenta);--r4:var(--violet)}
.footer-rich::before{
  background:linear-gradient(90deg,
    var(--r1) 0%, var(--r2) 34%, var(--r3) 67%, var(--r4) 100%);
  opacity:.24;
  filter:saturate(.68) brightness(.74);
}
/* The glass is drawn, not refracted. backdrop-filter was the obvious reach
   here and it does nothing: the invite scrim above has already faded to
   near-black by the seam, so there is no imagery left to blur (measured: 7/255
   max difference). Instead the seam is built like a pane of smoked glass —
   a soft shadow falling up into the invite, and a specular sheen catching the
   top edge of the footer below. Both halves have a background they can
   actually be seen against. */
/* footer glow removed — the seam is a plain rule on a darker ground now */
.footer-rich::after{display:none}

/* Alternating band: sections step between the page ground and one shade
   deeper so the scroll reads as rhythm rather than one continuous dark field.
   Running order — occasions light, first-visit deep, testimonials light,
   FAQ deep — with the hero and invite photos bookending. Cards (--bg-2 /
   --surface) still lift off the deep band. */
.firststeps{background:var(--bg-deep)}

/* first-visit step numbers stepped through the pillar palette */
/* The per-card teal/magenta/violet numerals were retired 2026-07-22 when the
   numerals took the pillar stroke — a hue-tinted digit inside a four-hue ring
   read as two competing accents. Each card still declares its own --glow, so
   the spotlight keeps the cards distinct. Restore these three rules if the
   numerals ever need to carry the colour again. */

/* =========================================================================
   THE PHOTOGRAPHIC SLOT SYSTEM
   ========================================================================= */
.shot{position:relative;border-radius:var(--radius);overflow:hidden;background:#171009;border:1px solid var(--line);isolation:isolate;min-height:180px}
/* cinematic wash — warm key + cool accent = "lighting, not brightness" */
.shot::before{content:"";position:absolute;inset:0;z-index:0;background:
  radial-gradient(130% 100% at 82% 8%, rgba(255,182,74,.34), transparent 54%),
  radial-gradient(95% 90% at 10% 96%, rgba(255,92,146,.20), transparent 56%),
  radial-gradient(80% 80% at 46% 64%, rgba(69,214,208,.10), transparent 62%),
  linear-gradient(180deg,#2a1e11,#140f0a)}
/* grain + vignette for photographic depth */
.shot::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  box-shadow:inset 0 0 120px 24px rgba(0,0,0,.5), inset 0 -60px 90px -30px rgba(0,0,0,.6);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");background-size:140px}
/* pillar-accent tints for variety across the page */
.shot.t-teal::before{background:radial-gradient(120% 100% at 80% 10%,rgba(255,182,74,.20),transparent 55%),radial-gradient(95% 90% at 12% 92%,rgba(69,214,208,.30),transparent 56%),linear-gradient(180deg,#12211f,#0f100c)}
.shot.t-magenta::before{background:radial-gradient(120% 100% at 82% 8%,rgba(255,182,74,.18),transparent 54%),radial-gradient(95% 92% at 14% 94%,rgba(255,92,146,.34),transparent 56%),linear-gradient(180deg,#241320,#140b10)}
.shot.t-violet::before{background:radial-gradient(120% 100% at 80% 10%,rgba(255,182,74,.16),transparent 54%),radial-gradient(95% 90% at 14% 92%,rgba(166,132,255,.30),transparent 56%),linear-gradient(180deg,#1b1626,#100c14)}

/* real image drops straight in and covers */
.shot-img{position:absolute;inset:0;z-index:2;width:100%;height:100%;object-fit:cover}

/* on-canvas art-direction brief (remove when real photo lands) */
.shot-tag{position:absolute;top:13px;left:13px;z-index:4;display:inline-flex;align-items:center;gap:7px;font-family:var(--sans);font-weight:700;font-size:.62rem;letter-spacing:.15em;text-transform:uppercase;color:var(--amber);background:rgba(15,11,7,.55);border:1px solid var(--line);padding:5px 10px;border-radius:100px;backdrop-filter:blur(3px)}
.shot-tag::before{content:"◉";font-size:.7rem}
.shot-brief{position:absolute;inset:auto 16px 16px;z-index:4}
.shot-brief b{display:block;font-family:var(--serif);font-weight:400;font-size:clamp(1.25rem,2vw,1.7rem);letter-spacing:.02em;line-height:.98;color:var(--paper)}
.shot-brief span{display:block;margin-top:6px;font-size:.8rem;line-height:1.4;color:var(--muted);max-width:40ch}
.shot-brief em{color:var(--ink-soft);font-style:normal}

/* =========================================================================
   HERO — full-bleed cinematic
   ========================================================================= */
.v2hero{position:relative;min-height:calc(100vh - 20px);display:flex;align-items:flex-end;overflow:hidden;isolation:isolate}
.v2hero .shot{position:absolute;inset:0;z-index:-1;border:0;border-radius:0}
/* full-bleed shots read as cinematic photo; hide the on-canvas brief so it never fights copy */
.v2hero .shot-tag,.v2hero .shot-brief,.invite .shot-tag,.invite .shot-brief{display:none}
.v2hero-scrim{position:absolute;inset:0;z-index:0;background:linear-gradient(180deg,rgba(20,15,10,.55) 0%,rgba(20,15,10,.15) 34%,rgba(20,15,10,.72) 78%,var(--bg) 100%)}
.v2hero-inner{position:relative;z-index:1;padding-block:0 clamp(30px,4.4vw,64px);padding-top:clamp(120px,18vh,200px)}
.v2hero .kicker{display:inline-flex;align-items:center;gap:12px;letter-spacing:.209em}
.v2hero .kicker::before{content:"";width:30px;height:1px;background:var(--amber)}
.v2hero h1{font-family:var(--serif);font-weight:400;font-size:clamp(3.3rem,10vw,8.2rem);line-height:.9;letter-spacing:.01em;color:var(--paper);margin:.12em 0 .18em;text-shadow:0 2px 40px rgba(0,0,0,.5)}
.v2hero .lead{font-size:clamp(1.12rem,1.7vw,1.4rem);color:var(--ink-soft);max-width:62ch;margin-bottom:26px}
.hero-actions{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
/* margin-top matches .v2hero-inner's bottom padding so the tag row sits
   centred between the CTA row and the bottom of the hero */
.chips{display:flex;gap:9px;flex-wrap:wrap;margin-top:clamp(30px,4.4vw,64px)}
/* the track/set wrappers exist only for the mobile ticker — at desktop they
   dissolve so the chips stay direct flex children of .chips and wrap as before */
.chips-track,.chips-set{display:contents}
.chips-set[aria-hidden="true"]{display:none}
.chip{font-size:.82rem;font-weight:600;color:var(--ink-soft);background:rgba(244,237,225,.05);border:1px solid var(--line);border-radius:100px;padding:7px 14px;backdrop-filter:blur(3px)}
.chip b{color:var(--amber);font-weight:700;margin-right:5px}

/* =========================================================================
   SHARED SECTION BITS
   ========================================================================= */
.sec-head{max-width:60ch;margin-bottom:clamp(28px,4vw,46px)}
.sec-head.center{margin-inline:auto;text-align:center}
.eyebrow{display:block}
h2{font-family:var(--serif);font-weight:400;font-size:var(--fs-h2);line-height:.98;letter-spacing:.01em;color:var(--paper)}
h3{font-family:var(--serif);font-weight:400;font-size:var(--fs-h3);letter-spacing:.02em;color:var(--paper)}
h4{font-family:var(--serif);font-weight:400;font-size:var(--fs-h4);letter-spacing:.02em;color:var(--paper)}
.subhead{font-family:var(--sans);font-weight:600;font-size:1.05rem;color:var(--amber);margin:12px 0 0}

/* =========================================================================
   DAY MIRROR — image left, copy right
   ========================================================================= */
.daymirror .wrap{display:grid;grid-template-columns:.92fr 1.08fr;gap:clamp(28px,5vw,64px);align-items:center}
.daymirror .shot{min-height:480px;height:100%}
.beats{display:grid;gap:14px;margin-top:24px}
.beat{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:baseline;padding:16px 0;border-top:1px solid var(--line-soft)}
.beat:first-child{border-top:0}
.beat .bk{font-family:var(--serif);font-size:1.6rem;color:var(--amber);line-height:1}
.beat b{font-family:var(--serif);font-weight:400;font-size:1.5rem;letter-spacing:.02em;color:var(--paper);display:block;margin-bottom:2px}
.beat p{color:var(--muted);font-size:1rem}

/* =========================================================================
   FIRST VISIT — 3 steps, each image-topped
   ========================================================================= */
/* merged first-visit: give the empathetic headline + lead a wider measure */
.firststeps .sec-head{max-width:none}
.firststeps .sec-head .lead{max-width:none;margin-top:16px;text-wrap:balance}
.firststeps .steps{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.steps-dots{display:none}   /* only shown for the mobile one-card carousel */
/* border transparent — the edge is the .gr-ring child. It has to be a child and
   not ::before/::after: both of those already carry the pointer spotlight, and
   the last time something reached into those rules it silently killed the whole
   effect (see the .step:hover::before note below). */
.step{background:var(--bg-2);border:1px solid transparent;border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column}
.step .gr-ring{z-index:3;opacity:.3;transition:opacity .35s var(--ease)}
.step:hover .gr-ring,.step:focus-within .gr-ring{opacity:.75}
.step .shot{border:0;border-radius:0;min-height:200px}
.step-body{padding:22px 24px 26px;display:grid;grid-template-columns:auto 1fr;column-gap:14px;row-gap:14px;align-items:center}

/* --- spotlight cards ----------------------------------------------------
   The pointer acts like a light source moving across the card: a soft wash
   falls on the surface and the nearest edge catches the light. Same premise
   as the cabinets and the lit rule grid — light is the brand's material.

   global.js writes --mx/--my (pointer position, as a %) onto the hovered
   card; each card supplies its own --glow, matching its step number, so the
   colour that lights is the one already assigned to that step. Cards keep a
   50%/50% default so a keyboard-focused card lights from its centre rather
   than a stale pointer position. */
.step,.faq-item{position:relative;--mx:50%;--my:50%}
/* Resting origin for the step wash: low and to the LEFT, with the centre pushed
   past the bottom edge so the colour rises INTO the card from beneath its
   bottom-left corner rather than sitting inside it. Only the top of the 640px
   pool reaches the card, which is what keeps it a gradient rather than a blob.
   global.js overwrites both as inline props while the pointer is over a card,
   and clears them on the way out so the card falls back to here. */
.step{--mx:10%;--my:120%}
.steps .step:nth-child(1){--glow:69,214,208}
.steps .step:nth-child(2){--glow:255,92,146}
.steps .step:nth-child(3){--glow:166,132,255}
.faq-item{--glow:255,182,74}

/* the wash — sits above the photo, below the copy */
.step .shot{z-index:0}
.step-body{position:relative;z-index:2}
/* Carries a resting glow (2026-07-22): the wash sits at .42 at rest and fades
   to full on hover, so each card is quietly lit in its own pillar hue before
   anyone touches it. --mx/--my default to 50% 50%, so the resting pool is
   centred and only starts tracking once the pointer is over the card. Only the
   WASH rests visible — the lit edge below stays a pure hover reward, because
   the edge already belongs to the .gr-ring gradient and a second, pillar-hued
   edge at rest would muddy it. */
.step::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.42;
  border-radius:inherit;transition:opacity .35s var(--ease);
  /* 640px against a ~420px-wide card: the pool is wider than the card, so this
     reads as the whole card warming toward the cursor rather than a puck that
     tracks it. Deliberate (Tyler, 2026-07-22). The edge light below stays at
     260 — it is what keeps the effect legible as pointer-driven. */
  background:radial-gradient(640px circle at var(--mx) var(--my),rgba(var(--glow),.17),transparent 68%);
}
/* the lit edge — a 1px gradient ring, masked so only the border shows */
.step::after{
  content:"";position:absolute;inset:0;z-index:6;pointer-events:none;opacity:0;
  border-radius:inherit;padding:1px;transition:opacity .35s var(--ease);
  background:radial-gradient(260px circle at var(--mx) var(--my),
    rgba(var(--glow),1),rgba(var(--glow),.35) 45%,transparent 72%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
}
/* the hover edge used to be a per-card pillar border-color; the .gr-ring now
   owns the edge and brightens instead, so lighting the border too would double
   up. The pointer spotlight below still carries each card's own --glow. */
.step{transition:transform .35s var(--ease)}
.step:hover,.step:focus-within{transform:translateY(-3px)}
/* NB: this rule needs its own braces. It once ran on into the .faq-item rule
   below via a trailing comma, which silently killed the whole card spotlight —
   the step pseudo-elements inherited opacity:0 and a 1px bottom-edge box. */
.step:hover::before,.step:focus-within::before,
.step:hover::after,.step:focus-within::after{opacity:1}

/* FAQ rows are not cards, so the spotlight is a lit BOTTOM EDGE rather than a
   full ring — left/right/top strokes would draw a box that no longer exists. */
.faq-item::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;z-index:2;
  pointer-events:none;opacity:0;transition:opacity .3s var(--ease);
  background:radial-gradient(300px circle at var(--mx) 50%,
    rgba(var(--glow),1),rgba(var(--glow),.35) 46%,transparent 74%);
}
.faq-item:hover::after,.faq-item:focus-within::after{opacity:1}

/* no pointer to follow, and the lift costs layout work on scroll-heavy phones.
   The wash stays: since 2026-07-22 it is a RESTING glow, not a pointer effect,
   so on touch it simply sits centred (--mx/--my never leave 50%). Only the
   things that need a cursor to mean anything are dropped. */
@media (hover:none){
  .step:hover,.step:focus-within{transform:none}
  .step::after,.faq-item::after{display:none}
}
@media (prefers-reduced-motion:reduce){
  .step{transition:none}
  .step:hover,.step:focus-within{transform:none}
  .step .gr-ring,.step-n::after{transition:none}
}
/* The numeral wears the same edge as the card it sits in: gradient ring, no
   fill of its own, numeral in paper rather than a pillar hue — the four-hue
   stroke IS the colour, so tinting the digit too would be two accents on one
   40px object. Each card's identity still comes through in its --glow
   spotlight, which is untouched. */
.step-n{position:relative;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:100px;background:rgba(255,255,255,.04);border:1px solid transparent;color:var(--paper);font-weight:800;font-size:1.15rem;grid-column:1;grid-row:1}
.step-n::after{
  content:"";position:absolute;inset:-1px;border-radius:100px;padding:1px;
  pointer-events:none;opacity:.55;transition:opacity .35s var(--ease);
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}
.step:hover .step-n::after,.step:focus-within .step-n::after{opacity:1}
.step h3{grid-column:2;grid-row:1;font-size:var(--fs-h4);margin:0}
.step p{grid-column:1 / -1;grid-row:2;color:var(--muted);font-size:1rem;margin:0}

/* =========================================================================
   REGULARS — testimonial cards w/ portraits
   ========================================================================= */
.regulars .tcards{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.tcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:22px;display:flex;flex-direction:column;gap:14px}
.tcard .stars{color:var(--amber);letter-spacing:3px;font-size:.95rem}
.tcard blockquote{font-size:1.12rem;line-height:1.5;color:var(--ink-soft)}
.tcard .who{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;margin-top:auto;padding-top:4px;border-top:1px solid var(--line-soft)}
.tcard .who b{color:var(--paper);font-weight:700;font-size:.98rem}
.tcard .who span{color:var(--faint);font-size:.86rem}

/* =========================================================================
   THE ROOM — honest mosaic gallery
   ========================================================================= */
.roomgallery .mosaic{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:190px;gap:16px}
.roomgallery .shot.big{grid-column:span 2;grid-row:span 2}
.roomgallery .shot.tall{grid-row:span 2}

/* =========================================================================
   REASSURANCE — image left, confidence checklist right
   ========================================================================= */
.reassure .wrap{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,64px);align-items:center}
.reassure .shot{min-height:430px;height:100%}
.conf{list-style:none;display:grid;gap:2px;margin-top:22px}
.conf li{display:flex;gap:14px;align-items:flex-start;padding:13px 0;border-top:1px solid var(--line-soft);font-size:1.08rem;color:var(--ink-soft)}
.conf li:first-child{border-top:0}
.conf svg{flex:none;width:22px;height:22px;color:var(--amber);margin-top:3px}

/* =========================================================================
   NEIGHBORHOOD
   ========================================================================= */
/* =========================================================================
   COMBINED FOOTER — visit block (storefront + address + map) + site footer
   ========================================================================= */
.footer-rich{background:#121110;position:relative;border-top:0;padding:0 0 44px}
.footer-rich .wrap{display:block}                 /* neutralize inherited 3-col grid */
.footer-rich .kicker{display:inline-flex;align-items:center;gap:12px;color:var(--amber);font-size:.82rem;letter-spacing:.209em}
.footer-rich .kicker::before{content:"";width:30px;height:1px;background:var(--amber)}
/* "Find us on Ashland." steps up two sizes (was clamp(2.1,4.4vw,3.4)) to the
   same scale as the invite close, so the footer opens with a real statement. */
.footer-rich h2{font-family:var(--serif);font-weight:400;font-size:clamp(2.6rem,7vw,6rem);line-height:1;letter-spacing:.01em;color:var(--paper);margin:10px 0 16px}

/* align-items left at its stretch default + space-between on the copy column
   pins the phone button and the tag row to the bottom edge of the photo. */
.footer-rich .footer-visit{display:grid;grid-template-columns:1.5fr 1fr;gap:clamp(32px,5vw,64px);padding-top:clamp(44px,6vw,72px)}
.footer-rich .foot-visit-copy{display:flex;flex-direction:column;justify-content:space-between;gap:26px}
.footer-rich .foot-visit-copy p{max-width:none}   /* lift the inherited 34ch footer cap */
.footer-rich .foot-copy-top{display:flex;flex-direction:column;gap:13px}
.footer-rich .foot-copy-top h2,.footer-rich .foot-copy-top .addr,.footer-rich .foot-copy-top .sub2{margin:0}
/* the phone CTA sits with the address copy it belongs to; only the tags stay
   pinned to the bottom of the photo */
.footer-rich .foot-copy-top .hood-cta{margin:14px 0 0}
.footer-rich .foot-copy-bottom .foot-facts{margin-top:0}
/* =========================================================================
   FOOTER MAP — hand-drawn, geographically true.
   Ashland runs N-S, Division E-W, Milwaukee cuts NW at ~45 degrees, and the
   three enclose the Polish Triangle where the Blue Line station sits. Drawn
   rather than embedded so it carries brand colour, weighs ~2KB, needs no API
   key, and works offline.
   ========================================================================= */
/* Swapped again (2026-07-21): the storefront photo → a simple contact form,
   per Tyler. The address line + "Get directions" + phone already cover
   wayfinding, so the right column now earns its space by capturing a lead. */
.footer-rich .foot-form{
  position:relative;
  margin:0;border-radius:var(--radius);
  /* the edge is the ::after ring below; the border only holds geometry */
  background:var(--bg-deep);border:1px solid transparent;
  padding:clamp(22px,2.4vw,32px);
  display:flex;flex-direction:column;gap:14px;justify-content:center;
}
/* Card edge: the same masked pillar gradient as the controls inside it, but
   held well back. The stack has to read in one direction — card .2, controls
   .5 at rest, controls 1 on focus — so the container never competes with the
   thing you're actually filling in. inset:-1px because an abs-positioned child
   is laid out against the padding box, and this ring belongs on the border. */
.footer-rich .foot-form::after{
  content:"";position:absolute;inset:-1px;border-radius:var(--radius);
  padding:1px;pointer-events:none;opacity:.2;
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}
.footer-rich .ff-lead{color:var(--paper);font-size:1.16rem;font-weight:600;margin:0 0 2px}
.footer-rich .ff-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:520px){.footer-rich .ff-row{grid-template-columns:1fr}}
.footer-rich .ff-field{display:flex;flex-direction:column;gap:6px}
/* label text only — .ff-ctrl is a span too, so this must not catch it */
.footer-rich .ff-field>span:not(.ff-ctrl){font-size:.8rem;letter-spacing:.04em;color:var(--muted);text-transform:uppercase;font-weight:600}
.footer-rich .ff-field input,
.footer-rich .ff-field textarea{
  font:inherit;color:var(--paper);background:rgba(255,255,255,.03);
  /* the visible edge is .ff-ctrl::after; this border only holds the box's
     geometry (and turns red on invalid), so it stays transparent at rest */
  border:1px solid transparent;border-radius:10px;padding:11px 13px;
  width:100%;display:block;
  transition:border-color .18s var(--ease),background .18s var(--ease);
}
.footer-rich .ff-field textarea{resize:vertical;min-height:96px}
.footer-rich .ff-field input:focus,
.footer-rich .ff-field textarea:focus{
  outline:none;background:rgba(255,255,255,.05);
}
/* Same masked conic stroke as .btn-ring, same idle→lit grammar: the fields and
   the submit they sit above now share one edge treatment. Sits on a wrapper
   because pseudo-elements don't apply to <input>. */
.footer-rich .ff-ctrl{position:relative;display:block}
.footer-rich .ff-ctrl::after{
  content:"";position:absolute;inset:0;border-radius:10px;padding:1px;
  /* .25 against the submit's .5: four fields versus one button, so at equal
     weight the fields won the section on mass alone. Half the weight is what
     makes the button lead. This is at the low end of legible against
     --bg-deep — don't go further without re-checking the field edges are
     still findable. Focus still goes to full. */
  pointer-events:none;opacity:.25;transition:opacity .18s var(--ease);
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}
.footer-rich .ff-ctrl:focus-within::after{opacity:1}
/* the error colour has to read on its own — drop the gradient rather than
   letting red and four brand hues fight on the same 1px edge */
.footer-rich .ff-ctrl:has(:user-invalid)::after{opacity:0}
.footer-rich .ff-field input:user-invalid,
.footer-rich .ff-field textarea:user-invalid{border-color:#c9603f}
@media(prefers-reduced-motion:reduce){
  .footer-rich .ff-ctrl::after,
  .footer-rich .ff-field input,
  .footer-rich .ff-field textarea{transition:none}
}
.footer-rich .ff-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.footer-rich .ff-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:4px}
.footer-rich .ff-status{margin:0;font-size:.92rem;color:var(--muted)}
.footer-rich .ff-status.ok{color:#7fd18a}
.footer-rich .ff-status.err{color:#e08a6c}
.footer-rich .foot-form.is-sending button{opacity:.6;pointer-events:none}
.footer-rich .addr{font-size:1.38rem;color:var(--paper);font-weight:600;margin:2px 0 6px}
.footer-rich .sub2{color:var(--muted);font-size:1.16rem;margin-bottom:18px}
.footer-rich .hood-cta{display:flex;gap:12px;flex-wrap:wrap;margin:20px 0 24px}
/* white label here only — the nav's stays amber (see .btn-outline above) */
.footer-rich .btn-outline{color:var(--paper)}
.footer-rich .btn-outline:hover{color:#241300}
.footer-rich .map-frame{border-radius:var(--radius);overflow:hidden;border:1px solid var(--line);min-height:200px}
.footer-rich .map-frame iframe{width:100%;height:100%;min-height:200px;border:0;display:block;filter:grayscale(.35) contrast(1.05) brightness(.8)}

.footer-rich .footer-meta{display:grid;grid-template-columns:1.5fr 1fr;gap:40px;margin-top:clamp(40px,5vw,64px);padding-top:clamp(32px,4vw,44px);border-top:1px solid var(--line-soft)}
.footer-rich .foot-brand .brand{font-size:1.9rem;margin-bottom:12px}
.footer-rich .foot-brand p{color:var(--muted);font-size:.95rem;max-width:34ch}
.footer-rich .foot-line{display:block;color:var(--ink-soft);font-weight:600;font-size:1.12rem;padding:5px 0}
/* .footer-rich .wrap{display:block} above kills global.css's flex on .foot-bottom,
   which is why the copyright was running on straight after the brand line instead
   of sitting at the right edge. Re-assert the row here, and drop the hairline. */
.footer-rich .foot-bottom{display:flex;flex-wrap:wrap;justify-content:space-between;
  align-items:center;gap:12px 28px;
  border-top:0;margin-top:clamp(40px,5vw,60px)}
/* compact inline facts, folded under the CTAs (replaces the old meta row) */
/* tags, not a dot-separated run-on — same pill language as the hero chips and
   the occasion chooser, so the page has one way of showing a set of facts. */
.footer-rich .foot-facts{list-style:none;display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:26px}
.footer-rich .foot-facts li{font-size:.92rem;font-weight:600;color:var(--ink-soft);
  background:rgba(244,237,225,.05);border:1px solid var(--line);border-radius:100px;
  padding:8px 16px;white-space:nowrap}
.footer-rich .foot-facts li b{color:var(--amber);font-weight:700;margin-right:6px}
.footer-rich .foot-brandline{display:inline-flex;align-items:baseline;gap:10px;flex-wrap:wrap;color:var(--muted)}
/* one type treatment across the whole sentence — the wordmark keeps the amber
   but matches the size, family and weight of the line it now sits inside. */
.footer-rich .foot-bottom .brand{font-family:inherit;font-size:inherit;font-weight:inherit;letter-spacing:inherit;color:inherit}
/* the whole sentence in one colour and weight — .brand .fl is amber by
   default (global.css), so it has to be overridden here too */
/* plain inline, NOT inline-flex: as flex items the wordmark and the sentence
   were unbreakable boxes, so on mobile the whole sentence dropped to its own
   line instead of wrapping mid-phrase. The markup carries a literal space, so
   the gap goes too. */
.footer-rich .foot-brandline{display:inline;gap:0;color:var(--paper);font-weight:400}
.footer-rich .foot-brandline .brand{display:inline;gap:0}
.footer-rich .foot-brandline .fl{color:inherit}

/* =========================================================================
   INVITE — full-bleed close
   ========================================================================= */
.invite{position:relative;min-height:74vh;display:flex;align-items:center;text-align:center;overflow:hidden;isolation:isolate}
.invite .shot{position:absolute;inset:0;z-index:-1;border:0;border-radius:0}
.invite-scrim{position:absolute;inset:0;z-index:0;background:linear-gradient(180deg,rgba(20,15,10,.7),rgba(20,15,10,.55) 45%,var(--bg))}
.invite-inner{position:relative;z-index:1;margin-inline:auto}
.invite h2{font-size:clamp(2.6rem,7vw,6rem)}
.invite p{color:var(--ink-soft);font-size:1.15rem;margin:16px auto 28px;max-width:46ch}

/* The sticky mobile Call/Directions bar was removed — the hero CTAs carry the
   actions on mobile now, and the footer keeps Call and Get directions. */

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media(max-width:960px){
  .firststeps .steps,.regulars .tcards{grid-template-columns:1fr}
  .daymirror .wrap,.reassure .wrap{grid-template-columns:1fr}
  .daymirror .shot,.reassure .shot{min-height:320px}
  .footer-rich .footer-visit{grid-template-columns:1fr}
  .footer-rich .foot-facade{min-height:300px}
  .footer-rich .footer-meta{grid-template-columns:1fr 1fr}
  .roomgallery .mosaic{grid-template-columns:1fr 1fr;grid-auto-rows:170px}
  .roomgallery .shot.big{grid-column:span 2}
}
/* mobile header: sticky bottom bar handles actions, so keep the header to logo + menu */
@media(max-width:640px){
  .site-header .live,.site-header .nav-tools .btn{display:none}
}
@media(max-width:560px){
  .roomgallery .mosaic{grid-template-columns:1fr;grid-auto-rows:200px}
  .roomgallery .shot.big{grid-column:span 1}
  .footer-rich .footer-meta{grid-template-columns:1fr}
  /* the checkmarks push each tag past the fold point at 375px, so the four of
     them stack. Tighten them here so the block stays compact. */
  .footer-rich .foot-facts{gap:8px}
  .footer-rich .foot-facts li{font-size:.84rem;padding:7px 13px}
  .footer-rich .foot-facts li b{margin-right:5px}
}

/* =========================================================================
   MOBILE HERO — stack the photo over a dark text block so copy never lands on
   a face. Same structure as the TCW hero: the image stops being a background
   and becomes the top block of content, the scrim is dropped because the type
   is on solid ground now, and the CTAs go full width.
   ========================================================================= */
@media(max-width:640px){
  .v2hero{min-height:0;display:block;overflow:visible}
  .v2hero .shot{position:relative;height:44vh;min-height:0;z-index:auto}
  /* relative, not static: the base rule gives .shot-img z-index:2, and a static
     box ignores z-index — the photo would paint under .shot::before's placeholder
     wash. The wash and grain are for empty slots anyway, so drop them here. */
  /* framed right so the lit cabinet stays in view — a PERCENTAGE, not
     calc(100% - 20px): subtracting a length from 100% pushes a cover image
     left of the container's right edge, exposing the dark .shot ground as a
     strip. A percent always keeps the image covering. */
  .v2hero .shot .shot-img{position:relative;z-index:2;width:100%;height:44vh;object-fit:cover;object-position:84% 32%}
  .v2hero .shot::before{display:none}
  /* top-down scrim baked onto the photo: darkens the top edge so the wordmark
     and menu icon hold contrast over a bright hero, clearing by mid-frame.
     z-index outranks .shot-img (2) so it sits over the photo. */
  .v2hero .shot::after{
    display:block;inset:0;z-index:3;box-shadow:none;background:
      linear-gradient(180deg,rgba(9,6,3,.82) 0%,rgba(9,6,3,.52) 13%,rgba(9,6,3,.14) 30%,transparent 46%);
  }
  .v2hero-scrim{display:none}          /* type is on solid dark — no scrim needed */
  .v2hero-inner{
    position:static;background:var(--bg);
    display:flex;flex-direction:column;
    padding-top:22px;padding-bottom:40px;
  }
  /* eyebrow removed on mobile — headline leads the stacked hero. With the
     eyebrow gone the .16em under the headline read as cramped; open it up so
     headline + lead sit as a balanced group. */
  .v2hero .kicker{display:none}
  .v2hero h1{text-shadow:none;margin:.08em 0 .34em}
  .v2hero .lead{max-width:none;margin-bottom:26px}
  /* with the sticky bar gone these are the mobile CTAs — give them the width.
     Scoped to the hero: .hero-actions is reused by the invite section, whose
     single centred CTA should stay as it is. */
  .v2hero .hero-actions{gap:11px}
  .v2hero .hero-actions .btn{width:100%;justify-content:center;padding-block:15px}
  /* one CTA on mobile — "Find us" is covered by the footer and the nav */
  .v2hero .hero-actions .btn-ghost{display:none}

  /* one-and-a-peek: each card is ~82% so the next peeks in from the right; the
     3-dot pager (built in global.js) sits centred below. First card still
     left-aligns with the heading (snap-start within the text column). */
  .firststeps .steps{
    display:flex;grid-template-columns:none;gap:14px;
    padding:2px 0 6px;
    /* full-bleed: strip spans 100vw so the next card peeks in at the true
       screen edge; padding-inline + scroll-padding re-inset so the first card
       still snaps left-aligned under the heading. */
    width:100vw;margin-left:calc(50% - 50vw);
    padding-inline:var(--gutter);scroll-padding-inline:var(--gutter);
    overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
    /* horizontal-only scroller. overflow-x:auto silently promotes overflow-y
       to auto (spec), which let the strip wobble ~20px vertically; clip pins
       it. touch-action:pan-x hands the browser the gesture so a slightly
       diagonal swipe scrolls the cards instead of the page; overscroll
       contain stops the swipe chaining to the page / back-gesture. */
    overflow-y:clip;touch-action:pan-x;overscroll-behavior-x:contain;
  }
  .firststeps .steps::-webkit-scrollbar{display:none}
  .firststeps .step{flex:0 0 82%;scroll-snap-align:start}
  .steps-dots{display:flex;justify-content:center;gap:9px;margin-top:14px}
  .steps-dot{
    width:7px;height:7px;padding:0;border:0;border-radius:50%;cursor:pointer;
    background:rgba(255,255,255,.3);
    transition:background .25s var(--ease),transform .25s var(--ease);
  }
  .steps-dot.is-on{background:#fff;transform:scale(1.15)}

  /* trust claims run as a right-to-left ticker: pill chrome dropped, dot
     separators, full-bleed. The second .chips-set is a verbatim copy that
     seams the loop — aria-hidden so the claims are announced once. */
  /* order:-1 lifts the ticker to the top of the stacked hero — a full-bleed
     band directly under the photo and above the eyebrow, separating image
     from copy. (Parent .v2hero-inner is flex-column so order applies.) */
  .chips{
    order:-1;
    display:block;flex-wrap:nowrap;overflow:hidden;
    width:100vw;margin-left:calc(50% - 50vw);margin-top:0;margin-bottom:18px;
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
    mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  }
  .chips-track{display:flex;width:max-content;animation:chipTicker 26s linear infinite}
  .chips-set{display:flex;align-items:center;flex:0 0 auto}
  /* outranks the base rule that hides the copy at desktop — the loop needs it */
  .chips-set[aria-hidden="true"]{display:flex}
  .chip{
    background:none;border:0;border-radius:0;padding:0;backdrop-filter:none;
    display:inline-flex;align-items:center;white-space:nowrap;
    font-size:.9rem;color:var(--ink-soft);
  }
  .chips-set .chip::after{
    content:"";flex:none;width:3px;height:3px;border-radius:50%;
    background:var(--faint);margin-inline:16px;
  }
  @keyframes chipTicker{from{transform:translateX(0)}to{transform:translateX(-50%)}}
}
/* no motion: a swipeable strip that still shows every claim */
@media(max-width:640px) and (prefers-reduced-motion:reduce){
  .chips{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .chips-track{animation:none}
  .chips-set[aria-hidden="true"]{display:none}
}

/* ---- large-screen breakpoints: widen the canvas + scale up ---- */
@media(min-width:1440px){
  :root{--maxw:1440px}
  body{font-size:19px}
  .roomgallery .mosaic{grid-auto-rows:220px}
  .daymirror .shot,.reassure .shot{min-height:540px}
  .footer-rich .foot-facade{min-height:380px}
  .step .shot{min-height:300px}
  .step-body{padding:26px 28px 30px;column-gap:16px;row-gap:16px}
  .step-n{width:44px;height:44px;font-size:1.2rem}
  .step p{font-size:1.1rem}
}
/* =========================================================================
   CONTENT PASS (Jul 2026) — games note, neighbors quote, live-pill states,
   mosaic bottom row, invite tagline close
   ========================================================================= */

/* live pill — closed state (toggled by global.js) */
.live.closed{color:var(--muted);background:rgba(182,166,143,.07);border-color:rgba(182,166,143,.28)}
.live.closed::before{background:var(--faint);animation:none;box-shadow:none}

/* what-are-the-games note (first visit) */
.games-note{margin-top:22px;padding:26px 30px 28px;background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius)}
.games-note p{color:var(--muted);max-width:70ch}

/* neighbors — single featured review */
.neighbors .sec-head{margin-bottom:clamp(20px,3vw,34px)}
.tfeature{max-width:780px;display:grid;gap:16px}
.tfeature .stars{color:var(--amber);letter-spacing:6px;font-size:1.05rem}
.tfeature blockquote{font-size:clamp(1.35rem,2.4vw,1.9rem);line-height:1.45;color:var(--ink-soft)}
.tfeature .who{display:flex;align-items:center;gap:10px}
.tfeature .who::before{content:"";width:26px;height:1px;background:var(--amber)}
.tfeature .who b{color:var(--paper);font-weight:700}
.tfeature .who span{color:var(--faint);font-size:.9rem}

/* =========================================================================
   TESTIMONIALS — its own full-width row, centred.
   The quote is the largest body text on the page: it is the only place a
   stranger vouches for the room, so it gets the weight a headline would.
   ========================================================================= */
/* more air than a standard .section so the quote reads as a featured moment
   rather than another band in the stack */
.testimonials{padding-block:clamp(78px,10.5vw,152px)}
.testimonials .wrap{text-align:center}
.testimonials .sec-head{max-width:none;margin-bottom:clamp(26px,3.4vw,44px)}
/* the rating sits under the heading and stays put while quotes cycle */
.testimonials .sec-head .stars{
  color:var(--amber);letter-spacing:10px;font-size:1.25rem;
  margin:16px 0 0;padding-left:10px;   /* offsets the trailing letter-space */
}
/* slides are absolutely positioned at inset:0, so the grid would stretch and
   strand the byline at the bottom — centre the block and keep it together */
.testimonials .tfeature{max-width:none;justify-items:center;gap:20px;height:100%;align-content:center}
.testimonials .tfeature blockquote{
  font-size:clamp(1.6rem,3.1vw,2.7rem);line-height:1.32;color:var(--paper);
  max-width:46ch;margin-inline:auto;text-wrap:balance;
}
.testimonials .tfeature .who{justify-content:center}
.testimonials .tdots{justify-content:center;margin-top:30px}

/* testimonial carousel — fade-through.
   Slides stack in a single grid cell rather than being absolutely positioned,
   so the viewport sizes itself to the tallest quote. The old approach needed a
   min-height to stop the container collapsing, and that reserved height became
   stale the moment the quote width changed — leaving 200px of dead space. */
.tcarousel{max-width:none}
.tviewport{position:relative;display:grid}
.tviewport .tslide{grid-area:1/1;margin:0;opacity:0;transition:opacity .7s var(--ease);pointer-events:none}
.tviewport .tslide.is-active{opacity:1;pointer-events:auto}
.tdots{display:flex;gap:10px;margin-top:22px}
.tdot{width:9px;height:9px;padding:0;border:0;border-radius:50%;cursor:pointer;background:var(--line);transition:background .25s var(--ease),transform .25s var(--ease)}
.tdot:hover{background:var(--faint)}
.tdot.is-active{background:var(--amber);transform:scale(1.25)}
@media(prefers-reduced-motion:reduce){.tviewport .tslide{transition:none}}
/* =========================================================================
   GOOD TO KNOW — its own row beneath the testimonial.
   Dark glass: a translucent pane over the deep band rather than the opaque
   warm-brown card it replaced. Like the footer seam, the glass is DRAWN, not
   refracted — an inset top highlight for the lit edge of the pane, a low-alpha
   fill for the body, and a soft drop for the lift. backdrop-filter is included
   for browsers that composite it, but nothing depends on it: the section sits
   on a flat ground, so there is nothing behind to blur.
   ========================================================================= */
.faqs{background:var(--bg-deep)}
/* Pulled in a column on BOTH sides (the Occasions indent is left-only), so the
   question list reads as a narrower, quieter block than the sections around it.
   Scoped above 900px so it doesn't clobber .wrap's tighter mobile gutters. */
@media(min-width:901px){
  .faqs .wrap{padding-inline:calc(70px + clamp(0px,5vw,160px))}
}
.faqs .sec-head{max-width:none;margin-bottom:clamp(20px,2.6vw,32px)}

.faq-list{display:flex;flex-direction:column;gap:0;margin-bottom:clamp(28px,4vw,60px)}
/* closing rule so the last question is enclosed like the rest */
.faq-list::after{
  content:"";display:block;height:1px;
  background:linear-gradient(90deg,var(--teal),var(--amber) 34%,var(--magenta) 67%,var(--violet));
  opacity:.3;
}
.faq-item{background:none;border:0;border-radius:0;box-shadow:none;
  backdrop-filter:none;-webkit-backdrop-filter:none;position:relative}
/* items are separated by a lit rule rather than boxed — same gradient family
   as the section seams, so the list reads as part of the page's rule system */
.faq-item + .faq-item::before{
  content:"";position:absolute;top:0;left:0;right:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,var(--teal),var(--amber) 34%,var(--magenta) 67%,var(--violet));
  opacity:.3;
}
.faq-item summary,.faq-item .faq-a{position:relative;z-index:1}
.faq-item summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:22px;padding:26px 4px;color:var(--paper);transition:color .2s var(--ease)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::marker{content:"";display:none}

.faq-item .faq-q{font-family:var(--sans);font-weight:500;font-size:clamp(1.45rem,1.9vw,1.85rem);line-height:1.2;text-box:trim-both cap alphabetic;transform:translateY(4px);transition:transform .28s var(--ease)}
/* larger nudge where leading-trim is unavailable (untrimmed line box sits higher) */
@supports not (text-box:trim-both cap alphabetic){.faq-item .faq-q{transform:translateY(3px)}}
/* the question steps toward the reader on rollover; the Y value is the cap-trim
   correction and has to be carried through or the text jumps vertically */
.faq-item summary:hover .faq-q,.faq-item summary:focus-visible .faq-q{transform:translate(9px,4px)}
@supports not (text-box:trim-both cap alphabetic){
  .faq-item summary:hover .faq-q,.faq-item summary:focus-visible .faq-q{transform:translate(9px,3px)}
}
/* + (closed) → − (open) indicator */
/* the plus is now the interactive object — the row itself stays quiet, and the
   rollover lives entirely on the button: it fills, and its ring lights with the
   same pillar gradient the separators use. */
.faq-pm{
  position:relative;flex:none;width:52px;height:52px;border-radius:50%;
  border:1px solid rgba(255,182,74,.42);
  transition:border-color .25s var(--ease),background .25s var(--ease),transform .25s var(--ease);
}
.faq-pm::before,.faq-pm::after{
  content:"";position:absolute;top:50%;left:50%;background:var(--amber);
  border-radius:2px;transition:transform .3s var(--ease);
}
.faq-pm::before{width:18px;height:2px;transform:translate(-50%,-50%)}
.faq-pm::after{width:2px;height:18px;transform:translate(-50%,-50%)}
.faq-item[open] .faq-pm::after{transform:translate(-50%,-50%) scaleY(0)}

/* rollover — lit ring drawn as a masked gradient so it can carry all four hues */
.faq-pm-ring{
  position:absolute;inset:-1px;border-radius:50%;padding:1px;pointer-events:none;
  opacity:0;transition:opacity .25s var(--ease);
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}
.faq-item summary:hover .faq-pm,.faq-item summary:focus-visible .faq-pm{
  background:none;border-color:transparent;transform:scale(1.06);
}
.faq-item summary:hover .faq-pm-ring,.faq-item summary:focus-visible .faq-pm-ring{opacity:.62}
.faq-item[open] .faq-pm-ring{opacity:.4}
/* no measure cap — the answers are short enough to sit on one line in the
   full column, and wrap naturally once the viewport cannot hold them */
.faq-a{padding:0 4px 30px;font-size:1.3rem;line-height:1.55;max-width:none}
.faq-a p{color:var(--ink-soft);max-width:none}
/* smooth open where supported; instant + fully usable everywhere else */
@supports (interpolate-size: allow-keywords){
  :root{interpolate-size:allow-keywords}
  .faq-item::details-content{height:0;overflow:clip;opacity:0;transition:height .32s var(--ease),opacity .28s var(--ease),content-visibility .32s allow-discrete}
  .faq-item[open]::details-content{height:auto;opacity:1}
}
@media(prefers-reduced-motion:reduce){
  .faq-item,.faq-item summary,.faq-pm::before,.faq-pm::after{transition:none}
  .faq-item::details-content{transition:none}
}
@media(max-width:860px){
}

/* room mosaic — bottom row pair completes the grid */
.roomgallery .shot.wide{grid-column:span 2}
@media(max-width:560px){.roomgallery .shot.wide{grid-column:span 1}}

/* =========================================================================
   OCCASIONS — the 11-to-11 timeline.
   Three columns are the three parts of the trading day; a lit rule runs across
   the top as the spine, with a dot marking where each part begins. One photo
   per column instead of one per occasion — nine occasions would need nine
   frames, and the library is entirely night-lit, so the daytime ones could not
   be illustrated honestly. The three chosen frames build from quiet to full,
   which is the arc the section is claiming.
   ========================================================================= */
.occasions .sec-head{max-width:none;  /* let the display heading sit on one line */
  /* NB: this collapses with .chooser's margin-top (adjacent siblings) — the
     larger wins, so both have to come down to actually close the gap. */
  margin-bottom:clamp(16px,1.8vw,28px)}

/* --- OCCASION CHOOSER ----------------------------------------------------
   Nine reasons people come in, as chips. Pick one, see it. The chips are the
   whole affordance: nothing to decode before you get something back, which is
   why this replaced the scrubbable day rail.

   It is also the home for the shelved room-gallery frames — nine photographs
   in one section's worth of height, one visible at a time.

   The <ol> is the source content; .is-live (set by global.js) swaps it for the
   interactive stage, so no-JS still gets every occasion as plain text. */
/* Two columns: the nine chips stack flush left as a menu, the chosen photo
   fills the rest. Left-aligned, NOT centred — the chips have to start on the
   same line as the section heading above them. */
/* The section's content is indented a column from the hero's flush-left edge,
   so the eye steps inward here. Heading and chips share the indent, which keeps
   the chips aligned to the heading above them. Zeroed on narrow screens where
   the width is needed more than the gesture. */
.occasions .sec-head,
.occasions .chooser{margin-left:clamp(0px,5vw,160px)}

/* Capped, and deliberately NOT var(--maxw) — that token scales to 1800px on
   large screens, and past ~1500 the photo letterboxes badly against its 3:2
   source. Trailing space to the right on very wide screens is intentional. */
.chooser{margin-top:clamp(14px,1.6vw,26px);max-width:1500px}

.chooser .oc-chips,
.chooser .oc-stage{display:none}
/* align-items defaults to stretch, so the row is as tall as the chip stack and
   the photo matches it exactly at any width — no clamp to keep re-tuning. */
.chooser.is-live{display:grid;gap:clamp(18px,2.2vw,38px);
  grid-template-columns:minmax(210px,255px) minmax(0,1fr)}
.chooser.is-live .oc-chips{display:flex}
.chooser.is-live .oc-stage{display:block}
.chooser.is-live .oc-list{display:none}

/* no-JS / pre-upgrade list */
.oc-list{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:clamp(20px,2.6vw,38px)}
.oc-item{padding-top:16px;border-top:1px solid var(--line-soft)}
.oc-item h3{font-family:var(--serif);font-weight:700;font-size:1.38rem;
  color:var(--paper);margin:0 0 6px}
.oc-item p{color:var(--muted);font-size:.97rem;line-height:1.5;margin:0}

/* the chips — a vertical menu in the left column. They hug their text rather
   than filling the column, so they stay pills and don't read as nav buttons. */
.oc-chips{flex-direction:column;align-items:flex-start;gap:10px}
.oc-chip{font:inherit;font-size:1rem;cursor:pointer;background:var(--surface);
  color:var(--ink-soft);border:1px solid var(--line);border-radius:999px;
  padding:11px 20px;white-space:nowrap;
  transition:background .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease),
    box-shadow .2s var(--ease)}
.oc-chip:hover{border-color:var(--amber);color:var(--paper)}
/* the glow is .btn-primary's (global.css:120) scaled to pill size, so the lit
   chip reads as the same species of control as the hero CTA */
.oc-chip[aria-selected="true"]{background:var(--amber);border-color:var(--amber);
  color:#201200;font-weight:600;box-shadow:0 8px 26px -10px rgba(255,182,74,.7)}

/* the stage */
.oc-stage{position:relative}
.oc-stage:focus-visible{outline-offset:6px}
.oc-frame{position:relative;overflow:hidden;border-radius:var(--radius);
  /* transparent — the edge is the .gr-ring child. NB overflow:hidden clips to
     the padding box, so the ring sits at inset:0 (inside the 1px border) rather
     than the -1px the unclipped cards use. */
  border:1px solid transparent;background:#171009;
  /* lifts the photo off the band: a tight contact shadow plus a wide ambient
     one, in near-black violet (the cool pillar crushed almost to black) so the
     dark stays cool against the warm ground instead of reading neutral */
  box-shadow:0 10px 24px -12px rgba(20,8,38,.72),0 32px 70px -28px rgba(20,8,38,.72);
  /* aspect-ratio sets the row's natural height; height:100% then fills whatever
     the row ends up being. Both are needed: without the ratio the photo can
     never grow past the chip stack, and without height:100% it stays SHORTER
     than the stretched stage on mid-widths and the readout floats off the photo. */
  width:100%;aspect-ratio:16/11;height:100%;min-height:380px}
/* Jumping to #occasions should land heading + chips + the WHOLE card on one
   screen. 270px of chrome sits above the photo (96 section pad + 102 heading
   block + a 28px collapsed gap), so the photo gets the rest, less a small
   buffer. Capped on BOTH stage and frame so they stay in lockstep — capping
   only the frame lets the stretched stage run taller and the readout, which
   anchors to the stage, floats off the bottom of the photo. */
.oc-stage,.oc-frame{max-height:calc(100vh - 278px)}
.oc-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .45s var(--ease)}
.oc-img.is-on{opacity:1}
.oc-wash{position:absolute;inset:0;pointer-events:none;mix-blend-mode:soft-light;
  background:var(--oc-wash,rgba(255,182,74,.26));transition:background .45s var(--ease)}
/* the copy sits on photography, so it needs its own bed: the scrim ramps
   earlier and lands darker than a decorative vignette would */
.oc-vig{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(14,10,6,.34),rgba(14,10,6,.02) 26%,
    rgba(14,10,6,.55) 62%,rgba(14,10,6,.93))}
.oc-readout{position:absolute;left:clamp(20px,2.8vw,40px);right:clamp(20px,2.8vw,40px);
  /* NB: a ch cap here resolves against the CONTAINER's font-size, not the
     title's, so it froze while the type grew. Sized off the frame instead,
     wide enough to keep the longest support line unwrapped (797px at 24px);
     the body scales on vw so the ratio holds down to the 1180px collapse. */
  /* Reserve keeps the last body line clear of the .oc-timer dial in the
     bottom-right of the same frame. NB: the % resolves against .oc-stage, not
     against this box's inset width, so the number is the dial (34) + its inset
     (24) + a real gutter — 96 measured out to a 2px miss. */
  bottom:clamp(20px,2.8vw,38px);max-width:min(calc(100% - 132px),900px)}
.oc-readout .oc-when{font-family:var(--sans);font-weight:700;font-size:.9rem;
  letter-spacing:.16em;text-transform:uppercase;color:var(--amber);margin:0 0 11px;
  text-shadow:0 1px 12px rgba(0,0,0,.85)}
.oc-readout .oc-title{font-family:var(--serif);
  /* regular, matching the section h2s (v2.css:178). NB: bebas-neue-pro serves
     600 and 700 from the same face in this kit — distinct faces are
     200/300/400/500/600+ — so don't expect a 600/700 difference. */
  font-weight:400;font-size:var(--fs-h3);line-height:1.02;color:var(--paper);margin:0 0 11px;
  text-shadow:0 2px 20px rgba(0,0,0,.7)}
.oc-readout .oc-body{color:var(--paper);font-size:clamp(1.15rem,1.4vw,1.375rem);
  line-height:1.45;margin:0;text-shadow:0 1px 16px rgba(0,0,0,.85)}

/* matches the step cards — same content-card level, and it sits above the
   photo, wash and vignette so the edge stays legible over any frame */
.oc-frame .gr-ring{z-index:4;opacity:.3}

/* auto-advance dial — shows how long the current occasion has left. It is only
   present while autoplay is genuinely running: global.js adds .is-auto in
   ocStart() and drops it in ocStop(), so hover, focus, an off-screen section,
   a deliberate chip pick and prefers-reduced-motion all hide it rather than
   leaving a stalled or lying indicator on the photo. --oc-delay is written by
   global.js from OC_DELAY so the sweep and the interval share one number. */
.oc-timer{
  position:absolute;right:clamp(16px,1.8vw,24px);bottom:clamp(16px,1.8vw,24px);
  width:34px;height:34px;pointer-events:none;
  opacity:0;transition:opacity .3s var(--ease);
  filter:drop-shadow(0 1px 6px rgba(0,0,0,.5));
}
.chooser.is-auto .oc-timer{opacity:.55}
.oc-timer svg{width:100%;height:100%;transform:rotate(-90deg);display:block}
.oc-timer circle{fill:none;stroke-width:2.5;stroke-linecap:round}
.oc-timer-track{stroke:rgba(255,255,255,.28)}
/* r=16 → circumference 100.53 */
.oc-timer-arc{stroke:#fff;stroke-dasharray:100.53;stroke-dashoffset:100.53}
.chooser.is-auto .oc-timer-arc{
  animation:oc-sweep var(--oc-delay,3800ms) linear infinite;
}
@keyframes oc-sweep{from{stroke-dashoffset:100.53}to{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){
  .oc-timer{display:none}
}

/* Below this the 255px chip column starves the photo — it goes square-ish
   (1.12:1 at 1024px) against a 3:2 source. Back to chips over photo. */
@media(max-width:1180px){
  .occasions .sec-head,
  .occasions .chooser{margin-left:0}
  .chooser.is-live{grid-template-columns:1fr}
  .oc-frame{aspect-ratio:auto}
  .oc-chips{flex-direction:row;flex-wrap:wrap;max-width:860px;gap:10px;
    margin-bottom:clamp(20px,2.4vw,30px)}
  /* width-driven, not vh-driven: a fixed height ignored the browser width, so
     narrowing the window only cropped the photo harder (2.07:1 out of a 3:2
     source at 1000px). Now it scales down with the viewport and keeps its
     crop; max-height stops it dominating a short window. */
  .oc-stage{max-height:none}
  .oc-frame{height:auto;aspect-ratio:16/10;max-height:72vh}
}

@media(max-width:760px){
  /* a filter bar, not five rows of wrapped chips — keeps the photo near the top.
     Full-bleed: the strip spans 100vw (same breakout as the hero ticker) so
     chips scroll to the true screen edge instead of stopping a gutter short.
     The leading padding + scroll-padding re-inset the first chip so it still
     starts left-aligned with the heading; only the scroll runs edge to edge. */
  .oc-chips{flex-wrap:nowrap;overflow-x:auto;scroll-snap-type:x proximity;
    scrollbar-width:none;
    width:100vw;margin-left:calc(50% - 50vw);
    padding-inline:var(--gutter);scroll-padding-inline:var(--gutter)}
  .oc-chips::-webkit-scrollbar{display:none}
  .oc-chip{scroll-snap-align:start;font-size:.94rem;padding:9px 16px}
  /* the frame is a tap target here (global.js): tapping steps to the next
     occasion. cursor + no tap-flash + a quick brightness dip give the press
     tactile feedback; the ::after chevron is the standing "there's more, tap"
     cue — a pointer affordance only, so it's aria-hidden by being a pseudo. It
     mirrors the auto-advance dial in the opposite corner (skip vs. time). */
  /* full-bleed: the photo spans 100vw and drops its corner radius so it meets
     the screen edges cleanly. The readout below stays inset (aligned to the
     heading), giving a full-bleed image + indented caption. */
  .oc-frame{height:auto;aspect-ratio:4/5;max-height:none;
    width:100vw;margin-left:calc(50% - 50vw);border-radius:0;
    cursor:pointer;-webkit-tap-highlight-color:transparent}
  .oc-frame:active{filter:brightness(.93)}
  .oc-frame::after{content:"";position:absolute;left:12px;bottom:12px;z-index:5;
    width:34px;height:34px;border-radius:50%;pointer-events:none;
    border:1px solid rgba(255,255,255,.28);background:rgba(20,14,8,.5) center/17px no-repeat
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E");
    backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
  /* the photo is too small to also carry the copy — drop it underneath, and
     lighten the vignette now that nothing has to be legible on top of it */
  .oc-readout{position:static;max-width:none;margin-top:18px}
  .oc-readout .oc-when,
  .oc-readout .oc-title,
  .oc-readout .oc-body{text-shadow:none}
  .oc-readout .oc-body{color:var(--ink-soft)}
  .oc-vig{background:linear-gradient(180deg,rgba(14,10,6,.4),rgba(14,10,6,0) 26%,rgba(14,10,6,.46))}
}
@media(prefers-reduced-motion:reduce){
  .oc-img,.oc-wash,.oc-chip{transition:none}
}

/* =========================================================================
   SAVE-YOUR-SEAT BAND — the invite section's treatment, at half the height.
   Full-bleed photo behind, scrim fading to the page ground so the band melts
   out rather than ending in a border, centred type. Shorter than the closing
   invite (45vh vs 74vh) so it reads as a lighter echo of it, not a rival.
   ========================================================================= */
.cta-band{
  position:relative;min-height:54vh;display:flex;align-items:center;
  text-align:center;overflow:hidden;isolation:isolate;
  margin-top:clamp(46px,5.4vw,84px);
  border-radius:var(--radius);border:1px solid var(--line);
}
.cta-band .shot{position:absolute;inset:0;z-index:-1;border:0;border-radius:0;min-height:0}
.cta-band .shot-tag,.cta-band .shot-brief{display:none}
.cta-scrim{
  position:absolute;inset:0;z-index:0;
  /* the edges stay bright so the room reads; a soft centred pool darkens only
     where the type sits. Measured: without it the checks fell to 3.96:1. */
  background:
    radial-gradient(66% 76% at 50% 52%, rgba(8,5,3,.88), rgba(8,5,3,.42) 60%, rgba(8,5,3,0) 84%),
    linear-gradient(180deg,rgba(14,10,6,.46),rgba(14,10,6,.3) 45%,rgba(14,10,6,.56));
}
.cta-inner{position:relative;z-index:1;margin-inline:auto;padding:clamp(64px,8.6vw,125px) clamp(24px,4vw,64px)}
.cta-band h3{
  font-family:var(--serif);font-weight:700;font-size:clamp(2.2rem,5vw,4rem);
  line-height:.98;letter-spacing:.01em;color:var(--paper);margin:0;
}
.cta-band .tagline{
  font-family:var(--serif);font-weight:700;
  font-size:clamp(1.1rem,1.8vw,1.5rem);letter-spacing:.16em;text-transform:uppercase;
  color:var(--amber);margin:16px auto 0;
}
.cta-band .conf{
  list-style:none;display:flex;flex-wrap:wrap;justify-content:center;
  gap:9px clamp(16px,2.1vw,30px);margin:26px auto 0;max-width:70ch;
}
.cta-band .conf li{
  display:inline-flex;gap:8px;align-items:center;border:0;padding:0;
  font-size:clamp(.98rem,1.15vw,1.1rem);font-weight:600;color:var(--ink-soft);
}
.cta-band .conf svg{flex:none;width:17px;height:17px;color:var(--amber)}
.btn-cta{
  display:inline-flex;margin-top:clamp(24px,2.8vw,36px);
  background:var(--amber);color:#241300;border:1px solid transparent;
}
.btn-cta:hover{background:#ffc76e;transform:translateY(-2px)}
/* hollow button carrying the same masked pillar-gradient stroke as the FAQ +
   ring (.faq-pm-ring). Same idle→rollover grammar too: the stroke sits back at
   rest and lights on hover/focus, so the two controls read as one family.
   The stroke is a child span, not a ::before — .btn's own pseudo-elements are
   spoken for elsewhere, and a real element keeps the mask off the label. */
.btn-ring{position:relative;background:transparent;color:var(--paper);border-color:transparent}
.btn-ring-line{
  position:absolute;inset:0;border-radius:inherit;padding:1px;pointer-events:none;
  opacity:.5;transition:opacity .25s var(--ease);
  background:var(--stroke-grad);filter:saturate(.78);
  -webkit-mask:var(--stroke-mask);-webkit-mask-composite:xor;
  mask:var(--stroke-mask);mask-composite:exclude;
}
.btn-ring:hover,.btn-ring:focus-visible{background:rgba(255,182,74,.06);color:var(--amber);transform:translateY(-2px)}
.btn-ring:hover .btn-ring-line,.btn-ring:focus-visible .btn-ring-line{opacity:1}
/* the label must clear the masked stroke layer */
.btn-ring>:not(.btn-ring-line){position:relative;z-index:1}
@media(prefers-reduced-motion:reduce){
  .btn-ring,.btn-ring-line{transition:none}
  .btn-ring:hover,.btn-ring:focus-visible{transform:none}
}
@media(max-width:640px){
  .cta-band{min-height:0}
  .cta-inner{padding-block:clamp(44px,11vw,64px)}
  .cta-band .conf{gap:10px 18px}
  .btn-cta{width:100%;justify-content:center}
}

/* invite — tagline close, centered single CTA, fest note */
.invite .hero-actions{justify-content:center}
.invite .tagline{font-family:var(--serif);font-weight:700;font-size:clamp(1.5rem,2.6vw,2.2rem);letter-spacing:.16em;text-transform:uppercase;color:var(--amber);margin:20px auto 0}
.invite .fest-note{font-size:.95rem;color:var(--muted);margin:26px auto 0;max-width:60ch}

@media(min-width:1920px){
  :root{--maxw:1800px;--gutter:clamp(48px,5vw,120px)}
  body{font-size:20px}
  .roomgallery .mosaic{grid-auto-rows:270px}
  .daymirror .shot,.reassure .shot{min-height:620px}
  .footer-rich .foot-facade{min-height:420px}
  .step .shot{min-height:380px}
  .step-body{padding:30px 32px 34px;column-gap:18px;row-gap:18px}
  .step-n{width:48px;height:48px;font-size:1.3rem}
  .step p{font-size:1.2rem}
}

/* =========================================================================
   MOBILE MENU — full-height off-canvas panel, slides in from the right.
   Only reachable ≤860px, where the header collapses to logo + hamburger.
   The phone CTA moves out of the header and lives at the foot of the panel.
   ========================================================================= */

/* hamburger sits ~40px off the right edge across the mobile range (overrides
   the tighter header gutters set above) and the standalone phone button is
   retired here — it now lives inside the panel. */
@media(max-width:860px){
  /* the desktop 1fr/auto/1fr grid mis-places the tools cluster once the
     horizontal nav is display:none, so collapse to a plain flex row: brand
     left, hamburger hard right, 40px off each edge. */
  .site-header .nav-wrap{display:flex;justify-content:space-between;padding-inline:40px}
  .site-header .nav-tools .btn{display:none}
}

.menu-scrim{
  position:fixed;inset:0;z-index:190;
  background:rgba(8,5,2,.58);backdrop-filter:blur(3px);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .4s var(--ease),visibility .4s var(--ease);
}
.menu-scrim.is-on{opacity:1;visibility:visible;pointer-events:auto}

.menu-panel{
  position:fixed;top:0;right:0;z-index:200;
  height:100dvh;width:min(86vw,360px);
  display:flex;flex-direction:column;overflow-y:auto;
  /* translucent + frosted so the dimmed hero reads through the panel as
     blurred colour behind the type */
  background:linear-gradient(202deg,rgba(28,20,11,.68) 0%,rgba(19,14,9,.78) 62%);
  backdrop-filter:blur(22px) saturate(1.15);
  -webkit-backdrop-filter:blur(22px) saturate(1.15);
  border-left:1px solid var(--line);
  box-shadow:-30px 0 60px -22px rgba(0,0,0,.72);
  transform:translateX(100%);
  transition:transform .46s var(--ease);
  will-change:transform;
}
.menu-panel.is-open{transform:translateX(0)}

.menu-inner{display:flex;flex-direction:column;min-height:100%;padding:22px 30px 34px}

/* top row: open/closed status pill on the left, close button on the right —
   both vertically centred on the row (no offset nudge on the close button). */
.menu-top{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:6px}
.menu-close{
  flex:none;width:46px;height:46px;margin:0 -8px 0 0;
  display:inline-flex;align-items:center;justify-content:center;
  background:none;border:0;border-radius:100px;color:var(--paper);cursor:pointer;
  transition:color .2s var(--ease),background .2s var(--ease);
}
.menu-close:hover{color:var(--amber);background:rgba(255,255,255,.05)}
.menu-close svg{width:22px;height:22px}

/* the header hamburger is a flex button but its glyph was top-aligned, leaving
   the icon sitting ~9px above the status pill's centre — centre it so the two
   line up. */
.nav-toggle{align-items:center;justify-content:center}
.nav-toggle svg{width:22px;height:22px}

/* each link is an equal-height slice that fills the space between the top row
   and the phone CTA, with a rule line above it — so the lines read as
   separators sitting midway between items. Text is centred in its slice. */
.menu-nav{flex:1;display:flex;flex-direction:column;margin:6px 0}
.menu-nav a{
  flex:1;display:flex;align-items:center;
  position:relative;font-family:var(--serif);font-size:clamp(2.07rem,7.65vw,2.79rem);
  line-height:1.02;color:var(--paper);
  border-top:1px solid rgba(255,240,222,.12);
  transition:color .2s var(--ease),padding-left .25s var(--ease);
}
.menu-nav a:first-child{border-top:0}
.menu-nav a::before{
  content:"";position:absolute;left:0;top:50%;width:0;height:2px;
  background:var(--amber);border-radius:2px;transform:translateY(-50%);
  box-shadow:0 0 10px rgba(255,182,74,.55);
  transition:width .25s var(--ease);
}
.menu-nav a:hover,.menu-nav a:focus-visible{color:var(--amber);padding-left:26px}
.menu-nav a:hover::before,.menu-nav a:focus-visible::before{width:18px}

.menu-foot{padding-top:20px;display:flex;flex-direction:column;gap:16px}
.menu-call{width:100%;justify-content:center;font-size:1.05rem}

body.menu-locked{overflow:hidden}

@media(prefers-reduced-motion:reduce){
  .menu-panel{transition:transform .001s linear}
  .menu-scrim{transition:opacity .2s linear,visibility .2s linear}
}

/* At ≤560 the section copy drops to a 22px gutter while the header stayed at
   40px — pull the wordmark + menu icon onto the same gutter so they line up
   with the hero/section copy below. (After the ≤860 rule so it wins.) */
@media(max-width:560px){
  .site-header .nav-wrap{padding-inline:22px}
}

/* 861–1120px: with the horizontal nav shown, the tools cluster is tight and
   the status pill + phone CTA were wrapping into blobs. Never let them wrap,
   and drop the (secondary) open/closed pill in this band so the phone CTA
   keeps its shape. Below 861 the hamburger takes over; above 1120 there's room
   and the pill returns. (The ≤640 rule already hides the pill on mobile.) */
.site-header .live,.site-header .nav-tools .btn{white-space:nowrap}
@media(min-width:861px) and (max-width:1120px){
  .site-header .live{display:none}
}
