/* Generated by npm run build:css. Edit the source stylesheets instead. */

/* source: base.css */
:root {
  color-scheme: dark;
  --ink: #080a12;
  --night: #0b1020;
  --night-soft: #121a2a;
  --panel: rgba(10, 14, 24, 0.88);
  --panel-solid: #101521;
  --parchment: #e9e0ca;
  --parchment-dim: #a89f8b;
  --gold: #d4b467;
  --gold-bright: #f2d58a;
  --gold-dark: #80642f;
  --cyan: #7adfd4;
  --emerald: #2f8d78;
  --burgundy: #6a283b;
  --obsidian: #121923;
  --ivory: #eee4cc;
  --board-size: min(66vw, 72vh, 720px);
  --board-tilt: 39deg;
  --serif: Georgia, "Times New Roman", serif;
  --sans: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
  min-height: 100%;
  background: var(--ink);
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  overflow-x: hidden;
  color: var(--parchment);
  background: var(--ink);
  font-family: var(--sans);
}

button,
input {
  font: inherit;
}

button {
  color: inherit;
}

button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

[hidden] {
  display: none !important;
}

.sr-only,
.piece-definitions {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.world,
.world__image,
.world__veil,
.floating-embers {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.world {
  z-index: 0;
  overflow: hidden;
  background: #05070d;
}

.world__image {
  background-image: url("../assets/images/enchanted-castle.webp");
  background-position: 50% 38%;
  background-size: cover;
  transform: scale(1.025);
  animation: world-breathe 20s ease-in-out infinite alternate;
}

.world__veil {
  z-index: 1;
  background:
    linear-gradient(90deg, rgba(2, 5, 10, 0.73), rgba(5, 8, 16, 0.13) 43%, rgba(3, 5, 10, 0.66)),
    linear-gradient(180deg, rgba(3, 6, 14, 0.34), rgba(2, 4, 9, 0.74) 78%, #04060b 100%),
    radial-gradient(circle at 50% 20%, transparent 0, rgba(1, 3, 8, 0.1) 38%, rgba(1, 3, 8, 0.74) 100%);
}

.world__mist {
  position: fixed;
  z-index: 2;
  width: 75vw;
  height: 32vh;
  left: -20vw;
  bottom: 4vh;
  pointer-events: none;
  opacity: 0.16;
  filter: blur(42px);
  border-radius: 50%;
  background: rgba(120, 157, 182, 0.6);
  animation: mist-drift 24s ease-in-out infinite alternate;
}

.world__mist--two {
  right: -25vw;
  left: auto;
  bottom: 25vh;
  opacity: 0.1;
  animation-delay: -9s;
  animation-direction: alternate-reverse;
}

.floating-embers {
  z-index: 3;
  overflow: hidden;
}

.ember {
  position: absolute;
  bottom: -20px;
  width: 3px;
  height: 3px;
  border-radius: 999px;
  background: var(--gold-bright);
  box-shadow: 0 0 9px 2px rgba(231, 179, 74, 0.55);
  opacity: 0;
  animation: ember-rise var(--duration, 10s) linear var(--delay, 0s) infinite;
}

.app-shell {
  position: relative;
  z-index: 1;
  width: min(1480px, 100%);
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: 18px clamp(18px, 3vw, 54px) 20px;
}

.masthead {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 66px;
  border-bottom: 1px solid rgba(212, 180, 103, 0.22);
}

.brand {
  display: inline-flex;
  gap: 13px;
  align-items: center;
  padding: 6px 10px 6px 2px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

.brand__sigil {
  position: relative;
  display: grid;
  width: 43px;
  height: 43px;
  place-items: center;
  border: 1px solid rgba(223, 191, 114, 0.7);
  transform: rotate(45deg);
  background: radial-gradient(circle, rgba(213, 174, 86, 0.18), transparent 65%);
  box-shadow: inset 0 0 12px rgba(212, 180, 103, 0.12), 0 0 20px rgba(212, 180, 103, 0.08);
}

.brand__sigil::before,
.brand__sigil::after,
.brand__sigil i::before,
.brand__sigil i::after {
  position: absolute;
  content: "";
  background: var(--gold);
}

.brand__sigil::before {
  width: 1px;
  height: 25px;
}

.brand__sigil::after {
  width: 25px;
  height: 1px;
}

.brand__sigil i::before {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  transform: translate(-3px, -3px);
  box-shadow: 0 0 10px var(--gold);
}

.brand strong,
.brand small {
  display: block;
}

.brand strong {
  font-family: var(--serif);
  font-size: clamp(16px, 1.5vw, 21px);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.brand small {
  margin-top: 3px;
  color: var(--gold);
  font-size: 9px;
  letter-spacing: 0.31em;
  text-transform: uppercase;
}

.masthead__actions {
  display: flex;
  gap: 7px;
  align-items: center;
}

.icon-button {
  display: inline-flex;
  gap: 8px;
  min-height: 38px;
  align-items: center;
  padding: 8px 11px;
  border: 1px solid rgba(218, 191, 126, 0.18);
  border-radius: 2px;
  color: #b9b4a8;
  background: rgba(8, 11, 18, 0.45);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: 180ms ease;
}

.icon-button:hover {
  color: var(--parchment);
  border-color: rgba(218, 191, 126, 0.5);
  background: rgba(23, 28, 39, 0.72);
}

.icon-button--round {
  width: 38px;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  color: var(--gold);
  font-family: var(--serif);
  font-size: 15px;
}

.icon {
  position: relative;
  display: inline-block;
  width: 15px;
  height: 15px;
}

.icon--cube {
  border: 1px solid currentColor;
  transform: rotate(30deg) skew(-5deg);
}

.icon--cube::after {
  position: absolute;
  top: 4px;
  right: -3px;
  width: 8px;
  height: 8px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  content: "";
}

.icon--sound::before {
  position: absolute;
  top: 4px;
  left: 1px;
  width: 5px;
  height: 7px;
  border: 1px solid currentColor;
  border-right: 0;
  content: "";
}

.icon--sound::after {
  position: absolute;
  top: 3px;
  right: 1px;
  width: 7px;
  height: 9px;
  border-right: 1px solid currentColor;
  border-radius: 50%;
  content: "";
}

.icon-button[aria-pressed="false"] .icon--sound::after {
  width: 14px;
  height: 1px;
  top: 7px;
  right: -1px;
  border: 0;
  border-top: 1px solid currentColor;
  border-radius: 0;
  transform: rotate(-45deg);
}

.game-layout {
  position: relative;
  z-index: 5;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(285px, 340px);
  gap: clamp(26px, 4vw, 64px);
  align-items: center;
  max-width: 1240px;
  min-height: calc(100dvh - 142px);
  margin: 0 auto;
  padding: 25px 0 20px;
}

.arena {
  display: flex;
  min-width: 0;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.player-rail {
  position: relative;
  z-index: 6;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 11px;
  align-items: center;
  width: min(var(--board-size), 100%);
  padding: 6px 4px;
}

.player-rail--rival {
  margin-bottom: -1px;
}

.player-rail--hero {
  margin-top: 0;
}

.player-crest {
  position: relative;
  display: grid;
  width: 34px;
  height: 39px;
  place-items: center;
  clip-path: polygon(50% 0, 92% 17%, 84% 77%, 50% 100%, 16% 77%, 8% 17%);
  font-family: var(--serif);
  font-size: 18px;
}

.player-crest--dark {
  border: 1px solid var(--emerald);
  color: #79c8b5;
  background: linear-gradient(145deg, #20332f, #09100f);
}

.player-crest--light {
  color: #4a3421;
  background: linear-gradient(145deg, #f1dfae, #9d7e40);
}

.player-copy small,
.player-copy strong {
  display: block;
}

.player-copy small {
  margin-bottom: 2px;
  color: var(--gold);
  font-size: 8px;
  letter-spacing: 0.24em;
}

.player-copy strong {
  font-family: var(--serif);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.03em;
}

.rail-status {
  display: flex;
  gap: 7px;
  align-items: center;
  color: #8f918f;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.rail-status::before {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #59605f;
  content: "";
}

.rail-status--active {
  color: var(--gold-bright);
}

.rail-status--active::before {
  background: var(--gold-bright);
  box-shadow: 0 0 10px var(--gold);
  animation: pulse-dot 1.5s ease-in-out infinite;
}

.board-stage {
  position: relative;
  width: var(--board-size);
  height: calc(var(--board-size) * 0.86);
  perspective: 1200px;
  perspective-origin: 50% 36%;
  transition: height 400ms var(--ease-out);
}

.board-shadow {
  position: absolute;
  z-index: -1;
  right: 6%;
  bottom: -1%;
  left: 6%;
  height: 27%;
  border-radius: 50%;
  opacity: 0.9;
  background: #000;
  filter: blur(28px);
  transform: translateZ(-100px);
}

.board-frame {
  position: absolute;
  top: -9%;
  left: 0;
  width: 100%;
  aspect-ratio: 1;
  padding: 3.4%;
  border: 1px solid #8b6b32;
  border-radius: 5px;
  background:
    linear-gradient(135deg, transparent 20%, rgba(255, 222, 140, 0.16) 35%, transparent 50%),
    linear-gradient(145deg, #31200f, #0d0b09 47%, #2e1c0d 100%);
  box-shadow:
    0 3px 0 #76572a,
    0 9px 0 #31200f,
    0 14px 0 #100d09,
    0 28px 35px rgba(0, 0, 0, 0.76),
    inset 0 0 0 4px #130e08,
    inset 0 0 0 6px rgba(200, 158, 73, 0.46),
    inset 0 0 36px #000;
  transform: rotateX(var(--board-tilt));
  transform-style: preserve-3d;
  transform-origin: 50% 88%;
  transition: transform 500ms var(--ease-out), top 500ms var(--ease-out);
}

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

.board-frame::before {
  inset: 1.15%;
  border: 1px solid rgba(241, 205, 116, 0.44);
  border-radius: 2px;
}

.board-frame::after {
  right: 2%;
  bottom: 1.4%;
  left: 2%;
  height: 8px;
  border-radius: 50%;
  background: rgba(211, 171, 78, 0.15);
  filter: blur(5px);
}

.board-corner {
  position: absolute;
  z-index: 4;
  width: 21px;
  height: 21px;
  pointer-events: none;
}

.board-corner::before,
.board-corner::after {
  position: absolute;
  background: var(--gold-dark);
  content: "";
}

.board-corner::before {
  width: 1px;
  height: 21px;
  left: 10px;
}

.board-corner::after {
  width: 21px;
  height: 1px;
  top: 10px;
}

.board-corner--tl { top: 0.8%; left: 0.8%; transform: rotate(45deg); }
.board-corner--tr { top: 0.8%; right: 0.8%; transform: rotate(45deg); }
.board-corner--bl { bottom: 0.8%; left: 0.8%; transform: rotate(45deg); }
.board-corner--br { right: 0.8%; bottom: 0.8%; transform: rotate(45deg); }

.chessboard {
  position: relative;
  display: grid;
  width: 100%;
  height: 100%;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  overflow: visible;
  border: 2px solid #0c0906;
  background: #16110b;
  box-shadow: 0 0 0 1px #96703a, inset 0 0 20px #000;
  transform-style: preserve-3d;
}

.square {
  position: relative;
  display: grid;
  min-width: 0;
  min-height: 0;
  padding: 0;
  place-items: center;
  overflow: visible;
  border: 0;
  isolation: isolate;
  cursor: pointer;
  transform-style: preserve-3d;
  transition: filter 160ms ease, box-shadow 160ms ease;
}

.square--light {
  background:
    radial-gradient(circle at 22% 18%, rgba(255, 255, 255, 0.23), transparent 18%),
    linear-gradient(135deg, rgba(111, 78, 42, 0.1), transparent 50%),
    linear-gradient(145deg, #c9b992, #9d8a68);
}

.square--dark {
  background:
    radial-gradient(circle at 70% 22%, rgba(71, 116, 103, 0.25), transparent 24%),
    linear-gradient(145deg, #213c38, #122723 65%, #0e1c1b);
}

.square::before {
  position: absolute;
  z-index: 0;
  inset: 0;
  border: 1px solid rgba(255, 255, 255, 0.035);
  box-shadow: inset 1px 1px rgba(255, 255, 255, 0.08), inset -2px -2px rgba(0, 0, 0, 0.18);
  content: "";
}

.square:hover {
  z-index: 3;
  filter: brightness(1.13);
}

.square:focus-visible {
  z-index: 9;
  outline: 3px solid var(--gold-bright);
  outline-offset: -3px;
}

.square[data-file-label]::after {
  position: absolute;
  z-index: 6;
  right: 4px;
  bottom: 2px;
  color: rgba(29, 25, 19, 0.65);
  font-family: var(--serif);
  font-size: clamp(7px, calc(var(--board-size) / 76), 10px);
  font-weight: 700;
  content: attr(data-file-label);
}

.square--dark[data-file-label]::after {
  color: rgba(212, 205, 176, 0.58);
}

.rank-label {
  position: absolute;
  z-index: 6;
  top: 2px;
  left: 4px;
  color: rgba(29, 25, 19, 0.65);
  font-family: var(--serif);
  font-size: clamp(7px, calc(var(--board-size) / 76), 10px);
  font-weight: 700;
  pointer-events: none;
}

.square--dark .rank-label {
  color: rgba(212, 205, 176, 0.58);
}

.piece-token {
  position: absolute;
  z-index: 4;
  bottom: 5%;
  left: 8%;
  display: grid;
  width: 84%;
  height: 98%;
  place-items: end center;
  pointer-events: none;
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px);
  transform-origin: 50% 92%;
  transform-style: preserve-3d;
  transition: transform 230ms var(--ease-out), filter 180ms ease;
}

.piece-token::before {
  position: absolute;
  z-index: -1;
  right: 16%;
  bottom: 3%;
  left: 16%;
  height: 13%;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.54);
  filter: blur(4px);
  content: "";
  transform: rotateX(var(--board-tilt)) translateZ(-2px);
}

.piece-icon {
  width: 92%;
  height: 96%;
  overflow: visible;
  fill: currentColor;
  stroke-width: 1.4;
  transform-origin: bottom center;
}

.piece--white {
  color: #e9dfc5;
}

.piece--white .piece-icon {
  stroke: #6d552c;
  filter:
    drop-shadow(0 1px 0 #fff6dc)
    drop-shadow(0 3px 0 #aa8b51)
    drop-shadow(0 5px 2px rgba(0, 0, 0, 0.48));
}

.piece--black {
  color: #182522;
}

.piece--black .piece-icon {
  stroke: #77a994;
  filter:
    drop-shadow(0 1px 0 #395a50)
    drop-shadow(0 3px 0 #07100e)
    drop-shadow(0 5px 2px rgba(0, 0, 0, 0.72));
}

.piece-eye {
  fill: var(--gold-bright);
  stroke: none;
}

.piece-cut {
  fill: #2a2116;
  stroke: none;
}

.piece--black .piece-cut {
  fill: #8ebca7;
}

.square:hover .piece-token,
.square.is-selected .piece-token {
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-17%) translateZ(19px) scale(1.05);
  filter: brightness(1.14);
}

.square.is-selected {
  z-index: 8;
  box-shadow: inset 0 0 0 3px rgba(237, 203, 119, 0.88), inset 0 0 25px rgba(225, 185, 89, 0.46);
}

.square.is-selected::before {
  inset: 10%;
  border: 1px solid rgba(255, 225, 141, 0.84);
  border-radius: 50%;
  box-shadow: 0 0 10px var(--gold), inset 0 0 12px var(--gold);
  animation: rune-spin 8s linear infinite;
}

.move-marker {
  position: absolute;
  z-index: 7;
  display: grid;
  width: 26%;
  aspect-ratio: 1;
  place-items: center;
  border: 1px solid rgba(255, 228, 155, 0.85);
  border-radius: 50%;
  background: rgba(28, 42, 37, 0.55);
  box-shadow: 0 0 0 4px rgba(224, 191, 109, 0.1), 0 0 13px rgba(242, 210, 128, 0.7);
  pointer-events: none;
  animation: marker-pulse 1.35s ease-in-out infinite;
}

.move-marker::before,
.move-marker::after {
  position: absolute;
  width: 45%;
  height: 1px;
  background: var(--gold-bright);
  content: "";
}

.move-marker::after {
  transform: rotate(90deg);
}

.square.is-capture .move-marker {
  width: 72%;
  border: 0;
  border-radius: 0;
  background:
    linear-gradient(var(--gold-bright), var(--gold-bright)) left top / 22% 2px no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) left top / 2px 22% no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) right top / 22% 2px no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) right top / 2px 22% no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) left bottom / 22% 2px no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) left bottom / 2px 22% no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) right bottom / 22% 2px no-repeat,
    linear-gradient(var(--gold-bright), var(--gold-bright)) right bottom / 2px 22% no-repeat;
  box-shadow: none;
}

.square.is-capture .move-marker::before,
.square.is-capture .move-marker::after {
  display: none;
}

.square.is-last-from,
.square.is-last-to {
  box-shadow: inset 0 0 0 2px rgba(113, 210, 194, 0.55), inset 0 0 21px rgba(73, 179, 157, 0.2);
}

.square.is-hint {
  box-shadow: inset 0 0 0 3px rgba(136, 226, 214, 0.9), inset 0 0 26px rgba(95, 217, 200, 0.56);
  animation: hint-glow 900ms ease-in-out infinite alternate;
}

.square.is-check {
  z-index: 6;
  box-shadow: inset 0 0 0 3px #d46b55, inset 0 0 30px rgba(184, 46, 38, 0.78);
  animation: check-warning 1.1s ease-in-out infinite;
}

.board-stage.is-locked .square {
  cursor: wait;
}

.board-stage.is-locked .square:hover {
  filter: none;
}

.flat-view {
  --board-tilt: 0deg;
}

.flat-view .board-stage {
  height: var(--board-size);
}

.flat-view .board-frame {
  top: 0;
}

.command-panel {
  position: relative;
  overflow: hidden;
  padding: clamp(20px, 3vh, 32px) clamp(18px, 2vw, 28px) 20px;
  border: 1px solid rgba(211, 178, 99, 0.31);
  border-radius: 3px;
  background:
    linear-gradient(150deg, rgba(30, 38, 51, 0.78), rgba(6, 9, 16, 0.95)),
    var(--panel);
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.45), inset 0 0 0 4px rgba(0, 0, 0, 0.25), inset 0 0 45px rgba(83, 109, 125, 0.08);
  backdrop-filter: blur(19px) saturate(0.8);
}

.command-panel::before,
.command-panel::after {
  position: absolute;
  width: 38px;
  height: 38px;
  border-color: rgba(216, 182, 103, 0.62);
  pointer-events: none;
  content: "";
}

.command-panel::before {
  top: 7px;
  left: 7px;
  border-top: 1px solid;
  border-left: 1px solid;
}

.command-panel::after {
  right: 7px;
  bottom: 7px;
  border-right: 1px solid;
  border-bottom: 1px solid;
}

.turn-oracle {
  display: grid;
  grid-template-columns: 54px 1fr;
  gap: 15px;
  align-items: center;
}

.turn-oracle__halo {
  position: relative;
  display: grid;
  width: 51px;
  height: 51px;
  place-items: center;
  border: 1px solid rgba(219, 184, 103, 0.38);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(218, 181, 91, 0.18), rgba(19, 24, 33, 0.15) 65%);
  box-shadow: 0 0 18px rgba(217, 178, 86, 0.08);
}

.turn-oracle__halo::before {
  position: absolute;
  inset: -5px;
  border: 1px dotted rgba(218, 184, 103, 0.42);
  border-radius: 50%;
  content: "";
  animation: rune-spin 12s linear infinite;
}

.turn-oracle__piece {
  color: var(--ivory);
  font-family: var(--serif);
  font-size: 28px;
  text-shadow: 0 2px 0 #775c32, 0 0 10px rgba(246, 214, 132, 0.42);
}

.turn-oracle small,
.turn-oracle h1,
.turn-oracle p {
  margin: 0;
}

.turn-oracle small {
  color: var(--gold);
  font-size: 8px;
  letter-spacing: 0.22em;
}

.turn-oracle h1 {
  margin: 3px 0 4px;
  font-family: var(--serif);
  font-size: clamp(18px, 2vw, 24px);
  font-weight: 500;
}

.turn-oracle p {
  color: #9c9c99;
  font-family: var(--serif);
  font-size: 11px;
  font-style: italic;
  line-height: 1.35;
}

.panel-rule {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 9px;
  align-items: center;
  margin: 19px 0 16px;
}

.panel-rule span {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(206, 171, 90, 0.46));
}

.panel-rule span:last-child {
  transform: scaleX(-1);
}

.panel-rule i {
  width: 7px;
  height: 7px;
  border: 1px solid var(--gold-dark);
  transform: rotate(45deg);
}

.section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 9px;
}

.section-heading h2 {
  margin: 0;
  color: #d3c9b3;
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.section-heading > span,
.text-button {
  color: var(--gold);
  font-size: 8px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.text-button {
  padding: 4px;
  border: 0;
  background: none;
  cursor: pointer;
}

.captured-section {
  margin-bottom: 17px;
}

.captured-row {
  display: grid;
  grid-template-columns: 96px 1fr;
  min-height: 25px;
  align-items: center;
  border-top: 1px solid rgba(205, 181, 126, 0.08);
}

.captured-row > span {
  color: #717578;
  font-size: 8px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.captured-list {
  min-width: 0;
  color: var(--ivory);
  font-family: var(--serif);
  font-size: 17px;
  letter-spacing: -0.08em;
  white-space: nowrap;
}

.captured-list--dark {
  color: #72a695;
}

.captured-list em {
  color: #4e5355;
  font-size: 11px;
}

.chronicle {
  margin-bottom: 16px;
}

.move-list {
  min-height: 90px;
  max-height: min(18vh, 145px);
  overflow: auto;
  border-top: 1px solid rgba(208, 176, 101, 0.19);
  border-bottom: 1px solid rgba(208, 176, 101, 0.12);
  scrollbar-color: #66512c transparent;
  scrollbar-width: thin;
}

.chronicle-empty {
  display: flex;
  gap: 8px;
  min-height: 88px;
  align-items: center;
  justify-content: center;
  color: #676b6e;
  font-family: var(--serif);
  font-size: 11px;
  font-style: italic;
}

.chronicle-empty span {
  color: #8d743e;
}

.move-pair {
  display: grid;
  grid-template-columns: 26px 1fr 1fr;
  gap: 4px;
  min-height: 29px;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.045);
  font-family: var(--serif);
  font-size: 11px;
}

.move-pair:last-child {
  border: 0;
}

.move-number {
  color: #63686b;
  font-family: var(--sans);
  font-size: 8px;
}

.move-san {
  color: #beb7a8;
}

.move-san:last-child {
  color: #77a99b;
}

.move-san.is-latest {
  color: var(--gold-bright);
}

.primary-actions {
  display: grid;
  grid-template-columns: 1fr 0.72fr;
  gap: 8px;
}

.action-button {
  min-height: 41px;
  padding: 9px 12px;
  border: 1px solid rgba(201, 172, 104, 0.25);
  border-radius: 2px;
  color: #b5b2a9;
  background: rgba(21, 26, 35, 0.76);
  font-family: var(--serif);
  font-size: 11px;
  cursor: pointer;
  transition: 180ms ease;
}

.action-button:hover:not(:disabled) {
  border-color: var(--gold);
  color: var(--parchment);
  transform: translateY(-1px);
}

.action-button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.action-button--gold {
  border-color: #a9813b;
  color: #16140f;
  background: linear-gradient(145deg, #e0c57f, #9e7938);
  box-shadow: inset 0 1px rgba(255, 244, 205, 0.48), 0 6px 18px rgba(202, 161, 73, 0.12);
}

.action-button--gold:hover:not(:disabled) {
  color: #080808;
  filter: brightness(1.1);
}

.secondary-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 10px 0 14px;
}

.secondary-actions button {
  min-height: 30px;
  border: 0;
  color: #86898a;
  background: transparent;
  font-size: 8px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.secondary-actions button + button {
  border-left: 1px solid rgba(212, 180, 103, 0.15);
}

.secondary-actions button:hover {
  color: var(--gold-bright);
}

.cinematic-toggle {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px solid rgba(212, 180, 103, 0.15);
  cursor: pointer;
}

.cinematic-toggle strong,
.cinematic-toggle small {
  display: block;
}

.cinematic-toggle strong {
  color: #b7b3a7;
  font-family: var(--serif);
  font-size: 10px;
  font-weight: 500;
}

.cinematic-toggle small {
  margin-top: 2px;
  color: #686d70;
  font-size: 8px;
}

.cinematic-toggle input {
  position: absolute;
  opacity: 0;
}

.cinematic-toggle i {
  position: relative;
  width: 34px;
  height: 17px;
  border: 1px solid #47504d;
  border-radius: 999px;
  background: #171d20;
  transition: 180ms ease;
}

.cinematic-toggle i::after {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #727879;
  content: "";
  transition: 180ms var(--ease-out);
}

.cinematic-toggle input:checked + i {
  border-color: #a8853f;
  background: rgba(178, 135, 53, 0.2);
}

.cinematic-toggle input:checked + i::after {
  background: var(--gold-bright);
  box-shadow: 0 0 8px var(--gold);
  transform: translateX(17px);
}

.cinematic-toggle input:focus-visible + i {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

.footer-note {
  position: relative;
  z-index: 5;
  display: flex;
  gap: 10px;
  justify-content: center;
  color: rgba(196, 191, 177, 0.45);
  font-family: var(--serif);
  font-size: 9px;
  font-style: italic;
  letter-spacing: 0.04em;
  text-align: center;
}

.footer-note span {
  color: rgba(212, 180, 103, 0.55);
}

/* Dialogs */
.modal {
  width: min(94vw, 680px);
  max-height: 94dvh;
  padding: 0;
  overflow: visible;
  border: 0;
  color: var(--parchment);
  background: transparent;
}

.modal::backdrop {
  background:
    radial-gradient(circle at 50% 42%, rgba(29, 48, 59, 0.22), rgba(2, 4, 9, 0.88) 68%),
    rgba(2, 3, 7, 0.78);
  backdrop-filter: blur(8px);
}

.modal-card {
  position: relative;
  max-height: 92dvh;
  padding: clamp(24px, 5vw, 45px);
  overflow: auto;
  border: 1px solid rgba(224, 190, 109, 0.57);
  border-radius: 3px;
  background:
    linear-gradient(145deg, rgba(26, 34, 47, 0.97), rgba(6, 9, 16, 0.99)),
    #0b101b;
  box-shadow: 0 32px 100px #000, inset 0 0 0 5px rgba(4, 6, 11, 0.85), inset 0 0 60px rgba(85, 119, 132, 0.08);
  text-align: center;
}

.modal-card::before,
.modal-card::after {
  position: absolute;
  width: 68px;
  height: 68px;
  border-color: rgba(218, 183, 100, 0.55);
  pointer-events: none;
  content: "";
}

.modal-card::before {
  top: 10px;
  left: 10px;
  border-top: 1px solid;
  border-left: 1px solid;
}

.modal-card::after {
  right: 10px;
  bottom: 10px;
  border-right: 1px solid;
  border-bottom: 1px solid;
}

.modal-runes {
  margin-bottom: 16px;
  color: var(--gold);
  font-size: 12px;
  letter-spacing: 0.25em;
}

.eyebrow {
  margin: 0 0 7px;
  color: var(--gold);
  font-size: 9px;
  letter-spacing: 0.3em;
}

.modal-card h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(27px, 5vw, 42px);
  font-weight: 400;
  letter-spacing: 0.015em;
}

.modal-intro,
.promotion-card > p:last-of-type {
  width: min(420px, 100%);
  margin: 9px auto 25px;
  color: #9d9a91;
  font-family: var(--serif);
  font-size: 13px;
  font-style: italic;
  line-height: 1.5;
}

.choice-group {
  padding: 0;
  margin: 0;
  border: 0;
  text-align: left;
}

.choice-group legend {
  width: 100%;
  padding: 0 0 8px;
  color: #7f827f;
  font-size: 8px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.mode-choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.choice-card {
  position: relative;
  display: grid;
  grid-template-columns: 44px 1fr auto;
  gap: 11px;
  min-height: 71px;
  align-items: center;
  padding: 12px 13px;
  border: 1px solid rgba(201, 176, 113, 0.17);
  background: rgba(13, 18, 27, 0.78);
  cursor: pointer;
  transition: 170ms ease;
}

.choice-card:hover,
.choice-card:has(input:checked) {
  border-color: rgba(224, 190, 105, 0.66);
  background: rgba(42, 42, 38, 0.55);
  box-shadow: inset 0 0 24px rgba(206, 169, 79, 0.07);
}

.choice-card input,
.compact-choices input {
  position: absolute;
  opacity: 0;
}

.choice-card__icon {
  display: grid;
  width: 39px;
  height: 43px;
  place-items: center;
  border: 1px solid rgba(214, 179, 94, 0.22);
  color: #a0aa9f;
  background: linear-gradient(145deg, #1b2927, #0b100f);
  font-family: var(--serif);
  font-size: 25px;
  clip-path: polygon(50% 0, 94% 18%, 84% 78%, 50% 100%, 16% 78%, 6% 18%);
}

.choice-card strong,
.choice-card small {
  display: block;
}

.choice-card strong {
  font-family: var(--serif);
  font-size: 13px;
  font-weight: 500;
}

.choice-card small {
  margin-top: 4px;
  color: #6f7474;
  font-size: 8px;
}

.choice-card > i {
  width: 13px;
  height: 13px;
  border: 1px solid #555b5a;
  border-radius: 50%;
}

.choice-card input:checked ~ i {
  border: 3px solid #222117;
  background: var(--gold-bright);
  box-shadow: 0 0 0 1px var(--gold), 0 0 9px rgba(224, 187, 98, 0.58);
}

.choice-card input:focus-visible ~ i {
  outline: 2px solid var(--gold-bright);
  outline-offset: 4px;
}

.setup-options {
  display: grid;
  grid-template-columns: 0.82fr 1.18fr;
  gap: 18px;
  margin-top: 20px;
}

.compact-choices {
  display: flex;
  gap: 4px;
}

.compact-choices label {
  position: relative;
  flex: 1;
  cursor: pointer;
}

.compact-choices span {
  display: grid;
  min-height: 33px;
  padding: 5px;
  place-items: center;
  border: 1px solid rgba(203, 177, 113, 0.14);
  color: #7b7f7d;
  background: rgba(7, 10, 16, 0.55);
  font-size: 8px;
}

.compact-choices input:checked + span {
  border-color: #a98641;
  color: var(--gold-bright);
  background: rgba(158, 121, 55, 0.18);
}

.compact-choices input:focus-visible + span {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.begin-button {
  display: flex;
  width: min(330px, 100%);
  min-height: 49px;
  align-items: center;
  justify-content: space-between;
  margin: 26px auto 0;
  padding: 9px 16px 9px 24px;
  border: 1px solid #c39b4e;
  color: #17130c;
  background: linear-gradient(145deg, #ecd48f, #a47a35);
  box-shadow: inset 0 1px rgba(255, 252, 223, 0.6), 0 10px 30px rgba(204, 158, 67, 0.16);
  font-family: var(--serif);
  font-size: 14px;
  cursor: pointer;
  transition: 180ms ease;
}

.begin-button:hover {
  filter: brightness(1.1);
  transform: translateY(-2px);
}

.begin-button i {
  font-family: var(--sans);
  font-style: normal;
}

.keyboard-note {
  margin: 13px 0 0;
  color: #555b5e;
  font-size: 8px;
  letter-spacing: 0.06em;
}

.modal-close {
  position: absolute;
  z-index: 3;
  top: 17px;
  right: 17px;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(203, 179, 119, 0.23);
  border-radius: 50%;
  color: #a7a398;
  background: rgba(4, 7, 12, 0.5);
  font-size: 21px;
  cursor: pointer;
}

.promotion-modal {
  width: min(92vw, 460px);
}

.promotion-options {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 22px;
}

.promotion-option {
  display: grid;
  min-height: 86px;
  place-items: center;
  border: 1px solid rgba(212, 180, 103, 0.28);
  color: var(--ivory);
  background: rgba(8, 12, 19, 0.76);
  cursor: pointer;
  transition: 180ms ease;
}

.promotion-option:hover {
  border-color: var(--gold);
  background: rgba(82, 66, 34, 0.28);
  transform: translateY(-3px);
}

.promotion-option svg {
  width: 53px;
  height: 62px;
  fill: currentColor;
  stroke: #7b6031;
  filter: drop-shadow(0 3px 1px #6e542c) drop-shadow(0 5px 4px #000);
}

.promotion-option small {
  display: block;
  margin-top: -8px;
  color: #88877f;
  font-size: 8px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.rules-modal {
  width: min(92vw, 620px);
}

.rules-card {
  text-align: left;
}

.rules-card > .eyebrow,
.rules-card > h2 {
  text-align: center;
}

.rules-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 28px;
}

.rules-grid > div {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 10px;
  padding: 13px;
  border: 1px solid rgba(204, 176, 106, 0.14);
  background: rgba(5, 8, 13, 0.38);
}

.rules-grid > div > span {
  color: var(--gold);
  font-family: var(--serif);
  font-size: 17px;
}

.rules-grid p,
.rules-grid strong {
  display: block;
  margin: 0;
}

.rules-grid p {
  color: #858986;
  font-size: 9px;
  line-height: 1.45;
}

.rules-grid strong {
  margin-bottom: 3px;
  color: #c7c0b0;
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 500;
}

.rules-footnote {
  margin: 18px 0 0;
  color: #747875;
  font-family: var(--serif);
  font-size: 10px;
  font-style: italic;
  text-align: center;
}

.toast {
  position: fixed;
  z-index: 1100;
  bottom: 24px;
  left: 50%;
  max-width: calc(100vw - 32px);
  padding: 11px 17px;
  border: 1px solid rgba(219, 184, 103, 0.44);
  color: var(--parchment);
  background: rgba(8, 12, 19, 0.93);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  font-family: var(--serif);
  font-size: 11px;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 15px);
  transition: 260ms var(--ease-out);
}

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

/* Motion */
@keyframes world-breathe {
  from { transform: scale(1.025) translate3d(-0.2%, -0.1%, 0); }
  to { transform: scale(1.055) translate3d(0.35%, 0.25%, 0); }
}

@keyframes mist-drift {
  from { transform: translate3d(-8vw, 2vh, 0) scale(0.85); }
  to { transform: translate3d(45vw, -4vh, 0) scale(1.2); }
}

@keyframes ember-rise {
  0% { opacity: 0; transform: translate3d(0, 0, 0) scale(0.5); }
  12% { opacity: 0.7; }
  80% { opacity: 0.35; }
  100% { opacity: 0; transform: translate3d(var(--drift, 20px), -105vh, 0) scale(1.4); }
}

@keyframes pulse-dot {
  50% { opacity: 0.6; box-shadow: 0 0 17px var(--gold); }
}

@keyframes rune-spin {
  to { transform: rotate(360deg); }
}

@keyframes marker-pulse {
  50% { opacity: 0.65; transform: scale(0.84); }
}

@keyframes hint-glow {
  to { filter: brightness(1.18); }
}

@keyframes check-warning {
  50% { filter: brightness(1.18); box-shadow: inset 0 0 0 3px #eb8d6c, inset 0 0 38px rgba(200, 52, 38, 0.9); }
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(18px) scale(0.97); }
  to { opacity: 1; transform: none; }
}

@keyframes letterbox-in {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes attacker-enter {
  from { transform: translateX(-120vw) rotate(-12deg); }
  to { transform: translateX(0) rotate(0); }
}

@keyframes defender-enter {
  from { transform: translateX(120vw) rotate(12deg); }
  to { transform: translateX(0) rotate(0); }
}

@keyframes attacker-strike {
  0%, 20% { transform: translateX(0) rotate(0); }
  45% { transform: translateX(-7%) rotate(-6deg); }
  67% { transform: translateX(118%) rotate(8deg) scale(1.08); }
  100% { transform: translateX(72%) rotate(1deg); }
}

@keyframes knight-strike {
  0%, 16% { transform: translate(0, 0) rotate(0); }
  48% { transform: translate(54%, -36%) rotate(-9deg) scale(1.07); }
  70% { transform: translate(128%, -3%) rotate(12deg) scale(1.11); }
  100% { transform: translate(76%, 0) rotate(2deg); }
}

@keyframes rook-strike {
  0%, 20% { transform: translateX(0); }
  40% { transform: translateX(-16%) scale(1.06); }
  68% { transform: translateX(135%) scale(1.1); }
  100% { transform: translateX(76%); }
}

@keyframes spell-strike {
  0%, 18% { transform: translateX(0) rotate(0); filter: brightness(1); }
  42% { transform: translateX(12%) rotate(-4deg); filter: brightness(1.7); }
  72% { transform: translateX(46%) rotate(4deg); filter: brightness(1.25); }
  100% { transform: translateX(30%); filter: brightness(1); }
}

@keyframes defender-fall {
  0%, 10% { opacity: 1; transform: translateX(0) rotate(0) scale(1); filter: brightness(1); }
  26% { transform: translateX(7%) rotate(7deg) scale(1.04); filter: brightness(2.6); }
  58% { opacity: 0.78; transform: translate(17%, 5%) rotate(19deg) scale(0.94); filter: brightness(0.8) blur(0); }
  100% { opacity: 0; transform: translate(28%, 48%) rotate(48deg) scale(0.35); filter: brightness(0.2) blur(8px); }
}

@keyframes magic-strike {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(-7deg) scaleX(0); }
  20% { opacity: 1; }
  62% { opacity: 1; transform: translate(-50%, -50%) rotate(-7deg) scaleX(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(-7deg) scaleX(1.2); }
}

@keyframes impact-burst {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0); }
  16% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(12); border-width: 0.5px; }
}

@keyframes particle-fly {
  0% { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--particle-x), var(--particle-y)) scale(0); }
}

@keyframes title-reveal {
  from { opacity: 0; transform: translate(-50%, 14px); letter-spacing: 0.08em; }
  to { opacity: 1; transform: translate(-50%, 0); letter-spacing: normal; }
}

/* Responsive */
@media (max-width: 1100px) {
  :root {
    --board-size: min(86vw, 67vh, 680px);
  }

  .game-layout {
    grid-template-columns: 1fr;
    max-width: 760px;
    gap: 24px;
    padding-top: 17px;
  }

  .command-panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 24px;
  }

  .turn-oracle,
  .panel-rule,
  .cinematic-toggle {
    grid-column: 1 / -1;
  }

  .panel-rule {
    margin: 16px 0;
  }

  .captured-section {
    grid-column: 1;
    grid-row: 3 / span 2;
  }

  .chronicle {
    grid-column: 2;
    grid-row: 3 / span 3;
  }

  .primary-actions,
  .secondary-actions {
    grid-column: 1;
  }

  .cinematic-toggle {
    margin-top: 2px;
  }

  .footer-note {
    margin-top: 12px;
  }
}

@media (max-width: 620px) {
  :root {
    --board-size: min(94vw, 58dvh);
    --board-tilt: 25deg;
  }

  .app-shell {
    padding: 10px 10px max(16px, env(safe-area-inset-bottom));
  }

  .masthead {
    min-height: 55px;
  }

  .brand__sigil {
    width: 34px;
    height: 34px;
  }

  .brand strong {
    font-size: 13px;
  }

  .brand small {
    display: none;
  }

  .icon-button {
    width: 36px;
    height: 36px;
    justify-content: center;
    padding: 0;
  }

  .icon-button__label {
    display: none;
  }

  .game-layout {
    min-height: auto;
    gap: 16px;
    padding-top: 11px;
  }

  .player-rail {
    width: var(--board-size);
  }

  .board-stage {
    height: calc(var(--board-size) * 0.98);
  }

  .board-frame {
    top: -3%;
  }

  .player-rail--hero {
    margin-top: 2px;
  }

  .player-copy strong {
    font-size: 12px;
  }

  .rail-status {
    max-width: 94px;
    justify-content: flex-end;
    font-size: 7px;
    text-align: right;
  }

  .command-panel {
    display: block;
    padding: 21px 17px 17px;
  }

  .captured-section,
  .chronicle {
    margin-bottom: 14px;
  }

  .move-list {
    max-height: 120px;
  }

  .footer-note {
    padding: 0 12px;
    font-size: 8px;
  }

  .mode-choices,
  .setup-options,
  .rules-grid {
    grid-template-columns: 1fr;
  }

  .setup-options {
    gap: 14px;
  }

  .modal-card {
    padding: 30px 18px 24px;
  }

  .modal-card::before,
  .modal-card::after {
    width: 40px;
    height: 40px;
  }

  .mode-choices {
    gap: 7px;
  }

  .choice-card {
    min-height: 61px;
  }

  .keyboard-note {
    display: none;
  }
}

@media (max-height: 700px) and (min-width: 1101px) {
  :root {
    --board-size: min(62vw, 70vh, 650px);
  }

  .game-layout {
    padding-top: 12px;
  }

  .command-panel {
    padding-top: 20px;
  }

  .move-list {
    max-height: 90px;
  }
}

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

/* source: battle.css */
/* Sculpted magical soldiers */
.piece-token,
.promotion-piece {
  --piece-outline: #6d552c;
  --piece-shadow: #a78e63;
  --piece-accent: #bf8d38;
  --piece-metal: #f0d68e;
}

.piece--black {
  --piece-outline: #5a9987;
  --piece-shadow: #0b1513;
  --piece-accent: #3c917c;
  --piece-metal: #9ce9dc;
}

.soldier-icon {
  overflow: visible;
}

.soldier-body {
  fill: currentColor;
  stroke: var(--piece-outline);
  stroke-width: 1.6;
  stroke-linejoin: round;
}

.soldier-shadow {
  fill: var(--piece-shadow);
  stroke: var(--piece-outline);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.soldier-accent {
  fill: var(--piece-accent);
  stroke: var(--piece-outline);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.soldier-rune {
  fill: var(--piece-metal);
  stroke: var(--piece-outline);
  stroke-width: 1;
  filter: drop-shadow(0 0 3px var(--piece-metal));
}

.soldier-weapon,
.soldier-line {
  fill: none;
  stroke: var(--piece-metal);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.soldier-line {
  stroke: var(--piece-outline);
  stroke-width: 1.4;
}

.piece-role--p .piece-icon { width: 84%; }
.piece-role--r .piece-icon { width: 95%; }
.piece-role--n .piece-icon { width: 98%; }
.piece-role--b .piece-icon { width: 90%; }
.piece-role--q .piece-icon,
.piece-role--k .piece-icon { width: 96%; }

.square:hover .soldier-accent,
.square.is-selected .soldier-accent {
  filter: brightness(1.2) drop-shadow(0 0 4px var(--piece-metal));
}

/* Combat now occurs directly on the board. */
.board-battle-layer {
  position: absolute;
  z-index: 60;
  inset: 0;
  overflow: visible;
  pointer-events: none;
  transform-style: preserve-3d;
}

.is-board-battling .square {
  pointer-events: none;
  transition: filter 220ms ease, box-shadow 220ms ease;
}

.is-board-battling .square:not(.is-battle-source):not(.is-battle-target) {
  filter: brightness(0.64) saturate(0.75);
}

.is-battle-source > .piece-token {
  opacity: 0;
}

.is-battle-target {
  z-index: 45;
  box-shadow:
    inset 0 0 0 2px rgba(248, 216, 137, 0.82),
    inset 0 0 28px rgba(86, 226, 206, 0.45),
    0 0 18px rgba(106, 232, 214, 0.55);
}

.board-battle-attacker {
  position: absolute;
  z-index: 64;
  transform: translate3d(0, 0, 24px);
  transform-style: preserve-3d;
  will-change: transform;
}

.board-battle-attacker .piece-token {
  width: 88%;
  height: 104%;
  filter: brightness(1.13) drop-shadow(0 0 7px var(--piece-metal));
}

.is-battle-playing .board-battle-attacker {
  animation: board-soldier-assault 1.7s cubic-bezier(0.45, 0, 0.25, 1) both;
}

.is-battle-playing .battle-piece-n .board-battle-attacker {
  animation-name: board-knight-assault;
}

.is-battle-playing .battle-piece-b .board-battle-attacker,
.is-battle-playing .battle-piece-q .board-battle-attacker {
  animation-name: board-mage-assault;
}

.is-battle-playing .battle-piece-r .board-battle-attacker {
  animation-name: board-guardian-assault;
}

.is-battle-playing .is-battle-target > .piece-token {
  z-index: 62;
  animation: board-defender-defeat 1.7s cubic-bezier(0.45, 0, 0.5, 1) both;
}

.board-battle-trail {
  position: absolute;
  z-index: 61;
  height: 3px;
  opacity: 0;
  transform: rotate(var(--trail-angle)) scaleX(0);
  transform-origin: left center;
}

.board-battle-trail::before,
.board-battle-trail::after,
.board-battle-trail i {
  position: absolute;
  right: 0;
  left: 0;
  height: 2px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--gold-bright), #fff 62%, var(--cyan));
  box-shadow: 0 0 5px #fff, 0 0 13px var(--gold), 0 0 22px var(--cyan);
  content: "";
}

.board-battle-trail::after {
  transform: rotate(7deg) translateY(4px);
}

.board-battle-trail i:first-child {
  transform: rotate(-6deg) translateY(-4px);
}

.board-battle-trail i:last-child {
  display: none;
}

.is-battle-playing .board-battle-trail {
  animation: board-trail-strike 1.7s ease-out both;
}

.board-battle-impact,
.board-battle-shards {
  position: absolute;
  z-index: 70;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.board-battle-impact i,
.board-battle-impact b {
  position: absolute;
  top: 0;
  left: 0;
  width: 18px;
  height: 18px;
  border: 2px solid #fff4c4;
  border-radius: 50%;
  opacity: 0;
  box-shadow: 0 0 10px #fff, 0 0 24px var(--gold), 0 0 42px var(--cyan);
  transform: translate(-50%, -50%) scale(0);
}

.board-battle-impact i:nth-child(2) {
  width: 28px;
  height: 28px;
  border-color: var(--cyan);
}

.board-battle-impact b {
  width: 4px;
  height: 54px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(transparent, #fff, var(--gold-bright), transparent);
  box-shadow: 0 0 8px #fff, 0 0 18px var(--gold);
  transform: translate(-50%, -50%) rotate(42deg) scaleY(0);
}

.is-battle-playing .board-battle-impact i:first-child {
  animation: board-impact-ring 1.7s ease-out both;
}

.is-battle-playing .board-battle-impact i:nth-child(2) {
  animation: board-impact-ring 1.7s ease-out 70ms both;
}

.is-battle-playing .board-battle-impact b {
  animation: board-impact-slash 1.7s ease-out both;
}

.board-battle-shards i {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  opacity: 0;
  background: var(--shard-color);
  box-shadow: 0 0 7px var(--shard-color);
}

.is-battle-playing .board-battle-shards i {
  animation: board-shard-flight 760ms ease-out var(--shard-delay) both;
}

.board-battle-hud {
  position: absolute;
  z-index: 80;
  top: 1%;
  left: 50%;
  display: flex;
  width: max-content;
  max-width: 92%;
  min-height: 37px;
  gap: 12px;
  align-items: center;
  padding: 6px 7px 6px 13px;
  border: 1px solid rgba(231, 198, 118, 0.62);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.91);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.55), inset 0 0 18px rgba(87, 210, 193, 0.09);
  backdrop-filter: blur(10px);
  transform: translateX(-50%);
  animation: battle-hud-in 240ms var(--ease-out) both;
}

.board-battle-hud > span {
  min-width: 0;
}

.board-battle-hud small,
.board-battle-hud strong {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.board-battle-hud small {
  color: var(--gold);
  font-size: 6px;
  letter-spacing: 0.2em;
}

.board-battle-hud strong {
  margin-top: 2px;
  font-family: var(--serif);
  font-size: 10px;
  font-weight: 500;
}

.board-battle-skip {
  min-height: 25px;
  padding: 4px 7px;
  border: 1px solid rgba(221, 193, 126, 0.3);
  color: #c8c1b0;
  background: rgba(22, 28, 35, 0.85);
  font-size: 7px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.board-battle-skip span {
  margin-left: 4px;
  color: #777b78;
  font-size: 6px;
}

@keyframes board-soldier-assault {
  0%, 18% { transform: translate3d(0, 0, 24px) scale(1); }
  42% { transform: translate3d(var(--impact-70-x), var(--impact-70-y), 30px) scale(1.07); }
  55% { transform: translate3d(var(--impact-92-x), var(--impact-92-y), 34px) rotate(-5deg) scale(1.12); }
  65% { transform: translate3d(var(--impact-x), var(--impact-y), 40px) rotate(7deg) scale(1.2); }
  74% { transform: translate3d(var(--recoil-x), var(--recoil-y), 28px) rotate(-3deg) scale(1.02); }
  100% { transform: translate3d(var(--end-x), var(--end-y), 24px) scale(1); }
}

@keyframes board-knight-assault {
  0%, 17% { transform: translate3d(0, 0, 24px) rotate(0); }
  43% { transform: translate3d(var(--mid-x), var(--mid-y), 68px) rotate(-7deg) scale(1.08); }
  64% { transform: translate3d(var(--impact-x), var(--impact-y), 42px) rotate(10deg) scale(1.2); }
  75% { transform: translate3d(var(--recoil-x), var(--recoil-y), 30px) rotate(-4deg); }
  100% { transform: translate3d(var(--end-x), var(--end-y), 24px) rotate(0); }
}

@keyframes board-mage-assault {
  0%, 22% { transform: translate3d(0, 0, 24px); filter: brightness(1); }
  43% { transform: translate3d(var(--impact-70-x), var(--impact-70-y), 42px) scale(1.1); filter: brightness(1.65); }
  64% { transform: translate3d(var(--impact-70-x), var(--impact-70-y), 42px) scale(1.14); filter: brightness(2); }
  79% { transform: translate3d(var(--recoil-x), var(--recoil-y), 30px); filter: brightness(1.15); }
  100% { transform: translate3d(var(--end-x), var(--end-y), 24px); filter: brightness(1); }
}

@keyframes board-guardian-assault {
  0%, 22% { transform: translate3d(0, 0, 24px) scale(1); }
  40% { transform: translate3d(var(--windup-x), var(--windup-y), 22px) scale(1.08); }
  64% { transform: translate3d(var(--impact-x), var(--impact-y), 36px) scale(1.23); }
  76% { transform: translate3d(var(--recoil-x), var(--recoil-y), 26px) scale(1.04); }
  100% { transform: translate3d(var(--end-x), var(--end-y), 24px) scale(1); }
}

@keyframes board-defender-defeat {
  0%, 34% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); filter: brightness(1); }
  48% { transform: rotateX(calc(-1 * var(--board-tilt))) translate(-4%, -11%) translateZ(17px) rotate(-4deg); filter: brightness(1.4); }
  57% { transform: rotateX(calc(-1 * var(--board-tilt))) translate(6%, -9%) translateZ(19px) rotate(5deg); filter: brightness(2.4); }
  70% { opacity: 0.9; transform: rotateX(calc(-1 * var(--board-tilt))) translate(12%, 4%) translateZ(9px) rotate(17deg) scale(0.9); filter: brightness(0.8); }
  100% { opacity: 0; transform: rotateX(calc(-1 * var(--board-tilt))) translate(24%, 42%) translateZ(0) rotate(38deg) scale(0.22); filter: brightness(0.25) blur(3px); }
}

@keyframes board-trail-strike {
  0%, 35% { opacity: 0; transform: rotate(var(--trail-angle)) scaleX(0); }
  47% { opacity: 1; transform: rotate(var(--trail-angle)) scaleX(0.65); }
  60% { opacity: 1; transform: rotate(var(--trail-angle)) scaleX(1); }
  72%, 100% { opacity: 0; transform: rotate(var(--trail-angle)) scaleX(1.06); }
}

@keyframes board-impact-ring {
  0%, 51% { opacity: 0; transform: translate(-50%, -50%) scale(0); }
  58% { opacity: 1; }
  78%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(4.3); border-width: 0.5px; }
}

@keyframes board-impact-slash {
  0%, 49% { opacity: 0; transform: translate(-50%, -50%) rotate(42deg) scaleY(0); }
  57% { opacity: 1; transform: translate(-50%, -50%) rotate(42deg) scaleY(1); }
  73%, 100% { opacity: 0; transform: translate(-50%, -50%) rotate(42deg) scaleY(1.25); }
}

@keyframes board-shard-flight {
  from { opacity: 1; transform: translate(0, 0) scale(1); }
  to { opacity: 0; transform: translate(var(--shard-x), var(--shard-y)) scale(0); }
}

@keyframes battle-hud-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

@media (max-width: 620px) {
  .board-battle-hud {
    top: 2%;
    gap: 7px;
    max-width: 96%;
    padding-left: 9px;
  }

  .board-battle-hud strong {
    max-width: 210px;
    font-size: 9px;
  }

  .board-battle-skip span {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .board-battle-layer,
  .board-battle-hud {
    display: none !important;
  }
}

/* source: motion.css */
/* Larger board with dedicated, non-overlapping player-label space. */
:root {
  --board-size: min(70vw, 78vh, 840px);
}

.game-layout {
  max-width: 1380px;
  gap: clamp(30px, 3.4vw, 56px);
}

.board-stage {
  width: min(var(--board-size), 100%);
  height: auto;
  aspect-ratio: 1 / 1;
}

.board-frame {
  top: 0;
}

.flat-view .board-stage {
  width: min(var(--board-size), 100%);
  height: auto;
  aspect-ratio: 1;
}

.player-rail {
  min-height: 50px;
  padding: 7px 11px;
  border: 1px solid rgba(214, 181, 103, 0.16);
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(7, 11, 18, 0.88), rgba(11, 16, 24, 0.52), rgba(7, 11, 18, 0.82));
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  backdrop-filter: blur(8px);
}

.player-rail--rival {
  margin-bottom: 14px;
}

.player-rail--hero {
  margin-top: 14px;
}

/* Layered metal, stone, cloth, and enchanted details. */
.piece-token,
.promotion-piece {
  --piece-highlight: #fff8df;
  --piece-mid: #d0bf98;
  --piece-deep: #705a37;
  --piece-accent-bright: #f2d788;
  --piece-accent-deep: #745321;
  --piece-metal-deep: #83672f;
  --piece-gem: #ffe5a0;
  --piece-gem-deep: #aa681f;
}

.piece--black {
  --piece-highlight: #668f83;
  --piece-mid: #233c36;
  --piece-deep: #050c0b;
  --piece-accent-bright: #8ce1cc;
  --piece-accent-deep: #123d35;
  --piece-metal-deep: #1c5c50;
  --piece-gem: #92fff0;
  --piece-gem-deep: #087366;
}

.detailed-soldier .soldier-body { fill: var(--armor-fill); }
.detailed-soldier .soldier-shadow { fill: var(--shadow-fill); }
.detailed-soldier .soldier-accent { fill: var(--accent-fill); }
.detailed-soldier .soldier-weapon { stroke: var(--metal-stroke); }
.detailed-soldier .soldier-rune { fill: var(--gem-fill); }

.soldier-etch,
.soldier-cape-edge {
  fill: none;
  stroke: var(--piece-outline);
  stroke-width: 1.25;
  stroke-linecap: round;
  opacity: 0.78;
}

.soldier-cape-edge {
  stroke: var(--piece-highlight);
  opacity: 0.42;
}

.soldier-glint {
  fill: none;
  stroke: #fffbea;
  stroke-width: 1.35;
  stroke-linecap: round;
  opacity: 0.72;
}

.soldier-gem {
  fill: var(--gem-fill);
  stroke: var(--piece-outline);
  stroke-width: 0.9;
  filter: drop-shadow(0 0 3px var(--piece-gem));
}

.soldier-rivet {
  fill: var(--piece-metal);
  stroke: var(--piece-outline);
  stroke-width: 0.65;
}

.detailed-soldier {
  transform-origin: 50% 100%;
}

.piece-token::after {
  position: absolute;
  z-index: -1;
  bottom: 7%;
  left: 50%;
  width: 56%;
  height: 24%;
  border-radius: 50%;
  opacity: 0.24;
  background: radial-gradient(ellipse, var(--piece-gem), transparent 68%);
  filter: blur(5px);
  content: "";
  transform: translateX(-50%);
}

/* Piece-to-piece square travel. */
.board-move-layer {
  position: absolute;
  z-index: 58;
  inset: 0;
  overflow: visible;
  pointer-events: none;
  transform-style: preserve-3d;
}

.is-piece-moving .square {
  pointer-events: none;
}

.is-piece-moving .square:not(.is-move-source):not(.is-move-target) {
  filter: brightness(0.82) saturate(0.88);
}

.is-move-source > .piece-token {
  opacity: 0;
}

.is-move-target {
  z-index: 42;
  box-shadow: inset 0 0 0 2px rgba(243, 211, 131, 0.56), inset 0 0 24px rgba(83, 207, 190, 0.25);
}

.board-move-actor {
  position: absolute;
  z-index: 62;
  transform: translate3d(0, 0, 22px);
  transform-style: preserve-3d;
  will-change: transform, filter, opacity;
}

.board-move-actor .piece-token {
  width: 90%;
  height: 106%;
  filter: brightness(1.13) drop-shadow(0 0 7px var(--piece-gem));
}

.is-move-playing .move-role-p { animation: move-pawn var(--move-duration) cubic-bezier(0.45, 0, 0.2, 1) both; }
.is-move-playing .move-role-n { animation: move-knight var(--move-duration) cubic-bezier(0.35, 0, 0.18, 1) both; }
.is-move-playing .move-role-b { animation: move-bishop var(--move-duration) cubic-bezier(0.4, 0, 0.2, 1) both; }
.is-move-playing .move-role-r { animation: move-rook var(--move-duration) cubic-bezier(0.54, 0, 0.16, 1) both; }
.is-move-playing .move-role-q { animation: move-queen var(--move-duration) cubic-bezier(0.35, 0, 0.2, 1) both; }
.is-move-playing .move-role-k { animation: move-king var(--move-duration) cubic-bezier(0.42, 0, 0.22, 1) both; }
.is-move-playing .castle-rook-actor { animation-name: move-rook; animation-delay: 90ms; }

.board-move-path {
  position: absolute;
  z-index: 54;
  height: 2px;
  opacity: 0;
  transform: rotate(var(--move-angle)) scaleX(0);
  transform-origin: left center;
}

.board-move-path::before,
.board-move-path i {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, var(--gold-bright), #fff, var(--cyan), transparent);
  box-shadow: 0 0 5px #fff, 0 0 12px var(--gold), 0 0 20px var(--cyan);
  content: "";
}

.board-move-path i {
  transform: rotate(5deg) translateY(3px);
}

.is-move-playing .board-move-path {
  animation: move-path var(--move-duration) ease-out both;
}

.moving-piece-p .board-move-path,
.moving-piece-r .board-move-path,
.moving-piece-k .board-move-path {
  height: 1px;
  filter: sepia(0.65);
  opacity: 0;
}

.moving-piece-n .board-move-path {
  border-top: 1px dashed rgba(241, 211, 139, 0.72);
  background: none;
  box-shadow: none;
}

.board-move-landing {
  position: absolute;
  z-index: 64;
  width: 1px;
  height: 1px;
}

.board-move-landing > b {
  position: absolute;
  width: 18px;
  height: 18px;
  border: 1px solid var(--gold-bright);
  border-radius: 50%;
  opacity: 0;
  box-shadow: 0 0 12px var(--gold), inset 0 0 9px var(--cyan);
  transform: translate(-50%, -50%) scale(0);
}

.board-move-landing span i {
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  opacity: 0;
  background: var(--piece-gem, var(--gold-bright));
  box-shadow: 0 0 5px var(--gold-bright);
}

.is-move-playing .board-move-landing > b {
  animation: move-land-ring var(--move-duration) ease-out both;
}

.is-move-playing .board-move-landing span i {
  animation: move-land-spark var(--move-spark-duration) ease-out var(--move-spark-delay) both;
}

.is-move-playing .is-quick-capture-target > .piece-token {
  animation: quick-capture-fade var(--move-duration) ease-in both;
}

@keyframes move-pawn {
  0%, 12% { transform: translate3d(0, 0, 22px); }
  29% { transform: translate3d(var(--move-25-x), calc(var(--move-25-y) - 6px), 31px) rotate(-2deg); }
  42% { transform: translate3d(var(--move-42-x), var(--move-42-y), 24px) rotate(2deg); }
  66% { transform: translate3d(var(--move-72-x), calc(var(--move-72-y) - 5px), 30px) rotate(-2deg); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 22px); }
}

@keyframes move-knight {
  0%, 10% { transform: translate3d(0, 0, 22px) rotate(0) scale(1); }
  48% { transform: translate3d(var(--move-mid-x), var(--move-mid-y), 74px) rotate(-8deg) scale(1.14); }
  76% { transform: translate3d(var(--move-88-x), calc(var(--move-88-y) - 5px), 38px) rotate(6deg) scale(1.06); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 22px) rotate(0) scale(1); }
}

@keyframes move-bishop {
  0%, 12% { opacity: 1; transform: translate3d(0, 0, 22px); filter: brightness(1); }
  38% { opacity: 0.45; transform: translate3d(var(--move-42-x), var(--move-42-y), 42px) scale(0.86); filter: brightness(2) blur(1px); }
  68% { opacity: 0.5; transform: translate3d(var(--move-72-x), var(--move-72-y), 42px) scale(0.9); filter: brightness(2.2) blur(1px); }
  100% { opacity: 1; transform: translate3d(var(--move-x), var(--move-y), 22px) scale(1); filter: brightness(1); }
}

@keyframes move-rook {
  0%, 14% { transform: translate3d(0, 0, 22px); }
  28% { transform: translate3d(var(--move-windup-x), var(--move-windup-y), 20px) scale(1.08); }
  74% { transform: translate3d(var(--move-88-x), var(--move-88-y), 30px) scale(1.12); }
  91% { transform: translate3d(var(--move-x), var(--move-y), 24px) scale(1.08); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 22px) scale(1); }
}

@keyframes move-queen {
  0%, 10% { transform: translate3d(0, 0, 24px) scale(1); filter: brightness(1); }
  48% { transform: translate3d(var(--move-arc-x), var(--move-arc-y), 58px) scale(1.1) rotate(-3deg); filter: brightness(1.85); }
  82% { transform: translate3d(var(--move-88-x), var(--move-88-y), 36px) scale(1.06) rotate(2deg); filter: brightness(1.35); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 24px) scale(1); filter: brightness(1); }
}

@keyframes move-king {
  0%, 13% { transform: translate3d(0, 0, 24px); }
  35% { transform: translate3d(var(--move-25-x), calc(var(--move-25-y) - 4px), 31px) rotate(-1deg); }
  61% { transform: translate3d(var(--move-58-x), var(--move-58-y), 26px) rotate(1deg); }
  83% { transform: translate3d(var(--move-88-x), calc(var(--move-88-y) - 3px), 30px); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 24px); }
}

@keyframes move-path {
  0%, 16% { opacity: 0; transform: rotate(var(--move-angle)) scaleX(0); }
  42% { opacity: 0.85; }
  78% { opacity: 0.48; transform: rotate(var(--move-angle)) scaleX(1); }
  100% { opacity: 0; transform: rotate(var(--move-angle)) scaleX(1.04); }
}

@keyframes move-land-ring {
  0%, 72% { opacity: 0; transform: translate(-50%, -50%) scale(0); }
  82% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(2.6); }
}

@keyframes move-land-spark {
  from { opacity: 1; transform: translate(0, 0); }
  to { opacity: 0; transform: translate(var(--move-spark-x), var(--move-spark-y)); }
}

@keyframes quick-capture-fade {
  0%, 72% { opacity: 1; filter: brightness(1); }
  86% { opacity: 0.5; filter: brightness(2); }
  100% { opacity: 0; filter: brightness(0.4); }
}

@media (max-width: 1100px) {
  :root {
    --board-size: min(92vw, 78vh, 760px);
  }

  .player-rail--rival { margin-bottom: 11px; }
  .player-rail--hero { margin-top: 11px; }
}

@media (max-width: 620px) {
  :root {
    --board-size: min(96vw, 61dvh);
  }

  .board-stage {
    width: min(var(--board-size), 100%);
    height: auto;
    aspect-ratio: 1 / 1;
  }

  .player-rail {
    width: min(var(--board-size), 100%);
    min-height: 46px;
    padding: 6px 8px;
  }

  .player-rail--rival { margin-bottom: 8px; }
  .player-rail--hero { margin-top: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .board-move-layer {
    display: none !important;
  }
}

/* source: articulated.css */
/* Articulated miniature soldiers: readable materials and independently moving anatomy. */
.soldier-icon[data-renderer="articulated"] {
  shape-rendering: geometricPrecision;
  paint-order: stroke fill markers;
}

.soldier-icon[data-renderer="articulated"] .soldier-body {
  fill: var(--armor-fill);
  stroke: var(--piece-outline);
  stroke-width: 1.45;
}

.soldier-icon[data-renderer="articulated"] .soldier-shadow {
  fill: var(--shadow-fill);
  stroke: var(--piece-outline);
  stroke-width: 1.15;
}

.soldier-icon[data-renderer="articulated"] .soldier-accent {
  fill: var(--accent-fill);
  stroke: var(--piece-outline);
  stroke-width: 1.15;
}

.soldier-icon[data-renderer="articulated"] .soldier-ground-shadow {
  fill: rgba(0, 0, 0, 0.5);
  stroke: none;
  filter: blur(1.4px);
}

.soldier-weapon-filled {
  stroke: var(--piece-outline);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="articulated"] .soldier-line {
  stroke-width: 1.2;
}

.soldier-icon[data-renderer="articulated"] .soldier-gem,
.soldier-icon[data-renderer="articulated"] .soldier-rune {
  fill: var(--gem-fill);
}

.articulated-soldier,
.articulated-soldier .soldier-head,
.articulated-soldier .soldier-torso,
.articulated-soldier .soldier-cape,
.articulated-soldier .soldier-arm,
.articulated-soldier .soldier-leg,
.articulated-soldier .soldier-weapon-rig,
.articulated-soldier .soldier-shield,
.articulated-soldier .soldier-casting-hand {
  transform-box: fill-box;
}

.articulated-soldier { transform-origin: 50% 100%; }
.articulated-soldier .soldier-head { transform-origin: 50% 90%; }
.articulated-soldier .soldier-torso { transform-origin: 50% 84%; }
.articulated-soldier .soldier-cape { transform-origin: 50% 20%; }
.articulated-soldier .soldier-arm--shield { transform-origin: 84% 18%; }
.articulated-soldier .soldier-arm--weapon { transform-origin: 16% 18%; }
.articulated-soldier .soldier-leg { transform-origin: 50% 8%; }
.articulated-soldier .soldier-weapon-rig { transform-origin: 50% 72%; }
.articulated-soldier .soldier-shield { transform-origin: 76% 46%; }
.articulated-soldier .soldier-casting-hand { transform-origin: 60% 60%; }

.square:not(.is-selected):not(.is-battle-target) .articulated-soldier .soldier-cape {
  animation: soldier-cape-idle 4.6s ease-in-out infinite alternate;
}

.square:nth-child(3n) .articulated-soldier .soldier-cape { animation-delay: -1.7s; }
.square:nth-child(4n) .articulated-soldier .soldier-cape { animation-delay: -3.1s; }

.square .articulated-soldier .soldier-gem,
.square .articulated-soldier .soldier-rune {
  animation: soldier-gem-idle 3.2s ease-in-out infinite;
}

.square:hover .articulated-soldier .soldier-head,
.square.is-selected .articulated-soldier .soldier-head {
  transform: translateY(-1.5px) rotate(-2deg);
}

.square:hover .articulated-soldier .soldier-arm--weapon,
.square.is-selected .articulated-soldier .soldier-arm--weapon {
  transform: rotate(-4deg);
}

/* Limbs keep moving while the full figure travels between squares. */
.is-move-playing .board-move-actor .soldier-cape {
  animation: moving-cape var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-p .soldier-leg--shield,
.is-move-playing .move-role-k .soldier-leg--shield {
  animation: soldier-step-left var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-p .soldier-leg--weapon,
.is-move-playing .move-role-k .soldier-leg--weapon {
  animation: soldier-step-right var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-p .soldier-spear {
  animation: spear-brace var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-n .soldier-torso {
  animation: knight-body-leap var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-n .soldier-lance {
  animation: lance-couch var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-b .soldier-casting-arm,
.is-move-playing .move-role-q .soldier-casting-arm {
  animation: casting-hand-rise var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-b .soldier-staff {
  animation: staff-channel var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-r .soldier-arm--shield {
  animation: shield-charge var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-r .soldier-arm--weapon {
  animation: hammer-march var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-q .soldier-winged-cape {
  animation: queen-cape-flight var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-q .soldier-rapier {
  animation: rapier-salute var(--move-duration) ease-in-out both;
}

.is-move-playing .move-role-k .soldier-greatsword {
  animation: sword-march var(--move-duration) ease-in-out both;
}

/* Capture choreography moves the weapon, shield and body independently. */
.is-battle-playing .board-battle-attacker .soldier-torso {
  animation: attack-body 1.7s cubic-bezier(0.45, 0, 0.22, 1) both;
}

.is-battle-playing .battle-piece-p .soldier-spear {
  animation: attack-spear 1.7s cubic-bezier(0.35, 0, 0.2, 1) both;
}

.is-battle-playing .battle-piece-n .soldier-lance {
  animation: attack-lance 1.7s cubic-bezier(0.35, 0, 0.2, 1) both;
}

.is-battle-playing .battle-piece-r .soldier-arm--weapon {
  animation: attack-hammer 1.7s cubic-bezier(0.5, 0, 0.15, 1) both;
}

.is-battle-playing .battle-piece-r .soldier-shield {
  animation: attack-shield 1.7s ease-in-out both;
}

.is-battle-playing .battle-piece-b .soldier-staff,
.is-battle-playing .battle-piece-q .soldier-casting-arm {
  animation: attack-spell 1.7s ease-in-out both;
}

.is-battle-playing .battle-piece-q .soldier-rapier {
  animation: attack-rapier 1.7s cubic-bezier(0.45, 0, 0.15, 1) both;
}

.is-battle-playing .battle-piece-k .soldier-greatsword {
  animation: attack-greatsword 1.7s cubic-bezier(0.48, 0, 0.12, 1) both;
}

.is-battle-playing .is-battle-target .soldier-head {
  animation: defender-head-recoil 1.7s ease-out both;
}

.is-battle-playing .is-battle-target .soldier-arm--shield {
  animation: defender-block 1.7s cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes soldier-cape-idle {
  from { transform: skewX(-0.7deg) scaleX(0.99); }
  to { transform: skewX(1.2deg) scaleX(1.015); }
}

@keyframes soldier-gem-idle {
  0%, 100% { opacity: 0.82; }
  48% { opacity: 1; }
  52% { opacity: 0.9; }
}

@keyframes moving-cape {
  0%, 100% { transform: skewX(0) scaleX(1); }
  38% { transform: skewX(-7deg) scaleX(1.08); }
  72% { transform: skewX(5deg) scaleX(0.96); }
}

@keyframes soldier-step-left {
  0%, 100% { transform: rotate(0); }
  30% { transform: rotate(8deg) translateY(-1px); }
  64% { transform: rotate(-7deg); }
}

@keyframes soldier-step-right {
  0%, 100% { transform: rotate(0); }
  30% { transform: rotate(-8deg); }
  64% { transform: rotate(7deg) translateY(-1px); }
}

@keyframes spear-brace {
  0%, 100% { transform: rotate(0); }
  32%, 78% { transform: rotate(-7deg) translateY(-2px); }
}

@keyframes knight-body-leap {
  0%, 100% { transform: rotate(-5deg); }
  42% { transform: rotate(-13deg) skewX(-2deg); }
  75% { transform: rotate(2deg); }
}

@keyframes lance-couch {
  0%, 100% { transform: rotate(-36deg); }
  38%, 72% { transform: rotate(-51deg) translate(2px, 1px); }
}

@keyframes casting-hand-rise {
  0%, 100% { transform: rotate(0); }
  38%, 72% { transform: rotate(-16deg) translateY(-3px); }
}

@keyframes staff-channel {
  0%, 100% { transform: rotate(0); filter: brightness(1); }
  48%, 72% { transform: rotate(7deg); filter: brightness(1.7); }
}

@keyframes shield-charge {
  0%, 100% { transform: rotate(0); }
  28%, 76% { transform: rotate(8deg) translateX(2px); }
}

@keyframes hammer-march {
  0%, 100% { transform: rotate(0); }
  28% { transform: rotate(-12deg); }
  72% { transform: rotate(8deg); }
}

@keyframes queen-cape-flight {
  0%, 100% { transform: scaleX(1); }
  46% { transform: scaleX(1.12) translateY(-2px); }
}

@keyframes rapier-salute {
  0%, 100% { transform: rotate(0); }
  42% { transform: rotate(-13deg) translateY(-2px); }
}

@keyframes sword-march {
  0%, 100% { transform: rotate(0); }
  38%, 72% { transform: rotate(5deg) translateY(-2px); }
}

@keyframes attack-body {
  0%, 28%, 100% { transform: rotate(0) skewX(0); }
  42% { transform: rotate(-5deg) skewX(-3deg); }
  62% { transform: rotate(7deg) skewX(4deg); }
  74% { transform: rotate(-2deg); }
}

@keyframes attack-spear {
  0%, 30%, 100% { transform: rotate(0) translate(0); }
  43% { transform: rotate(10deg) translate(-3px, 2px); }
  61% { transform: rotate(-17deg) translate(9px, -4px); }
  72% { transform: rotate(-7deg) translate(2px, -1px); }
}

@keyframes attack-lance {
  0%, 28%, 100% { transform: rotate(-36deg); }
  45% { transform: rotate(-52deg) translateY(3px); }
  63% { transform: rotate(-59deg) translate(8px, -2px); }
  75% { transform: rotate(-42deg); }
}

@keyframes attack-hammer {
  0%, 28%, 100% { transform: rotate(0); }
  44% { transform: rotate(-44deg) translate(-3px, -3px); }
  62% { transform: rotate(34deg) translate(5px, 3px); }
  73% { transform: rotate(9deg); }
}

@keyframes attack-shield {
  0%, 100% { transform: rotate(0); }
  38%, 70% { transform: rotate(8deg) translateX(3px); }
}

@keyframes attack-spell {
  0%, 30%, 100% { transform: rotate(0); filter: brightness(1); }
  48% { transform: rotate(-17deg) translateY(-4px); filter: brightness(1.5); }
  64% { transform: rotate(14deg) translate(3px, -2px); filter: brightness(2.25); }
  76% { transform: rotate(3deg); filter: brightness(1.2); }
}

@keyframes attack-rapier {
  0%, 31%, 100% { transform: rotate(0); }
  45% { transform: rotate(-28deg) translate(-2px, -2px); }
  62% { transform: rotate(25deg) translate(7px, -2px); }
}

@keyframes attack-greatsword {
  0%, 28%, 100% { transform: rotate(0); }
  43% { transform: rotate(-24deg) translate(-7px, -3px); }
  63% { transform: rotate(31deg) translate(8px, 3px); }
  74% { transform: rotate(6deg); }
}

@keyframes defender-head-recoil {
  0%, 42%, 100% { transform: rotate(0) translate(0); }
  56% { transform: rotate(-8deg) translate(-2px, -2px); }
  65% { transform: rotate(12deg) translate(3px, 1px); }
}

@keyframes defender-block {
  0%, 38%, 100% { transform: rotate(0); }
  49% { transform: rotate(-18deg) translate(2px, -2px); }
  63% { transform: rotate(15deg) translate(-2px, 2px); }
}

@media (prefers-reduced-motion: reduce) {
  .articulated-soldier *,
  .square .articulated-soldier * {
    animation: none !important;
  }
}

/* source: readable-pieces.css */
/* High-readability soldier silhouettes for 45–75px board rendering. */
.piece-token,
.promotion-piece {
  --readable-edge: #443a2d;
  --readable-highlight: #fffdf2;
  --readable-mid: #d2c9b3;
  --readable-deep: #675b49;
  --readable-accent-hi: #ecdfbd;
  --readable-accent: #8b7852;
  --readable-metal-hi: #fff5d5;
  --readable-metal: #c4b184;
  --readable-metal-deep: #716141;
  --readable-gem-hi: #fff7d9;
  --readable-gem: #aa8e55;
  --readable-polish-edge: #ffffff;
  --readable-polish: #fff8df;
}

.piece--black {
  --readable-edge: #73938f;
  --readable-highlight: #566d69;
  --readable-mid: #202e2d;
  --readable-deep: #050a0b;
  --readable-accent-hi: #8ba9a5;
  --readable-accent: #365a56;
  --readable-metal-hi: #c2d5d1;
  --readable-metal: #708f8b;
  --readable-metal-deep: #1c3332;
  --readable-gem-hi: #d5e9e6;
  --readable-gem: #6caaa2;
  --readable-polish-edge: #b9d6d1;
  --readable-polish: #668c87;
}

.soldier-icon[data-renderer="readable"] {
  --piece-outline: var(--readable-edge);
  --piece-accent: var(--readable-accent);
  --piece-metal: var(--readable-metal);
  shape-rendering: geometricPrecision;
}

.soldier-icon[data-renderer="readable"] .readable-fill,
.soldier-icon[data-renderer="readable"] .readable-shadow,
.soldier-icon[data-renderer="readable"] .readable-accent,
.soldier-icon[data-renderer="readable"] .readable-metal,
.soldier-icon[data-renderer="readable"] .readable-gem {
  stroke: var(--readable-edge);
  stroke-width: 2.05;
  stroke-linejoin: round;
  paint-order: stroke fill;
}

.soldier-icon[data-renderer="readable"] .readable-fill { fill: var(--armor-fill); }
.soldier-icon[data-renderer="readable"] .readable-shadow { fill: var(--shadow-fill); }
.soldier-icon[data-renderer="readable"] .readable-accent { fill: var(--accent-fill); }
.soldier-icon[data-renderer="readable"] .readable-metal { fill: var(--metal-fill); }
.soldier-icon[data-renderer="readable"] .readable-gem { fill: var(--gem-fill); }

.soldier-icon[data-renderer="readable"] .readable-polish {
  fill: var(--polish-fill);
  stroke: none;
  opacity: 0.78;
  pointer-events: none;
}

.soldier-icon[data-renderer="readable"] .armor-facet,
.soldier-icon[data-renderer="readable"] .helm-polish {
  mix-blend-mode: screen;
}

.soldier-icon[data-renderer="readable"] .royal-cape-polish,
.soldier-icon[data-renderer="readable"] .plinth-polish {
  opacity: 0.48;
}

.soldier-icon[data-renderer="readable"] .armor-groove,
.soldier-icon[data-renderer="readable"] .plinth-rim {
  opacity: 0.72;
  stroke-width: 1.35;
}

.soldier-icon[data-renderer="readable"] .sculpted-pauldron {
  stroke-width: 1.8;
}

.soldier-icon[data-renderer="readable"] .readable-soldier {
  filter: drop-shadow(0 1px 0 rgba(255, 247, 218, 0.22)) drop-shadow(0 3px 2px rgba(0, 0, 0, 0.28));
}

.piece--black .soldier-icon[data-renderer="readable"] .readable-soldier {
  filter: drop-shadow(0 1px 0 rgba(91, 190, 166, 0.22)) drop-shadow(0 4px 2px rgba(0, 0, 0, 0.52));
}

.soldier-icon[data-renderer="readable"] .readable-line,
.soldier-icon[data-renderer="readable"] .readable-visor {
  fill: none;
  stroke: var(--readable-edge);
  stroke-width: 2.2;
  stroke-linecap: round;
}

.soldier-icon[data-renderer="readable"] .readable-ground {
  fill: rgba(0, 0, 0, 0.5);
  stroke: none;
  filter: blur(1px);
}

.soldier-icon[data-renderer="readable"] .role-sigil {
  stroke-width: 1.7;
}

/* Role silhouettes stay intentionally different even when rendered at 45px. */
.piece-token .soldier-icon[data-renderer="readable"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"] .readable-soldier {
  transform-box: view-box;
  transform-origin: 50% 100%;
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="p"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="p"] .readable-soldier {
  transform: scale(0.76, 1);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="r"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="r"] .readable-soldier {
  transform: scale(0.86, 1.05);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="n"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="n"] .readable-soldier {
  transform: translateX(-1px) rotate(-1deg) scale(0.96, 1.06);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="b"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="b"] .readable-soldier {
  transform: scale(0.86, 1.12);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="q"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="q"] .readable-soldier {
  transform: translateY(1px) scale(0.9, 1.3);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="k"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="k"] .readable-soldier {
  transform: translateY(1px) scale(1, 1.4);
}

.piece-token.piece-role--q > .piece-icon { width: 92%; }
.piece-token.piece-role--k > .piece-icon { width: 98%; }

.soldier-icon[data-renderer="readable"] :is(.queen-crown, .king-crown, .king-cross) {
  stroke-width: 1.9;
}

.soldier-icon[data-renderer="readable"] .royal-plinth {
  filter: drop-shadow(0 1px 0 var(--readable-highlight));
}

/* Do not let idle decoration soften the identifying outer contours. */
.square:not(.is-selected):not(.is-battle-target)
  .soldier-icon[data-renderer="readable"] .soldier-cape {
  animation-duration: 7s;
  animation-timing-function: ease-in-out;
}

@media (max-width: 720px) {
  .soldier-icon[data-renderer="readable"] .readable-fill,
  .soldier-icon[data-renderer="readable"] .readable-shadow,
  .soldier-icon[data-renderer="readable"] .readable-accent,
  .soldier-icon[data-renderer="readable"] .readable-metal,
  .soldier-icon[data-renderer="readable"] .readable-gem {
    stroke-width: 2.45;
  }

  .soldier-icon[data-renderer="readable"] .readable-line,
  .soldier-icon[data-renderer="readable"] .readable-visor {
    stroke-width: 2.6;
  }
}

@media (prefers-reduced-motion: reduce) {
  .soldier-icon[data-renderer="readable"] .readable-soldier,
  .soldier-icon[data-renderer="readable"] .readable-soldier * {
    animation: none !important;
  }
}

/* source: motion-natural.css */
/* Grounded, articulated board-local locomotion. */
.natural-move-layer {
  overflow: visible;
}

.is-natural-motion.is-piece-moving .square:not(.is-move-source):not(.is-move-target) {
  filter: none;
}

.is-natural-motion .is-move-target {
  box-shadow: inset 0 0 0 1px rgba(235, 211, 157, 0.28);
}

.natural-move-actor {
  transform: translate3d(0, 0, 0);
  transform-origin: 50% 88%;
  will-change: transform;
}

.natural-body-rig {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: block;
  pointer-events: none;
  transform: translate3d(0, 0, 0);
  transform-origin: 50% 88%;
  will-change: transform;
}

.natural-move-actor .piece-token {
  z-index: 2;
  width: 92%;
  height: 116%;
  filter: none;
}

.is-natural-move-playing .natural-move-actor {
  animation-delay: var(--move-delay, 0ms);
  animation-duration: var(--move-duration);
  animation-fill-mode: both;
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor.move-role-p { animation-name: natural-pawn-march-v2; }
.is-natural-move-playing .natural-move-actor.move-role-n { animation-name: natural-knight-gallop-v2; }
.is-natural-move-playing .natural-move-actor.move-role-b { animation-name: natural-bishop-procession-v2; }
.is-natural-move-playing .natural-move-actor.move-role-r { animation-name: natural-rook-stomp-v2; }
.is-natural-move-playing .natural-move-actor.move-role-q { animation-name: natural-queen-procession-v2; }
.is-natural-move-playing .natural-move-actor.move-role-k { animation-name: natural-king-procession-v2; }

/* Fine contact dust marks departure and landing without drawing a trail. */
.natural-footfall {
  position: absolute;
  z-index: 56;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%);
}

.natural-footfall i,
.natural-footfall b,
.natural-footfall span {
  position: absolute;
  bottom: 0;
  left: 50%;
  display: block;
  border-radius: 50%;
  background: rgba(198, 183, 146, 0.42);
  filter: blur(2px);
  content: "";
  transform: translateX(-50%);
}

.natural-footfall i { width: 38%; height: 36%; }
.natural-footfall b { width: 22%; height: 28%; margin-left: -16%; }
.natural-footfall span { width: 18%; height: 24%; margin-left: 18%; }

.is-natural-move-playing .natural-footfall--departure {
  animation: natural-dust-depart-v2 var(--primary-move-duration) ease-out both;
}

.is-natural-move-playing .natural-footfall--arrival {
  animation: natural-dust-arrive-v2 var(--primary-move-duration) ease-out both;
}

.natural-moving-piece-b .natural-footfall,
.natural-moving-piece-q .natural-footfall {
  filter: opacity(0.6);
}

.natural-moving-piece-r .natural-footfall {
  filter: sepia(0.32) brightness(0.82);
  transform: translate(-50%, -50%) scale(1.25);
}

.is-natural-move-playing .is-quick-capture-target > .piece-token {
  animation: natural-quick-capture-v2 var(--primary-move-duration) cubic-bezier(0.55, 0, 1, 1) both;
}

/* Every visible rig uses the actor clock so foot plants and carried equipment agree. */
.is-natural-move-playing .natural-move-actor .natural-body-rig,
.is-natural-move-playing .natural-move-actor .natural-knight-mount,
.is-natural-move-playing .natural-move-actor .natural-mount-body,
.is-natural-move-playing .natural-move-actor .natural-mount-neck,
.is-natural-move-playing .natural-move-actor .natural-mount-head,
.is-natural-move-playing .natural-move-actor .natural-mount-leg,
.is-natural-move-playing .natural-move-actor .natural-mount-tail,
.is-natural-move-playing .natural-move-actor .soldier-cape,
.is-natural-move-playing .natural-move-actor .soldier-arm,
.is-natural-move-playing .natural-move-actor .soldier-leg,
.is-natural-move-playing .natural-move-actor .soldier-weapon-rig,
.is-natural-move-playing .natural-move-actor .soldier-torso,
.is-natural-move-playing .natural-move-actor .soldier-head,
.is-natural-move-playing .natural-move-actor .soldier-base,
.is-natural-move-playing .natural-move-actor .readable-ground {
  animation-delay: var(--move-delay, 0ms);
  animation-duration: var(--move-duration);
  animation-fill-mode: both;
}

.natural-move-actor .soldier-leg,
.natural-move-actor .soldier-arm,
.natural-move-actor .soldier-weapon-rig,
.natural-move-actor .soldier-cape,
.natural-move-actor .soldier-torso,
.natural-move-actor .soldier-head,
.natural-move-actor .soldier-base,
.natural-move-actor .readable-ground {
  transform-box: fill-box;
}

.natural-move-actor .soldier-leg { transform-origin: 50% 8%; }
.natural-move-actor .soldier-base { transform-origin: 50% 72%; }
.natural-move-actor .readable-ground { transform-origin: 50% 50%; }

/* Foot soldier: three readable marching contacts. */
.is-natural-move-playing .move-role-p .natural-body-rig {
  animation-name: natural-pawn-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-p .soldier-leg--shield {
  animation-name: natural-march-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-p .soldier-leg--weapon {
  animation-name: natural-march-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-p .soldier-arm--shield {
  animation-name: natural-march-shield-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-p .soldier-spear {
  animation-name: natural-march-spear-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-p .soldier-cape {
  animation-name: natural-march-cape-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-p .soldier-base {
  animation-name: natural-march-boots-v2;
  animation-timing-function: linear;
}

/* Spellwarden: staff plants lead a restrained diagonal procession. */
.is-natural-move-playing .move-role-b .natural-body-rig {
  animation-name: natural-caster-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-b .soldier-casting-arm {
  animation-name: natural-caster-orb-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-b .soldier-staff {
  animation-name: natural-caster-staff-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-b .soldier-cape {
  animation-name: natural-caster-robe-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-b .soldier-base {
  animation-name: natural-caster-foot-v2;
  animation-timing-function: linear;
}

/* Tower guard: two slow, weighty stomps with a braced shield and counter-swinging hammer. */
.is-natural-move-playing .move-role-r .natural-body-rig {
  animation-name: natural-rook-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-r .soldier-leg--shield {
  animation-name: natural-rook-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-r .soldier-leg--weapon {
  animation-name: natural-rook-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-r .soldier-arm--shield {
  animation-name: natural-rook-shield-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-r .soldier-arm--weapon,
.is-natural-move-playing .move-role-r .soldier-warhammer {
  animation-name: natural-rook-hammer-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-r .soldier-cape {
  animation-name: natural-rook-cape-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-r .soldier-base {
  animation-name: natural-rook-boots-v2;
  animation-timing-function: linear;
}

/* Queen: poised, even royal steps; the orb remains level while the cape breathes. */
.is-natural-move-playing .move-role-q .natural-body-rig {
  animation-name: natural-queen-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-q .soldier-leg--shield {
  animation-name: natural-royal-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-q .soldier-leg--weapon {
  animation-name: natural-royal-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-q .soldier-casting-arm {
  animation-name: natural-queen-orb-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-q .soldier-winged-cape {
  animation-name: natural-queen-cape-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-q .soldier-rapier {
  animation-name: natural-queen-rapier-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-q .soldier-base {
  animation-name: natural-royal-boots-v2;
  animation-timing-function: linear;
}

/* King: broad two-step cadence with the greatsword held as a counterweight. */
.is-natural-move-playing .move-role-k .natural-body-rig {
  animation-name: natural-king-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-k .soldier-leg--shield {
  animation-name: natural-king-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-k .soldier-leg--weapon {
  animation-name: natural-king-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-k .soldier-greatsword {
  animation-name: natural-king-sword-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-k .soldier-cape {
  animation-name: natural-king-cape-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-k .soldier-base {
  animation-name: natural-king-boots-v2;
  animation-timing-function: linear;
}

/* Mounted knight: a temporary armored warhorse carries the authored rider through two beats. */
.natural-knight-mount {
  --mount-main: #c5b17f;
  --mount-light: #f2dfad;
  --mount-deep: #5d4726;
  --mount-edge: #302411;
  position: absolute;
  z-index: 1;
  right: 2%;
  bottom: 1%;
  left: 2%;
  height: 54%;
  pointer-events: none;
  opacity: 0;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.48));
  transform-origin: 48% 78%;
}

.natural-move-color-b .natural-knight-mount {
  --mount-main: #245348;
  --mount-light: #69b09e;
  --mount-deep: #061713;
  --mount-edge: #8ad5c1;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.68));
}

.natural-mount-body,
.natural-mount-neck,
.natural-mount-head,
.natural-mount-leg,
.natural-mount-tail {
  position: absolute;
  display: block;
  box-sizing: border-box;
  border: 1.5px solid var(--mount-edge);
  background: linear-gradient(145deg, var(--mount-light), var(--mount-main) 46%, var(--mount-deep));
}

.natural-mount-body {
  top: 25%;
  left: 21%;
  width: 59%;
  height: 39%;
  border-radius: 48% 38% 42% 46%;
  box-shadow:
    inset 0 -3px rgba(0, 0, 0, 0.25),
    inset 9px 4px rgba(255, 255, 255, 0.08);
  transform-origin: 50% 70%;
}

.natural-mount-body::before {
  position: absolute;
  top: 16%;
  right: 14%;
  width: 31%;
  height: 52%;
  border: 1px solid color-mix(in srgb, var(--mount-edge), transparent 18%);
  border-radius: 45%;
  background: color-mix(in srgb, var(--mount-light), transparent 58%);
  content: "";
}

.natural-mount-neck {
  top: 2%;
  left: 67%;
  width: 16%;
  height: 46%;
  border-radius: 70% 24% 30% 55%;
  transform: rotate(-25deg);
  transform-origin: 50% 90%;
}

.natural-mount-head {
  top: -2%;
  left: 75%;
  width: 23%;
  height: 24%;
  border-radius: 68% 45% 58% 44%;
  clip-path: polygon(0 16%, 24% 0, 91% 24%, 100% 60%, 73% 92%, 18% 79%);
  transform-origin: 20% 70%;
}

.natural-mount-head::before,
.natural-mount-head::after {
  position: absolute;
  top: -34%;
  width: 20%;
  height: 54%;
  border: 1px solid var(--mount-edge);
  background: var(--mount-main);
  content: "";
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.natural-mount-head::before { left: 20%; transform: rotate(-11deg); }
.natural-mount-head::after { left: 52%; transform: rotate(13deg); }

.natural-mount-leg {
  top: 56%;
  width: 7%;
  height: 39%;
  border-radius: 999px;
  transform-origin: 50% 5%;
}

.natural-mount-leg::after {
  position: absolute;
  right: -42%;
  bottom: -4%;
  width: 145%;
  height: 18%;
  border-radius: 3px 8px 5px 3px;
  background: var(--mount-edge);
  content: "";
}

.natural-mount-leg--hind-a { left: 28%; }
.natural-mount-leg--hind-b { left: 39%; }
.natural-mount-leg--fore-a { left: 68%; }
.natural-mount-leg--fore-b { left: 78%; }

.natural-mount-tail {
  top: 30%;
  left: 4%;
  width: 24%;
  height: 8%;
  border-width: 2px 0 0 0;
  border-radius: 70% 0 0 0;
  background: none;
  transform: rotate(18deg);
  transform-origin: 100% 50%;
}

.is-natural-move-playing .move-role-n .natural-knight-mount {
  animation-name: natural-mount-presence-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .natural-mount-body {
  animation-name: natural-mount-gallop-body-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .natural-mount-neck {
  animation-name: natural-mount-neck-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .natural-mount-head {
  animation-name: natural-mount-head-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n :is(.natural-mount-leg--hind-a, .natural-mount-leg--fore-b) {
  animation-name: natural-mount-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n :is(.natural-mount-leg--hind-b, .natural-mount-leg--fore-a) {
  animation-name: natural-mount-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .natural-mount-tail {
  animation-name: natural-mount-tail-v2;
  animation-timing-function: ease-in-out;
}

.is-natural-move-playing .move-role-n .natural-body-rig {
  animation-name: natural-rider-seat-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-leg--shield {
  animation-name: natural-rider-leg-a-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-leg--weapon {
  animation-name: natural-rider-leg-b-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-torso {
  animation-name: natural-rider-torso-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-head {
  animation-name: natural-rider-head-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-lance {
  animation-name: natural-rider-lance-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-n .soldier-cape {
  animation-name: natural-rider-cape-v2;
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor .readable-ground {
  animation-name: natural-contact-shadow-v2;
  animation-timing-function: linear;
}

/* Actor paths encode acceleration through uneven progress, while every lift alters screen Y. */
@keyframes natural-pawn-march-v2 {
  0%, 7% { transform: translate3d(0, 0, 0); }
  11% { transform: translate3d(0, 1px, 0) rotate(var(--motion-counter-lean)); }
  16% { transform: translate3d(var(--travel-8-x), calc(var(--travel-8-y) - var(--step-rise)), 0) rotate(var(--motion-lean)); }
  28% { transform: translate3d(var(--travel-24-x), var(--travel-24-y), 0); }
  41% { transform: translate3d(var(--travel-42-x), calc(var(--travel-42-y) - var(--step-rise)), 0) rotate(var(--motion-counter-lean)); }
  55% { transform: translate3d(var(--travel-60-x), var(--travel-60-y), 0); }
  68% { transform: translate3d(var(--travel-76-x), calc(var(--travel-76-y) - var(--step-rise)), 0) rotate(var(--motion-lean)); }
  82% { transform: translate3d(var(--travel-92-x), var(--travel-92-y), 0); }
  92% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleY(0.975); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-rook-stomp-v2 {
  0%, 10% { transform: translate3d(0, 0, 0); }
  15% { transform: translate3d(0, 1px, 0) scaleX(1.02) scaleY(0.98); }
  24% { transform: translate3d(var(--travel-8-x), calc(var(--travel-8-y) - var(--stomp-rise)), 0) rotate(var(--motion-lean)); }
  40% { transform: translate3d(var(--travel-36-x), var(--travel-36-y), 0) scaleX(1.018) scaleY(0.982); }
  55% { transform: translate3d(var(--travel-56-x), calc(var(--travel-56-y) - var(--stomp-rise)), 0) rotate(var(--motion-counter-lean)); }
  73% { transform: translate3d(var(--travel-82-x), var(--travel-82-y), 0) scaleX(1.022) scaleY(0.978); }
  87% { transform: translate3d(var(--travel-97-x), calc(var(--travel-97-y) - 1px), 0); }
  93% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.03) scaleY(0.97); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-bishop-procession-v2 {
  0%, 8% { transform: translate3d(0, 0, 0); }
  18% { transform: translate3d(var(--travel-12-x), calc(var(--travel-12-y) - var(--step-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  34% { transform: translate3d(var(--travel-32-x), var(--travel-32-y), 0); }
  50% { transform: translate3d(var(--travel-54-x), calc(var(--travel-54-y) - var(--step-rise-low)), 0) rotate(var(--motion-lean)); }
  68% { transform: translate3d(var(--travel-76-x), var(--travel-76-y), 0); }
  82% { transform: translate3d(var(--travel-92-x), calc(var(--travel-92-y) - var(--step-rise-low)), 0); }
  94%, 100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-queen-procession-v2 {
  0%, 10% { transform: translate3d(0, 0, 0); }
  22% { transform: translate3d(var(--travel-14-x), calc(var(--travel-14-y) - var(--step-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  40% { transform: translate3d(var(--travel-40-x), var(--travel-40-y), 0); }
  58% { transform: translate3d(var(--travel-66-x), calc(var(--travel-66-y) - var(--step-rise-low)), 0) rotate(var(--motion-lean)); }
  78% { transform: translate3d(var(--travel-90-x), var(--travel-90-y), 0); }
  94%, 100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-king-procession-v2 {
  0%, 12% { transform: translate3d(0, 0, 0); }
  24% { transform: translate3d(var(--travel-8-x), calc(var(--travel-8-y) - var(--step-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  46% { transform: translate3d(var(--travel-42-x), var(--travel-42-y), 0) scaleY(0.985); }
  61% { transform: translate3d(var(--travel-62-x), calc(var(--travel-62-y) - var(--step-rise-low)), 0) rotate(var(--motion-lean)); }
  82% { transform: translate3d(var(--travel-92-x), var(--travel-92-y), 0) scaleY(0.982); }
  93%, 100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-knight-gallop-v2 {
  0%, 7% { transform: translate3d(0, 0, 0); }
  12% { transform: translate3d(0, 1px, 0) scaleX(1.03) scaleY(0.95); }
  18% { transform: translate3d(var(--travel-4-x), calc(var(--travel-4-y) - var(--knight-lift-low)), 0) rotate(var(--motion-counter-lean)); }
  33% { transform: translate3d(var(--travel-32-x), calc(var(--travel-32-y) - var(--knight-lift-mid)), 0) rotate(var(--motion-lean)); }
  46% { transform: translate3d(var(--travel-50-x), calc(var(--travel-50-y) - var(--knight-lift-low)), 0); }
  62% { transform: translate3d(var(--travel-72-x), calc(var(--travel-72-y) - var(--knight-lift)), 0) rotate(var(--motion-lean)); }
  78% { transform: translate3d(var(--travel-92-x), calc(var(--travel-92-y) - var(--knight-lift-low)), 0) rotate(var(--motion-counter-lean)); }
  88% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.045) scaleY(0.9); }
  95% { transform: translate3d(var(--move-x), calc(var(--move-y) - 2px), 0) scaleX(0.99) scaleY(1.025); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-pawn-body-v2 {
  0%, 7%, 100% { transform: translate3d(0, 0, 0); }
  16%, 68% { transform: translate3d(var(--body-sway), -1.5px, 0) rotate(-1deg); }
  28%, 82% { transform: translate3d(0, 0.7px, 0) scaleY(0.99); }
  41% { transform: translate3d(var(--body-counter-sway), -1.5px, 0) rotate(1deg); }
  55% { transform: translate3d(0, 0.7px, 0) scaleY(0.99); }
  92% { transform: translate3d(0, 0.5px, 0); }
}

@keyframes natural-march-leg-a-v2 {
  0%, 7%, 100% { transform: rotate(0) translate(0, 0); }
  16% { transform: rotate(15deg) translate(1px, -2.2px); }
  28% { transform: rotate(-8deg) translate(-0.5px, 0.5px); }
  41% { transform: rotate(-13deg) translate(-1px, 0); }
  55% { transform: rotate(10deg) translate(0.5px, -1.5px); }
  68% { transform: rotate(16deg) translate(1px, -2px); }
  82% { transform: rotate(-7deg) translate(-0.5px, 0.5px); }
}

@keyframes natural-march-leg-b-v2 {
  0%, 7%, 100% { transform: rotate(0) translate(0, 0); }
  16% { transform: rotate(-13deg) translate(-1px, 0); }
  28% { transform: rotate(10deg) translate(0.5px, -1.5px); }
  41% { transform: rotate(15deg) translate(1px, -2.2px); }
  55% { transform: rotate(-8deg) translate(-0.5px, 0.5px); }
  68% { transform: rotate(-12deg) translate(-1px, 0); }
  82% { transform: rotate(9deg) translate(0.5px, -1.3px); }
}

@keyframes natural-march-shield-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  16%, 68% { transform: rotate(4deg) translateY(-1px); }
  41% { transform: rotate(-3deg) translateY(1px); }
  82% { transform: rotate(2deg); }
}

@keyframes natural-march-spear-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  16%, 68% { transform: rotate(-5deg) translateY(-1.5px); }
  28%, 82% { transform: rotate(2deg) translateY(0.5px); }
  41% { transform: rotate(4deg) translateY(-1px); }
  55% { transform: rotate(-2deg); }
}

@keyframes natural-march-cape-v2 {
  0%, 7%, 100% { transform: skewX(0); }
  16%, 68% { transform: skewX(var(--motion-cape-lean)) translateY(-1px); }
  41% { transform: skewX(var(--motion-counter-lean)); }
  82% { transform: skewX(1deg); }
}

@keyframes natural-march-boots-v2 {
  0%, 7%, 100% { transform: scale(1); }
  16%, 41%, 68% { transform: translateY(-1px) scaleX(0.985); }
  28%, 55%, 82% { transform: translateY(0.8px) scaleX(1.02) scaleY(0.97); }
}

@keyframes natural-caster-body-v2 {
  0%, 8%, 100% { transform: translate3d(0, 0, 0); }
  18% { transform: translate3d(var(--body-counter-sway), -1.5px, 0) rotate(-0.8deg); }
  34% { transform: translate3d(0, 0.5px, 0); }
  50% { transform: translate3d(var(--body-sway), -1.5px, 0) rotate(0.8deg); }
  68% { transform: translate3d(0, 0.5px, 0); }
  82% { transform: translate3d(var(--body-counter-sway), -0.8px, 0); }
}

@keyframes natural-caster-orb-v2 {
  0%, 8%, 100% { transform: rotate(0); }
  18%, 50% { transform: rotate(-5deg) translateY(-2px); }
  34%, 68% { transform: rotate(2deg) translateY(-0.5px); }
  82% { transform: rotate(-2deg) translateY(-1px); }
}

@keyframes natural-caster-staff-v2 {
  0%, 8%, 100% { transform: rotate(0) translateY(0); }
  18% { transform: rotate(5deg) translateY(-2px); }
  34% { transform: rotate(-3deg) translateY(1px); }
  50% { transform: rotate(-5deg) translateY(-2px); }
  68% { transform: rotate(3deg) translateY(1px); }
  82% { transform: rotate(-2deg) translateY(-1px); }
}

@keyframes natural-caster-robe-v2 {
  0%, 8%, 100% { transform: skewX(0) scaleX(1); }
  18%, 50% { transform: skewX(var(--motion-cape-lean)) scaleX(1.025); }
  34%, 68% { transform: skewX(var(--motion-counter-lean)) scaleX(0.99); }
}

@keyframes natural-caster-foot-v2 {
  0%, 8%, 100% { transform: scale(1); }
  18%, 50%, 82% { transform: translateY(-1px) scaleX(0.98); }
  34%, 68% { transform: translateY(0.5px) scaleX(1.015) scaleY(0.98); }
}

@keyframes natural-rook-body-v2 {
  0%, 10%, 100% { transform: translate3d(0, 0, 0); }
  15% { transform: translate3d(0, 1px, 0) scaleY(0.985); }
  24% { transform: translate3d(var(--body-sway), -1px, 0) rotate(var(--motion-lean)); }
  40% { transform: translate3d(0, 1.2px, 0) scaleX(1.02) scaleY(0.975); }
  55% { transform: translate3d(var(--body-counter-sway), -1px, 0) rotate(var(--motion-counter-lean)); }
  73% { transform: translate3d(0, 1.2px, 0) scaleX(1.02) scaleY(0.975); }
  93% { transform: translate3d(0, 0.8px, 0) scaleY(0.985); }
}

@keyframes natural-rook-leg-a-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  24% { transform: rotate(9deg) translate(1px, -1.5px); }
  40% { transform: rotate(-5deg) translateY(1px); }
  55% { transform: rotate(-8deg); }
  73% { transform: rotate(6deg) translateY(0.8px); }
}

@keyframes natural-rook-leg-b-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  24% { transform: rotate(-8deg); }
  40% { transform: rotate(6deg) translateY(0.8px); }
  55% { transform: rotate(9deg) translate(1px, -1.5px); }
  73% { transform: rotate(-5deg) translateY(1px); }
}

@keyframes natural-rook-shield-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  15% { transform: rotate(-2deg) translateX(-1px); }
  24%, 55% { transform: rotate(7deg) translate(1px, -1px); }
  40%, 73% { transform: rotate(4deg) translateX(1px); }
  93% { transform: rotate(-2deg); }
}

@keyframes natural-rook-hammer-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  24% { transform: rotate(-8deg) translateY(-1px); }
  40% { transform: rotate(4deg) translateY(1px); }
  55% { transform: rotate(7deg) translateY(-1px); }
  73% { transform: rotate(-4deg) translateY(1px); }
  93% { transform: rotate(2deg); }
}

@keyframes natural-rook-cape-v2 {
  0%, 10%, 100% { transform: skewX(0); }
  24%, 55% { transform: skewX(var(--motion-cape-lean)); }
  40%, 73% { transform: skewX(var(--motion-counter-lean)); }
}

@keyframes natural-rook-boots-v2 {
  0%, 10%, 100% { transform: scale(1); }
  24%, 55% { transform: translateY(-0.8px) scaleX(0.99); }
  40%, 73%, 93% { transform: translateY(1px) scaleX(1.035) scaleY(0.95); }
}

@keyframes natural-queen-body-v2 {
  0%, 10%, 100% { transform: translate3d(0, 0, 0); }
  22% { transform: translate3d(var(--body-counter-sway), -1.2px, 0) rotate(-0.6deg); }
  40% { transform: translate3d(0, 0.4px, 0); }
  58% { transform: translate3d(var(--body-sway), -1.2px, 0) rotate(0.6deg); }
  78% { transform: translate3d(0, 0.4px, 0); }
}

@keyframes natural-royal-leg-a-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  22% { transform: rotate(9deg) translateY(-1.5px); }
  40% { transform: rotate(-5deg); }
  58% { transform: rotate(-7deg); }
  78% { transform: rotate(5deg) translateY(-0.8px); }
}

@keyframes natural-royal-leg-b-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  22% { transform: rotate(-7deg); }
  40% { transform: rotate(5deg) translateY(-0.8px); }
  58% { transform: rotate(9deg) translateY(-1.5px); }
  78% { transform: rotate(-5deg); }
}

@keyframes natural-queen-orb-v2 {
  0%, 10%, 100% { transform: rotate(0) translateY(0); }
  22%, 58% { transform: rotate(-4deg) translateY(-2px); }
  40%, 78% { transform: rotate(2deg) translateY(-0.5px); }
}

@keyframes natural-queen-cape-v2 {
  0%, 10%, 100% { transform: scaleX(1) skewX(0); }
  22%, 58% { transform: scaleX(1.05) skewX(var(--motion-cape-lean)); }
  40%, 78% { transform: scaleX(0.99) skewX(var(--motion-counter-lean)); }
}

@keyframes natural-queen-rapier-v2 {
  0%, 10%, 100% { transform: rotate(0); }
  22%, 58% { transform: rotate(-6deg) translateY(-1px); }
  40%, 78% { transform: rotate(3deg) translateY(0.5px); }
}

@keyframes natural-royal-boots-v2 {
  0%, 10%, 100% { transform: scale(1); }
  22%, 58% { transform: translateY(-0.7px) scaleX(0.99); }
  40%, 78% { transform: translateY(0.6px) scaleX(1.02) scaleY(0.98); }
}

@keyframes natural-king-body-v2 {
  0%, 12%, 100% { transform: translate3d(0, 0, 0); }
  24% { transform: translate3d(var(--body-counter-sway), -1px, 0) rotate(-0.8deg); }
  46% { transform: translate3d(0, 0.8px, 0) scaleY(0.985); }
  61% { transform: translate3d(var(--body-sway), -1px, 0) rotate(0.8deg); }
  82% { transform: translate3d(0, 0.8px, 0) scaleY(0.985); }
}

@keyframes natural-king-leg-a-v2 {
  0%, 12%, 100% { transform: rotate(0); }
  24% { transform: rotate(11deg) translateY(-1.5px); }
  46% { transform: rotate(-6deg) translateY(0.5px); }
  61% { transform: rotate(-8deg); }
  82% { transform: rotate(6deg) translateY(0.5px); }
}

@keyframes natural-king-leg-b-v2 {
  0%, 12%, 100% { transform: rotate(0); }
  24% { transform: rotate(-8deg); }
  46% { transform: rotate(6deg) translateY(0.5px); }
  61% { transform: rotate(11deg) translateY(-1.5px); }
  82% { transform: rotate(-6deg) translateY(0.5px); }
}

@keyframes natural-king-sword-v2 {
  0%, 12%, 100% { transform: rotate(0); }
  24% { transform: rotate(4deg) translateY(-1px); }
  46% { transform: rotate(-2deg) translateY(0.5px); }
  61% { transform: rotate(-4deg) translateY(-1px); }
  82% { transform: rotate(2deg) translateY(0.5px); }
}

@keyframes natural-king-cape-v2 {
  0%, 12%, 100% { transform: skewX(0); }
  24%, 61% { transform: skewX(var(--motion-cape-lean)); }
  46%, 82% { transform: skewX(var(--motion-counter-lean)); }
}

@keyframes natural-king-boots-v2 {
  0%, 12%, 100% { transform: scale(1); }
  24%, 61% { transform: translateY(-0.7px) scaleX(0.99); }
  46%, 82% { transform: translateY(0.8px) scaleX(1.025) scaleY(0.975); }
}

@keyframes natural-mount-presence-v2 {
  0%, 6%, 100% { opacity: 0; transform: translateY(3px) scale(0.9); }
  13% { opacity: 0.96; transform: translateY(0) scale(1); }
  82% { opacity: 0.96; transform: translateY(0) scale(1); }
  94% { opacity: 0; transform: translateY(2px) scale(0.94); }
}

@keyframes natural-mount-gallop-body-v2 {
  0%, 7%, 100% { transform: rotate(0) scale(1); }
  12% { transform: rotate(-2deg) scaleX(1.04) scaleY(0.94); }
  33% { transform: rotate(2deg) scaleX(0.98) scaleY(1.04); }
  46% { transform: rotate(-2deg) scaleX(1.035) scaleY(0.96); }
  62% { transform: rotate(2deg) scaleX(0.98) scaleY(1.04); }
  78% { transform: rotate(-1deg) scaleX(1.02) scaleY(0.98); }
  88% { transform: rotate(0) scaleX(1.06) scaleY(0.9); }
}

@keyframes natural-mount-neck-v2 {
  0%, 7%, 100% { transform: rotate(-25deg); }
  18%, 46% { transform: rotate(-32deg) translateY(1px); }
  33%, 62% { transform: rotate(-18deg) translateY(-1px); }
  78% { transform: rotate(-28deg); }
  88% { transform: rotate(-15deg) translateY(2px); }
}

@keyframes natural-mount-head-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  18%, 46% { transform: rotate(-8deg) translateY(1px); }
  33%, 62% { transform: rotate(6deg) translateY(-1px); }
  78% { transform: rotate(-4deg); }
  88% { transform: rotate(8deg) translateY(2px); }
}

@keyframes natural-mount-leg-a-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  18% { transform: rotate(28deg) translateY(-2px); }
  33% { transform: rotate(-30deg) translateY(-4px) scaleY(0.82); }
  46% { transform: rotate(20deg) translateY(-1px); }
  62% { transform: rotate(-26deg) translateY(-4px) scaleY(0.84); }
  78% { transform: rotate(18deg) translateY(-1px); }
  88% { transform: rotate(-7deg) scaleY(0.9); }
}

@keyframes natural-mount-leg-b-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  18% { transform: rotate(-24deg) translateY(-3px) scaleY(0.86); }
  33% { transform: rotate(26deg) translateY(-1px); }
  46% { transform: rotate(-28deg) translateY(-3px) scaleY(0.84); }
  62% { transform: rotate(24deg) translateY(-1px); }
  78% { transform: rotate(-18deg) translateY(-2px); }
  88% { transform: rotate(8deg) scaleY(0.9); }
}

@keyframes natural-mount-tail-v2 {
  0%, 7%, 100% { transform: rotate(18deg); }
  24%, 55% { transform: rotate(38deg) skewX(-10deg); }
  40%, 72% { transform: rotate(6deg) skewX(8deg); }
  88% { transform: rotate(24deg); }
}

@keyframes natural-rider-seat-v2 {
  0%, 7%, 100% { transform: translate3d(0, 0, 0); }
  13% { transform: translate3d(0, -7%, 0) rotate(-2deg); }
  18% { transform: translate3d(var(--body-counter-sway), -10%, 0) rotate(-4deg); }
  33% { transform: translate3d(var(--body-sway), -14%, 0) rotate(2deg); }
  46% { transform: translate3d(var(--body-counter-sway), -10%, 0) rotate(-3deg); }
  62% { transform: translate3d(var(--body-sway), -15%, 0) rotate(2deg); }
  78% { transform: translate3d(0, -9%, 0) rotate(-2deg); }
  88% { transform: translate3d(0, -3%, 0) scaleY(0.96); }
  95% { transform: translate3d(0, -1%, 0) scaleY(1.015); }
}

@keyframes natural-rider-leg-a-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  18%, 46% { transform: rotate(22deg) translate(2px, -2px); }
  33%, 62% { transform: rotate(34deg) translate(3px, -4px); }
  78% { transform: rotate(14deg) translateY(-1px); }
  88% { transform: rotate(-7deg); }
}

@keyframes natural-rider-leg-b-v2 {
  0%, 7%, 100% { transform: rotate(0); }
  18%, 46% { transform: rotate(-18deg) translate(-1px, -2px); }
  33%, 62% { transform: rotate(-30deg) translate(-2px, -4px); }
  78% { transform: rotate(-12deg) translateY(-1px); }
  88% { transform: rotate(6deg); }
}

@keyframes natural-rider-torso-v2 {
  0%, 7%, 100% { transform: rotate(-5deg); }
  12% { transform: rotate(-10deg) scaleY(0.96); }
  18%, 46% { transform: rotate(-12deg); }
  33%, 62% { transform: rotate(-5deg) scaleY(1.02); }
  78% { transform: rotate(-8deg); }
  88% { transform: rotate(3deg) scaleY(0.95); }
}

@keyframes natural-rider-head-v2 {
  0%, 7%, 100% { transform: rotate(8deg); }
  18%, 46% { transform: rotate(3deg) translateY(1px); }
  33%, 62% { transform: rotate(11deg) translateY(-1px); }
  78% { transform: rotate(6deg); }
  88% { transform: rotate(13deg) translateY(1px); }
}

@keyframes natural-rider-lance-v2 {
  0%, 7%, 100% { transform: rotate(-38deg); }
  18%, 46% { transform: rotate(-47deg) translate(2px, 1px); }
  33%, 62% { transform: rotate(-43deg) translate(3px, -1px); }
  78% { transform: rotate(-40deg); }
  88% { transform: rotate(-34deg) translateY(1px); }
}

@keyframes natural-rider-cape-v2 {
  0%, 7%, 100% { transform: skewX(0); }
  18%, 46%, 78% { transform: skewX(var(--motion-cape-lean)) scaleX(1.04); }
  33%, 62% { transform: skewX(var(--motion-cape-strong)) scaleX(1.08); }
  88% { transform: skewX(var(--motion-counter-lean)); }
}

@keyframes natural-contact-shadow-v2 {
  0%, 7%, 100% { opacity: 0.48; transform: scale(1); }
  16%, 24%, 33%, 41%, 50%, 55%, 62%, 68% { opacity: 0.28; transform: scaleX(0.82) scaleY(0.72); }
  28%, 34%, 40%, 46%, 55%, 68%, 73%, 78%, 82%, 88%, 93% { opacity: 0.55; transform: scaleX(1.08) scaleY(0.92); }
}

@keyframes natural-dust-depart-v2 {
  0%, 10% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); }
  18% { opacity: 0.3; }
  38%, 100% { opacity: 0; transform: translate(-50%, -72%) scale(1.12); }
}

@keyframes natural-dust-arrive-v2 {
  0%, 80% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  90% { opacity: 0.34; }
  100% { opacity: 0; transform: translate(-50%, -72%) scale(1.24); }
}

@keyframes natural-quick-capture-v2 {
  0%, 74% { opacity: 1; transform: none; filter: brightness(1); }
  87% { opacity: 0.58; transform: translateY(-2%) scale(0.96); filter: brightness(0.8); }
  100% { opacity: 0; transform: translateY(5%) scale(0.88); filter: brightness(0.55); }
}

@media (prefers-reduced-motion: reduce) {
  .natural-move-layer,
  .natural-move-actor,
  .natural-move-actor * {
    animation: none !important;
  }
}
/* Planted gait travel: contact plateaus separate every weight transfer. */
.natural-move-actor {
  --gait-rise: var(--step-rise-low);
  --gait-rise-low: 1.4px;
  --gait-plant-x: 1.014;
  --gait-plant-y: 0.982;
  --gait-contact-color: rgba(213, 194, 148, 0.52);
}

.natural-move-actor.move-role-p {
  --gait-rise: var(--step-rise);
  --gait-plant-x: 1.018;
  --gait-plant-y: 0.974;
}

.natural-move-actor.move-role-r {
  --gait-rise: var(--stomp-rise);
  --gait-plant-x: 1.035;
  --gait-plant-y: 0.958;
  --gait-contact-color: rgba(191, 169, 121, 0.68);
}

.natural-move-actor.move-role-k {
  --gait-plant-x: 1.024;
  --gait-plant-y: 0.972;
}

.natural-move-actor.move-role-n {
  --gait-contact-color: rgba(205, 185, 139, 0.66);
}

.is-natural-move-playing .natural-move-actor.gait-steps-2:not(.move-role-n) {
  animation-name: natural-grounded-travel-2-v3;
}

.is-natural-move-playing .natural-move-actor.gait-steps-3:not(.move-role-n) {
  animation-name: natural-grounded-travel-3-v3;
}

.is-natural-move-playing .natural-move-actor.gait-steps-4:not(.move-role-n) {
  animation-name: natural-grounded-travel-4-v3;
}

.is-natural-move-playing .natural-move-actor.move-role-n {
  animation-name: natural-knight-grounded-gallop-v3;
}

/* A small contact bed appears only while the carrier is genuinely stationary. */
.natural-gait-contacts {
  position: absolute;
  z-index: 1;
  bottom: 7%;
  left: 50%;
  width: 48%;
  height: 9%;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-50%);
  transform-origin: 50% 50%;
}

.natural-gait-contacts > i,
.natural-gait-contacts > b,
.natural-gait-contacts > em {
  position: absolute;
  bottom: 0;
  display: block;
  height: 34%;
  border-radius: 50%;
  background: var(--gait-contact-color);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.42);
  content: "";
  filter: blur(0.65px);
}

.natural-gait-contacts > i { left: 15%; width: 26%; transform: rotate(-6deg); }
.natural-gait-contacts > b { right: 15%; width: 26%; transform: rotate(6deg); }
.natural-gait-contacts > em { right: 27%; left: 27%; height: 24%; opacity: 0.34; }

.natural-gait-contacts--hooves {
  bottom: 3%;
  width: 64%;
}

.natural-gait-contacts--hooves > i,
.natural-gait-contacts--hooves > b {
  width: 22%;
  height: 28%;
  border-radius: 2px 7px 3px 6px;
  filter: blur(0.35px);
}

.is-natural-move-playing .gait-steps-2 .natural-gait-contacts {
  animation: natural-contact-2-v3 var(--move-duration) linear var(--move-delay, 0ms) both;
}

.is-natural-move-playing .gait-steps-3 .natural-gait-contacts {
  animation: natural-contact-3-v3 var(--move-duration) linear var(--move-delay, 0ms) both;
}

.is-natural-move-playing .gait-steps-4 .natural-gait-contacts {
  animation: natural-contact-4-v3 var(--move-duration) linear var(--move-delay, 0ms) both;
}

/* Articulation cycles over the travel clock instead of stretching one pose into a glide. */
.is-natural-move-playing .natural-move-actor:not(.move-role-n) :is(
  .natural-body-rig,
  .soldier-leg,
  .soldier-base
) {
  animation-delay: calc(var(--move-delay, 0ms) + var(--gait-lead));
  animation-duration: var(--gait-cycle-duration);
  animation-iteration-count: var(--gait-cycle-count);
  animation-timing-function: linear;
}

.is-natural-move-playing .move-role-p .natural-body-rig { animation-name: natural-march-body-cycle-v3; }
.is-natural-move-playing .move-role-p .soldier-leg--shield { animation-name: natural-march-leg-a-cycle-v3; }
.is-natural-move-playing .move-role-p .soldier-leg--weapon { animation-name: natural-march-leg-b-cycle-v3; }
.is-natural-move-playing .move-role-p .soldier-base { animation-name: natural-march-sole-cycle-v3; }

.is-natural-move-playing .move-role-r .natural-body-rig { animation-name: natural-heavy-body-cycle-v3; }
.is-natural-move-playing .move-role-r .soldier-leg--shield { animation-name: natural-heavy-leg-a-cycle-v3; }
.is-natural-move-playing .move-role-r .soldier-leg--weapon { animation-name: natural-heavy-leg-b-cycle-v3; }
.is-natural-move-playing .move-role-r .soldier-base { animation-name: natural-heavy-sole-cycle-v3; }

.is-natural-move-playing :is(.move-role-b, .move-role-q, .move-role-k) .natural-body-rig {
  animation-name: natural-procession-body-cycle-v3;
}

.is-natural-move-playing :is(.move-role-q, .move-role-k) .soldier-leg--shield {
  animation-name: natural-procession-leg-a-cycle-v3;
}

.is-natural-move-playing :is(.move-role-q, .move-role-k) .soldier-leg--weapon {
  animation-name: natural-procession-leg-b-cycle-v3;
}

.is-natural-move-playing :is(.move-role-b, .move-role-q, .move-role-k) .soldier-base {
  animation-name: natural-procession-sole-cycle-v3;
}

.is-natural-move-playing .move-role-b .soldier-staff {
  animation-name: natural-staff-plant-cycle-v3;
  animation-delay: calc(var(--move-delay, 0ms) + var(--gait-lead));
  animation-duration: var(--gait-cycle-duration);
  animation-iteration-count: var(--gait-cycle-count);
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor.gait-steps-2 .readable-ground {
  animation-name: natural-shadow-2-v3;
}

.is-natural-move-playing .natural-move-actor.gait-steps-3 .readable-ground {
  animation-name: natural-shadow-3-v3;
}

.is-natural-move-playing .natural-move-actor.gait-steps-4 .readable-ground {
  animation-name: natural-shadow-4-v3;
}

.is-natural-move-playing .natural-move-actor .readable-ground {
  animation-delay: var(--move-delay, 0ms);
  animation-duration: var(--move-duration);
  animation-iteration-count: 1;
  animation-timing-function: linear;
}

@keyframes natural-grounded-travel-2-v3 {
  0%, 8% { transform: translate3d(0, 0, 0); }
  10% { transform: translate3d(0, 1px, 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); animation-timing-function: cubic-bezier(0.28, 0, 0.5, 1); }
  14% { transform: translate3d(var(--travel-2-x), calc(var(--travel-2-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  29% { transform: translate3d(var(--travel-40-x), calc(var(--travel-40-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); animation-timing-function: cubic-bezier(0.3, 0.02, 0.72, 1); }
  36% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  42% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0) scaleX(1.008) scaleY(0.99); }
  46% { transform: translate3d(var(--travel-53-x), calc(var(--travel-53-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); animation-timing-function: cubic-bezier(0.24, 0, 0.62, 1); }
  67% { transform: translate3d(var(--travel-88-x), calc(var(--travel-88-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); animation-timing-function: cubic-bezier(0.3, 0.02, 0.78, 1); }
  77% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  87% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.006) scaleY(0.991); }
  94% { transform: translate3d(var(--move-x), calc(var(--move-y) - 1px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-grounded-travel-3-v3 {
  0%, 7% { transform: translate3d(0, 0, 0); }
  9% { transform: translate3d(0, 1px, 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  13% { transform: translate3d(var(--travel-2-x), calc(var(--travel-2-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  24% { transform: translate3d(var(--travel-22-x), calc(var(--travel-22-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  30% { transform: translate3d(var(--travel-30-x), var(--travel-30-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  35% { transform: translate3d(var(--travel-30-x), var(--travel-30-y), 0); }
  39% { transform: translate3d(var(--travel-34-x), calc(var(--travel-34-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  50% { transform: translate3d(var(--travel-58-x), calc(var(--travel-58-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  57% { transform: translate3d(var(--travel-66-x), var(--travel-66-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  62% { transform: translate3d(var(--travel-66-x), var(--travel-66-y), 0); }
  66% { transform: translate3d(var(--travel-69-x), calc(var(--travel-69-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  78% { transform: translate3d(var(--travel-90-x), calc(var(--travel-90-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  85% { transform: translate3d(var(--travel-97-x), var(--travel-97-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  90% { transform: translate3d(var(--travel-97-x), var(--travel-97-y), 0); }
  94% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.012) scaleY(0.982); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-grounded-travel-4-v3 {
  0%, 6% { transform: translate3d(0, 0, 0); }
  8% { transform: translate3d(0, 1px, 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  11% { transform: translate3d(var(--travel-1-x), calc(var(--travel-1-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  20% { transform: translate3d(var(--travel-14-x), calc(var(--travel-14-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  24% { transform: translate3d(var(--travel-20-x), var(--travel-20-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  28% { transform: translate3d(var(--travel-20-x), var(--travel-20-y), 0); }
  32% { transform: translate3d(var(--travel-24-x), calc(var(--travel-24-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  43% { transform: translate3d(var(--travel-44-x), calc(var(--travel-44-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  47% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  51% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0); }
  55% { transform: translate3d(var(--travel-54-x), calc(var(--travel-54-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  66% { transform: translate3d(var(--travel-72-x), calc(var(--travel-72-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  70% { transform: translate3d(var(--travel-78-x), var(--travel-78-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  74% { transform: translate3d(var(--travel-78-x), var(--travel-78-y), 0); }
  78% { transform: translate3d(var(--travel-82-x), calc(var(--travel-82-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  89% { transform: translate3d(var(--travel-96-x), calc(var(--travel-96-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  93% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(var(--gait-plant-x)) scaleY(var(--gait-plant-y)); }
  97% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.006) scaleY(0.992); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-knight-grounded-gallop-v3 {
  0%, 8% { transform: translate3d(0, 0, 0); }
  11% { transform: translate3d(0, 1px, 0) scaleX(1.025) scaleY(0.955); }
  16% { transform: translate3d(var(--travel-2-x), calc(var(--travel-2-y) - 2px), 0) rotate(var(--motion-counter-lean)); }
  28% { transform: translate3d(var(--travel-38-x), calc(var(--travel-38-y) - var(--hoof-flight)), 0) rotate(var(--motion-lean)); }
  36% { transform: translate3d(var(--travel-50-x), calc(var(--travel-50-y) - 2px), 0); }
  40% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0) scaleX(1.035) scaleY(0.94); }
  46% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0) scaleX(1.01) scaleY(0.985); }
  50% { transform: translate3d(var(--travel-53-x), calc(var(--travel-53-y) - 2px), 0) rotate(var(--motion-counter-lean)); }
  66% { transform: translate3d(var(--travel-84-x), calc(var(--travel-84-y) - var(--hoof-flight)), 0) rotate(var(--motion-lean)); }
  75% { transform: translate3d(var(--travel-96-x), calc(var(--travel-96-y) - 2px), 0); }
  79% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.045) scaleY(0.925); }
  88% { transform: translate3d(var(--move-x), var(--move-y), 0) scaleX(1.01) scaleY(0.985); }
  95% { transform: translate3d(var(--move-x), calc(var(--move-y) - 1px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-march-body-cycle-v3 {
  0%, 100% { transform: translate3d(0, 0.7px, 0) scaleY(0.99); }
  14% { transform: translate3d(var(--body-counter-sway), 0, 0) rotate(-1.2deg); }
  32% { transform: translate3d(var(--body-sway), -1.8px, 0) rotate(1.4deg); }
  50% { transform: translate3d(0, 0.8px, 0) scaleX(1.012) scaleY(0.982); }
  68% { transform: translate3d(var(--body-counter-sway), -1.8px, 0) rotate(-1.4deg); }
  86% { transform: translate3d(var(--body-sway), 0, 0) rotate(1.2deg); }
}

@keyframes natural-march-leg-a-cycle-v3 {
  0%, 8%, 100% { transform: rotate(-7deg) translateY(0.8px) scaleY(1.02); }
  22% { transform: rotate(-14deg) translate(-1px, 0); }
  40% { transform: rotate(18deg) translate(1px, -2.5px); }
  50%, 58% { transform: rotate(7deg) translateY(0.8px) scaleY(1.02); }
  72% { transform: rotate(13deg) translateY(0); }
  90% { transform: rotate(-15deg) translate(-1px, -2px); }
}

@keyframes natural-march-leg-b-cycle-v3 {
  0%, 8%, 100% { transform: rotate(7deg) translateY(0.8px) scaleY(1.02); }
  22% { transform: rotate(14deg) translateY(0); }
  40% { transform: rotate(-15deg) translate(-1px, -2px); }
  50%, 58% { transform: rotate(-7deg) translateY(0.8px) scaleY(1.02); }
  72% { transform: rotate(-14deg) translate(-1px, 0); }
  90% { transform: rotate(18deg) translate(1px, -2.5px); }
}

@keyframes natural-march-sole-cycle-v3 {
  0%, 50%, 100% { transform: translateY(0.9px) scaleX(1.035) scaleY(0.958); }
  24%, 74% { transform: translateY(-1px) scaleX(0.985); }
}

@keyframes natural-heavy-body-cycle-v3 {
  0%, 50%, 100% { transform: translate3d(0, 1.5px, 0) scaleX(1.026) scaleY(0.965); }
  17% { transform: translate3d(var(--body-counter-sway), 0, 0) rotate(var(--motion-counter-lean)); }
  31% { transform: translate3d(var(--body-sway), -1.2px, 0) rotate(var(--motion-lean)); }
  67% { transform: translate3d(var(--body-sway), 0, 0) rotate(var(--motion-lean)); }
  81% { transform: translate3d(var(--body-counter-sway), -1.2px, 0) rotate(var(--motion-counter-lean)); }
}

@keyframes natural-heavy-leg-a-cycle-v3 {
  0%, 10%, 100% { transform: rotate(-5deg) translateY(1.1px) scaleY(1.025); }
  29% { transform: rotate(11deg) translate(1px, -1.5px); }
  50%, 60% { transform: rotate(5deg) translateY(1.1px) scaleY(1.025); }
  79% { transform: rotate(-10deg) translate(-1px, -1.2px); }
}

@keyframes natural-heavy-leg-b-cycle-v3 {
  0%, 10%, 100% { transform: rotate(5deg) translateY(1.1px) scaleY(1.025); }
  29% { transform: rotate(-10deg) translate(-1px, -1.2px); }
  50%, 60% { transform: rotate(-5deg) translateY(1.1px) scaleY(1.025); }
  79% { transform: rotate(11deg) translate(1px, -1.5px); }
}

@keyframes natural-heavy-sole-cycle-v3 {
  0%, 50%, 100% { transform: translateY(1.3px) scaleX(1.055) scaleY(0.93); }
  25%, 75% { transform: translateY(-0.6px) scaleX(0.99); }
}

@keyframes natural-procession-body-cycle-v3 {
  0%, 50%, 100% { transform: translate3d(0, 0.55px, 0) scaleY(0.992); }
  24% { transform: translate3d(var(--body-counter-sway), -1.15px, 0) rotate(-0.7deg); }
  74% { transform: translate3d(var(--body-sway), -1.15px, 0) rotate(0.7deg); }
}

@keyframes natural-procession-leg-a-cycle-v3 {
  0%, 50%, 100% { transform: rotate(-4deg) translateY(0.55px); }
  24% { transform: rotate(9deg) translateY(-1.3px); }
  74% { transform: rotate(-8deg) translateY(-0.8px); }
}

@keyframes natural-procession-leg-b-cycle-v3 {
  0%, 50%, 100% { transform: rotate(4deg) translateY(0.55px); }
  24% { transform: rotate(-8deg) translateY(-0.8px); }
  74% { transform: rotate(9deg) translateY(-1.3px); }
}

@keyframes natural-procession-sole-cycle-v3 {
  0%, 50%, 100% { transform: translateY(0.55px) scaleX(1.018) scaleY(0.978); }
  25%, 75% { transform: translateY(-0.6px) scaleX(0.993); }
}

@keyframes natural-staff-plant-cycle-v3 {
  0%, 8%, 50%, 58%, 100% { transform: rotate(-3deg) translateY(1px); }
  24% { transform: rotate(5deg) translateY(-2px); }
  74% { transform: rotate(-6deg) translateY(-2px); }
}

@keyframes natural-contact-2-v3 {
  0%, 7% { opacity: 0.44; transform: translateX(-50%) scale(1); }
  14%, 30%, 48%, 69% { opacity: 0.08; transform: translateX(-50%) scale(0.78); }
  36%, 42% { opacity: 0.7; transform: translateX(-50%) scale(1.08); }
  77%, 88% { opacity: 0.82; transform: translateX(-50%) scale(1.12); }
  100% { opacity: 0.26; transform: translateX(-50%) scale(1); }
}

@keyframes natural-contact-3-v3 {
  0%, 6% { opacity: 0.4; }
  14%, 24%, 40%, 50%, 67%, 78% { opacity: 0.06; }
  30%, 35%, 57%, 62% { opacity: 0.72; }
  85%, 94% { opacity: 0.84; }
  100% { opacity: 0.26; }
}

@keyframes natural-contact-4-v3 {
  0%, 5% { opacity: 0.38; }
  11%, 20%, 32%, 43%, 55%, 66%, 78%, 89% { opacity: 0.05; }
  24%, 28%, 47%, 51%, 70%, 74% { opacity: 0.7; }
  93%, 97% { opacity: 0.84; }
  100% { opacity: 0.25; }
}

@keyframes natural-shadow-2-v3 {
  0%, 8%, 36%, 42%, 77%, 88%, 100% { opacity: 0.56; transform: scaleX(1.07) scaleY(0.9); }
  20%, 58% { opacity: 0.25; transform: scaleX(0.78) scaleY(0.68); }
}

@keyframes natural-shadow-3-v3 {
  0%, 7%, 30%, 35%, 57%, 62%, 85%, 94%, 100% { opacity: 0.55; transform: scaleX(1.06) scaleY(0.9); }
  20%, 47%, 74% { opacity: 0.25; transform: scaleX(0.8) scaleY(0.7); }
}

@keyframes natural-shadow-4-v3 {
  0%, 6%, 24%, 28%, 47%, 51%, 70%, 74%, 93%, 100% { opacity: 0.55; transform: scaleX(1.06) scaleY(0.9); }
  17%, 39%, 62%, 85% { opacity: 0.24; transform: scaleX(0.8) scaleY(0.7); }
}

/* The horse now has two explicit suspension-to-hoof-contact beats. */
.is-natural-move-playing .move-role-n .natural-knight-mount {
  animation-name: natural-mount-presence-v3;
}

.is-natural-move-playing .move-role-n .natural-mount-body {
  animation-name: natural-mount-gallop-body-v3;
}

.is-natural-move-playing .move-role-n :is(.natural-mount-leg--hind-a, .natural-mount-leg--fore-b) {
  animation-name: natural-mount-leg-a-v3;
}

.is-natural-move-playing .move-role-n :is(.natural-mount-leg--hind-b, .natural-mount-leg--fore-a) {
  animation-name: natural-mount-leg-b-v3;
}

.is-natural-move-playing .move-role-n .natural-body-rig {
  animation-name: natural-rider-seat-v3;
}

@keyframes natural-mount-presence-v3 {
  0% { opacity: 0; transform: translateY(3px) scale(0.92); }
  7%, 90% { opacity: 0.98; transform: translateY(0) scale(1); }
  98%, 100% { opacity: 0; transform: translateY(1px) scale(0.96); }
}

@keyframes natural-mount-gallop-body-v3 {
  0%, 8% { transform: rotate(0) scale(1); }
  11% { transform: rotate(-2deg) scaleX(1.045) scaleY(0.94); }
  28% { transform: rotate(1.5deg) scaleX(0.985) scaleY(1.025); }
  40%, 46% { transform: rotate(-1deg) scaleX(1.06) scaleY(0.91); }
  66% { transform: rotate(1.5deg) scaleX(0.985) scaleY(1.025); }
  79%, 88% { transform: rotate(-1deg) scaleX(1.065) scaleY(0.9); }
  100% { transform: rotate(0) scale(1); }
}

@keyframes natural-mount-leg-a-v3 {
  0%, 9% { transform: rotate(-4deg) translateY(1px) scaleY(1.06); }
  17% { transform: rotate(26deg) translateY(-1px); }
  28% { transform: rotate(-30deg) translateY(-4px) scaleY(0.82); }
  36% { transform: rotate(15deg) translateY(-1px); }
  40%, 46% { transform: rotate(-6deg) translateY(1px) scaleY(1.07); }
  53% { transform: rotate(24deg) translateY(-1px); }
  66% { transform: rotate(-28deg) translateY(-4px) scaleY(0.83); }
  75% { transform: rotate(14deg) translateY(-1px); }
  79%, 89% { transform: rotate(-5deg) translateY(1px) scaleY(1.07); }
  100% { transform: rotate(0); }
}

@keyframes natural-mount-leg-b-v3 {
  0%, 9% { transform: rotate(5deg) translateY(1px) scaleY(1.05); }
  17% { transform: rotate(-25deg) translateY(-3px) scaleY(0.86); }
  28% { transform: rotate(25deg) translateY(-1px); }
  36%, 46% { transform: rotate(-4deg) translateY(1px) scaleY(1.06); }
  53% { transform: rotate(-27deg) translateY(-3px) scaleY(0.84); }
  66% { transform: rotate(24deg) translateY(-1px); }
  75%, 89% { transform: rotate(5deg) translateY(1px) scaleY(1.06); }
  100% { transform: rotate(0); }
}

@keyframes natural-rider-seat-v3 {
  0%, 8% { transform: translate3d(0, -6%, 0) rotate(-2deg); }
  11% { transform: translate3d(0, -4%, 0) rotate(-5deg) scaleY(0.96); }
  28% { transform: translate3d(var(--body-sway), -11%, 0) rotate(2deg); }
  40%, 46% { transform: translate3d(var(--body-counter-sway), -4%, 0) rotate(-4deg) scaleY(0.95); }
  66% { transform: translate3d(var(--body-sway), -12%, 0) rotate(2deg); }
  79%, 88% { transform: translate3d(0, -3%, 0) rotate(-3deg) scaleY(0.95); }
  95% { transform: translate3d(0, -5%, 0) scaleY(1.015); }
  100% { transform: translate3d(0, 0, 0); }
}


/* Grounded locomotion v4: constant-scale carriers and a continuous knight arc. */
.is-natural-move-playing .natural-move-actor.gait-steps-2:not(.move-role-n) {
  animation-name: natural-root-travel-2-v4;
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor.gait-steps-3:not(.move-role-n) {
  animation-name: natural-root-travel-3-v4;
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor.gait-steps-4:not(.move-role-n) {
  animation-name: natural-root-travel-4-v4;
  animation-timing-function: linear;
}

.is-natural-move-playing .natural-move-actor.move-role-n {
  animation-name: natural-knight-arc-v4;
  animation-timing-function: linear;
}

@keyframes natural-root-travel-2-v4 {
  0%, 5% { transform: translate3d(0, 0, 0); }
  10% { transform: translate3d(var(--travel-3-x), calc(var(--travel-3-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  26% { transform: translate3d(var(--travel-35-x), calc(var(--travel-35-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  42% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0); }
  48% { transform: translate3d(var(--travel-54-x), calc(var(--travel-54-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  68% { transform: translate3d(var(--travel-84-x), calc(var(--travel-84-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  86% { transform: translate3d(var(--travel-98-x), calc(var(--travel-98-y) - var(--gait-rise-low)), 0); }
  94% { transform: translate3d(var(--move-x), calc(var(--move-y) - 0.8px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-root-travel-3-v4 {
  0%, 4% { transform: translate3d(0, 0, 0); }
  9% { transform: translate3d(var(--travel-2-x), calc(var(--travel-2-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  24% { transform: translate3d(var(--travel-28-x), calc(var(--travel-28-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  34% { transform: translate3d(var(--travel-35-x), var(--travel-35-y), 0); }
  39% { transform: translate3d(var(--travel-40-x), calc(var(--travel-40-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  55% { transform: translate3d(var(--travel-63-x), calc(var(--travel-63-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  64% { transform: translate3d(var(--travel-69-x), var(--travel-69-y), 0); }
  69% { transform: translate3d(var(--travel-72-x), calc(var(--travel-72-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  85% { transform: translate3d(var(--travel-96-x), calc(var(--travel-96-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  94% { transform: translate3d(var(--move-x), calc(var(--move-y) - 0.7px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-root-travel-4-v4 {
  0%, 4% { transform: translate3d(0, 0, 0); }
  8% { transform: translate3d(var(--travel-1-x), calc(var(--travel-1-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  19% { transform: translate3d(var(--travel-18-x), calc(var(--travel-18-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  27% { transform: translate3d(var(--travel-24-x), var(--travel-24-y), 0); }
  31% { transform: translate3d(var(--travel-28-x), calc(var(--travel-28-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  42% { transform: translate3d(var(--travel-44-x), calc(var(--travel-44-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  50% { transform: translate3d(var(--travel-50-x), var(--travel-50-y), 0); }
  54% { transform: translate3d(var(--travel-54-x), calc(var(--travel-54-y) - var(--gait-rise-low)), 0) rotate(var(--motion-lean)); }
  65% { transform: translate3d(var(--travel-70-x), calc(var(--travel-70-y) - var(--gait-rise)), 0) rotate(var(--motion-lean)); }
  73% { transform: translate3d(var(--travel-76-x), var(--travel-76-y), 0); }
  77% { transform: translate3d(var(--travel-80-x), calc(var(--travel-80-y) - var(--gait-rise-low)), 0) rotate(var(--motion-counter-lean)); }
  89% { transform: translate3d(var(--travel-96-x), calc(var(--travel-96-y) - var(--gait-rise)), 0) rotate(var(--motion-counter-lean)); }
  96% { transform: translate3d(var(--move-x), calc(var(--move-y) - 0.7px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

@keyframes natural-knight-arc-v4 {
  0%, 4% { transform: translate3d(0, 0, 0); }
  9% { transform: translate3d(var(--knight-8-x), calc(var(--knight-8-y) - 2px), 0) rotate(var(--knight-facing-in)); }
  20% { transform: translate3d(var(--knight-18-x), calc(var(--knight-18-y) - var(--hoof-flight)), 0) rotate(var(--knight-facing-in)); }
  32% { transform: translate3d(var(--knight-30-x), calc(var(--knight-30-y) - 2px), 0) rotate(var(--knight-facing-in)); }
  43% { transform: translate3d(var(--knight-42-x), calc(var(--knight-42-y) - var(--hoof-flight)), 0) rotate(var(--knight-facing-in)); }
  54% { transform: translate3d(var(--knight-54-x), calc(var(--knight-54-y) - 2px), 0) rotate(var(--knight-facing-out)); }
  65% { transform: translate3d(var(--knight-66-x), calc(var(--knight-66-y) - var(--hoof-flight)), 0) rotate(var(--knight-facing-out)); }
  76% { transform: translate3d(var(--knight-78-x), calc(var(--knight-78-y) - 2px), 0) rotate(var(--knight-facing-out)); }
  86% { transform: translate3d(var(--knight-88-x), calc(var(--knight-88-y) - var(--hoof-flight)), 0) rotate(var(--knight-facing-out)); }
  94% { transform: translate3d(var(--knight-96-x), calc(var(--knight-96-y) - 1px), 0); }
  100% { transform: translate3d(var(--move-x), var(--move-y), 0); }
}

body:not(.flat-view) .chessboard > .square:hover:not(.is-selected) > .piece-token {
  transform:
    rotateX(calc(-1 * var(--board-tilt)))
    translateY(-9%)
    translateZ(13px)
    scale(1.012);
  filter: brightness(1.06);
}

body:not(.flat-view) .chessboard > .square.is-selected > .piece-token {
  transform:
    rotateX(calc(-1 * var(--board-tilt)))
    translateY(-8%)
    translateZ(14px)
    scale(1.01);
  filter: brightness(1.07);
}

/* source: battle-polish.css */
/* Drop-in, in-place capture choreography. All selectors are intentionally
   namespaced so this sheet can sit after the original battle styles. */
.polished-battle-layer {
  position: absolute;
  z-index: 90;
  inset: 0;
  overflow: visible;
  pointer-events: none;
  transform-style: preserve-3d;
  isolation: isolate;
}

.is-polished-battling .square {
  pointer-events: none;
  transition: filter 180ms ease, box-shadow 180ms ease;
}

.is-polished-battling .square:not(.is-polished-battle-source):not(.is-polished-battle-target):not(.is-polished-battle-destination) {
  filter: brightness(0.58) saturate(0.72);
}

.is-polished-battle-source > .piece-token {
  opacity: 0;
}

.is-polished-battle-target {
  z-index: 78;
  box-shadow:
    inset 0 0 0 2px rgba(255, 231, 164, 0.84),
    inset 0 0 calc(var(--pb-cell) * 0.32) rgba(73, 232, 209, 0.42),
    0 0 calc(var(--pb-cell) * 0.24) rgba(92, 239, 218, 0.5);
}

.is-polished-battle-destination {
  z-index: 76;
  box-shadow:
    inset 0 0 0 2px rgba(230, 197, 118, 0.62),
    inset 0 0 calc(var(--pb-cell, 70px) * 0.24) rgba(236, 194, 94, 0.25);
}

.polished-battle-attacker {
  position: absolute;
  z-index: 98;
  transform: translate3d(0, 0, 28px);
  transform-style: preserve-3d;
  will-change: transform, filter;
}

.polished-battle-attacker .piece-token {
  width: 90%;
  height: 106%;
  filter: brightness(1.12) contrast(1.05) drop-shadow(0 0 calc(var(--pb-cell) * 0.08) var(--piece-gem, #f2d788));
  transition: none;
}

.is-polished-battle-playing .polished-battle-role-p .polished-battle-attacker {
  animation: pb-attacker-thrust var(--pb-duration) cubic-bezier(0.38, 0, 0.2, 1) both;
}

.is-polished-battle-playing .polished-battle-role-n .polished-battle-attacker {
  animation: pb-attacker-lance var(--pb-duration) cubic-bezier(0.32, 0, 0.17, 1) both;
}

.is-polished-battle-playing .polished-battle-role-r .polished-battle-attacker {
  animation: pb-attacker-hammer var(--pb-duration) cubic-bezier(0.5, 0, 0.16, 1) both;
}

.is-polished-battle-playing .polished-battle-role-b .polished-battle-attacker {
  animation: pb-attacker-staff var(--pb-duration) cubic-bezier(0.38, 0, 0.18, 1) both;
}

.is-polished-battle-playing .polished-battle-role-q .polished-battle-attacker {
  animation: pb-attacker-arcana var(--pb-duration) cubic-bezier(0.33, 0, 0.16, 1) both;
}

.is-polished-battle-playing .polished-battle-role-k .polished-battle-attacker {
  animation: pb-attacker-greatsword var(--pb-duration) cubic-bezier(0.42, 0, 0.18, 1) both;
}

/* Optional articulation hooks. They animate future grouped SVG soldiers and
   also give today's weapon paths a visible wind-up and follow-through. */
.polished-battle-attacker :is(
  .soldier-head,
  .soldier-torso,
  .soldier-cape,
  .soldier-legs,
  .soldier-arm--weapon,
  .soldier-weapon-arm,
  .soldier-arm--shield,
  .soldier-shield-arm,
  .soldier-weapon,
  .soldier-greatsword,
  .soldier-casting-arm,
  [data-soldier-part]
) {
  transform-box: fill-box;
}

.polished-battle-attacker :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, [data-soldier-part="weapon-arm"]) {
  transform-origin: 50% 82%;
}

.polished-battle-attacker :is(.soldier-arm--shield, .soldier-shield-arm, [data-soldier-part="shield-arm"]) {
  transform-origin: 50% 48%;
}

.polished-battle-attacker :is(.soldier-head, [data-soldier-part="head"]) {
  transform-origin: 50% 86%;
}

.polished-battle-attacker :is(.soldier-cape, [data-soldier-part="cape"]) {
  transform-origin: 50% 14%;
}

.is-polished-battle-playing .polished-battle--thrust :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, [data-soldier-part="weapon-arm"]) {
  animation: pb-articulate-thrust var(--pb-duration) cubic-bezier(0.4, 0, 0.2, 1) both;
}

.is-polished-battle-playing .polished-battle--lance :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, [data-soldier-part="weapon-arm"]) {
  animation: pb-articulate-lance var(--pb-duration) cubic-bezier(0.38, 0, 0.16, 1) both;
}

.is-polished-battle-playing .polished-battle--hammer :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, [data-soldier-part="weapon-arm"]) {
  animation: pb-articulate-hammer var(--pb-duration) cubic-bezier(0.48, 0, 0.16, 1) both;
}

.is-polished-battle-playing .polished-battle--greatsword :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, [data-soldier-part="weapon-arm"]) {
  animation: pb-articulate-greatsword var(--pb-duration) cubic-bezier(0.44, 0, 0.18, 1) both;
}

.is-polished-battle-playing .polished-battle--magic :is(.soldier-arm--weapon, .soldier-weapon-arm, .soldier-weapon, .soldier-greatsword, .soldier-casting-arm, [data-soldier-part="weapon-arm"]) {
  animation: pb-articulate-cast var(--pb-duration) ease-in-out both;
}

.is-polished-battle-playing .polished-battle--melee :is(.soldier-arm--shield, .soldier-shield-arm, [data-soldier-part="shield-arm"]) {
  animation: pb-articulate-guard var(--pb-duration) ease-in-out both;
}

.is-polished-battle-playing .polished-battle--magic :is(.soldier-cape, [data-soldier-part="cape"]) {
  animation: pb-articulate-cape var(--pb-duration) ease-in-out both;
}

/* Defender answers the feint first, regains stance, then yields only to the
   decisive contact. The brief final hit-stop is applied by JS. */
.is-polished-battle-playing .is-polished-battle-target > .piece-token {
  z-index: 94;
  animation: pb-defender-knockback var(--pb-duration, 1900ms) cubic-bezier(0.4, 0, 0.4, 1) both;
  will-change: transform, filter, opacity;
}

.is-polished-battle-playing[data-polished-battle-response="evade"] .is-polished-battle-target > .piece-token {
  animation-name: pb-defender-evade;
}

.is-polished-battle-playing[data-polished-battle-piece="b"] .is-polished-battle-target > .piece-token,
.is-polished-battle-playing[data-polished-battle-piece="q"] .is-polished-battle-target > .piece-token {
  animation-name: pb-defender-dissolve;
}

.is-polished-hit-stop {
  filter: brightness(2.35) saturate(0.7) !important;
}

.chessboard.is-polished-battle-parry {
  animation: pb-board-parry 180ms cubic-bezier(0.35, 0, 0.2, 1) both;
}

.chessboard.is-polished-battle-impact {
  animation: pb-board-shake 270ms cubic-bezier(0.35, 0, 0.2, 1) both;
}

/* Travel streak for physical attacks, focused beam for spellcasters. */
.polished-battle-vector {
  position: absolute;
  z-index: 92;
  height: 3px;
  opacity: 0;
  transform: rotate(var(--pb-vector-angle));
  transform-origin: left center;
}

.polished-battle-vector i,
.polished-battle-vector b {
  position: absolute;
  right: 0;
  left: 0;
  display: block;
  height: 2px;
  border-radius: 999px;
  transform-origin: left center;
}

.polished-battle--melee .polished-battle-vector i {
  background: linear-gradient(90deg, transparent, rgba(249, 221, 151, 0.2), #fff2c7 78%, transparent);
  box-shadow: 0 0 5px rgba(255, 236, 186, 0.75), 0 0 10px rgba(221, 170, 66, 0.45);
}

.polished-battle--melee .polished-battle-vector i:nth-child(2) {
  opacity: 0.55;
  transform: translateY(calc(var(--pb-cell) * 0.05)) rotate(2deg);
}

.polished-battle--melee .polished-battle-vector b {
  display: none;
}

.is-polished-battle-playing .polished-battle--melee .polished-battle-vector {
  animation: pb-melee-travel var(--pb-duration) ease-out both;
}

.polished-battle--magic .polished-battle-vector {
  z-index: 96;
  height: 8px;
}

.polished-battle--magic .polished-battle-vector i:first-child {
  height: 4px;
  background: linear-gradient(90deg, transparent 2%, #5de3d0 24%, #fff 58%, #f0c777 100%);
  box-shadow:
    0 0 4px #fff,
    0 0 calc(var(--pb-cell) * 0.1) #55ead3,
    0 0 calc(var(--pb-cell) * 0.22) rgba(118, 247, 225, 0.84);
}

.polished-battle--magic .polished-battle-vector i:nth-child(2) {
  top: -3px;
  height: 1px;
  background: linear-gradient(90deg, transparent, #f5c9ff 38%, #fff6cc);
  box-shadow: 0 0 7px #c381ff;
}

.polished-battle--magic .polished-battle-vector b {
  right: auto;
  left: 0;
  width: calc(var(--pb-cell) * 0.13);
  height: calc(var(--pb-cell) * 0.13);
  border: 1px solid #fff;
  border-radius: 50%;
  background: #9bfff0;
  box-shadow: 0 0 8px #fff, 0 0 calc(var(--pb-cell) * 0.2) #4ee7cf;
  transform: translate(-50%, -45%);
}

.polished-battle--arcana .polished-battle-vector i:nth-child(2) {
  top: 6px;
  height: 3px;
  background: linear-gradient(90deg, transparent, #c393ff 36%, #fff 70%, #f3c565);
  transform: rotate(-2deg);
}

.is-polished-battle-playing .polished-battle--magic .polished-battle-vector {
  animation: pb-magic-vector var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle--magic .polished-battle-vector i {
  animation: pb-magic-beam var(--pb-duration) cubic-bezier(0.4, 0, 0.18, 1) both;
}

.is-polished-battle-playing .polished-battle--magic .polished-battle-vector b {
  animation: pb-magic-bolt var(--pb-duration) cubic-bezier(0.35, 0, 0.12, 1) both;
}

/* Runic casting circles. */
.polished-battle-caster-sigil,
.polished-battle-impact-sigil {
  position: absolute;
  z-index: 95;
  display: none;
  width: 1px;
  height: 1px;
  color: #c8fff5;
  pointer-events: none;
}

.polished-battle--magic :is(.polished-battle-caster-sigil, .polished-battle-impact-sigil) {
  display: block;
}

.polished-battle-caster-sigil i,
.polished-battle-impact-sigil i {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(var(--pb-cell) * 0.72);
  height: calc(var(--pb-cell) * 0.72);
  border: 1px solid currentColor;
  border-radius: 50%;
  opacity: 0;
  box-shadow: inset 0 0 calc(var(--pb-cell) * 0.12) rgba(94, 242, 219, 0.2), 0 0 8px rgba(105, 244, 223, 0.65);
  transform: translate(-50%, -50%) rotate(0) scale(0.2);
}

.polished-battle-caster-sigil i:nth-child(2),
.polished-battle-impact-sigil i:nth-child(2) {
  width: calc(var(--pb-cell) * 0.52);
  height: calc(var(--pb-cell) * 0.52);
  border-style: dashed;
  color: #f4ca73;
}

.polished-battle-caster-sigil i:nth-child(3),
.polished-battle-impact-sigil i:nth-child(3) {
  width: calc(var(--pb-cell) * 0.9);
  height: calc(var(--pb-cell) * 0.9);
  border-color: rgba(204, 154, 255, 0.72);
  border-style: dotted;
}

.polished-battle-caster-sigil span,
.polished-battle-impact-sigil span {
  position: absolute;
  opacity: 0;
  text-shadow: 0 0 7px currentColor;
  transform: translate(-50%, -50%);
}

.polished-battle-caster-sigil span:nth-of-type(1),
.polished-battle-impact-sigil span:nth-of-type(1) { left: calc(var(--pb-cell) * -0.25); }
.polished-battle-caster-sigil span:nth-of-type(2),
.polished-battle-impact-sigil span:nth-of-type(2) { left: calc(var(--pb-cell) * 0.25); }
.polished-battle-caster-sigil span:nth-of-type(3),
.polished-battle-impact-sigil span:nth-of-type(3) { top: calc(var(--pb-cell) * -0.26); }

.is-polished-battle-playing .polished-battle-caster-sigil i {
  animation: pb-caster-sigil var(--pb-duration) ease-in-out both;
}

.is-polished-battle-playing .polished-battle-caster-sigil i:nth-child(2) { animation-direction: reverse; }
.is-polished-battle-playing .polished-battle-caster-sigil i:nth-child(3) { animation-duration: calc(var(--pb-duration) * 0.86); }

.is-polished-battle-playing .polished-battle-caster-sigil span {
  animation: pb-caster-glyph var(--pb-duration) ease-in-out both;
}

.has-polished-battle-parry .polished-battle-impact-sigil i {
  animation: pb-parry-sigil 360ms ease-out both;
}

.has-polished-battle-parry .polished-battle-impact-sigil i:nth-child(2) { animation-delay: 28ms; }
.has-polished-battle-parry .polished-battle-impact-sigil i:nth-child(3) { animation-delay: 54ms; }

.has-polished-battle-impact .polished-battle-impact-sigil i {
  animation: pb-impact-sigil 520ms cubic-bezier(0.16, 0.72, 0.2, 1) both;
}

.has-polished-battle-impact .polished-battle-impact-sigil i:nth-child(2) { animation-delay: 35ms; }
.has-polished-battle-impact .polished-battle-impact-sigil i:nth-child(3) { animation-delay: 70ms; }
.has-polished-battle-impact .polished-battle-impact-sigil span { animation: pb-impact-glyph 460ms ease-out both; }

/* Physical strike shapes. Pawn thrusts, knight cleaves downward, rook smashes,
   and king draws a broad royal blade arc. */
.polished-battle-strike {
  position: absolute;
  z-index: 102;
  display: none;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.polished-battle--melee .polished-battle-strike {
  display: block;
}

.polished-battle-strike i {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
}

.polished-battle--thrust .polished-battle-strike i:first-child {
  width: calc(var(--pb-cell) * 1.18);
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #f4c769 52%, #fff 88%);
  box-shadow: 0 0 5px #fff, 0 0 13px #d99d37;
  transform-origin: right center;
}

.polished-battle--thrust .polished-battle-strike i:nth-child(2) {
  width: calc(var(--pb-cell) * 0.25);
  height: calc(var(--pb-cell) * 0.25);
  border: 2px solid #fff0b8;
  transform: translate(-50%, -50%) rotate(45deg);
}

.polished-battle--lance .polished-battle-strike i,
.polished-battle--greatsword .polished-battle-strike i {
  width: calc(var(--pb-cell) * 1.08);
  height: calc(var(--pb-cell) * 0.66);
  border-top: max(2px, calc(var(--pb-cell) * 0.04)) solid #fff3c6;
  border-radius: 50%;
  filter: drop-shadow(0 0 4px #fff) drop-shadow(0 0 8px #dba545);
}

.polished-battle--lance .polished-battle-strike i:nth-child(2) {
  width: calc(var(--pb-cell) * 0.84);
  border-color: #6fe7d5;
}

.polished-battle--greatsword .polished-battle-strike i {
  width: calc(var(--pb-cell) * 1.32);
  height: calc(var(--pb-cell) * 0.78);
  border-width: max(3px, calc(var(--pb-cell) * 0.05));
}

.polished-battle--greatsword .polished-battle-strike i:nth-child(2) {
  width: calc(var(--pb-cell) * 1.08);
  border-color: #80ebd8;
}

.polished-battle--hammer .polished-battle-strike i:first-child,
.polished-battle--hammer .polished-battle-strike i:nth-child(2) {
  width: calc(var(--pb-cell) * 0.72);
  height: max(4px, calc(var(--pb-cell) * 0.065));
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #fff1bd, transparent);
  box-shadow: 0 0 7px #fff, 0 0 14px #d6a143;
}

.polished-battle--hammer .polished-battle-strike i:nth-child(2) {
  transform: rotate(90deg);
}

/* The first exchange is deliberately smaller than the finishing blow. */
.has-polished-battle-parry.polished-battle--thrust .polished-battle-strike i:first-child {
  animation: pb-parry-thrust 300ms cubic-bezier(0.18, 0.68, 0.25, 1) both;
}

.has-polished-battle-parry.polished-battle--thrust .polished-battle-strike i:nth-child(2) {
  animation: pb-parry-diamond 320ms ease-out 18ms both;
}

.has-polished-battle-parry.polished-battle--lance .polished-battle-strike i {
  animation: pb-parry-lance 340ms cubic-bezier(0.18, 0.68, 0.25, 1) both;
}

.has-polished-battle-parry.polished-battle--lance .polished-battle-strike i:nth-child(2) {
  animation-delay: 28ms;
}

.has-polished-battle-parry.polished-battle--hammer .polished-battle-strike i {
  animation: pb-parry-hammer 320ms cubic-bezier(0.18, 0.68, 0.25, 1) both;
}

.has-polished-battle-parry.polished-battle--greatsword .polished-battle-strike i {
  animation: pb-parry-greatsword 360ms cubic-bezier(0.18, 0.68, 0.25, 1) both;
}

.has-polished-battle-parry.polished-battle--greatsword .polished-battle-strike i:nth-child(2) {
  animation-delay: 30ms;
}

.has-polished-battle-impact.polished-battle--thrust .polished-battle-strike i:first-child {
  animation: pb-strike-thrust 330ms cubic-bezier(0.1, 0.72, 0.2, 1) both;
}

.has-polished-battle-impact.polished-battle--thrust .polished-battle-strike i:nth-child(2) {
  animation: pb-strike-diamond 360ms ease-out 35ms both;
}

.has-polished-battle-impact.polished-battle--lance .polished-battle-strike i {
  animation: pb-strike-lance 430ms cubic-bezier(0.12, 0.74, 0.2, 1) both;
}

.has-polished-battle-impact.polished-battle--lance .polished-battle-strike i:nth-child(2) { animation-delay: 42ms; }

.has-polished-battle-impact.polished-battle--hammer .polished-battle-strike i {
  animation: pb-strike-hammer 390ms cubic-bezier(0.12, 0.75, 0.22, 1) both;
}

.has-polished-battle-impact.polished-battle--greatsword .polished-battle-strike i {
  animation: pb-strike-greatsword 510ms cubic-bezier(0.12, 0.72, 0.2, 1) both;
}

.has-polished-battle-impact.polished-battle--greatsword .polished-battle-strike i:nth-child(2) { animation-delay: 48ms; }

/* Shared contact flash, rings, crater and size-aware debris. */
.polished-battle-contact,
.polished-battle-debris,
.polished-battle-ground {
  position: absolute;
  z-index: 108;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.polished-battle-contact i,
.polished-battle-contact b,
.polished-battle-contact span {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0);
}

.polished-battle-contact i:first-child {
  width: calc(var(--pb-cell) * 0.56);
  height: calc(var(--pb-cell) * 0.56);
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0 10%, #fff3b4 20%, rgba(81, 241, 218, 0.74) 44%, transparent 72%);
  box-shadow: 0 0 calc(var(--pb-cell) * 0.2) #fff, 0 0 calc(var(--pb-cell) * 0.46) #59e8d2;
  mix-blend-mode: screen;
}

.polished-battle-contact i:nth-child(2),
.polished-battle-contact span {
  width: calc(var(--pb-cell) * 0.44);
  height: calc(var(--pb-cell) * 0.44);
  border: 2px solid #fff4ca;
  border-radius: 50%;
  box-shadow: 0 0 8px #fff, 0 0 calc(var(--pb-cell) * 0.2) #dca44c;
}

.polished-battle-contact span {
  width: calc(var(--pb-cell) * 0.72);
  height: calc(var(--pb-cell) * 0.72);
  border-color: #70eedb;
}

.polished-battle-contact b {
  width: max(3px, calc(var(--pb-cell) * 0.04));
  height: calc(var(--pb-cell) * 1.1);
  border-radius: 999px;
  background: linear-gradient(transparent, #fff, #f7cf72, #fff, transparent);
  box-shadow: 0 0 7px #fff, 0 0 15px #e8b850;
  transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(0);
}

.has-polished-battle-parry .polished-battle-contact i:first-child {
  animation: pb-parry-flash 300ms cubic-bezier(0.18, 0.68, 0.25, 1) both;
}

.has-polished-battle-parry .polished-battle-contact i:nth-child(2) {
  animation: pb-parry-ring 390ms ease-out 18ms both;
}

.has-polished-battle-parry .polished-battle-contact span {
  animation: pb-parry-ring 440ms ease-out 50ms both;
}

.has-polished-battle-parry .polished-battle-contact b {
  animation: pb-parry-blade 330ms ease-out both;
}

.has-polished-battle-impact .polished-battle-contact i:first-child {
  animation: pb-contact-flash 380ms cubic-bezier(0.12, 0.72, 0.2, 1) both;
}

.has-polished-battle-impact .polished-battle-contact i:nth-child(2) {
  animation: pb-contact-ring 560ms ease-out 24ms both;
}

.has-polished-battle-impact .polished-battle-contact span {
  animation: pb-contact-ring 680ms ease-out 72ms both;
}

.has-polished-battle-impact .polished-battle-contact b {
  animation: pb-contact-blade 420ms ease-out both;
}

.polished-battle--magic .polished-battle-contact b {
  width: calc(var(--pb-cell) * 0.14);
  height: calc(var(--pb-cell) * 0.86);
  background: linear-gradient(transparent, #bcfff6, #fff, #c693ff, transparent);
  transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 90deg)) scaleY(0);
}

.polished-battle-ground {
  z-index: 101;
}

.polished-battle-ground i {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(var(--pb-cell) * 0.68);
  height: 1px;
  opacity: 0;
  background: linear-gradient(90deg, #f5d68b, rgba(52, 29, 16, 0.92), transparent);
  box-shadow: 0 0 3px rgba(246, 208, 117, 0.68);
  transform-origin: left center;
}

.polished-battle-ground i:first-child { transform: rotate(22deg) scaleX(0); }
.polished-battle-ground i:nth-child(2) { transform: rotate(148deg) scaleX(0); }

.polished-battle-ground b {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(var(--pb-cell) * 0.75);
  height: calc(var(--pb-cell) * 0.25);
  border-radius: 50%;
  opacity: 0;
  background: radial-gradient(ellipse, rgba(218, 178, 94, 0.45), rgba(30, 22, 15, 0.2) 48%, transparent 72%);
  filter: blur(calc(var(--pb-cell) * 0.035));
  transform: translate(-50%, -20%) scale(0.2);
}

.polished-battle--magic .polished-battle-ground i {
  background: linear-gradient(90deg, #8affec, #9a6ed2, transparent);
}

.has-polished-battle-impact .polished-battle-ground i {
  animation: pb-ground-crack 760ms ease-out both;
}

.has-polished-battle-impact .polished-battle-ground i:nth-child(2) { animation-delay: 30ms; }
.has-polished-battle-impact .polished-battle-ground b { animation: pb-ground-dust 690ms ease-out both; }

.polished-battle-debris i {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: var(--pb-debris-size);
  height: calc(var(--pb-debris-size) * 0.66);
  border-radius: 40% 10% 50% 20%;
  opacity: 0;
  background: var(--pb-debris-color);
  box-shadow: 0 0 calc(var(--pb-debris-size) * 1.8) var(--pb-debris-color);
}

.polished-battle--magic .polished-battle-debris i:nth-child(3n) {
  border-radius: 50%;
  clip-path: polygon(50% 0, 63% 36%, 100% 50%, 63% 64%, 50% 100%, 37% 64%, 0 50%, 37% 36%);
}

.has-polished-battle-impact .polished-battle-debris i {
  animation: pb-debris-flight 720ms cubic-bezier(0.15, 0.64, 0.25, 1) var(--pb-debris-delay) both;
}

/* Battle status is deliberately compact and leaves the actors readable. */
.polished-battle-hud {
  position: absolute;
  z-index: 118;
  top: 1.5%;
  left: 50%;
  display: flex;
  width: max-content;
  max-width: 92%;
  min-height: 40px;
  gap: 12px;
  align-items: center;
  padding: 7px 8px 7px 14px;
  border: 1px solid rgba(236, 204, 126, 0.68);
  border-radius: 3px;
  color: #eee7d5;
  background:
    linear-gradient(90deg, rgba(27, 20, 13, 0.28), transparent 30%),
    rgba(5, 10, 16, 0.92);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.58), inset 0 0 22px rgba(70, 218, 198, 0.1);
  backdrop-filter: blur(11px);
  pointer-events: auto;
  transform: translateX(-50%);
  animation: pb-hud-enter 260ms cubic-bezier(0.16, 0.72, 0.2, 1) both;
}

.polished-battle-hud--magic {
  border-color: rgba(103, 231, 211, 0.66);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.58), inset 0 0 24px rgba(111, 97, 206, 0.18);
}

.polished-battle-hud > span { min-width: 0; }

.polished-battle-hud small,
.polished-battle-hud strong {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.polished-battle-hud small {
  color: #e2bd6b;
  font-size: 6px;
  letter-spacing: 0.19em;
}

.polished-battle-hud--magic small { color: #74e8d6; }

.polished-battle-hud strong {
  margin-top: 2px;
  font-family: var(--serif);
  font-size: 10px;
  font-weight: 500;
}

.polished-battle-skip {
  min-height: 27px;
  padding: 5px 8px;
  border: 1px solid rgba(230, 201, 130, 0.34);
  border-radius: 2px;
  color: #d2cabb;
  background: rgba(18, 25, 31, 0.9);
  font-size: 7px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.polished-battle-skip:hover,
.polished-battle-skip:focus-visible {
  border-color: rgba(244, 214, 141, 0.8);
  color: #fff4d3;
  outline: none;
  box-shadow: 0 0 12px rgba(227, 188, 96, 0.28);
}

.polished-battle-skip span {
  margin-left: 4px;
  color: #7f8b88;
  font-size: 6px;
}

@keyframes pb-attacker-thrust {
  0%, 9% { transform: translate3d(0, 0, 28px) scale(1); filter: brightness(1); }
  18% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 24px) rotate(calc(var(--pb-facing) * -6deg)) scale(0.97, 1.03); }
  30% { transform: translate3d(var(--pb-feint-x), var(--pb-feint-y), 32px) rotate(calc(var(--pb-facing) * -2deg)) scale(1.05); }
  36%, 40% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 36px) rotate(calc(var(--pb-facing) * 5deg)) scale(1.1, 0.97); filter: brightness(1.22); }
  48% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 28px) rotate(calc(var(--pb-facing) * -5deg)) scale(0.99, 1.03); filter: brightness(1); }
  58% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 23px) rotate(calc(var(--pb-facing) * -9deg)) scale(0.95, 1.05); }
  66% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 35px) rotate(calc(var(--pb-facing) * -2deg)) scale(1.08); }
  72%, 76% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 43px) rotate(calc(var(--pb-facing) * 10deg)) scale(1.2, 0.96); filter: brightness(1.38); }
  84% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 31px) rotate(calc(var(--pb-facing) * -4deg)) scale(1.02); filter: brightness(1.05); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px) scale(1); filter: brightness(1); }
}

@keyframes pb-attacker-lance {
  0%, 10% { transform: translate3d(0, 0, 28px) rotate(0) scale(1); filter: brightness(1); }
  18% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 22px) rotate(calc(var(--pb-facing) * -8deg)) scale(0.95); }
  29% { transform: translate3d(var(--pb-feint-leap-x), var(--pb-feint-leap-y), 60px) rotate(calc(var(--pb-facing) * -10deg)) scale(1.08); }
  37%, 41% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 47px) rotate(calc(var(--pb-facing) * 11deg)) scale(1.13); filter: brightness(1.24); }
  48% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 25px) rotate(calc(var(--pb-facing) * -5deg)) scale(0.98); filter: brightness(1); }
  57% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 19px) rotate(calc(var(--pb-facing) * -11deg)) scale(0.94, 0.98); }
  66% { transform: translate3d(var(--pb-leap-x), var(--pb-leap-y), 84px) rotate(calc(var(--pb-facing) * -13deg)) scale(1.12); }
  73%, 77% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 48px) rotate(calc(var(--pb-facing) * 16deg)) scale(1.2); filter: brightness(1.4); }
  85% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 34px) rotate(calc(var(--pb-facing) * -5deg)) scale(1.03); filter: brightness(1.04); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px) rotate(0) scale(1); filter: brightness(1); }
}

@keyframes pb-attacker-hammer {
  0%, 11% { transform: translate3d(0, 0, 28px) scale(1); filter: brightness(1); }
  20% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 23px) rotate(calc(var(--pb-facing) * -6deg)) scale(1.06, 0.97); }
  31% { transform: translate3d(var(--pb-feint-x), var(--pb-feint-y), 31px) rotate(calc(var(--pb-facing) * -2deg)) scale(1.1); }
  39%, 42% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 32px) rotate(calc(var(--pb-facing) * 4deg)) scale(1.16, 0.94); filter: brightness(1.2); }
  49% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 27px) rotate(calc(var(--pb-facing) * -4deg)) scale(1.04); filter: brightness(1); }
  59% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 20px) rotate(calc(var(--pb-facing) * -10deg)) scale(1.12, 0.94); }
  68% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 36px) rotate(calc(var(--pb-facing) * -3deg)) scale(1.14); }
  74%, 78% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 34px) rotate(calc(var(--pb-facing) * 8deg)) scale(1.25, 0.92); filter: brightness(1.34); }
  86% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 29px) scale(1.06); filter: brightness(1.04); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px) scale(1); filter: brightness(1); }
}

@keyframes pb-attacker-staff {
  0%, 10% { transform: translate3d(0, 0, 28px) scale(1); filter: brightness(1); }
  19% { transform: translate3d(var(--pb-windup-x), calc(var(--pb-windup-y) - var(--pb-cell) * 0.06), 39px) rotate(calc(var(--pb-facing) * -3deg)) scale(1.04); filter: brightness(1.14); }
  31% { transform: translate3d(var(--pb-feint-x), var(--pb-feint-y), 48px) scale(1.09); filter: brightness(1.28); }
  36%, 40% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 52px) rotate(calc(var(--pb-facing) * 4deg)) scale(1.12); filter: brightness(1.42); }
  48% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 34px) rotate(calc(var(--pb-facing) * -3deg)) scale(1.01); filter: brightness(1.08); }
  58% { transform: translate3d(var(--pb-windup-x), calc(var(--pb-windup-y) - var(--pb-cell) * 0.1), 45px) rotate(calc(var(--pb-facing) * -5deg)) scale(1.08); filter: brightness(1.24); }
  67% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 57px) scale(1.13); filter: brightness(1.38); }
  72%, 76% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 60px) rotate(calc(var(--pb-facing) * 6deg)) scale(1.16); filter: brightness(1.54); }
  84% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 38px) scale(1.03); filter: brightness(1.14); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px) scale(1); filter: brightness(1); }
}

@keyframes pb-attacker-arcana {
  0%, 9% { transform: translate3d(0, 0, 30px) scale(1); filter: brightness(1); }
  18% { transform: translate3d(var(--pb-windup-x), calc(var(--pb-windup-y) - var(--pb-cell) * 0.1), 48px) rotate(calc(var(--pb-facing) * -4deg)) scale(1.06); filter: brightness(1.18); }
  31% { transform: translate3d(var(--pb-feint-x), calc(var(--pb-feint-y) - var(--pb-cell) * 0.06), 58px) rotate(calc(var(--pb-facing) * 2deg)) scale(1.11); filter: brightness(1.32); }
  37%, 41% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 62px) rotate(calc(var(--pb-facing) * 5deg)) scale(1.14); filter: brightness(1.46); }
  49% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 38px) rotate(calc(var(--pb-facing) * -3deg)) scale(1.02); filter: brightness(1.1); }
  58% { transform: translate3d(var(--pb-windup-x), calc(var(--pb-windup-y) - var(--pb-cell) * 0.15), 56px) rotate(calc(var(--pb-facing) * -6deg)) scale(1.1); filter: brightness(1.28); }
  68% { transform: translate3d(var(--pb-approach-x), calc(var(--pb-approach-y) - var(--pb-cell) * 0.08), 67px) rotate(calc(var(--pb-facing) * 3deg)) scale(1.15); filter: brightness(1.42); }
  73%, 77% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 70px) rotate(calc(var(--pb-facing) * 8deg)) scale(1.2); filter: brightness(1.58); }
  85% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 42px) scale(1.06); filter: brightness(1.16); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 30px) scale(1); filter: brightness(1); }
}

@keyframes pb-attacker-greatsword {
  0%, 10% { transform: translate3d(0, 0, 30px) scale(1); filter: brightness(1); }
  19% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 25px) rotate(calc(var(--pb-facing) * -8deg)) scale(1.05); }
  31% { transform: translate3d(var(--pb-feint-x), var(--pb-feint-y), 35px) rotate(calc(var(--pb-facing) * -4deg)) scale(1.09); }
  38%, 42% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 40px) rotate(calc(var(--pb-facing) * 8deg)) scale(1.15); filter: brightness(1.24); }
  49% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 30px) rotate(calc(var(--pb-facing) * -5deg)) scale(1.03); filter: brightness(1); }
  59% { transform: translate3d(var(--pb-windup-x), var(--pb-windup-y), 23px) rotate(calc(var(--pb-facing) * -12deg)) scale(1.08); }
  68% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 39px) rotate(calc(var(--pb-facing) * -5deg)) scale(1.12); }
  74%, 78% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 47px) rotate(calc(var(--pb-facing) * 14deg)) scale(1.22); filter: brightness(1.4); }
  86% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 33px) rotate(calc(var(--pb-facing) * -3deg)) scale(1.05); filter: brightness(1.05); }
  100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 30px) rotate(0) scale(1); filter: brightness(1); }
}

@keyframes pb-defender-knockback {
  0%, 27% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); filter: brightness(1); }
  33% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * -0.05), calc(var(--pb-knock-y) * -0.05 - 7%), 15px) rotate(calc(var(--pb-knock-spin) * -0.05)) scale(1.03); }
  36%, 41% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * -0.11), calc(var(--pb-knock-y) * -0.1 - 7%), 19px) rotate(calc(var(--pb-knock-spin) * -0.1)) scale(1.06); filter: brightness(1.2); }
  49% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.04), calc(var(--pb-knock-y) * 0.03 - 7%), 13px) scale(0.99); filter: brightness(1); }
  59%, 68% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) scale(1); }
  73%, 77% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.12), calc(var(--pb-knock-y) * 0.1 - 8%), 24px) rotate(calc(var(--pb-knock-spin) * 0.1)) scale(1.08); filter: brightness(1.38); }
  85% { opacity: 0.88; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.56), calc(var(--pb-knock-y) * 0.5), 15px) rotate(calc(var(--pb-knock-spin) * 0.56)) scale(0.87); filter: brightness(0.76); }
  100% { opacity: 0; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(var(--pb-knock-x), var(--pb-knock-y), 0) rotate(var(--pb-knock-spin)) scale(0.18); filter: brightness(0.18) blur(calc(var(--pb-cell) * 0.045)); }
}

@keyframes pb-defender-evade {
  0%, 25% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); filter: brightness(1); }
  32% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-evade-x) * 0.55), calc(var(--pb-evade-y) * 0.55 - 7%), 16px) rotate(calc(var(--pb-knock-spin) * -0.04)) scale(0.98); }
  36%, 42% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(var(--pb-evade-x), calc(var(--pb-evade-y) - 8%), 22px) rotate(calc(var(--pb-knock-spin) * -0.08)) scale(0.96, 1.03); filter: brightness(1.12); }
  50% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-evade-x) * 0.28), calc(var(--pb-evade-y) * 0.22 - 7%), 13px) scale(1.01); filter: brightness(1); }
  59%, 68% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); }
  73%, 77% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.12), calc(var(--pb-knock-y) * 0.1 - 8%), 24px) rotate(calc(var(--pb-knock-spin) * 0.1)) scale(1.08); filter: brightness(1.38); }
  85% { opacity: 0.88; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.56), calc(var(--pb-knock-y) * 0.5), 15px) rotate(calc(var(--pb-knock-spin) * 0.56)) scale(0.87); filter: brightness(0.76); }
  100% { opacity: 0; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(var(--pb-knock-x), var(--pb-knock-y), 0) rotate(var(--pb-knock-spin)) scale(0.18); filter: brightness(0.18) blur(calc(var(--pb-cell) * 0.045)); }
}

@keyframes pb-defender-dissolve {
  0%, 27% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); filter: brightness(1) saturate(1); }
  34%, 41% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(var(--pb-evade-x), calc(var(--pb-evade-y) - 8%), 21px) scale(1.04); filter: brightness(1.28) saturate(0.82); }
  50% { transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-evade-x) * 0.22), calc(var(--pb-evade-y) * 0.2 - 7%), 14px) scale(1); filter: brightness(1.04) saturate(1); }
  59%, 68% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px); filter: brightness(1) saturate(1); }
  73%, 77% { opacity: 1; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.1), calc(var(--pb-knock-y) * 0.08 - 10%), 30px) rotate(calc(var(--pb-knock-spin) * 0.08)) scale(1.1); filter: brightness(1.5) saturate(0.58); }
  85% { opacity: 0.62; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(calc(var(--pb-knock-x) * 0.5), calc(var(--pb-knock-y) * 0.32 - 12%), 35px) rotate(calc(var(--pb-knock-spin) * 0.4)) scale(0.72, 1.08); filter: brightness(1.16) saturate(0.25) blur(1px); }
  100% { opacity: 0; transform: rotateX(calc(-1 * var(--board-tilt))) translate3d(var(--pb-knock-x), calc(var(--pb-knock-y) - var(--pb-cell) * 0.34), 45px) rotate(var(--pb-knock-spin)) scale(0.08, 1.28); filter: brightness(1.55) saturate(0) blur(calc(var(--pb-cell) * 0.08)); }
}

@keyframes pb-articulate-thrust {
  0%, 14% { transform: rotate(0) translate(0, 0); }
  22% { transform: rotate(calc(var(--pb-facing) * -16deg)) translate(calc(var(--pb-facing) * -3%), 2%); }
  35%, 40% { transform: rotate(calc(var(--pb-facing) * 11deg)) translate(calc(var(--pb-facing) * 10%), -3%); }
  49% { transform: rotate(calc(var(--pb-facing) * -8deg)) translate(0, 1%); }
  59% { transform: rotate(calc(var(--pb-facing) * -22deg)) translate(calc(var(--pb-facing) * -5%), 3%); }
  72%, 78% { transform: rotate(calc(var(--pb-facing) * 20deg)) translate(calc(var(--pb-facing) * 18%), -5%) scaleY(1.08); }
  86%, 100% { transform: rotate(0) translate(0, 0); }
}

@keyframes pb-articulate-lance {
  0%, 15% { transform: rotate(0); }
  24% { transform: rotate(calc(var(--pb-facing) * -20deg)) translateY(-5%); }
  37%, 42% { transform: rotate(calc(var(--pb-facing) * 16deg)) translate(calc(var(--pb-facing) * 8%), 2%); }
  50% { transform: rotate(calc(var(--pb-facing) * -8deg)); }
  59% { transform: rotate(calc(var(--pb-facing) * -28deg)) translateY(-8%); }
  73%, 79% { transform: rotate(calc(var(--pb-facing) * 28deg)) translate(calc(var(--pb-facing) * 13%), 4%); }
  87%, 100% { transform: rotate(0); }
}

@keyframes pb-articulate-hammer {
  0%, 16% { transform: rotate(0); }
  26% { transform: rotate(calc(var(--pb-facing) * -34deg)) translateY(-7%); }
  39%, 43% { transform: rotate(calc(var(--pb-facing) * 19deg)) translateY(4%); }
  50% { transform: rotate(calc(var(--pb-facing) * -10deg)); }
  58%, 67% { transform: rotate(calc(var(--pb-facing) * -62deg)) translateY(-13%); }
  74%, 80% { transform: rotate(calc(var(--pb-facing) * 36deg)) translateY(9%); }
  88%, 100% { transform: rotate(0); }
}

@keyframes pb-articulate-greatsword {
  0%, 15% { transform: rotate(0); }
  25% { transform: rotate(calc(var(--pb-facing) * -28deg)) translateY(-5%); }
  38%, 43% { transform: rotate(calc(var(--pb-facing) * 22deg)) translate(calc(var(--pb-facing) * 5%), 3%); }
  51% { transform: rotate(calc(var(--pb-facing) * -12deg)); }
  59%, 68% { transform: rotate(calc(var(--pb-facing) * -48deg)) translateY(-9%); }
  74%, 80% { transform: rotate(calc(var(--pb-facing) * 44deg)) translate(calc(var(--pb-facing) * 9%), 5%); }
  88%, 100% { transform: rotate(0); }
}

@keyframes pb-articulate-cast {
  0%, 14% { transform: rotate(0) translateY(0); filter: brightness(1); }
  24% { transform: rotate(calc(var(--pb-facing) * -9deg)) translateY(-5%); filter: brightness(1.12); }
  35%, 41% { transform: rotate(calc(var(--pb-facing) * 6deg)) translate(calc(var(--pb-facing) * 4%), -8%); filter: brightness(1.34); }
  49% { transform: rotate(calc(var(--pb-facing) * -4deg)) translateY(-2%); filter: brightness(1.06); }
  59% { transform: rotate(calc(var(--pb-facing) * -15deg)) translateY(-8%); filter: brightness(1.18); }
  72%, 79% { transform: rotate(calc(var(--pb-facing) * 9deg)) translate(calc(var(--pb-facing) * 7%), -12%); filter: brightness(1.46); }
  87%, 100% { transform: rotate(0) translateY(0); filter: brightness(1); }
}

@keyframes pb-articulate-guard {
  0%, 18% { transform: rotate(0); }
  30%, 42% { transform: rotate(calc(var(--pb-facing) * -9deg)) translate(calc(var(--pb-facing) * -5%), -3%); }
  50% { transform: rotate(0); }
  66%, 79% { transform: rotate(calc(var(--pb-facing) * -10deg)) translate(calc(var(--pb-facing) * -5%), -4%); }
  88%, 100% { transform: rotate(0); }
}

@keyframes pb-articulate-cape {
  0%, 14%, 100% { transform: skewX(0) scaleY(1); }
  29%, 41% { transform: skewX(calc(var(--pb-facing) * -6deg)) scaleY(1.03); }
  49% { transform: skewX(calc(var(--pb-facing) * 5deg)) scaleY(1.02); }
  68%, 79% { transform: skewX(calc(var(--pb-facing) * -9deg)) scaleY(1.07); }
  88% { transform: skewX(calc(var(--pb-facing) * 3deg)) scaleY(1.01); }
}

@keyframes pb-melee-travel {
  0%, 24% { opacity: 0; transform: rotate(var(--pb-vector-angle)) scaleX(0); }
  31% { opacity: 0.28; }
  38%, 41% { opacity: 0.58; transform: rotate(var(--pb-vector-angle)) scaleX(0.84); }
  46%, 60% { opacity: 0; transform: rotate(var(--pb-vector-angle)) scaleX(0.15); }
  68% { opacity: 0.34; }
  74%, 78% { opacity: 0.78; transform: rotate(var(--pb-vector-angle)) scaleX(1); }
  86%, 100% { opacity: 0; transform: rotate(var(--pb-vector-angle)) scaleX(1.03); }
}

@keyframes pb-magic-vector {
  0%, 23% { opacity: 0; }
  30% { opacity: 0.38; }
  36%, 41% { opacity: 0.7; }
  46%, 59% { opacity: 0; }
  66% { opacity: 0.42; }
  72%, 77% { opacity: 0.82; }
  85%, 100% { opacity: 0; }
}

@keyframes pb-magic-beam {
  0%, 24% { transform: scaleX(0); opacity: 0; }
  31% { transform: scaleX(0.58); opacity: 0.38; }
  36%, 41% { transform: scaleX(0.88); opacity: 0.7; }
  46% { transform: scaleX(0.94); opacity: 0; }
  47%, 61% { transform: scaleX(0); opacity: 0; }
  67% { transform: scaleX(0.68); opacity: 0.48; }
  72%, 78% { transform: scaleX(1); opacity: 0.86; }
  85%, 100% { transform: scaleX(1.02); opacity: 0; }
}

@keyframes pb-magic-bolt {
  0%, 24% { left: 0; opacity: 0; transform: translate(-50%, -45%) scale(0.3); }
  30% { opacity: 0.55; }
  36%, 40% { left: 88%; opacity: 0.72; transform: translate(-50%, -45%) scale(0.88); }
  45% { left: 100%; opacity: 0; transform: translate(-50%, -45%) scale(0.25); }
  46%, 62% { left: 0; opacity: 0; transform: translate(-50%, -45%) scale(0.3); }
  67% { opacity: 0.7; }
  72%, 77% { left: 100%; opacity: 0.9; transform: translate(-50%, -45%) scale(1.08); }
  84%, 100% { left: 100%; opacity: 0; transform: translate(-50%, -45%) scale(0); }
}

@keyframes pb-caster-sigil {
  0%, 15% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scale(0.2); }
  27% { opacity: 0.45; }
  36%, 41% { opacity: 0.72; transform: translate(-50%, -50%) rotate(105deg) scale(0.78); }
  48% { opacity: 0; transform: translate(-50%, -50%) rotate(150deg) scale(0.92); }
  54% { opacity: 0; transform: translate(-50%, -50%) rotate(165deg) scale(0.34); }
  66% { opacity: 0.55; }
  72%, 78% { opacity: 0.9; transform: translate(-50%, -50%) rotate(285deg) scale(1); }
  88%, 100% { opacity: 0; transform: translate(-50%, -50%) rotate(360deg) scale(1.12); }
}

@keyframes pb-caster-glyph {
  0%, 22% { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  34%, 41% { opacity: 0.54; transform: translate(-50%, -50%) scale(0.8); }
  48%, 61% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  70%, 78% { opacity: 0.78; transform: translate(-50%, -50%) scale(1); }
  88%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.24); }
}

@keyframes pb-parry-sigil {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(-18deg) scale(0.14); }
  26%, 44% { opacity: 0.48; transform: translate(-50%, -50%) rotate(22deg) scale(0.66); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(74deg) scale(1.02); }
}

@keyframes pb-parry-thrust {
  0% { opacity: 0; transform: translate(-86%, -50%) rotate(var(--pb-arc-angle)) scaleX(0.18); }
  34%, 58% { opacity: 0.68; transform: translate(-92%, -50%) rotate(var(--pb-arc-angle)) scaleX(0.74); }
  100% { opacity: 0; transform: translate(-96%, -50%) rotate(var(--pb-arc-angle)) scaleX(0.86); }
}

@keyframes pb-parry-diamond {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(35deg) scale(0.12); }
  36%, 52% { opacity: 0.56; transform: translate(-50%, -50%) rotate(62deg) scale(0.78); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(112deg) scale(1.18); }
}

@keyframes pb-parry-lance {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 40deg)) scale(0.18) rotate(-32deg); }
  35%, 58% { opacity: 0.64; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 48deg)) scale(0.72) rotate(0); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 52deg)) scale(0.9) rotate(12deg); }
}

@keyframes pb-parry-hammer {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scaleX(0.16); }
  32%, 58% { opacity: 0.62; transform: translate(-50%, -50%) rotate(0) scaleX(0.7); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scaleX(0.88); }
}

@keyframes pb-parry-greatsword {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 36deg)) scale(0.16) rotate(-46deg); }
  34%, 58% { opacity: 0.66; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 34deg)) scale(0.72) rotate(5deg); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 32deg)) scale(0.9) rotate(18deg); }
}

@keyframes pb-parry-flash {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.08); }
  22%, 38% { opacity: 0.58; transform: translate(-50%, -50%) scale(0.72); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.42); }
}

@keyframes pb-parry-ring {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.16); border-width: 2px; }
  24% { opacity: 0.5; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.72); border-width: 0.5px; }
}

@keyframes pb-parry-blade {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(0.08); }
  25%, 52% { opacity: 0.62; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(0.66); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(0.82); }
}

@keyframes pb-impact-sigil {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scale(0.1); }
  22% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(145deg) scale(1.75); }
}

@keyframes pb-impact-glyph {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(0.4) rotate(0); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(2) rotate(40deg); }
}

@keyframes pb-strike-thrust {
  0% { opacity: 0; transform: translate(-100%, -50%) rotate(var(--pb-arc-angle)) scaleX(0); }
  28% { opacity: 1; }
  62% { opacity: 1; transform: translate(-100%, -50%) rotate(var(--pb-arc-angle)) scaleX(1); }
  100% { opacity: 0; transform: translate(-100%, -50%) rotate(var(--pb-arc-angle)) scaleX(1.12); }
}

@keyframes pb-strike-diamond {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(45deg) scale(0); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(145deg) scale(2.1); }
}

@keyframes pb-strike-lance {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 58deg)) scale(0.2) rotate(-52deg); }
  25% { opacity: 1; }
  70% { opacity: 1; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 58deg)) scale(1) rotate(7deg); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 58deg)) scale(1.18) rotate(20deg); }
}

@keyframes pb-strike-hammer {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scaleX(0); }
  24% { opacity: 1; }
  68% { opacity: 1; transform: translate(-50%, -50%) rotate(0) scaleX(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scaleX(1.28); }
}

@keyframes pb-strike-greatsword {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 42deg)) scale(0.15) rotate(-70deg); }
  22% { opacity: 1; }
  68% { opacity: 1; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 42deg)) scale(1) rotate(15deg); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) - 42deg)) scale(1.2) rotate(32deg); }
}

@keyframes pb-contact-flash {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.05); }
  14%, 28% { opacity: 1; transform: translate(-50%, -50%) scale(1.25); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(2.8); }
}

@keyframes pb-contact-ring {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.12); border-width: 3px; }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(3.3); border-width: 0.5px; }
}

@keyframes pb-contact-blade {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(0); }
  22%, 60% { opacity: 1; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(calc(var(--pb-arc-angle) + 42deg)) scaleY(1.25); }
}

@keyframes pb-ground-crack {
  0% { opacity: 0; transform: rotate(22deg) scaleX(0); }
  18% { opacity: 0.82; }
  70% { opacity: 0.42; transform: rotate(22deg) scaleX(1); }
  100% { opacity: 0; transform: rotate(22deg) scaleX(1.08); }
}

@keyframes pb-ground-dust {
  0% { opacity: 0; transform: translate(-50%, -20%) scale(0.2); }
  20% { opacity: 0.76; }
  100% { opacity: 0; transform: translate(-50%, -38%) scale(2.1); }
}

@keyframes pb-debris-flight {
  0% { opacity: 1; transform: translate(-50%, -50%) rotate(0) scale(1); }
  64% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(var(--pb-debris-x), var(--pb-debris-y)) rotate(var(--pb-debris-spin)) scale(0.12); }
}

@keyframes pb-board-shake {
  0%, 100% { transform: translate3d(0, 0, 0); filter: brightness(1); }
  12% { transform: translate3d(-3px, 2px, 0); filter: brightness(1.34); }
  24% { transform: translate3d(4px, -2px, 0); }
  39% { transform: translate3d(-3px, -1px, 0); }
  57% { transform: translate3d(2px, 2px, 0); }
  76% { transform: translate3d(-1px, 0, 0); }
}

@keyframes pb-board-parry {
  0%, 100% { transform: translate3d(0, 0, 0); }
  28% { transform: translate3d(-1.5px, 1px, 0); }
  58% { transform: translate3d(1.5px, -1px, 0); }
}

@keyframes pb-hud-enter {
  from { opacity: 0; transform: translate(-50%, -9px) scale(0.97); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

@media (max-width: 620px) {
  .polished-battle-hud {
    top: 1%;
    gap: 7px;
    max-width: 96%;
    min-height: 35px;
    padding: 5px 6px 5px 9px;
  }

  .polished-battle-hud strong {
    max-width: 190px;
    font-size: 8px;
  }

  .polished-battle-hud small { font-size: 5px; }
  .polished-battle-skip { min-height: 24px; padding: 4px 6px; }
  .polished-battle-skip span { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .polished-battle-layer,
  .polished-battle-hud {
    display: none !important;
  }
}

/* source: scene-integration.css */
/*
 * Castle-scene integration layer
 * Load after motion.css, articulated.css, and battle-polish.css.
 *
 * The castle artwork already contains a monumental checked terrace. This layer
 * gives the interactive board the same slate, brass, lighting, and perspective,
 * then grows a shallow dais out from beneath it so it reads as part of that
 * terrace rather than as a card floating over a backdrop.
 */

:root {
  --scene-slate-light: #827f72;
  --scene-slate-light-deep: #5c5b54;
  --scene-slate-dark: #263332;
  --scene-slate-dark-deep: #151e1f;
  --scene-stone-edge: #6f6c60;
  --scene-stone-mid: #343734;
  --scene-stone-deep: #111615;
  --scene-brass: #9f8148;
  --scene-brass-lit: #d5b66d;
  --scene-contact: rgba(0, 0, 0, 0.68);
  /* Reserve vertical space for both identity rails on desktop. */
  --board-size: min(69vw, calc(100dvh - 230px), 820px);
}

/* Keep the painted terrace/castle axis behind the physical board. */
.world__image {
  background-position: 50% 39%;
  filter: saturate(0.9) contrast(1.03);
}

.world__veil {
  background:
    linear-gradient(90deg, rgba(2, 5, 10, 0.67), rgba(4, 7, 13, 0.11) 43%, rgba(3, 5, 10, 0.68)),
    linear-gradient(180deg, rgba(3, 6, 14, 0.29), rgba(2, 4, 9, 0.59) 78%, #04060b 100%),
    radial-gradient(ellipse at 42% 67%, transparent 0 26%, rgba(1, 3, 8, 0.2) 54%, rgba(1, 3, 8, 0.72) 100%);
}

.arena {
  position: relative;
  z-index: 1;
  isolation: isolate;
}

/* A low pool of bounced moonlight joins the board to the painted floor. */
.arena::before {
  position: absolute;
  z-index: -5;
  top: 54px;
  bottom: 42px;
  left: 50%;
  width: calc(min(var(--board-size), 100%) * 1.25);
  border-radius: 45% 45% 28% 28%;
  background:
    radial-gradient(ellipse at 50% 70%, rgba(160, 177, 171, 0.1), transparent 63%),
    radial-gradient(ellipse at 50% 48%, rgba(203, 172, 104, 0.08), transparent 68%);
  filter: blur(17px);
  content: "";
  pointer-events: none;
  transform: translateX(-50%);
}

/* Stone steps continue the board toward the foreground like the source art. */
.arena::after {
  position: absolute;
  z-index: -4;
  right: 50%;
  bottom: 47px;
  width: calc(min(var(--board-size), 100%) * 1.12);
  height: clamp(86px, calc(var(--board-size) * 0.21), 166px);
  clip-path: polygon(7% 0, 93% 0, 100% 100%, 0 100%);
  background:
    linear-gradient(180deg,
      rgba(192, 185, 157, 0.16) 0 1px,
      rgba(39, 43, 41, 0.93) 2px 19%,
      rgba(10, 14, 14, 0.98) 20% 27%,
      rgba(113, 111, 99, 0.22) 28% 29%,
      rgba(35, 38, 36, 0.96) 30% 51%,
      rgba(9, 12, 12, 0.99) 52% 60%,
      rgba(123, 119, 102, 0.2) 61% 62%,
      rgba(28, 31, 30, 0.98) 63% 83%,
      rgba(7, 10, 10, 1) 84% 100%),
    linear-gradient(90deg, transparent, rgba(217, 188, 116, 0.07) 49%, transparent 51%);
  box-shadow: 0 26px 44px rgba(0, 0, 0, 0.58);
  content: "";
  opacity: 0.88;
  pointer-events: none;
  transform: translateX(50%);
}

.board-stage {
  z-index: 3;
  isolation: isolate;
  perspective: 1320px;
  perspective-origin: 50% 34%;
}

/* The slab around the frame: same tilt, same vanishing point, no detached card. */
.board-stage::before {
  position: absolute;
  z-index: -2;
  inset: -2.2% -3.5% -5.5%;
  border: 1px solid rgba(180, 170, 137, 0.24);
  clip-path: polygon(2.7% 0, 97.3% 0, 100% 97%, 97.4% 100%, 2.6% 100%, 0 97%);
  background:
    linear-gradient(125deg, transparent 0 21%, rgba(215, 202, 163, 0.07) 22% 22.4%, transparent 23% 64%, rgba(0, 0, 0, 0.26) 65%),
    linear-gradient(42deg, transparent 0 38%, rgba(218, 208, 170, 0.045) 38.4% 38.8%, transparent 39.2%),
    radial-gradient(ellipse at 50% 4%, rgba(179, 170, 139, 0.14), transparent 38%),
    linear-gradient(145deg, #464842 0, #252a28 43%, #151a19 72%, #2d302d 100%);
  box-shadow:
    0 2px 0 var(--scene-stone-edge),
    0 8px 0 #272b28,
    0 15px 0 #0e1211,
    0 22px 28px rgba(0, 0, 0, 0.48),
    inset 0 0 0 3px rgba(4, 7, 7, 0.55),
    inset 0 0 28px rgba(0, 0, 0, 0.52);
  content: "";
  pointer-events: none;
  transform: rotateX(var(--board-tilt)) translateZ(-18px);
  transform-origin: 50% 88%;
  transform-style: preserve-3d;
}

/* Front face of the inset dais; catches the same warm lights as the castle. */
.board-stage::after {
  position: absolute;
  z-index: -1;
  right: -0.8%;
  bottom: -1.6%;
  left: -0.8%;
  height: 10%;
  clip-path: polygon(1.5% 0, 98.5% 0, 96.5% 100%, 3.5% 100%);
  background:
    linear-gradient(90deg, transparent 4%, rgba(210, 175, 94, 0.28) 18%, transparent 34% 66%, rgba(210, 175, 94, 0.2) 82%, transparent 96%),
    linear-gradient(180deg, #4b4b43 0, #252a28 18%, #121716 76%, #080b0b 100%);
  box-shadow:
    inset 0 1px rgba(217, 203, 156, 0.2),
    inset 0 -1px #050707,
    0 18px 26px rgba(0, 0, 0, 0.52);
  content: "";
  opacity: 0.97;
  pointer-events: none;
}

/* Contact shadow stays directly under the masonry instead of floating below it. */
.board-shadow {
  right: 0;
  bottom: -2.5%;
  left: 0;
  height: 12%;
  opacity: 0.72;
  background: radial-gradient(ellipse, var(--scene-contact), transparent 72%);
  filter: blur(13px);
}

.board-frame {
  padding: 3.25%;
  border-color: rgba(161, 139, 86, 0.78);
  border-radius: 1px;
  background:
    linear-gradient(135deg, transparent 18%, rgba(230, 211, 159, 0.11) 29%, transparent 42%),
    linear-gradient(42deg, transparent 0 58%, rgba(255, 255, 255, 0.025) 58.5% 59%, transparent 59.5%),
    linear-gradient(145deg, #4b4a40, #252924 47%, #121716 72%, #39382f 100%);
  box-shadow:
    0 1px 0 var(--scene-brass-lit),
    0 4px 0 #575345,
    0 8px 0 #202522,
    0 12px 0 #0d1110,
    0 18px 20px rgba(0, 0, 0, 0.34),
    inset 0 0 0 4px #101412,
    inset 0 0 0 6px rgba(179, 149, 79, 0.5),
    inset 0 0 34px rgba(0, 0, 0, 0.72);
}

.board-frame::before {
  inset: 1.05%;
  border-color: rgba(220, 188, 112, 0.48);
  border-radius: 0;
  box-shadow: 0 0 9px rgba(214, 180, 98, 0.07);
}

.board-frame::after {
  right: 2%;
  bottom: 1.1%;
  left: 2%;
  height: 5px;
  background: linear-gradient(90deg, transparent, rgba(224, 191, 111, 0.28), transparent);
  filter: blur(3px);
}

.board-corner::before,
.board-corner::after {
  background: var(--scene-brass);
  box-shadow: 0 0 4px rgba(221, 184, 97, 0.24);
}

.chessboard {
  border-color: #0b100f;
  background: #111816;
  box-shadow:
    0 0 0 1px rgba(183, 153, 86, 0.78),
    inset 0 0 24px rgba(0, 0, 0, 0.76);
}

/* Stone instead of lacquer: the grid now belongs to the terrace in the art. */
.square--light {
  background:
    radial-gradient(circle at 20% 16%, rgba(255, 248, 211, 0.12), transparent 19%),
    linear-gradient(32deg, transparent 0 58%, rgba(15, 20, 19, 0.1) 59% 59.8%, transparent 61%),
    linear-gradient(145deg, var(--scene-slate-light), var(--scene-slate-light-deep));
}

.square--dark {
  background:
    radial-gradient(circle at 72% 18%, rgba(116, 162, 151, 0.12), transparent 25%),
    linear-gradient(38deg, transparent 0 63%, rgba(157, 170, 158, 0.045) 64% 64.8%, transparent 66%),
    linear-gradient(145deg, var(--scene-slate-dark), var(--scene-slate-dark-deep));
}

.square::before {
  border-color: rgba(229, 222, 190, 0.035);
  box-shadow:
    inset 1px 1px rgba(239, 230, 192, 0.075),
    inset -2px -2px rgba(0, 0, 0, 0.22);
}

/* Identity copy becomes engraved nameplates attached to the dais. */
.player-rail {
  z-index: 8;
  min-height: 48px;
  padding: 7px 12px;
  border: 0;
  border-right: 1px solid rgba(176, 160, 119, 0.16);
  border-left: 1px solid rgba(176, 160, 119, 0.16);
  border-radius: 0;
  background:
    linear-gradient(90deg, transparent, rgba(22, 27, 25, 0.84) 8% 92%, transparent),
    linear-gradient(180deg, rgba(150, 145, 123, 0.09), rgba(6, 10, 10, 0.22));
  box-shadow:
    inset 0 1px rgba(218, 200, 153, 0.1),
    inset 0 -1px rgba(0, 0, 0, 0.62);
  backdrop-filter: none;
}

.player-rail--rival {
  margin-bottom: 11px;
}

.player-rail--hero {
  margin-top: 13px;
}

.player-crest {
  filter: saturate(0.82) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.48));
}

/* Flat view keeps the material language but removes fake tabletop depth. */
.flat-view .board-stage::before {
  inset: -2.2%;
  transform: translateZ(-18px);
}

.flat-view .board-stage::after {
  bottom: -2%;
  height: 4%;
}

.flat-view .arena::after {
  opacity: 0.48;
}

@media (max-width: 1100px) {
  :root {
    --board-size: min(92vw, calc(100dvh - 225px), 750px);
  }

  .world__image {
    background-position: 50% 35%;
  }

  .arena::before {
    width: calc(min(var(--board-size), 100%) * 1.12);
  }

  .arena::after {
    width: calc(min(var(--board-size), 100%) * 1.04);
    opacity: 0.75;
  }
}

@media (max-width: 620px) {
  :root {
    --board-size: min(96vw, 60dvh);
  }

  .world__image {
    background-position: 50% 30%;
  }

  .arena::before {
    top: 48px;
    bottom: 40px;
    width: 104%;
    filter: blur(10px);
  }

  .arena::after {
    bottom: 43px;
    width: 100%;
    height: clamp(68px, calc(var(--board-size) * 0.18), 96px);
    opacity: 0.62;
  }

  .board-stage::before {
    inset: -1.4% -1.8% -3%;
  }

  .board-stage::after {
    right: 0;
    bottom: -0.6%;
    left: 0;
    height: 7%;
  }

  .board-frame {
    padding: 2.9%;
    box-shadow:
      0 1px 0 var(--scene-brass-lit),
      0 3px 0 #575345,
      0 6px 0 #202522,
      0 9px 0 #0d1110,
      0 13px 16px rgba(0, 0, 0, 0.34),
      inset 0 0 0 3px #101412,
      inset 0 0 0 5px rgba(179, 149, 79, 0.46),
      inset 0 0 26px rgba(0, 0, 0, 0.7);
  }

  .player-rail {
    min-height: 44px;
    padding: 6px 8px;
  }

  .player-rail--rival { margin-bottom: 8px; }
  .player-rail--hero { margin-top: 10px; }
}

@media (max-height: 700px) and (min-width: 1101px) {
  :root {
    --board-size: min(62vw, calc(100dvh - 196px), 650px);
  }

  .player-rail {
    min-height: 43px;
    padding-top: 5px;
    padding-bottom: 5px;
  }

  .player-rail--rival { margin-bottom: 8px; }
  .player-rail--hero { margin-top: 9px; }
}

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

/* source: interaction-visual-polish.css */
/*
 * Interaction visual polish
 * Load after battle-polish.css, motion-natural.css, and scene-integration.css.
 * This layer keeps the existing choreography and timing hooks while improving
 * combat legibility, control sizing, and directional travel body language.
 */

/* Keep the whole army present during a duel without competing with the actors. */
.is-polished-battling .square:not(.is-polished-battle-source):not(.is-polished-battle-target):not(.is-polished-battle-destination) {
  filter: brightness(0.73) saturate(0.86) contrast(0.98);
}

/* The target retains its material and outline rather than becoming a lightbox. */
.is-polished-battle-target {
  box-shadow:
    inset 0 0 0 2px rgba(255, 224, 145, 0.76),
    inset 0 0 calc(var(--pb-cell) * 0.22) rgba(73, 232, 209, 0.24),
    0 0 calc(var(--pb-cell) * 0.16) rgba(92, 239, 218, 0.3);
}

/*
 * Effects sit behind the animated attacker whenever their layer permits it.
 * The strike line stays immediately beneath the actor because weapon direction,
 * rather than an opaque flash, now communicates impact.
 */
.polished-battle-caster-sigil,
.polished-battle-impact-sigil,
.polished-battle-ground {
  z-index: 91;
}

.polished-battle-debris {
  z-index: 92;
}

.polished-battle-vector,
.polished-battle--magic .polished-battle-vector {
  z-index: 93;
}

.polished-battle-contact {
  z-index: 94;
}

.polished-battle-strike {
  z-index: 96;
}

.polished-battle-attacker {
  z-index: 98;
}

/* Preserve armor, weapon, and shield edges during the short hit-stop. */
.is-polished-hit-stop {
  filter: brightness(1.32) saturate(0.96) contrast(1.14)
    drop-shadow(0 1px 0 rgba(8, 13, 13, 0.82)) !important;
}

.polished-battle-attacker .piece-token {
  filter:
    brightness(1.08)
    contrast(1.08)
    drop-shadow(0 1px 0 rgba(5, 9, 9, 0.9))
    drop-shadow(0 0 calc(var(--pb-cell) * 0.055) var(--piece-gem, #f2d788));
}

/* A smaller translucent core leaves both soldiers readable at peak contact. */
.polished-battle-contact i:first-child {
  width: calc(var(--pb-cell) * 0.38);
  height: calc(var(--pb-cell) * 0.38);
  background: radial-gradient(
    circle,
    rgba(255, 252, 231, 0.86) 0 6%,
    rgba(255, 218, 132, 0.76) 15%,
    rgba(81, 241, 218, 0.42) 39%,
    transparent 69%
  );
  box-shadow:
    0 0 calc(var(--pb-cell) * 0.11) rgba(255, 241, 196, 0.65),
    0 0 calc(var(--pb-cell) * 0.27) rgba(89, 232, 210, 0.52);
  mix-blend-mode: screen;
}

.polished-battle-contact i:nth-child(2),
.polished-battle-contact span {
  border-color: rgba(255, 233, 176, 0.8);
  box-shadow:
    0 0 5px rgba(255, 245, 216, 0.62),
    0 0 calc(var(--pb-cell) * 0.12) rgba(220, 164, 76, 0.46);
}

.polished-battle-contact span {
  border-color: rgba(112, 238, 219, 0.72);
}

.polished-battle-contact b {
  width: max(2px, calc(var(--pb-cell) * 0.026));
  background: linear-gradient(
    transparent,
    rgba(255, 246, 217, 0.42),
    #f7cf72,
    rgba(255, 246, 217, 0.42),
    transparent
  );
  box-shadow:
    0 0 4px rgba(255, 245, 216, 0.62),
    0 0 9px rgba(232, 184, 80, 0.58);
}

.polished-battle--magic .polished-battle-vector i:first-child {
  background: linear-gradient(
    90deg,
    transparent 2%,
    rgba(93, 227, 208, 0.84) 24%,
    rgba(255, 255, 244, 0.82) 58%,
    rgba(240, 199, 119, 0.88) 100%
  );
  box-shadow:
    0 0 3px rgba(255, 255, 255, 0.72),
    0 0 calc(var(--pb-cell) * 0.08) rgba(85, 234, 211, 0.72),
    0 0 calc(var(--pb-cell) * 0.16) rgba(118, 247, 225, 0.48);
}

.polished-battle--magic .polished-battle-vector b {
  background: rgba(155, 255, 240, 0.8);
  box-shadow:
    0 0 5px rgba(255, 255, 255, 0.74),
    0 0 calc(var(--pb-cell) * 0.12) rgba(78, 231, 207, 0.72);
}

.has-polished-battle-impact .polished-battle-contact i:first-child {
  animation: interaction-contact-flash 380ms cubic-bezier(0.12, 0.72, 0.2, 1) both;
}

.has-polished-battle-impact .polished-battle-contact i:nth-child(2),
.has-polished-battle-impact .polished-battle-contact span {
  animation-name: interaction-contact-ring;
}

.has-polished-battle-impact .polished-battle-impact-sigil i {
  animation-name: interaction-impact-sigil;
}

/* First contact reads as metal-on-metal or a ward, never as the kill shot. */
.has-polished-battle-parry .polished-battle-contact i:first-child {
  width: calc(var(--pb-cell) * 0.3);
  height: calc(var(--pb-cell) * 0.3);
}

.is-polished-battle-parry .is-polished-battle-target {
  box-shadow:
    inset 0 0 0 2px rgba(255, 224, 145, 0.88),
    inset 0 0 calc(var(--pb-cell) * 0.18) rgba(73, 232, 209, 0.2),
    0 0 calc(var(--pb-cell) * 0.12) rgba(232, 192, 100, 0.34);
}

.chessboard.is-polished-battle-impact {
  animation: interaction-board-shake 270ms cubic-bezier(0.35, 0, 0.2, 1) both;
}

/* Premium plaque anchored to the board's top stone/brass course. */
.polished-battle-hud {
  top: clamp(7px, 1.45%, 12px);
  width: max-content;
  max-width: calc(100% - clamp(18px, 5%, 42px));
  min-height: 52px;
  gap: clamp(12px, 2vw, 20px);
  padding: 7px 8px 7px 16px;
  overflow: hidden;
  border: 1px solid rgba(213, 182, 109, 0.82);
  border-radius: 4px;
  color: #f4eddb;
  background:
    linear-gradient(90deg, rgba(213, 182, 109, 0.1), transparent 24% 76%, rgba(213, 182, 109, 0.07)),
    linear-gradient(180deg, #474940 0, #292d2a 13%, #101817 48%, #080f0f 100%);
  box-shadow:
    0 1px 0 rgba(244, 218, 153, 0.65),
    0 4px 0 rgba(52, 53, 47, 0.96),
    0 7px 0 rgba(9, 13, 12, 0.94),
    0 13px 24px rgba(0, 0, 0, 0.48),
    inset 0 0 0 2px rgba(5, 9, 9, 0.7),
    inset 0 0 24px rgba(0, 0, 0, 0.52);
  backdrop-filter: blur(8px) saturate(0.9);
}

.polished-battle-hud::before,
.polished-battle-hud::after {
  position: absolute;
  content: "";
  pointer-events: none;
}

.polished-battle-hud::before {
  z-index: -1;
  inset: 3px;
  border: 1px solid rgba(184, 151, 78, 0.32);
  border-radius: 2px;
}

.polished-battle-hud::after {
  top: 8px;
  bottom: 8px;
  left: 7px;
  width: 2px;
  background: linear-gradient(#f1d18b, #80612b, #d0a958);
  box-shadow: 0 0 7px rgba(220, 178, 82, 0.28);
}

.polished-battle-hud--magic {
  border-color: rgba(117, 224, 207, 0.7);
  background:
    linear-gradient(90deg, rgba(79, 221, 200, 0.1), transparent 24% 76%, rgba(156, 121, 218, 0.09)),
    linear-gradient(180deg, #3e4943 0, #26332f 13%, #0d1817 48%, #07100f 100%);
  box-shadow:
    0 1px 0 rgba(169, 246, 230, 0.55),
    0 4px 0 rgba(45, 61, 56, 0.96),
    0 7px 0 rgba(7, 14, 13, 0.94),
    0 13px 24px rgba(0, 0, 0, 0.48),
    inset 0 0 0 2px rgba(5, 11, 10, 0.72),
    inset 0 0 24px rgba(60, 185, 166, 0.12);
}

.polished-battle-hud > span {
  min-width: 0;
  flex: 1 1 auto;
}

.polished-battle-hud small {
  color: #e3bd68;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.14em;
}

.polished-battle-hud small::after {
  content: "  ·  " attr(data-phase);
  color: #b8c4bd;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.polished-battle-hud--magic small::after {
  color: #b6cec8;
}

.polished-battle-hud--magic small {
  color: #83e5d5;
}

.polished-battle-hud strong {
  margin-top: 4px;
  color: #f4eddb;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.015em;
}

.polished-battle-skip {
  min-width: 112px;
  min-height: 40px;
  flex: 0 0 auto;
  padding: 8px 11px;
  border: 1px solid rgba(219, 190, 121, 0.58);
  border-radius: 3px;
  color: #f0e6cf;
  background:
    linear-gradient(180deg, rgba(115, 111, 92, 0.22), transparent 42%),
    rgba(12, 20, 20, 0.92);
  box-shadow:
    inset 0 1px rgba(255, 241, 203, 0.09),
    0 2px 5px rgba(0, 0, 0, 0.36);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.09em;
}

.polished-battle-skip span {
  display: inline-grid;
  min-width: 22px;
  min-height: 20px;
  margin-left: 7px;
  padding: 0 4px;
  place-items: center;
  border: 1px solid rgba(190, 177, 143, 0.25);
  border-radius: 3px;
  color: #aeb7b1;
  background: rgba(2, 7, 7, 0.42);
  font-size: 9px;
  letter-spacing: 0.02em;
}

.polished-battle-skip:hover,
.polished-battle-skip:focus-visible {
  border-color: rgba(244, 214, 141, 0.94);
  color: #fff4d3;
  background:
    linear-gradient(180deg, rgba(161, 134, 72, 0.24), transparent 48%),
    rgba(18, 27, 25, 0.97);
  outline: 2px solid rgba(255, 224, 147, 0.82);
  outline-offset: 2px;
  box-shadow:
    inset 0 1px rgba(255, 242, 203, 0.12),
    0 0 0 1px rgba(21, 29, 27, 0.94),
    0 0 16px rgba(227, 188, 96, 0.3);
}

.polished-battle-skip:active {
  transform: translateY(1px);
}

/*
 * Lateral and diagonal travelers lead gently with the weapon shoulder. The
 * SVG is rotated, never mirrored, so shields, crests, and heraldry stay on the
 * authored side. All internal transforms return to neutral before landing.
 */
.natural-move-actor.travel-right {
  --interaction-body-facing: 5.5deg;
  --interaction-body-settle: 2deg;
  --interaction-head-facing: 3.5deg;
  --interaction-head-settle: 1deg;
  --interaction-shoulder-facing: 4deg;
  --interaction-shoulder-settle: 1.2deg;
  --interaction-direction-x: 1.5px;
  --interaction-direction-settle-x: 0.5px;
}

.natural-move-actor.travel-left {
  --interaction-body-facing: -5.5deg;
  --interaction-body-settle: -2deg;
  --interaction-head-facing: -3.5deg;
  --interaction-head-settle: -1deg;
  --interaction-shoulder-facing: -4deg;
  --interaction-shoulder-settle: -1.2deg;
  --interaction-direction-x: -1.5px;
  --interaction-direction-settle-x: -0.5px;
}


.natural-move-actor.travel-up {
  --interaction-direction-y: -1px;
}

.natural-move-actor.travel-down {
  --interaction-direction-y: 1px;
}

.is-natural-move-playing .natural-move-actor:is(.travel-horizontal, .travel-diagonal) .soldier-icon {
  animation: interaction-travel-facing var(--move-duration) cubic-bezier(0.35, 0, 0.22, 1) var(--move-delay, 0ms) both;
}

.is-natural-move-playing .natural-move-actor:is(.travel-horizontal, .travel-diagonal):not(.move-role-n) .soldier-head {
  animation: interaction-head-facing var(--move-duration) ease-in-out var(--move-delay, 0ms) both;
  transform-box: fill-box;
  transform-origin: 50% 88%;
}

.is-natural-move-playing .natural-move-actor:is(.travel-horizontal, .travel-diagonal):not(.move-role-r) .soldier-arm--weapon {
  animation: interaction-weapon-shoulder var(--move-duration) ease-in-out var(--move-delay, 0ms) both;
  transform-box: fill-box;
  transform-origin: 45% 72%;
}

@keyframes interaction-travel-facing {
  0%, 9%, 95%, 100% {
    transform: rotate(0) translate(0, 0);
  }
  24%, 70% {
    transform:
      rotate(var(--interaction-body-facing, 0deg))
      translate(var(--interaction-direction-x, 0), var(--interaction-direction-y, 0));
  }
  84% {
    transform:
      rotate(var(--interaction-body-settle, 0deg))
      translate(var(--interaction-direction-settle-x, 0), 0);
  }
}

@keyframes interaction-head-facing {
  0%, 12%, 94%, 100% { transform: rotate(0); }
  27%, 72% { transform: rotate(var(--interaction-head-facing, 0deg)); }
  84% { transform: rotate(var(--interaction-head-settle, 0deg)); }
}

@keyframes interaction-weapon-shoulder {
  0%, 11%, 94%, 100% { transform: rotate(0) translate(0, 0); }
  26%, 72% {
    transform:
      rotate(var(--interaction-shoulder-facing, 0deg))
      translate(var(--interaction-direction-x, 0), var(--interaction-direction-y, 0));
  }
  84% { transform: rotate(var(--interaction-shoulder-settle, 0deg)); }
}

@keyframes interaction-contact-flash {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.08); }
  16%, 28% { opacity: 0.76; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(2.25); }
}

@keyframes interaction-contact-ring {
  0% {
    opacity: 0;
    border-width: 2px;
    transform: translate(-50%, -50%) scale(0.16);
  }
  20% { opacity: 0.72; }
  100% {
    opacity: 0;
    border-width: 0.5px;
    transform: translate(-50%, -50%) scale(2.75);
  }
}

@keyframes interaction-impact-sigil {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(0) scale(0.12); }
  24% { opacity: 0.58; }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(145deg) scale(1.48); }
}

@keyframes interaction-board-shake {
  /* Avoid filtering this preserve-3d grid: Gecko can flatten the board while
     its already-filtered squares are composited and drop them for one frame. */
  0%, 100% { transform: translate3d(0, 0, 0); }
  12% { transform: translate3d(-3px, 2px, 0); }
  24% { transform: translate3d(4px, -2px, 0); }
  39% { transform: translate3d(-3px, -1px, 0); }
  57% { transform: translate3d(2px, 2px, 0); }
  76% { transform: translate3d(-1px, 0, 0); }
}

@media (max-width: 620px) {
  .polished-battle-hud {
    top: max(4px, 0.8%);
    width: calc(100% - 8px);
    max-width: calc(100% - 8px);
    min-height: 56px;
    gap: 8px;
    padding: 6px 6px 6px 11px;
  }

  .polished-battle-hud small {
    font-size: 10px;
    letter-spacing: 0.1em;
  }

  .polished-battle-hud strong {
    max-width: none;
    margin-top: 3px;
    font-size: 12px;
  }

  .polished-battle-skip {
    min-width: 96px;
    min-height: 44px;
    padding: 8px 9px;
    font-size: 10px;
  }

  .polished-battle-skip span {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .natural-move-actor:is(.travel-horizontal, .travel-diagonal) .soldier-icon,
  .natural-move-actor:is(.travel-horizontal, .travel-diagonal) .soldier-head,
  .natural-move-actor:is(.travel-horizontal, .travel-diagonal) .soldier-arm--weapon {
    animation: none !important;
  }
}

/* source: battle-grounded-v3.css */
/* Grounded duel v3: both combatants share one board-local coordinate system.
   The original target is hidden while an explicit defender rig blocks,
   counters and falls at a readable weapon-length distance. */

.is-polished-battling .is-polished-battle-target > .piece-token {
  opacity: 0 !important;
  animation: none !important;
}

.polished-battle-defender {
  position: absolute;
  z-index: 97;
  transform: translate3d(0, 0, 27px);
  transform-origin: 50% 88%;
  transform-style: preserve-3d;
  will-change: transform, filter, opacity;
}

.polished-battle-defender .piece-token,
.polished-battle-attacker .piece-token {
  width: 88%;
  height: 104%;
  transition: none;
}

.polished-battle-defender .piece-token {
  filter:
    brightness(1.04)
    contrast(1.08)
    drop-shadow(0 1px 0 rgba(5, 9, 9, 0.9))
    drop-shadow(0 0 calc(var(--pb-cell) * 0.035) var(--piece-gem, #7edaca));
}

.is-polished-hit-stop,
.is-polished-hit-stop * {
  animation-play-state: paused !important;
}

.is-polished-battle-playing .polished-battle--melee .polished-battle-attacker {
  animation: pb-attacker-grounded-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-role-n .polished-battle-attacker {
  animation-name: pb-attacker-cavalry-v3;
}

.is-polished-battle-playing .polished-battle-role-r .polished-battle-attacker,
.is-polished-battle-playing .polished-battle-role-k .polished-battle-attacker {
  animation-name: pb-attacker-heavy-v3;
}

.is-polished-battle-playing .polished-battle--magic .polished-battle-attacker {
  animation: pb-attacker-caster-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-response-block .polished-battle-defender {
  animation: pb-defender-block-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-response-evade .polished-battle-defender {
  animation: pb-defender-evade-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-response-ward .polished-battle-defender {
  animation: pb-defender-ward-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-defender :is(
  .soldier-arm--shield,
  .soldier-shield,
  .soldier-arm--weapon,
  .soldier-weapon-rig,
  .soldier-greatsword,
  .soldier-casting-arm,
  .soldier-head,
  .soldier-cape
) {
  animation-duration: var(--pb-duration);
  animation-fill-mode: both;
  transform-box: fill-box;
}

.is-polished-battle-playing .polished-battle-defender :is(.soldier-arm--shield, .soldier-shield) {
  animation-name: pb-defender-guard-v3;
  transform-origin: 50% 50%;
}

.is-polished-battle-playing .polished-battle-defender :is(.soldier-arm--weapon, .soldier-weapon-rig, .soldier-greatsword, .soldier-casting-arm) {
  animation-name: pb-defender-counter-v3;
  transform-origin: 50% 82%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-head {
  animation-name: pb-defender-head-v3;
  transform-origin: 50% 86%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-cape {
  animation-name: pb-defender-cape-v3;
  transform-origin: 50% 14%;
}

@keyframes pb-attacker-grounded-v3 {
  0%, 8% { transform: translate3d(0, 0, 28px); filter: brightness(1); }
  13% { transform: translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 2px), 31px) rotate(var(--pb-attacker-turn-in)); }
  18% { transform: translate3d(var(--pb-step-one-x), var(--pb-step-one-y), 28px) rotate(var(--pb-attacker-turn-in)); }
  24% { transform: translate3d(var(--pb-step-two-x), calc(var(--pb-step-two-y) - 2px), 31px) rotate(var(--pb-attacker-turn-out)); }
  29% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 28px); }
  35%, 40% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 30px) rotate(var(--pb-attacker-turn-in)); filter: brightness(1.14); }
  47% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 28px) rotate(var(--pb-attacker-turn-out)); filter: brightness(1); }
  55%, 61% { transform: translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 1px), 27px) rotate(var(--pb-attacker-windup)); }
  67% { transform: translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) - 2px), 31px) rotate(var(--pb-attacker-strike)); }
  72%, 77% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 30px) rotate(var(--pb-attacker-strike)); filter: brightness(1.22); }
  83% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 28px) rotate(var(--pb-attacker-turn-out)); filter: brightness(1.04); }
  90% { transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 2px), 31px); }
  95%, 100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px); filter: brightness(1); }
}

@keyframes pb-attacker-heavy-v3 {
  0%, 9% { transform: translate3d(0, 0, 28px); }
  15% { transform: translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 1px), 30px) rotate(var(--pb-attacker-turn-in)); }
  21% { transform: translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) + 1px), 27px); }
  27% { transform: translate3d(var(--pb-step-two-x), calc(var(--pb-step-two-y) - 1px), 30px) rotate(var(--pb-attacker-turn-out)); }
  32% { transform: translate3d(var(--pb-approach-x), calc(var(--pb-approach-y) + 1px), 27px); }
  38%, 42% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 29px) rotate(var(--pb-attacker-turn-in)); filter: brightness(1.14); }
  49% { transform: translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 1px), 27px); }
  57%, 64% { transform: translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 2px), 26px) rotate(var(--pb-attacker-windup)); }
  70% { transform: translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) - 1px), 30px) rotate(var(--pb-attacker-strike)); }
  74%, 79% { transform: translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) + 1px), 28px) rotate(var(--pb-attacker-strike)); filter: brightness(1.2); }
  85% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 28px); }
  92% { transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 1px), 30px); }
  97%, 100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px); }
}

@keyframes pb-attacker-cavalry-v3 {
  0%, 8% { transform: translate3d(0, 0, 28px); }
  15% { transform: translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 5px), 36px) rotate(var(--pb-attacker-turn-in)); }
  21% { transform: translate3d(var(--pb-step-one-x), var(--pb-step-one-y), 28px); }
  28% { transform: translate3d(var(--pb-step-two-x), calc(var(--pb-step-two-y) - 7px), 40px) rotate(var(--pb-attacker-turn-out)); }
  34% { transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 29px); }
  38%, 42% { transform: translate3d(var(--pb-parry-x), calc(var(--pb-parry-y) - 2px), 33px) rotate(var(--pb-attacker-turn-in)); filter: brightness(1.14); }
  49% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 28px); }
  57%, 63% { transform: translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 1px), 27px) rotate(var(--pb-attacker-windup)); }
  69% { transform: translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) - 6px), 39px) rotate(var(--pb-attacker-strike)); }
  74%, 78% { transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 31px) rotate(var(--pb-attacker-strike)); filter: brightness(1.22); }
  85% { transform: translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 28px); }
  91% { transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 4px), 35px); }
  96%, 100% { transform: translate3d(var(--pb-end-x), var(--pb-end-y), 28px); }
}

@keyframes pb-attacker-caster-v3 {
  0%, 10% { opacity: 1; transform: translate3d(0, 0, 30px); filter: brightness(1); }
  20% { transform: translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 2px), 33px) rotate(var(--pb-attacker-turn-in)); }
  31%, 40% { transform: translate3d(var(--pb-parry-x), var(--pb-parry-y), 34px); filter: brightness(1.18); }
  48% { transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 30px); filter: brightness(1); }
  58%, 66% { transform: translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 2px), 34px) rotate(var(--pb-attacker-windup)); }
  72%, 78% { opacity: 1; transform: translate3d(var(--pb-strike-x), var(--pb-strike-y), 36px) rotate(var(--pb-attacker-strike)); filter: brightness(1.24); }
  84% { opacity: 0.76; transform: translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) - 3px), 34px); }
  88% { opacity: 0; transform: translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) - 5px), 36px) scale(0.94); }
  89% { opacity: 0; transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 3px), 34px) scale(0.94); }
  95%, 100% { opacity: 1; transform: translate3d(var(--pb-end-x), var(--pb-end-y), 30px) scale(1); filter: brightness(1); }
}

@keyframes pb-defender-block-v3 {
  0%, 28% { opacity: 1; transform: translate3d(0, 0, 27px); filter: brightness(1); }
  34%, 40% { transform: translate3d(var(--pb-defender-parry-x), var(--pb-defender-parry-y), 30px) rotate(var(--pb-defender-turn-in)); filter: brightness(1.14); }
  47% { transform: translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 27px) rotate(var(--pb-defender-turn-out)); }
  54% { transform: translate3d(0, 0, 27px); }
  59%, 64% { transform: translate3d(var(--pb-defender-counter-x), calc(var(--pb-defender-counter-y) - 2px), 30px) rotate(var(--pb-defender-turn-in)); }
  69% { transform: translate3d(0, 0, 27px); }
  73%, 78% { opacity: 1; transform: translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 31px) rotate(var(--pb-defender-turn-out)); filter: brightness(1.22); }
  86% { opacity: 0.9; transform: translate3d(var(--pb-defender-knock-x), var(--pb-defender-knock-y), 20px) rotate(var(--pb-defender-knock-spin)) scale(0.93); filter: brightness(0.8); }
  96%, 100% { opacity: 0; transform: translate3d(var(--pb-defender-knock-x), calc(var(--pb-defender-knock-y) + 5px), 8px) rotate(var(--pb-defender-knock-spin)) scale(0.72); filter: brightness(0.46); }
}

@keyframes pb-defender-evade-v3 {
  0%, 28% { opacity: 1; transform: translate3d(0, 0, 27px); }
  34%, 40% { transform: translate3d(var(--pb-defender-evade-x), var(--pb-defender-evade-y), 30px) rotate(var(--pb-defender-turn-out)); }
  48% { transform: translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 27px); }
  54% { transform: translate3d(0, 0, 27px); }
  59%, 64% { transform: translate3d(var(--pb-defender-counter-x), calc(var(--pb-defender-counter-y) - 3px), 31px) rotate(var(--pb-defender-turn-in)); }
  69% { transform: translate3d(0, 0, 27px); }
  73%, 78% { opacity: 1; transform: translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 31px) rotate(var(--pb-defender-turn-out)); filter: brightness(1.2); }
  86% { opacity: 0.88; transform: translate3d(var(--pb-defender-knock-x), var(--pb-defender-knock-y), 20px) rotate(var(--pb-defender-knock-spin)) scale(0.92); }
  96%, 100% { opacity: 0; transform: translate3d(var(--pb-defender-knock-x), calc(var(--pb-defender-knock-y) + 5px), 8px) rotate(var(--pb-defender-knock-spin)) scale(0.7); }
}

@keyframes pb-defender-ward-v3 {
  0%, 28% { opacity: 1; transform: translate3d(0, 0, 27px); filter: brightness(1); }
  34%, 40% { transform: translate3d(var(--pb-defender-parry-x), calc(var(--pb-defender-parry-y) - 2px), 31px) rotate(var(--pb-defender-turn-in)); filter: brightness(1.2); }
  48%, 54% { transform: translate3d(0, 0, 27px); filter: brightness(1.02); }
  59%, 64% { transform: translate3d(var(--pb-defender-counter-x), calc(var(--pb-defender-counter-y) - 2px), 31px) rotate(var(--pb-defender-turn-in)); filter: brightness(1.12); }
  69% { transform: translate3d(0, 0, 27px); }
  73%, 78% { opacity: 1; transform: translate3d(var(--pb-defender-recoil-x), calc(var(--pb-defender-recoil-y) - 3px), 33px) rotate(var(--pb-defender-turn-out)); filter: brightness(1.3); }
  86% { opacity: 0.66; transform: translate3d(var(--pb-defender-knock-x), calc(var(--pb-defender-knock-y) - 5px), 34px) rotate(var(--pb-defender-knock-spin)) scale(0.82, 1.04); filter: brightness(1.1) saturate(0.55); }
  96%, 100% { opacity: 0; transform: translate3d(var(--pb-defender-knock-x), calc(var(--pb-defender-knock-y) - 10px), 39px) rotate(var(--pb-defender-knock-spin)) scale(0.42, 1.08); filter: brightness(1.2) saturate(0); }
}

@keyframes pb-articulate-thrust {
  0%, 14%, 100% { transform: rotate(0); }
  22% { transform: rotate(var(--pb-weapon-back)) translateY(2%); }
  35%, 40% { transform: rotate(var(--pb-weapon-contact)) translateY(-3%); }
  49% { transform: rotate(var(--pb-attacker-turn-out)); }
  59%, 66% { transform: rotate(var(--pb-weapon-back)) translateY(3%); }
  72%, 79% { transform: rotate(var(--pb-weapon-strike)) translateY(-5%); }
}

@keyframes pb-articulate-lance {
  0%, 14%, 100% { transform: rotate(0); }
  22% { transform: rotate(var(--pb-weapon-back)) translateY(-4%); }
  35%, 41% { transform: rotate(var(--pb-weapon-contact)) translateY(2%); }
  50% { transform: rotate(var(--pb-attacker-turn-out)); }
  59%, 67% { transform: rotate(var(--pb-weapon-back)) translateY(-6%); }
  73%, 80% { transform: rotate(var(--pb-weapon-strike)) translateY(3%); }
}

@keyframes pb-articulate-hammer {
  0%, 15%, 100% { transform: rotate(0); }
  24% { transform: rotate(var(--pb-weapon-back)) translateY(-6%); }
  38%, 43% { transform: rotate(var(--pb-weapon-contact)) translateY(3%); }
  50% { transform: rotate(var(--pb-attacker-turn-out)); }
  58%, 68% { transform: rotate(var(--pb-weapon-back)) translateY(-10%); }
  74%, 81% { transform: rotate(var(--pb-weapon-strike)) translateY(7%); }
}

@keyframes pb-articulate-greatsword {
  0%, 15%, 100% { transform: rotate(0); }
  24% { transform: rotate(var(--pb-weapon-back)) translateY(-6%); }
  38%, 43% { transform: rotate(var(--pb-weapon-contact)) translateY(3%); }
  50% { transform: rotate(var(--pb-attacker-turn-out)); }
  58%, 68% { transform: rotate(var(--pb-weapon-back)) translateY(-10%); }
  74%, 81% { transform: rotate(var(--pb-weapon-strike)) translateY(7%); }
}

@keyframes pb-articulate-cast {
  0%, 14%, 100% { transform: rotate(0) translateY(0); filter: brightness(1); }
  24% { transform: rotate(var(--pb-attacker-turn-out)) translateY(-4%); }
  35%, 41% { transform: rotate(var(--pb-weapon-contact)) translateY(-7%); filter: brightness(1.2); }
  49% { transform: rotate(0) translateY(-1%); }
  59%, 68% { transform: rotate(var(--pb-weapon-back)) translateY(-8%); }
  73%, 80% { transform: rotate(var(--pb-weapon-strike)) translateY(-10%); filter: brightness(1.28); }
}

@keyframes pb-articulate-guard {
  0%, 18%, 100% { transform: rotate(0); }
  30%, 42% { transform: rotate(var(--pb-attacker-turn-out)) translateY(-3%); }
  50% { transform: rotate(0); }
  66%, 79% { transform: rotate(var(--pb-attacker-turn-out)) translateY(-4%); }
}

@keyframes pb-defender-guard-v3 {
  0%, 25%, 100% { transform: rotate(0); }
  32%, 43% { transform: rotate(var(--pb-defender-turn-in)) translateY(-4%); }
  49% { transform: rotate(var(--pb-defender-turn-out)); }
  58%, 67% { transform: rotate(var(--pb-defender-turn-in)) translateY(-3%); }
  73%, 82% { transform: rotate(var(--pb-defender-turn-out)) translateY(3%); }
}

@keyframes pb-defender-counter-v3 {
  0%, 27%, 100% { transform: rotate(0); }
  34%, 43% { transform: rotate(var(--pb-weapon-contact)); }
  50% { transform: rotate(var(--pb-weapon-back)); }
  58%, 66% { transform: rotate(var(--pb-weapon-strike)) translateY(-4%); }
  71% { transform: rotate(var(--pb-weapon-back)); }
  76%, 84% { transform: rotate(var(--pb-defender-turn-out)) translateY(4%); }
}

@keyframes pb-defender-head-v3 {
  0%, 28%, 100% { transform: rotate(0); }
  34%, 43% { transform: rotate(var(--pb-defender-turn-in)); }
  47% { transform: rotate(var(--pb-defender-turn-out)); }
  58%, 67% { transform: rotate(var(--pb-defender-turn-in)); }
  74%, 88% { transform: rotate(var(--pb-defender-turn-out)); }
}

@keyframes pb-defender-cape-v3 {
  0%, 28%, 100% { transform: skewX(0); }
  34%, 43% { transform: skewX(-4deg); }
  48% { transform: skewX(3deg); }
  58%, 68% { transform: skewX(-6deg); }
  74%, 88% { transform: skewX(8deg); }
}

/* Vector-aimed weapon contact: both physical tips share the clash line at the
   parry, defender counter, and decisive guard. */
.polished-battle-weapon-tip {
  opacity: 0;
  fill: rgba(255, 250, 221, 0.96);
  stroke: rgba(96, 237, 215, 0.92);
  stroke-width: 0.8;
  filter: drop-shadow(0 0 2px #fff2c2) drop-shadow(0 0 4px #65e5d1);
  pointer-events: none;
  vector-effect: non-scaling-stroke;
}

.polished-battle-layer:is(
  .battle-phase-parry,
  .battle-phase-counter,
  .battle-phase-decisive
) .polished-battle-weapon-tip {
  opacity: 0.94;
  animation: pb-weapon-tip-contact-v4 420ms ease-in-out infinite alternate;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-arm--weapon,
.is-polished-battle-playing .polished-battle-attacker .soldier-greatsword {
  animation: pb-attacker-weapon-contact-v4 var(--pb-duration) linear both;
  transform-box: fill-box;
  transform-origin: 50% 60%;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-greatsword {
  transform-origin: 50% 38%;
}

/* The defender's rig previously inherited the same rotation on its parent arm
   and nested weapon, doubling every aim angle. One articulated joint owns it. */
.is-polished-battle-playing .polished-battle-defender .soldier-weapon-rig {
  animation: none;
}

.is-polished-battle-playing .polished-battle-defender .soldier-arm--weapon,
.is-polished-battle-playing .polished-battle-defender .soldier-greatsword {
  animation: pb-defender-weapon-contact-v4 var(--pb-duration) linear both;
  transform-box: fill-box;
  transform-origin: 50% 60%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-greatsword {
  transform-origin: 50% 38%;
}

.is-polished-battle-playing :is(
  .polished-battle-attacker,
  .polished-battle-defender
) .soldier-casting-arm {
  animation: pb-casting-hand-contact-v4 var(--pb-duration) linear both;
}

@keyframes pb-attacker-weapon-contact-v4 {
  0%, 12%, 100% { transform: rotate(0); }
  22% { transform: rotate(var(--pb-weapon-back)) translateY(2%); }
  34%, 42% { transform: rotate(var(--pb-weapon-contact)) translateY(-2%); }
  48%, 54% { transform: rotate(var(--pb-weapon-back)) translateY(2%); }
  58%, 65% { transform: rotate(var(--pb-weapon-counter)) translateY(-1%); }
  68% { transform: rotate(var(--pb-weapon-back)) translateY(1%); }
  72%, 80% { transform: rotate(var(--pb-weapon-strike)) translateY(-3%); }
  87% { transform: rotate(var(--pb-attacker-turn-out)); }
}

@keyframes pb-defender-weapon-contact-v4 {
  0%, 28%, 100% { transform: rotate(0); }
  34%, 43% { transform: rotate(var(--pb-defender-weapon-contact)) translateY(-2%); }
  49%, 54% { transform: rotate(var(--pb-defender-weapon-back)) translateY(2%); }
  58%, 66% { transform: rotate(var(--pb-defender-weapon-counter)) translateY(-3%); }
  69% { transform: rotate(var(--pb-defender-weapon-back)); }
  72%, 80% { transform: rotate(var(--pb-defender-weapon-guard)) translateY(-2%); }
  86% { transform: rotate(var(--pb-defender-turn-out)) translateY(3%); }
}

@keyframes pb-casting-hand-contact-v4 {
  0%, 25%, 100% { transform: rotate(0) translateY(0); }
  34%, 43% { transform: rotate(var(--pb-defender-turn-in)) translateY(-5%); }
  49%, 54% { transform: rotate(0) translateY(-2%); }
  58%, 66% { transform: rotate(var(--pb-defender-turn-out)) translateY(-7%); }
  72%, 80% { transform: rotate(var(--pb-defender-turn-in)) translateY(-5%); }
}

@keyframes pb-weapon-tip-contact-v4 {
  from { filter: drop-shadow(0 0 1px #fff2c2) drop-shadow(0 0 3px #65e5d1); }
  to { filter: drop-shadow(0 0 3px #fff8df) drop-shadow(0 0 6px #65e5d1); }
}

@media (prefers-reduced-motion: reduce) {
  .polished-battle-defender {
    display: none !important;
  }
}

/* source: battle-articulation-v3.css */
/* Close-range body mechanics for the two-actor duel rig. */

.polished-battle-defender .piece-token,
.polished-battle-attacker .piece-token {
  bottom: 0;
  left: -2%;
  width: 104%;
  height: 122%;
}

.polished-battle-defender::after,
.polished-battle-attacker::after {
  position: absolute;
  z-index: -1;
  right: 15%;
  bottom: 5%;
  left: 15%;
  height: 9%;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.58);
  filter: blur(3px);
  content: "";
  transform-origin: center;
}

.is-polished-battle-playing .polished-battle-attacker::after {
  animation: pb-duel-shadow-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-defender::after {
  animation: pb-defender-shadow-v3 var(--pb-duration) linear both;
}

.is-polished-battle-playing .polished-battle-attacker :is(
  .soldier-leg,
  .soldier-torso,
  .soldier-base,
  .soldier-cape
),
.is-polished-battle-playing .polished-battle-defender :is(
  .soldier-leg,
  .soldier-torso,
  .soldier-base,
  .soldier-cape
) {
  animation-duration: var(--pb-duration);
  animation-fill-mode: both;
  animation-timing-function: linear;
  transform-box: fill-box;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-leg--shield {
  animation-name: pb-duel-leg-a-v3;
  transform-origin: 50% 8%;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-leg--weapon {
  animation-name: pb-duel-leg-b-v3;
  transform-origin: 50% 8%;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-torso {
  animation-name: pb-duel-torso-v3;
  transform-origin: 50% 84%;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-base {
  animation-name: pb-duel-plinth-v3;
  transform-origin: 50% 78%;
}

.is-polished-battle-playing .polished-battle-attacker .soldier-cape {
  animation-name: pb-duel-cape-v3;
  transform-origin: 50% 14%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-leg--shield {
  animation-name: pb-defender-leg-a-v3;
  transform-origin: 50% 8%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-leg--weapon {
  animation-name: pb-defender-leg-b-v3;
  transform-origin: 50% 8%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-torso {
  animation-name: pb-defender-torso-v3;
  transform-origin: 50% 84%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-base {
  animation-name: pb-defender-plinth-v3;
  transform-origin: 50% 78%;
}

.is-polished-battle-playing .polished-battle-defender .soldier-cape {
  animation-name: pb-defender-cape-body-v3;
  transform-origin: 50% 14%;
}

@keyframes pb-duel-leg-a-v3 {
  0%, 8%, 100% { transform: rotate(0) translateY(0); }
  13% { transform: rotate(13deg) translateY(-2px); }
  18% { transform: rotate(-5deg) translateY(1px); }
  24% { transform: rotate(-12deg) translateY(0); }
  29% { transform: rotate(5deg) translateY(1px); }
  35%, 40% { transform: rotate(10deg) translateY(-1px); }
  47% { transform: rotate(-7deg) translateY(1px); }
  55%, 61% { transform: rotate(-4deg) translateY(1px); }
  67% { transform: rotate(14deg) translateY(-2px); }
  72%, 77% { transform: rotate(-6deg) translateY(1px); }
  83% { transform: rotate(-9deg) translateY(1px); }
  90% { transform: rotate(9deg) translateY(-1px); }
  95% { transform: rotate(-4deg) translateY(1px); }
}

@keyframes pb-duel-leg-b-v3 {
  0%, 8%, 100% { transform: rotate(0) translateY(0); }
  13% { transform: rotate(-11deg) translateY(0); }
  18% { transform: rotate(7deg) translateY(1px); }
  24% { transform: rotate(13deg) translateY(-2px); }
  29% { transform: rotate(-5deg) translateY(1px); }
  35%, 40% { transform: rotate(-8deg) translateY(1px); }
  47% { transform: rotate(8deg) translateY(-1px); }
  55%, 61% { transform: rotate(5deg) translateY(1px); }
  67% { transform: rotate(-12deg) translateY(0); }
  72%, 77% { transform: rotate(7deg) translateY(1px); }
  83% { transform: rotate(10deg) translateY(-1px); }
  90% { transform: rotate(-8deg) translateY(0); }
  95% { transform: rotate(4deg) translateY(1px); }
}

@keyframes pb-duel-torso-v3 {
  0%, 8%, 100% { transform: translateY(0) rotate(0); }
  13%, 24% { transform: translateY(-1px) rotate(var(--pb-attacker-turn-in)); }
  18%, 29% { transform: translateY(1px) rotate(0); }
  35%, 40% { transform: translateY(-1px) rotate(var(--pb-attacker-turn-in)); }
  47% { transform: translateY(1px) rotate(var(--pb-attacker-turn-out)); }
  55%, 61% { transform: translateY(1px) rotate(var(--pb-attacker-windup)); }
  67%, 77% { transform: translateY(-2px) rotate(var(--pb-attacker-strike)); }
  83% { transform: translateY(1px) rotate(var(--pb-attacker-turn-out)); }
  90% { transform: translateY(-1px); }
  95% { transform: translateY(1px); }
}

@keyframes pb-duel-plinth-v3 {
  0%, 8%, 100% { transform: translateY(0) scale(1); }
  13%, 24%, 67%, 90% { transform: translateY(-1px) scaleX(0.985); }
  18%, 29%, 47%, 77%, 95% { transform: translateY(1px) scaleX(1.025) scaleY(0.97); }
  55%, 61% { transform: translateY(1px) scaleX(1.015) scaleY(0.98); }
}

@keyframes pb-duel-cape-v3 {
  0%, 8%, 100% { transform: skewX(0); }
  13%, 24%, 35% { transform: skewX(-5deg) translateY(-1px); }
  18%, 29%, 47% { transform: skewX(3deg); }
  55%, 61% { transform: skewX(7deg) translateY(1px); }
  67%, 77% { transform: skewX(-9deg) translateY(-1px); }
  83%, 95% { transform: skewX(5deg); }
}

@keyframes pb-defender-leg-a-v3 {
  0%, 28%, 100% { transform: rotate(0) translateY(0); }
  34%, 40% { transform: rotate(-9deg) translateY(1px); }
  47% { transform: rotate(8deg) translateY(-1px); }
  54% { transform: rotate(0); }
  59%, 64% { transform: rotate(13deg) translateY(-2px); }
  69% { transform: rotate(-6deg) translateY(1px); }
  73%, 78% { transform: rotate(-10deg) translateY(1px); }
  86%, 96% { transform: rotate(18deg) translateY(2px); }
}

@keyframes pb-defender-leg-b-v3 {
  0%, 28%, 100% { transform: rotate(0) translateY(0); }
  34%, 40% { transform: rotate(10deg) translateY(-1px); }
  47% { transform: rotate(-7deg) translateY(1px); }
  54% { transform: rotate(0); }
  59%, 64% { transform: rotate(-11deg) translateY(0); }
  69% { transform: rotate(7deg) translateY(1px); }
  73%, 78% { transform: rotate(12deg) translateY(-1px); }
  86%, 96% { transform: rotate(-16deg) translateY(2px); }
}

@keyframes pb-defender-torso-v3 {
  0%, 28%, 100% { transform: translateY(0) rotate(0); }
  34%, 40% { transform: translateY(-1px) rotate(var(--pb-defender-turn-in)); }
  47% { transform: translateY(1px) rotate(var(--pb-defender-turn-out)); }
  54% { transform: translateY(0); }
  59%, 64% { transform: translateY(-2px) rotate(var(--pb-defender-turn-in)); }
  69% { transform: translateY(1px); }
  73%, 78% { transform: translateY(-1px) rotate(var(--pb-defender-turn-out)); }
  86%, 100% { transform: translateY(2px) rotate(var(--pb-defender-turn-out)); }
}

@keyframes pb-defender-plinth-v3 {
  0%, 28%, 100% { transform: translateY(0) scale(1); }
  34%, 59% { transform: translateY(-1px) scaleX(0.99); }
  40%, 47%, 64%, 69% { transform: translateY(1px) scaleX(1.025) scaleY(0.97); }
  73%, 78% { transform: translateY(1px) scaleX(1.04) scaleY(0.95); }
  86%, 100% { transform: translateY(2px) scaleX(1.06) scaleY(0.9); }
}

@keyframes pb-defender-cape-body-v3 {
  0%, 28%, 100% { transform: skewX(0); }
  34%, 40% { transform: skewX(-5deg); }
  47% { transform: skewX(4deg); }
  59%, 64% { transform: skewX(-7deg); }
  73%, 78% { transform: skewX(9deg); }
  86%, 100% { transform: skewX(13deg) translateY(2px); }
}

@keyframes pb-duel-shadow-v3 {
  0%, 8%, 18%, 29%, 47%, 61%, 77%, 83%, 95%, 100% { opacity: 0.72; transform: scale(1); }
  13%, 24%, 67%, 90% { opacity: 0.42; transform: scale(0.76); }
}

@keyframes pb-defender-shadow-v3 {
  0%, 28%, 40%, 54%, 64%, 69% { opacity: 0.72; transform: scale(1); }
  34%, 59% { opacity: 0.48; transform: scale(0.8); }
  73%, 78% { opacity: 0.6; transform: scale(1.05); }
  86%, 100% { opacity: 0.18; transform: scale(1.28); }
}

@media (prefers-reduced-motion: reduce) {
  .polished-battle-defender::after,
  .polished-battle-attacker::after {
    display: none !important;
  }
}


/* Grounded duel v4: readable close-up, three contact beats, physical fall. */
body:not(.flat-view) .board-stage.has-polished-battle > .board-frame {
  transform:
    rotateX(var(--board-tilt))
    rotateY(var(--board-yaw))
    scale(1.025);
  transform-origin: 50% 88%;
  transition: transform 420ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

.flat-view .board-stage.has-polished-battle > .board-frame {
  transform: scale(1.018);
  transform-origin: 50% 50%;
}

.polished-battle-defender .piece-token,
.polished-battle-attacker .piece-token {
  left: -6%;
  width: 112%;
  height: 132%;
}

body:not(.flat-view) .is-polished-battling
  .square:not(.is-polished-battle-source):not(.is-polished-battle-target):not(.is-polished-battle-destination)::before {
  background-color: rgba(1, 6, 9, 0.42);
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.3);
}

.is-polished-battle-playing .polished-battle-layer .polished-battle-attacker {
  animation-name: pb-attacker-duel-v4;
  animation-timing-function: linear;
}

.is-polished-battle-playing .polished-battle-layer.polished-battle--magic .polished-battle-attacker {
  animation-name: pb-attacker-caster-duel-v4;
}

.is-polished-battle-playing .polished-battle-layer .polished-battle-defender {
  animation-name: pb-defender-duel-v4;
  animation-timing-function: linear;
}

.polished-battle-layer:is(.battle-phase-parry, .battle-phase-counter, .battle-phase-decisive)
  :is(.polished-battle-attacker, .polished-battle-defender) .piece-token {
  filter:
    brightness(1.14)
    contrast(1.08)
    drop-shadow(0 0 calc(var(--pb-cell) * 0.055) var(--piece-gem, #ead088));
}

@keyframes pb-attacker-duel-v4 {
  0%, 8% {
    transform: translate3d(0, 0, 30px);
    filter: brightness(1);
  }
  12% {
    transform:
      translate3d(
        calc(var(--pb-step-one-x) * -0.16),
        calc(var(--pb-step-one-y) * -0.16 + 1px),
        29px
      )
      rotate(var(--pb-attacker-windup));
  }
  18% {
    transform:
      translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 2px), 33px)
      rotate(var(--pb-attacker-turn-in));
  }
  23% {
    transform:
      translate3d(var(--pb-step-one-x), var(--pb-step-one-y), 29px)
      rotate(var(--pb-attacker-turn-in));
  }
  28% {
    transform:
      translate3d(var(--pb-step-two-x), calc(var(--pb-step-two-y) - 2px), 33px)
      rotate(var(--pb-attacker-turn-out));
  }
  32% {
    transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 30px);
  }
  35%, 43% {
    transform:
      translate3d(var(--pb-parry-x), var(--pb-parry-y), 32px)
      rotate(var(--pb-attacker-turn-in));
    filter: brightness(1.16);
  }
  46% {
    transform:
      translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) + 1px), 29px)
      rotate(var(--pb-attacker-turn-out));
    filter: brightness(0.98);
  }
  52% {
    transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 29px);
  }
  57%, 65% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 1px), 28px)
      rotate(var(--pb-attacker-windup));
  }
  67% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 2px), 33px)
      rotate(var(--pb-attacker-windup));
  }
  71% {
    transform:
      translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) - 3px), 35px)
      rotate(var(--pb-attacker-strike));
  }
  72%, 80% {
    transform:
      translate3d(var(--pb-strike-x), var(--pb-strike-y), 32px)
      rotate(var(--pb-attacker-strike));
    filter: brightness(1.24);
  }
  84% {
    transform:
      translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 29px)
      rotate(var(--pb-attacker-turn-out));
    filter: brightness(1.04);
  }
  91% {
    transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 2px), 33px);
  }
  96%, 100% {
    transform: translate3d(var(--pb-end-x), var(--pb-end-y), 30px);
    filter: brightness(1);
  }
}

@keyframes pb-attacker-caster-duel-v4 {
  0%, 9% {
    opacity: 1;
    transform: translate3d(0, 0, 31px);
    filter: brightness(1);
  }
  16% {
    transform:
      translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 3px), 35px)
      rotate(var(--pb-attacker-turn-in));
  }
  25% {
    transform: translate3d(var(--pb-step-two-x), var(--pb-step-two-y), 31px);
  }
  34%, 42% {
    transform:
      translate3d(var(--pb-parry-x), calc(var(--pb-parry-y) - 1px), 35px)
      rotate(var(--pb-attacker-turn-in));
    filter: brightness(1.2);
  }
  46%, 52% {
    transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 31px);
  }
  57%, 64% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 3px), 36px)
      rotate(var(--pb-attacker-windup));
    filter: brightness(1.14);
  }
  68% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 5px), 39px)
      rotate(var(--pb-attacker-windup));
  }
  72%, 80% {
    opacity: 1;
    transform:
      translate3d(var(--pb-strike-x), var(--pb-strike-y), 38px)
      rotate(var(--pb-attacker-strike));
    filter: brightness(1.28);
  }
  84% {
    transform: translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) - 3px), 34px);
  }
  91% {
    transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 2px), 34px);
  }
  96%, 100% {
    opacity: 1;
    transform: translate3d(var(--pb-end-x), var(--pb-end-y), 31px);
    filter: brightness(1);
  }
}

@keyframes pb-defender-duel-v4 {
  0%, 31% {
    opacity: 1;
    transform: translate3d(0, 0, 30px);
    filter: brightness(1);
  }
  35%, 43% {
    transform:
      translate3d(var(--pb-defender-parry-x), var(--pb-defender-parry-y), 33px)
      rotate(var(--pb-defender-turn-in));
    filter: brightness(1.16);
  }
  46% {
    transform:
      translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 29px)
      rotate(var(--pb-defender-turn-out));
  }
  52% {
    transform: translate3d(0, 0, 30px);
    filter: brightness(1);
  }
  57%, 66% {
    transform:
      translate3d(
        var(--pb-defender-counter-x),
        calc(var(--pb-defender-counter-y) - 2px),
        34px
      )
      rotate(var(--pb-defender-turn-in));
    filter: brightness(1.12);
  }
  68% {
    transform: translate3d(0, 0, 30px);
  }
  72%, 80% {
    opacity: 1;
    transform:
      translate3d(
        var(--pb-defender-recoil-x),
        var(--pb-defender-recoil-y),
        34px
      )
      rotate(var(--pb-defender-turn-out));
    filter: brightness(1.3);
  }
  84% {
    opacity: 1;
    transform:
      translate3d(
        calc(var(--pb-defender-knock-x) * 0.25),
        calc(var(--pb-defender-knock-y) * 0.22),
        25px
      )
      rotate(calc(var(--pb-defender-knock-spin) * 0.22));
    filter: brightness(0.86);
  }
  89% {
    opacity: 0.96;
    transform:
      translate3d(
        calc(var(--pb-defender-knock-x) * 0.68),
        calc(var(--pb-defender-knock-y) * 0.72),
        13px
      )
      rotate(calc(var(--pb-defender-knock-spin) * 0.68));
    filter: brightness(0.7);
  }
  94%, 98% {
    opacity: 0.76;
    transform:
      translate3d(
        var(--pb-defender-knock-x),
        calc(var(--pb-defender-knock-y) + 5px),
        3px
      )
      rotate(var(--pb-defender-knock-spin));
    filter: brightness(0.52);
  }
  100% {
    opacity: 0;
    transform:
      translate3d(
        var(--pb-defender-knock-x),
        calc(var(--pb-defender-knock-y) + 5px),
        3px
      )
      rotate(var(--pb-defender-knock-spin));
    filter: brightness(0.46);
  }
}

.polished-battle-hud {
  top: clamp(5px, 1%, 9px);
  max-width: min(78%, 680px);
  min-height: 46px;
  gap: 10px;
  padding: 5px 7px 5px 14px;
}

.polished-battle-hud strong {
  margin-top: 2px;
  font-size: 12px;
}

.polished-battle-skip {
  min-height: 44px;
}

@media (max-width: 620px) {
  body:not(.flat-view) .board-stage.has-polished-battle > .board-frame {
    transform:
      rotateX(var(--board-tilt))
      rotateY(var(--board-yaw))
      scale(1.012);
  }

  .polished-battle-hud {
    width: calc(100% - 8px);
    max-width: calc(100% - 8px);
    min-height: 52px;
    padding: 5px 5px 5px 10px;
  }

  .polished-battle-hud strong {
    font-size: 11px;
  }

  .polished-battle-defender .piece-token,
  .polished-battle-attacker .piece-token {
    left: -4%;
    width: 108%;
    height: 126%;
  }
}

@media (prefers-reduced-motion: reduce) {
  body:not(.flat-view) .board-stage.has-polished-battle > .board-frame,
  .flat-view .board-stage.has-polished-battle > .board-frame {
    transform: rotateX(var(--board-tilt)) rotateY(var(--board-yaw));
    transition: none;
  }
}

/* source: ux-responsive-polish.css */
/*
 * UX responsive and legibility polish.
 * Load last: this layer sizes the complete physical arena, strengthens functional
 * contrast, and keeps the command surface reachable without changing the castle.
 */

:root {
  --board-size: min(70vw, calc(100dvh - 142px), 800px);
  --board-tilt: 52deg;
  --ux-travel: #a9e0d5;
  --ux-travel-deep: #4f9b8c;
  --ux-capture: #e0a458;
  --ux-copy: #b8b8b1;
  --ux-muted: #8e9492;
}

html,
body {
  max-width: 100%;
  overflow-x: clip;
}

.app-shell,
.game-layout,
.arena {
  min-width: 0;
  max-width: 100%;
}

.app-shell {
  padding: 8px clamp(16px, 2.7vw, 48px) 3px;
}

.masthead {
  min-height: 52px;
}

.game-layout {
  min-height: 0;
  padding: 4px 0;
}

.board-stage {
  perspective: 1040px;
  perspective-origin: 50% 27%;
}

@media (min-width: 1101px) and (min-height: 741px) {
  body:not(.flat-view) .board-frame {
    top: -30px;
  }

  body:not(.flat-view) .player-rail--hero {
    transform: translateY(-30px);
  }

  .flat-view {
    --board-size: min(68vw, calc(100dvh - 174px), 760px);
  }
}

/* Fit the board, masonry and both identity rails as one viewport envelope. */
.player-rail {
  min-height: 44px;
  padding: 2px 10px;
}

.player-rail--rival {
  width: min(calc(var(--board-size) * 0.94), 94%);
  margin-bottom: 4px;
  clip-path: polygon(1.4% 0, 98.6% 0, 100% 100%, 0 100%);
}

.player-rail--hero {
  margin-top: 4px;
}

.player-copy small {
  color: #ddbd72;
  font-size: 9px;
}

.player-copy strong {
  color: #e6decc;
  font-size: 15px;
  text-shadow: 0 1px 2px #000;
}

/* Rails identify the courts; the command panel remains the status authority. */
.rail-status {
  color: #c5cac5;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  opacity: 1;
}

.rail-status--active {
  color: #ead28e;
}

.rail-status--active::before {
  background: #c7a85d;
  box-shadow: 0 0 6px rgba(212, 180, 103, 0.48);
  animation: none;
}

/* Continue the terrace beyond the board instead of enclosing it in a card. */
.arena::before {
  width: min(calc(var(--board-size) * 1.42), calc(100vw - 20px));
  background:
    radial-gradient(ellipse at 50% 72%, rgba(174, 191, 182, 0.14), transparent 61%),
    radial-gradient(ellipse at 50% 45%, rgba(213, 179, 101, 0.09), transparent 68%);
}

.arena::after {
  width: min(calc(var(--board-size) * 1.34), calc(100vw - 18px));
  clip-path: none;
  opacity: 0.76;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}

.board-stage::before {
  border-color: rgba(180, 170, 137, 0.16);
  box-shadow:
    0 2px 0 rgba(111, 108, 96, 0.82),
    0 7px 0 #272b28,
    0 13px 0 #0e1211,
    0 18px 24px rgba(0, 0, 0, 0.42),
    inset 0 0 0 3px rgba(4, 7, 7, 0.5),
    inset 0 0 28px rgba(0, 0, 0, 0.5);
}

.board-stage::after {
  right: -2.4%;
  bottom: -1%;
  left: -2.4%;
  height: 9%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.board-shadow {
  right: -2%;
  bottom: -1.2%;
  left: -2%;
  height: 10%;
  opacity: 0.78;
  filter: blur(11px);
}

/* Functional contrast and readable controls. */
.icon-button {
  min-width: 44px;
  min-height: 44px;
  color: #d0ccc0;
  background: rgba(7, 11, 18, 0.68);
  font-size: 10px;
}

#view-toggle {
  position: relative;
}

#view-toggle[aria-pressed="true"] {
  border-color: rgba(226, 194, 114, 0.74);
  color: #f1d487;
  background: linear-gradient(180deg, rgba(119, 91, 42, 0.28), rgba(9, 13, 19, 0.78));
  box-shadow: inset 0 -2px #c99f4b, 0 0 15px rgba(205, 164, 73, 0.1);
}

#view-toggle .icon--cube {
  width: 17px;
  height: 17px;
  border-width: 1.5px;
}

#view-toggle[aria-pressed="false"] .icon--cube {
  height: 13px;
  transform: rotate(45deg) scaleY(0.58);
}

.command-panel {
  border-color: rgba(220, 187, 109, 0.42);
  background:
    linear-gradient(150deg, rgba(31, 40, 52, 0.9), rgba(6, 9, 16, 0.97)),
    var(--panel);
}

.turn-oracle small {
  color: #e0bd69;
  font-size: 10px;
}

.turn-oracle p {
  color: var(--ux-copy);
  font-size: 12px;
}

.section-heading > span,
.text-button,
.captured-row > span,
.move-number {
  font-size: 9px;
}

.captured-row > span,
.move-number {
  color: var(--ux-muted);
}

.text-button {
  display: inline-grid;
  min-width: 44px;
  min-height: 44px;
  place-items: center;
  color: #e0bc68;
}

.chronicle-empty {
  min-height: 62px;
  flex-wrap: wrap;
  align-content: center;
  color: #a6aaa6;
  font-size: 12px;
  line-height: 1.35;
  text-align: center;
}

.chronicle-empty::after {
  width: 100%;
  color: #7faaa0;
  content: "Select a soldier, then choose a marked square.";
  font-family: var(--sans);
  font-size: 9px;
  font-style: normal;
  letter-spacing: 0.035em;
}

.move-list {
  min-height: 64px;
}

.move-pair {
  min-height: 32px;
  font-size: 12px;
}

.action-button {
  min-height: 44px;
  font-size: 12px;
}

.secondary-actions button {
  min-height: 44px;
  color: #aaaead;
  font-size: 9px;
}

.cinematic-toggle {
  min-height: 44px;
}

.cinematic-toggle strong {
  color: #d0cabc;
  font-size: 11px;
}

.cinematic-toggle small {
  color: #949997;
  font-size: 9px;
}

.footer-note {
  color: rgba(215, 210, 195, 0.58);
  font-size: 10px;
}

/* Hint is supportive—not the primary empty-state call to action. */
.command-panel:has(.chronicle-empty) .captured-section {
  margin-bottom: 10px;
}

.command-panel:has(.chronicle-empty) #hint-button {
  border-color: rgba(193, 165, 103, 0.32);
  color: #c7c2b7;
  background: rgba(17, 23, 30, 0.86);
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.035);
}

.command-panel:has(.chronicle-empty) #hint-button > span {
  color: #d8b760;
}

/* Quiet paths are teal/ivory; danger uses unmistakable amber corners. */
.square:not(.is-capture) .move-marker {
  width: 22%;
  border-color: rgba(218, 239, 231, 0.92);
  background: radial-gradient(circle, #e8f3ed 0 20%, #75b8aa 24% 48%, rgba(31, 79, 71, 0.72) 52% 100%);
  box-shadow: 0 0 0 4px rgba(99, 174, 159, 0.11), 0 0 11px rgba(124, 211, 194, 0.68);
}

.square:not(.is-capture) .move-marker::before,
.square:not(.is-capture) .move-marker::after {
  display: none;
}

.square.is-capture .move-marker {
  width: 76%;
  background:
    linear-gradient(var(--ux-capture), var(--ux-capture)) left top / 25% 2px no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) left top / 2px 25% no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) right top / 25% 2px no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) right top / 2px 25% no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) left bottom / 25% 2px no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) left bottom / 2px 25% no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) right bottom / 25% 2px no-repeat,
    linear-gradient(var(--ux-capture), var(--ux-capture)) right bottom / 2px 25% no-repeat;
  filter: drop-shadow(0 0 5px rgba(224, 138, 54, 0.65));
}

.square.is-capture:hover,
.square.is-capture:focus-visible {
  box-shadow: inset 0 0 0 2px rgba(224, 164, 88, 0.72), inset 0 0 22px rgba(151, 74, 26, 0.2);
}

/* Coordinates remain visible across slate values and perspective compression. */
.square[data-file-label]::after,
.rank-label {
  font-size: clamp(9px, calc(var(--board-size) / 70), 11px);
  font-weight: 700;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.16);
  transform: translateZ(2px) scaleY(1.2);
  transform-origin: 50% 100%;
}

.square--light[data-file-label]::after,
.square--light .rank-label {
  color: rgba(20, 26, 24, 0.82);
}

.square--dark[data-file-label]::after,
.square--dark .rank-label {
  color: rgba(235, 228, 200, 0.82);
  text-shadow: 0 1px 2px #000;
}

/* Tiny outer-shape reinforcement only; no extra internal piece detail. */
.soldier-icon[data-renderer="readable"][data-piece="b"] .readable-soldier {
  transform: scale(0.91, 1.035);
}

.soldier-icon[data-renderer="readable"][data-piece="q"] .readable-soldier {
  transform: scale(1.055, 1.018);
}

.soldier-icon[data-renderer="readable"][data-piece="k"] .readable-soldier {
  transform: scale(1.06, 1.035);
}

/* Setup legibility plus hooks for the refined setup structure. */
.choice-group legend,
.choice-card small,
.compact-choices span,
.keyboard-note {
  color: #8f9693;
  font-size: 9px;
}

.choice-group legend {
  color: #a1a49f;
}

.choice-card small {
  color: #a1a5a2;
  line-height: 1.35;
}

.compact-choices label > span {
  min-height: 44px;
  color: #a7aaa6;
}

.setup-options {
  gap: 14px;
  margin-top: 16px;
}

.preference-stack {
  display: grid;
  gap: 12px;
  margin-top: 16px;
}

.option-label__theme,
.option-label__plain {
  display: block;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
}

.option-label__theme {
  color: #d5cebd;
  font-family: var(--serif);
  font-size: 10px;
  line-height: 1.15;
}

.option-label__plain {
  margin-top: 2px;
  color: #8f9693;
  font-size: 9px;
  line-height: 1.1;
}

.compact-choices input:checked + span .option-label__theme {
  color: var(--gold-bright);
}

#setup-close {
  position: absolute;
  z-index: 5;
  top: 12px;
  right: 12px;
  display: grid;
  width: 44px;
  height: 44px;
  padding: 0;
  place-items: center;
  border: 1px solid rgba(215, 185, 115, 0.36);
  border-radius: 50%;
  color: #d5cdbb;
  background: rgba(5, 9, 14, 0.76);
  font-size: 22px;
  cursor: pointer;
}

#setup-close:hover {
  border-color: var(--gold);
  color: var(--gold-bright);
}

/* Tablet: a pronounced but touch-friendly plane keeps the arena monumental. */
@media (max-width: 1100px) {
  :root {
    --board-size: min(88vw, calc(100dvh - 180px), 760px);
    --board-tilt: 44deg;
  }

  .board-stage {
    perspective: 920px;
    perspective-origin: 50% 29%;
  }

  .app-shell {
    padding-top: 8px;
  }

  .masthead {
    min-height: 52px;
  }

  .game-layout {
    gap: 10px;
    padding-top: 4px;
  }

  .world__image {
    background-position: 50% 38%;
  }

  .command-panel {
    grid-template-areas:
      "oracle oracle"
      "rule rule"
      "actions secondary"
      "captured chronicle"
      "toggle toggle";
    gap: 0 18px;
  }

  .turn-oracle { grid-area: oracle; }
  .panel-rule { grid-area: rule; }
  .captured-section { grid-area: captured; }
  .chronicle { grid-area: chronicle; }
  .primary-actions { grid-area: actions; }
  .secondary-actions {
    grid-area: secondary;
    margin: 0 0 14px;
  }
  .command-panel > .preference-stack { grid-area: toggle; }
  .preference-stack > .cinematic-toggle { grid-area: auto; }

  .arena::before {
    width: min(calc(var(--board-size) * 1.32), calc(100vw - 18px));
  }

  .arena::after {
    width: min(calc(var(--board-size) * 1.2), calc(100vw - 16px));
  }
}

/* Phone: visible depth, 44px controls and an early sticky action strip. */
@media (max-width: 620px) {
  :root {
    --board-size: min(calc(100vw - 12px), calc(100dvh - 310px), 560px);
    --board-tilt: 30deg;
  }

  .board-stage {
    perspective: 760px;
    perspective-origin: 50% 28%;
  }

  .square[data-file-label]::after,
  .rank-label {
    transform: translateZ(2px) scaleY(1.1);
  }

  .app-shell {
    padding: 8px 6px max(18px, env(safe-area-inset-bottom));
  }

  .masthead {
    min-height: 52px;
  }

  .brand {
    gap: 8px;
    padding-right: 4px;
  }

  .brand__sigil {
    width: 32px;
    height: 32px;
  }

  .brand strong {
    font-size: 12px;
    letter-spacing: 0.055em;
  }

  .masthead__actions {
    gap: 5px;
  }

  .icon-button,
  .icon-button--round {
    width: 44px;
    height: 44px;
    min-height: 44px;
  }

  #view-toggle[aria-pressed="true"]::after {
    position: absolute;
    right: 5px;
    bottom: 5px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--gold-bright);
    box-shadow: 0 0 6px var(--gold);
    content: "";
  }

  .game-layout {
    gap: 10px;
    padding-top: 5px;
  }

  .player-rail {
    min-height: 44px;
    padding: 2px 8px;
  }

  .player-rail--rival {
    width: min(calc(var(--board-size) * 0.95), 95%);
    margin-bottom: 4px;
  }

  .player-rail--hero {
    margin-top: 4px;
  }

  .player-copy small {
    font-size: 9px;
  }

  .player-copy strong {
    font-size: 13px;
  }

  .rail-status {
    max-width: 112px;
    font-size: 11px;
    letter-spacing: 0.08em;
  }

  .board-stage::before {
    inset: -1.2% -1.4% -2.4%;
  }

  .board-stage::after {
    right: -1%;
    left: -1%;
    height: 6%;
  }

  .arena::before,
  .arena::after {
    max-width: calc(100vw - 12px);
  }

  .arena::after {
    bottom: 41px;
    width: min(calc(var(--board-size) * 1.08), calc(100vw - 12px));
    opacity: 0.58;
  }

  .command-panel {
    display: flex;
    overflow: visible;
    flex-direction: column;
    padding: 18px 15px 16px;
  }

  .turn-oracle { order: 1; }
  .panel-rule {
    order: 2;
    margin: 12px 0;
  }
  .primary-actions {
    position: sticky;
    z-index: 20;
    top: max(8px, env(safe-area-inset-top));
    order: 3;
    grid-template-columns: 1fr 1fr;
    padding: 5px;
    margin: 0 -5px 8px;
    border: 1px solid rgba(204, 174, 105, 0.22);
    background: rgba(8, 13, 19, 0.93);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32);
    backdrop-filter: blur(12px);
  }
  .secondary-actions {
    order: 4;
    margin: 0 0 14px;
    border-top: 1px solid rgba(212, 180, 103, 0.12);
    border-bottom: 1px solid rgba(212, 180, 103, 0.12);
  }
  .captured-section { order: 5; }
  .chronicle { order: 6; }
  .command-panel > .preference-stack { order: 7; width: 100%; }
  .preference-stack > .cinematic-toggle { order: initial; }

  .turn-oracle {
    grid-template-columns: 48px 1fr;
    gap: 12px;
  }

  .turn-oracle__halo {
    width: 46px;
    height: 46px;
  }

  .turn-oracle small,
  .section-heading > span,
  .captured-row > span,
  .move-number,
  .secondary-actions button,
  .cinematic-toggle small,
  .chronicle-empty::after {
    font-size: 11px;
  }

  .turn-oracle p,
  .chronicle-empty,
  .move-pair,
  .action-button {
    font-size: 12px;
  }

  .text-button,
  .secondary-actions button,
  .cinematic-toggle {
    min-height: 44px;
  }

  .captured-row {
    min-height: 32px;
  }

  .square[data-file-label]::after,
  .rank-label {
    right: 2px;
    bottom: 1px;
    font-size: 10px;
  }

  .rank-label {
    top: 1px;
    right: auto;
    left: 2px;
  }

  .modal-card {
    padding: 26px 16px 20px;
  }

  .modal-intro {
    margin-bottom: 17px;
    font-size: 12px;
  }

  .choice-card {
    min-height: 64px;
    padding: 9px 10px;
  }

  .choice-card strong {
    font-size: 14px;
  }

  .choice-card small,
  .choice-group legend,
  .compact-choices span,
  .option-label__plain {
    font-size: 11px;
  }

  .compact-choices label > span {
    min-height: 48px;
    padding: 5px 3px;
  }

  .option-label__theme {
    font-size: 11px;
  }

  .setup-options,
  .preference-stack {
    gap: 10px;
    margin-top: 12px;
  }

  .begin-button {
    min-height: 52px;
    margin-top: 18px;
  }
}

@media (max-width: 360px) {
  .brand__sigil {
    display: none;
  }

  .brand strong {
    max-width: 112px;
    font-size: 11px;
  }
}

@media (max-height: 740px) and (min-width: 1101px) {
  .app-shell {
    padding-top: 8px;
    padding-bottom: 3px;
  }

  .masthead {
    min-height: 52px;
  }

  .game-layout {
    padding-top: 2px;
    padding-bottom: 2px;
  }

  .player-rail {
    min-height: 44px;
    padding-top: 4px;
    padding-bottom: 4px;
  }

  .player-rail--rival { margin-bottom: 4px; }
  .player-rail--hero { margin-top: 4px; }

  .footer-note {
    font-size: 9px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rail-status--active::before,
  .move-marker {
    animation: none;
  }
}

/* source: arrival-cinematic.css */
/* Castle-to-board opening flight. Loaded last so the cinematic can sit above
   every dialog and battle layer without changing their local stacking rules. */

.arrival-cinematic {
  --arrival-flight: 6900ms;
  /* The desktop live arena is centered at roughly 36.5vw. The final plate
     settles onto that same footprint before the interface is revealed. */
  --arrival-live-pan-x: -7.7%;
  --arrival-live-pan-y: 6.2%;
  position: fixed;
  z-index: 5000;
  inset: 0;
  overflow: hidden;
  color: #f0e7d2;
  background: #02050a;
  opacity: 0;
  isolation: isolate;
  transition: opacity 620ms cubic-bezier(0.4, 0, 0.2, 1);
}

.arrival-cinematic.is-active {
  opacity: 1;
}

.arrival-cinematic.is-leaving {
  opacity: 0;
  pointer-events: none;
}

.arrival-shot,
.arrival-shade,
.arrival-threshold,
.arrival-floor-light,
.arrival-flight-lines {
  position: absolute;
  inset: -8%;
  pointer-events: none;
}

.arrival-shot {
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
  will-change: opacity, transform, filter;
}

.arrival-shot--castle {
  z-index: 1;
  background-image:
    linear-gradient(180deg, rgba(2, 5, 12, 0.04), rgba(2, 5, 10, 0.2) 52%, rgba(1, 3, 7, 0.72)),
    url("../assets/images/enchanted-castle.webp");
  transform-origin: 50% 56%;
}

.arrival-shot--hall {
  z-index: 2;
  background-image:
    linear-gradient(180deg, rgba(2, 5, 9, 0.04), rgba(2, 5, 9, 0.12) 58%, rgba(1, 3, 7, 0.48)),
    url("../assets/images/grand-hall-arrival.webp");
  transform-origin: 50% 66%;
  opacity: 0;
}

.is-active .arrival-shot--castle {
  animation: arrival-castle-flight var(--arrival-flight) cubic-bezier(0.22, 0.72, 0.18, 1) both;
}

.is-active .arrival-shot--hall {
  animation: arrival-hall-flight var(--arrival-flight) cubic-bezier(0.22, 0.72, 0.18, 1) both;
}

.arrival-shade {
  z-index: 3;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(0, 2, 7, 0.74), transparent 22% 78%, rgba(0, 2, 7, 0.74)),
    linear-gradient(180deg, rgba(1, 3, 8, 0.28), transparent 35% 68%, rgba(0, 2, 6, 0.72)),
    radial-gradient(ellipse at 50% 58%, transparent 0 28%, rgba(0, 2, 7, 0.16) 58%, rgba(0, 2, 7, 0.68) 100%);
}

.arrival-threshold {
  z-index: 4;
  inset: -20%;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 54%, transparent 0 8%, rgba(191, 221, 224, 0.18) 9%, rgba(10, 21, 27, 0.62) 17%, rgba(0, 2, 7, 0.96) 31%, #010307 62%);
  mix-blend-mode: screen;
}

.is-active .arrival-threshold {
  animation: arrival-cross-threshold var(--arrival-flight) ease-in-out both;
}

.arrival-floor-light {
  z-index: 5;
  inset: 0;
  opacity: 0;
  background:
    linear-gradient(180deg, transparent 0 54%, rgba(112, 213, 201, 0.06) 66%, rgba(215, 181, 102, 0.14) 78%, transparent 100%),
    radial-gradient(ellipse at 50% 76%, rgba(225, 196, 125, 0.24), rgba(75, 167, 160, 0.09) 30%, transparent 64%);
}

.is-active .arrival-floor-light {
  animation: arrival-floor-awaken var(--arrival-flight) ease-in-out both;
}

.arrival-flight-lines {
  z-index: 6;
  inset: 0;
  overflow: hidden;
  opacity: 0;
}

.arrival-flight-lines i {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1px;
  height: 42vh;
  background: linear-gradient(transparent, rgba(176, 221, 218, 0.24), transparent);
  filter: blur(0.3px);
  transform-origin: 50% 0;
}

.arrival-flight-lines i:nth-child(1) { transform: translate(-29vw, -42vh) rotate(-24deg); }
.arrival-flight-lines i:nth-child(2) { transform: translate(-14vw, -45vh) rotate(-13deg); }
.arrival-flight-lines i:nth-child(3) { transform: translate(16vw, -45vh) rotate(14deg); }
.arrival-flight-lines i:nth-child(4) { transform: translate(31vw, -42vh) rotate(25deg); }

.is-active .arrival-flight-lines {
  animation: arrival-speed-lines var(--arrival-flight) ease both;
}

.arrival-caption {
  position: absolute;
  z-index: 10;
  right: 0;
  left: 0;
  display: grid;
  justify-items: center;
  padding: 0 20px;
  text-align: center;
  pointer-events: none;
}

.arrival-caption small,
.arrival-caption strong {
  display: block;
  text-shadow: 0 3px 20px #000, 0 1px 2px #000;
}

.arrival-caption small {
  color: #d8bc74;
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.34em;
}

.arrival-caption strong {
  margin-top: 10px;
  font-family: var(--serif);
  font-size: clamp(27px, 4.1vw, 62px);
  font-weight: 400;
  letter-spacing: 0.025em;
}

.arrival-caption--castle {
  top: 16%;
  opacity: 0;
}

.arrival-caption--hall {
  bottom: 15%;
  opacity: 0;
}

.is-active .arrival-caption--castle {
  animation: arrival-caption-castle var(--arrival-flight) ease both;
}

.is-active .arrival-caption--hall {
  animation: arrival-caption-hall var(--arrival-flight) ease both;
}

.arrival-skip {
  position: absolute;
  z-index: 20;
  top: max(18px, env(safe-area-inset-top));
  right: max(20px, env(safe-area-inset-right));
  display: inline-flex;
  min-width: 132px;
  min-height: 44px;
  gap: 10px;
  align-items: center;
  justify-content: center;
  padding: 8px 10px 8px 14px;
  border: 1px solid rgba(215, 183, 106, 0.62);
  border-radius: 2px;
  color: #e7ddc6;
  background: rgba(5, 10, 15, 0.74);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.34), inset 0 0 0 2px rgba(3, 7, 9, 0.7);
  backdrop-filter: blur(10px);
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.arrival-skip span {
  display: grid;
  min-width: 28px;
  height: 24px;
  place-items: center;
  border-left: 1px solid rgba(215, 183, 106, 0.35);
  color: #b9b5aa;
  font-size: 8px;
}

.arrival-skip:hover,
.arrival-skip:focus-visible {
  border-color: #e3c26e;
  color: #fff4d9;
  background: rgba(13, 22, 26, 0.9);
}

.arrival-progress {
  position: absolute;
  z-index: 20;
  right: 8vw;
  bottom: max(24px, env(safe-area-inset-bottom));
  left: 8vw;
  height: 1px;
  overflow: hidden;
  background: rgba(220, 198, 144, 0.14);
}

.arrival-progress i {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, #597f7a, #e1c271 72%, #f6e6af);
  box-shadow: 0 0 9px rgba(225, 194, 113, 0.46);
  transform: scaleX(0);
  transform-origin: left;
}

.is-active .arrival-progress i {
  animation: arrival-progress var(--arrival-flight) linear both;
}

@keyframes arrival-castle-flight {
  0% { opacity: 1; filter: brightness(0.72) saturate(0.82); transform: scale(1.015) translate3d(0, 0, 0); }
  16% { opacity: 1; filter: brightness(0.92) saturate(0.94); }
  36% { opacity: 1; filter: brightness(0.82) saturate(0.9); transform: scale(1.28) translate3d(0, -1.8%, 0); }
  47% { opacity: 0; filter: brightness(0.38) blur(2px); transform: scale(1.62) translate3d(0, 2.4%, 0); }
  100% { opacity: 0; transform: scale(1.66) translate3d(0, 2.4%, 0); }
}

@keyframes arrival-hall-flight {
  0%, 34% { opacity: 0; filter: brightness(0.42) blur(3px); transform: scale(0.96) translate3d(0, -4%, 0); }
  45% { opacity: 1; filter: brightness(0.76) blur(0); transform: scale(1.015) translate3d(0, -1%, 0); }
  68% { opacity: 1; filter: brightness(0.9) saturate(0.94); transform: scale(1.14) translate3d(0, -2.8%, 0); }
  82% { opacity: 1; filter: brightness(0.9) saturate(0.94); transform: scale(1.46) translate3d(0, -5.6%, 0); }
  91% { opacity: 1; filter: brightness(0.84) saturate(0.9); transform: scale(1.44) translate3d(-2.4%, -1.2%, 0); }
  100% {
    opacity: 1;
    filter: brightness(0.78) saturate(0.86) contrast(1.06);
    transform: scale(1.42) translate3d(var(--arrival-live-pan-x), var(--arrival-live-pan-y), 0);
  }
}

@keyframes arrival-cross-threshold {
  0%, 28% { opacity: 0; transform: scale(0.34); }
  38% { opacity: 0.72; transform: scale(0.58); }
  47% { opacity: 0; transform: scale(1.42); }
  100% { opacity: 0; transform: scale(1.6); }
}

@keyframes arrival-floor-awaken {
  0%, 58% { opacity: 0; transform: scale(0.8); }
  76% { opacity: 0.66; }
  100% { opacity: 0.22; transform: scale(1.18); }
}

@keyframes arrival-speed-lines {
  0%, 28%, 56%, 100% { opacity: 0; transform: scale(0.8); }
  38% { opacity: 0.45; transform: scale(1.4); }
  74% { opacity: 0.14; transform: scale(1.1); }
  86% { opacity: 0.28; transform: scale(1.6); }
}

@keyframes arrival-caption-castle {
  0%, 4% { opacity: 0; transform: translateY(12px); }
  12%, 27% { opacity: 1; transform: translateY(0); }
  36%, 100% { opacity: 0; transform: translateY(-10px); }
}

@keyframes arrival-caption-hall {
  0%, 48% { opacity: 0; transform: translateY(12px); }
  60%, 84% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-8px); }
}

@keyframes arrival-progress {
  to { transform: scaleX(1); }
}

@media (max-width: 1100px) {
  .arrival-cinematic {
    --arrival-live-pan-x: 0%;
    --arrival-live-pan-y: 2.4%;
  }
}

@media (max-width: 620px) {
  .arrival-shot {
    inset: -5%;
  }

  .arrival-shot--castle {
    background-position: 50% 48%;
  }

  .arrival-shot--hall {
    background-position: 50% 56%;
  }

  .arrival-caption--castle { top: 21%; }
  .arrival-caption--hall { bottom: 18%; }

  .arrival-caption small {
    font-size: 9px;
    letter-spacing: 0.24em;
  }

  .arrival-caption strong {
    max-width: 330px;
    font-size: clamp(27px, 9vw, 38px);
  }

  .arrival-skip {
    top: max(12px, env(safe-area-inset-top));
    right: max(12px, env(safe-area-inset-right));
    min-width: 118px;
  }

  .arrival-progress {
    right: 18px;
    left: 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .arrival-cinematic,
  .arrival-cinematic * {
    animation: none !important;
    transition-duration: 1ms !important;
  }
}

/* source: cinematic-playfield.css */
/*
 * Gameplay match-cut for the great-hall arrival.
 *
 * This sheet intentionally loads after the general responsive layer: the live
 * board should feel like the stone floor seen at the end of the arrival, rather
 * than a separate green tabletop placed in front of the exterior castle.
 */

:root {
  --hall-stone-light: #a9aea8;
  --hall-stone-light-deep: #747b79;
  --hall-stone-dark: #23333b;
  --hall-stone-dark-deep: #0d171d;
  --hall-edge: #788083;
  --hall-bronze: #8e7545;
  --hall-bronze-lit: #c1a66d;
  --hall-focus-x: 50%;
}

/* Stay inside the same hall once the arrival film releases the interface. */
.world__image {
  background-image: url("../assets/images/grand-hall-arrival.webp");
  background-position: 50% 50%;
  background-size: cover;
  filter: saturate(0.84) contrast(1.08) brightness(0.76);
  transform: scale(1.035);
  animation-name: hall-breathe;
}

.world__veil {
  background:
    linear-gradient(90deg,
      rgba(2, 7, 11, 0.32) 0,
      rgba(3, 8, 12, 0.13) 42%,
      rgba(2, 6, 10, 0.38) 67%,
      rgba(1, 4, 8, 0.72) 100%),
    linear-gradient(180deg,
      rgba(2, 7, 13, 0.22) 0,
      rgba(2, 6, 10, 0.12) 48%,
      rgba(1, 4, 7, 0.68) 100%),
    radial-gradient(ellipse at var(--hall-focus-x) 65%, transparent 0 31%, rgba(1, 5, 8, 0.22) 67%, rgba(1, 4, 7, 0.54) 100%);
}

/* On wide screens the board owns the left composition column. Pan the hall
   plate to the same vanishing point instead of leaving its aisle behind the
   command panel. The extra scale keeps both viewport edges fully painted. */
@media (min-width: 1101px) {
  :root {
    --hall-focus-x: 36.5%;
  }

  .world__image {
    transform: translate3d(-12.5vw, 0, 0) scale(1.26);
    animation-name: hall-breathe-desktop;
  }
}

@keyframes hall-breathe {
  from { transform: scale(1.025) translate3d(-0.16%, -0.08%, 0); }
  to { transform: scale(1.055) translate3d(0.22%, 0.18%, 0); }
}

@keyframes hall-breathe-desktop {
  from { transform: translate3d(-12.7vw, -0.08%, 0) scale(1.255); }
  to { transform: translate3d(-12.3vw, 0.16%, 0) scale(1.275); }
}

/* The live arena continues the hall floor instead of introducing a new dais. */
.arena::before {
  background:
    radial-gradient(ellipse at 50% 66%, rgba(161, 182, 183, 0.16), transparent 61%),
    radial-gradient(ellipse at 50% 47%, rgba(206, 168, 92, 0.075), transparent 70%);
  filter: blur(12px);
}

.arena::after {
  bottom: 45px;
  height: clamp(62px, calc(var(--board-size) * 0.14), 112px);
  background:
    linear-gradient(180deg,
      rgba(160, 166, 163, 0.13) 0 1px,
      rgba(27, 36, 38, 0.72) 2px 30%,
      rgba(7, 13, 16, 0.85) 31% 38%,
      rgba(80, 88, 88, 0.14) 39% 40%,
      rgba(17, 25, 28, 0.78) 41% 100%),
    linear-gradient(90deg, transparent, rgba(191, 158, 86, 0.08) 50%, transparent);
  box-shadow: 0 22px 40px rgba(0, 0, 0, 0.45);
  opacity: 0.64;
}

.board-stage::before {
  inset: -1.15% -1.45% -2.8%;
  border-color: rgba(160, 170, 168, 0.24);
  background:
    linear-gradient(128deg, transparent 0 24%, rgba(212, 218, 210, 0.065) 25% 25.4%, transparent 26% 71%, rgba(0, 0, 0, 0.22) 72%),
    radial-gradient(ellipse at 50% 2%, rgba(190, 198, 194, 0.16), transparent 43%),
    linear-gradient(145deg, #424a4a 0, #252e30 44%, #10191c 76%, #30393a 100%);
  box-shadow:
    0 1px 0 rgba(184, 190, 184, 0.58),
    0 4px 0 #293235,
    0 8px 0 #10171a,
    0 14px 22px rgba(0, 0, 0, 0.44),
    inset 0 0 0 2px rgba(5, 10, 12, 0.66),
    inset 0 0 24px rgba(0, 0, 0, 0.48);
}

.board-stage::after {
  right: -1.2%;
  bottom: -0.35%;
  left: -1.2%;
  height: 5.5%;
  background:
    linear-gradient(90deg, transparent 3%, rgba(191, 159, 89, 0.18) 20%, transparent 38% 62%, rgba(191, 159, 89, 0.14) 80%, transparent 97%),
    linear-gradient(180deg, #394245 0, #1b2529 28%, #0a1115 100%);
  box-shadow: inset 0 1px rgba(195, 201, 195, 0.18), 0 13px 22px rgba(0, 0, 0, 0.42);
}

.board-shadow {
  bottom: -0.3%;
  height: 8%;
  opacity: 0.62;
  filter: blur(9px);
}

.board-frame {
  padding: 2.35%;
  border-color: rgba(152, 133, 87, 0.72);
  background:
    linear-gradient(137deg, transparent 17%, rgba(218, 221, 209, 0.09) 31%, transparent 45%),
    linear-gradient(145deg, #4b5351, #273033 49%, #11191d 74%, #343d3d 100%);
  box-shadow:
    0 1px 0 var(--hall-edge),
    0 3px 0 #354043,
    0 6px 0 #141d21,
    0 11px 16px rgba(0, 0, 0, 0.36),
    inset 0 0 0 3px #11191c,
    inset 0 0 0 4px rgba(160, 136, 78, 0.55),
    inset 0 0 24px rgba(0, 0, 0, 0.62);
}

.board-frame::before {
  inset: 0.72%;
  border-color: rgba(189, 163, 99, 0.5);
  box-shadow: 0 0 7px rgba(205, 172, 95, 0.08);
}

.board-frame::after {
  right: 2%;
  bottom: 0.75%;
  left: 2%;
  background: linear-gradient(90deg, transparent, rgba(199, 169, 100, 0.2), transparent);
}

.board-corner::before,
.board-corner::after {
  background: var(--hall-bronze);
  box-shadow: 0 0 3px rgba(193, 166, 109, 0.18);
}

.chessboard {
  border: 1px solid #071015;
  background: #0d171b;
  box-shadow:
    0 0 0 1px rgba(154, 132, 77, 0.78),
    inset 0 0 26px rgba(0, 0, 0, 0.72);
}

/* Weathered blue-grey floor inlay from the arrival artwork. */
.square--light {
  background:
    radial-gradient(circle at 22% 17%, rgba(255, 255, 241, 0.17), transparent 23%),
    linear-gradient(31deg, transparent 0 57%, rgba(19, 29, 31, 0.1) 58% 59%, transparent 60%),
    repeating-linear-gradient(153deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 7px),
    linear-gradient(145deg, var(--hall-stone-light), var(--hall-stone-light-deep));
}

.square--dark {
  background:
    radial-gradient(circle at 70% 20%, rgba(137, 174, 180, 0.13), transparent 28%),
    linear-gradient(37deg, transparent 0 62%, rgba(184, 202, 202, 0.055) 63% 64%, transparent 65%),
    repeating-linear-gradient(151deg, rgba(255, 255, 255, 0.014) 0 1px, transparent 1px 8px),
    linear-gradient(145deg, var(--hall-stone-dark), var(--hall-stone-dark-deep));
}

.square::before {
  border-color: rgba(218, 226, 219, 0.045);
  box-shadow:
    inset 1px 1px rgba(238, 239, 219, 0.09),
    inset -2px -2px rgba(0, 0, 0, 0.25);
}

/* Monumental statue palette: aged ivory versus blackened iron, not teal. */
.piece--white {
  color: #ded6c3;
}

.piece--black {
  color: #1b272d;
}

.piece--black .piece-cut {
  fill: #89979a;
}

.piece-token,
.promotion-piece {
  --readable-edge: #4c4539;
  --readable-highlight: #fffbee;
  --readable-mid: #d7cfba;
  --readable-deep: #756a56;
  --readable-accent-hi: #e7d7ae;
  --readable-accent: #8b744b;
  --readable-metal-hi: #f1dfb1;
  --readable-metal: #b59b68;
  --readable-metal-deep: #665235;
  --readable-gem-hi: #fff0bf;
  --readable-gem: #a98240;
  --readable-polish-edge: #fffdf4;
  --readable-polish: #f2e7ca;
}

.piece--black {
  --readable-edge: #617076;
  --readable-highlight: #68767a;
  --readable-mid: #263238;
  --readable-deep: #070d11;
  --readable-accent-hi: #879397;
  --readable-accent: #46545a;
  --readable-metal-hi: #aeb8b8;
  --readable-metal: #68767a;
  --readable-metal-deep: #27343a;
  --readable-gem-hi: #c5d0cf;
  --readable-gem: #718587;
  --readable-polish-edge: #bcc6c4;
  --readable-polish: #778487;
}

.piece-token {
  bottom: 2%;
  left: 4%;
  width: 92%;
  height: 116%;
}

/* Slight projection compensation keeps the distant army imposing at high tilt. */
.square:nth-child(-n + 16) .piece-token {
  bottom: 1%;
  left: 2%;
  width: 96%;
  height: 123%;
}

.piece--white .piece-icon {
  stroke: #695b40;
  filter:
    drop-shadow(0 1px 0 rgba(255, 252, 229, 0.92))
    drop-shadow(0 3px 0 rgba(135, 108, 60, 0.72))
    drop-shadow(0 7px 4px rgba(0, 0, 0, 0.58));
}

.piece--black .piece-icon {
  stroke: #728186;
  filter:
    drop-shadow(0 1px 0 rgba(158, 172, 174, 0.44))
    drop-shadow(0 3px 0 rgba(12, 19, 23, 0.92))
    drop-shadow(0 8px 4px rgba(0, 0, 0, 0.76));
}

.piece-token .soldier-icon[data-renderer="readable"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"] .readable-soldier {
  transform-origin: 50% 100%;
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="p"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="p"] .readable-soldier {
  transform: scale(0.79, 1.04);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="r"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="r"] .readable-soldier {
  transform: scale(0.88, 1.12);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="n"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="n"] .readable-soldier {
  transform: translateX(-1px) rotate(-1deg) scale(0.98, 1.17);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="b"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="b"] .readable-soldier {
  transform: scale(0.91, 1.26);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="q"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="q"] .readable-soldier {
  transform: translateY(1px) scale(0.98, 1.45);
}

.piece-token .soldier-icon[data-renderer="readable"][data-piece="k"] .readable-soldier,
.promotion-piece .soldier-icon[data-renderer="readable"][data-piece="k"] .readable-soldier {
  transform: translateY(1px) scale(1.04, 1.56);
}

.piece-token.piece-role--q > .piece-icon { width: 96%; }
.piece-token.piece-role--k > .piece-icon { width: 100%; }

.soldier-icon[data-renderer="readable"] .readable-soldier {
  filter:
    drop-shadow(0 1px 0 rgba(255, 247, 218, 0.22))
    drop-shadow(0 5px 3px rgba(0, 0, 0, 0.42));
}

.piece--black .soldier-icon[data-renderer="readable"] .readable-soldier {
  filter:
    drop-shadow(0 1px 0 rgba(171, 188, 190, 0.18))
    drop-shadow(0 6px 3px rgba(0, 0, 0, 0.64));
}

@media (max-width: 620px) {
  .world__image {
    background-position: 50% 47%;
  }

  .board-frame {
    padding: 2.15%;
  }

  .piece-token {
    left: 3%;
    width: 94%;
    height: 114%;
  }

  .square:nth-child(-n + 16) .piece-token {
    left: 1%;
    width: 98%;
    height: 120%;
  }
}

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

/* source: touch-targets.css */
/* A square is the interaction control; artwork and markers are presentation. */
.chessboard {
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

.square {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Upright pieces overhang their square; the original token keeps ownership of
   that visible silhouette instead of letting the tap fall through a rank. */
.chessboard > .square > .piece-token {
  pointer-events: auto;
}

.chessboard > .square > .piece-token * {
  pointer-events: none;
}

.square-hit-target {
  position: absolute;
  z-index: 12;
  inset: 0;
  display: block;
  background: transparent;
  cursor: inherit;
  pointer-events: auto;
  touch-action: manipulation;
}

/* Once a source is chosen, add visible forgiveness beyond the painted edge.
   The input resolver independently guarantees a 44px viewport-space target,
   including perspective-compressed ranks and nearest-center overlap handling. */
.square.is-legal {
  z-index: 5;
}

@media (pointer: coarse), (max-width: 620px) {
  .square.is-selected > .square-hit-target,
  .square.is-legal > .square-hit-target {
    inset: -10%;
  }
}

.square.is-pointer-pressed:not(.is-selected) {
  filter: brightness(1.18);
  box-shadow: inset 0 0 0 2px rgba(229, 210, 158, 0.42);
}

.square.is-legal.is-pointer-pressed {
  box-shadow:
    inset 0 0 0 2px rgba(178, 226, 213, 0.78),
    inset 0 0 24px rgba(77, 170, 151, 0.24);
}

.square.is-capture.is-pointer-pressed {
  box-shadow:
    inset 0 0 0 2px rgba(230, 166, 87, 0.84),
    inset 0 0 24px rgba(159, 76, 27, 0.28);
}

@media (prefers-reduced-motion: reduce) {
  .square.is-pointer-pressed {
    transition: none;
  }
}

/* source: flat-view-piece-fit.css */
/* Flat-board containment only. 3D view keeps the cinematic statue scale. */
.flat-view .piece-token {
  --flat-piece-fit: 0.94;
  scale: var(--flat-piece-fit);
  transform-origin: 50% 92%;
}

.flat-view .piece-token.piece-role--p { --flat-piece-fit: 0.90; }
.flat-view .piece-token.piece-role--r { --flat-piece-fit: 0.90; }
.flat-view .piece-token.piece-role--n { --flat-piece-fit: 0.88; }
.flat-view .piece-token.piece-role--b { --flat-piece-fit: 0.86; }
.flat-view .piece-token.piece-role--q { --flat-piece-fit: 0.84; }
.flat-view .piece-token.piece-role--k { --flat-piece-fit: 0.80; }

.flat-view .chessboard > .square:hover > .piece-token,
.flat-view .chessboard > .square.is-selected > .piece-token {
  transform: translateY(-7%) translateZ(11px);
}

@media (prefers-reduced-motion: no-preference) {
  .chessboard > .square > .piece-token {
    transition: transform 230ms var(--ease-out), filter 180ms ease, scale 300ms var(--ease-out);
  }
}

/* source: structural-pieces-live.css */
/* Production structural chess family: weathered carved ivory versus blackened iron. */
.piece-token,
.promotion-piece {
  --piece-highlight: #fff8e6;
  --piece-light: #d8cfba;
  --piece-mid: #a99c83;
  --piece-deep: #5f513e;
  --piece-shadow: #352d24;
  --piece-metal-highlight: #e2cd98;
  --piece-metal-mid: #a78652;
  --piece-metal-deep: #554029;
  --piece-cloth-light: #cfc4ad;
  --piece-cloth: #92836a;
  --piece-cloth-deep: #4d4133;
  --piece-orb-highlight: #fff5dc;
  --piece-orb: #b8aa8f;
  --piece-orb-deep: #544837;
  --piece-line: #4d4234;
  --piece-recess: #25231e;
  --piece-rust: #79513a;
  --piece-patina: #61766e;
  --rook-highlight: #fff9e9;
  --rook-light: #dcd3bd;
  --rook-mid: #b3a68d;
  --rook-deep: #665943;
  --rook-shadow: #40372c;
  --rook-plinth-deep: #514332;
  --rook-metal-highlight: #e1cc98;
  --rook-metal-mid: #a98854;
  --rook-metal-deep: #5b442c;
  --rook-rust: #775039;
  --rook-patina: #66766e;
  --rook-line: #534838;
  --rook-recess: #292722;
  --rook-recess-deep: #111311;
  --rook-tomb: #c3b69a;
  --rook-tomb-shadow: #574b3b;
}

.piece--black {
  --piece-highlight: #7b8688;
  --piece-light: #404c50;
  --piece-mid: #222e32;
  --piece-deep: #091013;
  --piece-shadow: #020507;
  --piece-metal-highlight: #a6b0b0;
  --piece-metal-mid: #58666a;
  --piece-metal-deep: #172126;
  --piece-cloth-light: #435055;
  --piece-cloth: #202b30;
  --piece-cloth-deep: #070c0f;
  --piece-orb-highlight: #9aa6a7;
  --piece-orb: #3b494e;
  --piece-orb-deep: #070d10;
  --piece-line: #7a8789;
  --piece-recess: #020507;
  --piece-rust: #704634;
  --piece-patina: #3f726c;
  --rook-highlight: #778184;
  --rook-light: #3d494d;
  --rook-mid: #222d31;
  --rook-deep: #080d10;
  --rook-shadow: #030608;
  --rook-plinth-deep: #090e11;
  --rook-metal-highlight: #b5bebe;
  --rook-metal-mid: #667477;
  --rook-metal-deep: #202a2e;
  --rook-rust: #704634;
  --rook-patina: #4f7b75;
  --rook-line: #7a888b;
  --rook-recess: #05080a;
  --rook-recess-deep: #010304;
  --rook-tomb: #313c40;
  --rook-tomb-shadow: #05090b;
}

/* Gameplay-distance Obsidian: retain blackened recesses while lifting the
   planes that describe each role. Fallen sculptures intentionally keep their
   separate material treatment in the casualty lane. */
.arena .piece-token.piece--black:not(.fallen-piece) {
  --piece-highlight: #b1c1c2;
  --piece-light: #5a6b70;
  --piece-mid: #33454a;
  --piece-deep: #101a1e;
  --piece-shadow: #04090c;
  --piece-metal-highlight: #c5d1cf;
  --piece-metal-mid: #74868a;
  --piece-metal-deep: #29383d;
  --piece-cloth-light: #637378;
  --piece-cloth: #334248;
  --piece-cloth-deep: #0b1418;
  --piece-orb-highlight: #d0d9d5;
  --piece-orb: #586a6e;
  --piece-orb-deep: #10181b;
  --piece-line: #9babad;
  --piece-recess: #04090c;
  --rook-highlight: #a9b9ba;
  --rook-light: #596a6e;
  --rook-mid: #34454a;
  --rook-deep: #10191d;
  --rook-shadow: #05090c;
  --rook-plinth-deep: #10191d;
  --rook-metal-highlight: #ccd6d3;
  --rook-metal-mid: #77898c;
  --rook-metal-deep: #2a393d;
  --rook-line: #9babad;
  --rook-recess: #081013;
  --rook-recess-deep: #020608;
  --rook-tomb: #526267;
  --rook-tomb-shadow: #0b1316;
}

.arena .piece-token.piece--black:not(.fallen-piece)
  .structural-piece :is(.piece-highlight, .rook-highlight) {
  fill: rgba(226, 193, 130, 0.2);
}

.soldier-icon[data-renderer="structural"] {
  overflow: visible;
  pointer-events: none;
  shape-rendering: geometricPrecision;
}

.soldier-icon[data-renderer="structural"] *,
.soldier-icon[data-renderer="structural"] *::before,
.soldier-icon[data-renderer="structural"] *::after {
  pointer-events: none;
}

.soldier-icon[data-renderer="structural"] :is(.piece-ground, .rook-ground) {
  fill: rgba(0, 0, 0, 0.62);
  filter: blur(2px);
}

.soldier-icon[data-renderer="structural"] .piece-main {
  fill: var(--piece-main);
  stroke: var(--piece-line);
  stroke-width: 2;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"] :is(.piece-side, .piece-shadow) {
  fill: var(--piece-side);
  stroke: var(--piece-line);
  stroke-width: 1.8;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"] .piece-metal {
  fill: var(--piece-metal);
  stroke: var(--piece-metal-deep);
  stroke-width: 1.8;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"] .piece-cloth {
  fill: var(--piece-cloth);
  stroke: var(--piece-line);
  stroke-width: 1.9;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"] .piece-orb {
  fill: var(--piece-orb);
  stroke: var(--piece-line);
  stroke-width: 1.7;
}

.soldier-icon[data-renderer="structural"] .piece-recess {
  fill: var(--piece-recess);
  stroke: var(--piece-line);
  stroke-width: 1.7;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"] .piece-highlight {
  fill: rgba(255, 255, 255, 0.2);
  stroke: none;
}

.soldier-icon[data-renderer="structural"] .piece-line {
  fill: none;
  stroke: var(--piece-line);
  stroke-width: 1.8;
  stroke-linecap: round;
}

.soldier-icon[data-renderer="structural"] .piece-line.visor { stroke-width: 3; }

.soldier-icon[data-renderer="structural"] .piece-rivet {
  fill: var(--piece-metal-highlight);
  stroke: var(--piece-metal-deep);
  stroke-width: 1;
}

.soldier-icon[data-renderer="structural"] .piece-rust {
  fill: var(--piece-rust);
  opacity: 0.68;
  mix-blend-mode: multiply;
}

.soldier-icon[data-renderer="structural"] .piece-patina {
  fill: var(--piece-patina);
  opacity: 0.52;
  mix-blend-mode: multiply;
}

/* Architectural rook planes and open funerary chamber. */
.soldier-icon[data-renderer="structural"].architectural-rook .rook-main {
  fill: var(--rook-armor);
  stroke: var(--rook-line);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook :is(.rook-side, .rook-shadow) {
  fill: var(--rook-side);
  stroke: var(--rook-line);
  stroke-width: 1.35;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-metal {
  fill: var(--rook-metal);
  stroke: var(--rook-metal-deep);
  stroke-width: 1.35;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-highlight {
  fill: rgba(255, 255, 255, 0.18);
  stroke: none;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-line {
  fill: none;
  stroke: var(--rook-line);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-rivet {
  fill: var(--rook-metal-highlight);
  stroke: var(--rook-metal-deep);
  stroke-width: 0.8;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-rust {
  fill: var(--rook-rust);
  opacity: 0.68;
  mix-blend-mode: multiply;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-patina {
  fill: var(--rook-patina);
  opacity: 0.45;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-recess {
  fill: var(--rook-recess);
  stroke: var(--rook-line);
  stroke-width: 1.25;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-recess-arch {
  fill: var(--rook-recess-deep);
  stroke: var(--rook-line);
  stroke-width: 1.2;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb-shadow {
  fill: var(--rook-tomb-shadow);
  stroke: var(--rook-line);
  stroke-width: 1.2;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb {
  fill: var(--rook-tomb);
  stroke: var(--rook-line);
  stroke-width: 1.4;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb-lid {
  fill: var(--rook-armor);
  stroke: var(--rook-line);
  stroke-width: 1.35;
  stroke-linejoin: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb-line {
  fill: none;
  stroke: var(--rook-line);
  stroke-width: 1.2;
  stroke-linecap: round;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb-effigy {
  fill: var(--rook-metal);
  stroke: var(--rook-metal-deep);
  stroke-width: 1.1;
}

.soldier-icon[data-renderer="structural"].architectural-rook .rook-tomb-gem {
  fill: var(--rook-metal-highlight);
  stroke: var(--rook-metal-deep);
  stroke-width: 0.7;
}

/* The scale belongs to the role, not to a generic vertical stretch. */
.piece-token.piece-role--p > .structural-piece,
.promotion-piece.piece-role--p > .structural-piece { width: 78%; height: 60%; }

.piece-token.piece-role--r > .structural-piece,
.promotion-piece.piece-role--r > .structural-piece { width: 66%; height: 74%; }

.piece-token.piece-role--n > .structural-piece,
.promotion-piece.piece-role--n > .structural-piece { width: 92%; height: 88%; }

.piece-token.piece-role--b > .structural-piece,
.promotion-piece.piece-role--b > .structural-piece { width: 78%; height: 84%; }

.piece-token.piece-role--q > .structural-piece,
.promotion-piece.piece-role--q > .structural-piece { width: 86%; height: 92%; }

.piece-token.piece-role--k > .structural-piece,
.promotion-piece.piece-role--k > .structural-piece { width: 92%; height: 98%; }

.piece--white > .structural-piece {
  filter:
    drop-shadow(0 1px 0 rgba(255, 252, 229, 0.9))
    drop-shadow(0 3px 0 rgba(117, 91, 51, 0.6))
    drop-shadow(0 7px 4px rgba(0, 0, 0, 0.56));
}

.piece--black > .structural-piece {
  filter:
    drop-shadow(0 1px 0 rgba(151, 169, 170, 0.38))
    drop-shadow(0 3px 0 rgba(7, 12, 15, 0.94))
    drop-shadow(0 8px 4px rgba(0, 0, 0, 0.76));
}

.square:hover .structural-piece .piece-orb,
.square.is-selected .structural-piece .piece-orb {
  filter: brightness(1.22) drop-shadow(0 0 3px rgba(241, 214, 147, 0.55));
}

/* The pavilion advances as a single heavy structure; its pillars never masquerade as legs. */
.is-natural-move-playing .move-role-r .architectural-rook .upper-shrine {
  animation-name: structural-rook-shrine-brace !important;
  animation-timing-function: linear;
  transform-box: fill-box;
  transform-origin: 50% 92%;
}

.is-natural-move-playing .move-role-r .architectural-rook .structural-stone-ram {
  animation: none;
}

@keyframes structural-rook-shrine-brace {
  0%, 9%, 100% { transform: translateY(0) rotate(0); }
  24% { transform: translateY(1px) rotate(-1deg); }
  42% { transform: translateY(-1px) rotate(1deg); }
  62% { transform: translateY(1px) rotate(0); }
  82% { transform: translateY(-1px) rotate(-1deg); }
}

@media (max-width: 620px) {
  .piece-token.piece-role--p > .structural-piece { width: 82%; }
  .piece-token.piece-role--r > .structural-piece { width: 70%; }
  .piece-token.piece-role--n > .structural-piece { width: 96%; }
  .piece-token.piece-role--b > .structural-piece { width: 82%; }
  .piece-token.piece-role--q > .structural-piece { width: 90%; }
  .piece-token.piece-role--k > .structural-piece { width: 96%; }
}

@media (prefers-reduced-motion: reduce) {
  .soldier-icon[data-renderer="structural"] * { animation: none !important; }
}

/* source: structural-motion-polish.css */
/* Board-scale compensation and planted locomotion for the structural family. */
.piece-token.piece-role--p > .structural-piece {
  width: 96%;
  height: 94%;
}

.square:nth-child(-n + 16) .piece-token.piece-role--p > .structural-piece {
  width: 98%;
  height: 98%;
}

.piece-token.piece-role--r > .structural-piece {
  width: 80%;
  height: 90%;
}

.piece-token.piece-role--n > .structural-piece {
  width: 100%;
  height: 100%;
}

.piece-token.piece-role--b > .structural-piece {
  width: 96%;
  height: 106%;
}

.piece-token.piece-role--q > .structural-piece {
  width: 100%;
  height: 110%;
}

.piece-token.piece-role--k > .structural-piece {
  width: 104%;
  height: 116%;
}

.piece--black {
  --piece-highlight: #899396;
  --piece-light: #4a575b;
  --piece-mid: #2b383c;
  --piece-line: #93a1a3;
  --piece-recess: #0a1013;
  --rook-highlight: #879194;
  --rook-light: #485458;
  --rook-mid: #2b363a;
  --rook-line: #919fa2;
  --rook-recess: #0c1215;
  --rook-tomb: #3b474b;
}

.soldier-icon[data-renderer="structural"] :is(.piece-rust, .rook-rust) {
  opacity: 0.82;
  filter: saturate(1.25) contrast(1.12);
}

.piece--black > .soldier-icon[data-renderer="structural"] :is(.piece-patina, .rook-patina) {
  opacity: 0.68;
  filter: saturate(1.2) brightness(1.16);
}

.is-natural-move-playing .move-role-p .natural-body-rig {
  animation-name: structural-pawn-body-cycle !important;
}

.is-natural-move-playing .move-role-p .structural-piece .soldier-leg--shield {
  animation-name: structural-pawn-leg-a-cycle !important;
  transform-box: fill-box;
  transform-origin: 56% 7%;
}

.is-natural-move-playing .move-role-p .structural-piece .soldier-leg--weapon {
  animation-name: structural-pawn-leg-b-cycle !important;
  transform-box: fill-box;
  transform-origin: 44% 7%;
}

.is-natural-move-playing .move-role-p .structural-piece .soldier-spear {
  transform-box: fill-box;
  transform-origin: 50% 88%;
  animation: structural-pawn-spear-cycle var(--gait-cycle-duration) linear
    calc(var(--move-delay, 0ms) + var(--gait-lead)) var(--gait-cycle-count) both !important;
}

.is-natural-move-playing .move-role-p .structural-piece .soldier-arm--shield {
  transform-box: fill-box;
  transform-origin: 62% 54%;
  animation: structural-pawn-shield-cycle var(--gait-cycle-duration) linear
    calc(var(--move-delay, 0ms) + var(--gait-lead)) var(--gait-cycle-count) both !important;
}

.is-natural-move-playing .move-role-p .structural-piece .soldier-base {
  transform-box: fill-box;
  transform-origin: 50% 94%;
  animation: structural-pawn-base-release var(--move-duration) ease-in-out
    var(--move-delay, 0ms) 1 both !important;
}

.is-natural-move-playing .move-role-p .natural-gait-contacts {
  bottom: 3%;
  width: 58%;
}

@keyframes structural-pawn-body-cycle {
  0%, 7%, 48%, 55%, 100% {
    transform: translate3d(0, 1.5px, 0) scaleX(1.025) scaleY(0.965);
  }
  18% {
    transform: translate3d(-2px, -2px, 0) rotate(-4deg) scaleY(1.015);
  }
  32% {
    transform: translate3d(3px, -4px, 0) rotate(4.5deg) scaleY(1.025);
  }
  68% {
    transform: translate3d(2px, -2px, 0) rotate(4deg) scaleY(1.015);
  }
  84% {
    transform: translate3d(-3px, -4px, 0) rotate(-4.5deg) scaleY(1.025);
  }
}

@keyframes structural-pawn-leg-a-cycle {
  0%, 7%, 48%, 55%, 100% { transform: rotate(-10deg) translate(-2px, 1px) scaleY(1.05); }
  18% { transform: rotate(28deg) translate(4px, -7px) scaleY(0.94); }
  32% { transform: rotate(12deg) translate(3px, 0) scaleY(1.04); }
  68% { transform: rotate(-34deg) translate(-5px, -6px) scaleY(0.92); }
  84% { transform: rotate(-18deg) translate(-3px, 0) scaleY(1.04); }
}

@keyframes structural-pawn-leg-b-cycle {
  0%, 7%, 48%, 55%, 100% { transform: rotate(10deg) translate(2px, 1px) scaleY(1.05); }
  18% { transform: rotate(-34deg) translate(-5px, -6px) scaleY(0.92); }
  32% { transform: rotate(-18deg) translate(-3px, 0) scaleY(1.04); }
  68% { transform: rotate(28deg) translate(4px, -7px) scaleY(0.94); }
  84% { transform: rotate(12deg) translate(3px, 0) scaleY(1.04); }
}

@keyframes structural-pawn-spear-cycle {
  0%, 50%, 100% { transform: rotate(-3deg) translateY(1px); }
  20% { transform: rotate(10deg) translate(3px, -5px); }
  35% { transform: rotate(4deg) translate(1px, -1px); }
  70% { transform: rotate(-11deg) translate(-3px, -5px); }
  85% { transform: rotate(-5deg) translate(-1px, -1px); }
}

@keyframes structural-pawn-shield-cycle {
  0%, 50%, 100% { transform: rotate(3deg) translateY(1px); }
  20% { transform: rotate(-9deg) translate(-3px, -3px); }
  35% { transform: rotate(-3deg) translate(-1px, 0); }
  70% { transform: rotate(10deg) translate(3px, -3px); }
  85% { transform: rotate(4deg) translate(1px, 0); }
}

@keyframes structural-pawn-base-release {
  0%, 6%, 94%, 100% { opacity: 1; transform: translateY(0) scale(1); }
  14%, 88% { opacity: 0; transform: translateY(28%) scale(0.45, 0.1); }
}

@media (max-width: 620px) {
  .piece-token.piece-role--p > .structural-piece {
    width: 96%;
    height: 94%;
  }

  .square:nth-child(-n + 16) .piece-token.piece-role--p > .structural-piece {
    width: 98%;
    height: 98%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .is-natural-move-playing .move-role-p :is(.natural-body-rig, .soldier-leg) {
    animation: none !important;
  }
}

/* source: depth-pass.css */
/*
 * Spatial depth pass.
 *
 * The chess engine remains a reliable DOM grid, while these presentation-only
 * faces, shadows, and light cues make the perspective view read as a physical
 * miniature set. Flat view deliberately bypasses the entire layer.
 */

:root {
  --board-slab-depth: clamp(18px, calc(var(--board-size) * 0.032), 27px);
  --board-side-depth: clamp(12px, calc(var(--board-size) * 0.022), 19px);
  --board-yaw: 0deg;
}

body:not(.flat-view) .board-stage {
  perspective: 920px;
  perspective-origin: 50% 22%;
}

body:not(.flat-view) .board-stage::before {
  transform: rotateX(var(--board-tilt)) rotateY(var(--board-yaw)) translateZ(-28px);
}

body:not(.flat-view) .board-frame {
  overflow: visible;
  transform: rotateX(var(--board-tilt)) rotateY(var(--board-yaw));
  transform-style: preserve-3d;
}

/* Real faces perpendicular to the board surface replace painted shadow lines. */
.board-depth {
  position: absolute;
  z-index: 1;
  display: none;
  pointer-events: none;
  transform-style: preserve-3d;
}

body:not(.flat-view) .board-depth {
  display: block;
}

.board-depth--front {
  top: 100%;
  left: -0.1%;
  width: 100.2%;
  height: var(--board-slab-depth);
  border: 1px solid rgba(118, 105, 78, 0.72);
  border-top-color: rgba(226, 198, 128, 0.58);
  clip-path: polygon(0 0, 100% 0, 97.4% 100%, 2.6% 100%);
  background:
    repeating-linear-gradient(90deg,
      transparent 0 12.2%,
      rgba(211, 180, 105, 0.12) 12.35% 12.55%,
      transparent 12.7% 25%),
    linear-gradient(90deg,
      rgba(205, 175, 105, 0.16),
      transparent 22% 72%,
      rgba(0, 0, 0, 0.24)),
    linear-gradient(180deg, #4c5655 0, #283235 24%, #10181c 72%, #070c0f 100%);
  box-shadow:
    inset 0 1px rgba(255, 232, 172, 0.22),
    inset 0 -4px 8px rgba(0, 0, 0, 0.54),
    0 12px 20px rgba(0, 0, 0, 0.46);
  transform: rotateX(-90deg);
  transform-origin: 50% 0;
}

.board-depth--left,
.board-depth--right {
  top: -0.1%;
  width: var(--board-side-depth);
  height: 100.2%;
  border: 1px solid rgba(102, 94, 73, 0.64);
  background:
    linear-gradient(180deg, rgba(207, 180, 112, 0.16), transparent 25%),
    linear-gradient(90deg, #353f40, #11191c 70%, #080d10);
  box-shadow: inset 0 0 9px rgba(0, 0, 0, 0.44);
}

.board-depth--left {
  right: 100%;
  transform: rotateY(-90deg);
  transform-origin: 100% 50%;
}

.board-depth--right {
  left: 100%;
  background:
    linear-gradient(180deg, rgba(171, 149, 96, 0.08), transparent 24%),
    linear-gradient(90deg, #252f31, #080e11 76%);
  transform: rotateY(90deg);
  transform-origin: 0 50%;
}

body:not(.flat-view) .chessboard {
  transform: translateZ(2px);
  box-shadow:
    0 0 0 1px rgba(196, 166, 98, 0.9),
    0 0 0 4px rgba(4, 9, 11, 0.78),
    0 5px 0 rgba(8, 13, 15, 0.92),
    inset 0 0 28px rgba(0, 0, 0, 0.76);
}


body:not(.flat-view) .square {
  isolation: auto;
}

/*
 * Upright SVGs have deliberately different plinth proportions. Anchor their
 * actual ground ellipses inside the projected tile instead of scaling the
 * silhouettes down. These offsets only affect the perspective view; the flat
 * board keeps its dedicated sizing and placement rules.
 */
body:not(.flat-view) .chessboard > .square > .piece-token:not(.fallen-piece) {
  bottom: 12%;
}

body:not(.flat-view) .chessboard > .square > .piece-token.piece-role--r:not(.fallen-piece) {
  bottom: 5%;
}

body:not(.flat-view) .chessboard > .square > .piece-token.piece-role--n:not(.fallen-piece) {
  bottom: 17%;
}

body:not(.flat-view) .chessboard > .square > .piece-token.piece-role--b:not(.fallen-piece) {
  bottom: 9%;
}

body:not(.flat-view) .chessboard > .square > .piece-token.piece-role--q:not(.fallen-piece) {
  bottom: 11%;
}

/*
 * With the shared 3D context, default hit layers also share the board stack.
 * Keep them below pieces while legal/selected square contexts remain above.
 */
body:not(.flat-view) .square-hit-target {
  z-index: 2;
}

/* Keep the sculpture's Z lift alive through the animated carrier wrappers. */
body:not(.flat-view) :is(
  .natural-move-layer,
  .natural-move-actor,
  .natural-body-rig
) {
  transform-style: preserve-3d;
}

body:not(.flat-view) .square::before {
  background:
    linear-gradient(125deg,
      rgba(255, 236, 190, 0.075),
      transparent 34% 66%,
      rgba(0, 5, 8, 0.14));
}

body:not(.flat-view) .square:nth-child(-n + 16)::before {
  background:
    linear-gradient(180deg, rgba(7, 17, 22, 0.12), transparent 58%),
    linear-gradient(125deg,
      rgba(208, 224, 211, 0.045),
      transparent 34% 66%,
      rgba(0, 4, 7, 0.17));
}

/*
 * Filters on a square flatten its 3D descendants. Draw interaction feedback on
 * the square surface instead, so hover and press never discard piece Z-depth.
 */
body:not(.flat-view) .square:hover,
body:not(.flat-view) .square.is-pointer-pressed:not(.is-selected) {
  filter: none;
}

/* Never animate a filter on a preserve-3d ancestor. The legacy check pulse
   flattened the checked king because CSS filters create a grouped plane. */
body:not(.flat-view) .square.is-check {
  filter: none;
  transform-style: preserve-3d;
  animation-name: check-warning-depth;
}

body:not(.flat-view) .square.is-check::before {
  background-color: rgba(151, 28, 24, 0.16);
  animation: check-warning-floor 1.1s ease-in-out infinite;
}

body:not(.flat-view) .square:hover::before {
  background-color: rgba(239, 216, 157, 0.075);
  box-shadow:
    inset 0 0 0 2px rgba(231, 203, 132, 0.28),
    inset 0 0 22px rgba(221, 185, 105, 0.14),
    inset 1px 1px rgba(246, 236, 202, 0.1),
    inset -2px -2px rgba(0, 0, 0, 0.22);
}

body:not(.flat-view) .square.is-pointer-pressed:not(.is-selected)::before {
  background-color: rgba(144, 206, 192, 0.09);
  box-shadow:
    inset 0 0 0 2px rgba(190, 228, 217, 0.46),
    inset 0 0 24px rgba(75, 176, 157, 0.17);
}

/* Keep the sculpture internal depth layers intact while retaining its lift. */
body:not(.flat-view) .square:hover > .piece-token,
body:not(.flat-view) .square.is-selected > .piece-token {
  filter: none;
}

/* Fallback movement and legacy battle modes must not flatten occupied squares. */
body:not(.flat-view) .is-piece-moving
  .square:not(.is-move-source):not(.is-move-target),
body:not(.flat-view) .is-board-battling
  .square:not(.is-battle-source):not(.is-battle-target) {
  filter: none;
}

body:not(.flat-view) .is-board-battling
  .square:not(.is-battle-source):not(.is-battle-target)::before {
  background-color: rgba(1, 6, 9, 0.28);
}

/* A locked board should not make a stationary piece jump under the pointer. */
body:not(.flat-view) .board-stage.is-locked
  .square:hover:not(.is-selected) > .piece-token {
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px);
}

/* Battle dimming belongs to the floor plane, not to piece-bearing ancestors. */
body:not(.flat-view) .is-polished-battling
  .square:not(.is-polished-battle-source):not(.is-polished-battle-target):not(.is-polished-battle-destination) {
  filter: none;
}

body:not(.flat-view) .is-polished-battling
  .square:not(.is-polished-battle-source):not(.is-polished-battle-target):not(.is-polished-battle-destination)::before {
  background-color: rgba(1, 6, 9, 0.28);
}

/* A directional shadow plus a tight contact pool plants each upright sculpture. */
body:not(.flat-view) .piece-token {
  --piece-depth-rim: rgba(227, 203, 145, 0.16);
}

body:not(.flat-view) .piece-token.piece--black {
  --piece-depth-rim: rgba(135, 184, 180, 0.15);
}

.structural-extrusion {
  display: none;
  pointer-events: none;
}

body:not(.flat-view) .piece-token .structural-extrusion {
  display: inline;
}

body:not(.flat-view) .piece-token .structural-extrusion--deep {
  opacity: 0.86;
  filter: brightness(0.2) saturate(0.58);
}

body:not(.flat-view) .piece-token .structural-extrusion--mid {
  opacity: 0.8;
  filter: brightness(0.46) saturate(0.72);
}

body:not(.flat-view) .piece-token.piece--black .structural-extrusion--deep {
  filter: brightness(0.3) saturate(0.7);
}

body:not(.flat-view) .piece-token.piece--black .structural-extrusion--mid {
  filter: brightness(0.62) saturate(0.78);
}

body:not(.flat-view) .arena .piece-token.piece--black:not(.fallen-piece) .structural-extrusion--deep {
  filter: brightness(0.38) saturate(0.78);
}

body:not(.flat-view) .arena .piece-token.piece--black:not(.fallen-piece) .structural-extrusion--mid {
  filter: brightness(0.74) saturate(0.86);
}

body:not(.flat-view) .piece-token::before {
  right: auto;
  bottom: -1%;
  left: 50%;
  width: 78%;
  height: 22%;
  border-radius: 50%;
  opacity: 0.92;
  background: radial-gradient(ellipse at 34% 52%,
    rgba(0, 0, 0, 0.76) 0 17%,
    rgba(0, 0, 0, 0.48) 35%,
    rgba(0, 0, 0, 0.16) 58%,
    transparent 76%);
  filter: blur(3px);
  transform:
    translateX(-50%)
    rotateX(var(--board-tilt))
    rotateZ(-12deg)
    skewX(-18deg)
    scale(1.18, 0.72)
    translate(11%, 12%)
    translateZ(-4px);
  transform-origin: 50% 100%;
}

body:not(.flat-view) .piece-token::after {
  z-index: -1;
  bottom: 1%;
  left: 50%;
  width: 64%;
  height: 14%;
  border-radius: 50%;
  opacity: 0.52;
  background: radial-gradient(ellipse,
    var(--piece-depth-rim) 0 16%,
    rgba(0, 0, 0, 0.5) 34%,
    rgba(0, 0, 0, 0.12) 58%,
    transparent 74%);
  filter: blur(2px);
  transform: translateX(-50%) rotateX(var(--board-tilt)) translateZ(-2px);
}

/* Hard one-pixel steps imply a carved edge; the final soft shadow belongs to the room. */
body:not(.flat-view) .piece--white > .structural-piece {
  filter:
    drop-shadow(-1px -1px 0 rgba(255, 250, 226, 0.54))
    drop-shadow(1px 1px 0 rgba(112, 91, 58, 0.74))
    drop-shadow(2px 3px 0 rgba(53, 43, 30, 0.54))
    drop-shadow(7px 10px 5px rgba(0, 0, 0, 0.58));
}

body:not(.flat-view) .piece--black > .structural-piece {
  filter:
    drop-shadow(-1px -1px 0 rgba(151, 170, 171, 0.38))
    drop-shadow(1px 1px 0 rgba(5, 10, 13, 0.94))
    drop-shadow(2px 3px 0 rgba(0, 3, 5, 0.88))
    drop-shadow(8px 11px 5px rgba(0, 0, 0, 0.72));
}

body:not(.flat-view) .arena .piece-token.piece--black:not(.fallen-piece) > .structural-piece {
  filter:
    drop-shadow(-1px -1px 0 rgba(184, 207, 207, 0.58))
    drop-shadow(1px 0 0 rgba(224, 169, 83, 0.2))
    drop-shadow(1px 2px 0 rgba(7, 13, 16, 0.9))
    drop-shadow(7px 10px 5px rgba(0, 0, 0, 0.68));
}

body:not(.flat-view) .board-shadow {
  right: -4%;
  bottom: -2.8%;
  left: 1%;
  height: 13%;
  opacity: 0.86;
  background: radial-gradient(ellipse at 43% 45%, rgba(0, 0, 0, 0.82), transparent 70%);
  filter: blur(14px);
  transform: rotate(-1.5deg) translateZ(-80px);
}

@media (min-width: 1101px) and (min-height: 741px) {
  body:not(.flat-view) .board-frame {
    top: -44px;
  }
}

@media (max-width: 1100px) {
  :root {
    --board-slab-depth: clamp(13px, calc(var(--board-size) * 0.028), 20px);
    --board-side-depth: clamp(9px, calc(var(--board-size) * 0.02), 14px);
  }

  body:not(.flat-view) .board-stage {
    perspective: 820px;
  }
}

@media (max-width: 620px) {
  :root {
    --board-yaw: 0deg;
  }

  body:not(.flat-view) .board-stage {
    perspective: 760px;
    perspective-origin: 50% 25%;
  }

  body:not(.flat-view) .piece-token::before {
    opacity: 0.72;
    filter: blur(2px);
  }

  .board-depth--left,
  .board-depth--right {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  body:not(.flat-view) .board-stage {
    perspective: 960px;
  }
}

@keyframes check-warning-depth {
  50% {
    box-shadow:
      inset 0 0 0 3px #eb8d6c,
      inset 0 0 38px rgba(200, 52, 38, 0.9);
  }
}

@keyframes check-warning-floor {
  50% {
    background-color: rgba(195, 48, 37, 0.3);
    box-shadow:
      inset 0 0 0 3px rgba(255, 171, 129, 0.82),
      inset 0 0 34px rgba(204, 48, 35, 0.68),
      0 0 13px rgba(196, 48, 33, 0.34);
  }
}

/* source: castle-floor-scene.css */
/*
 * Great Hall floor pass.
 *
 * This final presentation layer turns the playable grid into a weathered floor
 * inlay, adds warm practical light around it, and keeps captured structural
 * sculptures on the same physical plane as the board.
 */

:root {
  --floor-ash-light: #76786f;
  --floor-ash-mid: #555d5b;
  --floor-ash-deep: #394344;
  --floor-slate-light: #293c42;
  --floor-slate-mid: #192b32;
  --floor-slate-deep: #0c171d;
  --floor-seam: #483f32;
  --floor-seam-lit: #b19760;
  --floor-brass: #8f6c36;
  --floor-brass-lit: #d0ad62;
  --candle-wax: #d9cba7;
  --candle-wax-deep: #8d7851;
}

.arena,
.board-stage,
.board-frame {
  overflow: visible;
}

body:not(.flat-view) .board-stage {
  perspective-origin: 50% 20%;
}

body:not(.flat-view) .board-stage::before {
  inset: -26% -36% -30%;
  border: 0;
  clip-path: none;
  -webkit-mask-image: radial-gradient(ellipse at 50% 55%, #000 0 57%, rgba(0, 0, 0, 0.86) 74%, transparent 100%);
  mask-image: radial-gradient(ellipse at 50% 55%, #000 0 57%, rgba(0, 0, 0, 0.86) 74%, transparent 100%);
  background:
    radial-gradient(ellipse at 18% 63%, rgba(116, 72, 38, 0.16), transparent 24%),
    radial-gradient(ellipse at 82% 41%, rgba(17, 39, 42, 0.32), transparent 27%),
    linear-gradient(31deg,
      transparent 0 57.1%,
      rgba(11, 17, 17, 0.25) 57.35% 57.55%,
      rgba(200, 177, 121, 0.045) 57.7%,
      transparent 57.9%),
    radial-gradient(circle at 50% 97%,
      transparent 0 7.4%,
      rgba(187, 153, 82, 0.34) 7.6% 8%,
      transparent 8.2% 11.2%,
      rgba(114, 102, 75, 0.48) 11.4% 11.8%,
      transparent 12% 16.2%,
      rgba(171, 138, 72, 0.19) 16.4% 16.8%,
      transparent 17%),
    linear-gradient(90deg,
      transparent 49.72%,
      rgba(181, 148, 76, 0.2) 49.82% 50.18%,
      transparent 50.28%),
    linear-gradient(90deg, rgba(207, 199, 165, 0.09) 0 1px, transparent 1px) 0 0 / 12.5% 100%,
    linear-gradient(0deg, rgba(5, 11, 14, 0.62) 0 1px, transparent 1px) 0 0 / 100% 12.5%,
    linear-gradient(127deg,
      transparent 0 20%,
      rgba(222, 213, 179, 0.05) 20.2% 20.5%,
      transparent 20.8% 68%,
      rgba(1, 6, 9, 0.3) 68.3%),
    radial-gradient(ellipse at 50% 18%, rgba(124, 155, 159, 0.13), transparent 48%),
    linear-gradient(148deg, #3c4748 0, #252f32 43%, #121d22 72%, #30393a 100%);
  box-shadow:
    inset 0 0 0 2px rgba(5, 10, 12, 0.68),
    inset 0 0 62px rgba(0, 0, 0, 0.52),
    inset 0 1px rgba(216, 208, 176, 0.14);
  transform: rotateX(var(--board-tilt)) rotateY(var(--board-yaw)) translateZ(-3px);
}

body:not(.flat-view) .board-stage::after {
  display: none;
}

.flat-view .board-stage::before {
  inset: -3.5%;
  border: 1px solid rgba(157, 144, 108, 0.25);
  clip-path: none;
  background:
    radial-gradient(circle at 50% 100%, transparent 0 11%, rgba(173, 141, 73, 0.24) 11.3% 11.8%, transparent 12.1%),
    linear-gradient(90deg, rgba(192, 184, 151, 0.07) 0 1px, transparent 1px) 0 0 / 12.5% 100%,
    linear-gradient(0deg, rgba(5, 10, 13, 0.56) 0 1px, transparent 1px) 0 0 / 100% 12.5%,
    linear-gradient(145deg, #384344, #182329 72%, #293234);
  box-shadow: inset 0 0 42px rgba(0, 0, 0, 0.55), 0 18px 34px rgba(0, 0, 0, 0.42);
}

.flat-view .board-stage::after {
  display: none;
}

.arena::after {
  opacity: 0.34;
}

body:not(.flat-view) .board-shadow {
  right: -11%;
  bottom: -5%;
  left: -8%;
  height: 18%;
  opacity: 0.72;
  background: radial-gradient(ellipse at 48% 38%, rgba(0, 0, 0, 0.7), transparent 70%);
  filter: blur(17px);
}

.board-frame {
  padding: 1.45%;
  border: 0;
  border-radius: 0;
  background:
    linear-gradient(90deg, transparent 0 1%, rgba(216, 180, 98, 0.24) 1.2% 1.45%, transparent 1.7% 98.3%, rgba(216, 180, 98, 0.2) 98.55% 98.8%, transparent 99%),
    linear-gradient(0deg, transparent 0 1%, rgba(216, 180, 98, 0.18) 1.2% 1.45%, transparent 1.7% 98.3%, rgba(216, 180, 98, 0.2) 98.55% 98.8%, transparent 99%),
    linear-gradient(145deg, #4a4d47, #222a2c 48%, #111a1e 72%, #3b3e38);
  box-shadow:
    0 0 0 1px rgba(188, 151, 76, 0.72),
    inset 0 0 0 2px rgba(8, 13, 15, 0.94),
    inset 0 0 0 4px rgba(139, 112, 58, 0.34),
    inset 0 0 25px rgba(0, 0, 0, 0.68),
    0 7px 15px rgba(0, 0, 0, 0.3);
}

.board-frame::before {
  inset: 0.42%;
  border-color: rgba(210, 177, 102, 0.48);
  box-shadow: 0 0 6px rgba(220, 184, 96, 0.09);
}

.board-frame::after {
  display: none;
}

body:not(.flat-view) .board-depth {
  display: none !important;
}

.board-corner {
  width: 16px;
  height: 16px;
  opacity: 0.68;
}

.board-corner::before {
  left: 8px;
  height: 16px;
}

.board-corner::after {
  top: 8px;
  width: 16px;
}

.chessboard {
  gap: clamp(1px, calc(var(--board-size) * 0.0018), 2px);
  border: 1px solid #080d0f;
  background:
    linear-gradient(145deg, rgba(191, 155, 83, 0.72), rgba(46, 44, 37, 0.95)),
    var(--floor-seam);
  box-shadow:
    0 0 0 1px rgba(178, 145, 76, 0.78),
    0 0 0 3px rgba(5, 10, 12, 0.94),
    inset 0 0 24px rgba(0, 0, 0, 0.62);
}

body:not(.flat-view) .chessboard {
  transform: translateZ(1px);
  box-shadow:
    0 0 0 1px rgba(189, 153, 79, 0.82),
    0 0 0 3px rgba(4, 9, 11, 0.9),
    inset 0 0 26px rgba(0, 0, 0, 0.67);
}

.square--light {
  background:
    radial-gradient(circle at 18% 19%, rgba(241, 232, 199, 0.15), transparent 19%),
    radial-gradient(ellipse at 79% 83%, rgba(5, 11, 13, 0.18), transparent 31%),
    linear-gradient(24deg, transparent 0 46%, rgba(37, 42, 41, 0.12) 46.4% 46.9%, transparent 47.3%),
    repeating-linear-gradient(159deg, rgba(255, 255, 239, 0.022) 0 1px, transparent 1px 8px),
    linear-gradient(145deg, var(--floor-ash-light), var(--floor-ash-mid) 54%, var(--floor-ash-deep));
}

.square--dark {
  background:
    radial-gradient(circle at 72% 22%, rgba(132, 174, 181, 0.12), transparent 25%),
    radial-gradient(ellipse at 16% 88%, rgba(0, 0, 0, 0.28), transparent 34%),
    linear-gradient(36deg, transparent 0 61%, rgba(159, 187, 188, 0.065) 61.4% 61.9%, transparent 62.3%),
    repeating-linear-gradient(153deg, rgba(236, 246, 239, 0.015) 0 1px, transparent 1px 9px),
    linear-gradient(145deg, var(--floor-slate-light), var(--floor-slate-mid) 58%, var(--floor-slate-deep));
}

.square:nth-child(4n + 1) {
  background-position: 17% 20%, 72% 78%, 2px -1px, 4px 1px, 0 0;
}

.square:nth-child(5n + 2) {
  box-shadow:
    inset 2px 1px rgba(231, 222, 188, 0.08),
    inset -3px -2px rgba(1, 5, 7, 0.3);
}

/* A board-wide patina map is sampled by each square. Its stains and hairline
   fractures continue across grout lines, avoiding 64 repeated tile textures. */
.square {
  --floor-patina-x: 0%;
  --floor-patina-y: 0%;
}

.square:nth-child(8n + 1) { --floor-patina-x: 0%; }
.square:nth-child(8n + 2) { --floor-patina-x: 14.285%; }
.square:nth-child(8n + 3) { --floor-patina-x: 28.57%; }
.square:nth-child(8n + 4) { --floor-patina-x: 42.855%; }
.square:nth-child(8n + 5) { --floor-patina-x: 57.145%; }
.square:nth-child(8n + 6) { --floor-patina-x: 71.43%; }
.square:nth-child(8n + 7) { --floor-patina-x: 85.715%; }
.square:nth-child(8n) { --floor-patina-x: 100%; }

.square:nth-child(-n + 8) { --floor-patina-y: 0%; }
.square:nth-child(n + 9):nth-child(-n + 16) { --floor-patina-y: 14.285%; }
.square:nth-child(n + 17):nth-child(-n + 24) { --floor-patina-y: 28.57%; }
.square:nth-child(n + 25):nth-child(-n + 32) { --floor-patina-y: 42.855%; }
.square:nth-child(n + 33):nth-child(-n + 40) { --floor-patina-y: 57.145%; }
.square:nth-child(n + 41):nth-child(-n + 48) { --floor-patina-y: 71.43%; }
.square:nth-child(n + 49):nth-child(-n + 56) { --floor-patina-y: 85.715%; }
.square:nth-child(n + 57) { --floor-patina-y: 100%; }

body:not(.flat-view) .square::before,
.flat-view .square::before {
  border: 1px solid rgba(228, 220, 186, 0.045);
  background:
    radial-gradient(ellipse at 18% 36%, rgba(121, 72, 35, 0.2), transparent 19%)
      var(--floor-patina-x) var(--floor-patina-y) / 800% 800% no-repeat,
    radial-gradient(ellipse at 78% 69%, rgba(4, 13, 16, 0.32), transparent 24%)
      var(--floor-patina-x) var(--floor-patina-y) / 800% 800% no-repeat,
    linear-gradient(128deg,
      transparent 0 44.55%,
      rgba(18, 18, 14, 0.24) 44.72% 44.92%,
      rgba(210, 189, 137, 0.05) 45.02%,
      transparent 45.2%)
      var(--floor-patina-x) var(--floor-patina-y) / 800% 800% no-repeat,
    radial-gradient(circle at 84% 13%, rgba(105, 66, 34, 0.22) 0 2%, transparent 8%),
    radial-gradient(circle at 20% 76%, rgba(4, 10, 12, 0.2) 0 3%, transparent 12%),
    linear-gradient(118deg,
      transparent 0 22%,
      rgba(240, 225, 178, 0.035) 22.3% 22.7%,
      transparent 23.1% 72%,
      rgba(2, 7, 9, 0.14) 72.4%),
    radial-gradient(circle at 9% 90%, rgba(8, 14, 15, 0.2), transparent 18%);
  box-shadow:
    inset 1px 1px rgba(240, 231, 198, 0.085),
    inset -2px -2px rgba(0, 0, 0, 0.28);
}

.castle-floor-dressing {
  position: absolute;
  z-index: 18;
  inset: -13% -16% -17%;
  overflow: visible;
  pointer-events: none;
  transform-style: preserve-3d;
}

/* The practical lights now illuminate the same plane as the board and pieces.
   Kept subtle so move markers and role silhouettes retain functional contrast. */
.castle-floor-dressing::before {
  position: absolute;
  z-index: -1;
  inset: -4%;
  background:
    radial-gradient(ellipse 23% 31% at 8% 27%, rgba(255, 190, 85, 0.14), transparent 72%),
    radial-gradient(ellipse 22% 30% at 92% 24%, rgba(255, 183, 73, 0.13), transparent 72%),
    radial-gradient(ellipse 27% 25% at 3% 83%, rgba(255, 143, 43, 0.18), transparent 74%),
    radial-gradient(ellipse 27% 25% at 97% 83%, rgba(255, 143, 43, 0.18), transparent 74%);
  content: "";
  filter: blur(6px);
  mix-blend-mode: screen;
  opacity: 0.68;
  animation: hall-spill-breathe 3.8s ease-in-out infinite alternate;
  pointer-events: none;
}

.candle-cluster {
  position: absolute;
  display: flex;
  width: 54px;
  height: 47px;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  isolation: isolate;
  filter: drop-shadow(0 8px 7px rgba(0, 0, 0, 0.72));
  transform-origin: 50% 100%;
}

.candle-cluster--left {
  top: 23%;
  left: 7%;
  transform: scale(0.84);
}

.candle-cluster--right {
  top: 20%;
  right: 8.5%;
  transform: scale(0.7);
}

.candle-cluster::before {
  position: absolute;
  z-index: -1;
  right: 4px;
  bottom: -4px;
  left: 4px;
  height: 8px;
  border: 1px solid rgba(203, 166, 89, 0.38);
  border-radius: 50%;
  background: linear-gradient(180deg, #b18b49, #4c351e 62%, #160f0b);
  box-shadow: inset 0 1px rgba(255, 220, 143, 0.32);
  content: "";
}

.candle-cluster::after {
  position: absolute;
  z-index: -2;
  top: auto;
  bottom: -14px;
  left: 50%;
  width: 122px;
  height: 34px;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255, 179, 72, 0.25), rgba(224, 104, 27, 0.075) 42%, transparent 72%);
  content: "";
  transform: translateX(-50%);
}

.floor-candle {
  position: relative;
  display: block;
  width: 8px;
  height: 27px;
  border: 1px solid rgba(78, 58, 34, 0.7);
  border-radius: 3px 3px 1px 1px;
  background:
    linear-gradient(90deg, var(--candle-wax-deep), #efe1b8 34%, #c8b889 68%, #75613e);
  box-shadow:
    inset 1px 0 rgba(255, 245, 205, 0.44),
    0 0 7px rgba(255, 174, 66, 0.15);
}

.floor-candle:nth-child(2) {
  height: 38px;
}

.floor-candle:nth-child(3) {
  height: 22px;
}

.floor-candle::before {
  position: absolute;
  top: -13px;
  left: 50%;
  width: 8px;
  height: 13px;
  border-radius: 58% 42% 62% 38%;
  background:
    radial-gradient(circle at 50% 72%, #fffbd6 0 14%, #ffca62 24%, #e86d22 58%, transparent 64%);
  filter: drop-shadow(0 0 5px rgba(255, 162, 50, 0.88));
  content: "";
  transform: translateX(-50%) rotate(2deg);
  transform-origin: 50% 100%;
  animation: candle-flutter 1.7s ease-in-out infinite alternate;
}

.floor-candle:nth-child(2)::before {
  animation-delay: -0.8s;
}

.floor-candle:nth-child(3)::before {
  animation-delay: -1.25s;
}

.floor-candle::after {
  position: absolute;
  top: -3px;
  left: 50%;
  width: 2px;
  height: 5px;
  border-radius: 2px;
  background: #27160d;
  content: "";
  transform: translateX(-50%);
}

.floor-brazier {
  position: absolute;
  bottom: 15%;
  width: 62px;
  height: 54px;
  filter: drop-shadow(0 12px 10px rgba(0, 0, 0, 0.76));
  transform-origin: 50% 100%;
}

.floor-brazier--left {
  left: 0;
}

.floor-brazier--right {
  right: 0;
  transform: scaleX(-1);
}

.floor-brazier::before {
  position: absolute;
  right: 5px;
  bottom: 3px;
  left: 5px;
  height: 24px;
  border: 1px solid rgba(221, 182, 96, 0.48);
  clip-path: polygon(2% 0, 98% 0, 82% 68%, 61% 81%, 58% 100%, 42% 100%, 39% 81%, 18% 68%);
  background:
    linear-gradient(180deg, #e0b766 0 9%, #8b5d2e 17% 52%, #3b2113 76%, #0c0806);
  box-shadow: inset 0 2px rgba(255, 220, 139, 0.3);
  content: "";
}

.floor-brazier::after {
  position: absolute;
  z-index: -1;
  top: -28px;
  left: 50%;
  width: 126px;
  height: 100px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 164, 49, 0.24), rgba(214, 80, 18, 0.08) 40%, transparent 69%);
  content: "";
  transform: translateX(-50%);
}

.floor-brazier i {
  position: absolute;
  bottom: 22px;
  left: 50%;
  width: 16px;
  height: 30px;
  border-radius: 55% 45% 62% 38%;
  background: radial-gradient(ellipse at 50% 72%, #fff8b4 0 12%, #ffb331 32%, #d84a18 66%, transparent 70%);
  filter: drop-shadow(0 0 9px rgba(255, 133, 27, 0.75));
  transform: translateX(-50%);
  transform-origin: 50% 100%;
  animation: brazier-fire 1.45s ease-in-out infinite alternate;
}

.floor-brazier i:nth-child(2) {
  bottom: 20px;
  margin-left: -10px;
  transform: translateX(-50%) rotate(-13deg) scale(0.72);
  animation-delay: -0.65s;
}

.floor-brazier i:nth-child(3) {
  bottom: 20px;
  margin-left: 11px;
  transform: translateX(-50%) rotate(14deg) scale(0.78);
  animation-delay: -1.05s;
}

.fallen-court {
  position: absolute;
  z-index: 26;
  top: 15%;
  bottom: 8%;
  display: grid;
  width: 16%;
  box-sizing: border-box;
  grid-template-columns: repeat(2, clamp(34px, calc(var(--board-size) * 0.055), 44px));
  grid-auto-flow: row;
  justify-content: center;
  grid-auto-rows: clamp(44px, calc(var(--board-size) * 0.065), 56px);
  align-content: end;
  align-items: center;
  justify-items: center;
  padding: 4px 2px;
  pointer-events: none;
  transform-style: preserve-3d;
  user-select: none;
}

.fallen-court:empty {
  display: none;
}

.fallen-court--ivory {
  left: calc(-20% + 2px);
  --fallen-angle: 87deg;
}

.fallen-court--obsidian {
  right: -20%;
  --fallen-angle: -88deg;
}

body:not(.flat-view) .fallen-court .fallen-piece.piece-token,
body.flat-view .fallen-court .fallen-piece.piece-token {
  --fallen-turn: 0deg;
  --fallen-shift: 0px;
  position: relative;
  inset: auto;
  display: grid;
  width: clamp(44px, calc(var(--board-size) * 0.072), 58px);
  height: clamp(44px, calc(var(--board-size) * 0.072), 58px);
  margin: 0;
  place-items: center;
  --fallen-filter: saturate(0.58) brightness(0.84);
  opacity: 0.88;
  filter: var(--fallen-filter);
  pointer-events: none;
  transform:
    translate3d(var(--fallen-shift), 0, 5px)
    rotateZ(calc(var(--fallen-angle) + var(--fallen-turn)))
    scale(0.9);
  transform-origin: 50% 55%;
  transform-style: preserve-3d;
  transition: none;
}

.fallen-court .fallen-piece.piece--black {
  --fallen-filter: saturate(0.72) brightness(1.18) drop-shadow(0 1px 0 rgba(166, 187, 184, 0.28));
  opacity: 0.92;
}

.fallen-court .fallen-piece + .fallen-piece {
  margin: 0;
}

.fallen-court .fallen-piece:nth-child(2n) {
  --fallen-turn: 5deg;
  --fallen-shift: 5px;
}

.fallen-court .fallen-piece:nth-child(3n) {
  --fallen-turn: -4deg;
  --fallen-shift: -4px;
}

.fallen-court .fallen-piece:nth-child(5n) {
  --fallen-turn: 8deg;
  --fallen-shift: 1px;
}

@media (min-width: 1101px) {
  .fallen-court--ivory .fallen-piece:nth-child(odd),
  .fallen-court--obsidian .fallen-piece:nth-child(even) {
    grid-column: 1;
  }

  .fallen-court--ivory .fallen-piece:nth-child(even),
  .fallen-court--obsidian .fallen-piece:nth-child(odd) {
    grid-column: 2;
  }
}

body .fallen-court .fallen-piece.piece-token::before {
  z-index: -1;
  right: 12%;
  bottom: 13%;
  left: 12%;
  width: auto;
  height: 22%;
  border-radius: 50%;
  opacity: 0.78;
  background: radial-gradient(ellipse, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0.22) 56%, transparent 75%);
  filter: blur(3px);
  transform: translateZ(-2px);
}

body .fallen-court .fallen-piece.piece-token::after {
  display: none;
}

.fallen-piece > .piece-icon {
  overflow: visible;
  transform-origin: 50% 56%;
}

body:not(.flat-view) .fallen-piece .structural-extrusion {
  display: inline;
}

body:not(.flat-view) .fallen-piece .structural-extrusion--deep {
  opacity: 0.72;
  filter: brightness(0.24) saturate(0.6);
}

body:not(.flat-view) .fallen-piece .structural-extrusion--mid {
  opacity: 0.62;
  filter: brightness(0.5) saturate(0.68);
}

.fallen-piece.is-latest-fallen {
  animation: fallen-settle 620ms cubic-bezier(0.17, 0.79, 0.28, 1) both;
}

.captured-glyphs {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.captured-glyphs > span {
  display: inline-grid;
  min-width: 13px;
  place-items: center;
}

/*
 * Flush inlay correction: no raised slab, only worn grout and a hairline of
 * brass where the playable stones meet the surrounding hall floor.
 */
.board-frame {
  padding: 0.48%;
  background:
    linear-gradient(145deg, rgba(90, 89, 76, 0.72), rgba(13, 20, 23, 0.92) 48%, rgba(61, 58, 48, 0.68));
  box-shadow:
    inset 0 0 0 1px rgba(8, 13, 15, 0.96),
    0 0 0 1px rgba(174, 139, 70, 0.52);
}

.board-frame::before {
  display: none;
}

.board-corner {
  opacity: 0.3;
}

body:not(.flat-view) .chessboard {
  transform: translateZ(0.25px);
  box-shadow:
    0 0 0 1px rgba(169, 135, 67, 0.58),
    inset 0 0 23px rgba(0, 0, 0, 0.62);
}

.flat-view .chessboard {
  box-shadow:
    0 0 0 1px rgba(169, 135, 67, 0.58),
    inset 0 0 23px rgba(0, 0, 0, 0.62);
}

body:not(.flat-view) .board-shadow {
  right: -4%;
  bottom: -1%;
  left: -4%;
  height: 10%;
  opacity: 0.13;
  filter: blur(9px);
}

.square:nth-child(7n + 3)::before {
  background-position: 8px -3px, -6px 5px, 2px 0, 0 0;
}

.square:nth-child(9n + 4) {
  box-shadow:
    inset 1px 2px rgba(231, 219, 181, 0.055),
    inset -3px -2px rgba(0, 0, 0, 0.34),
    inset 0 0 12px rgba(75, 48, 27, 0.075);
}

@media (max-width: 1100px) {
  body:not(.flat-view) .board-stage::before {
    inset: -11% -8% -15%;
  }

  .castle-floor-dressing {
    inset: -8% -7% -12%;
  }

  .candle-cluster--left {
    left: 0;
    transform: scale(0.62);
  }

  .candle-cluster--right {
    right: 0;
    transform: scale(0.62);
  }

  .floor-brazier {
    bottom: -1%;
    transform: scale(0.78);
  }

  .floor-brazier--right {
    transform: scale(-0.78, 0.78);
  }

  .board-stage {
    margin-bottom: clamp(20px, 4vw, 38px);
  }

  .fallen-court {
    top: auto;
    bottom: -13.5%;
    width: 43%;
    height: 15%;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    grid-auto-rows: clamp(24px, calc(var(--board-size) * 0.038), 30px);
    align-content: center;
    align-items: center;
    justify-items: center;
    padding: 5px 10px;
  }

  .fallen-court--ivory {
    left: 3.5%;
  }

  .fallen-court--obsidian {
    right: 3.5%;
  }

  body:not(.flat-view) .fallen-court .fallen-piece.piece-token,
  body.flat-view .fallen-court .fallen-piece.piece-token {
    width: clamp(38px, calc(var(--board-size) * 0.085), 62px);
    height: clamp(38px, calc(var(--board-size) * 0.085), 62px);
  }

  .fallen-court .fallen-piece + .fallen-piece {
    margin: 0;
  }
}

/* Tablet boards fill most of the viewport. Keep the horizontal casualty courts
 * in the clear gallery band above the projected floor instead of below it,
 * where they would collide with the hero rail and command panel. */
@media (min-width: 621px) and (max-width: 1100px) {
  .fallen-court {
    top: -14%;
    bottom: auto;
  }
}

@media (max-width: 620px) {
  body:not(.flat-view) .board-stage::before {
    inset: -7% -3.5% -11%;
  }

  .castle-floor-dressing {
    inset: -5% -3% -9%;
  }

  .candle-cluster {
    top: 6%;
  }

  .candle-cluster--left {
    transform: scale(0.62);
  }

  .candle-cluster--right {
    transform: scale(0.62);
  }

  .floor-candle:nth-child(3) {
    display: none;
  }

  .floor-brazier {
    display: none;
  }

  .board-stage {
    /* Leave the horizontal fallen courts clear of the hero identity rail. */
    margin-bottom: 68px;
  }

  .fallen-court {
    bottom: -14%;
    width: 48%;
    height: 13.5%;
    grid-auto-rows: clamp(19px, calc(var(--board-size) * 0.052), 21px);
    padding: 4px 8px;
  }

  .fallen-court--ivory {
    left: 1%;
  }

  .fallen-court--obsidian {
    right: 1%;
  }

  body:not(.flat-view) .fallen-court .fallen-piece.piece-token,
  body.flat-view .fallen-court .fallen-piece.piece-token {
    width: clamp(32px, calc(var(--board-size) * 0.082), 40px);
    height: clamp(32px, calc(var(--board-size) * 0.082), 40px);
    transform:
      translate3d(var(--fallen-shift), 0, 4px)
      rotateZ(calc(var(--fallen-angle) + var(--fallen-turn)))
      scale(0.88);
  }

  .fallen-court .fallen-piece.piece--black {
    --fallen-filter: saturate(0.76) brightness(1.34) drop-shadow(0 1px 0 rgba(174, 197, 193, 0.32));
  }

  body .fallen-court .fallen-piece.piece-token + .fallen-piece.piece-token {
    margin: 0;
  }
}

@keyframes candle-flutter {
  0% { opacity: 0.82; transform: translateX(-50%) rotate(-4deg) scale(0.9, 1.08); }
  52% { opacity: 1; transform: translateX(-50%) rotate(3deg) scale(1.04, 0.94); }
  100% { opacity: 0.9; transform: translateX(-50%) rotate(6deg) scale(0.86, 1.12); }
}

@keyframes brazier-fire {
  0% { opacity: 0.82; scale: 0.92 1.08; }
  55% { opacity: 1; scale: 1.06 0.9; }
  100% { opacity: 0.88; scale: 0.88 1.14; }
}

@keyframes hall-spill-breathe {
  from { opacity: 0.56; }
  to { opacity: 0.72; }
}

@keyframes fallen-settle {
  from {
    opacity: 0;
    filter: saturate(0.9) brightness(1.35);
    transform:
      translate3d(var(--fallen-shift), -13px, 22px)
      rotateZ(calc(var(--fallen-angle) + var(--fallen-turn) - 17deg))
      scale(0.82);
  }
  68% {
    opacity: 0.9;
    transform:
      translate3d(var(--fallen-shift), 2px, 3px)
      rotateZ(calc(var(--fallen-angle) + var(--fallen-turn) + 3deg))
      scale(0.93);
  }
  to {
    opacity: 0.82;
    filter: var(--fallen-filter);
    transform:
      translate3d(var(--fallen-shift), 0, 5px)
      rotateZ(calc(var(--fallen-angle) + var(--fallen-turn)))
      scale(0.9);
  }
}

@media (prefers-reduced-motion: reduce) {
  .floor-candle::before,
  .floor-brazier i,
  .castle-floor-dressing::before,
  .fallen-piece.is-latest-fallen {
    animation: none;
  }
}

/* source: duel-control-placement.css */
/*
 * Duel control placement.
 *
 * The fight remains on the board; its status and Skip control live in the
 * command surface (or a mobile bottom tray) so they never cover combatants.
 */

.command-panel.has-polished-battle-control {
  isolation: isolate;
}

.command-panel.has-polished-battle-control > .turn-oracle {
  visibility: hidden;
  opacity: 0;
}

.command-panel > .polished-battle-hud {
  position: absolute;
  z-index: 150;
  top: clamp(12px, 2.2vh, 20px);
  right: 12px;
  left: 12px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  width: auto;
  max-width: none;
  min-height: 52px;
  gap: 8px;
  transform: none;
  animation: duel-control-enter 240ms cubic-bezier(0.16, 0.72, 0.2, 1) both;
}

.command-panel > .polished-battle-hud > span {
  min-width: 0;
  width: 100%;
}

.command-panel > .polished-battle-hud small,
.command-panel > .polished-battle-hud strong,
body > .polished-battle-hud small,
body > .polished-battle-hud strong {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: break-word;
}

.command-panel > .polished-battle-hud .polished-battle-skip {
  min-width: 104px;
  min-height: 44px;
  justify-self: end;
}

@keyframes duel-control-enter {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (max-width: 1100px) {
  .command-panel.has-polished-battle-control > .turn-oracle {
    visibility: visible;
    opacity: 1;
  }

  body > .polished-battle-hud {
    position: fixed;
    z-index: 520;
    top: auto;
    right: auto;
    bottom: max(12px, env(safe-area-inset-bottom));
    left: 50%;
    width: min(520px, calc(100vw - 20px));
    max-width: calc(100vw - 20px);
    min-height: 56px;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 8px;
    padding: 8px 8px 8px 12px;
    transform: translateX(-50%);
    animation-name: duel-control-enter-mobile;
    box-shadow:
      0 1px 0 rgba(244, 218, 153, 0.58),
      0 9px 28px rgba(0, 0, 0, 0.72),
      inset 0 0 0 2px rgba(5, 9, 9, 0.72),
      inset 0 0 22px rgba(0, 0, 0, 0.54);
  }

  body > .polished-battle-hud > span {
    min-width: 0;
    width: 100%;
  }

  body > .polished-battle-hud .polished-battle-skip {
    min-height: 45px;
    justify-self: end;
  }

  @keyframes duel-control-enter-mobile {
    from {
      opacity: 0;
      transform: translate(-50%, 12px) scale(0.985);
    }
    to {
      opacity: 1;
      transform: translate(-50%, 0) scale(1);
    }
  }
}

@media (max-width: 620px) {
  body > .polished-battle-hud {
    gap: 8px;
    min-height: 58px;
  }

  body > .polished-battle-hud small {
    font-size: 9px;
  }

  body > .polished-battle-hud strong {
    font-size: 11px;
  }

  body > .polished-battle-hud .polished-battle-skip {
    min-width: 92px;
    min-height: 45px;
    padding-inline: 8px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .command-panel > .polished-battle-hud,
  body > .polished-battle-hud {
    animation: none;
  }
}

/* source: endgame-choreography.css */
/* In-place victory and defeat epilogue. This layer is decorative; result copy
   and the skip control stay in the command panel beside the board. */
.endgame-effects {
  position: absolute;
  z-index: 72;
  inset: -5% -4% -4%;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 360ms ease;
}

.endgame-effects[hidden] {
  display: none;
}

.endgame-effects.is-visible {
  opacity: 1;
}

.endgame-effects.is-settling {
  opacity: 0;
}

.endgame-effects__halo,
.endgame-effects__rays,
.endgame-effects__crown,
.endgame-effects__shade,
.endgame-effects__particles,
.endgame-effects__particles > i {
  position: absolute;
  display: block;
}

.endgame-effects__halo,
.endgame-effects__rays,
.endgame-effects__crown {
  left: var(--endgame-focus-x, 50%);
  top: var(--endgame-focus-y, 50%);
}

.endgame-effects__halo {
  width: calc(var(--endgame-cell, 64px) * 3.2);
  aspect-ratio: 1;
  border: 1px solid rgba(241, 204, 116, 0.36);
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(249, 215, 126, 0.34), rgba(216, 169, 72, 0.08) 35%, transparent 70%),
    conic-gradient(from 18deg, transparent, rgba(245, 218, 151, 0.24), transparent 15%, transparent 32%, rgba(245, 218, 151, 0.2), transparent 49%, transparent 70%, rgba(245, 218, 151, 0.18), transparent 86%);
  box-shadow: 0 0 calc(var(--endgame-cell, 64px) * 1.2) rgba(221, 173, 77, 0.32);
  transform: translate(-50%, -50%) scale(0.32);
  animation: endgame-halo-awaken 3.2s var(--ease-out, ease-out) 160ms both;
}

.endgame-effects__rays {
  width: calc(var(--endgame-cell, 64px) * 4.8);
  aspect-ratio: 1;
  background: repeating-conic-gradient(from 0deg,
    rgba(250, 218, 143, 0) 0 7deg,
    rgba(250, 218, 143, 0.17) 8deg,
    rgba(250, 218, 143, 0) 11deg 24deg);
  mask-image: radial-gradient(circle, transparent 0 17%, #000 29%, transparent 69%);
  transform: translate(-50%, -50%) scale(0.4) rotate(0deg);
  animation: endgame-rays-turn 6s linear 100ms both;
}

.endgame-effects__crown {
  display: flex;
  gap: clamp(4px, calc(var(--endgame-cell, 64px) * 0.1), 9px);
  align-items: end;
  color: #f4d98e;
  font-family: var(--serif, serif);
  filter: drop-shadow(0 2px 2px #261505) drop-shadow(0 0 10px rgba(245, 203, 99, 0.76));
  transform: translate(-50%, -118%) scale(0.3) rotate(-8deg);
  animation: endgame-crown-arrive 1.6s cubic-bezier(0.2, 0.78, 0.2, 1.2) 420ms both;
}

.endgame-effects__crown i {
  font-size: calc(var(--endgame-cell, 64px) * 0.24);
  font-style: normal;
}

.endgame-effects__crown b {
  font-size: calc(var(--endgame-cell, 64px) * 0.4);
  font-weight: 400;
  line-height: 0.8;
}

.endgame-effects__shade {
  inset: 0;
  opacity: 0;
  background: radial-gradient(circle at var(--endgame-focus-x, 50%) var(--endgame-focus-y, 50%),
    transparent 0 16%, rgba(1, 5, 8, 0.06) 38%, rgba(1, 4, 8, 0.34) 100%);
  animation: endgame-room-breathe 5.4s ease 100ms both;
}

.endgame-effects__particles {
  inset: 0;
}

.endgame-effects__particles > i {
  --particle-angle: calc(var(--particle) * 20deg - 84deg);
  --particle-distance: calc(var(--endgame-cell, 64px) * 1.8);
  left: var(--endgame-focus-x, 50%);
  top: var(--endgame-focus-y, 50%);
  width: clamp(2px, calc(var(--endgame-cell, 64px) * 0.05), 5px);
  aspect-ratio: 1;
  border-radius: 50% 0 50% 50%;
  opacity: 0;
  background: #f4cf73;
  box-shadow: 0 0 7px rgba(246, 197, 82, 0.88);
  transform: translate(-50%, -50%) rotate(var(--particle-angle)) translateY(0) scale(0.2);
  animation: endgame-particle-flight 2.7s ease-out calc(460ms + var(--particle) * 58ms) both;
}

.board-stage[data-endgame-outcome="defeat"] .endgame-effects__halo,
.board-stage[data-endgame-outcome="defeat"] .endgame-effects__crown,
.board-stage[data-endgame-outcome="defeat"] .endgame-effects__particles {
  filter: hue-rotate(135deg) saturate(0.72) brightness(0.8);
}

.board-stage[data-endgame-outcome="draw"] .endgame-effects__crown,
.board-stage[data-endgame-outcome="draw"] .endgame-effects__rays,
.board-stage[data-endgame-outcome="draw"] .endgame-effects__particles {
  display: none;
}

.board-stage[data-endgame-outcome="draw"] .endgame-effects__halo {
  border-color: rgba(184, 207, 207, 0.34);
  background: radial-gradient(circle, rgba(164, 196, 194, 0.2), transparent 68%);
  box-shadow: 0 0 36px rgba(109, 159, 158, 0.22);
}

.endgame-skip {
  width: auto;
  max-width: 100%;
  min-width: 44px;
  min-height: 44px;
  margin-top: 10px;
  padding: 8px 13px;
  border: 1px solid rgba(224, 195, 124, 0.42);
  border-radius: 999px;
  color: rgba(246, 233, 198, 0.92);
  background: linear-gradient(180deg, rgba(72, 59, 39, 0.72), rgba(18, 19, 21, 0.86));
  box-shadow: inset 0 1px rgba(255, 240, 195, 0.1), 0 5px 16px rgba(0, 0, 0, 0.2);
  font: 700 10px/1.1 var(--sans, sans-serif);
  letter-spacing: 0.075em;
  text-transform: uppercase;
  cursor: pointer;
}

.endgame-skip:hover {
  border-color: rgba(243, 211, 129, 0.8);
  color: #fff4d8;
  background: linear-gradient(180deg, rgba(105, 82, 45, 0.82), rgba(24, 24, 24, 0.92));
}

.endgame-skip:focus-visible {
  outline: 2px solid #f1d086;
  outline-offset: 3px;
}

/* Root piece transforms retain the board counter-tilt and translateZ at every
   keyframe. The figures never collapse into a flattened SVG during the pose. */
body:not(.flat-view) .board-stage.is-endgame-playing .square > .piece-token.is-endgame-victor {
  animation: endgame-victor-wave-3d 2.65s cubic-bezier(0.34, 0.08, 0.16, 1)
    calc(180ms + var(--endgame-order, 0) * 42ms) 2 both !important;
  filter: brightness(1.08) drop-shadow(0 0 8px rgba(237, 203, 117, 0.25));
}

body:not(.flat-view) .board-stage.is-endgame-playing .square > .piece-token.is-endgame-victor.is-endgame-king {
  animation-name: endgame-king-salute-3d !important;
  animation-duration: 4.8s !important;
  animation-iteration-count: 1 !important;
  filter: brightness(1.12) drop-shadow(0 0 12px rgba(244, 208, 118, 0.42));
}

body:not(.flat-view) .board-stage.is-endgame-playing .square > .piece-token.is-endgame-defeated {
  animation: endgame-defeated-bow-3d 3.1s cubic-bezier(0.26, 0.06, 0.2, 1)
    calc(320ms + var(--endgame-order, 0) * 36ms) both !important;
  transform-origin: 50% 94%;
}

body:not(.flat-view) .board-stage.is-endgame-playing .square > .piece-token.is-endgame-drawn {
  animation: endgame-drawn-bow-3d 2.5s ease-in-out calc(160ms + var(--endgame-order, 0) * 30ms) both !important;
}

body:not(.flat-view) .board-stage.is-endgame-settled .square > .piece-token.is-endgame-victor.is-endgame-king {
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-11%) translateZ(16px);
}

body:not(.flat-view) .board-stage.is-endgame-settled .square > .piece-token.is-endgame-defeated {
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-5%) translateZ(10px)
    rotateZ(calc(var(--endgame-direction, 1) * 6deg));
  filter: brightness(0.78) saturate(0.72);
}

body:not(.flat-view) .board-stage.is-endgame-settled .square > .piece-token.is-endgame-drawn {
  transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-5%) translateZ(10px) rotateZ(2deg);
}

/* Articulated salutes and bowed heads sit inside, rather than replacing, the
   structural SVG body and extrusion layers. */
.board-stage.is-endgame-playing .is-endgame-victor :is(.soldier-arm--weapon, .soldier-casting-arm, .king-guarded-sword) {
  transform-box: fill-box;
  transform-origin: 50% 92%;
  animation: endgame-weapon-salute 2.65s ease-in-out calc(180ms + var(--endgame-order, 0) * 42ms) 2 both !important;
}

.board-stage.is-endgame-playing .is-endgame-defeated :is(.soldier-head, .king-head-rig, .queen-head-rig) {
  transform-box: fill-box;
  transform-origin: 50% 90%;
  animation: endgame-head-bow 3.1s ease-out calc(320ms + var(--endgame-order, 0) * 36ms) both !important;
}

.flat-view .board-stage.is-endgame-playing .square > .piece-token.is-endgame-victor {
  animation: endgame-victor-wave-flat 2.65s cubic-bezier(0.34, 0.08, 0.16, 1)
    calc(180ms + var(--endgame-order, 0) * 42ms) 2 both !important;
}

.flat-view .board-stage.is-endgame-playing .square > .piece-token.is-endgame-victor.is-endgame-king {
  animation-name: endgame-king-salute-flat !important;
  animation-duration: 4.8s !important;
  animation-iteration-count: 1 !important;
}

.flat-view .board-stage.is-endgame-playing .square > .piece-token.is-endgame-defeated {
  animation: endgame-defeated-bow-flat 3.1s cubic-bezier(0.26, 0.06, 0.2, 1)
    calc(320ms + var(--endgame-order, 0) * 36ms) both !important;
}

.flat-view .board-stage.is-endgame-playing .square > .piece-token.is-endgame-drawn {
  animation: endgame-drawn-bow-flat 2.5s ease-in-out calc(160ms + var(--endgame-order, 0) * 30ms) both !important;
}

.flat-view .board-stage.is-endgame-settled .square > .piece-token.is-endgame-victor.is-endgame-king {
  transform: translateY(-11%) translateZ(8px);
}

.flat-view .board-stage.is-endgame-settled .square > .piece-token.is-endgame-defeated {
  transform: translateY(-4%) rotateZ(calc(var(--endgame-direction, 1) * 6deg));
  filter: brightness(0.78) saturate(0.72);
}

@keyframes endgame-victor-wave-3d {
  0%, 8%, 50%, 58%, 100% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) rotateZ(0); }
  17% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-17%) translateZ(22px) rotateZ(calc(var(--endgame-direction, 1) * -3deg)); }
  28% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-9%) translateZ(13px) rotateZ(calc(var(--endgame-direction, 1) * 2deg)); }
  38% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-15%) translateZ(20px) rotateZ(calc(var(--endgame-direction, 1) * -2deg)); }
  67% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-14%) translateZ(19px) rotateZ(calc(var(--endgame-direction, 1) * 2deg)); }
  80% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-8%) translateZ(12px) rotateZ(calc(var(--endgame-direction, 1) * -1deg)); }
}

@keyframes endgame-king-salute-3d {
  0%, 8% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) rotateZ(0); }
  20% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-18%) translateZ(24px) rotateZ(-2deg); }
  34%, 68% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-13%) translateZ(20px) rotateZ(1deg); }
  82%, 100% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-11%) translateZ(16px) rotateZ(0); }
}

@keyframes endgame-defeated-bow-3d {
  0%, 9% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) rotateZ(0); filter: brightness(1); }
  24% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-3%) translateZ(9px) rotateZ(calc(var(--endgame-direction, 1) * -3deg)); filter: brightness(0.92); }
  42% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(12px) rotateZ(calc(var(--endgame-direction, 1) * 2deg)); }
  64%, 100% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-5%) translateZ(10px) rotateZ(calc(var(--endgame-direction, 1) * 6deg)); filter: brightness(0.78) saturate(0.72); }
}

@keyframes endgame-drawn-bow-3d {
  0%, 12%, 100% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) rotateZ(0); }
  46%, 72% { transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-3%) translateZ(9px) rotateZ(2deg); }
}

@keyframes endgame-victor-wave-flat {
  0%, 8%, 50%, 58%, 100% { transform: translateY(-7%) translateZ(0) rotateZ(0); }
  17%, 67% { transform: translateY(-16%) translateZ(7px) rotateZ(calc(var(--endgame-direction, 1) * -3deg)); }
  38% { transform: translateY(-13%) translateZ(5px) rotateZ(calc(var(--endgame-direction, 1) * 2deg)); }
}

@keyframes endgame-king-salute-flat {
  0%, 8% { transform: translateY(-7%) translateZ(0); }
  20% { transform: translateY(-18%) translateZ(9px) rotateZ(-2deg); }
  34%, 68% { transform: translateY(-13%) translateZ(7px) rotateZ(1deg); }
  82%, 100% { transform: translateY(-11%) translateZ(5px); }
}

@keyframes endgame-defeated-bow-flat {
  0%, 9% { transform: translateY(-7%) rotateZ(0); filter: brightness(1); }
  42% { transform: translateY(-7%) rotateZ(calc(var(--endgame-direction, 1) * 2deg)); }
  64%, 100% { transform: translateY(-4%) rotateZ(calc(var(--endgame-direction, 1) * 6deg)); filter: brightness(0.78) saturate(0.72); }
}

@keyframes endgame-drawn-bow-flat {
  0%, 12%, 100% { transform: translateY(-7%) rotateZ(0); }
  46%, 72% { transform: translateY(-3%) rotateZ(2deg); }
}

@keyframes endgame-weapon-salute {
  0%, 8%, 50%, 58%, 100% { transform: rotate(0deg) translateY(0); }
  18%, 38%, 68% { transform: rotate(-22deg) translate(-1px, -3px); }
  29%, 79% { transform: rotate(-7deg) translateY(-1px); }
}

@keyframes endgame-head-bow {
  0%, 18% { transform: rotate(0) translateY(0); }
  46%, 100% { transform: rotate(calc(var(--endgame-direction, 1) * 5deg)) translateY(2px); }
}

@keyframes endgame-halo-awaken {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.32); }
  28% { opacity: 0.95; }
  62% { opacity: 0.68; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0.36; transform: translate(-50%, -50%) scale(1.12); }
}

@keyframes endgame-rays-turn {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.4) rotate(0); }
  25% { opacity: 0.55; }
  100% { opacity: 0.1; transform: translate(-50%, -50%) scale(1.08) rotate(34deg); }
}

@keyframes endgame-crown-arrive {
  0% { opacity: 0; transform: translate(-50%, -210%) scale(0.3) rotate(-8deg); }
  55% { opacity: 1; transform: translate(-50%, -112%) scale(1.08) rotate(3deg); }
  75% { transform: translate(-50%, -122%) scale(0.94) rotate(-1deg); }
  100% { opacity: 0.9; transform: translate(-50%, -118%) scale(1) rotate(0); }
}

@keyframes endgame-room-breathe {
  0% { opacity: 0; }
  22%, 72% { opacity: 1; }
  100% { opacity: 0.52; }
}

@keyframes endgame-particle-flight {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--particle-angle)) translateY(0) scale(0.2); }
  16% { opacity: 1; }
  70% { opacity: 0.78; }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--particle-angle)) translateY(calc(var(--particle-distance) * -1)) scale(0.9); }
}

@media (max-width: 760px) {
  .endgame-effects {
    inset: -2%;
  }

  .endgame-skip {
    margin-top: 8px;
    font-size: 9px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .endgame-effects,
  .board-stage.is-endgame-active .piece-token,
  .board-stage.is-endgame-active .structural-piece * {
    animation: none !important;
    transition: none !important;
  }

  body:not(.flat-view) .board-stage.is-endgame-settled .square > .piece-token,
  body:not(.flat-view) .board-stage.is-endgame-settled .square > .piece-token.is-endgame-king {
    transform: rotateX(calc(-1 * var(--board-tilt))) translateY(-7%) translateZ(11px) !important;
    filter: none;
  }

  .flat-view .board-stage.is-endgame-settled .square > .piece-token,
  .flat-view .board-stage.is-endgame-settled .square > .piece-token.is-endgame-king {
    transform: translateY(-7%) translateZ(0) !important;
    filter: none;
  }
}

/* source: combat-depth-restoration.css */
/*
 * Combat depth restoration.
 *
 * Filters, isolation, opacity, and their will-change hints are grouping
 * properties: on a preserve-3d ancestor they composite its descendants as one
 * flat plane. The duel rigs need to remain in the board's 3D context so each
 * cloned sculpture
 * can counter-rotate upright just like the stationary army.
 */
body:not(.flat-view) .polished-battle-layer {
  isolation: auto;
  transform-style: preserve-3d;
}

body:not(.flat-view) .polished-battle-layer
  :is(.polished-battle-attacker, .polished-battle-defender) {
  filter: none !important;
  opacity: 1 !important;
  transform-style: preserve-3d;
  will-change: transform;
}

body:not(.flat-view) .polished-battle-layer
  :is(.polished-battle-attacker, .polished-battle-defender)
  > .piece-token {
  filter: none !important;
  transform-style: preserve-3d;
}

/* The defender used to fade its outer motion carrier. Even before opacity
   visibly changed, Chrome composited that entire animated carrier as one flat
   board-plane image. Fade the already-upright sculpture instead, leaving the
   carrier in the shared 3D scene through the complete knockdown. */
body:not(.flat-view) .is-polished-battle-playing
  .polished-battle-defender > .piece-token {
  animation: combat-defender-fade-inner var(--pb-duration) linear both;
}

@keyframes combat-defender-fade-inner {
  0%, 84% { opacity: 1; }
  89% { opacity: 0.96; }
  94%, 98% { opacity: 0.76; }
  100% { opacity: 0; }
}

/* Chrome can pre-composite a carrier merely because its active keyframes name
   filter or opacity, even when a stronger declaration keeps the computed value
   neutral. These 3D-only tracks preserve every v4 transform/contact beat while
   omitting all grouping properties from the carrier animation itself. */
body:not(.flat-view) .is-polished-battle-playing
  .polished-battle-layer .polished-battle-attacker {
  animation-name: combat-attacker-depth-3d;
}

body:not(.flat-view) .is-polished-battle-playing
  .polished-battle-layer.polished-battle--magic .polished-battle-attacker {
  animation-name: combat-caster-depth-3d;
}

body:not(.flat-view) .is-polished-battle-playing
  .polished-battle-layer .polished-battle-defender {
  animation-name: combat-defender-depth-3d;
}

@keyframes combat-attacker-depth-3d {
  0%, 8% {
    transform: translate3d(0, 0, 30px);
  }
  12% {
    transform:
      translate3d(
        calc(var(--pb-step-one-x) * -0.16),
        calc(var(--pb-step-one-y) * -0.16 + 1px),
        29px
      )
      rotate(var(--pb-attacker-windup));
  }
  18% {
    transform:
      translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 2px), 33px)
      rotate(var(--pb-attacker-turn-in));
  }
  23% {
    transform:
      translate3d(var(--pb-step-one-x), var(--pb-step-one-y), 29px)
      rotate(var(--pb-attacker-turn-in));
  }
  28% {
    transform:
      translate3d(var(--pb-step-two-x), calc(var(--pb-step-two-y) - 2px), 33px)
      rotate(var(--pb-attacker-turn-out));
  }
  32% {
    transform: translate3d(var(--pb-approach-x), var(--pb-approach-y), 30px);
  }
  35%, 43% {
    transform:
      translate3d(var(--pb-parry-x), var(--pb-parry-y), 32px)
      rotate(var(--pb-attacker-turn-in));
  }
  46% {
    transform:
      translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) + 1px), 29px)
      rotate(var(--pb-attacker-turn-out));
  }
  52% {
    transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 29px);
  }
  57%, 65% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) + 1px), 28px)
      rotate(var(--pb-attacker-windup));
  }
  67% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 2px), 33px)
      rotate(var(--pb-attacker-windup));
  }
  71% {
    transform:
      translate3d(var(--pb-strike-x), calc(var(--pb-strike-y) - 3px), 35px)
      rotate(var(--pb-attacker-strike));
  }
  72%, 80% {
    transform:
      translate3d(var(--pb-strike-x), var(--pb-strike-y), 32px)
      rotate(var(--pb-attacker-strike));
  }
  84% {
    transform:
      translate3d(var(--pb-recoil-x), var(--pb-recoil-y), 29px)
      rotate(var(--pb-attacker-turn-out));
  }
  91% {
    transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 2px), 33px);
  }
  96%, 100% {
    transform: translate3d(var(--pb-end-x), var(--pb-end-y), 30px);
  }
}

@keyframes combat-caster-depth-3d {
  0%, 9% {
    transform: translate3d(0, 0, 31px);
  }
  16% {
    transform:
      translate3d(var(--pb-step-one-x), calc(var(--pb-step-one-y) - 3px), 35px)
      rotate(var(--pb-attacker-turn-in));
  }
  25% {
    transform: translate3d(var(--pb-step-two-x), var(--pb-step-two-y), 31px);
  }
  34%, 42% {
    transform:
      translate3d(var(--pb-parry-x), calc(var(--pb-parry-y) - 1px), 35px)
      rotate(var(--pb-attacker-turn-in));
  }
  46%, 52% {
    transform: translate3d(var(--pb-reset-x), var(--pb-reset-y), 31px);
  }
  57%, 64% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 3px), 36px)
      rotate(var(--pb-attacker-windup));
  }
  68% {
    transform:
      translate3d(var(--pb-reset-x), calc(var(--pb-reset-y) - 5px), 39px)
      rotate(var(--pb-attacker-windup));
  }
  72%, 80% {
    transform:
      translate3d(var(--pb-strike-x), var(--pb-strike-y), 38px)
      rotate(var(--pb-attacker-strike));
  }
  84% {
    transform: translate3d(var(--pb-recoil-x), calc(var(--pb-recoil-y) - 3px), 34px);
  }
  91% {
    transform: translate3d(var(--pb-end-x), calc(var(--pb-end-y) - 2px), 34px);
  }
  96%, 100% {
    transform: translate3d(var(--pb-end-x), var(--pb-end-y), 31px);
  }
}

@keyframes combat-defender-depth-3d {
  0%, 31% {
    transform: translate3d(0, 0, 30px);
  }
  35%, 43% {
    transform:
      translate3d(var(--pb-defender-parry-x), var(--pb-defender-parry-y), 33px)
      rotate(var(--pb-defender-turn-in));
  }
  46% {
    transform:
      translate3d(var(--pb-defender-recoil-x), var(--pb-defender-recoil-y), 29px)
      rotate(var(--pb-defender-turn-out));
  }
  52% {
    transform: translate3d(0, 0, 30px);
  }
  57%, 66% {
    transform:
      translate3d(
        var(--pb-defender-counter-x),
        calc(var(--pb-defender-counter-y) - 2px),
        34px
      )
      rotate(var(--pb-defender-turn-in));
  }
  68% {
    transform: translate3d(0, 0, 30px);
  }
  72%, 80% {
    transform:
      translate3d(
        var(--pb-defender-recoil-x),
        var(--pb-defender-recoil-y),
        34px
      )
      rotate(var(--pb-defender-turn-out));
  }
  84% {
    transform:
      translate3d(
        calc(var(--pb-defender-knock-x) * 0.25),
        calc(var(--pb-defender-knock-y) * 0.22),
        25px
      )
      rotate(calc(var(--pb-defender-knock-spin) * 0.22));
  }
  89% {
    transform:
      translate3d(
        calc(var(--pb-defender-knock-x) * 0.68),
        calc(var(--pb-defender-knock-y) * 0.72),
        13px
      )
      rotate(calc(var(--pb-defender-knock-spin) * 0.68));
  }
  94%, 98%, 100% {
    transform:
      translate3d(
        var(--pb-defender-knock-x),
        calc(var(--pb-defender-knock-y) + 5px),
        3px
      )
      rotate(var(--pb-defender-knock-spin));
  }
}
