/* =================================================================== GEAR ROTATE — continuous counter-rotation (global css) ===================================================================

   Two ASCII gears turning against each other, forever. One counter is kept —
   `--gear-rotation` on the group — and each gear derives its own angle from it,
   so the two can never drift apart no matter how long the page is open.

   assets/js/global/gear-rotate.js drives the counter; this file is the
   mechanism (the registered property, the transform, the fallback and the
   reduced-motion guard). WHERE the gears sit and how big they are belongs to
   the section — in the hero that is .hero__gears / .hero__gear in hero.css.
   Same split as ascii-scramble.css, which knows nothing about .hero__map.

   Sections write two attributes and nothing else:

     <div class="hero__gears" data-gear-rotate data-gear-rotate-speed="18">
         <img class="hero__gear" ...>                     <- turns one way
         <img class="hero__gear gear--reverse" ...>        <- turns the other
     </div>

   ⚠️ --gear-rotation is REGISTERED, and that is load-bearing twice over. An
   unregistered custom property is just a string: it cannot be interpolated, so
   the CSS fallback below could not animate it, and a browser cannot type-check
   it either, so a bad value would silently kill the transform rather than being
   ignored. Typed as an <angle> with an initial value it does both.
   =================================================================== */

@property --gear-rotation {
    syntax: '<angle>';
    inherits: true;
    initial-value: 0deg;
}

[data-gear-rotate] {
    /* The one value on the page the gears read. The script keeps adding to it. */
    --gear-rotation: 0deg;

    /* ⚠️ THE GEAR RATIO — teeth(driver) / teeth(follower), 1 for a pair that is
       not really meshing. Set it and the reverse gear turns that much faster,
       which is the only thing that lets two gears with different tooth counts
       mesh: equal speeds cannot, at any offset. gear-rotate.js reads this to
       work out where the counter may safely wrap. */
    --gear-ratio: 1;
}

/* Each gear is a complete circle, so its own box centre IS the circle's centre
   — the default transform-origin is already right and each one spins in place.

   ⚠️ There is deliberately no `transition`. The script writes a new angle every
   frame, so there is nothing for one to smooth: it would only add a frame of
   lag and smear the two gears out of sync with each other. */
.gear {
    /* --gear-offset is the gear's own static phase: the angle that puts one of
       its teeth (or one of its gaps) on the line of centres. Measured per
       drawing, so it belongs to the section, not here.

       ⚠️ --gear-place comes FIRST and defaults to nothing, because transforms
       apply right to left: this way a section can position the gear by its
       centre (`translate(-50%, -50%)`) and still have it rotate about that
       centre. Reversed, the gear orbits the point instead of spinning on it. */
    --gear-offset: 0deg;
    --gear-place: translate(0, 0);

    transform: var(--gear-place) rotate(calc(var(--gear-rotation) + var(--gear-offset)));
    will-change: transform;
}

/* Deriving this from the same `--gear-rotation` rather than keeping a second
   counter is what guarantees the ratio never drifts, however long the page is
   open. */
.gear--reverse {
    transform: var(--gear-place)
               rotate(calc(var(--gear-rotation) * -1 * var(--gear-ratio) + var(--gear-offset)));
}

/* Fallback: if the script never runs — JS off, or a throw — the gears still
   turn, because a registered <angle> is animatable in CSS. The script adds
   .is-driven before its first frame, so the two can never both be driving and
   the angle cannot jump between them. */
/* ⚠️ 1800deg, not 360, and the period stretches to match. With a ratio like
   1.6 the follower turns 576deg for every 360 of the driver, so a keyframe that
   loops at 360 snaps it back 216deg every cycle. 1800 is a whole number of
   turns for every ratio this build uses — 5 turns at 1:1, and 8 for the
   follower at 1.6 — so the loop is seamless either way. */
@keyframes gear-spin {
    to { --gear-rotation: 1800deg; }
}

[data-gear-rotate]:not(.is-driven) {
    animation: gear-spin calc(var(--gear-period, 20s) * 5) linear infinite;
}

/* Decorative, so it comes off entirely rather than being slowed down. The
   script tests the same query and never starts, so nothing moves either way. */
@media (prefers-reduced-motion: reduce) {
    [data-gear-rotate]:not(.is-driven) { animation: none; }
}
