/* ==========================================================================
   Games To Watch - application styles
   Every rule lives in a layer, so nothing here needs !important.
   ========================================================================== */

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

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

  body,
  h1, h2, h3, h4, h5, h6,
  p, figure, blockquote, dl, dd { margin: 0; }

  ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }

  img, svg, picture { display: block; max-width: 100%; }
  img { height: auto; }

  a { color: inherit; text-decoration: none; }

  button, input, select, textarea { font: inherit; color: inherit; }

  button {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
  }

  :focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
    border-radius: var(--r-badge);
  }
}

@layer base {
  body {
    margin: 0;
    min-height: 100dvh;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: var(--fs-400);
    line-height: var(--lh-normal);
    -webkit-font-smoothing: antialiased;
    /* Clears the fixed bottom tab bar on phones. */
    padding-bottom: calc(var(--tabbar-h) + var(--safe-b));
  }

  @media (min-width: 768px) {
    body { padding-bottom: 0; }
  }

  ::selection { background: var(--accent); color: var(--accent-ink); }
}

/* ==========================================================================
   Layout
   ========================================================================== */
@layer components {
  .page {
    width: 100%;
    max-width: var(--page-max);
    margin-inline: auto;
    padding-inline: var(--page-pad);
  }

  .page--read { max-width: var(--read-max); }
  .page--prose { max-width: var(--prose-max); }

  .stack { display: flex; flex-direction: column; }
  .stack-2 { gap: var(--sp-2); }
  .stack-3 { gap: var(--sp-3); }
  .stack-4 { gap: var(--sp-4); }
  .stack-6 { gap: var(--sp-6); }

  /* ------------------------------------------------------------------
     Typographic helpers. The design uses condensed uppercase for every
     label, so these two carry a lot of the look.
     ------------------------------------------------------------------ */
  .u-display {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    text-transform: uppercase;
  }

  .u-label {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-3);
    text-transform: uppercase;
    color: var(--ink-muted);
  }

  .u-num { font-variant-numeric: tabular-nums; }
  .u-muted { color: var(--ink-muted); }

  /* ==================================================================
     App chrome
     ================================================================== */
  .app-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: calc(var(--safe-t) + var(--sp-4)) var(--page-pad) var(--sp-3);
    max-width: var(--page-max);
    margin-inline: auto;
  }

  .brand {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    min-width: 0;
  }

  .brand__mark {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-900);
    line-height: 1;
    letter-spacing: .01em;
  }

  .brand__name {
    font-family: var(--font-display);
    font-weight: var(--fw-600);
    font-size: var(--fs-300);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-muted);
    white-space: nowrap;
  }

  /* Hidden by JS when the browser can't do push, or permission is denied. */
  .alerts-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    flex-shrink: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    padding: var(--sp-1) var(--sp-3);
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    white-space: nowrap;
    transition: border-color var(--dur) var(--ease);
  }

  .alerts-pill:hover { border-color: var(--border-strong); }

  /* JS flips the button's inline display, so the flex row lives one level in. */
  .alerts { flex-shrink: 0; }

  .alerts-pill__inner {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
  }

  /*
    Installed to the home screen: the header sticks, as it does today. The old
    build also hid the nav labels here because four buttons could not fit a
    narrow phone; the nav is now a bottom tab bar with room for words.

    Never give this element a backdrop-filter (or a filter, or a transform).
    A non-`none` backdrop-filter makes the header a containing block for its
    fixed-position descendants, and .tabbar is one of them: it stopped
    resolving against the viewport and pinned itself to the bottom of the
    *header* instead - over the status bar and on top of the brand. Only the
    installed app ever showed it, because only .pwa-mode set the filter. The
    scrim is 92% opaque, so the blur was buying almost nothing anyway.
  */
  .pwa-mode .app-header {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    background: var(--scrim);
    /* The status bar is drawn over the page (black-translucent + viewport-fit
       cover), so the brand needs more than the browser's --sp-4 of air. */
    padding-top: calc(var(--safe-t) + var(--sp-6));
  }

  .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-400);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    color: var(--ink-muted);
  }

  .back-link:hover { color: var(--ink); }

  /* ------------------------------------------------------------------
     Tab bar. One DOM node: pinned to the bottom on phones, and lifted
     into the header row on wider screens.
     ------------------------------------------------------------------ */
  .tabbar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: var(--z-tabbar);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    background: var(--scrim);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid var(--border);
    padding-bottom: var(--safe-b);
  }

  .tabbar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-2) 0;
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-300);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-muted);
    transition: color var(--dur) var(--ease);
  }

  .tabbar__item::before {
    content: '';
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: transparent;
    transition: background var(--dur) var(--ease);
  }

  .tabbar__item:hover { color: var(--ink); }

  .tabbar__item[aria-current='page'] { color: var(--accent); }
  .tabbar__item[aria-current='page']::before { background: var(--accent); }

  @media (min-width: 768px) {
    .tabbar {
      position: static;
      background: none;
      backdrop-filter: none;
      -webkit-backdrop-filter: none;
      border-top: 0;
      padding-bottom: 0;
      grid-auto-columns: auto;
      gap: var(--sp-6);
    }

    .tabbar__item { padding: 0; }

    .tabbar__item::before {
      order: 1;
      width: 100%;
    }
  }

  /* ------------------------------------------------------------------
     Footer
     ------------------------------------------------------------------ */
  .site-footer {
    padding: var(--sp-6) var(--page-pad) var(--sp-4);
    text-align: center;
    font-size: var(--fs-100);
    line-height: 1.6;
    color: var(--ink-muted);
  }

  .site-footer a { text-decoration: underline; }
  .site-footer a:hover { color: var(--accent); }

  /* ==================================================================
     Primitives
     ================================================================== */
  .icon {
    display: inline-block;
    vertical-align: -.15em;
    flex-shrink: 0;
  }

  .dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
  }

  .dot--live { background: var(--live); animation: gtw-pulse 1.4s ease-in-out infinite; }
  .dot--ok { background: var(--ok); }
  .dot--muted { background: var(--ink-muted); }
  .dot--on-accent { background: currentColor; animation: gtw-pulse 1.4s ease-in-out infinite; }

  @keyframes gtw-pulse {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.6); opacity: .35; }
  }

  @media (prefers-reduced-motion: reduce) {
    .dot--live, .dot--on-accent { animation: none; }
  }

  .badge {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    border-radius: var(--r-badge);
    padding: 2px 5px;
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-100);
    letter-spacing: var(--tr-1);
    text-transform: uppercase;
    white-space: nowrap;
  }

  .badge--hot { background: var(--accent); color: var(--accent-ink); }
  .badge--cold { background: var(--heat-low); color: #FFFFFF; }
  .badge--team { background: var(--team); color: var(--team-ink); }
  .badge--quiet { background: var(--surface-2); color: var(--ink-muted); }

  .status {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-200);
    letter-spacing: .14em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  .status--live { color: var(--live); }
  .status--other { font-weight: var(--fw-700); color: var(--ink-muted); }

  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    border-radius: var(--r-card);
    padding: var(--sp-3) var(--sp-6);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-500);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    transition: filter var(--dur) var(--ease);
  }

  .btn:hover { filter: brightness(1.08); }
  .btn--primary { background: var(--accent); color: var(--accent-ink); }
  .btn--invert { background: var(--ink); color: var(--bg); }
  .btn--full { width: 100%; padding-inline: 0; }

  .btn--play {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    padding: 0;
    background: var(--team);
    color: var(--team-ink);
    flex-shrink: 0;
  }

  .btn--play-lg { width: 44px; height: 44px; }

  /* ------------------------------------------------------------------
     Heat meter - the visual form of the watchability score.
     ------------------------------------------------------------------ */
  .meter {
    display: block;
    width: 100%;
    height: 5px;
    border-radius: 3px;
    background: var(--surface-2);
    overflow: hidden;
  }

  .meter__fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--heat-fill);
  }

  .meter--lg { height: 6px; }

  .meter--on-accent { background: rgb(255 255 255 / .3); }
  .meter--on-accent .meter__fill { background: #FFFFFF; }

  .heat {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
  }

  /* Inside a heat row the bar shares the line; elsewhere it spans its parent. */
  .heat > .meter { flex: 1; width: auto; }

  .heat__value {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-400);
    line-height: 1;
  }

  .heat__value sub {
    font-size: var(--fs-100);
    font-weight: var(--fw-600);
    color: var(--ink-muted);
    vertical-align: baseline;
  }

  .heat--low .heat__value, .heat--low .heat__label { color: var(--heat-low); }
  .heat--mid .heat__value, .heat--mid .heat__label { color: var(--heat-mid-2); }
  .heat--high .heat__value, .heat--high .heat__label { color: var(--heat-high); }

  .heat__label {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    white-space: nowrap;
  }

  /* ------------------------------------------------------------------
     Surfaces
     ------------------------------------------------------------------ */
  .card {
    background: var(--surface);
    border-radius: var(--r-card-lg);
    box-shadow: var(--sh-1);
    overflow: hidden;
  }

  .card--xl { border-radius: var(--r-card-xl); }

  .section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    padding-block: var(--sp-4) var(--sp-2);
  }

  .section-head__title {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-700);
    letter-spacing: .02em;
    text-transform: uppercase;
  }

  .section-head__meta {
    font-size: var(--fs-300);
    color: var(--ink-muted);
    white-space: nowrap;
  }

  .section-head__meta b { color: var(--accent); }

  .rule {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding-block: var(--sp-5) var(--sp-2);
  }

  .rule::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
  }

  .empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-12) var(--sp-6);
    text-align: center;
    color: var(--ink-muted);
  }

  .empty__title {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-700);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    color: var(--ink);
  }

  .empty__body { max-width: 34ch; }

  /* ==================================================================
     Team identity
     ================================================================== */
  .team-logo {
    width: var(--logo-size, 44px);
    height: var(--logo-size, 44px);
    flex-shrink: 0;
    object-fit: contain;
  }

  .team-abbr {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-400);
    letter-spacing: var(--tr-1);
  }

  /* The split colour bar that heads every matchup surface. */
  .team-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    height: var(--strip-h, 5px);
  }

  .team-strip__away { background: var(--team-away); }
  .team-strip__home { background: var(--team-home); }

  .team-rail {
    background: var(--team);
    width: var(--rail-w, 4px);
    align-self: stretch;
  }

  /* ==================================================================
     Home - hero
     ================================================================== */
  .hero {
    display: block;
    border-radius: var(--r-card-lg);
    overflow: hidden;
    padding: var(--sp-3) var(--sp-4);
    color: #FFFFFF;
    background: linear-gradient(100deg, var(--team-away) 0%, var(--team-home) 100%);
  }

  .hero__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-3);
    text-transform: uppercase;
  }

  .hero__scores {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: var(--sp-2);
  }

  .hero__side {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
  }

  .hero__score {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-900);
    line-height: 1;
  }

  .hero__clock {
    text-align: center;
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-600);
    line-height: 1.1;
  }

  .hero__clock small { font-size: var(--fs-300); opacity: .85; }

  .hero .meter { margin-top: var(--sp-3); }

  /*
    The hero is a single matchup, so its content stops growing well before the
    page does - otherwise the two crests end up a screen apart on a desktop.
  */
  .hero__inner {
    max-width: 34rem;
    margin-inline: auto;
  }

  /* ==================================================================
     Home - game grid
     ================================================================== */
  .game-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
  }

  @media (min-width: 600px) { .game-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  @media (min-width: 900px) { .game-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
  @media (min-width: 1200px) { .game-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

  .game-card {
    display: flex;
    flex-direction: column;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  }

  .game-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--sh-2);
  }

  .game-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3) 0;
  }

  .game-card__tv {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-1);
    color: var(--ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .game-card__body {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-2) var(--sp-3);
  }

  .game-card__team {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-1);
    min-width: 0;
  }

  .game-card__centre {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 70px;
  }

  .scoreline {
    display: flex;
    gap: var(--sp-2);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-900);
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  .scoreline__sep { color: var(--ink-dim); }
  .scoreline__value--lost { color: var(--ink-muted); }
  .scoreline__value--none { color: var(--ink-dim); }

  .game-card__detail {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-300);
    letter-spacing: var(--tr-1);
    font-variant-numeric: tabular-nums;
    text-align: center;
    color: var(--ink-muted);
  }

  .game-card__detail--live { color: var(--ink); }

  .game-card__heat {
    margin-top: auto;
    padding: var(--sp-2) var(--sp-3) var(--sp-3);
    border-top: 1px solid var(--border);
  }

  /* ==================================================================
     Home - news
     ================================================================== */
  .news-row {
    display: grid;
    grid-template-columns: 4px 1fr auto;
    gap: var(--sp-3);
    align-items: center;
    padding-right: var(--sp-4);
    border-bottom: 1px solid var(--border);
    transition: background var(--dur) var(--ease);
  }

  .news-row:last-child { border-bottom: 0; }
  .news-row:hover { background: var(--surface-2); }

  .news-row__rail {
    align-self: stretch;
    background: var(--accent);
  }

  .news-row__body { padding-block: var(--sp-3); min-width: 0; }

  .news-row__title {
    display: block;
    font-size: var(--fs-400);
    font-weight: var(--fw-600);
    line-height: 1.3;
  }

  .news-row__meta {
    display: block;
    font-size: var(--fs-200);
    color: var(--ink-muted);
    margin-top: var(--sp-1);
  }

  .news-row__icon { color: var(--ink-muted); flex-shrink: 0; }

  /* ==================================================================
     Pull to refresh. These match the DOM pull-to-refresh.js already builds;
     the rules used to be injected from that script with hardcoded Bootstrap
     blue, which a CSP would have blocked and no token could reach.
     ================================================================== */
  #pull-to-refresh-indicator {
    position: fixed;
    top: -100px;
    left: 0;
    right: 0;
    z-index: var(--z-overlay);
    height: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    pointer-events: none;
    background: linear-gradient(to bottom, var(--surface), transparent);
    transition: transform var(--dur) var(--ease);
  }

  #pull-to-refresh-indicator.pulling,
  #pull-to-refresh-indicator.refreshing { transform: translateY(100px); }

  #pull-to-refresh-indicator .refresh-spinner {
    color: var(--accent);
    transition: transform var(--dur) var(--ease);
  }

  #pull-to-refresh-indicator.ready .refresh-spinner { transform: rotate(180deg); }

  #pull-to-refresh-indicator.refreshing .refresh-spinner {
    animation: ptr-spin 1s linear infinite;
  }

  #pull-to-refresh-indicator .refresh-text {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    color: var(--ink-muted);
  }

  body.ptr-active { overflow: hidden; }

  @keyframes ptr-spin { to { transform: rotate(360deg); } }

  /* ==================================================================
     Game page
     ================================================================== */
  .game-topline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding-block: var(--sp-1) var(--sp-3);
  }

  .game-topline .u-label {
    text-align: right;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ------------------------------------------------------------------
     Score hero. One layout at every width - the old page shipped a
     desktop copy and a mobile copy of this, and they had drifted.
     ------------------------------------------------------------------ */
  .score-hero__body {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-4) var(--sp-3) var(--sp-2);
  }

  .score-hero__team {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
  }

  .score-hero__abbr {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-600);
    letter-spacing: .04em;
  }

  .score-hero__sog {
    font-size: var(--fs-100);
    letter-spacing: var(--tr-1);
    color: var(--ink-muted);
  }

  .score-hero__centre {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    min-width: 8rem;
  }

  .score-hero__score {
    display: flex;
    gap: var(--sp-3);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-hero);
    line-height: 1;
  }

  .score-hero__clock {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-500);
    letter-spacing: .08em;
  }

  .score-hero__heat {
    padding: var(--sp-2) var(--sp-4) var(--sp-3);
    border-top: 1px solid var(--border);
  }

  /* ------------------------------------------------------------------
     Tabs
     ------------------------------------------------------------------ */
  .tablist {
    display: flex;
    gap: var(--sp-1);
    margin-top: var(--sp-4);
    padding: var(--sp-1);
    background: var(--surface-2);
    border-radius: var(--r-card);
  }

  .tab {
    flex: 1;
    padding: var(--sp-2) var(--sp-1);
    border-radius: var(--r-tab);
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-300);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ink-muted);
    white-space: nowrap;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
  }

  .tab[aria-selected='true'],
  .tab[aria-current='page'] {
    background: var(--surface);
    color: var(--ink);
    font-weight: var(--fw-800);
    box-shadow: var(--sh-1);
  }

  /* The Latest/Random switch is the same control built from links. */
  .tablist--links { margin-top: var(--sp-2); }
  .tablist--links .tab { display: block; text-align: center; }

  .tabpanel { padding-top: var(--sp-3); }

  /*
    Without JavaScript there is nothing to switch tabs with, so the control is
    hidden and every panel is shown - the page becomes a long scroll rather
    than three-quarters invisible. Author rules beat the UA's [hidden] rule, so
    this needs no !important.
  */
  html:not(.js) .tablist { display: none; }
  html:not(.js) .tabpanel[hidden] { display: block; }

  .tabpanel__loading {
    padding: var(--sp-8) 0;
    text-align: center;
  }

  /* ------------------------------------------------------------------
     Player identity
     ------------------------------------------------------------------ */
  .mug {
    display: block;
    flex-shrink: 0;
    width: var(--mug-size, 36px);
    height: var(--mug-size, 36px);
    border-radius: 50%;
    background-color: var(--surface-2);
    background-size: cover;
    background-position: center top;
    background-repeat: no-repeat;
  }

  .player-link { font-weight: var(--fw-700); }
  a.player-link:hover { color: var(--accent); }

  /* ------------------------------------------------------------------
     Goals timeline - replaces an 8-column table that could only
     horizontal-scroll on a phone.
     ------------------------------------------------------------------ */
  .goal-timeline__period {
    padding: var(--sp-3) var(--sp-4) var(--sp-1);
  }

  .goal-row {
    display: grid;
    grid-template-columns: 4px 3rem auto 1fr auto;
    align-items: center;
    gap: var(--sp-3);
    /* The right inset matches the period label's --sp-4. */
    padding: var(--sp-4) var(--sp-4) var(--sp-4) 0;
    border-bottom: 1px solid var(--border);
  }

  .goal-row:last-child { border-bottom: 0; }

  /* Reach back into the row's padding so the rail keeps its --sp-2 inset
     from the dividers instead of shrinking to a stub as the row grows. */
  .goal-row > .team-rail { margin-block: calc(var(--sp-2) - var(--sp-4)); }

  .goal-row__time {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-400);
    color: var(--ink-muted);
    text-align: right;
  }

  .goal-row__who {
    display: grid;
    gap: var(--sp-1);
    min-width: 0;
  }

  .goal-row__name {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    min-width: 0;
  }

  .goal-row__name .player-link {
    font-size: var(--fs-400);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .goal-row__type {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-100);
    letter-spacing: .08em;
    color: var(--ink-muted);
    white-space: nowrap;
    flex-shrink: 0;
  }

  .goal-row__assists {
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

  .goal-row__after {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-500);
  }

  /* ------------------------------------------------------------------
     Moments
     ------------------------------------------------------------------ */
  .moment-row {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--border);
  }

  .moment-row:last-child { border-bottom: 0; }

  .moment-row__score .heat__value {
    font-size: var(--fs-800);
    min-width: 2ch;
  }

  .moment-row__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    min-width: 0;
  }

  .moment-row__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
  }

  .moment-row__time {
    font-size: var(--fs-100);
    color: var(--ink-muted);
    white-space: nowrap;
  }

  .moment-row__text { line-height: 1.4; }

  /* ------------------------------------------------------------------
     Hot / cold
     ------------------------------------------------------------------ */
  .hot-cold {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
  }

  .hot-cold-card {
    padding: var(--sp-3);
    border-top: 4px solid var(--team);
  }

  .hot-cold-card__head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding-bottom: var(--sp-3);
  }

  .hot-cold-card__rows {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
  }

  .hot-cold-card__empty {
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

  .streak-row {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
  }

  .streak-row__who { min-width: 0; flex: 1; }

  .streak-row__who .player-link {
    display: block;
    font-size: var(--fs-300);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .streak-row__meta {
    display: block;
    font-size: var(--fs-100);
    color: var(--ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* ------------------------------------------------------------------
     Three stars and goalies
     ------------------------------------------------------------------ */
  .stars__grid,
  .goalies {
    display: grid;
    gap: var(--sp-3);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  }

  .star-card,
  .goalie-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3);
    background: var(--surface);
    border-radius: var(--r-card-lg);
    box-shadow: var(--sh-1);
  }

  .star-card--first { outline: 2px solid var(--heat-mid); outline-offset: -2px; }

  .star-card__rank {
    flex-shrink: 0;
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-600);
    line-height: 1;
    color: var(--ink-dim);
  }

  .star-card--first .star-card__rank { color: var(--heat-mid); }

  .star-card__who,
  .goalie-card__who { min-width: 0; flex: 1; }

  .star-card__who .player-link,
  .goalie-card__who .player-link {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .star-card__meta,
  .goalie-card__meta,
  .goalie-card__empty {
    display: block;
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

  .star-card__stats { display: flex; gap: var(--sp-3); }

  .stat { text-align: center; }

  .stat__value {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-600);
    line-height: 1;
  }

  .stat__label {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-100);
    letter-spacing: var(--tr-1);
    color: var(--ink-muted);
  }

  .goalie-card { border-top: 4px solid var(--team); }
  .goalie-card__team { position: absolute; top: var(--sp-2); right: var(--sp-2); }

  /* ==================================================================
     Goal feed - one card serves /latest-goals and /random-goals, which
     used to be two near-identical 194-line templates.
     ================================================================== */
  .goal-feed,
  .moment-feed {
    display: grid;
    gap: var(--sp-3);
    margin-top: var(--sp-3);
  }

  .goal-feed { grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr)); }
  .moment-feed { grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr)); }

  .goal-card { display: grid; grid-template-columns: 5px 1fr; }

  .goal-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-3);
    min-width: 0;
  }

  .goal-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
  }

  .goal-card__team {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
  }

  .goal-card__team-name {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-500);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    white-space: nowrap;
  }

  .goal-card__when {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-400);
    letter-spacing: var(--tr-1);
    color: var(--ink-muted);
    white-space: nowrap;
  }

  .goal-card__scorer {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
  }

  .goal-card__who { flex: 1; min-width: 0; }

  .goal-card__name {
    display: block;
    font-size: var(--fs-600);
    line-height: 1.2;
  }

  .goal-card__type {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-200);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    color: var(--ink-muted);
  }

  .goal-card__assists {
    display: block;
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

  .goal-card__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    padding-top: var(--sp-2);
    border-top: 1px solid var(--border);
  }

  .goal-card__after {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-600);
    white-space: nowrap;
  }

  .goal-card__game {
    font-size: var(--fs-200);
    color: var(--ink-muted);
    text-decoration: underline;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .goal-card__game:hover { color: var(--accent); }

  /* ==================================================================
     Exciting-moments feed. The score leads: it is what ranks one moment
     against another, and the old build rendered it as a plain badge.
     ================================================================== */
  .moment-card {
    display: block;
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  }

  .moment-card:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }

  .moment-card__top {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4) var(--sp-2);
  }

  .moment-card__score .heat__value {
    font-size: var(--fs-900);
    min-width: 2ch;
  }

  .moment-card__meta {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    min-width: 0;
  }

  .moment-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
  }

  .moment-card__time {
    font-size: var(--fs-100);
    color: var(--ink-muted);
    white-space: nowrap;
  }

  /* The alert line is the point of the card, so it gets room to breathe:
     --sp-3 on top of the --sp-2 that __top ends with, --sp-5 below. */
  .moment-card__text {
    padding: var(--sp-3) var(--sp-4) var(--sp-5);
    line-height: 1.4;
  }

  /* The edge columns used to hold a .team-rail each; the padding replaces
     them so the crests keep their old 16px inset from the card edge. */
  .moment-card__foot {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: var(--sp-3);
    padding-inline: var(--sp-4);
    height: 2.75rem;
    border-top: 1px solid var(--border);
  }

  .moment-card__side {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    min-width: 0;
  }

  .moment-card__side--home { justify-content: flex-end; }

  .moment-card__goals {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-700);
    line-height: 1;
  }

  /* ==================================================================
     Notifications setup
     ================================================================== */
  .notify-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-6) var(--sp-5) var(--sp-5);
    text-align: center;
    background: var(--surface);
    border-radius: var(--r-card-xl);
    border-top: 5px solid var(--accent);
    box-shadow: var(--sh-1);
  }

  .notify-cta__eyebrow {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-300);
    letter-spacing: var(--tr-3);
    text-transform: uppercase;
    color: var(--accent);
  }

  .notify-cta__title {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-800);
    line-height: var(--lh-tight);
    text-transform: uppercase;
  }

  .notify-cta__body {
    max-width: 32ch;
    color: var(--ink-muted);
    line-height: 1.4;
  }

  .notify-cta__actions { width: 100%; }

  .notify-cta__status {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

  /* The dot follows the status text's state, so the script needs no extra hook. */
  .notify-cta__status:has(.is-ok) .dot { background: var(--ok); }
  .notify-cta__status:has(.is-error) .dot { background: var(--accent); }

  .notify-cta__message {
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-badge);
    background: var(--surface-2);
    font-size: var(--fs-200);
  }

  .platform__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    padding-block: var(--sp-6) var(--sp-2);
  }

  .platform__detected {
    font-size: var(--fs-100);
    color: var(--ink-muted);
  }

  .steps { padding: 0 var(--sp-4); margin-bottom: var(--sp-3); }
  .steps:last-child { margin-bottom: 0; }

  .steps__title { padding-top: var(--sp-3); }

  .steps__row {
    display: flex;
    gap: var(--sp-3);
    padding-block: var(--sp-3);
    border-bottom: 1px solid var(--border);
    line-height: 1.4;
  }

  .steps__row:last-child { border-bottom: 0; }

  .steps__marker {
    flex-shrink: 0;
    width: 1.25rem;
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    color: var(--ink-muted);
  }

  .steps__row--warning { font-size: var(--fs-300); }
  .steps__row--warning .steps__marker { color: var(--accent); }

  .accordion { border-bottom: 1px solid var(--border); }

  .accordion__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    font-weight: var(--fw-600);
    cursor: pointer;
    list-style: none;
  }

  .accordion__summary::-webkit-details-marker { display: none; }

  .accordion__chevron {
    color: var(--ink-muted);
    transition: transform var(--dur) var(--ease);
  }

  .accordion[open] .accordion__chevron { transform: rotate(180deg); }

  .accordion__body {
    padding: 0 var(--sp-4) var(--sp-3);
    font-size: var(--fs-300);
    color: var(--ink-muted);
    line-height: 1.5;
  }

  .accordion__body ul { padding-left: var(--sp-4); list-style: disc; }
  .accordion__body li { margin-block: var(--sp-1); }
  .accordion__body p + p, .accordion__body p + ul { margin-top: var(--sp-2); }

  .accordion__link {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4);
    font-size: var(--fs-200);
    color: var(--ink-muted);
  }

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

  /* ==================================================================
     Error pages - replaces re-rendering the home page with a red banner
     ================================================================== */
  .error-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-12) var(--sp-5) var(--sp-16);
    text-align: center;
  }

  .error-page__strip {
    display: block;
    width: 12.5rem;
    height: 6px;
    border-radius: 3px;
    background: linear-gradient(90deg, var(--border-strong) 50%, var(--accent) 50%);
  }

  .error-page__code {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-numeral);
    line-height: .9;
    letter-spacing: var(--tr-tight);
  }

  .error-page__code span { color: var(--accent); }

  .error-page__title {
    font-family: var(--font-display);
    font-weight: var(--fw-800);
    font-size: var(--fs-700);
    letter-spacing: var(--tr-3);
    text-transform: uppercase;
  }

  .error-page__body {
    max-width: 34ch;
    color: var(--ink-muted);
    line-height: 1.45;
  }

  .error-page__alt {
    font-family: var(--font-display);
    font-weight: var(--fw-700);
    font-size: var(--fs-400);
    letter-spacing: var(--tr-2);
    text-transform: uppercase;
    color: var(--accent);
  }

  /* ==================================================================
     Push debug - a tool, not a page. Tokens only.
     ================================================================== */
  .debug { padding: var(--sp-4); }
  .debug__heading { padding-top: var(--sp-4); }
  .debug__group p { padding-block: var(--sp-1); font-size: var(--fs-300); }
  .debug__group b { color: var(--ink-muted); }

  .debug__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding-top: var(--sp-2);
  }

  .debug__actions .btn { font-size: var(--fs-300); padding: var(--sp-2) var(--sp-4); }

  .debug__console {
    margin-top: var(--sp-2);
    max-height: 18rem;
    overflow-y: auto;
    padding: var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r-badge);
    background: var(--bg);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--fs-200);
  }
}

/* ==========================================================================
   Utilities - last layer, so a one-off override never needs !important.
   ========================================================================== */
@layer utilities {
  .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .is-hidden { display: none; }

  /* State classes push-notifications.js sets on the status and message
     elements. They replace Bootstrap's text-muted / text-success / etc. */
  .is-muted { color: var(--ink-muted); }
  .is-ok { color: var(--ok); }
  .is-warn { color: var(--warn); }
  .is-error { color: var(--accent); }
  .truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
