/* style.css — Wizards & Commoners · 2026 MLB Summer Rush
   Art direction: neumorphic broadcast console. Soft dual-shadow surfaces on a
   near-black (or near-white) field, hairline rings, and four accent glows
   (red / blue / gold / green) that carry every piece of state colour. */

/* The [hidden] attribute must always win over component display rules,
   regardless of specificity added later in this file. */
[hidden] { display: none !important; }

@font-face {
  font-family: 'SFSportsNight';
  src: url('./assets/fonts/SF-Sports-Night.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   TOKENS
   ============================================================ */
:root {
  --f-title: 'SFSportsNight', 'Arial Narrow', system-ui, sans-serif;
  --f-body: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --bg: #0d0f13;
  --bg-hi: #12151a;
  --surf: #161a20;
  --surf-2: #1b2028;
  --surf-in: #0d1015;
  --tx: #e9edf3;
  --mut: #9099a8;
  --fnt: #5e6673;
  --hair: #252a33;
  --hair-hi: #2f3540;

  --red: #ff3b47;
  --red-2: #ff6a72;
  --blue: #3d7dff;
  --blue-2: #79a4ff;
  --gold: #e7c56c;
  --green: #3ecf8e;

  --nm-out: 10px 10px 22px rgba(0,0,0,.62), -10px -10px 22px rgba(255,255,255,.028);
  --nm-out-sm: 5px 5px 12px rgba(0,0,0,.55), -5px -5px 12px rgba(255,255,255,.024);
  --nm-in: inset 7px 7px 16px rgba(0,0,0,.62), inset -7px -7px 16px rgba(255,255,255,.026);
  --nm-in-sm: inset 3px 3px 8px rgba(0,0,0,.58), inset -3px -3px 8px rgba(255,255,255,.022);
  --ring: 0 0 0 1px var(--hair);

  --glow-red: 0 0 0 1px color-mix(in srgb, var(--red) 42%, transparent), 0 0 26px -4px color-mix(in srgb, var(--red) 52%, transparent);
  --glow-blue: 0 0 0 1px color-mix(in srgb, var(--blue) 42%, transparent), 0 0 26px -4px color-mix(in srgb, var(--blue) 52%, transparent);
  --glow-gold: 0 0 0 1px color-mix(in srgb, var(--gold) 42%, transparent), 0 0 26px -4px color-mix(in srgb, var(--gold) 46%, transparent);
  --glow-green: 0 0 0 1px color-mix(in srgb, var(--green) 42%, transparent), 0 0 26px -4px color-mix(in srgb, var(--green) 46%, transparent);

  --r-card: 22px;
  --r-tile: 14px;
  --r-pill: 999px;

  /* Ticker geometry. Every scroll container that could run under the fixed
     ticker reserves --tick-clear so nothing ever renders beneath it. The extra
     term is breathing room between the footer and the top of the ticker pill. */
  --tick-h: 52px;
  --tick-gap: 16px;
  --tick-clear: calc(var(--tick-h) + var(--tick-gap) * 2 + 40px);
}

[data-theme='light'] {
  --bg: #eef0f3;
  --bg-hi: #f4f6f9;
  --surf: #e8ebf0;
  --surf-2: #dfe3ea;
  --surf-in: #e0e3e9;
  --tx: #0e1117;
  --mut: #4a5260;
  --fnt: #7a8494;
  --hair: #cdd3dc;
  --hair-hi: #bcc4d0;

  --red: #e2202d;
  --red-2: #b8121e;
  --blue: #0f4bd4;
  --blue-2: #0a37a0;
  --gold: #a67c10;
  --green: #0e8a5b;

  --nm-out: 10px 10px 22px rgba(11,18,32,.14), -10px -10px 22px rgba(255,255,255,.95);
  --nm-out-sm: 5px 5px 12px rgba(11,18,32,.12), -5px -5px 12px rgba(255,255,255,.9);
  --nm-in: inset 7px 7px 16px rgba(11,18,32,.13), inset -7px -7px 16px rgba(255,255,255,.95);
  --nm-in-sm: inset 3px 3px 8px rgba(11,18,32,.12), inset -3px -3px 8px rgba(255,255,255,.9);
}

body {
  background-image:
    radial-gradient(1100px 620px at 12% -8%, var(--bg-hi), transparent 62%),
    radial-gradient(900px 560px at 92% 4%, color-mix(in srgb, var(--blue) 7%, transparent), transparent 60%);
  background-attachment: fixed;
  /* Column layout keeps the footer at the bottom on short screens instead of
     floating mid-page above the fixed ticker. */
  display: flex;
  flex-direction: column;
  /* Clears the fixed bottom ticker on every screen. */
  padding-bottom: var(--tick-clear);
}

/* ============================================================
   UTILITIES
   ============================================================ */
.wrap { width: min(1240px, 100% - 2.5rem); margin-inline: auto; }

.ttl { font-family: var(--f-title); font-weight: 400; letter-spacing: .01em; }
.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

.eye {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--fnt);
  line-height: 1.2;
}
.eye.red { color: var(--red); }
.eye.blue { color: var(--blue); }
.eye.gold { color: var(--gold); }
.eye.green { color: var(--green); }
.eye.right { text-align: right; }

.nm { background: var(--surf); box-shadow: var(--nm-out), var(--ring); border-radius: var(--r-card); }
.nm-sm { background: var(--surf); box-shadow: var(--nm-out-sm), var(--ring); border-radius: var(--r-tile); }
.nm-in { background: var(--surf-in); box-shadow: var(--nm-in), var(--ring); border-radius: var(--r-card); }
.nm-in-sm { background: var(--surf-in); box-shadow: var(--nm-in-sm), var(--ring); border-radius: var(--r-tile); }

.glow-red { box-shadow: var(--nm-out), var(--glow-red); }
.glow-blue { box-shadow: var(--nm-out), var(--glow-blue); }
.glow-gold { box-shadow: var(--nm-out), var(--glow-gold); }
.glow-green { box-shadow: var(--nm-out), var(--glow-green); }
.glow-red-sm { box-shadow: var(--nm-out-sm), var(--glow-red); }
.glow-blue-sm { box-shadow: var(--nm-out-sm), var(--glow-blue); }

.grid-2 { display: grid; grid-template-columns: 1.25fr 1fr; gap: 1.1rem; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
.stretch > * { min-width: 0; }

.hide-mobile { display: inline-flex; }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .34; } }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes gradient-shift {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
@keyframes blur-animation {
  from { filter: blur(18px); transform: scale(1); }
  to { filter: blur(28px); transform: scale(1.03); }
}

.rise > * { animation: rise .42s cubic-bezier(.22,.9,.3,1) backwards; }
.rise > *:nth-child(1) { animation-delay: .02s; }
.rise > *:nth-child(2) { animation-delay: .08s; }
.rise > *:nth-child(3) { animation-delay: .14s; }
.rise > *:nth-child(4) { animation-delay: .2s; }

/* ============================================================
   CONTROLS
   ============================================================ */
.pill {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 32px; padding: .35rem .85rem;
  border-radius: var(--r-pill);
  background: var(--surf);
  box-shadow: var(--nm-out-sm), var(--ring);
  color: var(--mut);
  font-size: 10.5px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  transition: color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.pill:hover { color: var(--tx); transform: translateY(-1px); }
.pill:active { box-shadow: var(--nm-in-sm), var(--ring); transform: none; }
.pill[aria-pressed='true'] { color: var(--gold); box-shadow: var(--nm-in-sm), var(--glow-gold); }
.pill-icon { padding: .35rem; width: 32px; justify-content: center; }

/* Theme button shows exactly one glyph per theme. */
.icon-moon { display: none; }
[data-theme='light'] .icon-sun { display: none; }
[data-theme='light'] .icon-moon { display: block; }

.tabs-wrap, .filter-bar {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .3rem; border-radius: var(--r-pill);
}
.filter-bar { flex-wrap: wrap; }

.tab-btn {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .5rem 1rem; border-radius: var(--r-pill);
  color: var(--fnt);
  font-size: 10.5px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  white-space: nowrap;
  transition: color .18s ease, box-shadow .18s ease, background .18s ease;
}
.tab-btn:hover { color: var(--tx); }
.tab-btn.on { color: var(--tx); background: var(--surf); box-shadow: var(--nm-out-sm); }

.count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 .32rem;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--red) 20%, transparent);
  color: var(--red);
  font-size: 9.5px; font-weight: 800; letter-spacing: .04em;
}
.count-badge.zero { background: color-mix(in srgb, var(--fnt) 18%, transparent); color: var(--fnt); }

/* ------------------------------------------------------------
   Glowing corner-accent button
   Adapted from a Uiverse.io component by Baimyrzaev (MIT). The original
   hard-codes a single cyan glow on a pure-black body; here the glow colour is
   a per-instance custom property (--gb) bound to the palette accents, and the
   body/idle shadow use the neumorphic inset tokens so it sits in the design
   system rather than on top of it.
     .accent-blue  → primary navigation / informational CTAs
     .accent-gold  → commissioner + privileged actions
     .accent-red   → destructive or high-attention actions (sync, reset)
   ------------------------------------------------------------ */
.glow-btn {
  --gb: var(--blue);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 36px; padding: .5rem 1.35rem;
  border-radius: 4px; overflow: hidden;
  background: var(--surf-in);
  box-shadow: var(--nm-in-sm), var(--ring);
  transition: 500ms;
}
.glow-btn.accent-red { --gb: var(--red); }
.glow-btn.accent-gold { --gb: var(--gold); }
.glow-btn.accent-green { --gb: var(--green); }
.glow-btn.sm { min-height: 30px; padding: .35rem 1rem; }

.glow-btn > span {
  position: relative; z-index: 1;
  color: var(--mut);
  font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  transition: 500ms; transition-delay: 500ms;
}
.glow-btn::before {
  content: ''; position: absolute;
  width: 0; height: 0; left: 50%; right: 50%; top: 50%; bottom: 50%;
  background-color: var(--gb);
  box-shadow: 0 0 10px var(--gb), 0 0 30px var(--gb), 0 0 50px var(--gb);
  transition: 500ms; transition-delay: 500ms;
}
.glow-btn > i {
  position: absolute;
  background-color: var(--gb);
  box-shadow: 0 0 15px var(--gb), 0 0 30px var(--gb), 0 0 50px var(--gb);
  transition: 500ms;
}
.glow-btn .gb-t { width: 15px; height: 2px; top: 0; left: 0; }
.glow-btn .gb-b { width: 15px; height: 2px; right: 0; bottom: 0; }
.glow-btn .gb-l { width: 2px; height: 15px; left: 0; bottom: 0; }
.glow-btn .gb-r { width: 2px; height: 15px; right: 0; top: 0; }

.glow-btn:hover > span { color: var(--surf-in); }
[data-theme='light'] .glow-btn:hover > span { color: var(--bg-hi); }
.glow-btn:hover::before { width: 100%; height: 100%; top: 0; left: 0; right: 0; bottom: 0; }
.glow-btn:hover .gb-t, .glow-btn:hover .gb-b { width: 100%; }
.glow-btn:hover .gb-l, .glow-btn:hover .gb-r { height: 100%; }
.glow-btn:active { transform: translateY(1px); }

/* ============================================================
   HEADER
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 60;
  padding: 1.1rem 0 .85rem;
  display: flex; flex-direction: column; gap: .95rem;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hair);
}

/* Brand sits on its own centred row so the mark and wordmark read as the
   masthead rather than as one more item in the control bar. */
.head-brandbar {
  display: flex; align-items: center; justify-content: center;
  gap: 1.1rem; text-align: center;
}
.brand-mark {
  display: grid; place-items: center;
  width: 68px; height: 68px; flex: none; padding: 9px;
  border-radius: 18px;
}
.brand-mark img { width: 100%; height: 100%; object-fit: contain; }
[data-theme='light'] .brand-mark { background: #fff; }
[data-theme='light'] .brand-mark img { filter: invert(1); }
.brand-text { display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; min-width: 0; }
.brand-title { font-size: 38px; line-height: .95; color: var(--tx); }
.brand-eyebrow { font-size: 12px; letter-spacing: .3em; color: var(--mut); }

.head-row { display: flex; align-items: center; gap: 1rem; justify-content: space-between; }
.head-actions { display: flex; align-items: center; gap: .5rem; }

/* ============================================================
   MAIN / CARDS
   ============================================================ */
main { flex: 1 0 auto; padding: 1.4rem 0 2rem; }
.screen { display: flex; flex-direction: column; gap: 1.1rem; }
.screen-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.screen-head .ttl { font-size: 26px; color: var(--tx); }

.card { padding: 1.15rem 1.25rem; display: flex; flex-direction: column; gap: .85rem; }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.card-title { font-size: 17px; color: var(--tx); }
.card-note { font-size: 11.5px; color: var(--fnt); line-height: 1.5; margin-top: auto; padding-top: .35rem; }

.rowset { display: flex; flex-direction: column; gap: .5rem; }
.empty { padding: 1.1rem; text-align: center; color: var(--fnt); font-size: 12px; }

#banners:empty { display: none; }
.banner {
  display: flex; align-items: center; gap: .6rem;
  padding: .7rem 1rem; margin-bottom: 1rem;
  border-radius: var(--r-tile);
  background: var(--surf); box-shadow: var(--nm-out-sm), var(--ring);
  font-size: 12px; color: var(--mut);
}
.banner.warn { box-shadow: var(--nm-out-sm), var(--glow-gold); color: var(--gold); }
.banner.err { box-shadow: var(--nm-out-sm), var(--glow-red); color: var(--red); }

/* ------------------------------------------------------------
   Feature card — dark gradient body with a four-colour radial glow ring.
   Adapted from a Uiverse.io component by Cksunandh (.m2, MIT). The original
   ring is orange/blue/pink/purple; here the four radial stops are remapped to
   the palette accents (gold, blue, red, green) and the interior gradient uses
   --surf-2 → --surf-in so the card stays darker than the page field and the
   glow reads as a ring around the edge.
   ------------------------------------------------------------ */
/* No stacking context here on purpose: the negative-z pseudo-elements must
   paint behind this element's own background so the glow reads as a ring. */
.feature-card {
  position: relative;
  isolation: auto;
  border-radius: var(--r-card);
  padding: 1.4rem 1.5rem;
  display: flex; flex-direction: column; gap: .9rem;
  background: linear-gradient(135deg, var(--surf-2) 10%, var(--surf-in) 60%);
  background-size: 200% 200%;
  animation: gradient-shift 8s ease-in-out infinite;
}
.feature-card::before,
.feature-card::after {
  --size: 2px;
  content: ''; position: absolute;
  top: calc(var(--size) / -2); left: calc(var(--size) / -2);
  width: calc(100% + var(--size)); height: calc(100% + var(--size));
  border-radius: calc(var(--r-card) + 2px);
  background:
    radial-gradient(circle at 0 0, var(--gold), transparent),
    radial-gradient(circle at 100% 0, var(--blue), transparent),
    radial-gradient(circle at 0 100%, var(--red), transparent),
    radial-gradient(circle at 100% 100%, var(--green), transparent);
}
.feature-card::after { z-index: -1; }
.feature-card::before {
  --size: 10px;
  z-index: -2;
  filter: blur(18px);
  animation: blur-animation 3.4s ease-in-out alternate infinite;
}


.motd-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.motd-title { font-size: 20px; color: var(--tx); }
.motd-line { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; }
.motd-side { display: flex; align-items: center; justify-content: space-between; gap: .7rem; min-width: 0; }
.motd-side.right { flex-direction: row-reverse; }
.motd-info { display: flex; flex-direction: column; gap: .3rem; min-width: 0; align-items: flex-start; text-align: left; }
.motd-side.right .motd-info { align-items: flex-end; text-align: right; }
.motd-mgr { font-family: var(--f-title); font-size: 26px; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; line-height: 1.05; }
.motd-team { font-size: 12.5px; color: var(--mut); }
.motd-score { display: flex; flex-direction: column; align-items: center; gap: .1rem; flex: none; }
.motd-runs { font-family: var(--f-title); font-size: 42px; line-height: 1; color: var(--tx); }
.motd-runs-label { font-size: 9px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--fnt); }
.motd-vs { font-size: 11px; font-weight: 700; letter-spacing: .2em; color: var(--blue-2); flex: none; align-self: center; }
.motd-why { font-size: 11.5px; line-height: 1.55; color: var(--mut); }
.motd-meta { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.motd-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .6rem; border-radius: var(--r-pill);
  background: var(--surf-in); border: 1px solid var(--hair);
  font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--mut);
}
.motd-chip.live { color: var(--red-2); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.motd-chip .team-logo { --logo-size: 22px; }

/* Matchup of the Day - critical games */
.motd-critical { display: flex; flex-direction: column; gap: .5rem; padding-top: .5rem; border-top: 1px solid var(--hair); }
.motd-critical-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.motd-critical-title { font-size: 12.5px; font-weight: 800; letter-spacing: .04em; color: var(--tx); }
.cg-list { display: flex; flex-direction: column; gap: .45rem; }
.cg-row {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: .5rem;
  padding: .5rem .65rem; border-radius: var(--r-tile);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
}
.cg-row.live { box-shadow: var(--nm-in-sm), var(--glow-red); }
.cg-side { display: flex; align-items: center; gap: .35rem; min-width: 0; font-size: 11.5px; color: var(--mut); }
.cg-side.home { justify-content: flex-end; text-align: right; }
.cg-side .team-logo { --logo-size: 20px; }
.cg-abbr { font-weight: 700; letter-spacing: .04em; color: var(--tx); white-space: nowrap; }
.cg-score { font-family: var(--f-title); font-size: 16px; color: var(--tx); }
.cg-mid { display: flex; flex-direction: column; align-items: center; gap: .25rem; flex: none; min-width: 0; }
.cg-tag {
  font-size: 8.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--fnt);
  white-space: nowrap; max-width: 110px; overflow: hidden; text-overflow: ellipsis;
}
.cg-tag.featured { color: var(--gold); }
.cg-tag.both { color: var(--blue-2); }

/* Home lists */
.mover-row, .lead-row, .dt-row {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; row-gap: .4rem;
  padding: .6rem .75rem;
  border-radius: var(--r-tile);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
}
.mover-name, .lead-name, .dt-name {
  font-family: var(--f-title); font-size: 15px; color: var(--tx);
  flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mover-rank, .lead-rank {
  display: grid; place-items: center; flex: none;
  width: 26px; height: 26px; border-radius: 9px;
  background: var(--surf); box-shadow: var(--nm-out-sm);
  font-size: 11px; font-weight: 800; color: var(--mut);
}
.mover-delta { font-size: 12px; font-weight: 800; flex: none; }
.mover-delta.up { color: var(--green); }
.mover-delta.down { color: var(--red); }
.mover-delta.flat { color: var(--fnt); }
.lead-runs, .dt-runs { font-family: var(--f-title); font-size: 17px; color: var(--tx); flex: none; }
.dt-pair { display: inline-flex; align-items: center; gap: .3rem; flex-wrap: wrap; font-size: 10.5px; color: var(--gold); font-weight: 700; letter-spacing: .1em; min-width: 0; flex: 1 1 auto; }
.pair-item { display: inline-flex; align-items: center; gap: .28rem; white-space: nowrap; }
.pair-item .team-logo { --logo-size: 22px; }
.pair-sep { color: var(--fnt); }

.week-list { display: flex; flex-direction: column; gap: .55rem; }
.week-row { display: grid; grid-template-columns: 150px 1fr 56px; align-items: center; gap: .8rem; }
.week-mgr { font-family: var(--f-title); font-size: 15px; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.week-track { height: 12px; border-radius: var(--r-pill); background: var(--surf-in); box-shadow: var(--nm-in-sm); overflow: hidden; }
.week-bar { height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--blue), var(--blue-2)); transition: width .5s cubic-bezier(.22,.9,.3,1); }
.week-row:first-child .week-bar { background: linear-gradient(90deg, var(--gold), var(--red-2)); }
.week-val { font-family: var(--f-title); font-size: 16px; color: var(--tx); text-align: right; }

/* ============================================================
   LIVE GAMES
   ============================================================ */
.games-list { display: flex; flex-direction: column; gap: .8rem; }
/* One height for every card in the slate. A card carrying draft-impact chips is
   the tallest thing here, so its height becomes the module and the shorter cards
   centre their content inside it — uniform height against the uniform gap is what
   makes the slate scan as an even rhythm instead of a ragged stack. The module
   itself is measured in app.js (equalizeCards) rather than hard-coded, because
   what the tallest card holds changes with the day's slate and with the
   breakpoint; an expanded card is taller than the module by definition and is
   left out of both the measurement and the floor. */
.g-card {
  padding: 1rem 1.15rem; display: flex; flex-direction: column; gap: .55rem;
  justify-content: center;
}
.g-card:not(.open) { min-height: var(--g-card-min, 0px); }
/* Club blocks anchor to the outer edges and the two scores flank the centre
   column, so scores line up vertically down the slate no matter how long the
   club names are — and the row spends its width instead of pooling it in the
   gutters. The bottom padding is the chevron's lane. */
.g-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(132px, 210px) auto minmax(0, 1fr);
  align-items: center; gap: .5rem 1.1rem;
  min-height: 58px; padding-bottom: .85rem;
  border-radius: var(--r-tile);
}
.g-row[role='button'] { cursor: pointer; }
.g-row[role='button']:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

/* Each side is [crest | text] with the crest on the outside. The crest never
   shrinks and the text column shrinks ahead of it, so a long owner list narrows
   and clamps instead of spilling sideways under the crest. */
.g-side { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.g-side.away { flex-direction: row; justify-content: flex-start; }
.g-side.home { flex-direction: row-reverse; justify-content: flex-start; }
/* Club logos sit on a white plate: MLB cap marks are dark-on-transparent and
   would vanish against the dark surfaces. The plate is the crest itself — a
   single circle — and the club colour is spent on its ring rather than on a
   second shape behind it. Mixing a little text colour into the ring keeps a very
   dark club (SD, NYY) from disappearing into a dark card. */
.g-crest {
  --crest-size: 42px;
  display: grid; place-items: center; flex: none; overflow: hidden;
  width: var(--crest-size); height: var(--crest-size); border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--club, var(--hair-hi)) 80%, var(--tx)), var(--nm-out-sm);
  font-size: 11px; font-weight: 800; letter-spacing: .02em;
  color: color-mix(in srgb, var(--club, #333) 85%, #000);
}
.g-crest > * { grid-area: 1 / 1; }
/* The mark gets a square box centred in the plate, sized as a share of the crest
   rather than as a percentage of it: a percentage height inside this grid cell
   resolves against an indefinite track, so a tall mark used to keep its intrinsic
   aspect and grow straight out through the circle. */
.g-crest .team-logo { --logo-size: calc(var(--crest-size) * .74); }
/* The abbreviation is a fallback only: it shares the crest's grid cell, so it
   must stay out of sight while the mark is there to cover it. */
.crest-abbr { visibility: hidden; }
.g-crest:not(:has(.team-logo)) .crest-abbr { visibility: visible; }
/* Every mark sits in a square box and is centred inside it, so the club's own
   proportions never move it off centre. --logo-size is the nominal box for the
   context; --logo-opt is the per-club optical correction app.js works out from
   the mark's viewBox aspect (1 for a square mark, up to 1.18 for the tallest). */
.team-logo {
  --logo-size: 20px; --logo-opt: 1;
  width: calc(var(--logo-size) * var(--logo-opt));
  height: calc(var(--logo-size) * var(--logo-opt));
  object-fit: contain; object-position: center center;
  flex: none; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle;
}
.team-logo.plate {
  background: #fff; border-radius: 50%; padding: 2px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.12);
  box-sizing: content-box;
}
.g-meta {
  flex: 0 1 auto; min-width: 0;
  display: flex; flex-direction: column; align-items: stretch; gap: .15rem;
}
.g-side.away .g-meta { text-align: left; }
.g-side.home .g-meta { text-align: right; }
.g-name { font-size: 13px; font-weight: 600; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Narrow screens swap the full club name for its abbreviation rather than
   dropping the text entirely — the row still has to say who is playing. */
.g-abbr { display: none; font-size: 12px; font-weight: 800; letter-spacing: .08em; color: var(--tx); }
/* Owner lists have no length ceiling (a popular club can be held by six
   managers), so they wrap to at most two lines and then ellipsize. */
.g-owner {
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--gold);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; overflow-wrap: anywhere;
}
.g-owner.none { color: var(--fnt); }
.g-side.lose .g-name, .g-side.lose .g-owner { opacity: .5; }
.g-side.lose .g-crest { opacity: .55; }
.g-side.win .g-name { font-weight: 800; color: var(--tx); }
/* Both score cells reserve the same width and press toward the centre column, so
   a 1-run game and a 12-run game keep the same silhouette. */
.g-score-wrap { display: flex; align-items: center; min-width: 44px; }
.g-score-wrap.away { justify-content: flex-end; }
.g-score-wrap.home { justify-content: flex-start; }
.g-center { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .35rem; min-width: 0; width: 100%; }
.g-status-line { display: flex; align-items: center; justify-content: center; gap: .35rem; flex-wrap: wrap; }
.g-score { font-family: var(--f-title); font-size: 28px; color: var(--tx); letter-spacing: .02em; }
.g-score.lose { color: var(--fnt); }
.g-score.win { color: var(--tx); text-shadow: 0 0 12px color-mix(in srgb, var(--gold) 45%, transparent); }
/* SFSportsNight ships digits only — any dash has to fall back to the body font
   or it renders as a missing-glyph box. */
.g-score-blank, .g-count .dash, .sp-score .dash { font-family: var(--f-body); color: var(--fnt); }
.g-score-blank { font-size: .78em; font-weight: 700; }
.g-count .dash { margin: 0 .1em; }
.g-time { font-size: 10.5px; color: var(--fnt); font-weight: 600; }

.status-pill {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .2rem .55rem; border-radius: var(--r-pill);
  font-size: 9.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  background: var(--surf-in); box-shadow: var(--nm-in-sm); color: var(--fnt);
}
.status-pill.live { color: var(--red); box-shadow: var(--nm-in-sm), var(--glow-red); }
.status-pill.live::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--red); animation: pulse 1.4s ease-in-out infinite;
}
.status-pill.final { color: var(--mut); }
.status-pill.sched { color: var(--blue); }

.g-foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; padding-top: .55rem; border-top: 1px solid var(--hair); }
.g-situation { display: flex; align-items: center; justify-content: center; gap: .45rem; flex-wrap: wrap; max-width: 100%; }
.g-diamond {
  display: flex; align-items: center; gap: .55rem;
  padding: .3rem .6rem .3rem .45rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
}
.g-diamond svg { display: block; flex: none; }
.g-diamond .base { fill: var(--surf); stroke: var(--hair-hi); stroke-width: 1.4; }
.g-diamond .base.on { fill: var(--gold); stroke: var(--gold); filter: drop-shadow(0 0 4px color-mix(in srgb, var(--gold) 70%, transparent)); }
.g-diamond .plate-mark { fill: var(--hair-hi); stroke: none; }

.g-outs { display: inline-flex; align-items: center; gap: .3rem; font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--fnt); white-space: nowrap; }
.g-outs .out-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--hair-hi); }
.g-outs .out-dot.on { background: var(--red); box-shadow: 0 0 5px color-mix(in srgb, var(--red) 75%, transparent); }
.g-count { font-family: var(--f-title); font-size: 14px; letter-spacing: .06em; color: var(--tx); }
.g-count .lbl { font-family: var(--f-body); font-size: 9.5px; font-weight: 800; letter-spacing: .18em; color: var(--fnt); margin-right: .3rem; }

.inn-arrow { font-size: 8px; line-height: 1; }
.inn-half { font-size: 9px; letter-spacing: .1em; }

/* ---- expandable box score ----
   Pinned to the row's bottom edge rather than stacked in the centre column: as a
   flow item it added a fourth line to live rows and left short rows lopsided. */
.g-chev {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  font-size: 11px; line-height: 1; color: var(--fnt);
  transition: transform .18s ease, color .18s ease;
}
.g-card.open .g-chev { transform: translateX(-50%) rotate(180deg); color: var(--blue); }
.g-detail {
  display: flex; flex-direction: column; gap: .65rem;
  padding-top: .65rem; border-top: 1px solid var(--hair);
}
.ls-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Natural width, not 100%: stretched across a 1200px card the nine inning cells
   drift a finger-width apart and stop reading as a line score. Overflow on narrow
   screens is what .ls-scroll is for. */
.ls-table { border-collapse: collapse; width: auto; font-variant-numeric: tabular-nums; }
.ls-table th, .ls-table td {
  padding: .3rem .45rem; text-align: center; min-width: 26px;
  font-size: 12px; color: var(--mut); font-weight: 600;
}
.ls-table thead th {
  font-size: 9.5px; font-weight: 800; letter-spacing: .1em; color: var(--fnt);
  border-bottom: 1px solid var(--hair);
}
.ls-table tbody td { color: var(--tx); }
.ls-table tbody tr.win td { font-weight: 800; }
.ls-table .ls-team { text-align: left; white-space: nowrap; padding-right: .7rem; min-width: 68px; }
.ls-team-in {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: 11px; font-weight: 800; letter-spacing: .08em; color: var(--tx);
}
.ls-team-in .team-logo { --logo-size: 18px; }
/* Deliberately body-font: SFSportsNight is a chunky display face that turns
   single digits into near-solid blocks at box-score sizes. */
.ls-table .ls-tot { color: var(--tx); font-weight: 800; border-left: 1px solid var(--hair); }
.ls-table tbody .ls-tot.runs { font-size: 14px; color: var(--blue-2); }
.ls-table thead .ls-tot.runs { color: var(--blue-2); }
.ls-table .now { color: var(--red); }
.ls-table thead th.now { color: var(--red); }

.g-players { display: flex; flex-wrap: wrap; gap: .45rem .55rem; }
.gp {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .25rem .6rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 11.5px; font-weight: 600; color: var(--tx);
}
.gp-lbl { font-size: 9px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--fnt); }
.g-claims {
  display: flex; flex-wrap: wrap; gap: .3rem 1.2rem;
  font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--gold);
}
.gc { display: inline-flex; gap: .5rem; min-width: 0; }
.gc-abbr { color: var(--fnt); }
.g-claims .none { color: var(--fnt); }
.g-detail-foot { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--fnt); }

/* ---- draft-order impact ----
   Manager-facing state is gold everywhere in this app, and these chips are the
   most manager-facing thing on the slate, so they anchor to gold. A "flip" (the
   runs needed are plausibly still in the game) earns the ring glow; a "watch" is
   the same information at half the volume. */
.g-impact {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  padding-top: .5rem; border-top: 1px solid var(--hair);
}
.g-impact-lbl {
  font-size: 9px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  color: var(--fnt); flex: none;
}
.impact-chip {
  display: inline-flex; align-items: baseline; gap: .4rem; min-width: 0;
  padding: .22rem .6rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--mut); cursor: help;
}
.impact-chip .ic-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.impact-chip .ic-need { flex: none; font-variant-numeric: tabular-nums; color: var(--fnt); }
.impact-chip.flip { color: var(--gold); box-shadow: var(--nm-in-sm), var(--glow-gold); }
.impact-chip.flip .ic-need { color: var(--gold); }
.impact-chip.watch { color: var(--blue-2); }
.impact-chip.watch .ic-need { color: var(--blue); }
.impact-chip.more { color: var(--fnt); }
/* A row that can move the draft order gets a gold edge even before the chips are
   read — scanning the slate for gold is the whole point. */
.g-card.has-impact { box-shadow: var(--nm-out-sm), inset 3px 0 0 color-mix(in srgb, var(--gold) 60%, transparent); }

/* ---- close-game alert ---- */
.close-badge {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .18rem .5rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm), var(--glow-red);
  font-size: 9px; font-weight: 800; letter-spacing: .16em; color: var(--red);
}
.close-badge svg { fill: var(--red); display: block; flex: none; }
.g-card.close-game { box-shadow: var(--nm-out-sm), var(--glow-red); }
/* Both at once: red glow for the ballgame, gold edge for the draft order. */
.g-card.close-game.has-impact {
  box-shadow: var(--nm-out-sm), var(--glow-red), inset 3px 0 0 color-mix(in srgb, var(--gold) 70%, transparent);
}

/* ---- score-change pulse ---- */
@keyframes score-flash {
  0%   { box-shadow: var(--nm-out-sm), var(--glow-green); }
  35%  { box-shadow: var(--nm-out-sm), 0 0 0 1px var(--green), 0 0 30px -2px color-mix(in srgb, var(--green) 75%, transparent); }
  100% { box-shadow: var(--nm-out-sm); }
}
.g-card.score-pulse { animation: score-flash 1.8s ease-out 1; }

/* ---- due-up hitters ---- */
.g-dueup-chip {
  display: inline-flex; align-items: baseline; gap: .35rem;
  padding: .25rem .6rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 11px; font-weight: 800; letter-spacing: .06em; color: var(--tx);
}
.g-dueup-chip .lbl { font-size: 9px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--fnt); }
.g-dueup { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.du-hit {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .6rem .25rem .35rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 11.5px; font-weight: 600; color: var(--tx);
}
.du-hit .du-n {
  display: grid; place-items: center; width: 15px; height: 15px; border-radius: 50%;
  background: var(--surf-2); font-size: 8.5px; font-weight: 800; color: var(--fnt);
  font-variant-numeric: tabular-nums;
}

/* ---- detail tabs ---- */
.gd-tabs { display: flex; gap: .3rem; flex-wrap: wrap; }
.gd-tab {
  padding: .32rem .8rem; border: none; border-radius: var(--r-pill); cursor: pointer;
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-family: inherit; font-size: 9.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  color: var(--fnt);
}
.gd-tab:hover { color: var(--mut); }
.gd-tab.on { color: var(--blue-2); box-shadow: var(--nm-in-sm), var(--glow-blue); }
.gd-tab:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.gd-pane { display: flex; flex-direction: column; gap: .65rem; }
.gd-sub { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.gd-sub-ttl {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: 9.5px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--mut);
}
.gd-sub-ttl .team-logo { --logo-size: 18px; }
.gd-load { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--fnt); }
.gd-wp, .gd-plays { display: flex; flex-direction: column; gap: .4rem; }

/* ---- win probability sparkline ---- */
.wp-spark {
  width: 100%; height: 58px; display: block;
  border-radius: var(--r-tile); background: var(--surf-in); box-shadow: var(--nm-in-sm);
}
.wp-mid { stroke: var(--hair-hi); stroke-width: 1; stroke-dasharray: 3 3; }
.wp-area { fill: color-mix(in srgb, var(--blue) 18%, transparent); stroke: none; }
.wp-line { fill: none; stroke: var(--blue-2); stroke-width: 1.6; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.wp-dot { fill: var(--gold); }
.gd-wp-read { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--mut); }
.gd-wp-read strong { color: var(--tx); }
.gd-wp-read .num { color: var(--blue-2); }
.gd-wp-axis {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 9px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--fnt);
}
.gd-wp-axis .inn-arrow.up { color: var(--green); }
.gd-wp-axis .inn-arrow.down { color: var(--red); }
.gd-wp-even { color: var(--hair-hi); }

/* ---- scoring plays timeline ---- */
.sp-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.sp-row {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: baseline; gap: .6rem;
  padding: .38rem 0; border-top: 1px solid var(--hair);
}
.sp-row:first-child { border-top: none; }
.sp-inn {
  display: inline-flex; align-items: baseline; gap: .2rem;
  font-size: 10.5px; font-weight: 800; color: var(--mut); font-variant-numeric: tabular-nums;
}
.sp-desc { font-size: 11.5px; line-height: 1.45; color: var(--tx); }
.sp-score {
  font-family: var(--f-title); font-size: 14px; letter-spacing: .04em; color: var(--blue-2);
  white-space: nowrap;
}

/* ---- batting / pitching tables ---- */
.gd-box-team { display: flex; flex-direction: column; gap: .4rem; }
.box-table .ls-team { min-width: 128px; }
.box-table tbody .ls-team { display: table-cell; }
.bx-name { font-size: 11.5px; font-weight: 600; color: var(--tx); }
.bx-pos { margin-left: .35rem; font-size: 9px; font-weight: 800; letter-spacing: .1em; color: var(--fnt); }
.box-table tbody td { font-variant-numeric: tabular-nums; }

/* ---- sticky slate header ----
   Off by default: on a desktop viewport the whole filter bar is already in frame,
   and pinning it would only steal vertical space. */
.games-sticky { display: flex; flex-direction: column; gap: 1.1rem; }

/* ============================================================
   STANDINGS
   ============================================================ */
.board-controls { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.search-field { display: flex; align-items: center; gap: .5rem; padding: .5rem .85rem; flex: 1; min-width: 200px; max-width: 340px; color: var(--fnt); }
.search-field input { flex: 1; min-width: 0; background: none; border: none; outline: none; font-size: 13px; color: var(--tx); }
.search-field input::placeholder { color: var(--fnt); }
.filter-hint { color: var(--fnt); }

.st-well { padding: .6rem; display: flex; flex-direction: column; gap: .4rem; }
.st-head, .st-row { display: grid; grid-template-columns: 56px 1fr 320px 120px 56px; align-items: center; gap: .75rem; }
.st-head { padding: .5rem .9rem .3rem; }
.st-body { display: flex; flex-direction: column; gap: .4rem; }
.st-row {
  padding: .7rem .9rem;
  border-radius: var(--r-tile);
  background: var(--surf); box-shadow: var(--nm-out-sm);
  transition: box-shadow .18s ease, transform .18s ease;
}
.st-row:hover { transform: translateY(-1px); }
.st-row.rank-1 { box-shadow: var(--nm-out-sm), var(--glow-blue); }
.st-row.rank-last { box-shadow: var(--nm-out-sm), var(--glow-red); }
.st-row.dimmed { opacity: .3; }
.st-rank { font-family: var(--f-title); font-size: 19px; color: var(--mut); }
.st-row.rank-1 .st-rank { color: var(--blue); }
.st-row.rank-last .st-rank { color: var(--red); }
.st-mgr { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.st-name { font-family: var(--f-title); font-size: 17px; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-sub { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--fnt); }
.st-sub .tied { color: var(--gold); }
.st-clubs { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.st-total { font-family: var(--f-title); font-size: 24px; color: var(--tx); text-align: right; }
.st-delta { font-size: 12px; font-weight: 800; text-align: right; }
.st-delta.up { color: var(--green); }
.st-delta.down { color: var(--red); }
.st-delta.flat { color: var(--fnt); }

.club-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .5rem; border-radius: 9px;
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em; color: var(--mut);
  cursor: pointer;
  transition: color .16s ease, box-shadow .16s ease;
}
.club-chip:hover { color: var(--tx); }
.club-chip.active { color: var(--tx); box-shadow: var(--nm-in-sm), var(--glow-blue); }
.club-chip .team-logo { --logo-size: 22px; }
.club-chip .cr { color: var(--tx); font-variant-numeric: tabular-nums; }
.club-chip.live .cr { color: var(--red); }

/* ============================================================
   WILD CARDS
   ============================================================ */
.wc-card { padding: 1.2rem 1.3rem; display: flex; flex-direction: column; gap: .8rem; }
.wc-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.wc-title { font-size: 18px; color: var(--tx); }
.wc-winner { font-family: var(--f-title); font-size: 30px; color: var(--tx); line-height: 1.05; }
.wc-sub { font-size: 12px; color: var(--mut); line-height: 1.55; }
.wc-foot { font-size: 11.5px; color: var(--fnt); line-height: 1.55; margin-top: auto; padding-top: .5rem; border-top: 1px solid var(--hair); }
.wc-list { display: flex; flex-direction: column; gap: .45rem; }

/* ============================================================
   MODALS
   ============================================================ */
.modal-overlay {
  position: fixed; inset: 0; z-index: 80;
  display: none; align-items: flex-start; justify-content: center;
  padding: 1.5rem 1.25rem;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(6px);
  overflow-y: auto;
}
.modal-overlay.open { display: flex; }
.modal { width: min(720px, 100%); padding: 1.3rem 1.4rem; display: flex; flex-direction: column; gap: 1rem; max-height: 100%; overflow-y: auto; }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.modal-head .ttl { font-size: 21px; color: var(--tx); }
.modal-body { display: flex; flex-direction: column; gap: .9rem; font-size: 13px; line-height: 1.6; color: var(--mut); }
.modal-body h3 { font-family: var(--f-title); font-size: 15px; color: var(--tx); letter-spacing: .02em; }
.modal-body ul, .modal-body ol { padding-left: 1.1rem; display: flex; flex-direction: column; gap: .35rem; }
.modal-body strong { color: var(--tx); font-weight: 700; }
.modal-body .note { padding: .8rem 1rem; border-radius: var(--r-tile); background: var(--surf-in); box-shadow: var(--nm-in-sm); font-size: 12px; }

/* commissioner editor */
.form-row { display: flex; flex-direction: column; gap: .4rem; }
.form-row label { font-size: 10.5px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--fnt); }
.field {
  padding: .6rem .8rem; border-radius: var(--r-tile);
  background: var(--surf-in); box-shadow: var(--nm-in-sm), var(--ring);
  border: none; outline: none; font-size: 13px; color: var(--tx); width: 100%;
}
.field:focus { box-shadow: var(--nm-in-sm), var(--glow-blue); }
select.field { appearance: none; cursor: pointer; }
select.field option { background: var(--surf); color: var(--tx); }
.pick-row { display: grid; grid-template-columns: 130px repeat(3, 1fr); align-items: center; gap: .5rem; }
.pick-row .pr-name { font-family: var(--f-title); font-size: 15px; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pick-list { display: flex; flex-direction: column; gap: .5rem; max-height: 46vh; overflow-y: auto; padding-right: .3rem; }
.form-actions { display: flex; align-items: center; justify-content: flex-end; gap: .6rem; flex-wrap: wrap; }
.form-msg { font-size: 12px; }
.form-msg.err { color: var(--red); }
.form-msg.ok { color: var(--green); }

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  flex: none;
  margin-top: 1.6rem;
  padding: 1.5rem 0;
  border-top: 1px solid var(--hair);
  background: var(--bg);
}
.site-footer .inner {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem .9rem; flex-wrap: wrap;
  font-size: 10.5px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--fnt);
}
/* The commissioner button carries a glow that must not be clipped, and it has
   to stay clear of the fixed ticker pill's rounded corner below it. */
.footer-right { display: inline-flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.footer-right .glow-btn { flex: none; }

/* ============================================================
   BOTTOM TICKER
   Fixed to the viewport bottom at z-index 90. Page content clears it via the
   body's --tick-clear padding; while a modal is open the ticker is hidden
   outright rather than floating over the dialog's backdrop.
   ============================================================ */
.bottom-ticker {
  position: fixed; z-index: 90;
  left: var(--tick-gap); right: var(--tick-gap); bottom: var(--tick-gap);
  height: var(--tick-h);
  display: flex; align-items: center; gap: .9rem;
  padding: 0 .9rem 0 .55rem;
  border-radius: var(--r-pill);
  background: var(--surf);
  box-shadow: var(--nm-out), var(--ring);
  overflow: hidden;
}
.bt-label {
  flex: none; padding: .45rem .95rem; border-radius: var(--r-pill);
  background: var(--surf-in); box-shadow: var(--nm-in-sm);
  font-size: 10px; font-weight: 800; letter-spacing: .22em; text-transform: uppercase; color: var(--red);
}
.bt-viewport { position: relative; flex: 1; height: 100%; overflow: hidden; display: flex; align-items: center; }
.bt-slot { position: absolute; top: 0; left: 0; height: 100%; display: flex; align-items: center; white-space: nowrap; will-change: transform, opacity; }
.bt-seg { display: inline-flex; align-items: center; gap: .55rem; }
.bt-rank { font-size: 10px; font-weight: 800; letter-spacing: .14em; color: var(--fnt); }
.bt-name { font-family: var(--f-title); font-size: 16px; color: var(--tx); }
.bt-mgr { font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); }
.bt-runs { font-family: var(--f-title); font-size: 17px; color: var(--blue-2); }
.bt-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--hair-hi); margin: 0 .55rem; display: inline-block; vertical-align: middle; }
.bt-tag { font-size: 10px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--fnt); }
.bt-seg .team-logo { --logo-size: 24px; }

body:has(.modal-overlay.open) .bottom-ticker { display: none; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1120px) {
  .st-head, .st-row { grid-template-columns: 48px 1fr 240px 96px 48px; }
  .grid-2 { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .wrap { width: min(1240px, 100% - 1.75rem); }
  /* The centre column is the same width on every card so the scores stay in a
     vertical line down the slate; it just gets tighter as the viewport does, and
     the width it gives up goes to the club names. */
  .g-row { grid-template-columns: minmax(0, 1fr) auto minmax(112px, 172px) auto minmax(0, 1fr); gap: .45rem .75rem; }
  .g-crest { --crest-size: 38px; }
  .g-name { font-size: 12px; }
  .head-row { flex-wrap: wrap; justify-content: center; }
  .tabs-wrap { width: 100%; justify-content: center; flex-wrap: wrap; }
  .grid-3 { grid-template-columns: 1fr; }
  .st-head { display: none; }
  .st-row { grid-template-columns: 44px 1fr 72px; grid-template-areas: 'rank mgr total' 'clubs clubs clubs'; row-gap: .55rem; }
  .st-rank { grid-area: rank; }
  .st-mgr { grid-area: mgr; }
  .st-clubs { grid-area: clubs; }
  .st-total { grid-area: total; }
  .st-delta { display: none; }
}

@media (max-width: 700px) {
  .screen-head .ttl { font-size: 22px; }
  .g-row { grid-template-columns: minmax(0, 1fr) auto minmax(104px, 150px) auto minmax(0, 1fr); gap: .4rem .6rem; }
  .g-crest { --crest-size: 36px; font-size: 10px; }
  .g-score { font-size: 22px; }
  .g-score-wrap { min-width: 34px; }
  .g-name { font-size: 11px; }
  .g-card { padding: .85rem .9rem; }
  .g-side { gap: .5rem; }
  .ls-table th, .ls-table td { padding: .28rem .35rem; min-width: 22px; font-size: 11px; }
  /* Pins the date line and the filters under the masthead so a 15-game slate can
     be scrolled without losing them. --hdr-h is measured in app.js because the
     masthead reflows (and changes height) across these breakpoints. */
  .games-sticky {
    position: sticky; top: calc(var(--hdr-h, 0px) - 1px); z-index: 40;
    gap: .6rem; padding: .7rem 0 .55rem;
    /* Opaque enough that game rows never ghost through, with blur where supported. */
    background: color-mix(in srgb, var(--bg) 92%, transparent);
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    border-bottom: 1px solid var(--hair);
  }
  .box-table .ls-team { min-width: 104px; }
  .week-row { grid-template-columns: 100px 1fr 44px; }
  .pick-row { grid-template-columns: 1fr 1fr; }
  .pick-row .pr-name { grid-column: 1 / -1; }
  .hide-mobile { display: none; }
}

@media (max-width: 540px) {
  :root { --tick-gap: 10px; }
  .wrap { width: min(1240px, 100% - 1.25rem); }
  .brand-title { font-size: 24px; }
  .brand-eyebrow { font-size: 9.5px; letter-spacing: .2em; }
  .brand-mark { width: 44px; height: 44px; padding: 5px; border-radius: 14px; }
  .head-brandbar { gap: .6rem; }
  .site-header { padding: .7rem 0 .55rem; gap: .6rem; }
  /* Keep the controls on one row so the taller masthead doesn't eat the fold. */
  .head-row { flex-wrap: nowrap; }
  .tabs-wrap { width: auto; flex: 1 1 auto; min-width: 0; }
  .head-actions { flex: 0 0 auto; }
  .g-row { grid-template-columns: minmax(0, 1fr) auto minmax(88px, 104px) auto minmax(0, 1fr); gap: .3rem .45rem; padding-bottom: .7rem; }
  .g-side { gap: .4rem; }
  .g-crest { --crest-size: 30px; box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--club, var(--hair-hi)) 80%, var(--tx)); }
  .g-score { font-size: 20px; }
  .g-score-wrap { min-width: 24px; }
  .g-center { flex-direction: column; gap: .3rem; }
  /* The filled dots already carry the out count; the word is what pushes the
     situation chip wider than the centre track. */
  .g-outs .out-lbl { display: none; }
  /* Full club names don't fit at this width; the abbreviation does. */
  .g-name { display: none; }
  .g-abbr { display: block; }
  /* Two lines, not one: at this width a single line clips "JOE · JAKE" down to
     "JOE ·", which reads as a bug rather than as a claim list. */
  .g-owner { font-size: 9px; letter-spacing: .06em; line-height: 1.35; }
  .g-situation { gap: .4rem; }
  .g-diamond { padding: .25rem .45rem .25rem .35rem; gap: .35rem; }
  /* Inning, outs and the diamond are the load-bearing live details at this
     width; the ball-strike count is what gets dropped to make them fit. */
  .g-count { display: none; }
  .motd-line { grid-template-columns: 1fr; gap: .6rem; }
  .motd-vs { display: none; }
  .motd-side.right { flex-direction: row; }
  .motd-side.right .motd-info { align-items: flex-start; text-align: left; }
  .motd-mgr { font-size: 21px; }
  .motd-runs { font-size: 32px; }
  .cg-row { grid-template-columns: 1fr auto 1fr; gap: .35rem; padding: .45rem .5rem; }
  .cg-side { font-size: 10.5px; }
  .cg-tag { max-width: 70px; }
  .bt-label { display: none; }
  .bottom-ticker { padding: 0 .8rem; }
  .modal { padding: 1rem 1rem; }
  /* The chips carry their own "passes"/"vs" wording, so the section label is the
     first thing to go when width runs out. */
  .g-impact-lbl { display: none; }
  .impact-chip { font-size: 9px; letter-spacing: .06em; padding: .2rem .5rem; }
  .impact-chip .ic-label { max-width: 130px; }
  .sp-row { grid-template-columns: 28px minmax(0, 1fr) auto; gap: .45rem; }
  .sp-desc { font-size: 11px; }
  .du-hit { font-size: 10.5px; padding: .2rem .5rem .2rem .3rem; }
  .gd-tab { padding: .3rem .6rem; letter-spacing: .1em; }
}

/* Reduced motion: the pulse is a notification, so it degrades to a static hold
   rather than disappearing entirely. */
@media (prefers-reduced-motion: reduce) {
  .g-card.score-pulse { animation: none; box-shadow: var(--nm-out-sm), var(--glow-green); }
  .week-bar { transition: none; }
}
