:root {
  --bg: #090b0e;
  --bg-elev: #10141a;
  --bg-cell: #141920;
  --bg-cell-hover: #1b222c;
  --line: rgba(244, 241, 234, 0.08);
  --line-strong: rgba(244, 241, 234, 0.14);
  --text: #f4f1ea;
  --muted: #8b93a1;
  --faint: #5c6572;
  --accent: #6ec8ff;
  --accent-dim: rgba(110, 200, 255, 0.14);
  --accent-strong: rgba(110, 200, 255, 0.28);
  --radius: 18px;
  --font: "Manrope", system-ui, sans-serif;
  --display: "Syne", "Manrope", system-ui, sans-serif;
  --shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
}

.sport-mlb {
  --accent: #6ec8ff;
  --accent-dim: rgba(110, 200, 255, 0.14);
  --accent-strong: rgba(110, 200, 255, 0.28);
}

.sport-nba {
  --accent: #ff6b3d;
  --accent-dim: rgba(255, 107, 61, 0.16);
  --accent-strong: rgba(255, 107, 61, 0.3);
}

.sport-epl {
  --accent: #c6f04a;
  --accent-dim: rgba(198, 240, 74, 0.14);
  --accent-strong: rgba(198, 240, 74, 0.28);
}

.sport-laliga {
  --accent: #fb7185;
  --accent-dim: rgba(251, 113, 133, 0.16);
  --accent-strong: rgba(251, 113, 133, 0.3);
}

.sport-bundesliga {
  --accent: #818cf8;
  --accent-dim: rgba(129, 140, 248, 0.16);
  --accent-strong: rgba(129, 140, 248, 0.3);
}

.sport-ucl {
  --accent: #f5c542;
  --accent-dim: rgba(245, 197, 66, 0.16);
  --accent-strong: rgba(245, 197, 66, 0.3);
}

.sport-uel {
  --accent: #f97316;
  --accent-dim: rgba(249, 115, 22, 0.16);
  --accent-strong: rgba(249, 115, 22, 0.3);
}

.sport-nfl {
  --accent: #e03c31;
  --accent-dim: rgba(224, 60, 49, 0.16);
  --accent-strong: rgba(224, 60, 49, 0.3);
}

.sport-ncaaf {
  --accent: #f0b429;
  --accent-dim: rgba(240, 180, 41, 0.16);
  --accent-strong: rgba(240, 180, 41, 0.3);
}

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

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: var(--font);
  color: var(--text);
  background:
    radial-gradient(1200px 600px at 10% -10%, var(--accent-dim), transparent 55%),
    radial-gradient(900px 500px at 110% 0%, rgba(255, 255, 255, 0.04), transparent 50%),
    var(--bg);
  -webkit-font-smoothing: antialiased;
}

/* Below the sidebar breakpoint the nav is a sticky top bar (never scrolls out
   of view — the feed opens already scrolled past it, so without this there
   was no way back to it short of scrolling all the way up). At and above the
   breakpoint (.shell, further down) it becomes a sticky sidebar instead. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(9, 11, 14, 0.92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
  max-width: 72rem;
  margin: 0 auto;
  padding: 1.75rem clamp(1.25rem, 4vw, 2.25rem);
}

.app {
  max-width: 50rem;
  margin: 0 auto;
  padding: 2.25rem clamp(1.25rem, 4vw, 2.25rem) 4rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.mark {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 14px;
  background: var(--accent);
  color: #090b0e;
  font-family: var(--display);
  font-weight: 800;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}

.brand-copy h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.35rem, 2vw, 1.85rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.brand-copy p {
  margin: 0.2rem 0 0;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
}

.sports {
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: 0.3rem;
  padding: 0.28rem;
  border-radius: 22px;
  background: rgba(16, 20, 26, 0.8);
  border: 1px solid var(--line);
  backdrop-filter: blur(12px);
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: thin;
}

.sport-tab {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  text-decoration: none;
  border-radius: 999px;
  padding: 0.42rem 0.72rem;
  font-family: inherit;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-start;
  white-space: nowrap;
  line-height: 1.15;
  transition: background 0.15s ease, color 0.15s ease;
}

.sport-tab-full {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
  opacity: 0.7;
}

.sport-tab:hover {
  color: var(--text);
}

.sport-tab.is-active {
  background: var(--accent);
  color: #090b0e;
}

.sport-tab.is-active .sport-tab-full {
  opacity: 0.75;
}

/* The feed controller's own div exists only to scope Stimulus targets/actions
   over both .site-header (favorites picker) and .app (the feed itself) —
   `display: contents` drops it from the box tree so .shell's direct-child
   grid/layout rules below still apply to .site-header and .app as if the
   wrapper weren't there. */
[data-controller="feed"] {
  display: contents;
}

/* Wide screens: the nav becomes a sticky sidebar instead of a sticky top bar
   — same markup, restyled, so there's no separate template to keep in sync. */
@media (min-width: 68rem) {
  .shell {
    display: grid;
    grid-template-columns: 13rem 1fr;
    align-items: start;
    gap: 2.5rem;
    max-width: 66rem;
    margin: 0 auto;
    padding: 0 clamp(1.25rem, 4vw, 2.25rem);
  }

  .site-header {
    position: sticky;
    top: 2rem;
    z-index: 1;
    grid-column: 1;
    background: none;
    backdrop-filter: none;
    border-bottom: none;
    align-self: start;
  }

  .topbar {
    flex-direction: column;
    align-items: stretch;
    max-width: none;
    margin: 0;
    padding: 2rem 0;
    gap: 1.75rem;
  }

  .brand {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
  }

  .brand-copy h1 {
    font-size: 1.3rem;
  }

  .sports {
    flex-direction: column;
    align-items: stretch;
    max-width: none;
    overflow: visible;
    background: none;
    border: none;
    backdrop-filter: none;
    padding: 0;
    gap: 0.15rem;
  }

  .sport-tab {
    width: 100%;
    border-radius: 10px;
    padding: 0.55rem 0.7rem;
  }

  .app {
    grid-column: 2;
    margin: 0;
    padding: 2rem 0 4rem;
  }

  /* Favorite-team filtering moves into the sidebar, right below the sport
     list, instead of a horizontal row above the feed. */
  .team-filter {
    flex-direction: column;
    align-items: stretch;
    max-width: none;
    margin: 1.5rem 0 0;
    padding: 1.5rem 0 0;
    border-top: 1px solid var(--line);
  }

  .favorites-btn {
    width: 100%;
    text-align: left;
  }

  .toolbar {
    max-width: none;
    margin: 1.25rem 0 0;
    padding: 1.25rem 0 0;
    border-top: 1px solid var(--line);
  }

  .count {
    padding-left: 0;
  }
}

/* Lives inside .site-header now (sticky top bar below 68rem, sidebar at and
   above it) so switching sports and picking favorites are never more than a
   scroll-restore away, same as the sport nav itself. */
.team-filter {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  flex-wrap: wrap;
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 2.25rem) 1.25rem;
}

.favorites {
  position: relative;
}

.favorites-btn {
  white-space: nowrap;
}

.picker {
  position: absolute;
  top: calc(100% + 0.45rem);
  left: 0;
  z-index: 20;
  width: min(22rem, calc(100vw - 2rem));
  padding: 0.85rem;
  border-radius: 16px;
  background: var(--bg-elev);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
}

.picker-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.7rem;
}

.picker-kicker {
  margin: 0;
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.picker-head h3 {
  margin: 0.15rem 0 0;
  font-family: var(--display);
  font-size: 1.05rem;
  letter-spacing: -0.03em;
}

.picker-close {
  width: 2rem;
  height: 2rem;
  font-size: 1.2rem;
}

.picker-search {
  width: 100%;
  margin-bottom: 0.55rem;
  padding: 0.55rem 0.7rem;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: 0.85rem;
}

.picker-search:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.picker-list {
  max-height: 20rem;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.picker-group {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin: 0.35rem 0 0.15rem;
}

.picker-group h4 {
  margin: 0 0 0.2rem;
  padding: 0.15rem 0.45rem;
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.picker-item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 0.45rem;
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 600;
}

.picker-item:hover {
  background: var(--accent-dim);
}

.picker-item input {
  accent-color: var(--accent);
}

.team-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  min-height: 2.4rem;
}

.team-chip {
  appearance: none;
  border: 1px solid var(--line-strong);
  background: var(--bg-elev);
  color: var(--muted);
  cursor: pointer;
  border-radius: 999px;
  padding: 0.42rem 0.8rem;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.team-chip:hover {
  color: var(--text);
  border-color: var(--accent);
}

.team-chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #090b0e;
}

/* Lives inside .site-header, right below the favorites row, same as
   everything else there — reachable regardless of scroll position. */
.toolbar {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 2.25rem) 1.25rem;
}

.icon-btn,
.ghost-btn {
  appearance: none;
  font-family: inherit;
  cursor: pointer;
  border: 1px solid var(--line-strong);
  background: var(--bg-elev);
  color: var(--text);
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.icon-btn {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  font-size: 1.4rem;
  line-height: 1;
  display: grid;
  place-items: center;
}

.ghost-btn {
  border-radius: 999px;
  padding: 0.45rem 0.9rem;
  font-size: 0.8rem;
  font-weight: 700;
}

.icon-btn:hover,
.ghost-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.ghost-btn-accent {
  background: var(--accent-dim);
  border-color: var(--accent-strong);
  color: var(--accent);
}

.count {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
  padding-left: 0.4rem;
}

.count-line {
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   The feed: a continuous scroll of day-sections, shared structurally by
   the per-sport feed (many days, infinite scroll) and the brief (one day,
   split into dayparts instead of a date heading). Both render the same
   .row markup underneath so a highlight looks identical everywhere.
--------------------------------------------------------------------- */

.feed-sentinel {
  height: 1px;
}

/* Prepending older days adjusts window.scrollY manually (feed_controller#loadMore)
   to keep the reader's place — the browser's own scroll-anchoring heuristic
   would otherwise "correct" the same shift a second time and drift the page. */
.feed {
  overflow-anchor: none;
}

.day {
  padding: 1.6rem 0;
  border-bottom: 1px solid var(--line);
}

.day:first-child {
  padding-top: 0;
}

.day-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.day-date {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
}

.day.is-today .day-date {
  color: var(--accent);
}

.day-count {
  flex: 0 0 auto;
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--accent);
  background: var(--accent-dim);
  border-radius: 999px;
  padding: 0.12rem 0.5rem;
}

.day-empty {
  margin: 0;
  color: var(--faint);
  font-size: 0.82rem;
}

.daypart {
  margin-top: 1.75rem;
}

.daypart:first-of-type {
  margin-top: 0;
}

.daypart-label {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.games {
  list-style: none;
  margin: 0;
  padding: 0;
}

.row-shell {
  position: relative;
}

.row {
  display: grid;
  grid-template-columns: 3.4rem 1fr auto;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.92rem;
  transition: color 0.15s ease;
}

.row--tagged {
  grid-template-columns: 3.4rem auto 1fr auto;
}

li:last-child > .row,
li:last-child > .row-shell .row {
  border-bottom: none;
}

.row-shell .row {
  padding-right: 2.1rem;
}

a.row:hover {
  color: var(--accent);
}

.row.is-watched {
  color: var(--muted);
}

.row.is-watched:hover {
  color: var(--accent);
}

.row-check {
  appearance: none;
  position: absolute;
  top: 50%;
  right: 0;
  z-index: 1;
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  padding: 0;
  transform: translateY(-50%);
  border-radius: 999px;
  border: 1.5px solid var(--line-strong);
  background: var(--bg-cell);
  color: var(--faint);
  cursor: pointer;
}

.row-check::after {
  content: "";
  position: absolute;
  inset: -0.4rem;
}

.row-check::before {
  content: "";
  display: block;
  width: 0.3rem;
  height: 0.52rem;
  margin: 0 auto;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-0.5px, -1px);
  opacity: 0.45;
}

.row-check:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.row-check.is-watched {
  border-color: var(--accent);
  background: var(--accent);
  color: #090b0e;
}

.row-check.is-watched::before {
  opacity: 1;
}

.row-pending {
  cursor: default;
  color: var(--muted);
  font-weight: 500;
}

.row-time {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--muted);
}

.row-pending .row-time {
  color: var(--faint);
}

.row-tag {
  justify-self: start;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  background: var(--accent-dim);
  color: var(--accent);
}

.row-matchup {
  min-width: 0;
  overflow-wrap: break-word;
}

/* A team's record going into the game: quieter than the name it follows. */
.row-record {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
}

.row-pending .row-record {
  color: var(--faint);
}

.row-watch {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--faint);
}

.row-watch svg {
  width: 0.65rem;
  height: 0.65rem;
  fill: currentColor;
}

/* A caution, not a sport accent — stays the same amber regardless of which
   sport's page it's on, so it reads as "pay attention" rather than styling. */
.row-flag {
  color: #f0b429;
  font-size: 0.8rem;
  line-height: 1;
}

a.row:hover .row-watch {
  color: var(--accent);
}

.row-pending em {
  flex: 0 0 auto;
  font-style: normal;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
}

/* ---------------------------------------------------------------------
   The morning brief: one day, no sport picker, tags on every row since
   several sports share the page.
--------------------------------------------------------------------- */

.brief-masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
}

.brief-toggle {
  display: flex;
  gap: 0.4rem;
  flex: 0 0 auto;
}

.brief-dateline h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.brief-dateline p {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: 0.92rem;
}

.empty {
  margin: 0 0 1.25rem;
  padding: 1.4rem 1.5rem;
  border-radius: var(--radius);
  border: 1px dashed var(--line-strong);
  background: rgba(16, 20, 26, 0.65);
}

/* The season-boundary marker in a sport's feed: same "special state" box as
   .empty, but a solid accent border — this is a milestone to notice while
   scrolling past, not an apology for missing content. */
.offseason {
  margin: 1rem 0 1.75rem;
  border: 1px solid var(--accent-strong);
  background: linear-gradient(180deg, var(--accent-dim), rgba(16, 20, 26, 0.65) 60%);
}

.empty-kicker {
  margin: 0 0 0.25rem;
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.empty h3 {
  margin: 0 0 0.4rem;
  font-family: var(--display);
  font-size: 1.35rem;
  letter-spacing: -0.03em;
}

.empty p {
  margin: 0 0 0.9rem;
  color: var(--muted);
}

.empty code {
  font-size: 0.85em;
  color: var(--accent);
}

.footnote {
  margin-top: 1.5rem;
  color: var(--faint);
  font-size: 0.78rem;
  font-weight: 500;
}

.icon-btn:focus-visible,
.ghost-btn:focus-visible,
.sport-tab:focus-visible,
.team-chip:focus-visible,
.row:focus-visible,
.row-check:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 800px) {
  .app {
    padding-top: 1.75rem;
  }

  .sport-tab {
    padding: 0.5rem 0.75rem;
  }

  .sport-tab-full {
    display: none;
  }

  .team-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    max-width: 100%;
    padding-bottom: 0.2rem;
  }

  .team-chip {
    flex: 0 0 auto;
  }
}

@media (max-width: 26rem) {
  .row {
    grid-template-columns: 2.6rem 1fr auto;
    gap: 0.5rem;
  }

  .row--tagged {
    grid-template-columns: 2.6rem auto 1fr auto;
  }

  .row-watch span {
    display: none;
  }
}
