/*
 * site.css — Tier 1 (sitewide)
 *
 * Loaded on every page via src/templates/shell.html.
 * Contains: design tokens + tennis theme, reset, base, layout, chrome
 * (header/nav/font-size), footer, sections, hero, language switcher,
 * i18n visibility + CJK/RTL, legal-page generic styling.
 *
 * Do NOT put page-type-specific rules here — those belong in a Tier 2
 * file (homepage.css, calendar.css, tournament.css).
 *
 * See docs/design-system/tiers.md for the tier policy.
 */

/* ─────────────────────────────────────────────────────────────
 * 1. Theme tokens (colors, gradient stops, glow accents)
 *    Merged from: themes/default.css (base palette) + themes/tennis.css (accent override)
 * ───────────────────────────────────────────────────────────── */

:root {
  /* Background gradient stops */
  --grad-1: #070d1e;
  --grad-2: #0b1e4a;
  --grad-3: #0e2870;
  --grad-4: #1a3ca0;
  --grad-5: #2048c8;   /* brightest stop — all text must pass 4.5:1 against this */
  --grad-6: #2a3cb8;
  --grad-7: #2d1f80;
  --grad-8: #3c1870;
  --grad-9: #4a1560;
  --grad-10: #3a1050;

  /* Radial glow accents (body::after) */
  --glow-1-color: rgba(79, 195, 247, 0.12);
  --glow-1-pos: 15% 20%;
  --glow-2-color: rgba(206, 147, 216, 0.1);
  --glow-2-pos: 80% 60%;
  --glow-3-color: rgba(108, 99, 255, 0.08);
  --glow-3-pos: 50% 90%;

  /* Base colors */
  --dark-bg: #080e10;
  --white: #fff;
  --text-primary: #ededf0;
  --text-secondary: #dcdde2;
  --text-tertiary: #bcc0ca;
  --border-muted: #8b8d94;     /* BORDERS ONLY — never use as text color (enforced by scripts/postbuild.js). For low-emphasis text, use --text-tertiary. */

  /* Tennis accent (green) — overrides the default cyan-blue */
  --accent-primary: #C8E631;
  --accent-primary-rgb: 200, 230, 49;
  --accent-primary-text: #d4ee50;
  --accent-secondary: #A8D600;
  --accent-danger: #ff6b6b;
  --accent-danger-text: #ffb088;
  --accent-success-text: #5ae6c8;

  /* Tournament-specific accents */
  --tennis-green: #C8E631;
  --tennis-yellow: #A8D600;
  --gold: #FFD700;

  /* Brand colors for embedded media. The YouTube icon SVG paths use this
   * value as the body fill — kept as a documented token so a future change
   * (e.g. matching a YouTube brand refresh, or theming for accessibility)
   * is one edit. Currently consumed via inline `fill=` on SVG paths in
   * src/templates/tournament/template.html and scripts/prebuild.js. */
  --youtube-red: #E5322D;
}

/* ─────────────────────────────────────────────────────────────
 * 2. Design tokens (spacing, type scale, card, glass, transitions)
 *    Source: core/tokens.css
 * ───────────────────────────────────────────────────────────── */

:root {
  /* Typography */
  --font-body: 'Sora', sans-serif;
  --line-height-base: 1.6;

  /* Font size scale (only the steps actually consumed today; the v1.3
   * components hardcode their own px values, see homepage.css and
   * tournament.css. Add tokens here when a 2nd consumer materializes.) */
  --font-size-hero: clamp(28px, 5vw, 42px);
  --font-size-body: 16px;
  --font-size-base: 16px;
  --font-size-small: 14px;
  --font-size-caption: 14px;
  --font-size-min: 13px;

  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* Spacing scale (only the steps actually consumed today). */
  --space-lg: 24px;
  --space-2xl: 48px;
  --space-3xl: 80px;

  /* Content width */
  --content-max-width: 1160px;
  --content-padding: 24px;
  --content-padding-mobile: 16px;

  /* Transitions */
  --transition-fast: 0.2s ease;
  --transition-base: 0.3s ease;

  /* Breakpoints (reference only) */
  /* Mobile ≤ 600px · Tablet 601–1023px · Desktop ≥ 1024px */
}

/* Font-size scale (managed by core.js as <html class="fs-normal|large|xl">).
 * Two-pronged scaling so it works regardless of whether a component uses the
 * --font-size-* tokens (like Tier 1 chrome) or hard-coded px values (like the
 * v1.3 .bi-card and inherited Spark components). The CSS `zoom` property
 * scales everything inside <body> proportionally — text, padding, gaps,
 * borders — so even hard-coded px values respond. The token bumps remain so
 * components that DO use the tokens get an additional, more typographically
 * controlled scale step on top. */

/* Tasteful, restrained steps. Baseline shrunk ~6% so the default reads
 * elegant rather than oversized; large/XL keep the same relative jumps.
 * Effective zoom: normal = 0.94, large = 1.00, xl = 1.07.
 * See DESIGN-SYSTEM.md §10.6 for rationale (larger jumps look amateurish).
 * The body `zoom` does the heavy lifting so even hard-coded px components
 * (e.g. .bi-card) respond; token bumps add a typographic nudge on top. */

body { zoom: 0.94; }
.site-controls { zoom: calc(1 / 0.94); }

html.fs-large {
  --font-size-hero: clamp(30px, 5.3vw, 44px);
  --font-size-body: 17px;
  --font-size-base: 17px;
  --font-size-small: 15px;
  --font-size-caption: 15px;
  --font-size-min: 13px;
}
html.fs-large body { zoom: 1.00; }
html.fs-large .site-controls { zoom: 1; }

html.fs-xl {
  --font-size-hero: clamp(32px, 5.7vw, 48px);
  --font-size-body: 18px;
  --font-size-base: 18px;
  --font-size-small: 16px;
  --font-size-caption: 16px;
  --font-size-min: 13px;
}
html.fs-xl body { zoom: 1.07; }
html.fs-xl .site-controls { zoom: calc(1 / 1.07); }

/* ─────────────────────────────────────────────────────────────
 * 3. Reset
 *    Source: core/reset.css
 * ───────────────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

img, svg, video, iframe {
  display: block;
  max-width: 100%;
}

a { color: inherit; }

button {
  font: inherit;
  cursor: pointer;
  background: none;
  border: none;
}

/* ─────────────────────────────────────────────────────────────
 * 4. Base (body, gradient background, glow accents)
 *    Source: core/base.css
 * ───────────────────────────────────────────────────────────── */

body {
  background: var(--dark-bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  overflow-x: hidden;
  min-height: 100vh;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  background: linear-gradient(135deg,
    var(--grad-1) 0%,
    var(--grad-2) 15%,
    color-mix(in srgb, var(--grad-2) 50%, var(--grad-3)) 22%,
    var(--grad-3) 30%,
    color-mix(in srgb, var(--grad-3) 50%, var(--grad-4)) 37%,
    var(--grad-4) 45%,
    color-mix(in srgb, var(--grad-4) 50%, var(--grad-5)) 50%,
    var(--grad-5) 55%,
    var(--grad-6) 62%,
    var(--grad-7) 72%,
    var(--grad-8) 82%,
    var(--grad-9) 92%,
    var(--grad-10) 100%
  );
  z-index: -2;
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  background:
    radial-gradient(circle at var(--glow-1-pos), var(--glow-1-color) 0%, transparent 40%),
    radial-gradient(circle at var(--glow-2-pos), var(--glow-2-color) 0%, transparent 40%),
    radial-gradient(circle at var(--glow-3-pos), var(--glow-3-color) 0%, transparent 35%);
  z-index: -1;
  pointer-events: none;
}

/* ─────────────────────────────────────────────────────────────
 * 5. Layout (page width wrapper)
 *    Source: core/layout.css
 * ───────────────────────────────────────────────────────────── */

.pw {
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: 0 var(--content-padding) 80px;
  position: relative;
  z-index: 2;
}

@media (max-width: 600px) {
  .pw {
    padding: 0 var(--content-padding-mobile) 60px;
  }
}

/* ─────────────────────────────────────────────────────────────
 * 6. Site header (landing masthead + compact back-link) + controls
 *    Used on every page via shell.html. Two modes, selected per-page
 *    by the <!-- INJECT:HEADER:landing --> / <!-- INJECT:HEADER:compact -->
 *    marker. Controls (A/A/A size toggle + language chip) are shared.
 * ───────────────────────────────────────────────────────────── */

.site-header {
  position: relative;
  z-index: 2;
}

/* -- Landing mode: full masthead ---------------------------------- */
.site-header-landing {
  position: relative;
  z-index: 100;
}

.site-header-landing .masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 32px var(--content-padding) 40px;
  flex-wrap: wrap;
  max-width: var(--content-max-width);
  margin: 0 auto;
}

.brand-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  flex: 1 1 320px;
}

.wordmark-link {
  text-decoration: none;
  color: inherit;
  display: inline-block;
}

.wordmark {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.6px;
  line-height: 1;
  margin: 0;
}

.wordmark .brand-accent,
.back-wordmark .brand-accent {
  background: linear-gradient(135deg, var(--accent-primary) 30%, var(--accent-secondary) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  color: transparent;
}

.masthead-rule {
  width: 40px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
  border-radius: 2px;
  opacity: 0.85;
}

.tagline {
  font-size: clamp(14px, 1.6vw, 16px);
  font-weight: 400;
  color: var(--text-secondary);
  max-width: 520px;
  line-height: 1.55;
  margin: 0;
}

/* -- Compact mode: back-link + controls --------------------------- */
.site-header-compact {
  background: transparent;
  position: relative;
  z-index: 100;
}

.site-header-compact .compact-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: 32px var(--content-padding) 24px;
  flex-wrap: wrap;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.2px;
  transition: color var(--transition-fast);
}

.back-link:hover { color: var(--white); }
.back-wordmark { font-weight: 600; }

/* -- Shared controls (A/A/A + language chip) ---------------------- */
.site-controls {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.fs-toggle {
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  padding: 3px;
  gap: 2px;
}

.fs-btn {
  width: 28px;
  height: 26px;
  border-radius: 11px;
  border: none;
  background: none;
  color: rgba(208, 212, 232, 0.5);
  font-weight: 600;
  font-family: var(--font-body);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  padding: 0;
  transition: all var(--transition-fast);
}
.fs-btn[data-fs="normal"] { font-size: 11px; }
.fs-btn[data-fs="large"]  { font-size: 13px; }
.fs-btn[data-fs="xl"]     { font-size: 15px; }

.fs-btn:hover {
  color: rgba(208, 212, 232, 0.9);
  background: rgba(255, 255, 255, 0.06);
}

.fs-btn.active {
  background: var(--accent-primary);
  color: #0a0a0a;
  box-shadow: 0 0 0 1px rgba(var(--accent-primary-rgb), 0.6),
              0 0 12px rgba(var(--accent-primary-rgb), 0.35);
}

.lang-wrap {
  position: relative;
  display: inline-block;
}

.lang-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  padding: 5px 10px;
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all var(--transition-fast);
}

.lang-chip:hover {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.18);
}

.lang-chip[aria-expanded="true"] {
  color: var(--white);
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.22);
}
.lang-chip[aria-expanded="true"] .lang-caret { transform: rotate(180deg); }
.lang-chip .lang-caret { transition: transform var(--transition-fast); }

/* -- Language dropdown menu --------------------------------------- */
.lang-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  /* Sizes to content. min-width gives a small floor so a single very short
   * label (e.g. "中") still has a reasonable hit area; max-width caps it
   * for absurd cases (very long native names). */
  min-width: 96px;
  max-width: 240px;
  width: max-content;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: rgba(8, 12, 24, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(20px);
  z-index: 1000;
  max-height: min(70vh, 480px);
  overflow-y: auto;
}
.lang-menu[hidden] { display: none; }

/* Reset <li> defaults so spacing is fully controlled by .lang-option. */
.lang-menu li { margin: 0; padding: 0; list-style: none; }

.lang-option {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;             /* anchors carry default underline; override */
  transition: background var(--transition-fast), color var(--transition-fast);
}
.lang-option + .lang-option,
.lang-menu li + li .lang-option { margin-top: 2px; }

.lang-option:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--white);
  text-decoration: none;
}

.lang-option.active {
  background: rgba(var(--accent-primary-rgb), 0.12);
  color: var(--accent-primary);
}
.lang-option.active:hover {
  background: rgba(var(--accent-primary-rgb), 0.18);
}

.lang-option .lang-name { flex: 1; }

.lang-chip svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  flex-shrink: 0;
}

.lang-chip .lang-caret {
  width: 10px;
  height: 10px;
  stroke-width: 2;
  opacity: 0.7;
}

@media (max-width: 600px) {
  .site-header-landing .masthead {
    padding: 24px var(--content-padding-mobile) 28px;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 16px;
  }
  .site-header-landing .brand-block {
    align-items: center;
    flex: 0 1 auto;
  }
  .site-header-landing .site-controls {
    justify-content: center;
  }
  .site-header-landing .lang-menu {
    right: 50%;
    transform: translateX(50%);
  }
  .site-header-compact .compact-bar {
    padding: 24px var(--content-padding-mobile) 16px;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 16px;
  }
  .site-header-compact .site-controls {
    justify-content: center;
  }
  .site-header-compact .lang-menu {
    right: 50%;
    transform: translateX(50%);
  }
  .site-controls { gap: 8px; }
  .fs-btn { width: 24px; height: 24px; }
  .lang-chip { padding: 4px 8px; font-size: 12px; }
}

/* (Legacy `.sparks-back` rule removed 2026-04-18 — superseded by
 * `.back-link` in shell.html. See docs/design-system/INVENTORY.md.) */

/* ─────────────────────────────────────────────────────────────
 * 7. Site footer (shell) + spark data-source footer component
 *    .site-footer     — the shell footer injected on every page
 *    .spark-footer    — attribution/data-source block used inline
 *                       inside calendar and tournament templates
 * ───────────────────────────────────────────────────────────── */

/* Global footer (shell). Sits at the bottom of every page below <main>.
 * Design rule: 32px gap above. When a page-local `.spark-footer`
 * (source-attribution block) precedes it, the spark-footer's own
 * margin-top + border-top + padding handles its own breathing room;
 * this 32px is the gap from spark-footer's bottom edge to the global
 * footer-bar. When there's no spark-footer (landing, legal pages), the
 * 32px is the gap from main content to the footer divider. Same rule,
 * one number, regardless of stacking. */
.site-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 32px;
}

.site-footer .footer-bar {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  row-gap: 10px;
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: 32px var(--content-padding) 28px;
  font-size: 12px;
  color: var(--text-tertiary);
}

.site-footer .footer-copy { opacity: 0.7; }

.site-footer .footer-legal {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
}

.site-footer .footer-legal a {
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.site-footer .footer-legal a:hover { color: var(--white); }

.site-footer .footer-sep { opacity: 0.35; }

@media (max-width: 520px) {
  .site-footer .footer-legal { margin-left: 0; width: 100%; }
}

@media (max-width: 600px) {
  .site-footer .footer-bar { padding: 24px var(--content-padding-mobile) 20px; }
}



/* Page-local source-attribution block sitting inside <main> at the end of
 * page content. The global .site-footer follows it with its own margin-top
 * and border-top divider — so we DON'T draw our own border (avoids the
 * "double-decker" two-divider look) and don't add a bottom margin. The
 * tournament Tier 2 file overrides padding-top for tighter pages; this is
 * the sitewide default. */
.spark-footer {
  text-align: center;
  padding: var(--space-lg) 0 0;
  margin-top: var(--space-lg);
}

.spark-footer-source {
  font-size: var(--font-size-small);
  color: var(--text-tertiary);
  line-height: 1.6;
  margin-bottom: 0;
}

.spark-footer-source em {
  font-style: italic;
  color: var(--text-secondary);
}

/* (Dead Spark-era footer/section rules removed 2026-04-18:
 *  .spark-footer-credit, .spark-footer-timestamp, .footer-links,
 *  .footer-divider, .footer-copyright, .spark-disclaimer,
 *  .section-heading + descendants, .section-intro, .section-divider,
 *  .divider. Verified zero markup consumers in src/pages and
 *  src/templates. See docs/design-system/INVENTORY.md.) */

/* ─────────────────────────────────────────────────────────────
 * 9. Hero block (generic — used by multiple page types)
 *    Source: components/hero.css
 * ───────────────────────────────────────────────────────────── */

.hero {
  text-align: center;
  padding: var(--space-3xl) 0 var(--space-2xl);
  position: relative;
}

.hero-kicker,
.hero-ol {
  font-size: var(--font-size-caption);
  letter-spacing: 3px;
  text-transform: uppercase;
  font-weight: var(--font-weight-semibold);
  display: inline-block;
  padding: 6px 18px;
  border-radius: 100px;
  border: 1px solid rgba(var(--accent-primary-rgb), 0.4);
  box-shadow: inset 0 0 0 100px rgba(var(--accent-primary-rgb), 0.08);
  background: linear-gradient(135deg, var(--accent-primary) 30%, var(--accent-secondary) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.hero h1 {
  font-size: var(--font-size-hero);
  line-height: 1.15;
  font-weight: var(--font-weight-bold);
  margin-top: 20px;
  margin-bottom: 16px;
  color: var(--white);
  position: relative;
}

.hero-sub,
.hero p {
  font-size: var(--font-size-body);
  color: var(--text-secondary);
  max-width: 620px;
  margin: 0 auto;
  line-height: 1.7;
  position: relative;
}

@media (max-width: 600px) {
  .hero {
    padding: 60px 0 36px;
  }
}

/* ─────────────────────────────────────────────────────────────
 * 9b. Stats bar (cross-type component)
 *     Used by tournament pages (player counts, prize money) and calendar
 *     pages (event counts). Two naming conventions co-exist for legacy
 *     reasons — short Spark names (.sb / .st / .sn / .sl) and long
 *     names (.stats-bar / .stat-item / .stat-num / .stat-label) — both
 *     map to the same rules via comma-grouped selectors. The number
 *     gradient flows from --accent-primary → --accent-secondary, so the
 *     tournament-local cyan-blue palette redeclaration in tournament.css
 *     §1 automatically retints the numbers without any extra rule.
 *     See docs/specs/2026-04-18-shared-components-design.md §1.
 * ───────────────────────────────────────────────────────────── */

/* Shared base: container is a centered flex row with 32px gap.
 * Variant differences (wrap vs scroll, margin) preserved per name to
 * avoid any pixel diff against current production rendering. */
.sb,
.stats-bar {
  display: flex;
  justify-content: center;
  gap: 32px;
}

/* Tournament short-name variant — non-wrapping, horizontal scroll on
 * overflow, larger top + bottom margins. */
.sb {
  margin: 24px auto 32px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.sb::-webkit-scrollbar { display: none; }

/* Calendar long-name variant — wraps, only top margin. */
.stats-bar {
  margin: 20px auto 0;
  flex-wrap: wrap;
}

.st,
.stat-item { text-align: center; }

.sn,
.stat-num {
  font-size: 28px;
  font-weight: 700;
  background: linear-gradient(135deg, var(--accent-primary) 30%, var(--accent-secondary) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  display: block;
}

.sl,
.stat-label {
  font-size: 13px;
  color: var(--text-tertiary);
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 500;
}

/* Tournament-page responsive (matches the previous tournament.css
 * @media block). Calendar's stats-bar has no responsive override. */
@media (max-width: 768px) {
  .sb { gap: 20px; }
  .sn { font-size: 22px; }
}

/* ─────────────────────────────────────────────────────────────
 * 9c. Badges — tier color tokens + tier/surface combo chip
 *     Used by calendar pages on event cards, in the Gantt grid (bar
 *     fill via --tier-color), in the Gantt popup (left border), and as
 *     filter buttons. Tier color tokens are hardcoded hex values — not
 *     palette-derived — so the same colors render on every page type
 *     regardless of local accent overrides. Tournament pages do not
 *     currently render these classes; promoting is safe.
 *     See docs/specs/2026-04-18-shared-components-design.md §2.
 * ───────────────────────────────────────────────────────────── */

.tier-gs     { --tier-color: #f5c842; }
.tier-m1000  { --tier-color: #5dd4f5; }
.tier-500    { --tier-color: #4ade80; }
.tier-250    { --tier-color: var(--text-tertiary); }
.tier-finals { --tier-color: #c084fc; }

.combo-badge {
  display: inline-flex;
  align-items: stretch;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--tier-color);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  line-height: 1;
}
.combo-tier {
  padding: 4px 10px;
  color: var(--tier-color);
  background: rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
}
.combo-surface {
  padding: 4px 10px;
  background: var(--tier-color);
  color: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: center;
  font-weight: 600;
}

/* ─────────────────────────────────────────────────────────────
 * 10. Nav pills (sticky chapter nav)
 *     Source: components/nav.css
 * ───────────────────────────────────────────────────────────── */

.nav-chapters {
  position: sticky;
  top: 16px;
  z-index: 50;
  margin: 16px auto 32px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 30px;
  padding: 6px;
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  backdrop-filter: blur(24px) saturate(1.2);
  -webkit-backdrop-filter: blur(24px) saturate(1.2);
  max-width: fit-content;
}

.nav-chapters::-webkit-scrollbar {
  display: none;
}

.nav-pill {
  padding: 8px 16px;
  border-radius: 25px;
  font-size: var(--font-size-min);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--transition-base);
  color: var(--text-secondary);
  border: 1px solid transparent;
  background: none;
}

.nav-pill:hover {
  background: rgba(255, 255, 255, 0.06);
}

.nav-pill.active {
  background: rgba(var(--accent-primary-rgb), 0.2);
  color: var(--white);
  border-color: rgba(var(--accent-primary-rgb), 0.5);
  box-shadow: 0 0 12px rgba(var(--accent-primary-rgb), 0.15);
}

@media (max-width: 600px) {
  .nav-chapters {
    margin: 8px auto 24px;
  }
  .nav-pill {
    padding: 8px 14px;
    font-size: var(--font-size-caption);
  }
}

/* ─────────────────────────────────────────────────────────────
 * 11. Language switcher — REMOVED 2026-04-18 (slice f).
 *     The legacy short-name lang dropdown (.lb / .lt / .ld / .lo /
 *     .lc / .chev) was superseded by the v1.3 .lang-chip / .lang-menu
 *     / .lang-option / .lang-code / .lang-name vocabulary in §6 above.
 *     Verified zero consumers in src/templates/ for the short names.
 *     The tournament template's runtime JS still references ".lo" and
 *     "#llab" for an i18n update path that does nothing today (no
 *     matching markup exists); that is a separate, known-broken
 *     tournament-i18n issue, tracked elsewhere.
 * ───────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────
 * 12. i18n — language visibility, CJK typography, RTL mirroring
 *     Source: core/i18n.css
 *     Decision D007: explicit display values (not display:revert) to avoid
 *     the badge spacing bug with <span data-lang>.
 * ───────────────────────────────────────────────────────────── */

[data-lang] { display: none !important; }

body.lang-en [data-lang="en"],
body.lang-zh [data-lang="zh"],
body.lang-es [data-lang="es"],
body.lang-ko [data-lang="ko"],
body.lang-ja [data-lang="ja"],
body.lang-fr [data-lang="fr"],
body.lang-de [data-lang="de"],
body.lang-pt [data-lang="pt"],
body.lang-ar [data-lang="ar"],
body.lang-hi [data-lang="hi"],
body.lang-fa [data-lang="fa"],
body.lang-ru [data-lang="ru"] {
  display: block !important;
}

body.lang-en img[data-lang="en"],
body.lang-zh img[data-lang="zh"],
body.lang-es img[data-lang="es"],
body.lang-ko img[data-lang="ko"],
body.lang-ja img[data-lang="ja"],
body.lang-fr img[data-lang="fr"],
body.lang-de img[data-lang="de"],
body.lang-pt img[data-lang="pt"],
body.lang-ar img[data-lang="ar"],
body.lang-hi img[data-lang="hi"],
body.lang-fa img[data-lang="fa"],
body.lang-ru img[data-lang="ru"] {
  display: inline-block !important;
}

body.lang-en .hero-kicker[data-lang="en"], body.lang-en .hero-ol[data-lang="en"],
body.lang-zh .hero-kicker[data-lang="zh"], body.lang-zh .hero-ol[data-lang="zh"],
body.lang-es .hero-kicker[data-lang="es"], body.lang-es .hero-ol[data-lang="es"],
body.lang-ko .hero-kicker[data-lang="ko"], body.lang-ko .hero-ol[data-lang="ko"],
body.lang-ja .hero-kicker[data-lang="ja"], body.lang-ja .hero-ol[data-lang="ja"],
body.lang-fr .hero-kicker[data-lang="fr"], body.lang-fr .hero-ol[data-lang="fr"],
body.lang-de .hero-kicker[data-lang="de"], body.lang-de .hero-ol[data-lang="de"],
body.lang-pt .hero-kicker[data-lang="pt"], body.lang-pt .hero-ol[data-lang="pt"],
body.lang-ar .hero-kicker[data-lang="ar"], body.lang-ar .hero-ol[data-lang="ar"],
body.lang-hi .hero-kicker[data-lang="hi"], body.lang-hi .hero-ol[data-lang="hi"],
body.lang-fa .hero-kicker[data-lang="fa"], body.lang-fa .hero-ol[data-lang="fa"],
body.lang-ru .hero-kicker[data-lang="ru"], body.lang-ru .hero-ol[data-lang="ru"] {
  display: inline-block !important;
}

body.lang-en .nav-pill[data-lang="en"],
body.lang-zh .nav-pill[data-lang="zh"],
body.lang-es .nav-pill[data-lang="es"],
body.lang-ko .nav-pill[data-lang="ko"],
body.lang-ja .nav-pill[data-lang="ja"],
body.lang-fr .nav-pill[data-lang="fr"],
body.lang-de .nav-pill[data-lang="de"],
body.lang-pt .nav-pill[data-lang="pt"],
body.lang-ar .nav-pill[data-lang="ar"],
body.lang-hi .nav-pill[data-lang="hi"],
body.lang-fa .nav-pill[data-lang="fa"],
body.lang-ru .nav-pill[data-lang="ru"] {
  display: inline-flex !important;
}

/* CJK scripts have no true italic — drop slant on quote blocks */
body.lang-zh blockquote,
body.lang-ja blockquote,
body.lang-ko blockquote {
  font-style: normal;
}

body.lang-zh { font-family: 'Noto Sans SC', 'Sora', sans-serif; }
body.lang-ko { font-family: 'Noto Sans KR', 'Sora', sans-serif; }
body.lang-ja { font-family: 'Noto Sans JP', 'Sora', sans-serif; }
body.lang-ar { font-family: 'Noto Sans Arabic', 'Sora', sans-serif; direction: rtl; }
body.lang-hi { font-family: 'Noto Sans Devanagari', 'Sora', sans-serif; }
body.lang-fa { font-family: 'Noto Sans Arabic', 'Sora', sans-serif; direction: rtl; }
body.lang-ru { font-family: 'Sora', sans-serif; }

/* Arabic/Farsi connected letters — no letter-spacing */
body.lang-ar .hero-kicker, body.lang-fa .hero-kicker,
body.lang-ar .hero-ol,     body.lang-fa .hero-ol,
body.lang-ar .stat-label,  body.lang-fa .stat-label,
body.lang-ar .nav-pill,    body.lang-fa .nav-pill {
  letter-spacing: 0;
}

/* CJK/Arabic: uppercase is meaningless */
body.lang-zh .hero-kicker, body.lang-zh .hero-ol, body.lang-zh .stat-label,
body.lang-ko .hero-kicker, body.lang-ko .hero-ol, body.lang-ko .stat-label,
body.lang-ja .hero-kicker, body.lang-ja .hero-ol, body.lang-ja .stat-label,
body.lang-ar .hero-kicker, body.lang-ar .hero-ol, body.lang-ar .stat-label,
body.lang-fa .hero-kicker, body.lang-fa .hero-ol, body.lang-fa .stat-label {
  text-transform: none;
}

/* ─────────────────────────────────────────────────────────────
 * 13. Legal pages (privacy, terms) — generic sitewide styling
 *     Source: inline <style> in templates/legal/{privacy,terms}.html
 * ───────────────────────────────────────────────────────────── */

.legal-content {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
}

.legal-content h1 {
  font-size: clamp(24px, 4vw, 36px);
  font-weight: 700;
  color: var(--white);
  margin-bottom: 0.5rem;
}

.legal-content .legal-updated {
  font-size: 14px;
  color: var(--text-tertiary);
  margin-bottom: 2rem;
}

.legal-content h2 {
  font-size: 18px;
  font-weight: 600;
  color: var(--white);
  margin-top: 2rem;
  margin-bottom: 0.75rem;
}

.legal-content p {
  font-size: 15px;
  color: var(--text-secondary);
  line-height: 1.7;
  margin-bottom: 1rem;
}

.legal-content ul {
  padding-left: 1.25rem;
  margin-bottom: 1rem;
}

.legal-content li {
  font-size: 15px;
  color: var(--text-secondary);
  line-height: 1.7;
  margin-bottom: 0.5rem;
}

.legal-content a {
  color: var(--accent-primary-text);
  text-decoration: none;
}

.legal-content a:hover {
  text-decoration: underline;
}

/* Google Tag Manager noscript iframe — hidden fallback for JS-disabled clients. */
.gtm-noscript {
  display: none;
  visibility: hidden;
}
