/* ═══ Luna's sky (js/luna-sky.js), loaded after css/depth.css. Her space becomes a bright heavenly sky:
   a deep blue clear patch behind her face (her own ground #0d131e inside her feather → #1f3d6e →
   #3f6aa6 → #a8c8e8), the open sky #a8c8e8 → #c8dcec, a white-glass haze #e8f0fa on the chat side.
   Brand kit only: no purple, no orange, no night; gold only as rims mixed toward white.
   Every rule is scoped to .luna-space.sky / .centre.luna-sky (js/luna-sky.js adds both at mount), so
   depth.css v12 stays untouched underneath.
   - .luna-space.sky          the CSS sky: 'no WebGL' (and the instant before the first GL frame);
   - .luna-space.sky.sky-on   the canvas (.luna-sky-gl) draws the sky: only the bottom fade + unfurl;
   - the canvas has its own class (.luna-sky-gl), so no depth.css rule hides the still frame that low /
     reduced-motion devices get. ═══ */

/* night layers of v10–v12 never show over a sky */
.luna-space.sky :is(.luna-stars,.luna-aurora,.luna-seam,.luna-motes){display:none!important}

/* ── the CSS sky (fallback): the same twilight as the WebGL sky (phase C, W1): the curve
   g = 1/(1+(e/1.0)^5.2) (js/luna-sky-field.js twG) sampled at 14 radii out to 2.2 fr, colour by L along
   #0e1a36 → #2b528c → #5a8fcc → #a8c8e8, its centre nudged away from the sun (deeper on the far side);
   no ring: a soft sun-side light instead.
   Her keyed face adds next to nothing to her night, so it needs no pre-darkening here ── */
.centre.face-on .luna-space.sky{
  background-image:
    radial-gradient(circle calc(var(--fr,180px) * .1) at calc(var(--fx,66%) - var(--fr,180px) * .75) 2%,#fffdf6 0,#fffdf6 45%,rgba(255,248,226,.55) 70%,rgba(255,248,226,0) 100%),
    radial-gradient(circle calc(var(--fr,180px) * .9) at calc(var(--fx,66%) - var(--fr,180px) * .75) 2%,rgba(255,250,236,.7) 0,rgba(255,250,236,.25) 35%,rgba(255,250,236,0) 100%),
    radial-gradient(circle calc(var(--fr,180px) * 1.25) at calc(var(--fx,66%) - var(--fr,180px) * .62) calc(var(--fy,50%) - var(--fr,180px) * .78),rgba(255,250,236,.16) 0,rgba(252,250,244,.08) 45%,rgba(255,250,236,0) 85%),
    radial-gradient(circle calc(var(--fr,180px) * 2.2) at calc(var(--fx,66%) + var(--fr,180px) * .07) calc(var(--fy,50%) + var(--fr,180px) * .06),#0e1a36 0,#101e3c 22.7%,#15284b 29.5%,#1c3560 34.1%,#26487c 38.6%,#355f99 43.2%,#4776b2 47.7%,#578bc8 52.3%,#74a2d6 59.1%,#87b0dd 65.9%,#93b9e1 72.7%,rgba(156,192,228,.67) 81.8%,rgba(161,195,230,.33) 90.9%,rgba(164,197,231,0) 100%),
    radial-gradient(ellipse 60% 40% at 30% 0%,rgba(255,253,244,.55),rgba(255,253,244,0) 70%),
    radial-gradient(calc(var(--fr,180px) * 1.8) calc(var(--fr,180px) * 1.25) at calc(var(--fx,66%) - var(--fr,180px) * .1) 0%,rgba(126,174,224,.7) 0,rgba(126,174,224,.35) 50%,rgba(126,174,224,0) 100%),
    linear-gradient(180deg,rgba(168,200,232,0) 0%,rgba(200,220,236,.6) 100%),
    linear-gradient(90deg,#f7faff 0%,#e8f0fa calc(100% - var(--luna-sw) * 1.15),#c8dcec calc(100% - var(--luna-sw) * .9),#a8c8e8 calc(100% - var(--luna-sw) * .7),#a8c8e8 100%);
  background-image:
    radial-gradient(circle calc(var(--fr,180px) * .1) at calc(var(--fx,66%) - var(--fr,180px) * .75) 2% in oklab,#fffdf6 0,#fffdf6 45%,rgba(255,248,226,.55) 70%,rgba(255,248,226,0) 100%),
    radial-gradient(circle calc(var(--fr,180px) * .9) at calc(var(--fx,66%) - var(--fr,180px) * .75) 2% in oklab,rgba(255,250,236,.7) 0,rgba(255,250,236,.25) 35%,rgba(255,250,236,0) 100%),
    radial-gradient(circle calc(var(--fr,180px) * 1.25) at calc(var(--fx,66%) - var(--fr,180px) * .62) calc(var(--fy,50%) - var(--fr,180px) * .78) in oklab,rgba(255,250,236,.16) 0,rgba(252,250,244,.08) 45%,rgba(255,250,236,0) 85%),
    radial-gradient(circle calc(var(--fr,180px) * 2.2) at calc(var(--fx,66%) + var(--fr,180px) * .07) calc(var(--fy,50%) + var(--fr,180px) * .06) in oklab,#0e1a36 0,#101e3c 22.7%,#15284b 29.5%,#1c3560 34.1%,#26487c 38.6%,#355f99 43.2%,#4776b2 47.7%,#578bc8 52.3%,#74a2d6 59.1%,#87b0dd 65.9%,#93b9e1 72.7%,rgba(156,192,228,.67) 81.8%,rgba(161,195,230,.33) 90.9%,rgba(164,197,231,0) 100%),
    radial-gradient(ellipse 60% 40% at 30% 0% in oklab,rgba(255,253,244,.55),rgba(255,253,244,0) 70%),
    radial-gradient(calc(var(--fr,180px) * 1.8) calc(var(--fr,180px) * 1.25) at calc(var(--fx,66%) - var(--fr,180px) * .1) 0% in oklab,rgba(126,174,224,.7) 0,rgba(126,174,224,.35) 50%,rgba(126,174,224,0) 100%),
    linear-gradient(in oklab 180deg,rgba(168,200,232,0) 0%,rgba(200,220,236,.6) 100%),
    linear-gradient(in oklab 90deg,#f7faff 0%,#e8f0fa calc(100% - var(--luna-sw) * 1.15),#c8dcec calc(100% - var(--luna-sw) * .9),#a8c8e8 calc(100% - var(--luna-sw) * .7),#a8c8e8 100%)}
/* the fallback's clouds (phase B: the same composition as the WebGL sky, in soft lobed gradients): a
   towering cumulus and a smaller one rising left of her (sunlit crowns, slate-blue bases), a cloud sea
   under her, two flat-based puffs up by the sun. Lit crowns white, every lobe shaded toward #b8c8de at
   its rim, lower lobes in shade. They move by transform only; never over her face (all beyond 1.12) */
.luna-space.sky .luna-clouds{overflow:hidden}
.luna-space.sky .luna-clouds b{position:absolute;display:block;filter:blur(1.5px);animation:lunaCloud 90s ease-in-out infinite alternate}
.luna-space.sky .luna-clouds b:nth-child(1){left:calc(var(--fx,66%) - var(--fr,180px) * 2.2);top:calc(var(--fy,50%) - var(--fr,180px) * .78);width:calc(var(--fr,180px) * 1.3);height:calc(var(--fr,180px) * 2.2);
  animation:lunaTower 46s ease-in-out infinite alternate;background:
    radial-gradient(22% 9% at 50% 10%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(19% 8% at 33% 15%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(19% 8% at 67% 15%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(30% 11% at 50% 22%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(36% 13% at 42% 36%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(38% 13% at 58% 48%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(42% 14% at 45% 62%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(48% 16% at 55% 78%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%),
    radial-gradient(56% 16% at 46% 94%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%)}
.luna-space.sky .luna-clouds b:nth-child(2){left:calc(var(--fx,66%) - var(--fr,180px) * 2.95);top:calc(var(--fy,50%) + var(--fr,180px) * .1);width:calc(var(--fr,180px) * 1.15);height:calc(var(--fr,180px) * 1.4);
  animation:lunaTower 58s ease-in-out -20s infinite alternate;background:
    radial-gradient(26% 12% at 48% 14%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(22% 11% at 30% 24%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(24% 11% at 64% 26%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(40% 17% at 50% 46%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(50% 20% at 48% 74%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%)}
.luna-space.sky .luna-clouds b:nth-child(3){left:calc(var(--fx,66%) - var(--fr,180px) * 2.4);top:calc(var(--fy,50%) + var(--fr,180px) * 1.02);width:calc(var(--fr,180px) * 4.2);height:calc(var(--fr,180px) * .9);
  animation-duration:120s;animation-delay:-40s;background:
    radial-gradient(16% 30% at 12% 40%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(16% 32% at 30% 34%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(15% 30% at 48% 42%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(17% 32% at 66% 36%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(16% 30% at 84% 42%,#fdfdfe 0,#eef3f9 55%,#cad7e8 84%,rgba(200,214,234,0) 100%),
    radial-gradient(60% 40% at 50% 80%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%)}
.luna-space.sky .luna-clouds b:nth-child(4){left:calc(var(--fx,66%) - var(--fr,180px) * .35);top:calc(var(--fy,50%) - var(--fr,180px) * 1.95);width:calc(var(--fr,180px) * 1.1);height:calc(var(--fr,180px) * .52);
  animation-duration:150s;background:
    radial-gradient(24% 32% at 30% 38%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(26% 36% at 52% 30%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(22% 30% at 72% 42%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(46% 26% at 50% 78%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%)}
.luna-space.sky .luna-clouds b:nth-child(5){left:calc(var(--fx,66%) + var(--fr,180px) * .55);top:calc(var(--fy,50%) - var(--fr,180px) * 1.72);width:calc(var(--fr,180px) * .8);height:calc(var(--fr,180px) * .4);
  animation-duration:130s;animation-delay:-60s;background:
    radial-gradient(24% 32% at 30% 38%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(26% 36% at 52% 30%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(22% 30% at 72% 42%,#fff 0,#fbfcfe 55%,#dfe7f2 84%,rgba(200,214,234,0) 100%),
    radial-gradient(46% 26% at 50% 78%,#f1f5fa 0,#dbe4f0 55%,#b8c8de 84%,rgba(200,214,234,0) 100%)}
@keyframes lunaCloud{from{transform:translate3d(0,0,0)}to{transform:translate3d(-9%,-2%,0)}}
@keyframes lunaTower{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(-2%,-1.5%,0) scale(1.025)}}
@media (prefers-reduced-motion:reduce){ .luna-space.sky .luna-clouds b{animation:none} }
html[data-quality="low"] .luna-space.sky .luna-clouds b{animation:none}
/* W9: NO WebGL at all (.sky-nogl: js/luna-sky.js sets it only when no context or no programs, or a context lost
   before any snapshot) → the clouds are the WebGL still frame's own, baked by tools/sky-demo/bake (coverage matte
   over the backdrop). W13: ONE sprite of the whole scene (her towers, the puffs by the sun, the sea under her),
   its left and top feathered; rect in her half-sizes from her centre (bake.py SPRITES: −4.55…1.02 across,
   −2.0…1.36 down). Only this rule names the image, so only these visitors download it (~110 KB). Re-bake after
   the shaders change. */
.luna-space.sky.sky-nogl .luna-clouds b{filter:none;background:none}
.luna-space.sky.sky-nogl .luna-clouds b:nth-child(1){left:calc(var(--fx,66%) - var(--fr,180px) * 4.55);top:calc(var(--fy,50%) - var(--fr,180px) * 2);
  width:calc(var(--fr,180px) * 5.57);height:calc(var(--fr,180px) * 3.36);background:url(../img/luna-sky-clouds.webp) 0 0/100% 100% no-repeat;animation:lunaBaked 90s ease-in-out infinite alternate}
.luna-space.sky.sky-nogl .luna-clouds b:not(:nth-child(1)){display:none}
/* W13: no WebGL means no shader text guard (textGuard() keeps the sky under her greeting and the chat bubbles at
   #e8f0fa or lighter): here a veil of the haze does it, over the clouds, round the union of that text
   (--luna-tg-r / --luna-tg-b: its right and bottom edges, set by js/luna-sky.js), full to 8 px out, gone by 72–96 px */
@media (min-width:721px){
  .centre.luna-sky.face-on .luna-space.sky.sky-nogl::after{content:"";position:absolute;inset:0;pointer-events:none;background:#f6f9fe;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(var(--luna-tg-r,0px) + 8px),rgba(0,0,0,.5) calc(var(--luna-tg-r,0px) + 36px),rgba(0,0,0,0) calc(var(--luna-tg-r,0px) + 96px)),linear-gradient(180deg,#000 calc(var(--luna-tg-b,0px) + 8px),rgba(0,0,0,.5) calc(var(--luna-tg-b,0px) + 30px),rgba(0,0,0,0) calc(var(--luna-tg-b,0px) + 72px));
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(90deg,#000 calc(var(--luna-tg-r,0px) + 8px),rgba(0,0,0,.5) calc(var(--luna-tg-r,0px) + 36px),rgba(0,0,0,0) calc(var(--luna-tg-r,0px) + 96px)),linear-gradient(180deg,#000 calc(var(--luna-tg-b,0px) + 8px),rgba(0,0,0,.5) calc(var(--luna-tg-b,0px) + 30px),rgba(0,0,0,0) calc(var(--luna-tg-b,0px) + 72px));
            mask-composite:intersect}
}
@keyframes lunaBaked{from{transform:translate3d(0,0,0)}to{transform:translate3d(.8%,0,0)}}   /* (rightward: the right edge is the panel's, the left is feathered) */
@media (prefers-reduced-motion:reduce){ .luna-space.sky.sky-nogl .luna-clouds b{animation:none} }
html[data-quality="low"] .luna-space.sky.sky-nogl .luna-clouds b{animation:none}

/* ── WebGL on: the canvas draws the sky with its own alpha ── */
.luna-sky-gl{display:block;width:100%;height:100%}
.centre.face-on .luna-space.sky.sky-on{background:none;
  -webkit-mask-image:var(--luna-ease-b),linear-gradient(270deg,#000 calc(var(--reveal) * 1.25 - 25%),rgba(0,0,0,0) calc(var(--reveal) * 1.25));
          mask-image:var(--luna-ease-b),linear-gradient(270deg,#000 calc(var(--reveal) * 1.25 - 25%),rgba(0,0,0,0) calc(var(--reveal) * 1.25));
  -webkit-mask-composite:source-in;mask-composite:intersect}
.luna-space.sky.sky-on > :not(.luna-sky-gl,.luna-rim){display:none}

/* ── her portrait in the sky: a tighter feather (52% → 94%), and her face is SCREENED onto the sky
   (mix-blend-mode: screen) after a ground key (a gamma 1.6 curve, #luna-ground-key): her painting's
   smoky ground falls to near black and adds nothing, so only her light shows, and the WebGL sky under
   her feather is pre-darkened by exactly what is left of it (js/luna-sky.js) — no oval.
   For the blend to reach the sky, nothing between her iframe and the panel may be a stacking context:
   the wrap's fade and arrival (opacity, scale) move onto the iframe itself, and the wrap loses its z-index.
   (The slot is not one: .stage is display:contents.) ── */
.centre.luna-sky{
  --luna-sky-feather:radial-gradient(closest-side,#000 52%,rgba(0,0,0,.976) 56.2%,rgba(0,0,0,.905) 60.4%,rgba(0,0,0,.794) 64.6%,rgba(0,0,0,.655) 68.8%,rgba(0,0,0,.5) 73%,rgba(0,0,0,.345) 77.2%,rgba(0,0,0,.206) 81.4%,rgba(0,0,0,.095) 85.6%,rgba(0,0,0,.024) 89.8%,rgba(0,0,0,0) 94%)}
.centre.luna-sky.face-on .luna-face-wrap iframe{-webkit-mask-image:var(--luna-sky-feather);mask-image:var(--luna-sky-feather);mix-blend-mode:screen;
  filter:url(#luna-ground-key)}   /* (js/luna-sky.js: her grey ground → near black; her light stays) */
@media (min-width:721px){
  .centre.luna-sky .luna-face-wrap{z-index:auto;opacity:1;transition:none}
  .centre.luna-sky.face-arrive .luna-face-wrap{animation:none}
  .centre.luna-sky .luna-face-wrap > iframe,.centre.luna-sky .luna-face-wrap::after{opacity:0;transition:opacity .9s var(--ease-out)}
  .centre.luna-sky .luna-face-wrap.on > iframe,.centre.luna-sky .luna-face-wrap.on::after{opacity:1}
  .centre.luna-sky.face-arrive .luna-face-wrap > iframe,.centre.luna-sky.face-arrive .luna-face-wrap::after{transition:none;animation:lunaFaceIn 1.1s cubic-bezier(.22,.8,.3,1) .7s both}
  .centre.luna-sky.face-calm .luna-face-wrap > iframe,.centre.luna-sky.face-calm .luna-face-wrap::after{transition-duration:.4s}
}
@media (min-width:721px) and (prefers-reduced-motion:reduce){
  .centre.luna-sky .luna-face-wrap > iframe,.centre.luna-sky .luna-face-wrap::after{transition-duration:.4s}
}
/* her light wrap: only the key light from the sun's side (upper left), warm white — no edge ring (her
   ring is the sky's, out in her twilight) */
.centre.luna-sky.face-on .luna-face-wrap::after{
  background:
    radial-gradient(ellipse 30% 34% at 22% 22%,rgba(255,250,236,.08),rgba(255,250,236,0) 72%)}

/* ── wisps (js/luna-sky.js draws them once from the sky's own noise): 2–3 thin slow cloud streaks in
   FRONT of her edge. A square of 4 half-sizes on her centre, masked clear inside .64 of her half-size
   (her eyes, nose and mouth are never touched), full by her edge; they move by transform only ── */
.luna-wisps{position:absolute;left:50%;top:50%;z-index:1;pointer-events:none;
  width:calc(var(--fr,180px) * 4);height:calc(var(--fr,180px) * 4);margin:calc(var(--fr,180px) * -2) 0 0 calc(var(--fr,180px) * -2);
  opacity:0;transition:opacity 1.4s var(--ease-out);
  -webkit-mask-image:radial-gradient(closest-side,rgba(0,0,0,0) 16%,rgba(0,0,0,.06) 17.2%,rgba(0,0,0,.22) 18.6%,rgba(0,0,0,.45) 20%,rgba(0,0,0,.7) 21.6%,rgba(0,0,0,.9) 23.2%,#000 25%);
          mask-image:radial-gradient(closest-side,rgba(0,0,0,0) 16%,rgba(0,0,0,.06) 17.2%,rgba(0,0,0,.22) 18.6%,rgba(0,0,0,.45) 20%,rgba(0,0,0,.7) 21.6%,rgba(0,0,0,.9) 23.2%,#000 25%)}
.centre.face-on .luna-wisps.on{opacity:1}
.centre.face-arrive .luna-wisps.on{transition:opacity 1.2s ease-out 1.5s}
.luna-wisps canvas{position:absolute;display:block;opacity:.78;transition:opacity 1.2s ease-in-out;
  animation:lunaWisp 52s ease-in-out infinite alternate}
.luna-wisps canvas:nth-child(2){animation-duration:67s;animation-delay:-23s;animation-direction:alternate-reverse}
.luna-wisps canvas:nth-child(3){opacity:.62;animation-duration:81s;animation-delay:-40s}
/* her voice: the wisps she lights brighten with her ring and the cloud rims */
.centre.luna-talking .luna-wisps canvas{opacity:1}
.centre.luna-talking .luna-wisps canvas:nth-child(3){opacity:.85}
@keyframes lunaWisp{from{transform:translate3d(calc(var(--fr,180px) * .07),0,0)}to{transform:translate3d(calc(var(--fr,180px) * -.09),calc(var(--fr,180px) * -.02),0)}}
.luna-wisps.still canvas{animation:none}
@media (prefers-reduced-motion:reduce){ .luna-wisps canvas{animation:none} .luna-wisps{transition:none} }
html:is([data-quality="low"],[data-quality="static"]) .luna-wisps canvas{animation:none}
@media (max-width:720px){ .luna-wisps{display:none} }

/* W13: the chat thread sits ABOVE her sky. .stage is display:contents, so the thread (static, in flow) used to paint
   under .luna-space (absolute, z-index 0): its bubbles were covered by the canvas, and only the streamed words
   showed through (each .tok animates, so each was its own stacking context). With reduced motion the reply is
   not streamed, so its words sat under the sky's clouds and faded where a cloud was bright. */
.centre.luna-sky .thread{position:relative;z-index:1}

/* ── pills over the sky: solid white with a gold hairline ── */
.centre.luna-sky.face-on .luna-head .toggle{box-shadow:0 0 0 1px rgba(232,194,106,.55),0 4px 14px -6px rgba(31,61,110,.35)}
.centre.luna-sky.face-on .luna-head .badge{box-shadow:0 4px 14px -6px rgba(31,61,110,.3)}

/* ── phones (W4): "Luna rising over a sea of clouds" in her pearl window — a cerulean zenith #7eaee0 → #a8c8e8 →
   pale toward the horizon, the sun's bloom upper left, her celestial dawn round her face (drawn at .92 and
   lifted 3 %, transform only: the window's size never changes), and a continuous cloud sea along the bottom (a soft
   band, higher at the sides). No cloud in the rounded top corners. CSS here; js/luna-sky.js paints the real one over it ── */
@media (max-width:720px){
  .centre.luna-sky .luna-avatar-slot.face-on .luna-face-wrap{--luna-window-face-scale:.92;--luna-window-face-lift:.03}
  .centre.luna-sky .luna-avatar-slot.face-on .luna-face-wrap iframe{
    transform:translateY(calc(var(--luna-window-face-lift) * -100%)) scale(var(--luna-window-face-scale))}
  .centre.luna-sky .luna-avatar-slot.face-on .luna-face-wrap::before{
    background:
      radial-gradient(ellipse 42% 11% at 10% 88%,rgba(255,255,255,.95) 0,rgba(247,250,255,.8) 45%,rgba(214,226,242,0) 100%),
      radial-gradient(ellipse 44% 11% at 90% 89%,rgba(255,255,255,.95) 0,rgba(247,250,255,.8) 45%,rgba(214,226,242,0) 100%),
      linear-gradient(180deg,rgba(238,243,249,0) 84%,rgba(232,239,248,.85) 93%,#f4f8fd 100%),
      radial-gradient(ellipse 30% 26% at 16% 0%,rgba(255,252,242,.75),rgba(255,252,242,0) 70%),
      radial-gradient(ellipse 86cqh 110cqh at 50% 47%,#0e1a36 0.0%,#122141 13.6%,#1d3763 22.7%,#2a5089 29.5%,#3e6ba6 36.4%,#5082be 43.2%,rgba(90,143,204,0.91) 50.0%,rgba(90,143,204,0.68) 56.8%,rgba(90,143,204,0.52) 63.6%,rgba(90,143,204,0.31) 72.7%,rgba(90,143,204,0.13) 81.8%,rgba(90,143,204,0.03) 90.9%,rgba(90,143,204,0.00) 100.0%),
      linear-gradient(180deg,#7eaee0 0%,#a8c8e8 58%,#e8f0fa 100%);
    background:
      radial-gradient(ellipse 42% 11% at 10% 88% in oklab,rgba(255,255,255,.95) 0,rgba(247,250,255,.8) 45%,rgba(214,226,242,0) 100%),
      radial-gradient(ellipse 44% 11% at 90% 89% in oklab,rgba(255,255,255,.95) 0,rgba(247,250,255,.8) 45%,rgba(214,226,242,0) 100%),
      linear-gradient(in oklab 180deg,rgba(238,243,249,0) 84%,rgba(232,239,248,.85) 93%,#f4f8fd 100%),
      radial-gradient(ellipse 30% 26% at 16% 0% in oklab,rgba(255,252,242,.75),rgba(255,252,242,0) 70%),
      radial-gradient(ellipse 86cqh 110cqh at 50% 47% in oklab,#0e1a36 0.0%,#122141 13.6%,#1d3763 22.7%,#2a5089 29.5%,#3e6ba6 36.4%,#5082be 43.2%,rgba(90,143,204,0.91) 50.0%,rgba(90,143,204,0.68) 56.8%,rgba(90,143,204,0.52) 63.6%,rgba(90,143,204,0.31) 72.7%,rgba(90,143,204,0.13) 81.8%,rgba(90,143,204,0.03) 90.9%,rgba(90,143,204,0.00) 100.0%),
      linear-gradient(in oklab 180deg,#7eaee0 0%,#a8c8e8 58%,#e8f0fa 100%)}
  .luna-face-wrap > .luna-window-sky{position:absolute;inset:3px;width:calc(100% - 6px);height:calc(100% - 6px);z-index:0;
    border-radius:19px;-webkit-clip-path:inset(0 round 19px);clip-path:inset(0 round 19px);pointer-events:none}
  /* the glass sheen over a bright sky: a little softer; F1: plus a faint pearl veil from .6 to 1.0 R of her face,
     where her light fades into the day (the old darker ring there read as a porthole) */
  .centre.luna-sky .luna-avatar-slot.face-on .luna-face-wrap::after{background:
    radial-gradient(circle 52cqh at 50% 47%,rgba(214,228,248,0) 55%,rgba(214,228,248,.12) 70%,rgba(214,228,248,.06) 86%,rgba(214,228,248,0) 100%),
    linear-gradient(180deg,rgba(255,255,255,.16),rgba(255,255,255,.04) 18%,rgba(255,255,255,0) 36%)}
}
/* F1: the CSS night round her (both rules) is the GL one's: an upright oval, half dark at .8 R, a slow tail to 2.2
   (stops from g = 1/(1+(e/.8)^3) along the kit ramp #0e1a36 > #2b528c > #5a8fcc; her R = 45cqh of the window) */
/* W13: phones with NO WebGL: the window's own clouds (the cloud sea along the bottom, the small distant congestus on
   its left), baked from the WebGL still frame by tools/sky-demo/bake (--phone: the whole window), over the same
   gradients minus the two soft sea ellipses they replace. Only this rule names the image (~45 KB). */
@media (max-width:720px){
  .centre.luna-sky.sky-nogl .luna-avatar-slot.face-on .luna-face-wrap::before{
    background:
      url(../img/luna-sky-phone.webp) 0 0/100% 100% no-repeat,
      linear-gradient(180deg,rgba(238,243,249,0) 84%,rgba(232,239,248,.85) 93%,#f4f8fd 100%),
      radial-gradient(ellipse 30% 26% at 16% 0%,rgba(255,252,242,.75),rgba(255,252,242,0) 70%),
      radial-gradient(ellipse 86cqh 110cqh at 50% 47%,#0e1a36 0.0%,#122141 13.6%,#1d3763 22.7%,#2a5089 29.5%,#3e6ba6 36.4%,#5082be 43.2%,rgba(90,143,204,0.91) 50.0%,rgba(90,143,204,0.68) 56.8%,rgba(90,143,204,0.52) 63.6%,rgba(90,143,204,0.31) 72.7%,rgba(90,143,204,0.13) 81.8%,rgba(90,143,204,0.03) 90.9%,rgba(90,143,204,0.00) 100.0%),
      linear-gradient(180deg,#7eaee0 0%,#a8c8e8 58%,#e8f0fa 100%);
    background:
      url(../img/luna-sky-phone.webp) 0 0/100% 100% no-repeat,
      linear-gradient(in oklab 180deg,rgba(238,243,249,0) 84%,rgba(232,239,248,.85) 93%,#f4f8fd 100%),
      radial-gradient(ellipse 30% 26% at 16% 0% in oklab,rgba(255,252,242,.75),rgba(255,252,242,0) 70%),
      radial-gradient(ellipse 86cqh 110cqh at 50% 47% in oklab,#0e1a36 0.0%,#122141 13.6%,#1d3763 22.7%,#2a5089 29.5%,#3e6ba6 36.4%,#5082be 43.2%,rgba(90,143,204,0.91) 50.0%,rgba(90,143,204,0.68) 56.8%,rgba(90,143,204,0.52) 63.6%,rgba(90,143,204,0.31) 72.7%,rgba(90,143,204,0.13) 81.8%,rgba(90,143,204,0.03) 90.9%,rgba(90,143,204,0.00) 100.0%),
      linear-gradient(in oklab 180deg,#7eaee0 0%,#a8c8e8 58%,#e8f0fa 100%)}
}
/* F1: the still sky by time of day. The GL field grades its clouds by the visitor's hour (uGrade); the baked sprites
   take the same grade through #luna-tod-tint (js/luna-sky.js todTint(): diagonal mix(1, rgb, amount), luma-weighted),
   only while html[data-tod] is set (early morning, late afternoon). On phones the sprite shares the window's ::before
   with its gradients; the luma weight keeps the blue sky and her night untinted. */
html[data-tod] .luna-space.sky.sky-nogl .luna-clouds b:nth-child(1){filter:url(#luna-tod-tint)}
@media (max-width:720px){
  html[data-tod] .centre.luna-sky.sky-nogl .luna-avatar-slot.face-on .luna-face-wrap::before{filter:url(#luna-tod-tint)}
}
.luna-window-sky{display:none}
@media (max-width:720px){ .luna-face-wrap > .luna-window-sky{display:block} }

/* Layer D (CLS): the panel and her space CLIP, they do not scroll. Both were overflow:hidden, i.e. scroll
   containers; in RTL a scroll container's origin follows any overflow on its left, so the arrival's bloom
   (scale 1.5, held to the end of .face-arrive) and the rim riding past the edge moved that origin, and Chrome
   counted every child as shifted when .face-arrive ended (ar phone .043, ar desktop .038). clip paints the
   same and lays out the same (all 21 en/de/ar × 360–1920 rects identical); older engines keep hidden. */
.centre.luna-sky,.centre.luna-sky.face-on .luna-space{overflow:hidden;overflow:clip}

/* rtl (W10): Arabic mirrors the panel, so her face sits on the LEFT. js/luna-sky.js then measures everything
   in mirrored space (--fx is W − x) and the whole space (the WebGL canvas, the CSS fallback's gradients and
   clouds, its bottom fade and the arrival's unfurl) is flipped back here: the white side stays under the
   text, the open sky and clouds stay round her, the sun between them. Her wisps flip about her centre. */
@media (min-width:721px){
  .centre.luna-sky-rtl.face-on .luna-space.sky{transform:scaleX(-1)}
  .centre.luna-sky-rtl .luna-wisps{transform:scaleX(-1)}
  .centre.luna-sky-rtl.face-on .luna-face-wrap::after{transform:scaleX(-1)}   /* her key light from the sun's side */
  /* the panel glass's top sheen sits over the white side (depth.css r4): in RTL that is the top RIGHT */
  .centre.luna-sky-rtl.glass.face-on{background:
    radial-gradient(70% 70% at 86% -10%, rgba(255,253,244,.85), rgba(255,255,255,0) 60%),
    linear-gradient(220deg, rgba(255,255,255,.5) 0%, rgba(255,255,255,0) 34%),
    rgba(255,255,255,.56)}
}

/* a11y (W12): preference media. The sky is decorative (aria-hidden, no pointer events, never focusable).
   No visible "Still sky" control (owner default); reduced motion already gives the still frame.
   - color-scheme: light (the brand has no dark mode; it also keeps a transparent face iframe transparent:
     an iframe whose used scheme differs from its embedder's gets an opaque canvas behind it);
   - prefers-contrast: more → the haze on the text side lifts from #e8f0fa to ~#f2f6fc (40% white over it),
     the pills get a 1.5 px gold border, and js/luna-sky.js widens the text guard by 16 px a side;
   - forced-colors: active → no sky at all (a canvas cannot be recoloured): no canvas, wisps, clouds or
     gradients; js/luna-sky.js does not even start WebGL. Her face stays;
   - prefers-reduced-transparency (Chromium) → the glass on the text side becomes opaque white. */
:root{color-scheme:light}
@media (min-width:721px) and (prefers-contrast:more){
  .centre.luna-sky.face-on .luna-space.sky::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(90deg,rgba(255,255,255,.4) 0,rgba(255,255,255,.4) calc(100% - var(--luna-sw) * 1.15),rgba(255,255,255,0) calc(100% - var(--luna-sw) * .8))}
}
@media (prefers-contrast:more){
  .centre.luna-sky.face-on .luna-head :is(.toggle,.badge){border:1.5px solid #e8c26a;box-shadow:0 4px 14px -6px rgba(31,61,110,.35)}
  .centre.luna-sky.face-on #thread .msg.luna{background:#fff}
}
@media (forced-colors:active){
  .centre.luna-sky :is(.luna-sky-gl,.luna-wisps,.luna-clouds){display:none!important}
  .centre.luna-sky .luna-space.sky{background:none!important}
  .centre.luna-sky .luna-avatar-slot.face-on .luna-face-wrap::before{background:none!important}
}
@media (prefers-reduced-transparency:reduce){
  @media (min-width:721px){
    .centre.luna-sky.face-on .luna-space.sky::after{content:"";position:absolute;inset:0;pointer-events:none;
      background:linear-gradient(90deg,#fff 0,#fff calc(100% - var(--luna-sw) * 1.15),rgba(255,255,255,0) calc(100% - var(--luna-sw) * .8))}
  }
  .centre.luna-sky.face-on #thread .msg.luna,.centre.luna-sky.face-on .luna-head :is(.toggle,.badge){background:#fff;-webkit-backdrop-filter:none;backdrop-filter:none}
}
