/* ---- 踏频齿轮 game layers (gear mode; loaded after number-effects.css, which keeps the sprocket's box, gates,
   turn and fire). Same DOM as before — .nfx-gear > i (rotor) > b (flame ring), and .nfx-gear > b (wind-fire
   tail) — no new elements, no script, no timers: only free pseudo-elements and restyled parts.
   - Rotor (turns with nfx-gear-turn, unchanged): a pixel chainring — dark rim with a lit edge, a spider ring,
     teeth with a bright leading edge (clockwise) — and on its ::after a real crankset: two opposite crank arms
     through the hub, pedal A (the tier's pedal colour, with its glow) and a darker pedal B, and the arms'
     motion-blur sweep behind each arm, as wide as the cadence (--led-reach: 12°–82°).
   - One engine cycle per crank turn on the rotor's own clock (same period and delay as nfx-gear-turn, so
     φ = 0 is crank A up): charge (ring converges on the teeth, core gathers, a pip as crank B passes 3 o'clock)
     → contact/hit at φ .25 (crank A forward: the most torque) → release (the ring blasts out behind the wheel
     and slows, embers are thrown back along the tail and fall, the tail flares, then cools). The stops are
     ui/gear-game.mjs GEAR_RING / GEAR_EMBERS / GEAR_THRUST, played linearly.
   - Strength --gg-k = .3 + .7 · LED energy (the row's real speed); embers cyan, turning gold with --nfx-fire.
   - Everything stays inside the speed cell under the digits (the box's z-index 0): the ring is a crescent on
     the wheel's back (left) side, the core stays inside the chainring, embers fly left. No white on the
     number; transform/opacity only; the same running gate as the turn (motion off, hold, hidden tab, parked
     rows: no motion; reduced motion: no gear at all). Phones: a narrower lower-left crescent, a shorter
     throw, fewer embers and no tail flare. */
#ladder-rows .nfx-gear {
  --gg-arc: #39ff88; --gg-core: #3ff2ff; --gg-volt: #67e8f9; --gg-ember: #fbbf24; --gg-crank: #9ff7e6; --gg-hub: #d9fff0;
  --gg-tooth: #1fd876; --gg-edge: #c4ffe0;
  --gg-k: calc(.3 + .7 * var(--led-energy, 0)); --gg-amp: 1; --gg-throw: calc(var(--nfx-gd) * 1);
  --gg-blur: calc((12 + 70 * var(--led-reach, 0)) * 1deg);
  --gg-delay: calc(var(--nfx-gear-t, var(--led-t, 0ms)) - var(--nfx-gear-off, 0ms));
  --gg-spark: color-mix(in srgb, var(--gg-ember) calc(var(--nfx-fire, 0) * 100%), var(--gg-volt));
  --gg-px: 2px; }
#ladder-rows .nfx-gear:is(.t3, .t4) { --gg-arc: #3ff2ff; }
#ladder-rows .nfx-gear:is(.t5, .t6) { --gg-arc: #67e8f9; --gg-core: #fde047; }
#ladder-rows .nfx-gear.t7 { --gg-arc: #a5f3fc; --gg-core: #facc15; --gg-edge: #fde68a; }

/* The chainring (rotor background): spider ring, rim with a lit outer edge. The interior stays open so the
   core below shows through it. */
#ladder-rows .nfx-gear > i {
  background: radial-gradient(closest-side, transparent 0 27%, rgba(57, 255, 136, .32) 27% 31%, transparent 31% 56%,
    #0b3a24 56% 60%, #1f6b45 60% 69%, #4ade80 69% 72%, #0b3a24 72% 74%, transparent 74%); }
/* Teeth: a darker body and a bright leading (clockwise) edge, so the turn reads as a drive. */
#ladder-rows .nfx-gear > i::before {
  background: repeating-conic-gradient(var(--gg-tooth) 0 9deg, var(--gg-edge) 9deg 13deg, transparent 13deg 30deg); }
/* The crankset on the rotor's ::after (was the single pedal): a disc as wide as the crank circle carrying
   pedal A (top, the tier's --nfx-pedal, glowing), pedal B (bottom, darker), the two arms through the hub,
   the hub cap and each arm's motion-blur sweep behind it (counter-clockwise of the arm). */
#ladder-rows .nfx-gear > i::after {
  --gg-d: calc(var(--nfx-gd) * .64 + var(--nfx-pd));
  width: var(--gg-d); height: var(--gg-d); left: calc(50% - var(--gg-d) / 2); top: calc(50% - var(--gg-d) / 2);
  border-radius: 50%; box-shadow: none;
  background:
    linear-gradient(var(--nfx-pedal) 0 0) 50% 0 / var(--nfx-pd) var(--nfx-pd) no-repeat,
    linear-gradient(color-mix(in srgb, var(--nfx-pedal) 55%, #0b3a24) 0 0) 50% 100% / var(--nfx-pd) var(--nfx-pd) no-repeat,
    linear-gradient(var(--gg-crank) 0 0) 50% 50% / 2px calc(100% - var(--nfx-pd)) no-repeat,
    radial-gradient(closest-side, var(--gg-hub) 0 13%, #03140c 13% 20%, transparent 20%),
    radial-gradient(circle at 50% calc(var(--nfx-pd) / 2), color-mix(in srgb, var(--nfx-pedal) 60%, transparent) 0, transparent calc(var(--nfx-pd) * 1.8)),
    repeating-conic-gradient(from calc(-1 * var(--gg-blur)), transparent 0deg, color-mix(in srgb, var(--gg-crank) 32%, transparent) var(--gg-blur), transparent var(--gg-blur) 180deg); }

/* The stroke ring and core (the box's ::before, under the rotor): a ring at the tooth tips, cut to a crescent
   on the wheel's back side, and a core inside the chainring. Quiet unless its cycle runs. */
#ladder-rows .nfx-gear::before { content: ""; position: absolute; inset: calc(var(--nfx-gd) * -.06); border-radius: 50%;
  pointer-events: none; opacity: 0;
  background:
    radial-gradient(closest-side, var(--gg-core) 0 14%, color-mix(in srgb, var(--gg-core) 45%, transparent) 22%, transparent 34%),
    radial-gradient(closest-side, transparent 0 80%, color-mix(in srgb, var(--gg-arc) 35%, transparent) 84%, var(--gg-arc) 88% 91%,
      color-mix(in srgb, var(--gg-arc) 30%, transparent) 95%, transparent);
  -webkit-mask: radial-gradient(closest-side, #000 0 36%, transparent 37%), conic-gradient(from 180deg, transparent, #000 45deg 135deg, transparent 180deg);
  mask: radial-gradient(closest-side, #000 0 36%, transparent 37%), conic-gradient(from 180deg, transparent, #000 45deg 135deg, transparent 180deg); }
/* The embers (the box's ::after, over the rotor): pixel sparks at the wheel's back rim, thrown left. Count by
   tier; gold accents from t5. */
#ladder-rows .nfx-gear::after { content: ""; position: absolute; left: 0; top: calc(50% - var(--gg-px) / 2);
  width: var(--gg-px); height: var(--gg-px); pointer-events: none; opacity: 0; background: var(--gg-spark);
  box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt); }
#ladder-rows .nfx-gear:is(.t3, .t4)::after {
  box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt), calc(var(--nfx-gd) * -.22) calc(var(--nfx-gd) * -.06) 0 var(--gg-spark),
    calc(var(--nfx-gd) * -.05) calc(var(--nfx-gd) * -.16) 0 var(--gg-spark); }
#ladder-rows .nfx-gear:is(.t5, .t6, .t7)::after {
  box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt), calc(var(--nfx-gd) * -.22) calc(var(--nfx-gd) * -.06) 0 var(--gg-spark),
    calc(var(--nfx-gd) * -.05) calc(var(--nfx-gd) * -.16) 0 var(--gg-spark), calc(var(--nfx-gd) * -.31) calc(var(--nfx-gd) * .03) 0 var(--gg-ember),
    calc(var(--nfx-gd) * -.17) calc(var(--nfx-gd) * .2) 0 var(--gg-spark); }
#ladder-rows .nfx-gear.t7::after {
  box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt), calc(var(--nfx-gd) * -.22) calc(var(--nfx-gd) * -.06) 0 var(--gg-spark),
    calc(var(--nfx-gd) * -.05) calc(var(--nfx-gd) * -.16) 0 var(--gg-spark), calc(var(--nfx-gd) * -.31) calc(var(--nfx-gd) * .03) 0 var(--gg-ember),
    calc(var(--nfx-gd) * -.17) calc(var(--nfx-gd) * .2) 0 var(--gg-spark), calc(var(--nfx-gd) * -.38) calc(var(--nfx-gd) * -.14) 0 var(--gg-ember); }

/* Running: the gear's own gate, and the rotor's period and delay, so each layer is phase-locked to the crank. */
.ladder-wrap[data-num-fx="gear"]:not([data-fx-off]):not([data-rain-hold]):not([data-led-paused]) #ladder-rows .c-value[data-led]:not([data-led-idle]) .nfx-gear::before {
  animation: nfx-gg-ring var(--nfx-gear-p, 2s) linear infinite var(--gg-delay); }
.ladder-wrap[data-num-fx="gear"]:not([data-fx-off]):not([data-rain-hold]):not([data-led-paused]) #ladder-rows .c-value[data-led]:not([data-led-idle]) .nfx-gear::after {
  animation: nfx-gg-embers var(--nfx-gear-p, 2s) linear infinite var(--gg-delay); }
.ladder-wrap[data-num-fx="gear"]:not([data-fx-off]):not([data-rain-hold]):not([data-led-paused]) #ladder-rows .c-value[data-led]:not([data-led-idle]) .nfx-gear > b {
  animation: nfx-gg-thrust var(--nfx-gear-p, 2s) linear infinite var(--gg-delay); }

/* Phones (also turned to landscape): the crescent only lower-left (the digits are above the unit line), a
   smaller swing, a shorter throw, two embers at most (three from t5), and the tail keeps its steady light. */
@media (max-width: 720px), (pointer: coarse) and (max-height: 720px) {
  #ladder-rows .nfx-gear { --gg-k: calc((.3 + .7 * var(--led-energy, 0)) * .7); --gg-amp: .45; --gg-throw: calc(var(--nfx-gd) * .55); }
  #ladder-rows .nfx-gear::before {
    -webkit-mask: radial-gradient(closest-side, #000 0 36%, transparent 37%), conic-gradient(from 190deg, transparent, #000 30deg 90deg, transparent 120deg);
    mask: radial-gradient(closest-side, #000 0 36%, transparent 37%), conic-gradient(from 190deg, transparent, #000 30deg 90deg, transparent 120deg); }
  #ladder-rows .nfx-gear:is(.t3, .t4)::after { box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt); }
  #ladder-rows .nfx-gear:is(.t5, .t6, .t7)::after {
    box-shadow: calc(var(--nfx-gd) * -.12) calc(var(--nfx-gd) * .08) 0 var(--gg-volt), calc(var(--nfx-gd) * -.31) calc(var(--nfx-gd) * .03) 0 var(--gg-ember); }
  .ladder-wrap[data-num-fx="gear"]:not([data-fx-off]):not([data-rain-hold]):not([data-led-paused]) #ladder-rows .c-value[data-led]:not([data-led-idle]) .nfx-gear > b {
    animation: none; }
}

/* Keyframes: ui/gear-game.mjs tables, one stop each (tests compare them). */
@keyframes nfx-gg-ring {
  0% { transform: scale(calc(1 + 0.18 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.58); }
  12% { transform: scale(calc(1 + 0.1 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.7); }
  20% { transform: scale(calc(1 + 0.02 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.82); }
  23% { transform: scale(calc(1 + -0.08 * var(--gg-amp))); opacity: calc(var(--gg-k) * 1); }
  25% { transform: scale(calc(1 + -0.04 * var(--gg-amp))); opacity: calc(var(--gg-k) * 1); }
  29% { transform: scale(calc(1 + 0.3 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.62); }
  38% { transform: scale(calc(1 + 0.58 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.24); }
  55% { transform: scale(calc(1 + 0.8 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0); }
  55.5% { transform: scale(calc(1 + 0.62 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0); }
  66% { transform: scale(calc(1 + 0.48 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.1); }
  74% { transform: scale(calc(1 + 0.38 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.25); }
  76% { transform: scale(calc(1 + 0.3 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.5); }
  88% { transform: scale(calc(1 + 0.24 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.52); }
  100% { transform: scale(calc(1 + 0.18 * var(--gg-amp))); opacity: calc(var(--gg-k) * 0.58); }
}
@keyframes nfx-gg-embers {
  0% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
  24.5% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
  25% { transform: translate(calc(-0.08 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.8, 0.8); opacity: calc(var(--gg-k) * 1); }
  30% { transform: translate(calc(-0.45 * var(--gg-throw)), calc(0.04 * var(--gg-throw))) scale(1.25, 1); opacity: calc(var(--gg-k) * 0.85); }
  40% { transform: translate(calc(-0.82 * var(--gg-throw)), calc(0.14 * var(--gg-throw))) scale(1.5, 1.1); opacity: calc(var(--gg-k) * 0.45); }
  55% { transform: translate(calc(-1.1 * var(--gg-throw)), calc(0.28 * var(--gg-throw))) scale(1.6, 1.15); opacity: calc(var(--gg-k) * 0); }
  55.5% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
  75% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
  76% { transform: translate(calc(-0.05 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.65, 0.65); opacity: calc(var(--gg-k) * 0.4); }
  84% { transform: translate(calc(-0.38 * var(--gg-throw)), calc(0.07 * var(--gg-throw))) scale(1, 0.9); opacity: calc(var(--gg-k) * 0); }
  84.5% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
  100% { transform: translate(calc(0 * var(--gg-throw)), calc(0 * var(--gg-throw))) scale(0.6, 0.6); opacity: calc(var(--gg-k) * 0); }
}
@keyframes nfx-gg-thrust {
  0% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.74); }
  23% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.82); }
  25% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 1); }
  30% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.96); }
  55% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.66); }
  75% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.7); }
  77% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.82); }
  90% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.74); }
  100% { opacity: calc(min(1, var(--nfx-fire, 0) * 1.6) * 0.74); }
}
