:root {
  --rose-50: #fff6fa;
  --rose-100: #ffe7f2;
  --rose-200: #ffc7e1;
  --rose-300: #ff9ccf;
  --rose-400: #ff72bd;
  --rose-500: #ff4fa8;
  --rose-600: #e8298f;
  --plum-900: #2b1025;
  --plum-800: #401833;
  --plum-700: #58203f;
  --plum-600: #76305d;
  --cyan-300: #7fe7ef;
  --cyan-400: #24c7d9;
  --mint-300: #8cf0c5;
  --gold-300: #ffe06b;
  --gold-500: #ffb02e;
  --cream: #fffaf4;
  --ink: var(--plum-900);
  --muted: #806179;
  --surface: rgba(255, 255, 255, 0.72);
  --surface-strong: rgba(255, 255, 255, 0.92);
  --line: rgba(88, 32, 63, 0.14);
  --shadow-soft: 0 22px 70px rgba(88, 32, 63, 0.16);
  --shadow-pop: 0 18px 0 rgba(88, 32, 63, 0.13), 0 28px 70px rgba(255, 79, 168, 0.24);
  --radius-xs: 8px;
  --radius-sm: 14px;
  --radius-md: 22px;
  --radius-lg: 34px;
  --header-h: 82px;
  --content: 1180px;
  --display: "Unbounded", "Nunito", system-ui, sans-serif;
  --body: "Nunito", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Spring easing curves (5.2). Used by chess board piece pickup/land,
     drag-ghost lift, and selected-square pulse. The 'overshoot' variant
     bounces past the target value before settling — gives the board a
     tactile, weighty feel even on flat CSS-only animations. */
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-spring-soft: cubic-bezier(.4, 1.3, .55, 1);
  --ease-out-elastic: cubic-bezier(.18, 1.5, .35, 1.05);

  /* === Modal design language tokens (skill-redesign-piped-truffle).
     Single source of truth for all 8 chess auxiliary modals so that
     surface treatments, shadows, easing and stagger feel uniform
     instead of being hand-rolled per modal. */
  --modal-bg-glass: linear-gradient(165deg, rgba(255, 250, 244, .96), rgba(255, 232, 244, .9));
  --modal-bg-glass-warm: linear-gradient(165deg, #fffaf4 0%, #fff5fa 60%, #ffeef5 100%);
  --modal-border: 1px solid rgba(255, 255, 255, .96);
  --modal-inner-glow: inset 0 1px 0 rgba(255, 255, 255, .96), inset 0 0 0 1px rgba(255, 200, 224, .32);
  --modal-shadow: 0 30px 70px rgba(46, 14, 32, .34), 0 8px 16px rgba(116, 18, 70, .16);
  --modal-backdrop: radial-gradient(circle at 50% 0%, rgba(255, 144, 203, .36), transparent 58%), rgba(46, 14, 32, .58);
  --modal-blur: blur(12px);
  --modal-radius-sheet: 26px;
  --modal-radius-card: 22px;
  --modal-radius-toast: 18px;
  --modal-easing-spring: cubic-bezier(.34, 1.56, .64, 1);
  --modal-easing-soft: cubic-bezier(.18, .76, .35, 1.05);
  --modal-stagger: .06s;

  /* === Depth stack tokens (visual-reference-audit 2026-05-05).
     Concept reference shows every surface stacks 3-4 shadow layers:
     colored ambient + tight drop + inset top-pearl + inset bottom-tint.
     Without these, decorations read as stickers on flat paper. */
  --depth-1:
    0 4px 10px rgba(216, 24, 121, .14),
    0 1px 3px rgba(46, 14, 32, .12),
    inset 0 1px 0 rgba(255, 255, 255, .82),
    inset 0 -1px 0 rgba(216, 24, 121, .12);
  --depth-2:
    0 12px 24px rgba(216, 24, 121, .18),
    0 3px 8px rgba(46, 14, 32, .14),
    inset 0 1px 0 rgba(255, 255, 255, .92),
    inset 0 -2px 4px rgba(216, 24, 121, .08);
  --depth-3:
    0 30px 70px rgba(46, 14, 32, .34),
    0 8px 16px rgba(116, 18, 70, .22),
    0 0 0 1px rgba(255, 200, 224, .42),
    inset 0 2px 0 rgba(255, 255, 255, .96),
    inset 0 -3px 6px rgba(216, 24, 121, .1);
  --depth-4:
    0 18px 32px rgba(216, 24, 121, .42),
    0 6px 12px rgba(196, 26, 100, .28),
    inset 0 2px 0 rgba(255, 255, 255, .42),
    inset 0 -2px 6px rgba(116, 12, 60, .26);
  --depth-pressed:
    0 2px 4px rgba(216, 24, 121, .26),
    inset 0 2px 6px rgba(116, 12, 60, .42),
    inset 0 -1px 0 rgba(255, 255, 255, .12);

  /* Colored ambient shadow tints — apply contextually per character */
  --shadow-tint-rose: rgba(216, 24, 121, .22);
  --shadow-tint-gold: rgba(255, 184, 92, .22);
  --shadow-tint-plum: rgba(88, 32, 63, .26);
  --shadow-tint-lavender: rgba(141, 120, 180, .22);

  /* === Character asset inversion (2026-05-07).
     Default values match canonical pairing: goose=white, cat=black.
     When body[data-chess-inverted="1"] (chosen character is on opposing
     chess side: goose+black or cat+white), 25 PNGs swap to `-inv` variants
     via the override block below. Assets without `-inv` companions
     (props/, capture-burst, daily-badge, etc.) keep direct url() in their
     own rules — they're neutral decorations. */
  --asset-avatar-cat: url("assets/chess/final-png/characters/avatar-cat.png");
  --asset-avatar-goose: url("assets/chess/final-png/characters/avatar-goose.png");
  --asset-hero-cat: url("assets/chess/final-png/characters/hero-cat.png");
  --asset-hero-goose: url("assets/chess/final-png/characters/hero-goose.png");
  --asset-logo-cat: url("assets/chess/final-png/characters/logo-cat.png");
  --asset-side-cat: url("assets/chess/final-png/characters/side-cat.png");
  --asset-side-goose: url("assets/chess/final-png/characters/side-goose.png");
  --asset-cat-step: url("assets/chess/final-png/effects/cat-step.png");
  --asset-goose-step: url("assets/chess/final-png/effects/goose-step.png");
  --asset-piece-white-king: url("assets/chess/final-png/pieces/piece-white-king.png");
  --asset-piece-white-queen: url("assets/chess/final-png/pieces/piece-white-queen.png");
  --asset-piece-white-rook: url("assets/chess/final-png/pieces/piece-white-rook.png");
  --asset-piece-white-bishop: url("assets/chess/final-png/pieces/piece-white-bishop.png");
  --asset-piece-white-knight: url("assets/chess/final-png/pieces/piece-white-knight.png");
  --asset-piece-white-pawn: url("assets/chess/final-png/pieces/piece-white-pawn.png");
  --asset-piece-black-king: url("assets/chess/final-png/pieces/piece-black-king.png");
  --asset-piece-black-queen: url("assets/chess/final-png/pieces/piece-black-queen.png");
  --asset-piece-black-rook: url("assets/chess/final-png/pieces/piece-black-rook.png");
  --asset-piece-black-bishop: url("assets/chess/final-png/pieces/piece-black-bishop.png");
  --asset-piece-black-knight: url("assets/chess/final-png/pieces/piece-black-knight.png");
  --asset-piece-black-pawn: url("assets/chess/final-png/pieces/piece-black-pawn.png");
  --asset-lesson-badge: url("assets/chess/final-png/ui/lesson-badge.png");
  --asset-result-draw: url("assets/chess/final-png/ui/result-draw.png");
  --asset-result-win-cat: url("assets/chess/final-png/ui/result-win-cat.png");
  --asset-result-win-goose: url("assets/chess/final-png/ui/result-win-goose.png");
}

body[data-chess-inverted="1"] {
  /* Avatar / hero / logo / result / lesson — simple -inv recolor.
     Character swap rule already selects correct file by player character;
     -inv just shifts coat color to match the side that character now plays. */
  --asset-avatar-cat: url("assets/chess/final-png/characters/avatar-cat-inv.png");
  --asset-avatar-goose: url("assets/chess/final-png/characters/avatar-goose-inv.png");
  --asset-hero-cat: url("assets/chess/final-png/characters/hero-cat-inv.png");
  --asset-hero-goose: url("assets/chess/final-png/characters/hero-goose-inv.png");
  --asset-logo-cat: url("assets/chess/final-png/characters/logo-cat-inv.png");
  --asset-lesson-badge: url("assets/chess/final-png/ui/lesson-badge-inv.png");
  --asset-result-draw: url("assets/chess/final-png/ui/result-draw-inv.png");
  --asset-result-win-cat: url("assets/chess/final-png/ui/result-win-cat-inv.png");
  --asset-result-win-goose: url("assets/chess/final-png/ui/result-win-goose-inv.png");

  /* Side-portraits / step-effects / pieces — CROSS-MAP across characters.
     `.white-side` / `[data-active-chess-turn="w"]` / `.piece-w-*` are
     keyed on chess color (which doesn't change). When inverted, the
     character occupying that color flips: cat now sits on white side
     (so we pull from the cat file but recolored white via -inv) and
     goose sits on black side. Without this swap, white pieces would
     render as a black goose (correct character but wrong piece-color)
     creating an unreadable board. */
  --asset-side-goose: url("assets/chess/final-png/characters/side-cat-inv.png");
  --asset-side-cat: url("assets/chess/final-png/characters/side-goose-inv.png");
  --asset-goose-step: url("assets/chess/final-png/effects/cat-step-inv.png");
  --asset-cat-step: url("assets/chess/final-png/effects/goose-step-inv.png");
  --asset-piece-white-king: url("assets/chess/final-png/pieces/piece-black-king-inv.png");
  --asset-piece-white-queen: url("assets/chess/final-png/pieces/piece-black-queen-inv.png");
  --asset-piece-white-rook: url("assets/chess/final-png/pieces/piece-black-rook-inv.png");
  --asset-piece-white-bishop: url("assets/chess/final-png/pieces/piece-black-bishop-inv.png");
  --asset-piece-white-knight: url("assets/chess/final-png/pieces/piece-black-knight-inv.png");
  --asset-piece-white-pawn: url("assets/chess/final-png/pieces/piece-black-pawn-inv.png");
  --asset-piece-black-king: url("assets/chess/final-png/pieces/piece-white-king-inv.png");
  --asset-piece-black-queen: url("assets/chess/final-png/pieces/piece-white-queen-inv.png");
  --asset-piece-black-rook: url("assets/chess/final-png/pieces/piece-white-rook-inv.png");
  --asset-piece-black-bishop: url("assets/chess/final-png/pieces/piece-white-bishop-inv.png");
  --asset-piece-black-knight: url("assets/chess/final-png/pieces/piece-white-knight-inv.png");
  --asset-piece-black-pawn: url("assets/chess/final-png/pieces/piece-white-pawn-inv.png");
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  min-width: 320px;
  margin: 0;
  color: var(--ink);
  font-family: var(--body);
  font-weight: 700;
  letter-spacing: 0;
  background:
    radial-gradient(circle at 14% 18%, rgba(127, 231, 239, 0.35), transparent 25rem),
    radial-gradient(circle at 88% 2%, rgba(255, 224, 107, 0.34), transparent 21rem),
    linear-gradient(135deg, #fff7fb 0%, #ffd8ea 32%, #ff8fcb 64%, #ffc6df 100%);
  background-attachment: fixed;
  overflow-x: hidden;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background-image:
    linear-gradient(45deg, rgba(255,255,255,.18) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(255,255,255,.18) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(255,255,255,.18) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(255,255,255,.18) 75%);
  background-position: 0 0, 0 12px, 12px -12px, -12px 0;
  background-size: 24px 24px;
  opacity: .28;
  pointer-events: none;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle, rgba(255,255,255,.98) 0 2px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.65) 0 1px, transparent 2px);
  background-position: 8% 11%, 88% 14%;
  background-size: 220px 220px, 160px 160px;
  animation: sparkleDrift 16s linear infinite;
}

button,
input,
select {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  border: 0;
  cursor: pointer;
}

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

img,
svg,
canvas {
  max-width: 100%;
}

::selection {
  color: #fff;
  background: var(--rose-600);
}

.skip-link {
  position: fixed;
  left: 16px;
  top: 10px;
  z-index: 50;
  transform: translateY(-140%);
  padding: 12px 18px;
  border-radius: var(--radius-xs);
  color: #fff;
  background: var(--plum-800);
  font-weight: 700;
  transition: transform .2s ease, outline-offset .15s ease;
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 3px solid #ffe06b;
  outline-offset: 3px;
  box-shadow: 0 8px 22px rgba(46, 14, 32, .42);
}

/* Chess page: high-contrast keyboard focus ring on every key action.
   Hover/click states keep their existing colour shifts; this rule only
   triggers on real keyboard focus (not mouse-down) thanks to
   :focus-visible heuristics. */
body[data-page="chess"] .chess-header-cta:focus-visible,
body[data-page="chess"] .header-actions .icon-button:focus-visible,
body[data-page="chess"] .dock-actions button:focus-visible,
body[data-page="chess"] .chess-board-dock button:focus-visible,
body[data-page="chess"] .chess-bottom-sheet-tabs button:focus-visible,
body[data-page="chess"] .chess-game-action:focus-visible,
body[data-page="chess"] .chess-game-setting:focus-visible,
body[data-page="chess"] .chess-start-quick:focus-visible,
body[data-page="chess"] .chess-start-grid button:focus-visible,
body[data-page="chess"] .chess-start-levels button:focus-visible,
body[data-page="chess"] .chess-start-back:focus-visible,
body[data-page="chess"] .chess-start-close:focus-visible,
body[data-page="chess"] .chess-puzzle-close:focus-visible,
body[data-page="chess"] .chess-puzzle-options button:focus-visible,
body[data-page="chess"] .chess-shop-item:focus-visible,
body[data-page="chess"] [data-chess-board] .chess-square:focus-visible {
  outline: 3px solid var(--rose-600, #d71879);
  outline-offset: 3px;
  z-index: 5;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  min-height: var(--header-h);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  width: min(var(--content), calc(100% - 32px));
  margin: 14px auto 0;
  padding: 12px 14px 12px 16px;
  border: 1px solid rgba(255, 255, 255, .64);
  border-radius: 999px;
  background: rgba(255, 250, 252, .78);
  backdrop-filter: blur(22px);
  box-shadow: var(--shadow-soft);
}

.compact-header {
  margin-top: 10px;
}

.brand {
  display: inline-grid;
  grid-template-columns: 48px auto;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-mark {
  width: 48px;
  height: 48px;
  filter: drop-shadow(0 12px 18px rgba(255, 79, 168, .28));
}

.brand strong {
  display: block;
  font-family: var(--display);
  font-size: 1rem;
  line-height: 1.05;
}

.brand small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: .76rem;
  line-height: 1;
  text-transform: lowercase;
}

.top-nav {
  justify-self: center;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .56);
}

.top-nav a {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border-radius: 999px;
  color: var(--plum-700);
  font-size: .9rem;
  transition: background .2s ease, color .2s ease, transform .2s ease;
}

.top-nav a:hover,
.top-nav a:focus-visible {
  color: #fff;
  background: var(--plum-800);
  transform: translateY(-1px);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.icon-button,
.pill-button,
.segmented,
.primary-action,
.secondary-action,
.card-primary,
.card-secondary,
.control-grid button,
.chip-row button,
.lesson-card button {
  position: relative;
  isolation: isolate;
  transition: transform .2s ease, box-shadow .2s ease, background .2s ease, color .2s ease, border-color .2s ease;
}

.icon-button {
  width: 44px;
  height: 44px;
  display: inline-grid;
  place-items: center;
  border-radius: 999px;
  color: var(--plum-800);
  background: #fff;
  box-shadow: 0 10px 22px rgba(88, 32, 63, .12);
}

.icon-button:hover,
.icon-button:focus-visible,
.pill-button:hover,
.pill-button:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 16px 28px rgba(88, 32, 63, .18);
}

.pill-button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 15px;
  border-radius: 999px;
  color: #fff;
  background: linear-gradient(135deg, var(--plum-800), var(--rose-600));
  box-shadow: 0 12px 24px rgba(232, 41, 143, .24);
}

.menu-toggle {
  display: none;
}

.hero-section {
  position: relative;
  width: min(1360px, calc(100% - 28px));
  min-height: calc(100svh - var(--header-h) - 20px);
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(420px, 1.08fr);
  align-items: center;
  gap: 28px;
  margin: 0 auto;
  padding: 56px 0 44px;
}

.hero-copy {
  max-width: 620px;
  width: 100%;
  min-width: 0;
  padding-left: max(0px, calc((100% - var(--content)) / 2));
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  color: var(--rose-600);
  font-family: var(--display);
  font-size: .78rem;
  line-height: 1.2;
  text-transform: uppercase;
}

.eyebrow::before {
  content: "";
  width: 20px;
  height: 20px;
  border-radius: 6px;
  background:
    linear-gradient(135deg, #fff 0 30%, transparent 31%),
    linear-gradient(135deg, var(--cyan-300), var(--rose-400));
  box-shadow: 0 8px 16px rgba(255, 79, 168, .2);
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--display);
  line-height: 1.02;
  letter-spacing: 0;
}

h1 {
  max-width: 780px;
  font-size: 4.15rem;
}

h2 {
  font-size: 2.2rem;
}

h3 {
  font-size: 1.35rem;
}

p {
  margin: 0;
}

.hero-lead,
.section-heading p,
.club-copy p,
.academy-preview p,
.game-hero p,
.academy-hero p,
.soft-note {
  color: var(--plum-700);
  font-size: 1.05rem;
  line-height: 1.65;
}

.hero-lead {
  max-width: 620px;
  margin-top: 22px;
  font-size: 1.18rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.primary-action,
.secondary-action {
  min-height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 22px;
  border-radius: 999px;
  font-weight: 900;
}

.primary-action {
  color: #fff;
  background:
    linear-gradient(135deg, rgba(255,255,255,.28), transparent 35%),
    linear-gradient(135deg, var(--rose-600), var(--rose-400) 54%, var(--cyan-400));
  box-shadow: 0 18px 32px rgba(232, 41, 143, .28);
}

.primary-action:hover,
.primary-action:focus-visible,
.card-primary:hover,
.card-primary:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 24px 40px rgba(232, 41, 143, .34);
}

.secondary-action {
  color: var(--plum-800);
  border: 1px solid rgba(88, 32, 63, .13);
  background: rgba(255,255,255,.72);
  box-shadow: 0 14px 32px rgba(88, 32, 63, .12);
}

.secondary-action:hover,
.secondary-action:focus-visible,
.card-secondary:hover,
.card-secondary:focus-visible,
.control-grid button:hover,
.control-grid button:focus-visible,
.chip-row button:hover,
.chip-row button:focus-visible,
.lesson-card button:hover,
.lesson-card button:focus-visible {
  color: #fff;
  background: var(--plum-800);
  transform: translateY(-2px);
}

.compact {
  min-height: 46px;
  padding: 0 18px;
}

.full {
  width: 100%;
}

.signal-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}

.signal-strip span,
.meta-row span,
.mini-score span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, .72);
  border-radius: 999px;
  color: var(--plum-700);
  background: rgba(255,255,255,.54);
  box-shadow: 0 10px 24px rgba(88,32,63,.08);
}

.hero-stage {
  position: relative;
  min-height: 650px;
  overflow: hidden;
  border-radius: 48px;
  background:
    linear-gradient(145deg, rgba(255, 255, 255, .36), rgba(255,255,255,.05)),
    linear-gradient(135deg, rgba(255, 79, 168, .92), rgba(184, 44, 190, .64) 54%, rgba(36, 199, 217, .72));
  box-shadow: var(--shadow-pop);
}

.hero-stage::before,
.hero-stage::after {
  content: "";
  position: absolute;
  pointer-events: none;
}

.hero-stage::before {
  inset: 0;
  background:
    linear-gradient(110deg, transparent 0 24%, rgba(255,255,255,.34) 24% 26%, transparent 26% 54%, rgba(255,255,255,.2) 54% 56%, transparent 56%),
    radial-gradient(circle at 72% 18%, rgba(255,224,107,.55), transparent 11rem),
    radial-gradient(circle at 24% 72%, rgba(140,240,197,.42), transparent 10rem);
  animation: stageShimmer 8s ease-in-out infinite alternate;
}

.hero-stage::after {
  width: 160%;
  height: 80px;
  left: -30%;
  top: 52%;
  transform: rotate(-18deg);
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.72) 0 22px, rgba(255,255,255,.12) 22px 40px);
  opacity: .18;
}

.glow-orbit {
  position: absolute;
  width: 76%;
  height: 38px;
  left: 12%;
  top: 14%;
  transform: rotate(-16deg);
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.52), transparent);
  opacity: .42;
  animation: ribbonSweep 7s ease-in-out infinite;
}

.phone-frame {
  position: absolute;
  width: 230px;
  min-height: 444px;
  padding: 15px;
  border: 10px solid #2e2230;
  border-radius: 36px;
  background: #2e2230;
  box-shadow: 0 28px 48px rgba(43,16,37,.32);
  transform-style: preserve-3d;
}

.phone-main {
  left: 50%;
  top: 11%;
  width: 252px;
  min-height: 488px;
  transform: translateX(-50%) rotate(-7deg);
  animation: floatMain 4.8s ease-in-out infinite;
}

.phone-left {
  left: 6%;
  top: 22%;
  transform: rotate(-18deg);
  opacity: .94;
  animation: floatLeft 5.6s ease-in-out infinite;
}

.phone-right {
  right: 5%;
  top: 28%;
  transform: rotate(15deg);
  opacity: .94;
  animation: floatRight 5.2s ease-in-out infinite;
}

.phone-top {
  position: absolute;
  top: 6px;
  left: 50%;
  width: 82px;
  height: 18px;
  border-radius: 0 0 14px 14px;
  background: #2e2230;
  transform: translateX(-50%);
  z-index: 2;
}

.phone-screen {
  position: relative;
  min-height: 414px;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 22px;
  padding: 34px 16px 20px;
  overflow: hidden;
  border-radius: 24px;
  color: #fff;
  background:
    radial-gradient(circle at 28% 20%, rgba(255,255,255,.48), transparent 7rem),
    linear-gradient(155deg, #ff78c2, #d737c5 54%, #8b3ed5);
}

.screen-label {
  position: absolute;
  top: 22px;
  left: 16px;
  right: 16px;
  overflow-wrap: anywhere;
  font-family: var(--display);
  font-size: .88rem;
  text-shadow: 0 2px 0 rgba(88, 32, 63, .28);
}

.mini-cards {
  display: flex;
  transform: rotate(-8deg);
}

.mini-cards span,
.playing-card {
  width: 66px;
  height: 90px;
  display: grid;
  place-items: center;
  margin-left: -12px;
  border: 2px solid rgba(88, 32, 63, .16);
  border-radius: 14px;
  color: var(--plum-800);
  font-family: var(--display);
  background: #fff;
  box-shadow: 0 12px 22px rgba(88,32,63,.18);
}

.mini-cards span:first-child {
  margin-left: 0;
}

.phone-screen button {
  min-width: 126px;
  min-height: 54px;
  border-radius: 999px;
  color: #fff;
  font-family: var(--display);
  text-transform: uppercase;
  background: linear-gradient(180deg, #64eaf2, #0db5cf);
  box-shadow: inset 0 4px 0 rgba(255,255,255,.34), 0 14px 0 #087d94, 0 22px 26px rgba(43,16,37,.25);
}

.mini-board {
  width: 150px;
  height: 150px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  overflow: hidden;
  border: 5px solid rgba(255,255,255,.88);
  border-radius: 18px;
  box-shadow: 0 20px 34px rgba(43,16,37,.26);
}

.mini-board span:nth-child(odd) {
  background: #ffe7f2;
}

.mini-board span:nth-child(even) {
  background: #ff72bd;
}

.mini-board span:nth-child(6)::after,
.mini-board span:nth-child(10)::after {
  content: "♞";
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: var(--plum-800);
  font-size: 1.45rem;
}

.mini-billiards {
  justify-content: center;
}

.cue-line {
  width: 170px;
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold-300), #fff);
  transform: rotate(-22deg);
  box-shadow: 0 10px 20px rgba(43,16,37,.25);
}

.pool-ball {
  position: absolute;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 4px solid rgba(255,255,255,.75);
  border-radius: 50%;
  color: #fff;
  font-family: var(--display);
  box-shadow: inset -8px -10px 12px rgba(43,16,37,.22), 0 12px 18px rgba(43,16,37,.2);
}

.ball-a { left: 44px; top: 170px; background: #2b1025; }
.ball-b { right: 42px; top: 228px; background: #24c7d9; }
.ball-c { left: 104px; bottom: 90px; background: #ffb02e; }

.floating-badge {
  position: absolute;
  z-index: 4;
  display: grid;
  grid-template-columns: 36px auto;
  align-items: center;
  gap: 0 9px;
  min-width: 164px;
  padding: 12px 14px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 18px;
  background: rgba(255,255,255,.74);
  backdrop-filter: blur(16px);
  box-shadow: 0 18px 32px rgba(88,32,63,.16);
}

.floating-badge i {
  grid-row: 1 / span 2;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--plum-800);
  background: var(--gold-300);
}

.floating-badge strong {
  font-family: var(--display);
}

.floating-badge span {
  color: var(--muted);
  font-size: .82rem;
}

.badge-coins {
  right: 8%;
  bottom: 12%;
}

.badge-streak {
  left: 7%;
  bottom: 10%;
}

.section-shell {
  width: min(var(--content), calc(100% - 32px));
  margin: 0 auto 30px;
}

.section-heading {
  max-width: 720px;
  margin-bottom: 24px;
}

.section-heading h2,
.club-copy h2,
.academy-preview h2,
.mission-panel h2,
.academy-hero h1,
.game-hero h1 {
  margin-bottom: 14px;
}

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 22px;
}

.segmented {
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 16px;
  border: 1px solid rgba(255,255,255,.66);
  border-radius: 999px;
  color: var(--plum-700);
  background: rgba(255,255,255,.58);
  box-shadow: 0 12px 26px rgba(88,32,63,.08);
}

.segmented.active {
  color: #fff;
  border-color: transparent;
  background: var(--plum-800);
  box-shadow: 0 14px 30px rgba(43,16,37,.2);
}

.game-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.game-card {
  position: relative;
  min-height: 520px;
  display: grid;
  grid-template-rows: 230px 1fr;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.72);
  border-radius: 26px;
  background: var(--surface);
  box-shadow: var(--shadow-soft);
  backdrop-filter: blur(18px);
  transform: translateZ(0);
}

.game-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(125deg, rgba(255,255,255,.5), transparent 30%, transparent 70%, rgba(255,255,255,.24));
  opacity: .68;
}

.game-card.is-hidden {
  display: none;
}

.game-art {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(circle at 18% 16%, rgba(255,255,255,.9), transparent 4.8rem),
    linear-gradient(145deg, var(--rose-300), var(--rose-600));
}

.game-art::after {
  content: "";
  position: absolute;
  inset: auto -20% -35% -20%;
  height: 70%;
  border-radius: 50%;
  background: rgba(255,255,255,.24);
  transform: rotate(-8deg);
}

.chess-card .game-art {
  background:
    linear-gradient(45deg, rgba(255,255,255,.16) 25%, transparent 25% 75%, rgba(255,255,255,.16) 75%),
    linear-gradient(45deg, rgba(255,255,255,.16) 25%, transparent 25% 75%, rgba(255,255,255,.16) 75%),
    linear-gradient(145deg, #ff8fcb, #d944b8 62%, #7fe7ef);
  background-position: 0 0, 28px 28px, 0 0;
  background-size: 56px 56px, 56px 56px, auto;
}

.blackjack-card .game-art {
  background: linear-gradient(145deg, #ffb4d7, #d93ab5 52%, #32162c);
}

.poker-card .game-art {
  background: linear-gradient(145deg, #ffe06b, #ff72bd 42%, #6e2aa5);
}

.billiards-card .game-art {
  background: linear-gradient(145deg, #8cf0c5, #ff9ccf 52%, #411a39);
}

.game-piece {
  position: relative;
  z-index: 2;
  color: #fff;
  font-size: 8rem;
  text-shadow: 0 14px 0 rgba(88,32,63,.15), 0 28px 40px rgba(43,16,37,.35);
  animation: pieceBob 4s ease-in-out infinite;
}

.spark {
  position: absolute;
  z-index: 3;
  width: 28px;
  height: 28px;
}

.spark::before,
.spark::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: #fff;
}

.spark::before { width: 6px; height: 28px; border-radius: 999px; }
.spark::after { width: 28px; height: 6px; border-radius: 999px; }
.spark-one { left: 18%; top: 18%; animation: twinkle 2s ease-in-out infinite; }
.spark-two { right: 16%; bottom: 24%; animation: twinkle 2.8s ease-in-out infinite reverse; }

.blackjack-card .playing-card {
  position: absolute;
  z-index: 2;
}

.card-one { left: 25%; top: 28%; transform: rotate(-14deg); }
.card-two { left: 42%; top: 22%; transform: rotate(4deg); }
.card-three { right: 18%; top: 35%; transform: rotate(17deg); }

.chip {
  position: absolute;
  width: 72px;
  height: 72px;
  border: 10px dashed #fff;
  border-radius: 50%;
  box-shadow: inset 0 0 0 12px rgba(255,255,255,.36), 0 16px 26px rgba(43,16,37,.24);
}

.chip-a { left: 16%; top: 24%; background: var(--rose-600); }
.chip-b { right: 14%; top: 30%; background: var(--cyan-400); }
.chip-c { left: 38%; bottom: 20%; background: var(--gold-500); }
.poker-ace { position: relative; z-index: 3; transform: rotate(-8deg); }

.billiard-art {
  border: 14px solid rgba(43,16,37,.7);
}

.table-pocket {
  position: absolute;
  z-index: 3;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: #1c0c19;
}

.p1 { left: 14px; top: 14px; }
.p2 { right: 14px; top: 14px; }
.p3 { right: 14px; bottom: 14px; }
.art-white { left: 34%; top: 48%; background: #fff; color: var(--plum-800); }
.art-eight { right: 25%; top: 34%; background: var(--plum-900); }
.cue-stick {
  position: absolute;
  left: 18%;
  top: 58%;
  width: 190px;
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold-500), #ffe7b4);
  transform: rotate(-23deg);
  box-shadow: 0 10px 20px rgba(43,16,37,.26);
}

.game-content {
  position: relative;
  z-index: 2;
  display: grid;
  align-content: start;
  gap: 14px;
  padding: 22px;
}

.game-tag {
  width: fit-content;
  padding: 7px 10px;
  border-radius: 999px;
  color: var(--plum-800);
  font-size: .8rem;
  background: rgba(255,255,255,.72);
}

.game-content p,
.lesson-card p,
.glossary-list span {
  color: var(--muted);
  line-height: 1.55;
}

.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 2px;
}

.card-actions {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  margin-top: auto;
}

.card-primary,
.card-secondary {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-weight: 900;
}

.card-primary {
  color: #fff;
  background: var(--plum-800);
}

.card-secondary {
  padding: 0 14px;
  color: var(--plum-800);
  background: #fff;
}

.mission-band,
.club-section,
.academy-preview,
.academy-hero,
.game-hero {
  display: grid;
  gap: 18px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 32px;
  background: rgba(255,255,255,.62);
  backdrop-filter: blur(18px);
  box-shadow: var(--shadow-soft);
}

.mission-band {
  grid-template-columns: 1fr 280px;
  align-items: stretch;
  padding: 18px;
}

.mission-panel {
  display: grid;
  grid-template-columns: 1fr minmax(260px, 360px);
  gap: 22px;
  padding: 26px;
  border-radius: 24px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.72), rgba(255,255,255,.34)),
    linear-gradient(135deg, rgba(255,114,189,.16), rgba(127,231,239,.14));
}

.mission-list {
  display: grid;
  gap: 10px;
}

.mission-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-radius: 18px;
  background: rgba(255,255,255,.72);
}

.mission-item input {
  width: 20px;
  height: 20px;
  accent-color: var(--rose-600);
}

.mission-item span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.mission-item strong {
  color: var(--rose-600);
}

.reward-card {
  display: grid;
  align-content: center;
  justify-items: start;
  gap: 10px;
  min-height: 260px;
  padding: 24px;
  border-radius: 26px;
  color: #fff;
  background:
    linear-gradient(135deg, rgba(255,255,255,.28), transparent 34%),
    linear-gradient(135deg, var(--plum-800), var(--rose-600));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.24);
}

.reward-card .primary-action {
  color: var(--plum-800);
  background: #fff;
}

.reward-cat {
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--rose-600);
  font-size: 2rem;
  background: var(--gold-300);
}

.reward-card strong {
  font-family: var(--display);
  font-size: 1.55rem;
}

.club-section {
  grid-template-columns: minmax(0, .92fr) minmax(360px, .8fr);
  padding: 28px;
}

.club-copy {
  align-self: center;
}

.club-form {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 10px;
  margin-top: 24px;
}

.club-form label {
  display: grid;
  gap: 7px;
}

.club-form span {
  color: var(--muted);
  font-size: .86rem;
}

.club-form input,
.club-form select,
.academy-search input,
.leaderboard-top select {
  width: 100%;
  min-height: 48px;
  border: 1px solid rgba(88,32,63,.14);
  border-radius: 999px;
  padding: 0 16px;
  color: var(--ink);
  background: rgba(255,255,255,.78);
  outline: none;
}

.club-form input:focus,
.club-form select:focus,
.academy-search input:focus,
.leaderboard-top select:focus {
  border-color: var(--rose-500);
  box-shadow: 0 0 0 4px rgba(255,79,168,.16);
}

.leaderboard-card {
  padding: 18px;
  border-radius: 26px;
  background: var(--surface-strong);
}

.leaderboard-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.leaderboard-top h3 {
  font-size: 1.15rem;
}

.leaderboard-top select {
  width: auto;
  min-height: 42px;
}

.leaderboard-list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: place;
}

.leaderboard-list li {
  counter-increment: place;
  display: grid;
  grid-template-columns: 36px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(255,231,242,.8), rgba(255,255,255,.78));
}

.leaderboard-list li::before {
  content: counter(place);
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  background: var(--plum-800);
}

.leaderboard-list small {
  color: var(--muted);
}

.leaderboard-list strong:last-child {
  color: var(--rose-600);
  font-family: var(--display);
  font-size: .95rem;
}

.academy-preview {
  grid-template-columns: 320px 1fr;
  align-items: center;
  padding: 32px;
  margin-bottom: 54px;
}

.academy-visual {
  position: relative;
  min-height: 250px;
  display: grid;
  place-items: center;
  border-radius: 28px;
  color: #fff;
  background: linear-gradient(135deg, var(--plum-800), var(--rose-500) 56%, var(--cyan-400));
  overflow: hidden;
}

.academy-visual i {
  font-size: 6rem;
  filter: drop-shadow(0 14px 20px rgba(43,16,37,.24));
}

.lesson-bubble {
  position: absolute;
  display: grid;
  place-items: center;
  min-width: 70px;
  min-height: 42px;
  padding: 0 12px;
  border-radius: 999px;
  color: var(--plum-800);
  background: rgba(255,255,255,.82);
  box-shadow: 0 18px 24px rgba(43,16,37,.18);
}

.bubble-one { left: 24px; top: 34px; }
.bubble-two { right: 22px; top: 82px; }
.bubble-three { left: 72px; bottom: 38px; }

.site-footer {
  width: min(var(--content), calc(100% - 32px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin: 0 auto 22px;
  padding: 20px 0 calc(20px + env(safe-area-inset-bottom));
  color: var(--plum-700);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-links a {
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  border-radius: 999px;
  background: rgba(255,255,255,.56);
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom));
  z-index: 70;
  max-width: min(440px, calc(100% - 32px));
  padding: 13px 16px;
  border-radius: 18px;
  color: #fff;
  text-align: center;
  background: rgba(43,16,37,.92);
  box-shadow: 0 22px 48px rgba(43,16,37,.3);
  transform: translate(-50%, 130%);
  opacity: 0;
  transition: transform .25s ease, opacity .25s ease;
}

.toast.show {
  transform: translate(-50%, 0);
  opacity: 1;
}

/* Game pages */
.game-layout {
  width: min(1320px, calc(100% - 28px));
  margin: 0 auto 44px;
}

.game-hero {
  grid-template-columns: 1fr auto;
  align-items: center;
  margin: 28px 0 18px;
  padding: 26px 28px;
}

.slim-hero h1 {
  font-size: 3rem;
}

.mode-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.play-surface {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 260px;
  gap: 16px;
  align-items: stretch;
}

.game-panel {
  display: grid;
  align-content: start;
  gap: 14px;
  padding: 18px;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 26px;
  background: rgba(255,255,255,.66);
  backdrop-filter: blur(18px);
  box-shadow: var(--shadow-soft);
}

.game-panel h2 {
  font-size: 1rem;
}

.status-card {
  display: grid;
  gap: 7px;
  padding: 17px;
  border-radius: 20px;
  color: #fff;
  background:
    linear-gradient(135deg, rgba(255,255,255,.2), transparent 38%),
    linear-gradient(135deg, var(--plum-800), var(--rose-600));
}

.status-card span {
  opacity: .78;
}

.status-card strong {
  font-family: var(--display);
  font-size: 1.35rem;
}

.status-card p {
  color: rgba(255,255,255,.84);
  line-height: 1.45;
}

.control-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
}

.control-grid.vertical {
  grid-template-columns: 1fr;
}

.control-grid button,
.chip-row button,
.lesson-card button {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  color: var(--plum-800);
  background: rgba(255,255,255,.84);
  box-shadow: 0 10px 22px rgba(88,32,63,.09);
}

.captured-box,
.mini-score,
.bet-display,
.pool-meter {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 20px;
  background: rgba(255,255,255,.58);
}

.captured-box div {
  min-height: 48px;
  color: var(--plum-700);
  font-size: 1.35rem;
  line-height: 1.3;
}

.board-wrap {
  display: grid;
  place-items: center;
  min-height: 680px;
  padding: 18px;
  border: 1px solid rgba(255,255,255,.72);
  border-radius: 30px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.42), rgba(255,255,255,.12)),
    linear-gradient(135deg, rgba(255,79,168,.18), rgba(127,231,239,.16));
  box-shadow: var(--shadow-soft);
}

.chess-board {
  position: relative;
  width: min(72svh, 660px);
  max-width: 100%;
  aspect-ratio: 1;
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  grid-template-rows: repeat(8, minmax(0, 1fr));
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-rows: minmax(0, 1fr);
  overflow: hidden;
  border: 12px solid var(--plum-800);
  border-radius: 24px;
  box-shadow: 0 30px 70px rgba(43,16,37,.24);
}

.chess-square {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  aspect-ratio: 1;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  color: var(--plum-900);
  font-size: 2.85rem;
  user-select: none;
  transition: background .15s ease, transform .15s ease;
}

.chess-square .piece {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  line-height: 1;
  transition: transform .26s var(--ease-spring), filter .2s ease;
  will-change: transform;
}

/* Pickup gesture (5.2): when a square is selected, its piece briefly
   floats above the board with a slight overshoot. */
.chess-square.selected .piece {
  transform: translateY(-3px) scale(1.08);
  filter: drop-shadow(0 10px 12px rgba(196, 50, 126, .28));
}

.chess-square .coord {
  position: absolute;
  left: 6px;
  bottom: 5px;
  z-index: 1;
  color: rgba(64, 24, 51, .45);
  font-family: var(--body);
  font-size: .62rem;
  line-height: 1;
}

.chess-square.light {
  background: #fff2f8;
}

.chess-square.dark {
  background: #ff93c9;
}

.chess-square.black-piece {
  color: #35142d;
  text-shadow: 0 2px 0 rgba(255,255,255,.28);
}

.chess-square.white-piece {
  color: #fffafc;
  -webkit-text-stroke: 1.4px rgba(64,24,51,.62);
  text-shadow: 0 2px 0 rgba(88,32,63,.42), 0 9px 18px rgba(43,16,37,.34);
}

.chess-square.selected {
  outline: 4px solid var(--gold-300);
  outline-offset: -6px;
  z-index: 2;
}

.chess-square.last-move {
  background:
    linear-gradient(135deg, rgba(255,224,107,.48), rgba(127,231,239,.28)),
    var(--rose-300);
}

.chess-board.board-entry .chess-square {
  animation: chessBoardEnter .56s cubic-bezier(.2, .85, .25, 1.05) both;
  animation-delay: calc((var(--row, 0) + var(--col, 0)) * 28ms + 40ms);
}

@keyframes chessBoardEnter {
  0%   { opacity: 0; transform: scale(.62) translateY(10px); }
  60%  { opacity: 1; transform: scale(1.04) translateY(-2px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

.chess-square.selected::before {
  content: "";
  position: absolute;
  inset: 6%;
  border-radius: 14%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 224, 107, .42), transparent 70%);
  pointer-events: none;
  animation: chessSelectedPulse 1.6s var(--ease-spring-soft) infinite;
}

@keyframes chessSelectedPulse {
  0%, 100% { opacity: .55; transform: scale(.92); }
  35%      { opacity: 1;   transform: scale(1.08); }
  70%      { opacity: .8;  transform: scale(1.02); }
}

@media (prefers-reduced-motion: reduce) {
  .chess-board.board-entry .chess-square,
  .chess-square.selected::before,
  .chess-square.legal::after,
  .chess-square.capture::after,
  .chess-square.capture::before {
    animation: none !important;
  }
}

.chess-square.legal::after {
  content: "";
}

.chess-square.capture::after {
  content: "";
  position: absolute;
  inset: 10%;
}

.chess-square.castle-move::after {
  content: "";
  width: 56%;
  height: 18%;
  border-radius: 999px;
  background: rgba(255, 224, 107, .9);
  box-shadow: 0 0 0 5px rgba(255, 255, 255, .42);
}

@keyframes chessLegalPulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: .82; }
  50%      { transform: translate(-50%, -50%) scale(1.12); opacity: 1; }
}

@keyframes chessCapturePulse {
  0%, 100% { transform: scale(1); opacity: .9; }
  50%      { transform: scale(1.04); opacity: 1; }
}

.chess-square.in-check {
  background:
    radial-gradient(circle, rgba(255, 224, 107, .9), transparent 46%),
    #ff4fa8;
  animation: chessKingDanger 1.1s ease-in-out infinite;
  z-index: 3;
}

.chess-square.in-check::before {
  content: "";
  position: absolute;
  inset: -10%;
  border-radius: 30%;
  background: radial-gradient(circle, rgba(255, 79, 168, .55), transparent 65%);
  pointer-events: none;
  animation: chessKingDangerHalo 1.1s ease-in-out infinite;
  z-index: -1;
}

@keyframes chessKingDanger {
  0%, 100% { box-shadow: inset 0 0 0 3px rgba(255, 79, 168, .68), 0 0 0 0 rgba(255, 79, 168, .55); }
  50%      { box-shadow: inset 0 0 0 4px rgba(255, 79, 168, 1),   0 0 22px 6px rgba(255, 79, 168, .42); }
}

@keyframes chessKingDangerHalo {
  0%, 100% { opacity: .35; transform: scale(.95); }
  50%      { opacity: 1;   transform: scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .chess-square.in-check,
  .chess-square.in-check::before { animation: none !important; }
}

.chess-board {
  transition: transform .55s cubic-bezier(.18, .76, .35, 1);
}

.chess-board.flipped {
  transform: rotate(180deg);
}

.chess-board.flipped .chess-square {
  transform: rotate(180deg);
  transition: transform .55s cubic-bezier(.18, .76, .35, 1);
}

/* Duel "rotate-pieces" variant — each square rotates 180° in place
   (board itself does not flip; pieces appear right-side-up for player on opposite side) */
body[data-page="chess"] .chess-board.rotate-pieces .chess-square {
  transform: rotate(180deg);
  transition: transform .42s cubic-bezier(.18, .76, .35, 1);
}

@media (prefers-reduced-motion: reduce) {
  .chess-board,
  .chess-board.flipped .chess-square { transition: none !important; }
}

.move-log {
  display: grid;
  gap: 8px;
  max-height: 440px;
  margin: 0;
  padding: 0 0 0 20px;
  overflow: auto;
}

.move-log li {
  padding: 8px 10px;
  border-radius: 14px;
  background: rgba(255,255,255,.62);
}

.move-log span {
  color: var(--rose-600);
  font-weight: 900;
}

.promotion-picker {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 20px;
  /* bg + shadow + border from data-bevel="card-pearl" */
}

.promotion-picker[hidden] {
  display: none;
}

.promotion-picker div {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.promotion-picker button {
  min-height: 56px;
  display: inline-grid;
  place-items: center;
  border-radius: 16px;
  font-family: var(--display);
  font-size: 1.6rem;
  line-height: 1;
  /* bg + shadow + border from data-bevel="button-jewel" (Q) or "button-clean" (R/B/N) */
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.promotion-picker button:hover,
.promotion-picker button:focus-visible {
  transform: translateY(-2px) scale(1.03);
  filter: brightness(1.06) saturate(1.06);
}

.promotion-picker button span {
  font-size: 2rem;
  text-shadow: 0 2px 0 rgba(255,255,255,.35);
}

/* === Promotion picker — PNG figure swap (skill-redesign-piped-truffle).
   When `body.has-chess-piece-assets` is on, replace the unicode glyphs
   with the actual board PNGs so the pawn promotion screen feels like a
   real piece roster instead of a font-glyph row. Color is driven by
   `[data-promote-color]` set in showPromotion() — defaults to white. */
body.has-chess-piece-assets .promotion-picker button {
  position: relative;
  background: linear-gradient(135deg, rgba(255, 255, 255, .92), rgba(255, 232, 244, .85));
  color: var(--plum-700);
  border: 1px solid rgba(255, 144, 203, .42);
  box-shadow: 0 6px 14px rgba(116, 18, 70, .14), inset 0 1px 0 rgba(255, 255, 255, .82);
  min-height: 64px;
  padding: 8px 6px 18px;
}

body.has-chess-piece-assets .promotion-picker button > span[aria-hidden="true"] {
  display: block;
  width: 40px;
  height: 40px;
  margin: 0 auto;
  font-size: 0;
  color: transparent;
  text-shadow: none;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 2px 4px rgba(116, 18, 70, .22));
}

/* White-side default piece roster */
body.has-chess-piece-assets [data-chess-promotion]:not([data-promote-color="b"]) button[data-promote-piece="Q"] > span {
  background-image: var(--asset-piece-white-queen);
}
body.has-chess-piece-assets [data-chess-promotion]:not([data-promote-color="b"]) button[data-promote-piece="R"] > span {
  background-image: var(--asset-piece-white-rook);
}
body.has-chess-piece-assets [data-chess-promotion]:not([data-promote-color="b"]) button[data-promote-piece="B"] > span {
  background-image: var(--asset-piece-white-bishop);
}
body.has-chess-piece-assets [data-chess-promotion]:not([data-promote-color="b"]) button[data-promote-piece="N"] > span {
  background-image: var(--asset-piece-white-knight);
}

/* Black-side: when the AI promotes a pawn (rare) or in duel mode */
body.has-chess-piece-assets [data-chess-promotion][data-promote-color="b"] button[data-promote-piece="Q"] > span {
  background-image: var(--asset-piece-black-queen);
}
body.has-chess-piece-assets [data-chess-promotion][data-promote-color="b"] button[data-promote-piece="R"] > span {
  background-image: var(--asset-piece-black-rook);
}
body.has-chess-piece-assets [data-chess-promotion][data-promote-color="b"] button[data-promote-piece="B"] > span {
  background-image: var(--asset-piece-black-bishop);
}
body.has-chess-piece-assets [data-chess-promotion][data-promote-color="b"] button[data-promote-piece="N"] > span {
  background-image: var(--asset-piece-black-knight);
}

/* Tiny letter chip under the figure (promotional code visual cue). */
body.has-chess-piece-assets .promotion-picker button::after {
  content: attr(data-promote-piece);
  position: absolute;
  bottom: 4px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--display);
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--rose-600);
  opacity: .76;
}

/* Default-Queen highlight — soft golden glow so the most common choice
   reads as the recommended pick at a glance. */
body.has-chess-piece-assets .promotion-picker button[data-promote-piece="Q"] {
  background: linear-gradient(135deg, rgba(255, 248, 220, .96), rgba(255, 232, 244, .9));
  border-color: rgba(255, 213, 74, .62);
  box-shadow: 0 8px 18px rgba(255, 184, 92, .26), inset 0 1px 0 rgba(255, 255, 255, .92);
  transform: scale(1.02);
}

body.has-chess-piece-assets .promotion-picker button:hover,
body.has-chess-piece-assets .promotion-picker button:focus-visible {
  background: linear-gradient(135deg, rgba(255, 255, 255, 1), rgba(255, 200, 224, .82));
  border-color: var(--rose-500);
  transform: translateY(-3px) scale(1.05);
  box-shadow: 0 14px 26px rgba(216, 24, 121, .26), inset 0 1px 0 rgba(255, 255, 255, .92);
}

body.has-chess-piece-assets .promotion-picker button:active {
  transform: scale(.96);
}

body[data-chess-mode="duel"] [data-chess-difficulty-card] {
  display: none;
}

.card-table {
  min-height: 660px;
}

.table-center {
  display: grid;
  align-content: space-between;
  gap: 18px;
  min-height: 660px;
  padding: 22px;
  border: 16px solid rgba(64,24,51,.82);
  border-radius: 42px;
  background:
    radial-gradient(circle at 20% 18%, rgba(255,255,255,.44), transparent 8rem),
    radial-gradient(circle at 80% 85%, rgba(127,231,239,.26), transparent 10rem),
    linear-gradient(135deg, #ff79bf, #bc40ba 52%, #472044);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.18), 0 30px 70px rgba(43,16,37,.22);
}

.hand-zone,
.poker-seat,
.community-zone {
  display: grid;
  gap: 10px;
}

.hand-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: #fff;
}

.hand-title strong,
.community-zone > span {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  color: var(--plum-800);
  background: rgba(255,255,255,.8);
}

.card-hand {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  min-height: 112px;
}

.card-hand.small {
  min-height: 100px;
}

.game-card-ui {
  width: 76px;
  height: 104px;
  display: grid;
  place-items: center;
  border: 2px solid rgba(88,32,63,.16);
  border-radius: 14px;
  color: var(--plum-800);
  font-family: var(--display);
  font-size: 1.25rem;
  background:
    linear-gradient(135deg, rgba(255,255,255,.92), rgba(255,231,242,.94));
  box-shadow: 0 15px 24px rgba(43,16,37,.18);
}

.game-card-ui.red {
  color: var(--rose-600);
}

.game-card-ui.back {
  color: transparent;
  background:
    linear-gradient(45deg, rgba(255,255,255,.22) 25%, transparent 25% 75%, rgba(255,255,255,.22) 75%),
    linear-gradient(45deg, rgba(255,255,255,.22) 25%, transparent 25% 75%, rgba(255,255,255,.22) 75%),
    linear-gradient(135deg, var(--plum-800), var(--rose-600));
  background-size: 18px 18px, 18px 18px, auto;
  background-position: 0 0, 9px 9px, 0 0;
}

.table-message {
  justify-self: center;
  max-width: 560px;
  padding: 12px 18px;
  border-radius: 999px;
  color: #fff;
  text-align: center;
  background: rgba(43,16,37,.58);
  backdrop-filter: blur(12px);
}

.chip-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.chip-row button {
  min-height: 48px;
  color: var(--plum-800);
  background:
    radial-gradient(circle, #fff 0 22%, transparent 23%),
    conic-gradient(var(--rose-600) 0 12%, #fff 12% 18%, var(--rose-600) 18% 30%, #fff 30% 36%, var(--rose-600) 36% 48%, #fff 48% 54%, var(--rose-600) 54% 66%, #fff 66% 72%, var(--rose-600) 72% 84%, #fff 84% 90%, var(--rose-600) 90%);
}

.poker-table .table-center {
  background:
    radial-gradient(circle at 48% 50%, rgba(255,224,107,.22), transparent 12rem),
    linear-gradient(135deg, #4a1f42, #a7339d 48%, #ff72bd);
}

.community-zone {
  justify-items: center;
  align-self: center;
}

.community-hand {
  justify-content: center;
}

.pool-surface {
  grid-template-columns: 250px minmax(0, 1fr) 250px;
}

.pool-canvas-wrap {
  min-height: 640px;
  display: grid;
  place-items: center;
  padding: 16px;
  border: 1px solid rgba(255,255,255,.72);
  border-radius: 30px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.5), rgba(255,255,255,.16)),
    linear-gradient(135deg, rgba(255,79,168,.14), rgba(127,231,239,.18));
  box-shadow: var(--shadow-soft);
}

.pool-canvas {
  width: 100%;
  max-width: 960px;
  aspect-ratio: 16 / 9;
  border-radius: 30px;
  box-shadow: 0 30px 70px rgba(43,16,37,.24);
  touch-action: none;
}

.pool-meter div {
  height: 12px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(88,32,63,.12);
}

.pool-meter i {
  display: block;
  width: 0%;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--cyan-400), var(--gold-300), var(--rose-600));
  transition: width .12s ease;
}

/* Academy */
.academy-hero {
  width: min(var(--content), calc(100% - 32px));
  grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
  align-items: center;
  margin: 28px auto 26px;
  padding: 34px;
}

.academy-hero h1 {
  font-size: 3.3rem;
}

.academy-search {
  position: relative;
}

.academy-search i {
  position: absolute;
  left: 18px;
  top: 50%;
  color: var(--rose-600);
  transform: translateY(-50%);
}

.academy-search input {
  min-height: 58px;
  padding-left: 48px;
}

.lesson-tabs {
  margin-bottom: 26px;
}

.lesson-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.lesson-card {
  display: grid;
  align-content: start;
  gap: 14px;
  min-height: 390px;
  padding: 22px;
  border: 1px solid rgba(255,255,255,.74);
  border-radius: 24px;
  background: rgba(255,255,255,.7);
  box-shadow: var(--shadow-soft);
}

.lesson-card.is-hidden {
  display: none;
}

.lesson-icon {
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  color: #fff;
  font-size: 1.6rem;
  background: linear-gradient(135deg, var(--rose-600), var(--cyan-400));
}

.lesson-card h2 {
  font-size: 1.2rem;
}

.lesson-card a {
  width: fit-content;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border-radius: 999px;
  color: #fff;
  background: var(--plum-800);
}

.quiz-answer {
  display: none;
  padding: 12px;
  border-radius: 16px;
  background: rgba(255,231,242,.8);
}

.quiz-answer.show {
  display: block;
}

.glossary-section {
  margin-bottom: 54px;
}

.glossary-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.glossary-list article {
  display: grid;
  gap: 8px;
  min-height: 130px;
  padding: 18px;
  border: 1px solid rgba(255,255,255,.72);
  border-radius: 22px;
  background: rgba(255,255,255,.68);
  box-shadow: 0 14px 32px rgba(88,32,63,.09);
}

.glossary-list article.is-hidden {
  display: none;
}

@keyframes sparkleDrift {
  0% { background-position: 8% 11%, 88% 14%; }
  100% { background-position: 18% 24%, 78% 4%; }
}

@keyframes stageShimmer {
  from { transform: translateX(-2%); opacity: .82; }
  to { transform: translateX(2%); opacity: 1; }
}

@keyframes ribbonSweep {
  0%, 100% { transform: translateX(-6%) rotate(-16deg); opacity: .25; }
  50% { transform: translateX(8%) rotate(-16deg); opacity: .55; }
}

@keyframes floatMain {
  0%, 100% { transform: translateX(-50%) translateY(0) rotate(-7deg); }
  50% { transform: translateX(-50%) translateY(-14px) rotate(-5deg); }
}

@keyframes floatLeft {
  0%, 100% { transform: translateY(0) rotate(-18deg); }
  50% { transform: translateY(16px) rotate(-15deg); }
}

@keyframes floatRight {
  0%, 100% { transform: translateY(0) rotate(15deg); }
  50% { transform: translateY(-14px) rotate(12deg); }
}

@keyframes pieceBob {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50% { transform: translateY(-12px) rotate(4deg); }
}

@keyframes twinkle {
  0%, 100% { transform: scale(.72) rotate(0deg); opacity: .55; }
  50% { transform: scale(1.1) rotate(45deg); opacity: 1; }
}

@media (max-width: 1180px) {
  h1 {
    font-size: 3.35rem;
  }

  .site-header {
    grid-template-columns: auto auto;
  }

  .top-nav {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    display: none;
    justify-content: center;
    border-radius: 24px;
  }

  .top-nav.open {
    display: flex;
  }

  .menu-toggle {
    display: inline-grid;
  }

  .header-actions {
    justify-self: end;
  }

  .hero-section {
    grid-template-columns: 1fr;
    min-height: auto;
    padding-top: 42px;
  }

  .hero-copy {
    max-width: 820px;
    padding-left: 0;
  }

  .hero-stage {
    min-height: 560px;
  }

  .game-grid,
  .lesson-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .play-surface,
  .pool-surface {
    grid-template-columns: 1fr;
  }

  .game-panel {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .game-panel .status-card,
  .game-panel .control-grid.vertical,
  .game-panel .strong-link,
  .captured-box,
  .mini-score {
    grid-column: auto;
  }

  .board-wrap,
  .pool-canvas-wrap,
  .table-center {
    min-height: auto;
  }

  .chess-board {
    width: min(92vw, 660px);
  }
}

@media (max-width: 900px) {
  :root {
    --header-h: 76px;
  }

  body {
    background-attachment: scroll;
  }

  .site-header {
    width: calc(100% - 20px);
    margin-top: 10px;
    gap: 10px;
  }

  .brand {
    grid-template-columns: 44px auto;
  }

  .brand-mark {
    width: 44px;
    height: 44px;
  }

  .install-button span {
    display: none;
  }

  .hero-section {
    width: calc(100% - 20px);
    padding-top: 32px;
  }

  h1,
  .academy-hero h1 {
    font-size: 2.62rem;
  }

  h2 {
    font-size: 1.85rem;
  }

  .hero-lead {
    font-size: 1.04rem;
  }

  .hero-stage {
    min-height: 500px;
    border-radius: 34px;
  }

  .phone-frame {
    width: 198px;
    min-height: 392px;
  }

  .phone-main {
    width: 220px;
    min-height: 430px;
  }

  .phone-left {
    left: -2%;
  }

  .phone-right {
    right: -4%;
  }

  .phone-screen {
    min-height: 348px;
  }

  .floating-badge {
    min-width: 136px;
    grid-template-columns: 30px auto;
    padding: 10px;
  }

  .floating-badge i {
    width: 30px;
    height: 30px;
  }

  .mission-band,
  .mission-panel,
  .club-section,
  .academy-preview,
  .academy-hero,
  .game-hero {
    grid-template-columns: 1fr;
  }

  .club-form {
    grid-template-columns: 1fr;
  }

  .academy-preview {
    padding: 22px;
  }

  .academy-visual {
    min-height: 210px;
  }

  .glossary-list {
    grid-template-columns: 1fr 1fr;
  }

  .slim-hero h1 {
    font-size: 2.35rem;
  }

  .game-hero {
    padding: 22px;
  }

  .mode-switch {
    justify-content: flex-start;
  }

  .game-panel {
    grid-template-columns: 1fr;
  }

  .card-table {
    min-height: auto;
  }

  .table-center {
    border-width: 10px;
    border-radius: 30px;
  }

  .game-card-ui {
    width: 66px;
    height: 92px;
    font-size: 1.05rem;
  }
}

@media (max-width: 640px) {
  .hero-section,
  .section-shell,
  .site-footer,
  .academy-hero,
  .game-layout,
  .site-header {
    width: calc(100vw - 20px);
    max-width: calc(100vw - 20px);
  }

  .hero-copy {
    max-width: 100%;
  }

  .hero-section > *,
  .game-hero > *,
  .academy-hero > * {
    min-width: 0;
  }

  .site-header {
    display: flex;
    align-items: center;
    padding: 10px;
    border-radius: 26px;
  }

  .brand {
    flex: 1 1 0;
    grid-template-columns: 40px minmax(0, 1fr);
    gap: 8px;
    overflow: hidden;
  }

  .brand-mark {
    width: 40px;
    height: 40px;
  }

  .brand small {
    display: none;
  }

  .brand strong {
    font-size: .92rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .header-actions {
    flex: 0 0 auto;
    gap: 5px;
  }

  .icon-button,
  .pill-button {
    width: 36px;
    min-width: 36px;
    height: 36px;
    min-height: 36px;
    padding: 0;
  }

  .top-nav {
    flex-direction: column;
    align-items: stretch;
    padding: 10px;
  }

  .top-nav a {
    justify-content: center;
  }

  h1,
  .academy-hero h1 {
    max-width: 100%;
    overflow-wrap: anywhere;
    font-size: 1.96rem;
  }

  h2 {
    font-size: 1.55rem;
  }

  .hero-actions,
  .signal-strip,
  .filter-row {
    align-items: stretch;
    flex-direction: column;
  }

  .primary-action,
  .secondary-action,
  .segmented {
    width: 100%;
  }

  .hero-stage {
    min-height: 410px;
  }

  .phone-left,
  .phone-right {
    display: none;
  }

  .phone-main {
    left: 50%;
    top: 8%;
    width: min(230px, 78%);
    transform: translateX(-50%) rotate(-4deg);
  }

  .floating-badge {
    position: absolute;
    min-width: 128px;
  }

  .badge-coins {
    right: 12px;
    bottom: 20px;
  }

  .badge-streak {
    left: 12px;
    bottom: 76px;
  }

  .game-grid,
  .lesson-grid,
  .glossary-list {
    grid-template-columns: 1fr;
  }

  .game-card {
    min-height: auto;
  }

  .mission-band,
  .club-section,
  .academy-hero,
  .game-hero {
    padding: 18px;
    border-radius: 24px;
  }

  .mission-panel {
    padding: 18px;
  }

  .mission-item {
    grid-template-columns: auto 1fr;
  }

  .mission-item strong {
    grid-column: 2;
  }

  .leaderboard-top,
  .site-footer {
    align-items: stretch;
    flex-direction: column;
  }

  .leaderboard-top select {
    width: 100%;
  }

  .game-layout {
    width: calc(100% - 16px);
  }

  .play-surface {
    gap: 10px;
  }

  .board-wrap,
  .pool-canvas-wrap,
  .table-center,
  .game-panel {
    border-radius: 22px;
    padding: 12px;
  }

  .chess-board {
    width: 100%;
    border-width: 7px;
    border-radius: 16px;
  }

  .chess-square {
    font-size: 2.05rem;
  }

  .card-hand {
    gap: 7px;
  }

  .game-card-ui {
    width: 54px;
    height: 78px;
    border-radius: 10px;
    font-size: .9rem;
  }

  .pool-canvas-wrap {
    padding: 8px;
  }

  .pool-canvas {
    border-radius: 18px;
  }

  body[data-page="chess"] .game-layout {
    display: flex;
    flex-direction: column;
  }

  body[data-page="chess"] .play-surface {
    order: 1;
  }

  body[data-page="chess"] .game-hero {
    order: 2;
    margin-top: 10px;
  }

  body[data-page="chess"] .game-hero .eyebrow,
  body[data-page="chess"] .game-hero p {
    display: none;
  }

  body[data-page="chess"] .game-hero h1 {
    margin-bottom: 0;
    font-size: 1.45rem;
  }

  body[data-page="chess"] .mode-switch {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  body[data-page="chess"] .chess-surface .board-wrap {
    order: 1;
  }

  body[data-page="chess"] .chess-surface > .game-panel:not(.move-panel) {
    order: 2;
  }

  body[data-page="chess"] .chess-surface .move-panel {
    order: 3;
  }

  body[data-page="chess"] .chess-board {
    border-width: 6px;
  }

  body[data-page="chess"] .chess-square {
    font-size: 1.92rem;
  }

  body[data-page="chess"] .chess-square .coord {
    left: 3px;
    bottom: 3px;
    font-size: .52rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* Chess Bloom flagship skin */
body[data-page="chess"] {
  background:
    radial-gradient(circle at 12% 8%, rgba(255,255,255,.72), transparent 18rem),
    linear-gradient(135deg, #fff8fb 0%, #ffddeb 32%, #ff9bc8 70%, #ffd4e5 100%);
}

body[data-page="chess"]::before {
  background-image:
    radial-gradient(circle at 14px 14px, rgba(255,255,255,.52) 0 1px, transparent 2px),
    linear-gradient(135deg, rgba(255,255,255,.16) 25%, transparent 25% 75%, rgba(255,255,255,.16) 75%);
  background-size: 120px 120px, 34px 34px;
  opacity: .32;
}

.chess-atmosphere {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.chess-atmosphere span {
  position: absolute;
  top: -48px;
  left: var(--x);
  width: 22px;
  height: 13px;
  border-radius: 70% 30% 70% 30%;
  background: linear-gradient(135deg, rgba(255,255,255,.94), rgba(255,103,170,.72));
  box-shadow: 0 8px 16px rgba(196, 50, 126, .12);
  opacity: .78;
  animation: chessPetalFall var(--dur, 17s) linear infinite;
  animation-delay: var(--delay, 0s);
}

/* Mobile: drop the 6 always-running falling petals — paint cost on
   low-end Android compounds with the players-bar pulse + atmosphere
   sparkle and is the main reason CDP screenshot occasionally times
   out (renderer never idles). Burst-petal one-shots stay (they're
   triggered by gameplay, not always-on). */
@media (max-width: 760px) {
  .chess-atmosphere span:not(.burst-petal) { display: none; }
  /* Body sparkle drift also paused on mobile for the same reason. */
  body[data-page="chess"]::after { animation: none; opacity: .55; }
}

.chess-atmosphere .burst-petal {
  top: 42%;
  animation: chessPetalBurst 1.25s cubic-bezier(.18,.72,.22,1) forwards;
}

body.has-chess-art-assets .chess-atmosphere span {
  background-color: transparent;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  box-shadow: none;
}

body.has-chess-art-assets .chess-atmosphere span:nth-child(5n + 1),
body.has-chess-art-assets .petal-asset-1 {
  background-image: url("assets/chess/final-png/props/soft-petal-01.png");
}

body.has-chess-art-assets .chess-atmosphere span:nth-child(5n + 2),
body.has-chess-art-assets .petal-asset-2 {
  background-image: url("assets/chess/final-png/props/soft-petal-02.png");
}

body.has-chess-art-assets .chess-atmosphere span:nth-child(5n + 3),
body.has-chess-art-assets .petal-asset-3 {
  background-image: url("assets/chess/final-png/props/soft-petal-03.png");
}

body.has-chess-art-assets .chess-atmosphere span:nth-child(5n + 4),
body.has-chess-art-assets .petal-asset-4 {
  background-image: url("assets/chess/final-png/props/soft-petal-04.png");
}

body.has-chess-art-assets .chess-atmosphere span:nth-child(5n + 5),
body.has-chess-art-assets .petal-asset-5 {
  background-image: url("assets/chess/final-png/props/soft-petal-05.png");
}

.chess-header {
  width: min(1410px, calc(100% - 44px));
  min-height: 92px;
  padding: 14px 18px;
  border-radius: 36px;
  border-color: rgba(255,255,255,.92);
  background: rgba(255, 250, 253, .86);
  box-shadow: 0 18px 42px rgba(196, 50, 126, .18), inset 0 1px 0 rgba(255,255,255,.9);
}

/* === Chess profile pill (Phase 1A): always-visible жетоны balance in header.
   Sits in .header-actions on desktop, gets a mobile override below to stay
   visible when the rest of header-actions hides at <=760. */
.chess-profile-pill {
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px 0 12px;
  border-radius: 999px;
  font-family: inherit;
  font-weight: 800;
  font-size: 15px;
  color: var(--plum-800);
  background: linear-gradient(180deg, #fff7ee 0%, #fde8c5 100%);
  border: 1.5px solid rgba(255, 200, 110, .65);
  box-shadow: 0 4px 12px rgba(232, 41, 143, .14), inset 0 1px 0 rgba(255, 255, 255, .9);
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background .2s ease;
  white-space: nowrap;
}
.chess-profile-pill:hover,
.chess-profile-pill:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 8px 18px rgba(232, 41, 143, .22), inset 0 1px 0 rgba(255, 255, 255, .92);
}
.chess-profile-pill .ti-coin {
  font-size: 18px;
  color: #c89318;
  filter: drop-shadow(0 1px 0 rgba(255, 235, 180, .9));
}
.chess-profile-balance {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  min-width: 1.5ch;
  text-align: right;
}
/* Phase 16: floor hint as ABSOLUTE-positioned tooltip below pill (was inline,
   pushed header CTAs into squeeze on small viewports). Click on pill toggles.
   The [hidden] override is necessary because display:flex shadows the
   implicit [hidden] {display:none} UA rule. */
.chess-profile-pill {
  position: relative; /* anchor for floor-hint absolute positioning */
}
.chess-profile-floor-hint {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--plum-700, #6e2752);
  background: linear-gradient(180deg, #fffaee 0%, #fde8c5 100%);
  border: 1.5px solid rgba(255, 200, 110, .65);
  box-shadow: 0 8px 18px rgba(232, 41, 143, .22);
  white-space: nowrap;
  z-index: 60;
}
.chess-profile-floor-hint::before {
  content: "";
  position: absolute;
  top: -6px;
  right: 16px;
  width: 10px;
  height: 10px;
  background: linear-gradient(135deg, #fffaee, #fde8c5);
  transform: rotate(45deg);
  border-left: 1.5px solid rgba(255, 200, 110, .65);
  border-top: 1.5px solid rgba(255, 200, 110, .65);
}
.chess-profile-floor-hint[hidden] { display: none; }
.chess-profile-floor-hint .ti {
  font-size: 14px;
  color: var(--plum-700, #4d1c3b);
}
/* Pulse animation when balance changes — added/removed by JS via the
   .is-pulsing class so a credit/debit feels tactile. */
@keyframes chess-profile-balance-pulse {
  0% { transform: scale(1); }
  35% { transform: scale(1.18); color: #d4731a; }
  100% { transform: scale(1); }
}
.chess-profile-balance.is-pulsing {
  animation: chess-profile-balance-pulse .42s var(--ease-spring, cubic-bezier(.5, 1.6, .5, 1)) both;
}
/* Floor-hit feedback — brief red flash + shield emphasis when transact()
   reports hitFloor: true. */
@keyframes chess-profile-floor-flash {
  0%, 100% { box-shadow: 0 4px 12px rgba(232, 41, 143, .14), inset 0 1px 0 rgba(255, 255, 255, .9); }
  40% { box-shadow: 0 0 0 3px rgba(255, 100, 130, .55), 0 6px 16px rgba(232, 60, 100, .35), inset 0 1px 0 rgba(255, 255, 255, .9); }
}
.chess-profile-pill.is-floor-hit {
  animation: chess-profile-floor-flash .85s ease both;
}

/* Header-mounted controls are mobile-only — desktop keeps the same buttons
   inside the hero strip below. The mobile @media block re-enables them. */
.chess-header-controls {
  display: none;
}

.chess-brand {
  grid-template-columns: 66px auto;
}

.brand-avatar,
.clock-avatar,
.side-portrait,
.hero-character {
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
}

.brand-avatar {
  position: relative;
  width: 66px;
  height: 66px;
  border: 3px solid rgba(255,255,255,.86);
  border-radius: 50%;
  background-image:
    radial-gradient(circle at 38% 41%, #fff 0 5%, transparent 6%),
    radial-gradient(circle at 62% 41%, #fff 0 5%, transparent 6%),
    radial-gradient(circle at 40% 43%, #1b1720 0 2%, transparent 3%),
    radial-gradient(circle at 64% 43%, #1b1720 0 2%, transparent 3%),
    radial-gradient(circle at 51% 54%, #ff72ad 0 4%, transparent 5%),
    radial-gradient(circle at 50% 46%, #211b24 0 38%, transparent 39%),
    radial-gradient(circle at 50% 50%, #ff8fc3 0 56%, #fff 57%);
  box-shadow: 0 12px 26px rgba(197, 39, 116, .18), inset 0 0 0 4px rgba(255,180,213,.4);
  animation: chessAvatarBreath 5.8s ease-in-out infinite;
}

body.has-chess-art-assets .brand-avatar {
  background-image:
    var(--asset-logo-cat),
    radial-gradient(circle at 38% 41%, #fff 0 5%, transparent 6%),
    radial-gradient(circle at 62% 41%, #fff 0 5%, transparent 6%),
    radial-gradient(circle at 40% 43%, #1b1720 0 2%, transparent 3%),
    radial-gradient(circle at 64% 43%, #1b1720 0 2%, transparent 3%),
    radial-gradient(circle at 51% 54%, #ff72ad 0 4%, transparent 5%),
    radial-gradient(circle at 50% 46%, #211b24 0 38%, transparent 39%),
    radial-gradient(circle at 50% 50%, #ff8fc3 0 56%, #fff 57%);
}

body.has-chess-art-assets .brand-avatar::before,
body.has-chess-art-assets .brand-avatar::after,
body.has-chess-art-assets .hero-cat::before,
body.has-chess-art-assets .hero-cat::after,
body.has-chess-art-assets .hero-goose::before,
body.has-chess-art-assets .hero-goose::after,
body.has-chess-art-assets .white-side::after {
  display: none;
}

.brand-avatar::before,
.brand-avatar::after {
  content: "";
  position: absolute;
  top: 9px;
  width: 18px;
  height: 22px;
  border-radius: 4px 12px 4px 12px;
  background: linear-gradient(135deg, #1b1720 62%, #ff6fab 63%);
  transform: rotate(-24deg);
}

.brand-avatar::before { left: 14px; }
.brand-avatar::after { right: 14px; transform: rotate(24deg) scaleX(-1); }

.chess-header .brand strong {
  color: var(--rose-600);
  font-size: 1.28rem;
}

.chess-header .brand small {
  color: var(--plum-600);
  font-size: .88rem;
}

.chess-layout {
  width: min(1410px, calc(100% - 44px));
  margin-bottom: 34px;
}

.chess-bloom-hero {
  position: relative;
  min-height: 200px;
  display: grid;
  grid-template-columns: minmax(320px, .9fr) minmax(320px, .82fr) minmax(220px, .42fr);
  align-items: center;
  gap: 20px;
  margin: 14px 0 10px;
  padding: 22px 36px 26px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.92);
  border-radius: 30px;
  background:
    linear-gradient(90deg, rgba(255,255,255,.86), rgba(255,241,247,.78) 46%, rgba(255,255,255,.76)),
    radial-gradient(circle at 56% 88%, rgba(255,114,189,.28), transparent 20rem);
  box-shadow: 0 20px 56px rgba(196, 50, 126, .18), inset 0 1px 0 rgba(255,255,255,.9);
}

body.has-chess-art-assets .chess-bloom-hero {
  background:
    url("assets/chess/final-png/props/hero-blossom-left.png") -108px -28px / 260px auto no-repeat,
    url("assets/chess/final-png/props/hero-blossom-right.png") right top / 280px auto no-repeat,
    url("assets/chess/final-png/props/hero-blossom-right-down.png") right bottom / 240px auto no-repeat,
    linear-gradient(90deg, rgba(255,255,255,.86), rgba(255,241,247,.78) 46%, rgba(255,255,255,.76)),
    radial-gradient(circle at 56% 88%, rgba(255,114,189,.28), transparent 20rem);
}

.chess-bloom-hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 58px;
  background: linear-gradient(0deg, rgba(255,153,198,.3), transparent);
  pointer-events: none;
}

.chess-hero-copy {
  position: relative;
  z-index: 2;
}

.chess-hero-copy h1 {
  color: #6b073b;
  font-size: clamp(2.4rem, 3.6vw, 3.9rem);
  text-shadow: 0 3px 0 rgba(255,255,255,.72), 0 10px 20px rgba(116, 18, 70, .12);
}

.chess-hero-copy p:last-child {
  max-width: 520px;
  margin-top: 12px;
  color: #4d3567;
  font-size: 1rem;
  line-height: 1.5;
}

.chess-hero-art {
  position: relative;
  z-index: 2;
  min-height: 160px;
}

.hero-shadow {
  position: absolute;
  bottom: -8px;
  z-index: 1;
  height: 32px;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(116, 18, 70, .23), transparent 68%);
  filter: blur(1px);
  animation: heroShadowPulse 4.8s ease-in-out infinite;
}

.cat-shadow {
  left: 16%;
  width: 190px;
}

.goose-shadow {
  right: 4%;
  width: 216px;
  animation-delay: -1.8s;
}

.hero-character {
  position: absolute;
  z-index: 3;
  filter: drop-shadow(0 16px 18px rgba(80, 26, 56, .2));
  pointer-events: none;
  transition: filter .4s ease, transform .4s ease;
}

.chess-bloom-hero:hover .hero-cat {
  filter: drop-shadow(0 20px 22px rgba(80, 26, 56, .26)) saturate(1.08) brightness(1.04);
}

.chess-bloom-hero:hover .hero-goose {
  filter: drop-shadow(0 20px 22px rgba(80, 26, 56, .26)) saturate(1.08) brightness(1.04);
}

.chess-bloom-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 100%, rgba(255, 144, 203, .22), transparent 55%);
  opacity: 0;
  transition: opacity .5s ease;
  pointer-events: none;
  z-index: 1;
}

.chess-bloom-hero:hover::before {
  opacity: 1;
}

body.has-chess-art-assets .hero-shadow {
  display: none;
}

.hero-cat {
  left: 12%;
  bottom: -10px;
  width: 174px;
  height: 188px;
  transform-origin: 52% 94%;
  animation: heroCatIdle 5.2s ease-in-out infinite;
  background-image:
    radial-gradient(circle at 42% 32%, #fff 0 4%, transparent 5%),
    radial-gradient(circle at 60% 32%, #fff 0 4%, transparent 5%),
    radial-gradient(circle at 43% 33%, #25131e 0 2%, transparent 3%),
    radial-gradient(circle at 61% 33%, #25131e 0 2%, transparent 3%),
    radial-gradient(circle at 51% 43%, #ff5f9f 0 3%, transparent 4%),
    radial-gradient(ellipse at 70% 78%, #1a1720 0 9%, transparent 10%),
    radial-gradient(ellipse at 50% 76%, #1b1821 0 34%, transparent 35%),
    radial-gradient(circle at 51% 34%, #28242d 0 25%, transparent 26%),
    radial-gradient(ellipse at 40% 98%, rgba(255,111,171,.72) 0 14%, transparent 15%);
}

body.has-chess-art-assets .hero-cat {
  background-image: var(--asset-hero-cat);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center bottom;
}

body.has-chess-art-assets .hero-cat::before,
body.has-chess-art-assets .hero-cat::after {
  display: none;
}

.hero-cat::before,
.hero-cat::after {
  content: "";
  position: absolute;
  top: 18px;
  width: 54px;
  height: 70px;
  background: linear-gradient(135deg, #1b1821, #3b303a);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.hero-cat::before { left: 42px; transform: rotate(-15deg); }
.hero-cat::after { right: 38px; transform: rotate(15deg); }

.hero-goose {
  right: 6%;
  bottom: -10px;
  width: 188px;
  height: 176px;
  transform-origin: 55% 96%;
  animation: heroGooseIdle 5.6s ease-in-out infinite;
  background-image:
    radial-gradient(circle at 68% 30%, #1e1720 0 2%, transparent 3%),
    radial-gradient(ellipse at 74% 35%, #ffb131 0 10%, transparent 11%),
    radial-gradient(ellipse at 58% 84%, #fff 0 33%, transparent 34%),
    radial-gradient(circle at 62% 37%, #fff 0 18%, transparent 19%),
    radial-gradient(ellipse at 48% 98%, rgba(255,111,171,.55) 0 16%, transparent 17%);
}

body.has-chess-art-assets .hero-goose {
  background-image: var(--asset-hero-goose);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center bottom;
}

body.has-chess-art-assets .hero-goose::before,
body.has-chess-art-assets .hero-goose::after {
  display: none;
}

.hero-goose::before {
  content: "";
  position: absolute;
  right: 62px;
  top: 26px;
  width: 78px;
  height: 128px;
  border-radius: 60% 60% 50% 50%;
  border: 12px solid #fff;
  border-left-color: transparent;
  border-bottom-color: transparent;
  transform: rotate(18deg);
}

.hero-goose::after {
  content: "";
  position: absolute;
  right: 18px;
  top: 48px;
  width: 54px;
  height: 28px;
  border-radius: 70% 30% 70% 30%;
  background: #ffb131;
  transform: rotate(8deg);
}

.hero-petal {
  position: absolute;
  z-index: 3;
  width: 22px;
  height: 12px;
  border-radius: 70% 30% 70% 30%;
  background: linear-gradient(135deg, #fff, #ff7fb8);
  box-shadow: 0 6px 12px rgba(196, 50, 126, .14);
  animation: petalFloat 6s ease-in-out infinite;
}

.petal-one { left: 3%; top: 22%; }
.petal-two { left: 54%; top: 18%; animation-delay: -1.6s; }
.petal-three { right: 12%; top: 34%; animation-delay: -3s; }

.chess-mode-switch {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 8px;
  border-radius: 999px;
  background: rgba(255,255,255,.7);
  box-shadow: 0 16px 34px rgba(196, 50, 126, .18), inset 0 1px 0 rgba(255,255,255,.9);
}

.chess-mode-switch .segmented {
  min-width: 142px;
  min-height: 58px;
  gap: 10px;
  font-size: 1.05rem;
}

.chess-mode-switch .segmented.active {
  background: linear-gradient(135deg, #ff4fa8, #d71879);
  box-shadow: 0 14px 26px rgba(216, 24, 121, .3), inset 0 1px 0 rgba(255,255,255,.38);
}

/* Two-action CTA group inside the chess hero-strip ("Новая игра" + "Reset")
   replaces the previous Solo/Duel toggle. Primary is filled pink, secondary
   is outlined — neither carries a persistent "selected" state, both fire on
   every tap. Mode/level selection lives inside the start picker now. */
.chess-game-controls .chess-game-cta-primary {
  color: #fff;
  /* bg + shadow + border from data-bevel="button-bold" */
}
.chess-game-controls .chess-game-cta-primary:hover,
.chess-game-controls .chess-game-cta-primary:focus-visible {
  transform: translateY(-1px);
  filter: brightness(1.04) saturate(1.06);
}
.chess-game-controls .chess-game-cta-secondary {
  color: var(--plum-700);
  /* bg + shadow + border from data-bevel="button-clean" */
}
.chess-game-controls .chess-game-cta-secondary:hover,
.chess-game-controls .chess-game-cta-secondary:focus-visible {
  filter: brightness(1.04);
}

.chess-play-grid {
  display: grid;
  grid-template-columns: minmax(250px, 300px) minmax(520px, 1fr) minmax(260px, 300px);
  gap: 14px;
  align-items: start;
}

.chess-side-panel,
.chess-board-stage {
  border: 1px solid rgba(255,255,255,.9);
  border-radius: 30px;
  background: rgba(255, 243, 249, .78);
  box-shadow: 0 18px 46px rgba(196, 50, 126, .16), inset 0 1px 0 rgba(255,255,255,.86);
  backdrop-filter: blur(18px);
}

.chess-side-panel {
  display: grid;
  align-content: start;
  gap: 16px;
  padding: 18px;
}

.turn-card {
  position: relative;
  min-height: 224px;
  display: grid;
  align-content: start;
  gap: 8px;
  overflow: hidden;
  padding: 22px;
  border-radius: 24px;
  color: #fff;
  background: linear-gradient(135deg, #8e1853, #e51b83);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.24), 0 16px 30px rgba(196, 50, 126, .2);
}

.turn-card::after {
  content: "";
  position: absolute;
  right: -32%;
  bottom: -42%;
  width: 190px;
  height: 190px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.32), transparent 64%);
  animation: panelGlowDrift 6.4s ease-in-out infinite;
  pointer-events: none;
}

.turn-card > *:not(.side-portrait) {
  position: relative;
  z-index: 2;
}

body.has-chess-art-assets .turn-card {
  background:
    url("assets/chess/final-png/props/panel-blossom.png") right bottom / 170px auto no-repeat,
    linear-gradient(135deg, #8e1853, #e51b83);
}

.turn-card span:first-child {
  color: rgba(255,255,255,.72);
  text-transform: uppercase;
}

.turn-card strong {
  font-family: var(--display);
  font-size: 2rem;
}

.turn-card p {
  max-width: 168px;
  color: rgba(255,255,255,.9);
  font-size: .92rem;
  line-height: 1.5;
}

.side-portrait {
  position: absolute;
  right: 0;
  bottom: -8px;
  width: 140px;
  height: 168px;
  z-index: 1;
  filter: drop-shadow(0 14px 14px rgba(80, 26, 56, .22));
  animation: sidePortraitFloat 5.8s ease-in-out infinite;
  pointer-events: none;
}

.white-side {
  background-image:
    radial-gradient(ellipse at 72% 32%, #ffb131 0 10%, transparent 11%),
    radial-gradient(circle at 63% 28%, #241621 0 3%, transparent 4%),
    radial-gradient(ellipse at 54% 74%, #fff 0 32%, transparent 33%),
    radial-gradient(circle at 62% 28%, #fff 0 17%, transparent 18%);
}

body.has-chess-art-assets .white-side {
  background-image: var(--asset-side-goose);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.black-side {
  background-image:
    radial-gradient(circle at 42% 31%, #fff 0 4%, transparent 5%),
    radial-gradient(circle at 61% 31%, #fff 0 4%, transparent 5%),
    radial-gradient(circle at 52% 43%, #ff66a6 0 4%, transparent 5%),
    radial-gradient(ellipse at 50% 72%, #1b1720 0 33%, transparent 34%),
    radial-gradient(circle at 52% 31%, #28242d 0 26%, transparent 27%);
}

body.has-chess-art-assets .black-side {
  background-image: var(--asset-side-cat);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

body.has-chess-art-assets .white-side::after,
body.has-chess-art-assets .black-side::after {
  display: none;
}

.clock-stack,
.captured-lux,
.hint-card,
.move-history-card,
.rule-link {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.84);
  border-radius: 22px;
  background: rgba(255,255,255,.62);
  box-shadow: 0 14px 26px rgba(115, 24, 73, .08), inset 0 1px 0 rgba(255,255,255,.88);
}

.clock-stack {
  display: grid;
  gap: 0;
  overflow: hidden;
}

.clock-row {
  display: grid;
  grid-template-columns: 42px 1fr auto;
  align-items: center;
  gap: 10px;
  min-height: 62px;
  padding: 10px 14px;
}

.clock-row + .clock-row {
  border-top: 1px solid rgba(112, 31, 75, .1);
}

.clock-row time {
  color: var(--plum-800);
  font-family: var(--display);
  font-size: .98rem;
}

body[data-active-chess-turn="w"] .clock-row:first-child .clock-avatar,
body[data-active-chess-turn="b"] .clock-row:nth-child(2) .clock-avatar {
  animation: activeClockPulse 1.8s ease-in-out infinite;
}

.clock-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
}

.clock-white {
  background-image:
    radial-gradient(circle, #fff 0 52%, #ffdceb 53%);
}

.clock-black {
  background-image:
    radial-gradient(circle, #1d1921 0 52%, #ff8fc3 53%);
}

body.has-chess-art-assets .clock-white {
  background-image: var(--asset-avatar-goose);
  background-size: cover;
  background-position: center;
}

body.has-chess-art-assets .clock-black {
  background-image: var(--asset-avatar-cat);
  background-size: cover;
  background-position: center;
}

.difficulty-card {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid rgba(255,255,255,.84);
  border-radius: 22px;
  background: rgba(255,255,255,.68);
  box-shadow: 0 14px 26px rgba(115, 24, 73, .08), inset 0 1px 0 rgba(255,255,255,.88);
}

.difficulty-head {
  display: grid;
  gap: 4px;
}

.difficulty-head h2 {
  margin: 0;
  color: #3e1a35;
  font-size: .96rem;
}

.difficulty-head strong {
  color: var(--rose-600);
  font-family: var(--display);
  font-size: 1.08rem;
}

.difficulty-control {
  display: grid;
  grid-template-columns: 38px 1fr 38px;
  align-items: center;
  gap: 8px;
}

.difficulty-control button,
.difficulty-pips button {
  display: grid;
  place-items: center;
  border-radius: 999px;
  color: var(--rose-600);
  background: rgba(255,255,255,.82);
  box-shadow: inset 0 0 0 1px rgba(255,79,168,.12);
}

.difficulty-control button {
  min-height: 38px;
}

.difficulty-control label {
  display: grid;
  gap: 6px;
  color: rgba(77, 53, 103, .74);
  font-size: .74rem;
  font-weight: 900;
  text-transform: uppercase;
}

.difficulty-control input {
  width: 100%;
  accent-color: var(--rose-600);
}

.difficulty-pips {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 4px;
}

.difficulty-pips button {
  min-height: 28px;
  padding: 0;
  font-size: .72rem;
  font-weight: 900;
}

.difficulty-pips button.active {
  color: #fff;
  background: linear-gradient(135deg, #ff4fa8, #c71872);
  box-shadow: 0 10px 18px rgba(216, 24, 121, .2);
}

.difficulty-card p {
  margin: 0;
  color: #4d3567;
  font-size: .82rem;
  line-height: 1.4;
}

.chess-action-stack {
  display: grid;
  gap: 10px;
}

.chess-action-stack button {
  position: relative;
  overflow: hidden;
  min-height: 58px;
  display: grid;
  grid-template-columns: 34px 1fr;
  align-items: center;
  gap: 10px;
  padding: 0 20px;
  border-radius: 999px;
  color: #3e1a35;
  background: rgba(255,255,255,.76);
  box-shadow: 0 12px 24px rgba(115, 24, 73, .1), inset 0 1px 0 rgba(255,255,255,.95);
}

.chess-action-stack button i {
  color: var(--rose-600);
  font-size: 1.3rem;
}

.chess-action-stack button:hover,
.chess-action-stack button:focus-visible {
  color: #fff;
  background: linear-gradient(135deg, #ff4fa8, #c71872);
  transform: translateY(-2px);
}

.chess-action-stack button::after,
.dock-actions button::after,
.chess-result-overlay button::after {
  content: "";
  position: absolute;
  inset: -60% auto -60% -55%;
  width: 44%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  transform: rotate(18deg);
  opacity: 0;
  pointer-events: none;
}

.chess-action-stack button:hover::after,
.chess-action-stack button:focus-visible::after,
.dock-actions button:hover::after,
.dock-actions button:focus-visible::after,
.chess-result-overlay button:hover::after,
.chess-result-overlay button:focus-visible::after {
  animation: buttonGleam .68s ease both;
}

.chess-action-stack button:hover i,
.chess-action-stack button:focus-visible i {
  color: #fff;
}

.captured-lux {
  padding: 16px;
}

.captured-lux::after,
.move-history-card::after,
.hint-card::after {
  content: "";
  position: absolute;
  inset: auto 12px 10px auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,119,184,.16), transparent 68%);
  animation: panelSoftPulse 5.6s ease-in-out infinite;
  pointer-events: none;
}

.captured-lux h2,
.status-panel h2,
.move-history-card h2 {
  font-size: 1.08rem;
}

.captured-lux .captured-content {
  min-height: 46px;
  color: var(--plum-700);
  font-size: 1.4rem;
}

.captured-empty {
  display: grid;
  grid-template-columns: 44px 1fr;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(255, 255, 255, .76), rgba(255, 233, 243, .58));
  border: 1px dashed rgba(255, 140, 196, .42);
  font-size: 1rem;
}

.captured-empty-icon {
  width: 44px;
  height: 44px;
  background: var(--asset-piece-white-pawn) center / contain no-repeat;
  opacity: .55;
  filter: grayscale(.3);
}

.captured-empty > div {
  display: grid;
  gap: 2px;
}

.captured-empty strong {
  font-family: var(--display);
  font-size: .98rem;
  color: #6b073b;
  line-height: 1.2;
}

.captured-empty p {
  font-size: .8rem;
  line-height: 1.4;
  color: rgba(77, 53, 103, .82);
  margin: 0;
}

.captured-pieces {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 1.4rem;
  line-height: 1;
}

.captured-piece {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .72);
  box-shadow: inset 0 0 0 1px rgba(255, 140, 191, .26), 0 4px 10px rgba(196, 50, 126, .1);
  animation: capturedPieceIn .32s cubic-bezier(.2, .8, .24, 1) both;
}

@keyframes capturedPieceIn {
  0% { transform: scale(.6) rotate(-8deg); opacity: 0; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

.chess-board-stage {
  position: relative;
  display: grid;
  place-items: center;
  gap: 12px;
  padding: 18px;
  background:
    linear-gradient(135deg, rgba(255,255,255,.52), rgba(255,222,236,.34)),
    radial-gradient(circle at 50% 50%, rgba(255,255,255,.72), transparent 25rem);
}

.chess-board-stage::after {
  content: "";
  position: absolute;
  right: -14px;
  bottom: -12px;
  z-index: 0;
  width: 78px;
  height: 78px;
  background: url("assets/chess/final-png/props/corner-paw.png") center / contain no-repeat;
  opacity: .24;
  filter: drop-shadow(0 8px 14px rgba(196, 50, 126, .14));
  pointer-events: none;
}

.chess-board-stage > * {
  position: relative;
  z-index: 1;
}

.board-shell {
  position: relative;
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) 26px;
  gap: 6px;
  width: min(74svh, 720px);
  max-width: 100%;
  /* padding bumped from 22→28 to give room for the 9-layer frame stripes
     (8-9px concentric bands) — see [data-bevel="frame-board-luxe"]. */
  padding: 28px;
  border-radius: 26px;
  /* bg + shadow + border now from data-bevel="frame-board-luxe" */
  isolation: isolate;
}

/* Board-shell sakura corners — branches in all 4 corners frame the
   playing surface. Inset slightly so they don't get clipped on small
   viewports. */
.board-shell::before,
.board-shell::after {
  content: "";
  position: absolute;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
  z-index: 0;
  opacity: .82;
  filter: drop-shadow(0 3px 6px rgba(216, 24, 121, .22));
}

.board-shell::before {
  top: -8px;
  left: -8px;
  width: 64px;
  height: 64px;
  background-image: url("assets/chess/final-png/props/hero-blossom-left.png");
  transform: rotate(-12deg);
}

.board-shell::after {
  bottom: -6px;
  right: -8px;
  width: 60px;
  height: 60px;
  background-image: url("assets/chess/final-png/props/hero-blossom-right-down.png");
  transform: rotate(8deg);
}

/* Paw-print at bottom-left of board */
body[data-page="chess"] .board-shell .rank-labels.left::before {
  content: "";
  position: absolute;
  bottom: -10px;
  left: -10px;
  width: 36px;
  height: 36px;
  background: url("assets/chess/final-png/props/corner-paw.png") center/contain no-repeat;
  opacity: .58;
  transform: rotate(-18deg);
  pointer-events: none;
  z-index: 1;
  filter: drop-shadow(0 2px 4px rgba(216, 24, 121, .2));
}

.rank-labels {
  grid-row: 1;
  display: grid;
  grid-template-rows: repeat(8, 1fr);
  align-items: center;
  justify-items: center;
  color: var(--rose-600);
  font-family: var(--display);
  font-size: .82rem;
}

.file-labels {
  grid-column: 2;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  align-items: center;
  justify-items: center;
  color: var(--rose-600);
  font-family: var(--display);
  font-size: .82rem;
}

body[data-page="chess"] .chess-board {
  grid-column: 2;
  grid-row: 1;
  position: relative;
  width: 100%;
  background: #ffe5ee url("assets/chess/board-bloom-texture.png") center / 100% 100% no-repeat;
  border: 4px solid rgba(255,255,255,.96);
  border-radius: 16px;
  box-shadow: 0 18px 38px rgba(116, 18, 70, .18), inset 0 0 0 1px rgba(255,255,255,.7);
  cursor: grab;
  touch-action: none;
}

.board-animation-layer {
  grid-column: 2;
  grid-row: 1;
  position: relative;
  z-index: 8;
  align-self: stretch;
  justify-self: stretch;
  width: 100%;
  min-width: 0;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 16px;
  pointer-events: none;
  contain: layout paint;
}

body[data-page="chess"] .chess-board.dragging-piece {
  cursor: grabbing;
}

body[data-page="chess"] .chess-board::before,
body[data-page="chess"] .chess-board::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  opacity: 0;
}

body[data-page="chess"] .chess-square {
  font-size: clamp(2rem, 4.4vw, 3.65rem);
  background: transparent;
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,.24),
    inset 0 1px 0 rgba(255,255,255,.24),
    inset -1px 0 0 rgba(116, 18, 70, .04),
    inset 0 -1px 0 rgba(116, 18, 70, .04);
}

body[data-page="chess"] .chess-square.light {
  background: transparent;
}

body[data-page="chess"] .chess-square.dark {
  background: transparent;
}

body[data-page="chess"] .chess-square.last-move {
  background:
    radial-gradient(circle, rgba(255,255,255,.56), transparent 50%),
    linear-gradient(135deg, rgba(255,224,107,.46), rgba(255,79,168,.18));
}

body[data-page="chess"] .chess-square.move-destination .piece {
  animation: chessPieceLand .42s cubic-bezier(.2,.9,.2,1.25);
}

body[data-page="chess"] .chess-square.selected {
  outline: 0;
}

body[data-page="chess"] .chess-square.selected::before {
  content: "";
  position: absolute;
  inset: 4px;
  z-index: 1;
  border: 3px solid rgba(255,255,255,.96);
  border-radius: 14px;
  box-shadow: 0 0 0 3px rgba(255,79,168,.6), 0 0 24px rgba(255,79,168,.72);
}

body[data-page="chess"] .chess-square.legal::after {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 0;
  background: transparent;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  box-shadow: none;
  opacity: .85;
  filter: drop-shadow(0 4px 8px rgba(196, 50, 126, .26));
  animation: chessLegalPulse 1.6s ease-in-out infinite;
  pointer-events: none;
}

body[data-page="chess"][data-active-chess-turn="w"] .chess-square.legal::after {
  width: 36%;
  height: 36%;
  background-image: var(--asset-goose-step);
  filter: drop-shadow(0 4px 6px rgba(196, 50, 126, .3)) drop-shadow(0 0 6px rgba(255, 255, 255, .55));
}

body[data-page="chess"][data-active-chess-turn="b"] .chess-square.legal::after {
  width: 31%;
  height: 31%;
  background-image: var(--asset-cat-step);
  filter: drop-shadow(0 4px 6px rgba(48, 12, 37, .42)) drop-shadow(0 0 4px rgba(255, 255, 255, .35));
}

body[data-page="chess"][data-active-chess-turn="w"] .chess-square.capture::before {
  width: 40%;
  height: 40%;
  filter: drop-shadow(0 5px 8px rgba(196, 50, 126, .35)) drop-shadow(0 0 8px rgba(255, 255, 255, .6));
}

body[data-page="chess"][data-active-chess-turn="b"] .chess-square.capture::before {
  width: 35%;
  height: 35%;
  filter: drop-shadow(0 5px 8px rgba(48, 12, 37, .48)) drop-shadow(0 0 6px rgba(255, 255, 255, .42));
}

body[data-page="chess"] .chess-square.capture::after {
  inset: 8%;
  border: 4px solid rgba(255, 79, 168, .82);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, transparent 56%, rgba(255, 79, 168, .14) 82%);
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .45), 0 0 20px rgba(255, 79, 168, .36);
  animation: chessCapturePulse 1.4s ease-in-out infinite;
}

body[data-page="chess"] .chess-square.capture::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: .92;
  filter: drop-shadow(0 6px 10px rgba(196, 50, 126, .28));
  z-index: 2;
  pointer-events: none;
}

body[data-page="chess"][data-active-chess-turn="w"] .chess-square.capture::before {
  background-image: var(--asset-goose-step);
}

body[data-page="chess"][data-active-chess-turn="b"] .chess-square.capture::before {
  background-image: var(--asset-cat-step);
}

body[data-page="chess"] .chess-square.last-move.move-origin::after,
body[data-page="chess"] .chess-square.last-move.move-destination::after {
  content: "";
  position: absolute;
  z-index: 2;
  border: 0;
  box-shadow: none;
  pointer-events: none;
  animation: chessTrackStamp .6s ease both;
}

body[data-page="chess"] .chess-square.last-move.move-origin::after {
  right: 12%;
  bottom: 12%;
  --stamp-opacity: .28;
  transform: scale(.72) rotate(-14deg);
}

body[data-page="chess"] .chess-square.last-move.move-destination::after {
  left: 12%;
  top: 10%;
  --stamp-opacity: .54;
  transform: rotate(12deg);
}

body[data-page="chess"] .chess-square.track-cat::after {
  width: 30%;
  height: 28%;
  background: var(--asset-cat-step) center / contain no-repeat;
  opacity: var(--stamp-opacity, .54);
}

body[data-page="chess"] .chess-square.track-goose::after {
  width: 34%;
  height: 31%;
  background: var(--asset-goose-step) center / contain no-repeat;
  opacity: var(--stamp-opacity, .54);
  filter: drop-shadow(0 2px 2px rgba(148, 61, 88, .2));
}

body[data-page="chess"] .chess-square.drag-source .piece {
  opacity: .25;
  transform: scale(.88);
}

body[data-page="chess"] .chess-square .coord {
  display: none;
}

body[data-page="chess"] .piece {
  width: 86%;
  height: 86%;
  border-radius: 30%;
  font-size: .95em;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  transition: transform .18s ease, filter .18s ease;
}

body[data-page="chess"] .chess-square:hover .piece,
body[data-page="chess"] .chess-square:focus-visible .piece {
  transform: translateY(-3px) scale(1.03);
}

body[data-page="chess"] .black-piece .piece {
  color: #21151f;
  filter: drop-shadow(0 8px 8px rgba(48, 12, 37, .22));
  text-shadow: 0 1px 0 rgba(255,255,255,.2), 0 4px 9px rgba(48, 12, 37, .28);
}

body[data-page="chess"] .white-piece .piece {
  color: #fff8f4;
  -webkit-text-stroke: 1.25px #d27054;
  filter: drop-shadow(0 8px 8px rgba(139, 55, 49, .2));
  text-shadow: 0 1px 0 #fff, 0 4px 9px rgba(139, 55, 49, .2);
}

body.has-chess-piece-assets .piece,
body.has-chess-piece-assets[data-page="chess"] .white-piece .piece,
body.has-chess-piece-assets[data-page="chess"] .black-piece .piece {
  color: transparent !important;
  -webkit-text-stroke: 0 !important;
  text-shadow: none !important;
}

body.has-chess-piece-assets[data-page="chess"] .white-piece .piece,
body.has-chess-piece-assets[data-page="chess"] .black-piece .piece {
  /* Bumped 86-90% → 100% so PNG fills the full square via
     background-size: contain (PNG aspect preserved). Visible piece is
     ~77% wide × 100% tall — significantly larger than before. */
  width: 100%;
  height: 100%;
  position: relative;
}

/* Base "ground" shadow — dark ellipse beneath piece, simulates piece
   sitting on the board surface with a tight contact shadow. Color is
   parameterised via CSS vars so it can shift based on square underneath:
     - on light (cream) square → gold-amber tint (square reflects yellow)
     - on dark (pink) square → rose-magenta tint (square reflects pink)
   Default values are warm-dark (works as fallback). */
body.has-chess-piece-assets[data-page="chess"] .white-piece .piece,
body.has-chess-piece-assets[data-page="chess"] .black-piece .piece {
  --piece-shadow-rgb: 60, 24, 30;
  --piece-shadow-tint-rgb: 120, 50, 40;
  --piece-shadow-alpha: .56;
}

/* Black pieces — heavier core (denser darkness under) */
body.has-chess-piece-assets[data-page="chess"] .black-piece .piece {
  --piece-shadow-rgb: 20, 6, 14;
  --piece-shadow-alpha: .68;
}

/* On LIGHT (cream #fff2f8) squares — gold-amber tint.
   .light/.dark and .white-piece/.black-piece are all classes on the
   same .chess-square element, so compound selectors (no space). */
body.has-chess-piece-assets[data-page="chess"] .chess-square.light.white-piece .piece {
  --piece-shadow-rgb: 132, 78, 30;        /* warm gold-amber dark */
  --piece-shadow-tint-rgb: 200, 140, 60;  /* gold tint */
}
body.has-chess-piece-assets[data-page="chess"] .chess-square.light.black-piece .piece {
  --piece-shadow-rgb: 70, 38, 14;         /* deep amber-brown */
  --piece-shadow-tint-rgb: 160, 100, 40;
}

/* On DARK (pink #ff93c9) squares — rose-magenta tint */
body.has-chess-piece-assets[data-page="chess"] .chess-square.dark.white-piece .piece {
  --piece-shadow-rgb: 158, 50, 110;       /* rose-magenta dark */
  --piece-shadow-tint-rgb: 220, 90, 160;  /* pink tint */
}
body.has-chess-piece-assets[data-page="chess"] .chess-square.dark.black-piece .piece {
  --piece-shadow-rgb: 90, 18, 60;         /* deep magenta-plum */
  --piece-shadow-tint-rgb: 130, 32, 88;
}

body.has-chess-piece-assets[data-page="chess"] .white-piece .piece::after,
body.has-chess-piece-assets[data-page="chess"] .black-piece .piece::after {
  content: "";
  position: absolute;
  left: 14%;
  right: 14%;
  bottom: 2%;
  height: 16%;
  border-radius: 50%;
  pointer-events: none;
  z-index: -1;
  filter: blur(2.5px);
  background: radial-gradient(ellipse at 50% 30%,
    rgba(var(--piece-shadow-rgb), var(--piece-shadow-alpha)) 0%,
    rgba(var(--piece-shadow-tint-rgb), calc(var(--piece-shadow-alpha) * .55)) 50%,
    rgba(var(--piece-shadow-tint-rgb), 0) 100%);
}

body.has-chess-piece-assets[data-page="chess"] .white-piece .piece {
  filter:
    /* Top rim — warm peachy highlight on top of the piece */
    drop-shadow(0 1px 0 rgba(218, 92, 60, .5))
    /* Mid soft shadow — diffuse penumbra around piece */
    drop-shadow(0 4px 8px rgba(139, 55, 49, .26))
    /* Far ambient shadow — gives lift */
    drop-shadow(0 10px 14px rgba(70, 28, 24, .12));
}

body.has-chess-piece-assets[data-page="chess"] .black-piece .piece {
  filter:
    drop-shadow(0 1px 0 rgba(255, 200, 228, .26))
    drop-shadow(0 4px 8px rgba(48, 12, 37, .34))
    drop-shadow(0 10px 16px rgba(40, 18, 32, .14));
}

body.has-chess-piece-assets .piece-w-k { background-image: var(--asset-piece-white-king); }
body.has-chess-piece-assets .piece-w-q { background-image: var(--asset-piece-white-queen); }
body.has-chess-piece-assets .piece-w-r { background-image: var(--asset-piece-white-rook); }
body.has-chess-piece-assets .piece-w-b { background-image: var(--asset-piece-white-bishop); }
body.has-chess-piece-assets .piece-w-n { background-image: var(--asset-piece-white-knight); }
body.has-chess-piece-assets .piece-w-p { background-image: var(--asset-piece-white-pawn); }
body.has-chess-piece-assets .piece-b-k { background-image: var(--asset-piece-black-king); }
body.has-chess-piece-assets .piece-b-q { background-image: var(--asset-piece-black-queen); }
body.has-chess-piece-assets .piece-b-r { background-image: var(--asset-piece-black-rook); }
body.has-chess-piece-assets .piece-b-b { background-image: var(--asset-piece-black-bishop); }
body.has-chess-piece-assets .piece-b-n { background-image: var(--asset-piece-black-knight); }
body.has-chess-piece-assets .piece-b-p { background-image: var(--asset-piece-black-pawn); }

.chess-drag-ghost {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1000;
  width: clamp(54px, 8vw, 82px);
  height: clamp(54px, 8vw, 82px);
  display: grid;
  place-items: center;
  border-radius: 28%;
  font-size: clamp(2rem, 5vw, 4rem);
  line-height: 1;
  pointer-events: none;
  filter: drop-shadow(0 18px 18px rgba(68, 19, 49, .25));
  transition: none;
}

.chess-drag-ghost.white {
  color: #fff8f4;
  -webkit-text-stroke: 1.25px #d27054;
}

.chess-drag-ghost.black {
  color: #21151f;
  text-shadow: 0 1px 0 rgba(255,255,255,.2), 0 4px 9px rgba(48, 12, 37, .28);
}

body.has-chess-piece-assets .chess-drag-ghost {
  color: transparent;
  -webkit-text-stroke: 0;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  text-shadow: none;
}

body[data-page="chess"] .chess-board.move-flash::after {
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.55), transparent 58%);
  animation: chessBoardFlash .65s ease both;
}

body[data-page="chess"] .chess-board.capture-flash::after {
  background:
    radial-gradient(circle at 50% 50%, rgba(255,224,107,.55), transparent 24%),
    radial-gradient(circle at 50% 50%, rgba(255,79,168,.34), transparent 58%);
  animation: chessCaptureFlash .8s ease both;
}

body[data-page="chess"] .chess-board.check-flash::after {
  background: radial-gradient(circle at 50% 50%, rgba(255,79,168,.42), transparent 62%);
  animation: chessCheckFlash .82s ease both;
}

body[data-page="chess"] .chess-board.mate-flash::after {
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,.76), transparent 24%),
    radial-gradient(circle at 50% 50%, rgba(255,79,168,.44), transparent 62%);
  animation: chessMateFlash .95s ease both;
}

.move-trail-fx,
.board-effect-fx {
  position: absolute;
  pointer-events: none;
}

.move-trail-fx {
  left: var(--x);
  top: var(--y);
  width: var(--length);
  height: calc(var(--cell) * .1);
  min-height: 5px;
  max-height: 10px;
  transform: translateY(-50%) rotate(var(--angle));
  transform-origin: 0 50%;
  border-radius: 999px;
  opacity: 0;
  animation: chessTrailShell 1s ease both;
}

.move-trail-fx::before,
.move-trail-fx::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.move-trail-fx::before {
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.96) 22%, rgba(255,79,168,.62) 64%, rgba(255,255,255,0));
  box-shadow: 0 0 18px rgba(255,79,168,.26);
  transform-origin: 0 50%;
  animation: chessTrailDraw .72s cubic-bezier(.2,.8,.24,1) both;
}

.move-trail-fx::after {
  inset: calc(var(--cell) * -.13) 0;
  opacity: .74;
  background-repeat: repeat-x;
  background-size: calc(var(--cell) * .34) 100%;
  animation: chessTrailMarks .82s ease both;
}

body.has-chess-effect-assets .move-trail-fx::after {
  inset: calc(var(--cell) * -.18) 0;
  background-position: 0 center;
  background-size: calc(var(--cell) * .3) calc(var(--cell) * .3);
}

.cat-trail::after {
  background-image: var(--asset-cat-step);
}

.goose-trail::after {
  background-image: var(--asset-goose-step);
}

.hint-trail::before {
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,224,107,.92), rgba(255,255,255,0));
}

.capture-trail::before,
.check-trail::before,
.mate-trail::before {
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.96) 18%, rgba(255,79,168,.88) 54%, rgba(255,224,107,.8), rgba(255,255,255,0));
}

.board-effect-fx {
  left: var(--x);
  top: var(--y);
  width: calc(var(--cell) * 1.02);
  height: calc(var(--cell) * 1.02);
  transform: translate(-50%, -50%);
}

.impact-ring-fx {
  border: 3px solid rgba(255,255,255,.88);
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(255,79,168,.36), 0 0 22px rgba(255,79,168,.28);
  animation: chessImpactRing .82s cubic-bezier(.16,.82,.24,1) both;
}

.impact-ring-fx.capture-tone,
.impact-ring-fx.check-tone {
  border-color: rgba(255,224,107,.9);
  box-shadow: 0 0 0 3px rgba(255,79,168,.48), 0 0 28px rgba(255,79,168,.38);
}

.capture-burst-fx {
  width: calc(var(--cell) * 1.22);
  height: calc(var(--cell) * 1.22);
  animation: chessBurstFade 1.06s ease both;
}

body.has-chess-effect-assets .capture-burst-fx {
  width: calc(var(--cell) * 1.32);
  height: calc(var(--cell) * 1.32);
  background: url("assets/chess/final-png/effects/capture-burst.png") center / contain no-repeat;
  background-color: transparent;
  mix-blend-mode: screen;
  filter: drop-shadow(0 8px 16px rgba(216, 24, 121, .22));
  opacity: 1;
}

body.has-chess-effect-assets .capture-burst-fx::before,
body.has-chess-effect-assets .capture-burst-fx::after {
  display: none;
}

.capture-burst-fx::before,
.capture-burst-fx::after {
  content: "";
  position: absolute;
  inset: 12%;
  border-radius: 50%;
  background:
    conic-gradient(from 18deg, transparent 0 9%, rgba(255,255,255,.92) 10% 13%, transparent 14% 23%, rgba(255,79,168,.78) 24% 28%, transparent 29% 43%, rgba(255,224,107,.86) 44% 48%, transparent 49% 100%);
  filter: drop-shadow(0 4px 10px rgba(216, 24, 121, .22));
  animation: chessBurstSpin 1.06s ease both;
}

.capture-burst-fx::after {
  inset: 28%;
  background: radial-gradient(circle, rgba(255,255,255,.96), rgba(255,79,168,.6) 46%, transparent 48%);
  animation-name: chessBurstCore;
}

.check-aura-fx {
  width: calc(var(--cell) * 1.34);
  height: calc(var(--cell) * 1.34);
  border-radius: 30%;
  background:
    radial-gradient(circle, rgba(255,255,255,.78), transparent 34%),
    radial-gradient(circle, rgba(255,79,168,.5), transparent 66%);
  box-shadow: 0 0 0 3px rgba(255,255,255,.58), 0 0 30px rgba(255,79,168,.38);
  animation: chessCheckAura 1.28s ease both;
}

body.has-chess-effect-assets .check-aura-fx {
  width: calc(var(--cell) * 1.55);
  height: calc(var(--cell) * 1.55);
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,1) 0 20%, rgba(255,144,203,.96) 44%, rgba(255,224,107,.82) 68%, transparent 84%);
  background-color: transparent;
  -webkit-mask-image: url("assets/chess/final-png/effects/check-aura.png");
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-image: url("assets/chess/final-png/effects/check-aura.png");
  mask-mode: luminance;
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: contain;
  border-radius: 0;
  box-shadow: none;
  mix-blend-mode: screen;
  opacity: 1;
}

.check-aura-fx.mate-tone {
  background:
    radial-gradient(circle, rgba(255,255,255,.9), transparent 34%),
    radial-gradient(circle, rgba(255,224,107,.62), transparent 46%),
    radial-gradient(circle, rgba(255,79,168,.58), transparent 70%);
}

body.has-chess-effect-assets .check-aura-fx.mate-tone {
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,1) 0 22%, rgba(255,224,107,.94) 44%, rgba(255,79,168,.86) 68%, transparent 88%);
  -webkit-mask-image: url("assets/chess/final-png/effects/checkmate-bloom.png");
  mask-image: url("assets/chess/final-png/effects/checkmate-bloom.png");
  width: calc(var(--cell) * 1.74);
  height: calc(var(--cell) * 1.74);
}

.promotion-glow-fx,
.hint-ripple-fx {
  width: calc(var(--cell) * 1.18);
  height: calc(var(--cell) * 1.18);
  border-radius: 30%;
}

.promotion-glow-fx {
  background:
    linear-gradient(135deg, transparent 48%, rgba(255,224,107,.9) 49% 54%, transparent 55%),
    radial-gradient(circle at 50% 68%, rgba(255,255,255,.86), transparent 34%),
    radial-gradient(circle, rgba(255,79,168,.48), transparent 72%);
  box-shadow: 0 0 0 3px rgba(255,255,255,.54), 0 0 30px rgba(255,79,168,.28);
  animation: chessPromotionGlow 1.4s ease both;
}

body.has-chess-effect-assets .promotion-glow-fx {
  width: calc(var(--cell) * 1.5);
  height: calc(var(--cell) * 1.5);
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,1) 0 26%, rgba(255,197,226,.92) 50%, rgba(255,79,168,.78) 74%, transparent 88%);
  background-color: transparent;
  -webkit-mask-image: url("assets/chess/final-png/effects/promotion-glow.png");
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-image: url("assets/chess/final-png/effects/promotion-glow.png");
  mask-mode: luminance;
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: contain;
  border-radius: 0;
  box-shadow: none;
  mix-blend-mode: screen;
  opacity: 1;
}

.hint-ripple-fx {
  border: 3px dashed rgba(255,224,107,.9);
  box-shadow: 0 0 20px rgba(255,224,107,.34);
  animation: chessHintRipple 1.06s ease both;
}

body.has-chess-effect-assets .hint-ripple-fx {
  border: 0;
  background: url("assets/chess/final-png/effects/move-sparkle.png") center / contain no-repeat;
  background-color: transparent;
  box-shadow: none;
  mix-blend-mode: screen;
  filter: drop-shadow(0 6px 12px rgba(255, 79, 168, .26));
  opacity: 1;
}

body[data-page="chess"] .promotion-picker {
  position: relative;
  overflow: hidden;
}

body[data-page="chess"] .promotion-picker:not([hidden]) {
  animation: promotionPanelIn .34s cubic-bezier(.2,.95,.25,1.18) both;
}

body.has-chess-ui-assets .promotion-picker {
  background:
    url("assets/chess/final-png/ui/promotion-frame.png") center / 100% 100% no-repeat,
    rgba(255,255,255,.78);
}

body[data-page="chess"] .promotion-picker:not([hidden])::before {
  content: "";
  position: absolute;
  inset: -30%;
  background:
    radial-gradient(circle at 28% 42%, rgba(255,224,107,.34), transparent 20%),
    radial-gradient(circle at 68% 38%, rgba(255,79,168,.25), transparent 18%);
  animation: promotionPanelGlow 2.4s ease-in-out infinite;
  pointer-events: none;
}

body[data-page="chess"] .promotion-picker > * {
  position: relative;
  z-index: 1;
}

.chess-board-dock {
  width: min(74svh, 720px);
  max-width: 100%;
  display: grid;
  grid-template-columns: minmax(110px, auto) minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(255,255,255,.88);
  border-radius: 22px;
  background: rgba(255,255,255,.68);
  box-shadow: 0 16px 34px rgba(116, 18, 70, .13), inset 0 1px 0 rgba(255,255,255,.9);
  backdrop-filter: blur(16px);
}

/* Phase 2: boss-match flag spans all dock columns at the top, telegraphing
   the no-hint/no-undo restriction immediately before the player taps either
   button. Hidden by default; JS shows when state.aiLevel maps to a boss. */
.chess-board-boss-flag {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 14px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .02em;
  color: #fff;
  background: linear-gradient(135deg, #d8348e 0%, #ff6f4a 100%);
  box-shadow: 0 4px 12px rgba(216, 24, 121, .28);
}
.chess-board-boss-flag[hidden] { display: none; }
.chess-board-boss-flag .ti-flame {
  font-size: 14px;
  filter: drop-shadow(0 1px 0 rgba(255, 200, 80, .6));
}

/* Phase 4: streak badge — surfaces win-streak multiplier (×1.2/1.5/2.0).
   Shares the dock-top-row slot with boss flag. Only one is visible at a
   time in practice (boss-match disables hints which usually breaks streak
   anyway), but stacked rendering is fine if both fire. */
.chess-board-streak-badge {
  /* Phase 27: badge moved out of grid stack — floating top-right corner of
     board area instead of taking own dock row. Frees vertical space. */
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .02em;
  color: #4d1f0a;
  background: linear-gradient(135deg, #ffe48a 0%, #ffb347 100%);
  box-shadow: 0 4px 12px rgba(255, 130, 50, .28);
  animation: chess-streak-pulse 2.4s ease-in-out infinite;
  z-index: 5;
}
/* Anchor parent для absolute streak badge — board-stage is the natural
   container since it wraps board + dock + player rows. */
.chess-board-stage {
  position: relative;
}
.chess-board-streak-badge[hidden] { display: none; }
.chess-board-streak-badge .ti-bolt {
  font-size: 14px;
  color: #b85518;
}
.chess-board-streak-badge em {
  font-style: normal;
  font-variant-numeric: tabular-nums;
  font-weight: 900;
  color: #7a2c0a;
}
.chess-board-streak-badge[data-streak-tier="hot"] {
  background: linear-gradient(135deg, #ff6f4a 0%, #d8348e 100%);
  color: #fff;
}
.chess-board-streak-badge[data-streak-tier="hot"] .ti-bolt,
.chess-board-streak-badge[data-streak-tier="hot"] em { color: #fff5e0; }
@keyframes chess-streak-pulse {
  0%, 100% { box-shadow: 0 4px 12px rgba(255, 130, 50, .28); }
  50%      { box-shadow: 0 6px 20px rgba(255, 130, 50, .55); }
}
@media (prefers-reduced-motion: reduce) {
  .chess-board-streak-badge { animation: none; }
}

/* Phase 2: dock buttons greyed-out when blocked. Hint exhausted (no
   charges left) was already styled via [data-hint-exhausted="true"];
   add boss-block visual treatment for hint+undo. */
.dock-actions [data-hint-blocked="boss"],
.dock-actions [data-undo-blocked="boss"] {
  opacity: .42;
  cursor: not-allowed;
  pointer-events: auto; /* keep clickable so toast can fire */
}

/* === Phase 4: Cosmetics teaser ("Скоро в обновлениях" в Копилка tab).
   Showcases future purchases with placeholder pricing so balance has a
   visible long-term destination. All items are visually locked — no buy
   buttons in this version. */
.chess-shop-coming-soon {
  display: grid;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 18px;
  background: rgba(255, 247, 236, .68);
}
.chess-shop-coming-soon-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.chess-shop-coming-soon-head h3 {
  margin: 0;
  font-family: 'Unbounded', system-ui, sans-serif;
  font-size: 16px;
  font-weight: 700;
  color: var(--plum-900, #2a0d28);
  letter-spacing: -0.01em;
}
.chess-shop-coming-soon-head em {
  font-style: normal;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #c89318;
}
.chess-shop-coming-soon-list {
  display: grid;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.chess-shop-coming-soon-item {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  opacity: .72;
}
.chess-shop-coming-soon-icon {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: linear-gradient(135deg, rgba(255, 230, 240, .7), rgba(255, 200, 110, .35));
  color: var(--plum-700);
}
.chess-shop-coming-soon-icon .ti {
  font-size: 20px;
}
.chess-shop-coming-soon-item strong {
  display: block;
  font-size: 14px;
  font-weight: 800;
  color: var(--plum-900, #2a0d28);
  letter-spacing: -0.01em;
}
.chess-shop-coming-soon-item span {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--plum-700, #4d1c3b);
  opacity: .8;
  margin-top: 2px;
}
.chess-shop-coming-soon-price {
  font-style: normal;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  font-size: 13px;
  color: #b85518;
  white-space: nowrap;
}
.chess-shop-coming-soon-foot {
  margin: 0;
  padding-top: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--plum-700, #4d1c3b);
  opacity: .75;
  text-align: center;
}

/* Scoped to the desktop turn label (".chess-board-dock > div > span") so the
   transform doesn't leak to the dock-action button labels nested inside
   ".dock-actions button > span". */
.chess-board-dock > div > span {
  display: block;
  color: rgba(77, 53, 103, .68);
  font-size: .72rem;
  font-weight: 900;
  text-transform: uppercase;
}

.chess-board-dock strong {
  color: #6b073b;
  font-family: var(--display);
  font-size: 1rem;
}

.chess-board-dock p {
  min-width: 0;
  color: #4d3567;
  font-size: .88rem;
  line-height: 1.35;
}

.dock-actions {
  display: grid;
  grid-template-columns: repeat(4, 42px);
  gap: 8px;
}

.dock-actions button,
.chess-result-overlay button {
  position: relative;
  overflow: hidden;
  min-height: 42px;
  border-radius: 999px;
  /* bg + shadow + color from data-bevel preset on each button */
}

.dock-actions button {
  display: grid;
  place-items: center;
  padding: 0;
}

/* === Post-game result overlay — premium redesign ============================
   Stage-level overlay sits above the board on game-end. Uses real PNG hero
   illustrations (result-win-cat / result-win-goose / result-draw) rather
   than the previous opacity-.11 background trick — the assets are 1.5-1.7 MB
   and deserve to be seen. Result-kind drives a CSS variable palette so the
   accent ring, halo and primary CTA shift between win (gold), loss
   (lavender), and draw (rose). */

/* Phase 8: global backdrop dim for promotion picker. Applied via :has()
   selector on body — лучше чем picker's own ::before которая не работала
   из-за picker's position:fixed parent создающего own stacking context. */
body[data-page="chess"]:has(.promotion-picker:not([hidden]))::after {
  content: "";
  position: fixed;
  inset: 0;
  background: rgba(46, 14, 32, .52);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  z-index: 75;
  pointer-events: auto;
  animation: chessPromoBackdropIn .28s ease both;
}
@keyframes chessPromoBackdropIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* End-of-game peek bar — bottom-floating pill that appears for ~2.4 s
   after checkmate/stalemate so the user sees the final board (king in
   check, last move arrow) before the result modal lands. Tap to skip
   the wait; undo cancels the pending reveal entirely. */
.chess-end-peek {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
  transform: translateX(-50%);
  z-index: 120;
  display: inline-grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border: none;
  border-radius: 16px;
  background: linear-gradient(135deg, #fff5fa 0%, #ffe2f0 100%);
  color: var(--plum-800, #4d1933);
  cursor: pointer;
  text-align: left;
  box-shadow:
    0 14px 32px rgba(46, 14, 32, .38),
    0 0 0 1px rgba(255, 255, 255, .9),
    inset 0 1px 0 rgba(255, 255, 255, 1);
  animation: chessEndPeekIn .35s cubic-bezier(.34, 1.56, .64, 1) both;
  max-width: min(94vw, 360px);
}
.chess-end-peek[hidden] { display: none !important; }
.chess-end-peek:hover, .chess-end-peek:focus-visible {
  transform: translateX(-50%) translateY(-2px);
  filter: brightness(1.04);
}
.chess-end-peek:active { transform: translateX(-50%) scale(.98); }

.chess-end-peek-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(180deg, #ffd84a 0%, #ffaa1f 100%);
  color: #fff;
  font-size: 1.05rem;
  box-shadow: 0 3px 8px rgba(255, 153, 0, .45), inset 0 1px 2px rgba(255, 255, 255, .55);
}
.chess-end-peek[data-outcome="stalemate"] .chess-end-peek-icon {
  background: linear-gradient(180deg, #c9b3e0 0%, #6f4d8a 100%);
}

.chess-end-peek-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.chess-end-peek-text {
  font-family: var(--display, inherit);
  font-size: .95rem;
  font-weight: 900;
  color: var(--plum-800, #4d1933);
  letter-spacing: -.01em;
  line-height: 1.1;
}
.chess-end-peek-body em {
  font-style: normal;
  font-family: var(--display, inherit);
  font-size: .68rem;
  font-weight: 700;
  color: var(--plum-700, #6f4d8a);
  letter-spacing: .02em;
}
.chess-end-peek-arrow {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(216, 24, 121, .12);
  color: var(--rose-600, #d71879);
  font-size: 1rem;
  animation: chessEndPeekArrow 1.4s ease-in-out infinite;
}

@keyframes chessEndPeekIn {
  from { opacity: 0; transform: translate(-50%, 14px) scale(.94); }
  to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
@keyframes chessEndPeekArrow {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .chess-end-peek { animation: none; }
  .chess-end-peek-arrow { animation: none; }
}

.chess-result-overlay {
  --result-accent: #ffe06b;
  --result-accent-soft: rgba(255, 224, 107, .42);
  --result-text: #4d1933;
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  padding: 16px;
  background:
    radial-gradient(circle at 50% 30%, rgba(255, 192, 220, .55), transparent 60%),
    rgba(46, 14, 32, .56);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.chess-result-overlay[hidden] { display: none !important; }

.chess-result-overlay[data-result-kind="goose"] {
  --result-accent: #ffd54a;
  --result-accent-soft: rgba(255, 213, 74, .42);
}
.chess-result-overlay[data-result-kind="cat"] {
  --result-accent: #c9b3e0;
  --result-accent-soft: rgba(180, 150, 220, .38);
  --result-text: #3a1147;
}
.chess-result-overlay[data-result-kind="draw"] {
  --result-accent: #ff8fc4;
  --result-accent-soft: rgba(255, 143, 196, .42);
}

.chess-result-card {
  position: relative;
  width: min(94%, 340px);
  max-height: calc(100% - 24px);
  overflow: hidden auto;
  display: grid;
  gap: 10px;
  padding: 18px 18px 16px;
  text-align: center;
  border-radius: 22px;
  /* bg + shadow + border from data-bevel + per-kind override in style-bevels.css.
     The kind-specific accent ring (--result-accent-soft) is preserved by adding
     it as an inset stack on top via .chess-result-overlay[data-result-kind] rule. */
  animation: chessResultCardIn .52s cubic-bezier(.34, 1.56, .64, 1) both;
}
@keyframes chessResultCardIn {
  0%   { opacity: 0; transform: translateY(24px) scale(.86); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Hero illustration --------------------------------------------------------
   Full-width banner (card-padding-aware) so the dense PNG composition
   (goose / trophy / cat / 'ПОБЕДА ГУСЯ' lettering) is actually readable.
   Rounded corners + soft drop-shadow + radial halo behind to anchor it
   visually. Aspect ratio 5/4 matches the source illustrations. */
.chess-result-hero {
  position: relative;
  width: 100%;
  aspect-ratio: 5 / 4;
  display: block;
  isolation: isolate;
  border-radius: 18px;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(255, 230, 240, .82), rgba(255, 245, 250, .92));
  box-shadow:
    0 12px 24px rgba(116, 18, 70, .22),
    inset 0 0 0 1px rgba(255, 255, 255, .92);
  animation: chessResultHeroIn .72s cubic-bezier(.34, 1.56, .64, 1) .12s both;
}
@keyframes chessResultHeroIn {
  0%   { opacity: 0; transform: translateY(20px) scale(.94); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.chess-result-hero-img {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.chess-result-hero-halo {
  position: absolute;
  inset: -10% -8% -10% -8%;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(circle, var(--result-accent-soft) 0%, transparent 64%);
  animation: chessResultHaloPulse 3.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes chessResultHaloPulse {
  0%, 100% { transform: scale(.96); opacity: .68; }
  50%      { transform: scale(1.06); opacity: 1; }
}

/* Loss variant: dim/desaturate the cat illustration so it still reads as
   'opponent wins' rather than a celebration of the cat. */
.chess-result-overlay[data-result-kind="cat"] .chess-result-hero-img {
  filter: saturate(.85) brightness(.96);
}
.chess-result-overlay[data-result-kind="cat"] .chess-result-hero {
  box-shadow:
    0 10px 22px rgba(58, 17, 71, .26),
    inset 0 0 0 1px rgba(255, 255, 255, .82);
}

/* Phase 7: hide sticky resume button when result modal is open — was
   intruding bottom-left on result celebration screens. */
body:has([data-chess-result]:not([hidden])) [data-chess-sticky-resume] {
  display: none !important;
}
/* Phase 7: outcome-aware hero treatment placeholder. Loss outcomes get
   subtle desaturation since current art has both characters celebrating —
   makes loss feel less misleading until proper loss assets land. */
[data-chess-result-hero-img][data-outcome="loss"] {
  filter: saturate(.55) brightness(.92);
}
/* Shared entrance animation for prize chip + actions (used to be for stats
   row but stats are gone — kept the keyframe for the prize chip + actions). */
@keyframes chessResultStatsIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Action row — V18 3-button layout. Primary CTA on row 1 (full-width),
   2 secondaries on row 2 (side-by-side). Close X is absolute-positioned
   in the card corner — outside this grid entirely.
   When chess-result-next is hidden (last boss), chess-new is promoted
   to primary via data-role="primary" set by JS. */
.chess-result-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 6px;
  animation: chessResultStatsIn .5s cubic-bezier(.34, 1.56, .64, 1) .68s both;
}
.chess-result-action[hidden] { display: none !important; }
/* Primary CTA spans both columns */
.chess-result-actions .chess-result-primary,
.chess-result-actions .chess-result-action[data-role="primary"] {
  grid-column: 1 / -1;
}
/* When promoted to primary via data-role, override the secondary visuals */
.chess-result-action[data-role="primary"].chess-result-new {
  min-height: 52px;
  font: 800 1rem var(--display, inherit);
}
/* Secondary CTAs each take 1 column */
.chess-result-actions .chess-result-action[data-role="secondary"] {
  grid-column: span 1;
}
/* Single secondary alone = full row */
.chess-result-actions .chess-result-action[data-role="secondary-wide"] {
  grid-column: 1 / -1;
}

/* Close X — anchored to card corner, outside actions flow.
   Card already has position: relative via the existing rule below.
   Selector specificity bumped via .chess-result-overlay so it beats the
   `.chess-result-overlay button { position: relative }` reset rule
   that affects all buttons inside the overlay. */
.chess-result-overlay .chess-result-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="button-clean" */
  color: var(--plum-700, #6f4d8a);
  cursor: pointer;
  z-index: 5;
  transition: transform .18s ease, filter .18s ease;
}
.chess-result-overlay .chess-result-close:hover,
.chess-result-overlay .chess-result-close:focus-visible {
  transform: scale(1.05);
  filter: brightness(1.04);
}
.chess-result-overlay .chess-result-close:active { transform: scale(.94); }
.chess-result-overlay .chess-result-close i { font-size: 1.1rem; }

@media (max-width: 480px) {
  .chess-result-card { position: relative; }
  .chess-result-actions .chess-result-action {
    min-height: 48px;
    padding: 0 14px;
    font-size: .92rem;
  }
  .chess-result-actions .chess-result-primary,
  .chess-result-actions .chess-result-action[data-role="primary"] {
    min-height: 52px;
    font-size: 1rem;
  }
}
.chess-result-primary {
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 22px;
  border-radius: 16px;
  /* bg + shadow + border from data-bevel="button-jewel" */
  color: #fff;
  font: 800 1rem var(--display, inherit);
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}
.chess-result-primary:hover,
.chess-result-primary:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.04) saturate(1.06);
}
.chess-result-primary:active {
  transform: translateY(0) scale(.98);
}
.chess-result-primary i {
  font-size: 1.2rem;
}
/* Secondary action ("Заново" / "Анализ") — sits side-by-side with its sibling
   secondary on row 2 of the actions grid. Subtle thin-pill style so it does
   not compete with the rose-gradient primary CTA above. */
.chess-result-new,
.chess-result-review {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 14px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="button-thin" */
  color: var(--plum-800, #4d1933);
  font: 700 .92rem var(--display, inherit);
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}
.chess-result-new:hover,
.chess-result-new:focus-visible,
.chess-result-review:hover,
.chess-result-review:focus-visible {
  transform: translateY(-1px);
  filter: brightness(1.04) saturate(1.06);
}
.chess-result-new:active,
.chess-result-review:active { transform: scale(.98); }
.chess-result-new i,
.chess-result-review i { font-size: 1.05rem; color: var(--rose-600, #d71879); }
.chess-result-review[disabled] {
  opacity: .58;
  cursor: progress;
}
.chess-result-review-progress {
  font-style: normal;
  font-size: .76rem;
  color: var(--plum-700, #6f4d8a);
  font-variant-numeric: tabular-nums;
  margin-left: 4px;
}
.chess-result-review-progress[hidden] { display: none; }

/* Reduced motion: kill spring entrances; keep crossfade only */
@media (prefers-reduced-motion: reduce) {
  .chess-result-card,
  .chess-result-hero,
  .chess-result-prize,
  .chess-result-tasks,
  .chess-result-actions {
    animation: chessResultPop .28s ease both !important;
  }
  .chess-result-hero-halo,
  .chess-result-hero-rays { animation: none !important; }
}

@keyframes chessResultShake {
  10%, 90% { transform: translate3d(-1px, 0, 0); }
  20%, 80% { transform: translate3d(2px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
  40%, 60% { transform: translate3d(4px, 0, 0); }
}

.pulse-attract {
  position: relative;
  animation: pulseAttract 1.6s ease-in-out infinite;
}

.pulse-attract::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: inherit;
  border: 2px solid rgba(255, 79, 168, .55);
  animation: pulseAttractRing 1.6s ease-in-out infinite;
  pointer-events: none;
}

@keyframes pulseAttract {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 79, 168, .35); }
  50%      { box-shadow: 0 0 0 8px rgba(255, 79, 168, 0); }
}

@keyframes pulseAttractRing {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 0;   transform: scale(1.18); }
}

.chess-confetti-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
  z-index: 30;
}

.chess-confetti-layer span {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 6px;
  border-radius: 50%;
  background: var(--color, #ff5fb7);
  opacity: 0;
  transform: translate(-50%, -50%);
  animation: chessConfettiFly 1.8s cubic-bezier(.18, .76, .35, 1) var(--delay, 0s) both;
  filter: drop-shadow(0 4px 6px rgba(116, 18, 70, .26));
}

.chess-confetti-layer span:nth-child(3n) {
  width: 8px;
  height: 8px;
  border-radius: 2px;
}

.chess-confetti-layer span:nth-child(4n) {
  width: 14px;
  height: 7px;
  border-radius: 70% 30% 70% 30%;
}

@keyframes chessConfettiFly {
  0%   { opacity: 0; transform: translate(-50%, -50%) rotate(0); }
  12%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot, 360deg)); }
}

/* Accessibility: ensure 44px touch targets even on densest viewport */
@media (max-width: 760px) {
  body[data-page="chess"] .dock-actions button,
  body[data-page="chess"] .chess-game-action,
  body[data-page="chess"] .chess-game-setting,
  body[data-page="chess"] .chess-bottom-sheet-tabs button,
  body[data-page="chess"] .chess-start-grid button,
  body[data-page="chess"] .chess-start-levels button,
  body[data-page="chess"] .promotion-picker button,
  body[data-page="chess"] [data-chess-bar-clock],
  body[data-page="chess"] .chess-result-actions button {
    min-height: 44px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .chess-board.board-entry .chess-square,
  .chess-square.selected::before,
  .chess-square.legal::after,
  .chess-square.capture::after,
  .chess-square.capture::before,
  .chess-square.in-check,
  .chess-square.in-check::before,
  .turn-card.turn-flip,
  .player-bar.is-active .player-bar-avatar,
  .chess-bottom-sheet-card,
  .chess-bottom-sheet-backdrop,
  .chess-confetti-layer span,
  .chess-square.illegal-shake { animation: none !important; transition: none !important; }
}

.chess-square.illegal-shake {
  animation: chessIllegalShake .42s cubic-bezier(.36, .07, .19, .97) both;
}

.chess-square.illegal-shake::after {
  content: "";
  position: absolute;
  inset: 12%;
  border-radius: 14%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 79, 168, .42), transparent 70%);
  pointer-events: none;
  animation: chessIllegalGlow .42s ease both;
}

@keyframes chessIllegalShake {
  10%, 90% { transform: translate3d(-2px, 0, 0); }
  20%, 80% { transform: translate3d(3px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-5px, 0, 0); }
  40%, 60% { transform: translate3d(5px, 0, 0); }
}

@keyframes chessIllegalGlow {
  0%, 100% { opacity: 0; }
  40%      { opacity: 1; }
}

body[data-page="chess"][data-active-chess-turn="w"] .chess-square.white-piece:hover .piece,
body[data-page="chess"][data-active-chess-turn="b"] .chess-square.black-piece:hover .piece {
  transform: translateY(-4px) scale(1.06);
  filter: drop-shadow(0 12px 14px rgba(196, 50, 126, .32)) drop-shadow(0 0 8px rgba(255, 224, 107, .55));
}

.dock-actions button[aria-label] {
  position: relative;
}

.dock-actions button[aria-label]::after {
  content: attr(aria-label);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(46, 14, 32, .92);
  color: #fff8fc;
  font-family: var(--display);
  font-size: .72rem;
  letter-spacing: .02em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease;
  box-shadow: 0 8px 16px rgba(58, 16, 40, .26);
  z-index: 12;
}

.dock-actions button[aria-label]:hover::after,
.dock-actions button[aria-label]:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.turn-card {
  perspective: 800px;
}

.turn-card.turn-flip {
  animation: chessTurnFlip .58s cubic-bezier(.18, .76, .35, 1) both;
}

@keyframes chessTurnFlip {
  0%   { transform: rotateY(0); }
  45%  { transform: rotateY(-18deg) translateX(-4px); filter: brightness(1.12); }
  100% { transform: rotateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .turn-card.turn-flip { animation: none !important; }
}

.chess-square.hint-source::before,
.chess-square.hint-target::before {
  content: "";
  position: absolute;
  inset: 4%;
  border-radius: 14%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 224, 107, .58), rgba(255, 79, 168, .26) 60%, transparent 80%);
  box-shadow: inset 0 0 0 2px rgba(255, 224, 107, .82);
  pointer-events: none;
  z-index: 2;
  animation: chessHintHalo 1.6s ease both;
}

.chess-square.hint-target::before {
  background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .7), rgba(255, 224, 107, .65) 50%, rgba(255, 79, 168, .35) 78%, transparent 90%);
  box-shadow: inset 0 0 0 3px rgba(255, 224, 107, .88), 0 0 24px rgba(255, 224, 107, .42);
  animation: chessHintTargetHalo 1.6s ease both;
}

@keyframes chessHintHalo {
  0%   { opacity: 0; transform: scale(.7); }
  30%  { opacity: 1; transform: scale(1.06); }
  100% { opacity: 0; transform: scale(1); }
}

@keyframes chessHintTargetHalo {
  0%, 100% { opacity: 0; transform: scale(.85); }
  20%      { opacity: 1; transform: scale(1.08); }
  50%      { opacity: 1; transform: scale(1); }
  80%      { opacity: 1; transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .chess-square.hint-source::before,
  .chess-square.hint-target::before { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .chess-confetti-layer span,
  .chess-square.illegal-shake { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .chess-result-overlay > div { animation: chessResultPop .38s ease both; }
}

/* The previous opacity:.11 background trick is replaced by the real <img>
   inside .chess-result-hero — these legacy hooks are kept commented out for
   reference but no longer set anything. */
.chess-result-overlay .chess-bloom-mark { display: none; }

.chess-result-overlay button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 18px;
}

.status-panel {
  padding: 24px;
}

.panel-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.panel-heading span {
  color: var(--rose-500);
  font-size: 1.7rem;
}

.rule-link {
  min-height: 88px;
  display: grid;
  grid-template-columns: 48px 1fr 20px;
  align-items: center;
  gap: 14px;
  padding: 16px;
  color: var(--plum-800);
}

.rule-link i:first-child {
  color: var(--rose-600);
  font-size: 2rem;
}

.rule-link i:last-child {
  color: var(--rose-600);
}

.chess-asset-cards {
  display: grid;
  gap: 12px;
}

.asset-cta-card {
  position: relative;
  min-height: 76px;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border: 1px solid rgba(255, 255, 255, .92);
  border-radius: 22px;
  color: #3e1a35;
  text-align: left;
  text-decoration: none;
  background: linear-gradient(135deg, rgba(255, 255, 255, .9), rgba(255, 235, 247, .72));
  box-shadow: 0 14px 28px rgba(115, 24, 73, .12), inset 0 1px 0 rgba(255, 255, 255, .92);
  cursor: pointer;
  transition: transform .2s ease, box-shadow .2s ease;
}

.asset-cta-card:hover,
.asset-cta-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 18px 36px rgba(115, 24, 73, .18), inset 0 1px 0 rgba(255, 255, 255, .96);
}

.asset-cta-card[disabled] {
  cursor: default;
  opacity: .72;
  transform: none;
}

.asset-icon {
  width: 56px;
  height: 56px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 6px 12px rgba(216, 24, 121, .22));
}

body.has-chess-ui-assets .daily-asset-card .asset-icon {
  background-image: url("assets/chess/final-png/ui/daily-badge.png");
}

body.has-chess-ui-assets .lesson-asset-card .asset-icon {
  background-image: var(--asset-lesson-badge);
}

.asset-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.asset-eyebrow {
  color: var(--rose-600);
  font-size: .7rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.asset-text strong {
  color: #3e1a35;
  font-family: var(--display);
  font-size: 1.04rem;
  line-height: 1.2;
}

.asset-meta {
  color: #6f4d8a;
  font-size: .78rem;
  line-height: 1.3;
}

.asset-arrow {
  color: var(--rose-600);
  font-size: 1.2rem;
  opacity: .68;
  transition: transform .2s ease, opacity .2s ease;
}

.asset-cta-card:hover .asset-arrow,
.asset-cta-card:focus-visible .asset-arrow {
  transform: translateX(2px);
  opacity: 1;
}

.panel-copy {
  margin-top: 18px;
  color: #4d3567;
  line-height: 1.55;
}

.hint-card {
  display: grid;
  grid-template-columns: 38px 1fr;
  gap: 8px 12px;
  margin-top: 20px;
  padding: 18px;
}

.hint-card i {
  grid-row: 1 / span 2;
  color: var(--rose-600);
  font-size: 1.7rem;
}

.hint-card p {
  color: #4d3567;
  line-height: 1.5;
}

.move-history-card {
  display: grid;
  gap: 12px;
  margin-top: 18px;
  padding: 16px;
}

body[data-page="chess"] .move-log {
  max-height: 170px;
  padding-left: 0;
  list-style: none;
}

body[data-page="chess"] .move-log li {
  display: flex;
  gap: 8px;
  align-items: center;
  background: rgba(255,255,255,.72);
}

body[data-page="chess"] .move-log li:last-child {
  animation: moveLogIn .32s ease both;
}

.move-log-empty {
  display: grid;
  gap: 6px;
  place-items: center;
  padding: 18px 16px;
  text-align: center;
  border-radius: 18px;
  /* bg + shadow + border from data-bevel="chip-flat" */
  color: var(--plum-700);
}
/* Phase 24: compact empty state на mobile so sheet doesn't go too tall */
@media (max-width: 480px) {
  .move-log-empty {
    padding: 12px 14px;
    gap: 4px;
  }
  .move-log-empty p {
    font-size: .76rem;
    line-height: 1.4;
    max-width: 240px;
    margin: 0;
  }
}

.move-log:not(:empty) ~ .move-log-empty,
.move-history-card:has(.move-log:not(:empty)) .move-log-empty {
  display: none;
}

.move-log-empty-icon {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: #c4327e;
  font-size: 1.4rem;
  box-shadow: inset 0 0 0 1px rgba(255, 140, 191, .32), 0 6px 14px rgba(196, 50, 126, .12);
}

/* P2.3: Empty state — paws walking animation. 3 paw icons floating in
   sequence, suggesting a path to make. Cozy + suggests "make your move". */
.move-log-empty-paws {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 4px;
}
.move-log-empty-paws i {
  font-size: 1.4rem;
  color: var(--rose-500);
  opacity: 0.4;
  animation: chess-empty-paw-fade 2.4s ease-in-out infinite;
}
.move-log-empty-paws i:nth-child(1) { animation-delay: 0s; }
.move-log-empty-paws i:nth-child(2) { animation-delay: 0.4s; }
.move-log-empty-paws i:nth-child(3) { animation-delay: 0.8s; }

@keyframes chess-empty-paw-fade {
  0%, 70%, 100% { opacity: 0.25; transform: translateY(0); }
  30%           { opacity: 1; transform: translateY(-4px); }
}

@media (prefers-reduced-motion: reduce) {
  .move-log-empty-paws i { animation: none; opacity: 0.6; }
}

.move-log-empty strong {
  font-family: var(--display);
  font-size: 1rem;
  color: #6b073b;
}

.move-log-empty p {
  font-size: .82rem;
  line-height: 1.5;
  color: #6f4d8a;
  margin: 0;
  max-width: 220px;
}

@keyframes chessAvatarBreath {
  0%, 100% { transform: translateY(0) scale(1); box-shadow: 0 12px 26px rgba(197, 39, 116, .18), inset 0 0 0 4px rgba(255,180,213,.4); }
  50% { transform: translateY(-2px) scale(1.025); box-shadow: 0 16px 30px rgba(197, 39, 116, .22), inset 0 0 0 4px rgba(255,180,213,.52); }
}

@keyframes heroShadowPulse {
  0%, 100% { transform: scaleX(.92); opacity: .5; }
  50% { transform: scaleX(1.05); opacity: .68; }
}

@keyframes heroCatIdle {
  0%, 100% { transform: translateY(0) rotate(-.5deg) scale(1); }
  45% { transform: translateY(-8px) rotate(1deg) scale(1.015); }
  70% { transform: translateY(-3px) rotate(-.2deg) scale(1.005); }
}

@keyframes heroGooseIdle {
  0%, 100% { transform: translateY(0) rotate(.4deg); }
  42% { transform: translateY(-10px) rotate(-1.1deg); }
  68% { transform: translateY(-4px) rotate(.6deg); }
}

@keyframes sidePortraitFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-6px) rotate(-1deg); }
}

@keyframes activeClockPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,79,168,.28); transform: scale(1); }
  50% { box-shadow: 0 0 0 8px rgba(255,79,168,0); transform: scale(1.045); }
}

@keyframes panelGlowDrift {
  0%, 100% { transform: translate3d(0, 0, 0) scale(.9); opacity: .44; }
  50% { transform: translate3d(-24px, -12px, 0) scale(1.08); opacity: .72; }
}

@keyframes panelSoftPulse {
  0%, 100% { transform: scale(.92); opacity: .5; }
  50% { transform: scale(1.12); opacity: .82; }
}

@keyframes buttonGleam {
  0% { transform: translateX(0) rotate(18deg); opacity: 0; }
  18% { opacity: .72; }
  100% { transform: translateX(380%) rotate(18deg); opacity: 0; }
}

@keyframes moveLogIn {
  0% { transform: translateY(8px) scale(.98); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

@keyframes chessTrailShell {
  0% { opacity: 0; filter: blur(2px); }
  18%, 70% { opacity: .95; filter: blur(0); }
  100% { opacity: 0; filter: blur(2px); }
}

@keyframes chessTrailDraw {
  0% { transform: scaleX(.04); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: scaleX(1); opacity: .92; }
}

@keyframes chessTrailMarks {
  0% { transform: translateX(-8%); opacity: 0; }
  28% { opacity: .76; }
  100% { transform: translateX(10%); opacity: 0; }
}

@keyframes chessImpactRing {
  0% { transform: translate(-50%, -50%) scale(.38); opacity: 0; }
  26% { opacity: .98; }
  100% { transform: translate(-50%, -50%) scale(1.24); opacity: 0; }
}

@keyframes chessBurstFade {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.78); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.18); }
}

@keyframes chessBurstSpin {
  0% { transform: rotate(0deg) scale(.78); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: rotate(64deg) scale(1.18); opacity: 0; }
}

@keyframes chessBurstCore {
  0% { transform: scale(.38); opacity: 0; }
  35% { opacity: .9; }
  100% { transform: scale(1.8); opacity: 0; }
}

@keyframes chessCheckAura {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.7) rotate(-6deg); }
  28%, 64% { opacity: .94; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.15) rotate(4deg); }
}

@keyframes chessPromotionGlow {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.74) rotate(-8deg); }
  28%, 72% { opacity: .96; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.16) rotate(8deg); }
}

@keyframes chessHintRipple {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.62); }
  32% { opacity: .92; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.22); }
}

@keyframes promotionPanelIn {
  0% { opacity: 0; transform: translateY(10px) scale(.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes promotionPanelGlow {
  0%, 100% { transform: rotate(0deg) scale(.98); opacity: .68; }
  50% { transform: rotate(5deg) scale(1.08); opacity: .96; }
}

@keyframes petalFloat {
  0%, 100% { transform: translate(0, 0) rotate(-12deg); opacity: .62; }
  50% { transform: translate(12px, 16px) rotate(18deg); opacity: 1; }
}

@keyframes chessPetalFall {
  0% { transform: translate3d(0, -8vh, 0) rotate(0deg); opacity: 0; }
  8% { opacity: .78; }
  100% { transform: translate3d(54px, 112vh, 0) rotate(340deg); opacity: 0; }
}

@keyframes chessPetalBurst {
  0% { transform: translate3d(0, 0, 0) rotate(0deg) scale(.72); opacity: 0; }
  12% { opacity: .95; }
  100% { transform: translate3d(var(--dx), var(--dy), 0) rotate(var(--rot)) scale(1); opacity: 0; }
}

@keyframes chessPieceLand {
  0%   { transform: translateY(-18%) scale(1.12); filter: drop-shadow(0 22px 18px rgba(116, 18, 70, .3)); }
  55%  { transform: translateY(6%)  scale(.94);  filter: drop-shadow(0 6px 10px rgba(116, 18, 70, .2)); }
  78%  { transform: translateY(-2%) scale(1.03); }
  100% { transform: translateY(0)   scale(1);    filter: drop-shadow(0 4px 8px rgba(116, 18, 70, .14)); }
}

@keyframes chessTrackStamp {
  0% { opacity: 0; transform: translateY(-6px) scale(.72) rotate(-8deg); }
  100% { opacity: var(--stamp-opacity, .54); }
}

@keyframes chessBoardFlash {
  0% { opacity: 0; transform: scale(.98); }
  45% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.03); }
}

@keyframes chessCaptureFlash {
  0% { opacity: 0; transform: scale(.96) rotate(0deg); }
  36% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.08) rotate(2deg); }
}

@keyframes chessCheckFlash {
  0%, 100% { opacity: 0; }
  26%, 58% { opacity: .95; }
}

@keyframes chessMateFlash {
  0% { opacity: 0; transform: scale(.94); }
  38% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.1); }
}

@keyframes chessResultPop {
  0% { opacity: 0; transform: translateY(16px) scale(.92); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@media (max-width: 1180px) {
  .chess-bloom-hero {
    grid-template-columns: 1fr minmax(260px, 420px);
  }

  .chess-mode-switch {
    grid-column: 1 / -1;
    width: min(420px, 100%);
    justify-self: start;
  }

  .chess-play-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .player-panel {
    grid-template-columns: minmax(260px, 1fr) minmax(260px, 1fr);
  }

  .turn-card,
  .captured-lux {
    grid-column: auto;
  }

  .board-shell {
    width: min(88vw, 720px);
  }
}

/* === Landscape warning on small landscape phones === */
.chess-landscape-warning { display: none; }

@media (max-height: 480px) and (orientation: landscape) and (max-width: 920px) {
  body[data-page="chess"] .chess-landscape-warning {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    align-content: center;
    text-align: center;
    gap: 12px;
    padding: 24px;
    background:
      radial-gradient(circle at 50% 0%, rgba(255, 144, 203, .42), transparent 60%),
      rgba(46, 14, 32, .92);
    color: #fff;
    overflow: hidden;
  }
  body[data-page="chess"] .chess-landscape-petal {
    position: absolute;
    background-repeat: no-repeat;
    background-size: contain;
    background-position: center;
    pointer-events: none;
    opacity: .42;
    filter: drop-shadow(0 4px 8px rgba(255, 144, 203, .42));
    animation: chessLandscapeDrift 6s ease-in-out infinite alternate;
  }
  body[data-page="chess"] .chess-landscape-petal-1 {
    top: 12%;
    left: 8%;
    width: 70px;
    height: 70px;
    background-image: url("assets/chess/final-png/props/soft-petal-01.png");
    transform: rotate(-12deg);
  }
  body[data-page="chess"] .chess-landscape-petal-2 {
    bottom: 16%;
    right: 8%;
    width: 80px;
    height: 80px;
    background-image: url("assets/chess/final-png/props/soft-petal-04.png");
    transform: rotate(18deg);
    animation-delay: -2s;
  }
  body[data-page="chess"] .chess-landscape-phone {
    width: 76px;
    height: 132px;
    color: #ffb6e0;
    animation: chessLandscapePhoneRotate 2.4s ease-in-out infinite;
    transform-origin: 50% 50%;
    filter: drop-shadow(0 6px 14px rgba(255, 144, 203, .26));
  }
  body[data-page="chess"] .chess-landscape-warning strong {
    font-family: var(--display);
    font-size: 1.4rem;
    font-weight: 900;
    color: #ffe7f2;
    text-wrap: balance;
    letter-spacing: -0.01em;
  }
  body[data-page="chess"] .chess-landscape-warning p {
    color: rgba(255, 232, 244, .82);
    margin: 0;
    font-size: .92rem;
    line-height: 1.45;
    max-width: 380px;
    text-wrap: pretty;
  }
  body[data-page="chess"] .chess-landscape-tip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .14);
    border: 1px solid rgba(255, 255, 255, .22);
    color: rgba(255, 232, 244, .92);
    font-size: .76rem;
    font-weight: 700;
    backdrop-filter: blur(8px);
  }
  body[data-page="chess"] .chess-landscape-tip i {
    color: #ffe06b;
    font-size: .92rem;
  }
}

@keyframes chessLandscapePhoneRotate {
  0%, 18%   { transform: rotate(0); }
  46%, 64%  { transform: rotate(90deg); }
  92%, 100% { transform: rotate(0); }
}

@keyframes chessLandscapeDrift {
  0%   { transform: translateY(0) rotate(-12deg); }
  100% { transform: translateY(-12px) rotate(-4deg); }
}

@keyframes chessRotateHint {
  0%, 100% { transform: rotate(0); }
  50%      { transform: rotate(90deg); }
}

@media (prefers-reduced-motion: reduce) {
  body[data-page="chess"] .chess-landscape-phone,
  body[data-page="chess"] .chess-landscape-petal { animation: none !important; }
}

/* === Stockfish first-load indicator (visually distinct from "думает…") === */
.chess-ai-loader[hidden] { display: none !important; }
.chess-ai-loader {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: 4px 10px;
  align-items: center;
  padding: 8px 14px;
  margin: 0 0 8px;
  background: linear-gradient(135deg, rgba(255, 230, 240, .94), rgba(255, 245, 235, .94));
  border: 1px solid rgba(232, 41, 143, .35);
  border-radius: 14px;
  box-shadow: 0 6px 14px rgba(232, 41, 143, .15);
}

/* P2.7: Mascot icon (cat or goose) jumps gently while loader plays */
.chess-ai-loader-mascot {
  grid-row: 1 / span 2;
  font-size: 1.6rem;
  display: inline-block;
  animation: chess-loader-mascot-bounce 1.4s ease-in-out infinite;
}
@keyframes chess-loader-mascot-bounce {
  0%, 100% { transform: translateY(0) rotate(-5deg); }
  50%      { transform: translateY(-4px) rotate(5deg); }
}
.chess-ai-loader-bar {
  position: relative;
  display: block;
  height: 4px;
  width: 100%;
  background: rgba(120, 170, 255, .25);
  border-radius: 999px;
  overflow: hidden;
}
.chess-ai-loader-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, rgba(60, 120, 220, .9), transparent);
  border-radius: 999px;
  animation: chessAiLoaderSlide 1.2s ease-in-out infinite;
}
@keyframes chessAiLoaderSlide {
  from { transform: translateX(-100%); }
  to   { transform: translateX(250%); }
}
.chess-ai-loader-text {
  font-family: var(--display, inherit);
  font-weight: 700;
  font-size: .76rem;
  color: #1f3b76;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .chess-ai-loader-bar::after { animation: none; opacity: .6; }
}

/* === Weekly puzzle pack (4.2): list of 7 puzzles with solved-state and a
   progress bar. Reset on ISO week boundary; +500 жетонов on full clear. */
.chess-weekly-pack {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(255, 224, 107, .14), rgba(255, 144, 203, .12));
  border: 1px solid rgba(255, 144, 203, .28);
}
.chess-weekly-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  align-items: baseline;
}
.chess-weekly-head h3 {
  margin: 0;
  font-family: var(--display, inherit);
  font-size: 1rem;
  color: var(--plum-800, #4d1933);
}
.chess-weekly-progress-label {
  font: 800 .76rem var(--display, inherit);
  color: var(--rose-600, #d71879);
  font-variant-numeric: tabular-nums;
}
.chess-weekly-progress-bar {
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: rgba(141, 39, 95, .12);
  overflow: hidden;
}
.chess-weekly-progress-bar > span {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, #ff4fa8, #ffe06b);
  border-radius: 4px;
  transition: width .3s cubic-bezier(.34, 1.56, .64, 1);
}
.chess-weekly-list {
  display: grid;
  gap: 4px;
}
.chess-weekly-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 24px;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  min-height: 44px;
  border-radius: 10px;
  /* bg + shadow + border from data-bevel="chip-clean / state-jewel-active" */
  cursor: pointer;
  font: inherit;
  text-align: left;
  transition: filter .18s ease;
}
.chess-weekly-row.is-solved { color: #fff; }
.chess-weekly-row > .chess-weekly-num {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .8);
  color: var(--plum-800, #4d1933);
  font: 800 .82rem var(--display, inherit);
}
.chess-weekly-row.is-solved > .chess-weekly-num {
  background: var(--rose-600, #d71879);
  color: #fff;
}
.chess-weekly-row > .chess-weekly-title {
  font-size: .88rem;
  color: var(--plum-800, #4d1933);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chess-weekly-row > .chess-weekly-state i {
  color: rgba(141, 39, 95, .42);
}
.chess-weekly-row.is-solved > .chess-weekly-state i {
  color: var(--rose-600, #d71879);
}
.chess-weekly-reward {
  font-size: .8rem;
  color: var(--plum-700, #6f4d8a);
}
.chess-weekly-reward.is-claimed {
  color: var(--rose-600, #d71879);
  font-weight: 700;
}

/* === First-win install nudge: a slim card that drops in from the bottom
   exactly once after the player's first solo win, IF the browser has
   queued a beforeinstallprompt and the PWA isn't already installed.
   Dismissal (either button) is sticky — never shown again on this device. */
.chess-install-nudge[hidden] { display: none !important; }
.chess-install-nudge {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(env(safe-area-inset-bottom) + 12px);
  z-index: 215;
  pointer-events: none;
  animation: chessInstallNudgeIn .42s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
  max-width: 420px;
  margin: 0 auto;
}
/* Phase 25: backdrop dim — install nudge gets focus, не competes с board */
body[data-page="chess"]:has(.chess-install-nudge:not([hidden]))::after {
  content: "";
  position: fixed;
  inset: 0;
  background: rgba(46, 14, 32, 0.42);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  z-index: 210;
  pointer-events: auto;
}
@keyframes chessInstallNudgeIn {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Two-row card (skill-redesign-piped-truffle): row 1 = mark + heading,
   row 2 = full-width primary CTA, row 3 = skip text-button. Eliminates
   the previous truncation of the description on 360px viewports. */
.chess-install-nudge-card {
  position: relative;
  pointer-events: auto;
  display: grid;
  gap: 10px;
  padding: 14px 14px 10px;
  border-radius: 18px;
  /* bg + shadow + border from data-bevel="card-pearl" */
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* Small sakura accent in the bottom-right corner of nudge */
.chess-install-nudge-card::after {
  content: "";
  position: absolute;
  bottom: -8px;
  right: -6px;
  width: 56px;
  height: 56px;
  background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
  transform: rotate(12deg);
  opacity: .72;
  pointer-events: none;
  z-index: 1;
  filter: drop-shadow(0 2px 4px rgba(216, 24, 121, .18));
}

.chess-install-nudge-dismiss {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* bg + shadow + border from data-bevel="button-ghost" */
  color: var(--plum-700, #6f4d8a);
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
  z-index: 2;
}

.chess-install-nudge-dismiss:hover,
.chess-install-nudge-dismiss:focus-visible {
  filter: brightness(1.08);
  transform: scale(1.08);
}

.chess-install-nudge-row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding-right: 32px;
}

.chess-install-nudge-mark {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  display: block;
  background: rgba(255, 144, 203, .12);
  padding: 4px;
  box-sizing: border-box;
  filter: drop-shadow(0 4px 8px rgba(216, 24, 121, .22));
}

/* Result-overlay brand mark — sits at the top of the win/draw card */
.chess-bloom-mark {
  width: 56px;
  height: 56px;
  display: block;
  margin: 0 auto 4px;
  filter: drop-shadow(0 4px 8px rgba(216, 24, 121, .22));
}

.chess-install-nudge-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.chess-install-nudge-text strong {
  font-family: var(--display, inherit);
  font-size: 1rem;
  font-weight: 900;
  color: var(--plum-800, #4d1933);
}

.chess-install-nudge-text span {
  font-size: .78rem;
  color: var(--plum-700, #6f4d8a);
  line-height: 1.4;
  text-wrap: pretty;
}

.chess-install-nudge-text em {
  font-style: normal;
  color: rgba(77, 53, 103, .58);
  font-size: .72rem;
  margin-left: 2px;
}

/* P2.5: install nudge premium — hero icon + benefits list, replaces tiny
   icon+text row. Visually anchored, more inviting. */
.chess-install-nudge-hero {
  display: flex;
  justify-content: center;
  margin-top: 4px;
  margin-bottom: 2px;
}
.chess-install-nudge-hero img {
  width: 64px;
  height: 64px;
  filter: drop-shadow(0 6px 16px rgba(216, 24, 121, .42));
  animation: chess-install-hero-pop .42s cubic-bezier(.34, 1.56, .64, 1) both;
}
@keyframes chess-install-hero-pop {
  from { opacity: 0; transform: scale(.7); }
  to   { opacity: 1; transform: scale(1); }
}
.chess-install-nudge-title {
  font-family: var(--display, inherit);
  font-size: 1.05rem;
  font-weight: 900;
  text-align: center;
  color: var(--plum-800);
  margin: 4px 0 2px;
}
.chess-install-nudge-benefits {
  list-style: none;
  margin: 4px 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.chess-install-nudge-benefits li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: .82rem;
  color: var(--plum-700);
  padding: 6px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .55);
}
.chess-install-nudge-benefits i {
  color: var(--rose-600);
  font-size: 1.1rem;
  width: 22px;
  text-align: center;
  flex: none;
}

.chess-install-nudge-go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 0 16px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="button-bold" */
  color: #fff;
  font: 800 .9rem var(--display, inherit);
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.chess-install-nudge-go i {
  font-size: 1.05rem;
}

.chess-install-nudge-go:hover,
.chess-install-nudge-go:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.04) saturate(1.06);
}

.chess-install-nudge-go:active {
  transform: scale(.97);
}

.chess-install-nudge-skip {
  /* bg + shadow + border from data-bevel="button-ghost" */
  color: rgba(77, 53, 103, .68);
  font: 700 .76rem var(--body, inherit);
  text-decoration: underline;
  text-decoration-color: rgba(255, 144, 203, .42);
  text-underline-offset: 3px;
  cursor: pointer;
  padding: 6px;
  min-height: 32px;
  justify-self: center;
}

.chess-install-nudge-skip:hover,
.chess-install-nudge-skip:focus-visible {
  color: var(--plum-700);
  text-decoration-color: var(--rose-500);
}

@media (prefers-reduced-motion: reduce) {
  .chess-install-nudge { animation: none; }
}

/* === First-time tutor: a 3-step coach card pinned just below the board.
   Persisted dismissal via localStorage 'koskaChessTutorialDone'. The card
   is non-modal — players can still tap the board through it. */
.chess-tutor[hidden] { display: none !important; }
.chess-tutor {
  position: fixed;
  left: 50%;
  /* Phase 6: Top 22dvh — was 28dvh. Lifts card higher so board lower ⅔
     fully visible с spotlight cutout below. */
  top: 22dvh;
  transform: translate(-50%, -50%);
  z-index: 150;
  max-width: min(92vw, 360px);
  pointer-events: none;
  animation: chessTutorIn .32s cubic-bezier(.34, 1.56, .64, 1) both;
}
@keyframes chessTutorIn {
  from { opacity: 0; transform: translate(-50%, -58%) scale(.9); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* Phase 6: spotlight backdrop — dark overlay с circular hole at target
   square. CSS vars --tutor-target-x/--tutor-target-y set by JS via
   renderTutorStep. Defaults to center if not set. Cutout radius animates
   subtle pulse to draw attention. */
.chess-tutor::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(46, 14, 32, 0.42);
  -webkit-mask: radial-gradient(
    circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%),
    transparent 0,
    transparent 36px,
    black 56px,
    black 100%
  );
  mask: radial-gradient(
    circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%),
    transparent 0,
    transparent 36px,
    black 56px,
    black 100%
  );
  pointer-events: none;
  animation: chessTutorSpotlightPulse 2s ease-in-out infinite;
}
@keyframes chessTutorSpotlightPulse {
  0%, 100% {
    -webkit-mask: radial-gradient(circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%), transparent 0, transparent 36px, black 56px, black 100%);
    mask: radial-gradient(circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%), transparent 0, transparent 36px, black 56px, black 100%);
  }
  50% {
    -webkit-mask: radial-gradient(circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%), transparent 0, transparent 42px, black 64px, black 100%);
    mask: radial-gradient(circle at var(--tutor-target-x, 50%) var(--tutor-target-y, 65%), transparent 0, transparent 42px, black 64px, black 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .chess-tutor::before {
    animation: none;
    background: rgba(46, 14, 32, 0.32);
    mask: none;
    -webkit-mask: none;
  }
}
.chess-tutor-card {
  position: relative;
  pointer-events: auto;
  display: grid;
  gap: 8px;
  padding: 16px 18px;
  border-radius: 18px;
  /* bg + shadow + border from data-bevel="card-pearl" */
  text-align: left;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Tail-arrow pointing down at the board — visual link between coach
   card and the actual element it's describing. */
.chess-tutor-card::after {
  content: "";
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%) rotate(45deg);
  width: 14px;
  height: 14px;
  background: linear-gradient(135deg, rgba(255, 232, 244, .9), rgba(255, 232, 244, .9));
  border-right: 1px solid rgba(255, 200, 224, .62);
  border-bottom: 1px solid rgba(255, 200, 224, .62);
  pointer-events: none;
}

/* Step dots — replaces the text "1 / 3" with a visual progress trail.
   Active dot is larger and plum-filled. */
.chess-tutor-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: 2px;
}

.chess-tutor-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(141, 39, 95, .22);
  transition: width .22s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)), background .22s ease;
}

.chess-tutor[data-tutor-active="1"] .chess-tutor-dot[data-tutor-dot="1"],
.chess-tutor[data-tutor-active="2"] .chess-tutor-dot[data-tutor-dot="2"],
.chess-tutor[data-tutor-active="3"] .chess-tutor-dot[data-tutor-dot="3"] {
  width: 18px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--plum-800), var(--rose-600));
}

.chess-tutor-step {
  display: none; /* superseded by the dot indicator above */
}

.chess-tutor-card strong {
  font-family: var(--display, inherit);
  font-size: 1.1rem;
  font-weight: 900;
  color: var(--plum-800, #4d1933);
  text-wrap: balance;
}

.chess-tutor-card p {
  margin: 0;
  font-size: .88rem;
  color: var(--plum-700, #6f4d8a);
  line-height: 1.45;
  text-wrap: pretty;
}

.chess-tutor-actions {
  display: flex;
  gap: 8px;
  justify-content: space-between;
  align-items: center;
  margin-top: 4px;
}

.chess-tutor-actions button {
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  cursor: pointer;
}

.chess-tutor-skip {
  /* bg + shadow + border from data-bevel="button-ghost" — visual treatment is just text */
  color: rgba(77, 53, 103, .68);
  font: 700 .76rem var(--body, inherit);
  text-decoration: underline;
  text-decoration-color: rgba(255, 144, 203, .5);
  text-underline-offset: 3px;
  border-radius: 8px;
  padding: 6px 8px;
  min-height: 36px;
}

.chess-tutor-skip:hover,
.chess-tutor-skip:focus-visible {
  color: var(--plum-700);
  text-decoration-color: var(--rose-500);
}

.chess-tutor-next {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 18px;
  border-radius: 999px;
  /* bg + shadow + border from data-bevel="button-magenta" */
  color: #fff;
  font: 800 .88rem var(--display, inherit);
  transition: transform .18s ease, filter .18s ease;
}

.chess-tutor-next i {
  font-size: 1rem;
}

.chess-tutor-next:hover,
.chess-tutor-next:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.04) saturate(1.06);
}

.chess-tutor-next:active {
  transform: scale(.96);
}

@media (prefers-reduced-motion: reduce) {
  .chess-tutor { animation: none; }
  .chess-tutor-dot { transition: none; }
}

/* === Stats + achievements panel inside Game-tab. Stats grid up top
   (4 cards) and an achievements list below where each row carries an
   icon, title/description, and a check / lock state. */
.chess-stats-panel {
  display: grid;
  gap: 12px;
  margin-top: 12px;
  padding: 14px;
  border-radius: 16px;
  /* bg + shadow + border from data-bevel="card-pearl" */
}
.chess-stats-panel h3 {
  margin: 0;
  font-family: var(--display, inherit);
  font-size: 1rem;
  color: var(--plum-800, #4d1933);
}
.chess-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.chess-stat-cell {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="chip-clean" */
}
.chess-stat-cell .chess-stat-label {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--rose-600, #d71879);
  font-weight: 800;
}
.chess-stat-cell .chess-stat-value {
  font-family: var(--display, inherit);
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--plum-800, #4d1933);
  font-variant-numeric: tabular-nums;
}

/* Phase 5: personal records panel — mirrors chess-stats grid look */
.chess-records-panel {
  display: grid;
  gap: 12px;
  margin-top: 12px;
  padding: 14px;
  border-radius: 16px;
}
.chess-records-panel h3 {
  margin: 0;
  font-family: var(--display, inherit);
  font-size: 1rem;
  color: var(--plum-800, #4d1933);
}
.chess-records-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.chess-record-cell {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 12px;
}
.chess-record-cell .chess-record-label {
  font-size: .65rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--rose-600, #d71879);
  font-weight: 800;
}
.chess-record-cell .chess-record-value {
  font-family: var(--display, inherit);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--plum-800, #4d1933);
  font-variant-numeric: tabular-nums;
}

/* Phase 5: practice mode entry button in start modal mode-step. Sits below
   Solo/Duel grid as a tertiary option — visually distinct as "off-ladder". */
.chess-start-practice {
  margin-top: 14px;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: transform .18s ease, box-shadow .18s ease;
}
.chess-start-practice:hover,
.chess-start-practice:focus-visible {
  transform: translateY(-1px);
}
.chess-start-practice-icon {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(255, 230, 240, .8), rgba(190, 220, 255, .65));
  color: var(--plum-700);
}
.chess-start-practice-icon .ti {
  font-size: 22px;
}
.chess-start-practice strong {
  display: block;
  font-size: 14px;
  font-weight: 800;
  color: var(--plum-900, #2a0d28);
}
.chess-start-practice span {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--plum-700, #4d1c3b);
  opacity: .75;
  margin-top: 2px;
}
.chess-start-practice-arrow {
  font-weight: 900;
  color: var(--plum-800);
  font-size: 18px;
}
.chess-achievements {
  display: grid;
  gap: 6px;
}
.chess-achievement-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) 24px;
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="chip-flat / state-jewel-active" */
  transition: filter .18s ease;
}
.chess-achievement-row.is-unlocked { color: #fff; }
.chess-achievement-row > i {
  font-size: 1.3rem;
  color: var(--rose-600, #d71879);
  background: rgba(255, 255, 255, .9);
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 10px;
  box-shadow: inset 0 0 0 1px rgba(255, 144, 203, .26);
}
.chess-achievement-row.is-unlocked > i {
  color: var(--plum-800, #4d1933);
}
.chess-achievement-row .chess-achievement-text { display: grid; gap: 2px; min-width: 0; }
.chess-achievement-row .chess-achievement-title {
  font-family: var(--display, inherit);
  font-size: .92rem;
  font-weight: 700;
  color: var(--plum-800, #4d1933);
}
.chess-achievement-row .chess-achievement-desc {
  font-size: .76rem;
  color: var(--plum-700, #6f4d8a);
  line-height: 1.3;
}
.chess-achievement-row .chess-achievement-state {
  display: grid; place-items: center;
  font-size: 1.1rem;
  color: rgba(141, 39, 95, .42);
}
.chess-achievement-row.is-unlocked .chess-achievement-state {
  color: var(--rose-600, #d71879);
}
.chess-achievements-empty {
  text-align: center;
  font-size: .82rem;
  color: var(--plum-700, #6f4d8a);
  padding: 12px;
}

/* === Review modal: post-game analysis with per-move 5-star ratings ====== */
.chess-review-modal[hidden] { display: none !important; }
.chess-review-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 0;
}
.chess-review-backdrop {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 50% 30%, rgba(255, 192, 220, .55), transparent 60%),
    rgba(46, 14, 32, .72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  cursor: pointer;
}
.chess-review-card {
  position: relative;
  width: min(94%, 380px);
  max-height: calc(100dvh - 24px);
  display: grid;
  gap: 8px;
  /* head + batch + board + controls + list (summary moved into list) */
  grid-template-rows: auto auto auto auto minmax(0, 1fr);
  padding: 14px 14px 16px;
  border-radius: 22px;
  border: 1px solid rgba(255, 255, 255, .92);
  background: linear-gradient(180deg, #fff, #fff5fa);
  box-shadow: 0 24px 52px rgba(46, 14, 32, .42), inset 0 1px 0 rgba(255, 255, 255, .96);
  animation: chessResultCardIn .42s cubic-bezier(.34, 1.56, .64, 1) both;
  overflow: hidden;
}
.chess-review-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
}
.chess-review-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.1rem;
  color: #4d1933;
}
.chess-review-close {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="button-clean" */
  color: var(--plum-700, #6f4d8a);
  cursor: pointer;
  transition: filter .18s ease, color .18s ease;
}
.chess-review-close:hover, .chess-review-close:focus-visible {
  filter: brightness(1.06);
  color: #4d1933;
}

.chess-review-list-summary {
  list-style: none;
  margin: 0 0 6px;
}
.chess-review-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.chess-review-summary-cell {
  display: grid;
  gap: 0;
  padding: 8px 4px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .82);
  border: 1px solid rgba(255, 144, 203, .2);
  text-align: center;
}
.chess-review-summary-cell strong {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  color: #4d1933;
  line-height: 1;
}
.chess-review-summary-cell span {
  display: block;
  font-size: .62rem;
  color: var(--plum-700, #6f4d8a);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-top: 2px;
}
.chess-review-summary-cell[data-chess-review-summary-cell="best"]    strong { color: #2c8055; }
.chess-review-summary-cell[data-chess-review-summary-cell="good"]    strong { color: #6f4d8a; }
.chess-review-summary-cell[data-chess-review-summary-cell="inacc"]   strong { color: #c47a17; }
.chess-review-summary-cell[data-chess-review-summary-cell="blunder"] strong { color: #a01c52; }

/* Batch-analyze CTA: opt-in sweep through all unanalysed moves. Replaces
   the old auto-loop UX — analysis stays on-demand by default; this button
   lets impatient users 'analyse the whole game' in one tap. */
.chess-review-batch {
  position: relative;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="button-thin" */
  color: var(--plum-800, #4d1933);
  font: 700 .82rem var(--display, inherit);
  cursor: pointer;
  overflow: hidden;
  transition: transform .18s ease, filter .18s ease;
}
.chess-review-batch:hover,
.chess-review-batch:focus-visible {
  transform: translateY(-1px);
  filter: brightness(1.06);
}
.chess-review-batch[disabled] {
  cursor: progress;
  opacity: .94;
}
.chess-review-batch > i {
  font-size: 1rem;
  color: var(--rose-600, #d71879);
  justify-self: center;
}
.chess-review-batch[hidden] { display: none; }

.chess-review-batch-bar {
  position: absolute;
  inset: 0 0 0 0;
  height: 3px;
  bottom: auto;
  background: rgba(141, 39, 95, .12);
  pointer-events: none;
}
.chess-review-batch-bar > span {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #ff4fa8, #ffe06b);
  transition: width .22s ease;
}

/* === R2: compact in-list summary ====================================== */
/* Summary <li> lives at top of the scrollable move list, NOT as a separate
   panel above the board. Two-row compact layout — big accuracy number left,
   breakdown chips right, optional streak + jump-to-mistakes pill on row 2. */
.chess-review-list-summary {
  list-style: none;
  /* Summary is the FIRST item in the move list and scrolls with everything
     else — when the user scrolls down to study moves, the summary moves out
     of view (freeing real estate). Previously was sticky-pinned but the
     panel is too tall (≈144 px on mobile) to permanently occupy ~half the
     visible list area. */
}
.chess-review-summary {
  /* Flex column — explicit single-column vertical stack. Grid was creating
     mysterious implicit columns and squeezing summary-top width to ~98px,
     which then caused chips inside to wrap one-per-row. */
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  margin-bottom: 6px;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .94), rgba(255, 240, 248, .9));
  border: 1px solid rgba(216, 24, 121, .18);
  box-shadow: 0 2px 6px rgba(116, 18, 70, .1);
}
/* === Redesigned summary card ===========================================
   Vertical centred layout with 4 stacked sections separated by thin
   dividers: hero accuracy → quality cells row → optional streak → jump
   action. Every section is optional and gracefully collapses. */

/* 1) Hero — centred accuracy display ================================ */
.chess-review-summary-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 4px 0 6px;
}
.chess-review-summary-hero-num {
  font-family: var(--display, inherit);
  font-size: 2.25rem;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -.02em;
  background: linear-gradient(180deg, #d71879 0%, #a01c52 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  display: inline-flex;
  align-items: baseline;
}
.chess-review-summary-hero-num > span {
  font-size: 1.1rem;
  margin-left: 2px;
  /* Reuse same gradient — bg-clip text doesn't inherit so re-declare */
  background: linear-gradient(180deg, #d71879 0%, #a01c52 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.chess-review-summary-hero-label {
  font-style: normal;
  font-family: var(--display, inherit);
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--plum-700, #6f4d8a);
}

/* 2) Quality cells row — evenly spaced icon + coloured count + label =
   Three stacked rows per cell: icon, large coloured number, tiny label.
   The COLOURED number is the primary scan signal — eye picks out "много
   розовых цифр" immediately. Label below disambiguates the icon (no
   need to learn glyph meanings). */
.chess-review-summary-cells {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 4px;
  padding: 6px 4px;
  border-top: 1px solid rgba(216, 24, 121, .12);
}
.chess-review-summary-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 2px;
  padding: 5px 2px;
  border-radius: 8px;
  font-family: var(--display, inherit);
  min-width: 0;
}
.chess-review-summary-cell > i {
  font-size: 13px;
  line-height: 1;
  opacity: .85;
}
.chess-review-summary-cell > strong {
  font-variant-numeric: tabular-nums;
  font-weight: 900;
  font-size: 1.05rem;
  line-height: 1;
  letter-spacing: -.01em;
}
.chess-review-summary-cell > em {
  font-style: normal;
  font-weight: 700;
  font-size: .5rem;
  line-height: 1.05;
  text-transform: lowercase;
  letter-spacing: .01em;
  color: var(--plum-700, #6f4d8a);
  text-align: center;
  /* Allow soft hyphenation + word-break so labels like «спокойных» can wrap
     to a second line when too long for the cell. Hyphens use Russian word
     boundaries via browser-built-in dictionary (lang="ru" on <html>). */
  max-width: 100%;
  -webkit-hyphens: auto;
  hyphens: auto;
  overflow-wrap: anywhere;
}

/* Per-quality colour — applied to BOTH icon AND number so the cell reads
   as a coherent colour block. Background stays subtle so the number can
   pop without competing. */
.chess-review-summary-cell[data-quality="best"]              { background: rgba(255, 196, 51, .14); }
.chess-review-summary-cell[data-quality="best"]    > i,
.chess-review-summary-cell[data-quality="best"]    > strong  { color: #b85518; }
.chess-review-summary-cell[data-quality="good"]              { background: rgba(44, 128, 85, .12); }
.chess-review-summary-cell[data-quality="good"]    > i,
.chess-review-summary-cell[data-quality="good"]    > strong  { color: #1e6b46; }
.chess-review-summary-cell[data-quality="ok"]                { background: rgba(141, 39, 95, .09); }
.chess-review-summary-cell[data-quality="ok"]      > i,
.chess-review-summary-cell[data-quality="ok"]      > strong  { color: var(--plum-700, #6f4d8a); }
.chess-review-summary-cell[data-quality="inacc"]             { background: rgba(196, 122, 23, .14); }
.chess-review-summary-cell[data-quality="inacc"]   > i,
.chess-review-summary-cell[data-quality="inacc"]   > strong  { color: #b86c0e; }
.chess-review-summary-cell[data-quality="blunder"]           { background: rgba(216, 24, 121, .14); }
.chess-review-summary-cell[data-quality="blunder"] > i,
.chess-review-summary-cell[data-quality="blunder"] > strong  { color: #a01c52; }

/* 3) Streak row — small, centred, with flame icon =================== */
.chess-review-summary-streak-row {
  display: flex;
  justify-content: center;
  padding: 4px 0;
  border-top: 1px solid rgba(216, 24, 121, .12);
}

/* 4) Action row — К промахам pill, centred ========================== */
.chess-review-summary-actions {
  display: flex;
  justify-content: center;
  padding-top: 4px;
  border-top: 1px solid rgba(216, 24, 121, .12);
}
.chess-review-summary-streak {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: .72rem;
  font-weight: 700;
  color: var(--rose-600, #d71879);
}
.chess-review-summary-streak strong { color: var(--plum-800, #4d1933); font-weight: 900; }
.chess-review-summary-streak i { font-size: 12px; color: #ff8c1a; }

.chess-review-summary-jump {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: 999px;
  background: linear-gradient(135deg, #ff4fa8, #d71879);
  color: #fff;
  font: 800 .72rem var(--display, inherit);
  letter-spacing: .03em;
  border: none;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(216, 24, 121, .35);
  transition: transform .15s ease, filter .15s ease;
}
.chess-review-summary-jump:hover, .chess-review-summary-jump:focus-visible {
  transform: translateY(-1px);
  filter: brightness(1.06);
}
.chess-review-summary-jump:active { transform: scale(.97); }
.chess-review-summary-jump i { font-size: .9rem; }
.chess-review-batch-bar[hidden] { display: none; }

/* Board host: 2×2 grid laying out
     [rank-labels (1-8)] [board ]
     [corner spacer    ] [files A-H]
   The labels mirror the main game board's labels — same convention,
   same orientation. Eval bar removed per user request. */
.chess-review-board-host {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) 16px;
  gap: 4px;
  align-items: stretch;
}

.chess-review-board-wrap {
  position: relative;
  width: 100%;
  grid-column: 2;
  grid-row: 1;
}

.chess-review-rank-labels {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  font-family: var(--display, inherit);
  font-size: .65rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--plum-700, #6f4d8a);
  letter-spacing: .02em;
}
.chess-review-rank-labels > span {
  display: block;
  line-height: 1;
}

.chess-review-file-labels {
  grid-column: 2;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  align-items: center;
  font-family: var(--display, inherit);
  font-size: .65rem;
  font-weight: 800;
  color: var(--plum-700, #6f4d8a);
  letter-spacing: .02em;
}
.chess-review-file-labels > span {
  text-align: center;
  line-height: 1;
}

.chess-review-corner {
  grid-column: 1;
  grid-row: 2;
}

/* Phase 4: Review modal empty state — illustration + copy when no moves to
   analyze. Hidden when board has square children (rendered position). */
.chess-review-empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 28px;
  text-align: center;
  z-index: 1;
}
.chess-review-board:not(:empty) ~ .chess-review-empty,
.chess-review-board-wrap:has(.chess-review-square) .chess-review-empty {
  display: none;
}
.chess-review-empty-icon {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: rgba(255, 220, 240, .65);
  font-size: 1.8rem;
  color: var(--rose-600);
  box-shadow: inset 0 0 0 2px rgba(232, 41, 143, .22);
}
.chess-review-empty-paw {
  position: absolute;
  bottom: -4px;
  right: -4px;
  font-size: 1rem !important;
  color: var(--gold-500);
  background: #fff;
  border-radius: 50%;
  padding: 2px;
  filter: drop-shadow(0 2px 4px rgba(216, 24, 121, .22));
}
.chess-review-empty strong {
  font-family: var(--display);
  font-size: 1rem;
  color: var(--plum-800);
}
.chess-review-empty p {
  font-size: .82rem;
  color: var(--plum-700);
  line-height: 1.45;
  text-wrap: pretty;
  max-width: 280px;
  margin: 0;
}
/* Phase F: visual legend below the empty-state copy. Each row shows the
   actual quality-chip glyph next to a Russian label so a first-time user
   sees what they will get without needing to play yet. */
.chess-review-empty-legend {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
  display: grid;
  gap: 6px;
  max-width: 220px;
  text-align: left;
}
.chess-review-empty-legend li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 8px;
  align-items: center;
  font-size: .78rem;
  color: var(--plum-800, #4d1933);
  font-family: var(--display, inherit);
  font-weight: 700;
}
.chess-review-empty-legend .chess-review-quality-chip {
  width: 22px;
  height: 22px;
}
/* R1 fix: disable navigation when there's no analysed game. Previous rule
   was broken on two counts:
     1. `:not([hidden])` checks the HTML attribute, but `.chess-review-empty`
        is hidden via CSS `display: none` (no attribute) — selector matched
        ALWAYS → controls permanently disabled.
     2. After Phase D, `.chess-review-board-wrap` is no longer a sibling of
        `.chess-review-controls` (it's nested in `.chess-review-board-host`),
        so the first sibling selector never matched either.
   New rule scopes to the actual data signal — `.chess-review-board:empty`
   reliably indicates the empty (no-position-rendered) state. */
.chess-review-modal:has(.chess-review-board:empty) .chess-review-controls,
.chess-review-modal:has(.chess-review-board:empty) .chess-review-jump-mistakes {
  opacity: .35;
  pointer-events: none;
}
.chess-review-board {
  width: 100%;
  aspect-ratio: 1;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid rgba(141, 39, 95, .22);
  background: #fff5fa;
}
/* SVG arrow overlay for «лучший ход» highlighting. Sits between cell
   backgrounds (z-index auto = 0) and pieces (lifted to z-index 2 below)
   so the trail dots appear UNDER the chess pieces — pieces stay clearly
   readable, the suggestion is visible against the board pattern.
   Pointer events disabled so taps still pass through to the cells.
   Soft drop-shadow blends the dots into the board. */
.chess-review-arrow-layer {
  position: absolute;
  inset: 2px;          /* match border thickness so arrow lines up cell-grid */
  width: calc(100% - 4px);
  height: calc(100% - 4px);
  pointer-events: none;
  z-index: 1;
  filter: drop-shadow(0 1px 2px rgba(116, 18, 70, .28));
  animation: chessReviewArrowIn .32s cubic-bezier(.34, 1.56, .64, 1) both;
}
.chess-review-arrow-layer:empty { display: none; }
@keyframes chessReviewArrowIn {
  from { opacity: 0; transform: scale(.94); }
  to   { opacity: 1; transform: scale(1); }
}

/* Animate the paw-print dots so they appear to FLOW from source to target.
   stroke-dasharray "0 0.22" + stroke-linecap: round makes each dash a dot;
   shifting stroke-dashoffset over time slides them along the line so the
   trail reads as «footprints walking toward the suggested square». */
.chess-review-arrow-layer line {
  animation: chessReviewArrowFlow 1.6s linear infinite;
}
@keyframes chessReviewArrowFlow {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -0.44; }  /* 2 dash periods so the loop is seamless */
}
@media (prefers-reduced-motion: reduce) {
  .chess-review-arrow-layer line { animation: none; }
}
.chess-review-board .chess-review-square {
  position: relative;
  display: grid;
  place-items: center;
  font-size: clamp(1.2rem, 4vw, 1.6rem);
  line-height: 1;
}
.chess-review-board .chess-review-square.light { background: #fff5fa; }
.chess-review-board .chess-review-square.dark  { background: #ffd4e5; }
/* From-square: pulsing golden halo so the «откуда» is visible even when
   the cell is now empty. Stamp + animation borrowed from the main board's
   .hint-source effect, recalibrated for the static review context. */
.chess-review-board .chess-review-square.from {
  box-shadow: inset 0 0 0 2px rgba(255, 224, 107, .92);
  position: relative;
}
.chess-review-board .chess-review-square.from::after {
  content: "";
  position: absolute;
  inset: 6%;
  border-radius: 14%;
  background: radial-gradient(circle at 50% 50%, rgba(255, 224, 107, .58), rgba(255, 79, 168, .22) 60%, transparent 80%);
  box-shadow: inset 0 0 0 1.5px rgba(255, 224, 107, .65);
  pointer-events: none;
  z-index: 1;
  animation: chessReviewFromPulse 1.8s ease-in-out infinite;
}
@keyframes chessReviewFromPulse {
  0%, 100% { transform: scale(.92); opacity: .58; }
  50%      { transform: scale(1.06); opacity: 1;   }
}
.chess-review-board .chess-review-square.to {
  box-shadow: inset 0 0 0 3px rgba(216, 24, 121, .82);
  position: relative;
}
.chess-review-board .chess-review-square.to::after {
  content: "";
  position: absolute;
  inset: 6%;
  border-radius: 14%;
  background: radial-gradient(circle at 50% 50%, rgba(216, 24, 121, .26), transparent 65%);
  pointer-events: none;
  z-index: 0;
}
@media (prefers-reduced-motion: reduce) {
  .chess-review-board .chess-review-square.from::after { animation: none; }
}
/* Unicode-glyph fallback colours (when has-chess-piece-assets is absent) */
.chess-review-board .piece-w { color: #fff8f4; -webkit-text-stroke: 1.5px #d27054; text-shadow: 0 1px 2px rgba(116, 18, 70, .42); }
.chess-review-board .piece-b { color: #21151f; text-shadow: 0 1px 0 rgba(255, 255, 255, .35); }
/* PNG pieces (loaded by the existing body.has-chess-piece-assets rules
   that already set background-image on .piece-w-p / .piece-b-q / etc.).
   `position: relative; z-index: 2` lifts the piece above the arrow trail
   layer (z-index 1) so the suggested-move dots render UNDER the figures
   rather than on top — pieces stay clearly readable while the arrow is
   visible between them. */
.chess-review-board .chess-review-piece {
  position: relative;
  z-index: 2;
  width: 86%;
  height: 86%;
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  display: grid;
  place-items: center;
  filter: drop-shadow(0 2px 3px rgba(116, 18, 70, .22));
}
/* When PNG asset is loaded, hide the Unicode fallback character so it
   doesn't render alongside the image. */
body.has-chess-piece-assets .chess-review-board .chess-review-piece {
  font-size: 0;
  color: transparent;
  -webkit-text-stroke: 0;
  text-shadow: none;
}

.chess-review-controls {
  display: grid;
  /* Phase G: bumped from 40px to 48px to match WCAG 44px touch floor */
  grid-template-columns: 48px 48px minmax(0, 1fr) 48px 48px;
  gap: 6px;
  align-items: center;
}
.chess-review-step {
  /* Phase G: bumped touch targets 40 → 48 (WCAG 44 floor + 4px buffer) */
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="button-clean" */
  color: var(--plum-700, #6f4d8a);
  cursor: pointer;
  transition: filter .18s ease, color .18s ease;
}
.chess-review-step:hover, .chess-review-step:focus-visible {
  filter: brightness(1.06);
  color: #4d1933;
}
.chess-review-step:active { transform: scale(.94); }
.chess-review-step i { font-size: 1.05rem; }

/* R2: «К промахам» moved into .chess-review-summary-jump inside the in-list
   summary <li>. Old standalone .chess-review-jump-mistakes removed. */

/* Quality timeline strip — Lichess-style bird's-eye. Sits below pagination,
   one button per ply, colour coded by quality. Click to jump. The active
   ply gets a tall outline so the user always knows where they are. */
.chess-review-timeline {
  display: flex;
  align-items: stretch;
  gap: 1px;
  height: 10px;
  padding: 0 2px;
  margin-top: 2px;
  border-radius: 6px;
  background: rgba(141, 39, 95, .06);
}
.chess-review-timeline:empty { display: none; }
.chess-review-timeline-tick {
  flex: 1;
  min-width: 2px;
  background: rgba(141, 39, 95, .14);
  border: none;
  cursor: pointer;
  border-radius: 2px;
  padding: 0;
  transition: transform .12s ease, box-shadow .12s ease;
}
.chess-review-timeline-tick:hover { transform: scaleY(1.4); }
.chess-review-timeline-tick[data-quality="best"]    { background: #ffaa1f; }
.chess-review-timeline-tick[data-quality="good"]    { background: #2c8055; }
.chess-review-timeline-tick[data-quality="ok"]      { background: rgba(141, 39, 95, .35); }
.chess-review-timeline-tick[data-quality="inacc"]   { background: #c47a17; }
.chess-review-timeline-tick[data-quality="blunder"] { background: #d71879; }
.chess-review-timeline-tick.is-active {
  box-shadow: 0 0 0 2px var(--plum-800, #4d1933), 0 0 6px rgba(216, 24, 121, .5);
  transform: scaleY(1.6);
  z-index: 2;
  position: relative;
}
/* In solo mode the opponent's ticks are dimmer so player's ticks pop. */
[data-chess-review][data-chess-review-player-color="w"] .chess-review-timeline-tick[data-color="b"],
[data-chess-review][data-chess-review-player-color="b"] .chess-review-timeline-tick[data-color="w"] {
  opacity: .42;
}
.chess-review-ply {
  text-align: center;
  font-family: var(--display);
  font-size: .92rem;
  color: #4d1933;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.chess-review-list {
  list-style: none;
  margin: 0;
  /* Bottom padding clears the floating «К партии» CTA (height ~48 +
     bottom inset 14 + breathing 8 ≈ 80). Without it, the last few
     entries hide behind the sticky button. */
  padding: 0 4px 88px;
  overflow-y: auto;
  display: grid;
  gap: 6px;
}

/* Legacy 3-col `.chess-review-list-row` rule was removed 2026-05-11 — the
   live rule at line ~7152 (5 cols including new quality-chip slot) wins
   by source order, but keeping the obsolete duplicate caused confusion
   during the Phase B grid debug. Per-quality left-borders moved next to
   the active rule for the same reason. */
.chess-review-list-row[data-quality="best"]    { border-left: 3px solid #2c8055; }
.chess-review-list-row[data-quality="good"]    { border-left: 3px solid #6f4d8a; }
.chess-review-list-row[data-quality="ok"]      { border-left: 3px solid #b9aaca; }
.chess-review-list-row[data-quality="inacc"]   { border-left: 3px solid #c47a17; }
.chess-review-list-row[data-quality="blunder"] { border-left: 3px solid #a01c52; }
.chess-review-ply-num {
  font-variant-numeric: tabular-nums;
  color: var(--plum-700, #6f4d8a);
  font-size: .76rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.chess-review-notation {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chess-review-stars {
  font-size: .82rem;
  letter-spacing: -1px;
  color: #ffb53a;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chess-review-stars-empty { color: rgba(141, 39, 95, .22); }

/* ===== List item with expandable detail ===== */
/* Chat-style alignment: white moves left, black moves right — like a
   conversation between two players. The list itself is full-width;
   each row inside is constrained to ~78% and shifted via margins. */
.chess-review-list-item {
  display: grid;
  gap: 0;
}
.chess-review-list-item[data-color="w"] > .chess-review-list-row,
.chess-review-list-item[data-color="w"] > .chess-review-detail {
  margin-right: auto;
  width: min(86%, 100%);
}
.chess-review-list-item[data-color="b"] > .chess-review-list-row,
.chess-review-list-item[data-color="b"] > .chess-review-detail {
  margin-left: auto;
  width: min(86%, 100%);
}

.chess-review-list-row {
  display: grid;
  /* ply-num · quality-chip · notation · stars · chevron */
  grid-template-columns: 28px 22px minmax(0, 1fr) auto auto;
  gap: 8px;
  align-items: center;
  padding: 9px 12px;
  border-radius: 12px;
  background: linear-gradient(180deg, #fff, rgba(255, 245, 250, .92));
  border: 1px solid rgba(216, 24, 121, .18);
  cursor: pointer;
  font: 600 .9rem var(--display, inherit);
  color: #4d1933;
  text-align: left;
  width: 100%;
  box-shadow: 0 2px 6px rgba(116, 18, 70, .08);
  transition: transform .14s ease, box-shadow .14s ease, background .14s ease;
}
.chess-review-list-row:hover { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(116, 18, 70, .14); }

/* Phase B: full-row tint based on quality. Только для inacc/blunder, чтобы
   ребёнок СРАЗУ видел «здесь была ошибка». Best/good/ok оставляем нейтральным
   фоном — не хотим заливать пол-списка золотом. */
.chess-review-list-row[data-quality="inacc"] {
  background: linear-gradient(180deg, rgba(255, 240, 220, .92), rgba(255, 230, 200, .88));
}
.chess-review-list-row[data-quality="blunder"] {
  background: linear-gradient(180deg, rgba(255, 228, 240, .94), rgba(255, 210, 226, .9));
}

/* Phase B: quality glyph chip — circular pill with the Tabler icon. Color
   per quality matches existing left-border palette so palette stays consistent
   end-to-end. Empty data-quality renders as transparent placeholder so grid
   columns don't shift across pre/post analysis. */
.chess-review-quality-chip {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: 13px;
  line-height: 1;
}
.chess-review-quality-chip[data-quality=""] {
  background: transparent;
  visibility: hidden;
}
.chess-review-quality-chip[data-quality="best"] {
  background: linear-gradient(180deg, #ffd84a 0%, #ffaa1f 100%);
  color: #fff;
  box-shadow: 0 2px 6px rgba(255, 153, 0, .35), inset 0 1px 2px rgba(255, 255, 255, .55);
}
.chess-review-quality-chip[data-quality="good"] {
  background: linear-gradient(180deg, #6fcf95 0%, #2c8055 100%);
  color: #fff;
  box-shadow: 0 2px 5px rgba(44, 128, 85, .35), inset 0 1px 2px rgba(255, 255, 255, .35);
}
.chess-review-quality-chip[data-quality="ok"] {
  background: rgba(141, 39, 95, .12);
  color: var(--plum-700, #6f4d8a);
  box-shadow: inset 0 0 0 1px rgba(141, 39, 95, .22);
}
.chess-review-quality-chip[data-quality="inacc"] {
  background: linear-gradient(180deg, #ffb84c 0%, #c47a17 100%);
  color: #fff;
  box-shadow: 0 2px 5px rgba(196, 122, 23, .4), inset 0 1px 2px rgba(255, 255, 255, .4);
}
.chess-review-quality-chip[data-quality="blunder"] {
  background: linear-gradient(180deg, #d71879 0%, #a01c52 100%);
  color: #fff;
  box-shadow: 0 2px 6px rgba(216, 24, 121, .45), inset 0 1px 2px rgba(255, 255, 255, .4);
}
/* Black-row override: when bubble is dark (b-side), use slightly muted
   chips so they don't blow out against the dark gradient. */
.chess-review-list-item[data-color="b"] .chess-review-quality-chip {
  filter: saturate(.92) brightness(1.04);
}

/* Player-side focus (solo mode): dim OPPONENT rows so the user's own
   moves visually pop. Opponent moves stay readable but recede — they're
   context, not the subject of study. The modal carries
   data-chess-review-player-color ∈ {w, b}; we dim rows whose color does
   NOT match. Only the row body fades — the chip glyph stays bright so
   the quality scan still works at a glance. */
[data-chess-review][data-chess-review-player-color="w"] .chess-review-list-item[data-color="b"] > .chess-review-list-row,
[data-chess-review][data-chess-review-player-color="b"] .chess-review-list-item[data-color="w"] > .chess-review-list-row {
  opacity: .55;
  transition: opacity .18s ease;
}
[data-chess-review][data-chess-review-player-color="w"] .chess-review-list-item[data-color="b"] > .chess-review-list-row:hover,
[data-chess-review][data-chess-review-player-color="b"] .chess-review-list-item[data-color="w"] > .chess-review-list-row:hover,
[data-chess-review][data-chess-review-player-color="w"] .chess-review-list-item[data-color="b"].is-expanded > .chess-review-list-row,
[data-chess-review][data-chess-review-player-color="b"] .chess-review-list-item[data-color="w"].is-expanded > .chess-review-list-row {
  opacity: 1;
}
/* Black bubbles: subdued dark-rose background — DOWN-tone so it doesn't
   shout louder than white moves (player typically plays white). */
.chess-review-list-row[data-color="b"] {
  background: linear-gradient(180deg, rgba(60, 36, 56, .92), rgba(43, 25, 40, .92));
  color: #f5e2ee;
  border-color: rgba(255, 255, 255, .08);
}
.chess-review-list-row[data-color="b"] .chess-review-ply-num {
  color: rgba(255, 230, 245, .68);
}
/* Active state — strong, drawing focus to current ply */
.chess-review-list-row.is-active {
  border-color: var(--rose-600, #d71879);
  border-width: 2px;
  padding: 8px 11px; /* compensate for the extra 1px of border */
  box-shadow: 0 6px 16px rgba(216, 24, 121, .26);
  transform: translateY(-1px);
}
.chess-review-list-row[data-color="b"].is-active {
  border-color: #ffe06b;
  box-shadow: 0 6px 16px rgba(255, 224, 107, .32);
}
.chess-review-list-item[data-color="b"].is-expanded > .chess-review-list-row {
  background: linear-gradient(180deg, rgba(80, 50, 76, .98), rgba(60, 36, 56, .94));
}

/* PNG piece chip + from→to path text. Glyph is a small rounded chip that
   borrows the same body.has-chess-piece-assets background-image rules
   that the main board uses (.piece-w-p / .piece-b-q etc.) so we don't
   need a second asset reference. */
.chess-review-notation {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chess-review-glyph {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 8px;
  background-position: center;
  background-size: 22px 22px;
  background-repeat: no-repeat;
  filter: drop-shadow(0 1px 2px rgba(116, 18, 70, .26));
}
/* Subtle backplate that helps the PNG read on either bubble bg. */
.chess-review-list-row[data-color="w"] .chess-review-glyph {
  background-color: rgba(255, 255, 255, .92);
  box-shadow: inset 0 0 0 1px rgba(216, 24, 121, .18);
}
.chess-review-list-row[data-color="b"] .chess-review-glyph {
  background-color: rgba(255, 255, 255, .94);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .22);
}
.chess-review-path {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: .04em;
}
.chess-review-arrow {
  font-weight: 800;
  color: var(--rose-600, #d71879);
  font-size: 1rem;
  line-height: 1;
  margin: 0 1px;
}
.chess-review-list-row[data-color="b"] .chess-review-arrow {
  color: #ffb6e0;
}
.chess-review-capture {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(216, 24, 121, .82);
  color: #fff;
  font-size: .76rem;
  font-weight: 800;
  line-height: 1;
  margin: 0 2px;
}
.chess-review-suffix {
  display: inline-block;
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  margin-left: 6px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .42);
}
.chess-review-suffix[data-kind="check"]   { background: rgba(255, 224, 107, .72); color: #4d1933; }
.chess-review-suffix[data-kind="mate"]    { background: rgba(216, 24, 121, .82);  color: #fff;    }
.chess-review-list-row[data-color="b"] .chess-review-suffix[data-kind="check"] { background: rgba(255, 224, 107, .92); }
.chess-review-san {
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  font-weight: 700;
}

.chess-review-list-item.is-expanded > .chess-review-list-row {
  background: linear-gradient(135deg, rgba(255, 224, 107, .26), rgba(255, 144, 203, .22));
  border-color: rgba(255, 144, 203, .42);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.chess-review-expand-arrow {
  font-size: .92rem;
  color: var(--plum-700, #6f4d8a);
  transition: transform .18s ease, color .18s ease;
}
.chess-review-list-item.is-expanded .chess-review-expand-arrow {
  color: var(--rose-600, #d71879);
}
.chess-review-detail {
  padding: 12px 12px 14px;
  border: 1px solid rgba(255, 144, 203, .42);
  border-top: 0;
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 245, 250, .86), rgba(255, 255, 255, .92));
  display: grid;
  gap: 6px;
  animation: chessReviewDetailIn .24s cubic-bezier(.34, 1.56, .64, 1) both;
}
@keyframes chessReviewDetailIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Loading state inside detail */
.chess-review-detail-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px;
  font-size: .82rem;
  color: var(--plum-700, #6f4d8a);
}
.chess-review-spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid rgba(216, 24, 121, .22);
  border-top-color: var(--rose-600, #d71879);
  border-radius: 50%;
  animation: chessReviewSpin .72s linear infinite;
}
@keyframes chessReviewSpin { to { transform: rotate(360deg); } }

/* Pristine (never-analysed) detail with CTA */
.chess-review-detail-pristine {
  display: grid;
  gap: 6px;
  text-align: center;
}
.chess-review-detail-analyze {
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 0;
  border-radius: 10px;
  background: linear-gradient(135deg, #ff4fa8, #d71879);
  color: #fff;
  font: 700 .82rem var(--display, inherit);
  cursor: pointer;
  padding: 0 14px;
  box-shadow: 0 6px 14px rgba(216, 24, 121, .28);
  transition: transform .18s ease;
}
.chess-review-detail-analyze:hover,
.chess-review-detail-analyze:focus-visible { transform: translateY(-1px); }
.chess-review-detail-analyze:active { transform: scale(.98); }
.chess-review-detail-analyze i { font-size: 1rem; }
.chess-review-detail-hint {
  margin: 0;
  font-size: .7rem;
  color: var(--plum-700, #6f4d8a);
}

/* Analysed result */
.chess-review-detail-result { display: grid; gap: 6px; }
.chess-review-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.chess-review-detail-quality {
  font-family: var(--display);
  font-size: .94rem;
  color: #4d1933;
}
.chess-review-detail-result[data-quality="best"]    .chess-review-detail-quality { color: #2c8055; }
.chess-review-detail-result[data-quality="good"]    .chess-review-detail-quality { color: #6f4d8a; }
.chess-review-detail-result[data-quality="ok"]      .chess-review-detail-quality { color: #6b5e8a; }
.chess-review-detail-result[data-quality="inacc"]   .chess-review-detail-quality { color: #c47a17; }
.chess-review-detail-result[data-quality="blunder"] .chess-review-detail-quality { color: #a01c52; }
.chess-review-detail-stars {
  font-size: .94rem;
  letter-spacing: -1px;
  color: #ffb53a;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chess-review-detail-blurb {
  margin: 0;
  font-size: .8rem;
  color: var(--plum-800, #4d1933);
  line-height: 1.4;
}
.chess-review-detail-loss {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: start;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(216, 24, 121, .12);
  color: #a01c52;
  font: 700 .72rem var(--display, inherit);
}
.chess-review-detail-loss i { font-size: .82rem; }
.chess-review-detail-alt {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .82);
  border: 1px dashed rgba(255, 144, 203, .42);
  font-size: .82rem;
  color: #4d1933;
}
.chess-review-detail-alt-label {
  font-size: .72rem;
  text-transform: uppercase;
  color: var(--rose-600, #d71879);
  letter-spacing: .04em;
  font-weight: 700;
}
.chess-review-detail-alt strong {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
}
/* Phase E: piece sprite + arrow text inline. The sprite is sized to match
   the surrounding text so it reads as «move this piece here». */
.chess-review-detail-alt-move {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.chess-review-detail-alt-move .chess-review-glyph {
  width: 22px;
  height: 22px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  display: inline-block;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 2px rgba(116, 18, 70, .22));
}

/* Game-mode specific hides — no analysis surface during play. */
.chess-review-modal[data-chess-review-mode="game"] .chess-review-summary { display: none; }
.chess-review-modal[data-chess-review-mode="game"] .chess-review-list-row {
  grid-template-columns: 36px minmax(0, 1fr);
}

@media (prefers-reduced-motion: reduce) {
  .chess-review-card { animation: none; }
}

/* === Sticky resume CTA — appears in lower-right when there is an active
   game and the user is in a covering UI (start-modal, bottom-sheet,
   puzzle-modal, error overlay). Z-index intentionally above the
   bottom-sheet (z=80) and start-modal (z=120) so it always wins for
   thumb-reach. */
.chess-sticky-resume[hidden] { display: none !important; }
.chess-sticky-resume {
  position: fixed;
  right: 14px;
  bottom: calc(env(safe-area-inset-bottom) + 14px);
  z-index: 210;
  display: inline-grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 10px;
  row-gap: 0;
  min-height: 56px;
  padding: 8px 18px 8px 16px;
  border-radius: 999px;
  color: #fff;
  font: 800 .9rem var(--display, inherit);
  cursor: pointer;
  /* bg + shadow + border from data-bevel="button-jewel" */
  backdrop-filter: blur(8px);
  animation: chessStickyResumeIn .28s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
  transition: transform .18s ease, filter .18s ease, bottom .24s ease;
}

/* When install-nudge is open it pins to the same bottom-right zone — lift
   the sticky resume CTA above it so they don't overlap or cover. */
body[data-install-nudge-open="1"] .chess-sticky-resume {
  bottom: calc(env(safe-area-inset-bottom) + 96px);
}

.chess-sticky-resume i {
  font-size: 1.2rem;
  grid-row: 1 / span 2;
  grid-column: 1;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .22);
  color: #fff;
}

.chess-sticky-resume-label {
  grid-row: 1;
  grid-column: 2;
  font-size: .92rem;
  line-height: 1.1;
  letter-spacing: .01em;
  align-self: end;
}

.chess-sticky-resume-state {
  grid-row: 2;
  grid-column: 2;
  font-family: var(--body);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  line-height: 1.1;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .82);
  align-self: start;
  font-variant-numeric: tabular-nums;
}

.chess-sticky-resume-state:empty {
  display: none;
}

.chess-sticky-resume-state:empty + * {
  /* fallback when state is unknown — collapse to single row */
}

/* When state-slot is empty, collapse vertical layout */
.chess-sticky-resume:has(.chess-sticky-resume-state:empty) {
  grid-template-rows: 1fr;
}

.chess-sticky-resume:has(.chess-sticky-resume-state:empty) .chess-sticky-resume-label {
  grid-row: 1 / span 2;
  align-self: center;
}

/* Golden pulse when it's the player's turn — subtle urgency cue without
   competing with the active board. */
.chess-sticky-resume[data-turn="mine"] {
  animation: chessStickyResumeIn .28s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both,
             chessStickyResumePulse 1.8s ease-in-out 1.2s infinite;
}

@keyframes chessStickyResumePulse {
  0%, 100% { box-shadow: 0 14px 26px rgba(216, 24, 121, .42), 0 0 0 0 rgba(255, 213, 74, 0), inset 0 1px 0 rgba(255,255,255,.32); }
  50%      { box-shadow: 0 16px 30px rgba(216, 24, 121, .48), 0 0 0 6px rgba(255, 213, 74, .42), inset 0 1px 0 rgba(255,255,255,.32); }
}

.chess-sticky-resume:hover,
.chess-sticky-resume:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 18px 34px rgba(216, 24, 121, .5), inset 0 1px 0 rgba(255,255,255,.42);
}

.chess-sticky-resume:active {
  transform: scale(.96);
}

@keyframes chessStickyResumeIn {
  from { opacity: 0; transform: translateY(20px) scale(.92); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Mobile: center horizontally so the CTA sits in the thumb-zone of the
   bottom edge — easier to reach with either hand than a corner pin. */
@media (max-width: 480px) {
  .chess-sticky-resume {
    right: auto;
    left: 50%;
    transform: translateX(-50%);
  }
  .chess-sticky-resume:hover,
  .chess-sticky-resume:focus-visible {
    transform: translateX(-50%) translateY(-2px);
  }
  .chess-sticky-resume:active {
    transform: translateX(-50%) scale(.96);
  }
}

@media (prefers-reduced-motion: reduce) {
  .chess-sticky-resume,
  .chess-sticky-resume[data-turn="mine"] { animation: none; }
}

/* === Engine error overlay — shown if chess-engine.js / chess-ai.js fail
   to load or initChessPro() throws. Friendly playful framing instead
   of a sterile system-error look (skill-redesign-piped-truffle). */
.chess-engine-error[hidden] { display: none !important; }
.chess-engine-error {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(circle at 50% 30%, rgba(255, 144, 203, .42), transparent 60%),
    rgba(46, 14, 32, .68);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.chess-engine-error-card {
  position: relative;
  display: grid;
  gap: 14px;
  justify-items: center;
  text-align: center;
  width: min(92vw, 360px);
  padding: 28px 24px 22px;
  border-radius: 20px;
  /* bg + shadow + border from data-bevel="hero-premium" */
  color: #4d1933;
  animation: chessEngineErrorIn .42s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
}

.chess-engine-error-card::before,
.chess-engine-error-card::after {
  content: "";
  position: absolute;
  z-index: 4;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 3px 6px rgba(216, 24, 121, .2));
}
.chess-engine-error-card::before {
  top: -22px;
  left: -18px;
  width: 80px;
  height: 80px;
  background-image: url("assets/chess/final-png/props/hero-blossom-left.png");
  transform: rotate(-12deg);
  opacity: .85;
}
.chess-engine-error-card::after {
  bottom: -18px;
  right: -16px;
  width: 70px;
  height: 70px;
  background-image: url("assets/chess/final-png/props/panel-blossom.png");
  transform: rotate(8deg);
  opacity: .82;
}

@keyframes chessEngineErrorIn {
  0%   { opacity: 0; transform: translateY(20px) scale(.92); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Hero mascot — gentle wobble so the still PNG feels alive on what's
   otherwise a frozen error screen. Filter saturates down slightly so
   it reads as 'sad cat' without needing a separate sad-variant asset. */
.chess-engine-error-hero {
  width: 96px;
  height: 96px;
  object-fit: contain;
  filter: drop-shadow(0 8px 16px rgba(116, 18, 70, .26)) saturate(.78);
  animation: chessEngineErrorWobble 3.2s ease-in-out infinite;
}

@keyframes chessEngineErrorWobble {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}

.chess-engine-error-card strong {
  font-family: var(--display, inherit);
  font-size: 1.24rem;
  font-weight: 900;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
  color: #6b073b;
}

.chess-engine-error-card p {
  margin: 0;
  font-size: .92rem;
  color: #6f4d8a;
  line-height: 1.5;
  text-wrap: pretty;
}

.chess-engine-error-actions {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  width: 100%;
  margin-top: 4px;
}

/* P0: stack engine-error buttons vertically on mobile so neither gets clipped
   by the right edge. The previous 1fr/auto grid would overflow at <420px. */
@media (max-width: 480px) {
  .chess-engine-error-actions {
    grid-template-columns: 1fr;
  }
  .chess-engine-error-secondary {
    width: 100%;
  }
}

.chess-engine-error-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 22px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="button-bold" */
  color: #fff;
  font: 800 .94rem var(--display, inherit);
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.chess-engine-error-primary i {
  font-size: 1.1rem;
}

.chess-engine-error-primary:hover,
.chess-engine-error-primary:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.04) saturate(1.06);
}

.chess-engine-error-primary:active {
  transform: scale(.96);
}

.chess-engine-error-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 48px;
  padding: 0 16px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="button-thin" */
  color: var(--plum-700, #6f4d8a);
  font: 700 .82rem var(--display, inherit);
  text-decoration: none;
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.chess-engine-error-secondary i {
  font-size: 1rem;
  color: var(--rose-600);
}

.chess-engine-error-secondary:hover,
.chess-engine-error-secondary:focus-visible {
  filter: brightness(1.04);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .chess-engine-error-card,
  .chess-engine-error-hero { animation: none; }
}

/* === Player rows — split into top (opponent above board) + bottom (self
   below board, before dock). Each row is a card-pearl chip with avatar +
   name + status pill. Active player's pill is visible; inactive's is hidden.
   Avatars sit on opposite outer edges (top-right for opponent, bottom-left
   for self) so the page reads as "two players facing each other across the
   board". */
.player-row { display: none; }

/* Tabular nums on numeric labels so digits don't nudge layout. */
.player-row-name,
.clock-stack time,
.turn-card strong,
[data-chess-dock-turn],
body[data-page="chess"] .move-log li {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

@media (max-width: 760px) {
  .player-row {
    display: flex;
    align-items: center;
    gap: 10px;
    /* Compact vertical padding (10 → 6) so each card eats less of the
       limited mobile real-estate. Horizontal padding kept at 14 because
       chip-clean bevel + avatar look right with that breathing room. */
    padding: 6px 14px;
    border-radius: 16px;
    /* bg + shadow + border from data-bevel="card-pearl" */
    min-height: 52px;
    box-sizing: border-box;
    transition: filter .25s ease, opacity .25s ease;
  }

  /* Top row (opponent): DOM is [status, name, avatar].
     Auto-margin on name pushes it (and avatar) to the right edge,
     leaving status anchored at the left. Avatar ends up at far right. */
  .player-row--top .player-row-name { margin-left: auto; }

  /* Bottom row (self): DOM is [avatar, name, status].
     Auto-margin on status pushes it to the right edge while
     avatar + name stay grouped at the left. */
  .player-row--bottom .player-row-status { margin-left: auto; }

  .player-row--bottom { width: 100%; justify-self: stretch; }

  .player-row-avatar {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    box-shadow:
      inset 0 0 0 2px rgba(255, 255, 255, .96),
      inset 0 0 0 4px rgba(255, 144, 203, .32),
      var(--depth-1);
    transition: box-shadow .25s ease, transform .25s ease;
    flex: none;
  }
  .player-row.is-active .player-row-avatar {
    box-shadow:
      inset 0 0 0 2px rgba(255, 255, 255, .96),
      inset 0 0 0 4px rgba(255, 79, 168, .82),
      0 8px 18px rgba(216, 24, 121, .26),
      var(--depth-1);
    animation: chessAvatarPulse 1.8s ease-in-out infinite;
  }

  .player-row-name {
    color: var(--plum-700);
    font-family: var(--display);
    font-size: .96rem;
    font-weight: 700;
    line-height: 1.05;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }

  .player-row-status {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 30px;
    padding: 4px 12px;
    border-radius: 999px;
    /* bg + shadow + border from data-bevel="state-jewel-active" */
    color: #fff;
    font-family: var(--display);
    font-size: .85rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    line-height: 1.05;
    white-space: nowrap;
    flex: none;
    box-sizing: border-box;
  }

  .player-row-status strong { color: #fff !important; }

  .player-row-status::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 6px rgba(255, 255, 255, .6);
    flex: none;
  }

  .player-row-status[hidden] { display: none !important; }

  /* Per-kind status badge styling. The default state-jewel-active bevel
     provides the rose pill background; we override colour + animation for
     specific game states so check/mate/win/draw read distinct at a glance. */

  /* «Шах!» — red urgent pulse on the side-to-move's card. The base bevel
     already gives a rose surface; we layer a brighter red gradient + ring
     pulse so it feels alarming (vs the calm «Ваш ход»). */
  .player-row-status[data-status-kind="check"] {
    background: linear-gradient(135deg, #ff3a5f 0%, #c01939 100%) !important;
    box-shadow: 0 4px 12px rgba(216, 24, 64, .55),
                inset 0 1px 2px rgba(255, 255, 255, .35),
                0 0 0 0 rgba(255, 79, 100, .55) !important;
    animation: chessPlayerCheckPulse 1.05s ease-in-out infinite;
  }
  .player-row-status[data-status-kind="check"]::before {
    background: #ffe06b;
    box-shadow: 0 0 8px rgba(255, 224, 107, .9);
  }
  @keyframes chessPlayerCheckPulse {
    0%, 100% { box-shadow: 0 4px 12px rgba(216, 24, 64, .55),
                            inset 0 1px 2px rgba(255, 255, 255, .35),
                            0 0 0 0 rgba(255, 79, 100, .55); }
    50%      { box-shadow: 0 4px 14px rgba(216, 24, 64, .7),
                            inset 0 1px 2px rgba(255, 255, 255, .45),
                            0 0 0 6px rgba(255, 79, 100, 0); }
  }

  /* «Мат» — dark, dramatic, static (game over, no pulse). Shown on the
     LOSER's card. Pairs with the «Победа!» / «Поражение» badge on the
     winner's card so both rows reflect the outcome semantically. */
  .player-row-status[data-status-kind="mate"] {
    background: linear-gradient(135deg, #5a0e22 0%, #2a0612 100%) !important;
    box-shadow: 0 4px 14px rgba(46, 14, 32, .6),
                inset 0 1px 2px rgba(255, 255, 255, .12) !important;
    animation: none;
  }
  .player-row-status[data-status-kind="mate"]::before {
    background: #d71879;
    box-shadow: 0 0 8px rgba(216, 24, 121, .9);
  }

  /* «Победа!» — gold celebratory; shown on the winner's card */
  .player-row-status[data-status-kind="win"] {
    background: linear-gradient(135deg, #ffd84a 0%, #ffaa1f 100%) !important;
    color: #4d1933 !important;
    box-shadow: 0 4px 14px rgba(255, 153, 0, .55),
                inset 0 1px 2px rgba(255, 255, 255, .55) !important;
  }
  .player-row-status[data-status-kind="win"]::before {
    background: #4d1933;
    box-shadow: 0 0 6px rgba(77, 25, 51, .5);
  }

  /* «Поражение» (rare — only when winner's text shows on the LOSER's card
     in some edge layouts). Subdued plum. */
  .player-row-status[data-status-kind="loss"] {
    background: linear-gradient(135deg, #6f4d8a 0%, #4d1933 100%) !important;
    box-shadow: 0 3px 10px rgba(77, 25, 51, .42),
                inset 0 1px 2px rgba(255, 255, 255, .2) !important;
  }

  /* «Ничья» — muted neutral plum */
  .player-row-status[data-status-kind="draw"] {
    background: linear-gradient(135deg, #b9aaca 0%, #6f4d8a 100%) !important;
    box-shadow: 0 3px 8px rgba(141, 39, 95, .35),
                inset 0 1px 2px rgba(255, 255, 255, .25) !important;
  }

  @media (prefers-reduced-motion: reduce) {
    .player-row-status[data-status-kind="check"] { animation: none; }
  }

  /* Inactive row: dimmed slightly so the active row reads as the live one.
     The pill being hidden is the primary signal; this is the secondary cue. */
  .player-row:not(.is-active):not(.is-host) {
    filter: saturate(.85);
    opacity: .82;
  }

  /* Avatar art mapping. Default canonical: self=goose, opponent=cat.
     When body[data-chess-character="cat"] (player picked cat in start-modal),
     swap so self=cat / opponent=goose regardless of chess side. -inv recolor
     of the file is handled separately by body[data-chess-inverted="1"] vars. */
  body.has-chess-art-assets .player-row-avatar[data-chess-bar-avatar="opponent"] {
    background-image: var(--asset-avatar-cat);
    background-color: rgba(255, 255, 255, .86);
    background-position: 50% 38%;
  }
  body.has-chess-art-assets .player-row-avatar[data-chess-bar-avatar="self"] {
    background-image: var(--asset-avatar-goose);
    background-color: rgba(255, 255, 255, .86);
    background-position: 50% 42%;
  }
  body[data-chess-character="cat"] .player-row-avatar[data-chess-bar-avatar="opponent"] {
    background-image: var(--asset-avatar-goose);
    background-color: rgba(255, 255, 255, .86);
    background-position: 50% 42%;
  }
  body[data-chess-character="cat"] .player-row-avatar[data-chess-bar-avatar="self"] {
    background-image: var(--asset-avatar-cat);
    background-color: rgba(255, 255, 255, .86);
    background-position: 50% 38%;
  }

  @keyframes chessAvatarPulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.06); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .player-row,
  .player-row-avatar,
  .player-row-status {
    transition: none !important;
    animation: none !important;
  }
}

/* === Mobile bottom sheet (desktop hides trigger; sheet hidden by default) === */
.dock-actions .chess-sheet-trigger { display: none !important; }

.chess-header-more { display: none; }

.chess-bottom-sheet[hidden] { display: none; }

.chess-bottom-sheet {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  align-items: end;
}

.chess-bottom-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(46, 14, 32, .42);
  backdrop-filter: blur(6px);
  cursor: pointer;
  animation: chessSheetBackdrop .25s ease both;
}

.chess-bottom-sheet-card {
  position: relative;
  width: min(540px, 100%);
  margin: 0 auto;
  max-height: min(80dvh, 720px);
  padding: 12px 18px 18px;
  border-radius: 26px 26px 0 0;
  /* bg + shadow + border from data-bevel="card-production" + sheet-specific
     inverted top→bottom shadow is added below via cascade override */
  overflow-y: auto;
  animation: chessSheetSlideUp .32s cubic-bezier(.18, .76, .35, 1.05) both;
}

/* Bottom-sheet inverted shadow direction (slides up — heavy top, light bottom).
   Layered ON TOP of the data-bevel="card-production" base shadow. */
.chess-bottom-sheet-card[data-bevel] {
  box-shadow:
    0 -28px 60px rgba(46, 14, 32, .32),
    0 -10px 20px rgba(116, 18, 70, .22),
    0 -1px 0 rgba(255, 200, 224, .42),
    inset 0 2px 0 rgba(255, 255, 255, .96),
    inset 0 1px 4px rgba(216, 24, 121, .08);
}

/* Sakura corner on top-right of sheet — top-left occupied by handle */
.chess-bottom-sheet-card::before {
  content: "";
  position: absolute;
  top: -16px;
  right: -14px;
  width: 76px;
  height: 76px;
  background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
  transform: rotate(8deg);
  opacity: .82;
  pointer-events: none;
  z-index: 3;
  filter: drop-shadow(0 3px 6px rgba(216, 24, 121, .2));
}

@keyframes chessSheetBackdrop {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes chessSheetSlideUp {
  0%   { transform: translateY(100%); }
  100% { transform: translateY(0); }
}

.chess-bottom-sheet-handle {
  width: 56px;
  height: 5px;
  border-radius: 999px;
  background: rgba(116, 18, 70, .24);
  margin: 0 auto 10px;
}

.chess-bottom-sheet-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--plum-700);
  /* bg + shadow + border from data-bevel="button-clean" */
  cursor: pointer;
  z-index: 2;
  transition: transform .18s ease, filter .18s ease;
}

.chess-bottom-sheet-close:hover,
.chess-bottom-sheet-close:focus-visible {
  filter: brightness(1.06);
  transform: scale(1.06);
}

.chess-bottom-sheet-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 4px;
  margin-bottom: 14px;
  background: rgba(46, 14, 32, .06);
  border-radius: 16px;
}

.chess-bottom-sheet-tabs button {
  min-height: 44px;
}

.chess-game-actions {
  display: grid;
  gap: 8px;
}
/* Phase 11: 2-col grid на mobile reduces vertical stack of 5 buttons.
   "Новая игра" stays full-width (most-used), остальные в 2-col. */
@media (max-width: 480px) {
  .chess-game-actions {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }
  .chess-game-actions [data-chess-new] {
    grid-column: 1 / -1;
  }
  .chess-game-action {
    padding: 10px 12px !important;
    font-size: .85rem;
  }
  .chess-game-action span {
    font-size: .82rem;
  }
}

.chess-game-action {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="button-bold/clean/thin" */
  font-family: var(--display);
  font-size: 1rem;
  text-align: left;
  cursor: pointer;
  min-height: 48px;
  transition: transform .18s ease, filter .18s ease;
}

.chess-game-action[data-chess-new] { color: #fff; }
.chess-game-action[data-chess-flip],
.chess-game-action[data-chess-history] { color: var(--plum-800); }
.chess-game-action[data-chess-resign],
.chess-game-action[data-chess-draw] { color: var(--plum-700); }

.chess-game-action i { font-size: 1.2rem; }

.chess-game-settings {
  display: grid;
  gap: 4px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, .6);
}

.chess-game-setting {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 14px;
  min-height: 44px;
  border-radius: 12px;
  color: var(--plum-700);
  text-decoration: none;
  font-family: var(--body);
  font-size: .92rem;
  cursor: pointer;
  /* bg + shadow + border from data-bevel="chip-flat" */
  transition: filter .18s ease;
}

.chess-game-setting:hover,
.chess-game-setting:focus-visible {
  filter: brightness(1.04);
}

.chess-game-setting i {
  color: var(--rose-600);
  font-size: 1.1rem;
}

.chess-game-setting em {
  font-style: normal;
  color: var(--rose-600);
  font-weight: 700;
  font-size: .82rem;
}

.chess-game-difficulty {
  display: grid;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .6);
}

.chess-game-difficulty h3 {
  margin: 0;
  font-family: var(--display);
  font-size: .98rem;
  color: var(--plum-700);
}

body[data-chess-mode="duel"] .chess-game-difficulty,
body[data-chess-mode="duel"] [data-chess-draw] {
  display: none;
}

body[data-chess-mode="duel"] [data-chess-draw][data-chess-draw-show] {
  display: grid;
}

.chess-bottom-sheet-tabs button {
  display: grid;
  place-items: center;
  gap: 2px;
  padding: 8px 6px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="chip-flat"
     active aria-pressed promoted to state-jewel-active in style-bevels.css */
  color: var(--plum-700);
  font-family: var(--display);
  font-size: .76rem;
  cursor: pointer;
  transition: filter .18s ease, color .18s ease;
}

.chess-bottom-sheet-tabs button[aria-pressed="true"] {
  color: #fff;
}

.chess-bottom-sheet-tabs button i { font-size: 1.1rem; }

.chess-bottom-sheet-slot[hidden] { display: none; }

.chess-bottom-sheet-slot {
  display: grid;
  gap: 12px;
  padding-bottom: env(safe-area-inset-bottom);
}

/* When sheet is open, hide its trigger active state */
body.chess-sheet-open { overflow: hidden; }

/* === Shop tab: balance + theme/accent unlocks === */
.chess-shop-balance {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 12px;
  /* bg + shadow + border from data-bevel="card-toy" */
  font-family: var(--display, inherit);
  color: var(--plum-700);
  font-weight: 700;
}
.chess-shop-balance i { font-size: 1.3rem; }
.chess-shop-balance strong { margin-left: auto; font-size: 1.1rem; }
.chess-shop-hint {
  margin: 0;
  font-size: .82rem;
  color: var(--plum-700);
  opacity: .82;
  line-height: 1.35;
}
.chess-shop-section h3 {
  margin: 0 0 8px;
  font-size: .92rem;
  color: var(--plum-700);
}
.chess-shop-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.chess-shop-item {
  display: grid;
  gap: 6px;
  padding: 10px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="chip-clean / state-jewel-active / state-disabled" */
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: var(--plum-700);
  transition: filter .18s ease;
}
.chess-shop-item:hover, .chess-shop-item:focus-visible {
  filter: brightness(1.04);
  outline: none;
}
.chess-shop-item[data-state="active"] { color: #fff; }
.chess-shop-item[disabled] { cursor: not-allowed; }
.chess-shop-preview {
  height: 48px;
  border-radius: 10px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .9);
}
.chess-shop-preview span {
  display: block;
}
.chess-shop-item-name {
  font-weight: 700;
  font-size: .86rem;
}
.chess-shop-item-state {
  font-size: .76rem;
  color: var(--plum-700);
  opacity: .8;
  display: flex;
  align-items: center;
  gap: 4px;
}
.chess-shop-item[data-state="active"] .chess-shop-item-state { color: var(--rose-600); opacity: 1; font-weight: 700; }
.chess-shop-item[data-state="locked"] .chess-shop-item-state i.ti-lock { color: var(--plum-700); }

/* === Daily puzzle card + modal === */
.chess-puzzle-card {
  display: grid;
  gap: 4px;
  padding: 12px 14px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="card-toy" */
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: var(--plum-700);
}
.chess-puzzle-card[data-state="solved"] { filter: hue-rotate(75deg) saturate(.85); }
.chess-puzzle-card[data-state="solved"] .chess-puzzle-meta::before { content: "✓ "; color: rgb(40, 140, 80); font-weight: 800; }
.chess-puzzle-eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: .76rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: rgb(90, 60, 160); }
.chess-puzzle-card strong { font-size: .98rem; font-weight: 800; }
.chess-puzzle-meta { font-size: .8rem; opacity: .8; }

.chess-puzzle-modal[hidden] { display: none !important; }
.chess-puzzle-modal {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  padding: 16px;
}
.chess-puzzle-backdrop {
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 50% 0%, rgba(255, 144, 203, .36), transparent 58%),
    rgba(46, 14, 32, .58);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.chess-puzzle-card-modal {
  position: relative;
  width: min(420px, 100%);
  max-height: calc(100dvh - 32px);
  overflow: visible;
  border-radius: var(--modal-radius-card, 22px);
  padding: 26px 22px 20px;
  /* bg + shadow + border now from data-bevel="hero-jewel" */
  color: var(--plum-700);
  display: grid; gap: 12px;
  animation: chessPuzzleCardIn .42s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
}

/* Sakura corners on puzzle modal (smaller scale than start-card) */
.chess-puzzle-card-modal::before {
  content: "";
  position: absolute;
  z-index: 4;
  pointer-events: none;
  top: -22px;
  left: -18px;
  width: 88px;
  height: 88px;
  background: url("assets/chess/final-png/props/hero-blossom-left.png") center/contain no-repeat;
  transform: rotate(-10deg);
  opacity: .9;
  filter: drop-shadow(0 4px 8px rgba(216, 24, 121, .22));
}

@keyframes chessPuzzleCardIn {
  0%   { opacity: 0; transform: translateY(20px) scale(.94); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Daily-badge sticker — pinned top-center, slightly oversized so it
   acts as a hero sticker rather than a quiet decoration. */
.chess-puzzle-hero-badge {
  position: absolute;
  top: -34px;
  left: 50%;
  transform: translateX(-50%) rotate(-6deg);
  width: 72px;
  height: 72px;
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 8px 16px rgba(216, 24, 121, .32));
  animation: chessPuzzleBadgeIn .56s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
}

@keyframes chessPuzzleBadgeIn {
  0%   { opacity: 0; transform: translateX(-50%) rotate(-30deg) scale(.4); }
  100% { opacity: 1; transform: translateX(-50%) rotate(-6deg) scale(1); }
}

.chess-puzzle-close {
  position: absolute; top: 12px; right: 12px;
  width: 44px; height: 44px;
  border-radius: 50%;
  /* bg + shadow + border from data-bevel="button-clean" */
  color: var(--plum-700);
  display: grid; place-items: center;
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.chess-puzzle-close:hover,
.chess-puzzle-close:focus-visible {
  filter: brightness(1.06);
  transform: scale(1.06);
}

.chess-puzzle-head {
  display: grid;
  gap: 4px;
  text-align: center;
  margin-top: 28px;
}

.chess-puzzle-head .chess-puzzle-eyebrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--display);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--rose-600);
}

.chess-puzzle-head .chess-puzzle-eyebrow i {
  font-size: .9rem;
}

.chess-puzzle-card-modal h2 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.2rem, 4.5vw, 1.4rem);
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #6b073b;
  text-wrap: balance;
}

.chess-puzzle-subcopy {
  margin: 0;
  font-family: var(--body);
  font-size: .82rem;
  line-height: 1.4;
  color: rgba(77, 53, 103, .76);
  text-wrap: pretty;
}

.chess-puzzle-prompt {
  margin: 0; padding: 12px 14px;
  border-radius: 14px;
  /* bg + shadow + border from data-bevel="chip-flat" */
  font-family: ui-monospace, "JetBrains Mono", "Courier New", monospace;
  font-size: .92rem;
  line-height: 1.5;
  color: var(--plum-800);
  white-space: pre-line;
  text-align: center;
}

/* Phase 1: weekly progress dots на puzzle modal — visualizes 1/7 position
   in weekly puzzle pack. Filled = solved, current = ring, future = dim. */
.chess-puzzle-progress-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 6px;
}
.chess-puzzle-progress-dots[hidden] { display: none; }
.chess-puzzle-progress-dots > span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(141, 39, 95, .22);
  transition: background .2s ease, transform .2s ease;
}
.chess-puzzle-progress-dots > span.is-solved {
  background: linear-gradient(135deg, var(--rose-600), var(--gold-500));
}
.chess-puzzle-progress-dots > span.is-current {
  background: linear-gradient(135deg, var(--plum-800), var(--rose-600));
  transform: scale(1.3);
  box-shadow: 0 0 0 3px rgba(232, 41, 143, .22);
}

.chess-puzzle-question {
  margin: 4px 0 2px;
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 800;
  text-align: center;
  color: var(--plum-800);
}

.chess-puzzle-options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.chess-puzzle-options button {
  position: relative;
  min-height: 56px;
  padding: 10px 12px;
  border-radius: 14px;
  border: 2px solid rgba(255, 144, 203, .42);
  background: linear-gradient(135deg, rgba(255, 255, 255, .96), rgba(255, 232, 244, .82));
  color: var(--plum-800);
  font: 800 1rem ui-monospace, "JetBrains Mono", "Courier New", monospace;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease, background .18s ease;
  font-variant-numeric: tabular-nums;
}

.chess-puzzle-options button:hover:not(:disabled),
.chess-puzzle-options button:focus-visible:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--rose-500);
  box-shadow: 0 12px 22px rgba(216, 24, 121, .2);
}

.chess-puzzle-options button:active:not(:disabled) {
  transform: scale(.96);
}

.chess-puzzle-options button:disabled { cursor: not-allowed; opacity: .55; }

.chess-puzzle-options button[data-result="right"] {
  border-color: rgb(60, 170, 100);
  background: linear-gradient(135deg, rgba(220, 250, 230, .95), rgba(190, 240, 215, .9));
  animation: chessPuzzleRightFlash .56s ease both;
}

.chess-puzzle-options button[data-result="right"]::after {
  content: "✓";
  position: absolute;
  top: -10px;
  right: -10px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(135deg, #4cc97a, #2c8055);
  color: #fff;
  font: 800 1rem var(--display, inherit);
  box-shadow: 0 6px 14px rgba(44, 128, 85, .4);
  animation: chessPuzzleCheckIn .42s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
}

@keyframes chessPuzzleRightFlash {
  0%   { box-shadow: 0 0 0 0 rgba(60, 170, 100, .56); }
  60%  { box-shadow: 0 0 0 12px rgba(60, 170, 100, 0); }
  100% { box-shadow: 0 0 0 0 rgba(60, 170, 100, 0); }
}

@keyframes chessPuzzleCheckIn {
  0%   { transform: scale(0) rotate(-90deg); opacity: 0; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

.chess-puzzle-options button[data-result="wrong"] {
  border-color: rgb(220, 80, 100);
  background: linear-gradient(135deg, rgba(255, 220, 225, .95), rgba(255, 200, 210, .9));
  animation: chessPuzzleWrongShake .26s ease both;
  text-decoration: line-through;
  text-decoration-color: rgba(180, 50, 70, .6);
}

@keyframes chessPuzzleWrongShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}

.chess-puzzle-feedback {
  margin: 4px 0 0;
  padding: 10px 14px;
  border-radius: 12px;
  font-family: var(--display);
  font-weight: 700;
  font-size: .92rem;
  text-align: center;
}
.chess-puzzle-feedback[data-tone="ok"] {
  color: rgb(28, 100, 60);
  background: linear-gradient(135deg, rgba(220, 250, 230, .9), rgba(190, 240, 215, .8));
  border: 1px solid rgba(60, 170, 100, .42);
}
.chess-puzzle-feedback[data-tone="bad"] {
  color: rgb(160, 28, 60);
  background: linear-gradient(135deg, rgba(255, 220, 225, .9), rgba(255, 200, 210, .8));
  border: 1px solid rgba(220, 80, 100, .42);
}

/* Petal-burst overlay — fires when feedback turns 'ok'. The 5 petals
   fan out from the centre of the card with staggered delays. Triggered
   via :has() on the feedback element rather than a JS class swap. */
.chess-puzzle-petal-burst {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: hidden;
  border-radius: inherit;
}

.chess-puzzle-petal {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  background: url("assets/chess/final-png/props/soft-petal-01.png") center/contain no-repeat;
  opacity: 0;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 4px 6px rgba(216, 24, 121, .28));
}

.chess-puzzle-petal[style*="--p:2"] {
  background-image: url("assets/chess/final-png/props/soft-petal-02.png");
}
.chess-puzzle-petal[style*="--p:3"] {
  background-image: url("assets/chess/final-png/props/soft-petal-03.png");
}
.chess-puzzle-petal[style*="--p:4"] {
  background-image: url("assets/chess/final-png/props/soft-petal-04.png");
}
.chess-puzzle-petal[style*="--p:5"] {
  background-image: url("assets/chess/final-png/props/soft-petal-05.png");
}

.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal {
  animation: chessPuzzlePetalBurst 1.2s cubic-bezier(.18, .76, .35, 1.05) both;
}

.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal[style*="--p:1"] { animation-delay: 0ms; --burst-x: -110px; --burst-y: -90px; --burst-r: -180deg; }
.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal[style*="--p:2"] { animation-delay: 60ms; --burst-x: 110px;  --burst-y: -90px; --burst-r: 220deg; }
.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal[style*="--p:3"] { animation-delay: 120ms; --burst-x: -130px; --burst-y: 70px; --burst-r: -240deg; }
.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal[style*="--p:4"] { animation-delay: 180ms; --burst-x: 130px;  --burst-y: 70px; --burst-r: 280deg; }
.chess-puzzle-card-modal:has(.chess-puzzle-feedback[data-tone="ok"]:not([hidden])) .chess-puzzle-petal[style*="--p:5"] { animation-delay: 240ms; --burst-x: 0; --burst-y: -130px; --burst-r: 360deg; }

@keyframes chessPuzzlePetalBurst {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.4) rotate(0); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--burst-x, 0)), calc(-50% + var(--burst-y, 0))) scale(1) rotate(var(--burst-r, 0)); }
}

@media (prefers-reduced-motion: reduce) {
  .chess-puzzle-card-modal,
  .chess-puzzle-hero-badge,
  .chess-puzzle-petal { animation: none !important; }
}

/* === Skin variants: applied via body data attributes === */
body[data-chess-skin-board="midnight"] {
  --chess-light-square: #4a3568;
  --chess-dark-square: #2c1f4a;
}
body[data-chess-skin-board="midnight"] .chess-square.light {
  background: linear-gradient(135deg, #5a4280, #4a3568);
}
body[data-chess-skin-board="midnight"] .chess-square.dark {
  background: linear-gradient(135deg, #2c1f4a, #1a1230);
}
body[data-chess-skin-board="midnight"] .chess-square .coord { color: rgba(255,255,255,.55); }

body[data-chess-skin-accent="emerald"] .chess-square.last-move,
body[data-chess-skin-accent="emerald"] .chess-square.selected {
  box-shadow: inset 0 0 0 3px rgba(60, 200, 140, .9);
}
body[data-chess-skin-accent="emerald"] .chess-square.legal-move::after {
  background: rgba(60, 200, 140, .6);
}

@media (prefers-reduced-motion: reduce) {
  .chess-bottom-sheet-card,
  .chess-bottom-sheet-backdrop { animation: none; }
}

/* === Start modal: mode → difficulty/variant → side === */
.chess-start-modal {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 16px;
}

.chess-start-modal[hidden] { display: none; }

.chess-start-backdrop {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 50% 0%, rgba(255, 144, 203, .42), transparent 56%),
    rgba(46, 14, 32, .58);
  backdrop-filter: blur(10px);
  cursor: pointer;
}

.chess-start-card {
  position: relative;
  width: min(440px, 100%);
  max-height: min(90vh, 720px);
  overflow: visible;
  padding: 26px 24px 22px;
  border-radius: 28px;
  /* background + box-shadow + border теперь приходят из data-bevel="hero-premium" */
  animation: chessStartIn .42s cubic-bezier(.18, .76, .35, 1.05) both;
}
/* Phase 9: contain sakura decorations within card bounds на mobile —
   their negative top/left positioning otherwise pushes them off-viewport
   right edge clipped by browser. */
@media (max-width: 480px) {
  .chess-start-card {
    overflow: hidden;
  }
  .chess-start-card::before {
    top: -28px;
    left: -24px;
    width: 76px;
    height: 76px;
  }
  .chess-start-card::after {
    bottom: -24px;
    right: -20px;
    width: 76px;
    height: 76px;
  }
}

/* Phase 9: migration bullets list — replaces verbose 3-paragraph copy */
/* Phase 10: chapter detail progress bar — shows X/7 levels cleared */
.chapter-detail-progress {
  display: grid;
  gap: 4px;
  margin: 8px 0 4px;
}
.chapter-detail-progress-label {
  font-size: .75rem;
  font-weight: 800;
  color: var(--rose-600);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.chapter-detail-progress-track {
  height: 6px;
  border-radius: 3px;
  background: rgba(141, 39, 95, .15);
  overflow: hidden;
}
.chapter-detail-progress-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--rose-500), var(--gold-500));
  transition: width .42s cubic-bezier(.34, 1.56, .64, 1);
}

.migration-bullets {
  list-style: none;
  margin: 8px 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.migration-bullets li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(255, 235, 245, .55);
  font-size: .9rem;
  font-weight: 700;
  color: var(--plum-800);
}
.migration-bullets i {
  font-size: 1.2rem;
  color: var(--rose-600);
  width: 24px;
  text-align: center;
  flex: none;
}

/* Sakura blossom corners — wired-in via existing PNG props.
   Branches extend slightly past the card boundary for a "framed" feel.
   pointer-events: none so taps pass through to the controls beneath. */
.chess-start-card::before,
.chess-start-card::after {
  content: "";
  position: absolute;
  z-index: 4;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 4px 8px rgba(216, 24, 121, .22));
}

.chess-start-card::before {
  top: -42px;
  left: -38px;
  width: 96px;
  height: 96px;
  background-image: url("assets/chess/final-png/props/hero-blossom-left.png");
  transform: rotate(-12deg);
  opacity: .92;
}

.chess-start-card::after {
  bottom: -32px;
  right: -28px;
  width: 92px;
  height: 92px;
  background-image: url("assets/chess/final-png/props/hero-blossom-right.png");
  transform: rotate(12deg);
  opacity: .88;
}

@media (prefers-reduced-motion: reduce) {
  .chess-start-card::before,
  .chess-start-card::after { filter: none; }
}

@keyframes chessStartIn {
  0%   { opacity: 0; transform: translateY(24px) scale(.94); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.chess-start-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  color: var(--plum-700);
  background: rgba(255, 255, 255, .82);
  cursor: pointer;
  transition: transform .18s ease, background .18s ease;
  z-index: 2;
}

.chess-start-close:hover,
.chess-start-close:focus-visible {
  background: rgba(255, 144, 203, .3);
  transform: scale(1.08);
}

.chess-start-step {
  display: grid;
  gap: 14px;
}

.chess-start-step[hidden] { display: none; }

.chess-start-step h2 {
  position: relative;
  font-family: var(--display);
  font-size: 1.6rem;
  color: #6b073b;
  margin: 0 0 4px;
}

/* Decorative sakura divider under each step heading (P1.8). Inline SVG
   keeps the asset weightless and lets currentColor / fill cascade from
   the heading's text color. The divider is two thin lines flanking a
   small 5-petal sakura blossom at the centre. */
.chess-start-step h2::after {
  content: "";
  display: block;
  width: 70%;
  max-width: 240px;
  height: 14px;
  margin: 8px 0 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='14' viewBox='0 0 200 14' fill='none'><line x1='8' y1='7' x2='84' y2='7' stroke='%23e8298f' stroke-width='1' stroke-opacity='.42'/><line x1='116' y1='7' x2='192' y2='7' stroke='%23e8298f' stroke-width='1' stroke-opacity='.42'/><g transform='translate(100 7)'><path d='M 0,-5 C 1.5,-3.5 1.5,-1 0,0 C -1.5,-1 -1.5,-3.5 0,-5 Z' fill='%23ff90cb' fill-opacity='.86'/><path d='M 0,-5 C 1.5,-3.5 1.5,-1 0,0 C -1.5,-1 -1.5,-3.5 0,-5 Z' fill='%23ff90cb' fill-opacity='.86' transform='rotate(72)'/><path d='M 0,-5 C 1.5,-3.5 1.5,-1 0,0 C -1.5,-1 -1.5,-3.5 0,-5 Z' fill='%23ff90cb' fill-opacity='.86' transform='rotate(144)'/><path d='M 0,-5 C 1.5,-3.5 1.5,-1 0,0 C -1.5,-1 -1.5,-3.5 0,-5 Z' fill='%23ff90cb' fill-opacity='.86' transform='rotate(216)'/><path d='M 0,-5 C 1.5,-3.5 1.5,-1 0,0 C -1.5,-1 -1.5,-3.5 0,-5 Z' fill='%23ff90cb' fill-opacity='.86' transform='rotate(288)'/><circle r='1.4' fill='%23ffd54a'/></g></svg>");
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
}

.chess-start-step p {
  margin: 0;
  color: rgba(77, 53, 103, .82);
  font-size: .92rem;
  line-height: 1.45;
}

.chess-start-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.chess-start-grid.two { grid-template-columns: 1fr 1fr; }
.chess-start-grid.three { grid-template-columns: repeat(3, 1fr); }

.chess-start-grid button {
  position: relative;
  display: grid;
  grid-template-columns: 36px 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 4px 12px;
  padding: 14px 16px;
  text-align: left;
  border-radius: 18px;
  /* bg + shadow + border from data-bevel="card-clean" or "state-disabled" */
  cursor: pointer;
  color: #3e1a35;
  font-family: var(--body);
  overflow: hidden;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

/* Paw-print corner accent on every start-grid button (mode + duel + side) */
.chess-start-grid button::before {
  content: "";
  position: absolute;
  bottom: -4px;
  right: -4px;
  width: 40px;
  height: 40px;
  background: url("assets/chess/final-png/props/corner-paw.png") center/contain no-repeat;
  opacity: .26;
  transform: rotate(-12deg);
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 2px 3px rgba(216, 24, 121, .14));
}

.chess-start-grid button > * {
  position: relative;
  z-index: 1;
}

.chess-start-grid.two button,
.chess-start-grid.three button {
  grid-template-columns: 1fr;
  grid-template-rows: auto auto auto;
  padding: 16px 12px;
  text-align: center;
  justify-items: center;
}

.chess-start-grid button:hover:not([disabled]),
.chess-start-grid button:focus-visible:not([disabled]) {
  transform: translateY(-3px);
  filter: brightness(1.04) saturate(1.08);
}

.chess-start-grid button:active:not([disabled]) {
  transform: translateY(0) scale(.98);
}

.chess-start-grid button[disabled] {
  cursor: default;
  opacity: .55;
}

.chess-start-grid button > i {
  grid-row: 1;
  grid-column: 1;
  color: var(--rose-600);
  font-size: 1.4rem;
}

.chess-start-grid.two button > i,
.chess-start-grid.three button > i {
  font-size: 1.8rem;
}

.chess-start-grid button > strong {
  grid-row: 1;
  grid-column: 2;
  color: #3e1a35;
  font-family: var(--display);
  font-size: 1.05rem;
  line-height: 1.1;
}

.chess-start-grid.two button > strong,
.chess-start-grid.three button > strong {
  grid-row: 2;
  grid-column: 1;
  font-size: 1.1rem;
  margin-top: 4px;
}

.chess-start-grid button > span:not(.mode-card-icon-frame) {
  grid-row: 2;
  grid-column: 2;
  color: rgba(77, 53, 103, .76);
  font-size: .82rem;
  line-height: 1.3;
}

.chess-start-grid.two button > span:not(.mode-card-icon-frame),
.chess-start-grid.three button > span:not(.mode-card-icon-frame) {
  grid-row: 3;
  grid-column: 1;
  font-size: .76rem;
}

/* Mode-card icon-frame is its own sub-pearl bevel container — explicitly
   placed at row 1 so it doesn't inherit the description-text grid rules
   above (which previously also matched it as a `> span` sibling, causing
   overlap with the inner <i>). */
.chess-start-grid.two button > .mode-card-icon-frame,
.chess-start-grid.three button > .mode-card-icon-frame {
  grid-row: 1;
  grid-column: 1;
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  /* bg + border from data-bevel="sub-pearl" */
}
.chess-start-grid.two button > .mode-card-icon-frame > i,
.chess-start-grid.three button > .mode-card-icon-frame > i {
  font-size: 1.6rem;
  color: var(--rose-600);
}

/* === Unified pick step (2026-05-07).
   One screen, one click sets BOTH character and chess side. 4 cards
   in a 2x2 grid (cat row, goose row) + 1 full-width random. Avatars
   use direct file URLs — they MUST stay canonical previews even when
   body[data-chess-inverted="1"] carries over from a prior session. */
.chess-start-pick-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.chess-start-pick-card {
  position: relative;
  display: grid;
  place-items: center;
  padding: 14px 12px;
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  /* Phase 19: contain decoration overflow within card bounds */
  overflow: hidden;
  animation: chessSideCardIn .42s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) both;
  animation-delay: calc(var(--i, 0) * 70ms + 80ms);
}

@keyframes chessSideCardIn {
  0%   { opacity: 0; transform: translateY(12px) scale(.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .chess-start-pick-card { animation: none; }
}

/* Side-tinted backgrounds — visual hint of which chess color this combo
   will play, even without text labels. White-side = gold, black = plum. */
.chess-start-pick-card[data-chess-start-side="w"] {
  background: linear-gradient(135deg, #fffaef, rgba(255, 224, 107, .22)) !important;
  box-shadow: var(--depth-2), inset 0 0 0 1px rgba(255, 213, 74, .32) !important;
}
.chess-start-pick-card[data-chess-start-side="b"] {
  background: linear-gradient(135deg, rgba(255, 240, 248, .96), rgba(141, 120, 180, .22)) !important;
  box-shadow: var(--depth-2), inset 0 0 0 1px rgba(141, 120, 180, .32) !important;
}
.chess-start-pick-card-random {
  grid-column: 1 / -1;
  grid-template-columns: 60px 1fr !important;
  place-items: center !important;
  gap: 12px;
  padding: 12px 16px !important;
  background: linear-gradient(135deg, rgba(255, 244, 250, .98), rgba(255, 144, 203, .26)) !important;
  box-shadow: var(--depth-2), inset 0 0 0 1px rgba(255, 144, 203, .42) !important;
}

.chess-start-pick-card[data-chess-start-side="w"]:hover:not([disabled]),
.chess-start-pick-card[data-chess-start-side="w"]:focus-visible:not([disabled]) {
  border-color: rgba(255, 224, 107, .82) !important;
}
.chess-start-pick-card[data-chess-start-side="b"]:hover:not([disabled]),
.chess-start-pick-card[data-chess-start-side="b"]:focus-visible:not([disabled]) {
  border-color: rgba(141, 39, 95, .72) !important;
}
.chess-start-pick-card-random:hover:not([disabled]),
.chess-start-pick-card-random:focus-visible:not([disabled]) {
  border-color: rgba(255, 79, 168, .82) !important;
}
.chess-start-pick-card:active:not([disabled]) {
  transform: scale(.98) !important;
}
.chess-start-pick-card[data-active="true"] {
  outline: 2px solid var(--rose-500);
  outline-offset: 2px;
}

/* Avatar disc — direct file URLs (canonical previews, never inverted). */
.chess-start-pick-avatar {
  position: relative;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, .92);
  background-position: 50% 36%;
  background-repeat: no-repeat;
  background-size: 88%;
  border: 2px solid rgba(255, 255, 255, .96);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .72),
    0 0 0 4px rgba(255, 144, 203, .28),
    0 8px 18px rgba(216, 24, 121, .26),
    0 2px 4px rgba(46, 14, 32, .14);
  transition: transform .22s cubic-bezier(.34, 1.56, .64, 1), box-shadow .22s ease;
  overflow: hidden;
}

/* White-side combos — light backgrounds + gold accent ring */
.chess-start-pick-avatar[data-pick="cat-w"] {
  background-image: url("assets/chess/final-png/characters/avatar-cat-inv.png");
  background-color: rgba(255, 250, 232, .98);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .72),
    0 0 0 4px rgba(255, 213, 74, .42),
    0 8px 18px rgba(255, 184, 92, .32),
    0 2px 4px rgba(46, 14, 32, .12);
}
.chess-start-pick-avatar[data-pick="goose-w"] {
  background-image: url("assets/chess/final-png/characters/avatar-goose.png");
  background-color: rgba(255, 250, 232, .98);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .72),
    0 0 0 4px rgba(255, 213, 74, .42),
    0 8px 18px rgba(255, 184, 92, .32),
    0 2px 4px rgba(46, 14, 32, .12);
}

/* Black-side combos — dark backgrounds + plum accent ring */
.chess-start-pick-avatar[data-pick="cat-b"] {
  background-image: url("assets/chess/final-png/characters/avatar-cat.png");
  background-color: #21151f;
  border-color: rgba(255, 255, 255, .42);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .42),
    0 0 0 4px rgba(141, 120, 180, .34),
    0 8px 18px rgba(88, 32, 63, .42),
    0 2px 4px rgba(46, 14, 32, .14);
}
.chess-start-pick-avatar[data-pick="goose-b"] {
  background-image: url("assets/chess/final-png/characters/avatar-goose-inv.png");
  background-color: #21151f;
  border-color: rgba(255, 255, 255, .42);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .42),
    0 0 0 4px rgba(141, 120, 180, .34),
    0 8px 18px rgba(88, 32, 63, .42),
    0 2px 4px rgba(46, 14, 32, .14);
}

/* Random avatar — sparkle icon disc */
.chess-start-pick-avatar[data-pick="random"] {
  width: 60px;
  height: 60px;
  background: linear-gradient(135deg, #ffe06b, #ff4fa8);
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 28px;
  box-shadow: 0 4px 12px rgba(216, 24, 121, .42);
}
.chess-start-pick-avatar[data-pick="random"] .ti {
  font-size: 28px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .2);
}

.chess-start-pick-card-random > strong {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  justify-self: start;
}

.chess-start-pick-card:hover:not([disabled]) .chess-start-pick-avatar,
.chess-start-pick-card:focus-visible:not([disabled]) .chess-start-pick-avatar {
  transform: scale(1.06) rotate(-2deg);
  box-shadow: 0 0 0 4px rgba(255, 79, 168, .32), 0 6px 14px rgba(116, 18, 70, .22), inset 0 0 0 1px rgba(255, 255, 255, .82);
}

@media (max-width: 480px) {
  .chess-start-pick-avatar:not([data-pick="random"]) {
    width: 84px;
    height: 84px;
  }
}

.chess-start-levels {
  display: grid;
  gap: 12px;
}

/* Chapter map (Phase 2 — chapter+boss progression).
   Vertical scrolling list of 7 chapters; each card surfaces unlock state,
   star tally, ELO range, and current/completed status badges. Bevel
   presets handle background+shadow so we only style layout/typography. */
.chess-chapters-list {
  display: grid;
  gap: 10px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 4px 2px;
  scrollbar-width: thin;
  /* Phase 18: smooth scroll + scroll-snap so swipe lands on a chapter card */
  scroll-snap-type: y proximity;
  scroll-behavior: smooth;
}
.chess-chapters-list .chess-chapter-card {
  scroll-snap-align: start;
}
@media (max-width: 480px) {
  .chess-chapters-list {
    max-height: 70vh;
  }
}
.chess-chapter-card {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border: none;
  border-radius: 18px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform .18s ease;
}
.chess-chapter-card:hover:not(:disabled) { transform: translateY(-1px); }
.chess-chapter-card:disabled { cursor: not-allowed; opacity: .55; }
.chess-chapter-card .chapter-card-body {
  display: grid;
  gap: 4px;
}
.chess-chapter-card strong {
  font-family: "Unbounded", sans-serif;
  font-weight: 700;
  font-size: 17px;
  color: var(--plum-900);
  letter-spacing: -0.01em;
}
.chess-chapter-card .chapter-card-elo {
  font-style: normal;
  font-size: 13px;
  font-weight: 600;
  color: var(--plum-700);
  font-variant-numeric: tabular-nums;
  opacity: .8;
}
.chess-chapter-card .chapter-card-flavor {
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
  color: var(--plum-700);
  opacity: .85;
  line-height: 1.35;
}
.chess-chapter-card .chapter-card-stars {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--gold-500);
  font-variant-numeric: tabular-nums;
}
.chess-chapter-card .chapter-card-stars i { font-size: 14px; }
.chess-chapter-card .chapter-card-current {
  position: absolute;
  top: 10px;
  right: 14px;
  font-size: 11px;
  font-weight: 800;
  color: var(--cyan-400);
  text-transform: uppercase;
  letter-spacing: .08em;
}
.chess-chapter-card .chapter-card-lock,
.chess-chapter-card .chapter-card-crown {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  font-size: 18px;
}
.chess-chapter-card .chapter-card-lock { color: var(--plum-700); opacity: .55; }
.chess-chapter-card .chapter-card-crown { color: var(--gold-500); }

/* === P2.2 Chapter map visual path =========================================
 * Transforms the simple vertical list into a "stepping stones" visual path:
 * each chapter becomes a stone, connected by dotted curves. Current chapter
 * pulses with glow. Locked chapters have chain decoration. Completed
 * chapters get a crown stamp + path is highlighted between them.
 */
.chess-chapters-list {
  position: relative;
  padding-left: 8px;
  padding-top: 8px;
}

/* Vertical dotted path running through center of stones */
.chess-chapters-list::before {
  content: "";
  position: absolute;
  left: 36px;
  top: 24px;
  bottom: 24px;
  width: 3px;
  background-image: linear-gradient(
    to bottom,
    rgba(232, 41, 143, .35) 0,
    rgba(232, 41, 143, .35) 6px,
    transparent 6px,
    transparent 14px
  );
  background-size: 100% 14px;
  background-repeat: repeat-y;
  z-index: 0;
}

.chess-chapter-card {
  position: relative;
  z-index: 1;
  /* Indent right of the path */
  margin-left: 56px;
}

/* Stone marker (number + checkpoint glyph) on each chapter — sits on the
   path. Replaces the path dot at this card's position. */
.chess-chapter-card::before {
  content: "";
  position: absolute;
  left: -56px;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff7ee 0%, #fde8c5 60%, #f5b76e 100%);
  box-shadow:
    0 4px 10px rgba(232, 41, 143, .22),
    inset 0 0 0 2px rgba(255, 255, 255, .9),
    inset 0 0 0 4px rgba(232, 41, 143, .18);
  z-index: 1;
}

/* Current chapter — pulse glow */
.chess-chapter-card[data-bevel="card-toy"]::before {
  background: radial-gradient(circle at 35% 35%, #ffe4f0 0%, #ff8db9 60%, #d8348e 100%);
  animation: chess-chapter-current-pulse 2.2s ease-in-out infinite;
}
@keyframes chess-chapter-current-pulse {
  0%, 100% { transform: translateY(-50%) scale(1); box-shadow: 0 4px 10px rgba(232, 41, 143, .22), inset 0 0 0 2px rgba(255, 255, 255, .9), inset 0 0 0 4px rgba(232, 41, 143, .18); }
  50%      { transform: translateY(-50%) scale(1.12); box-shadow: 0 0 0 8px rgba(255, 145, 195, .25), 0 8px 22px rgba(232, 41, 143, .42), inset 0 0 0 2px rgba(255, 255, 255, .9), inset 0 0 0 4px rgba(232, 41, 143, .18); }
}

/* Locked stone — greyed out + chain icon */
.chess-chapter-card:disabled::before {
  background: radial-gradient(circle at 35% 35%, #f0e8ed 0%, #c9b8c5 60%, #8e7585 100%);
  opacity: .6;
}

/* Completed chapter — gold star inside stone */
.chess-chapter-card .chapter-card-crown ~ * + ::before,
.chess-chapter-card[data-bevel="card-pearl"]::before {
  background: radial-gradient(circle at 35% 35%, #fff5dc 0%, #ffd966 60%, #c89318 100%);
}

/* Add chapter number floating on stone — 1-indexed via data-chapter-num */
.chess-chapter-card::after {
  content: attr(data-chapter-num);
  position: absolute;
  left: -56px;
  top: 50%;
  transform: translate(0, -50%);
  width: 36px;
  text-align: center;
  font-family: "Unbounded", sans-serif;
  font-size: 14px;
  font-weight: 800;
  color: var(--plum-900);
  z-index: 2;
  pointer-events: none;
}

/* Card body — slightly compact since path takes the visual hierarchy */
.chess-chapter-card {
  padding: 12px 16px;
  border-radius: 16px;
}
.chess-chapter-card strong { font-size: 15px; }
.chess-chapter-card .chapter-card-flavor { font-size: 11.5px; }

/* Chapter detail (7 levels + 1 boss in a 2×4 grid). The boss slot is the
   wide last item, spanning columns to emphasise its end-of-chapter role. */
.chess-chapter-levels {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 8px;
}
.chess-chapter-levels .chapter-level-chip {
  position: relative;
  display: grid;
  gap: 4px;
  align-items: center;
  justify-items: center;
  padding: 12px 8px;
  border: none;
  border-radius: 16px;
  cursor: pointer;
  font-family: inherit;
  transition: transform .18s ease;
}
.chess-chapter-levels .chapter-level-chip:hover:not(:disabled) { transform: translateY(-1px); }
.chess-chapter-levels .chapter-level-chip:disabled { cursor: not-allowed; opacity: .5; }
.chess-chapter-levels .chapter-level-chip .lvl-num {
  font-family: "Unbounded", sans-serif;
  font-weight: 700;
  font-size: 22px;
  color: var(--plum-900);
  font-variant-numeric: tabular-nums;
}
.chess-chapter-levels .chapter-level-chip .lvl-stars,
.chess-chapter-levels .chapter-level-boss .boss-stars,
.chess-chapter-card .chapter-card-stars-row {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1px;
}
/* Filled stars (★) inherit gold; empty (☆) drop to a soft tint so
   you can see at a glance how many stars the user has earned. */
.chess-chapter-levels .chapter-level-chip .lvl-stars,
.chess-chapter-levels .chapter-level-boss .boss-stars {
  color: var(--gold-500);
}
.chess-chapter-levels .chapter-level-chip[data-stars="0"] .lvl-stars,
.chess-chapter-levels .chapter-level-boss[data-stars="0"] .boss-stars {
  color: rgba(193, 162, 99, .35);
}
.chess-chapter-levels .star-filled { color: var(--gold-500); }
.chess-chapter-levels .star-empty { color: rgba(193, 162, 99, .35); }
.chess-chapter-levels .chapter-level-boss {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: transform .18s ease;
}
.chess-chapter-levels .chapter-level-boss:hover:not(:disabled) { transform: translateY(-1px); }
.chess-chapter-levels .chapter-level-boss:disabled { cursor: not-allowed; opacity: .55; }
.chess-chapter-levels .chapter-level-boss .boss-crown {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--gold-500);
  font-size: 22px;
}
.chess-chapter-levels .chapter-level-boss strong {
  font-family: "Unbounded", sans-serif;
  font-weight: 800;
  color: var(--plum-900);
  letter-spacing: -.01em;
}
.chess-chapter-levels .chapter-level-boss em {
  display: block;
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
  color: var(--plum-700);
  opacity: .85;
}
.chess-chapter-levels .chapter-level-boss .boss-stars {
  font-size: 14px;
  font-weight: 800;
  color: var(--gold-500);
  font-variant-numeric: tabular-nums;
}
.chess-chapter-levels .chapter-card-lock {
  position: absolute;
  top: 6px;
  right: 6px;
  color: var(--plum-700);
  opacity: .65;
  font-size: 14px;
}

.boss-attempts-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--plum-800);
  border: none;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.boss-attempts-pill i { font-size: 13px; color: var(--rose-600); }

/* Hint counter pill — sits inline within the hint button to surface the
   per-game limit (3) without taking a tooltip. */
.hint-counter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  margin-left: 6px;
  padding: 1px 7px;
  font-style: normal;
  font-size: 11px;
  font-weight: 800;
  color: var(--plum-900);
  background: rgba(255, 255, 255, 0.65);
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
[data-chess-hint][data-hint-exhausted="true"] {
  opacity: .5;
}
[data-chess-hint][data-hint-exhausted="true"] .hint-counter {
  color: var(--rose-600);
}

/* Prize chip — single prominent gold pill replaces the legacy 4-cell stats
   grid. Shows total winnings (stake prize + capture bonus + first-time star
   bonus). Placed between hero and tasks list so it reads as the "you earned
   this" headline. */
.chess-result-prize {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 18px;
  border-radius: 999px;
  background: linear-gradient(180deg, #ffd84a 0%, #ffaa1f 100%);
  color: #fff;
  font-family: "Unbounded", sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  box-shadow: 0 6px 18px rgba(255, 153, 0, .4),
              inset 0 1px 2px rgba(255, 255, 255, .55);
  margin: 2px auto 0;
  animation: chessResultStatsIn .55s cubic-bezier(.34, 1.56, .64, 1) .35s both;
}
.chess-result-prize[hidden] { display: none !important; }
.chess-result-prize i {
  font-size: 1.25rem;
  color: #fff7d6;
}
.chess-result-prize-amount { font-size: 1.15rem; }
.chess-result-prize-label {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .85;
}

/* Result overlay — V18 task list: each row is a quest goal with a leading
   crown badge, descriptive text, the actual measured value, and a mark
   (★ for earned, percentage for in-progress). Missed tasks add a thin
   progress bar so the user can see how close they were. Pattern from
   result-modal-lab-v3.html variant 18 with the per-row crown decoration. */
.chess-result-tasks {
  display: grid;
  gap: 6px;
  margin: 10px 0 4px;
  width: 100%;
}
/* SHARED P4: explicit [hidden] override — display:grid above otherwise
   shadows the browser's implicit [hidden] {display:none} UA rule, causing
   the task list to remain visible on loss/draw outcomes (audit Phase 2/3). */
.chess-result-tasks[hidden] { display: none !important; }

.chess-result-task {
  background: rgba(255, 255, 255, .65);
  border-radius: 14px;
  padding: 9px 12px;
  display: grid;
  /* crown · text · value (the crown itself signals earned/missed —
      no need for a separate ★ / % mark column). */
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  column-gap: 10px;
  row-gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--plum-700);
  transition: background .25s ease, transform .25s ease, box-shadow .25s ease;
}
.chess-result-task[data-earned="true"] {
  background: linear-gradient(135deg, #fff5e0, #ffe06b);
  color: #6b3000;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(255, 176, 46, .22);
}

/* Crown — the leading task marker. Earned: gold gradient with halo.
   Missed: faint plum fill so it reads as "locked" but still recognizable. */
.chess-result-task-crown {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(180deg, #fffaee 0%, #ffe9c0 100%);
  box-shadow: 0 2px 6px rgba(255, 176, 46, .28), inset 0 1px 2px rgba(255, 255, 255, .7);
  color: var(--gold-500);
  font-size: 16px;
}
.chess-result-task[data-earned="true"] .chess-result-task-crown {
  background: linear-gradient(180deg, #ffd84a 0%, #ffaa1f 100%);
  color: #fff;
  box-shadow: 0 3px 8px rgba(255, 153, 0, .55), inset 0 1px 2px rgba(255, 255, 255, .55);
}
.chess-result-task[data-earned="false"] .chess-result-task-crown {
  background: rgba(255, 255, 255, .42);
  color: rgba(141, 39, 95, .35);
  box-shadow: inset 0 0 0 1px rgba(141, 39, 95, .2);
}

.chess-result-task-text {
  font-family: "Nunito", sans-serif;
  font-size: 13px;
  letter-spacing: .005em;
  text-wrap: pretty;
  line-height: 1.2;
}

/* Value cell — actual measured result (00:47 / ✓ / +18). Display font for
   tabular nums + clear right-aligned read. */
.chess-result-task-value {
  font-family: "Unbounded", sans-serif;
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  white-space: nowrap;
  color: var(--plum-800);
  padding-left: 4px;
}
.chess-result-task[data-earned="true"] .chess-result-task-value {
  color: #6b3000;
  text-shadow: 0 1px 2px rgba(255, 255, 255, .55);
}
.chess-result-task[data-earned="false"] .chess-result-task-value {
  color: var(--rose-600);
  opacity: .85;
}

/* Progress bar — only on missed tasks. Spans the full row on row 2. */
.chess-result-task-bar {
  grid-column: 1 / -1;
  height: 4px;
  background: rgba(141, 39, 95, .15);
  border-radius: 999px;
  overflow: hidden;
}
.chess-result-task-bar[hidden] { display: none !important; }
.chess-result-task-bar > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--rose-400), var(--rose-500));
  border-radius: 999px;
  transition: width .6s var(--ease-spring, cubic-bezier(.34, 1.56, .64, 1));
}

@media (prefers-reduced-motion: reduce) {
  .chess-result-task,
  .chess-result-task-bar > span {
    transition: none;
  }
}

/* === Phase 1: Stake ceremony — pre-match ritual showing both sides'
   взнос → копилка → buttons. Cozy not casino: warm gradients, chip art
   not roulette, "взнос/приз/копилка" not "ставка/банк/выигрыш". */
.chess-stake-ceremony {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  padding: 16px;
  background:
    radial-gradient(circle at 50% 30%, rgba(255, 192, 220, .55), transparent 60%),
    rgba(46, 14, 32, .56);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  animation: chess-stake-ceremony-enter .35s var(--ease-spring, cubic-bezier(.4, 1.5, .5, 1)) both;
}
.chess-stake-ceremony[hidden] { display: none !important; }

@keyframes chess-stake-ceremony-enter {
  from { opacity: 0; backdrop-filter: blur(0); }
  to   { opacity: 1; backdrop-filter: blur(14px); }
}

.chess-stake-ceremony-backdrop {
  position: absolute;
  inset: 0;
  cursor: pointer;
}

.chess-stake-ceremony-card {
  position: relative;
  width: min(520px, 100%);
  max-height: calc(100svh - 32px);
  overflow-y: auto;
  display: grid;
  gap: 18px;
  padding: 26px 24px;
  border-radius: var(--modal-radius-card, 22px);
  text-align: center;
  animation: chess-stake-card-pop .42s var(--ease-spring, cubic-bezier(.5, 1.7, .5, 1)) both;
}

@keyframes chess-stake-card-pop {
  from { opacity: 0; transform: scale(.88) translateY(14px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.chess-stake-ceremony-head {
  display: grid;
  gap: 10px;
  justify-items: center;
}
.chess-stake-ceremony-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--plum-700);
}
.chess-stake-ceremony-title {
  font-family: 'Unbounded', system-ui, sans-serif;
  font-size: clamp(20px, 5.5vw, 24px);
  font-weight: 700;
  color: var(--plum-900, #2a0d28);
  line-height: 1.2;
  text-wrap: balance;
}

.chess-stake-ceremony-faceoff {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 14px;
  padding: 8px 0;
}

.chess-stake-ceremony-side {
  display: grid;
  gap: 8px;
  justify-items: center;
}
.chess-stake-ceremony-side strong {
  font-size: 14px;
  font-weight: 800;
  color: var(--plum-800);
  letter-spacing: -0.01em;
}

.chess-stake-ceremony-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--rose-100, #ffe4f0);
  background-size: 72% auto;
  background-position: center 56%;
  background-repeat: no-repeat;
  border: 3px solid #fff;
  box-shadow: 0 6px 16px rgba(216, 24, 121, .22), inset 0 0 0 2px rgba(255, 192, 220, .35);
}
/* Phase 20: explicit character data attribute beats body class fallback */
.chess-stake-ceremony-avatar[data-character="goose"] {
  background-image: url("assets/chess/final-png/characters/avatar-goose.png") !important;
}
.chess-stake-ceremony-avatar[data-character="cat"] {
  background-image: url("assets/chess/final-png/characters/avatar-cat.png") !important;
}
/* Fallback (если data-character не установлен) — use body class */
.chess-stake-ceremony-you .chess-stake-ceremony-avatar:not([data-character]) {
  background-image: url("assets/chess/final-png/characters/avatar-goose.png");
}
body[data-chess-character="cat"] .chess-stake-ceremony-you .chess-stake-ceremony-avatar:not([data-character]) {
  background-image: url("assets/chess/final-png/characters/avatar-cat.png");
}
.chess-stake-ceremony-rival .chess-stake-ceremony-avatar:not([data-character]) {
  background-image: url("assets/chess/final-png/characters/avatar-cat.png");
}
body[data-chess-character="cat"] .chess-stake-ceremony-rival .chess-stake-ceremony-avatar:not([data-character]) {
  background-image: url("assets/chess/final-png/characters/avatar-goose.png");
}

/* Phase 22: Boss avatar variant — bigger size + pulse to distinguish from
   regular opponents. Activated when ceremony shows boss badge. */
.chess-stake-ceremony:has([data-chess-stake-boss-badge]:not([hidden])) .chess-stake-ceremony-rival .chess-stake-ceremony-avatar {
  width: 84px;
  height: 84px;
  border: 3px solid #ffb02e;
  box-shadow: 0 8px 22px rgba(216, 80, 40, .35), inset 0 0 0 2px rgba(255, 255, 255, .9);
  animation: chess-boss-avatar-pulse 2s ease-in-out infinite;
}
@keyframes chess-boss-avatar-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .chess-stake-ceremony:has([data-chess-stake-boss-badge]:not([hidden])) .chess-stake-ceremony-rival .chess-stake-ceremony-avatar {
    animation: none;
  }
}

.chess-stake-ceremony-stake {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  border-radius: 999px;
  /* P1.8: bumped from 13px → 16px so взнос reads with weight matching pot */
  font-size: 16px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--plum-800);
}
.chess-stake-ceremony-stake .ti-coin {
  color: #c89318;
  font-size: 17px;
}

.chess-stake-ceremony-pot {
  position: relative;
  display: grid;
  gap: 2px;
  justify-items: center;
  min-width: 110px;
  padding: 14px 18px 12px;
  border-radius: 22px;
  background:
    radial-gradient(circle at 50% 35%, rgba(255, 235, 180, .9), rgba(255, 200, 120, .55) 60%, rgba(255, 180, 90, .35) 100%);
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, .85),
    inset 0 0 0 4px rgba(255, 200, 120, .6),
    0 8px 24px rgba(216, 24, 121, .18),
    0 2px 6px rgba(216, 24, 121, .1);
}
.chess-stake-ceremony-pot-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--plum-700);
  opacity: .85;
}
.chess-stake-ceremony-pot-value {
  font-family: 'Unbounded', system-ui, sans-serif;
  font-size: 28px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--plum-900);
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.chess-stake-ceremony-pot-unit {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--plum-700);
  opacity: .7;
}

.chess-stake-ceremony-chips {
  position: absolute;
  inset: -8px -10px -10px;
  pointer-events: none;
}
.chess-stake-chip {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #ffe48a, #d49620 70%, #a26b10 100%);
  box-shadow: 0 1px 3px rgba(50, 20, 0, .35);
  opacity: 0;
  animation: chess-stake-chip-fly 1.4s ease-in-out infinite;
}
.chess-stake-chip:nth-child(1) { left: 6%;  top: 22%; animation-delay: 0s; }
.chess-stake-chip:nth-child(2) { left: 88%; top: 18%; animation-delay: 0.28s; }
.chess-stake-chip:nth-child(3) { left: 12%; top: 70%; animation-delay: 0.56s; }
.chess-stake-chip:nth-child(4) { left: 84%; top: 76%; animation-delay: 0.84s; }
.chess-stake-chip:nth-child(5) { left: 50%; top: 92%; animation-delay: 1.12s; }
@keyframes chess-stake-chip-fly {
  0%   { opacity: 0; transform: scale(.6) translate(0, 0); }
  18%  { opacity: 1; }
  60%  { opacity: 1; transform: scale(.9) translate(calc(50% - var(--from, 0px)), -20px); }
  100% { opacity: 0; transform: scale(.4) translate(40%, -32px); }
}
@media (prefers-reduced-motion: reduce) {
  .chess-stake-chip { animation: none; opacity: .7; }
}

.chess-stake-ceremony-boss-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 14px;
  font-size: 13px;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(135deg, #d8348e 0%, #ff6f4a 100%);
}
.chess-stake-ceremony-boss-badge[hidden] { display: none; }
.chess-stake-ceremony-boss-badge .ti-flame {
  font-size: 16px;
  filter: drop-shadow(0 1px 0 rgba(255, 200, 80, .6));
}

.chess-stake-ceremony-note {
  margin: 0;
  padding: 10px 14px;
  border-radius: 14px;
  background: rgba(255, 230, 240, .65);
  font-size: 13px;
  font-weight: 600;
  color: var(--plum-700);
  line-height: 1.45;
  text-wrap: pretty;
}
.chess-stake-ceremony-note strong {
  font-weight: 800;
  color: var(--plum-900);
  font-variant-numeric: tabular-nums;
}

.chess-stake-ceremony-warning {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 8px 10px;
  padding: 10px 14px;
  border-radius: 14px;
  font-size: 13px;
  font-weight: 700;
  color: #7a2418;
  background: rgba(255, 220, 200, .85);
}
/* Phase 23: CTA button inside warning — span full width on row 2 */
.chess-stake-warning-cta {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 38px;
  padding: 0 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  color: var(--plum-800);
  cursor: pointer;
  border-radius: 10px;
  margin-top: 4px;
}
.chess-stake-warning-cta[hidden] { display: none; }

/* Phase 23: stronger disabled state for accept button когда insufficient */
.chess-stake-ceremony-accept[disabled] {
  opacity: .42 !important;
  cursor: not-allowed !important;
  position: relative;
}
.chess-stake-ceremony-accept[disabled]::before {
  content: "🔒";
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  font-size: 14px;
}
.chess-stake-ceremony-warning[hidden] { display: none; }
.chess-stake-ceremony-warning .ti-alert-triangle {
  font-size: 18px;
  color: #c44818;
  flex: none;
}

.chess-stake-ceremony-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 10px;
}
.chess-stake-ceremony-cancel,
.chess-stake-ceremony-accept {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 16px;
  border-radius: 14px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, opacity .18s ease;
}
.chess-stake-ceremony-accept[disabled] {
  opacity: .55;
  cursor: not-allowed;
}
.chess-stake-ceremony-accept .ti-coins {
  font-size: 18px;
}

@media (max-width: 480px) {
  .chess-stake-ceremony-card {
    padding: 22px 18px;
    gap: 14px;
  }
  .chess-stake-ceremony-faceoff {
    gap: 10px;
  }
  .chess-stake-ceremony-avatar {
    width: 56px;
    height: 56px;
    border-width: 2px;
  }
  .chess-stake-ceremony-pot {
    min-width: 92px;
    padding: 12px 14px 10px;
  }
  .chess-stake-ceremony-pot-value {
    font-size: 24px;
  }
  .chess-stake-ceremony-side strong {
    font-size: 12px;
  }
}

/* Chapter-unlock overlay — celebratory full-screen reveal when a boss
   falls and the next chapter unlocks. Lock shatters, crown rises. */
.chess-chapter-unlock-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
}
.chess-chapter-unlock-overlay[hidden] { display: none; }
.chess-chapter-unlock-backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 30%, rgba(255, 220, 100, .25), rgba(0, 0, 0, .65) 70%);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.chess-chapter-unlock-overlay .chapter-unlock-card {
  position: relative;
  display: grid;
  gap: 12px;
  justify-items: center;
  padding: 32px 28px;
  border-radius: 24px;
  text-align: center;
  max-width: 360px;
  animation: chapter-unlock-pop .7s cubic-bezier(.2, .7, .3, 1.4);
}
.chess-chapter-unlock-overlay .lock-anim-host {
  position: relative;
  width: 80px;
  height: 80px;
  display: grid;
  place-items: center;
}
.chess-chapter-unlock-overlay .lock-icon,
.chess-chapter-unlock-overlay .crown-icon {
  position: absolute;
  font-size: 48px;
  line-height: 1;
}
.chess-chapter-unlock-overlay .lock-icon { animation: lock-shatter .9s .25s forwards; }
.chess-chapter-unlock-overlay .crown-icon { opacity: 0; animation: crown-rise .9s .85s forwards; }
.chess-chapter-unlock-overlay strong {
  font-family: "Unbounded", sans-serif;
  font-size: 22px;
  color: var(--plum-900);
  font-weight: 800;
  letter-spacing: -.01em;
}
.chess-chapter-unlock-overlay p {
  font-size: 15px;
  font-weight: 600;
  color: var(--plum-800);
}
.chess-chapter-unlock-overlay em {
  font-style: normal;
  font-weight: 800;
  color: var(--rose-600);
}
.chess-chapter-unlock-overlay button {
  margin-top: 8px;
  padding: 12px 28px;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
}
@keyframes chapter-unlock-pop {
  0% { transform: scale(.7); opacity: 0; filter: blur(6px); }
  60% { transform: scale(1.05); opacity: 1; filter: blur(0); }
  100% { transform: scale(1); }
}
@keyframes lock-shatter {
  0% { transform: scale(1) rotate(0); opacity: 1; }
  60% { transform: scale(1.4) rotate(8deg); opacity: .55; }
  100% { transform: scale(0) rotate(20deg); opacity: 0; }
}
@keyframes crown-rise {
  0% { transform: translateY(40px) scale(.5); opacity: 0; }
  60% { transform: translateY(-6px) scale(1.15); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

/* Daily quest card (Phase 3 gamification). Sits at the top of the
   bottom-sheet game tab — surfaces today's challenge, completion state,
   and the claim CTA. State chip shifts colour from "in progress" → "ready". */
.chess-daily-quest {
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  border-radius: 18px;
  margin-bottom: 12px;
}
.chess-daily-quest-head {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: center;
}
.chess-daily-quest-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: var(--rose-600);
  font-size: 18px;
}
.chess-daily-quest-head strong {
  display: block;
  font-family: "Unbounded", sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--plum-900);
}
.chess-daily-quest-head em {
  font-style: normal;
  font-weight: 700;
  color: var(--gold-500);
  font-size: 12px;
}
.chess-daily-quest p {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--plum-800);
}
.chess-daily-quest-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.chess-daily-quest-state {
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  color: var(--plum-800);
}
.chess-daily-quest [data-chess-quest-claim] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}

/* Migration step icon — celebratory entry point for legacy users. */
.migration-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin: 0 auto 12px;
  font-size: 28px;
  color: var(--gold-500);
}

/* Tier grouping (skill-redesign-piped-truffle): three semantic groups —
   learning (1-3, gold tint), tournament (4-6, rose), hard (7-10, plum
   tint). Group eyebrow above each row hints at the difficulty journey
   without forcing the player to read all 10 cells. */
.chess-start-level-tier {
  display: grid;
  gap: 6px;
}

.chess-start-tier-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--display);
  font-style: normal;
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(77, 53, 103, .58);
}

/* Tier eyebrow ornaments — small sakura blossom on either side of the
   text. Inline SVG so they pick up the eyebrow's color via fill and
   stay branded across tiers. */
.chess-start-tier-eyebrow::before,
.chess-start-tier-eyebrow::after {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-6 -6 12 12'><g><path d='M 0,-4.5 C 1.4,-3.2 1.4,-1 0,0 C -1.4,-1 -1.4,-3.2 0,-4.5 Z' fill='%23ff90cb' fill-opacity='.92'/><path d='M 0,-4.5 C 1.4,-3.2 1.4,-1 0,0 C -1.4,-1 -1.4,-3.2 0,-4.5 Z' fill='%23ff90cb' fill-opacity='.92' transform='rotate(72)'/><path d='M 0,-4.5 C 1.4,-3.2 1.4,-1 0,0 C -1.4,-1 -1.4,-3.2 0,-4.5 Z' fill='%23ff90cb' fill-opacity='.92' transform='rotate(144)'/><path d='M 0,-4.5 C 1.4,-3.2 1.4,-1 0,0 C -1.4,-1 -1.4,-3.2 0,-4.5 Z' fill='%23ff90cb' fill-opacity='.92' transform='rotate(216)'/><path d='M 0,-4.5 C 1.4,-3.2 1.4,-1 0,0 C -1.4,-1 -1.4,-3.2 0,-4.5 Z' fill='%23ff90cb' fill-opacity='.92' transform='rotate(288)'/><circle r='1.2' fill='%23ffd54a'/></g></svg>");
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  flex-shrink: 0;
}

.chess-start-level-tier[data-tier="learn"] .chess-start-tier-eyebrow {
  color: #b07700;
}
.chess-start-level-tier[data-tier="tournament"] .chess-start-tier-eyebrow {
  color: var(--rose-600);
}
.chess-start-level-tier[data-tier="hard"] .chess-start-tier-eyebrow {
  color: var(--plum-800);
}

.chess-start-tier-row {
  display: grid;
  gap: 8px;
}

.chess-start-level-tier .chess-start-tier-row {
  grid-template-columns: repeat(3, 1fr);
}

.chess-start-levels button {
  position: relative;
  min-height: 50px;
  border-radius: 14px;
  /* base bg + shadow from data-bevel="chip-clean";
     tier-specific tints (data-tier="learn|tournament|hard") add on top */
  color: #6b073b;
  font-family: var(--display);
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  overflow: hidden;
  transition: transform .18s ease, filter .18s ease, background .18s ease, border-color .18s ease;
}

/* Sakura watermark inside every level button — bottom-right corner,
   subtle so it doesn't compete with the digit. */
.chess-start-levels button::before {
  content: "";
  position: absolute;
  bottom: -8px;
  right: -8px;
  width: 36px;
  height: 36px;
  background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
  opacity: .22;
  transform: rotate(8deg);
  pointer-events: none;
  z-index: 0;
}

.chess-start-levels button > * {
  position: relative;
  z-index: 1;
}

/* Active level bloom-overlay (P0.5) — large sakura blossom in the
   top-right corner + intense magenta gradient + depth-4 pressed glow. */
.chess-start-levels button[aria-pressed="true"]::after,
.chess-start-levels button[data-active="true"]::after {
  content: "";
  position: absolute;
  top: -12px;
  right: -10px;
  width: 38px;
  height: 38px;
  background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
  opacity: 1;
  transform: rotate(-12deg);
  pointer-events: none;
  z-index: 2;
  filter: drop-shadow(0 4px 8px rgba(255, 184, 92, .56));
  animation: chessLevelBloom 2.4s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)) infinite;
}

@keyframes chessLevelBloom {
  0%, 100% { transform: rotate(-12deg) scale(1); }
  50%      { transform: rotate(-8deg) scale(1.06); }
}

/* Tier-tinted backgrounds — the visual gradient of risk increases as
   levels get harder, so the page reads as a difficulty journey. */
.chess-start-levels button[data-tier="learn"] {
  background: linear-gradient(135deg, #fff8d4, #ffe9a8);
  border-color: rgba(255, 213, 74, .42);
}

.chess-start-levels button[data-tier="tournament"] {
  background: linear-gradient(135deg, rgba(255, 255, 255, .92), rgba(255, 232, 244, .82));
  border-color: rgba(255, 144, 203, .42);
}

.chess-start-levels button[data-tier="hard"] {
  background: linear-gradient(135deg, rgba(88, 32, 63, .12), rgba(141, 39, 95, .18));
  border-color: rgba(141, 39, 95, .32);
  color: var(--plum-800);
}

.chess-start-levels button:hover,
.chess-start-levels button:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.06) saturate(1.08);
}

.chess-start-levels button[aria-pressed="true"],
.chess-start-levels button[data-active="true"] {
  /* bg + shadow + border from data-bevel="state-jewel-active" override */
  color: #fff;
  transform: scale(1.04);
}

.chess-start-level-copy {
  position: relative;
  margin: 0;
  padding: 12px 32px;
  border-radius: 18px;
  background: linear-gradient(165deg, rgba(255, 250, 244, .92), rgba(255, 232, 244, .82));
  border: 1px solid rgba(255, 144, 203, .26);
  color: var(--plum-700);
  font-family: var(--body);
  font-size: .82rem;
  font-weight: 700;
  text-align: center;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Double-inset border creates "passe-partout" effect */
  box-shadow:
    var(--depth-1),
    inset 0 0 0 1px rgba(255, 144, 203, .26),
    inset 0 0 0 6px rgba(255, 245, 250, .68);
}

/* Paw-print corners on description pill */
.chess-start-level-copy::before,
.chess-start-level-copy::after {
  content: "";
  position: absolute;
  width: 22px;
  height: 22px;
  background: url("assets/chess/final-png/props/corner-paw.png") center/contain no-repeat;
  opacity: .42;
  pointer-events: none;
}
.chess-start-level-copy::before {
  top: 4px;
  left: 8px;
  transform: rotate(-18deg);
}
.chess-start-level-copy::after {
  bottom: 4px;
  right: 8px;
  transform: rotate(14deg);
}

.chess-start-foot {
  display: flex;
  justify-content: flex-start;
  margin-top: 4px;
}

.chess-start-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 6px 16px;
  border-radius: 999px;
  /* bg + shadow + border from data-bevel="button-thin" */
  color: var(--plum-700);
  font-family: var(--display);
  font-size: .88rem;
  cursor: pointer;
  transition: transform .18s ease, filter .18s ease;
}

.chess-start-back:hover,
.chess-start-back:focus-visible {
  filter: brightness(1.04);
  transform: translateX(-2px);
}

.chess-start-quick {
  position: relative;
  display: grid;
  grid-template-columns: 32px 1fr 32px;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-radius: 20px;
  /* bg + shadow + border from data-bevel="button-magenta" */
  color: #fff;
  font-family: var(--display);
  font-size: 1.04rem;
  text-align: left;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
  min-height: 60px;
  overflow: visible;
}

/* Sakura accent on Quick-CTA — petal floating off the left edge */
.chess-start-quick::before {
  content: "";
  position: absolute;
  top: -10px;
  left: -8px;
  width: 32px;
  height: 32px;
  background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
  transform: rotate(-12deg);
  opacity: .92;
  pointer-events: none;
  z-index: 2;
  filter: drop-shadow(0 3px 6px rgba(255, 184, 92, .42));
}

.chess-start-quick::after {
  content: "";
  position: absolute;
  bottom: -8px;
  right: -10px;
  width: 28px;
  height: 28px;
  background: url("assets/chess/final-png/props/soft-petal-02.png") center/contain no-repeat;
  transform: rotate(18deg);
  opacity: .82;
  pointer-events: none;
  z-index: 2;
}

.chess-start-quick:hover,
.chess-start-quick:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.04) saturate(1.06);
}

.chess-start-quick:active {
  transform: scale(.98);
}

.chess-start-quick i {
  font-size: 1.4rem;
}

.chess-start-quick-arrow {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  /* bg + shadow from data-bevel="sub-flat" */
  font-size: 1.05rem;
  font-family: var(--body);
  font-weight: 800;
  color: #fff;
  transition: transform .22s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1));
}

.chess-start-quick:hover .chess-start-quick-arrow,
.chess-start-quick:focus-visible .chess-start-quick-arrow {
  transform: translateX(3px);
}

/* Mode card icon frame (P0.2 — double-frame nesting). The icon now sits
   in its own surface within the card so it reads as "icon in a holder"
   rather than glued to the card padding. */
.mode-card-icon-frame {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  border-radius: 18px;
  /* bg + shadow + border from data-bevel="sub-pearl" */
  margin: 0 auto;
  position: relative;
  transition: transform .22s var(--modal-easing-spring, cubic-bezier(.34, 1.56, .64, 1)), filter .22s ease;
}

.mode-card-icon-frame i {
  font-size: 2.4rem !important;
  background: linear-gradient(135deg, var(--rose-500), var(--rose-600));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent !important;
  filter: drop-shadow(0 2px 4px rgba(216, 24, 121, .22));
}

/* Subtle sakura petal accent on the icon-frame */
.mode-card-icon-frame::after {
  content: "";
  position: absolute;
  bottom: -6px;
  right: -8px;
  width: 22px;
  height: 22px;
  background: url("assets/chess/final-png/props/soft-petal-04.png") center/contain no-repeat;
  opacity: .82;
  pointer-events: none;
  transform: rotate(14deg);
  filter: drop-shadow(0 2px 3px rgba(216, 24, 121, .22));
}

.chess-start-grid.two button:hover .mode-card-icon-frame,
.chess-start-grid.two button:focus-visible .mode-card-icon-frame {
  transform: translateY(-2px) rotate(-3deg);
  box-shadow: var(--depth-2), inset 0 0 0 1px rgba(255, 144, 203, .82);
}

/* Duel variant card: thumb + text + chevron 3-column row layout.
   Thumb in its own framed sub-container creates the same depth feel
   as mode cards but optimised for horizontal row composition. */
.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid {
  gap: 12px;
}

.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid button {
  display: grid !important;
  grid-template-columns: 64px minmax(0, 1fr) auto !important;
  grid-template-rows: auto !important;
  align-items: center !important;
  gap: 0 !important;
  column-gap: 14px !important;
  padding: 14px 18px 14px 14px !important;
  text-align: left !important;
  justify-items: stretch !important;
}

.duel-variant-thumb {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 16px;
  /* bg + shadow + border from data-bevel="sub-pearl" */
  flex-shrink: 0;
  position: relative;
  grid-column: 1;
  grid-row: 1;
}

.duel-variant-thumb i {
  font-size: 1.8rem !important;
  color: var(--rose-600) !important;
  background: none !important;
}

.duel-variant-thumb::after {
  content: "";
  position: absolute;
  top: -4px;
  right: -6px;
  width: 16px;
  height: 16px;
  background: url("assets/chess/final-png/props/soft-petal-02.png") center/contain no-repeat;
  opacity: .76;
  transform: rotate(18deg);
  pointer-events: none;
}

.duel-variant-text {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  gap: 2px;
  min-width: 0;
}

.duel-variant-text strong {
  grid-column: 1 !important;
  grid-row: 1 !important;
  font-family: var(--display);
  font-size: 1.05rem !important;
  font-weight: 900;
  color: var(--plum-800);
  text-align: left !important;
  margin: 0 !important;
}

.duel-variant-text span {
  grid-column: 1 !important;
  grid-row: 2 !important;
  font-size: .82rem !important;
  color: rgba(77, 53, 103, .76) !important;
  line-height: 1.35;
  text-align: left !important;
}

.duel-variant-chevron {
  grid-column: 3;
  grid-row: 1;
  font-size: 1.2rem !important;
  color: var(--rose-500) !important;
  background: none !important;
  opacity: .72;
  transition: transform .22s ease, opacity .22s ease;
}

.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid button:hover:not([disabled]) .duel-variant-chevron,
.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid button:focus-visible:not([disabled]) .duel-variant-chevron {
  transform: translateX(4px);
  opacity: 1;
}

.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid button[disabled] .duel-variant-thumb {
  opacity: .58;
}

.chess-start-step[data-chess-start-step="duel-variant"] .chess-start-grid button[disabled] .duel-variant-chevron {
  color: var(--plum-700) !important;
  opacity: .42;
}

/* Back-pill icon frame: arrow lives in its own circular sub-container
   so the pill reads as "icon + label" rather than a flat row of glyphs. */
.back-pill-icon-frame {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* bg + shadow from data-bevel="sub-flat" */
  margin-right: 4px;
  transition: transform .22s ease, filter .22s ease;
}

.back-pill-icon-frame i {
  font-size: 1rem;
  color: var(--rose-600);
}

.chess-start-back:hover .back-pill-icon-frame,
.chess-start-back:focus-visible .back-pill-icon-frame {
  transform: translateX(-2px);
  filter: brightness(1.06);
}

.chess-start-or {
  text-align: center;
  font-size: .82rem;
  color: rgba(77, 53, 103, .68);
  margin: 0;
}

@media (max-width: 480px) {
  .chess-start-card {
    width: 100%;
    max-height: calc(100dvh - 24px);
    padding: 22px 18px 18px;
    border-radius: 22px;
  }
  .chess-start-step h2 { font-size: 1.32rem; }
  .chess-start-grid.three { grid-template-columns: 1fr; }
  .chess-start-levels button { min-height: 56px; font-size: 1.15rem; }
}

@media (prefers-reduced-motion: reduce) {
  .chess-start-card { animation: none; }
}

@media (max-width: 760px) {
  /* App-shell layout: header → mini-hero → board-stage (fills) → bottom drawer */
  body[data-page="chess"] {
    overflow-x: hidden;
  }

  /* Header reads as a translucent navigation strip, not a card. The mobile
     layout collapses to: [brand-avatar 44] [Новая игра | Ещё раз] [⋯ 44].
     "Koska App" text + PWA pill move out (text → hidden, PWA → bottom-sheet
     "Партия" tab where data-install-app already lives). */
  .chess-header {
    position: sticky;
    top: 6px;
    z-index: 30;
    width: calc(100vw - 12px);
    min-height: 44px;
    padding: 12px;
    display: flex;
    align-items: center;
    gap: 10px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .42);
    border: 0;
    box-shadow: none;
    backdrop-filter: blur(8px);
  }

  /* On mobile, header-actions only shows the chess-profile-pill — the rest
     of its children are hide-on-mobile or hidden anyway. The pill itself
     is critical to keep visible (always-on balance display per Phase 1A),
     so the container stays as a flex item but everything other than the
     pill collapses. */
  .chess-header > .header-actions {
    display: inline-flex;
    align-items: center;
    flex: none;
  }
  .chess-header > .header-actions > *:not(.chess-profile-pill) {
    display: none;
  }
  /* Compact pill sizing for mobile — header is tight at 44px min-height. */
  .chess-profile-pill {
    min-height: 36px;
    padding: 0 12px 0 10px;
    font-size: 14px;
    gap: 5px;
  }
  .chess-profile-pill .ti-coin { font-size: 16px; }

  /* Brand collapses to a single 44×44 square with just the cat avatar. The
     "Koska App" wordmark + subtitle are hidden — the page itself is
     unmistakable as Chess Bloom and the brand-avatar still routes home. */
  .chess-brand {
    grid-template-columns: 44px;
    width: 44px;
    height: 44px;
    gap: 0;
    flex: none;
    place-items: center;
  }
  .chess-brand > span:not(.brand-avatar) { display: none; }

  /* Mobile brand-avatar — match the rounded-square players-bar avatar style
     (12px radius, single image, soft white pearl ring) so it harmonises with
     the header card's soft geometry instead of clashing as a hard pink disc. */
  .brand-avatar {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    border: 0;
    background-image: url("assets/chess/final-png/characters/logo-cat.png");
    background-color: rgba(255, 255, 255, .92);
    background-position: 50% 50%;
    background-size: 80% auto;
    background-repeat: no-repeat;
    box-shadow:
      inset 0 0 0 2px rgba(255, 255, 255, .96),
      inset 0 0 0 4px rgba(255, 144, 203, .32),
      0 4px 12px rgba(216, 24, 121, .14);
    animation: none;
  }
  .brand-avatar::before,
  .brand-avatar::after { display: none; }
  body.has-chess-art-assets .brand-avatar {
    background-image: url("assets/chess/final-png/characters/logo-cat.png");
  }

  /* Header-mounted controls — visible only on mobile. The desktop equivalent
     stays inside the hero strip. Both buttons fire the same data-chess-new /
     data-chess-reset handlers (event listeners use $$ so duplicate triggers
     are fine). */
  .chess-header-controls {
    flex: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 8px;
    min-width: 0;
  }

  .chess-header-cta {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
    border-radius: 16px;
    font-family: var(--display);
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1;
    border: 0;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .chess-header-cta.chess-game-cta-primary {
    position: relative;
    color: #fff;
    overflow: visible;
    /* bg + shadow + border from data-bevel="button-bold" */
  }

  /* Sakura petal accent on the header primary CTA — small bloom hugs
     the right edge so the pill reads "branded action" not "system btn". */
  .chess-header-cta.chess-game-cta-primary::after {
    content: "";
    position: absolute;
    top: -6px;
    right: -8px;
    width: 22px;
    height: 22px;
    background: url("assets/chess/final-png/props/panel-blossom.png") center/contain no-repeat;
    transform: rotate(14deg);
    pointer-events: none;
    filter: drop-shadow(0 2px 4px rgba(255, 184, 92, .42));
  }

  .chess-header-cta.chess-game-cta-secondary {
    color: var(--plum-700);
    /* bg + shadow + border from data-bevel="button-clean" */
  }

  .chess-header-cta:hover,
  .chess-header-cta:focus-visible {
    transform: translateY(-1px);
  }

  /* PWA install pill: the same `data-install-app` action lives inside the
     bottom-sheet "Партия" tab, so we keep the pill out of the mobile header
     to avoid duplicate buttons fighting for the limited width budget. */
  .header-actions .install-button {
    display: none !important;
  }

  .header-actions {
    flex: none;
  }

  .top-nav { display: none; }

  .header-actions { gap: 6px; }

  .hide-on-mobile { display: none !important; }

  .chess-header-more { display: grid; place-items: center; }

  .header-actions .icon-button {
    width: 44px; height: 44px;
  }

  /* Tabler icons default to 1em (~16px) which leaves the 44×44 button
     looking under-filled next to the Новая игра / Ещё раз CTAs. Bumping
     to 1.25rem (~20px) gives the kebab and sound icons visual weight that
     matches the rest of the header without changing button hit-area. */
  .chess-header-more i,
  .header-actions .icon-button i {
    font-size: 1.25rem;
  }

  body[data-page="chess"] .chess-layout {
    width: calc(100vw - 8px);
    margin: 4px auto 0;
    padding-bottom: calc(env(safe-area-inset-bottom) + 6px);
    display: grid;
    grid-auto-rows: min-content;
    /* Tightened gap 12 → 6 → saves ~24 px across 4 stacked children on
       a mobile screen, returning that real-estate to the board. */
    gap: 6px;
  }

  body[data-page="chess"] .chess-layout > .chess-bloom-hero    { order: 1; }
  body[data-page="chess"] .chess-layout > .player-row--top      { order: 2; }
  body[data-page="chess"] .chess-layout > .chess-play-grid       { order: 3; }

  /* Hero is fully hidden on mobile — its only remaining purpose was hosting
     the mode-switch, which has now moved into the header (above). The
     desktop hero with title + decorative cat/goose stays intact at >760px. */
  .chess-bloom-hero {
    display: none;
  }

  /* Title and tagline are redundant with the page header brand on mobile. */
  .chess-hero-copy {
    display: none;
  }

  .chess-hero-art {
    display: none;
  }

  .chess-mode-switch {
    grid-area: modes;
    width: auto;
    gap: 4px;
    align-self: center;
    justify-self: center;
  }

  .chess-mode-switch .segmented {
    min-width: 0;
    min-height: 44px;
    padding: 0 14px;
    font-size: .82rem;
  }

  .chess-mode-switch .segmented i { font-size: .95rem; }

  /* Chess play grid: stack vertically, board in focus */
  .chess-play-grid {
    display: grid;
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
    gap: 8px;
    align-content: stretch;
  }

  /* Player panel transparent — children flow into play-grid via display: contents */
  .player-panel,
  .status-panel {
    display: contents;
  }

  /* Mobile shows the sheet trigger; sheet itself stays hidden until tapped */
  .dock-actions .chess-sheet-trigger { display: grid !important; place-items: center; }

  /* Hide secondary panel items inline on mobile (they live inside the bottom sheet) */
  .player-panel > .turn-card,
  .player-panel > .chess-action-stack,
  .player-panel > .clock-stack,
  .player-panel > .difficulty-card,
  .player-panel > .captured-box,
  .status-panel > .move-history-card,
  .status-panel > .chess-asset-cards {
    display: none;
  }

  /* Board stage + bars layout */
  .chess-board-stage { order: 2; }

  /* Inside bottom-sheet slots, clones are the source nodes so they get re-shown */
  .chess-bottom-sheet-slot .clock-stack,
  .chess-bottom-sheet-slot .difficulty-card,
  .chess-bottom-sheet-slot .captured-box,
  .chess-bottom-sheet-slot .move-history-card,
  .chess-bottom-sheet-slot .chess-asset-cards {
    display: grid !important;
    background: rgba(255, 255, 255, .82);
    border: 1px solid rgba(255, 255, 255, .82);
    border-radius: 16px;
    padding: 14px;
    margin: 0;
  }

  .chess-bottom-sheet-slot .difficulty-pips {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    margin-top: 8px;
  }

  .chess-bottom-sheet-slot .difficulty-pips button {
    min-height: 44px;
    font-size: 1rem;
  }

  .chess-bottom-sheet-slot .clock-row {
    min-height: 56px;
  }

  .chess-bottom-sheet-slot .move-log {
    max-height: 220px;
  }

  .turn-card {
    min-height: auto;
    padding: 6px 12px;
    display: grid;
    grid-template-columns: 44px 1fr;
    grid-template-areas: "portrait label";
    align-items: center;
    gap: 10px;
    border-radius: 14px;
  }

  .turn-card span:first-child {
    grid-area: label;
    align-self: end;
    font-size: .58rem;
    line-height: 1;
  }

  .turn-card strong {
    grid-area: label;
    align-self: start;
    font-size: 1.12rem;
    line-height: 1;
  }

  .turn-card p { display: none; }

  .turn-card .side-portrait {
    grid-area: portrait;
    position: static;
    width: 44px;
    height: 44px;
    bottom: auto;
    right: auto;
    filter: drop-shadow(0 4px 8px rgba(80, 26, 56, .24));
    animation: none;
  }

  /* Hide secondary status-panel content on mobile */
  .status-panel > .panel-heading,
  .status-panel > .rule-link,
  .status-panel > .panel-copy,
  .status-panel > .hint-card {
    display: none;
  }

  .chess-asset-cards {
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }

  .asset-cta-card {
    min-height: 56px;
    grid-template-columns: 38px minmax(0, 1fr) 16px;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 16px;
  }

  .asset-icon { width: 38px; height: 38px; }

  .asset-text strong { font-size: .88rem; }
  .asset-eyebrow { font-size: .58rem; }
  .asset-meta { display: none; }
  .asset-arrow { font-size: 1rem; }

  .move-history-card {
    margin-top: 0;
    padding: 12px;
    border-radius: 16px;
  }

  body[data-page="chess"] .move-log {
    max-height: 110px;
  }

  .move-log-empty {
    padding: 12px;
  }

  .move-log-empty p { display: none; }

  /* Board stage: occupies remaining vertical space */
  body[data-page="chess"] .chess-layout > .chess-play-grid > .chess-board-stage {
    /* 8 → 4 → reclaims another 8 px height + the surrounding card no longer
       has a visible background here (.chess-board-stage is transparent on
       mobile, board-shell carries its own framed look), so the inner
       padding was purely decorative. */
    padding: 4px;
    border-radius: 20px;
    gap: 6px;
    min-height: 0;
    align-self: stretch;
  }

  .chess-board-stage::after { display: none; }

  /* Mobile reclaims ~32px vertical + ~16px horizontal by collapsing the
     rank/file label tracks to 0 — board (still grid-area col 2 / row 1)
     fills the freed space and individual cells become large enough to clear
     the 44px touch-target floor. Each square keeps its aria-label
     "{file}{rank}: {piece}" so screen-readers still announce coordinates. */
  .board-shell {
    /* Loosened constraints — the old 320 / 280 subtractions assumed the
       larger paddings + 12 px gap that the layout no longer uses. Recompute
       so the board can grow into the freed space. */
    width: min(100%, calc(100dvh - 270px));
    max-height: calc(100dvh - 240px);
    margin: 0 auto;
    /* Padding 18 → 12 — still leaves room for the 9-band frame stripes
       (each ~6 px wide) but reclaims ~12 px of board cell space (6 each side). */
    padding: 12px;
    grid-template-columns: 0 minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) 0;
    gap: 0;
    border-radius: 16px;
    aspect-ratio: 1;
  }

  .rank-labels,
  .file-labels {
    display: none;
  }

  body[data-page="chess"] .chess-board {
    border-width: 2px;
    border-radius: 10px;
  }

  body[data-page="chess"] .chess-square {
    font-size: clamp(1.4rem, 7.6vw, 2rem);
  }

  /* Bottom action dock: floating row right under board.
     Desktop turn label ("Ход / Белые") and inline status copy live inside
     this dock on wider screens — both are hidden on mobile because the
     players-bar status pill replaces them. */
  .chess-board-dock {
    position: relative;
    bottom: auto;
    grid-template-columns: 1fr;
    grid-template-areas: "actions";
    width: 100%;
    gap: 8px;
    padding: 8px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .9);
    backdrop-filter: blur(10px);
  }

  .chess-board-dock > div:first-child,
  .chess-board-dock > p {
    display: none;
  }

  .dock-actions {
    grid-area: actions;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    width: 100%;
  }

  .dock-actions button {
    min-height: 56px;
    width: auto;
    display: grid;
    place-items: center;
    gap: 6px;
    padding: 8px 6px;
    font-family: var(--display);
    font-size: .76rem;
    color: var(--plum-700);
    border-radius: 16px;
    /* bg + shadow + border from data-bevel="button-clean" */
    cursor: pointer;
    transition: transform .18s ease, filter .18s ease;
  }

  .dock-actions button:active {
    transform: scale(.96);
    filter: brightness(.94);
  }

  .dock-actions button > span {
    font-weight: 700;
    letter-spacing: -0.005em;
  }

  .dock-actions button i {
    font-size: 1.4rem;
    color: var(--rose-600);
  }

  .dock-actions button:hover,
  .dock-actions button:focus-visible {
    filter: brightness(1.04) saturate(1.08);
    transform: translateY(-2px);
  }

  /* Mobile: overlay is fixed full-viewport (declared in main rule); only
     tweak card sizing here so the hero banner + stats + actions fit. */
  .chess-result-card {
    width: min(94%, 320px);
    padding: 12px 14px 14px;
    gap: 8px;
  }
  .chess-result-primary { min-height: 50px; padding: 0 18px; font-size: .94rem; }

  /* Compact versions hidden on mobile — content lives inside bottom-sheet */
  .player-panel > .difficulty-card,
  .player-panel > .clock-stack,
  .player-panel > .captured-box {
    display: none;
  }

  /* Compact difficulty: just headline + slider, hide pip grid */
  .player-panel > .difficulty-card .difficulty-pips,
  .player-panel > .difficulty-card p {
    display: none;
  }

  .player-panel > .difficulty-card .difficulty-head {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 8px;
  }

  .player-panel > .difficulty-card .difficulty-head h2 {
    font-size: .82rem;
    margin: 0;
    color: var(--plum-700);
  }

  .player-panel > .difficulty-card .difficulty-head strong {
    font-size: .82rem;
    color: #6b073b;
  }

  .player-panel > .difficulty-card .difficulty-control {
    display: grid;
    grid-template-columns: 32px 1fr 32px;
    align-items: center;
    gap: 6px;
  }

  .player-panel > .difficulty-card .difficulty-control button {
    min-height: 32px;
    width: 32px;
  }

  .player-panel > .difficulty-card .difficulty-control label {
    font-size: 0;
  }

  .player-panel > .difficulty-card .difficulty-control input { width: 100%; }

  body[data-chess-mode="duel"] .player-panel > .difficulty-card { display: none; }

  /* Compact clock-stack as 2-column row */
  .player-panel > .clock-stack {
    grid-template-columns: 1fr 1fr;
  }

  .player-panel > .clock-stack .clock-row {
    min-height: 42px;
    padding: 6px 8px;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    gap: 6px;
  }

  .player-panel > .clock-stack .clock-row + .clock-row {
    border-top: 0;
    border-left: 1px solid rgba(112, 31, 75, .1);
  }

  .player-panel > .clock-stack .clock-avatar {
    width: 28px; height: 28px;
  }

  .player-panel > .clock-stack strong {
    font-size: .76rem;
  }

  .player-panel > .clock-stack time {
    font-size: .92rem;
  }

  /* Compact captured row */
  .player-panel > .captured-box {
    padding: 8px 12px;
  }

  .player-panel > .captured-box h2 { font-size: .76rem; margin: 0; }

  .player-panel > .captured-box .captured-content { font-size: 1.1rem; min-height: 32px; }

  .player-panel > .captured-box .captured-empty { padding: 4px 8px; }

  .player-panel > .captured-box .captured-empty-icon { width: 28px; height: 28px; }

  .player-panel > .captured-box .captured-empty strong { font-size: .82rem; }

  .player-panel > .captured-box .captured-empty p { font-size: .7rem; }

  .player-panel > .captured-box .captured-piece { width: 30px; height: 30px; }

  /* Move-history collapsed below */
  .status-panel .move-history-card {
    display: grid;
    background: rgba(255, 255, 255, .82);
    border: 1px solid rgba(255, 255, 255, .82);
    border-radius: 16px;
    padding: 10px 12px;
    margin: 0;
  }

  body[data-page="chess"] .status-panel .move-log {
    max-height: 88px;
  }

  /* P1.9: Promotion picker — center-of-viewport overlay on mobile.
     Was bottom-anchored (clipped on small screens). Now sits dead-center
     with backdrop dim so attention focuses on choice. 2x2 grid of larger
     piece tiles for clearer touch targets.
     Fix 2026-05-11 — three latent bugs prevented the picker from working:
       (1) `inset: auto` (CSS shorthand) clobbered `top: 50dvh; left: 50%`
           declared earlier in the same rule. Reorder: `inset: auto` first.
       (2) Global rule `body[data-page="chess"] .promotion-picker:not([hidden])`
           had higher specificity (0,3,1) than the old mobile rule (0,3,0)
           AND its `promotionPanelIn` keyframes used `transform: translateY(0)
           scale(1)` (identity) — which erased the mobile `translate(-50%, -50%)`
           centering at the end of the cascade. Bump mobile selector to also
           include `body[data-page="chess"]` so specificity ties + source order
           lets mobile win.
       (3) Picker was a descendant of `<main>` which has `z-index: 1` (set in
           style-wallpaper-petals.css to lift it above the wallpaper layer).
           That stacking context trapped the picker — its `z-index: 80` was
           local to main's slot in root context. Meanwhile `body::after` (the
           dim backdrop, z-index 75 in root context) escaped main's slot and
           painted ABOVE the picker. Result: picker invisible / unclickable
           after pawn promotion → "game freezes" bug. FIXED in markup by moving
           picker out of <main> to be a sibling of .chess-result-overlay. Now
           CSS selector no longer needs `.player-panel >`. */
  body[data-page="chess"] > .promotion-picker:not([hidden]) {
    display: grid;
    position: fixed;
    inset: auto;
    top: 50dvh;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(86vw, 320px);
    z-index: 80;
    padding: 18px;
    border-radius: 22px;
    grid-template-columns: 1fr;
    gap: 12px;
    background: rgba(255, 255, 255, .96);
    box-shadow:
      0 32px 80px rgba(46, 14, 32, .35),
      0 0 0 1px rgba(255, 255, 255, .9),
      inset 0 1px 0 rgba(255, 255, 255, 1);
    animation: chessPromoPickerIn .32s cubic-bezier(.34, 1.56, .64, 1) both;
  }

  /* Phase 8: backdrop dim applied via body :has() selector OUTSIDE @media —
     see global rule below этого блока. ::before на picker не работала
     из-за position:fixed parent создающего own stacking context. */

  @keyframes chessPromoPickerIn {
    from { opacity: 0; transform: translate(-50%, -42%) scale(.86); }
    to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  }
  @keyframes chessPromoBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* 2×2 grid for the 4 piece options — bigger touch targets than 1×4 row */
  body[data-page="chess"] > .promotion-picker:not([hidden]) > div[role="group"] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
  body[data-page="chess"] > .promotion-picker:not([hidden]) > div[role="group"] button {
    min-height: 64px;
    font-size: 2rem;
    border-radius: 14px;
  }
  body[data-page="chess"] > .promotion-picker:not([hidden]) > h2 {
    font-size: .95rem;
    text-align: center;
    margin: 0;
  }

  body[data-page="chess"] > .promotion-picker[hidden] { display: none; }

  /* === P0 App-shell refactor (2026-05-10) ============================
     Locks chess.html to one viewport — no page scroll. All non-critical
     side-panel content (turn card, action stack, panel-heading, rule-link,
     asset-cards, hint-card, move-history) lives in the bottom sheet on
     mobile. Main view = header / opponent player-row / board-stage / self
     player-row / dock, fitted into 100svh exactly. */
  body[data-page="chess"] {
    overflow: hidden;
    height: 100svh;
  }

  /* Hide all side-panel content that's not in the critical path on mobile */
  body[data-page="chess"] .player-panel > .turn-card,
  body[data-page="chess"] .player-panel > .chess-action-stack,
  body[data-page="chess"] .status-panel > .panel-heading,
  body[data-page="chess"] .status-panel > .rule-link,
  body[data-page="chess"] .status-panel > .chess-asset-cards,
  body[data-page="chess"] .status-panel > .hint-card,
  body[data-page="chess"] .status-panel > .move-history-card {
    display: none;
  }

  /* chess-layout fits exactly in viewport minus header strip */
  body[data-page="chess"] .chess-layout {
    height: calc(100svh - 64px);
    margin: 0 auto;
    padding: 6px 8px calc(env(safe-area-inset-bottom) + 4px);
    overflow: hidden;
    box-sizing: border-box;
  }

  /* play-grid fills remaining height (after opponent player-row) */
  body[data-page="chess"] .chess-play-grid {
    min-height: 0;
    flex: 1 1 auto;
  }

  /* board-stage takes all flex-fill space within play-grid */
  body[data-page="chess"] .chess-board-stage {
    min-height: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  /* board-shell auto-fits available space, square aspect */
  body[data-page="chess"] .board-shell {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    max-width: 100%;
    aspect-ratio: 1;
    margin: 0 auto;
    max-height: none;
  }

  /* Fix dock duplicate turn-info — boss-flag/streak-badge now first-children,
     pushing the original ":first-child" rule to wrong target. Hide explicitly
     by attribute-presence (works regardless of element order). */
  body[data-page="chess"] .chess-board-dock > div:has([data-chess-dock-turn]) {
    display: none;
  }
  body[data-page="chess"] .chess-board-dock > p[data-chess-dock-status] {
    display: none;
  }
  /* === end P0 app-shell ============================================ */
}

@media (max-width: 380px) {
  .chess-mode-switch .segmented {
    padding: 6px 10px;
    font-size: .76rem;
  }
  .chess-mode-switch .segmented i { display: none; }

  /* Header controls on 360-class viewports — "Новая игра" loses 2-3px of
     intrinsic width over the available CTA cell, tighten padding + font so
     it fits cleanly without ellipsis. */
  .chess-header {
    gap: 8px;
    padding: 10px 8px;
  }
  .chess-header-controls { gap: 6px; }
  .chess-header-cta {
    padding: 0 6px;
    font-size: .78rem;
  }

  /* On 360-class viewports, tighten the player-rows so "Bot · LV3" still
     fits without ellipsis. Avatar 44 → 36, padding shrinks. */
  .player-row {
    gap: 8px;
    padding: 8px 10px;
    min-height: 52px;
  }
  .player-row-avatar {
    width: 36px;
    height: 36px;
    border-radius: 11px;
  }
  .player-row-name {
    font-size: .88rem;
  }
  .player-row-status {
    padding: 4px 10px;
    gap: 4px;
    font-size: .78rem;
  }

  .turn-card {
    grid-template-columns: 48px 1fr auto;
  }
  .turn-card .side-portrait { width: 48px; height: 48px; }
  .turn-card strong { font-size: 1.18rem; }

  /* Keep the labelled 3-button dock at all mobile widths to avoid
     breakpoint-flip muscle-memory churn between phones (iPhone SE 375 vs
     iPhone 13 390). Inter-button gap matches dock padding for visual rhythm. */
  .dock-actions { gap: 8px; }
  .dock-actions button {
    padding: 8px 3px;
    font-size: .7rem;
  }
  .dock-actions button i { font-size: 1.25rem; }
}

/* Short viewports (iPhone SE etc): hide hero, board fills more */
@media (max-width: 760px) and (max-height: 700px) {
  body[data-page="chess"] .chess-bloom-hero {
    display: none;
  }
  body[data-page="chess"] .chess-layout {
    gap: 4px;
    min-height: calc(100dvh - 60px);
  }
  body[data-page="chess"] .chess-layout > .chess-play-grid > .chess-board-stage {
    padding: 2px;
    gap: 2px;
  }
  body[data-page="chess"] .player-bar {
    min-height: 40px;
    padding: 4px 10px;
  }
  body[data-page="chess"] .player-bar-avatar {
    width: 28px;
    height: 28px;
  }
  body[data-page="chess"] .player-bar-info strong { font-size: .9rem; }
  body[data-page="chess"] .player-bar-info span  { font-size: .7rem; }
  body[data-page="chess"] .chess-board-dock {
    padding: 4px 6px;
  }
  body[data-page="chess"] .dock-actions button {
    min-height: 32px;
    width: 32px;
  }
  body[data-page="chess"] .board-shell {
    width: min(100%, calc(100dvh - 230px));
    max-height: calc(100dvh - 200px);
    /* tighter padding on small landscape — frame becomes thin but visible */
    padding: 12px;
  }
}

/* === Chess modal common utilities (skill-redesign-piped-truffle).
   Reusable building blocks referenced by start, sheet, puzzle, tutor,
   install-nudge, engine-error and landscape modals. They consume the
   --modal-* tokens declared in :root so the entire surface system can
   be retuned in one place. */

.chess-modal-head {
  display: grid;
  gap: 4px;
  padding-bottom: 2px;
}

.chess-modal-head .chess-modal-eyebrow {
  font-family: var(--display);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--rose-600);
  font-weight: 800;
}

.chess-modal-head .chess-modal-heading {
  font-family: var(--display);
  font-size: clamp(1.32rem, 4.2vw, 1.6rem);
  font-weight: 900;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: #6b073b;
  text-wrap: balance;
  margin: 0;
}

.chess-modal-head .chess-modal-description {
  margin: 0;
  font-family: var(--body);
  font-size: .92rem;
  line-height: 1.45;
  color: rgba(77, 53, 103, .82);
  text-wrap: pretty;
}

.chess-modal-cta-sticky {
  position: sticky;
  bottom: 0;
  z-index: 3;
  padding: 12px 0 calc(env(safe-area-inset-bottom) + 8px);
  background: linear-gradient(180deg, transparent, rgba(255, 245, 250, .88) 28%, rgba(255, 245, 250, .98) 64%);
  margin: 0 -2px;
}

/* Subtle noise grain overlay — pure inline SVG turbulence, no asset.
   Apply via .chess-modal-grain on a positioned ancestor to add the
   tiny tactile imperfection that distinguishes hand-built UIs from
   AI-defaults. */
.chess-modal-grain {
  position: relative;
  isolation: isolate;
}

.chess-modal-grain::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: .045;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .26 0 0 0 0 .07 0 0 0 0 .2 0 0 0 .9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 160px 160px;
}

.chess-modal-grain > * {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .chess-modal-cta-sticky { transition: none; }
}

/* === Login page ============================================================ */

body[data-page="login"] {
  min-height: 100dvh;
  margin: 0;
  background:
    radial-gradient(circle at 20% 12%, rgba(255, 200, 230, .55), transparent 55%),
    radial-gradient(circle at 80% 88%, rgba(255, 165, 210, .45), transparent 60%),
    radial-gradient(circle at 50% 50%, var(--rose-50), var(--rose-100) 70%);
  color: var(--plum-900, #33152b);
  font-family: 'Nunito', sans-serif;
  overflow-x: hidden;
}

.login-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  min-height: 100dvh;
  padding: clamp(24px, 6vw, 64px) clamp(16px, 5vw, 48px);
  text-align: center;
}

.login-petals {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

.login-petals .petal {
  position: absolute;
  width: clamp(60px, 12vw, 130px);
  opacity: .45;
  filter: drop-shadow(0 8px 22px rgba(255, 100, 170, .25));
  animation: login-petal-drift 18s ease-in-out infinite alternate;
}

.login-petals .petal.p1 { top: 6%; left: 4%; animation-delay: 0s; transform: rotate(-12deg); }
.login-petals .petal.p2 { top: 12%; right: 8%; animation-delay: -3s; transform: rotate(18deg); width: clamp(50px, 10vw, 100px); }
.login-petals .petal.p3 { bottom: 8%; left: 10%; animation-delay: -7s; transform: rotate(8deg); }
.login-petals .petal.p4 { bottom: 16%; right: 6%; animation-delay: -12s; transform: rotate(-22deg); width: clamp(55px, 11vw, 110px); }

@keyframes login-petal-drift {
  from { translate: 0 0; }
  to { translate: 8px -12px; }
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  position: relative;
  z-index: 1;
}

.login-brand-mark {
  width: clamp(56px, 10vw, 80px);
  height: auto;
  filter: drop-shadow(0 6px 14px rgba(255, 95, 183, .25));
}

.login-brand-title {
  margin: 0;
  font-family: 'Unbounded', sans-serif;
  font-weight: 700;
  font-size: clamp(2rem, 6vw, 3rem);
  letter-spacing: -.02em;
  color: var(--plum-900, #33152b);
}

.login-prompt {
  margin: 0 0 6px;
  font-family: 'Unbounded', sans-serif;
  font-weight: 600;
  font-size: clamp(1.15rem, 3.5vw, 1.5rem);
  color: var(--plum-700, #58203f);
  position: relative;
  z-index: 1;
}

.login-pickers {
  display: flex;
  gap: clamp(14px, 3vw, 28px);
  flex-wrap: wrap;
  justify-content: center;
  max-width: 520px;
  width: 100%;
  position: relative;
  z-index: 1;
}

.login-pickers[hidden] { display: none; }

.login-picker {
  flex: 1 1 200px;
  min-width: 180px;
  max-width: 240px;
  padding: 22px 16px 18px;
  border: 0;
  border-radius: 22px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  font-family: inherit;
  color: inherit;
  transition: transform .22s var(--ease-spring, cubic-bezier(.34, 1.56, .64, 1)), filter .2s ease;
}

.login-picker:hover,
.login-picker:focus-visible {
  transform: translateY(-3px) scale(1.02);
  outline: none;
  filter: brightness(1.04);
}

.login-picker:active {
  transform: translateY(-1px) scale(.99);
  transition-duration: .08s;
}

.login-picker-hero {
  width: clamp(110px, 22vw, 160px);
  height: clamp(110px, 22vw, 160px);
  object-fit: contain;
  pointer-events: none;
  user-select: none;
  filter: drop-shadow(0 10px 24px rgba(88, 32, 63, .18));
}

.login-picker-name {
  font-family: 'Unbounded', sans-serif;
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--plum-800, #44182f);
}

.login-form {
  width: min(100%, 380px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px 22px 22px;
  border-radius: 24px;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .92), rgba(255, 240, 248, .88));
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow:
    0 24px 52px rgba(88, 32, 63, .18),
    inset 0 1px 0 rgba(255, 255, 255, .95),
    inset 0 -1px 0 rgba(255, 180, 220, .35);
  position: relative;
  z-index: 1;
  animation: login-form-rise .35s var(--ease-spring, cubic-bezier(.34, 1.56, .64, 1));
}

.login-form[hidden] { display: none; }

@keyframes login-form-rise {
  from { opacity: 0; transform: translateY(12px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.login-form-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.login-form-back {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  border: 1px solid rgba(255, 145, 195, .35);
  background: rgba(255, 255, 255, .65);
  font-size: 1.2rem;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: var(--plum-700, #58203f);
  transition: background .15s ease;
}

.login-form-back:hover {
  background: rgba(255, 245, 250, .95);
}

.login-form-greeting {
  font-family: 'Unbounded', sans-serif;
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--plum-900, #33152b);
}

.login-form-prompt {
  margin: 0;
  font-size: .95rem;
  color: var(--plum-700, #58203f);
  text-align: center;
}

.login-form-password,
.login-form-confirm {
  width: 100%;
  padding: 14px 16px;
  font-family: inherit;
  font-size: 1rem;
  border-radius: 14px;
  border: 1.5px solid rgba(255, 145, 195, .35);
  background: rgba(255, 255, 255, .85);
  color: var(--plum-900, #33152b);
  transition: border-color .15s ease, box-shadow .15s ease;
  box-sizing: border-box;
}

.login-form-password:focus,
.login-form-confirm:focus {
  outline: none;
  border-color: var(--rose-500, #ff5fb7);
  box-shadow: 0 0 0 4px rgba(255, 95, 183, .15);
}

.login-form-confirm[hidden] { display: none; }

.login-form-submit {
  margin-top: 4px;
  padding: 14px 22px;
  border: 0;
  border-radius: 16px;
  font-family: 'Unbounded', sans-serif;
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
  color: white;
  transition: transform .12s ease, filter .15s ease;
}

.login-form-submit:hover:not(:disabled) {
  filter: brightness(1.06);
}

.login-form-submit:active:not(:disabled) {
  transform: translateY(1px);
}

.login-form-submit:disabled {
  opacity: .55;
  cursor: wait;
}

.login-form-error {
  margin: 4px 0 0;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(255, 95, 105, .12);
  border: 1px solid rgba(255, 95, 105, .25);
  color: #a8132a;
  font-size: .88rem;
  text-align: center;
}

.login-form-error[hidden] { display: none; }

.login-dev-banner {
  position: fixed;
  top: 12px;
  left: 50%;
  translate: -50% 0;
  padding: 6px 14px;
  border-radius: 12px;
  background: rgba(50, 30, 60, .85);
  color: #ffe4f0;
  font-size: .78rem;
  z-index: 100;
  font-family: 'Nunito', sans-serif;
}

@media (max-width: 420px) {
  .login-pickers {
    flex-direction: row;
    gap: 12px;
  }
  .login-picker {
    flex: 1 1 0;
    min-width: 0;
    padding: 16px 8px 12px;
  }
  .login-picker-hero {
    width: clamp(80px, 28vw, 130px);
    height: clamp(80px, 28vw, 130px);
  }
  .login-picker-name {
    font-size: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .login-petals .petal { animation: none; }
  .login-form { animation: none; }
}

.koska-logout-btn {
  position: fixed;
  top: max(env(safe-area-inset-top, 0px), 10px);
  right: max(env(safe-area-inset-right, 0px), 10px);
  z-index: 1000;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  border: 1px solid rgba(88, 32, 63, .18);
  background: rgba(255, 255, 255, .92);
  color: var(--plum-700, #58203f);
  font-size: 1rem;
  font-family: inherit;
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: 0 4px 14px rgba(88, 32, 63, .14);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform .15s ease, background .15s ease;
}

.koska-logout-btn:hover,
.koska-logout-btn:focus-visible {
  transform: scale(1.08);
  background: rgba(255, 235, 245, 1);
  outline: none;
}

.koska-logout-btn:active {
  transform: scale(.96);
}
