/* ═══════════════════════════════════════════════════════════════════════════
   home-v2.css — Season 2 home redesign ("news rail + season banner").

   Every class here is `hv-` prefixed. main.css is one flat 4k-line global
   namespace and short modifier names collide silently (a `.tg.am` tag pill
   once inherited `flex:1` from the rail's `.am` and stretched to 464px) — the
   prefix is the cheap insurance against repeating that.

   Loaded AFTER main.css, so the few deliberate overrides at the bottom win.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Everything chromatic below derives from --accent, which applyCosmetics()
     overwrites live when the user picks an unlocked season accent. Nothing here
     may hardcode purple, or the whole cosmetics system silently stops applying
     to the home page. color-mix is already used ~37× in main.css, so it's safe. */
  --hv-a-hi:  color-mix(in srgb, var(--accent) 78%, #fff);
  --hv-a-lo:  color-mix(in srgb, var(--accent) 78%, #000);
  --hv-a-90:  color-mix(in srgb, var(--accent) 90%, transparent);
  --hv-a-85:  color-mix(in srgb, var(--accent) 85%, transparent);
  --hv-a-75:  color-mix(in srgb, var(--accent) 75%, transparent);
  --hv-a-70:  color-mix(in srgb, var(--accent) 70%, transparent);
  --hv-a-55:  color-mix(in srgb, var(--accent) 55%, transparent);
  --hv-a-42:  color-mix(in srgb, var(--accent) 42%, transparent);
  --hv-a-32:  color-mix(in srgb, var(--accent) 32%, transparent);
  --hv-a-28:  color-mix(in srgb, var(--accent) 28%, transparent);
  --hv-a-26:  color-mix(in srgb, var(--accent) 26%, transparent);
  --hv-a-16:  color-mix(in srgb, var(--accent) 16%, transparent);
  --hv-a-04:  color-mix(in srgb, var(--accent) 4%,  transparent);

  --hv-amber: #f5b518;
  --hv-amber-2: #ffd679;
  --hv-amber-dim: rgba(245, 181, 24, 0.10);
  --hv-panel: #14141d;
  --hv-panel-2: #191922;
}

/* ─── page scaffolding ─── */
/* NOTE: do NOT add `.hv-home { display: block }` here. main.css has
   `.page { display:none }` / `.page.active { display:block }` at the same (0,1,0)
   specificity, and this file loads later — so a bare `.hv-home` display rule wins
   over `.page` and pins the home page visible on every route. That shipped once;
   every page rendered home above its own content. Page visibility belongs to
   `.page.active` alone. */
/* The sections live inside .page-inner, so this must reach a level deeper —
   `.hv-home > * + *` matched nothing, which is why everything sat flush. */
.hv-home > .page-inner > * + * { margin-top: 44px; }
/* The banner is a continuation of the rail above it, so it stays tucked closer. */
.hv-home > .page-inner > .hv-sban { margin-top: 18px; }
/* #recap-card sits above the rail as a display:none first child, so `* + *` was
   still giving the rail a 44px top margin on top of .page-inner's own padding. */
.hv-home > .page-inner > .hv-news { margin-top: 0; }
.hv-sh { scroll-margin-top: 80px; }

/* ═══ NEWS RAIL ═══ */
.hv-news {
  position: relative;
  min-height: 372px;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  isolation: isolate;
}
.hv-news-bg {
  position: absolute; inset: 0; z-index: -2;
  /* Two layers: the art, then the slide's gradient underneath as the fallback
     (see hvShow). `cover` and the position apply to the art layer; the gradient
     is sized to the box either way. */
  background-size: cover;
  background-repeat: no-repeat;
  /* Set per slide by hvShow(). Comic covers anchor `top` because the logo and
     title live in the top third of a cover; a landscape backdrop centres. */
  background-position: var(--hv-bg-pos, center 22%);
  transition: opacity .28s ease;
  transform-origin: var(--hv-bg-origin, 50% 50%);
  animation: hv-kenburns 26s ease-out both;
  will-change: transform;
}
/* A slow push-in, the way a media player's now-playing art drifts. It ends
   parked rather than looping, so a slide that sits open doesn't visibly cycle;
   hvShow() restarts it on every slide change. 26s against an 8s auto-advance
   means only the gentle opening third is normally seen. */
@keyframes hv-kenburns {
  from { transform: scale(1.005); }
  to   { transform: scale(1.11); }
}

/* Cover strip for a collection-backed event ("things you can play toward this").
   Sits above the art layer and below the scrim, so the glow still lays a contrast
   floor under the title. Masked away on the left because the title, tags and CTA
   all live there — the strip is texture on the right, never something to read. */
.hv-news-mosaic {
  position: absolute; inset: 0; z-index: -2;
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; padding: 0 18px;
  opacity: .5;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 8%, #000 62%);
          mask-image: linear-gradient(90deg, transparent 8%, #000 62%);
}
.hv-news-mosaic[hidden] { display: none; }
.hv-news-mosaic img {
  height: 78%; width: auto; aspect-ratio: 2 / 3; object-fit: cover;
  border-radius: 8px; flex: none;
  box-shadow: 0 10px 28px rgba(0,0,0,.55);
  /* Alternate lift so a row of covers reads as a spread, not a filmstrip. */
  transform: rotate(-2.5deg) translateY(6px);
}
.hv-news-mosaic img:nth-child(even) { transform: rotate(2.5deg) translateY(-10px); }
/* Landscape art (Jellyfin stills) would otherwise stretch to the 2:3 box. */
.hv-news-mosaic img:nth-child(3n) { aspect-ratio: 3 / 4; }

@media (max-width: 900px) {
  /* Below this the title wraps into the strip's space — three covers is all the
     room there is, and the mask has to bite much harder. */
  .hv-news-mosaic { opacity: .34; gap: 7px; -webkit-mask-image: linear-gradient(90deg, transparent 34%, #000 88%); mask-image: linear-gradient(90deg, transparent 34%, #000 88%); }
  .hv-news-mosaic img:nth-child(n+4) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hv-news-mosaic img { transform: none; }
}

/* The scrim moved off .hv-news-bg::after and onto the glow layer. It has to sit
   in a element that ISN'T being transformed — as a pseudo of the scaling
   background it scaled with it, so the gradient crept off the bottom edge and
   the title lost its contrast floor part-way through the pan. */
.hv-news-glow {
  position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(ellipse 70% 80% at 0% 100%, var(--hv-a-26), transparent 60%);
}
.hv-news-glow::before {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(0deg, rgba(10,10,14,.98) 3%, rgba(10,10,14,.72) 40%, rgba(10,10,14,.16) 100%),
    linear-gradient(95deg, rgba(10,10,14,.88), transparent 60%);
}
@media (prefers-reduced-motion: reduce) {
  /* The global rule collapses the duration; pin the end state so a stopped pan
     doesn't leave the art at a hair over 1:1 with a visible seam. */
  .hv-news-bg { animation: none; transform: scale(1.02); }
}
.hv-news-in { position: relative; padding: 26px 30px; max-width: 640px; }

.hv-tags { display: flex; gap: 7px; margin-bottom: 12px; flex-wrap: wrap; }
.hv-tag {
  font-size: 10px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 5px; flex: 0 0 auto;
}
.hv-tag-live  { background: var(--red); color: #fff; }
.hv-tag-a     { background: var(--accent); color: #12061e; }
.hv-tag-gold  { background: linear-gradient(135deg, #f5c518, #f59e0b); color: #2b1a00; }
.hv-tag-ghost { background: rgba(255,255,255,.10); border: 1px solid var(--border-strong); color: var(--text-2); }

.hv-news-title {
  font-family: var(--font-display);
  font-size: 36px; font-weight: 800; letter-spacing: -.03em; line-height: 1.04;
  margin-bottom: 8px; text-wrap: balance;
}
.hv-news-sub {
  font-size: 14px; color: var(--text-2); margin-bottom: 18px; max-width: 500px;
}
.hv-news-sub b { color: #fff; font-weight: 650; }

/* Cover strip on a "just added" drop slide. A haul is ~40 different series with
   one issue each, so a single hero cover can't carry the news — the strip is
   what says "a batch arrived". It sits inside .hv-news-sub, hence `display:flex`
   on a <span>. Overlapping the covers keeps eight of them inside the 500px sub
   column; the first is on top, so the row reads left-to-right like a fanned
   deck rather than a right-anchored stack. */
.hv-drop-strip {
  display: flex; margin-top: 12px; padding-left: 3px;
}
.hv-drop-strip img {
  width: 34px; height: 51px; object-fit: cover; border-radius: 3px;
  margin-left: -9px; flex: none;
  border: 1px solid rgba(255,255,255,.22);
  box-shadow: 0 3px 10px rgba(0,0,0,.55);
  background: var(--bg-2);
}
/* Stack the leftmost on top. 8 covers max, so the depth range is small. */
.hv-drop-strip img:nth-child(1) { margin-left: 0; z-index: 8; }
.hv-drop-strip img:nth-child(2) { z-index: 7; }
.hv-drop-strip img:nth-child(3) { z-index: 6; }
.hv-drop-strip img:nth-child(4) { z-index: 5; }
.hv-drop-strip img:nth-child(5) { z-index: 4; }
.hv-drop-strip img:nth-child(6) { z-index: 3; }
.hv-drop-strip img:nth-child(7) { z-index: 2; }
.hv-drop-strip img:nth-child(8) { z-index: 1; }
.hv-news-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.hv-cta, .hv-cta2 {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 44px; border-radius: 9px; transition: .16s; text-decoration: none;
}
.hv-cta {
  padding: 0 26px; font-family: var(--font-display); font-size: 14.5px; font-weight: 800;
  background: linear-gradient(135deg, var(--hv-a-hi), var(--hv-a-lo)); color: #fff;
  box-shadow: 0 6px 20px var(--hv-a-42), inset 0 1px 0 rgba(255,255,255,.26);
}
.hv-cta:hover { transform: translateY(-2px); box-shadow: 0 10px 28px var(--hv-a-55), inset 0 1px 0 rgba(255,255,255,.26); }
.hv-cta-red { background: linear-gradient(135deg, #ff5f6d, #e3243b); box-shadow: 0 6px 20px rgba(255,77,94,.4), inset 0 1px 0 rgba(255,255,255,.26); }
.hv-cta svg { width: 15px; height: 15px; }
.hv-cta2 {
  padding: 0 17px; background: rgba(255,255,255,.07); border: 1px solid var(--border-strong);
  font-weight: 650; font-size: 12.5px; color: var(--text);
}
.hv-cta2:hover { background: rgba(255,255,255,.13); }
.hv-news-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-3); }
.hv-avs { display: flex; }
.hv-avs img, .hv-avs span {
  width: 23px; height: 23px; border-radius: 50%; margin-left: -7px;
  border: 2px solid rgba(10,10,14,.9); object-fit: cover;
  background: linear-gradient(135deg, #3b3b52, #252533);
  display: grid; place-items: center; font-size: 9px; font-weight: 700; color: var(--text-2);
}
.hv-avs :first-child { margin-left: 0; }

/* controls — bottom right, Fortnite style */
.hv-ctl { position: absolute; right: 20px; bottom: 18px; z-index: 6; display: flex; align-items: center; gap: 12px; }
.hv-count { font-size: 11px; font-weight: 700; color: rgba(255,255,255,.5); font-variant-numeric: tabular-nums; }
.hv-dots { display: flex; gap: 6px; align-items: center; }
.hv-dot {
  width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,.28);
  cursor: pointer; transition: .2s; border: none; padding: 0;
}
.hv-dot:hover { background: rgba(255,255,255,.6); }
.hv-dot.on { background: #fff; width: 22px; border-radius: 99px; box-shadow: 0 0 10px rgba(255,255,255,.55); }
.hv-arrs { display: flex; gap: 6px; }
.hv-arr {
  width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center;
  background: rgba(10,10,14,.55); border: 1px solid rgba(255,255,255,.22);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); transition: .16s; color: var(--text); cursor: pointer;
}
.hv-arr:hover { background: var(--hv-a-85); border-color: var(--hv-a-90); transform: scale(1.06); }
.hv-arr svg { width: 15px; height: 15px; }
.hv-news-prog { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255,255,255,.12); z-index: 2; }
.hv-news-prog i { display: block; height: 100%; background: var(--accent); box-shadow: 0 0 10px var(--accent); }

/* ═══ SEASON BANNER ═══ */
.hv-sban {
  /* Deliberately NOT the user's accent. This widget represents the season, so it
     wears the season's own colour (`--sp-season-primary`, set from
     season.colors.nav in topbar.js) and stays put when the user reskins the site.
     Falls back to --accent for a season that ships no palette. */
  --hv-s:    var(--sp-season-primary, var(--accent));
  --hv-s-hi: color-mix(in srgb, var(--hv-s) 62%, #fff);
  --hv-s-lo: color-mix(in srgb, var(--hv-s) 80%, #000);
  --hv-s-70: color-mix(in srgb, var(--hv-s) 70%, transparent);
  --hv-s-50: color-mix(in srgb, var(--hv-s) 50%, transparent);
  --hv-s-30: color-mix(in srgb, var(--hv-s) 30%, transparent);
  --hv-s-17: color-mix(in srgb, var(--hv-s) 17%, transparent);
  --hv-s-08: color-mix(in srgb, var(--hv-s) 8%,  transparent);

  position: relative; display: flex; align-items: center; gap: 22px;
  padding: 18px 22px; border-radius: 14px; overflow: hidden;
  background: linear-gradient(112deg, var(--hv-s-17), var(--hv-s-08) 52%, rgba(20,20,29,.5));
  border: 1px solid var(--hv-s-30);
}
.hv-sban::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 40% 130% at 92% 50%, var(--hv-s-17), transparent 66%);
}
.hv-sb-lv {
  position: relative; width: 52px; height: 52px; border-radius: 13px; flex: none;
  display: grid; place-items: center;
  font-family: var(--font-display); font-size: 22px; font-weight: 800; color: #12061e;
  background: linear-gradient(140deg, var(--hv-s-hi), var(--hv-s-lo));
  box-shadow: 0 4px 16px var(--hv-s-50);
}
.hv-sb-mid { position: relative; flex: 1; min-width: 0; }
.hv-sb-top { display: flex; align-items: baseline; gap: 10px; margin-bottom: 9px; flex-wrap: wrap; }
.hv-sb-nm { font-family: var(--font-display); font-size: 17px; font-weight: 800; letter-spacing: -.02em; }
.hv-sb-dt { font-size: 11.5px; color: var(--text-3); font-weight: 600; }
.hv-sb-warn {
  margin-left: auto; font-size: 11.5px; font-weight: 700; color: #ffcf6b;
  padding: 3px 10px; border-radius: 99px;
  background: rgba(255,208,66,.11); border: 1px solid rgba(255,208,66,.3);
}
.hv-sb-trk { position: relative; height: 9px; border-radius: 99px; background: rgba(255,255,255,.11); margin-bottom: 9px; }
.hv-sb-fill {
  position: absolute; left: 0; top: 0; bottom: 0; border-radius: 99px;
  background: linear-gradient(90deg, var(--hv-s-lo), var(--hv-s), var(--hv-s-hi));
  box-shadow: 0 0 16px var(--hv-s-70);
}
.hv-sb-nod {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  width: 17px; height: 17px; border-radius: 50%;
  background: #15151f; border: 2px solid rgba(255,255,255,.22);
  display: grid; place-items: center; font-size: 8.5px; transition: .16s;
}
.hv-sb-nod:hover { transform: translate(-50%, -50%) scale(1.22); }
.hv-sb-nod.got {
  background: linear-gradient(135deg, var(--hv-s), var(--hv-s-hi));
  border-color: var(--hv-s-hi);
  box-shadow: 0 0 13px var(--hv-s-70);
}
.hv-sb-nod.next { border-color: var(--gold); background: #221a06; animation: hv-pulse 2.2s ease-in-out infinite; }
@keyframes hv-pulse {
  0%, 100% { box-shadow: 0 0 12px rgba(255,208,66,.5); }
  50%      { box-shadow: 0 0 24px rgba(255,208,66,.95); }
}
.hv-sb-foot { display: flex; justify-content: space-between; gap: 14px; font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.hv-sb-foot b { color: var(--hv-s-hi); font-weight: 700; }
.hv-sb-rw { position: relative; flex: none; display: flex; align-items: center; gap: 11px; padding-left: 20px; border-left: 1px solid rgba(255,255,255,.12); }
.hv-sb-art {
  width: 46px; height: 46px; border-radius: 11px; display: grid; place-items: center; font-size: 21px;
  background: linear-gradient(140deg, rgba(255,208,66,.26), rgba(255,95,188,.14));
  border: 1px solid rgba(255,208,66,.34);
}
.hv-sb-rl { font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.hv-sb-rn { font-family: var(--font-display); font-size: 13.5px; font-weight: 800; letter-spacing: -.01em; }
.hv-sb-rd { font-size: 10.5px; color: var(--text-3); }
.hv-sb-btn {
  display: inline-flex; align-items: center; height: 40px; padding: 0 20px; border-radius: 9px;
  font-family: var(--font-display); font-size: 13px; font-weight: 800;
  background: linear-gradient(135deg, var(--hv-s-hi), var(--hv-s-lo)); color: #fff;
  box-shadow: 0 5px 18px var(--hv-s-50); transition: .16s; margin-left: 6px; text-decoration: none;
}
.hv-sb-btn:hover { transform: translateY(-2px); }

/* ═══ SHELVES ═══ */
.hv-sh { display: flex; align-items: baseline; gap: 11px; margin-bottom: 16px; }
.hv-sh-t { font-family: var(--font-display); font-size: 18px; font-weight: 800; letter-spacing: -.025em; }
.hv-sh-n { font-size: 12.5px; color: var(--text-3); }
.hv-sh-n b { color: var(--accent); font-weight: 650; }
.hv-sh-l { margin-left: auto; font-size: 12.5px; font-weight: 650; color: var(--text-3); transition: .15s; text-decoration: none; }
.hv-sh-l:hover { color: var(--accent); }
.hv-dl {
  font-size: 10.5px; font-weight: 800; letter-spacing: .05em; padding: 3px 8px; border-radius: 5px;
  background: rgba(248,113,113,.15); color: #fca5a5; border: 1px solid rgba(248,113,113,.3);
}

/* horizontal scroller — padding-top so the hover lift isn't clipped */
.hv-rail { display: flex; gap: 13px; overflow-x: auto; padding: 4px 2px 11px; scroll-snap-type: x proximity; }
.hv-rail::-webkit-scrollbar { height: 7px; }
.hv-rail::-webkit-scrollbar-track { background: rgba(255,255,255,.04); border-radius: 99px; }
.hv-rail::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 99px; }
.hv-rail::-webkit-scrollbar-thumb:hover { background: var(--hv-a-55); }

.hv-cap {
  width: 164px; flex: none; scroll-snap-align: start; border-radius: 11px; overflow: hidden;
  background: var(--hv-panel); border: 1px solid var(--border);
  transition: .18s; cursor: pointer; position: relative; text-decoration: none; color: inherit;
  display: block;
}
.hv-cap:hover { transform: translateY(-4px); border-color: var(--hv-a-55); box-shadow: 0 14px 32px rgba(0,0,0,.55); }
.hv-cap-art { aspect-ratio: 2/3; position: relative; overflow: hidden; background: linear-gradient(155deg, #1f1f2b, #13131b); }
.hv-cap-art img { width: 100%; height: 100%; object-fit: cover; position: relative; z-index: 1; transition: .4s; }
.hv-cap:hover .hv-cap-art img { transform: scale(1.05); }
.hv-cap-fb {
  position: absolute; inset: 0; display: grid; place-items: center; padding: 11px; text-align: center;
  font-size: 11px; font-weight: 650; color: var(--text-3); z-index: 0;
}
.hv-cap-shade { position: absolute; inset: 0; z-index: 2; pointer-events: none; background: linear-gradient(0deg, rgba(10,10,14,.8), transparent 40%); }
.hv-pip {
  position: absolute; z-index: 3; font-size: 9px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; padding: 3px 6px; border-radius: 5px; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.hv-pip-tl { top: 7px; left: 7px; background: rgba(10,10,14,.75); border: 1px solid rgba(255,255,255,.16); color: var(--text-2); }
.hv-pip-tr { top: 7px; right: 7px; background: var(--accent); color: #12061e; }
.hv-pip-tr.gold { background: linear-gradient(135deg, #f5c518, #f59e0b); color: #2b1a00; }
.hv-pip-tr.green { background: var(--green); color: #062012; }
.hv-cap-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255,255,255,.16); z-index: 3; }
.hv-cap-bar i { display: block; height: 100%; background: var(--accent); box-shadow: 0 0 8px var(--accent); }
.hv-cap-hov {
  position: absolute; inset: 0; z-index: 4; display: grid; place-items: center;
  opacity: 0; transition: .18s; background: rgba(10,10,14,.5); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
}
.hv-cap:hover .hv-cap-hov { opacity: 1; }
.hv-cap-hov span { width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; background: var(--accent); box-shadow: 0 4px 20px var(--hv-a-75); }
.hv-cap-hov svg { width: 14px; height: 14px; margin-left: 2px; }
.hv-cap-b { padding: 9px 11px 11px; }
.hv-cap-src { font-size: 9px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--accent); margin-bottom: 3px; }
.hv-cap-n {
  font-size: 12px; font-weight: 650; line-height: 1.3; margin-bottom: 4px; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 31px;
}
.hv-cap-f { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.hv-cap-note { font-size: 10.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ═══ CHALLENGE BOARD ═══ */
.hv-board { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.hv-col { border-radius: 14px; background: var(--hv-panel); border: 1px solid var(--border); overflow: hidden; display: flex; flex-direction: column; }
.hv-col-wk { border-color: var(--hv-a-28); }
.hv-col-mo { border-color: rgba(245,181,24,.24); }

.hv-col-head { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.hv-col-wk .hv-col-head { background: linear-gradient(100deg, var(--hv-a-16), var(--hv-a-04)); }
.hv-col-mo .hv-col-head { background: linear-gradient(100deg, rgba(245,181,24,.13), rgba(245,181,24,.015)); }
.hv-cad { flex: 1; min-width: 0; }
.hv-kick { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.hv-cad-nm { font-family: var(--font-display); font-size: 16.5px; font-weight: 800; letter-spacing: -.02em; }
.hv-when { font-size: 11.5px; color: var(--text-3); font-weight: 600; }
.hv-col-wk .hv-when b { color: var(--accent); font-weight: 700; }
.hv-col-mo .hv-when b { color: var(--hv-amber-2); font-weight: 700; }

.hv-dots-c { display: flex; gap: 4px; flex: none; }
.hv-cdot { width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,.13); border: 1px solid rgba(255,255,255,.14); }
.hv-col-wk .hv-cdot.f { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 9px var(--hv-a-70); }
.hv-col-mo .hv-cdot.f { background: var(--hv-amber); border-color: var(--hv-amber); box-shadow: 0 0 9px rgba(245,181,24,.6); }
.hv-score { flex: none; text-align: right; }
.hv-score-v { font-family: var(--font-display); font-size: 17px; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.hv-col-wk .hv-score-v { color: var(--accent); }
.hv-col-mo .hv-score-v { color: var(--hv-amber-2); }
.hv-score-l { font-size: 9.5px; letter-spacing: .11em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.hv-pill { font-size: 10px; font-weight: 800; letter-spacing: .05em; padding: 3px 7px; border-radius: 5px; flex: none; }
.hv-pill-soon { background: rgba(255,77,94,.15); color: #ff9aa5; border: 1px solid rgba(255,77,94,.3); }
.hv-pill-ok { background: rgba(255,255,255,.07); color: var(--text-3); border: 1px solid var(--border); }

/* the grid wraps — it never scrolls sideways, so weekly and monthly stay distinct */
.hv-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; padding: 14px 16px 16px; }
.hv-q {
  border-radius: 10px; overflow: hidden; background: var(--hv-panel-2); border: 1px solid var(--border);
  transition: .17s; cursor: pointer; position: relative; display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
}
.hv-q:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(0,0,0,.5); }
.hv-col-wk .hv-q:hover { border-color: var(--hv-a-55); }
.hv-col-mo .hv-q:hover { border-color: rgba(245,181,24,.5); }
.hv-q.done { border-color: rgba(74,222,128,.4); background: rgba(74,222,128,.05); }
.hv-q-art { aspect-ratio: 2/3; position: relative; overflow: hidden; background: linear-gradient(155deg, #1f1f2b, #13131b); }
.hv-q-art img { width: 100%; height: 100%; object-fit: cover; position: relative; z-index: 1; }
.hv-q-fb { position: absolute; inset: 0; display: grid; place-items: center; padding: 9px; text-align: center; font-size: 10px; font-weight: 650; color: var(--text-3); z-index: 0; }
.hv-q-shade { position: absolute; inset: 0; z-index: 2; background: linear-gradient(0deg, rgba(10,10,14,.78), transparent 44%); }
.hv-q-pip { position: absolute; z-index: 3; font-size: 9px; font-weight: 800; letter-spacing: .06em; padding: 2.5px 6px; border-radius: 4px; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.hv-q-pts { top: 6px; right: 6px; background: var(--accent); color: #12061e; }
.hv-col-mo .hv-q-pts { background: linear-gradient(135deg, #f5c518, #f59e0b); color: #2b1a00; }
.hv-q-tick { top: 6px; right: 6px; background: var(--green); color: #062012; }
.hv-q-type { top: 6px; left: 6px; background: rgba(10,10,14,.78); border: 1px solid rgba(255,255,255,.16); color: var(--text-2); }
.hv-q-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255,255,255,.18); z-index: 3; }
.hv-q-bar i { display: block; height: 100%; background: var(--accent); box-shadow: 0 0 8px var(--accent); }
.hv-col-mo .hv-q-bar i { background: var(--hv-amber); box-shadow: 0 0 8px var(--hv-amber); }
.hv-q-b { padding: 8px 10px 10px; flex: 1; display: flex; flex-direction: column; }
.hv-q-src {
  font-size: 8.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hv-q-n {
  font-size: 11.5px; font-weight: 650; line-height: 1.28; margin-bottom: 5px; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 29px;
}
.hv-q-f { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 5px; }
.hv-q-note { font-size: 10px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv-q-note.gr { color: #86efac; font-weight: 600; }
.hv-q-avs { display: flex; flex: none; }
.hv-q-avs img, .hv-q-avs span {
  width: 16px; height: 16px; border-radius: 50%; margin-left: -5px; border: 1.5px solid var(--hv-panel-2);
  object-fit: cover; background: #2f2f3d; display: grid; place-items: center;
  font-size: 7px; font-weight: 700; color: var(--text-2);
}
.hv-q-avs :first-child { margin-left: 0; }

/* the wide odd-one-out per cadence: Groove under weekly, Retro under monthly */
.hv-wide {
  display: flex; align-items: center; gap: 13px; margin: 0 16px 16px; padding: 11px 13px;
  border-radius: 10px; background: var(--hv-panel-2); border: 1px solid var(--border);
  transition: .16s; cursor: pointer; text-decoration: none; color: inherit;
}
.hv-wide:hover { transform: translateY(-2px); }
.hv-col-wk .hv-wide:hover { border-color: var(--hv-a-55); }
.hv-col-mo .hv-wide:hover { border-color: rgba(245,181,24,.45); }
.hv-wide.done { border-color: rgba(74,222,128,.4); background: rgba(74,222,128,.05); }
.hv-w-art { width: 40px; height: 40px; border-radius: 9px; flex: none; display: grid; place-items: center; font-size: 19px; overflow: hidden; }
.hv-w-art img { width: 100%; height: 100%; object-fit: cover; }
.hv-w-b { flex: 1; min-width: 0; }
.hv-w-t { display: flex; align-items: center; gap: 7px; margin-bottom: 2px; }
.hv-w-n { font-size: 12.5px; font-weight: 650; letter-spacing: -.01em; }
.hv-w-p { font-size: 9px; font-weight: 800; padding: 1.5px 5px; border-radius: 4px; background: var(--accent-dim); color: var(--accent); border: 1px solid var(--hv-a-28); }
.hv-col-mo .hv-w-p { background: var(--hv-amber-dim); color: var(--hv-amber-2); border-color: rgba(245,181,24,.3); }
.hv-w-s { font-size: 11px; color: var(--text-3); }
.hv-w-r { flex: none; display: flex; align-items: center; gap: 9px; }
.hv-w-bar { width: 78px; height: 5px; border-radius: 99px; background: rgba(255,255,255,.14); overflow: hidden; }
.hv-w-bar i { display: block; height: 100%; border-radius: 99px; background: var(--hv-amber); box-shadow: 0 0 8px var(--hv-amber); }
.hv-w-v { font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--hv-amber-2); }
.hv-w-check { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--green); color: #062012; font-weight: 800; font-size: 12px; }

/* ═══ TWO-UP ═══ */
.hv-duo { display: grid; grid-template-columns: 1fr 336px; gap: 18px; }

/* ═══ LEFT-RAIL LIVE STATE ═══ */
/* The rail entries become launcher tiles: name on top, live status underneath. */
#side-rail .rail-app.hv-tile { align-items: center; padding-top: 7px; padding-bottom: 7px; }
.hv-app-txt { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.2; }
.hv-app-nm { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv-app-sub {
  font-size: 10.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 1px;
}
.hv-app-sub.act { color: var(--accent); }
.hv-app-sub.on { color: var(--green); }
.hv-app-sub:empty { display: none; }
/* Tiles with more than one fact rotate through them. The swap is a soft dip in
   opacity only — no rise, and it never fades to nothing — because several of
   these turn over within a few hundred ms of each other and anything more
   assertive reads as the rail flickering. The stagger that spaces them out is in
   home-v2.js (hvRailRotate). Disabled wholesale by the global
   prefers-reduced-motion rule in main.css. */
@keyframes hv-sub-in {
  from { opacity: .4; }
  to   { opacity: 1; }
}
.hv-app-sub { animation: hv-sub-in .5s ease-out; }

/* Same facts in the topbar Apps dropdown — the only route to these apps on
   mobile, where the side rail is hidden. Trailing and right-aligned, since the
   dropdown rows are a single line of icon + name. */
.app-drop-sub {
  margin-left: auto; padding-left: 10px; max-width: 46%;
  font-size: 10.5px; text-align: right;
}

/* ═══ RESPONSIVE ═══ */
@media (max-width: 1180px) {
  .hv-duo { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .hv-news { min-height: 330px; }
  .hv-news-in { padding: 20px 16px 56px; }
  .hv-news-title { font-size: 27px; }
  .hv-news-sub { font-size: 13px; margin-bottom: 15px; }
  .hv-drop-strip img { width: 28px; height: 42px; margin-left: -8px; }
  .hv-news-row { gap: 9px; }
  .hv-ctl { right: 14px; bottom: 13px; gap: 9px; }
  .hv-count { display: none; }
  .hv-arr { width: 29px; height: 29px; }

  .hv-sban { flex-wrap: wrap; gap: 14px; padding: 15px 16px; }
  .hv-sb-lv { width: 44px; height: 44px; font-size: 19px; border-radius: 11px; }
  .hv-sb-mid { flex: 1 1 220px; }
  .hv-sb-nm { font-size: 15.5px; }
  .hv-sb-warn { margin-left: 0; flex: 0 0 100%; text-align: center; }
  .hv-sb-foot { flex-direction: column; gap: 3px; }
  .hv-sb-rw { flex: 1 1 100%; padding-left: 0; border-left: none; padding-top: 13px; border-top: 1px solid rgba(255,255,255,.12); }
  .hv-sb-btn { margin-left: auto; }

  /* board stacks; cap the grid so quest cards stay card-sized, not poster-sized */
  .hv-board { grid-template-columns: 1fr; gap: 13px; }
  .hv-grid { max-width: 560px; }
  .hv-wide { max-width: 560px; }
  .hv-cap { width: 136px; }
  .hv-sh-t { font-size: 16px; }
}
@media (max-width: 620px) {
  /* 3-across is deliberate: a week stays one row, a month stays one row */
  .hv-grid { grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 12px 12px 13px; }
  .hv-col-head { padding: 12px; gap: 9px; }
  .hv-cad-nm { font-size: 15px; white-space: nowrap; }
  .hv-kick { flex-wrap: wrap; gap: 6px; }
  .hv-q-b { padding: 7px 8px 9px; }
  .hv-q-n { font-size: 10.5px; min-height: 26px; }
  .hv-q-src { font-size: 8px; }
  .hv-q-note { font-size: 9px; }
  .hv-q-pip { font-size: 8px; padding: 2px 5px; }
  .hv-wide { margin: 0 12px 13px; padding: 10px 11px; gap: 11px; }
  .hv-w-n { font-size: 12px; }
  .hv-w-s { font-size: 10.5px; }
  .hv-score-v { font-size: 15px; }
  .hv-dot { width: 6px; height: 6px; }
  .hv-dot.on { width: 16px; }
  .hv-news-title { font-size: 24px; }

  /* section headers stop colliding: title owns its own line */
  .hv-sh { flex-wrap: wrap; gap: 4px 10px; }
  .hv-sh-t { flex: 0 0 100%; }
  .hv-sh-l { margin-left: auto; }
  .hv-sh-n { font-size: 11.5px; }
}
@media (prefers-reduced-motion: reduce) {
  .hv-sb-nod.next { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   OVERRIDES — what the new blocks supersede.

   The legacy markup all stays in the DOM on purpose: eggs.js, widgets.js and
   home-init.js write into these elements, and several of them don't null-check.
   Hiding rather than deleting keeps every module working untouched, and the
   old .home-2col block becomes this design's bottom two-up for free.
   `!important` is required because the JS sets `style.display=''` on some of
   these once their data arrives.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-home #hero,                 /* superseded by the challenge board */
.hv-home #continue-strip,       /* superseded by the continue shelf */
.hv-home #home-season-widget {  /* superseded by the season banner  */
  display: none !important;
}

/* The surviving two-column block is now the bottom two-up: community feed on
   the left, everything else stacked on the right. */
.hv-home .home-2col { margin-top: 44px; }

/* Scoring popover is opened from the board header now; keep it usable there. */
.hv-home #hv-scoring-btn { background: none; border: none; cursor: pointer; font: inherit; }

/* ═══════════════════════════════════════════════════════════════════════════
   EGG CHIP — the hatchery, moved out of the sidebar and into the top bar.

   The widget markup itself is unchanged and still carries #home-egg-widget /
   #home-egg-body, so eggs.js renders into it exactly as before — this is a
   relocation, not a rewrite. The chip mirrors the widget's state by observing
   that body, so there is no second source of truth and no extra request.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-retired { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.hv-egg-wrap { position: relative; }
.hv-egg-chip { gap: 6px; }
.hv-egg-ico { font-size: 14px; line-height: 1; display: inline-block; }
.hv-egg-txt:empty { display: none; }

/* Ready state: the chip is the notification, so it has to catch the eye without
   becoming a distraction — one slow sweep, and it stops for reduced-motion. */
.hv-egg-chip.ready {
  border-color: var(--hv-a-55);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--text);
  position: relative;
  overflow: hidden;
}
.hv-egg-chip.ready .hv-egg-ico { animation: hv-egg-bob 2.4s ease-in-out infinite; }
.hv-egg-chip.ready::after {
  content: '';
  position: absolute; top: 0; bottom: 0; width: 45%; left: -60%;
  background: linear-gradient(100deg, transparent, color-mix(in srgb, #fff 38%, transparent), transparent);
  animation: hv-egg-sheen 3.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes hv-egg-bob {
  0%, 70%, 100% { transform: translateY(0) rotate(0); }
  78%           { transform: translateY(-2px) rotate(-8deg); }
  86%           { transform: translateY(-2px) rotate(8deg); }
}
@keyframes hv-egg-sheen { 0% { left: -60%; } 55%, 100% { left: 130%; } }

.hv-egg-pop {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 500;
  width: 320px; max-width: calc(100vw - 24px);
  border-radius: 13px; overflow: hidden;
  background: var(--hv-panel); border: 1px solid var(--border-strong);
  box-shadow: 0 22px 54px rgba(0,0,0,.66);
  animation: hv-egg-in .16s cubic-bezier(.16,1,.3,1);
}
@keyframes hv-egg-in { from { opacity: 0; transform: translateY(-6px); } }
.hv-egg-pop.hidden { display: none; }
/* the widget is already styled by main.css — just strip its outer chrome here */
.hv-egg-pop .widget { border: none; background: none; margin: 0; }

/* On a narrow screen an anchored dropdown either clips at the viewport edge or
   ends up wider than the space left of its chip, so all three popovers become a
   sheet pinned under the topbar instead. The egg popover always did this; the
   other two now match it. */
@media (max-width: 900px) {
  .hv-egg-pop, .hv-rank-pop, .hv-radio-pop {
    position: fixed; top: calc(var(--topbar-h) + 8px); right: 10px; left: 10px; width: auto; max-width: none;
  }
  .hv-rank-pop #lb-list { max-height: calc(100vh - var(--topbar-h) - 90px); }
}
/* The bottom nav only exists at 680px and below, so only subtract it there —
   --mobile-nav-h is defined on :root and would otherwise cost 64px of popover
   height in the 681-900px band where there is no bottom nav. */
@media (max-width: 680px) {
  .hv-rank-pop #lb-list { max-height: calc(100vh - var(--topbar-h) - var(--mobile-nav-h) - 90px); }
}
@media (prefers-reduced-motion: reduce) {
  .hv-egg-chip.ready .hv-egg-ico, .hv-egg-chip.ready::after { animation: none; }
  .hv-egg-pop { animation: none; }
}

/* ═══ CHIPS ON MOBILE ═══════════════════════════════════════════════════════
   main.css used to hide .hp-chips entirely at 680px (that rule is now gone). It
   was fine when the leaderboard and the egg hatchery lived in the home sidebar,
   but both moved into these popovers when the sidebar was retired — so hiding
   the chips made two features unreachable on a phone. They stay, tightened up
   to fit: at 390px the
   topbar is carrying a wordmark, two chips, Apps and the avatar, which is about
   20px more than fits at desktop padding.

   The radio chip deliberately stays hidden below 900px — #mnav-radio in the
   bottom nav already covers it, and the space is better spent on the two that
   have no other route. The Apps button keeps its label: it is the only route to
   Comics / TV / Audiobooks / Retro, and the width works out without trimming it. */
@media (max-width: 680px) {
  .hp-chips { gap: 6px; }
  .hp-chip { padding: 6px 9px; gap: 5px; font-size: 12px; }
  .topbar-right { gap: 8px; }
}
/* Very narrow (small phones, ~360px): the egg chip's label is the first thing
   that can go — the icon plus its ready-state shimmer still says enough. */
@media (max-width: 400px) {
  .hv-egg-txt { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RADIO CHIP — the only persistent desktop way into the radio.

   #radio-player is display:none until _radioOpen() fires and #mnav-radio is
   mobile-only, so before this chip the sidebar Live card's "Listen →" was the
   sole entry point on desktop. The chip is a launcher + now-playing readout; it
   opens the EXISTING mini-player rather than duplicating any of its controls.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-radio-wrap { position: relative; }
.hv-radio-chip { gap: 7px; max-width: 230px; }
.hv-radio-ico { font-size: 13px; line-height: 1; flex: none; }
.hv-radio-txt {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 150px; font-weight: 600;
}
.hv-radio-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--text-3); transition: .2s;
}
.hv-radio-chip.live { border-color: var(--hv-a-42); }
.hv-radio-chip.live .hv-radio-dot {
  background: var(--green);
  box-shadow: 0 0 7px var(--green);
  animation: hv-radio-pulse 2.4s ease-in-out infinite;
}
.hv-radio-chip.playing { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--text); }
@keyframes hv-radio-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

@media (max-width: 1100px) { .hv-radio-txt { display: none; } .hv-radio-chip { max-width: none; } }
@media (max-width: 900px)  { .hv-radio-wrap { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .hv-radio-chip.live .hv-radio-dot { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   TOPBAR SEARCH — replaces the rotating activity pulse.
   A readonly input that opens the existing full-screen media-search overlay, so
   there is one search implementation, not two. The overlay's admin gate was
   lifted (topbar.js) when this became everyone's search.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-search { position: relative; flex: 1; max-width: 380px; margin-left: 18px; }
.hv-search svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--text-3); pointer-events: none;
}
.hv-search input {
  width: 100%; height: 34px; border-radius: 8px; padding: 0 12px 0 34px;
  font: inherit; font-size: 13px; color: var(--text); cursor: pointer;
  background: rgba(255,255,255,.05); border: 1px solid var(--border);
  outline: none; transition: .15s;
}
.hv-search input::placeholder { color: var(--text-3); }
.hv-search input:hover  { background: rgba(255,255,255,.08); border-color: var(--border-strong); }
.hv-search input:focus  { border-color: var(--hv-a-55); background: rgba(255,255,255,.09); }
@media (max-width: 1100px) { .hv-search { max-width: 210px; } }
@media (max-width: 780px)  { .hv-search { display: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   SHARED CHIP POPOVER
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-rank-wrap { position: relative; }
.hv-rank-pop, .hv-radio-pop {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 500;
  border-radius: 13px; overflow: hidden;
  background: var(--hv-panel); border: 1px solid var(--border-strong);
  box-shadow: 0 22px 54px rgba(0,0,0,.66);
  animation: hv-egg-in .16s cubic-bezier(.16,1,.3,1);
}
.hv-rank-pop.hidden, .hv-radio-pop.hidden { display: none; }
.hv-pop-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
  font-family: var(--font-display); font-size: 13.5px; font-weight: 800;
}
.hv-pop-sub { margin-left: auto; font-family: var(--font-body); font-size: 11px; font-weight: 600; color: var(--text-3); }

/* leaderboard — the whole board now, so it scrolls */
.hv-rank-pop { width: 340px; max-width: calc(100vw - 24px); }
.hv-rank-pop #lb-list { max-height: min(62vh, 560px); overflow-y: auto; padding-bottom: 4px; }
.hv-rank-pop #lb-list::-webkit-scrollbar { width: 5px; }
.hv-rank-pop #lb-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 99px; }

/* ═══════════════════════════════════════════════════════════════════════════
   RADIO POPOVER — the real mini-player, re-docked.
   #radio-player is normally position:fixed bottom-right. Inside the popover it
   becomes a static block and always shows its expanded panel, since a popover
   you deliberately opened shouldn't need a second click to reveal the art. Its
   own close button is redundant here (clicking outside closes) so it's hidden.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-radio-pop { width: 300px; max-width: calc(100vw - 24px); }
.hv-radio-pop #radio-player {
  display: block !important;
  position: static; width: 100%;
  bottom: auto; right: auto;
  border: none; border-left: none; border-radius: 0;
  box-shadow: none; animation: none; background: transparent;
  z-index: auto;
}
.hv-radio-pop #rp-expanded { max-height: 460px; }   /* always open in the popover */
.hv-radio-pop #rp-close { display: none; }
/* The expanded panel already shows title + artist, so the collapsed bar's copy of
   the title is a duplicate here — leave the bar as pure transport. */
.hv-radio-pop .rp-bar-info { display: none; }
.hv-radio-pop #rp-bar { justify-content: flex-start; gap: 10px; }
/* the fixed-position player is hidden under 680px in radio.css; the popover copy
   must not inherit that, because the chip is already hidden under 900px anyway */
@media (max-width: 680px) { .hv-radio-pop #radio-player { display: block !important; } }

/* ═══════════════════════════════════════════════════════════════════════════
   SEASON PAGE — ways to earn, relocated from the retired leaderboard widget
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-scoring-wrap { padding-top: 8px; padding-bottom: 48px; }
.hv-scoring-section { display: block !important; }
.hv-scoring-section.lb-scoring { position: static; width: auto; border-radius: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   RIGHT COLUMN RETIRED
   Everything that lived there has a better home now: season → banner, egg and
   leaderboard and radio → topbar chips, guide → news rail, live card → news rail,
   annual goals → deleted, RAF → the avatar menu's existing invite item. All the
   sidebar still holds is the permanently-hidden season snapshot, so the grid
   collapses and the community feed takes the full width.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-home .home-2col { display: block; }
.hv-home .home-sidebar { display: none; }

/* Full width, matching the shelves above it. The earlier 860px cap kept the line
   length comfortable but left it visibly narrower than everything else, which
   read as a mistake rather than a choice. */
.hv-home #home-community-widget { max-width: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   PRESENCE CHIP — "who's online", moved into the chip group.
   Was a bare avatar cluster floating in the middle of the topbar; now it reads
   as one of the chips and opens the same kind of popover as egg/rank/radio.
   The roster and heartbeat in topbar.js are unchanged.
   ═══════════════════════════════════════════════════════════════════════════ */
.hv-pres-wrap { position: relative; }
.hv-pres-chip { gap: 8px; padding-left: 6px; }
.hv-pres-chip .tb-presence-avs { display: flex; align-items: center; }
.hv-pres-chip .tb-presence-av {
  width: 21px; height: 21px; border-radius: 50%; margin-left: -7px; flex: none;
  border: 2px solid var(--bg); overflow: hidden; background: linear-gradient(135deg, #3b3b52, #252533);
  display: grid; place-items: center; font-size: 9px; font-weight: 700; color: var(--text-2);
}
.hv-pres-chip .tb-presence-av:first-child { margin-left: 0; }
.hv-pres-chip .tb-presence-av img { width: 100%; height: 100%; object-fit: cover; }
.hv-pres-txt { font-size: 12.5px; font-weight: 600; white-space: nowrap; }

.hv-pres-pop {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 500;
  width: 290px; max-width: calc(100vw - 24px); padding: 6px;
  border-radius: 13px; background: var(--hv-panel); border: 1px solid var(--border-strong);
  box-shadow: 0 22px 54px rgba(0,0,0,.66);
  animation: hv-egg-in .16s cubic-bezier(.16,1,.3,1);
}
.hv-pres-pop.hidden { display: none; }
.hv-pres-pop .tb-presence-row {
  display: flex; align-items: center; gap: 11px; padding: 9px 10px;
  border-radius: 10px; cursor: pointer; transition: .15s;
}
.hv-pres-pop .tb-presence-row:hover { background: rgba(255,255,255,.06); }
.hv-pres-pop .tb-presence-av {
  width: 32px; height: 32px; border-radius: 50%; flex: none; overflow: hidden;
  background: linear-gradient(135deg, #3b3b52, #252533);
  display: grid; place-items: center; font-size: 12px; font-weight: 700; color: var(--text-2);
}
.hv-pres-pop .tb-presence-av img { width: 100%; height: 100%; object-fit: cover; }
.hv-pres-pop .tb-presence-who { font-size: 12.5px; font-weight: 650; }
.hv-pres-pop .tb-presence-what { font-size: 11.5px; color: var(--text-3); margin-top: 1px; }

@media (max-width: 780px) { .hv-pres-txt { display: none; } }
@media (max-width: 620px) { .hv-pres-wrap { display: none !important; } }
