/**
 * Die-appropriate dice rendering and tumble animation.
 * SPEC-REALM-006 US-6.1 — shared by the creation wizard and the combat log.
 * Created: 2026-09-06T23:44:00Z
 */

.dice-tray {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
}

.dice-tray-label {
  font-family: var(--font-stats);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.dice-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}

.die {
  display: inline-block;
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  /* Settled state; the tumble animation overrides this transform. */
  transform: rotate(0deg) scale(1);
  transition: filter 0.2s ease;
}

.die svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/*
 * Dice skin variables (SPEC-REALM-012 §2.3). Each defaults to the theme value
 * it replaced, so an unskinned page is pixel-identical to before. A skin is a
 * set of these applied to any ancestor element — which is why choosing one
 * needs no change to DiceAnimator's rendering.
 */
:root {
  --die-face: var(--bg-surface-elevated);
  --die-edge: var(--border-active);
  --die-edge-hero: var(--color-purple-light);
  --die-pip: var(--color-gold-light);
  --die-numeral: var(--text-primary);
  --die-glow: rgba(168, 85, 247, 0.35);
}

.die-shape {
  fill: var(--die-face);
  stroke: var(--die-edge);
  stroke-width: 3;
  filter: drop-shadow(0 0 6px var(--die-glow));
}

.die-pip {
  fill: var(--die-pip);
}

.die-number {
  fill: var(--die-numeral);
  font-family: var(--font-stats);
  font-size: 42px;
  font-weight: 700;
}

/* A d20 is the hero die: slightly larger and more strongly lit. */
.die-d20 {
  width: 52px;
  height: 52px;
}

.die-d20 .die-shape {
  stroke: var(--die-edge-hero);
  stroke-width: 4;
}

/* Dropped die in 4d6-drop-lowest: dimmed and struck through. */
.die-dropped {
  opacity: 0.35;
  filter: grayscale(0.8);
}

.die-dropped .die-shape {
  stroke: var(--text-secondary);
  filter: none;
}

.die-dropped .die-number,
.die-dropped .die-pip {
  fill: var(--text-secondary);
}

.die-crit-hit .die-shape {
  stroke: var(--color-gold);
  filter: drop-shadow(0 0 12px rgba(245, 158, 11, 0.8));
}

.die-crit-hit .die-number {
  fill: var(--color-gold-light);
}

.die-crit-miss .die-shape {
  stroke: var(--color-crimson);
  filter: drop-shadow(0 0 12px rgba(239, 68, 68, 0.7));
}

.die-crit-miss .die-number {
  fill: var(--color-crimson);
}

/*
 * Tumble. Each die shape gets its own spin distance so the motion reads as the
 * right solid: a d6 tips through quarter turns, a d20 spins freely.
 */
@keyframes die-tumble-cube {
  0% {
    transform: rotate(0deg) scale(0.7);
  }
  40% {
    transform: rotate(180deg) scale(1.12);
  }
  70% {
    transform: rotate(300deg) scale(0.96);
  }
  100% {
    transform: rotate(360deg) scale(1);
  }
}

@keyframes die-tumble-poly {
  0% {
    transform: rotate(0deg) scale(0.6);
  }
  35% {
    transform: rotate(280deg) scale(1.18);
  }
  65% {
    transform: rotate(520deg) scale(0.94);
  }
  100% {
    transform: rotate(720deg) scale(1);
  }
}

.die-tumbling {
  animation: die-tumble-poly 620ms cubic-bezier(0.34, 1.3, 0.64, 1) both;
}

.die-tumbling.die-d6,
.die-tumbling.die-d4 {
  animation-name: die-tumble-cube;
}

.die-settled {
  animation: none;
  transform: rotate(0deg) scale(1);
}

/* A settled crit gets one pulse so it is noticed without a sound cue. */
@keyframes die-crit-pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.16);
  }
}

.die-settled.die-crit-hit,
.die-settled.die-crit-miss {
  animation: die-crit-pulse 520ms ease-in-out 1;
}

@media (prefers-reduced-motion: reduce) {
  .die-tumbling,
  .die-settled.die-crit-hit,
  .die-settled.die-crit-miss {
    animation: none;
    transform: none;
  }
}
