/* ===================================================================
   夸夸星球 · 星空背景布（全站唯一来源）
   -------------------------------------------------------------------
   三屏共用同一张背景：深空微光 + 星云 + 三层闪烁星点 + 流星。
   用法（顺序无所谓，样式先加载更好）：
       <link rel="stylesheet" href="sky.css">
       <script src="sky.js"></script>
   sky.js 会自动插好 .sky 这一层（页面里已有就复用）。
   调参数：在引入 sky.js 之前写
       window.SKY = { stars:false, meteors:false, density:1 };
   改流星角度：只动这里的 --sky-angle（外层 rotate），位移在内层，
   两者绝不能挤在同一个 transform 里。
   =================================================================== */

.sky{
  position:fixed;inset:0;z-index:var(--sky-z,0);
  overflow:hidden;pointer-events:none;
}

/* 深空底：从中心偏上一点往外压暗 */
.sky__deep{
  position:absolute;inset:0;
  /* 2026-11-01 汤哥：「把首页的星空背景用到所有页面」。
     原来这里是四段 radial-gradient 拼的纯色深空 —— 干净但没有真实感（一片死蓝）。
     现在换成实拍星空图（银河 + 细碎星点），和首页是同一片天。
     ⚠️ 上面那层 dark 渐变不能省：图本身偏亮偏蓝，直接铺会把文字压不住；
        压到边缘 .82 的暗，中间只压 .10，星星在中间最清、四周自然沉下去。 */
  background-color:#050c1c;
  background-image:
    radial-gradient(ellipse 118% 82% at 50% 38%,
      rgba(4,10,26,.06) 0%, rgba(3,8,20,.34) 46%,
      rgba(2,6,16,.64) 78%, rgba(1,4,11,.86) 100%),
    url("assets/bg-stars.webp");
  background-position:50% 50%, 50% 50%;
  background-size:cover, cover;
  background-repeat:no-repeat, no-repeat;
}
/* 星云：四团极淡的彩色雾，缓慢漂移 */
.sky__nebula{
  position:absolute;inset:-12%;
  background:
    radial-gradient(ellipse 40% 32% at 20% 28%, rgba(169,139,255,.17), transparent 68%),
    radial-gradient(ellipse 34% 28% at 80% 64%, rgba(255,122,89,.11), transparent 66%),
    radial-gradient(ellipse 46% 36% at 64% 16%, rgba(123,224,192,.075), transparent 70%),
    radial-gradient(ellipse 30% 26% at 44% 82%, rgba(240,184,78,.075), transparent 68%);
  filter:blur(34px);
  animation:skyDrift 48s cubic-bezier(.4,0,.2,1) infinite alternate;
}
@keyframes skyDrift{
  from{transform:translate3d(0,0,0) scale(1);}
  to  {transform:translate3d(-1.8%,1.4%,0) scale(1.07);}
}

/* ---------- 星点：远 / 中 / 近三层，三层都闪 ----------
   只让大星闪、占多数的远层小星全静，整片星空看着就是「死的」。
   谷值取 --so 的 34%、峰值 112%：起伏够大，均值又接近静态亮度。 */
.sky__stars{position:absolute;inset:0;z-index:2;}
.sky__stars .star{position:absolute;border-radius:50%;background:var(--sc,#fff);opacity:var(--so,.7);}
.sky__stars .star--tw{
  animation:skyTwinkle var(--sd,6s) ease-in-out infinite;
  animation-delay:var(--sdel,0s);
}
.sky__stars--near .star--tw{will-change:opacity;}   /* 只给近层预提升：三层全加会堆出几百个图层 */
@keyframes skyTwinkle{
  /* 汤哥 2026-10-14：原来谷 .34 / 峰 1.12，起伏太小，暗底上几乎看不出在闪。
     现在拉开到 .16 ~ 1.36，并且三档之和（.16+.78+1.36 = 2.30）与原来完全一致
     —— 落差变大但均值不变，星空亮度不会被闪暗。 */
  0%,100%{opacity:calc(var(--so,.7) * .16);transform:scale(.76);}
  48%    {opacity:calc(var(--so,.7) * 1.36);transform:scale(1.18);}
  64%    {opacity:calc(var(--so,.7) * .78);transform:scale(.99);}
}
/* 中/近层的呼吸顺带把「光晕」一起放大 —— 只改透明度的话，
   给人的感觉只是「变淡/变浓」；光晕跟着涨落才像「在发光」。
   注意：这条必须写在 .star--blink 那条之前，权重相同、靠后者的 shorthand
   重置 animation-name，爆闪元素才会照常走爆闪。 */
.sky__stars--mid  .star--tw,
.sky__stars--near .star--tw{animation-name:skyTwinkleGlow;}
@keyframes skyTwinkleGlow{
  0%,100%{opacity:calc(var(--so,.7) * .16);transform:scale(.76);
          box-shadow:0 0 4px rgba(232,240,255,.34);}
  48%    {opacity:calc(var(--so,.7) * 1.36);transform:scale(1.24);
          box-shadow:0 0 13px rgba(255,247,220,.98), 0 0 28px rgba(255,226,160,.62);}
  64%    {opacity:calc(var(--so,.7) * .78);transform:scale(1);
          box-shadow:0 0 6px rgba(240,246,255,.55);}
}
.sky__stars--far {filter:blur(.18px) drop-shadow(0 0 2.1px rgba(206,220,255,.78));}
.sky__stars--mid  .star{box-shadow:0 0 6px rgba(232,240,255,.72);}
.sky__stars--near .star{box-shadow:0 0 9px rgba(255,248,228,.95),0 0 22px rgba(255,232,180,.50);}

/* ---------- 随机爆闪：从三层里抽约 10% 的星 ----------
   三层统一呼吸虽然「都在闪」，但节奏相近，整片星空看着还是平的。
   这些星用更短的周期（1.6~3s）+ 大得多的振幅（基准 → 全亮 + 放大 1.85 倍），
   且各自带随机负延迟，效果就是「时不时有几颗特别亮地闪一下」，有生气。
   注意：blink 会和 tw 抢同一个 animation（同优先级，后者胜），
   这是有意为之 —— 爆闪的元素只做爆闪，不做基础呼吸，才够「跳」。 */
.sky__stars .star--blink{
  animation:skyBlink var(--bd,2.2s) ease-in-out infinite;
  animation-delay:var(--bdel,0s);
  will-change:opacity,transform;
}
@keyframes skyBlink{
  /* 爆闪要有「起跳」才有生气：谷值压到基准的 72%（平时淡淡的），
     峰值冲到全亮 + 放大 2.25 倍，光晕扩三层，像真的爆了一下。 */
  /* 谷值压到基准的 34%：实测过一版 .72，透明度起伏只有 0.39，
     比普通呼吸星（0.51）还小 —— 那时它只靠放大和光晕在「装亮」。
     压到 34% 之后落差约 0.66，配合 scale 2.25 与三层光晕才真的像「爆」一下。 */
  0%,58%,100%{opacity:calc(var(--so,.7) * .34);transform:scale(.86);
              box-shadow:0 0 4px rgba(255,248,228,.22);}
  78%        {opacity:1;transform:scale(2.25);
              box-shadow:0 0 14px rgba(255,248,228,1),0 0 34px rgba(255,232,180,.70),
                         0 0 62px rgba(255,210,130,.34);}
}

/* ---------- 流星 ----------
   两层结构：外层只负责「角度」，内层只跑位移。
   角度和位移挤进同一个 transform / 同一个 @keyframes 会互相覆盖，
   表现就是「条的方向和飞行方向对不上」。
   位移必须用 vmax（纯角度换算）——用 vw/vh 混搭时，轨道角会随屏幕比例变形。 */
.sky__meteors{position:absolute;inset:0;z-index:5;overflow:hidden;}
.sky__meteors .meteor{
  position:absolute;display:block;width:0;height:0;    /* 纯锚点：定位 + 角度 */
  transform:rotate(var(--sky-angle,-32deg));
}
.sky__meteors .meteor > i{
  position:absolute;left:0;top:-1.5px;display:block;
  width:var(--ml,220px);height:3px;border-radius:3px;
  transform-origin:0 50%;                              /* 头端固定，尾巴伸缩 */
  opacity:0;
  /* to left：亮头在左端，也就是前进方向那一端 */
  background:linear-gradient(to left,
    rgba(255,255,255,0) 0%,    rgba(198,222,255,.10) 36%,
    rgba(216,234,255,.44) 68%, rgba(240,247,255,.88) 88%, #ffffff 100%);
  filter:drop-shadow(0 0 6px rgba(196,220,255,.90));
  animation:skyMeteor var(--md,18s) linear infinite;
  animation-delay:var(--mdel,0s);
  will-change:transform,opacity;
}
/* 只有周期的前 14% 在飞 —— 「每次只划过 2~3 颗」靠长周期 + 短可见窗口，
   而不是把元素减少（15 颗 × 14% ≈ 同屏 2 颗） */
@keyframes skyMeteor{
  0%   {opacity:0;  transform:translate3d(0,0,0) scaleX(.20);}
  3%   {opacity:.95;}
  9%   {opacity:.82;}
  14%  {opacity:0;  transform:translate3d(-118vmax,0,0) scaleX(1.55);}
  100% {opacity:0;  transform:translate3d(-118vmax,0,0) scaleX(1.55);}
}
/* 定格演示：?sky=freeze 把流星钉在轨迹上（无头截图抓不到动画中间帧） */
.sky__meteors.is-frozen .meteor > i{animation:none !important;}
.sky__meteors.is-frozen .meteor:nth-child(1) > i{opacity:.92;transform:translate3d(-22vmax,0,0) scaleX(1.12);}
.sky__meteors.is-frozen .meteor:nth-child(2) > i{opacity:.62;transform:translate3d(-46vmax,0,0) scaleX(1.34);}
.sky__meteors.is-frozen .meteor:nth-child(3) > i{opacity:.88;transform:translate3d(-70vmax,0,0) scaleX(1.50);}
.sky__meteors.is-frozen .meteor:nth-child(4) > i{opacity:.45;transform:translate3d(-10vmax,0,0) scaleX(.84);}
.sky__meteors.is-frozen .meteor:nth-child(5) > i{opacity:.80;transform:translate3d(-96vmax,0,0) scaleX(1.60);}
.sky__meteors.is-frozen .meteor:nth-child(6) > i{opacity:.70;transform:translate3d(-34vmax,0,0) scaleX(1.22);}
.sky__meteors.is-frozen .meteor:nth-child(7) > i{opacity:.85;transform:translate3d(-58vmax,0,0) scaleX(1.42);}

/* ---------- 减弱动效：氛围放慢保留，绝不一刀切停掉 ----------
   直接 animation:none 会让开了「减弱动态效果」的人看到一片死星空，
   而星空本身就是这一屏的主体；基础态为 opacity:0 的流星更会永远不可见。 */
@media (prefers-reduced-motion:reduce){
  .sky__nebula          {animation-duration:150s !important;}
  .sky__stars .star--tw {animation-duration:calc(var(--sd,6s) * 2.8) !important;}
  .sky__stars .star--blink{animation-duration:calc(var(--bd,2.2s) * 2.6) !important;}
  .sky__meteors .meteor > i{animation-duration:calc(var(--md,18s) * 2.4) !important;}
}
