/* ═══════════════════════════════════════════════════════════════════════════
   BrewTrails — brewtrails.app

   The palette, type, spacing and motion all come from DESIGN.md, so the site
   and the product read as the same object. Two deliberate departures from
   every competitor are carried through from the app: terracotta instead of
   beer-gold, and a warm serif (Fraunces) instead of a geometric sans.

   No build step. One stylesheet, two small scripts, five pages.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Tokens ──────────────────────────────────────────────────────────────
   Light is the default so the legal pages, which carry no theme script,
   still render correctly before anything runs. */
:root {
  color-scheme: light;

  --bg:            #F7F0E4;   /* warm cream, never stark white */
  --bg-sink:       #F1E6D3;   /* recessed bands */
  --surface:       #FFFBF3;
  --surface-2:     #FBF3E7;

  --text:          #2B2019;
  --muted:         #6B5C4D;
  --taupe:         #8C7A68;

  --accent:        #C1502E;   /* terracotta — every CTA */
  --accent-deep:   #A63A2B;
  --accent-wash:   #F3DCCD;
  --on-accent:     #FFF8F0;

  --secondary:     #5B6B3F;   /* hop green */
  --ochre:         #C98A2E;
  --slate:         #5C7080;

  --border:        #E4D8C4;
  --border-firm:   #D9C9AF;

  --ink-shadow:    43, 32, 25;
  --shadow-sm:  0 1px 2px rgba(var(--ink-shadow), .05), 0 8px 24px rgba(var(--ink-shadow), .06);
  --shadow-md:  0 2px 4px rgba(var(--ink-shadow), .06), 0 18px 44px rgba(var(--ink-shadow), .10);
  --shadow-lg:  0 30px 70px rgba(var(--ink-shadow), .24);

  --grain-blend:   multiply;
  --grain-alpha:   .045;
  --map-land:      #E8E3CE;
  --map-water:     #BBD6E4;
  --map-park:      #D6DFC0;
  --map-road:      #FFFBF3;

  --max: 1140px;
  --r-sm: 10px;
  --r:    16px;
  --r-lg: 26px;

  --ease: cubic-bezier(.16,.84,.44,1);
  --spring: cubic-bezier(.34,1.56,.64,1);
}

/* Dark is a parallel palette, not an inversion — warm charcoal-brown, never
   pure black, exactly as the app does it. Declared twice on purpose: once
   for the system preference, once for an explicit choice, so the manual
   toggle wins in both directions. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #211A15; --bg-sink: #1A1410; --surface: #2B221B; --surface-2: #33281F;
    --text: #F3E9DA; --muted: #B8A891; --taupe: #A6907A;
    --accent: #E06B45; --accent-deep: #C9553F; --accent-wash: #47281C; --on-accent: #1B120D;
    --secondary: #7C9159; --ochre: #DDA649; --slate: #7E94A4;
    --border: #3D3126; --border-firm: #4E3F31;
    --ink-shadow: 0, 0, 0;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.28);
    --shadow-md: 0 2px 4px rgba(0,0,0,.34), 0 18px 44px rgba(0,0,0,.38);
    --shadow-lg: 0 30px 70px rgba(0,0,0,.55);
    --grain-blend: overlay; --grain-alpha: .08;
    --map-land: #2F2A20; --map-water: #22323C; --map-park: #2C3527; --map-road: #40372B;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #211A15; --bg-sink: #1A1410; --surface: #2B221B; --surface-2: #33281F;
  --text: #F3E9DA; --muted: #B8A891; --taupe: #A6907A;
  --accent: #E06B45; --accent-deep: #C9553F; --accent-wash: #47281C; --on-accent: #1B120D;
  --secondary: #7C9159; --ochre: #DDA649; --slate: #7E94A4;
  --border: #3D3126; --border-firm: #4E3F31;
  --ink-shadow: 0, 0, 0;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.28);
  --shadow-md: 0 2px 4px rgba(0,0,0,.34), 0 18px 44px rgba(0,0,0,.38);
  --shadow-lg: 0 30px 70px rgba(0,0,0,.55);
  --grain-blend: overlay; --grain-alpha: .08;
  --map-land: #2F2A20; --map-water: #22323C; --map-park: #2C3527; --map-road: #40372B;
}


/* ── Base ────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Paper grain. The app's surfaces carry a subtle tooth; a flat web page beside
   it looks like a different product. One inline SVG, no request, no weight.
   It sits above everything, including the header. Underneath the header it
   would be sampled by that element's backdrop-filter, and a blended noise
   layer run through a blur washes the dark theme's header out to grey. */
body::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 60;
  opacity: var(--grain-alpha);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
}

img { max-width: 100%; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: var(--accent); color: var(--on-accent); }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 24px; position: relative; z-index: 2; }
.narrow { max-width: 720px; }
.centered { text-align: center; }
.centered p { max-width: 580px; margin-left: auto; margin-right: auto; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ── Type ────────────────────────────────────────────────────────────────
   Fraunces carries all the personality at display size, so body text does
   not have to fight for attention. SOFT and WONK are the axes that give it
   the slightly wonky terminals the design system asks for. */
h1, h2, h3, .display {
  font-family: Fraunces, Georgia, "Times New Roman", serif;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.015em;
  font-variation-settings: "SOFT" 28, "WONK" 1;
  text-wrap: balance;
}
h1 { font-size: clamp(2.3rem, 5.4vw, 3.9rem); margin: 0 0 .45em; font-weight: 700; }
h2 { font-size: clamp(1.75rem, 3.6vw, 2.7rem); margin: 2.5rem 0 .75rem; }
h3 { font-size: 1.2rem; margin: 1.75rem 0 .4rem; }

.eyebrow {
  text-transform: uppercase; letter-spacing: .12em; font-size: .74rem;
  font-weight: 700; color: var(--secondary); margin: 0 0 .75rem;
  display: flex; align-items: center; gap: .55rem;
}
.eyebrow::before {
  content: ""; width: 22px; height: 2px; background: currentColor;
  border-radius: 2px; flex: none;
}
.centered .eyebrow, .eyebrow.mid { justify-content: center; }

.lead { font-size: clamp(1.08rem, 1.6vw, 1.28rem); color: var(--muted); line-height: 1.6; }

/* A drawn underline under one word of the headline, in the app's accent.
   It is a background image so it wraps with the text instead of sitting in
   a fixed spot. */
.swash {
  position: relative;
  white-space: nowrap;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 92%;
  background-size: 0% 6px;
  border-radius: 2px;
  animation: swash-in 1s var(--ease) .5s forwards;
}
@keyframes swash-in { to { background-size: 100% 6px; } }


/* ── Header ──────────────────────────────────────────────────────────────── */
header.site {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .3s ease, background .3s ease;
}
header.site.stuck { border-bottom-color: var(--border); }
/* The mark is a detailed badge — a barrel, mountains, a script wordmark and
   two arced taglines. At 42px all of that collapses into a smudge, so the
   header is sized around the logo rather than the logo squeezed into the
   header. 58px is the largest that still leaves the bar looking like a bar. */
header.site .wrap { display: flex; align-items: center; gap: 12px; height: 80px; }
header.site img { width: 58px; height: 58px; border-radius: 50%; }
header.site .name {
  font-family: Fraunces, Georgia, serif; font-weight: 700; font-size: 1.3rem;
  letter-spacing: -.02em;
}
header.site nav { margin-left: auto; display: flex; align-items: center; gap: 4px; }
header.site nav a {
  color: var(--text); text-decoration: none; font-size: .93rem; font-weight: 600;
  padding: 8px 12px; border-radius: 9px; transition: background .2s ease, color .2s ease;
}
header.site nav a:hover { background: var(--surface-2); color: var(--accent); }
header.site nav a.cta {
  background: var(--accent); color: var(--on-accent); margin-left: 6px;
  box-shadow: var(--shadow-sm);
}
header.site nav a.cta:hover { background: var(--accent-deep); color: var(--on-accent); }

/* Theme toggle. Mirrors the Light/Dark/System control in the app's settings;
   here it is a two-state switch that remembers the choice. */
.theme-toggle {
  margin-left: 8px; width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); border-radius: 50%; cursor: pointer;
  transition: color .2s, border-color .2s, transform .3s var(--spring);
}
.theme-toggle:hover { color: var(--accent); border-color: var(--accent); transform: rotate(-18deg); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }
:root[data-theme="dark"] .theme-toggle .sun  { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .sun  { display: none; }
}

@media (max-width: 700px) {
  header.site .wrap { height: 68px; gap: 8px; }
  header.site img { width: 46px; height: 46px; }
  header.site .name { font-size: 1.1rem; }
  header.site nav a { padding: 7px 8px; font-size: .85rem; white-space: nowrap; }
  header.site nav a.hide-sm { display: none; }
}

/* On a narrow phone the wordmark beside the badge is what tips the row over
   and wraps the button onto two lines. The badge is 46px here and carries
   its own wordmark, so the text one is the part that goes. */
@media (max-width: 470px) {
  header.site .name { display: none; }
}


/* ── Buttons and pills ───────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--accent); color: var(--on-accent);
  padding: 15px 28px; border-radius: 13px; text-decoration: none;
  font-weight: 650; font-size: 1rem; border: 1px solid var(--accent);
  box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden;
}
.btn:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--on-accent); }
.btn.ghost {
  background: transparent; color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: none;
}
.btn.ghost:hover { background: var(--accent-wash); color: var(--accent); border-color: var(--accent); }
.btn.big { padding: 18px 34px; font-size: 1.06rem; }

/* A light sweep crossing the button on hover — the one glossy moment on the
   page, and only on a deliberate action. */
.btn::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 45%;
  left: -60%; transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.28), transparent);
  pointer-events: none;
}

.pill-row { display: flex; flex-wrap: wrap; gap: 10px; }
.pill {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--muted); font-size: .84rem; font-weight: 600;
  padding: 7px 14px; border-radius: 999px;
}
.pill svg { width: 15px; height: 15px; color: var(--secondary); }
/* The flag. A hairline ring keeps the white band from dissolving into a
   light background, and a matching light ring does the same job against the
   Canada section's night sky. */
.flag-ca {
  width: 26px; height: 13px; flex: none; display: block;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(43,32,25,.18);
}
.north .flag-ca { box-shadow: 0 0 0 1px rgba(255,255,255,.28); }
.north .btn .flag-ca { box-shadow: 0 0 0 1px rgba(0,0,0,.22); }
.eyebrow .flag-ca { width: 24px; height: 12px; }

a.pill { text-decoration: none; }
a.pill.flag {
  color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-wash);
}
a.pill.flag:hover { border-color: var(--accent); }

.tag {
  display: inline-block; background: var(--secondary); color: #fff;
  font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 6px; margin-bottom: 10px;
}


/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  padding: clamp(48px, 8vw, 96px) 0 clamp(56px, 8vw, 104px);
  /* The contour texture and the glows are deliberately wider than the page.
     Clipped here rather than left to `overflow-x: hidden` on the body: that
     stops the scrollbar but still reports the overflow, and iOS Safari will
     still rubber-band sideways into the empty space. */
  overflow: hidden;
}
.hero-grid {
  display: grid; grid-template-columns: 1.03fr .97fr;
  gap: clamp(32px, 5vw, 72px); align-items: center;
}
/* The mark, at a size where the barrel, the script and both arced taglines
   actually read. The header can never do that — no bar 80px tall can — so
   the logo gets said properly once at the top of the page and once at the
   download, and the header carries a small lockup of it. */
.hero-mark {
  width: clamp(104px, 9.5vw, 146px); height: auto;
  display: block; margin: 0 0 20px;
}
.hero h1 { margin-bottom: .35em; }
.hero .lead { max-width: 30rem; margin: 0 0 2rem; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 1.75rem; }

/* Topography. Concentric rings drawn with repeating gradients rather than a
   traced SVG — same contour-map read, a few hundred bytes, and it recolours
   itself with the theme. */
.topo {
  position: absolute; inset: -10% -20% auto; height: 150%;
  z-index: 0; pointer-events: none; opacity: .5;
  background:
    repeating-radial-gradient(ellipse 44% 38% at 12% 22%, transparent 0 26px, var(--border-firm) 26px 27px),
    repeating-radial-gradient(ellipse 40% 46% at 86% 68%, transparent 0 30px, var(--border-firm) 30px 31px);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 20%, transparent 78%);
          mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 20%, transparent 78%);
}

/* Warm light behind the product, the same gradient family as the app's
   badge celebration stage. */
.glow {
  position: absolute; z-index: 0; pointer-events: none;
  border-radius: 50%; filter: blur(70px); opacity: .55;
}
.glow.a { width: 46vw; height: 46vw; right: -8vw; top: -6vw; background: var(--accent-wash); }
.glow.b { width: 34vw; height: 34vw; left: -12vw; bottom: -10vw;
          background: color-mix(in srgb, var(--secondary) 30%, transparent); opacity: .32; }
/* On the dark ground the hop green reads as a colour cast rather than as
   light, so it is pulled right back. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .glow.b { opacity: .14; } }
:root[data-theme="dark"] .glow.b { opacity: .14; }

/* The product, on a tilted stage with a route drawn behind it. The inner
   wrapper is exactly the width of the phone, so the cards that float off it
   can be positioned against the device rather than against the column — the
   column changes width at every breakpoint, the phone does not. */
.stage { position: relative; display: grid; place-items: center; min-height: 480px; }
.stage-inner { position: relative; }
.stage .route { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.stage .route path {
  fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 9 11; opacity: .55;
}
.stage .route circle { fill: var(--surface); stroke: var(--accent); stroke-width: 3; }

.phone-tilt {
  position: relative; z-index: 2;
  transform: perspective(1400px) rotateY(-13deg) rotateX(3deg) rotate(1.4deg);
  transform-style: preserve-3d;
}

/* Cards that float off the phone: the moments the app is actually for. */
.float {
  position: absolute; z-index: 3;
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 10px 14px;
  box-shadow: var(--shadow-md); font-size: .86rem; font-weight: 600;
  white-space: nowrap;
}
.float small { display: block; font-weight: 500; color: var(--muted); font-size: .76rem; }
.float .dot {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center; color: #fff; font-size: .9rem;
}
.float.one   { top: 8%;    right: calc(100% - 22px); }
.float.two   { bottom: 27%; left:  calc(100% - 22px); }
.float.three { bottom: 5%;  right: calc(100% - 40px); }

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; text-align: center; }
  .hero-mark { margin-inline: auto; }
  .hero .lead { margin-left: auto; margin-right: auto; }
  .hero-cta, .hero .pill-row { justify-content: center; }
  .eyebrow { justify-content: center; }
  .stage { min-height: 420px; }
  .phone-tilt { transform: none; }
  .float.three { display: none; }
  /* The drawn route wrapped around the phone only reads on a wide stage;
     stacked, its ends poke out from behind the device looking like errors. */
  .stage .route { display: none; }
}

/* Below this the phone is nearly as wide as the screen and the cards have
   nowhere to sit without covering the screenshot they are advertising. */
@media (max-width: 620px) {
  .float { display: none; }
  /* Two buttons of different widths stacked down the middle look like a
     mistake; matched full-width ones look like a choice. */
  .hero-cta { flex-direction: column; align-items: stretch; }
  .hero-cta .btn { justify-content: center; }
}


/* ── Phone frame ─────────────────────────────────────────────────────────
   A real frame in CSS rather than a mockup image, so the screenshot inside
   stays crisp at any pixel density and weighs nothing. */
.phone {
  --phone-w: min(310px, 76vw);
  position: relative; display: inline-block; width: var(--phone-w);
  padding: 10px; background: linear-gradient(150deg, #4A4038, #1B1512 34%, #131010);
  border-radius: 46px;
  box-shadow: var(--shadow-lg), inset 0 0 0 1px rgba(255,255,255,.10);
  vertical-align: bottom;
}
.phone-screen {
  position: relative; overflow: hidden; border-radius: 36px;
  background: #F7F0E4; display: block; aspect-ratio: 414 / 900;
}
.phone-screen img {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: top;
}
/* Dynamic island */
.phone::before {
  content: ""; position: absolute; top: 20px; left: 50%; transform: translateX(-50%);
  width: 30%; height: 22px; background: #0D0B0A; border-radius: 999px; z-index: 4;
}
/* Glass */
.phone::after {
  content: ""; position: absolute; inset: 10px; border-radius: 36px; z-index: 3;
  pointer-events: none;
  background: linear-gradient(128deg, rgba(255,255,255,.20) 0%, rgba(255,255,255,0) 34%);
}
.phone.plain::before { display: none; }

.phones { display: flex; gap: 26px; justify-content: center; align-items: flex-end; flex-wrap: wrap; }
.phones .phone:nth-child(2) { margin-bottom: -28px; }
@media (max-width: 640px) { .phones .phone:nth-child(2) { display: none; } }


/* ── Ticker ──────────────────────────────────────────────────────────────
   Trail names, moving slowly. It says "this is a thing people make" faster
   than a paragraph would. */
.ticker {
  border-block: 1px solid var(--border);
  background: var(--bg-sink);
  padding: 14px 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ticker-track { display: flex; width: max-content; gap: 0; }
.ticker-track > span {
  display: inline-flex; align-items: center; gap: 34px;
  padding-right: 34px; white-space: nowrap;
  font-family: Fraunces, Georgia, serif; font-size: 1.05rem;
  color: var(--muted); font-variation-settings: "SOFT" 40, "WONK" 1;
}
.ticker-track b { font-weight: 600; color: var(--text); }
.ticker-track i { color: var(--accent); font-style: normal; }


/* ── Section furniture ───────────────────────────────────────────────────── */
section { padding: clamp(48px, 7vw, 88px) 0; }
section.tight { padding: 32px 0; }
.band { background: var(--bg-sink); border-block: 1px solid var(--border); }
.section-head { max-width: 46rem; margin-bottom: clamp(28px, 4vw, 48px); }
.section-head.mid { margin-inline: auto; text-align: center; }
.section-head h2 { margin-top: 0; }
.section-head p { color: var(--muted); font-size: 1.1rem; margin-bottom: 0; }


/* ── Interactive trail builder ───────────────────────────────────────────
   The one thing on the page that is not a claim. Tap breweries, watch the
   route sort itself — the same job the app does, done in the browser. */
.builder {
  display: grid; grid-template-columns: 1.35fr .65fr; gap: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-md);
}
.builder-map { position: relative; background: var(--map-land); min-height: 460px; }
.builder-map svg { display: block; width: 100%; height: 100%; }

.node { cursor: pointer; }
.node .hit { fill: transparent; }
.node .ring {
  fill: var(--surface); stroke: var(--taupe); stroke-width: 2.5;
  transition: fill .3s var(--ease), stroke .3s var(--ease), r .35s var(--spring);
}
/* A + inside every stop you have not picked yet. Without it the map reads as
   a picture rather than as something you are meant to touch. */
.node .plus {
  stroke: var(--taupe); stroke-width: 2.4; stroke-linecap: round;
  pointer-events: none; transition: opacity .25s ease, stroke .3s ease;
}
.node:hover .plus { stroke: var(--accent); }
.node.on .plus { opacity: 0; }
.node .label {
  font: 600 11px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  fill: var(--muted); paint-order: stroke; stroke: var(--map-land); stroke-width: 3px;
  pointer-events: none; transition: fill .3s ease;
}
.node .num {
  font: 700 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  fill: var(--on-accent); text-anchor: middle; dominant-baseline: central;
  opacity: 0; transition: opacity .25s ease; pointer-events: none;
}
.node:hover .ring { stroke: var(--accent); }
.node.on .ring { fill: var(--accent); stroke: var(--accent-deep); }
.node.on .num { opacity: 1; }
.node.on .label { fill: var(--text); }

.route-line {
  fill: none; stroke: var(--accent); stroke-width: 4.5;
  stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 8 10;
}

.builder-side {
  border-left: 1px solid var(--border); background: var(--surface-2);
  padding: 22px; display: flex; flex-direction: column; min-width: 0;
}
.builder-side h3 { margin: 0 0 2px; font-size: 1.15rem; }
.builder-side .hint { color: var(--muted); font-size: .84rem; margin: 0 0 14px; }

.modes { display: flex; background: var(--bg-sink); border-radius: 10px; padding: 3px; margin-bottom: 16px; }
.modes button {
  flex: 1; border: 0; background: transparent; color: var(--muted);
  font: inherit; font-size: .82rem; font-weight: 600; padding: 7px 4px;
  border-radius: 8px; cursor: pointer; transition: background .25s, color .25s;
}
.modes button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }

.stops { list-style: none; margin: 0; padding: 0; flex: 1; min-height: 150px; }
.stops li {
  display: grid; grid-template-columns: 26px 1fr auto; gap: 10px; align-items: center;
  padding: 9px 0; border-bottom: 1px dashed var(--border);
  font-size: .89rem; animation: stop-in .4s var(--ease) both;
}
.stops li:last-child { border-bottom: 0; }
.stops .n {
  width: 24px; height: 24px; border-radius: 50%; background: var(--accent);
  color: var(--on-accent); display: grid; place-items: center;
  font-size: .74rem; font-weight: 700;
}
.stops .nm { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stops .leg { color: var(--muted); font-size: .78rem; font-variant-numeric: tabular-nums; }
.stops .empty {
  display: block; grid-column: 1 / -1; color: var(--muted); font-style: italic;
  border: 0; padding: 20px 0; text-align: center;
}
@keyframes stop-in { from { opacity: 0; transform: translateX(10px); } }

.totals {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
  display: flex; gap: 18px;
}
.totals div { flex: 1; }
.totals .v {
  font-family: Fraunces, Georgia, serif; font-size: 1.5rem; font-weight: 600;
  font-variant-numeric: tabular-nums; display: block; line-height: 1.1;
}
.totals .k { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }

.builder-actions { display: flex; gap: 8px; margin-top: 16px; }
.builder-actions button {
  flex: 1; border: 1px solid var(--border-firm); background: var(--surface);
  color: var(--text); font: inherit; font-size: .85rem; font-weight: 600;
  padding: 10px; border-radius: 10px; cursor: pointer;
  transition: border-color .2s, color .2s, transform .2s;
}
.builder-actions button:hover { border-color: var(--accent); color: var(--accent); }
.builder-note { font-size: .74rem; color: var(--muted); margin: 14px 0 0; text-align: center; }

/* Stacked, the map is no longer sized by the panel beside it. Give it the
   viewBox's own proportions so the drawing fills the box instead of sitting
   letterboxed inside it — and scale the map's own type and targets up, since
   everything inside an SVG shrinks with the drawing. */
@media (max-width: 880px) {
  .builder { grid-template-columns: 1fr; }
  .builder-map { min-height: 0; aspect-ratio: 640 / 420; }
  .builder-side { border-left: 0; border-top: 1px solid var(--border); }

  .node .hit   { r: 32px; }
  .node .ring  { r: 15px; }
  .node .num   { font-size: 18px; }
  /* Eight names at this scale is a wall of 6px type. The stops you have
     picked are named on the map and in the list; the rest are pins to try,
     which is how you would read a paper map of a city you do not know. */
  .node .label { font-size: 20px; stroke-width: 5px; opacity: 0; transition: opacity .25s ease; }
  .node.on .label { opacity: 1; }
  .route-line  { stroke-width: 6; }
}


/* ── Scroll story: one phone, three beats ────────────────────────────────── */
.story { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 5vw, 72px); align-items: start; }
.story-stage {
  position: sticky; top: 102px; display: grid; place-items: center; padding: 12px 0;
}
.story-stage .phone { --phone-w: min(300px, 70vw); }
.story-stage .phone-screen img {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity .55s var(--ease), transform .8s var(--ease);
  transform: scale(1.04);
}
.story-stage .phone-screen img.on { opacity: 1; transform: none; }

.beat {
  min-height: min(62vh, 520px);
  display: flex; flex-direction: column; justify-content: center;
  padding: 3vh 0;
}
.beat h2 { margin-top: 0; }
.beat p { color: var(--muted); font-size: 1.08rem; }
.beat ul { list-style: none; padding: 0; margin: 1rem 0 0; }
.beat li {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 7px 0; color: var(--muted); font-size: .97rem;
}
.beat li svg { width: 19px; height: 19px; flex: none; margin-top: 3px; color: var(--secondary); }
.beat .marker {
  display: inline-grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: var(--accent-wash); color: var(--accent);
  font-family: Fraunces, serif; font-weight: 700; margin-bottom: 14px;
}

/* Stacked, the phone pins itself under the header and the prose scrolls
   beneath it. The bar has to be opaque, not a fade: a gradient lets the
   text underneath show through around the sides of the device, which reads
   as a rendering fault rather than as depth. */
@media (max-width: 880px) {
  .story { grid-template-columns: 1fr; }
  .story-stage {
    top: 78px; order: -1; padding: 10px 0 14px;
    background: var(--bg);
  }
  .story-stage::after {
    content: ""; position: absolute; left: -24px; right: -24px; top: 100%;
    height: 26px; pointer-events: none;
    background: linear-gradient(var(--bg), transparent);
  }
  .story-stage .phone { --phone-w: min(200px, 50vw); }
  .beat { min-height: auto; padding: 26px 0; }
}


/* ── Badge wall ──────────────────────────────────────────────────────────
   The patches in the app are dark, gold-embroidered artwork on a lit stage.
   These are line-drawn stand-ins in the same spirit: each category keeps its
   own stage gradient and glow colour from the design system. */
.badge-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 900px) { .badge-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 620px) { .badge-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }
.patch-card {
  margin: 0; position: relative; text-align: center;
  padding: 22px 12px 18px; border-radius: var(--r);
  background: radial-gradient(ellipse at 50% 34%, var(--stage-1), var(--stage-2) 72%);
  border: 1px solid rgba(255,255,255,.08);
  overflow: hidden; isolation: isolate;
  box-shadow: var(--shadow-sm);
}
/* The spotlight and light-ray burst behind the patch, as in the app. */
.patch-card::before {
  content: ""; position: absolute; z-index: 0;
  left: 50%; top: 32%; width: 190px; height: 190px; translate: -50% -50%;
  background: radial-gradient(circle, rgb(var(--glow) / .55), transparent 66%);
  filter: blur(10px);
  transition: opacity .6s ease, scale .6s var(--ease);
  opacity: 0; scale: .6;
}
.patch-card.lit::before { opacity: 1; scale: 1; }
.patch-card svg {
  position: relative; z-index: 1; width: 104px; height: 104px; display: block; margin: 0 auto;
  filter: drop-shadow(0 8px 16px rgba(0,0,0,.55));
}
.patch-card figcaption {
  position: relative; z-index: 1; margin-top: 14px;
  font-family: Fraunces, Georgia, serif; font-weight: 600; font-size: .95rem;
  color: #F6EBDA;
}
/* Lifted towards white rather than used at full saturation: the glow colour
   is chosen to read as light behind the patch, which makes it too dim to read
   as text on the same dark stage. */
.patch-card .sub {
  display: block; font-family: inherit; font-size: .75rem; font-weight: 500; margin-top: 3px;
  color: color-mix(in srgb, rgb(var(--glow)) 62%, #FFF6E4);
}

/* Dark fabric, a heavy metallic rim, a stitch line inside it. The fill is
   lighter than the stage behind it rather than darker — a patch is a thing
   sitting on the surface, not a hole cut in it. */
.die    { fill: rgba(255,244,222,.10); stroke: #EFC378; stroke-width: 5; }
.stitch { fill: none; stroke: #FFE7B0; stroke-width: 1.6; stroke-dasharray: 3 3.5; opacity: .9; }
.glyph  { fill: none; stroke: #FFDFA2; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.glyph.solid { fill: #FFDFA2; stroke: none; }

/* The patch arrives the way it does in the app: the ring fills, then the
   patch lands with a spring. */
.patch-card svg { opacity: 0; transform: scale(.72) rotate(-8deg); }
.patch-card.lit svg { animation: patch-land .75s var(--spring) forwards; }
@keyframes patch-land { to { opacity: 1; transform: none; } }

.patch-card:hover .glyph { stroke: #FFF0C8; }


/* ── Canada ──────────────────────────────────────────────────────────────
   A night stage, dark in both themes. The design system already does this
   for badge celebrations — the artwork needs contrast more than it needs to
   match the ambient chrome — and the same reasoning applies to an aurora.
   Colours here are literal rather than tokens for exactly that reason. */
.north {
  position: relative; overflow: hidden;
  background: linear-gradient(178deg, #0C1A1B 0%, #0A1214 52%, #0D1116 100%);
  color: #E8F1EC;
  padding: clamp(60px, 8vw, 104px) 0;
  border-block: 1px solid #1D2A2A;
}
.north h2, .north h3 { color: #F4FAF6; }
.north .section-head p { color: #A9BFB6; }
.north .eyebrow { color: #7FD3B4; }

/* Aurora. Three blurred ribbons on screen blend, drifting at different
   speeds so the band never repeats a shape you have already seen. */
.aurora { position: absolute; inset: -20% -10% auto; height: 90%; pointer-events: none; }
.aurora i {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(70px); mix-blend-mode: screen; opacity: .48;
}
.aurora i:nth-child(1) { left:  2%; top: 6%;  width: 52%; height: 46%; background: #3FBF86; }
.aurora i:nth-child(2) { left: 34%; top: 0;   width: 46%; height: 54%; background: #35A8B8; opacity: .40; }
.aurora i:nth-child(3) { left: 62%; top: 10%; width: 44%; height: 42%; background: #6E6ADB; opacity: .34; }

/* A scatter of stars, hand-placed rather than tiled: a repeating pattern
   reads as a texture, and the sky is not a texture. */
.stars {
  position: absolute; inset: 0; pointer-events: none; opacity: .55;
  background-image:
    radial-gradient(1.4px 1.4px at 12% 18%, #fff, transparent),
    radial-gradient(1px 1px   at 27% 9%,   #fff, transparent),
    radial-gradient(1.6px 1.6px at 41% 24%, #fff, transparent),
    radial-gradient(1px 1px   at 55% 7%,   #fff, transparent),
    radial-gradient(1.2px 1.2px at 68% 20%, #fff, transparent),
    radial-gradient(1px 1px   at 79% 11%,  #fff, transparent),
    radial-gradient(1.5px 1.5px at 91% 22%, #fff, transparent),
    radial-gradient(1px 1px   at 7%  38%,  #fff, transparent),
    radial-gradient(1.3px 1.3px at 33% 44%, #fff, transparent),
    radial-gradient(1px 1px   at 61% 39%,  #fff, transparent),
    radial-gradient(1.2px 1.2px at 86% 47%, #fff, transparent),
    radial-gradient(1px 1px   at 19% 62%,  #fff, transparent),
    radial-gradient(1.4px 1.4px at 47% 71%, #fff, transparent),
    radial-gradient(1px 1px   at 73% 66%,  #fff, transparent),
    radial-gradient(1.1px 1.1px at 95% 78%, #fff, transparent),
    radial-gradient(1px 1px   at 4%  86%,  #fff, transparent);
}

/* ── The coast-to-coast trail ────────────────────────────────────────────
   The product's own metaphor at national scale: stops, in order, with the
   distance between them. Every number is a real road distance, which is why
   the total is allowed to be the headline. */
.cc { position: relative; margin: clamp(36px, 5vw, 60px) 0 0; }

.cc-rail { position: relative; height: 216px; }
.cc-line {
  /* Inset to match the track, so the road starts at Victoria and stops at
     St. John's rather than running off into two oceans. */
  position: absolute; left: 66px; right: 66px; top: 50%; height: 3px;
  transform-origin: left center;
  background-image: repeating-linear-gradient(90deg,
    #E06B45 0 11px, transparent 11px 24px);
}

/* The track is inset by half a label, so a stop at 0% or 100% still has its
   name fully inside the container instead of hanging off the end. */
.cc-stops {
  list-style: none; margin: 0; padding: 0;
  position: absolute; inset: 0 66px;
}
.cc-stop { position: absolute; top: 50%; width: 132px; margin-left: -66px; text-align: center; }
.cc-stop .pin {
  position: absolute; left: 50%; top: 0; translate: -50% -50%;
  width: 17px; height: 17px; border-radius: 50%;
  background: #0A1214; border: 3px solid #E06B45;
  box-shadow: 0 0 0 5px rgba(224,107,69,.16);
}
.cc-stop .who { position: absolute; left: 0; right: 0; }
.cc-stop:nth-child(odd)  .who { bottom: 26px; }
.cc-stop:nth-child(even) .who { top: 26px; }

.cc-stop .city { display: block; font-weight: 650; font-size: .96rem; color: #F4FAF6; letter-spacing: -.01em; }
.cc-stop .hood { display: block; font-size: .78rem; color: #9DB4AB; margin-top: 1px; }
.cc-stop .leg  { display: block; font-size: .74rem; color: #E89272; margin-top: 4px;
                 font-variant-numeric: tabular-nums; }

/* Totals */
.cc-figures {
  display: flex; flex-wrap: wrap; gap: clamp(24px, 5vw, 56px);
  justify-content: center; margin-top: clamp(28px, 4vw, 44px);
  padding-top: 28px; border-top: 1px solid #1E2C2B;
}
.cc-figures div { text-align: center; }
.cc-figures .v {
  display: block; font-family: Fraunces, Georgia, serif; font-weight: 700;
  font-size: clamp(1.9rem, 4vw, 2.8rem); line-height: 1; color: #FFF3E6;
  font-variant-numeric: tabular-nums;
}
.cc-figures .k { display: block; margin-top: 8px; font-size: .82rem; color: #9DB4AB; }

.north-actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 36px; }
.north .btn { background: #E06B45; border-color: #E06B45; color: #1B120D; }
.north .btn:hover { background: #F0805C; border-color: #F0805C; color: #1B120D; }
.north .btn.ghost { background: transparent; color: #8FE0C0; border-color: rgba(143,224,192,.45); }
.north .btn.ghost:hover { background: rgba(143,224,192,.12); color: #A9EBD1; border-color: #8FE0C0; }

/* The candour note. Same job as the "honest about where we are" box on the
   brewery page: say the unglamorous part before someone finds it out. */
.north-note {
  max-width: 46rem; margin: 34px auto 0; padding: 18px 22px;
  background: rgba(255,255,255,.045); border: 1px solid #1E2C2B;
  border-left: 3px solid #7FD3B4; border-radius: 0 12px 12px 0;
  font-size: .92rem; color: #B6CCC3;
}
.north-note strong { color: #E8F1EC; }
.north-note code {
  font-size: .88em; background: rgba(255,255,255,.07);
  border: 1px solid #263634; border-radius: 5px; padding: 1px 5px; color: #CFE6DC;
}

/* Stacked, the rail becomes what it is underneath: an ordered list of stops,
   which is also what a screen reader has been reading all along. */
@media (max-width: 940px) {
  .cc-rail { height: auto; }
  .cc-line { display: none; }
  .cc-stops { position: static; inset: auto; display: grid; gap: 2px; }
  .cc-stop {
    position: static; width: auto; margin: 0; text-align: left;
    display: grid; grid-template-columns: 24px 1fr; align-items: center;
    gap: 14px; padding: 12px 0; border-bottom: 1px solid #1B2827;
  }
  .cc-stop:last-child { border-bottom: 0; }
  .cc-stop .pin { position: static; translate: none; box-shadow: none; }
  .cc-stop .who { position: static; }
  .cc-stop .leg { margin-top: 2px; }
}

/* ── Cards, grid, pricing (carried from the original pages) ──────────────── */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); padding: 26px; position: relative; overflow: hidden;
}
.card h3 { margin-top: 0; }
.card p { color: var(--muted); margin-bottom: 0; }
.card .ico {
  width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  background: var(--accent-wash); color: var(--accent); margin-bottom: 14px;
}
.card .ico svg { width: 22px; height: 22px; }
.card.featured { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }

.price { font-family: Fraunces, Georgia, serif; font-size: 2.5rem; font-weight: 600; line-height: 1; }
.price span { font-size: .95rem; color: var(--muted); font-family: inherit; font-weight: 400; }


/* ── Numbers strip ───────────────────────────────────────────────────────── */
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; }
.figures div { padding: 18px 20px; border-left: 2px solid var(--border); }
.figures .v {
  font-family: Fraunces, Georgia, serif; font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700; line-height: 1; display: block; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.figures .k { color: var(--muted); font-size: .9rem; margin-top: 6px; display: block; }


/* ── Long-form pages ─────────────────────────────────────────────────────── */
.prose { max-width: 760px; }
.prose h2 { border-top: 1px solid var(--border); padding-top: 1.75rem; }
.prose ul, .prose ol { padding-left: 1.2rem; }
.prose li { margin: .35rem 0; }
.prose hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }
.prose code {
  font-size: .92em; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px;
}

/* The privacy policy's "what we collect" tables. Wide by nature, so they get
   their own scroller rather than pushing the whole page sideways on a phone. */
.table-scroll { overflow-x: auto; margin: 1.25rem 0; -webkit-overflow-scrolling: touch; }
.prose table { border-collapse: collapse; width: 100%; min-width: 460px; font-size: .93rem; }
.prose th, .prose td {
  text-align: left; vertical-align: top;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
}
.prose thead th {
  background: var(--surface-2); border-bottom: 2px solid var(--border-firm);
  font-size: .76rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}
.prose tbody tr:last-child td { border-bottom: 0; }
.prose td:first-child { width: 34%; }
.prose .note, .note {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--secondary);
  padding: 16px 20px; border-radius: 0 10px 10px 0; margin: 1.25rem 0;
}

/* The safety line, carried from the app so it reads the same in both. */
.safety {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  padding: 18px 22px; border-radius: 0 12px 12px 0; margin: 2rem 0;
  font-size: .95rem; display: flex; gap: 14px; align-items: flex-start;
}
.safety svg { width: 22px; height: 22px; flex: none; color: var(--accent); margin-top: 2px; }


/* ── Closing call to action ──────────────────────────────────────────────── */
/* A lit panel, the same idea as the badge stage and the Canada band: it
   keeps one identity in both themes. Built on tokens it did the opposite —
   in dark mode --accent lightens and --on-accent goes near-black, so the
   page's calmest moment turned into a glowing orange slab with black type. */
.finale {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg); padding: clamp(40px, 6vw, 72px);
  background: linear-gradient(158deg, #C1502E 0%, #A63A2B 58%, #7A2A1E 100%);
  color: #FFF8F0; text-align: center;
  box-shadow: var(--shadow-md);
}
.finale::before {
  content: ""; position: absolute; inset: -40% -10%;
  background: repeating-radial-gradient(ellipse 40% 34% at 50% 50%, transparent 0 24px, rgba(255,255,255,.13) 24px 25px);
  -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000, transparent 70%);
          mask-image: radial-gradient(ellipse at 50% 50%, #000, transparent 70%);
  pointer-events: none;
}
.finale > * { position: relative; }
/* The one place the mark is shown large enough to read every word of it,
   and the place it earns that: this is the icon you will be scanning the
   App Store for. Cream ring so the badge's own cream edge does not
   disappear into the terracotta behind it. */
.finale-mark {
  width: clamp(124px, 17vw, 172px); height: auto;
  display: block; margin: 0 auto 1.5rem;
  border-radius: 50%;
  box-shadow: 0 0 0 5px rgba(255,248,240,.22), 0 18px 40px rgba(0,0,0,.28);
}
.finale h2 { color: inherit; margin-top: 0; font-size: clamp(2rem, 4.6vw, 3.2rem); }
.finale p { color: rgba(255,248,240,.86); font-size: 1.1rem; max-width: 34rem; margin-inline: auto; }
.finale .btn {
  background: #FFF8F0; color: #A63A2B; border-color: #FFF8F0;
  margin-top: .5rem;
}
.finale .btn:hover { background: #fff; color: #8F3124; border-color: #fff; }
.finale .fine { font-size: .84rem; color: rgba(255,248,240,.72); margin-top: 1.25rem; }

/* The store badge, drawn rather than borrowed — the app is not on the store
   yet, and a real Apple badge would imply it is. */
.store-badge {
  display: inline-flex; align-items: center; gap: 12px;
  border: 1px solid rgba(255,255,255,.42); border-radius: 14px;
  padding: 12px 22px; color: inherit; text-decoration: none; font-weight: 600;
}
.store-badge svg { width: 26px; height: 26px; }
.store-badge small { display: block; font-size: .68rem; font-weight: 500; opacity: .8;
                     letter-spacing: .06em; text-transform: uppercase; }
.store-badge b { font-size: 1.06rem; font-weight: 650; }


/* ── Showcase / feature rows (still used by the interior pages) ──────────── */
.showcase {
  background: linear-gradient(170deg, var(--surface-2) 0%, var(--accent-wash) 45%, var(--accent) 100%);
  border-radius: var(--r-lg); padding: 56px 24px 0; margin: 40px 0 8px;
  overflow: hidden; text-align: center;
}
.feature-row {
  display: grid; gap: 40px; align-items: center;
  grid-template-columns: 1fr 1fr; margin: 72px 0;
}
.feature-row .copy h2 { margin-top: 0; }
.feature-row .copy p { color: var(--muted); font-size: 1.05rem; }
.feature-row .shot { text-align: center; }
.feature-row.reverse .shot { order: -1; }
@media (max-width: 820px) {
  .feature-row { grid-template-columns: 1fr; gap: 24px; }
  .feature-row.reverse .shot { order: 0; }
  .showcase { padding: 40px 16px 0; }
}


/* ── Footer ──────────────────────────────────────────────────────────────
   Reading text is always --muted, never --taupe: taupe on the cream ground
   is about 3.5:1, under the 4.5:1 small-text minimum. Taupe stays for
   strokes, pin outlines and other decoration. */
footer.site {
  border-top: 1px solid var(--border); margin-top: 72px; background: var(--bg-sink);
  padding: 44px 0 56px; color: var(--muted); font-size: .9rem;
}
footer.site nav { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 16px; }
footer.site a { color: var(--muted); }
footer.site a:hover { color: var(--accent); }


/* ── Motion ──────────────────────────────────────────────────────────────
   Restrained on purpose: content arrives, it does not perform. Everything
   here sits inside a reduced-motion guard, because vestibular disorders are
   real and a marketing page is a poor reason to trigger one. */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0; transform: translateY(20px);
    transition: opacity .75s var(--ease), transform .75s var(--ease);
  }
  .reveal.in { opacity: 1; transform: none; }
  .reveal.d1 { transition-delay: .08s; }
  .reveal.d2 { transition-delay: .16s; }
  .reveal.d3 { transition-delay: .24s; }

  .hero .eyebrow, .hero h1, .hero .lead, .hero .hero-cta, .hero .pill-row {
    animation: rise .85s var(--ease) both;
  }
  .hero h1        { animation-delay: .06s; }
  .hero .lead     { animation-delay: .14s; }
  .hero .hero-cta { animation-delay: .22s; }
  .hero .pill-row { animation-delay: .30s; }
  @keyframes rise { from { opacity: 0; transform: translateY(22px); } }

  .stage .phone-tilt { animation: rise 1s var(--ease) .1s both, bob 7s ease-in-out 1.2s infinite; }
  @keyframes bob { 50% { translate: 0 -12px; } }

  .float { animation: rise .7s var(--spring) both; }
  .float.one   { animation-delay: .9s; }
  .float.two   { animation-delay: 1.1s; }
  .float.three { animation-delay: 1.3s; }

  /* The route behind the phone draws itself once, on load. */
  .stage .route path { stroke-dashoffset: 600; animation: draw 2.4s var(--ease) .3s forwards; }
  @keyframes draw { to { stroke-dashoffset: 0; } }
  .stage .route circle { opacity: 0; animation: pin .6s var(--spring) forwards; }
  .stage .route circle:nth-of-type(1) { animation-delay: .7s; }
  .stage .route circle:nth-of-type(2) { animation-delay: 1.2s; }
  .stage .route circle:nth-of-type(3) { animation-delay: 1.7s; }
  .stage .route circle:nth-of-type(4) { animation-delay: 2.2s; }
  @keyframes pin { from { opacity: 0; r: 0; } to { opacity: 1; } }

  /* The route in the builder redraws whenever the stops change. */
  .route-line { animation: crawl 1.1s linear infinite; }
  @keyframes crawl { to { stroke-dashoffset: -36; } }

  /* The aurora drifts. Slow enough that you notice it has moved rather than
     watching it move — anything faster turns a background into an event. */
  .aurora i { animation: drift 26s ease-in-out infinite alternate; }
  .aurora i:nth-child(2) { animation-duration: 34s; animation-delay: -8s; }
  .aurora i:nth-child(3) { animation-duration: 30s; animation-delay: -16s; }
  @keyframes drift {
    from { transform: translate3d(-6%, 0, 0) scale(1);    opacity: .30; }
    to   { transform: translate3d(8%, 4%, 0) scale(1.14); opacity: .52; }
  }

  /* The rail draws west to east, then the stops land along it. */
  .cc-line { transform: scaleX(0); transition: transform 1.6s var(--ease); }
  .cc.in .cc-line { transform: scaleX(1); }

  /* Hidden only while the section is still waiting. Putting `opacity: 0` on
     .cc-stop itself would also become the animation's end state — `rise` has
     no `to`, so it resolves to the element's own computed style — and every
     stop would fade back out the moment it arrived. */
  .cc:not(.in) .cc-stop { opacity: 0; }
  .cc.in .cc-stop { animation: rise .6s var(--spring) both; }
  .cc.in .cc-stop:nth-child(1) { animation-delay: .30s; }
  .cc.in .cc-stop:nth-child(2) { animation-delay: .45s; }
  .cc.in .cc-stop:nth-child(3) { animation-delay: .60s; }
  .cc.in .cc-stop:nth-child(4) { animation-delay: .75s; }
  .cc.in .cc-stop:nth-child(5) { animation-delay: .90s; }
  .cc.in .cc-stop:nth-child(6) { animation-delay: 1.05s; }
  .cc.in .cc-stop:nth-child(7) { animation-delay: 1.20s; }
  .cc.in .cc-stop:nth-child(8) { animation-delay: 1.35s; }
  .cc.in .cc-stop:nth-child(9) { animation-delay: 1.50s; }

  .ticker-track { animation: slide 46s linear infinite; }
  .ticker:hover .ticker-track { animation-play-state: paused; }
  @keyframes slide { to { transform: translateX(-50%); } }

  .phone, .card, .btn, .patch-card {
    transition: transform .4s var(--ease), box-shadow .4s var(--ease), border-color .3s ease;
  }
  .card:hover { transform: translateY(-4px); border-color: var(--border-firm); box-shadow: var(--shadow-md); }
  .btn:hover  { transform: translateY(-2px); }
  .btn::after { transition: left .55s var(--ease); }
  .btn:hover::after { left: 120%; }
  .patch-card:hover { transform: translateY(-5px); }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
  .cc-line { transform: scaleX(1); }
  .cc-stop { opacity: 1; transform: none; }
  .swash { background-size: 100% 6px; animation: none; }
  .patch-card svg { opacity: 1; transform: none; }
}


/* ── Notify-me form (breweries.html) ─────────────────────────────────────── */
.notify { margin: clamp(24px, 3vw, 40px) auto 0; padding: clamp(24px, 3vw, 40px); max-width: 44rem; text-align: center; }
.notify h3 { font-size: clamp(1.25rem, 2.2vw, 1.6rem); max-width: 34rem; margin-inline: auto; }
.notify-form { margin: 20px auto 0; text-align: left; }
.notify-form .btn { display: block; margin-inline: auto; }
.notify-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px 16px; }
.notify-grid label { grid-column: span 3; }
.notify-grid label { display: flex; flex-direction: column; gap: 6px; font-size: .9rem; font-weight: 600; color: var(--text); }
.notify-grid .wide { grid-column: 1 / -1; }
.notify-grid .c3 { grid-column: span 3; }
.notify-grid .c1 { grid-column: span 1; }
.notify-grid .c2 { grid-column: span 2; }
.notify-grid input {
  font: inherit; font-weight: 400; color: var(--text); background: var(--bg);
  border: 1px solid var(--border-firm); border-radius: 12px; padding: 12px 14px; min-height: 48px;
}
.notify-grid input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.notify-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.notify-form .btn { margin-top: 18px; cursor: pointer; }
.notify-form .btn:disabled { opacity: .6; cursor: default; }
.notify-status { min-height: 1.5em; margin: 14px 0 0; font-size: .95rem; color: var(--muted); }
.notify-status.ok { color: var(--secondary); font-weight: 600; }
.notify-status.err { color: var(--accent-deep); font-weight: 600; }
@media (max-width: 560px) { .notify-grid { grid-template-columns: 1fr; } .notify-grid label, .notify-grid .c1, .notify-grid .c2, .notify-grid .c3 { grid-column: 1 / -1; } }


/* ── Launch sign-up (index.html, inside .finale) ─────────────────────────── */
.launch-form { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; max-width: 36rem; margin: 1.75rem auto 0; }
.launch-form input[type="email"] {
  flex: 1 1 15rem; min-height: 54px; padding: 0 18px; border-radius: 999px; border: 2px solid transparent;
  font: inherit; font-size: 1.02rem; color: #2B2019; background: #FFF8F0;
}
.launch-form input[type="email"]::placeholder { color: #8C7A68; }
.launch-form input[type="email"]:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.launch-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.launch-form .btn { cursor: pointer; margin: 0; }
.launch-form .btn:disabled { opacity: .65; cursor: default; }
.launch-status { flex: 1 1 100%; min-height: 1.5em; margin: 2px 0 0; font-size: .98rem; color: rgba(255,248,240,.9); }
.launch-status.ok { font-weight: 600; color: #fff; }
.launch-status.err { font-weight: 600; color: #FFE1C7; }
