/* MMI CPA — v7 "Portland" (version B: illustration)

   Same skeleton as v6, one difference that changes everything: the hero is a flat-color
   screen-print landscape instead of a drawn skyline, and every surface token in the page
   is sampled from that artwork. The illustration lives at low chroma (C ~ 0.035), so the
   old band green (C 0.068) would have fought it. These greens are the picture's greens.

   Saturation carries meaning here: surfaces stay at the artwork's chroma, and only
   interactive elements are allowed to lift above it. */

:root {
  /* --paper is WELDED to the artwork. It is the mean of the illustration's sky,
     measured, and the hero's flat ground has to be exactly it or the seam where
     the picture starts becomes visible. It is used by the hero and nothing else.
     Do not reuse it as a page colour: a landscape is allowed its own warm light,
     a page is not, and at hue 63 it was the only non-accent token sitting outside
     the 120-160 family every other surface in this palette lives in. */
  --paper: oklch(96.9% 0.016 63);

  /* --ground is the page. It never touches the artwork: the forest band always
     sits between the hero and the first section that uses it, so it is free to
     leave the artwork's hue behind and join the 130-160 family the rest of the
     palette lives in. Chroma stays at 0.008 so it reads as paper stock rather
     than as a tinted surface.
     The 2.6 points of lightness between this and --paper-raised are deliberate:
     that gap is what makes the cards read as cards. A near-white ground closes
     it to 1.3 and leaves the border doing all the work. */
  --ground: oklch(96% 0.008 130);
  --paper-raised: oklch(98.6% 0.004 130);  /* cards, lifted off the ground */
  --mist: oklch(80.3% 0.026 140);        /* the far ridge behind the city */
  --sage: oklch(92% 0.018 145);
  --ridge: oklch(52.9% 0.036 153);
  --forest-mid: oklch(38.4% 0.033 159);
  --forest: oklch(31% 0.035 159);        /* the deepest firs, and every dark band */

  --ink: oklch(25% 0.03 158);
  --ink-soft: oklch(46% 0.028 156);
  --on-forest: oklch(90% 0.02 130);
  --on-forest-strong: oklch(97% 0.012 125);

  /* Lifted above the artwork on purpose. Every surface in this page sits at the
     illustration's own chroma (C ~ 0.035); these do not, and that gap is what makes
     them read as things you can act on instead of scenery.
     The gold is carried over from v1 and it only ever lands on the dark bands:
     measured 5.1:1 on forest and 6.8:1 on the footer, both past AA. */
  --green: oklch(45% 0.075 155);
  --green-deep: oklch(36% 0.07 156);
  /* Two golds, same hue family, because one cannot do both jobs. The bright one
     needs a dark band under it: on cream it measures 2.3:1 and disappears.
     gold-ink is the same accent taken down to where it holds on light surfaces. */
  --gold: oklch(72% 0.12 78);
  --gold-ink: oklch(52% 0.125 68);

  --line: oklch(89% 0.012 120);
  --line-strong: oklch(80% 0.016 130);

  --display: "Archivo", -apple-system, sans-serif;
  --font: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;

  --step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.9rem);
  --step-0: clamp(1rem, 0.95rem + 0.24vw, 1.13rem);
  --step-1: clamp(1.2rem, 1.08rem + 0.6vw, 1.55rem);
  --step-2: clamp(1.55rem, 1.3rem + 1.25vw, 2.3rem);
  --step-3: clamp(2rem, 1.6rem + 2.1vw, 3.15rem);
  --step-4: clamp(2.7rem, 2rem + 3.6vw, 4.8rem);

  --space-section: clamp(4.25rem, 3.2rem + 5vw, 8rem);
  --pad: clamp(1.25rem, 4vw, 3rem);
  --shell: 82rem;
  --measure: 64ch;
  --radius: 14px;
  --nav-h: 4.1rem;

  /* The artwork's geometry, measured from the file, not chosen by eye.
     Its height is derived from its own ratio so it is always shown whole:
     a fixed height plus `cover` was cropping the fir tops and Mount Hood.

     --art-sky is the flat-sky slice above the artwork's first painted pixel,
     and it is measured on the LEFT HALF only (row 88 of 1036), because that
     is where the copy lives. Measuring it across the full width picks up
     whichever framing fir is tallest anywhere, which parked the buttons in
     mid-air above the left crown with a band of dead cream under them.
     The copy is allowed to sit over this slice. Nothing sits over the rest. */
  --art-ratio: 3072 / 1036;
  --art-h: calc(100vw / 2.9653);
  --art-sky: 0.0849;
  --art-solid-h: calc(var(--art-h) * (1 - var(--art-sky)));
}

* { box-sizing: border-box; margin: 0; }
html { scroll-behavior: smooth; }

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 { font-family: var(--display); font-weight: 800; line-height: 1.05; letter-spacing: -0.025em; }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); font-weight: 700; }

a { color: inherit; }

/* ---------- Nav ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.2rem);
  height: var(--nav-h);
  padding: 0 var(--pad);
  /* Transparent at rest. The nav is the one element that sits over BOTH grounds,
     and now that the page ground left the artwork's hue behind, painting it the
     page colour put a 12-level seam across the top of the hero. 12 levels against
     a hard border is well past what the eye ignores.
     So at scroll 0 it paints nothing and the hero runs full bleed under it. The
     moment anything starts moving underneath, it becomes a surface, which is when
     a surface is what it actually needs to be. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 200ms ease, border-color 200ms ease;
}
.nav.stuck {
  background: color-mix(in oklch, var(--ground) 90%, transparent);
  backdrop-filter: saturate(1.1) blur(8px);
  border-bottom-color: var(--line);
}
@media (prefers-reduced-motion: reduce) { .nav { transition: none; } }
.wordmark { font-family: var(--display); font-weight: 800; font-size: 1.3rem; letter-spacing: -0.02em; text-decoration: none; }
.nav-links { display: flex; gap: clamp(0.9rem, 2.5vw, 1.7rem); margin-left: auto; }
.nav-links a { text-decoration: none; font-weight: 600; font-size: 0.94rem; color: var(--ink-soft); transition: color 160ms ease; }
.nav-links a:hover { color: var(--green-deep); }

/* ---------- Buttons ---------- */

.btn { display: inline-block; font-weight: 600; font-family: var(--font); text-decoration: none; padding: 0.9rem 1.6rem; border-radius: 10px; transition: background-color 200ms cubic-bezier(0.22,1,0.36,1), border-color 200ms ease, color 200ms ease, transform 200ms cubic-bezier(0.22,1,0.36,1); }
.btn-primary { background: var(--ink); color: var(--paper-raised); }
.btn-primary:hover { background: var(--green-deep); transform: translateY(-1px); }
.btn-ghost { border: 1.5px solid var(--line-strong); color: var(--ink); background: color-mix(in oklch, var(--ground) 70%, transparent); }
.btn-ghost:hover { border-color: var(--green); color: var(--green-deep); }
.nav-cta { padding: 0.55rem 1.15rem; font-size: 0.92rem; white-space: nowrap; background: var(--green); color: var(--paper-raised); border-radius: 10px; }
.nav-cta:hover { background: var(--green-deep); }
@media (max-width: 560px) { .nav-links { display: none; } .nav-cta { margin-left: auto; } }

/* ---------- Hero (illustration at the foot) ---------- */

.hero {
  position: relative;
  /* A floor and a ceiling, and they are two different problems.
     Floor: never shorter than the artwork, or `overflow: hidden` clips its top
     back off on wide, short viewports.
     Ceiling: filling the first screen is worth doing, but only up to a point.
     With the copy pinned to the treeline (see flex-end below) every extra pixel
     of viewport height turns into empty sky ABOVE the headline, and on a tall
     narrow window that is a void: at 1067x1345 it was ~500px of nothing.
     1.9 sits above every ratio a real desktop hits (1920x1080 is 1.57, 1440x900
     is 1.72), so the cap never touches those and only bites on portrait-ish
     windows, where it hands the height back to the content. */
  min-height: max(calc(var(--art-h) + 11rem),
                  min(calc(100svh - var(--nav-h)), calc(var(--art-h) * 1.9)));
  display: flex;
  flex-direction: column;
  /* flex-end, not center. The copy's distance to the treeline is the one
     relationship that has to hold at every width, and centring made it a
     function of viewport HEIGHT: on a tall narrow window the content box
     overflowed the copy and floated it up off the artwork. Pinning the copy
     to the foot of its box makes that distance a constant (the 1.5rem below),
     and sends the leftover slack to the top, where it is just more sky. */
  justify-content: flex-end;
  /* Reserve only the artwork's solid part. The copy is meant to land on the sky. */
  padding: clamp(1.75rem, 1.25rem + 2.5vw, 3.5rem) var(--pad) calc(var(--art-solid-h) + 1.5rem);
  overflow: hidden;
  background: var(--paper);
}
.hero-inner { max-width: var(--shell); margin: 0 auto; width: 100%; position: relative; z-index: 1; }
/* 24ch, not 15ch: each sentence has to hold its own line. Below that the headline
   breaks into four lines and eats the fold the artwork is supposed to sit in. */
.hero h1 { font-size: var(--step-4); max-width: 24ch; text-wrap: balance; }
.hero h1 em { font-style: normal; color: var(--green); }
.hero-sub { font-family: var(--font); margin-top: 1.6rem; font-size: var(--step-1); line-height: 1.45; color: var(--ink-soft); max-width: 52ch; text-wrap: pretty; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 2.3rem; }

/* The box carries the artwork's own aspect ratio, so `100% 100%` fills it with
   zero crop and zero distortion at any width. The join at the top still never
   shows, not because the crop hides it, but because --paper is sampled from
   this file's own sky: the first painted row and the page are the same colour. */
.hero-art {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  aspect-ratio: var(--art-ratio);
  /* Plain url() first as the floor, then image-set for anything that can pick.
     2400 covers a 1x desktop; 3072 is what a 2dppx desktop actually asks for. */
  background-image: url("../assets/portland-v2-2400.webp");
  background-image: image-set(url("../assets/portland-v2-2400.webp") 1x,
                              url("../assets/portland-v2-3072.webp") 2x);
  background-size: 100% 100%;
  background-position: bottom center;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* The artwork's own haze, continued past its edge. Its bottom row runs from deep fir at
   the margins to mid ridge in the centre, so it cannot butt flat against the band below.
   This is the one gradient in the page and it exists to finish the picture, not decorate. */
.hero-art::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: clamp(56px, 9vw, 130px);
  background: linear-gradient(to bottom, oklch(31% 0.035 159 / 0), var(--forest));
}

/* 1280 already covers this branch at any density (620px at 2dppx is 1240),
   so there is nothing for image-set to choose between here. */
@media (max-width: 620px) {
  .hero-art { background-image: url("../assets/portland-v2-1280.webp"); }
}

/* ---------- Fold 2 (forest band + data panel) ---------- */

.fold2 { background: var(--forest); color: var(--on-forest); }
.fold2-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: clamp(2.5rem, 2rem + 3vw, 4.5rem) var(--pad) clamp(3.5rem, 3rem + 4vw, 6rem);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4.5vw, 4.5rem);
  align-items: center;
}
.fold2-copy h2 { color: var(--on-forest-strong); max-width: 16ch; }
.fold2-copy p { font-family: var(--font); margin-top: 1.4rem; line-height: 1.65; max-width: 44ch; }
.fold2-cta { font-family: var(--font); display: inline-block; margin-top: 1.6rem; font-weight: 600; text-decoration: none; color: var(--on-forest-strong); border-bottom: 2px solid var(--gold); padding-bottom: 3px; }
.fold2-cta:hover { color: var(--gold); }
@media (max-width: 860px) { .fold2-inner { grid-template-columns: 1fr; } }

/* Data panel */
.panel { background: var(--paper-raised); border-radius: 18px; padding: clamp(1.5rem, 3vw, 2.1rem); box-shadow: 0 30px 60px -34px oklch(18% 0.03 158 / 0.65); font-variant-numeric: tabular-nums; color: var(--ink); }
.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.panel-title { font-family: var(--display); font-weight: 700; font-size: 1.05rem; letter-spacing: -0.01em; }
.panel-tag { font-size: 0.8rem; color: var(--ink-soft); font-weight: 600; }
.panel-figure { display: flex; align-items: baseline; gap: 0.8rem; margin-top: 1.1rem; flex-wrap: wrap; }
.panel-big { font-family: var(--display); font-weight: 800; font-size: clamp(2.4rem, 1.8rem + 2.6vw, 3.3rem); letter-spacing: -0.03em; line-height: 1; }
.panel-delta { font-weight: 700; color: var(--green-deep); font-size: 0.95rem; }
.panel-delta span { color: var(--ink-soft); font-weight: 600; }
.panel-chart { margin-top: 1.4rem; }
.panel-chart svg { width: 100%; height: clamp(88px, 14vw, 120px); display: block; }
.panel-chart .bar { fill: var(--mist); }
.panel-chart .bar-hi { fill: var(--green); }
.panel-chart .axis { stroke: var(--line-strong); stroke-width: 1; }

/* The panel used to arrive whole, chart and all, which made the one section
   that is about reading numbers over time feel like a screenshot.
   Now the bars grow off the axis when the panel comes into view, left to right.
   `transform-box: fill-box` is what makes `transform-origin: bottom` mean the
   bottom of each rect instead of the bottom of the whole SVG viewport.
   The per-bar delay is set in JS so the stagger stays in step with the data. */
.panel-chart .bar {
  transform: scaleY(0);
  transform-origin: bottom;
  transform-box: fill-box;
  transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
}
.panel.in .panel-chart .bar { transform: scaleY(1); }

/* The copy leads, the panel follows a beat later. Reading order, not decoration. */
.fold2 .panel { transition-delay: 130ms; }
.panel-stats > div, .panel-note {
  opacity: 0;
  transition: opacity 500ms ease 420ms;
}
.panel.in .panel-stats > div, .panel.in .panel-note { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .panel-chart .bar { transform: none; transition: none; }
  .fold2 .panel { transition-delay: 0s; }
  .panel-stats > div, .panel-note { opacity: 1; transition: none; }
}
.panel-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 1.5rem; padding-top: 1.3rem; border-top: 1px solid var(--line); }
.panel-stats dt { font-size: 0.78rem; color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.panel-stats dd { font-family: var(--display); font-weight: 700; font-size: 0.98rem; margin-top: 0.3rem; }
.panel-note { margin-top: 1.3rem; font-size: 0.82rem; color: var(--ink-soft); }

/* ---------- Moments (sage band, and it routes) ----------

   This used to be four bordered sentences on the same cream as the section
   under it, which is exactly why it read as filler: it looked like services
   without doing anything. Two changes give it a job.
   1. Its own surface, so it stops being a pale copy of what follows.
   2. Every card hands off to the service that answers it. The section turns
      "this is my week" into "then this is the thing you need", which is the
      one move a landing page owes a visitor who has not self-diagnosed yet. */

/* No surface of its own and no margin: it butts straight against the forest band
   above, the same join the services section already uses. The band edge is what
   separates it now, so it does not need a colour to stop reading as filler.
   Its job (routing each call to a service) is doing that work instead. */
.moments { margin-top: 0; }
/* No bottom padding on purpose. While this had its own surface it needed to close
   itself off; now that it shares the page ground with what follows, the section
   rhythm below (services' own top margin) is the only gap there should be. Keeping
   both stacked 208px of dead cream between the cards and the next heading. */
.moments-inner { max-width: var(--shell); margin: 0 auto; padding: clamp(3.25rem, 2.75rem + 3vw, 5.5rem) var(--pad) 0; }
.moments-deck { font-family: var(--font); margin-top: 1.1rem; max-width: 54ch; color: var(--ink-soft); }
.moments-grid { margin-top: 2.4rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }

.moment {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1.15rem;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem 1.6rem 1.25rem;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 200ms ease, transform 200ms cubic-bezier(0.22,1,0.36,1), box-shadow 200ms ease;
}
.moment-line { font-weight: 600; font-size: 1.04rem; line-height: 1.42; }
.moment-tag {
  font-family: var(--font);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--gold-ink);
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}
.moment:hover { border-color: var(--gold-ink); transform: translateY(-2px); box-shadow: 0 16px 30px -22px oklch(25% 0.03 158 / 0.55); }
.moment:hover .arw { transform: translateX(3px); }

/* Shared with the service CTAs: the arrow is the one thing that moves. */
.arw { display: inline-block; transition: transform 200ms cubic-bezier(0.22,1,0.36,1); }
@media (prefers-reduced-motion: reduce) { .arw, .moment { transition: none; } }

/* ---------- Services ---------- */

.services { max-width: var(--shell); margin: var(--space-section) auto 0; padding: 0 var(--pad) var(--space-section); }
.stream { padding: clamp(1.9rem, 3.5vw, 2.8rem) 0; border-bottom: 1px solid var(--line); }
.stream:first-of-type { margin-top: 2rem; border-top: 2px solid var(--line-strong); }
.stream-body { max-width: 62rem; }
.stream-body p { font-family: var(--font); margin-top: 0.75rem; color: var(--ink-soft); max-width: var(--measure); }
/* The arrow carries the accent full time; the words only take it on hover.
   That way the gold marks where the links are before you go hunting for one,
   and the hover still has somewhere to go. */
.stream-cta { font-family: var(--font); display: inline-block; margin-top: 1.1rem; font-weight: 600; text-decoration: none; color: var(--green-deep); transition: color 180ms ease; }
.stream-cta .arw { color: var(--gold-ink); }
.stream-cta:hover { color: var(--gold-ink); text-decoration: underline; text-decoration-color: var(--gold-ink); text-decoration-thickness: 2px; text-underline-offset: 4px; }
.stream-cta:hover .arw { transform: translateX(3px); }

/* ---------- Differentiator (forest band) ---------- */

.every-dollar { background: var(--forest); color: var(--on-forest); }
.dollar-inner { max-width: var(--shell); margin: 0 auto; padding: clamp(2rem, 2rem + 2vw, 4rem) var(--pad) clamp(3.5rem, 3rem + 4vw, 6.5rem); display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.dollar-copy h2 { max-width: 18ch; color: var(--on-forest-strong); }
.dollar-copy p { font-family: var(--font); margin-top: 1.5rem; line-height: 1.7; max-width: 52ch; }
.dollar-viz { display: grid; gap: clamp(1.25rem, 2vw, 2rem); align-content: center; }
.viz-block { min-width: 0; background: var(--forest-mid); border: 1px solid oklch(45% 0.03 157); border-radius: var(--radius); padding: clamp(1rem, 2vw, 1.5rem); }
.viz-block svg { width: 100%; height: auto; display: block; }
.viz-block figcaption { font-family: var(--font); margin-top: 1rem; font-size: 0.85rem; font-weight: 600; color: oklch(80% 0.025 140); }
.dot { fill: oklch(48% 0.03 157); }
.dot.lit { fill: var(--gold); }
@media (max-width: 800px) { .dollar-inner { grid-template-columns: 1fr; } .dollar-viz { grid-template-columns: 1fr 1fr; max-width: 34rem; } }

/* ---------- Trust (sage, one quiet line) ---------- */

.trust { background: var(--sage); }
.trust p { max-width: 54rem; margin: 0 auto; padding: clamp(3rem, 2.5rem + 3vw, 5rem) var(--pad); font-family: var(--display); font-weight: 700; font-size: var(--step-2); line-height: 1.3; letter-spacing: -0.02em; color: var(--forest); text-align: center; }

/* ---------- About ---------- */

.about { max-width: var(--shell); margin: var(--space-section) auto 0; padding: 0 var(--pad); display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: clamp(2.5rem, 5vw, 5.5rem); align-items: start; }
.about-copy p { font-family: var(--font); margin-top: 1.3rem; max-width: var(--measure); color: var(--ink-soft); }
.about-copy p:first-of-type { margin-top: 2rem; }
.about-molly { font-weight: 600; color: var(--ink) !important; background: var(--sage); border-radius: var(--radius); padding: 1.3rem 1.5rem; }
/* height:auto is load-bearing. The width/height attributes on the img are a
   presentational hint, and with both of them resolved the browser ignores
   aspect-ratio and renders the raw 1200px. */
.about-photo img { width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius); display: block; }
.about-photo figcaption { font-family: var(--font); margin-top: 0.7rem; font-size: 0.88rem; color: var(--ink-soft); }
@media (max-width: 800px) { .about { grid-template-columns: 1fr; } .about-photo { max-width: 24rem; } }

/* ---------- How ---------- */

.how { max-width: var(--shell); margin: var(--space-section) auto 0; padding: 0 var(--pad); }
.steps { margin-top: 2.2rem; padding-left: 0; list-style: none; counter-reset: step; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: clamp(1.5rem, 3vw, 3rem); }
.steps li { counter-increment: step; color: var(--ink-soft); max-width: 38ch; font-family: var(--font); }
.steps li::before { content: counter(step, decimal-leading-zero); display: block; font-family: var(--display); font-weight: 800; font-size: 1.5rem; color: var(--green); margin-bottom: 0.5rem; font-variant-numeric: tabular-nums; }
.steps strong { color: var(--ink); }

/* ---------- FAQ ---------- */

.faq { max-width: 52rem; margin: var(--space-section) auto 0; padding: 0 var(--pad); }
.faq details { border-bottom: 1px solid var(--line); }
.faq details:first-of-type { margin-top: 2rem; border-top: 2px solid var(--line-strong); }
.faq summary { cursor: pointer; font-family: var(--display); font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; padding: 1.3rem 2.5rem 1.3rem 0; list-style: none; position: relative; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; position: absolute; right: 0.3rem; top: 1.15rem; font-family: var(--font); font-weight: 400; font-size: 1.5rem; color: var(--green); transition: transform 220ms cubic-bezier(0.22,1,0.36,1); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq-body { padding: 0 0 1.4rem; }
.faq-body p { font-family: var(--font); color: var(--ink-soft); max-width: var(--measure); }

/* Opening a <details> is a hard cut by default. Two layers here, and only one
   of them ever runs.
   Baseline everywhere: the answer fades and slides in. The box still snaps.
   Where the browser can interpolate to `auto`, the panel actually slides open
   and the fade is turned off so the two do not stack. */
@keyframes faq-in {
  from { opacity: 0; translate: 0 -6px; }
  to   { opacity: 1; translate: 0 0; }
}
.faq details[open] .faq-body { animation: faq-in 240ms cubic-bezier(0.22, 1, 0.36, 1); }

@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .faq details::details-content {
    height: 0;
    overflow: hidden;
    transition: height 300ms cubic-bezier(0.22, 1, 0.36, 1),
                content-visibility 300ms allow-discrete;
  }
  .faq details[open]::details-content { height: auto; }
  .faq details[open] .faq-body { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .faq details[open] .faq-body { animation: none; }
  .faq details::details-content { transition: none; }
}

/* ---------- Contact (forest band) ---------- */

.contact { margin-top: var(--space-section); background: var(--forest); color: var(--on-forest); }
.contact-inner { max-width: 52rem; margin: 0 auto; padding: clamp(3.5rem, 3rem + 4vw, 6.5rem) var(--pad); text-align: center; }
.contact h2 { color: var(--on-forest-strong); }
.contact-lede { font-family: var(--font); margin-top: 1rem; }
.contact-phone { font-family: var(--display); display: inline-block; margin-top: 1.9rem; font-weight: 800; font-size: var(--step-3); letter-spacing: -0.02em; text-decoration: none; color: var(--on-forest-strong); font-variant-numeric: tabular-nums; }
.contact-phone:hover { color: var(--gold); }
.contact-alt { font-family: var(--font); margin-top: 1.3rem; font-size: 0.95rem; }
.contact-alt a { color: var(--gold); font-weight: 600; }

/* ---------- Footer ---------- */

.footer { background: oklch(22% 0.026 158); color: oklch(80% 0.018 135); padding: clamp(3rem, 2.5rem + 2vw, 4.5rem) var(--pad) 2.5rem; font-size: 0.95rem; }
.footer-grid { max-width: var(--shell); margin: 0 auto; display: grid; grid-template-columns: 2fr 1fr 1fr; gap: clamp(2rem, 4vw, 4rem); }
.wordmark-footer { font-family: var(--display); font-weight: 800; font-size: 1.3rem; color: oklch(96% 0.012 128); }
.footer-tag { margin-top: 0.6rem; max-width: 24ch; }
.footer-head { font-weight: 800; font-size: 0.8rem; letter-spacing: 0.08em; text-transform: uppercase; color: oklch(96% 0.012 128); margin-bottom: 1rem; }
.footer-col a { display: block; text-decoration: none; margin-top: 0.55rem; }
.footer-col a:hover { color: var(--gold); }
.footer-col p { margin-top: 0.55rem; }
.footer-fine { max-width: var(--shell); margin: 3rem auto 0; padding-top: 1.5rem; border-top: 1px solid oklch(35% 0.025 158); font-size: 0.85rem; color: oklch(66% 0.018 135); }
@media (max-width: 700px) { .footer-grid { grid-template-columns: 1fr; } }

/* ---------- Reveal motion ---------- */

.reveal { opacity: 0; translate: 0 24px; transition: opacity 700ms cubic-bezier(0.22,1,0.36,1), translate 700ms cubic-bezier(0.22,1,0.36,1); }
.reveal.in { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .reveal { opacity: 1; translate: 0 0; transition: none; } .btn, .nav-links a { transition: none; } }
