/* Gambit Chess — the board. */
.board-frame {
  position: relative;
  padding: 5px;
  border-radius: 12px;
  background: var(--board-frame);
  box-shadow: 0 0 0 1px var(--line), var(--shadow-2);
}
.board {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  container-type: inline-size;
  --sq: 60px;
}
.board:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.b-squares { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr); border-radius: inherit; overflow: hidden; }
.b-overlay .promo-shade { border-radius: 6px; }
.sq { position: relative; background: var(--sq-light); }
.sq.dark { background: var(--sq-dark); }
.sq::before, .sq::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.sq.last::before { background: var(--hl-last); animation: sq-in 260ms var(--ease) both; }
.sq.sel::before { background: var(--hl-select); animation: sq-in 120ms ease-out both; }
/* A premove waits on the board: its squares breathe until it is played. */
.sq.pm::before { background: var(--hl-premove); animation: pm-breathe 1.7s ease-in-out infinite; }
.sq.over::before { box-shadow: inset 0 0 0 calc(var(--sq) * 0.06) rgba(255, 246, 220, 0.75); }
.sq.check::before { background: radial-gradient(circle at 50% 50%, var(--hl-check) 0%, rgba(226, 64, 48, 0.55) 34%, rgba(226, 64, 48, 0) 72%); animation: check-flash 900ms var(--ease) both; }
.sq.dest::after { inset: 36%; border-radius: 50%; background: var(--dot); animation: dot-in 180ms var(--spring) both; }
.sq.pdest::after { inset: 38%; border-radius: 50%; background: rgba(70, 110, 190, 0.45); animation: dot-in 180ms var(--spring) both; }
.sq.cap::after { inset: 2%; border-radius: 50%; background: radial-gradient(circle, transparent 0 66%, var(--dot) 67% 82%, transparent 83%); animation: dot-in 200ms var(--spring) both; }
/* The last move's squares fade in; check flares, then glows; the legal
   squares pop in when a piece is picked up. Redrawing the same highlight
   never restarts these (the board swaps classes within one frame). */
@keyframes sq-in { from { opacity: 0; } }
@keyframes check-flash { 0% { opacity: 0; transform: scale(0.35); } 30% { opacity: 1; transform: scale(1.3); } 55% { transform: scale(0.92); } 75% { transform: scale(1.08); } 100% { opacity: 1; transform: none; } }
@keyframes pm-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
@keyframes dot-in { from { opacity: 0; transform: scale(0.3); } }
.sq.kcur { box-shadow: inset 0 0 0 3px var(--focus); }
.co { position: absolute; font-size: clamp(8px, calc(var(--sq) * 0.19), 13px); font-weight: 700; line-height: 1; pointer-events: none; font-family: var(--font-ui); }
.co-r { left: 4%; top: 5%; }
.co-f { right: 5%; bottom: 4%; }
.sq.light .co { color: var(--sq-coord-light); }
.sq.dark .co { color: var(--sq-coord-dark); }

.b-pieces { position: absolute; inset: 0; pointer-events: none; }
.pc-wrap {
  position: absolute; left: 0; top: 0; width: 12.5%; height: 12.5%;
  will-change: transform;
  z-index: 2;
}
.pc-wrap .pc { width: 100%; height: 100%; padding: 4%; filter: drop-shadow(0 calc(var(--sq) * 0.025) calc(var(--sq) * 0.02) rgba(0, 0, 0, 0.32)); transition: transform 140ms var(--ease); }
.pc-wrap.dragging { z-index: 10; }
.pc-wrap.dragging .pc { transform: scale(1.12); filter: drop-shadow(0 calc(var(--sq) * 0.08) calc(var(--sq) * 0.06) rgba(0, 0, 0, 0.45)); }
/* A captured piece fades and shrinks away under the one that took it. */
.pc-wrap.fading { opacity: 0; transition: opacity 200ms ease-in !important; }
.pc-wrap.fading .pc { transform: scale(0.45); transition: transform 220ms ease-in; }
/* A piece that appears (a promotion, a reset) grows into its square. */
.pc-wrap.appearing { animation: pc-appear 240ms var(--ease) both; }
@keyframes pc-appear { from { opacity: 0; scale: 0.6; } }
.pc-wrap.toppled .pc { transform-origin: 50% 88%; animation: topple 700ms cubic-bezier(.5,.0,.7,1) forwards; }
@keyframes topple { 0% { transform: rotate(0); } 60% { transform: rotate(84deg) translateY(-4%); } 75% { transform: rotate(78deg); } 100% { transform: rotate(82deg) translateY(2%); } }

.b-shapes { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 4; }
.b-badges { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.b-badge { position: absolute; left: 0; top: 0; width: 12.5%; height: 12.5%; }
.b-badge .badge-ico { position: absolute; right: -9%; top: -9%; width: 46%; height: 46%; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45)); }
.b-badge.pop .badge-ico { animation: badge-pop 420ms var(--ease-out-back) both; }
.b-badge.sparkle::after {
  content: ""; position: absolute; right: -4%; top: -4%; width: 36%; height: 36%; border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(38, 181, 164, 0.8); animation: sparkle 900ms ease-out 120ms both;
}
@keyframes badge-pop { 0% { transform: scale(0) rotate(-30deg); opacity: 0; } 70% { transform: scale(1.25) rotate(6deg); opacity: 1; } 100% { transform: scale(1) rotate(0); } }
@keyframes sparkle { 0% { box-shadow: 0 0 0 0 rgba(38, 181, 164, 0.85), 0 0 0 0 rgba(255, 255, 255, 0.7); } 100% { box-shadow: 0 0 0 calc(var(--sq) * 0.5) rgba(38, 181, 164, 0), 0 0 0 calc(var(--sq) * 0.9) rgba(255, 255, 255, 0); } }

.b-overlay { position: absolute; inset: 0; z-index: 20; pointer-events: none; }
.b-overlay > * { pointer-events: auto; }
/* A right move in a puzzle: a ring of light around the board, then gone. */
.b-overlay > .b-glow { position: absolute; inset: 0; border-radius: 6px; pointer-events: none; box-shadow: inset 0 0 0 3px var(--win), inset 0 0 calc(var(--sq) * 0.6) color-mix(in srgb, var(--win) 40%, transparent); opacity: 0; }
.b-overlay > .b-glow.bad { box-shadow: inset 0 0 0 3px var(--loss), inset 0 0 calc(var(--sq) * 0.6) color-mix(in srgb, var(--loss) 40%, transparent); }
.promo-shade { position: absolute; inset: 0; background: rgba(6, 10, 8, 0.45); }
.promo { position: absolute; width: 12.5%; display: flex; flex-direction: column; background: var(--surface-2); border: 1px solid var(--line-accent); border-radius: 12px; box-shadow: var(--shadow-2); overflow: hidden; animation: rise-in 140ms var(--ease); }
.promo.top { top: 0; }
.promo.bottom { bottom: 0; flex-direction: column-reverse; }
.promo-pc { aspect-ratio: 1; border: 0; background: transparent; padding: 6%; display: grid; place-items: center; }
.promo-pc:hover, .promo-pc:focus-visible { background: var(--accent-glow); }
.promo-pc .pc { width: 100%; height: 100%; }

.b-moment { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; text-align: center; animation: moment-in 380ms var(--ease-out-back) both; }
.b-moment.out { animation: moment-out 380ms ease both; }
.b-moment .moment-card { padding: 14px 26px; border-radius: 16px; background: rgba(10, 18, 15, 0.82); border: 1px solid var(--line-accent); box-shadow: var(--shadow-2); backdrop-filter: blur(4px); }
:root[data-theme="light"] .b-moment .moment-card { background: rgba(251, 247, 238, 0.9); }
.b-moment .moment-title { font-family: var(--font-display); font-weight: 800; font-size: clamp(30px, 9cqi, 64px); line-height: 1; color: var(--accent-2); text-shadow: 0 2px 18px rgba(0, 0, 0, 0.45); letter-spacing: -0.03em; }
.b-moment .moment-sub { margin-top: 6px; font-weight: 650; font-size: clamp(13px, 3.4cqi, 17px); color: var(--text); }
@keyframes moment-in { from { opacity: 0; transform: scale(0.82); } to { opacity: 1; transform: none; } }
@keyframes moment-out { to { opacity: 0; transform: scale(1.06); } }

/* The slam: a heavy shake */
.board.slam { animation: slam-shake 520ms cubic-bezier(.36,.07,.19,.97) both; z-index: 40; }
@keyframes slam-shake {
  0% { transform: translate(0, 0) rotate(0); }
  10% { transform: translate(-1.5%, 2.2%) rotate(-0.8deg); }
  22% { transform: translate(1.8%, -1.6%) rotate(0.9deg); }
  36% { transform: translate(-1.4%, 1.2%) rotate(-0.6deg); }
  52% { transform: translate(1%, -0.6%) rotate(0.4deg); }
  70% { transform: translate(-0.5%, 0.4%) rotate(-0.2deg); }
  100% { transform: none; }
}

/* Handshake moment */
.shake-hands { width: 82%; max-width: 440px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.shake-hands svg { width: 100%; height: auto; overflow: visible; filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.45)); }
.shake-hands .hs-left { animation: hs-left 1300ms var(--ease) both; }
.shake-hands .hs-right { animation: hs-right 1300ms var(--ease) both; }
.hs-caption { font-family: var(--font-display); font-weight: 750; font-size: clamp(22px, 6cqi, 40px); color: var(--accent-2); text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6); animation: rise-in 500ms 700ms var(--ease) both; letter-spacing: -0.02em; }
@keyframes hs-left { 0% { transform: translateX(-170px); opacity: 0; } 32% { transform: translateX(0); opacity: 1; } 46% { transform: translateY(-9px); } 60% { transform: translateY(9px); } 74% { transform: translateY(-5px); } 88% { transform: translateY(3px); } 100% { transform: none; } }
@keyframes hs-right { 0% { transform: translateX(170px); opacity: 0; } 32% { transform: translateX(0); opacity: 1; } 46% { transform: translateY(-9px); } 60% { transform: translateY(9px); } 74% { transform: translateY(-5px); } 88% { transform: translateY(3px); } 100% { transform: none; } }

/* Eval bar */
.evalbar { position: relative; width: 22px; border-radius: 6px; overflow: hidden; background: #2b2a26; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.4); flex: none; }
.evalbar .white { position: absolute; left: 0; right: 0; bottom: 0; background: #ece6d6; transition: height 420ms var(--ease); }
.evalbar.flipped .white { bottom: auto; top: 0; }
.evalbar .ev-num { position: absolute; left: 0; right: 0; font-size: 10px; font-weight: 800; text-align: center; font-variant-numeric: tabular-nums; z-index: 1; }
.evalbar .ev-num.bottom { bottom: 4px; color: #1d1b16; }
.evalbar .ev-num.top { top: 4px; color: #ece6d6; }
.b-marks { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.b-mark { position: absolute; left: 0; top: 0; width: 12.5%; height: 12.5%; display: grid; place-items: center; }
.b-mark svg { width: 58%; height: 58%; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35)); }
.b-mark.star svg { animation: star-in 380ms var(--ease-out-back) both; }
.b-mark.got svg { animation: star-out 420ms ease-in forwards; }
.b-mark.target { background: radial-gradient(circle, rgba(90, 163, 97, 0.35) 0 32%, transparent 34%); }
@keyframes star-in { from { transform: scale(0.2) rotate(-40deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes star-out { to { transform: scale(1.8) rotate(30deg); opacity: 0; } }
