html, body { margin: 0; padding: 0; }
  html { overflow-x: hidden; }
  /* Theme tokens are injected inline on the app root element, so var() does not
     resolve on body/a — those keep the players-platform light literals. */
  body { font-family: 'Inter', sans-serif; font-size: 0.875rem; color: #000000; background: #ffffff; }
  a { color: #114b2a; text-decoration: none; }
  a:hover { color: #0b6b23; }
  h1,h2,h3,h4,h5,h6 { font-family: 'Teko', sans-serif; margin: 0; line-height: 100%; letter-spacing: -0.01em; text-transform: uppercase; }
  :focus-visible { outline: 2px solid #114b2a; outline-offset: 2px; }
  ::selection { background: #d4fd2b; color: #0a2c18; }
  @container hub (max-width: 1360px) {
    header nav { display: none !important; }
  }
  @container hub (max-width: 1440px) {
    header nav { gap: 14px !important; }
    header nav a { font-size: 0.8125rem !important; }
  }
  @container hub (max-width: 1080px) {
    [data-logo="full"] { display: none !important; }
    [data-logo="icon"] { display: block !important; }
    [data-r="home"], [data-r="picks"], [data-r="ligas"] { grid-template-columns: minmax(0, 1fr) !important; }
    [data-r="events"] { position: static !important; max-height: none !important; }
    [data-r="eventscroll"] { max-height: 300px !important; min-width: 0 !important; }
    [data-r="hero"] { grid-template-columns: minmax(0, 1fr) !important; }
    [data-r="playercard"] { max-width: 240px !important; margin: 0 auto !important; }
  }
  @container hub (max-width: 900px) {
    [data-r="rank"], [data-r="members"] { grid-template-columns: 38px 1fr 78px !important; }
    [data-r="ledger"] { grid-template-columns: 58px 1fr 74px !important; }
    [data-r="canjes"] { grid-template-columns: 1fr auto !important; }
    [data-r="answers"], [data-r="answershead"] { grid-template-columns: 1fr 96px 96px 18px !important; font-size: 0.75rem !important; }
    [data-r="perf"] { grid-template-columns: repeat(2, 1fr) !important; }
    [data-sm="hide"] { display: none !important; }
  }
  @container hub (max-width: 720px) {
    /* Compact single-row mobile header: keep only balance/deposit,
       notifications and avatar. Clock, settings and the level/streak
       badge are dropped — their info is repeated in the hero card
       just below the header, so nothing is actually lost. */
    [data-r="hdrclock"], [data-r="hdrgear"], [data-r="hdrlevel"], [data-r="hdrrefresh"] { display: none !important; }
    [data-r="hdrbalancebonus"] { display: none !important; }
    [data-r="toolbar"] { gap: 8px !important; }
    [data-r="hdrbalance"] { padding: 3px 3px 3px 10px !important; }
    [data-r="podium"] { padding: 16px 12px 12px !important; gap: 8px !important; align-items: stretch !important; }
    [data-r="podium"] > div {
      width: auto !important;
      flex: 1 1 0 !important;
      min-width: 0 !important;
      height: auto !important;
      padding: 14px 8px 10px !important;
      border-radius: 14px !important;
      animation: none !important;
    }
    [data-r="podium"] > div > span:nth-child(4) { font-size: 1.5rem !important; }
    [data-r="podium"] > div > span:last-child { display: none !important; }
    [data-r="chips"] {
      flex-wrap: nowrap !important;
      overflow-x: auto !important;
      scrollbar-width: none !important;
      max-width: 100% !important;
      scroll-snap-type: x mandatory !important;
    }
    [data-r="chips"] > button { flex: 0 0 auto !important; scroll-snap-align: start !important; }
    [data-r="progress"] { width: 100% !important; min-width: 0 !important; box-sizing: border-box !important; }
    [data-r="progress"] > div:last-child { flex: 1 !important; min-width: 0 !important; }
    [data-r="hero"] h1 { font-size: clamp(2rem, 11cqw, 3rem) !important; }
    [data-r="hero"] { overflow: hidden !important; }
    /* Hero reflow: the title block leads, then the level card sits beside the
       lead copy. display:contents dissolves the two wrapper divs so their
       children become direct grid items of the hero, without touching desktop. */
    [data-r="herocol"], [data-r="heroblock"] { display: contents !important; }
    [data-r="hero"] {
      grid-template-columns: 158px minmax(0, 1fr) !important;
      grid-template-areas:
        "chip chip"
        "title title"
        "card tiles"
        "progress progress" !important;
      align-items: start !important;
      row-gap: 12px !important;
      column-gap: 12px !important;
    }
    /* The wrappers carried position:relative, which is what kept this copy above
       the hero scrim. display:contents drops that box, so restate it per part. */
    [data-r="herochip"], [data-r="herotitle"], [data-r="herolead"], [data-r="herotiles"] { position: relative !important; }
    [data-r="herochip"] { grid-area: chip !important; }
    [data-r="herotitle"] { grid-area: title !important; }
    [data-r="playercard"] {
      grid-area: card !important;
      max-width: none !important;
      margin: 0 !important;
      min-height: 0 !important;
      align-self: stretch !important;
    }
    /* The lead copy repeats what the tabs already offer; on a phone the space is
       better spent putting the stat tiles beside the level card. */
    [data-r="herolead"] { display: none !important; }
    [data-r="progress"] { grid-area: progress !important; }
    [data-r="herotiles"] {
      grid-area: tiles !important;
      grid-template-columns: minmax(0, 1fr) !important;
      align-content: start !important;
      gap: 8px !important;
    }
    /* The level card is 158px wide here, not 236px: the rank name and its
       subtitle have to come down with it. */
    [data-r="pcname"] > span:first-child { font-size: 1.5rem !important; }
    [data-r="pcname"] > span:last-child { font-size: 0.5rem !important; letter-spacing: 0.06em !important; }
    /* Stat tile labels ship with white-space: nowrap, which is what pushes
       "Puntos canjeables" past the tile edge in a two-column grid. */
    [data-r="herotiles"] [style*="white-space: nowrap"] {
      white-space: normal !important;
      letter-spacing: 0.05em !important;
      line-height: 1.25 !important;
    }
    [data-nav="tabs"] { scroll-snap-type: x mandatory !important; }
    [data-nav="tabs"] > button { scroll-snap-align: center !important; }
    [data-r="eventscroll"] {
      flex-direction: row !important;
      overflow-x: auto !important;
      overflow-y: hidden !important;
      scroll-snap-type: x mandatory !important;
      padding-bottom: 6px !important;
    }
    [data-r="eventscroll"] > button {
      flex: 0 0 76% !important;
      scroll-snap-align: start !important;
    }
    [data-r="events"] { max-height: none !important; }
    [data-r="lineupwarn"] { white-space: normal !important; }
    [data-r="seasoncd"] { flex-wrap: wrap !important; }
    [data-r="seasoncd"] > button { flex: 1 1 100% !important; }
    /* Answers stop being a table below 720px: two 96px columns cannot hold
       "Tu respuesta" / "Resultado real", so each answer becomes a small card. */
    [data-r="answershead"] { display: none !important; }
    [data-r="answers"] {
      grid-template-columns: 1fr auto !important;
      grid-template-areas: "q mark" "lpick ltruth" "pick truth" !important;
      row-gap: 4px !important;
      column-gap: 12px !important;
      align-items: center !important;
      padding: 11px 12px !important;
    }
    [data-r="answers"] > [data-c="q"] { grid-area: q !important; }
    [data-r="answers"] > [data-c="mark"] { grid-area: mark !important; }
    [data-r="answers"] > [data-c="pick"] { grid-area: pick !important; justify-self: start !important; }
    [data-r="answers"] > [data-c="truth"] { grid-area: truth !important; justify-self: end !important; text-align: right !important; }
    [data-r="answers"] > [data-c="lpick"], [data-r="answers"] > [data-c="ltruth"] {
      display: block !important;
      margin-top: 6px;
      font-family: 'Inter', sans-serif;
      font-size: 0.5625rem;
      font-weight: 700;
      letter-spacing: 0.09em;
      text-transform: uppercase;
      color: var(--muted);
    }
    [data-r="answers"] > [data-c="lpick"] { grid-area: lpick !important; }
    [data-r="answers"] > [data-c="ltruth"] { grid-area: ltruth !important; text-align: right !important; }
    /* Search pills carry desktop width caps that leave dead space on a phone.
       flex must stay 0 0 auto: these live in a row container in the store but a
       column one in ranking and duel, and flex-basis follows the main axis — a
       basis of 100% would fight the pill height instead of its width. */
    [data-r="search"] {
      width: 100% !important;
      max-width: none !important;
      min-width: 0 !important;
      flex: 0 0 auto !important;
      box-sizing: border-box !important;
    }
    [data-r="ligatabs"] {
      max-width: 100% !important;
      overflow-x: auto !important;
      scrollbar-width: none !important;
    }
  }
    @keyframes sortiRise { from { transform: translateY(26px) scaleY(0.88); opacity: 0 } to { transform: translateY(0) scaleY(1); opacity: 1 } }
  @keyframes sortiGlow { 0%,100% { box-shadow: 0 0 18px rgba(212,253,43,0.25) } 50% { box-shadow: 0 0 38px rgba(212,253,43,0.6) } }
  @keyframes sortiFloat { 0%,100% { transform: translateY(0) } 50% { transform: translateY(-6px) } }
  @keyframes sortiShine { 0% { transform: translateX(-120%) } 60%,100% { transform: translateX(220%) } }
  @keyframes sortiSpin { to { transform: rotate(360deg) } }
  @keyframes sortiPing { 0% { transform: scale(0.9); opacity: 0.8 } 100% { transform: scale(1.35); opacity: 0 } }
  @keyframes sortiPop { from { transform: scale(0.7); opacity: 0 } to { transform: scale(1); opacity: 1 } }
  main button[style*="cursor: pointer"]:not([style*="border-radius: 50%"]):not([style*="grid-template-columns"]) { box-shadow: inset 0 -2px 0 var(--inset-bottom, rgba(0,0,0,0.3)); }
  main button:active:not([disabled]) { transform: translateY(2px); }
  main button[style*="cursor: pointer"]:hover { filter: var(--hover-filter); }
  main [style*="border: 1px solid var(--line)"] { box-shadow: var(--shadow-3, 0 10px 30px rgba(0,0,0,0.35)); }
  main h2, main h3 { letter-spacing: -0.005em; }
  /* Form controls default to content-box, so padding and border add to a 1fr
     track instead of fitting inside it — that is what pushes the shipping
     inputs past the modal edge. */
  /* Form controls default to content-box, and an <input> carries an intrinsic
     min-width from its size attribute that min-width:auto refuses to shrink
     past. Both make them overflow a narrow flex or grid track. */
  input, select, textarea, button { box-sizing: border-box; }
  input, select, textarea { min-width: 0; max-width: 100%; }

  /* Modal sizing. 100vh on mobile counts the browser chrome, so the panel ends
     up taller than the visible viewport; centred flex overflow then hides the
     top with no way to scroll to it. dvh measures what is actually on screen,
     and flex-start + margin:auto keeps it centred when it fits and reachable
     when it does not. */
  [style*="var(--modal-veil)"] { align-items: flex-start !important; }
  [style*="var(--modal-bg)"] {
    margin: auto !important;
    max-height: calc(100dvh - 24px) !important;
  }

  main input, main select, main textarea { color: var(--text) !important; border-color: var(--line-2) !important; }
  /* Search fields declare their own transparent background because a styled
     pill wrapper provides the surface. Forcing a fill on those paints a grey
     block behind the placeholder, so only fill inputs that ask for one. */
  main input:not([style*="background: transparent"]),
  main select:not([style*="background: transparent"]),
  main textarea:not([style*="background: transparent"]) { background: var(--surface-2) !important; }
  main input::placeholder, main textarea::placeholder { color: var(--muted); }
  /* Podium backdrop layers. Both are <span> on purpose: the mobile container
     query below restyles `[data-r="podium"] > div`, and a <div> here would be
     caught by it. */
  [data-r="podiumscrim"], [data-r="podiumfx"] {
    position: absolute;
    inset: 0;
    display: block;
    pointer-events: none;
  }
  [data-r="podiumscrim"] { background: var(--podium-scrim); }
  /* Two mote sizes drifting upward at different rates for parallax depth.
     Each layer is an oversized tiled pseudo-element moved with transform
     (compositor-only) rather than background-position, which would repaint
     every frame. Travelling exactly one tile height keeps the loop seamless. */
  [data-r="podiumfx"] { overflow: hidden; }
  [data-r="podiumfx"]::before, [data-r="podiumfx"]::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 300%;
    will-change: transform;
  }
  [data-r="podiumfx"]::before {
    background-image:
      radial-gradient(circle at 15% 30%, rgba(212,253,43,0.50) 0 1.6px, transparent 2px),
      radial-gradient(circle at 62% 12%, rgba(255,255,255,0.30) 0 1.2px, transparent 1.6px),
      radial-gradient(circle at 82% 66%, rgba(212,253,43,0.35) 0 1.8px, transparent 2.2px),
      radial-gradient(circle at 34% 78%, rgba(255,255,255,0.22) 0 1px, transparent 1.4px);
    background-size: 240px 240px;
    animation: sortiMotesNear 24s linear infinite;
  }
  [data-r="podiumfx"]::after {
    background-image:
      radial-gradient(circle at 45% 20%, rgba(255,255,255,0.18) 0 1px, transparent 1.3px),
      radial-gradient(circle at 8% 62%, rgba(212,253,43,0.22) 0 1px, transparent 1.3px),
      radial-gradient(circle at 74% 44%, rgba(255,255,255,0.14) 0 0.8px, transparent 1.1px);
    background-size: 380px 380px;
    animation: sortiMotesFar 40s linear infinite;
  }
  @keyframes sortiMotesNear { from { transform: translateY(0) } to { transform: translateY(-240px) } }
  @keyframes sortiMotesFar { from { transform: translateY(0) } to { transform: translateY(-380px) } }
  /* Soft ripple for the current level card. The inset bevel is repeated in both
     stops because an animated box-shadow replaces the property outright, and
     transform is unavailable here — the cards already carry a translateY. */
  @keyframes sortiPulseCard {
    from { box-shadow: inset 0 -4px 0 rgba(0,0,0,0.3), 0 0 0 0 rgba(17,75,42,0.35) }
    to { box-shadow: inset 0 -4px 0 rgba(0,0,0,0.3), 0 0 0 14px rgba(17,75,42,0) }
  }
  @keyframes sortiShimmer { 0% { transform: translateX(-140%) } 55%,100% { transform: translateX(260%) } }
  @keyframes sortiSparkle { 0%,100% { opacity: 0.35; transform: scale(0.85) } 50% { opacity: 1; transform: scale(1.15) } }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  }
