/* Dino Competitions: stomping footprint page transition.
   Curtain rises from the ground, three prints are punched into it, curtain
   carries on up and off the top of the screen on the next page. Reveal is pure
   CSS, so the curtain always lifts even if the JavaScript never runs.

   Weight comes from four things layered on each footfall: a hard punch with no
   bounce, a camera jolt, ground ejecta that hugs the floor, and a slower billow
   that rises and hangs. Take any one away and it goes back to feeling like a
   sticker landing on a page. */

:root {
  /* Must be root relative or absolute, never relative. A relative URL inside a
     custom property resolves against a different stylesheet depending on the
     browser, so it silently 404s and you get dust with no footprint. */
  --dino-tx-print: url("/wp-content/uploads/dino-footprint.webp");
  /* Photographed dust, 16 frames in a 4 by 4 grid, shot on black and
     composited with screen blend so no alpha channel is needed. Optional:
     if it fails to load the CSS dust below still carries the impact. */
  --dino-tx-plate: url("/wp-content/uploads/dino-dust-sprite.webp");

  --dino-tx-ink: #050A08;
  --dino-tx-forest: #0B3B2E;
  --dino-tx-forest-deep: #06231B;
  --dino-tx-gold: #C9A24A;
  --dino-tx-gold-lit: #E8C46A;
  /* Dust is neutral, not gold. Chosen 8 Sep 2026 from the side by side in
     demo/compare.html: the gold print is already doing the brand work, and
     gold dust muddies the print at the moment of impact. */
  --dino-tx-dust: 216, 210, 199;

  /* Inline fractal noise, no network request. Coarse for the billow, fine for
     the ejecta. */
  --dino-tx-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.035' numOctaves='4' seed='7'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  --dino-tx-noise-fine: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.11' numOctaves='3' seed='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");

  --dino-tx-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dino-tx-punch: cubic-bezier(0.2, 0.85, 0.3, 1);   /* fast in, dead stop, no bounce */
  --dino-tx-settle: cubic-bezier(0.12, 0.6, 0.25, 1); /* dust: quick out, long hang */
}

.dino-curtain {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: none;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 62% at 50% 84%, var(--dino-tx-forest) 0%, var(--dino-tx-forest-deep) 44%, var(--dino-tx-ink) 78%),
    var(--dino-tx-ink);
  transform: translate3d(0, 100%, 0);
  will-change: transform;
  pointer-events: none;
  overflow: hidden;
}

.dino-curtain__trail {
  display: flex;
  align-items: center;
  gap: clamp(4px, 1.2vw, 14px);
}

/* One footfall. Everything below is positioned against it. */
.dino-step {
  position: relative;
  width: clamp(46px, 9vw, 88px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}

/* Walking across and slightly toward camera: each print a little larger,
   a little brighter, and set down on a different part of the gait. */
.dino-step:nth-child(1) { rotate: -11deg; translate: 0 7%;  scale: 0.86; --dino-lit: 0.72; --dino-at: 110ms; }
.dino-step:nth-child(2) { rotate: 8deg;   translate: 0 -9%; scale: 1;    --dino-lit: 0.88; --dino-at: 200ms; }
.dino-step:nth-child(3) { rotate: -5deg;  translate: 0 6%;  scale: 1.14; --dino-lit: 1;    --dino-at: 290ms; }
/* Middle print is the other foot. */
.dino-step:nth-child(2) .dino-step__mark { scale: -1 1; }

/* ---- The print itself: a depression, not a sticker ---- */

.dino-step__mark {
  position: absolute;
  inset: 0;
  opacity: 0;
}

/* Shadow cast into the hollow, offset down and away from the light. */
.dino-step__mark::before {
  content: "";
  position: absolute;
  inset: 0;
  translate: 2.5% 4%;
  background: rgba(0, 0, 0, 0.85);
  -webkit-mask: var(--dino-tx-print) no-repeat center / contain;
  mask: var(--dino-tx-print) no-repeat center / contain;
  filter: blur(1.5px);
}

/* The print, lit from the upper left so the far wall of the hollow catches it. */
.dino-step__mark::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(155deg, #F4DCA4 0%, var(--dino-tx-gold-lit) 22%, var(--dino-tx-gold) 52%, #5F4B24 100%);
  -webkit-mask: var(--dino-tx-print) no-repeat center / contain;
  mask: var(--dino-tx-print) no-repeat center / contain;
  opacity: var(--dino-lit, 1);
}

/* ---- Ground ejecta: fast, wide, hugs the floor ---- */

.dino-step__ejecta {
  position: absolute;
  left: 50%;
  top: 64%;
  width: 150%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--dino-tx-dust), 0.78) 0%, rgba(var(--dino-tx-dust), 0.26) 46%, rgba(var(--dino-tx-dust), 0) 68%);
  /* Noise for texture, intersected with a soft ellipse so the tile never shows
     its square edge. Without the second layer you get a visible seam. */
  -webkit-mask-image: var(--dino-tx-noise-fine), radial-gradient(closest-side, #000 58%, transparent 100%);
  -webkit-mask-size: 100% 100%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
  -webkit-mask-position: center, center;
  -webkit-mask-composite: source-in;
  mask-image: var(--dino-tx-noise-fine), radial-gradient(closest-side, #000 58%, transparent 100%);
  mask-size: 100% 100%, 100% 100%;
  mask-repeat: no-repeat, no-repeat;
  mask-position: center, center;
  mask-composite: intersect;
  opacity: 0;
}

/* The moment of contact, 70ms of heat. */
.dino-step__ejecta::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 42%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(252, 249, 242, 0.8) 0%, rgba(var(--dino-tx-dust), 0) 70%);
  opacity: 0;
}

/* ---- Billow: slower, taller, drifts and hangs ---- */

.dino-step__billow {
  position: absolute;
  left: 50%;
  top: 58%;
  width: 165%;
  aspect-ratio: 1;
  translate: -50% -50%;
  opacity: 0;
  /* Three offset lobes so the edge is not a clean circle. */
  background:
    radial-gradient(circle at 32% 62%, rgba(var(--dino-tx-dust), 0.62) 0%, rgba(var(--dino-tx-dust), 0) 52%),
    radial-gradient(circle at 68% 56%, rgba(var(--dino-tx-dust), 0.54) 0%, rgba(var(--dino-tx-dust), 0) 48%),
    radial-gradient(circle at 50% 40%, rgba(var(--dino-tx-dust), 0.44) 0%, rgba(var(--dino-tx-dust), 0) 58%);
  /* Fractal noise punches holes in the cloud so it clumps like dust instead of
     glowing like a lamp. The gradients above still control the falloff, so no
     mask compositing is needed and it degrades to a soft cloud if unsupported. */
  -webkit-mask-image: var(--dino-tx-noise), radial-gradient(closest-side, #000 62%, transparent 100%);
  -webkit-mask-size: 140% 140%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
  -webkit-mask-position: center, center;
  -webkit-mask-composite: source-in;
  mask-image: var(--dino-tx-noise), radial-gradient(closest-side, #000 62%, transparent 100%);
  mask-size: 140% 140%, 100% 100%;
  mask-repeat: no-repeat, no-repeat;
  mask-position: center, center;
  mask-composite: intersect;
  filter: blur(1.5px);
}

/* ---- Photographic dust plate ---- */

/* The plate is a MASK, not an image. mix-blend-mode was the obvious route and it
   does not work here: the trail's jolt transform opens a new stacking context,
   so screen blending has no curtain backdrop to blend against and the plate's
   black corners render as a visible box. A mask has no backdrop dependency, and
   it means the dust is tinted from the brand variable like everything else. */
.dino-step__plate {
  position: absolute;
  left: 50%;
  top: 54%;
  width: 430%;
  aspect-ratio: 230 / 146;
  translate: -50% -58%;
  background: rgb(var(--dino-tx-dust));
  -webkit-mask-image: var(--dino-tx-plate);
  -webkit-mask-size: 400% 400%;      /* 4 columns, 4 rows */
  -webkit-mask-position: 0% 0%;
  -webkit-mask-repeat: no-repeat;
  mask-image: var(--dino-tx-plate);
  mask-size: 400% 400%;
  mask-position: 0% 0%;
  mask-repeat: no-repeat;
  opacity: 0;
  pointer-events: none;
}

/* ---- Grit: four clods thrown out on arcs ---- */

.dino-step__grit {
  position: absolute;
  left: 50%;
  top: 66%;
  width: 0;
  height: 0;
}

.dino-step__grit i {
  position: absolute;
  border-radius: 50% 50% 45% 55%;
  background: rgb(var(--dino-tx-dust));
  opacity: 0;
}

.dino-step__grit i:nth-child(1) { --gx: -420%; --gy: 120%; --gh: -260%; width: 5px; height: 4px; }
.dino-step__grit i:nth-child(2) { --gx: 380%;  --gy: 150%; --gh: -320%; width: 3px; height: 3px; }
.dino-step__grit i:nth-child(3) { --gx: -260%; --gy: 90%;  --gh: -170%; width: 4px; height: 3px; }
.dino-step__grit i:nth-child(4) { --gx: 470%;  --gy: 130%; --gh: -210%; width: 6px; height: 5px; }

/* ---- Leaving: the cover phase ---- */

.dino-tx-leaving .dino-curtain {
  display: flex;
  animation: dino-tx-rise 300ms var(--dino-tx-ease) forwards;
}

/* Camera jolt. One timeline, three hits, each heavier than the last. */
.dino-tx-leaving .dino-curtain__trail {
  animation: dino-tx-jolt 620ms linear forwards;
}

.dino-tx-leaving .dino-step__mark {
  animation: dino-tx-punch 190ms var(--dino-tx-punch) var(--dino-at) forwards;
}
.dino-tx-leaving .dino-step__ejecta {
  animation: dino-tx-ejecta 520ms ease-out var(--dino-at) forwards;
}
.dino-tx-leaving .dino-step__ejecta::after {
  animation: dino-tx-flash 140ms ease-out var(--dino-at) forwards;
}
.dino-tx-leaving .dino-step__billow {
  animation: dino-tx-billow 820ms var(--dino-tx-settle) var(--dino-at) forwards;
}
.dino-tx-leaving .dino-step__grit i {
  animation: dino-tx-grit 560ms cubic-bezier(0.25, 0.7, 0.4, 1) var(--dino-at) forwards;
}
/* Two axes because the sheet is a grid. jump-none is the important part: plain
   steps(4) lands on 0/25/50/75 percent and never reaches the last column. */
.dino-tx-leaving .dino-step__plate {
  animation:
    dino-tx-plate-x 130ms steps(4, jump-none) var(--dino-at) 4 forwards,
    dino-tx-plate-y 520ms steps(4, jump-none) var(--dino-at) 1 forwards,
    dino-tx-plate-o 640ms ease-out var(--dino-at) 1 forwards;
}
/* The drawn cloud steps back to a base layer once the photograph is on top. */
.dino-tx-leaving .dino-step__billow { opacity: 0; animation-name: dino-tx-billow-soft; }
/* Mirrored foot keeps its flip through the punch. */
.dino-tx-leaving .dino-step:nth-child(2) .dino-step__mark {
  animation-name: dino-tx-punch-flip;
}

@keyframes dino-tx-rise {
  from { transform: translate3d(0, 100%, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* No overshoot. Heavy things stop dead. */
@keyframes dino-tx-punch {
  0%   { opacity: 0; scale: 1.16; }
  18%  { opacity: 1; scale: 1.01; }
  100% { opacity: 1; scale: 1; }
}
@keyframes dino-tx-punch-flip {
  0%   { opacity: 0; scale: -1.16 1.16; }
  18%  { opacity: 1; scale: -1.01 1.01; }
  100% { opacity: 1; scale: -1 1; }
}

@keyframes dino-tx-jolt {
  0%, 15%   { translate: 0 0; }
  18%       { translate: 0 2px; }
  23%       { translate: 0 -1px; }
  28%, 30%  { translate: 0 0; }
  33%       { translate: 0 3px; }
  38%       { translate: 0 -1px; }
  43%, 45%  { translate: 0 0; }
  48%       { translate: 0 5px; }
  53%       { translate: 0 -2px; }
  58%       { translate: 0 1px; }
  64%, 100% { translate: 0 0; }
}

@keyframes dino-tx-ejecta {
  0%   { opacity: 0; scale: 0.35 0.2; }
  10%  { opacity: 1; }
  100% { opacity: 0; scale: 2.3 0.42; }
}

@keyframes dino-tx-flash {
  0%   { opacity: 0; scale: 0.4; }
  20%  { opacity: 1; }
  100% { opacity: 0; scale: 1.5; }
}

@keyframes dino-tx-billow {
  0%   { opacity: 0; scale: 0.42; translate: -50% -50%; }
  18%  { opacity: 1; }
  100% { opacity: 0; scale: 1.85; translate: -50% -86%; }
}

/* Up on the throw, down on the way back. */
@keyframes dino-tx-grit {
  0%   { opacity: 0; translate: 0 0; }
  8%   { opacity: 1; }
  45%  { translate: calc(var(--gx) * 0.62) var(--gh); }
  100% { opacity: 0; translate: var(--gx) var(--gy); }
}

@keyframes dino-tx-plate-x {
  from { -webkit-mask-position-x: 0%; mask-position-x: 0%; }
  to   { -webkit-mask-position-x: 100%; mask-position-x: 100%; }
}
@keyframes dino-tx-plate-y {
  from { -webkit-mask-position-y: 0%; mask-position-y: 0%; }
  to   { -webkit-mask-position-y: 100%; mask-position-y: 100%; }
}
@keyframes dino-tx-plate-o {
  0%   { opacity: 0; }
  6%   { opacity: 1; }
  65%  { opacity: 0.85; }
  100% { opacity: 0; }
}
@keyframes dino-tx-billow-soft {
  0%   { opacity: 0; scale: 0.42; translate: -50% -50%; }
  18%  { opacity: 0.4; }
  100% { opacity: 0; scale: 1.85; translate: -50% -86%; }
}

/* ---- Arriving: the reveal phase. Pure CSS, no JavaScript required. ---- */

.dino-tx-arriving .dino-curtain {
  display: flex;
  transform: translate3d(0, 0, 0);
  animation: dino-tx-exit 400ms 70ms var(--dino-tx-ease) forwards;
}
.dino-tx-arriving .dino-step__mark {
  opacity: 1;
  animation: dino-tx-fade 240ms 70ms ease-out forwards;
}
.dino-tx-arriving .dino-step:nth-child(2) .dino-step__mark { scale: -1 1; }

@keyframes dino-tx-exit {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -100%, 0); }
}

@keyframes dino-tx-fade {
  to { opacity: 0; }
}

/* ---- Degraded states ---- */

@media (prefers-reduced-motion: reduce) {
  .dino-tx-leaving .dino-curtain,
  .dino-tx-arriving .dino-curtain {
    display: none;
    animation: none;
  }
}
