/* =====================================================================================================
   LR STUDS  --  LEGO Racers' front-end stud plate, as a background.                          (card R41B)
   =====================================================================================================

   The original is one 640 x 480, 256-colour picture (MENUDATA/BACKDRP.BMP). Measured, it is a product:

       picture = light(x, y) * tile(u, v)

   a uniformly lit plate of studs with the corner shading multiplied on afterwards. That is exactly what
   `background-blend-mode: multiply` does, so that is all this file is:

       stud-tile.svg    one pitch of plate, repeated. Never stretched, so a stud is round at any aspect.
       stud-light.svg   the light, stretched to the box, multiplied over the tile.
       a gradient       colour-dodged on top: the original is over-exposed in its hot corner (x1.22),
                        which multiply alone cannot say.

   The constants live in src/present/studbackdrop.cpp; make-svg.py turns them into the two SVGs.

       <body class="lr-studs lr-studs--spot">            the original: lit from the bottom right
       <div  class="lr-studs">                           evenly lit, no corner shading
       <div  class="lr-studs lr-studs--spot lr-studs--sweep lr-studs--drift">    and moving

   Everything is a custom property, so a page can re-tune it without touching this file.
   ===================================================================================================== */

.lr-studs {
  /* Nine studs across the shorter side: the original's count. `cqmin` is the nearest size container's
     shorter side and, with no container, the viewport's -- so this is right for a page and for a panel. */
  --lr-studs-across: 9;
  --lr-studs-pitch: calc(100cqmin / var(--lr-studs-across));
  /* How bright the plate is when it is evenly lit. The original's centre reads 0.6. */
  --lr-studs-level: 0.62;
  --lr-studs-tile: url("stud-tile.svg");
  --lr-studs-light: url("stud-light.svg");
  /* The over-exposed corner. Written by make-svg.py; dodging by s multiplies by 1 / (1 - s). */
  --lr-studs-hotspot: radial-gradient(ellipse 156.25% 208.333% at 100% 123.75%,
      rgb(94 94 94) 0%, rgb(66 66 66) 8%, rgb(26 26 26) 16%, #000 21.41%);

  background-color: #00f;
  background-image:
    linear-gradient(hsl(0 0% calc(var(--lr-studs-level) * 100%)) 0 0),
    var(--lr-studs-tile);
  background-blend-mode: multiply, normal;
  background-repeat: no-repeat, repeat;
  background-size: 100% 100%, var(--lr-studs-pitch) var(--lr-studs-pitch);
  /* Studs stand half a pitch in from the top left, as the original's do. */
  background-position: 0 0, var(--lr-studs-drift) var(--lr-studs-drift);
}

/* ---- the corner shading ---------------------------------------------------------------------------- */
.lr-studs--spot {
  background-image: var(--lr-studs-hotspot), var(--lr-studs-light), var(--lr-studs-tile);
  background-blend-mode: color-dodge, multiply, normal;
  background-repeat: no-repeat, no-repeat, repeat;
  background-size: 100% 100%, 100% 100%, var(--lr-studs-pitch) var(--lr-studs-pitch);
  background-position: 0 0, 0 0, var(--lr-studs-drift) var(--lr-studs-drift);
}

/* ---- bare studs ------------------------------------------------------------------------------------ */
/* The same plate without the lettering on its studs (`--no-lettering` in lrbackdrop). */
.lr-studs--plain { --lr-studs-tile: url("stud-tile-plain.svg"); }

/* ---- motion ---------------------------------------------------------------------------------------- */
/* Drift: the plate slides one pitch and is where it began -- a seamless loop. It animates one registered
   length and nothing else, so it composes with the sweep below instead of fighting it for
   `background-position`. (Without `@property` the length cannot interpolate and the plate stays put.) */
@property --lr-studs-drift { syntax: "<length>"; inherits: false; initial-value: 0px; }
.lr-studs--drift { animation: lr-studs-drift var(--lr-studs-drift-time, 24s) linear infinite; }
@keyframes lr-studs-drift {
  to { --lr-studs-drift: calc(var(--lr-studs-pitch) * -1); }
}

/* Sweep: the light swells out of its corner and settles. It rests on the original's composition exactly,
   and grows about the hot corner, so the over-exposure never leaves the frame. */
.lr-studs--spot.lr-studs--sweep {
  background-position: 100% 100%, 100% 100%, var(--lr-studs-drift) var(--lr-studs-drift);
  animation: lr-studs-sweep var(--lr-studs-sweep-time, 12s) ease-in-out infinite alternate;
}
.lr-studs--spot.lr-studs--sweep.lr-studs--drift {
  animation: lr-studs-sweep var(--lr-studs-sweep-time, 12s) ease-in-out infinite alternate,
             lr-studs-drift var(--lr-studs-drift-time, 24s) linear infinite;
}
@keyframes lr-studs-sweep {
  from { background-size: 100% 100%, 100% 100%, var(--lr-studs-pitch) var(--lr-studs-pitch); }
  to   { background-size: 128% 118%, 128% 118%, var(--lr-studs-pitch) var(--lr-studs-pitch); }
}

@media (prefers-reduced-motion: reduce) {
  .lr-studs--drift, .lr-studs--sweep { animation: none !important; }
}
