/* uwu.kim — ambient background: falling comets + twinkling stars.
 *
 * Shared by the landing page, /home and the admin pages, so it lives here
 * rather than being duplicated into three stylesheets.
 *
 * Visibility is gated on `.entered` on <body>:
 *   landing page — app.js adds it once the visitor is through the loader, so
 *                  none of this runs during the boot or loading screens.
 *   home / admin — the markup ships with class="entered" already set, since
 *                  there's no boot sequence to wait for.
 *
 * Must be linked AFTER style.css on the landing page: that file has a blanket
 * prefers-reduced-motion rule using !important, and the override at the bottom
 * here only wins if it comes later in source order.
 */

.sky {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.entered .sky { display: block; }

/* ------------------------------- COMETS -------------------------------- */
.comet {
  position: absolute;
  white-space: nowrap;
  font-family: var(--mono, ui-monospace, Consolas, monospace);
  font-size: clamp(10px, 1.5vw, 14px);
  letter-spacing: 0.16em;
  opacity: 0;
  will-change: transform, opacity;
  animation-name: cometFall;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-duration: var(--dur, 26s);
}

.comet__tail { opacity: 0.45; }
.comet__head { margin-left: 0.35em; }

.comet--1 { top: -14%; left:  6%; --dur: 24s; animation-delay:  1s; color: var(--pink, #ff6ac1); }
.comet--2 { top: -18%; left: 34%; --dur: 29s; animation-delay:  6s; color: var(--cyan, #5ef1e8); }
.comet--3 { top: -10%; left: 62%; --dur: 26s; animation-delay: 11s; color: var(--pink, #ff6ac1); }
.comet--4 { top: -20%; left: 18%; --dur: 31s; animation-delay: 16s; color: var(--cyan, #5ef1e8); }
.comet--5 { top: -12%; left: 78%; --dur: 27s; animation-delay: 20s; color: var(--pink, #ff6ac1); }
.comet--6 { top: -16%; left: 48%; --dur: 33s; animation-delay: 25s; color: var(--cyan, #5ef1e8); }

/* Steep downward fall. BOTH axes are in vh on purpose: mixing vw and vh makes
   the angle change with window shape, and then the rotation below no longer
   lines up with the direction of travel. Keep them both vh.
   70vh across / 110vh down => atan(110/70) ≈ 57.5deg, which is what the
   rotate() matches so the tail trails properly behind the head. */
@keyframes cometFall {
  0%   { transform: translate3d(0, 0, 0) rotate(57.5deg); opacity: 0; }
  4%   { opacity: 0.85; }
  20%  { opacity: 0.85; }
  26%  { transform: translate3d(70vh, 110vh, 0) rotate(57.5deg); opacity: 0; }
  100% { transform: translate3d(70vh, 110vh, 0) rotate(57.5deg); opacity: 0; }
}

/* -------------------------------- STARS -------------------------------- */
/* Stars sit in their own masked layer, comets don't.
 *
 * A star is static, so one sitting half-under an opaque card edge looks like a
 * bug — it reads as a sliced glyph, not as depth. (The z-index is fine: .sky is
 * 0 and every other body child is 1. This is about occlusion, not stacking.)
 * A comet is in motion and passes behind content in a fraction of a second,
 * which reads as exactly what it is, so comets are left alone.
 *
 * The mask fades the star layer out across the centre column where the content
 * lives, leaving them to the gutters either side. Because the gutter is derived
 * from the viewport rather than hardcoded, it degrades on its own: on a narrow
 * window the gutter collapses, every stop clamps, and the layer goes fully
 * transparent — no stars at all, rather than clipped ones.
 *
 * --sky-col is the widest content column on any page that uses this file
 * (the landing page's 780px; /home's is 720px), plus breathing room.
 *
 * The admin pages opt out of stars entirely — their grid is full-width, so
 * there's no gutter for the mask to leave them in. See admin.css. */
.sky__stars {
  position: absolute;
  inset: 0;
  --sky-col: 800px;
  --sky-edge: calc((100% - var(--sky-col)) / 2);
  -webkit-mask-image: linear-gradient(to right,
    #000 0,
    #000 calc(var(--sky-edge) - 40px),
    transparent var(--sky-edge),
    transparent calc(100% - var(--sky-edge)),
    #000 calc(100% - var(--sky-edge) + 40px),
    #000 100%);
  mask-image: linear-gradient(to right,
    #000 0,
    #000 calc(var(--sky-edge) - 40px),
    transparent var(--sky-edge),
    transparent calc(100% - var(--sky-edge)),
    #000 calc(100% - var(--sky-edge) + 40px),
    #000 100%);
}

.star {
  position: absolute;
  font-family: var(--mono, ui-monospace, Consolas, monospace);
  /* --sz varies size per star, so the field reads with some depth instead of
     as one flat layer of identical glyphs.
   *
   * The clamp scales with the viewport, and the 16px ceiling matters. It used
   * to cap at 12px, which is fine at 1080p and nearly invisible on a 4K panel:
   * the star COUNT is fixed, so a bigger screen spreads the same field over
   * more area. Measured, the density fell from ~6 lit per megapixel at 1440p to
   * ~3 at 2160p while each glyph stayed 12px, and the effect read as "the stars
   * don't work here" rather than as "the stars are small".
   * Growing the glyph is the right lever rather than adding stars: more stars
   * would fix 4K and make a laptop screen look like static. */
  font-size: calc(var(--sz, 1) * clamp(8px, 0.45vw, 16px));
  opacity: 0;
  /* No will-change here on purpose. It's right for the six comets, but there
     are 140 stars — promoting each to its own compositor layer costs far more
     than it saves for a glyph that only fades. */
  animation-name: twinkle;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-duration: var(--dur, 30s);
}

/* A glimmer near the end of a long cycle, rather than a slow pulse across it —
   so each star is dark most of the time and no two are ever breathing in
   unison. The 18% window is worth understanding before changing it: how many
   stars are lit at any moment is (star count x this window), so shortening it
   thins the whole sky out fast — at 6% the field read as empty even with 34
   stars. 18% of a 15-59s cycle is a 2.7-10.6s fade in and out, gentle enough to
   stay ambient, and against 140 stars it keeps roughly 25 alight at once.
   Note the interplay: long intervals are the look Kim asked for, but they make
   each individual star rare, so density has to come from the count. Raising the
   count is the safe knob; shortening the durations changes the character. */
@keyframes twinkle {
  0%, 82%, 100% { opacity: 0;                 transform: scale(0.5); }
  91%           { opacity: var(--peak, 0.75); transform: scale(1); }
}

/* ---------------------- GENERATED — DO NOT HAND-EDIT ----------------------
   140 rules, produced by a seeded generator rather than written by hand. Same
   seed gives the same field, so regenerating is reproducible. Editing one rule
   in place is fine for a one-off tweak, but anything structural (count,
   spacing, the bands below) should change the generator and be re-run, or the
   two will drift apart. The count must stay in step with STAR_COUNT in
   worker/src/sky.js and the span list in public/index.html.

   The generator's rules:
   - top stays within 16-93%. The 16% floor clears the opaque full-width sticky
     topbar on /home and /admin, which is the one piece of content the mask
     can't route around.
   - left is drawn from six bands — 1-13, 13-26, 26-38 and their mirrors —
     weighted 3:2:1 toward the screen edges. The mask trims inward from the
     content column, so edge stars are the ones that survive a narrow window;
     weighting that way means the field thins out rather than emptying.
   - no two stars land within 4.2 units of each other.
   - --sz varies 0.8-1.55 so the field has some depth.
   - roughly one in five gets a NEGATIVE animation-delay. This is the part that
     matters: a positive delay parks a star at phase 0 — dark — until it
     elapses, so with 15-59s intervals a page can open to a minute of empty
     sky. A negative delay starts the animation partway through its cycle
     instead, so the star is already mid-glimmer on first paint and then
     continues on its normal interval like any other. The value is
     -(phase x duration), drawn from phase 0.72-0.99: past 0.82 is inside the
     visible window (lit immediately), below it arrives a few seconds later, so
     they don't all announce themselves at once. Nothing else about the
     animation differs, so once the first cycle is out there's no telling which
     stars were seeded. */
.star--1   { top: 68%; left: 88.3%; --dur: 55.4s; --peak: .59; --sz: 1.03; animation-delay: 21.3s; color: var(--cyan, #5ef1e8); }
.star--2   { top: 55.2%; left: 93.6%; --dur: 28.5s; --peak: .86; --sz: 1.05; animation-delay: 9s; color: var(--cyan, #5ef1e8); }
.star--3   { top: 30.8%; left: 97.2%; --dur: 44.2s; --peak: .88; --sz: 1.37; animation-delay: 19.4s; color: var(--pink, #ff6ac1); }
.star--4   { top: 35.4%; left: 32.4%; --dur: 29.2s; --peak: .89; --sz: 1.29; animation-delay: 40.1s; color: var(--pink, #ff6ac1); }
.star--5   { top: 73.3%; left: 88.8%; --dur: 17.2s; --peak: .67; --sz: 1.42; animation-delay: 5.1s; color: var(--pink, #ff6ac1); }
.star--6   { top: 36.5%; left: 5.7%; --dur: 42.8s; --peak: .57; --sz: 1.51; animation-delay: -32.4s; color: var(--cyan, #5ef1e8); }
.star--7   { top: 63.9%; left: 21.8%; --dur: 22.9s; --peak: .84; --sz: 1.18; animation-delay: 28.8s; color: var(--cyan, #5ef1e8); }
.star--8   { top: 26.7%; left: 64.9%; --dur: 58.1s; --peak: .84; --sz: 1.53; animation-delay: 7s; color: var(--cyan, #5ef1e8); }
.star--9   { top: 87.3%; left: 8%; --dur: 22s; --peak: .62; --sz: 0.96; animation-delay: 32.5s; color: var(--pink, #ff6ac1); }
.star--10  { top: 29%; left: 75%; --dur: 24.5s; --peak: .69; --sz: 0.88; animation-delay: 30.6s; color: var(--cyan, #5ef1e8); }
.star--11  { top: 63.3%; left: 91.2%; --dur: 15.1s; --peak: .58; --sz: 1.29; animation-delay: 32s; color: var(--pink, #ff6ac1); }
.star--12  { top: 44.3%; left: 90%; --dur: 44.6s; --peak: .76; --sz: 1.48; animation-delay: 1.2s; color: var(--pink, #ff6ac1); }
.star--13  { top: 41.9%; left: 84.2%; --dur: 27.5s; --peak: .81; --sz: 1.20; animation-delay: 33.3s; color: var(--pink, #ff6ac1); }
.star--14  { top: 17.2%; left: 5.5%; --dur: 16.5s; --peak: .72; --sz: 1.49; animation-delay: 39.8s; color: var(--pink, #ff6ac1); }
.star--15  { top: 69.6%; left: 7.8%; --dur: 27.1s; --peak: .76; --sz: 0.89; animation-delay: 43.4s; color: var(--pink, #ff6ac1); }
.star--16  { top: 50.4%; left: 6%; --dur: 46.3s; --peak: .57; --sz: 1.09; animation-delay: -45.3s; color: var(--pink, #ff6ac1); }
.star--17  { top: 25.4%; left: 25.2%; --dur: 49.4s; --peak: .63; --sz: 1.39; animation-delay: -36.5s; color: var(--pink, #ff6ac1); }
.star--18  { top: 47.3%; left: 65.5%; --dur: 47.7s; --peak: .61; --sz: 1.50; animation-delay: 51s; color: var(--pink, #ff6ac1); }
.star--19  { top: 58.2%; left: 3.9%; --dur: 32s; --peak: .70; --sz: 1.25; animation-delay: 7.5s; color: var(--pink, #ff6ac1); }
.star--20  { top: 77.1%; left: 91.2%; --dur: 41.2s; --peak: .73; --sz: 1.33; animation-delay: 53.8s; color: var(--pink, #ff6ac1); }
.star--21  { top: 83.2%; left: 1%; --dur: 31.5s; --peak: .75; --sz: 1.24; animation-delay: -27.3s; color: var(--cyan, #5ef1e8); }
.star--22  { top: 77.3%; left: 11.2%; --dur: 19.3s; --peak: .62; --sz: 1.45; animation-delay: 7.9s; color: var(--pink, #ff6ac1); }
.star--23  { top: 52.4%; left: 15.3%; --dur: 17.8s; --peak: .81; --sz: 1.25; animation-delay: -17.1s; color: var(--cyan, #5ef1e8); }
.star--24  { top: 20.8%; left: 70.1%; --dur: 35.9s; --peak: .65; --sz: 1.39; animation-delay: 33.3s; color: var(--pink, #ff6ac1); }
.star--25  { top: 22.4%; left: 19.8%; --dur: 35.4s; --peak: .66; --sz: 0.92; animation-delay: -33.6s; color: var(--pink, #ff6ac1); }
.star--26  { top: 60.7%; left: 75.9%; --dur: 21.9s; --peak: .70; --sz: 0.96; animation-delay: -15.8s; color: var(--cyan, #5ef1e8); }
.star--27  { top: 83.9%; left: 92.7%; --dur: 16.3s; --peak: .67; --sz: 1.26; animation-delay: 29.8s; color: var(--pink, #ff6ac1); }
.star--28  { top: 88.7%; left: 22.7%; --dur: 30.1s; --peak: .82; --sz: 0.83; animation-delay: 33.3s; color: var(--cyan, #5ef1e8); }
.star--29  { top: 51.3%; left: 25.4%; --dur: 52.9s; --peak: .86; --sz: 1.30; animation-delay: 39.4s; color: var(--pink, #ff6ac1); }
.star--30  { top: 48.1%; left: 92.5%; --dur: 31.1s; --peak: .77; --sz: 1.51; animation-delay: 49.6s; color: var(--cyan, #5ef1e8); }
.star--31  { top: 37.1%; left: 76.7%; --dur: 31s; --peak: .70; --sz: 1.32; animation-delay: 33s; color: var(--pink, #ff6ac1); }
.star--32  { top: 24.9%; left: 77.5%; --dur: 55.5s; --peak: .73; --sz: 0.98; animation-delay: -40.5s; color: var(--cyan, #5ef1e8); }
.star--33  { top: 26.5%; left: 95.8%; --dur: 49s; --peak: .87; --sz: 1.33; animation-delay: -42.6s; color: var(--pink, #ff6ac1); }
.star--34  { top: 19.8%; left: 77.9%; --dur: 27.3s; --peak: .61; --sz: 1.37; animation-delay: 48.1s; color: var(--pink, #ff6ac1); }
.star--35  { top: 26%; left: 30.2%; --dur: 45.9s; --peak: .85; --sz: 0.98; animation-delay: -37.5s; color: var(--pink, #ff6ac1); }
.star--36  { top: 33.3%; left: 10.6%; --dur: 43.9s; --peak: .79; --sz: 1.33; animation-delay: 46.5s; color: var(--cyan, #5ef1e8); }
.star--37  { top: 31.8%; left: 79.6%; --dur: 43.7s; --peak: .65; --sz: 0.90; animation-delay: 7.2s; color: var(--cyan, #5ef1e8); }
.star--38  { top: 41.1%; left: 15.5%; --dur: 55.8s; --peak: .89; --sz: 0.97; animation-delay: 54.2s; color: var(--cyan, #5ef1e8); }
.star--39  { top: 81.8%; left: 76.3%; --dur: 42.2s; --peak: .84; --sz: 1.30; animation-delay: -38.9s; color: var(--cyan, #5ef1e8); }
.star--40  { top: 17.1%; left: 13.8%; --dur: 54.6s; --peak: .79; --sz: 1.24; animation-delay: 10.1s; color: var(--pink, #ff6ac1); }
.star--41  { top: 27.5%; left: 37.6%; --dur: 38.9s; --peak: .69; --sz: 1.22; animation-delay: -36s; color: var(--cyan, #5ef1e8); }
.star--42  { top: 79%; left: 20.7%; --dur: 15.6s; --peak: .84; --sz: 1.13; animation-delay: 14.1s; color: var(--pink, #ff6ac1); }
.star--43  { top: 21.4%; left: 88.2%; --dur: 52.4s; --peak: .86; --sz: 1.35; animation-delay: -44.8s; color: var(--pink, #ff6ac1); }
.star--44  { top: 19.9%; left: 64.8%; --dur: 28s; --peak: .84; --sz: 1.39; animation-delay: 7.8s; color: var(--cyan, #5ef1e8); }
.star--45  { top: 47.1%; left: 17.2%; --dur: 37.2s; --peak: .79; --sz: 1.26; animation-delay: -35.6s; color: var(--cyan, #5ef1e8); }
.star--46  { top: 69.4%; left: 3.1%; --dur: 49.9s; --peak: .74; --sz: 1.41; animation-delay: 53.7s; color: var(--pink, #ff6ac1); }
.star--47  { top: 76.2%; left: 96.3%; --dur: 51.9s; --peak: .87; --sz: 1.48; animation-delay: -47.8s; color: var(--pink, #ff6ac1); }
.star--48  { top: 23.9%; left: 9.5%; --dur: 47.3s; --peak: .82; --sz: 1.13; animation-delay: 38.4s; color: var(--cyan, #5ef1e8); }
.star--49  { top: 79.5%; left: 5.2%; --dur: 25.8s; --peak: .62; --sz: 1.12; animation-delay: 37.4s; color: var(--pink, #ff6ac1); }
.star--50  { top: 34.2%; left: 25.3%; --dur: 32.2s; --peak: .64; --sz: 0.94; animation-delay: 27.1s; color: var(--pink, #ff6ac1); }
.star--51  { top: 41.8%; left: 97.2%; --dur: 39.1s; --peak: .88; --sz: 1.38; animation-delay: 54.4s; color: var(--cyan, #5ef1e8); }
.star--52  { top: 75.3%; left: 23%; --dur: 31.7s; --peak: .66; --sz: 1.03; animation-delay: 41s; color: var(--pink, #ff6ac1); }
.star--53  { top: 63.6%; left: 4.3%; --dur: 56.4s; --peak: .58; --sz: 1.36; animation-delay: 37.6s; color: var(--pink, #ff6ac1); }
.star--54  { top: 38.4%; left: 80.8%; --dur: 55.5s; --peak: .70; --sz: 1.41; animation-delay: -52.3s; color: var(--pink, #ff6ac1); }
.star--55  { top: 73.3%; left: 14.7%; --dur: 52.8s; --peak: .79; --sz: 0.97; animation-delay: 46.6s; color: var(--cyan, #5ef1e8); }
.star--56  { top: 88.2%; left: 84.5%; --dur: 54.5s; --peak: .69; --sz: 1.40; animation-delay: 0.4s; color: var(--pink, #ff6ac1); }
.star--57  { top: 61.5%; left: 80.8%; --dur: 17s; --peak: .81; --sz: 1.33; animation-delay: 42.4s; color: var(--pink, #ff6ac1); }
.star--58  { top: 46.2%; left: 80.1%; --dur: 36.1s; --peak: .59; --sz: 1.26; animation-delay: 8.4s; color: var(--cyan, #5ef1e8); }
.star--59  { top: 49.5%; left: 11.8%; --dur: 38.4s; --peak: .72; --sz: 1.11; animation-delay: 23.4s; color: var(--cyan, #5ef1e8); }
.star--60  { top: 37.6%; left: 90.2%; --dur: 26.9s; --peak: .72; --sz: 1.31; animation-delay: 33s; color: var(--cyan, #5ef1e8); }
.star--61  { top: 39.9%; left: 25.8%; --dur: 47.3s; --peak: .66; --sz: 1.25; animation-delay: -40.4s; color: var(--cyan, #5ef1e8); }
.star--62  { top: 58.3%; left: 97.9%; --dur: 23.2s; --peak: .62; --sz: 0.87; animation-delay: 43.6s; color: var(--cyan, #5ef1e8); }
.star--63  { top: 17.6%; left: 84.1%; --dur: 53.5s; --peak: .71; --sz: 1.01; animation-delay: -45.1s; color: var(--pink, #ff6ac1); }
.star--64  { top: 54.1%; left: 79.9%; --dur: 53.7s; --peak: .90; --sz: 1.15; animation-delay: 35s; color: var(--pink, #ff6ac1); }
.star--65  { top: 26.5%; left: 90%; --dur: 51.3s; --peak: .74; --sz: 0.81; animation-delay: 43.5s; color: var(--cyan, #5ef1e8); }
.star--66  { top: 46.3%; left: 72.3%; --dur: 37.1s; --peak: .88; --sz: 1.55; animation-delay: -32s; color: var(--pink, #ff6ac1); }
.star--67  { top: 89.9%; left: 16.9%; --dur: 36.7s; --peak: .67; --sz: 1.37; animation-delay: 47.4s; color: var(--cyan, #5ef1e8); }
.star--68  { top: 80.6%; left: 70.4%; --dur: 44.7s; --peak: .68; --sz: 1.31; animation-delay: -39.2s; color: var(--cyan, #5ef1e8); }
.star--69  { top: 51%; left: 69.4%; --dur: 21.7s; --peak: .70; --sz: 1.22; animation-delay: 13.9s; color: var(--pink, #ff6ac1); }
.star--70  { top: 74.9%; left: 62.7%; --dur: 48.3s; --peak: .85; --sz: 1.19; animation-delay: 5s; color: var(--pink, #ff6ac1); }
.star--71  { top: 31.7%; left: 3.6%; --dur: 54.9s; --peak: .63; --sz: 0.99; animation-delay: 27.5s; color: var(--cyan, #5ef1e8); }
.star--72  { top: 45%; left: 22.1%; --dur: 18.4s; --peak: .88; --sz: 1.48; animation-delay: -14.1s; color: var(--cyan, #5ef1e8); }
.star--73  { top: 18%; left: 19%; --dur: 40.5s; --peak: .61; --sz: 1.48; animation-delay: 15s; color: var(--pink, #ff6ac1); }
.star--74  { top: 43.8%; left: 8%; --dur: 53.7s; --peak: .90; --sz: 1.27; animation-delay: -41.2s; color: var(--cyan, #5ef1e8); }
.star--75  { top: 33.3%; left: 86.9%; --dur: 58.4s; --peak: .69; --sz: 1.24; animation-delay: 32.9s; color: var(--cyan, #5ef1e8); }
.star--76  { top: 92.1%; left: 6.6%; --dur: 40.3s; --peak: .62; --sz: 0.85; animation-delay: 50.1s; color: var(--cyan, #5ef1e8); }
.star--77  { top: 17.7%; left: 35.1%; --dur: 26.2s; --peak: .76; --sz: 0.83; animation-delay: 33.7s; color: var(--pink, #ff6ac1); }
.star--78  { top: 24.4%; left: 4%; --dur: 28.3s; --peak: .86; --sz: 0.97; animation-delay: 20.2s; color: var(--pink, #ff6ac1); }
.star--79  { top: 66.2%; left: 97.2%; --dur: 50s; --peak: .71; --sz: 1.22; animation-delay: 31.4s; color: var(--cyan, #5ef1e8); }
.star--80  { top: 33%; left: 68.6%; --dur: 30.8s; --peak: .78; --sz: 1.41; animation-delay: 49.4s; color: var(--pink, #ff6ac1); }
.star--81  { top: 82.2%; left: 83.8%; --dur: 19.6s; --peak: .90; --sz: 1.29; animation-delay: -15.8s; color: var(--pink, #ff6ac1); }
.star--82  { top: 62.9%; left: 66.7%; --dur: 54.6s; --peak: .83; --sz: 0.96; animation-delay: 34.2s; color: var(--cyan, #5ef1e8); }
.star--83  { top: 75%; left: 31.4%; --dur: 35s; --peak: .56; --sz: 1.07; animation-delay: 26.7s; color: var(--pink, #ff6ac1); }
.star--84  { top: 19.7%; left: 97.2%; --dur: 48.8s; --peak: .90; --sz: 1.09; animation-delay: 33.1s; color: var(--pink, #ff6ac1); }
.star--85  { top: 58.9%; left: 64.2%; --dur: 47.3s; --peak: .66; --sz: 1.43; animation-delay: -41.6s; color: var(--pink, #ff6ac1); }
.star--86  { top: 76.8%; left: 81.3%; --dur: 55.4s; --peak: .62; --sz: 1.38; animation-delay: -47.5s; color: var(--pink, #ff6ac1); }
.star--87  { top: 54.1%; left: 66%; --dur: 20.7s; --peak: .67; --sz: 0.81; animation-delay: 3s; color: var(--cyan, #5ef1e8); }
.star--88  { top: 68%; left: 19.9%; --dur: 35.4s; --peak: .65; --sz: 1.37; animation-delay: 8s; color: var(--pink, #ff6ac1); }
.star--89  { top: 56.7%; left: 11.6%; --dur: 47.8s; --peak: .67; --sz: 1.07; animation-delay: 22.5s; color: var(--cyan, #5ef1e8); }
.star--90  { top: 33.3%; left: 62.7%; --dur: 53.1s; --peak: .61; --sz: 1.10; animation-delay: 0.7s; color: var(--pink, #ff6ac1); }
.star--91  { top: 29.3%; left: 11.8%; --dur: 57.8s; --peak: .86; --sz: 1.15; animation-delay: 34.4s; color: var(--cyan, #5ef1e8); }
.star--92  { top: 63.1%; left: 27.9%; --dur: 26.5s; --peak: .68; --sz: 0.92; animation-delay: 14.1s; color: var(--pink, #ff6ac1); }
.star--93  { top: 63.9%; left: 14.2%; --dur: 57.7s; --peak: .59; --sz: 1.17; animation-delay: -44.6s; color: var(--pink, #ff6ac1); }
.star--94  { top: 66.5%; left: 77.5%; --dur: 58.9s; --peak: .88; --sz: 0.88; animation-delay: 0.4s; color: var(--pink, #ff6ac1); }
.star--95  { top: 56.2%; left: 25.1%; --dur: 31.3s; --peak: .67; --sz: 1.41; animation-delay: 4.8s; color: var(--pink, #ff6ac1); }
.star--96  { top: 86.1%; left: 77.1%; --dur: 30.8s; --peak: .58; --sz: 1.24; animation-delay: 9s; color: var(--cyan, #5ef1e8); }
.star--97  { top: 87.4%; left: 97.3%; --dur: 27.6s; --peak: .66; --sz: 1.38; animation-delay: 9.9s; color: var(--cyan, #5ef1e8); }
.star--98  { top: 83.5%; left: 36.5%; --dur: 20.7s; --peak: .88; --sz: 1.01; animation-delay: 18s; color: var(--cyan, #5ef1e8); }
.star--99  { top: 47.3%; left: 2.2%; --dur: 55s; --peak: .59; --sz: 0.98; animation-delay: 15.2s; color: var(--pink, #ff6ac1); }
.star--100 { top: 31.8%; left: 15.6%; --dur: 54.6s; --peak: .82; --sz: 1.05; animation-delay: -48.3s; color: var(--pink, #ff6ac1); }
.star--101 { top: 83.6%; left: 18.8%; --dur: 44s; --peak: .56; --sz: 0.82; animation-delay: 29.5s; color: var(--cyan, #5ef1e8); }
.star--102 { top: 42.1%; left: 32.5%; --dur: 58.6s; --peak: .56; --sz: 1.26; animation-delay: 25.6s; color: var(--pink, #ff6ac1); }
.star--103 { top: 34.1%; left: 20.1%; --dur: 54.1s; --peak: .59; --sz: 1.55; animation-delay: 31.6s; color: var(--pink, #ff6ac1); }
.star--104 { top: 49.9%; left: 85.1%; --dur: 28.3s; --peak: .86; --sz: 0.90; animation-delay: 32.8s; color: var(--pink, #ff6ac1); }
.star--105 { top: 63%; left: 85.5%; --dur: 54.6s; --peak: .69; --sz: 0.84; animation-delay: 36.7s; color: var(--cyan, #5ef1e8); }
.star--106 { top: 16.9%; left: 89.2%; --dur: 23.3s; --peak: .66; --sz: 0.93; animation-delay: 38.8s; color: var(--pink, #ff6ac1); }
.star--107 { top: 70.5%; left: 80.2%; --dur: 41.4s; --peak: .89; --sz: 0.94; animation-delay: 18.8s; color: var(--cyan, #5ef1e8); }
.star--108 { top: 28.3%; left: 20.2%; --dur: 17.6s; --peak: .82; --sz: 0.98; animation-delay: -13.2s; color: var(--cyan, #5ef1e8); }
.star--109 { top: 36.9%; left: 95.4%; --dur: 36.5s; --peak: .61; --sz: 1.30; animation-delay: 20.9s; color: var(--cyan, #5ef1e8); }
.star--110 { top: 81%; left: 97.8%; --dur: 57.8s; --peak: .79; --sz: 0.96; animation-delay: 47s; color: var(--cyan, #5ef1e8); }
.star--111 { top: 74.6%; left: 4.2%; --dur: 55.8s; --peak: .56; --sz: 1.03; animation-delay: -50.1s; color: var(--cyan, #5ef1e8); }
.star--112 { top: 24.2%; left: 34.7%; --dur: 28.5s; --peak: .65; --sz: 1.39; animation-delay: 19.4s; color: var(--cyan, #5ef1e8); }
.star--113 { top: 75.8%; left: 73.5%; --dur: 58.6s; --peak: .79; --sz: 0.98; animation-delay: 43.9s; color: var(--cyan, #5ef1e8); }
.star--114 { top: 76.9%; left: 67.6%; --dur: 53.8s; --peak: .86; --sz: 1.18; animation-delay: 15.8s; color: var(--cyan, #5ef1e8); }
.star--115 { top: 25.3%; left: 16.3%; --dur: 48.1s; --peak: .86; --sz: 1.35; animation-delay: 52.4s; color: var(--pink, #ff6ac1); }
.star--116 { top: 56.4%; left: 71.1%; --dur: 53s; --peak: .76; --sz: 0.98; animation-delay: -39.3s; color: var(--pink, #ff6ac1); }
.star--117 { top: 58.9%; left: 30.7%; --dur: 32.3s; --peak: .66; --sz: 0.96; animation-delay: 8.5s; color: var(--pink, #ff6ac1); }
.star--118 { top: 42.6%; left: 1.9%; --dur: 44.8s; --peak: .69; --sz: 0.93; animation-delay: 4.9s; color: var(--cyan, #5ef1e8); }
.star--119 { top: 69.9%; left: 65.4%; --dur: 55.6s; --peak: .79; --sz: 0.85; animation-delay: 2.9s; color: var(--cyan, #5ef1e8); }
.star--120 { top: 89.4%; left: 32.9%; --dur: 29.5s; --peak: .71; --sz: 1.44; animation-delay: 23.2s; color: var(--pink, #ff6ac1); }
.star--121 { top: 47.6%; left: 30.8%; --dur: 41.4s; --peak: .59; --sz: 1.28; animation-delay: -40.7s; color: var(--pink, #ff6ac1); }
.star--122 { top: 41.7%; left: 63.2%; --dur: 37.6s; --peak: .66; --sz: 1.30; animation-delay: 12.7s; color: var(--cyan, #5ef1e8); }
.star--123 { top: 83.5%; left: 24.3%; --dur: 21.8s; --peak: .57; --sz: 1.41; animation-delay: 41.7s; color: var(--pink, #ff6ac1); }
.star--124 { top: 87.8%; left: 3.4%; --dur: 33.8s; --peak: .62; --sz: 1.27; animation-delay: 19.4s; color: var(--cyan, #5ef1e8); }
.star--125 { top: 35.7%; left: 37.6%; --dur: 58.7s; --peak: .60; --sz: 1.07; animation-delay: 54.1s; color: var(--pink, #ff6ac1); }
.star--126 { top: 86.3%; left: 71.5%; --dur: 47.5s; --peak: .87; --sz: 1.31; animation-delay: -35.6s; color: var(--cyan, #5ef1e8); }
.star--127 { top: 92%; left: 74.6%; --dur: 53.1s; --peak: .87; --sz: 1.05; animation-delay: 30.5s; color: var(--cyan, #5ef1e8); }
.star--128 { top: 47.4%; left: 98.7%; --dur: 28.3s; --peak: .74; --sz: 1.05; animation-delay: 10.3s; color: var(--pink, #ff6ac1); }
.star--129 { top: 58.3%; left: 84.7%; --dur: 33.1s; --peak: .56; --sz: 1.18; animation-delay: 2.7s; color: var(--cyan, #5ef1e8); }
.star--130 { top: 31.6%; left: 34.9%; --dur: 29.9s; --peak: .65; --sz: 0.89; animation-delay: -23.6s; color: var(--pink, #ff6ac1); }
.star--131 { top: 56.7%; left: 19.4%; --dur: 25.2s; --peak: .88; --sz: 1.42; animation-delay: 43.4s; color: var(--cyan, #5ef1e8); }
.star--132 { top: 53.7%; left: 2.6%; --dur: 33.3s; --peak: .70; --sz: 1.03; animation-delay: 10.3s; color: var(--cyan, #5ef1e8); }
.star--133 { top: 83.4%; left: 66.3%; --dur: 49.3s; --peak: .64; --sz: 1.35; animation-delay: 48s; color: var(--cyan, #5ef1e8); }
.star--134 { top: 69.4%; left: 28.8%; --dur: 16.9s; --peak: .66; --sz: 1.00; animation-delay: 17s; color: var(--cyan, #5ef1e8); }
.star--135 { top: 67%; left: 69.5%; --dur: 23.2s; --peak: .63; --sz: 1.22; animation-delay: 7.2s; color: var(--cyan, #5ef1e8); }
.star--136 { top: 52.3%; left: 98.3%; --dur: 55.2s; --peak: .70; --sz: 1.07; animation-delay: 15.3s; color: var(--pink, #ff6ac1); }
.star--137 { top: 86.3%; left: 30%; --dur: 39.7s; --peak: .80; --sz: 1.29; animation-delay: 17.6s; color: var(--pink, #ff6ac1); }
.star--138 { top: 50.2%; left: 36.8%; --dur: 48.3s; --peak: .78; --sz: 1.00; animation-delay: 30.1s; color: var(--pink, #ff6ac1); }
.star--139 { top: 59.8%; left: 8%; --dur: 39.2s; --peak: .70; --sz: 1.30; animation-delay: 11s; color: var(--cyan, #5ef1e8); }
.star--140 { top: 90.2%; left: 88.6%; --dur: 43.1s; --peak: .89; --sz: 1.47; animation-delay: -38.2s; color: var(--cyan, #5ef1e8); }

/* Kim's call: the flair stays visible for everyone, same decision as the
   crying face's tears. This is the most debatable of those exemptions —
   ambient looping motion is the textbook reduced-motion case — so if it ever
   needs gating, delete this block and both stop dead.
   !important is required to beat style.css's blanket * rule. */
@media (prefers-reduced-motion: reduce) {
  .comet {
    animation-duration: var(--dur, 26s) !important;
    animation-iteration-count: infinite !important;
  }
  .star {
    animation-duration: var(--dur, 30s) !important;
    animation-iteration-count: infinite !important;
  }
}
