/* ============================================================================
   Sunny Days Digital — THE stylesheet (SPEC §3, CLAUDE.md rule 1)
   ----------------------------------------------------------------------------
   This is the ONLY authored stylesheet in the factory. Every site in the
   portfolio loads this file unchanged, then a generated tokens.css that
   contains nothing but :root custom-property overrides from config.yaml.

   Rules for editing:
     - No literal colors below :root. Use var(--*).
     - No new effects in page templates. Add a shared class here instead.
     - Effects are CSS-only. No animation libraries, no JS-driven motion.
     - Contrast meets WCAG AA against --bg. Readable on a phone in sunlight
       beats pretty.
   ========================================================================== */

/* ---------------------------------------------------------------- 1. Tokens */

:root {
  /* -- Surfaces. Site-overridable via config.yaml -> tokens.css ------------ */
  --bg: #0c0f0a;
  --bg2: #141a0f;
  --card: #1a2114;
  --card-hover: #212b1a;
  --border: rgba(134, 239, 172, 0.08);

  /* -- Accents. Site-overridable ------------------------------------------ */
  --green: #4ade80;
  --green-dim: #22c55e;
  --green-dark: #166534;
  --lime: #a3e635;
  --amber: #fbbf24;
  --purple: #c084fc;
  --rose: #fb7185;

  /* -- Type colors. Site-overridable -------------------------------------- */
  --white: #f0fdf4;
  --text: #c2d6ba;
  /* --muted carries most body copy. The live site's #6b7f64 measured 3.81:1 on
     cards and 3.40:1 on card-hover — below the 4.5:1 AA floor SPEC §3 sets as
     non-negotiable. Same hue, lightened 19%: worst case is now 4.63:1. Do not
     darken this without re-measuring against --card-hover, the lightest
     surface it ever sits on. */
  --muted: #7f9777;

  /* -- Derived accent washes. Kept as tokens so hover/glow states never
        hard-code an rgba() halfway down the file. --------------------------- */
  --accent-wash: rgba(74, 222, 128, 0.06);
  --accent-line: rgba(74, 222, 128, 0.2);
  --accent-line-hover: rgba(74, 222, 128, 0.3);
  --accent-glow: rgba(74, 222, 128, 0.12);
  --accent-glow-soft: rgba(74, 222, 128, 0.08);

  /* Section background loops sit this far below the copy. Anything above ~0.2
     starts costing text contrast, which WCAG AA wins (SPEC §3). */
  --bg-video-opacity: 0.12;
  --shadow-cast: rgba(0, 0, 0, 0.3);
  --shadow-cast-deep: rgba(0, 0, 0, 0.4);
  --danger: #f87171;

  /* -- Fonts --------------------------------------------------------------- */
  --font-body: "Outfit", system-ui, -apple-system, sans-serif;
  --font-display: "Fraunces", Georgia, serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* -- Type scale ---------------------------------------------------------- */
  --fs-3xs: 0.65rem;
  --fs-2xs: 0.7rem;
  --fs-xs: 0.78rem;
  --fs-sm: 0.85rem;
  --fs-base: 0.95rem;
  --fs-md: 1.05rem;
  --fs-lg: 1.3rem;
  --fs-xl: 1.6rem;
  --fs-hero: clamp(2.8rem, 5.5vw, 4.2rem);
  --fs-h2: clamp(1.8rem, 3.5vw, 2.4rem);

  /* -- Spacing ------------------------------------------------------------- */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.25rem;
  --sp-6: 1.5rem;
  --sp-8: 2rem;
  --sp-12: 3rem;
  --sp-16: 4rem;

  /* -- Radii --------------------------------------------------------------- */
  --r-sm: 6px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-pill: 100px;

  /* -- Layout -------------------------------------------------------------- */
  --w-wide: 1200px;
  --w-mid: 1000px;
  --w-narrow: 900px;
  --w-prose: 800px;

  /* -- Motion -------------------------------------------------------------- */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 0.2s;
  --t-mid: 0.3s;
  --t-slow: 0.4s;
}

/* ------------------------------------------------------------- 2. Reset/base */

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  overflow-x: hidden;
}

img,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--green);
}

/* Keyboard focus must always be visible — AA requirement. */
:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: var(--sp-3) var(--sp-4);
  background: var(--green);
  color: var(--bg);
  font-weight: 700;
  border-radius: 0 0 var(--r-md) 0;
}
.skip-link:focus {
  left: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------- 3. Effect classes */
/* Templates compose these. They never invent their own effects (SPEC §3).   */

/* .glass — frosted translucent surface for overlays and sticky nav */
.glass {
  background: color-mix(in srgb, var(--card) 72%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--border);
}

/* .lift — hover elevation + accent border + inner glow */
.lift {
  position: relative;
  transition: transform var(--t-slow) var(--ease),
    box-shadow var(--t-slow) var(--ease), border-color var(--t-slow) var(--ease),
    background var(--t-slow) var(--ease);
}
.lift:hover {
  transform: translateY(-4px);
  border-color: var(--accent-line-hover);
  box-shadow: 0 0 20px var(--accent-glow), 0 4px 24px var(--shadow-cast),
    inset 0 0 20px var(--accent-wash);
}

/* .shimmer — diagonal light sweep across a card on hover */
.shimmer::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    105deg,
    transparent 40%,
    var(--accent-wash) 45%,
    var(--accent-glow) 50%,
    var(--accent-wash) 55%,
    transparent 60%
  );
  background-size: 200% 100%;
  opacity: 0;
  transition: opacity var(--t-mid);
  pointer-events: none;
  z-index: 1;
}
.shimmer:hover::after {
  opacity: 1;
  animation: shimmer 1.2s ease-in-out;
}

@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

/* .fade-in — scroll-reveal.
   Content is visible by DEFAULT and only hides once the script has proved it
   can run the reveal, by putting .js-reveal on <html>. Never make visibility
   depend on a callback firing: if IntersectionObserver is missing, blocked, or
   throws, the page must still render its content rather than go blank. */
.fade-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.js-reveal .fade-in {
  opacity: 0;
  transform: translateY(30px);
}
.js-reveal .fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}

@keyframes pulse-glow {
  0%,
  100% {
    box-shadow: 0 0 8px transparent, 0 0 20px transparent;
  }
  50% {
    box-shadow: 0 0 12px var(--accent-glow), 0 0 30px var(--accent-glow-soft);
  }
}
.pulse {
  animation: pulse-glow 3s ease-in-out infinite;
}

/* Motion is decoration. Anyone who asks for less gets none of it. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js-reveal .fade-in,
  .js-reveal .fade-in.visible {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------------ 4. Atmosphere */

.atmosphere {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
      ellipse at 15% 20%,
      var(--accent-wash) 0%,
      transparent 50%
    ),
    radial-gradient(
      ellipse at 85% 80%,
      color-mix(in srgb, var(--lime) 4%, transparent) 0%,
      transparent 50%
    ),
    radial-gradient(
      ellipse at 50% 50%,
      color-mix(in srgb, var(--purple) 3%, transparent) 0%,
      transparent 40%
    ),
    var(--bg);
}

.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.3;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------- 5. Age gate */
/* Cannabis profile only (SPEC §4). Rendered by base.html.j2 when
   config.profile.age_gate is true. Blocks the page until acknowledged. */

.age-gate {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.age-gate[hidden] {
  display: none;
}
.age-gate-box {
  max-width: 460px;
  width: 100%;
  padding: var(--sp-8);
  border-radius: var(--r-xl);
  background: var(--card);
  border: 1px solid var(--accent-line);
  box-shadow: 0 0 40px var(--accent-glow-soft), 0 20px 60px var(--shadow-cast-deep);
  text-align: center;
}
.age-gate-box h2 {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 900;
  color: var(--white);
  margin-bottom: var(--sp-3);
}
.age-gate-box p {
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: var(--sp-6);
}
.age-gate-actions {
  display: flex;
  gap: var(--sp-3);
  justify-content: center;
  flex-wrap: wrap;
}
.age-gate-deny {
  font-size: var(--fs-xs);
  color: var(--muted);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-family: var(--font-body);
}
.age-gate-deny:hover {
  color: var(--text);
}

/* ------------------------------------------------------------------ 6. Nav */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  transition: background var(--t-mid), border-color var(--t-mid);
  border-bottom: 1px solid transparent;
}
/* .scrolled is toggled by base.html.j2; pairs with .glass */
.site-nav.scrolled {
  border-bottom-color: var(--border);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: var(--sp-5) var(--sp-8);
}
.logo {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 900;
  color: var(--white);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.logo-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--bg), var(--bg2));
  border: 1px solid var(--accent-line);
  padding: 5px;
  font-size: var(--fs-md);
}
.nav-links {
  display: flex;
  gap: var(--sp-8);
  align-items: center;
}
.nav-links a {
  font-size: var(--fs-sm);
  color: var(--muted);
  text-decoration: none;
  font-weight: 500;
  transition: color var(--t-fast);
}
.nav-links a:hover {
  color: var(--green);
}

/* Mobile menu button. Hidden here and revealed below 900px — and only for
   browsers that ran the script, since it is the script that opens the panel.
   44px square is the smallest comfortable tap target on a phone. */
.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  color: var(--white);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.nav-toggle:hover {
  border-color: var(--accent-line-hover);
  background: var(--accent-wash);
}
.nav-toggle-bars {
  position: relative;
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: background var(--t-fast);
}
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--t-fast);
}
.nav-toggle-bars::before {
  top: -6px;
}
.nav-toggle-bars::after {
  top: 6px;
}
/* Open: the bars cross into an X. Middle bar goes transparent, not display
   none, so the two pseudo-elements keep their box to rotate around. */
.nav-toggle.open .nav-toggle-bars {
  background: transparent;
}
.nav-toggle.open .nav-toggle-bars::before {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle.open .nav-toggle-bars::after {
  transform: translateY(-6px) rotate(-45deg);
}

/* --------------------------------------------------- 6b. Hub path chooser */

/* The three routes off the homepage. Whole card is the link — a small "read
   more" target is the wrong shape on a phone, where these stack. */
.path-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
}
.path-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-8);
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  text-decoration: none;
  color: var(--text);
}
.path-card h3 {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  color: var(--white);
  line-height: 1.15;
}
.path-card p {
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
  flex: 1;
}
.path-icon {
  font-size: 2rem;
  line-height: 1;
}
.path-cta {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--green);
}
.path-card:hover .path-cta {
  color: var(--lime);
}

/* Route-out link under a homepage teaser section. */
.section-more {
  margin-top: var(--sp-8);
  text-align: center;
}

/* ------------------------------------------------------------ 6c. Game cards */

.game-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  background: var(--card);
}
.game-thumb {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.game-thumb .media-slot,
.game-thumb .media-placeholder,
.game-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.game-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-6);
}
.game-body h3 {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: var(--white);
}
.game-body p {
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
  flex: 1;
}
.game-card:hover .path-cta {
  color: var(--lime);
}

/* ----------------------------------------------------------------- 7. Hero */

.hero {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: 5rem var(--sp-8) var(--sp-16);
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--sp-16);
  align-items: center;
  position: relative;
  z-index: 1;
}
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--green);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  margin-bottom: var(--sp-4);
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
}
.hero-text h1 {
  font-family: var(--font-display);
  font-size: var(--fs-hero);
  font-weight: 900;
  color: var(--white);
  line-height: 1.08;
  margin-bottom: var(--sp-6);
}
.hero-text h1 .accent {
  background: linear-gradient(135deg, var(--green), var(--lime));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero-text p {
  font-size: 1.1rem;
  color: var(--muted);
  line-height: 1.7;
  max-width: 520px;
  margin-bottom: var(--sp-8);
}
.hero-ctas {
  display: flex;
  gap: var(--sp-4);
  flex-wrap: wrap;
}
.hero-visual {
  position: relative;
  display: flex;
  justify-content: center;
}
/* The floating stat stack. The stagger is per-COLUMN, not per-child index:
   the old rule offset children 2 and 3 by different amounts, which only
   composed into an even arrangement at exactly four cards. At three it left a
   hole and three different-looking gaps. Keying on :nth-child(even) means the
   right-hand column always sits lower by the same amount, so any number of
   cards reads as deliberate and every gap is identical. */
.stat-stack {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5);
  transform: rotate(-2deg);
  align-items: start;
}
.stat-card {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
}
.stat-card:nth-child(even) {
  transform: translateY(1.25rem);
}
/* Sized against the number below it, not as an afterthought — at --fs-xl the
   icon read as a stray character next to a display-face figure. */
.stat-icon {
  font-size: 2rem;
  line-height: 1;
  margin-bottom: var(--sp-3);
}
.stat-number {
  font-family: var(--font-display);
  font-size: 2.2rem;
  font-weight: 900;
  color: var(--white);
  margin-bottom: var(--sp-1);
}
.stat-label {
  font-size: var(--fs-xs);
  color: var(--muted);
  font-weight: 500;
}

/* --------------------------------------------------------------- 8. Buttons */

.btn-primary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.9rem var(--sp-8);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  border-radius: var(--r-md);
  text-decoration: none;
  transition: all var(--t-mid);
  cursor: pointer;
}
.btn-primary {
  background: linear-gradient(135deg, var(--green), var(--green-dim));
  color: var(--bg);
  font-weight: 700;
  border: none;
  box-shadow: 0 4px 20px color-mix(in srgb, var(--green) 25%, transparent);
}
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 30px color-mix(in srgb, var(--green) 35%, transparent);
}
.btn-ghost {
  background: transparent;
  color: var(--green);
  font-weight: 600;
  border: 1.5px solid var(--accent-line);
}
.btn-ghost:hover {
  background: var(--accent-wash);
  border-color: var(--green);
}

/* -------------------------------------------------------- 9. Section chrome */

.section {
  position: relative;
  z-index: 1;
}
.section-header {
  text-align: center;
  max-width: 700px;
  margin: 0 auto var(--sp-12);
  padding: var(--sp-16) var(--sp-8) 0;
}
.section-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--green);
  margin-bottom: var(--sp-3);
  padding: 0.3rem var(--sp-4);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
}
.section-header h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 900;
  color: var(--white);
  margin-bottom: var(--sp-3);
  transition: text-shadow var(--t-slow);
}
.section-header:hover h2 {
  text-shadow: 0 0 20px var(--accent-glow-soft);
}
.section-header p {
  font-size: var(--fs-base);
  color: var(--muted);
  line-height: 1.6;
}
.section-body {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: 0 var(--sp-8) var(--sp-16);
}
.section-body.narrow {
  max-width: var(--w-mid);
}
.section-body.prose {
  max-width: var(--w-prose);
}
.highlight {
  color: var(--green);
  font-weight: 600;
}

/* ------------------------------------------------------------- 10. Grids */

.grid-auto-wide {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--sp-5);
}
.grid-auto-narrow {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--sp-5);
}
.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5);
}
.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-5);
}
.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-4);
}

/* --------------------------------------------------------- 11. Notice box */
/* Neutral emphasis panel — legal updates, policy notes, callouts. */

.notice-box {
  padding: 2.5rem;
  border-radius: var(--r-xl);
  background: linear-gradient(
    135deg,
    var(--accent-wash),
    color-mix(in srgb, var(--lime) 4%, transparent)
  );
  border: 1px solid var(--accent-line);
  box-shadow: 0 0 30px var(--accent-glow-soft), 0 4px 40px var(--shadow-cast);
  position: relative;
  overflow: hidden;
}
.notice-box::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at 30% 40%,
    var(--accent-wash),
    transparent 70%
  );
  pointer-events: none;
}
.notice-box > * {
  position: relative;
}
.notice-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 900;
  color: var(--white);
  margin-bottom: var(--sp-2);
}
.notice-lede {
  font-size: var(--fs-base);
  color: var(--text);
  margin-bottom: var(--sp-6);
  line-height: 1.7;
}
.notice-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-8);
  text-align: left;
  margin-bottom: var(--sp-6);
}
.notice-cols h4 {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--green);
  margin-bottom: var(--sp-3);
}
.notice-cols li {
  font-size: var(--fs-sm);
  color: var(--text);
  line-height: 1.7;
  margin-bottom: var(--sp-2);
  list-style: none;
  padding-left: var(--sp-4);
  position: relative;
}
.notice-cols li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--green);
}
.notice-actions {
  display: flex;
  justify-content: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
}
.notice-foot {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-top: var(--sp-6);
}
.notice-foot strong {
  color: var(--text);
}

/* --------------------------------------------------------- 12. Local cards */

.local-card {
  padding: 1.75rem;
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
  text-align: center;
  overflow: hidden;
}
.local-card .icon {
  font-size: var(--sp-8);
  margin-bottom: var(--sp-3);
}
.local-card h4 {
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-2);
}
.local-card p {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.5;
}

/* ------------------------------------------------------ 13. Dispensary card */

.disp-card {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
  overflow: hidden;
}
.disp-card:hover {
  background: var(--card-hover);
}
.disp-card:hover .disp-name {
  text-shadow: 0 0 12px var(--accent-line-hover);
}
.disp-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.disp-name {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--white);
}
.disp-badge {
  font-size: var(--fs-3xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: var(--sp-1) 0.6rem;
  border-radius: var(--r-sm);
  background: var(--accent-glow);
  color: var(--green);
  white-space: nowrap;
}
.disp-neighborhood {
  font-size: 0.72rem;
  color: var(--green-dim);
  font-weight: 600;
  margin-bottom: var(--sp-2);
}
.disp-address {
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: var(--sp-2);
}
.disp-address a {
  color: var(--muted);
  text-decoration: none;
}
.disp-address a:hover {
  color: var(--green);
}
.disp-meta {
  display: flex;
  gap: var(--sp-6);
  font-size: var(--fs-xs);
  color: var(--muted);
  flex-wrap: wrap;
}
.disp-meta span {
  display: flex;
  align-items: center;
  gap: 0.3rem;
}
.star {
  color: var(--amber);
}
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-3);
}
.tag {
  font-size: 0.68rem;
  padding: 0.2rem 0.6rem;
  border-radius: var(--r-sm);
  background: var(--border);
  color: var(--text);
  font-weight: 500;
}

/* --------------------------------------------------------- 14. Product card */

.prod-card {
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.prod-card:hover {
  box-shadow: 0 0 25px var(--accent-glow), 0 8px 32px var(--shadow-cast-deep),
    inset 0 0 20px var(--accent-wash);
}
.prod-media {
  height: 200px;
  background: linear-gradient(135deg, var(--bg2), var(--card));
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
.prod-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 60%, var(--card));
  z-index: 2;
  pointer-events: none;
}
.prod-badge {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-4);
  font-size: var(--fs-3xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.3rem var(--sp-3);
  border-radius: var(--r-xl);
  z-index: 3;
}
.badge-best {
  background: var(--green);
  color: var(--bg);
}
/* Dark ink on every accent badge. --white on --purple measured 2.52:1; the
   accents are light colors, so the text on them has to be the dark one. */
.badge-popular {
  background: var(--purple);
  color: var(--bg);
}
.badge-value {
  background: var(--amber);
  color: var(--bg);
}
.prod-body {
  padding: var(--sp-5);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.prod-category {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--green);
  font-weight: 600;
  margin-bottom: var(--sp-2);
}
.prod-name {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-2);
}
.prod-desc {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.5;
  margin-bottom: var(--sp-4);
  flex: 1;
}
.prod-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
}
.prod-price {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--white);
}
.prod-link {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--green);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  transition: color var(--t-fast);
}
.prod-link:hover {
  color: var(--lime);
}

/* FTC disclosure — required above every affiliate section (CLAUDE.md rule 7) */
.affiliate-disclosure {
  max-width: var(--w-wide);
  margin: 0 auto var(--sp-6);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-md);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--amber);
  font-size: var(--fs-xs);
  color: var(--text);
  line-height: 1.6;
}
.affiliate-disclosure a {
  color: var(--amber);
}

/* ------------------------------------------------------------- 15. Law card */

.law-card {
  padding: var(--sp-8);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
  overflow: hidden;
}
.law-card .icon {
  font-size: var(--sp-8);
  margin-bottom: var(--sp-4);
}
.law-card h3 {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-3);
}
.law-card p {
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
}

/* ------------------------------------------------------------ 16. Step card */

.steps {
  counter-reset: step;
}
.step-card {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--border);
  text-align: center;
  counter-increment: step;
  overflow: hidden;
}
.step-card::before {
  content: counter(step);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--green), var(--lime));
  color: var(--bg);
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 900;
  margin: 0 auto var(--sp-4);
  transition: all var(--t-mid);
}
.step-card:hover::before {
  box-shadow: 0 0 20px var(--accent-line-hover);
  transform: scale(1.1);
}
.step-card h4 {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-2);
}
.step-card p {
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.5;
}

/* ------------------------------------------------------------------ 17. FAQ */

.faq-item {
  border-bottom: 1px solid var(--border);
  padding: var(--sp-6) 0;
}
.faq-q {
  font-size: 1rem;
  font-weight: 700;
  color: var(--white);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  font-family: var(--font-body);
}
.faq-q::after {
  content: "+";
  font-size: 1.4rem;
  color: var(--green);
  transition: transform var(--t-mid);
  flex-shrink: 0;
}
.faq-q[aria-expanded="true"]::after {
  transform: rotate(45deg);
}
.faq-a {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--t-slow) ease, padding var(--t-slow) ease;
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.7;
}
.faq-a.open {
  max-height: 800px;
  padding-top: var(--sp-4);
}
/* Without JS every answer is simply open — content stays readable/indexable. */
.no-js .faq-a {
  max-height: none;
  padding-top: var(--sp-4);
}

/* ------------------------------------------------------------ 18. Daily tip */

.tip-card {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: linear-gradient(
    135deg,
    var(--accent-wash),
    color-mix(in srgb, var(--lime) 3%, transparent)
  );
  border: 1px solid var(--accent-line);
}
.tip-eyebrow {
  font-size: var(--fs-3xs);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--green);
  font-weight: 700;
  margin-bottom: var(--sp-2);
}
.tip-text {
  font-size: var(--fs-base);
  color: var(--white);
  line-height: 1.7;
}
.tip-cat {
  display: inline-block;
  margin-top: var(--sp-3);
  font-size: 0.68rem;
  padding: var(--sp-1) var(--sp-3);
  background: var(--accent-wash);
  border-radius: var(--r-xl);
  color: var(--green);
}

/* --------------------------------------------------- 19. Media placeholders */
/* SPEC §6: a slot with no file still renders clean, at the right dimensions. */

.media-slot {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--bg2);
}
.media-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.media-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  height: 100%;
  min-height: 120px;
  background: linear-gradient(135deg, var(--bg2), var(--card));
  border: 1px dashed var(--accent-line);
  border-radius: var(--r-lg);
  color: var(--muted);
  text-align: center;
  padding: var(--sp-4);
}
.media-placeholder .icon {
  font-size: var(--fs-xl);
  opacity: 0.6;
}
.media-placeholder .label {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: 0.06em;
  word-break: break-all;
}

/* --------------------------------------------------------------- 19b. Video */
/* SPEC §6 allows short muted self-hosted loops only. Everything here is a
   shared class — the pre-rebuild site did this with inline style attributes,
   which rule 1 forbids. Any slot can degrade to its poster with no layout
   shift, so a blocked or unsupported video costs nothing. */

.media-slot video {
  display: block;
  width: 100%;
  height: auto;
}
/* Inside a product card the media box is a fixed height, so the slot fills it
   and the poster/video crop rather than stretch. ::after keeps its gradient on
   top (z-index 2). */
.prod-media .media-slot {
  position: absolute;
  inset: 0;
  border-radius: 0;
  z-index: 1;
}
.prod-media .media-slot video,
.prod-media .media-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Section background loops. .section already sets position:relative;z-index:1,
   so this sits behind the content without a stacking-context fight. */
.section-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
}
.section-bg video,
.section-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--bg-video-opacity);
}
.section-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--bg) 0%, transparent 25%, transparent 75%, var(--bg) 100%);
}
/* Lift the content above the background layer. Must exclude .section-bg itself:
   it is a sibling of the content, and this rule would otherwise override its
   position:absolute at equal specificity and collapse it to content size. */
.has-bg-video > *:not(.section-bg) {
  position: relative;
  z-index: 1;
}

/* Motion is decoration here, never information. Anyone who has asked their OS
   to calm down gets the poster frame instead — the JS also skips play(). */
@media (prefers-reduced-motion: reduce) {
  .section-bg video,
  .prod-media video {
    display: none;
  }
}

/* ------------------------------------------------------------ 19c. Legal doc */
/* Long-form compliance prose. Narrow measure, generous leading — these get
   read carefully or not at all, and AA contrast is not negotiable here. */

.legal-doc {
  max-width: 68ch;
  margin: 0 auto;
  color: var(--text);
  line-height: 1.75;
}
.legal-doc h3 {
  margin: var(--sp-8) 0 var(--sp-3);
  font-size: var(--fs-lg);
  color: var(--white);
}
.legal-doc h3:first-of-type {
  margin-top: var(--sp-4);
}
.legal-doc p {
  margin-bottom: var(--sp-4);
}
.legal-doc ul {
  margin: 0 0 var(--sp-4) var(--sp-6);
  padding: 0;
}
.legal-doc li {
  margin-bottom: var(--sp-2);
}
.legal-doc a {
  color: var(--green);
  text-decoration: underline;
}
.legal-updated {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: 0.06em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- 19d. Games */
/* Interactives (CONTENT-PLAN). All game markup is built by JS at runtime, so
   these classes are the whole contract between the games and the design
   system — the games never invent a colour or a font. */

.game-mount {
  max-width: 30rem;
  margin: 0 auto var(--sp-8);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
}
.sotd-board {
  display: grid;
  gap: 6px;
}
.sotd-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
}
.sotd-cell {
  width: 3.1rem;
  height: 3.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--border);
  border-radius: var(--r-sm);
  font-family: var(--font-body);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--white);
  text-transform: uppercase;
  background: var(--bg2);
}
.sotd-cell.filled {
  border-color: var(--accent-line-hover);
}
/* AA contrast: dark ink on the light fills, not white. */
.sotd-cell.correct {
  background: var(--green);
  border-color: var(--green);
  color: var(--bg);
}
.sotd-cell.present {
  background: var(--amber);
  border-color: var(--amber);
  color: var(--bg);
}
.sotd-cell.absent {
  background: var(--card);
  border-color: var(--card);
  color: var(--muted);
}
.sotd-keys {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.sotd-key-row {
  display: flex;
  gap: 5px;
  justify-content: center;
}
.sotd-key {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--sp-3) 0;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.sotd-key.wide { flex: 1.4 1 auto; }
.sotd-key:hover { border-color: var(--green); }
.sotd-key.correct { background: var(--green); color: var(--bg); border-color: var(--green); }
.sotd-key.present { background: var(--amber); color: var(--bg); border-color: var(--amber); }
.sotd-key.absent { background: var(--bg2); color: var(--muted); }
.sotd-message {
  min-height: 1.4rem;
  margin: 0;
  text-align: center;
  color: var(--white);
  font-size: var(--fs-sm);
  white-space: pre-line;
}
.sotd-stats {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: 0.06em;
  color: var(--muted);
  text-transform: uppercase;
}
.sotd-share { margin-top: var(--sp-2); }

.jumble-word {
  font-family: var(--font-mono);
  font-size: 2rem;
  letter-spacing: 0.35em;
  color: var(--lime);
  text-align: center;
  padding: var(--sp-6) 0;
}
.jumble-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: center;
}
.jumble-input {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg2);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 1rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  width: 9rem;
}
.jumble-input:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

.run-canvas {
  width: 100%;
  max-width: 22.5rem;
  height: auto;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--bg);
  touch-action: manipulation;
}
.run-controls {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

/* Quiz */
.quiz-q {
  font-size: var(--fs-lg);
  color: var(--white);
  margin-bottom: var(--sp-5);
  text-align: center;
}
.quiz-options {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: 100%;
}
.quiz-option {
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.quiz-option:hover {
  border-color: var(--green);
  background: var(--card-hover);
}
.quiz-progress {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  letter-spacing: 0.06em;
  color: var(--muted);
  text-transform: uppercase;
}
.quiz-result {
  text-align: center;
  color: var(--text);
}
.quiz-result h4 {
  font-size: var(--fs-xl);
  color: var(--white);
  margin-bottom: var(--sp-3);
}

@media (max-width: 480px) {
  .sotd-cell { width: 2.6rem; height: 2.6rem; font-size: 1.25rem; }
  .jumble-word { font-size: 1.5rem; letter-spacing: 0.25em; }
}

/* ------------------------------------------------------------- 19e. Signup */
/* Email capture. The provider renders its own form inside [data-signup-mount],
   so we style only our chrome around it. The no-JS fallback link is hidden
   unless <html> still carries .no-js — i.e. our script never ran. */

/* The provider injects its own markup into [data-signup-mount]. We cannot
   change what it emits, so style it by element rather than by their class
   names, which are not ours to depend on. Harmless if it ever becomes an
   iframe — the rules simply stop matching. */
[data-signup-mount] input[type="email"],
[data-signup-mount] input[type="text"] {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg2);
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--fs-base);
}
[data-signup-mount] input::placeholder { color: var(--muted); }
[data-signup-mount] button,
[data-signup-mount] input[type="submit"] {
  padding: var(--sp-3) var(--sp-6);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--green);
  color: var(--bg);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
}
[data-signup-mount] button:hover,
[data-signup-mount] input[type="submit"]:hover { background: var(--green-dim); }
[data-signup-mount] form { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
[data-signup-mount] a { color: var(--muted); }

.signup-nojs { display: none; }
.no-js .signup-nojs { display: flex; }
.no-js .signup-cta { display: none; }

.signup-small {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--muted);
}
.signup-small a {
  color: var(--green);
  text-decoration: underline;
}

/* ---------------------------------------------------------- 20. Sister site */

.sister-strip {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-8);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--muted);
}
.sister-strip a {
  color: var(--green);
  font-weight: 600;
  text-decoration: none;
}
.sister-strip a:hover {
  color: var(--lime);
}

/* --------------------------------------------------------------- 21. Footer */

/* Flex, not a fixed grid. The old `grid-template-columns: 1.5fr 1fr 1fr 1fr`
   assumed exactly four children; this site renders five (brand, Navigate,
   Dispensaries, Resources, Legal) and the fifth wrapped onto a second row
   under the brand. Column count is a per-site data question — the umbrella
   renders one — so the layout has to derive it rather than hard-code it. */
.site-footer {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: var(--sp-12) var(--sp-8);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--sp-8) var(--sp-12);
}
.footer-brand {
  flex: 1 1 17rem;
  min-width: 0;
}
.footer-col {
  flex: 1 1 8rem;
  min-width: 0;
}
.footer-brand p {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.6;
  margin-top: var(--sp-3);
}
.footer-col h4 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: var(--sp-4);
}
.footer-col a {
  display: block;
  font-size: var(--fs-sm);
  color: var(--text);
  text-decoration: none;
  margin-bottom: var(--sp-2);
  transition: color var(--t-fast);
}
.footer-col a:hover {
  color: var(--green);
}
.footer-bottom {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-8);
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
}
.footer-bottom p {
  font-size: 0.72rem;
  color: var(--muted);
}
.footer-disclaimer {
  max-width: var(--w-wide);
  margin: 0 auto;
  padding: 0 var(--sp-8) var(--sp-8);
  font-size: 0.68rem;
  color: var(--muted);
  line-height: 1.6;
}

/* ----------------------------------------------------------- 22. Share bar */

.share-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-top: var(--sp-6);
}
.share-label {
  font-size: 0.72rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 600;
}
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  transition: all var(--t-fast);
}
.share-btn:hover {
  border-color: var(--green);
  color: var(--green);
  background: var(--accent-wash);
  transform: translateY(-2px);
}
.share-btn svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

/* ------------------------------------------------------------ 23. Responsive */

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    padding: var(--sp-12) var(--sp-6) var(--sp-8);
    gap: var(--sp-8);
  }
  /* Tablet keeps the stats — they answer "what does it cost" and "who
     delivers", which is worth more than the diagonal flourish. Rotation and
     stagger come off so they read as a plain 2x2 under the hero copy. */
  .hero-visual {
    width: 100%;
  }
  .stat-stack {
    transform: none;
  }
  .stat-card:nth-child(even) {
    transform: none;
  }

  /* Tablet and phone: the link row becomes a drop panel behind the button.
     Gated on the script having run — `.nav-links` used to be a flat
     `display: none` here, which left phones and tablets with no navigation at
     all except the footer. A no-JS browser gets the wrapped row below. */
  html:not(.no-js) .nav-toggle {
    display: inline-flex;
  }
  html:not(.no-js) .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    right: var(--sp-6);
    left: var(--sp-6);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: var(--bg2);
    box-shadow: 0 18px 40px var(--shadow-cast-deep);
  }
  html:not(.no-js) .nav-links.open {
    display: flex;
  }
  html:not(.no-js) .nav-links a {
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r-md);
    color: var(--text);
    font-size: var(--fs-base);
  }
  html:not(.no-js) .nav-links a:hover {
    background: var(--accent-wash);
    color: var(--green);
  }

  /* No script, no panel: keep the links on the page as a wrapped row. */
  .no-js .nav-inner {
    flex-wrap: wrap;
    gap: var(--sp-3);
  }
  .no-js .nav-links {
    flex-wrap: wrap;
    gap: var(--sp-4);
  }
  .grid-2,
  .grid-3,
  .notice-cols {
    grid-template-columns: 1fr;
  }
  /* Tablet: two routes across, third below. One column would push the third
     option — the shop — off the first screen entirely. */
  .path-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid-4 {
    grid-template-columns: 1fr 1fr;
  }
  /* Tablet: brand across the top, then every link column on ONE row beneath.
     The basis has to leave room for four columns plus three gaps inside
     768px minus padding — 10rem fit only three and pushed Legal to a third
     row, which is the wrap this change exists to remove. */
  .site-footer {
    gap: var(--sp-8);
  }
  .footer-brand {
    flex-basis: 100%;
  }
  .footer-col {
    flex: 1 1 7rem;
  }
  .section-header {
    padding: var(--sp-12) var(--sp-6) 0;
  }
  .section-body {
    padding: 0 var(--sp-6) var(--sp-12);
  }
  .notice-box {
    padding: var(--sp-6);
  }
}

@media (max-width: 600px) {
  .grid-4 {
    grid-template-columns: 1fr;
  }
  .grid-auto-wide,
  .grid-auto-narrow,
  .path-grid {
    grid-template-columns: 1fr;
  }
  .path-card {
    padding: var(--sp-6);
  }
  /* Phone: the hero was 742px tall, which pushed the three-route chooser to
     y=1088 — a whole screen of scrolling before a reader sees where to go,
     which defeats the point of a hub. Tighter padding, and the share bar goes:
     offering to share a page nobody has read yet is not worth 40px above the
     fold. It returns at tablet width and up. */
  .hero {
    padding: var(--sp-8) var(--sp-6) var(--sp-8);
    gap: var(--sp-6);
  }
  .hero .share-bar {
    display: none;
  }
  /* Phone: the stats go too. Four cards is another full screen before the
     reader reaches the three routes, and the same facts appear further down
     the page anyway. Tablet and desktop keep them. */
  .hero-visual {
    display: none;
  }
  .hero-ctas,
  .notice-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .hero-ctas a,
  .notice-actions a {
    justify-content: center;
  }
  /* Phone: two columns of links, brand full width above them. One column each
     would push the legal links a screen and a half down. */
  .site-footer {
    gap: var(--sp-6);
  }
  .footer-col {
    flex: 1 1 42%;
  }
  .footer-bottom {
    flex-direction: column;
    gap: var(--sp-2);
    text-align: center;
  }
  .nav-inner {
    padding: var(--sp-4) var(--sp-6);
  }
}

/* ------------------------------------------------------------- 24. Print */

@media print {
  .atmosphere,
  .grain,
  .age-gate,
  .site-nav,
  .share-bar {
    display: none !important;
  }
  body {
    background: #fff;
    color: #000;
  }
}
