/* ─── BRAND WORDMARK FACE ───────────────────────────────────── */
/* Self-hosted (21KB latin subset) — the FH logo's heavy slanted caps.
   Wordmark lockups only; display/body faces stay on Google Fonts. */
@font-face {
  font-family: 'Kanit';
  font-style: italic;
  font-weight: 800;
  font-display: swap;
  src: url('/fonts/kanit/kanit-800italic-latin.woff2') format('woff2');
}

/* ─── DESIGN TOKENS ─────────────────────────────────────────── */
:root {
  --bg:        #08090d;
  --bg-1:      #0e1118;
  --bg-2:      #161a23;
  --surface:   #1c2030;
  --surface-2: #232737;

  --line:        rgba(244, 241, 234, 0.07);
  --line-strong: rgba(244, 241, 234, 0.14);

  --text:       #f4f1ea;
  --text-muted: #8e93a3;
  /* --text-dim lifted from #5b6273 (3.09:1 on near-black, fails AA) */
  /* to #7f8aa0 so .ticker-cell-label and .yard-line-num pass 4.5:1.   */
  --text-dim:   #7f8aa0;

  /* Franchise Hub rebrand (Phase 1, marketing world, 2026-08-06): token
     NAMES are unchanged (--red / --gold have hundreds of refs across the
     public templates) but the VALUES are now the FH palette — brand green
     on black/white. Green is a LIGHT accent: any text sitting on it must
     use --accent-ink, never white (white on this green is ~1.6:1). */
  --red:         #38e939; /* FH brand green — primary accent */
  --red-pressed: #24c229; /* darker green for hover/pressed fills */
  --red-glow:    rgba(56, 233, 57, 0.45);

  /* Ink for text ON the green accent. #06220a on #38e939 ≈ 10.4:1
     (passes AA/AAA at every size the button system uses). */
  --accent-ink:  #06220a;

  /* Secondary accent — used as 1px structural elements only.
     Was gold #fdb913; now a pale tint of the brand green. */
  --gold: #8ff593;

  --blurple:         #5865f2;
  --blurple-pressed: #404eed;

  --font-display: "Saira Semi Condensed", "Arial Black", system-ui, sans-serif;
  --font-body:    "Manrope", system-ui, sans-serif;
  /* Brand wordmark face — matches the FH logo's heavy slanted caps.
     Self-hosted (see @font-face below); wordmark lockups only. */
  --font-brand:   "Kanit", var(--font-display);
  /* Retired the JetBrains Mono "typewriter" label font — labels now use the
     clean body sans (Manrope) so public league pages match the app's look. */
  --font-mono:    var(--font-body);

  --pill-h:       44px;
  --pill-radius:  10px;
  --pill-padding: 0 1.1rem;

  --w-tight:  720px;
  --w-narrow: 880px;
  --w-page:   1600px;

  /* iOS safe-area-inset custom props — pages can compose
     against these rather than re-typing env() per surface.
     Apple HIG audit 2026-05-14 flagged these as missing. */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);
}

/* ─── RESET + BASE ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* Kill the default gray iOS tap flash — pages style their own
   :active / :focus states. Apple HIG audit 2026-05-14. */
* { -webkit-tap-highlight-color: transparent; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  font-feature-settings: "ss01", "cv11";
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* `overflow-x: hidden` on body implicitly forces `overflow-y: auto`
     (any explicit overflow-x paired with a default overflow-y becomes a
     scroll container per spec), which makes body a scrolling ancestor
     and breaks `position: sticky` on descendants like `.nav` — the
     header would scroll away instead of pinning. `clip` (matched on
     html below) only clips paint, never creates an implicit scroll
     container, so sticky descendants keep working. 2026-07-22 mobile
     polish pass. */
  overflow-x: clip;
}
html { overflow-x: clip; }
a { color: inherit; text-decoration: none; transition: color 120ms ease; }
a:hover { color: var(--text); }
img, svg { display: block; max-width: 100%; }
::selection { background: var(--red); color: var(--accent-ink); }

/* ─── DISPLAY HEADINGS ─────────────────────────────────────── */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 0.95;
  font-weight: 800;
  margin: 0;
  color: var(--text);
}
h1 { font-weight: 900; letter-spacing: 0; }

/* ─── SKIP LINK ────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  background: var(--red);
  color: var(--accent-ink);
  padding: 0.6rem 1rem;
  border-radius: 6px;
  z-index: 1000;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  transition: top 0.18s ease;
}
.skip-link:focus { top: 8px; outline: 2px solid #fff; outline-offset: 2px; color: var(--accent-ink); }

/* ─── NAV ──────────────────────────────────────────────────── */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(8, 9, 13, 0.85);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  max-width: var(--w-page);
  margin: 0 auto;
  padding: 0.85rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  flex-shrink: 0;
}
.nav-brand .brand-mark {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  object-fit: contain;
}
.nav-brand .brand-wordmark {
  /* Operator 2026-08-06: wordmark uses the logo's own letterform voice —
     Kanit 800 italic (real italic cut; the old synthetic skew is gone). */
  font-family: var(--font-brand);
  font-weight: 800;
  font-style: italic;
  font-size: 1.08rem;
  letter-spacing: 0.01em;
  display: inline-block;
  padding-right: .08em; /* italic overhang clips at the box edge */
  color: var(--text);
}
.nav-brand .brand-wordmark .accent { color: var(--red); }

.nav-spacer { flex: 1; }

.nav-links { display: flex; align-items: center; gap: 0.25rem; }
.nav-link {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-muted);
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  transition: color 120ms ease, background 120ms ease;
}
.nav-link:hover, .nav-link:focus-visible {
  color: var(--text);
  background: rgba(244, 241, 234, 0.04);
}
.nav-link.is-active { color: var(--text); }

.nav-cta-group { display: flex; align-items: center; gap: 0.5rem; margin-left: 0.5rem; }

/* ─── NAV HAMBURGER ─────────────────────────────────────────
   Hidden on desktop; shown on mobile as the nav toggle.
   Uses aria-expanded to drive the .is-open class on the menu. */
.nav-hamburger {
  display: none;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  color: var(--text);
  cursor: pointer;
  padding: 0;
  min-height: 44px;
  min-width: 44px;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
  transition: background 120ms ease, border-color 120ms ease;
  flex-shrink: 0;
}
.nav-hamburger:hover { background: rgba(244,241,234,0.06); border-color: rgba(244,241,234,0.22); }
.nav-hamburger[aria-expanded="true"] { background: rgba(244,241,234,0.08); }

/* ─── BUTTON SYSTEM ────────────────────────────────────────── */
/* Single geometry. Three fills. Nothing else. */
.btn-mp {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: var(--pill-h);
  padding: var(--pill-padding);
  border-radius: var(--pill-radius);
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: pointer;
  /* line-height: 1 matches .nav-hamburger's own line-height so both
     controls' content centers on the same visual axis inside the
     nav row (was relying on the inherited body line-height of 1.55,
     which nudged the button's text/icon baseline down relative to
     the hamburger glyph — the "off-center in the nav" bug). */
  line-height: 1;
  transition: transform 140ms ease, box-shadow 140ms ease, background 140ms ease, border-color 140ms ease, color 140ms ease;
  font-feature-settings: "tnum", "ss01";
}
.btn-mp:hover { transform: translateY(-1px); }
.btn-mp:active { transform: translateY(0); }
.btn-mp:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.btn-primary-mp {
  background: var(--red);
  /* Dark ink on the FH green: #06220a on #38e939 ≈ 10.4:1 (AA/AAA pass).
     White ink here would be ~1.6:1 — never use it on the green accent. */
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px var(--red), 0 4px 14px -4px var(--red-glow);
}
.btn-primary-mp:hover {
  background: var(--red-pressed);
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px var(--red-pressed), 0 8px 22px -4px var(--red-glow);
}

.btn-ghost-mp {
  background: transparent;
  color: var(--text);
  border-color: var(--line-strong);
}
.btn-ghost-mp:hover {
  background: rgba(244, 241, 234, 0.05);
  border-color: rgba(244, 241, 234, 0.25);
  color: var(--text);
}

.btn-blurple-mp {
  background: var(--blurple);
  /* #fff on Discord blurple #5865f2 = ~4.99:1 (AA pass). --text gave 4.08. */
  color: #ffffff;
  box-shadow: 0 0 0 1px var(--blurple), 0 4px 14px -4px rgba(88, 101, 242, 0.5);
}
.btn-blurple-mp:hover {
  background: var(--blurple-pressed);
  color: #ffffff;
  box-shadow: 0 0 0 1px var(--blurple-pressed), 0 8px 22px -4px rgba(88, 101, 242, 0.55);
}

.btn-mp-sm { height: 36px; font-size: 0.78rem; padding: 0 0.85rem; }
/* Small primary CTA — under the old red palette this needed a deeper
   hand-tuned shade (#c12838) so 12.48px white text cleared 4.5:1. With
   the FH green + dark --accent-ink (~10.4:1) the base tokens already
   pass at small sizes, so the variant just reuses them. */
.btn-primary-mp.btn-mp-sm {
  background: var(--red);
  box-shadow: 0 0 0 1px var(--red), 0 4px 14px -4px var(--red-glow);
}
.btn-primary-mp.btn-mp-sm:hover {
  background: var(--red-pressed);
  box-shadow: 0 0 0 1px var(--red-pressed), 0 8px 22px -4px var(--red-glow);
}

/* ─── YARD-LINE DIVIDER ────────────────────────────────────── */
.yard-line {
  max-width: var(--w-page);
  margin: 0 auto;
  padding: 0 1.25rem;
  position: relative;
}
.yard-line::before {
  content: "";
  display: block;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--line) 8%, var(--line) 92%, transparent);
}
.yard-line-num {
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg);
  padding: 0 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--text-dim);
  letter-spacing: 0.1em;
}
.yard-line-num::before {
  content: "";
  display: inline-block;
  width: 18px;
  height: 1px;
  background: var(--gold);
  vertical-align: middle;
  margin-right: 0.55rem;
}
.yard-line-num::after {
  content: "";
  display: inline-block;
  width: 18px;
  height: 1px;
  background: var(--gold);
  vertical-align: middle;
  margin-left: 0.55rem;
}

/* ─── VIEW TRANSITIONS ───────────────────────────────────────
   Opt-in is via the meta tag in head; this rule + the timing
   control how the crossfade animates. Reduce-motion users get
   an instant swap. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: ease;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}

/* ─── MAIN ─────────────────────────────────────────────────── */
.marketing-main { flex: 1; position: relative; }

/* ─── SW UPDATE BANNER ────────────────────────────────────────
   Surfaced when the service worker detects a new version. Same
   visual treatment as the dashboard layout's banner so users
   get a consistent refresh prompt regardless of which surface
   they're on when a deploy lands. */
.mp-sw-banner {
  position: fixed;
  left: 50%;
  bottom: max(1rem, env(safe-area-inset-bottom, 1rem));
  transform: translateX(-50%);
  z-index: 9999;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  max-width: calc(100vw - 2rem);
  padding: 0.7rem 0.7rem 0.7rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  box-shadow: 0 14px 38px -10px rgba(0, 0, 0, 0.6);
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--text);
  animation: mp-sw-banner-in 240ms ease-out;
}
@keyframes mp-sw-banner-in {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.mp-sw-banner-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60vw;
}
.mp-sw-banner-text strong { color: var(--gold); }
.mp-sw-banner-btn {
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--text-muted);
  border-radius: 999px;
  padding: 0.35rem 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.mp-sw-banner-btn:hover { color: var(--text); border-color: rgba(244, 241, 234, 0.35); }
.mp-sw-banner-btn.is-primary {
  background: var(--red);
  border-color: var(--red);
  color: var(--accent-ink);
}
.mp-sw-banner-btn.is-primary:hover { background: var(--red-pressed); border-color: var(--red-pressed); }
@media (max-width: 575.98px) {
  .mp-sw-banner { font-size: 0.78rem; padding: 0.55rem 0.55rem 0.55rem 0.85rem; gap: 0.45rem; }
  .mp-sw-banner-text { max-width: 50vw; }
  .mp-sw-banner-btn { padding: 0.3rem 0.6rem; font-size: 0.81rem; }
}

/* ─── FOOTER ───────────────────────────────────────────────── */
.footer-mp { margin-top: 6rem; background: var(--bg-1); border-top: 1px solid var(--line); }
.footer-mp-inner {
  max-width: var(--w-page);
  margin: 0 auto;
  padding: 2.5rem 1.25rem 2rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  align-items: start;
}
.footer-brand { display: flex; flex-direction: column; gap: 0.75rem; max-width: 320px; }
.footer-brand-row { display: inline-flex; align-items: center; gap: 0.65rem; }
.footer-brand-row .brand-mark { width: 28px; height: 28px; object-fit: contain; }
.footer-brand-row .brand-wordmark {
  font-family: var(--font-brand);
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.01em;
  font-size: 0.95rem;
  padding-right: .08em;
}
.footer-brand-row .brand-wordmark .accent { color: var(--red); }
.footer-tag { font-size: 0.82rem; color: var(--text-muted); line-height: 1.55; }
.footer-meta { display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-end; text-align: right; }
.footer-mp-links { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; font-size: 0.78rem; color: var(--text-muted); }
.footer-mp-links a:hover { color: var(--text); }
.footer-copy {
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--text-dim);
  letter-spacing: 0.04em;
}

/* Trademark / non-affiliation notice. Quiet but legible — a disclaimer that
   is too small or too faint to read is worth less if it is ever pointed at.
   Sentence case and the body font on purpose: it should read as a real
   notice rather than styled footer furniture. */
.footer-legal {
  margin-top: 0.85rem;
  max-width: 70ch;
  font-size: 0.76rem;
  line-height: 1.55;
  color: var(--text-dim);
  opacity: 0.85;
}

/* ─── RESPONSIVE — MOBILE-FIRST ────────────────────────────── */
@media (max-width: 991.98px) {
  .nav-inner { padding: 0.7rem 1rem; gap: 0.75rem; }
}
@media (max-width: 767.98px) {
  .nav-inner {
    padding: 0.7rem 1rem;
    padding-top: calc(0.7rem + env(safe-area-inset-top));
    gap: 0.5rem;
  }
  .nav-spacer { display: none; }
  /* With the spacer gone the CTA cluster sat mid-bar (operator 2026-07-22):
     brand hugs LEFT, buttons+hamburger hug RIGHT. */
  .nav-cta-group { margin-left: auto; }

  /* Hamburger: show toggle, collapse nav-links into a dropdown */
  .nav-hamburger { display: inline-flex; }
  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    flex-direction: column;
    gap: 0;
    overflow-x: visible;
    background: rgba(8,9,13,0.97);
    backdrop-filter: saturate(160%) blur(16px);
    -webkit-backdrop-filter: saturate(160%) blur(16px);
    border-bottom: 1px solid var(--line-strong);
    padding: 0.5rem 0.75rem 1rem;
    z-index: 49;
  }
  .nav-links.is-open { display: flex; }
  /* Rework-5: bump nav links to 44px tap target. */
  .nav-link {
    padding: 0.75rem 0.85rem;
    font-size: 0.88rem;
    width: 100%;
    border-radius: 8px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  /* Add to Discord stays visible in header, bumped to 44px tap target */
  .nav-cta-group .btn-mp { height: 44px; font-size: 0.78rem; padding: 0 0.85rem; }
  /* Sign In: compact ghost variant, kept VISIBLE in the header bar on
     mobile (2026-07-22 — previously `display: none` here, leaving no
     way to sign in from the top bar without opening the hamburger).
     Narrower font/padding than the primary Add-to-Discord pill so the
     two plus the hamburger all fit one row without wrapping. */
  .nav-cta-group .btn-ghost-mp { font-size: 0.68rem; padding: 0 0.55rem; }
  .footer-mp-inner { grid-template-columns: 1fr; gap: 1.5rem; }
  .footer-meta { align-items: flex-start; text-align: left; }
  body { padding-bottom: env(safe-area-inset-bottom); }
}
@media (max-width: 575.98px) {
  .nav-brand .brand-wordmark { font-size: 0.95rem; }
  .nav-link { padding: 0.55rem 0.7rem; font-size: 0.75rem; }
}
@media (max-width: 430px) {
  /* Smallest phones. 2026-07-22: the top-bar CTA is now the short "Leagues"
     pill (Add to Discord moved to the hero + hamburger menu), so the
     wordmark fits again — keep it, just slightly smaller. */
  .nav-brand .brand-wordmark { font-size: 0.85rem; }
  .nav-brand { gap: 0.45rem; }
  /* Header must fit a 393px viewport with zero sideways overflow.
     2026-07-22: moved this block to AFTER the 575.98px block above —
     it was declared earlier in the file (right after the .mp-sw-banner
     rules), so at ≤430px the later-declared 767.98px block's
     `.nav-cta-group .btn-mp` rule won the cascade (equal specificity,
     later source order wins) and silently clobbered this rule's
     smaller 40px sizing, leaving the Add-to-Discord pill at 44px next
     to a 40px hamburger — the mismatched heights read as "off-center"
     in the nav row. Source order now matches the narrowing breakpoints
     so each rule's overrides actually apply at its own width. */
  .nav-cta-group { gap: 0.3rem; margin-left: 0.2rem; }
  .nav-cta-group .btn-mp { height: 40px; font-size: 0.7rem; padding: 0 0.55rem; gap: 0.3rem; letter-spacing: 0; }
  .nav-cta-group .btn-ghost-mp { font-size: 0.6rem; padding: 0 0.4rem; }
  .nav-hamburger { width: 40px; height: 40px; min-width: 40px; }
}

/* ─── REWORK-5: PUBLIC-PAGE MOBILE AUDIT ─────────────────────
   Global rules that cascade to every page extending this layout
   (home, leagues_directory, league_portal, league_view_public,
   team_view, player_view, leaders, compare_players, status,
   achievements_leaderboard).
   ───────────────────────────────────────────────────────────── */

/* 1. 16px input font on mobile — no iOS auto-zoom on focus. */
@media (max-width: 575.98px) {
  input[type="text"], input[type="email"], input[type="password"],
  input[type="search"], input[type="number"], input[type="tel"],
  input[type="url"], input[type="date"], input[type="datetime-local"],
  select, textarea {
    font-size: 16px !important;
    min-height: 44px;
  }
}

/* 2. Every interactive button/link inside main meets 44px. */
.marketing-main a.btn-mp,
.marketing-main button:not(.btn-close) {
  min-height: 44px;
}

/* 3. Tables — public stat surfaces (team_view, player_view,
   leaders, compare_players) get horizontal-scroll wrappers on
   mobile so columns don't crush. */
@media (max-width: 767.98px) {
  .marketing-main table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  .marketing-main table th,
  .marketing-main table td {
    white-space: nowrap;
  }
  /* Allow specifically-marked tables to stay wrapped (rare). */
  .marketing-main table.table-stack {
    display: table; white-space: normal;
  }
}

/* 4. Card grids — public pages frequently use .mp-card-grid /
   .league-card-grid / .team-card-grid; collapse those to single
   column under 575px. */
@media (max-width: 575.98px) {
  .mp-card-grid,
  .league-card-grid,
  .team-card-grid,
  .player-card-grid,
  .stat-card-grid {
    grid-template-columns: 1fr !important;
  }
}

/* 5. Hero typography scales down to readable on phones (some
   per-page heroes set 4-6rem H1s that overflow at 360px). */
@media (max-width: 575.98px) {
  .marketing-main .hero h1,
  .marketing-main h1.hero-headline {
    font-size: clamp(2rem, 9vw, 3rem) !important;
    line-height: 1.05;
  }
}

/* 6. Container max-width respects viewport on phones. */
@media (max-width: 575.98px) {
  .marketing-main > * { padding-left: 1rem; padding-right: 1rem; }
  .container-mp { padding-left: 0 !important; padding-right: 0 !important; }
}

/* ─── Rework-5: Madden-hub primitives (public pages) ───────────
   Mirrors the .mp-card / .mp-stage / .mp-section-title vocab
   from mixins/owner_chrome.pug so every public surface
   (directory, portal, team view, player view, leaders, compare)
   can drop in matching card / hero / section-label styles
   without re-defining them per page.
   The owner_chrome version is team-themed via --team-hex; this
   version uses the FH brand green as the default accent. Pages
   that want a team-tinted variant can wrap their content in
   a scope that overrides --hub-accent locally. */
:root {
  --hub-accent: var(--red);
  --hub-accent-2: var(--gold);

  /* Spacing scale — also used by .full-bleed pages */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;

  --r-sm:   6px;
  --r-md:   10px;
  --r-lg:   14px;
  --r-pill: 999px;
}

.mp-card {
  position: relative;
  padding: 1.1rem 1.25rem;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--hub-accent) 9%, rgba(28,32,48,0.62)),
      rgba(8,11,16,0.55) 65%,
      rgba(8,11,16,0.7));
  border: 1px solid color-mix(in srgb, var(--hub-accent) 32%, rgba(244,241,234,0.07));
  border-radius: var(--r-lg);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.03) inset,
    0 14px 38px rgba(0,0,0,0.42),
    0 0 0 1px color-mix(in srgb, var(--hub-accent) 12%, transparent);
  backdrop-filter: blur(6px) saturate(140%);
}
.mp-card.is-flat { box-shadow: none; backdrop-filter: none; }
.mp-card.is-edge::before {
  content: "";
  position: absolute; left: 0; top: 14px; bottom: 14px;
  width: 3px; border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, var(--hub-accent), color-mix(in srgb, var(--hub-accent-2) 60%, var(--hub-accent)));
  box-shadow: 0 0 12px color-mix(in srgb, var(--hub-accent) 55%, transparent);
}
.mp-card-header {
  display: flex; align-items: center; gap: 0.55rem;
  flex-wrap: wrap;
  margin-bottom: 0.85rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(244,241,234,0.06);
}
.mp-card-title {
  font-family: var(--font-display); font-weight: 800;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text); font-size: 1rem; margin: 0;
  display: inline-flex; align-items: center; gap: 0.45rem;
}
.mp-card-title i { color: var(--hub-accent); font-size: 1.1rem; }
.mp-card-meta {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 0.78rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-dim); font-weight: 700;
}

.mp-section-title {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.32rem 0.75rem;
  margin-bottom: 0.65rem;
  font-family: var(--font-mono); font-size: 0.76rem;
  letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700;
  color: var(--hub-accent);
  border-radius: var(--r-pill);
  background: rgba(8,11,16,0.55);
  border: 1px solid color-mix(in srgb, var(--hub-accent) 38%, transparent);
}
.mp-section-title i { font-size: 0.88rem; }

.mp-stage {
  position: relative;
  padding: 1.5rem 1.25rem;
  border-radius: 16px;
  margin-bottom: 1.25rem;
  overflow: hidden;
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--hub-accent) 26%, rgba(8,11,16,0.85)),
      rgba(8,11,16,0.85) 60%,
      color-mix(in srgb, var(--hub-accent-2) 18%, rgba(8,11,16,0.85)));
  border: 1px solid color-mix(in srgb, var(--hub-accent) 32%, rgba(244,241,234,0.07));
}
.mp-stage::before {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(135deg, transparent 0 28px, rgba(244,241,234,0.025) 28px 30px);
  pointer-events: none;
}
.mp-stage > * { position: relative; z-index: 1; }

/* Per-page team-tinted variant: scope `<div class="hub-team">` over
   any block where you want .mp-card / .mp-stage / .mp-section-title
   to inherit a team primary color instead of the brand green. Set
   `style="--hub-accent: #COLOR; --hub-accent-2: #COLOR2;"` on that
   wrapper. The cascade does the rest — no per-page CSS surgery. */
.hub-team { display: contents; }

/* ─── PRICING GRID (three-column) ──────────────────────────── */
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  align-items: stretch;
  margin: 0 auto;
  max-width: 1020px;
}
.pricing-col {
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--line-strong);
  border-radius: 18px;
  padding: 2.5rem 2rem;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pricing-col::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(to right, var(--line-strong), transparent);
  border-radius: 18px 18px 0 0;
}
.pricing-col.is-featured {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red), 0 16px 48px -16px rgba(56, 233, 57, 0.28);
}
.pricing-col.is-featured::before {
  background: linear-gradient(to right, var(--red), var(--gold), transparent);
}
.pricing-col-badge {
  position: absolute;
  top: -1px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--red);
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.28rem 0.85rem;
  border-radius: 0 0 8px 8px;
  white-space: nowrap;
}
.pricing-col-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.84rem;
  letter-spacing: 0.18em;
  color: var(--red);
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 0.4rem;
}
.pricing-col-name {
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--text);
  margin-bottom: 1.25rem;
}
.pricing-col-price {
  display: flex;
  align-items: baseline;
  gap: 0;
  margin-bottom: 0.4rem;
}
.pricing-col-price-dollar {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 900;
  color: var(--text);
  opacity: 0.6;
  line-height: 1;
  align-self: flex-start;
  margin-top: 0.5rem;
}
.pricing-col-price-main {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 4vw, 3.2rem);
  font-weight: 900;
  letter-spacing: -0.02em;
  line-height: 0.95;
  color: var(--text);
}
.pricing-col-price-period {
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  align-self: flex-end;
  margin-bottom: 0.18rem;
  margin-left: 0.2rem;
}
.pricing-col-desc {
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.55;
  margin-bottom: 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
}
/* Override the home.pug inline-style max-width: 380px so list fills
   the column without centering. Higher specificity wins. */
.pricing-col .pricing-list {
  flex: 1;
  max-width: none;
  margin-bottom: 2rem;
}
.pricing-col .btn-mp {
  width: 100%;
  justify-content: center;
  margin-top: auto;
}
@media (max-width: 991.98px) {
  .pricing-grid {
    grid-template-columns: 1fr;
    max-width: 480px;
  }
}
@media (max-width: 767.98px) {
  .pricing-col { padding: 2rem 1.5rem; }
}


/* iOS App Store wrapper (Apple 3.1.1): purchase CTAs are hidden in-app. */
.is-app .app-hide{display:none !important}
/* Counterpart to .app-hide — app-wrapper-only content. Mirrors app.css so a
   template can use the same idiom on either layout. Hidden on the website. */
.app-only{display:none !important}
.is-app .app-only{display:block !important}
/* FH rebrand round 2: inside the iOS wrapper marketing pages read as the
   app — website chrome goes away, the .app-backbar (layout_marketing)
   takes over navigation. */
.is-app .app-only.app-backbar{display:flex !important}
.is-app nav.nav{display:none !important}
.is-app footer.footer-mp{display:none !important}
