/*
 * Dice presentation layer.
 * The game result stays server-authoritative; SVG geometry plus transform-only
 * CSS animation keeps the normal dice readable and inexpensive on mobile.
 */
.dice-geometry {
  --dice-accent: #60a5fa;
  --dice-edge: #f2d28b;
  --dice-face-a: #283c5f;
  --dice-face-b: #172640;
  --dice-face-c: #0d182c;
  --dice-face-d: #3f5f8e;
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  perspective: 560px;
  transform-style: preserve-3d;
  contain: layout paint;
}

.dice-geometry::before {
  content: '';
  position: absolute;
  width: 78%;
  height: 42%;
  left: 11%;
  bottom: 6%;
  border-radius: 50%;
  background: radial-gradient(ellipse, color-mix(in srgb, var(--dice-accent) 32%, transparent), transparent 70%);
  filter: blur(6px);
  opacity: .3;
  transform: translateZ(-12px) scaleX(1.1);
  pointer-events: none;
}

.dice-geometry.dice-shape-d2 {
  --dice-face-a: #b48b3c;
  --dice-face-b: #72551f;
  --dice-face-c: #3d2b13;
  --dice-face-d: #e5c16e;
  --dice-edge: #ffe5a2;
}

.dice-geometry.dice-shape-d3 {
  --dice-face-a: #8c334f;
  --dice-face-b: #551f3a;
  --dice-face-c: #321629;
  --dice-face-d: #c35d74;
}

.dice-geometry.dice-shape-d4 {
  --dice-face-a: #7f2632;
  --dice-face-b: #4d1727;
  --dice-face-c: #a33b3b;
  --dice-face-d: #d26d52;
}

.dice-geometry.dice-shape-d5 {
  --dice-face-a: #365c89;
  --dice-face-b: #203c66;
  --dice-face-c: #132846;
  --dice-face-d: #6f9fc7;
}

.dice-geometry.dice-shape-d6 {
  --dice-face-a: #31547f;
  --dice-face-b: #1c3559;
  --dice-face-c: #10233f;
  --dice-face-d: #4e79ac;
}

.dice-geometry.dice-shape-d7 {
  --dice-face-a: #6b3d91;
  --dice-face-b: #452565;
  --dice-face-c: #291842;
  --dice-face-d: #b06bca;
}

.dice-geometry.dice-shape-d8 {
  --dice-face-a: #14614f;
  --dice-face-b: #0d403d;
  --dice-face-c: #082b31;
  --dice-face-d: #2a9a73;
}

.dice-geometry.dice-shape-d10 {
  --dice-face-a: #a66a1b;
  --dice-face-b: #714413;
  --dice-face-c: #432a12;
  --dice-face-d: #e2a947;
}

.dice-geometry.dice-shape-d12 {
  --dice-face-a: #69408d;
  --dice-face-b: #40265f;
  --dice-face-c: #25183f;
  --dice-face-d: #a365c6;
}

.dice-geometry.dice-shape-d20 {
  --dice-face-a: #cdbd91;
  --dice-face-b: #8e805f;
  --dice-face-c: #4d493a;
  --dice-face-d: #efe1b2;
  --dice-edge: #f6dda1;
}

.dice-sculpt {
  position: relative;
  display: grid;
  place-items: center;
  width: 92%;
  height: 92%;
  transform-style: preserve-3d;
  transform: rotateX(16deg) rotateY(-22deg) rotateZ(-3deg);
  filter: drop-shadow(0 11px 8px rgba(0,0,0,.48));
  transition: transform .42s cubic-bezier(.18,.9,.28,1.16), filter .42s ease;
}

.dice-shape-d2 .dice-sculpt { transform: rotateX(10deg) rotateY(-19deg) rotateZ(-8deg); }
.dice-shape-d3 .dice-sculpt { transform: rotateX(18deg) rotateY(-28deg) rotateZ(-3deg); }
.dice-shape-d5 .dice-sculpt,
.dice-shape-d7 .dice-sculpt { transform: rotateX(12deg) rotateY(-18deg) rotateZ(-4deg); }

.dice-geometry.is-rolling .dice-sculpt {
  animation: diceShapeRoll .76s cubic-bezier(.34,.04,.52,.96) infinite;
  filter: drop-shadow(0 15px 11px rgba(0,0,0,.54)) saturate(1.16) brightness(1.08);
}

.dice-geometry.is-settled .dice-sculpt {
  animation: diceShapeSettle .48s cubic-bezier(.18,.9,.28,1.24);
  filter: drop-shadow(0 12px 9px rgba(0,0,0,.5)) drop-shadow(0 0 9px rgba(255,214,107,.2));
}

.dice-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.dice-svg .face {
  stroke: var(--dice-edge);
  stroke-width: 1.35;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.dice-svg .face-a { fill: var(--dice-face-a); }
.dice-svg .face-b { fill: var(--dice-face-b); }
.dice-svg .face-c { fill: var(--dice-face-c); }
.dice-svg .face-d { fill: var(--dice-face-d); }
.dice-svg .face-number {
  fill: #fff1bd;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 18px;
  font-weight: 900;
  text-anchor: middle;
  dominant-baseline: middle;
  paint-order: stroke;
  stroke: rgba(44,20,7,.78);
  stroke-width: .8px;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.42));
}
.dice-shape-d3 .dice-side-label { right: 5%; bottom: 5%; }
.dice-svg .edge-highlight { fill: none; stroke: rgba(255,244,203,.62); stroke-width: 1.1; stroke-linecap: round; }
.dice-svg .edge-shadow { fill: none; stroke: rgba(6,10,18,.42); stroke-width: 2.1; stroke-linecap: round; }

.dice-result-glyph {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 35%;
  max-width: 75%;
  min-height: 31%;
  padding: 4px 9px 5px;
  border: 1px solid rgba(255,238,180,.78);
  border-radius: 9px;
  box-sizing: border-box;
  color: #fff1bd;
  background: linear-gradient(155deg, rgba(54,41,23,.82), rgba(10,14,21,.62));
  box-shadow: inset 0 1px 5px rgba(255,255,255,.16), 0 2px 5px rgba(0,0,0,.42), 0 0 9px rgba(255,211,100,.2);
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(19px, 4.4vw, 42px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 rgba(34,20,7,.9), 0 0 10px rgba(255,210,106,.72);
  transform: translateZ(18px) rotateZ(1deg);
  pointer-events: none;
}

.dice-shape-d4 .dice-result-glyph {
  top: 0%;
  left: 50%;
  transform: translate(-50%, -4%) translateZ(18px);
}
.dice-shape-d8 .dice-result-glyph { transform: translateY(1%) translateZ(18px); }
.dice-shape-d10 .dice-result-glyph { transform: translateY(2%) translateZ(18px) rotateZ(0); }
.dice-shape-d12 .dice-result-glyph { transform: translateY(1%) translateZ(18px); }
.dice-shape-d20 .dice-result-glyph { color: #fff7dc; background: linear-gradient(155deg, rgba(47,41,27,.84), rgba(16,18,17,.72)); }

.dice-side-label {
  position: absolute;
  z-index: 3;
  right: 7%;
  bottom: 7%;
  padding: 2px 5px;
  border: 1px solid rgba(255,239,190,.38);
  border-radius: 999px;
  color: rgba(255,245,208,.72);
  background: rgba(5,10,17,.48);
  font: 800 9px/1 Arial, sans-serif;
  letter-spacing: .4px;
  text-shadow: 0 1px 2px #000;
  transform: translateZ(16px);
  pointer-events: none;
}

.dice-geometry.is-rolling .dice-result-glyph {
  color: #e2e8f0;
  border-color: rgba(226,232,240,.46);
  background: rgba(6,12,23,.58);
  text-shadow: 0 0 10px rgba(255,255,255,.46);
}

/* D6/D20 标签是形状提示，不参与掷骰读数；移动和旋转期间都暂隐，定格后再出现。 */
.dice-geometry.is-rolling .dice-side-label,
.dice-3d-shell.is-rolling > .dice-side-label,
.dice-entry-attacker.entrying .dice-side-label,
.dice-entry-defender.entrying .dice-side-label {
  opacity: 0;
  visibility: hidden;
}

/* Normal dice never expose embedded SVG face labels; the simulated readout stays on the die body. */
.dice-geometry.hide-face-numbers .dice-svg .face-number { display: none; }
.dice-geometry.is-rolling .dice-svg .face-number { opacity: 0; }

.dice-geometry.is-special .dice-result-glyph {
  border-color: rgba(216,180,254,.88);
  color: #f5e8ff;
  box-shadow: inset 0 1px 5px rgba(255,255,255,.18), 0 2px 5px rgba(0,0,0,.42), 0 0 14px rgba(192,132,252,.42);
}

/* Normal comparison dice use the same SVG body as special dice.  The wrapper
   below supplies a deterministic, transform-only simulation so no model,
   canvas, WebGL context, or physics world is needed on the active page. */
.dice-3d-shell {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  overflow: visible;
  contain: none;
  perspective: 560px;
  transform-style: preserve-3d;
  isolation: isolate;
  --dice-accent: #e28b82;
}

.dice-3d-shell::before {
  background: radial-gradient(ellipse, rgba(226,139,130,.42), transparent 70%);
  opacity: .52;
}

.dice-3d-shell::after {
  content: '';
  position: absolute;
  z-index: 0;
  left: 13%;
  right: 13%;
  bottom: 2%;
  height: 20%;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(244,155,145,.28), rgba(120,30,43,.13) 42%, transparent 72%);
  transform: translateZ(-10px) scaleX(1.12);
  pointer-events: none;
}

.dice-sim-stage {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  pointer-events: none;
  will-change: transform;
}

.dice-sim-stage > .dice-geometry {
  width: 100%;
  height: 100%;
}

.dice-sim-stage > .dice-geometry::before {
  filter: none;
  opacity: .18;
}

.dice-sim-stage > .dice-geometry .dice-sculpt {
  filter: none;
  transition: none;
}

.dice-sim-stage > .dice-geometry .dice-sim-face-value {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) translateZ(22px) rotateZ(var(--dice-rest-rotate, -2deg));
}

.dice-sim-stage .dice-side-label {
  display: none;
}

.dice-sim-stage.is-rolling {
  animation: diceSimRoll var(--dice-roll-duration, 1.08s) cubic-bezier(.36,.02,.57,.99) infinite;
}

.dice-sim-stage.is-settled {
  animation: diceSimSettle .5s cubic-bezier(.17,.87,.24,1.18) both;
  animation-delay: var(--dice-settle-delay, 0ms);
}

.dice-sim-face-value {
  position: absolute;
  z-index: 3;
  display: grid;
  place-items: center;
  min-width: 30%;
  max-width: 72%;
  padding: 2px 6px;
  color: #fff1bd;
  font-family: "Palatino Linotype", Georgia, "Times New Roman", serif;
  font-size: clamp(22px, 5vw, 44px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  text-align: center;
  text-shadow: 0 1px 0 rgba(255,248,211,.94), 0 2px 0 rgba(78,39,7,.86), 0 0 10px rgba(255,194,70,.82);
  transform: translate(-50%, -50%) translateZ(22px) rotateZ(var(--dice-rest-rotate, -2deg));
  pointer-events: none;
  user-select: none;
}

.dice-sim-stage.is-rolling .dice-sim-face-value {
  animation: diceSimFaceTick .18s ease-out both;
}

.dice-sim-stage.is-settled .dice-sim-face-value {
  animation: diceSimFaceReveal .44s cubic-bezier(.18,.88,.26,1.18) both;
  animation-delay: calc(var(--dice-delay, 0ms) + 40ms);
}

.dice-3d-shell.dice-shape-d4 .dice-sim-face-value,
.dice-3d-shell.dice-shape-d10 .dice-sim-face-value,
.dice-3d-shell.dice-shape-d12 .dice-sim-face-value,
.dice-3d-shell.dice-shape-d20 .dice-sim-face-value {
  font-size: clamp(17px, 4vw, 34px);
}

@keyframes diceSimFaceTick {
  0% { opacity: .35; transform: translate(-50%, -50%) translateZ(22px) rotateZ(var(--dice-rest-rotate, -2deg)) scale(.78); }
  100% { opacity: 1; transform: translate(-50%, -50%) translateZ(22px) rotateZ(var(--dice-rest-rotate, -2deg)) scale(1); }
}

@keyframes diceSimFaceReveal {
  0% { opacity: 0; text-shadow: 0 0 0 rgba(255,194,70,0); transform: translate(-50%, -50%) translateZ(12px) scale(.58) rotateZ(-8deg); }
  58% { opacity: 1; text-shadow: 0 1px 0 rgba(255,248,211,.94), 0 2px 0 rgba(78,39,7,.86), 0 0 15px rgba(255,194,70,.94); transform: translate(-50%, -50%) translateZ(28px) scale(1.14) rotateZ(3deg); }
  100% { opacity: 1; text-shadow: 0 1px 0 rgba(255,248,211,.94), 0 2px 0 rgba(78,39,7,.86), 0 0 10px rgba(255,194,70,.82); transform: translate(-50%, -50%) translateZ(22px) scale(1) rotateZ(var(--dice-rest-rotate, -2deg)); }
}

@keyframes diceSimRoll {
  0% { transform: translate3d(var(--dice-sway-a, -2px), -5px, 0) rotateX(0deg) rotateY(0deg) rotateZ(var(--dice-rest-rotate, -2deg)) scale(.94); }
  16% { transform: translate3d(var(--dice-sway-b, 2px), 1px, 0) rotateX(92deg) rotateY(-70deg) rotateZ(18deg) scale(1.03); }
  34% { transform: translate3d(var(--dice-sway-a, -2px), 4px, 0) rotateX(184deg) rotateY(-150deg) rotateZ(-14deg) scale(.98); }
  53% { transform: translate3d(var(--dice-sway-b, 2px), -1px, 0) rotateX(276deg) rotateY(-238deg) rotateZ(12deg) scale(1.04); }
  72% { transform: translate3d(var(--dice-sway-a, -2px), 3px, 0) rotateX(360deg) rotateY(-330deg) rotateZ(-7deg) scale(.99); }
  88% { transform: translate3d(var(--dice-sway-b, 2px), -2px, 0) rotateX(432deg) rotateY(-410deg) rotateZ(5deg) scale(1.02); }
  100% { transform: translate3d(var(--dice-sway-a, -2px), -5px, 0) rotateX(540deg) rotateY(-510deg) rotateZ(var(--dice-rest-rotate, -2deg)) scale(.94); }
}

@keyframes diceSimSettle {
  0% { transform: translate3d(0, -16px, 0) rotateX(30deg) rotateY(-28deg) rotateZ(-8deg) scale(.72); opacity: .52; }
  62% { transform: translate3d(0, 4px, 0) rotateX(8deg) rotateY(-12deg) rotateZ(3deg) scale(1.08); opacity: 1; }
  100% { transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg) rotateZ(var(--dice-rest-rotate, -2deg)) scale(1); opacity: 1; }
}

@keyframes diceShapeRoll {
  0% { transform: rotateX(16deg) rotateY(-22deg) rotateZ(-3deg) scale(.97); }
  50% { transform: rotateX(196deg) rotateY(158deg) rotateZ(-15deg) scale(1.02); }
  100% { transform: rotateX(376deg) rotateY(338deg) rotateZ(-3deg) scale(.97); }
}

@keyframes diceShapeSettle {
  0% { transform: rotateX(20deg) rotateY(-35deg) rotateZ(-7deg) scale(.78); }
  62% { transform: rotateX(8deg) rotateY(-12deg) rotateZ(2deg) scale(1.08); }
  100% { transform: rotateX(16deg) rotateY(-22deg) rotateZ(-3deg) scale(1); }
}

/* 普通对投复用同一枚 SVG 骰子：从视口外飞入，落定后直接切换为滚动状态。 */
.dice-entry-attacker.entrying,
.dice-entry-defender.entrying {
  position: relative;
  z-index: 8;
  pointer-events: none;
  contain: layout paint;
  backface-visibility: hidden;
  transform: translateZ(0);
  will-change: transform, opacity;
}

.dice-entry-attacker.entrying {
  animation: diceEntryAttacker 920ms linear both;
}

.dice-entry-defender.entrying {
  animation: diceEntryDefender 940ms linear both;
}

@keyframes diceEntryAttacker {
  0% { opacity: 0; transform: translate3d(-78vw,-68vh,0) rotate(-42deg) scale(.38); }
  10% { opacity: 1; transform: translate3d(-67vw,-57vh,0) rotate(20deg) scale(.56); }
  38% { transform: translate3d(-40vw,-31vh,0) rotate(148deg) scale(1.04); }
  65% { transform: translate3d(-15vw,-9vh,0) rotate(282deg) scale(.98); }
  84% { transform: translate3d(-3vw,-2vh,0) rotate(346deg) scale(.96); }
  100% { opacity: 1; transform: translate3d(0,0,0) rotate(390deg) scale(.94); }
}

@keyframes diceEntryDefender {
  0% { opacity: 0; transform: translate3d(78vw,-68vh,0) rotate(42deg) scale(.38); }
  10% { opacity: 1; transform: translate3d(67vw,-57vh,0) rotate(-20deg) scale(.56); }
  38% { transform: translate3d(40vw,-31vh,0) rotate(-148deg) scale(1.04); }
  65% { transform: translate3d(15vw,-9vh,0) rotate(-282deg) scale(.98); }
  84% { transform: translate3d(3vw,-2vh,0) rotate(-346deg) scale(.96); }
  100% { opacity: 1; transform: translate3d(0,0,0) rotate(-390deg) scale(.94); }
}

@media (prefers-reduced-motion: reduce) {
  .dice-geometry.is-rolling .dice-sculpt,
  .dice-sim-stage.is-rolling,
  .dice-sim-stage.is-settled,
  .dice-entry-attacker.entrying,
  .dice-entry-defender.entrying { animation-duration: 1ms; animation-iteration-count: 1; }
  .dice-sim-stage.is-rolling .dice-sim-face-value,
  .dice-sim-stage.is-settled .dice-sim-face-value { animation-duration: 1ms; animation-delay: 0ms; }
}

@media (max-width: 760px) {
  .dice-result-glyph { font-size: clamp(17px, 5.2vw, 30px); padding-inline: 6px; }
  .dice-side-label { font-size: 7px; right: 4%; bottom: 4%; }
}

@supports not (color: color-mix(in srgb, red 20%, transparent)) {
  .dice-geometry::before { background: radial-gradient(ellipse, rgba(96,165,250,.2), transparent 70%); }
}
