/* Neon Arena — progression: weekly quests (lobby card), achievements (profile
   section), battle pass (header / level strip / legends). Loaded after
   components.css; reuses .glass-card/.card-title/.btn/.chip primitives and the
   shared motion tokens (spring / popIn / spinPulse). */

/* === quests (lobby) === */
.pr-quests-hint { margin-bottom: 8px; font-size: 12px; line-height: 1.5; color: var(--text-dim); }
.pr-quest-list { display: flex; flex-direction: column; gap: 8px; }
.pr-quest {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--stroke);
  background: var(--panel-soft);
  cursor: pointer;
  transition: transform var(--dur-med) var(--spring), border-color var(--dur-fast), background var(--dur-fast);
}
@media (hover: hover) {
  .pr-quest:hover { border-color: var(--stroke-strong); background: var(--panel); transform: translateX(3px); }
}
.pr-quest.done { border-color: rgba(53, 199, 131, 0.45); background: rgba(53, 199, 131, 0.06); }
.pr-quest-icon { font-size: 20px; line-height: 1; flex: 0 0 auto; }
.pr-quest-main { min-width: 0; }
.pr-quest-name { font-weight: 700; font-size: 13.5px; }
.pr-quest-rail {
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke);
  background: var(--panel-soft);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}
.pr-quest-bar {
  margin-top: 6px;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--panel-soft);
  border: 1px solid var(--stroke);
  overflow: hidden;
}
.pr-quest-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--gold-grad);
  box-shadow: 0 0 10px rgba(241, 193, 82, 0.5);
  transition: width var(--dur-slow) var(--ease-out);
}
.pr-quest.done .pr-quest-fill { background: linear-gradient(135deg, var(--ok), #6fe3ae); box-shadow: 0 0 10px rgba(53, 199, 131, 0.55); }
.pr-quest-check {
  color: var(--ok);
  font-weight: 800;
  font-size: 15px;
  text-shadow: 0 0 12px rgba(53, 199, 131, 0.65);
  animation: spinPulse 2.4s ease-in-out infinite;
  flex: 0 0 auto;
}
.pr-quest-count { font-size: 12px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.pr-quest-details { margin-top: 6px; font-size: 12px; font-weight: 700; color: var(--gold); animation: fadeUp var(--dur-fast) var(--ease-out) both; }
.pr-bp-btn { white-space: nowrap; }

/* === battle pass: header === */
.bp-head-grid { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.bp-level { flex: 0 0 auto; text-align: center; }
.bp-level-num {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 46px;
  line-height: 1;
  color: var(--gold);
  text-shadow: 0 0 22px rgba(241, 193, 82, 0.5);
  font-variant-numeric: tabular-nums;
}
.bp-level-lbl { margin-top: 4px; font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-faint); }
.bp-xp { flex: 1 1 200px; min-width: 170px; }
.bp-xp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 13px; font-weight: 700; }
.bp-xp-next { font-size: 11.5px; font-weight: 600; color: var(--text-faint); }
.bp-bar {
  margin-top: 8px;
  height: 10px;
  border-radius: var(--r-pill);
  background: var(--panel-soft);
  border: 1px solid var(--stroke);
  overflow: hidden;
}
.bp-bar-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--gold-grad);
  box-shadow: 0 0 14px rgba(241, 193, 82, 0.55);
  transition: width var(--dur-slow) var(--ease-out);
}
.bp-premium-pill { font-size: 14px; box-shadow: var(--shadow-glow-violet); }
.bp-paywait {
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 13px;
  border-radius: var(--r-md);
  border: 1px dashed rgba(241, 193, 82, 0.45);
  background: rgba(241, 193, 82, 0.06);
  font-size: 13px;
  font-weight: 600;
}
.bp-paywait .spin { animation: spinPulse 1.6s ease-in-out infinite; }

/* === battle pass: level strip === */
@keyframes bpPulse {
  0%, 100% { box-shadow: 0 0 0 rgba(241, 193, 82, 0); }
  50% { box-shadow: 0 0 18px rgba(241, 193, 82, 0.5); }
}
@keyframes bpPulseViolet {
  0%, 100% { box-shadow: 0 0 0 rgba(167, 139, 250, 0); }
  50% { box-shadow: 0 0 18px rgba(167, 139, 250, 0.55); }
}
.bp-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 2px 10px;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.bp-cell {
  flex: 0 0 auto;
  width: 94px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  scroll-snap-align: center;
}
.bp-cell.current { border-color: rgba(241, 193, 82, 0.4); background: rgba(241, 193, 82, 0.06); box-shadow: var(--shadow-glow-gold); }
.bp-cell-num { text-align: center; font-size: 11px; font-weight: 800; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.bp-cell.current .bp-cell-num { color: var(--gold); text-shadow: 0 0 10px rgba(241, 193, 82, 0.6); }
.bp-rw {
  min-height: 66px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 6px;
  border-radius: var(--r-sm);
  border: 1px solid var(--stroke);
  background: var(--panel-soft);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  color: var(--text);
  transition: transform var(--dur-med) var(--spring), border-color var(--dur-fast), background var(--dur-fast), box-shadow var(--dur-med);
}
.bp-rw-title { overflow-wrap: anywhere; }
.bp-rw-state { font-size: 13px; line-height: 1; }
.bp-rw:disabled { cursor: default; }
.bp-rw:disabled:not(.claimed) { opacity: 0.55; }
.bp-rw.claimable { cursor: pointer; border-color: rgba(241, 193, 82, 0.55); background: rgba(241, 193, 82, 0.08); animation: bpPulse 1.8s ease-in-out infinite; }
@media (hover: hover) {
  .bp-rw.claimable:hover { transform: translateY(-2px); }
}
.bp-rw-premium.claimable { border-color: rgba(167, 139, 250, 0.55); background: rgba(167, 139, 250, 0.09); animation: bpPulseViolet 1.8s ease-in-out infinite; }
.bp-rw.claimed { border-color: rgba(53, 199, 131, 0.5); background: rgba(53, 199, 131, 0.08); }
.bp-rw.claimed .bp-rw-state { color: var(--ok); text-shadow: 0 0 10px rgba(53, 199, 131, 0.6); }
.bp-rw.locked .bp-rw-state { opacity: 0.9; }
.bp-rw.busy { pointer-events: none; opacity: 0.7; }
.bp-pop { animation: popIn var(--dur-med) var(--spring) both; }

/* === battle pass: legends === */
.bp-legend + .bp-legend { margin-top: 8px; }
.bp-legend-toggle {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--stroke);
  background: var(--panel-soft);
  color: var(--text);
  font-weight: 700;
  font-size: 13px;
  transition: border-color var(--dur-fast), background var(--dur-fast), transform var(--dur-med) var(--spring);
}
@media (hover: hover) {
  .bp-legend-toggle:hover { border-color: var(--stroke-strong); background: var(--panel); transform: translateY(-1px); }
}
.bp-legend-list { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; max-height: 280px; overflow-y: auto; scrollbar-width: thin; }
.bp-legend-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--stroke);
  background: var(--panel-soft);
  font-size: 12.5px;
  font-weight: 600;
}
.bp-legend-row.claimed { opacity: 0.6; }
.bp-legend-n { width: 22px; flex: 0 0 auto; text-align: center; font-weight: 800; color: var(--text-faint); font-variant-numeric: tabular-nums; }

/* === «Прогресс» — the pass, its track, the quests, and the seal ===

   Every number below is the Claude Design console mock's ПРОГРЕСС block,
   copied rather than eyeballed. Two deliberate departures, both because the
   mock draws data this product does not hold:

   * The mock's shop column is gone. `crowns_add` has no caller, `user_crowns`
     is absent from production, and every ♛ price on it was unpayable — see the
     header of views/progress.js. The seal («что звёзды не купят никогда»)
     takes that column, which is the one block of that section that was true.
   * The mock's reward track is a row of 44px ICON tiles. Ours carries reward
     NAMES, because /chess/api/battlepass serves titles and no icons. The cell
     keeps the mock's 7px gap, its 26×20 mono level pill and its card chrome;
     the tile itself stays a text tile so the reward is legible.

   Breakpoints are @container scene, never @media: at a 1280px window the scene
   is ~858px. See shell.css § WINDOW CLASSES. */

/* host: the screen owns the whole scene, edge to edge. The selector carries
   #scene because shell.css sets `padding-top: 18px` on
   `#scene.shell-scene .container`, which outranks a plain #view rule. */
#view.progress-host,
#scene.shell-scene #view.progress-host {
  max-width: none;
  padding: 0;
  overflow-x: hidden;
}

/* mock (phone): padding:0 15px 12px;gap:11px — the wide 16/18 and 13 arrive
   in the @container block at the foot. */
.pg-view {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 12px 15px 12px;
  min-width: 0;
}
.pg-track { display: flex; flex-direction: column; gap: 11px; min-width: 0; }
.pg-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 11px;
  min-width: 0;
}

/* ── The composed battle pass, given the mock's proportions ──────────────
   Reached through classes battlepass.js already sets and progression.css
   already styles, so this lane restyles the block in place without owning
   views/battlepass.js. */

/* mock hero: gap:18px;padding:14px 18px;border-radius:16px;
   border:1px solid rgba(167,139,250,.24);
   background:linear-gradient(115deg,rgba(44,26,78,.76),rgba(18,12,34,.6)) */
.pg-track > .glass-card:first-child {
  padding: 14px 18px;
  border-radius: 16px;
  border: 1px solid rgba(var(--t-violet), 0.24);
  background: linear-gradient(115deg, rgba(44, 26, 78, 0.76), rgba(18, 12, 34, 0.6));
}
.pg-track .bp-head-grid { gap: 18px; }
/* mock: Unbounded 38px/800, line-height 1, gold, glow 0 0 24px rgba(g,.5) */
.pg-track .bp-level-num { font-size: 38px; text-shadow: 0 0 24px rgba(var(--t-gold), 0.5); }
/* mock: 9px, letter-spacing .14em, uppercase, rgba(236,231,250,.44) */
.pg-track .bp-level-lbl {
  margin-top: 4px;
  font-size: 9px;
  letter-spacing: 0.14em;
  color: rgba(var(--t-mute), 0.44);
}
.pg-track .bp-xp-row { font-size: 13px; }
.pg-track .bp-xp-next { font-size: 11px; color: var(--text-soft); }
/* mock: height:9px;border-radius:5px;background:rgba(167,139,250,.14) */
.pg-track .bp-bar {
  margin-top: 7px;
  height: 9px;
  border-radius: 5px;
  border: 0;
  background: rgba(var(--t-violet), 0.14);
}
/* mock: linear-gradient(90deg,#a78bfa,#f1c152);box-shadow:0 0 14px rgba(g,.4) */
.pg-track .bp-bar-fill {
  background: linear-gradient(90deg, var(--violet), var(--gold));
  box-shadow: 0 0 14px rgba(var(--t-gold), 0.4);
}
/* mock premium button: padding:11px 20px;border-radius:11px;
   background:linear-gradient(135deg,#a78bfa,#7c3aed);Unbounded 12px/800;
   box-shadow:0 8px 24px rgba(124,58,237,.4) */
.pg-track .bp-head-grid .btn {
  padding: 11px 20px;
  border-radius: 11px;
  background: linear-gradient(135deg, var(--violet), var(--violet-600));
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  box-shadow: 0 8px 24px rgba(124, 58, 237, 0.4);
}

/* mock track card: border-radius:16px;border:1px solid rgba(167,139,250,.18);
   background:rgba(18,12,34,.56);padding:12px 14px */
.pg-track > .glass-card {
  border-radius: 16px;
  border: 1px solid rgba(var(--t-violet), 0.18);
  background: var(--panel);
  padding: 12px 14px;
}
/* mock strip: display:flex;gap:7px;overflow-x:auto;padding-bottom:4px */
.pg-track .bp-strip { gap: 7px; padding: 0 0 4px; align-items: stretch; }
/* The mock's track reads as three straight lines — free tiles, level pills,
   premium tiles — because every tile is a fixed 44px square. Ours are text
   tiles that grow with the reward name, so the pills drifted to a different
   height in every cell and the row read as broken. A stretched cell split
   `1fr auto 1fr` puts every pill back on one line without capping the name. */
.pg-track .bp-cell {
  display: grid;
  grid-template-rows: 1fr auto 1fr;
  gap: 4px;
}
/* mock level pill: 26×20;border-radius:6px;mono 10px/700 */
.pg-track .bp-cell-num {
  width: 26px;
  height: 20px;
  margin: 0 auto;
  display: grid;
  place-items: center;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
}
.pg-track .bp-cell.current .bp-cell-num { background: rgba(var(--t-gold), 0.14); }

/* ── Panels: the quests and the seal ────────────────────────────────────── */

/* mock (phone): a bare labelled list; the card chrome is the wide block's. */
.pg-quests,
.pg-never {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.pg-panel-head {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.pg-empty { font-size: 11px; line-height: 1.5; color: var(--text-soft); }
.pg-quest-list { display: flex; flex-direction: column; gap: 7px; min-width: 0; }

/* mock row: gap:10px;padding:10px 11px;border-radius:11px;
   border:1px solid rgba(167,139,250,.14);background:rgba(26,17,48,.5) */
.pg-quest {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 11px;
  border-radius: 11px;
  border: 1px solid var(--hairline);
  /* Literal rather than --row: the token is rgba(24,16,44,.46) and the mock's
     quest row is rgba(26,17,48,.5). */
  background: rgba(26, 17, 48, 0.5);
  min-width: 0;
}
/* mock: the finished row sits back at opacity .5 */
.pg-quest.is-done { opacity: 0.5; }
/* The in-flight row: the final geometry, nothing claimed. 44px is the row's
   own height at this padding (10 + 24 + 10). */
.pg-quest.is-skel {
  height: 44px;
  border-style: dashed;
  background: var(--panel-soft);
}
.pg-quest-icon { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.pg-quest-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.pg-quest-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
/* mock: font-size:11px;font-weight:700;line-height:1.3 */
.pg-quest-name { font-size: 11px; font-weight: 700; line-height: 1.3; min-width: 0; }
.pg-quest-count {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-faint);
}
/* mock bar: height:4px;border-radius:3px;background:rgba(167,139,250,.16) */
.pg-quest-bar {
  height: 4px;
  border-radius: 3px;
  background: rgba(var(--t-violet), 0.16);
  overflow: hidden;
}
.pg-quest-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--violet), var(--gold));
  transition: width var(--dur-slow) var(--ease-out);
}
.pg-quest.is-done .pg-quest-fill { background: var(--ok); }
/* mock reward: font-size:9px;font-weight:800;white-space:nowrap */
.pg-quest-rw {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 9px;
  font-weight: 800;
  color: rgba(var(--t-mute), 0.42);
}
.pg-quest-rw.is-done { color: var(--ok); }

/* The seal. Not in the mock — it stands where the mock's ♛ shop stood, in the
   mock's own panel grammar, because it is what remains true of that section. */
.pg-never {
  gap: 9px;
  padding: 14px;
  border-radius: 15px;
  border: 1px solid rgba(var(--t-gold), 0.3);
  background: rgba(26, 19, 8, 0.36);
}
.pg-never-title {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 800;
  color: var(--gold);
}
.pg-never-lead { font-size: 11px; line-height: 1.6; color: rgba(var(--t-mute), 0.62); }
.pg-never-list { display: flex; flex-wrap: wrap; gap: 6px; }
.pg-never-chip {
  padding: 4px 9px;
  border-radius: 7px;
  border: 1px solid rgba(var(--t-violet), 0.22);
  background: var(--panel-soft);
  font-size: 9.5px;
  font-weight: 700;
  color: var(--text-soft);
  white-space: nowrap;
}
.pg-store {
  white-space: nowrap;
  min-height: 44px;
  padding: 11px;
  border-radius: 11px;
  border: 1px solid rgba(var(--t-violet), 0.26);
  background: var(--panel-soft);
  font: inherit;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-soft);
  cursor: pointer;
}
@media (hover: hover) {
  .pg-store:hover { border-color: rgba(var(--t-gold), 0.45); color: var(--gold); }
}

/* ── Medium scene: the panels take their card chrome ───────────────────── */

@container scene (min-width: 600px) {
  .pg-view { gap: 13px; padding: 16px 18px; }
  .pg-track { gap: 13px; }
  .pg-cols { gap: 12px; }

  .pg-quests {
    gap: 9px;
    padding: 15px 16px;
    border-radius: 16px;
    border: 1px solid rgba(var(--t-violet), 0.2);
    background: rgba(18, 12, 34, 0.5);
  }
  .pg-panel-head { font-size: 11px; }
  .pg-never { gap: 9px; padding: 15px 16px; border-radius: 16px; }
  .pg-never-title { font-size: 13px; }
  .pg-store { align-self: flex-start; min-height: 38px; padding: 10px 14px; border-radius: 10px; }
}

/* ── Wide scene: the mock's two columns ────────────────────────────────── */

@container scene (min-width: 620px) {
  .pg-cols { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
}

/* The phone reading of the pass strip, kept from the previous port — now asked
   of the SCENE, like the two blocks above it (shell.css «WINDOW CLASSES»).
   520 is kept as the number; what changes is the box it is asked of, and the
   place that matters is not the one you would guess. In UPRIGHT windows the
   two units agree at this threshold: below 800px the shell is one column and
   scene width == window width, and above 800 the narrowest scene any window
   produces is 527. Measured at 390 / 905 / 1280: byte-identical before and
   after.
   SIDEWAYS THEY DISAGREE BY 408px, and that is where this now fires. A
   notched phone in landscape spends 47px of window on each ear (§safe area in
   shell.css) and 61–77 more on the rail before the scene sees anything:
   measured 844x390 -> scene 436, and 932x430 -> scene 460. So the pass strip
   was drawing its 94px desktop cells inside a 436px box, because 844 is not
   less than 520. After: 80px cells, `.bp-cell` 94 -> 80 and `.bp-rw` 80 -> 66
   wide on /progress and /battlepass at 844x390, with no new overflow. */
@container scene (max-width: 520px) {
  .bp-cell { width: 80px; }
  .bp-level-num { font-size: 38px; }
  .bp-head-grid { gap: 14px; }
}

/* ── Huge scene — the fifth window class (shell.css «WINDOW CLASSES») ─────
   Both screens are FRAME_HOME (ui/shell.js): the scene is the window minus
   the rail, so 1728×1080 is a 1650×1022 scene and the class is `huge`. The
   two screens this file carries answer differently because they ARE
   different:

   /battlepass is the track and nothing else — so at huge the strip stops
   being a horizontal scroller and shows the WHOLE season: three rows of
   beads, every level on screen at once (measured before: 68% fill, and the
   current level only visible after a scroll the screen never advertised).
   The reward detail — the legends — sits two abreast under it rather than
   stacked, since the width is there and the stack only spent height.

   /progress carries the quests and the seal UNDER the track — wrapping the
   strip there would push them past the frame — so its track keeps the
   scroller and grows its tiles instead, and the quest rows take the 52px
   the density law gives them (they were 44, under the floor). Measured
   before: 85%. */
@container scene (min-width: 1600px) {
  /* /battlepass: the whole season at once. The legend selectors carry
     .view-battlepass because the SAME block is composed onto /progress,
     where the legends must keep their stack — side by side there they
     would steal the height the quests are spending. */
  .view-battlepass .bp-strip { flex-wrap: wrap; overflow-x: visible; scroll-snap-type: none; }
  .view-battlepass .bp-cell { width: 88px; }
  .view-battlepass .bp-rw { min-height: 54px; }
  .view-battlepass .bp-level-num { font-size: 56px; }
  .view-battlepass .bp-legend-card { display: flex; gap: 12px; }
  .view-battlepass .bp-legend-card .bp-legend { flex: 1 1 0; min-width: 0; }
  .view-battlepass .bp-legend-card .bp-legend + .bp-legend { margin-top: 0; }

  /* /progress: bigger beads on the scroller, denser cards below */
  .pg-track .bp-cell { width: 110px; }
  .pg-track .bp-rw { min-height: 96px; }
  .pg-view { gap: 16px; }
  .pg-track { gap: 16px; }
  .pg-quest { padding: 12px 13px; }
  .pg-quest-name { font-size: 12px; }
  .pg-never-lead { font-size: 12px; }
  .pg-never-chip { padding: 6px 12px; font-size: 11px; }
}

/* 2560×1440 (scene 2482): same content, breathing larger inside the 1400px
   container cap. The wrapped season grows its tiles; the composed track and
   the quest rows grow theirs. */
@container scene (min-width: 2200px) {
  .view-battlepass .bp-rw { min-height: 72px; }
  .view-battlepass .bp-cell { width: 96px; }
  .pg-track .bp-rw { min-height: 124px; }
  .pg-track .bp-cell { width: 120px; }
  .pg-quest { padding: 14px 15px; }
}
