/*
 * Browser shell styles — V02 battle look (Issue #141).
 *
 * Design tokens and geometry follow the approved V02 artboards
 * (assets/p0-ui/revisions/v02 + docs/design/p0-ui/design-spec.md): warm-paper
 * ground, ink panels, category colors as accents only, seat trim keyed by
 * stable seat id (Alpha purple long-dash double track / Beta rose short-dash
 * single track) — never by screen position.
 *
 * Responsive targets: 360×800 / 390×844 (portrait default), 844×390
 * (landscape: stage+HUD left, controls right), 1440×900 (desktop: top
 * left/right HUD, full-width stage, six bottom slots). Breakpoints per design-spec:
 * width <600 → portrait; width ≥600 and height <500 → landscape compact;
 * otherwise desktop.
 */

:root {
  /* V02 palette */
  --paper: #f3e9d2;
  --paper-deep: #ede3c8;
  --ink: #24282b;
  --ink-soft: #52575a;
  --shadow-tone: #e2d6be;
  --panel-shadow: #d8c8ad;
  --track: #c5b598;
  --icon-idle: #625d53;
  --muted: #6f6a60;
  --fixture: #8a6d1f;
  /* Category accents — symbols/labels only, never small body text. */
  --attack: #df6d43;
  --defense: #728c8a;
  --charge: #e3b044;
  /* Seat identity */
  --alpha: #6e56a8;
  --beta: #b74f78;
  --accent: #6e56a8;
  font-synthesis: none;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Noto Sans CJK SC", sans-serif;
}

#app {
  max-width: 1280px;
  margin: 0 auto;
  padding: 10px 12px 16px;
}

/* Screen-reader-only text: machine-readable values without visual HUD. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Header / fixture notice ---- */

.shell-header {
  margin-bottom: 10px;
}

.shell-title {
  margin: 0 0 0.4rem;
  font-size: 1.5rem;
}

/* V02 wordmark: 决拍 + DUELBEAT submark. */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.wordmark__zh {
  font-size: 29px;
  font-weight: 900;
  color: var(--ink);
}

.wordmark__en {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--ink-soft);
}

.fixture-notice {
  margin: 0;
  padding: 0.45rem 0.7rem;
  border: 1.5px solid var(--panel-shadow);
  background: var(--paper-deep);
  border-radius: 8px;
  color: var(--fixture);
  font-size: 0.8rem;
}

.candidate-banner {
  margin: 0.4rem 0 0;
  font-size: 0.8rem;
  color: var(--accent);
  word-break: break-all;
}

.shell-header__controls {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* ---- Shared buttons ---- */

.start-button {
  font: inherit;
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.7rem 1.6rem;
  border-radius: 10px;
  border: 2px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  box-shadow: 3px 3px 0 var(--panel-shadow);
  cursor: pointer;
}

.start-button:hover,
.start-button:focus-visible {
  background: #fff9e8;
}

.settings-button {
  display: inline-block;
  margin: 0.4rem 0.4rem 0 0;
  padding: 0.45rem 0.9rem;
  background: var(--paper);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 8px;
  font-size: 0.9rem;
  cursor: pointer;
}

.settings-button:hover {
  background: #fff9e8;
}

.mute-button, .motion-button {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  border: 1.5px solid var(--ink-soft);
  background: var(--paper);
  color: var(--ink-soft);
  cursor: pointer;
}

.mute-button:hover,
.mute-button:focus-visible {
  border-color: var(--ink);
  color: var(--ink);
}

.mute-button[aria-pressed="true"] {
  color: var(--fixture);
  border-color: var(--fixture);
}

.time-sync-debug {
  display: block;
  margin-top: 0.35rem;
  color: var(--ink-soft);
  font: 0.75rem/1.3 ui-monospace, SFMono-Regular, Menlo, monospace;
  text-align: right;
}

/* ---- Battle body grid (portrait default) ---- */

.shell-body {
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "hudself hudopp"
    "stage stage"
    "moves moves"
    "info info"
    "expl expl"
    "menu menu";
}

.duelist--self { grid-area: hudself; }
.duelist--opponent { grid-area: hudopp; }
.stage { grid-area: stage; }
.moves { grid-area: moves; }
.info-card { grid-area: info; }
.explanation-panel { grid-area: expl; }
.in-match-menu { grid-area: menu; }

/* ---- Mirrored resource cards (V02) ---- */

.duelist {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  border-radius: 10px;
  padding: 14px 12px 10px;
  min-width: 0;
}

/* Seat trim keyed by STABLE seat id — same pattern whichever side the seat
   renders on. Alpha: double long-dash track; Beta: single short-dash track. */
.duelist--id-alpha::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 10px;
  right: 10px;
  height: 9px;
  background:
    repeating-linear-gradient(90deg, var(--alpha) 0 16px, transparent 16px 22px)
      0 0 / 100% 3px no-repeat,
    repeating-linear-gradient(90deg, var(--alpha) 0 16px, transparent 16px 22px)
      0 6px / 100% 3px no-repeat;
}

.duelist--id-beta::before {
  content: "";
  position: absolute;
  top: 9px;
  left: 10px;
  right: 10px;
  height: 3px;
  background: repeating-linear-gradient(
    90deg,
    var(--beta) 0 4px,
    transparent 4px 10px
  );
}

/* Self card reads right-to-left toward the center; opponent mirrors. */
.duelist__label {
  display: block;
  font-weight: 700;
  font-size: 0.9rem;
  margin: 10px 0 6px;
}

.duelist--self {
  text-align: right;
}

.duelist--self .duelist__label {
  margin-right: 2px;
}

.duelist__stats {
  margin: 0;
  display: grid;
  gap: 3px;
}

/* Mirrored alignment: the self card's rows hug the stage-facing edge
   (right), the opponent's hug theirs (left). */
.duelist--self .duelist__stats {
  justify-items: end;
}

.duelist--opponent .duelist__stats {
  justify-items: start;
}

.pips {
  display: inline-flex;
  gap: 3px;
  align-items: center;
  min-height: 18px;
}

.duelist--self .pips {
  flex-direction: row-reverse; /* owned pips fill from the near-center outward */
}

.pip {
  width: 17px;
  height: 16px;
  display: inline-block;
}

.pip svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Unowned pips keep their outline (V02: 未拥有的资源保留轮廓). */
.pip svg path,
.pip svg circle {
  fill: none;
  stroke: #77705f;
  stroke-width: 2.4;
}

.pip--owned svg path,
.pip--owned svg circle {
  fill: var(--paper);
  stroke: var(--paper);
}

/* The win pip's check stroke stays a stroke even when owned. */
.pip--wins svg .icon-check,
.pip--wins svg path[d^="M9.5"],
.pip--wins svg path[d^="M9 16"] {
  fill: none !important;
}

/* ---- Stage (V02): placeholder background + seat layers + progress line ---- */

.stage {
  min-width: 0;
}

.stage__scene {
  position: relative;
  container-type: size;
  height: clamp(200px, 42vh, 430px);
  border: 2px solid var(--ink);
  border-radius: 12px;
  overflow: hidden;
  background: var(--paper-deep);
  /* Character display height: a share of the scene via container units, so
     all breakpoints read at V02 scale without JS measurement. */
  --char-h: 170px; /* fallback for engines without container-query units */
  --char-h: clamp(88px, 52cqh, 235px);
  --sprite: calc(var(--char-h) * 1.28);
}

.stage__background,
.stage__background-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.stage__background {
  opacity: 0;
}

.stage__background.is-loaded {
  opacity: 1;
}

.stage__background.is-error {
  display: none;
}

/* Emergency backdrop when even the background file is missing. */
.stage__background-fallback {
  background:
    radial-gradient(circle at 50% 30%, transparent 52px, var(--shadow-tone) 54px),
    linear-gradient(var(--paper-deep) 0 74%, var(--panel-shadow) 74% 100%);
}

/* Seat anchor point: one per duelist, placed on the floor line. All seat
   layers (trim/sprite/fx/flash) hang off it, so mirroring or motion moves the
   whole seat together. */
.stage__seat {
  position: absolute;
  left: 27%;
  top: 82%;
  width: 0;
  height: 0;
  --dir: 1; /* lunge/recoil direction: toward the opponent */
}

.stage__seat--right {
  left: 73%;
  --dir: -1;
}

.stage__trim {
  position: absolute;
  top: 8px;
  left: -60px;
  width: 120px;
  height: 12px;
}

.stage__trim svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Sprite box: square of side 1.28×char-h, anchored so the source's (512,896)
   bottom anchor sits exactly on the seat point. Fixed geometry ⇒ a failed or
   swapped image can never shift layout. */
.stage__sprite-box {
  position: absolute;
  width: var(--sprite);
  height: var(--sprite);
  left: calc(var(--sprite) / -2);
  top: calc(var(--sprite) * -0.875);
  transform-origin: 50% 87.5%;
}

/* CSS fallback figure under the sprite — visible until (or unless) the mapped
   image loads; keeps the stage playable with zero assets. */
.stage__sprite-fallback {
  position: absolute;
  inset: 12.5% 22%;
  background: var(--paper);
  border: 3px solid var(--ink);
  border-radius: 42% 42% 26% 26%;
}

.stage__sprite-fallback::before {
  content: "";
  position: absolute;
  top: 9%;
  left: 28%;
  width: 44%;
  height: 24%;
  background: var(--ink);
  border-radius: 40%;
}

.stage__sprite {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}

.stage__sprite.is-loaded {
  opacity: 1;
}

.stage__sprite.is-error {
  display: none;
}

/* The right seat mirrors the shared source frame — presentation only, never
   a second character identity. */
.stage__seat--mirror .stage__sprite,
.stage__seat--mirror .stage__sprite-fallback {
  /* Mirror the artwork only; the parent owns world-direction motion. */
  transform: scaleX(-1);
}

.stage__seat--mirror .stage__sprite-fallback::before {
  left: auto;
  right: 28%;
}

/* Category effect overlay near the seat. */
.stage__fx {
  position: absolute;
  width: calc(var(--char-h) * 0.92);
  height: calc(var(--char-h) * 0.92);
  left: calc(var(--char-h) * -0.46);
  top: calc(var(--char-h) * -1.42);
}

.stage__fx-img {
  width: 100%;
  height: 100%;
}

/* Placeholder motions (simple transforms on a --resolution-ms budget). They
   run ONLY on a fresh settlement reveal; a re-render of the same settlement
   keeps the state with no motion (stage__seat--played). */
.stage__seat--motion-lunge.stage__seat--fresh .stage__sprite-box {
  animation: stage-lunge var(--resolution-ms, 400ms) ease-out;
}

.stage__seat--motion-lunge-heavy.stage__seat--fresh .stage__sprite-box {
  animation: stage-lunge-heavy var(--resolution-ms, 400ms) ease-out;
}

.stage__seat--motion-brace.stage__seat--fresh .stage__sprite-box {
  animation: stage-brace var(--resolution-ms, 400ms) ease-out;
}

.stage__seat--motion-gather.stage__seat--fresh .stage__sprite-box,
.stage__seat--motion-gather-heavy.stage__seat--fresh .stage__sprite-box {
  animation: stage-gather var(--resolution-ms, 400ms) ease-in-out;
}

.stage__seat--motion-recoil.stage__seat--fresh .stage__sprite-box {
  animation: stage-recoil var(--resolution-ms, 400ms) ease-out;
}

@keyframes stage-lunge {
  0%, 100% { transform: translateX(0); }
  38% { transform: translateX(calc(var(--dir) * var(--char-h) * 0.34)); }
}

@keyframes stage-lunge-heavy {
  0%, 100% { transform: translateX(0); }
  42% { transform: translateX(calc(var(--dir) * var(--char-h) * 0.48)); }
}

@keyframes stage-brace {
  0%, 100% { transform: scale(1, 1); }
  40% { transform: scale(1.04, 0.94); }
}

@keyframes stage-gather {
  0%, 100% { transform: scale(1); }
  55% { transform: scale(1.07); }
}

@keyframes stage-recoil {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  40% {
    transform: translateX(calc(var(--dir) * var(--char-h) * -0.26))
      rotate(calc(var(--dir) * -6deg));
  }
}

/* Hit flash: neutral paper burst, fades within the resolution beat. */
.stage__flash {
  position: absolute;
  width: calc(var(--char-h) * 1.05);
  height: calc(var(--char-h) * 1.05);
  left: calc(var(--char-h) * -0.525);
  top: calc(var(--char-h) * -1.5);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(243, 233, 210, 0.85), transparent 65%);
  opacity: 0;
  pointer-events: none;
}

.stage__seat--hit.stage__seat--fresh .stage__flash {
  animation: stage-flash var(--resolution-ms, 400ms) ease-out;
}

@keyframes stage-flash {
  0% { opacity: 0.9; }
  100% { opacity: 0; }
}

.stage__seat--no-action .stage__sprite-box {
  opacity: 0.55;
}

/* Reveal banner: both moves + deltas, top-center of the scene. */
.stage__banner {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--paper);
  padding: 7px 14px;
  border-radius: 8px;
  text-align: center;
  max-width: 86%;
}

.stage__banner-moves {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stage__banner-deltas {
  margin: 2px 0 0;
  font-size: 0.78rem;
  opacity: 0.9;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Open-countdown numeral (pre-match state, not a decision countdown). */
.stage__countdown {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  font-size: clamp(64px, 30cqh, 120px);
  font-weight: 900;
  color: var(--ink);
  pointer-events: none;
}

/* ---- Short progress line (V02) ---- */

.progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 7px;
  padding: 0 8px;
}

.progress__track {
  position: relative;
  width: 190px;
  height: 3px;
  background: var(--track);
  border-radius: 2px;
}

/* The dark segment is the REMAINING window, consumed left-to-right. */
.progress__remaining {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 100%;
  background: var(--ink);
  border-radius: 0 2px 2px 0;
}

.progress__icons {
  display: flex;
  align-items: center;
  gap: 12px;
}

.progress__icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--paper);
  display: grid;
  place-items: center;
}

.progress__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.progress__icon .icon-core {
  fill: var(--paper);
  stroke: var(--icon-idle);
  stroke-width: 1.5;
}

.progress__icon .icon-ring {
  fill: none;
  stroke: var(--icon-idle);
  stroke-width: 1;
  opacity: 0.5;
}

/* Active icon fills; past icons keep their outline (V02 beat-icon contract). */
.progress__icon.is-active .icon-core {
  fill: var(--ink);
  stroke: var(--ink);
}

.progress__icon.is-active .icon-ring {
  stroke: var(--ink);
  opacity: 0.4;
}

.progress__icon.is-active {
  animation: beat-pulse 120ms ease-out;
}

@keyframes beat-pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* ---- Move cards (V02) ---- */

.moves__title {
  margin: 0 0 6px;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.moves__grid {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-areas:
    "a0 d0 c0"
    "a1 d1 c1";
}

.move-card--attack-0 { grid-area: a0; }
.move-card--defense-0 { grid-area: d0; }
.move-card--charge-0 { grid-area: c0; }
.move-card--attack-1 { grid-area: a1; }
.move-card--defense-1 { grid-area: d1; }
.move-card--charge-1 { grid-area: c1; }

.moves__grid--idle {
  opacity: 0.55;
}

.move-card {
  position: relative;
  font: inherit;
  text-align: left;
  display: grid;
  grid-template-rows: auto auto auto auto;
  gap: 2px;
  padding: 8px 9px 7px;
  min-height: 104px;
  background: var(--paper);
  border: 1.5px solid var(--ink);
  border-radius: 10px;
  box-shadow: 3px 3px 0 var(--panel-shadow);
  color: var(--ink);
  cursor: pointer;
  overflow: hidden;
}

.move-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--category, var(--ink-soft));
}

.move-card--attack { --category: var(--attack); }
.move-card--defense { --category: var(--defense); }
.move-card--charge { --category: var(--charge); }

.move-card:hover:not(:disabled),
.move-card:focus-visible {
  background: #fff9e8;
}

.move-card__shape {
  width: 30px;
  height: 22px;
  display: block;
}

.move-card__shape svg {
  width: 100%;
  height: 100%;
  display: block;
}

.move-card__shape .icon-fill {
  fill: var(--category, var(--ink-soft));
  stroke: var(--ink);
  stroke-width: 8;
}

.move-card__shape .icon-notch {
  stroke: var(--paper);
  stroke-width: 9;
}

.move-card__shape .icon-inner {
  stroke: var(--paper);
  stroke-width: 9;
}

.move-card__name {
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--ink);
}

.move-card__effect {
  font-size: 0.78rem;
  color: var(--ink-soft);
  line-height: 1.25;
}

.move-card__cost {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  justify-self: start;
}

.move-card__cost svg {
  width: 13px;
  height: 13px;
}

.move-card__cost svg path {
  fill: var(--ink);
  stroke: var(--ink);
  stroke-width: 2;
}

.move-card__cost-value {
  font-size: 0.85rem;
  font-weight: 750;
  color: var(--ink);
}

.move-card__key {
  position: absolute;
  top: 7px;
  right: 7px;
  font-size: 0.68rem;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1px solid var(--icon-idle);
  color: var(--icon-idle);
  background: var(--paper);
}

/* Selected: thick border + check badge — only the viewer's own accepted pick. */
.move-card--selected {
  border: 3px solid var(--ink);
  box-shadow: 3px 3px 0 var(--panel-shadow), inset 0 0 0 1.5px var(--paper);
  background: #fff3d4;
}

.move-card__badge {
  position: absolute;
  right: 7px;
  bottom: 7px;
  width: 18px;
  height: 18px;
}

.move-card__badge svg {
  width: 100%;
  height: 100%;
  display: block;
}

.move-card__badge circle {
  fill: var(--ink);
}

.move-card__badge path {
  fill: none;
  stroke: var(--paper);
  stroke-width: 2.6;
}

/* Unavailable explains itself, not just dimmed (V02). */
.move-card__unavailable {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink-soft);
  background: repeating-linear-gradient(
    -45deg,
    rgba(133, 130, 122, 0.16) 0 7px,
    transparent 7px 14px
  );
  border-radius: 8px;
  pointer-events: none;
}

.move-card[disabled],
.move-card:disabled {
  cursor: not-allowed;
}

.move-card[disabled]:not(.move-card--selected) {
  opacity: 0.62;
}

/* ---- Result card (info) + explanation ---- */

.info-card {
  background: var(--paper-deep);
  border: 1.5px solid var(--panel-shadow);
  border-left: 4px solid var(--accent);
  border-radius: 10px;
  padding: 8px 12px;
}

.info-card__title {
  margin: 0 0 4px;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.info-card__rows {
  margin: 0;
  display: grid;
  gap: 2px;
}

.info-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
}

.info-row dt {
  color: var(--ink-soft);
  font-size: 0.8rem;
}

.info-row dd {
  margin: 0;
  font-size: 0.88rem;
  font-weight: 600;
  text-align: right;
}

.info-card__notice {
  margin: 6px 0 0;
  padding-top: 5px;
  border-top: 1px solid var(--panel-shadow);
  color: var(--accent);
  font-size: 0.85rem;
  font-weight: 700;
}

.explanation-panel {
  background: var(--paper-deep);
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 8px 12px;
}

.explanation-panel__title {
  margin: 0 0 5px;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.explanation-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 2px 0;
  border-bottom: 1px solid var(--panel-shadow);
  font-size: 0.82rem;
}

.explanation-line:last-child {
  border-bottom: none;
}

.explanation-line__kind {
  font-size: 0.66rem;
  color: var(--ink-soft);
  background: var(--paper);
  padding: 1px 5px;
  border-radius: 4px;
  flex-shrink: 0;
  min-width: fit-content;
}

.explanation-line__text {
  color: var(--ink);
}

.in-match-menu {
  display: flex;
  gap: 0.5rem;
}

/* ---- Pause overlay / end screens ---- */

.pause-overlay,
.online-menu {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  box-sizing: border-box;
  background: rgba(36, 40, 43, 0.68);
  z-index: 10;
}

.overlay-card {
  width: min(100%, 28rem);
  box-sizing: border-box;
  padding: clamp(1.5rem, 6vw, 2.5rem);
  border: 2px solid var(--ink);
  background: var(--paper);
  box-shadow: 6px 6px 0 var(--panel-shadow);
  display: grid;
  gap: 0.85rem;
  text-align: center;
  max-height: calc(100svh - 2rem);
  overflow-y: auto;
}

.overlay-card .start-button,
.overlay-card .settings-button {
  min-height: 48px;
  width: 100%;
}

.overlay-card > .start-button,
.online-wait > .start-button {
  background: var(--ink);
  color: var(--paper);
}

.pause-overlay__title {
  margin: 0;
  font-size: 1.6rem;
  color: var(--ink);
}

.pause-overlay__phase {
  margin: 0 0 1rem;
  color: var(--ink-soft);
}

.end-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  max-width: 34rem;
  margin: 2rem auto;
  text-align: center;
}

.end-screen__headline {
  margin: 0;
  font-size: 1.5rem;
  color: var(--ink);
}

.end-screen__reason {
  margin: 0;
  color: var(--ink-soft);
}

.end-screen__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: 0.5rem;
}

/* ---- Start page / settings / history / online lobby (kept pages, V02 tone) ---- */

.arena {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.arena--start {
  align-items: center;
  padding: 2rem 0;
}

.bot-choices {
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 0.8rem 1rem;
  display: grid;
  gap: 0.4rem;
  max-width: 30rem;
  width: 100%;
  background: var(--paper-deep);
}

.bot-choices__legend {
  font-size: 0.85rem;
  color: var(--ink-soft);
  padding: 0 0.25rem;
}

.bot-choice__label {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-size: 0.9rem;
}

.seed-field {
  font: inherit;
  padding: 0.5rem 0.7rem;
  border: 1.5px solid var(--ink);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  max-width: 30rem;
  width: 100%;
}

/* ---- Online private-room entry + waiting room (Issue #142) ---- */

.online-entry {
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 0.8rem 1rem;
  display: grid;
  gap: 0.5rem;
  max-width: 30rem;
  width: 100%;
  background: var(--paper-deep);
}

.online-entry__legend {
  font-size: 0.85rem;
  color: var(--ink-soft);
  padding: 0 0.25rem;
}

.online-entry__hint {
  margin: 0;
  font-size: 0.75rem;
  color: var(--ink-soft);
  word-break: break-all;
}

.online-entry__error {
  margin: 0;
  font-size: 0.85rem;
  color: #a03b2e;
}

.online-entry__code {
  font: inherit;
  padding: 0.5rem 0.7rem;
  border: 1.5px solid var(--ink);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  width: 8em;
  justify-self: center;
  text-align: center;
  text-transform: uppercase;
}

.online-entry__actions {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  flex-wrap: wrap;
}

.online-wait {
  align-items: center;
  gap: 0.75rem;
  max-width: 30rem;
}

.online-wait__title {
  margin: 0;
  font-size: 1.1rem;
}

.online-wait__code {
  margin: 0;
  font-size: 1.6rem;
  letter-spacing: 0.15em;
  font-weight: 700;
}

.online-wait__hint {
  margin: 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: center;
}

.online-wait__status {
  margin: 0;
  font-size: 0.9rem;
}

.online-wait__seats {
  margin: 0;
  font-size: 0.8rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* ---- Settings screen (Issue #142: mute / reduced motion / back only) ---- */

.settings-screen {
  gap: 1.25rem;
}

.settings-screen__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 30rem;
  width: 100%;
  background: var(--paper-deep);
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 0.8rem 1rem;
}

.settings-screen__label {
  font-size: 0.95rem;
}

/* ---- Global entry, preferences, and menus (Issue #151) ---- */

body {
  background-color: var(--paper);
}

body:has(.home-page, .screen-page) {
  background: linear-gradient(#f3e9d233, #f3e9d233), url("assets/p0-runtime-ui/background_arena.png") center / cover fixed no-repeat;
  background-color: var(--paper);
}

.home-page,
.screen-page {
  min-height: calc(100svh - 2rem);
  justify-content: center;
  align-items: center;
  padding: clamp(1rem, 4vh, 3rem) 0;
}

.home-panel,
.settings-panel,
.online-wait {
  width: min(100%, 34rem);
  box-sizing: border-box;
  padding: clamp(1.25rem, 4vw, 2.5rem);
  border: 2px solid var(--ink);
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  box-shadow: 5px 5px 0 var(--panel-shadow);
  display: grid;
  gap: 0.9rem;
}

.home-title,
.settings-panel__title {
  margin: 0;
  text-align: center;
  font-size: clamp(1.8rem, 7vw, 3.7rem);
  letter-spacing: 0.05em;
}

.home-title {
  display: grid;
  justify-items: start;
  padding: 1rem 0 2rem;
}

.home-title__zh { font-size: 6.5rem; font-weight: 900; line-height: 1.1; }
.home-title__en { font-size: clamp(1rem, 5vw, 1.8rem); letter-spacing: 0; }
.home-panel__tagline { font-size: 1.2rem; font-weight: 700; }
.home-panel__description { margin: 0 0 1rem; text-align: center; font-size: 0.85rem; }
.home-panel__description > span { display: block; }
.home-page [hidden] { display: none !important; }
.bot-setup { width: min(100%, 34rem); }
.bot-setup .bot-choices { box-sizing: border-box; border-radius: 0; }
.bot-choice__label { min-height: 48px; }

.home-panel__tagline,
.settings-panel__lead,
.home-panel__notice {
  margin: 0;
  text-align: center;
  color: var(--ink-soft);
}

.home-entry {
  border: 0;
}

.home-entry__summary,
.home-panel > .settings-button,
.home-panel > .start-button {
  min-height: 48px;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: 100%;
  padding: 0.75rem 1rem;
  border: 2px solid var(--ink);
  cursor: pointer;
  text-align: center;
  font-weight: 700;
}

.home-entry__summary {
  list-style: none;
  background: var(--paper);
}

.home-entry__summary::-webkit-details-marker {
  display: none;
}

.home-entry--bot > summary {
  border: 0;
  min-height: 44px;
  padding: 0.25rem;
  font-size: 0.8rem;
  font-weight: 400;
  text-decoration: underline;
  background: transparent;
}

.menu-preferences > summary {
  cursor: pointer;
  padding: 0.75rem;
  min-height: 48px;
  box-sizing: border-box;
  border: 2px solid var(--ink);
}

.menu-preferences .settings-screen__row {
  box-sizing: border-box;
  margin: 0.6rem 0;
  flex-wrap: wrap;
}

.home-panel button,
.settings-panel button,
.online-wait button,
.overlay-card button {
  border-radius: 0;
  min-height: 48px;
}

.settings-panel .settings-screen__row {
  border-radius: 0;
  flex-wrap: wrap;
}

.settings-panel [data-setting="result-text"],
.menu-preferences [data-setting="result-text"] {
  font: inherit;
  padding: 0.65rem;
  background: var(--paper-deep);
  color: var(--ink);
  border: 1.5px solid var(--ink);
}

.online-wait {
  text-align: center;
}

.online-wait__code {
  overflow-wrap: anywhere;
}

.home-entry[open] > .home-entry__summary {
  border-bottom-width: 1px;
}

.home-entry .bot-choices,
.home-entry .online-entry {
  width: 100%;
  max-width: none;
  box-sizing: border-box;
  border: 2px solid var(--ink);
  border-top: 0;
  border-radius: 0;
  background: var(--paper-deep);
}

.home-panel > .start-button {
  background: var(--ink);
  color: var(--paper);
}

.home-panel > .settings-button {
  background: var(--paper);
  color: var(--ink);
}

.home-page .debug-tools {
  background: var(--paper);
  padding: 0.5rem;
  box-sizing: border-box;
}

.settings-panel {
  width: min(100%, 32rem);
}

.settings-panel__lead {
  font-size: 0.9rem;
}

.settings-panel .settings-screen__row,
.settings-panel .result-text-toggle,
.settings-panel > .settings-button {
  max-width: none;
  width: 100%;
  box-sizing: border-box;
}

@media (min-width: 900px) {
  .home-panel {
    width: min(82vw, 72rem);
    padding: clamp(2rem, 5vw, 4.5rem);
  }
}

@media (max-height: 500px) and (orientation: landscape) {
  .online-wait {
    width: min(92vw, 46rem);
    padding: 0.75rem 1rem;
    gap: 0.4rem;
  }

  .online-wait__code { font-size: 1.2rem; letter-spacing: 0.05em; }

  .settings-panel {
    width: min(92vw, 46rem);
    padding: 0.75rem 1rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
  }
  .settings-panel__title, .settings-panel__lead { grid-column: 1 / -1; }
  .settings-panel__title { font-size: 1.5rem; }
  .settings-panel .settings-screen__row { padding: 0.5rem; gap: 0.5rem; }
  .home-page,
  .screen-page {
    min-height: 0;
    justify-content: start;
    padding: 0.5rem 0;
  }

  .home-panel {
    width: min(92vw, 46rem);
    padding: 0.75rem 1rem;
    gap: 0.4rem;
  }

  .home-title {
    font-size: 1.5rem;
    padding: 0;
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
  }

  .home-title__zh { font-size: 1.8rem; }
  .home-title__en { font-size: 1rem; }
  .home-panel__description { margin: 0; font-size: 0.7rem; }

  .home-panel__tagline,
  .home-panel__notice {
    font-size: 0.72rem;
  }

  .home-entry__summary,
  .home-panel > .settings-button,
  .home-panel > .start-button {
    min-height: 48px;
    padding: 0.35rem 0.75rem;
  }
}

/* ---- Debug tools section (Issue #142: explicit debug mode) ---- */

/* Approved start composition: 80px wordmark × 1.3 mobile / × 2 desktop. */
.home-panel {
  width: min(84vw, 75.6rem);
  min-height: 82svh;
  padding: 2.5rem 0.4rem 5rem;
  gap: 0.6rem;
  background: var(--paper);
  align-content: start;
}
.home-title { margin: 0 auto 4.5rem; padding: 0; width: max-content; }
.home-title__en { font-size: 1.70625rem; font-weight: 800; }
.home-panel__tagline { font-size: 1.5rem; font-weight: 850; color: var(--ink); }
.home-panel__description { font-size: 0.875rem; line-height: 1.875rem; margin: 0.3rem 0 1.6rem; }
.home-panel > .settings-button { margin: 0; }
.home-panel > .start-button, .home-panel > .settings-button, .home-entry__summary { font-size: 1rem; }
@media (min-width: 900px) {
  .home-title__zh { font-size: 10rem; }
  .home-title__en { font-size: 2.625rem; }
  .home-title { margin-bottom: 2rem; }
  .home-panel > .start-button, .home-panel > .settings-button, .home-entry--online {
    width: min(100%, 30rem); justify-self: center;
  }
}
@media (max-height: 500px) and (orientation: landscape) {
  .home-panel { min-height: 0; padding: 0.75rem 1rem; width: min(92vw, 46rem); gap: 0.4rem; }
  .home-title { margin: 0; width: auto; }
  .home-title__zh { font-size: 1.8rem; }
  .home-title__en { font-size: 1rem; }
  .home-panel__tagline { font-size: 1rem; }
  .home-panel__description { font-size: 0.75rem; line-height: 1.2; margin: 0; }
}

.debug-tools {
  display: grid;
  gap: 0.75rem;
  max-width: 30rem;
  width: 100%;
  justify-items: center;
}

.debug-tools__toggle {
  font: inherit;
  font-size: 0.8rem;
  color: var(--ink-soft);
  background: transparent;
  border: 1.5px dashed var(--icon-idle);
  border-radius: 8px;
  padding: 0.4rem 0.8rem;
  cursor: pointer;
}

.debug-tools__toggle[aria-pressed="true"] {
  color: var(--ink);
  border-style: solid;
}

.debug-tools__panel {
  display: grid;
  gap: 0.75rem;
  width: 100%;
  justify-items: center;
}

/* The hidden attribute must win over the grid display above. */
.debug-tools__panel[hidden] {
  display: none;
}

.debug-tools__note {
  margin: 0;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.playtest-panel {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem;
  border: 1.5px dashed var(--icon-idle);
  border-radius: 0.6rem;
  max-width: 30rem;
  width: 100%;
  background: var(--paper-deep);
}

.playtest-panel__legend {
  font-size: 0.85rem;
  color: var(--ink-soft);
  padding: 0 0.25rem;
}

.playtest-panel__report {
  resize: vertical;
  font-family: monospace;
  font-size: 0.8rem;
  min-width: 0;
}

.playtest-panel__select {
  max-width: 100%;
}

.playtest-panel__status {
  margin: 0;
  font-size: 0.8rem;
  word-break: break-all;
}

.playtest-panel__status--loaded { color: var(--accent); }
.playtest-panel__status--idle { color: var(--ink-soft); }
.playtest-panel__status--error { color: #a03b2e; }

.playtest-panel__file-label {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.playtest-panel__file {
  font-size: 0.8rem;
  max-width: 100%;
}

/* ---- Keybind settings panel ---- */

.settings-panel-root {
  margin-top: 1rem;
}

.keybind-settings {
  background: var(--paper-deep);
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 1rem;
  max-width: 28rem;
}

.keybind-settings__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.keybind-settings__title {
  margin: 0;
  font-size: 1rem;
  color: var(--ink);
}

.keybind-settings__restore {
  padding: 0.35rem 0.75rem;
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 6px;
  font-size: 0.8rem;
  cursor: pointer;
}

.keybind-settings__restore:hover {
  background: var(--paper);
}

.keybind-settings__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.keybind-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0.5rem;
  border-left: 3px solid var(--muted);
  background: var(--paper);
}

.keybind-row--attack { border-left-color: var(--attack); }
.keybind-row--defense { border-left-color: var(--defense); }
.keybind-row--charge { border-left-color: var(--charge); }

.keybind-row__label {
  color: var(--ink);
  font-size: 0.9rem;
}

.keybind-row__key {
  min-width: 4.5rem;
  padding: 0.35rem 0.6rem;
  background: var(--paper-deep);
  color: var(--ink);
  border: 1.5px solid var(--icon-idle);
  border-radius: 6px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9rem;
  cursor: pointer;
  text-align: center;
}

.keybind-row__key--awaiting {
  border-color: var(--charge);
  color: var(--fixture);
}

/* ---- Match history ---- */

.history-storage-warning {
  margin: 0.5rem 0;
  padding: 0.5rem 0.8rem;
  border: 1.5px solid #a03b2e;
  border-radius: 8px;
  color: #a03b2e;
}

.history-empty {
  color: var(--ink-soft);
}

.history-list {
  list-style: none;
  margin: 0.5rem 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.history-entry {
  background: var(--paper-deep);
  border: 1.5px solid var(--panel-shadow);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
}

.history-entry__top {
  display: flex;
  justify-content: space-between;
  gap: 0.6rem;
  align-items: baseline;
}

.history-entry__label {
  font-size: 0.95rem;
}

.history-entry__status {
  font-size: 0.7rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--icon-idle);
  color: var(--ink-soft);
}

.history-entry__status--completed { color: var(--defense); border-color: var(--defense); }
.history-entry__status--aborted { color: #a03b2e; border-color: #a03b2e; }

.history-entry__score,
.history-entry__time {
  margin: 0.25rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.history-entry__error {
  margin: 0.25rem 0 0;
  font-size: 0.8rem;
  color: #a03b2e;
}

.history-entry__actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.history-entry__export,
.history-entry__clear,
.history-clear-all {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  border: 1.5px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}

/* ---- Reduced motion: no scale/diffusion/pulse, instant state swaps ---- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

body.reduced-motion *,
body.reduced-motion *::before,
body.reduced-motion *::after {
  animation: none !important;
  transition: none !important;
}

/* #145: approved static composition. Details overlay only on explicit demand. */
body { font-family: "PingFang SC", "Noto Sans CJK SC", system-ui, sans-serif; }
.battle-header { position: relative; display: flex; align-items: center; gap: 4px; }
.rule-details { margin-right: auto; min-width: 0; }
.rule-details__summary { cursor: pointer; list-style: none; min-height: 48px; }
.rule-details__summary::-webkit-details-marker { display: none; }
.rule-identity { display: block; font-size: .625rem; overflow-wrap: anywhere; }
.rule-details__panel, .battle-details__panel {
  position: absolute; z-index: 5; left: 0; right: 0; padding: 12px;
  background: var(--paper); border: 2px solid var(--ink); box-shadow: 3px 3px var(--panel-shadow);
  max-height: 65dvh; overflow: auto;
}
.battle-header .shell-title { margin: 0; }
.battle-header .shell-header__controls { margin: 0; }
.battle-header .mute-button:not(.motion-button), .battle-header .in-match-menu button {
  min-width: 48px; min-height: 48px; margin: 0; padding: 4px;
  border: 0; background: transparent; border-radius: 0; font-size: 0;
}
.battle-header .mute-button svg, .battle-header .in-match-menu button svg { width: 23px; height: 23px; display: block; margin: auto; }
.rule-details .motion-button { min-height: 48px; }
.shell-body { position: relative; }
.battle-details { position: absolute; top: 106px; left: 0; z-index: 2; }
.battle-details > summary { cursor: pointer; min-height: 48px; padding: 12px; font-size: .75rem; }
.battle-details[open] { right: 0; }
.battle-details__panel { min-width: min(328px, 85vw); }
.duelist { border-radius: 0; }
.duelist__heading { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.duelist--self .duelist__heading { flex-direction: row-reverse; }
.duelist__label { margin: 0; }
.duelist__heading .pips { gap: 5px; }
.duelist__heading .pip { width: 16px; height: 16px; }
.stage__sprite-box:has(.stage__sprite.is-loaded:not(.is-error)) .stage__sprite-fallback { display: none; }
.progress { position: relative; width: 190px; height: 22px; margin: 13.5px auto 0; padding: 0; }
.progress__track { position: absolute; left: 0; top: 9.5px; }
.progress__icons { position: absolute; left: -11px; right: -11px; inset-block: 0; justify-content: space-between; gap: 0; }
.stage__banner { border-radius: 0; }
.stage__banner-deltas { white-space: normal; overflow: visible; }
.move-card, .move-card__unavailable { border-radius: 0; }
.move-card { border-width: 1px; padding: 10px; box-shadow: 2px 3px 0 var(--panel-shadow); }
.move-card--selected { border-width: 3px; padding: 8px; }
.move-card__unavailable { position: static; font-size: .7rem; min-height: 18px; }
.moves__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.duelist { min-height: 91px; padding: 14px 12px 7px; }
.duelist__label { font-size: .75rem; line-height: 19px; }
.duelist__stats { gap: 5px; margin-top: 5px; }
.pips { gap: 3px; min-height: 19px; }
.pip--health { width: 22px; height: 22px; }
.pip--energy { width: 19px; height: 19px; }
.pips--energy { gap: 5px; }
.duelist--id-alpha::before { top: 5px; height: 6px; background-size: 100% 2px; background-position: 0 0, 0 4px; }
.duelist--id-beta::before { top: 5px; height: 2px; }
.move-card { min-height: 114px; grid-template-columns: 20px minmax(0, 1fr); grid-template-rows: auto minmax(2.25rem, 1fr) auto; column-gap: 4px; row-gap: 8px; padding: 10px 8px; overflow: visible; }
.move-card__shape { width: 22px; height: 20px; align-self: center; grid-row: 1; }
.move-card__name { font-size: .875rem; align-self: center; grid-row: 1; overflow-wrap: anywhere; }
.move-card__effect { grid-column: 1 / -1; grid-row: 2; font-size: .75rem; line-height: 1.5; font-weight: 650; color: var(--ink); }
.move-card__cost { grid-column: 1 / -1; grid-row: 3; }
.move-card__key { position: static; grid-column: 2; grid-row: 3; justify-self: end; border: 0; padding: 0; font-size: .6rem; }
.move-card__badge { right: 6px; bottom: 6px; }
.move-card--selected .move-card__key { visibility: hidden; }
.move-card__unavailable { position: absolute; inset: auto 4px 4px auto; padding: 2px; font-size: .625rem; }
.move-card--selected { padding: 8px 6px; }
@media (max-width: 599px) {
  #app:has(.battle-header) { padding: env(safe-area-inset-top, 0px) max(16px, env(safe-area-inset-right, 0px)) max(16px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px)); }
  .battle-header { min-height: 59px; margin: 0; }
  .battle-header .wordmark { gap: 7px; }
  .battle-header .wordmark__zh { font-size: 1.8125rem; }
  .battle-header .wordmark__en { font-size: .625rem; letter-spacing: 0; }
  .shell-body { column-gap: 12px; row-gap: 11px; grid-template-areas: "hudself hudopp" "stage stage" "moves moves"; }
  .stage { margin-inline: -16px; }
  .stage__scene { border: 0; border-radius: 0; height: max(240px, calc(100dvh - 484px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px))); --char-h: clamp(120px, 57cqh, 215px); }
  .stage__seat { top: 84%; left: 25%; }
  .stage__seat--right { left: 75%; }
  .stage__trim { width: 90px; left: -45px; top: 14px; }
  .stage__banner { top: 48px; width: calc(100% - 32px); max-width: none; }
  .moves { margin-top: 8.5px; }
  .moves__grid { gap: 8px; }
}

.selection-status { position: absolute; top: 106px; right: 0; max-width: 70%; padding: 12px 4px; margin: 0; font-size: .75rem; text-align: right; pointer-events: none; }
.move-card--pending { outline: 2px dashed var(--ink); outline-offset: -5px; }
.stage__placeholder-note { margin: 4px 0 0; font-size: .625rem; }
.stage__fx { width: 32px; height: 32px; left: -16px; top: calc(var(--char-h) * -1.15); }

/* Muted/disabled inputs remain readable; legality also has explicit text. */
.moves__grid--idle, .move-card[disabled]:not(.move-card--selected) { opacity: 1; }
.moves__grid--idle .move-card { background-color: var(--paper-deep); }
/* Disabled is visible without reducing text contrast or hiding accepted/pending marks. */
.move-card:disabled { filter: grayscale(1); background-color: #ddd9d0; }
body.reduced-motion .stage__fx, body.reduced-motion .stage__flash { display: none; }
@media (prefers-reduced-motion: reduce) {
  .stage__fx, .stage__flash { display: none; }
}

.pip--wins svg circle { fill: none; stroke: var(--paper); stroke-width: 1.6; }
.pip--wins svg .icon-check { stroke: #969184; stroke-width: 2; }
.pip--wins.pip--owned svg .icon-check { stroke: var(--paper); }

/* #145 neutral frames keep their shared floor anchors through settlement.
   Legacy placeholder mappings retain their own motion for replacement tests. */
.stage__seat.stage__seat--static-pose .stage__sprite-box { animation: none; }

/* #146: V02 wide battle geometry. Intrinsic rows may grow for enlarged text. */
@media (min-width: 600px) {
  .battle-header { min-height: 48px; margin: 0; }
  .battle-header .wordmark__zh { font-size: 1.25rem; }
  .battle-header .rule-details__summary { position: relative; padding-right: 110px; }
  .battle-header .rule-identity { position: absolute; left: 150px; top: 12px; min-width: 100px; }
}

@media (min-width: 600px) and (max-height: 499px) {
  #app:has(.battle-header) {
    max-width: none;
    padding: env(safe-area-inset-top, 0px) max(16px, env(safe-area-inset-right, 0px)) max(9px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px));
  }
  .shell-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(240px, calc(100% * 264 / 812));
    grid-template-areas: "hudself hudopp moves" "stage stage moves";
    column-gap: 12px; row-gap: 11px;
    grid-template-rows: minmax(91px, max-content) 1fr;
  }
  .moves__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas: "a0 a1" "d0 d1" "c0 c1";
    column-gap: 8px; row-gap: 6px;
  }
  .move-card { min-height: max(106px, calc((100dvh - 72px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)) / 3)); row-gap: 4px; }
  .stage__scene {
    height: max(140px, calc(100dvh - 202px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)));
    border: 0; border-radius: 0; --char-h: clamp(80px, 64cqh, 170px);
  }
  .stage__seat { left: 29%; top: 92%; }
  .stage__trim { top: 2px; height: 12px; }
  .stage__seat--right { left: 71%; }
  .progress { margin-top: 11.5px; }
  .battle-details { top: -48px; left: 240px; }
  .battle-details > summary { padding: 12px; }
  .selection-status { top: -48px; right: 100px; max-width: 40%; }
  .stage__banner { top: 0; width: 100%; max-width: none; padding: 3px 8px; display: grid; grid-template-columns: auto auto; justify-content: center; column-gap: 12px; }
  .stage__placeholder-note { grid-column: 1 / -1; margin-top: 2px; }
  .stage__banner-moves { font-size: .875rem; }
  .stage__banner-deltas { font-size: .75rem; }
}

@media (min-width: 600px) and (min-height: 500px) {
  #app { padding: 16px 32px 24px; }
  .info-card, .explanation-panel { max-width: 60rem; width: 100%; margin: 0 auto; }
  #app:has(.battle-header) {
    max-width: none;
    padding: env(safe-area-inset-top, 0px) max(48px, env(safe-area-inset-right, 0px)) max(32px, env(safe-area-inset-bottom, 0px)) max(48px, env(safe-area-inset-left, 0px));
  }
  .shell-body {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas: "hudself hudopp" "stage stage" "moves moves";
    column-gap: 12px; row-gap: 11px;
  }
  .stage__scene {
    height: max(220px, calc(100dvh - 364px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)));
    border: 0; border-radius: 0; --char-h: clamp(140px, 68cqh, 365px);
  }
  .stage__seat { left: 29%; top: 96%; }
  .stage__trim { top: 6px; height: 12px; }
  .stage__seat--right { left: 71%; }
  .progress { margin-top: 11.5px; }
  .moves { margin-top: 23.5px; }
  .moves__grid { grid-template-columns: repeat(6, minmax(0, 1fr)); grid-template-areas: "a0 a1 d0 d1 c0 c1"; }
  .stage__banner { top: 48px; min-width: 360px; }
  .battle-details > summary { background: var(--paper); }
}

/* Approved PNG frames contain the motion; never layer placeholder transforms/flash. */
.stage__seat--sequenced .stage__fx, .stage__seat--sequenced .stage__flash { display: none; }

.stage__animation-fx { position: absolute; pointer-events: none; }
.stage__animation-fx[hidden] { display: none; }
.stage__banner { z-index: 1; }

/* #148: the taller approved defense/hurt silhouettes must clear the result
   banner. Share a compact two-column result row, without moving actors/HUD. */
@media (max-width: 599px) {
  .stage__banner { top: 46px; display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px 8px; padding: 3px 8px; line-height: 1.2; }
  .stage__banner-moves { font-size: .875rem; }
  .stage__banner-deltas { font-size: .6875rem; margin: 0; align-self: center; }
  .stage__placeholder-note { grid-column: 1 / -1; margin: 0; }
}

/* The approved advanced guard stays above impact, below result explanations. */
.stage__animation-fx { z-index: 0; }
.stage__animation-fx[data-effect="advanced-block-plane"] { z-index: 1; }
.stage__banner { z-index: 2; }

/* #149 visual revision: a bounded duel inside the full-width arena. The
   390 reference has anchors about .75 sprite widths apart; this ratio also
   bounds every contact effect, whose height follows the same sprite scale. */
.stage__seat { left: calc(50% - var(--sprite) * .375); }
.stage__seat--right { left: calc(50% + var(--sprite) * .375); }

/* A reserved HUD-adjacent report strip never covers the scene or moves when
   the preference changes. Full explanations remain in battle details. */
.stage { --report-space: 48px; }
.stage__report { height: var(--report-space); display: flex; align-items: center; justify-content: center; }
.stage__report .stage__banner {
 position: static; transform: none; min-width: 0; max-width: 100%; width: 100%;
 background: none; color: var(--ink); padding: 2px 4px; margin: 0;
 display: grid; grid-template-columns: max-content minmax(0,1fr); gap: 2px 8px;
 line-height: 1.2; box-sizing: border-box;
}
.stage__report .stage__banner-moves { font-size: .875rem; }
.stage__report .stage__banner-deltas { font-size: .6875rem; margin: 0; align-self: center; }
.stage__report .stage__placeholder-note { grid-column: 1/-1; margin: 0; }
.hide-result-text .stage__report .stage__banner {
 position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
 clip-path: inset(50%); white-space: nowrap;
}
.pip { position: relative; }
.pip__fragment { position: absolute; inset: 0; opacity: var(--resource-fade,0); pointer-events: none; transform: translateY(var(--resource-drop,0px)); }
.pip__fragment svg path { fill: var(--paper); stroke: var(--paper); }
.pip__fragment--left { clip-path: polygon(0 0,58% 0,42% 35%,57% 52%,43% 72%,50% 100%,0 100%); transform: translate(calc(-1 * var(--resource-split,0px)),var(--resource-drop,0px)); }
.pip__fragment--right { clip-path: polygon(58% 0,100% 0,100% 100%,50% 100%,43% 72%,57% 52%,42% 35%); transform: translate(var(--resource-split,0px),var(--resource-drop,0px)); }
.pip--gained > svg { transform: scale(var(--resource-pulse,1)); }
/* Keep the explicit details control out of the report's text area. */
@media (max-width:599px) {
 .battle-details { top: -59px; left: 144px; }
 .battle-details[open] { left: 16px; right: 16px; }
 .battle-details[open] > summary { margin-left: 128px; }
}
@media (min-width:600px) and (min-height:500px) {
 .battle-details { top: -48px; left: 240px; }
}
@media (min-width:600px) and (max-height:499px) {
 .stage__trim { top: -6px; }
}
/* Decorative heart fragments remain inside their resource slot, including
   when transparent at the end of the phase or under reduced motion. */
.pip--lost { overflow: hidden; }
/* Reserve explanation space without shrinking the approved character scale. */
@media (max-width:599px) {
 .stage__scene { height: max(calc(240px - var(--report-space)), calc(100dvh - 484px - var(--report-space) - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px))); --char-h: clamp(120px, calc(57cqh + var(--report-space) * .57), 215px); }
}
@media (min-width:600px) {
 .stage { --report-space: 36px; }
 .stage__report .stage__banner { max-width: 640px; }
}
@media (min-width:600px) and (max-height:499px) {
 .stage__scene { height: max(calc(140px - var(--report-space)), calc(100dvh - 202px - var(--report-space) - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px))); --char-h: clamp(80px, calc(64cqh + var(--report-space) * .64),170px); }
}
@media (min-width:600px) and (min-height:500px) {
 .stage__scene { height: max(calc(220px - var(--report-space)), calc(100dvh - 364px - var(--report-space) - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px))); --char-h: clamp(140px, calc(68cqh + var(--report-space) * .68),365px); }
}

/* #150: approved neutral absence and static danger; no fourth category/cue. */
.stage__no-action {
  position: absolute; bottom: 5%; left: 50%; transform: translateX(-50%);
  padding: 2px 9px; border: 1px solid var(--ink); background: var(--paper);
  color: var(--ink); font-size: 12px; white-space: nowrap; z-index: 4;
}
.duelist--low-health { outline: 2px solid #C85D3A; outline-offset: -2px; }
.duelist__danger { position: absolute; bottom: 3px; left: 0; width: 100%; text-align: center; font-size: 10px; color: #F3E9D2; }
.duelist--low-health .duelist__stats { padding-bottom: 10px; }

/* Approved outcome panel geometry (p0-outcomes V03), dynamic public content. */
.outcome-panel { box-sizing: border-box; width: min(316px, calc(100% - 32px)); padding: 14px 12px;
  background: #F3E9D2; color: #24282B; border: 2px solid #24282B; box-shadow: 3px 4px #85827A;
  text-align: center; opacity: 1; }
.outcome-panel p { margin: 8px 0; }
.outcome-panel__label { font-size: 13px; }
.outcome-panel__title { margin: 8px 0; font-size: 25px; line-height: 1.2; }
.outcome-panel__score { font-size: 18px; font-weight: 600; }
.outcome-panel__reason, .outcome-panel__detail { font-size: 12px; }
.outcome-panel--match { width: min(344px, 100%); border: 4px double #24282B; outline: 1px solid #24282B; outline-offset: -10px; padding: 18px; }
.outcome-panel--match .outcome-panel__title { font-size: 29px; }
.stage--round-end .outcome-panel { position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 6; }
.round-continuation { grid-area: moves; text-align: center; padding: 16px 8px; font-weight: 600; }
.round-continuation p { font-size: 12px; font-weight: 400; }
.shell-body--terminal { grid-template-areas: "hudself hudopp" "result result"; grid-template-rows: auto auto; }
.shell-body--terminal .end-screen { grid-area: result; width: 100%; margin: 16px auto; gap: 12px; }
.outcome-details { width: 100%; }
.outcome-details summary { cursor: pointer; padding: 8px; }
.outcome-details .explanation-panel { text-align: left; }
.outcome-panel--entering { animation: outcome-entry 320ms cubic-bezier(.25,.46,.45,.94) var(--outcome-entry-delay, 0ms) both; }
@keyframes outcome-entry { from { transform: translateY(8px); opacity: .65; } to { transform: translateY(0); opacity: 1; } }
body.reduced-motion .outcome-panel { animation: none; transform: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .outcome-panel { animation: none; transform: none; opacity: 1; } }
@media (min-width: 600px) and (max-height: 499px) {
  .stage--round-end .outcome-panel { padding: 4px 10px; }
  .stage--round-end .outcome-panel p { margin: 3px 0; }
  .stage--round-end .outcome-panel__title { margin: 3px 0; font-size: 22px; }
  .shell-body--terminal { grid-template-areas: "hudself hudopp result"; grid-template-rows: auto; align-items: start; }
  .shell-body--terminal .end-screen { margin: 0 auto; gap: 3px; }
  .shell-body--terminal .outcome-panel { padding: 10px; }
  .shell-body--terminal .outcome-panel p { margin: 5px 0; }
  .shell-body--terminal .end-screen__actions { gap: 4px; margin: 0; }
  .shell-body--terminal .end-screen__actions button { padding: 6px 10px; }
  .shell-body--terminal .outcome-details summary { padding: 4px; }
}
.shell-body--terminal:has(.postmatch-bar) { grid-template-areas: "hudself hudopp" "result result" "rematch rematch"; }
.shell-body--terminal .postmatch-bar { grid-area: rematch; margin: 0; width: 100%; min-width: 0; box-sizing: border-box; }
@media (min-width: 600px) and (max-height: 499px) {
  .shell-body--terminal:has(.postmatch-bar) { grid-template-areas: "hudself hudopp result" "rematch rematch result"; grid-template-rows: auto 1fr; }
  .shell-body--terminal .postmatch-bar { padding: 12px; }
}
