/* The animated rules demo.
   One shared 9s timeline; every part is a percentage of it, so the beats stay
   in step without a line of JavaScript. Pure CSS also means it animates on a
   phone that has blocked scripts, which is where half of these get read. */

.demo {
  --loop: 9s;
  position: relative;
  overflow: hidden;
}

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

/* ---- beat captions ------------------------------------------------------ */
/* Ruled, not boxed: the beats read as a strip of scorecard rather than tabs. */

.demo-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--ink);
  margin-top: -1px;
}

.demo-step {
  padding: 0.62rem 0.4rem 0.7rem;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pencil);
  border-right: 1px solid var(--rule);
  animation: stepGlow var(--loop) linear infinite;
}
.demo-step:last-child { border-right: 0; }
.demo-step b {
  display: block;
  color: var(--marker);
  font-weight: 400;
  margin-bottom: 0.15rem;
}

.demo-step:nth-child(1) { animation-delay: calc(var(--loop) * 0.00); }
.demo-step:nth-child(2) { animation-delay: calc(var(--loop) * -0.75); }
.demo-step:nth-child(3) { animation-delay: calc(var(--loop) * -0.50); }
.demo-step:nth-child(4) { animation-delay: calc(var(--loop) * -0.25); }

@keyframes stepGlow {
  0%,  2%   { color: var(--pencil); background: transparent; }
  4%, 22%   { color: var(--ink); background: var(--sand); }
  25%, 100% { color: var(--pencil); background: transparent; }
}

/* ---- the ruler ---------------------------------------------------------- */

.d-ruler {
  transform-box: fill-box;
  transform-origin: 6px 50%;
  animation: rulerIn var(--loop) ease-out infinite;
}
@keyframes rulerIn {
  0%, 4%    { opacity: 0; transform: rotate(-88deg); }
  13%       { opacity: 1; transform: rotate(-30deg); }
  17%       { transform: rotate(-41deg); }
  20%, 88%  { opacity: 1; transform: rotate(-38deg); }
  96%, 100% { opacity: 0; transform: rotate(-38deg); }
}

/* ---- driver badge ------------------------------------------------------- */

.d-driver {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: pop var(--loop) cubic-bezier(0.34, 1.7, 0.5, 1) infinite;
}
@keyframes pop {
  0%, 22%   { opacity: 0; transform: scale(0.4); }
  27%       { opacity: 1; transform: scale(1.12); }
  30%, 88%  { opacity: 1; transform: scale(1); }
  94%, 100% { opacity: 0; transform: scale(1); }
}

/* ---- the dice ----------------------------------------------------------- */

.d-die {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: dieRoll var(--loop) ease-out infinite;
}
@keyframes dieRoll {
  0%, 33%   { opacity: 0; transform: translateY(-10px) rotate(-40deg); }
  37%       { opacity: 1; transform: translateY(0) rotate(18deg); }
  40%       { transform: rotate(-12deg); }
  43%, 88%  { opacity: 1; transform: rotate(0deg); }
  94%, 100% { opacity: 0; }
}

/* Faces flicker through, then one settles - CSS cannot retype a number, so we
   cross-fade separate glyphs instead. */
.d-face { opacity: 0; }
.d-face-a { animation: faceA var(--loop) steps(1, end) infinite; }
.d-face-b { animation: faceB var(--loop) steps(1, end) infinite; }
.d-face-c { animation: faceC var(--loop) steps(1, end) infinite; }
@keyframes faceA { 0%,35% { opacity: 0; } 35.1%,37% { opacity: 1; } 37.1%,100% { opacity: 0; } }
@keyframes faceB { 0%,37% { opacity: 0; } 37.1%,39% { opacity: 1; } 39.1%,100% { opacity: 0; } }
@keyframes faceC { 0%,39% { opacity: 0; } 39.1%,88% { opacity: 1; } 88.1%,100% { opacity: 0; } }

/* ---- the sum ------------------------------------------------------------ */

.d-sum {
  transform-box: fill-box;
  animation: sumIn var(--loop) ease-out infinite;
}
@keyframes sumIn {
  0%, 44%   { opacity: 0; transform: translateY(6px); }
  50%, 88%  { opacity: 1; transform: translateY(0); }
  94%, 100% { opacity: 0; }
}

/* ---- the drawn line ----------------------------------------------------- */

.d-line {
  stroke-dasharray: 150;
  stroke-dashoffset: 150;
  animation: draw var(--loop) ease-in-out infinite;
}
@keyframes draw {
  0%, 55%   { stroke-dashoffset: 150; opacity: 1; }
  70%, 92%  { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* ---- the ball ----------------------------------------------------------- */

.d-ball {
  transform-box: fill-box;
  animation: fly var(--loop) ease-in-out infinite;
}
@keyframes fly {
  0%, 55%   { transform: translate(0, 0); }
  70%, 92%  { transform: translate(118px, -92px); }
  97%       { transform: translate(118px, -92px); }
  100%      { transform: translate(0, 0); }
}

/* ---- where it finished -------------------------------------------------- */

.d-result {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: resultIn var(--loop) cubic-bezier(0.34, 1.7, 0.5, 1) infinite;
}
@keyframes resultIn {
  0%, 70%   { opacity: 0; transform: scale(0.6) translateY(6px); }
  76%       { opacity: 1; transform: scale(1.08) translateY(0); }
  79%, 92%  { opacity: 1; transform: scale(1) translateY(0); }
  97%, 100% { opacity: 0; }
}

/* A ring pulsing over the water, to make the point that the flight does not
   matter - only where the ball comes to rest. */
.d-flyover {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: flyover var(--loop) ease-out infinite;
}
@keyframes flyover {
  0%, 60%   { opacity: 0; transform: scale(0.7); }
  66%       { opacity: 0.9; transform: scale(1.15); }
  74%, 92%  { opacity: 0.55; transform: scale(1); }
  97%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo * { animation: none !important; }
  .d-ruler, .d-driver, .d-die, .d-sum, .d-result, .d-flyover { opacity: 1; }
  .d-ruler { transform: rotate(-38deg); }
  .d-line { stroke-dashoffset: 0; }
  .d-ball { transform: translate(118px, -92px); }
  .d-face-c { opacity: 1; }
  .demo-step { color: var(--ink); }
}

/* SVG text cannot inherit the page font through a presentation attribute, and
   var() is unreliable there too, so labels are styled from CSS. */
.d-label {
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: 0.02em;
}
