/**
 * The rolling cube, shared by the Dice Roller and Number Knockout.
 *
 * Goes with js/dice3d.js. The faces are pushed out from the middle by half of
 * --size, so the two files have to agree about that: the stylesheet sets the
 * size and the script sets which way each face points.
 *
 * A page using this must also give the tray a perspective, or the cube is
 * flattened into a square and none of it means anything.
 */

.die {
  --size: clamp(3.5rem, 15vw, 5rem);
  width: var(--size);
  height: var(--size);
  position: relative;
  transform-style: preserve-3d;
}

/* ---------- D6: a real cube ---------- */

/* Holds the cube at a slight angle so you see the rolled face plus a sliver of
   two others, the way a die actually sits on a table. */
/* A cube held at an angle projects wider and taller than the box it sits in,
   so without this the corner of one cube runs into the next one along. */
.die--cube,
.die--solid {
  margin: calc(var(--size) * 0.09) calc(var(--size) * 0.15);
}

/* Every die is scaled by how far its furthest corner reaches, which keeps any
   of them from being clipped -- but a shape whose corners stick out further
   than its faces do, like the tetrahedron and the octahedron, ends up looking
   smaller than the rest. These sizes even that out, and give the many-sided
   dice room for the numbers on their smaller faces. */
.die--d4,
.die--d8,
.die--d10 { --size: clamp(4rem, 17vw, 5.75rem); }
.die--d12,
.die--d20 { --size: clamp(4.25rem, 19vw, 6.5rem); }

.die-stage {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(-16deg) rotateY(-20deg);
}

.die-cube {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  /* Slightly past 1 on the way out, so it lands with a small settle. */
  transition: transform 0.85s cubic-bezier(0.22, 0.85, 0.3, 1.04);
}

.cube-face {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 6%;
  padding: 14%;
  border-radius: 16%;
  border: 2px solid #e2d7c2;
  background: linear-gradient(150deg, #ffffff, #f0e9dc);
  box-shadow: inset 0 0 12px rgba(150, 128, 95, 0.16);
  backface-visibility: hidden;
}

/* Each face is pushed out from the centre by half the cube's width. Opposite
   faces carry numbers that add to 7, as on a real die. */
.cube-face--front  { transform: rotateY(0deg)    translateZ(calc(var(--size) / 2)); }
.cube-face--back   { transform: rotateY(180deg)  translateZ(calc(var(--size) / 2)); }
.cube-face--right  { transform: rotateY(90deg)   translateZ(calc(var(--size) / 2)); }
.cube-face--left   { transform: rotateY(-90deg)  translateZ(calc(var(--size) / 2)); }
.cube-face--top    { transform: rotateX(90deg)   translateZ(calc(var(--size) / 2)); }
.cube-face--bottom { transform: rotateX(-90deg)  translateZ(calc(var(--size) / 2)); }

.pip {
  /* A pip is an empty span. Without an explicit size it collapses to nothing
     under the parent's place-items: center, and the die renders blank. */
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: transparent;
}

.pip.is-on {
  background: radial-gradient(circle at 34% 30%, #5a6570, var(--color-text) 70%);
  box-shadow: inset 0 -1px 2px rgba(255, 255, 255, 0.25);
}


/* The hop a die does when it is thrown. */
.die--cube.is-rolling { animation: die-hop 0.85s cubic-bezier(0.3, 0.7, 0.4, 1); }

@keyframes die-hop {
  0%   { transform: translateY(0) scale(1); }
  30%  { transform: translateY(-34%) scale(1.06); }
  62%  { transform: translateY(-4%) scale(0.98); }
  80%  { transform: translateY(-14%) scale(1.02); }
  100% { transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .die--cube.is-rolling { animation: none; }
  .die-cube { transition: none; }
}
