/* ════════════════════════════════════════════════════════════════
   STARS SKY — full cosmos: galaxy spiral, nebulas, planets, comet,
   parallax layers, twinkling/drifting wish stars, quality tiers.

   Loaded only on /{locale}/donate (ru) when the sky enters viewport.
   Uses global CSS variables from app.css (--glass, --border, etc).
   ════════════════════════════════════════════════════════════════ */

/* Force [hidden] to win against later display:flex/block rules */
.dn-sky [hidden]{display:none!important}

.dn-sky{
    position:relative;width:100%;max-width:1100px;height:560px;margin:0 auto;
    border-radius:var(--radius-lg);
    background:
        radial-gradient(ellipse 80% 60% at 50% 20%,#1e1b4b 0%,#0c0a1f 40%,#020617 100%),
        #020617;
    border:1px solid rgba(99,102,241,.18);
    box-shadow:inset 0 0 80px rgba(59,130,246,.12),0 8px 30px rgba(0,0,0,.4);
    cursor:default;
    /* Clip with clip-path instead of overflow:hidden.
       clip-path only restricts the visual output of descendants —
       tooltips that live in body (portal) are unaffected and still
       overflow above/below the sky freely.
       Result: planets and stars stay neatly inside the sky frame
       without sacrificing tooltip overflow. */
    clip-path:inset(0 round var(--radius-lg));
}
/* Inner clipping wrapper for decorative layers that should NOT escape
   the sky frame (galaxy, nebulas, comet, bg stars). Tooltips and stars
   live outside this wrapper so they can extend past the sky edge. */
.dn-sky-clip{
    position:absolute;inset:0;
    border-radius:inherit;
    overflow:hidden;
    pointer-events:none;
}

/* Zoom + pan viewport (created by sky-zoom.js the first time it's loaded).
   All sky children are moved into this wrapper so we can scale/translate
   one element rather than five. transform-origin top-left so wheel zoom
   maths is straightforward. */
.dn-sky-viewport{
    position:absolute;inset:0;
    transform-origin:0 0;
    will-change:transform;
}
.dn-sky-reset{
    position:absolute;top:12px;right:12px;
    width:36px;height:36px;border-radius:50%;
    background:rgba(15,23,42,.85);
    border:1px solid rgba(251,191,36,.45);
    color:#fbbf24;font-size:18px;font-weight:700;cursor:pointer;
    z-index:30;display:flex;align-items:center;justify-content:center;
    backdrop-filter:blur(8px);
    transition:transform .2s,background .2s;
}
.dn-sky-reset:hover{background:rgba(251,191,36,.18);transform:scale(1.08)}
.dn-sky-reset[hidden]{display:none}

/* Solar flare layer (added inside Sun's <svg> by sky-flares.js) */
.dn-flare-layer{pointer-events:none}
[data-theme=light] .dn-sky{
    background:
        radial-gradient(ellipse 80% 60% at 50% 20%,#1e1b4b 0%,#0c0a1f 40%,#020617 100%),
        #020617;
}

/* Layered parallax containers.
   Sky-viewport carries the 3D perspective context; from-depth comets
   and the new planet-Z hooks (data-depth) use translateZ inside this
   context. Layer transforms are still 2D translate so mouse-parallax
   stays compatible. Depth feel comes from:
     • parallax speed (slow for far, fast for near — already in JS)
     • opacity step  (far layers slightly dimmer)
     • per-planet translateZ via [data-depth] attribute */
.dn-sky-viewport{transform-style:preserve-3d;perspective:1200px;perspective-origin:50% 50%}
.dn-sky-far,.dn-sky-mid,.dn-sky-planets,.dn-stars-layer,.dn-sky-constellations{
    position:absolute;inset:0;pointer-events:none;
    will-change:transform;transition:transform .25s cubic-bezier(.2,.7,.2,1);
}
.dn-sky-far          {opacity:.85}
.dn-sky-mid          {opacity:.95}
.dn-comet-layer      {position:absolute;inset:0;pointer-events:none;z-index:6}
/* Decorative layers no longer need their own overflow gate — the sky
   itself clip-paths everything inside. */
.dn-sky-planets{pointer-events:none}
.dn-sky-planets .dn-planet{pointer-events:auto}

/* Nebulas */
.dn-nebula{position:absolute;border-radius:50%;filter:blur(40px);opacity:.45;mix-blend-mode:screen}
.dn-nebula-1{width:340px;height:280px;top:-40px;left:-60px;background:radial-gradient(circle,rgba(139,92,246,.55),transparent 70%)}
.dn-nebula-2{width:420px;height:300px;bottom:-60px;right:-80px;background:radial-gradient(circle,rgba(236,72,153,.45),transparent 70%);opacity:.35}
.dn-nebula-3{width:260px;height:240px;top:30%;left:40%;background:radial-gradient(circle,rgba(34,211,238,.4),transparent 70%);opacity:.3}

/* Galaxy band — three depth layers (back / mid / front) for richer
   parallax. Each layer has:
     • A SHARED tile rotation animation (slow, ~1h per cycle) — close
       to the real sidereal motion of the celestial sphere.
     • Its OWN slow horizontal drift via the parent layer container —
       different periods per depth (back drifts slowest, front fastest)
       so they don't move in lockstep. Combined with mouse parallax
       this gives a real sense of stars at different distances.
   Stars in our universe don't actually drift independently — but our
   "depth bins" simulate the parallax-from-distance effect for the
   user's eye. The closer a star, the bigger its perceived motion. */
.dn-sky-galaxy-layer{
    position:absolute;inset:0;pointer-events:none;
    transform:translate3d(0,0,0);
    will-change:transform;
}
.dn-galaxy{
    position:absolute;left:50%;top:50%;
    width:170%;height:170%;
    transform:translate(-50%,-50%) rotate(0);
    animation:dn-galaxy-rotate 3600s linear infinite;
    opacity:.85;mix-blend-mode:screen;
}
@keyframes dn-galaxy-rotate{from{transform:translate(-50%,-50%) rotate(0)}to{transform:translate(-50%,-50%) rotate(360deg)}}

/* Per-depth slow drift — gives the band a layered, "stars at different
   distances" feel even when the user isn't moving the mouse. Direction
   is east→west (left to right in our south-centred projection), matching
   real sidereal motion. Periods are sped up vs reality (24 h sidereal
   day) so the drift is perceptible — but the relative ratios back:mid:front
   = 5:3:2 keep the depth illusion physically sensible. */
.dn-galaxy-back  {animation:dn-galaxy-drift-back 3000s linear infinite}
.dn-galaxy-mid   {animation:dn-galaxy-drift-mid  1800s linear infinite}
.dn-galaxy-front {animation:dn-galaxy-drift-front 1200s linear infinite}
@keyframes dn-galaxy-drift-back{
    0%   {transform:translate3d(-2%, -1%, 0)}
    100% {transform:translate3d( 2%,  1%, 0)}
}
@keyframes dn-galaxy-drift-mid{
    0%   {transform:translate3d(-3.5%, -1.5%, 0)}
    100% {transform:translate3d( 3.5%,  1.5%, 0)}
}
@keyframes dn-galaxy-drift-front{
    0%   {transform:translate3d(-5%, -2%, 0)}
    100% {transform:translate3d( 5%,  2%, 0)}
}
.dn-galaxy-back  .dn-galaxy{opacity:.65}    /* dimmer = farther */
.dn-galaxy-mid   .dn-galaxy{opacity:.85}
.dn-galaxy-front .dn-galaxy{opacity:1}      /* brightest = nearest */

@media (prefers-reduced-motion:reduce){
    .dn-sky.dn-q-low .dn-galaxy,
    .dn-sky.dn-q-low .dn-galaxy-back,
    .dn-sky.dn-q-low .dn-galaxy-mid,
    .dn-sky.dn-q-low .dn-galaxy-front{animation:none}
}

/* Background star fields */
.dn-bgstars{position:absolute;inset:0;animation:dn-twinkle-bg 6s ease-in-out infinite}
.dn-bgstars-far{
    background-image:
        radial-gradient(1px 1px at 6% 12%,rgba(255,255,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 14% 30%,rgba(180,200,255,.65) 50%,transparent),
        radial-gradient(1px 1px at 22% 8%,rgba(255,255,255,.4) 50%,transparent),
        radial-gradient(1px 1px at 28% 25%,rgba(255,220,180,.55) 50%,transparent),
        radial-gradient(1px 1px at 34% 14%,rgba(255,255,255,.65) 50%,transparent),
        radial-gradient(1px 1px at 42% 6%,rgba(200,220,255,.5) 50%,transparent),
        radial-gradient(1px 1px at 48% 38%,rgba(255,255,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 56% 18%,rgba(255,240,200,.45) 50%,transparent),
        radial-gradient(1px 1px at 64% 32%,rgba(255,255,255,.6) 50%,transparent),
        radial-gradient(1px 1px at 70% 8%,rgba(180,200,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 76% 22%,rgba(255,255,255,.5) 50%,transparent),
        radial-gradient(1px 1px at 84% 36%,rgba(255,220,180,.5) 50%,transparent),
        radial-gradient(1px 1px at 92% 14%,rgba(255,255,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 96% 28%,rgba(200,220,255,.45) 50%,transparent),
        radial-gradient(1px 1px at 4% 50%,rgba(255,255,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 16% 62%,rgba(255,240,200,.5) 50%,transparent),
        radial-gradient(1px 1px at 26% 74%,rgba(255,255,255,.5) 50%,transparent),
        radial-gradient(1px 1px at 38% 86%,rgba(180,200,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 52% 92%,rgba(255,255,255,.5) 50%,transparent),
        radial-gradient(1px 1px at 70% 84%,rgba(255,220,180,.45) 50%,transparent),
        radial-gradient(1px 1px at 88% 70%,rgba(255,255,255,.55) 50%,transparent),
        radial-gradient(1px 1px at 94% 88%,rgba(200,220,255,.5) 50%,transparent);
}
.dn-bgstars-mid{
    background-image:
        radial-gradient(2px 2px at 18% 18%,#fff 40%,transparent 60%),
        radial-gradient(1.5px 1.5px at 36% 30%,#bfdbfe 40%,transparent 60%),
        radial-gradient(2px 2px at 58% 12%,#fff 40%,transparent 60%),
        radial-gradient(1.5px 1.5px at 72% 28%,#fef3c7 40%,transparent 60%),
        radial-gradient(2px 2px at 88% 16%,#fff 40%,transparent 60%),
        radial-gradient(2px 2px at 12% 56%,#fbcfe8 40%,transparent 60%),
        radial-gradient(1.5px 1.5px at 30% 70%,#fff 40%,transparent 60%),
        radial-gradient(2px 2px at 50% 82%,#bfdbfe 40%,transparent 60%),
        radial-gradient(1.5px 1.5px at 78% 70%,#fff 40%,transparent 60%),
        radial-gradient(2px 2px at 94% 56%,#fef3c7 40%,transparent 60%);
    animation-delay:.7s;
}
@keyframes dn-twinkle-bg{0%,100%{opacity:.7}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-bgstars{animation:none;opacity:.85}}

/* The old single CSS-keyframed comet is gone — sky-comets.js now
   spawns randomized comets via Web Animations API. */
.dn-comet{display:none}                            /* legacy element kept hidden */

/* Comet layer holds dynamically-created particles */
.dn-comet-layer{
    position:absolute;inset:0;
    pointer-events:none;
    overflow:visible;
}
/* Each particle = a head + linear-gradient tail painted via ::before.
   The tail extends in direction (--angle + 180deg) — i.e. opposite of
   motion — so the bright head leads and the tail trails behind. */
.dn-comet-particle{
    position:absolute;
    /* Head: bright nucleus + soft coma halo. Real comets have a fuzzy
       glowing coma 10–100× brighter than the tail surface brightness. */
    width:calc(6px * var(--head-scale, 1));
    height:calc(6px * var(--head-scale, 1));
    border-radius:50%;
    background:radial-gradient(circle,
        var(--col-core,#fff)    0%,
        var(--col-mid, #fef3c7) 50%,
        transparent             100%);
    box-shadow:
        0 0 10px 3px var(--col-mid,  #fef3c7),
        0 0 26px 8px var(--col-edge, #fbbf24);
    transform-origin:center;
    will-change:transform,opacity;
}
/* TAIL — TWO LAYERS for the wispy "dust trail" look of NEOWISE-class
   comets. Both layers share the same rotation (--angle) so they always
   point along the comet→anti-Sun direction set in JS.

   Layer 1 (::before): bright dense core, narrow, sharp.
   Layer 2 (::after):  diffuse halo, wider, heavier blur — gives the
                       fuzzy yellow plume seen on long-exposure photos. */
.dn-comet-particle::before,
.dn-comet-particle::after{
    content:"";position:absolute;
    right:50%;top:50%;
    transform-origin:right center;
    transform:translateY(-50%) rotate(var(--angle,0deg));
    pointer-events:none;
    /* Tapered tail via CSS clip-path: 1px wide at the head end (right
       edge of tail box), tapering linearly to ~9× wider at the far end.
       This gives the cone shape comet tails actually have, instead of a
       parallel stripe. */
    clip-path:polygon(100% 30%, 100% 70%, 0 100%, 0 0);
}
.dn-comet-particle::before{
    width:var(--tail-len, 140px);
    height:calc(6px * var(--head-scale, 1));
    background:linear-gradient(to left,
        var(--col-core, #fff)    0%,
        var(--col-mid,  #fef3c7) 18%,
        var(--col-edge, #fbbf24) 55%,
        transparent              100%);
    filter:blur(.5px);
    opacity:.95;
}
.dn-comet-particle::after{
    /* Halo: longer + wider + much softer */
    width:calc(var(--tail-len, 140px) * 1.15);
    height:calc(14px * var(--head-scale, 1));
    background:linear-gradient(to left,
        rgba(255,255,255,.8) 0%,
        var(--col-mid,  #fef3c7) 20%,
        var(--col-edge, #fbbf24) 65%,
        transparent              100%);
    filter:blur(4px);
    opacity:.55;
}
/* From-depth comets grow + glow more (camera approaches) */
.dn-comet-from-depth{
    box-shadow:0 0 10px 3px var(--col-mid,#fef3c7),
               0 0 24px 6px var(--col-edge,#fbbf24);
}
@media (prefers-reduced-motion:reduce){
    .dn-sky.dn-q-low .dn-comet-particle{display:none}
}

/* Constellation slots */
.dn-sky-constellations{position:absolute;inset:0;pointer-events:none}
/* Constellations are positioned in % by sky.js from live alt/az, and
   rotated by the parallactic angle so they tilt correctly near the
   horizon. The transition keeps the drift smooth between 5-min refreshes
   instead of teleporting. */
.dn-constellation{
    position:absolute;
    transform:translate(-50%,-50%) rotate(var(--const-rotation,0deg));
    pointer-events:none;
    transition:left 1.6s linear, top 1.6s linear,
               transform 1.6s linear, opacity .8s ease-out;
}
.dn-constellation.is-below-horizon{opacity:0;pointer-events:none}
.dn-constellation-svg{display:block;width:100%;height:100%;overflow:visible}
/* Outlines hidden; empty slots are completely invisible until lit. */
.dn-c-lines{display:none}
.dn-c-slot{opacity:0;transition:opacity .6s ease-in-out}
.dn-c-slot-glow,.dn-c-slot-shape{
    fill:var(--star-color,#fff);
}
.dn-c-slot-glow{
    filter:blur(.6px);
    opacity:.6;
}
.dn-c-slot.is-filled{
    opacity:1;pointer-events:auto;cursor:pointer;
    animation:dn-c-pulse var(--pulse-dur,4s) ease-in-out infinite;
    animation-delay:var(--pulse-delay,0s);
}
.dn-c-slot.is-filled.is-bright .dn-c-slot-glow{filter:blur(1.4px);opacity:.9}
.dn-c-slot.is-donor .dn-c-slot-glow,
.dn-c-slot.is-donor .dn-c-slot-shape{fill:#fde047}
.dn-c-slot.is-donor .dn-c-slot-glow{filter:blur(1.2px);opacity:.85}
.dn-c-slot.is-donor{
    fill:#fde047;
    filter:drop-shadow(0 0 4px rgba(253,224,71,.95))
           drop-shadow(0 0 10px rgba(253,224,71,.7))
           drop-shadow(0 0 20px rgba(253,224,71,.4));
}
@keyframes dn-c-pulse{0%,100%{opacity:.7}50%{opacity:1}}
@keyframes dn-slot-fly{
    0%   {transform:translate(0,300px) scale(.2);opacity:0}
    20%  {opacity:1}
    80%  {transform:translate(0,0) scale(2);opacity:1}
    100% {transform:translate(0,0) scale(1);opacity:1}
}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-c-slot.is-filled{animation:none;opacity:.92}}

/* Slot tooltip — when used as body-level portal (.dn-slot-tip-portal),
   absolute positioning is in page coordinates so it can escape any
   overflow:hidden boundary along its way. */
.dn-slot-tip{
    position:absolute;transform:translate(-50%,-100%);
    min-width:200px;max-width:280px;padding:10px 14px;
    background:rgba(15,23,42,.96);border:1px solid rgba(251,191,36,.4);
    border-radius:10px;color:#f1f5f9;font-size:12px;line-height:1.5;text-align:center;
    opacity:0;pointer-events:none;transition:opacity .15s;z-index:9999;
    backdrop-filter:blur(8px);box-shadow:0 8px 24px rgba(0,0,0,.5);
    word-break:break-word;
}
.dn-slot-tip.show{opacity:1}
@media (max-width:560px){
    .dn-slot-tip{max-width:calc(100vw - 24px);min-width:0;font-size:13px}
}
.dn-slot-tip-name{display:block;font-weight:700;color:#fff;font-size:13px;margin:0 0 3px}
.dn-slot-tip-msg{display:block;color:#cbd5e1;word-break:break-word}
.dn-slot-tip-amt{display:none;margin-top:5px;padding:2px 8px;background:rgba(251,191,36,.18);border-radius:99px;color:#fbbf24;font-weight:700;font-size:11px;font-variant-numeric:tabular-nums}

/* Planets */
.dn-planet{
    position:absolute;cursor:pointer;border-radius:50%;
    filter:drop-shadow(0 4px 14px rgba(0,0,0,.5));transition:filter .3s;
}
.dn-planet-svg{width:100%;height:100%;display:block;overflow:visible}
/* Spin the planet's visible content. Each non-Saturn planet now wraps its
   surface markup in <g class="dn-planet-disc"> in the blade — same idea as
   Saturn's existing .dn-planet-body. Animating a `<g>` group with
   transform-origin:center is rock-solid across browsers, unlike applying
   the same animation to the root <svg> (Chrome's transform-box:fill-box
   support on SVG roots is patchy). */
.dn-planet-disc{
    transform-box:fill-box;
    transform-origin:center;
    animation:dn-planet-spin var(--spin-dur,80s) linear infinite;
}
.dn-planet-saturn .dn-planet-body{
    transform-box:fill-box;transform-origin:center;
    animation:dn-planet-spin var(--spin-dur,9s) linear infinite;
}
.dn-planet-saturn .dn-planet-rings{animation:none}
@keyframes dn-planet-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
.dn-planet-jupiter .dn-planet-svg{--spin-dur:8s}
.dn-planet-saturn  .dn-planet-svg{--spin-dur:9s}
.dn-planet-neptune .dn-planet-svg{--spin-dur:13s;animation-direction:reverse}
.dn-planet-earth   .dn-planet-svg{--spin-dur:20s}
.dn-planet-mars    .dn-planet-svg{--spin-dur:20.5s}
.dn-planet-mercury .dn-planet-svg{--spin-dur:60s}
.dn-planet-sun     .dn-planet-svg{--spin-dur:50s}

/* Rotation axes — tilted by each planet's real obliquity. Visible only
   on hover/focus so they don't clutter the resting state. The line is
   a 1-px gradient pseudo-element, longer than the disc to suggest the
   axis extends through both poles. Source: NASA fact sheet 2024. */
.dn-planet::before{
    content:"";position:absolute;left:50%;top:-18%;
    width:2px;height:136%;
    background:linear-gradient(to bottom,
        rgba(96,165,250,0) 0%,
        rgba(96,165,250,.55) 12%,
        rgba(96,165,250,.85) 50%,
        rgba(96,165,250,.55) 88%,
        rgba(96,165,250,0) 100%);
    transform:translateX(-50%) rotate(var(--axis-tilt, 0deg));
    transform-origin:50% 50%;
    opacity:0;transition:opacity .25s;
    pointer-events:none;border-radius:2px;
}
.dn-planet:hover::before,
.dn-planet:focus::before,
.dn-planet.active::before{opacity:.7}
/* Real axial obliquities (NASA): Mercury 0.034° → effectively 0;
   Venus 177° (retrograde — appears upside-down); Mars 25.19°;
   Jupiter 3.13°; Saturn 26.73°; Uranus 97.77° (lying on its side);
   Neptune 28.32°; Moon 6.68°. Sun has its own ~7° tilt to ecliptic
   but we don't show an axis on it (looks weird on a glowing disc). */
.dn-planet-mercury{--axis-tilt:0deg}
.dn-planet-venus  {--axis-tilt:177deg}
.dn-planet-mars   {--axis-tilt:25deg}
.dn-planet-jupiter{--axis-tilt:3deg}
.dn-planet-saturn {--axis-tilt:27deg}
.dn-planet-uranus {--axis-tilt:98deg}
.dn-planet-neptune{--axis-tilt:28deg}
.dn-planet-moon   {--axis-tilt:7deg}
.dn-planet-sun::before{display:none}

.dn-earth-moon-orbit{
    transform-origin:50px 50px;
    animation:dn-moon-orbit 28s linear infinite;
}
@keyframes dn-moon-orbit{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-earth-moon-orbit{animation:none}}

.dn-planet-sun{animation:dn-orbit-sun 240s linear infinite}
@keyframes dn-orbit-sun{
    0%   {transform:translate(calc(-50% + 4px),calc(-50% + 0px))}
    25%  {transform:translate(calc(-50% + 0px),calc(-50% + 4px))}
    50%  {transform:translate(calc(-50% - 4px),calc(-50% + 0px))}
    75%  {transform:translate(calc(-50% + 0px),calc(-50% - 4px))}
    100% {transform:translate(calc(-50% + 4px),calc(-50% + 0px))}
}
.dn-planet-earth{animation:dn-orbit-earth 110s linear infinite}
@keyframes dn-orbit-earth{
    0%   {transform:translate(calc(-50% + 8px),calc(-50% + 0px))}
    25%  {transform:translate(calc(-50% + 0px),calc(-50% + 8px))}
    50%  {transform:translate(calc(-50% - 8px),calc(-50% + 0px))}
    75%  {transform:translate(calc(-50% + 0px),calc(-50% - 8px))}
    100% {transform:translate(calc(-50% + 8px),calc(-50% + 0px))}
}
.dn-planet-mercury{animation:dn-orbit-mercury 40s linear infinite}
.dn-planet-mars   {animation:dn-orbit-mars    65s linear infinite}
.dn-planet-jupiter{animation:dn-orbit-jupiter 100s linear infinite}
.dn-planet-saturn {animation:dn-orbit-saturn  140s linear infinite}
.dn-planet-neptune{animation:dn-orbit-neptune 200s linear infinite}

@keyframes dn-orbit-mercury{0%{transform:translate(calc(-50% + 6px),calc(-50% + 0px))}25%{transform:translate(calc(-50% + 0px),calc(-50% + 6px))}50%{transform:translate(calc(-50% - 6px),calc(-50% + 0px))}75%{transform:translate(calc(-50% + 0px),calc(-50% - 6px))}100%{transform:translate(calc(-50% + 6px),calc(-50% + 0px))}}
@keyframes dn-orbit-mars   {0%{transform:translate(calc(-50% + 7px),calc(-50% + 0px))}25%{transform:translate(calc(-50% + 0px),calc(-50% + 7px))}50%{transform:translate(calc(-50% - 7px),calc(-50% + 0px))}75%{transform:translate(calc(-50% + 0px),calc(-50% - 7px))}100%{transform:translate(calc(-50% + 7px),calc(-50% + 0px))}}
@keyframes dn-orbit-jupiter{0%{transform:translate(calc(-50% + 9px),calc(-50% + 0px))}25%{transform:translate(calc(-50% + 0px),calc(-50% + 9px))}50%{transform:translate(calc(-50% - 9px),calc(-50% + 0px))}75%{transform:translate(calc(-50% + 0px),calc(-50% - 9px))}100%{transform:translate(calc(-50% + 9px),calc(-50% + 0px))}}
@keyframes dn-orbit-saturn {0%{transform:translate(calc(-50% + 10px),calc(-50% + 0px))}25%{transform:translate(calc(-50% + 0px),calc(-50% + 10px))}50%{transform:translate(calc(-50% - 10px),calc(-50% + 0px))}75%{transform:translate(calc(-50% + 0px),calc(-50% - 10px))}100%{transform:translate(calc(-50% + 10px),calc(-50% + 0px))}}
@keyframes dn-orbit-neptune{0%{transform:translate(calc(-50% + 12px),calc(-50% + 0px))}25%{transform:translate(calc(-50% + 0px),calc(-50% + 12px))}50%{transform:translate(calc(-50% - 12px),calc(-50% + 0px))}75%{transform:translate(calc(-50% + 0px),calc(-50% - 12px))}100%{transform:translate(calc(-50% + 12px),calc(-50% + 0px))}}

.dn-planet:hover,.dn-planet:focus-visible,.dn-planet.active{
    animation-play-state:paused;
    filter:drop-shadow(0 4px 18px rgba(251,191,36,.55)) brightness(1.15);
    outline:none;
}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-planet,.dn-sky.dn-q-low .dn-planet-svg{animation:none}}

/* Planet tooltip */
.dn-planet-tip{
    position:absolute;left:50%;bottom:calc(100% + 12px);transform:translateX(-50%);
    min-width:200px;max-width:260px;padding:10px 14px;
    background:rgba(15,23,42,.96);border:1px solid rgba(251,191,36,.4);
    border-radius:10px;color:#f1f5f9;font-size:12px;line-height:1.5;text-align:center;
    opacity:0;pointer-events:none;transition:opacity .2s;z-index:8;
    backdrop-filter:blur(8px);box-shadow:0 8px 24px rgba(0,0,0,.5);
}
.dn-planet-tip strong{display:block;color:#fbbf24;font-size:13px;font-weight:700;margin:0 0 4px}
.dn-planet:hover .dn-planet-tip,.dn-planet:focus-visible .dn-planet-tip,.dn-planet.active .dn-planet-tip{opacity:1}

/* ─── 4-point sparkle stars ✦ ───
   Dual-path SVG (blurred glow underneath + sharp shape on top) so the
   ✦ silhouette is ALWAYS visible. Box-shadow blurs alone collapse the
   shape into a fuzzy disc at small sizes — this approach keeps the
   four points crisp at any zoom.
*/
.dn-star{
    position:absolute;left:calc(var(--x) * 1%);top:calc(var(--y) * 1%);
    width:var(--size,16px);height:var(--size,16px);
    transform:translate(-50%,-50%);
    cursor:pointer;pointer-events:auto;
    color:var(--c,#cad7ff);
    animation:
        var(--twinkle-anim,dn-twinkle) var(--twinkle-dur,3s) ease-in-out infinite,
        dn-star-shimmer 6s ease-in-out infinite alternate;
    animation-delay:var(--delay,0s),0s;
    transition:transform .2s;
}
.dn-star-svg{width:100%;height:100%;display:block;overflow:visible}
.dn-star-glow{
    fill:var(--c,#cad7ff);
    filter:blur(1.5px);
    opacity:.55;
}
.dn-star-shape{
    fill:var(--c,#cad7ff);
}
.dn-star.is-bright .dn-star-glow{
    filter:blur(3px);
    opacity:.85;
}
.dn-star.is-bright .dn-star-shape{
    fill:#fffef5;
}
@keyframes dn-star-shimmer{
    0%   {filter:hue-rotate(0deg)}
    100% {filter:hue-rotate(35deg)}
}
.dn-star.is-donor{--c:#fde047;--c2:#fbbf24;--size:20px}
.dn-star.is-donor .dn-star-glow{filter:blur(2.5px);opacity:.8}
.dn-star.is-donor.is-bright .dn-star-glow{filter:blur(4px);opacity:1}
.dn-star:hover,.dn-star.active{transform:translate(-50%,-50%) scale(1.4);z-index:6}

/* Stars stop animating only on Low quality (and only if OS asked for
   reduce-motion). High quality always animates. */
@media (prefers-reduced-motion:reduce){
    .dn-sky.dn-q-low .dn-star{animation:none}
}

/* Zoom-mode bokeh fix:
   When close-up, every blurred element becomes a fat circle. We drop
   ALL of them — galaxy spirals, nebulas, bg-stars AND star glows —
   and keep only the crisp planet/star silhouettes. */
/* On zoom: hide bgstar radial-gradients (they bokeh into ugly giant
   circles at any scale > 1) and the legacy .dn-comet element, but keep
   the procedural SVG galaxy visible — its r=0.05..0.18 dots stay tiny
   even at 4× zoom and give the depth the user expects. */
.dn-sky.dn-zoomed .dn-bgstars,
.dn-sky.dn-zoomed .dn-nebula,
.dn-sky.dn-zoomed .dn-comet{display:none}
.dn-sky.dn-zoomed .dn-star-glow{display:none}
.dn-sky.dn-zoomed .dn-c-slot.is-filled,
.dn-sky.dn-zoomed .dn-c-slot.is-filled.is-bright{
    filter:drop-shadow(0 0 1px var(--star-color,#fff))
}

@keyframes dn-twinkle{0%,100%{opacity:.6}50%{opacity:1}}
@keyframes dn-twinkle-slow{0%,100%{opacity:.5;filter:drop-shadow(0 0 4px currentColor)}50%{opacity:1;filter:drop-shadow(0 0 10px currentColor)}}
@keyframes dn-twinkle-fast{0%,100%{opacity:.7;transform:translate(-50%,-50%) scale(1)}40%{opacity:1;transform:translate(-50%,-50%) scale(1.15)}60%{opacity:.85}}
@keyframes dn-twinkle-sparkle{0%,90%,100%{opacity:.65}45%{opacity:1;filter:drop-shadow(0 0 14px currentColor) brightness(1.4)}}

/* Atmospheric refraction model — stars seen through more atmosphere
   (low altitude) twinkle harder; stars near zenith are nearly steady.
   The classes are applied by sky.js based on the star's y% position. */
@keyframes dn-twinkle-low-alt{
    0%,100%{opacity:.45;filter:drop-shadow(0 0 3px currentColor)}
    20%    {opacity:1;  filter:drop-shadow(0 0 12px currentColor) brightness(1.3)}
    40%    {opacity:.5}
    65%    {opacity:.95}
    85%    {opacity:.4}
}
.dn-star.is-low-alt{
    /* Override the per-id twinkle picked at render time with the stronger
       horizon-class twinkle. Faster cycle ≈ scintillation rate of low stars. */
    animation:
        dn-twinkle-low-alt calc(var(--twinkle-dur,3s) * 0.7) ease-in-out infinite,
        dn-star-drift 9s ease-in-out infinite !important;
}
.dn-star.is-high-alt{
    /* Near the zenith — minimal turbulence, slower & shallower variation */
    animation:
        dn-twinkle 6s ease-in-out infinite,
        dn-star-drift 14s ease-in-out infinite !important;
    opacity:.92;
}
@media (prefers-reduced-motion:reduce){
    .dn-sky.dn-q-low .dn-star.is-low-alt,
    .dn-sky.dn-q-low .dn-star.is-high-alt{animation:none}
}

@keyframes dn-star-drift{
    0%,100%{translate:0 0}
    50%{translate:var(--drift-x,2px) var(--drift-y,-2px)}
}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-star{animation:none;opacity:.85}}
.dn-star-svg{width:100%;height:100%;display:block}

.dn-star-tip{
    position:absolute;left:50%;bottom:calc(100% + 6px);transform:translateX(-50%);
    min-width:180px;max-width:260px;padding:10px 12px;
    background:rgba(15,23,42,.96);border:1px solid rgba(251,191,36,.35);
    border-radius:8px;color:#f1f5f9;font-size:12px;line-height:1.45;text-align:center;
    opacity:0;pointer-events:none;transition:opacity .15s;z-index:10;
    backdrop-filter:blur(8px);
}
.dn-star:hover .dn-star-tip,.dn-star.active .dn-star-tip{opacity:1}
.dn-star-tip-name{font-weight:700;color:#fff;margin:0 0 3px;display:block;font-size:13px}
.dn-star-tip-msg{display:block;color:#cbd5e1;font-size:12px;line-height:1.45;word-break:break-word}
.dn-star-tip-amt{display:inline-block;margin-top:5px;padding:2px 8px;background:rgba(251,191,36,.18);border-radius:99px;color:#fbbf24;font-weight:700;font-size:11px;font-variant-numeric:tabular-nums}

.dn-star.flying{animation:dn-fly-up 1.6s cubic-bezier(.2,.7,.2,1) forwards;color:#fde047;filter:drop-shadow(0 0 18px rgba(253,224,71,.95))}
@keyframes dn-fly-up{
    0%   {transform:translate(-50%,calc(-50% + 280px)) scale(.4);opacity:0}
    15%  {opacity:1}
    85%  {transform:translate(-50%,-50%) scale(1.8);opacity:1}
    100% {transform:translate(-50%,-50%) scale(1);opacity:1}
}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-star.flying{animation:none}}

/* Empty state */
.dn-sky-empty{
    position:absolute;inset:auto 0 60px;display:flex;align-items:center;justify-content:center;
    color:rgba(216,180,254,.7);font-size:14px;text-align:center;padding:0 20px;
    text-shadow:0 0 12px rgba(139,92,246,.4);pointer-events:none;
}

.dn-sky-total{text-align:center;margin:18px auto 0;font-size:13px;color:var(--text-muted);max-width:600px}
.dn-sky-total strong{color:var(--text-primary);font-weight:700}

/* Quality tiers — set by JS via class on .dn-sky */
.dn-sky.dn-q-low .dn-comet,
.dn-sky.dn-q-low .dn-galaxy,
.dn-sky.dn-q-low .dn-nebula-3{display:none}
.dn-sky.dn-q-low .dn-nebula{filter:none;opacity:.25}
.dn-sky.dn-q-low .dn-bgstars{animation:none}
.dn-sky.dn-q-low .dn-c-slot.is-filled,
.dn-sky.dn-q-low .dn-star,
.dn-sky.dn-q-low .dn-planet-svg,
.dn-sky.dn-q-low .dn-planet,
.dn-sky.dn-q-low .dn-earth-moon-orbit{animation:none}

/* Planets currently below the horizon — hidden, not ghosted. The
   legend (#dn-sky-legend) lists which bodies are in this state. */
.dn-planet.is-below-horizon{display:none}

/* ─── Aurora — rare green/pink curtains above the horizon ─── */
.dn-aurora{
    position:absolute;left:-10%;right:-10%;
    bottom:0;height:55%;
    pointer-events:none;z-index:4;
    opacity:0;
    mix-blend-mode:screen;
    transition:opacity 1.2s ease-in-out;
    overflow:hidden;
}
.dn-aurora.is-active{opacity:.55}
.dn-aurora-band{
    position:absolute;left:-20%;right:-20%;
    height:100%;
    filter:blur(28px);
    transform:translate3d(0,30%,0);
    will-change:transform,opacity;
}
.dn-aurora-green{
    background:radial-gradient(ellipse 70% 90% at 30% 90%,
        rgba(74,222,128,.45) 0%,
        rgba(34,197,94,.25) 35%,
        transparent 65%);
}
.dn-aurora-pink{
    background:radial-gradient(ellipse 60% 80% at 70% 95%,
        rgba(244,114,182,.35) 0%,
        rgba(236,72,153,.18) 40%,
        transparent 70%);
}
.dn-aurora-violet{
    background:radial-gradient(ellipse 80% 70% at 50% 100%,
        rgba(167,139,250,.3) 0%,
        rgba(139,92,246,.15) 50%,
        transparent 75%);
}
.dn-aurora.is-active .dn-aurora-green {
    animation:dn-aurora-green-anim 14s ease-in-out infinite;
}
.dn-aurora.is-active .dn-aurora-pink {
    animation:dn-aurora-pink-anim 18s ease-in-out infinite;
    animation-delay:-3s;
}
.dn-aurora.is-active .dn-aurora-violet {
    animation:dn-aurora-violet-anim 22s ease-in-out infinite;
    animation-delay:-6s;
}
@keyframes dn-aurora-green-anim{
    0%,100%{transform:translate3d(-8%,28%,0) scaleY(1);  opacity:.7}
    50%    {transform:translate3d( 6%,18%,0) scaleY(1.1);opacity:1}
}
@keyframes dn-aurora-pink-anim{
    0%,100%{transform:translate3d( 6%,32%,0) scaleY(.95);opacity:.4}
    50%    {transform:translate3d(-9%,22%,0) scaleY(1.1);opacity:.8}
}
@keyframes dn-aurora-violet-anim{
    0%,100%{transform:translate3d( 0%,30%,0) scaleY(1);  opacity:.5}
    50%    {transform:translate3d( 8%,20%,0) scaleY(1.05);opacity:.85}
}
.dn-sky.dn-q-low .dn-aurora{display:none}
@media (prefers-reduced-motion:reduce){
    .dn-aurora.is-active .dn-aurora-band{animation:none}
}

/* ─── Polaris (Полярная звезда) ───
   Positioned at the real altitude for Moscow's latitude (~55.75° N).
   In our south-centred projection: az=0° (north) → x ≈ 0% (left edge);
   alt=55.75° → y = 90 - (55.75/90)*82 ≈ 39%. The 5% left offset gives
   a small visual margin — pure 0% would clip into the page edge. */
.dn-polaris{
    position:absolute;left:5%;top:39%;
    width:60px;height:60px;
    pointer-events:none;
    z-index:6;
    opacity:0;transform:scale(0.6);
    transition:opacity 1.6s ease-in-out, transform 1.6s ease-out;
}
.dn-polaris[hidden]{display:none !important}
.dn-polaris.is-visible{
    opacity:1;transform:scale(1);
}
.dn-polaris-svg{
    width:100%;height:100%;
    display:block;
    filter:drop-shadow(0 0 6px rgba(251,191,36,.55))
           drop-shadow(0 0 14px rgba(255,255,255,.4));
    animation:dn-polaris-pulse 6s ease-in-out infinite;
}
@keyframes dn-polaris-pulse{
    0%,100%{opacity:.85;filter:drop-shadow(0 0 6px rgba(251,191,36,.55)) drop-shadow(0 0 14px rgba(255,255,255,.4))}
    50%    {opacity:1;  filter:drop-shadow(0 0 10px rgba(251,191,36,.75)) drop-shadow(0 0 22px rgba(255,255,255,.55))}
}
.dn-polaris-label{
    position:absolute;left:50%;top:100%;
    transform:translate(-50%, 4px);
    font-size:10px;font-weight:600;letter-spacing:.5px;
    color:rgba(251,191,36,.75);
    white-space:nowrap;
    text-shadow:0 0 6px rgba(15,23,42,.9);
    pointer-events:none;
}
.dn-sky.dn-q-low .dn-polaris-svg{animation:none}
@media (prefers-reduced-motion:reduce){
    .dn-polaris-svg{animation:none}
    .dn-polaris.is-visible{transition:opacity .4s linear}
}
@media (max-width:560px){
    .dn-polaris{width:46px;height:46px;left:6%;top:36%}
    .dn-polaris-label{font-size:9px}
}

/* (Compass strip removed — felt static-y next to the moving sky.) */

/* ─── Space Shuttle launch (rare scheduled event) ─── */
.dn-shuttle-layer{
    position:absolute;inset:0;pointer-events:none;z-index:6;overflow:visible;
}
.dn-shuttle{
    position:absolute;
    width:24px;height:60px;
    transform:translate(-50%, -100%);  /* anchor at the pad point */
    will-change:translate, rotate, opacity;
}
.dn-shuttle-svg{
    width:100%;height:100%;display:block;overflow:visible;
}
/* Plume painted as ::after on the wrapper — long bright streak below
   the shuttle that shrinks as the craft accelerates and the perspective
   compresses. Two-layer (sharp inner + soft halo) for that flame look. */
.dn-shuttle::before,
.dn-shuttle::after{
    content:"";position:absolute;
    left:50%;top:100%;
    transform:translateX(-50%);
    pointer-events:none;
}
.dn-shuttle::before{
    /* Bright core flame */
    width:6px;
    height:32px;
    background:linear-gradient(to bottom,
        #fffbe8 0%,
        #fde68a 40%,
        #fb923c 75%,
        rgba(220,38,38,0) 100%);
    filter:blur(1px);
    border-radius:3px 3px 6px 6px;
}
.dn-shuttle::after{
    /* Outer halo */
    width:14px;
    height:50px;
    background:linear-gradient(to bottom,
        rgba(254,243,199,.55) 0%,
        rgba(251,146,60,.4)   45%,
        rgba(220,38,38,0)     100%);
    filter:blur(4px);
    border-radius:50%;
    z-index:-1;
}
/* Falling boosters after SRB separation */
.dn-shuttle-srb-falling{
    position:absolute;width:5px;height:46px;
    transform:translate(-50%, -50%);
    will-change:translate, rotate, opacity;
}
.dn-shuttle-svg-srb{width:100%;height:100%;display:block}

/* Skip the heavy gradients on Low quality, but keep the trajectory —
   just remove the plume blur layer. */
.dn-sky.dn-q-low .dn-shuttle::after{display:none}
@media (prefers-reduced-motion:reduce){.dn-sky.dn-q-low .dn-shuttle{display:none}}

/* ─── Supernova (rare bright stellar explosion) ─── */
.dn-supernova-layer{
    position:absolute;inset:0;pointer-events:none;z-index:5;overflow:visible;
}
.dn-supernova{
    position:absolute;
    width:18px;height:18px;
    transform:translate(-50%,-50%);
    border-radius:50%;
    background:radial-gradient(circle,
        var(--sn-core,#fff) 0%,
        var(--sn-mid,#dbeafe) 35%,
        var(--sn-edge,#3b82f6) 70%,
        transparent 100%);
    box-shadow:
        0 0 16px 4px var(--sn-mid,#dbeafe),
        0 0 40px 12px var(--sn-edge,#3b82f6);
    will-change:scale,opacity;
}
.dn-supernova-ring{
    position:absolute;
    inset:-3px;
    border-radius:50%;
    border:1.5px solid var(--sn-mid,#dbeafe);
    pointer-events:none;
    will-change:scale,opacity;
}
.dn-sky.dn-q-low .dn-supernova-layer{display:none}
@media (prefers-reduced-motion:reduce){.dn-supernova,.dn-supernova-ring{animation:none}}

/* ─── Satellite (slow, steady point of light, no tail) ─── */
.dn-satellite-layer{
    position:absolute;inset:0;pointer-events:none;z-index:5;overflow:visible;
}
.dn-satellite{
    position:absolute;
    width:3px;height:3px;
    border-radius:50%;
    background:#e0eaff;
    box-shadow:0 0 4px 1px rgba(224,234,255,.8),
               0 0 10px 2px rgba(180,200,255,.5);
    will-change:transform,opacity;
}
.dn-sky.dn-q-low .dn-satellite{display:none}

/* ─── Meteors (fast streaks, no head — just a glowing line) ─── */
.dn-meteor-layer{
    position:absolute;inset:0;pointer-events:none;z-index:5;overflow:visible;
}
.dn-meteor{
    position:absolute;
    width:var(--m-tail,60px);
    height:1.6px;
    transform-origin:right center;
    transform:rotate(var(--m-angle,30deg));
    background:linear-gradient(to left,
        var(--m-core,#fff)    0%,
        var(--m-mid,#fef9c3) 30%,
        var(--m-edge,#fbbf24) 65%,
        transparent 100%);
    filter:blur(0.4px) drop-shadow(0 0 4px var(--m-mid,#fef9c3));
    will-change:transform,opacity,scale;
    pointer-events:none;
}

/* Bolide breakup sparks — 3..5 of these spawn near a meteor's end
   point when fragmentation rolls (~6% of meteors). Tiny radial points
   that scatter outward and fade. */
.dn-meteor-spark{
    position:absolute;
    width:3px;height:3px;
    border-radius:50%;
    background:var(--m-mid,#fef9c3);
    box-shadow:0 0 4px 1px var(--m-mid,#fef9c3),
               0 0 10px 2px var(--m-edge,#fbbf24);
    pointer-events:none;
    will-change:translate,scale,opacity;
}
.dn-sky.dn-q-low .dn-meteor-spark{display:none}
@media (prefers-reduced-motion:reduce){
    .dn-sky.dn-q-low .dn-meteor{display:none}
}

/* Sky legend — "currently above / below horizon" + countdowns + events.
   Colours theme-aware (legend lives outside the .dn-sky frame, so the
   light theme reads it on a light background). */
.dn-sky-legend{
    max-width:900px;margin:14px auto 0;padding:12px 18px;
    background:var(--glass);border:1px solid var(--border);
    border-radius:var(--radius-md);
    font-size:13px;line-height:1.55;
    display:flex;flex-direction:column;gap:8px;
}
.dn-legend-row{
    display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
    color:var(--text-secondary);
}
.dn-legend-icon{font-size:14px;line-height:1;flex-shrink:0}
.dn-legend-label{
    color:var(--text-muted);font-size:12px;
    text-transform:uppercase;letter-spacing:.5px;font-weight:600;
    flex-shrink:0;
}
.dn-legend-bodies{color:var(--text-primary);font-weight:500}
/* "Currently in the sky" — readable on BOTH themes. Default: warm amber
   on dark; light theme overridden below. */
.dn-legend-up .dn-legend-bodies{color:#d97706}
[data-theme=light] .dn-legend-up .dn-legend-bodies{color:#b45309}
.dn-sky-legend [data-theme=dark],
:root:not([data-theme=light]) .dn-legend-up .dn-legend-bodies{color:#fbbf24}
.dn-legend-down{opacity:.7}
.dn-legend-down .dn-legend-bodies{color:var(--text-secondary);font-weight:400}
.dn-legend-eclipse .dn-legend-bodies{
    color:#dc2626;font-weight:700;
}
[data-theme=light] .dn-legend-eclipse .dn-legend-bodies{color:#991b1b}
.dn-legend-event .dn-legend-bodies{
    color:var(--accent);font-weight:600;
}
.dn-legend-countdown .dn-legend-bodies{
    color:var(--text-primary);font-weight:500;
}
.dn-legend-countdown-date{
    margin-left:6px;color:var(--text-muted);font-size:11.5px;
    font-variant-numeric:tabular-nums;
}
/* Observer disclaimer — small, muted, sits at the bottom of the legend.
   Tells visitors outside Moscow that this is a "view from Moscow" map,
   not their actual local sky. */
.dn-legend-observer{
    opacity:.65;
    border-top:1px solid var(--border);
    padding-top:8px;
    margin-top:2px;
}
.dn-legend-observer .dn-legend-bodies{
    font-size:12px;color:var(--text-muted);font-weight:400;
    font-variant-numeric:tabular-nums;
}
@media (max-width:560px){
    .dn-sky-legend{padding:12px 14px;font-size:12.5px}
    .dn-legend-row{gap:6px}
}

/* Quality control ▼ */
.dn-sky-quality{
    max-width:1100px;margin:8px auto 0;text-align:right;
    font-size:12px;color:var(--text-muted);
    display:flex;justify-content:flex-end;align-items:center;gap:14px;flex-wrap:wrap;
}
.dn-sky-quality label{display:inline-flex;align-items:center;gap:6px}
.dn-sky-motion-toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.dn-sky-motion-toggle input{margin:0;cursor:pointer;accent-color:var(--accent)}
.dn-sky-quality select{
    appearance:none;-webkit-appearance:none;
    padding:4px 26px 4px 10px;
    border:1px solid var(--border);background:var(--glass);
    border-radius:6px;color:var(--text-primary);
    font:inherit;font-size:12px;cursor:pointer;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='%23888'><path d='M3 4.5l3 3 3-3'/></svg>");
    background-repeat:no-repeat;background-position:right 8px center;background-size:10px 10px;
}
.dn-sky-quality select:hover{border-color:var(--border-hover)}

/* Canvas overflow renderer (foreground stars when wishes > threshold) */
.dn-stars-canvas{
    position:absolute;inset:0;width:100%;height:100%;
    pointer-events:none;
}

/* Tablet — slightly shorter sky, lighter blur. Per-planet size overrides
   removed because sky.js now sets each planet's size from the API's
   angular_arcsec (correct apparent size for the date). */
@media (max-width:780px){
    .dn-sky{height:460px}
    .dn-star{width:14px;height:14px}
    .dn-nebula{filter:blur(28px)}
}
/* Phone — keep the sky tall enough that planets don't pile on top of
   each other, but short enough to be obviously below the form. */
@media (max-width:560px){
    .dn-sky{height:380px;border-radius:var(--radius-md)}
}
/* Small phone (≤360px, e.g. iPhone SE 1st gen, low-end Android) — give
   the sky a bit more breathing room and shrink the legend / compass. */
@media (max-width:380px){
    .dn-sky{height:340px}
    .dn-sky-legend{font-size:11.5px;padding:10px 12px}
    .dn-recent{padding:12px}
    .dn-author{padding:20px 14px}
    .dn-author-greeting{font-size:17px}
}
