/* ============================================================================
   GA Deck Analysis -- viewer styles
   Dark by default, light theme via prefers-color-scheme.
   ========================================================================== */

:root {
  color-scheme: dark light;

  /* Fluid root font size -- the whole UI is rem-based, so this single
     viewport-scaled value makes everything (text, padding, the content
     column width below) auto-adjust to the screen: ~16px on a small
     laptop, ~19px at 1080p, up to 22px on a large monitor. */
  font-size: clamp(16px, 0.36vw + 11.9px, 22px);

  /* Dark theme (default) */
  --bg:            #0a0d12;
  --bg-elevated:   #131820;
  --panel-translucent: rgba(19, 24, 32, 0.44);   /* bg-elevated, see-through */
  --bg-soft:       rgba(255, 255, 255, 0.035);
  --bg-hover:      rgba(255, 255, 255, 0.06);
  --bg-row-alt:    rgba(255, 255, 255, 0.015);
  --border:        rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.16);
  --fg:            #d8dee9;
  --fg-strong:     #f1f5f9;
  --muted:         #94a3b8;
  --muted-dim:     #64748b;
  --accent:        #22d3ee;            /* cyan-400 */
  --accent-strong: #06b6d4;            /* cyan-500 */
  --accent-soft:   rgba(34, 211, 238, 0.12);
  --accent-glow:   rgba(34, 211, 238, 0.35);
  --accent-text:   #67e8f9;

  --warm-soft:     rgba(251, 146, 60, 0.14);
  --warm-text:     #fdba74;
  --warm-border:   rgba(251, 146, 60, 0.32);

  /* Ban-list flag -- the "Banned" ribbon over a banned card. Red reads the
     same on both themes (it always sits on top of card art). */
  --banned:        #dc2626;
  --banned-ring:   rgba(220, 38, 38, 0.9);

  /* Winrate ramp -- 10% buckets */
  --wr-0: #b91c1c; --wr-1: #dc2626; --wr-2: #ea580c; --wr-3: #f59e0b;
  --wr-4: #d97706; --wr-5: #84cc16; --wr-6: #22c55e; --wr-7: #16a34a;
  --wr-8: #15803d; --wr-9: #166534;
}

/* Light theme variables. Applied either by explicit override
   (data-theme="light") or by OS preference when no explicit theme is set. */
:root[data-theme="light"] {
  --bg:            #f8fafc;
  --bg-elevated:   #ffffff;
  --panel-translucent: rgba(255, 255, 255, 0.76);
  --bg-soft:       rgba(15, 23, 42, 0.035);
  --bg-hover:      rgba(15, 23, 42, 0.05);
  --bg-row-alt:    rgba(15, 23, 42, 0.02);
  --border:        rgba(15, 23, 42, 0.10);
  --border-strong: rgba(15, 23, 42, 0.20);
  --fg:            #0f172a;
  --fg-strong:     #020617;
  --muted:         #475569;
  --muted-dim:     #64748b;
  --accent:        #0891b2;
  --accent-strong: #0e7490;
  --accent-soft:   rgba(8, 145, 178, 0.10);
  --accent-glow:   rgba(8, 145, 178, 0.20);
  --accent-text:   #0e7490;
  --warm-soft:     rgba(234, 88, 12, 0.10);
  --warm-text:     #9a3412;
  --warm-border:   rgba(234, 88, 12, 0.25);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg:            #f8fafc;
    --bg-elevated:   #ffffff;
    --panel-translucent: rgba(255, 255, 255, 0.76);
    --bg-soft:       rgba(15, 23, 42, 0.035);
    --bg-hover:      rgba(15, 23, 42, 0.05);
    --bg-row-alt:    rgba(15, 23, 42, 0.02);
    --border:        rgba(15, 23, 42, 0.10);
    --border-strong: rgba(15, 23, 42, 0.20);
    --fg:            #0f172a;
    --fg-strong:     #020617;
    --muted:         #475569;
    --muted-dim:     #64748b;
    --accent:        #0891b2;
    --accent-strong: #0e7490;
    --accent-soft:   rgba(8, 145, 178, 0.10);
    --accent-glow:   rgba(8, 145, 178, 0.20);
    --accent-text:   #0e7490;
    --warm-soft:     rgba(234, 88, 12, 0.10);
    --warm-text:     #9a3412;
    --warm-border:   rgba(234, 88, 12, 0.25);
  }
}

* { box-sizing: border-box; }

html {
  background: var(--bg);
  /* Reserve the scrollbar gutter so opening the card lightbox (which locks
     body scroll) doesn't widen the viewport and shift the page sideways. */
  scrollbar-gutter: stable;
}
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 1rem;          /* follows the fluid root size set on :root */
  line-height: 1.55;
  background: var(--bg);
  color: var(--fg);
  margin: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
}

/* -- Page shell: left sidebar + main column ------------------------------- */
.layout-shell {
  display: grid;
  grid-template-columns: 15rem 1fr;   /* rem -> sidebar scales with the UI */
  min-height: 100vh;
  /* Sits explicitly above the fixed .page-art backdrop layer. */
  position: relative;
  z-index: 1;
}
.layout-main {
  min-width: 0;            /* prevents grid blowing out on wide tables */
  display: flex;
  flex-direction: column;
}
.layout-main main,
.layout-main footer {
  width: 100%;
  /* rem-based so the content column widens on larger screens in step with
     the fluid root font -- ~1320px small, ~1580px at 1080p, ~1815px max. */
  max-width: 82.5rem;
  margin: 0 auto;
  padding-left: 2rem;
  padding-right: 2rem;
}

/* -- Sidebar -------------------------------------------------------------- */
.sidebar {
  background: var(--bg-elevated);
  border-right: 1px solid var(--border);
  padding: 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  /* Subtle atmospheric inner glow at the bottom-left so the bar doesn't
     read as a flat panel. */
  background:
    radial-gradient(120% 60% at 0% 100%, var(--accent-soft) 0%, transparent 60%),
    var(--bg-elevated);
}
.sidebar .brand {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.65rem;
  margin-bottom: 0;
  text-decoration: none;
}
.brand {
  color: var(--fg-strong);
  text-decoration: none;
  font-family: 'Bricolage Grotesque', 'Inter', sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.brand:hover { text-decoration: none; }
.brand-logo {
  display: inline-flex;
  width: 34px; height: 34px;
  align-items: center; justify-content: center;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: #001216;
  font-weight: 800;
  font-size: 13px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  box-shadow: 0 0 0 1px var(--border-strong), 0 2px 8px var(--accent-glow);
  flex-shrink: 0;
}
.brand-text { display: flex; flex-direction: column; min-width: 0; }
.brand-name { font-size: 1rem; font-weight: 700; }
.brand-tagline {
  font-family: 'Inter', sans-serif;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1;
}
.sidebar-nav-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  border-radius: 8px;
  color: var(--fg);
  text-decoration: none;
  font-weight: 500;
  font-size: 0.92rem;
  transition: background 110ms ease, color 110ms ease, transform 110ms ease;
}
.sidebar-nav-link:hover {
  background: var(--bg-hover);
  color: var(--accent);
  text-decoration: none;
  transform: translateX(2px);
}
.sidebar-nav-link.is-active {
  background: var(--accent-soft);
  color: var(--accent-text);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--accent);
}
.sidebar-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.sidebar-bottom {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  justify-content: space-between;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}
.sidebar-bottom-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.32rem 0.55rem;
  border-radius: 7px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 500;
}
.sidebar-bottom-link:hover {
  color: var(--accent);
  background: var(--bg-hover);
  text-decoration: none;
}
.sidebar-bottom-link .sidebar-icon { width: 16px; height: 16px; }

main { padding-top: 1.5rem; padding-bottom: 2rem; flex: 1; }

footer {
  border-top: 1px solid var(--border);
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 3rem;
  padding-top: 1.25rem;
  padding-bottom: 2rem;
}

/* Mobile: collapse sidebar to a horizontal top bar with icon-only links. */
@media (max-width: 880px) {
  .layout-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1rem;
    border-right: none;
    border-bottom: 1px solid var(--border);
    /* Prevent children from blowing out the bar width. */
    overflow: hidden;
  }
  .sidebar .brand .brand-tagline { display: none; }
  /* Brand link: shrink but don't disappear until 375px breakpoint. */
  .sidebar .brand {
    flex-shrink: 0;
    min-width: 0;
  }
  .sidebar-nav {
    flex-direction: row;
    gap: 0.25rem;
    flex: 1;
    min-width: 0;
    justify-content: flex-end;
  }
  .sidebar-nav-link {
    padding: 0.5rem 0.7rem;
    min-width: 0;
    flex-shrink: 0;
    /* Ensure nav links are at least 40px tall for tap targets. */
    min-height: 2.5rem;
  }
  .sidebar-nav-link .sidebar-label { display: none; }
  .sidebar-bottom {
    flex-direction: row;
    padding: 0;
    border-top: none;
    border-left: 1px solid var(--border);
    padding-left: 0.6rem;
    flex-shrink: 0;
  }
  .sidebar-bottom-link .sidebar-label { display: none; }
  .layout-main main,
  .layout-main footer {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}
footer .footer-disclaimer {
  margin: 0 0 0.45rem;
  line-height: 1.55;
  font-size: 0.78rem;
}
footer .footer-trademark {
  margin: 0 0 0.45rem;
  line-height: 1.55;
  font-size: 0.72rem;
  font-style: italic;
  color: var(--muted-dim);
}
footer .footer-meta {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}
footer .dot { color: var(--muted-dim); }

/* -- Typography / links ----------------------------------------------------- */
a {
  color: var(--accent);
  text-decoration: none;
  transition: color 120ms ease;
}
a:hover { color: var(--accent-strong); text-decoration: underline; }
.muted { color: var(--muted); }

/* Bricolage Grotesque is a variable display face with a characterful
   "pulled-from-print" feel. Used for top-level headings and the brand
   wordmark; Inter still does the body, JetBrains Mono still does stats.
   That three-font system distinguishes us from the generic "Inter
   everywhere" look the frontend-design skill warns against. */
h1, h2, .h-display {
  font-family: 'Bricolage Grotesque', 'Inter', -apple-system, sans-serif;
  font-optical-sizing: auto;
}
h1 {
  font-size: 2.1rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin: 0.4rem 0 0.45rem;
  color: var(--fg-strong);
  line-height: 1.05;
}
h2 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-top: 2rem;
  margin-bottom: 0.5rem;
  color: var(--fg-strong);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
}

p { margin: 0.65rem 0; }
p.muted { line-height: 1.65; font-size: 0.88rem; }

/* -- Tables ---------------------------------------------------------------- */
table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  margin: 0.5rem 0 1.5rem;
  font-size: 0.875rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-elevated);
}
th, td {
  text-align: left;
  padding: 0.55rem 0.85rem;
  border-bottom: 1px solid var(--border);
}
th {
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: var(--bg-soft);
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background 100ms ease; }
tbody tr:nth-child(even) { background: var(--bg-row-alt); }
tbody tr:hover { background: var(--bg-hover); }
tbody tr:hover td:first-child {
  box-shadow: inset 2px 0 0 var(--accent);
}
td.num, th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}
td a { color: var(--fg-strong); font-weight: 500; }
td a:hover { color: var(--accent); }

/* -- Winrate / EV chips ---------------------------------------------------- */
.wr {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.18rem 0.5rem;
  border-radius: 5px;
  font-variant-numeric: tabular-nums;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.78rem;
  font-weight: 600;
  min-width: 4em;
  color: #fff;
  letter-spacing: -0.01em;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.18);
}
.wr-0 { background: var(--wr-0); }
.wr-1 { background: var(--wr-1); }
.wr-2 { background: var(--wr-2); }
.wr-3 { background: var(--wr-3); color: #1a1300; }
.wr-4 { background: var(--wr-4); }
.wr-5 { background: var(--wr-5); color: #0f1a00; }
.wr-6 { background: var(--wr-6); }
.wr-7 { background: var(--wr-7); }
.wr-8 { background: var(--wr-8); }
.wr-9, .wr-10 { background: var(--wr-9); }

/* Low-sample winrate / EV: a figure from only a handful of matches is
   faded so it reads as a rough estimate, not a precise number. Brightens
   on hover so it's still fully legible when you look closely. */
.wr.wr-low {
  opacity: 0.42;
  transition: opacity 130ms ease;
}
.wr.wr-low:hover {
  opacity: 0.85;
}
tbody tr:hover .wr.wr-low {
  opacity: 0.7;
}

/* -- Stat row (hero stats on archetype page) ------------------------------- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  margin: 1.5rem 0 2rem;
}
.stat {
  background: var(--bg-elevated);
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 4.5rem;
}
.stat-label {
  font-size: 0.66rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.stat-value {
  font-size: 1.3rem;
  font-weight: 600;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  line-height: 1.15;
}
.stat-value .wr { font-size: 1.1rem; padding: 0.25rem 0.6rem; }
.stat-sub {
  font-family: 'Inter', sans-serif;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--muted);
  margin-left: 0.5rem;
}

/* -- Pilot-skill badges + CP range bar ------------------------------------- */
.skew {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 5px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
}
.skew-top {
  background: var(--accent-soft);
  color: var(--accent-text);
  border: 1px solid rgba(34, 211, 238, 0.28);
}
.skew-low {
  background: var(--warm-soft);
  color: var(--warm-text);
  border: 1px solid var(--warm-border);
}
.skew-flat {
  background: var(--bg-soft);
  color: var(--muted);
  border: 1px solid var(--border);
}

.pilot-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.15rem 1.4rem;
  margin: 1.5rem 0 2rem;
}
.pilot-headline {
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted);
  margin-bottom: 0.45rem;
  display: flex;
  align-items: center;
  gap: 0.55rem;
}
.pilot-subhead {
  font-size: 0.9rem;
  color: var(--fg);
  margin-bottom: 0.85rem;
}
.pilot-subhead strong {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.05rem;
  color: var(--fg-strong);
  font-weight: 600;
}
.pilot-detail {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 0.8rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  line-height: 1.6;
}
.pilot-detail strong { color: var(--fg-strong); font-weight: 600; }

.cp-bar {
  position: relative;
  height: 12px;
  border-radius: 6px;
  background: var(--bg-soft);
  margin: 0.5rem 0 0.25rem;
  overflow: visible;
  border: 1px solid var(--border);
}
.cp-zone { position: absolute; top: 0; bottom: 0; }
.cp-zone-low  { background: rgba(251, 146, 60, 0.22); }
.cp-zone-mid  { background: rgba(148, 163, 184, 0.08); }
.cp-zone-high { background: rgba(34, 211, 238, 0.22); }
.cp-field-mean {
  position: absolute;
  top: -3px; bottom: -3px;
  width: 2px;
  background: var(--muted-dim);
  transform: translateX(-1px);
}
.cp-marker {
  position: absolute;
  top: -4px;
  height: 20px;
  width: 4px;
  background: var(--accent);
  border-radius: 2px;
  transform: translateX(-2px);
  box-shadow: 0 0 10px var(--accent-glow), 0 0 0 1px var(--bg-elevated);
}
.pilot-foot {
  display: flex;
  justify-content: space-between;
  font-size: 0.68rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--muted);
  margin-top: 0.3rem;
  letter-spacing: 0.02em;
}

/* -- Matrix view ----------------------------------------------------------- */
.filter-form {
  margin: 0.25rem 0 1rem;
  font-size: 0.85rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.4rem 0.7rem;
}
.filter-form label { display: inline-flex; gap: 0.4rem; align-items: center; color: var(--muted); }
.filter-form input {
  width: 4em;
  padding: 0.25rem 0.45rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--fg);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.85rem;
}
.filter-form input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.filter-form button {
  padding: 0.3rem 0.85rem;
  background: var(--accent);
  border: 1px solid var(--accent-strong);
  border-radius: 4px;
  color: #001216;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 0.02em;
}
.filter-form button:hover { background: var(--accent-strong); color: #001216; }

.matrix-wrap {
  /* Become a 2-axis scroll container with a bounded height so the sticky
     headers actually stick. Without max-height, this element grew to fit
     its content and the *page* scrolled instead -- sticky had nothing to
     stick relative to. */
  overflow: auto;
  max-height: calc(100vh - 220px);
  min-height: 24rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-elevated);
}
.matrix {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: 0.78rem;
  margin: 0;
  border: none;
  border-radius: 0;
  background: var(--bg-elevated);
}
.matrix th, .matrix td {
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  padding: 0;
}
.matrix tbody tr:nth-child(even) { background: transparent; }
.matrix th.corner {
  background: var(--bg-elevated);
  padding: 0.6rem 0.9rem;
  min-width: 14em;
  position: sticky;
  left: 0; z-index: 3;
  color: var(--muted);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 600;
}
.matrix th.row-head {
  background: var(--bg-elevated);
  padding: 0.45rem 0.9rem;
  min-width: 14em;
  max-width: 16em;
  position: sticky;
  left: 0; z-index: 2;
  text-align: left;
  font-weight: 500;
  font-size: 0.82rem;
  color: var(--fg);
  text-transform: none;
  letter-spacing: 0;
}
.matrix th.row-head a { color: var(--fg-strong); }
.matrix th.col-head {
  vertical-align: bottom;
  height: 10em;
  padding: 0;
  min-width: 3.8em;
  max-width: 3.8em;
  background: var(--bg-elevated);
}
.matrix th.col-head .col-head-inner {
  transform: rotate(-55deg);
  transform-origin: left bottom;
  white-space: nowrap;
  padding: 0.35rem 0.55rem;
  font-weight: 500;
  font-size: 0.78rem;
  display: inline-block;
  max-width: 10em;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: none;
  letter-spacing: 0;
}
.matrix th.col-head .col-head-inner a { color: var(--fg-strong); }
.matrix th.col-head .col-head-sub {
  display: block;
  font-size: 0.66rem;
  color: var(--muted);
  font-weight: 400;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.02em;
}
.matrix td.cell {
  padding: 0.3rem 0.25rem;
  min-width: 3.8em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.matrix td.cell .cell-wr {
  font-weight: 600;
  line-height: 1.15;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.85rem;
  color: #fff;
}
.matrix td.cell.wr-3 .cell-wr,
.matrix td.cell.wr-5 .cell-wr { color: #0f1a00; }
.matrix td.cell .cell-n {
  font-size: 0.66rem;
  opacity: 0.85;
  line-height: 1.05;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.matrix td.cell.mirror,
.matrix td.cell.empty {
  background: var(--bg-soft);
  color: var(--muted);
}
.matrix tbody tr:hover { background: transparent; }
.matrix tbody tr:hover th.row-head {
  background: var(--bg-hover);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* -- Code / pre ------------------------------------------------------------ */
pre, code {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 6px;
}
pre {
  padding: 0.9rem 1rem;
  overflow-x: auto;
  font-size: 0.83rem;
  line-height: 1.65;
  color: var(--fg);
}
code {
  padding: 0.08rem 0.32rem;
  font-size: 0.86em;
  color: var(--accent-text);
}

/* -- Misc small utilities -------------------------------------------------- */
.archetypes td:first-child a,
.h2h td:first-child a {
  font-weight: 600;
}

/* -- Event-type filter pills (events index) -------------------------------- */
.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 1rem 0 1.25rem;
}
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.32rem 0.75rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 20px;
  color: var(--fg);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
  transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
}
.filter-pill:hover {
  border-color: var(--accent);
  color: var(--accent);
  text-decoration: none;
}
.filter-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #001216;
  font-weight: 600;
}
.filter-pill.is-active:hover { color: #001216; }
/* Event-type pill with no events in the current scope (e.g. no Worlds in
   the selected season) -- faded to read as "0", still clickable. */
.filter-pill-zero { opacity: 0.4; }
.filter-pill-zero:hover { opacity: 0.75; }
/* Champion-variant marker in the archetype-page h1 (Razorgale > Kongming). */
.champ-sub { color: var(--muted); font-weight: 500; }
.filter-pill-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4em;
  padding: 0 0.35rem;
  background: var(--bg-soft);
  border-radius: 9px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
}
.filter-pill.is-active .filter-pill-count {
  background: rgba(0, 0, 0, 0.18);
  color: #001216;
}

/* Secondary filter-pill row -- season filter, hide-empty toggle, etc.
   Slightly smaller text + label prefix so it doesn't compete with the
   primary category row above it. */
.filter-pills-sub {
  margin-top: 0.5rem;
  font-size: 0.85rem;
}
.filter-pills-sub .filter-pill {
  padding: 0.24rem 0.6rem;
  font-size: 0.84rem;
}
.filter-pills-label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  align-self: center;
  margin-right: 0.15rem;
}
/* Toggle-style pill (used for "Include events without decklists"). The
   icon at the front + the is-active background communicates state. */
.filter-pill-toggle .filter-pill-icon {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1rem;
  line-height: 1;
}

/* Custom date-range form on /meta -- two native date inputs + apply. */
.date-range-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  margin-top: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
}
.date-range-field {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--muted);
  font-size: 0.8rem;
}
.date-range-field input[type="date"] {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--fg);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.8rem;
  padding: 0.28rem 0.5rem;
}
.date-range-field input[type="date"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.date-range-apply {
  padding: 0.3rem 0.85rem;
  border-radius: 7px;
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-weight: 600;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 120ms ease;
}
.date-range-apply:hover { background: rgba(34, 211, 238, 0.2); }
.date-range-clear {
  font-size: 0.8rem;
  color: var(--muted);
}
.date-range-form.is-active .filter-pills-label {
  color: var(--accent-text);
}

/* "no decklist" badge inline with the event name -- mutes the row visually
   so the eye skips past empty events when they're shown. */
.no-decklist-badge {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.06rem 0.45rem;
  border-radius: 4px;
  background: var(--bg-soft);
  border: 1px dashed var(--border-strong);
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 0.1em;
}
.event-no-decklist td { opacity: 0.7; }
.event-no-decklist td a { color: var(--muted); }
.event-no-decklist td a:hover { color: var(--accent); }

/* -- Inline category tag in the Type column (clickable filter) ------------- */
.cat-tag {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 5px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid var(--border);
  color: var(--fg);
  background: var(--bg-soft);
  transition: filter 120ms ease, border-color 120ms ease;
}
.cat-tag:hover { filter: brightness(1.15); border-color: var(--accent); text-decoration: none; }
/* Per-category color hints. Major events stand out; locals stay neutral. */
.cat-tag-worlds              { background: rgba(168, 85, 247, 0.18); color: #d8b4fe; border-color: rgba(168, 85, 247, 0.35); }
.cat-tag-nationals           { background: rgba(251, 191, 36, 0.18); color: #fcd34d; border-color: rgba(251, 191, 36, 0.4); }
.cat-tag-ascent              { background: rgba(34, 211, 238, 0.18); color: #67e8f9; border-color: rgba(34, 211, 238, 0.4); }
.cat-tag-regionals           { background: rgba(132, 204, 22, 0.18); color: #bef264; border-color: rgba(132, 204, 22, 0.4); }
.cat-tag-store-championships { background: rgba(148, 163, 184, 0.16); color: var(--fg); border-color: var(--border); }
.cat-tag-regular             { background: var(--bg-soft); color: var(--muted); border-color: var(--border); }

/* -- Season pill on the events index --------------------------------------- */
.season-pill {
  display: inline-block;
  padding: 0.08rem 0.5rem;
  border-radius: 5px;
  background: var(--accent-soft);
  color: var(--accent-text);
  border: 1px solid rgba(34, 211, 238, 0.28);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
}

/* -- "Pooled meta" entry-point link on the events index ------------------- */
.meta-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.85rem;
  background: var(--accent-soft);
  border: 1px solid rgba(34, 211, 238, 0.32);
  border-radius: 8px;
  color: var(--accent-text);
  font-weight: 500;
  font-size: 0.9rem;
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease;
}
.meta-link:hover {
  background: rgba(34, 211, 238, 0.18);
  border-color: var(--accent);
  color: var(--accent-text);
  text-decoration: none;
}

/* -- Theme-toggle button (sidebar bottom) --------------------------------- */
.theme-toggle {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--muted);
  cursor: pointer;
  font-size: 1rem;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
  flex-shrink: 0;
}
.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}
.theme-icon { line-height: 1; pointer-events: none; display: none; }
/* Show the icon reflecting the EFFECTIVE theme (so the user sees the toggle
   that matches what's actually on screen, not what they'd be switching to). */
:root[data-theme="dark"]  .theme-icon-sun  { display: inline; }
:root[data-theme="light"] .theme-icon-moon { display: inline; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .theme-icon-sun  { display: inline; }
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .theme-icon-moon { display: inline; }
}

/* -- Sortable column headers ----------------------------------------------- */
th.sortable {
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: color 120ms ease, background 120ms ease;
}
th.sortable:hover { color: var(--accent); background: var(--bg-hover); }
th.sortable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
th.sortable[data-sort] { color: var(--accent); }
th .sort-arrow {
  display: inline-block;
  margin-left: 0.3em;
  width: 0.85em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
  color: var(--accent);
  opacity: 0.85;
}
/* Faint up/down hint on every not-yet-sorted sortable header, so it's
   discoverable that the column can be clicked. sort.js swaps in a solid
   arrow (and sets data-sort) once a column is active. */
th.sortable:not([data-sort]) .sort-arrow::after {
  content: "\2195";
  color: var(--muted);
  opacity: 0.4;
}
th.sortable:not([data-sort]):hover .sort-arrow::after {
  color: var(--accent);
  opacity: 0.75;
}

/* -- Sticky filter bar + sticky matrix headers ----------------------------- */
.filter-form {
  position: sticky;
  top: 0;
  z-index: 6;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  background: color-mix(in oklab, var(--bg-elevated) 92%, transparent);
}
@supports not (backdrop-filter: blur(8px)) {
  .filter-form { background: var(--bg-elevated); }
}

/* Matrix: stick the column-header row to the top while the body scrolls.
   Combined with the existing sticky-left row-head, the corner cell needs
   the higher z-index so it sits above both sticky axes. */
.matrix thead th {
  position: sticky;
  top: 0;
  z-index: 4;
}
.matrix thead th.corner {
  z-index: 5;
}
.matrix th.row-head { z-index: 3; }

/* -- Event-page hero: donut + element bar + top list ---------------------- */
/* Was a donut + sidebar 2-column grid; the donut is gone, so this is now
   just a full-width wrapper for the remaining hero blocks. */
.hero-grid {
  margin: 1.5rem 0 2rem;
}
@media (max-width: 720px) {
  .hero-grid { grid-template-columns: 1fr; }
}

.hero-donut {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero-donut svg { width: 100%; height: auto; max-width: 240px; display: block; }
.donut-seg {
  transition: filter 120ms ease, transform 120ms ease;
  transform-origin: center;
  transform-box: fill-box;
  cursor: pointer;
}
.donut-seg:hover { filter: brightness(1.15) drop-shadow(0 0 8px var(--accent-glow)); }
.donut-center-num {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.7rem;
  font-weight: 700;
  fill: var(--fg-strong);
  letter-spacing: -0.02em;
}
.donut-center-label {
  font-family: 'Inter', sans-serif;
  font-size: 0.7rem;
  fill: var(--muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hero-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.hero-block {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.15rem;
}
.hero-block-label {
  font-size: 0.66rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted);
  margin-bottom: 0.65rem;
}

.element-bar {
  display: flex;
  height: 14px;
  border-radius: 7px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.element-seg {
  display: inline-block;
  height: 100%;
  transition: filter 120ms ease;
}
.element-seg:hover { filter: brightness(1.15); }
.element-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 0.65rem;
  font-size: 0.82rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.element-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--fg);
}
.element-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--border);
}

.hero-top-list {
  list-style: none;
  padding: 0; margin: 0;
  /* Flow across the full width now that it isn't a narrow donut sidebar. */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: 0.4rem 1.5rem;
}
.hero-top-list li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.9rem;
}
.hero-top-list li a { color: var(--fg-strong); font-weight: 500; }
.hero-top-list li a:hover { color: var(--accent); }
.hero-top-swatch {
  width: 10px; height: 10px;
  border-radius: 3px;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px var(--border);
}
.hero-top-share {
  margin-left: auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.85rem;
}

/* -- EV-page top-3 podium -------------------------------------------------- */
.podium {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  align-items: end;
  margin: 1.25rem 0 2rem;
}
@media (max-width: 720px) {
  .podium { grid-template-columns: 1fr; align-items: stretch; }
}
.podium-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.45rem;
  padding: 1.15rem 1rem 1.25rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  text-decoration: none;
  color: var(--fg);
  position: relative;
  overflow: hidden;
  transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}
.podium-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  text-decoration: none;
}
.podium-card::before {
  content: '';
  position: absolute;
  inset: -1px -1px auto -1px;
  height: 4px;
  border-radius: 12px 12px 0 0;
  background: var(--medal-color, var(--accent));
}
.podium-gold {
  --medal-color: linear-gradient(90deg, #fbbf24, #fde047, #fbbf24);
  transform: scale(1.04);
  box-shadow: 0 4px 22px rgba(251, 191, 36, 0.18);
}
.podium-gold:hover { transform: translateY(-2px) scale(1.04); box-shadow: 0 6px 26px rgba(251, 191, 36, 0.28); }
.podium-silver { --medal-color: linear-gradient(90deg, #a3a3a3, #e2e8f0, #a3a3a3); }
.podium-bronze { --medal-color: linear-gradient(90deg, #b45309, #f59e0b, #b45309); }

.podium-rank {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.podium-gold .podium-rank   { color: #fbbf24; }
.podium-silver .podium-rank { color: #cbd5e1; }
.podium-bronze .podium-rank { color: #f59e0b; }
.podium-name {
  font-weight: 600;
  font-size: 1rem;
  color: var(--fg-strong);
  letter-spacing: -0.01em;
}
.podium-ev {
  font-size: 1.05rem;
  padding: 0.3rem 0.7rem;
  min-width: 5em;
}
.podium-gold .podium-ev { font-size: 1.2rem; }
.podium-meta {
  font-size: 0.75rem;
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.podium-meta .dot { color: var(--muted-dim); margin: 0 0.2rem; }
.podium-skew { margin-top: 0.1rem; }

/* -- Mirror-analysis: friendly two-column layout ---------------------------- */
.warn { color: var(--warm-text); }

.mirror-narrative {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.9rem 1.1rem;
  margin: 1rem 0 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-size: 0.92rem;
  line-height: 1.55;
}
.mirror-narrative strong { font-weight: 600; color: var(--fg-strong); }
.mirror-narrative-win  strong { color: var(--accent-text); }
.mirror-narrative-lose strong { color: var(--warm-text); }

.mirror-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 1rem 0 1.5rem;
}
@media (max-width: 720px) {
  .mirror-cols { grid-template-columns: 1fr; }
}
.mirror-col {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.15rem 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.mirror-col-header {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.25rem;
}
.mirror-col-tick {
  width: 22px; height: 22px;
  display: inline-flex;
  align-items: center; justify-content: center;
  border-radius: 6px;
  font-weight: 700;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.85rem;
}
.mirror-col-title {
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  color: var(--fg-strong);
}
.mirror-col-win  .mirror-col-tick { background: var(--accent-soft); color: var(--accent-text); }
.mirror-col-lose .mirror-col-tick { background: var(--warm-soft);  color: var(--warm-text); }

.mirror-card {
  padding: 0.6rem 0.7rem;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  transition: border-color 120ms ease;
}
.mirror-card:hover { border-color: var(--accent); }
.mirror-card-name {
  font-weight: 600;
  font-size: 0.94rem;
  color: var(--fg-strong);
  letter-spacing: -0.005em;
}
.mirror-card-stat {
  font-size: 0.82rem;
  color: var(--fg);
  margin-top: 0.15rem;
}
.mirror-card-stat strong {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
}
.mirror-card-substat {
  font-size: 0.74rem;
  margin-top: 0.1rem;
  line-height: 1.45;
}

/* -- Card-art thumbnails on mirror cards (hotlinked from official endpoint) - */
.mirror-card-row {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
}
.mirror-card-body {
  flex: 1 1 auto;
  min-width: 0;
}
.mirror-card-thumb-wrap {
  position: relative;
  flex: 0 0 auto;
}
.mirror-card-thumb {
  display: block;
  width: 56px;
  height: 78px;                 /* GA card aspect ~5:7 */
  border-radius: 5px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  transition: border-color 120ms ease, transform 120ms ease;
}
.mirror-card-thumb:hover {
  border-color: var(--accent);
  transform: scale(1.03);
}
.mirror-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Card hover-preview is now the shared .card-preview module (cardpreview.js). */
.mirror-progress {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--bg-soft);
  margin-top: 0.45rem;
  overflow: hidden;
}
.mirror-progress-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
}
.mirror-progress-fill-win  { background: linear-gradient(90deg, var(--accent-strong), var(--accent)); box-shadow: 0 0 8px var(--accent-glow); }
.mirror-progress-fill-lose { background: linear-gradient(90deg, var(--warm-text), rgba(251, 146, 60, 0.55)); }
.mirror-empty { padding: 0.5rem 0; }

/* Collapsible raw-numbers table */
.mirror-details {
  margin: 1rem 0 1.5rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-elevated);
  padding: 0;
  overflow: hidden;
}
.mirror-details > summary {
  cursor: pointer;
  padding: 0.7rem 1rem;
  font-size: 0.85rem;
  color: var(--muted);
  user-select: none;
  list-style: none;
  font-weight: 500;
  transition: color 120ms ease;
}
.mirror-details > summary::before {
  content: '\25B8';   /* right-pointing triangle */
  display: inline-block;
  margin-right: 0.5rem;
  transition: transform 150ms ease;
  font-size: 0.7em;
}
.mirror-details[open] > summary::before { transform: rotate(90deg); }
.mirror-details > summary:hover { color: var(--accent); }
.mirror-details > table { margin: 0; border: none; border-radius: 0; border-top: 1px solid var(--border); }

/* -- Mirror-details raw table (kept for power users) ----------------------- */
.mirror td:first-child { font-weight: 500; color: var(--fg-strong); }
.mirror .edge-cell { width: 200px; padding-left: 0.75rem; padding-right: 0.75rem; }
.edge-bar {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  overflow: hidden;
}
.edge-axis {
  position: absolute;
  left: 50%; top: -2px; bottom: -2px;
  width: 1px;
  background: var(--muted-dim);
  transform: translateX(-0.5px);
  z-index: 1;
}
.edge-fill {
  position: absolute;
  top: 0; bottom: 0;
  min-width: 1px;
}
.edge-fill-winner {
  background: linear-gradient(90deg,
    rgba(34, 211, 238, 0.45),
    var(--accent));
  border-radius: 0 4px 4px 0;
  box-shadow: 0 0 8px var(--accent-glow);
}
.edge-fill-loser {
  background: linear-gradient(90deg,
    var(--warm-text),
    rgba(251, 146, 60, 0.45));
  border-radius: 4px 0 0 4px;
}

/* -- Home page hero ("meta at a glance" on /) ----------------------------- */
/* Three vertically-stacked blocks: page titles, big stat counters, and the
   donut + top-archetypes cards. Designed to make the landing page feel like
   a dashboard, not an events index. */
.home-hero {
  margin: 0.5rem 0 2.25rem;
  padding: 1.5rem 1.5rem 1.75rem;
  background:
    radial-gradient(ellipse at top right,
      var(--accent-soft) 0%,
      transparent 55%),
    var(--panel-translucent);
  border: 1px solid var(--border);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
}
.home-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    transparent 0,
    transparent 60%,
    var(--accent-glow) 100%
  );
  opacity: 0.06;
  mix-blend-mode: screen;
}
.home-hero-titles { margin-bottom: 1.1rem; }
.home-hero-h1 {
  margin: 0;
  font-family: 'Bricolage Grotesque', 'Inter', sans-serif;
  font-size: 2.45rem;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
  background: linear-gradient(95deg, var(--fg-strong) 30%, var(--accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.home-hero-sub {
  margin: 0.3rem 0 0;
  font-size: 0.92rem;
}

.home-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 1.5rem;
  position: relative;
  z-index: 1;
}
.home-stat {
  padding: 0.85rem 1.1rem;
  background: var(--bg-elevated);
}
.home-stat-num {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.65rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  line-height: 1.05;
}
.home-stat-label {
  margin-top: 0.15rem;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.home-hero-body {
  position: relative;
  z-index: 1;
}
/* Donut SVGs fill their (rem-scaled) column so they grow with the UI
   instead of staying a fixed pixel size on large screens. */
.home-hero-donut svg,
.hero-donut svg {
  width: 100%;
  height: auto;
}
@media (max-width: 760px) {
  .home-hero-body { grid-template-columns: 1fr; }
}
.home-hero-donut {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
}
.home-hero-donut svg { width: 100%; max-width: 220px; height: auto; }

.top-arch-cards { display: flex; flex-direction: column; gap: 0.7rem; }
.top-arch-cards-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.top-arch-cards-title {
  /* Override the global h2 uppercase/0.78rem here -- this is a hero heading. */
  margin: 0;
  text-transform: none;
  letter-spacing: -0.005em;
  font-size: 1rem;
  font-weight: 600;
  color: var(--fg-strong);
}
.top-arch-cards-more {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent-text);
}
.top-arch-cards-grid {
  display: grid;
  /* rem-based so the cards scale with the fluid root font -- a fixed-px
     min-width left the contents cramped once the font scaled up. */
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 0.65rem;
}
.top-arch-card {
  display: grid;
  grid-template-columns: 1.9rem 3.1rem 1fr;   /* rank | thumb | body, all rem */
  gap: 0.65rem;
  align-items: center;
  padding: 0.55rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  text-decoration: none;
  color: var(--fg);
  transition: border-color 120ms ease, transform 120ms ease,
              box-shadow 140ms ease;
}
.top-arch-card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px var(--accent-glow);
  text-decoration: none;
}
.top-arch-card-rank {
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 700;
  font-size: 0.95rem;
  text-align: right;
}
.top-arch-card-thumb {
  width: 3.1rem;
  height: 4.25rem;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.top-arch-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transform: scale(1.05);
  transform-origin: center 22%;
  display: block;
}
.top-arch-card-body { min-width: 0; }
.top-arch-card-name {
  font-weight: 600;
  font-size: 0.96rem;
  color: var(--fg-strong);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.top-arch-card-row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.25rem 0 0.3rem;
}
.top-arch-card-row .tier-pill { margin-left: 0; }
.top-arch-card-stats {
  display: flex;
  gap: 0.85rem;
  font-size: 0.78rem;
  align-items: center;
}
.top-arch-card-stat {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}
.top-arch-card-stat .muted {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.top-arch-card-stat strong {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--fg-strong);
}
/* Mini sparkline tucked at the bottom of each top-archetype card. The
   SVG inherits `currentColor` so the line picks up the accent (set on
   .top-arch-card-spark itself) and the trend chip is colored by direction. */
/* Share-momentum badge under each top-archetype card -- a plain
   gaining/steady/losing direction word. Replaced a tiny sparkline whose
   per-event share numbers read as noise and clashed with the card's
   pooled SHARE figure. */
.top-arch-card-trend {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  margin-top: 0.45rem;
  padding-top: 0.4rem;
  border-top: 1px dashed var(--border);
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--muted);
}
.top-arch-card-trend-icon { font-weight: 700; }
.top-arch-card-trend.is-up   { color: #4ade80; }
.top-arch-card-trend.is-down { color: #fb923c; }

/* Section header below the hero (the "Events" heading). */
.section-h2 {
  text-transform: none;
  letter-spacing: -0.01em;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--fg-strong);
  margin: 1.5rem 0 0.5rem;
}

/* -- Card-image lightbox -------------------------------------------------- */
/* Full-screen dimmed overlay with the card centered. Replaces the old
   "open image in a new tab" behavior for card thumbnails. */
.card-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3vh 3vw;
  background: rgba(3, 6, 12, 0.82);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  cursor: zoom-out;
  animation: lightbox-fade 130ms ease-out;
}
/* The [hidden] attribute and the display:flex above have equal specificity;
   spell out the hidden case so the overlay actually stays hidden. */
.card-lightbox[hidden] { display: none; }
.card-lightbox-img {
  max-width: 100%;
  max-height: 94vh;
  border-radius: 16px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.75),
              0 0 0 1px rgba(255, 255, 255, 0.08);
  animation: lightbox-pop 160ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.card-lightbox-close {
  position: absolute;
  top: max(1rem, 2vh);
  right: max(1rem, 2vw);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  color: #f1f5f9;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  transition: background 120ms ease;
}
.card-lightbox-close:hover { background: rgba(255, 255, 255, 0.22); }
@keyframes lightbox-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes lightbox-pop {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}

/* -- ELO gain/loss chip (op.gg-style) in H2H tables ----------------------- */
/* Average rating change per match in a matchup. Green when the deck beats
   its skill-expected result, warm when it underperforms. */
.elo-delta {
  display: inline-block;
  padding: 0.12rem 0.45rem;
  border-radius: 5px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.elo-pos {
  background: rgba(34, 197, 94, 0.16);
  color: #4ade80;
}
.elo-neg {
  background: var(--warm-soft);
  color: var(--warm-text);
}
.elo-flat {
  background: var(--bg-soft);
  color: var(--muted);
}

/* -- Recommendations page (/meta/recommendations) ------------------------- */
.rec-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
  margin: 1.25rem 0 1.5rem;
}
@media (max-width: 820px) {
  .rec-grid { grid-template-columns: 1fr; }
}
.rec-panel {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.1rem 1.15rem;
  /* A colored top edge keys each panel to its meaning. */
  border-top: 3px solid var(--border-strong);
  /* Let the panel shrink to its grid track on narrow screens instead of
     overflowing it (grid items default to min-width:auto = min-content). */
  min-width: 0;
}
.rec-panel-good { border-top-color: #22c55e; }
.rec-panel-tech { border-top-color: var(--accent); }
.rec-panel-bad  { border-top-color: #ef4444; }
.rec-panel-fav  { border-top-color: #fbbf24; }
.rec-panel-head {
  margin-bottom: 0.6rem;
}
.rec-panel-title {
  margin: 0;
  text-transform: capitalize;
  letter-spacing: -0.01em;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--fg-strong);
}
.rec-panel-note {
  display: block;
  text-transform: capitalize;
  font-size: 0.76rem;
  margin-top: 0.1rem;
}
/* Circled-"i" info affordance -- just the little icon; the hover bubble
   itself is the shared .app-tooltip below, driven by tooltip.js. */
.info-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-left: 0.4em;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 9px;
  font-style: normal;
  font-weight: 700;
  line-height: 1;
  text-transform: none;
  cursor: help;
  vertical-align: middle;
  transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease;
}
.info-dot:hover,
.info-dot:focus-visible {
  color: var(--accent-text);
  border-color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}

/* Shared themed tooltip -- a single floating bubble positioned by
   tooltip.js. Every element with a `title` or `data-tip` shows this in
   place of the browser's native white tooltip, so hover hints look the
   same across the whole site. */
.app-tooltip {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 300;
  max-width: min(300px, 90vw);
  padding: 0.55rem 0.7rem;
  border-radius: 9px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);
  color: var(--fg);
  font-size: 0.76rem;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 120ms ease, transform 120ms ease;
}
.app-tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Shared card hover-preview -- a single floating element positioned by
   cardpreview.js. Hovering any card-image thumbnail pops the full card
   here, so the preview behaves identically everywhere. */
.card-preview {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 250;
  width: 280px;
  max-width: 78vw;
  aspect-ratio: 5 / 7;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-elevated);
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--border-strong);
  pointer-events: none;
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 110ms ease, transform 110ms ease;
}
.card-preview.is-visible {
  opacity: 1;
  transform: scale(1);
}
.card-preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.rec-empty {
  font-size: 0.85rem;
  padding: 0.5rem 0;
}

.rec-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.4rem;
  border-radius: 8px;
  text-decoration: none;
  color: var(--fg);
  border-bottom: 1px solid var(--border);
  transition: background 110ms ease;
}
.rec-row:last-child { border-bottom: none; }
.rec-row:hover { background: var(--bg-hover); text-decoration: none; }
.rec-row-rank {
  flex: 0 0 1.3rem;
  text-align: right;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--muted);
}
.rec-row-thumb {
  display: block;          /* inside .rec-row-thumb-wrap it's no longer a
                              flex item -- block keeps its 38x53 box */
  width: 38px;
  height: 53px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.rec-row-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transform: scale(1.05);
  transform-origin: center 22%;
  display: block;
}
.rec-row-thumb-ph {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  color: var(--muted-dim);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
/* The rec-row thumbnail's flex slot. Its hover-preview is the shared
   .card-preview module (cardpreview.js). */
.rec-row-thumb-wrap {
  position: relative;
  flex: 0 0 38px;
}
.rec-row-body { flex: 1 1 auto; min-width: 0; }
.rec-row-name {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rec-row-meta {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.2rem;
}
.rec-row-meta .tier-pill { margin-left: 0; }
.rec-row-stat {
  flex: 0 0 auto;
  text-align: right;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
}
/* Tiny label above the headline number -- says whether it's EV, WR, etc.
   so the big green figure can't be misread as a plain winrate. */
.rec-row-stat-label {
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1;
}
.rec-row-stat-value {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 700;
  font-size: 0.9rem;
}
.rec-row-stat-value.wr {
  /* When the value is a winrate/EV chip, keep the chip look compact. */
  padding: 0.12rem 0.4rem;
}
.rec-row-stat-sub {
  font-size: 0.68rem;
  white-space: nowrap;
}
.rec-footnote {
  font-size: 0.78rem;
  line-height: 1.6;
  border-top: 1px solid var(--border);
  padding-top: 0.85rem;
}

/* "Recommendations for next event" call-to-action button on /meta. */
.recommendations-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1rem;
  margin: 0.25rem 0 0.5rem;
  background: linear-gradient(135deg, var(--accent-soft), transparent);
  border: 1px solid rgba(34, 211, 238, 0.32);
  border-radius: 9px;
  color: var(--accent-text);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  transition: border-color 120ms ease, background 120ms ease;
}
.recommendations-cta:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  text-decoration: none;
}

/* -- Scope notice (what events the page's numbers cover) ------------------ */
/* Spells out that a filtered page recomputes EVERY stat from just the
   selected events. The is-filtered variant gets an accent edge so the
   "you're looking at a subset" state is impossible to miss. */
.scope-notice {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.5rem 0 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--muted-dim);
  border-radius: 8px;
  background: var(--bg-soft);
  font-size: 0.86rem;
  line-height: 1.55;
}
.scope-notice.is-filtered {
  border-left-color: var(--accent);
  background: var(--accent-soft);
}
.scope-notice-empty {
  border-left-color: var(--warm-text);
  background: var(--warm-soft);
}
.scope-notice-tag {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  color: var(--muted);
}
.scope-notice.is-filtered .scope-notice-tag {
  background: var(--accent);
  color: #001216;
  border-color: var(--accent);
}
.scope-notice-text { flex: 1 1 16rem; color: var(--fg); }

/* -- Meta movers (risers / fallers board on /meta) ------------------------ */
.movers {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.15rem 1.15rem;
  margin: 1.5rem 0 2rem;
}
.movers-head { margin-bottom: 0.75rem; }
.movers-title {
  margin: 0;
  text-transform: none;
  letter-spacing: -0.005em;
  font-size: 1rem;
  font-weight: 600;
}
.movers-sub { margin: 0.2rem 0 0; font-size: 0.82rem; }
.movers-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}
@media (max-width: 720px) {
  .movers-grid { grid-template-columns: 1fr; }
}
.movers-col-title {
  margin: 0 0 0.4rem;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.82rem;
  font-weight: 700;
}
.movers-col-up   { color: #4ade80; }
.movers-col-down { color: var(--warm-text); }
.movers-empty { font-size: 0.84rem; padding: 0.4rem 0; }

.mover {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 0.4rem;
  border-radius: 8px;
  text-decoration: none;
  color: var(--fg);
  border-bottom: 1px solid var(--border);
  transition: background 110ms ease;
}
.mover:last-child { border-bottom: none; }
.mover:hover { background: var(--bg-hover); text-decoration: none; }
.mover-thumb {
  flex: 0 0 36px;
  width: 36px;
  height: 50px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.mover-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transform: scale(1.05);
  transform-origin: center 22%;
  display: block;
}
.mover-body { flex: 1 1 auto; min-width: 0; }
.mover-name {
  display: block;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mover-track {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-soft);
  margin: 0.3rem 0 0.25rem;
  overflow: hidden;
}
.mover-track-fill {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(34, 211, 238, 0.5), var(--accent));
}
.mover-shares {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
}
.mover-delta {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.18rem 0.5rem;
  border-radius: 6px;
}
.mover-delta-up   { color: #4ade80; background: rgba(34, 197, 94, 0.14); }
.mover-delta-down { color: var(--warm-text); background: var(--warm-soft); }

/* -- Meta-share-over-time line chart (/meta page) -------------------------- */
.share-trend {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.15rem 0.85rem;
  margin: 1.5rem 0 2rem;
}
.share-trend-header {
  margin-bottom: 0.5rem;
}
.share-trend-title {
  margin: 0;
  /* Override h2's uppercase styling for this hero-style heading. */
  text-transform: none;
  letter-spacing: -0.005em;
  font-size: 1rem;
  font-weight: 600;
}
.share-trend-sub {
  margin: 0.2rem 0 0;
  font-size: 0.82rem;
}
.share-trend-svg {
  display: block;
  width: 100%;
  height: auto;
}
/* Chart.js canvas wrapper. Fixed height because Chart.js with
   `maintainAspectRatio: false` will fill the container vertically. */
.share-trend-canvas-wrap {
  position: relative;
  width: 100%;
  height: 320px;
  margin-top: 0.25rem;
}
.share-trend-canvas-wrap canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}
.trend-grid {
  stroke: var(--border);
  stroke-width: 1;
  stroke-dasharray: 2 3;
  opacity: 0.55;
}
.trend-axis-line {
  stroke: var(--border-strong);
  stroke-width: 1;
}
.trend-tick {
  stroke: var(--border-strong);
  stroke-width: 1;
}
.trend-axis-label {
  fill: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: 0.03em;
}
.trend-line {
  transition: stroke-width 120ms ease, opacity 120ms ease;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18));
}
.trend-point {
  transition: r 120ms ease, stroke-width 120ms ease;
  stroke: var(--bg-elevated);
  stroke-width: 1;
}
/* Dim other series on hover so the focused one pops. CSS-only. */
.share-trend-svg:hover .trend-series { opacity: 0.35; }
.share-trend-svg .trend-series:hover { opacity: 1; }
.share-trend-svg .trend-series:hover .trend-line { stroke-width: 3; }
.share-trend-svg .trend-series:hover .trend-point { r: 4; }
.trend-series-label {
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 11px;
  font-weight: 600;
  dominant-baseline: middle;
}
/* Legend row below the chart -- replaces inline right-edge labels so we
   don't have to solve the label-collision problem when several series end
   at similar shares. Each item is a click-through to the archetype page. */
.trend-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.85rem;
  margin-top: 0.65rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}
.trend-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.18rem 0.5rem;
  border-radius: 5px;
  color: var(--fg);
  font-size: 0.82rem;
  font-weight: 500;
  text-decoration: none;
  transition: background 120ms ease;
}
.trend-legend-item:hover { background: var(--bg-hover); text-decoration: none; }
.trend-legend-swatch {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25) inset;
}
.trend-legend-item .muted {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.74rem;
}


/* -- Rich archetype table (champion thumbs + element pips + share bars) ---- */
/* Applied IN ADDITION to .archetypes — bumps row height + vertical alignment
   so thumbnails and pips don't crowd the data columns. The default `table`
   rule uses `overflow: hidden` to clip border-radius corners, but that also
   clips our hover-zoom overlay. Override so the zoom can escape the table. */
table.archetypes-rich {
  overflow: visible;
  border-radius: 14px;
}
/* Sticky table headers when the window scrolls past them. Combined with the
   visible overflow above (so hover-zoom can escape), the header stays on
   screen even on long tables -- a quality-of-life polish lifted from
   mtgdecks's winrates page. */
.archetypes-rich thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: color-mix(in oklab, var(--bg-elevated) 94%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border-strong);
}
@supports not (backdrop-filter: blur(6px)) {
  .archetypes-rich thead th { background: var(--bg-elevated); }
}
.archetypes-rich td,
.archetypes-rich th {
  vertical-align: middle;
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
}
/* Tier-tinted left border so the table reads like grouped bands at a glance,
   without screaming. Subtle in dark mode, slightly more pronounced in light. */
.archetypes-rich tbody tr {
  position: relative;
  box-shadow: inset 3px 0 0 transparent;
  transition: background 100ms ease, box-shadow 120ms ease,
              transform 120ms ease;
}
.archetypes-rich tbody tr:has(.tier-pill.tier-1) { box-shadow: inset 3px 0 0 rgba(132, 204, 22, 0.55); }
.archetypes-rich tbody tr:has(.tier-pill.tier-2) { box-shadow: inset 3px 0 0 rgba(251, 191, 36, 0.45); }
.archetypes-rich tbody tr:has(.tier-pill.tier-3) { box-shadow: inset 3px 0 0 rgba(148, 163, 184, 0.30); }
.archetypes-rich tbody tr:hover {
  background: var(--bg-hover);
  /* Override the default tbody hover that adds an accent stripe -- we already
     have the tier-stripe so the accent stripe would compete. */
  box-shadow: inset 3px 0 0 var(--accent);
}
/* The default rule `tbody tr:hover td:first-child { inset 2px ... }` would
   double-stripe in rich tables -- suppress it here. */
.archetypes-rich tbody tr:hover td:first-child { box-shadow: none; }
.archetypes-rich td.rank,
.archetypes-rich th.num:first-child {
  width: 2.5rem;
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
}
/* Champion-card thumbnail: small (~45x63) clickable cropped image. The
   archetype's most-played material card is the "signature" — clicking it
   drills into the archetype page same as clicking the name. */
.arch-thumb-cell {
  width: 70px;
  padding-right: 0.4rem;
}
/* Wrap is required for the hover-zoom overlay to absolutely-position relative
   to the small thumb. Mirrors the .mirror-card-thumb-wrap pattern. */
.arch-thumb-wrap {
  position: relative;
  width: 58px;
}
.arch-thumb {
  display: block;
  position: relative;            /* anchors the "Banned" ribbon overlay */
  width: 58px;
  height: 81px;                  /* GA card aspect ~5:7, a touch bigger */
  border-radius: 7px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.arch-thumb:hover {
  border-color: var(--accent);
  transform: scale(1.08);
  box-shadow: 0 4px 14px var(--accent-glow);
  text-decoration: none;
}
.arch-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Center on the art window. GA cards: name banner ~0-15%, art ~15-50%,
     text box bottom half. Cropping to ~25% from top frames the art nicely. */
  object-position: center 22%;
  transform: scale(1.05);        /* tighten the frame a bit to hide the bezel */
  transform-origin: center 22%;
}
/* Card hover-preview is now the shared .card-preview module (cardpreview.js). */
.arch-thumb-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.9rem;
}
/* Archetype-name cell: bigger name, element pips beneath. */
.arch-name-cell {
  min-width: 11rem;
}
.arch-name {
  display: inline-block;
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--fg-strong);
  letter-spacing: -0.005em;
}
.arch-name:hover { color: var(--accent); }
.element-pips {
  display: flex;
  gap: 0.3rem;
  margin-top: 0.35rem;
}
.element-pip {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25) inset;
}
.element-pip-Fire  { background: #f97316; }
.element-pip-Water { background: #22d3ee; }
.element-pip-Wind  { background: #84cc16; }
.element-pip-Norm  { background: #94a3b8; }
/* Share cell: % number on top, micro-bar below (relative to top-share row). */
.archetypes-rich td.share-cell { min-width: 5.2rem; }
.share-num {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
  font-size: 0.92rem;
}
.share-bar {
  position: relative;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-soft);
  margin-top: 0.3rem;
  overflow: hidden;
}
.share-bar-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  background: linear-gradient(90deg, rgba(34, 211, 238, 0.5), var(--accent));
  border-radius: 2px;
  box-shadow: 0 0 6px var(--accent-glow);
}
/* W-L-D cell in the rich tables: keep it on one line so the dashes don't
   stack vertically in narrow cells. */
.archetypes-rich td.num { white-space: nowrap; }
.archetypes-rich td.arch-name-cell .arch-name { white-space: normal; }

/* -- Tier pills (Tier 1 / 2 / 3 by cumulative meta share) ------------------ */
/* Mirrors the .cat-tag visual family (inline pill, monospace digit). Tier 1
   is the chart-leader green, Tier 2 the warm amber, Tier 3 the muted "fringe"
   styling. Used in archetype tables and on archetype detail headers. */
.tier-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  margin-left: 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-soft);
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: 0.1em;
}
.tier-1 {
  background: rgba(132, 204, 22, 0.18);
  color: #bef264;
  border-color: rgba(132, 204, 22, 0.4);
}
.tier-2 {
  background: rgba(251, 191, 36, 0.16);
  color: #fcd34d;
  border-color: rgba(251, 191, 36, 0.35);
}
.tier-3 {
  background: var(--bg-soft);
  color: var(--muted);
  border-color: var(--border);
}
/* Larger, badge-style variant for archetype-detail headers (next to <h1>). */
.tier-pill-large {
  padding: 0.25rem 0.65rem;
  border-radius: 6px;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  margin-left: 0.6rem;
  vertical-align: 0.18em;
}

/* -- Header nav (sibling of the brand) ------------------------------------- */
/* Tiny inline nav for top-level destinations like /meta and /cards/staples.
   Sits between the tagline and the theme toggle. Uses the .filter-pill family
   visually but stays compact so the header doesn't crowd. */
/* (Old top-header .brand-nav rules deleted -- nav now lives in the
   left sidebar. See .sidebar-nav* selectors above.) */

/* -- Card-staples grid (the /cards/staples page) --------------------------- */
.staples-grid {
  display: grid;
  /* rem-based tracks so the cards scale with the fluid root font instead of
     staying a fixed pixel width while their contents grow -- the mismatch is
     what pushed text past the card borders. */
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 1rem;
  margin: 1.25rem 0 2rem;
}
@media (max-width: 720px) {
  .staples-grid {
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.75rem;
  }
}

.staple-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.8rem 0.75rem 0.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.55rem;
  /* Let the card shrink to its grid track rather than forcing the track
     wider than minmax() (which spilled content past the border). */
  min-width: 0;
  transition: border-color 140ms ease, transform 140ms ease,
              box-shadow 140ms ease;
}
.staple-card:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 18px var(--accent-glow);
}
/* Reuse arch-thumb's hover-grow look but at staples-card scale.
   Fluid: fill the card width (capped) at a fixed 5:7 GA-card ratio so the
   image can never end up wider than the card it sits in. */
.staple-card-thumb.arch-thumb {
  width: 100%;
  max-width: 8.75rem;
  height: auto;
  aspect-ratio: 5 / 7;
  border-radius: 7px;
}
.staple-card-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--fg-strong);
  letter-spacing: -0.005em;
  line-height: 1.25;
  /* Cap to two lines so cards stay aligned even for long names. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  width: 100%;
}
.staple-card-stats {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.78rem;
  width: 100%;
}
.staple-card-stats li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
}
.staple-card-stat-label {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.66rem;
  font-weight: 600;
  /* Stay on one line; ellipsize rather than wrap or spill past the card edge
     if a track ever lands right at its minmax() minimum. */
  flex: 0 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.staple-card-stat-value {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  color: var(--fg-strong);
  font-weight: 600;
  font-size: 0.85rem;
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Element pip in filter pills picks up the existing .element-pip-* colors. */
.filter-pill .element-pip {
  width: 8px;
  height: 8px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18) inset;
}
.filter-pill.is-active .element-pip {
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35) inset;
}

/* ============================================================================
   Players -- username search (/players) + per-player profile (/players/{u})
   ========================================================================== */
/* -- Search bar ----------------------------------------------------------- */
.player-search {
  display: flex;
  align-items: center;
  max-width: 540px;
  margin: 1rem 0 0.4rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  overflow: hidden;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.player-search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.player-search-icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-left: 0.85rem;
  color: var(--muted);
}
.player-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--fg-strong);
  font: inherit;
  font-size: 0.95rem;
  padding: 0.7rem 0.75rem;
  outline: none;
}
.player-search-input::placeholder { color: var(--muted-dim); }
.player-search-btn {
  flex: 0 0 auto;
  border: none;
  background: var(--accent);
  color: #001216;
  font: inherit;
  font-weight: 700;
  font-size: 0.88rem;
  padding: 0.72rem 1.1rem;
  cursor: pointer;
  transition: background 120ms ease;
}
.player-search-btn:hover { background: var(--accent-strong); }
.player-search-meta { margin: 0.35rem 0 1.25rem; font-size: 0.85rem; }

/* -- Search results grid -------------------------------------------------- */
.player-grid {
  display: grid;
  /* Wider cards -- at 255px the name + archetype lines truncate hard ("Skysa…",
     "Water Ae…"); 300px gives the body room so usernames fit in full while
     still keeping 4-5 columns on a normal desktop. */
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 0.7rem;
  margin-bottom: 2rem;
}
.player-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0.8rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  text-decoration: none;
  color: var(--fg);
  transition: border-color 120ms ease, background 120ms ease, transform 120ms ease;
}
.player-card:hover {
  border-color: var(--accent);
  background: var(--bg-hover);
  text-decoration: none;
  transform: translateY(-1px);
}
.player-card-thumb {
  flex: 0 0 40px;
  width: 40px;
  height: 56px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.player-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transform: scale(1.05);
  transform-origin: center 22%;
  display: block;
}
.player-card-thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--muted);
}
.player-card-body { flex: 1 1 auto; min-width: 0; }
.player-card-name {
  display: block;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player-card-arch {
  display: block;
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player-card-side {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.05rem;
  text-align: right;
}
.player-card-events {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--accent-text);
}
.player-card-events-unit {
  font-size: 0.66rem;
  font-weight: 500;
  color: var(--muted);
}
.player-card-cp {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.7rem;
}

/* -- Profile hero --------------------------------------------------------- */
.pl-hero {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0.25rem 0 1.2rem;
}
.pl-hero-thumb {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border-strong);
}
.pl-hero-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 16%;
  transform: scale(1.18);
  display: block;
}
.pl-hero-thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.8rem;
  color: var(--muted);
}
.pl-hero-text { min-width: 0; }
.pl-hero-name {
  margin: 0;
  font-size: 1.7rem;
  line-height: 1.12;
  word-break: break-word;
}
.pl-hero-meta { margin: 0.3rem 0 0; font-size: 0.9rem; }

/* -- Stat strip ----------------------------------------------------------- */
.pl-stats { margin-bottom: 0.85rem; }
.home-stat-num.stat-pos { color: #4ade80; }
.home-stat-num.stat-neg { color: var(--warm-text); }

/* -- Section headings ----------------------------------------------------- */
.pl-section-h2 {
  margin: 1.85rem 0 0.2rem;
  font-size: 1.15rem;
}
.pl-section-note {
  margin: 0 0 0.85rem;
  font-size: 0.84rem;
  line-height: 1.55;
}

/* -- Archetype rows (decks piloted + matchup panels) ---------------------- */
.pl-panel { margin-bottom: 1rem; }
.pl-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.4rem;
  border-bottom: 1px solid var(--border);
}
.pl-row:last-child { border-bottom: none; }
.pl-row-thumb {
  flex: 0 0 38px;
  width: 38px;
  height: 53px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.pl-row-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  transform: scale(1.05);
  transform-origin: center 22%;
  display: block;
}
.pl-row-thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--muted-dim);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.pl-row-body { flex: 1 1 auto; min-width: 0; }
.pl-row-name {
  display: block;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pl-row-name a { color: var(--fg-strong); text-decoration: none; }
.pl-row-name a:hover { color: var(--accent); }
.pl-row-prefix {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.82rem;
}
.pl-row-sub {
  display: block;
  font-size: 0.72rem;
  margin-top: 0.15rem;
}
.pl-row-rec {
  flex: 0 0 auto;
  text-align: right;
}
.pl-rec {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.pl-row-wr {
  flex: 0 0 3.3rem;
  text-align: right;
}

/* Wide tables scroll inside their own box on narrow screens instead of
   stretching the whole page. */
.table-scroll > table { margin-top: 0; }
/* Wide tables scroll inside their own box, but only where it's needed --
   touch devices and narrow viewports. On a hover-capable desktop the
   wrapper stays inert, so an archetype table's hover-zoom card preview
   isn't clipped by an overflow container. */
@media (hover: none), (max-width: 720px) {
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Empty-state row inside a data table (no rows matched). */
.table-empty {
  text-align: center;
  padding: 1.4rem 0.85rem;
  font-size: 0.86rem;
  font-style: italic;
}

/* ============================================================================
   Decklist page (/events/{id}/decks/{player}) -- a visual decklist
   ========================================================================== */
.deck-hero { margin: 0.25rem 0 1rem; }
.deck-hero-title { margin: 0; font-size: 1.7rem; line-height: 1.15; }
.deck-hero-title a { color: inherit; text-decoration: none; }
.deck-hero-title a:hover { color: var(--accent); }
.deck-hero-meta { margin: 0.3rem 0 0; font-size: 0.9rem; }
.deck-summary { margin: 0 0 1.25rem; font-size: 0.85rem; }

.deck-zones {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  margin-bottom: 1.5rem;
}
.deck-zone-head {
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--fg-strong);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.4rem;
}
.deck-zone-count {
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  margin-left: 0.4rem;
}
.deck-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.6rem, 1fr));
  gap: 0.7rem;
}
.deck-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.deck-card-frame {
  position: relative;
  display: block;
  aspect-ratio: 5 / 7;
  border-radius: 7px;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--border);
}
.deck-card-thumb {
  display: block;
  width: 100%;
  height: 100%;
}
.deck-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 150ms ease;
}
.deck-card-frame:hover .deck-card-thumb img { transform: scale(1.06); }
.deck-card-thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted-dim);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.4rem;
}
.deck-card-qty {
  position: absolute;
  right: 0;
  bottom: 0;
  min-width: 1.7em;
  padding: 0.12rem 0.4rem;
  background: rgba(8, 11, 16, 0.92);
  color: var(--fg-strong);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
  border-top-left-radius: 7px;
  box-shadow: -1px -1px 0 var(--border);
}
.deck-card-name {
  font-size: 0.72rem;
  line-height: 1.25;
  color: var(--fg);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   "Banned" ribbon -- flags a card on the GA Standard ban list (rules/
   banlist.yaml), rendered by the banned_ribbon() macro inside any card
   thumbnail. The thumbnail wrappers (.deck-card-frame, .arch-thumb,
   .mirror-card-thumb-wrap) are all position:relative, so the ribbon pins
   itself diagonally across the card art.
   -------------------------------------------------------------------------- */
.banned-flag {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-13deg);
  z-index: 4;
  pointer-events: none;                /* clicks fall through to the art link */
  padding: 0.22em 0.8em;
  background: var(--banned);
  color: #fff;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 2px solid rgba(255, 255, 255, 0.95);
  border-radius: 3px;
  box-shadow: 0 2px 7px rgba(0, 0, 0, 0.7),
              0 0 0 4px rgba(120, 12, 12, 0.4);
}
/* The mirror-analysis thumbnail is only 56px wide -- trim the ribbon a bit. */
.mirror-card-thumb-wrap .banned-flag {
  font-size: 0.56rem;
  padding: 0.16em 0.5em;
  letter-spacing: 0.07em;
  border-width: 1.5px;
}
/* Red ring around a thumbnail that holds a banned card -- makes banned cards
   scannable in a full decklist grid. Browsers without :has() simply skip it
   (the ribbon itself still renders). */
.deck-card-frame:has(.banned-flag),
.arch-thumb:has(.banned-flag),
.mirror-card-thumb-wrap:has(.banned-flag) .mirror-card-thumb {
  outline: 2px solid var(--banned-ring);
  outline-offset: -2px;
}

/* Decklist links -- the individual decks of an archetype at an event. */
.decklist-links {
  list-style: none;
  margin: 0.5rem 0 1.5rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.5rem;
}
/* Lay the portrait card-art thumbnail beside its link card. */
.decklist-links > li {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
}
.decklist-link {
  flex: 1;
  min-width: 0;                  /* let the ellipsis on the pilot name work */
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.55rem 0.75rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  text-decoration: none;
  transition: border-color 120ms ease, background 120ms ease;
}
.decklist-link:hover {
  border-color: var(--accent);
  background: var(--bg-hover);
  text-decoration: none;
}
.decklist-link-pilot {
  font-weight: 600;
  color: var(--fg-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.decklist-link-meta {
  font-size: 0.78rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}

/* ---- Browse Decks: visual archetype grid on the event page -------------- */
/* A responsive grid of champion-art tiles, one per event archetype. Reuses
   the .arch-thumb art-window crop ideas (portrait 5:7 card, top-biased). */
.deck-browse-grid {
  list-style: none;
  margin: 0.5rem 0 0.5rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.7rem;
}
.deck-browse-tile {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.deck-browse-tile:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 4px 14px var(--accent-glow);
  text-decoration: none;
}
/* Card-art window: portrait aspect, art cropped toward the top like .arch-thumb. */
.deck-browse-art {
  display: block;
  position: relative;
  aspect-ratio: 5 / 4;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.deck-browse-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
  display: block;
  transform: scale(1.04);
  transform-origin: center 22%;
}
.deck-browse-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 1.1rem;
}
.deck-browse-meta {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
  padding: 0.5rem 0.6rem 0.6rem;
}
.deck-browse-name {
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--fg-strong);
  line-height: 1.25;
}
.deck-browse-count {
  font-size: 0.76rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.deck-browse-share { opacity: 0.85; }
/* Tighten the pip row inside a tile -- the default top margin is too much here. */
.deck-browse-meta .element-pips {
  margin-top: 0.3rem;
}

/* Consensus-decklist card breakdown (pooled archetype page). */
.cardbreak-zone {
  margin: 1.5rem 0 0.5rem;
  font-size: 0.98rem;
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--fg-strong);
}
.cardbreak-zone span {
  font-weight: 500;
  font-size: 0.78rem;
  color: var(--muted);
  margin-left: 0.4rem;
}
.cardbreak-tail {
  margin: 0.4rem 0 0;
  font-size: 0.8rem;
  font-style: italic;
}

/* -- Consensus decklist: card-art grid (archetype page) ------------------ */
/* An art-forward grid instead of a dense table -- players recognise cards
   by art far faster than by name. Tiles flow inclusion-sorted, so the most
   core cards come first. Shares the staples-grid look. */
.cdk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0.9rem;
  margin: 0.6rem 0 0.5rem;
}
@media (max-width: 720px) {
  .cdk-grid {
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
    gap: 0.7rem;
  }
}
.cdk-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.7rem 0.65rem 0.75rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.cdk-card:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 16px var(--accent-glow);
}
/* Fluid 5:7 art that can never exceed its tile (matches the staples fix). */
.cdk-card-thumb.arch-thumb {
  width: 100%;
  max-width: 8rem;
  height: auto;
  aspect-ratio: 5 / 7;
  border-radius: 7px;
}
.cdk-card-name {
  width: 100%;
  min-height: 2.5em;            /* 2 lines -- keeps bars aligned across a row */
  font-weight: 600;
  font-size: 0.88rem;
  line-height: 1.25;
  color: var(--fg-strong);
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cdk-card .share-bar {
  width: 100%;
  height: 5px;
  margin-top: 0;
}
.cdk-card-meta {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
}
/* Material cards show only the % (material is always a 1-of) -- centre it. */
.cdk-card-meta.is-solo { justify-content: center; }
.cdk-card-pct {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--fg-strong);
}
.cdk-card-copies {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--muted);
}

/* ============================================================================
   Motion polish -- entrance reveals, HTMX feedback, bar grow-in
   All effects animate only transform/opacity (compositor-friendly) and are
   neutralised by the prefers-reduced-motion guard at the end of this file.
   ========================================================================== */

/* Main content fades + rises -- but only on a real page load. After the
   first HTMX interaction <body> gets .ga-instant (set in base.html) so
   filter swaps replace content immediately, with no replayed load-in. */
#hx-content {
  /* `both` holds the opacity:0 start frame, so the content can't flash
     visible for a frame before the fade begins. */
  animation: ga-content-in 0.34s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
@keyframes ga-content-in {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Once the user has triggered any HTMX request (e.g. a filter click),
   entrance animations switch off so every later filter swap is instant. */
body.ga-instant #hx-content,
body.ga-instant .share-bar-fill,
body.ga-instant .mover-track-fill,
body.ga-instant .element-bar,
body.ga-instant .home-hero-donut svg,
body.ga-instant .hero-donut svg {
  animation: none;
}

/* Navigation loading bar -- a slim accent bar that creeps across the top
   of the viewport the instant a full-page navigation starts, so a click
   always feels acknowledged. The fresh page load clears it for free. */
.nav-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 9999;
  background: linear-gradient(90deg, var(--accent-strong), var(--accent));
  transform: scaleX(0);
  transform-origin: left;
  opacity: 0;
  pointer-events: none;
}
.nav-progress.is-loading {
  opacity: 1;
  /* jumps to a visible sliver immediately, then creeps -- never reaches
     100% because the real page load is what "finishes" it. */
  transform: scaleX(0.5);
  animation: ga-nav-creep 14s cubic-bezier(0.06, 0.8, 0.25, 1) forwards;
}
@keyframes ga-nav-creep {
  0%   { transform: scaleX(0.08); }
  35%  { transform: scaleX(0.55); }
  100% { transform: scaleX(0.93); }
}
/* Reduced motion: no creep -- just show a static half-width bar. */
@media (prefers-reduced-motion: reduce) {
  .nav-progress.is-loading { animation: none; transform: scaleX(0.5); }
}
/* A "working" cursor while a navigation is in flight. */
body.is-navigating { cursor: progress; }

/* Share / mover bars sweep out from the left on first paint. The width stays
   the inline % -- only the scaleX transform animates, so it works with any
   dynamic width. */
.share-bar-fill,
.mover-track-fill {
  transform-origin: left center;
  animation: ga-bar-grow 0.72s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
@keyframes ga-bar-grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* The element-distribution bar wipes in as a whole. */
.element-bar {
  animation: ga-wipe-in 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
@keyframes ga-wipe-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* The meta-share donut spins gently into place on load -- a small "render"
   flourish with a touch of overshoot. transform/opacity only. */
.home-hero-donut svg,
.hero-donut svg {
  transform-origin: center;
  animation: ga-donut-in 0.66s cubic-bezier(0.34, 1.18, 0.64, 1) both;
}
@keyframes ga-donut-in {
  from { opacity: 0; transform: scale(0.82) rotate(-14deg); }
  to   { opacity: 1; transform: scale(1) rotate(0); }
}

/* ============================================================================
   Atmospheric artwork backdrop
   A single fixed, heavily blurred, low-opacity layer carrying the page's
   champion card art (set inline via the `page_art` block). Masked to fade
   out below the hero zone. Content panels and tables are opaque, so this
   never sits behind live data -- it only fills page margins / negative
   space, giving "hero + ambient" atmosphere with zero readability cost.
   ========================================================================== */
.page-art {
  position: fixed;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center 24%;
  background-repeat: no-repeat;
  filter: blur(12px) brightness(0.5) saturate(1.05);
  opacity: 0.72;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom,
    #000 0%, #000 30%, rgba(0, 0, 0, 0.52) 56%, transparent 84%);
  mask-image: linear-gradient(to bottom,
    #000 0%, #000 30%, rgba(0, 0, 0, 0.52) 56%, transparent 84%);
  animation: ga-art-in 0.9s ease-out both;
}
@keyframes ga-art-in {
  from { opacity: 0; }
  to   { opacity: 0.72; }
}
/* Light theme: art needs to be fainter so it doesn't muddy the bright bg. */
:root[data-theme="light"] .page-art { opacity: 0.22; }
:root[data-theme="light"] .page-art { animation-name: ga-art-in-light; }
@keyframes ga-art-in-light {
  from { opacity: 0; }
  to   { opacity: 0.22; }
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .page-art { opacity: 0.22; animation-name: ga-art-in-light; }
}
/* Legibility over the artwork backdrop: a soft shadow keeps headings and
   intro copy crisp where they sit on top of the art. The shadow is
   effectively invisible on the plain dark background, so it costs
   nothing on art-free areas. */
h1, h2, h3,
p.muted,
.home-hero-sub,
.pl-hero-meta {
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
:root[data-theme="light"] h1, :root[data-theme="light"] h2,
:root[data-theme="light"] h3, :root[data-theme="light"] p.muted,
:root[data-theme="light"] .home-hero-sub,
:root[data-theme="light"] .pl-hero-meta { text-shadow: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) h1, :root:not([data-theme]) h2,
  :root:not([data-theme]) h3, :root:not([data-theme]) p.muted,
  :root:not([data-theme]) .home-hero-sub,
  :root:not([data-theme]) .pl-hero-meta { text-shadow: none; }
}

/* Sortable-table rows settle in with a soft fade when re-ordered or on load.
   Applied via a JS-toggled class so it only fires on an actual sort. */
.ga-sorted tbody tr {
  animation: ga-row-settle 0.3s ease-out both;
}
@keyframes ga-row-settle {
  from { opacity: 0.35; }
  to   { opacity: 1; }
}

/* -- Player event log: expandable round-by-round path -------------------- */
/* Each event is a native <details> -- collapsed it's a one-line summary,
   expanded it reveals the pilot's whole tournament path. No JS needed. */
.pl-events {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.pl-event {
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-elevated);
  overflow: hidden;
}
.pl-event[open] { border-color: var(--border-strong); }

.pl-event-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  padding: 0.6rem 0.85rem;
  cursor: pointer;
  list-style: none;
  transition: background-color 120ms ease;
}
/* Drop the default disclosure triangle -- we draw our own caret. */
.pl-event-summary::-webkit-details-marker { display: none; }
.pl-event-summary::marker { content: ""; }
.pl-event-summary:hover { background: var(--bg-soft); }

.pl-event-caret {
  flex: 0 0 auto;
  display: inline-flex;
  color: var(--muted);
  transition: transform 140ms ease, color 140ms ease;
}
.pl-event[open] .pl-event-caret {
  transform: rotate(90deg);
  color: var(--accent);
}

.pl-event-head {
  flex: 1 1 13rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.pl-event-name {
  font-weight: 600;
  color: var(--fg-strong);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pl-event-sub {
  font-size: 0.8rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pl-event-dot { opacity: 0.55; }

/* Fixed-width, right-anchored stat columns so W-L-D / win rate / ELO line
   up cleanly down the whole log regardless of event-name length. */
.pl-event-stats {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 4.6rem 3.4rem 4.4rem;
  align-items: center;
  justify-items: end;
  gap: 0.35rem;
}
@media (max-width: 560px) {
  .pl-event-stats {
    flex-basis: 100%;
    justify-items: start;
    padding-left: 1.55rem;   /* align under the event name */
  }
}

.pl-event-body {
  border-top: 1px solid var(--border);
  padding: 0.7rem 0.85rem 0.85rem;
  background: var(--bg-soft);
}
.pl-event-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.15rem;
  margin: 0 0 0.6rem;
  font-size: 0.83rem;
}

.pl-rounds {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
}
.pl-round {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem 0.55rem;
  padding: 0.34rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elevated);
  font-size: 0.87rem;
}
.pl-round-label {
  flex: 0 0 6.5rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.74rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
}
.pl-round-label.is-playoff { color: var(--accent); }
.pl-round-score {
  flex: 0 0 2.7rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--fg-strong);
}
.pl-round-opp {
  flex: 1 1 12rem;
  min-width: 0;
}
.pl-round-vs {
  color: var(--muted);
  font-size: 0.8rem;
  margin-right: 0.1rem;
}
.pl-round-opp-name { font-weight: 600; }
.pl-round-opp-arch::before {
  content: "·";
  margin: 0 0.35rem;
  color: var(--muted);
}
.pl-rounds-empty { font-size: 0.84rem; margin: 0.2rem 0 0; }

/* Round result pill -- W / L / D / BYE. */
.round-tag {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  padding: 0.1rem 0.36rem;
  border-radius: 4px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.round-tag-win  { background: rgba(34, 197, 94, 0.16); color: #4ade80; }
.round-tag-loss { background: var(--warm-soft);  color: var(--warm-text); }
.round-tag-draw {
  background: var(--bg-soft);
  color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--border);
}
.round-tag-bye  { background: var(--accent-soft); color: var(--accent); }

/* -- Back-to-top button --------------------------------------------------- */
/* Fixed bottom-right; fades in once the page is scrolled past 400px. */
.back-to-top {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--bg-elevated);
  color: var(--accent);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity 160ms ease, transform 160ms ease,
              background-color 140ms ease, color 140ms ease,
              border-color 140ms ease;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover {
  background: var(--accent);
  color: #001216;
  border-color: var(--accent);
}

/* ============================================================================
   JOB 1 — Generic collapsible component (.fold)
   Templates wrap long sections in:
     <details class="fold" open>
       <summary>Section Title</summary>
       <div class="fold-body"> …content… </div>
     </details>
   Matches the house style of .mirror-details > summary and .pl-event-summary.
   ========================================================================== */
.fold {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  margin: 0 0 1rem;
}
/* Stack multiple adjacent folds with a gap between them. */
.fold + .fold {
  margin-top: 0.5rem;
}

.fold > summary {
  /* Remove native disclosure marker (cross-browser). */
  list-style: none;
  cursor: pointer;
  user-select: none;
  /* Comfortable tap target — at least 40px tall. */
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--fg-strong);
  transition: color 120ms ease, background 120ms ease;
}
.fold > summary::-webkit-details-marker { display: none; }

/* Custom chevron caret, matches the .mirror-details pattern. */
.fold > summary::before {
  content: '\25B8';   /* right-pointing triangle ▸ */
  display: inline-block;
  flex-shrink: 0;
  margin-right: 0.3rem;
  font-size: 1.15em;             /* enlarged so it clearly reads as a control */
  color: var(--fg);
  transition: transform 150ms ease, color 150ms ease;
}
.fold[open] > summary::before {
  transform: rotate(90deg);
  color: var(--accent);
}
.fold > summary:hover {
  color: var(--accent);
  background: var(--bg-soft);
}
.fold > summary:hover::before {
  color: var(--accent);
}
/* Always-visible expand / collapse hint, pinned to the right of the header
   and swapped by the open state -- so it's obvious the bar is a control. */
.fold > summary::after {
  content: 'Click to Expand';
  margin-left: auto;
  flex-shrink: 0;
  padding-left: 1rem;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--accent-text);
  transition: color 120ms ease;
}
.fold[open] > summary::after { content: 'Click to Collapse'; }
.fold > summary:hover::after { color: var(--accent); }
/* Secondary muted text in a fold header (e.g. the card-count line). */
.fold-sub {
  font-weight: 500;
  font-size: 0.84rem;
  color: var(--muted);
}

.fold-body {
  padding: 0.75rem 1rem 1rem;
  border-top: 1px solid var(--border);
}

/* ============================================================================
   JOB 2 — Small thumbnail image classes
   ========================================================================== */

/* .decklist-thumb — small portrait card-art thumbnail for inline deck-list
   rows. GA cards are ~5:7 portrait; cropping toward the top keeps the card
   name/art visible instead of crushing the tall art into a square speck. */
.decklist-thumb {
  display: inline-block;
  width: 44px;
  height: 62px;                  /* ~5:7 portrait, matches .arch-thumb ratio */
  border-radius: 5px;
  object-fit: cover;
  object-position: center 18%;   /* bias to the top: name banner + art window */
  border: 1px solid var(--border);
  vertical-align: middle;
  flex-shrink: 0;
  background: var(--bg-soft);
}

/* .deck-hero-icon — ~48 px, for page-header use next to a heading. */
.deck-hero-icon {
  display: inline-block;
  width: 48px;
  height: 48px;
  border-radius: 8px;
  object-fit: cover;
  border: 1px solid var(--border-strong);
  vertical-align: middle;
  flex-shrink: 0;
  background: var(--bg-soft);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

/* ============================================================================
   JOB 3 — Mobile / responsive overhaul
   New breakpoints: ~600 px and ~400 px.
   The existing 880 px (sidebar→top bar) and 720–820 px cluster are preserved
   and extended below.
   ========================================================================== */

/* --- Safe-area insets (notch / home-bar on iOS, gesture zone on Android) -- */
/* Apply to the whole page so the sidebar / top bar and main content are never
   hidden behind hardware chrome. */
@supports (padding: env(safe-area-inset-left)) {
  .layout-shell {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
  /* The fixed top bar on ≤880 px also needs top inset when on iOS. */
  @media (max-width: 880px) {
    .sidebar {
      padding-top: max(0.6rem, env(safe-area-inset-top));
    }
    .layout-main main,
    .layout-main footer {
      padding-left:  max(1rem, env(safe-area-inset-left));
      padding-right: max(1rem, env(safe-area-inset-right));
    }
  }
}

/* Back-to-top: honour home bar + Android right-edge back-gesture zone. */
@supports (bottom: env(safe-area-inset-bottom)) {
  .back-to-top {
    right:  max(1.25rem, calc(env(safe-area-inset-right) + 0.75rem));
    bottom: max(1.25rem, calc(env(safe-area-inset-bottom) + 0.5rem));
  }
}

/* --- Table-scroll: reliable touch scrolling on all viewports --------------- */
/* Always enable horizontal scroll on .table-scroll wrappers; not just at 720px.
   On hover-capable desktops the wide-table overflow fix was conditional, but
   we now always set it so mobile always gets it.
   The existing @media (hover:none) rule is intentionally left in place and
   extended here to add the affordance hint. */
.table-scroll {
  /* Always scrollable – overrides the hover:none conditional for touch. */
  -webkit-overflow-scrolling: touch;
  /* Subtle scroll hint: fade the right edge when the table overflows. */
  /* (actual overflow:auto is already set for touch/narrow via the existing rule) */
}
@media (hover: none), (max-width: 720px) {
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Gradient on right edge signals "more content here". */
    /* We use a box-shadow approach to avoid clipping the table entirely. */
  }
  /* Sticky header still functions within a scrollable wrapper. */
  .table-scroll .archetypes-rich thead th {
    position: sticky;
    top: 0;
  }
}

/* --- ~600 px breakpoint: general layout tightening ----------------------- */
@media (max-width: 600px) {
  /* Main padding tighter on small phones. */
  .layout-main main,
  .layout-main footer {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }

  /* Hero heading: clamp from 2.45rem down to 1.45rem. */
  .home-hero-h1 {
    font-size: clamp(1.45rem, 5vw + 0.6rem, 2.45rem);
  }
  /* Hero padding reduction. */
  .home-hero {
    padding: 1rem 1rem 1.25rem;
  }

  /* Two-column grids → single column. */
  .mirror-cols      { grid-template-columns: 1fr; }
  .movers-grid      { grid-template-columns: 1fr; }
  .rec-grid         { grid-template-columns: 1fr; }
  .podium           { grid-template-columns: 1fr; align-items: stretch; }
  .hero-grid        { grid-template-columns: 1fr; }

  /* Top-arch-cards: single column on very small screens. */
  .top-arch-cards-grid {
    grid-template-columns: 1fr;
  }

  /* Card/staple/deck grids: 2 columns at 600 px. */
  .staples-grid {
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
    gap: 0.6rem;
  }
  .cdk-grid {
    grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
    gap: 0.6rem;
  }
  .deck-card-grid {
    grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr));
    gap: 0.5rem;
  }

  /* Stat row: min 140px so it stays 2-up on 360px screens. */
  .stat-row {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  }

  /* Player grid: 1 column. */
  .player-grid {
    grid-template-columns: 1fr;
  }

  /* Filter form: wrap to multiple lines. */
  .filter-form {
    flex-wrap: wrap;
  }

  /* Date inputs: cap width so native date chrome doesn't overflow. */
  .date-range-field input[type="date"] {
    max-width: 9rem;
  }

  /* Filter pills: smaller tap targets still ≥40px. */
  .filter-pill {
    min-height: 2.5rem;
  }

  /* Table-scroll: always active on mobile. */
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Matrix on small screens: shrink cell dimensions to maximise visible data. */
  .matrix th.corner,
  .matrix th.row-head {
    min-width: 9rem;
    max-width: 11rem;
    font-size: 0.78rem;
  }
  .matrix th.col-head {
    height: 7em;
    min-width: 3em;
    max-width: 3em;
  }
  .matrix td.cell {
    min-width: 3em;
    padding: 0.2rem 0.15rem;
  }
  .matrix td.cell .cell-wr { font-size: 0.76rem; }
  .matrix-wrap {
    max-height: calc(100vh - 160px);
  }

  /* Fold summary: ensure ≥40px tap target on small phones too. */
  .fold > summary {
    min-height: 2.75rem;
    padding: 0.65rem 0.85rem;
  }
  /* The expand/collapse hint is desktop-only -- the header gets cramped on a
     phone, and the bigger caret already signals the bar is tappable. */
  .fold > summary::after { display: none; }

  /* Back-to-top nudged away from Android right-edge gesture zone. */
  .back-to-top {
    right: max(1rem, 1.5rem);
  }
}

/* --- ~400 px breakpoint: very small phones -------------------------------- */
@media (max-width: 400px) {
  /* Root font slightly smaller so more fits. The fluid clamp still applies
     at these sizes; this nudges the baseline. */
  :root { font-size: clamp(14px, 0.36vw + 11.9px, 22px); }

  /* Even tighter main padding. */
  .layout-main main,
  .layout-main footer {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }

  /* Hero: minimum readable size. */
  .home-hero-h1 {
    font-size: clamp(1.25rem, 7vw, 1.8rem);
  }
  .home-hero {
    padding: 0.75rem 0.75rem 1rem;
  }

  /* Grids down to 2 columns where useful, 1 col where cramped. */
  .staples-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
  }
  .cdk-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
  }
  .deck-card-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 0.4rem;
  }
  .top-arch-cards-grid {
    grid-template-columns: 1fr;
  }
  .player-grid {
    grid-template-columns: 1fr;
  }

  /* Stat row: force 2 columns on 360-400px. */
  .stat-row {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Matrix: further reduction. */
  .matrix th.corner,
  .matrix th.row-head {
    min-width: 7.5rem;
    max-width: 9rem;
    font-size: 0.72rem;
    padding: 0.35rem 0.55rem;
  }
  .matrix th.col-head {
    height: 6em;
    min-width: 2.6em;
    max-width: 2.6em;
  }
  .matrix td.cell {
    min-width: 2.6em;
    padding: 0.15rem 0.1rem;
  }
  .matrix td.cell .cell-wr { font-size: 0.7rem; }

  /* Date inputs: tighter cap. */
  .date-range-field input[type="date"] {
    max-width: 7.5rem;
  }
}

/* --- Top-bar overflow fix: ≤375 px ---------------------------------------- */
/* At small widths, brand text + 5 nav icons + API link can overflow. Hide
   brand text and ensure flex children don't blow out. */
@media (max-width: 375px) {
  .sidebar {
    flex-wrap: nowrap;
    gap: 0.35rem;
    padding: 0.5rem 0.5rem;
  }
  /* Hide brand text, keep the logo mark visible. */
  .sidebar .brand-text {
    display: none;
  }
  /* Brand link: just the logo pill. */
  .sidebar .brand {
    flex-shrink: 0;
  }
  /* Nav: shrink buttons so 5 icons fit. */
  .sidebar-nav {
    gap: 0.15rem;
    min-width: 0;
  }
  .sidebar-nav-link {
    padding: 0.45rem 0.55rem;
    min-width: 0;
  }
  .sidebar-icon {
    width: 18px;
    height: 18px;
  }
  /* Bottom API link: minimal. */
  .sidebar-bottom {
    padding-left: 0.35rem;
  }
  .sidebar-bottom-link {
    padding: 0.28rem 0.4rem;
  }
  /* Prevent any accidental horizontal scroll from the bar. */
  body { overflow-x: hidden; }
}

/* Accessibility: honour the OS "reduce motion" setting. Roughly a third of
   users enable it -- so this neutralises every transition/animation above
   (and the JS passes animation:false to Chart.js when this query matches).
   Kept LAST so it wins the cascade. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
