/* ============================================================
   The living sky: motion and the ink it forces.
   Only loaded on pages that carry a sky.

   Everything that moves is a CSS transform or an opacity, on a
   group the renderer built once. Nothing here triggers a repaint
   of the sky itself, which is redrawn from JS once a minute and
   at no other time.
   ============================================================ */

/* Cloud drift. The travel distance arrives as two custom properties set inline
   per cluster, in px, so the sky does not need a container-type ancestor to
   size itself against. */
@keyframes lm-drift {
  from { transform: translateX(var(--lm-from, -24%)); }
  to   { transform: translateX(var(--lm-to, 122%)); }
}
@keyframes lm-tw    { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
@keyframes lm-flick { 0%, 100% { transform: scaleY(1); } 45% { transform: scaleY(0.82) scaleX(1.06); } 70% { transform: scaleY(1.1); } }
@keyframes lm-puff  { 0% { transform: translate(0,0) scale(0.7); opacity: 0; } 25% { opacity: 0.9; } 100% { transform: translate(3px,-9px) scale(1.5); opacity: 0; } }

.lmcl   { animation: lm-drift linear infinite; }
.lmtw   { animation: lm-tw 3.4s ease-in-out infinite; }
.lm-fl  { transform-box: fill-box; transform-origin: 50% 100%; animation: lm-flick 1.1s ease-in-out infinite; }
.lm-fl2 { transform-box: fill-box; transform-origin: 50% 100%; animation: lm-flick 0.9s ease-in-out infinite 0.3s; }
.lm-sm  { transform-box: fill-box; animation: lm-puff 3.2s ease-out infinite; }
.lm-sm2 { transform-box: fill-box; animation: lm-puff 3.2s ease-out infinite 1.1s; }
.lm-sm3 { transform-box: fill-box; animation: lm-puff 3.2s ease-out infinite 2.2s; }

/* Birds: the flock crosses and climbs, the flock bobs, the wing flaps. Three
   nested transforms, matching the app's three nested layer transforms. */
@keyframes lm-fly {
  from { transform: translate(var(--lm-fx0), var(--lm-fy0)); }
  to   { transform: translate(var(--lm-fx1), var(--lm-fy1)); }
}
@keyframes lm-bob  { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(var(--lm-bob, -8px)); } }
@keyframes lm-flap { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(0.42); } }

.lm-fly  { animation: lm-fly linear infinite; }
.lm-bob  { animation: lm-bob ease-in-out infinite; }
.lm-flap { animation: lm-flap ease-in-out infinite; }

/* Crepuscular rays. The whole fan sways +/-1.7 degrees over 26s about the light,
   and each wedge breathes its own opacity on its own cycle with its own offset,
   so the five never pulse in unison. Both are CSS; JS writes only the fan's
   master opacity, which is the cloud-over-light overlap. */
@keyframes lm-sway    { 0%, 100% { transform: rotate(-1.7deg); } 50% { transform: rotate(1.7deg); } }
@keyframes lm-breathe { 0%, 100% { opacity: var(--lm-lo, 0.5); } 50% { opacity: var(--lm-hi, 0.9); } }

.lm-sway    { animation: lm-sway 26s ease-in-out infinite; }
.lm-breathe { animation: lm-breathe ease-in-out infinite; }

/* Summoned elements. Each element's own idle motion, all of it CSS on a group
   the renderer built once; the flight itself is a Web Animation. */
@keyframes lm-kite        { 0%, 100% { transform: rotate(-11deg); } 50% { transform: rotate(9deg); } }
@keyframes lm-kite-tail   { 0%, 100% { transform: rotate(-7deg); }  50% { transform: rotate(8deg); } }
@keyframes lm-twinkle-sat { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
@keyframes lm-bob-slow    { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

.lm-kite      { animation: lm-kite 7s ease-in-out infinite; }
.lm-kite-tail { animation: lm-kite-tail 3.4s ease-in-out infinite; }
.lm-twinkle   { animation: lm-twinkle-sat 2.6s ease-in-out infinite; }
.lm-bob-slow  { animation: lm-bob-slow 9s ease-in-out infinite; }

/* Nav lights. The app's envelope exactly: dark at 0.1 for most of the cycle,
   a fast double-width flash between 89% and 93%, then back down. The strobe
   sits 1.6s off the beacon so the two never flash together. */
@keyframes lm-blink { 0%, 86% { opacity: 0.1; } 89%, 93% { opacity: 1; } 100% { opacity: 0.1; } }
.lm-beacon     { animation: lm-blink 3.2s linear infinite; }
.lm-strobe     { animation: lm-blink 3.2s linear infinite -1.6s; }
.lm-tail-light { animation: lm-blink 4.4s linear infinite; }

/* The airship's whole body pitches and floats on one 16s swing. */
@keyframes lm-as-pitch { 0%, 100% { transform: rotate(-0.8deg); } 50% { transform: rotate(0.8deg); } }
@keyframes lm-as-float { 0%, 100% { transform: translateY(2px); } 50% { transform: translateY(-4px); } }
.lm-as-pitch { animation: lm-as-pitch 16s ease-in-out infinite; }
.lm-as-float { animation: lm-as-float 16s ease-in-out infinite; }

/* Lanterns. Drift is a sine, so it starts at the MIDDLE of its travel rather
   than 9pt off to one side. The sway is the sheet's own slight asymmetry,
   -6 to +7 degrees. The flicker scales the glow and never its opacity, which is
   the day/night dial and nothing else's to touch. */
@keyframes lm-lt-drift {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(var(--lm-drift, 9px)); }
  75%      { transform: translateX(calc(-1 * var(--lm-drift, 9px))); }
}
@keyframes lm-lt-sway    { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(7deg); } }
@keyframes lm-lt-flicker { 0%, 100% { transform: scale(1); } 50% { transform: scale(0.9); } }
.lm-lt-drift   { animation: lm-lt-drift ease-in-out infinite; }
.lm-lt-sway    { animation: lm-lt-sway ease-in-out infinite; }
.lm-lt-flicker { animation: lm-lt-flicker ease-in-out infinite; }


/* The sky is tappable, so say so. */
.sky-host { cursor: pointer; }




/* Under reduced motion the renderer never attaches these classes in the first
   place. It draws a chosen composition instead: clouds parked at spread
   positions, stars at the bright end of their twinkle, one puff of smoke at
   rest. This block is the belt to that braces, in case a class ever survives. */
@media (prefers-reduced-motion: reduce) {
  .lmcl, .lmtw, .lm-fl, .lm-fl2, .lm-sm, .lm-sm2, .lm-sm3,
  .lm-fly, .lm-bob, .lm-flap, .lm-sway, .lm-breathe,
  .lm-kite, .lm-kite-tail, .lm-twinkle, .lm-bob-slow,
  .lm-beacon, .lm-strobe, .lm-tail-light, .lm-as-pitch, .lm-as-float,
  .lm-lt-drift, .lm-lt-sway, .lm-lt-flicker { animation: none !important; }
}

/* ---- a section that carries a sky ---- */

.sky-host { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* Ink follows the sky. It is a hard switch at the halfway point between two
   anchors, never a fade, because a half-faded label is unreadable at every
   brightness. The ~1s transition carries it across; the switch itself is
   already decided by then. */
.sky-lit {
  --sky-ink: #FFF1E4;
  --sky-ink-soft: rgba(255, 241, 228, 0.78);
  --sky-ink-faint: rgba(255, 241, 228, 0.62);
  --sky-chip-bg: rgba(255, 255, 255, 0.42);
  --sky-chip-border: rgba(60, 50, 70, 0.14);
  --sky-shadow: none;
  color: var(--sky-ink);
  transition: color 1s ease;
}
