/* ==========================================================================
   Theme layer — color, gradient, glow, grain.

   Sits ON TOP of site.css and changes only surface treatment. Every layout
   value, type size, and piece of copy stays exactly as the team delivered it.
   Delete this one <link> and the site returns to the flat original.

   Technique is lifted from beehiiv.com, which turns out to share this site's
   DNA already: same Satoshi typeface, same #060419 base, same #4e4e6c hairline.
   What it adds is an effects layer — blurred color blobs and a grain overlay.
   Notably it uses NO box-shadows; depth comes from glow and hairline alone,
   and its buttons are flat white. Same discipline is kept here.

   COLOR LIVES IN THE BACKGROUND, NOT IN THE FILLS. The ambient wash behind
   each section does the work; buttons, borders, rules, and figures are solid.
   Gradient fill survives in exactly one place — a single phrase in each page's
   hero headline (.grad-text). If you want even that gone, delete the two
   class="grad-text" spans in index.html and pricing.html; nothing else
   depends on them.

   The palette is a dawn ramp — indigo #7c6cf0 through orchid to coral #ff9b6a —
   rather than beehiiv's hot pink, which would read wrong for this subject.
   ========================================================================== */

:root {
  /* Dawn ramp ------------------------------------------------------------ */
  --dawn-1: #7c6cf0;  /* indigo   — night end   */
  --dawn-2: #a86ee0;  /* violet                 */
  --dawn-3: #d96fb8;  /* orchid                 */
  --dawn-4: #ff9b6a;  /* coral    — first light */

  /* Official Mission Grant logo gradient (assets/logo/README.md). Near-
     identical to the dawn ramp above, which was derived independently —
     #F9976A and #ff9b6a are within a hair. Kept as its own token so the
     mark can be rendered in true brand colour wherever that is wanted. */
  --brand-1: #A78BFA;
  --brand-2: #EC8CC0;
  --brand-3: #F9976A;
  --grad-brand: linear-gradient(135deg, var(--brand-1), var(--brand-2) 50%, var(--brand-3));

  --accent-cool: #7c6cf0;
  --accent-warm: #ff9b6a;
  /* Deeper indigo for anything carrying white text: #7c6cf0 only reaches
     3.99:1 against white, which fails AA for small type. */
  --accent-deep: #6a58e0;

  /* The one remaining gradient fill, used on a single phrase per page hero. */
  --grad-text:  linear-gradient(100deg, var(--accent) 0%, #cfa8ee 45%, var(--dawn-4) 100%);

  /* Surfaces — one step deeper than site.css, beehiiv's layering ---------- */
  --surface-1: #0d0b28;
  --surface-2: #1c1940;
  /* The quiet half of the page rhythm: washed section, near-black band,
     washed section, near-black band. Translucent on purpose — a whisper of
     the body wash showing through keeps bands from going dead flat, while
     staying black-ish rather than blue. (An opaque #131039 was tried here
     and read as a heavy blue block — do not go back to it.) */
  --band-quiet: rgba(11, 9, 33, 0.66);

  /* --text-muted (#9393a9) is tuned for the near-black page. On the light
     panel it only reaches 2.8:1, which fails AA. Same role, re-derived
     against a near-white ground: 6.19:1. */
  --ink-muted: #5c5a72;

  /* Muted text sitting over a photograph. --text-muted (#9393a9) is fine on
     the flat page but only reaches 3.67:1 against the brightest pixel a 0.80
     scrim can produce. This holds 5.16:1 there and is still visibly dimmer
     than --text-soft, so the type hierarchy survives the fix. */
  --text-muted-photo: #b0b0c2;

  /* Timeline steps, sampled along the dawn ramp so the sequence reads night ->
     first light across Week 1 -> Ongoing. Each is a SOLID colour, not a
     gradient fill — the "colour lives in the background" rule below still
     holds; what progresses is which solid each step gets.

     Two values per step. The base is for node fills, rules, and rail segments
     (non-text, where the 3:1 UI threshold applies and all five clear it). The
     -t variant is the same hue lifted 22% toward white for TEXT, because the
     raw #7c6cf0 lands at exactly 4.50:1 on the card — technically AA and far
     too close to the line to rely on. The -t values run 6.34-10.19. */
  --tl-1: #7c6cf0;  --tl-1-t: #998cf3;
  --tl-2: #9d6ee4;  --tl-2-t: #b38eea;
  --tl-3: #c06ecc;  --tl-3-t: #ce8ed7;
  --tl-4: #e27aa4;  --tl-4-t: #e997b8;
  --tl-5: #ff9b6a;  --tl-5-t: #ffb18b;

  /* Hairlines — white alphas read better over glow than a flat hex ------- */
  --border-soft: rgba(255, 255, 255, 0.07);
  --border-lit:  rgba(255, 255, 255, 0.14);
}

/* --------------------------------------------------------------------------
   Page ground — a deep indigo wash instead of flat black, plus grain.
   -------------------------------------------------------------------------- */
body {
  background:
    radial-gradient(1200px 700px at 78% -8%,  rgba(124, 108, 240, 0.16), transparent 62%),
    radial-gradient(900px  600px at 8%  12%,  rgba(217, 111, 184, 0.10), transparent 60%),
    radial-gradient(800px  500px at 92% 42%,  rgba(255, 155, 106, 0.07), transparent 60%),
    #05030f;
  background-attachment: fixed;
}

/* feTurbulence grain, tiled at 296px and blended soft-light. beehiiv runs
   this at 0.6; dialled back here so body copy stays crisp. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.32;
  mix-blend-mode: soft-light;
  background-size: 296px 296px;
  background-image: url("data:image/svg+xml,<svg viewBox='0 0 296 296' width='296' height='296' xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* --------------------------------------------------------------------------
   Glow blobs — the load-bearing effect. Absolutely positioned, heavily
   blurred, never interactive. Parent section needs .lit.
   -------------------------------------------------------------------------- */
.lit { position: relative; isolation: isolate; overflow: hidden; }
.lit > *:not(.glow) { position: relative; z-index: 1; }

/* Coverage layer. Percentage-positioned radial gradients on inset:0, so this
   always spans the whole section at every viewport and aspect ratio — no blur
   radius to run out of, no bare corners. The .glow accents below sit on top
   of this and add local intensity; this is what guarantees the floor. */
.lit::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    /* Base coat FIRST: a linear tint that by definition reaches every pixel,
       so there is no bare corner where the radials have faded out. The
       radials sit on top and only shape where the colour concentrates. */
    linear-gradient(165deg, rgba(124, 108, 240, 0.07) 0%, rgba(217, 111, 184, 0.045) 48%, rgba(255, 155, 106, 0.045) 100%),
    radial-gradient(78% 92% at 88%  6%, rgba(124, 108, 240, 0.13), transparent 75%),
    radial-gradient(72% 88% at  6% 94%, rgba(255, 155, 106, 0.08), transparent 75%);
}

/* Colour hierarchy: the page-top hero is the ONLY place the wash runs at
   full strength. Mid-page washes stay at the quiet default above so the
   hero keeps its impact and body copy sits on near-calm ground. */
.hero-band.lit::before,
.pricing-hero.lit::before {
  background:
    linear-gradient(165deg, rgba(124, 108, 240, 0.13) 0%, rgba(217, 111, 184, 0.08) 48%, rgba(255, 155, 106, 0.08) 100%),
    radial-gradient(78% 92% at 88%  6%, rgba(124, 108, 240, 0.22), transparent 75%),
    radial-gradient(72% 88% at  6% 94%, rgba(255, 155, 106, 0.13), transparent 75%);
}

/* Accent blobs. Sized in vw with clamp() so they scale with the device
   instead of sitting at one fixed pixel size, and offset in vw so the bleed
   past the section edge stays proportional too. */
.glow {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  border-radius: 9999px;
  filter: blur(clamp(52px, 6vw, 104px));
  opacity: 0.34;
  width:  clamp(300px, 58vw, 840px);
  height: clamp(260px, 42vw, 620px);
}
.hero-band .glow,
.pricing-hero .glow { opacity: 0.5; }
.glow--cool  { background: radial-gradient(circle, rgba(124, 108, 240, 0.85), transparent 70%); }
.glow--warm  { background: radial-gradient(circle, rgba(255, 155, 106, 0.60), transparent 70%); }
.glow--rose  { background: radial-gradient(circle, rgba(217, 111, 184, 0.60), transparent 70%); }

.glow--tr { top:    -12vw; right: -8vw; }
.glow--tl { top:    -13vw; left:  -9vw; }
.glow--br { bottom: -13vw; right: -7vw; }
.glow--bl { bottom: -12vw; left:  -8vw; }
.glow--c  {
  top: 2vw; left: 50%; transform: translateX(-50%);
  width: clamp(340px, 78vw, 1020px);
  opacity: 0.34;
}

/* --------------------------------------------------------------------------
   Gradient text — the only gradient fill left on the site. One phrase, in one
   headline, on each page. Deliberately not used anywhere else.
   -------------------------------------------------------------------------- */
.grad-text {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* --------------------------------------------------------------------------
   Surfaces
   -------------------------------------------------------------------------- */
.card,
.card--plain,
.qa,
.plan {
  background:
    /* 5% -> 1.2% white sheen. Reads as a top-light on the card, not as a
       gradient; it is what gives surfaces depth with no box-shadow. Swap for
       a flat rgba(255,255,255,0.03) if you want it gone entirely. */
    linear-gradient(160deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.012)),
    var(--surface-1);
  border-color: var(--border-soft);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: border-color 220ms ease, transform 220ms ease, background 220ms ease;
}

.card--hollow { border-color: var(--border-soft); transition: border-color 220ms ease, transform 220ms ease; }

.card:hover,
.card--plain:hover,
.card--hollow:hover,
.qa:hover { border-color: var(--border-lit); transform: translateY(-2px); }

/* Pills are labels, not controls. They used to take a hover treatment, which
   invited a click that goes nowhere; instead they drift, so the row reads as
   alive rather than interactive. Transform-only, so it composites on the GPU,
   and the global prefers-reduced-motion rule in site.css already stops it. */
.pill {
  border-color: var(--border-soft);
  cursor: default;
  animation: pill-drift 6s ease-in-out infinite alternate;
}

@keyframes pill-drift {
  from { transform: translateY(4px) rotate(-0.4deg); }
  to   { transform: translateY(-5px) rotate(0.4deg); }
}

/* Negative delays start every pill mid-cycle so nothing waits to begin, and
   the durations are deliberately mismatched — a 7-step cycle against rows of
   8 and 10 keeps them from ever settling into one visible wave. */
.pill:nth-child(7n+1) { animation-duration: 5.4s; animation-delay: -0.3s; }
.pill:nth-child(7n+2) { animation-duration: 6.6s; animation-delay: -2.4s; }
.pill:nth-child(7n+3) { animation-duration: 5.9s; animation-delay: -1.1s; }
.pill:nth-child(7n+4) { animation-duration: 7.1s; animation-delay: -3.2s; }
.pill:nth-child(7n+5) { animation-duration: 6.2s; animation-delay: -0.8s; }
.pill:nth-child(7n+6) { animation-duration: 5.6s; animation-delay: -2.9s; }
.pill:nth-child(7n+7) { animation-duration: 6.9s; animation-delay: -1.7s; }
.pill--solid {
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02)), var(--surface-2);
  border: 1px solid var(--border-soft);
}

/* Solid accent hairline. A real border rather than a masked pseudo-element,
   which also means nothing overlapping a card edge has to out-stack it. */
.card--accent  { border-color: var(--accent-cool); }
.plan--featured { border-color: var(--accent-cool); }

.hero__badge {
  border-color: var(--accent-cool);
  background: rgba(124, 108, 240, 0.10);
  color: var(--text-soft);
}

/* --------------------------------------------------------------------------
   Bands — the QUIET half of the alternating rhythm. Gradient washes (.lit)
   and near-black bands alternate down the page: colour, rest, colour, rest.
   A band never carries a wash; two washes never sit next to each other.
   -------------------------------------------------------------------------- */
.band {
  background: var(--band-quiet);
  border-top-color: var(--border-soft);
  border-bottom-color: var(--border-soft);
}

.nav {
  border-bottom-color: var(--border-soft);
}
/* Follows the glass onto the pseudo-element — see the note in site.css. */
.nav::before { background: rgba(5, 3, 15, 0.72); }

/* --------------------------------------------------------------------------
   Buttons — solid, as in the original design and as beehiiv does it
   -------------------------------------------------------------------------- */
.btn--primary { background: var(--text); color: #0b0820; border: 0; }
.btn--primary:hover { opacity: 1; filter: brightness(0.94); }

.btn--ghost { border-color: var(--border-lit); background: rgba(255, 255, 255, 0.03); }
.btn--ghost:hover { opacity: 1; background: rgba(255, 255, 255, 0.07); border-color: var(--accent); }

.btn--ink { background: var(--ink); color: var(--text); }

/* --------------------------------------------------------------------------
   Steps — solid accent rule
   -------------------------------------------------------------------------- */
/* Timeline ---------------------------------------------------------------- */
.tl__step:nth-child(1) { --step: var(--tl-1); --step-t: var(--tl-1-t); }
.tl__step:nth-child(2) { --step: var(--tl-2); --step-t: var(--tl-2-t); }
.tl__step:nth-child(3) { --step: var(--tl-3); --step-t: var(--tl-3-t); }
.tl__step:nth-child(4) { --step: var(--tl-4); --step-t: var(--tl-4-t); }
.tl__step:nth-child(5) { --step: var(--tl-5); --step-t: var(--tl-5-t); }

/* Solid fill, dark numeral. White on these hues tops out at 3.99:1 and fails;
   the ink reads 5.06-9.77 across the ramp. */
.tl__node {
  background: var(--step);
  border-color: transparent;
}
.tl__num { color: var(--ink); }

/* Halo ring. beehiiv's no-box-shadow discipline applies here too, so this is a
   real ring element rather than a spread shadow. */
.tl__node::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--step);
  opacity: 0.32;
  transition: opacity 200ms ease, transform 200ms ease;
}

/* Each segment takes the colour of the step it LEAVES, so the rail carries the
   progression while every individual segment stays one solid colour. */
.tl__step::before { background: var(--step); opacity: 0.45; }

.tl__card {
  background: rgba(255, 255, 255, 0.045);
  border-color: var(--border-soft);
}
.tl__when { color: var(--step-t); background: rgba(255, 255, 255, 0.06); }

/* Accent edge, colour half. The width lives in site.css per orientation; both
   halves have to be here or theme's border-color shorthand overwrites it. */
@media (min-width: 1025px) { .tl__card { border-top-color: var(--step); } }
@media (max-width: 1024px) { .tl__card { border-left-color: var(--step); } }

.tl__step:hover .tl__card,
.tl__step:focus-within .tl__card {
  background: rgba(255, 255, 255, 0.075);
  border-color: var(--step);
}
.tl__step:hover .tl__node::after,
.tl__step:focus-within .tl__node::after { opacity: 0.7; transform: scale(1.08); }

/* --------------------------------------------------------------------------
   Light section — warmed so it stops reading as a hole punched in the page
   -------------------------------------------------------------------------- */
.light {
  background:
    radial-gradient(700px 380px at 12% 0%, rgba(124, 108, 240, 0.10), transparent 65%),
    radial-gradient(700px 420px at 92% 100%, rgba(255, 155, 106, 0.12), transparent 65%),
    #f7f6fd;
  border-top-color: var(--border-soft);
}
.light .panel {
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(124, 108, 240, 0.16);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 24px 60px -28px rgba(76, 60, 160, 0.35);
}
.light .panel__price { color: var(--ink); }

/* Muted text inside a light section has to come off the ink, not off the
   dark page's --text-muted. Scoped to .light so dark sections are untouched. */
.light .note,
.light .eyebrow,
.light .panel__label { color: var(--ink-muted); }

/* "From" is a qualifier, not part of the figure — sized down and muted so the
   price still reads as one big number rather than a four-word sentence. */
.panel__from {
  font-size: 0.44em;
  font-weight: 500;
  letter-spacing: 0;
  vertical-align: 0.34em;
  color: var(--ink-muted);
}
/* The setup fee is material to the offer, and the panel's own copy promises no
   surprise charges — so it is stated here rather than left to the pricing page. */
.panel__setup { margin-top: 10px; }

/* --------------------------------------------------------------------------
   Form
   -------------------------------------------------------------------------- */
.field input,
.field select {
  background-color: rgba(255, 255, 255, 0.04);
  border-color: var(--border-soft);
  transition: border-color 180ms ease, background-color 180ms ease;
}
.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent-cool);
  background-color: rgba(124, 108, 240, 0.08);
}

/* The native dropdown popup is painted by the OS, not by the page. Without
   color-scheme it renders on a light system background — and since the option
   text inherits white, the list came out white-on-white and unreadable.
   color-scheme flips the popup dark; the explicit option colors are the
   fallback for browsers that ignore it. */
.field select {
  color-scheme: dark;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239393a9' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 42px;
  cursor: pointer;
}
.field select:hover { border-color: var(--border-lit); }

.field select option {
  background-color: #14122e;
  color: #ffffff;
}
.field select option:checked { background-color: #241f52; }

/* Rows read as raised cards on the wash, the way .card does — translucent so
   the section's glow shows through instead of punching flat blocks into it. */
.faq {
  background: rgba(255, 255, 255, 0.035);
  border-color: var(--border-soft);
}
.faq[open] { border-color: var(--border-lit); }
.faq__q:hover { background: rgba(255, 255, 255, 0.025); }
.faq[open] .faq__chev { color: var(--accent-cool); }

.faq-search__input {
  background: rgba(255, 255, 255, 0.035);
  border-color: var(--border-soft);
}
.faq-search__input:focus { border-color: var(--border-lit); outline: none; }
.faq-search__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.footer { border-top-color: var(--border-soft); }
.footer__legal { border-top-color: var(--border-soft); }

/* --------------------------------------------------------------------------
   Pricing page
   -------------------------------------------------------------------------- */
/* z-index kept deliberately: the chip overlaps the card's top edge, so it has
   to clear the border and anything else drawn there. */
.plan__flag {
  background: var(--accent-deep);
  color: #ffffff;
  z-index: 3;
}
.plan--featured .plan__amount { color: var(--accent-cool); }
.plan__list li::before { color: var(--accent-warm); }
.plan--featured .plan__list li::before { color: var(--dawn-3); }
.plan__setup { background: rgba(124, 108, 240, 0.10); }
.plan__eyebrow { color: var(--accent); }
.plan__fit { border-top-color: var(--border-soft); }
.custom-bundle { border-color: rgba(255, 255, 255, 0.16); background: rgba(124, 108, 240, 0.05); }

.compare th, .compare td { border-bottom-color: var(--border-soft); }
.compare .is-yes { color: var(--accent-warm); }
.compare .is-pick { background: rgba(124, 108, 240, 0.09); }
.compare thead .is-pick { background: rgba(124, 108, 240, 0.14); }
.compare thead .is-pick { color: var(--dawn-4); }

.pricing-hero { border-bottom-color: var(--border-soft); }
.pricing-hero__kicker { color: var(--accent); }

/* --------------------------------------------------------------------------
   SERP mockup — a live Google results card, not an image. Sharper at any
   zoom, responsive, editable, and weighs nothing.
   -------------------------------------------------------------------------- */
.serp {
  background: #ffffff;
  border-radius: 16px;
  padding: 18px 20px 20px;
  color: #202124;
  font-family: arial, sans-serif;
  box-shadow: 0 30px 70px -30px rgba(80, 60, 180, 0.55),
              0 0 0 1px rgba(255, 255, 255, 0.10);
  width: 100%;
  overflow: hidden;
}
/* Matches google.com's own bar: query hard left, tools on the right as
   clear - divider - voice - Lens - search. No left-hand magnifier; Google
   does not have one there. */
.serp__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid #dfe1e5;
  border-radius: 9999px;
  padding: 11px 18px;
  margin-bottom: 16px;
  font-size: 15px;
  color: #3c4043;
}
.serp__query { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.serp__tools { display: flex; align-items: center; gap: 13px; flex: none; }
.serp__ico { width: 21px; height: 21px; display: block; flex: none; }
.serp__ico--x { width: 19px; height: 19px; }
.serp__divider { width: 1px; height: 24px; background: #dadce0; flex: none; }

@media (max-width: 900px) {
  .serp__tools { gap: 10px; }
  .serp__ico { width: 19px; height: 19px; }
  .serp__ico--x { width: 17px; height: 17px; }
  .serp__divider { height: 21px; }
}
.serp__tabs { display: flex; gap: 18px; font-size: 12px; color: #70757a; border-bottom: 1px solid #ebebeb; padding-bottom: 8px; margin-bottom: 14px; }
.serp__tabs span:first-child { color: #1a73e8; border-bottom: 2px solid #1a73e8; padding-bottom: 8px; margin-bottom: -9px; font-weight: 600; }

.serp__result { margin-bottom: 16px; }
.serp__result:last-child { margin-bottom: 0; }
.serp__ad {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  color: #202124;
  margin-bottom: 3px;
}
.serp__url { font-size: 12px; color: #202124; line-height: 1.3; }
.serp__url span { color: #5f6368; }
.serp__title { font-size: 19px; line-height: 1.3; color: #1a0dab; margin: 2px 0 3px; font-weight: 400; }
.serp__desc { font-size: 13px; line-height: 1.5; color: #4d5156; }
.serp__links { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-top: 7px; font-size: 13px; color: #1a0dab; }
/* Demoted results are DESATURATED, not faded. opacity: 0.42 was the first
   approach and it dropped this copy to 2.0-2.6:1 on white — below AA, and
   the README's "every text pair passes AA" claim never covered it. Explicit
   greys read as more convincingly dead-link than a wash does, and clear AA:
   #737394 = 4.56:1, #70757a = 4.65:1. */
.serp__result--dim .serp__title,
.serp__result--buried .serp__title { color: #737394; }
.serp__result--dim .serp__url,
.serp__result--buried .serp__url,
.serp__result--dim .serp__url span,
.serp__result--buried .serp__url span,
.serp__result--dim .serp__desc,
.serp__result--buried .serp__desc { color: #70757a; }
.serp__result--dim .serp__title { font-size: 17px; }

.serp__cap {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid #ebebeb;
  font-family: var(--font);
  font-size: 11px;
  line-height: 1.5;
  color: #70757a;
}

@media (max-width: 720px) {
  .serp { padding: 14px 14px 16px; border-radius: 12px; }
  .serp__title { font-size: 17px; }
  .serp__tabs { gap: 12px; }
  .serp__bar { gap: 8px; padding: 9px 14px; font-size: 14px; }
  .serp__tools { gap: 8px; }
  /* Leave the clamp()'d blur alone — it already floors at 52px here. Just
     ease the intensity so type stays legible on a small, bright screen. */
  .glow { opacity: 0.28; }
  .hero-band .glow,
  .pricing-hero .glow { opacity: 0.42; }
  .lit::before { opacity: 0.85; }
  body::after { opacity: 0.24; }
}

/* Glow is decorative; drop it for anyone who asked for less motion/effect. */
@media (prefers-reduced-motion: reduce) {
  .card:hover, .card--plain:hover, .card--hollow:hover, .qa:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   Photo band — a band with a photograph behind the usual colour overlay.

   The overlay is the SAME colour the bands already use; only its opacity is
   raised, because the photo peaks at luma 235 and the band's normal 0.66
   would leave the muted eyebrow at 2.39:1. At 0.78, with the eyebrow lifted
   from --text-muted to --text-soft, every text pair clears AA against the
   image's brightest pixels — the worst case, not the average.
   -------------------------------------------------------------------------- */
.band--photo {
  position: relative;
  /* No hairlines here. .band draws a 1px translucent white border top and
     bottom, and because the photo paints across the BORDER box while the
     ::after feather only covers the PADDING box, each border rendered as a
     1px strip of un-feathered image — reading as a hard seam against the
     sections above and below. The feather below does the edge work instead. */
  border-top: 0;
  border-bottom: 0;
  background-clip: padding-box;
  background-color: var(--band-quiet);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* The photograph itself is a modifier, so the treatment above is written once
   and each band only names its own image. The plain url() line first is the
   fallback for browsers without image-set(); the second declaration wins
   where it is supported and serves WebP.

   The 0.78 scrim is not decoration — it is what keeps body copy at AA over a
   bright photo. Lower it and the text fails. */
.band--photo--volunteers {
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.78), rgba(11, 9, 33, 0.78)),
    url('../img/volunteers.jpg');
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.78), rgba(11, 9, 33, 0.78)),
    image-set(url('../img/volunteers.webp') type('image/webp'),
              url('../img/volunteers.jpg')  type('image/jpeg'));
}

.band--photo--staff {
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.80), rgba(11, 9, 33, 0.80)),
    url('../img/staff.jpg');
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.80), rgba(11, 9, 33, 0.80)),
    image-set(url('../img/staff.webp') type('image/webp'),
              url('../img/staff.jpg')  type('image/jpeg'));
}

.band--photo--community {
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.80), rgba(11, 9, 33, 0.80)),
    url('../img/community.jpg');
  background-image:
    linear-gradient(rgba(11, 9, 33, 0.80), rgba(11, 9, 33, 0.80)),
    image-set(url('../img/community.webp') type('image/webp'),
              url('../img/community.jpg')  type('image/jpeg'));
}

/* Matches .card's treatment — translucent so the section wash shows through
   rather than a flat block appearing where the form used to be. */
.form-done {
  background: rgba(255, 255, 255, 0.035);
  border-color: var(--border-lit);
}
.form-done__steps li::before { border-color: var(--accent-cool); }

/* The eyebrow is a label and wants full readability over a photo. */
.band--photo .eyebrow { color: var(--text-soft); }

/* Everything else in the muted role moves to the photo-safe tone rather than
   all the way up to --text-soft — lifting them that far passes AA but flattens
   body / muted / strong into one weight. Add a class here if you ever put
   another muted-role element on a photo band. */
.band--photo .muted,
.band--photo .body-sm,
.band--photo .note,
.band--photo .fine,
.band--photo .stat-note,
.band--photo .tl__when,
.band--photo .tl__desc { color: var(--text-muted-photo); }

/* Feather the top and bottom edges into the neighbouring sections so the
   photo reads as part of the page rather than a pasted-in rectangle. */
.band--photo::after {
  content: '';
  position: absolute;
  /* -1px so the feather overshoots the box on every side; a sub-pixel
     rounding gap at a section boundary is exactly what shows up as a seam. */
  inset: -1px;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(11, 9, 33, 0.98) 0%,
    rgba(11, 9, 33, 0.55) 7%,
    rgba(11, 9, 33, 0) 22%,
    rgba(11, 9, 33, 0) 78%,
    rgba(11, 9, 33, 0.55) 93%,
    rgba(11, 9, 33, 0.98) 100%);
}
.band--photo > * { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   Before / after search visibility — the same query in two states, built
   from the same .serp component as the hero rather than as an image pair.
   The panels are two-up on desktop and stack on phones; the labels carry
   the before/after read on their own once stacked.
   -------------------------------------------------------------------------- */
.vis { margin: 0; }

.vis__pair {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px;
  align-items: stretch;
}

/* Column is a flex chain so the .serp can be told to fill the taller of the
   two — otherwise the shorter panel floats and the pair stops reading as
   one comparison. */
.vis__col { display: flex; flex-direction: column; min-width: 0; }

.vis__label {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-muted);
}
.vis__label--on { color: var(--text); }

.vis__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  /* Hollow ring for the buried state, filled for the visible one — a shape
     difference, not just a colour one, so it survives greyscale and any
     form of colour blindness. */
  border: 1.5px solid var(--text-muted);
}
.vis__label--on .vis__dot { border-color: var(--accent-cool); background: var(--accent-cool); }

.vis .serp {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* The hero card's big purple drop shadow is right for one card floating
     alone; at two-up it muddies the gutter between them. */
  box-shadow: 0 18px 44px -26px rgba(80, 60, 180, 0.5),
              0 0 0 1px rgba(255, 255, 255, 0.08);
}

/* Mini variant: same anatomy, tighter scale, and the bar keeps only the
   search icon. Voice and Lens are real on google.com but at this size they
   are three-quarters noise. */
.serp--mini { padding: 14px 15px 16px; border-radius: 13px; }
.serp--mini .serp__bar { padding: 9px 14px; font-size: 13px; margin-bottom: 14px; }
.serp--mini .serp__result { margin-bottom: 14px; }
.serp--mini .serp__title { font-size: 16px; }
.serp--mini .serp__desc { font-size: 12px; }
.serp--mini .serp__links { font-size: 12px; gap: 4px 14px; }
.serp--mini .serp__ico { width: 18px; height: 18px; }

/* Burial is carried by the DISTANCE — the gap opens, then the page marker,
   then the org last — not by fading the org to the edge of legibility. Held
   at the same 0.42 the hero's demoted results already use; going lower made
   real copy unreadable for the sake of an effect. */
/* .vis prefix is load-bearing: .serp--mini .serp__result sets a 14px bottom
   margin at specificity (0,2,0), so a bare .serp__result--buried loses and
   leaves dead space under the last result. */
.vis .serp__result--buried {
  margin-bottom: 0;
}

/* auto margin sits HERE, not on the buried result, so the empty space opens
   above the ellipsis. That void is the thing doing the work. */
.serp__gap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  margin: auto 0 12px;
  padding-top: 18px;
}
.serp__gap span {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #bdc1c6;
}

/* #70757a, not Google's lighter #9aa0a6 — that only reaches 2.7:1 on white
   and fails AA for text this size. */
.serp__page {
  font-family: var(--font);
  font-size: 11px;
  color: #70757a;
  text-align: center;
  margin: 0 0 12px;
  padding-top: 10px;
  border-top: 1px solid #ebebeb;
}

.vis__note {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
}
.vis__col--on .vis__note { color: var(--text-soft); }

.vis__cap {
  margin: 22px auto 0;
  max-width: 720px;
  text-align: center;
  font-size: 11px;
  line-height: 1.55;
  color: var(--text-muted);
}

/* Stacks at 900, not at the usual 720. Two-up below ~900 leaves each card
   around 330px — narrower than the phone layout it is supposed to be the
   roomy version of, and a SERP that cramped stops reading as a SERP. Above
   900 each card clears 400px. */
@media (max-width: 900px) {
  .vis__pair { grid-template-columns: 1fr; gap: 32px; }
  /* Stacked, the cards no longer need to match heights. Content-driven
     height also collapses the gap's auto margin to zero, so its padding
     alone carries the break. */
  .vis .serp { flex: 0 0 auto; }
  .serp__gap { margin-top: 0; }
}

@media (max-width: 760px) {
  .vis__cap { text-align: left; }
}
