/* styles.css — radial World Cup 2026 bracket.
   Dark frame -> cream card -> circular flags around a centered trophy. */

:root {
  --frame-bg: #0e0e0e;
  --frame-bg2: #161616;
  --card-bg: #f4f0e9;
  --card-bg2: #efe9df;
  --ink: #1b1b1b;
  --ink-soft: #4a463f;
  --line: #2b2b2b;
  --line-soft: rgba(43, 43, 43, 0.32);
  --ring: #ffffff;
  --gold: #caa23c;
  --win: #1f7a4d;
  --win-ring: #2fae6e;
  --pill-bg: #1c1c1c;
  --pill-ink: #ece7dd;
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);

  --flag-r32: 42px;
  --flag-inner: 36px;

  --font-sans: "Space Grotesk", "Helvetica Neue", Arial, system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-sans);
  /* soft top light + faint warm floor → premium depth, still cream */
  background:
    radial-gradient(120% 72% at 50% -8%, #fcf9f3 0%, rgba(252, 249, 243, 0) 56%),
    radial-gradient(100% 60% at 50% 116%, rgba(31, 122, 77, 0.05) 0%, rgba(31, 122, 77, 0) 60%),
    var(--card-bg);
  background-attachment: fixed;
  color: var(--ink);
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: clamp(12px, 3vw, 40px);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- dark frame --- */
.frame {
  width: 100%;
  max-width: 1200px;
  background: none;
  padding: 0;
}

/* --- cream card --- */
.card {
  background: none;
  padding: clamp(8px, 2vw, 24px);
}

/* --- brand header (original mark + wordmark + host nations) --- */
.site-header {
  text-align: center;
  margin-bottom: clamp(4px, 1.4vw, 14px);
}
.brand-title {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: clamp(1.4rem, 4.6vw, 2.5rem);
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
}
.brand-title b {
  font-weight: 800;
  color: var(--gold);
}

/* --- bracket: square radial canvas --- */
.bracket-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
}

.bracket {
  position: relative;
  width: 100%;
  max-width: 1000px;
  aspect-ratio: 1 / 1; /* keep the radial layout perfectly square */
  /* Establish a query container so flag chips can size themselves as a
     fraction of the (square) bracket width and stay proportional on every
     viewport, exactly like the SVG connectors that scale with the viewBox. */
  container-type: inline-size;
  --flag-r32: clamp(18px, 5.3cqw, 49px);
  --flag-inner: clamp(15px, 4.4cqw, 41px);
}

/* warm focal glow behind the centre (premium depth, like the reference) */
.bracket::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 56cqw;
  height: 56cqw;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    circle,
    rgba(214, 170, 84, 0.34) 0%,
    rgba(214, 170, 84, 0.14) 34%,
    rgba(214, 170, 84, 0) 66%
  );
  pointer-events: none;
  z-index: 0;
}

.bracket-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

/* connectors — thin & delicate (like the reference) */
.connector {
  fill: none;
  stroke: rgba(43, 43, 43, 0.22);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transition:
    stroke 0.4s ease,
    opacity 0.2s ease;
}

/* the winner's route inward — CALM at rest (thin, semi-transparent) so the board
   doesn't turn into a green web at deep stages. Hover lights one route up. */
.connectors--paths .connector--active {
  stroke: #16a34a;
  stroke-width: 2.2;
  opacity: 0.58;
  transition:
    opacity 0.2s ease,
    stroke-width 0.2s ease;
}

/* focus + context: hovering a flag spotlights that team's whole route, dims rest */
.bracket.is-focus .connector {
  opacity: 0.32;
}
.bracket.is-focus .connectors--paths .connector--active {
  opacity: 0.07;
}
.bracket.is-focus .connectors--paths .connector--active.is-on {
  opacity: 1;
  stroke-width: 3.6;
}

/* node dots — small & subtle */
.node-dot {
  fill: rgba(43, 43, 43, 0.22);
  transition:
    fill 0.4s ease,
    r 0.4s ease;
}

/* --- HTML flag chip layer --- */
.chip-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.flag-chip {
  position: absolute;
  transform: translate(-50%, -50%);
  width: var(--flag-r32);
  height: var(--flag-r32);
  border-radius: 50%;
  pointer-events: auto;
  background: #ddd;
  box-shadow:
    0 0 0 2px var(--ring),
    0 3px 7px rgba(0, 0, 0, 0.28);
  overflow: visible;
  transition:
    transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
    box-shadow 0.3s ease,
    filter 0.3s ease,
    opacity 0.3s ease;
  display: grid;
  place-items: center;
  cursor: default;
}

/* focus mode: spotlight the hovered team's flags, recede the rest */
.bracket.is-focus .flag-chip:not(.is-on):not(.is-opp) {
  opacity: 0.2;
}
.bracket.is-focus .flag-chip.is-on {
  opacity: 1;
  z-index: 6;
}
/* the OPPONENT in the hovered match: kept visible with a distinct amber ring */
.bracket.is-focus .flag-chip.is-opp {
  opacity: 1;
  z-index: 6;
  box-shadow:
    0 0 0 2px #e0992f,
    0 0 0 5px rgba(224, 153, 47, 0.28),
    0 3px 9px rgba(0, 0, 0, 0.3);
}
.bracket.is-focus .flag-chip:not(.is-on):not(.is-opp) .flag-date,
.bracket.is-focus .flag-chip:not(.is-on):not(.is-opp) .flag-name {
  opacity: 0;
}
/* next opponent NOT yet decided: spotlight the empty node (the match that will
   decide it) as a dashed amber ring — "your rival comes from here". */
.bracket.is-focus .node-dot.is-oppnode {
  fill: rgba(224, 153, 47, 0.16);
  stroke: #e0992f;
  stroke-width: 2.5;
  stroke-dasharray: 4 3;
}

.flag-chip .flag-img,
.flag-chip .flag-initials {
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.flag-img {
  object-fit: cover;
  display: block;
}

.flag-initials {
  display: grid;
  place-items: center;
  background: #34302a;
  color: #f4f0e9;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.flag-chip--inner {
  width: var(--flag-inner);
  height: var(--flag-inner);
}

/* winner / loser states */
.flag-chip--winner {
  box-shadow:
    0 0 0 2px var(--win-ring),
    0 0 0 4px rgba(47, 174, 110, 0.25),
    0 3px 9px rgba(0, 0, 0, 0.3);
}

.flag-chip--loser {
  filter: grayscale(0.85) brightness(0.92);
  opacity: 0.55;
}

/* eliminated team: muted + desaturated so it reads as "out" at a glance, but
   still legible (it now sits at the ring it was knocked out on, not hidden on a
   pile). Fade only the FLAG so the score badge stays crisp. */
.flag-chip--out .flag-img {
  filter: grayscale(1) brightness(0.86);
  opacity: 0.38;
}

/* advance echo: the low-opacity "past" copy of a winner at its origin slot. It
   carries the match RESULT (score badge). Fade only the flag; keep the green
   ring and the score crisp. */
.flag-chip--echo {
  box-shadow:
    0 0 0 2px rgba(22, 163, 74, 0.85),
    0 2px 6px rgba(0, 0, 0, 0.18);
}
.flag-chip--echo .flag-img {
  opacity: 0.5;
}


/* live match: red "on air" ring + blinking flag */
.flag-chip--live {
  box-shadow:
    0 0 0 2px #c0392b,
    0 0 0 5px rgba(192, 57, 43, 0.25),
    0 3px 9px rgba(0, 0, 0, 0.3);
  animation: flag-blink 1s ease-in-out infinite;
}

/* champion: gold ring + glow, above the trophy */
.flag-chip--champion {
  box-shadow:
    0 0 0 2px var(--gold),
    0 0 0 6px rgba(202, 162, 60, 0.3),
    0 4px 14px rgba(0, 0, 0, 0.35);
}

.flag-chip:hover {
  transform: translate(-50%, -50%) scale(1.12);
  z-index: 5;
  box-shadow:
    0 0 0 2px var(--ring),
    0 6px 14px rgba(0, 0, 0, 0.35);
}

/* score badge */
.score-badge {
  position: absolute;
  bottom: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 8px;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  z-index: 4;
}
/* match decided on penalties: badge grows to "1 (4)" — keep it tight + legible */
.score-badge--pen {
  font-size: 0.54rem;
  letter-spacing: -0.01em;
  padding: 0 4px;
}

/* country name pill under each flag */
.flag-name {
  position: absolute;
  top: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  color: var(--pill-ink);
  background: var(--pill-bg);
  padding: 2.5px 6px;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
  pointer-events: none;
  z-index: 3;
}
/* the translucent "origin" copy doesn't repeat the name — the bright current
   copy (and losers / not-yet-played) carry it instead */
.flag-chip--echo .flag-name {
  display: none;
}
/* eliminated teams: dim their name pill along with the flag */
.flag-chip--out .flag-name {
  opacity: 0.5;
}

/* match-date pill above a flag (on the bright current copies) */
.flag-date {
  position: absolute;
  bottom: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  background: var(--win);
  padding: 2.5px 6px;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  z-index: 3;
}

.flag-chip--winner .score-badge {
  background: var(--win);
}

/* upcoming-match pill on the advanced copy ("→ 4 JUL"). Reuses .flag-date (green)
   but turns red + blinks when that next match is being played right now. */
.flag-next--live {
  background: #c0392b;
  animation: flag-blink 1s ease-in-out infinite;
}

/* --- centered trophy --- */
.trophy-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  pointer-events: none;
  z-index: 3;
}

/* Original gold "26" centre mark (replaces the trophy; NOT FIFA's emblem) */
.center-26 {
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: clamp(58px, 21cqw, 190px);
  line-height: 0.86;
  letter-spacing: -0.07em;
  background: linear-gradient(176deg, #fbeaa6 0%, #e7c560 34%, #cc9e34 68%, #9c7a25 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter: drop-shadow(0 5px 18px rgba(176, 134, 46, 0.4));
  user-select: none;
}

.champion-label {
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  max-width: 120px;
  text-align: center;
  line-height: 1.1;
}

.has-champion .trophy {
  filter: drop-shadow(0 0 10px rgba(202, 162, 60, 0.6))
    drop-shadow(0 6px 12px rgba(0, 0, 0, 0.3));
}

/* --- footer + status pill --- */
.card-footer {
  margin-top: clamp(10px, 2.4vw, 22px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--pill-bg);
  color: var(--pill-ink);
  padding: 7px 10px 7px 12px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 500;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--win-ring);
  box-shadow: 0 0 0 3px rgba(47, 174, 110, 0.22);
  animation: pulse 2.4s ease-in-out infinite;
}

.status-sep {
  opacity: 0.4;
}

.status-source {
  opacity: 0.8;
}

.refresh-btn {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.1);
  color: var(--pill-ink);
  cursor: pointer;
  transition: background 0.2s ease;
}

.refresh-btn:hover {
  background: rgba(255, 255, 255, 0.2);
}

.refresh-btn.is-loading svg {
  animation: spin 0.9s linear infinite;
}

.footer-note {
  margin: 0;
  font-size: 0.7rem;
  color: var(--ink-soft);
  opacity: 0.75;
}

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

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.45;
  }
}

/* ==========================================================================
   MICRO-INTERACTIONS / POLISH
   All non-essential motion is gated behind (prefers-reduced-motion: no-preference)
   and uses transform/opacity/filter only (GPU-friendly, no layout thrash).
   ========================================================================== */

/* --- styled tooltip (team + score) on hover/focus --- */
.flag-chip {
  cursor: pointer;
}

.flag-chip::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  white-space: nowrap;
  background: var(--ink);
  color: #f4f0e9;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 5px 9px;
  border-radius: 7px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.38);
  opacity: 0;
  pointer-events: none;
  z-index: 20;
  transition:
    opacity 0.16s ease,
    transform 0.16s ease;
}

/* little pointer triangle under the bubble */
.flag-chip::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 3px);
  width: 8px;
  height: 8px;
  background: var(--ink);
  transform: translateX(-50%) rotate(45deg) translateY(4px);
  opacity: 0;
  pointer-events: none;
  z-index: 20;
  transition:
    opacity 0.16s ease,
    transform 0.16s ease;
}

.flag-chip:hover::after,
.flag-chip:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.flag-chip:hover::before,
.flag-chip:focus-visible::before {
  opacity: 1;
  transform: translateX(-50%) rotate(45deg) translateY(0);
}

@media (prefers-reduced-motion: no-preference) {
  /* --- 1. ENTRANCE (first paint only): chips fade + scale in, staggered.
     Scoped to .bracket--intro, which the renderer only sets on the FIRST paint,
     so chips do NOT re-animate on every data refresh (that looked buggy). --- */
  .bracket--intro .flag-chip {
    animation: chip-in 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
    animation-delay: calc(var(--chip-i, 0) * 22ms);
  }

  @keyframes chip-in {
    from {
      opacity: 0;
      transform: translate(-50%, -50%) scale(0.4);
    }
    to {
      opacity: 1;
      transform: translate(-50%, -50%) scale(1);
    }
  }

  /* loser chips settle to their dimmed end-state via the entrance keyframes */
  .bracket--intro .flag-chip--loser {
    animation-name: chip-in-loser;
  }

  @keyframes chip-in-loser {
    from {
      opacity: 0;
      transform: translate(-50%, -50%) scale(0.4);
      filter: grayscale(0) brightness(1);
    }
    to {
      opacity: 0.55;
      transform: translate(-50%, -50%) scale(1);
      filter: grayscale(0.85) brightness(0.92);
    }
  }

  /* connectors draw in from the outer ring inward (first paint only) */
  .bracket--intro .connector {
    stroke-dasharray: 600;
    stroke-dashoffset: 600;
    animation: draw-in 1.1s ease forwards 0.25s;
  }

  @keyframes draw-in {
    to {
      stroke-dashoffset: 0;
    }
  }

  /* inner placeholder dots gently appear (first paint only) */
  .bracket--intro .node-dot {
    animation: dot-in 0.5s ease both 0.4s;
  }

  @keyframes dot-in {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  /* Winner ring is now STATIC (defined on .flag-chip--winner above) — no
     infinite pulse, and the green advance path keeps its solid colour. Those
     looping/forwards animations re-fired on every refresh and read as buggy. */

  /* --- 4. REFRESH FEEDBACK: ripple flash on changed matches --- */
  .flag-chip--flash {
    animation: chip-flash 0.9s ease;
  }

  @keyframes chip-flash {
    0% {
      box-shadow:
        0 0 0 2px var(--win-ring),
        0 0 0 3px rgba(47, 174, 110, 0.55),
        0 3px 9px rgba(0, 0, 0, 0.3);
    }
    60% {
      box-shadow:
        0 0 0 2px var(--win-ring),
        0 0 0 14px rgba(47, 174, 110, 0),
        0 3px 9px rgba(0, 0, 0, 0.3);
    }
    100% {
      box-shadow:
        0 0 0 2px var(--ring),
        0 3px 7px rgba(0, 0, 0, 0.28);
    }
  }

  /* status pill soft bump when fresh data lands */
  .status-pill--bump {
    animation: pill-bump 0.5s ease;
  }

  @keyframes pill-bump {
    0% {
      transform: scale(1);
    }
    35% {
      transform: scale(1.05);
    }
    100% {
      transform: scale(1);
    }
  }

  /* faster, brighter dot while a fetch is in flight */
  .status-pill.is-fetching .status-dot {
    animation: pulse 0.7s ease-in-out infinite;
    background: var(--gold);
    box-shadow: 0 0 0 3px rgba(202, 162, 60, 0.28);
  }

  /* --- 5. CHAMPION: gentle glow + sparkle near the trophy --- */
  .has-champion .trophy {
    animation: trophy-breathe 3s ease-in-out infinite;
  }

  @keyframes trophy-breathe {
    0%,
    100% {
      filter: drop-shadow(0 0 8px rgba(202, 162, 60, 0.55))
        drop-shadow(0 6px 12px rgba(0, 0, 0, 0.3));
    }
    50% {
      filter: drop-shadow(0 0 18px rgba(233, 196, 106, 0.85))
        drop-shadow(0 6px 12px rgba(0, 0, 0, 0.3));
    }
  }

  /* one-shot celebratory sparkle burst when a champion is first crowned */
  .trophy-center {
    --spark: rgba(233, 196, 106, 0.9);
  }

  .bracket.celebrate .trophy-center::before,
  .bracket.celebrate .trophy-center::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 38%;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--spark), rgba(233, 196, 106, 0));
    pointer-events: none;
    transform: translate(-50%, -50%);
    animation: sparkle-burst 1.1s ease-out forwards;
  }

  .bracket.celebrate .trophy-center::after {
    animation-delay: 0.25s;
    animation-duration: 1.3s;
  }

  @keyframes sparkle-burst {
    0% {
      opacity: 0;
      transform: translate(-50%, -50%) scale(0.3);
    }
    30% {
      opacity: 1;
    }
    100% {
      opacity: 0;
      transform: translate(-50%, -50%) scale(7);
    }
  }
}

/* --- responsive: shrink flags on small screens --- */
@media (max-width: 640px) {
  :root {
    --flag-r32: 31px;
    --flag-inner: 27px;
  }
  /* The country-name pills overlap badly at this size, so hide them — the flags
     carry the identity, the tooltip still shows the name on tap, and the
     scoreboard below lists every team in full. */
  .flag-name {
    display: none;
  }
  /* keep date + score pills but tighter so they don't collide with neighbours */
  .flag-date {
    font-size: 7px;
    padding: 2px 4.5px;
  }
  .score-badge {
    min-width: 13px;
    height: 13px;
    font-size: 0.54rem;
    line-height: 13px;
  }
  .score-badge--pen {
    font-size: 0.48rem;
  }
}

@media (max-width: 420px) {
  :root {
    --flag-r32: 25px;
    --flag-inner: 21px;
  }
  .flag-date {
    font-size: 6.5px;
    padding: 1.5px 4px;
  }
}

/* --- reduced motion --- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* =========================================================================
   Scoreboard — full World Cup fixture panel
   ========================================================================= */
.scoreboard {
  width: 100%;
  max-width: 1100px;
  margin: clamp(18px, 4vw, 40px) auto 0;
  padding-top: clamp(14px, 3vw, 24px);
  border-top: 1px solid rgba(43, 43, 43, 0.14);
}

.sb-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.sb-title {
  margin: 0;
  font-size: clamp(1.05rem, 3vw, 1.4rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.sb-total {
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.sb-section {
  margin-bottom: 20px;
}
.sb-section__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}
.sb-count {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--ink-soft);
  background: rgba(43, 43, 43, 0.08);
  border-radius: 999px;
  padding: 1px 8px;
}
.sb-section--live .sb-section__title {
  color: #c0392b;
}

.sb-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  gap: 10px;
}

.mrow {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(43, 43, 43, 0.1);
  border-radius: 12px;
  padding: 9px 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.mrow--live,
.mrow.is-live {
  border-color: rgba(192, 57, 43, 0.5);
  background: rgba(192, 57, 43, 0.05);
}

.mrow__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.mrow__times {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.mrow__when {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  white-space: nowrap;
  text-transform: uppercase;
}
/* live "starts in Xh Ym" countdown on upcoming matches */
.mcountdown {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--win);
  background: rgba(31, 122, 77, 0.1);
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
}
.mcountdown:empty {
  display: none;
}

/* fixed 3-column grid: home (truncates) | score | away (truncates) */
.mrow__match {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 8px;
}
.mteam {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: 0.85rem;
  font-weight: 500;
}
.mteam--home {
  justify-content: flex-end;
}
.mteam--away {
  justify-content: flex-start;
}
.mteam__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mteam__name--tbd {
  color: var(--ink-soft);
  font-style: italic;
  opacity: 0.7;
}
.mteam__flag {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
  flex: 0 0 auto;
}
.is-live .mteam__flag {
  animation: flag-blink 1s ease-in-out infinite;
}

.mscore {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.05;
  font-family: var(--font-mono);
  color: var(--ink);
}
.mscore__n {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  font-weight: 700;
  font-size: 0.98rem;
}
.msep {
  color: var(--ink-soft);
  font-weight: 600;
}
.mht {
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  margin-top: 1px;
}
/* penalty shootout result under the score (e.g. "penales 3-4") */
.mpen {
  font-size: 0.52rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--accent, #16a34a);
  margin-top: 1px;
  white-space: nowrap;
}

.mrow__meta {
  font-size: 0.68rem;
  color: var(--ink-soft);
}
.mrow__scorers {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 8px;
  align-items: start;
  font-size: 0.66rem;
  line-height: 1.35;
  color: var(--ink-soft);
}
.mrow__scorers > span:first-child {
  text-align: right;
}
.mrow__scorers .ball {
  font-size: 0.6rem;
  opacity: 0.65;
  padding-top: 1px;
}

@keyframes flag-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* status chips */
.chip {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: rgba(43, 43, 43, 0.07);
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}
.chip--ft {
  color: var(--win);
  background: rgba(31, 122, 77, 0.1);
}
.chip--today {
  color: #b07908;
  background: rgba(202, 162, 60, 0.14);
}
.chip--live {
  color: #fff;
  background: #c0392b;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.chip__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  animation: live-blink 1.1s ease-in-out infinite;
}
@keyframes live-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

.sb-empty {
  color: var(--ink-soft);
  font-size: 0.85rem;
  text-align: center;
  padding: 12px;
}

@media (max-width: 520px) {
  .sb-list {
    grid-template-columns: 1fr;
  }
}

/* =========================================================================
   Classic left→right bracket — MOBILE only (radial is hidden ≤640px).
   Rounds are columns; scroll sideways toward the champion.
   ========================================================================= */
/* Segmented Radial / Lista view switch (works on every viewport). */
.view-toggle {
  display: flex;
  width: fit-content;
  margin: 0 auto 12px;
  gap: 2px;
  padding: 3px;
  background: rgba(43, 43, 43, 0.06);
  border-radius: 999px;
}
.view-toggle__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 6px 15px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  border-radius: 999px;
  cursor: pointer;
  transition:
    background 0.16s ease,
    color 0.16s ease;
}
.view-toggle__btn svg {
  opacity: 0.75;
}
.view-toggle__btn:hover {
  color: var(--ink);
}
[data-view="radial"] .view-toggle__btn[data-view-btn="radial"],
[data-view="list"] .view-toggle__btn[data-view-btn="list"] {
  background: var(--ink);
  color: #fff;
}
[data-view="radial"] .view-toggle__btn[data-view-btn="radial"] svg,
[data-view="list"] .view-toggle__btn[data-view-btn="list"] svg {
  opacity: 1;
}

/* Show exactly one bracket based on <html data-view> (default set inline in
   <head>: list on phones, radial on wider screens; user toggle persists it). */
[data-view="radial"] .classic-wrap {
  display: none;
}
[data-view="list"] .bracket-wrap {
  display: none;
}

.classic-wrap {
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  padding-bottom: 6px;
}

/* Classic L→R bracket — rounds as columns; centred when it fits, scrolls when
   it overflows (phones). `@media all` = always applies (styled at every width so
   the toggle works on desktop too, not just ≤640px). */
@media all {
  .classic-bracket {
    --cb-gap: 13px;
    --cb-h: 620px; /* only 8 Octavos matches now, so a shorter column fits */
    --cb-line: rgba(43, 43, 43, 0.28);
    display: flex;
    gap: var(--cb-gap);
    align-items: flex-start;
    width: max-content;
    margin: 0 auto;
    padding: 2px 6px 6px;
  }
  .cb-round {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    width: 134px;
  }
  .cb-round--champ {
    width: 108px;
  }
  .cb-round__title {
    font-family: var(--font-mono);
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-soft);
    text-align: center;
    height: 22px;
    line-height: 22px;
    margin-bottom: 6px;
  }
  .cb-round__body {
    display: flex;
    flex-direction: column;
    height: var(--cb-h);
  }
  .cb-match {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    position: relative;
  }
  .cb-card {
    width: 100%;
    background: #fff;
    border: 1px solid rgba(43, 43, 43, 0.12);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    position: relative;
    z-index: 1;
  }
  /* live match: red pulsing ring + "EN VIVO" tab (parity with the radial). */
  .cb-card--live {
    overflow: visible; /* let the badge sit above the card */
    border-color: #c0392b;
    z-index: 2;
    animation: cb-live-pulse 1.15s ease-in-out infinite;
  }
  .cb-live-badge {
    position: absolute;
    top: -7px;
    right: 5px;
    z-index: 3;
    background: #c0392b;
    color: #fff;
    font-family: var(--font-mono);
    font-size: 0.44rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1;
    padding: 2px 5px;
    border-radius: 999px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  }
  @keyframes cb-live-pulse {
    0%,
    100% {
      box-shadow:
        0 0 0 1.5px #c0392b,
        0 0 0 3px rgba(192, 57, 43, 0),
        0 1px 3px rgba(0, 0, 0, 0.06);
    }
    50% {
      box-shadow:
        0 0 0 1.5px #c0392b,
        0 0 0 5px rgba(192, 57, 43, 0.22),
        0 1px 3px rgba(0, 0, 0, 0.06);
    }
  }
  .cb-team {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px;
    height: 23px;
  }
  .cb-team + .cb-team {
    border-top: 1px solid rgba(43, 43, 43, 0.1);
  }
  .cb-flag {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    overflow: hidden;
    flex: 0 0 auto;
    background: #ddd;
  }
  .cb-flag img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .cb-name {
    flex: 1;
    min-width: 0;
    font-size: 0.66rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--ink);
  }
  .cb-name--tbd {
    color: var(--ink-soft);
    font-style: italic;
    font-weight: 500;
  }
  .cb-score {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--ink-soft);
    flex: 0 0 auto;
  }
  .cb-team--win .cb-name,
  .cb-team--win .cb-score {
    color: var(--win);
  }
  .cb-team--lose {
    opacity: 0.5;
  }
  .cb-team--lose .cb-flag img {
    filter: grayscale(0.85);
  }

  /* connectors: horizontal stub out of each card + a vertical joining each pair
     (the next round's card sits at that vertical's midpoint). */
  .cb-round:not(.cb-round--champ) .cb-match::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 100%;
    width: var(--cb-gap);
    height: 2px;
    background: var(--cb-line);
    transform: translateY(-50%);
    z-index: 0;
  }
  .cb-round:not(.cb-round--F):not(.cb-round--champ) .cb-match:nth-child(odd)::before {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(100% + var(--cb-gap));
    width: 2px;
    height: 100%;
    background: var(--cb-line);
    z-index: 0;
  }

  /* champion box */
  .cb-round--champ .cb-round__body {
    justify-content: center;
  }
  .cb-champ {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 10px 8px;
    border: 1.5px solid var(--gold);
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 2px 8px rgba(202, 162, 60, 0.2);
  }
  .cb-champ img {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 0 0 2px var(--gold);
  }
  .cb-champ__name {
    font-size: 0.62rem;
    font-weight: 800;
    text-align: center;
    color: var(--ink);
  }
  .cb-champ__pending {
    font-size: 1.7rem;
    opacity: 0.35;
  }
}

/* Phones: tighter classic bracket so the Lista view needs far less scrolling. */
@media (max-width: 640px) {
  .classic-bracket {
    --cb-gap: 11px;
    --cb-h: 486px;
  }
  .cb-round {
    width: 120px;
  }
  .cb-round--champ {
    width: 96px;
  }
  .cb-team {
    height: 20px;
    padding: 2px 5px;
    gap: 5px;
  }
  .cb-flag {
    width: 14px;
    height: 14px;
  }
  .cb-name {
    font-size: 0.62rem;
  }
  .cb-round__title {
    font-size: 0.54rem;
    height: 18px;
    line-height: 18px;
    margin-bottom: 4px;
  }
}

/* Respect users who ask for less motion (accessibility). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
