/* ==========================================================================
   首页 · 3D 群岛地球
   --------------------------------------------------------------------------
   整页只有一块画布和一叠浮在上面的 HUD。
   HUD 的设计原则：不挡住海面中心 —— 中心是小船的位置，也是你正在看的地方。
   所以品牌名贴左上、说明贴左下、漂流瓶贴右下、详情卡贴右侧。
   ========================================================================== */

:root {
  --bg: #040a0f;
  --fg: #e7eef4;
  --dim: #a2b4c2;
  --faint: #6d8291;
  --line: rgba(255, 255, 255, .11);
  --line-hi: rgba(255, 255, 255, .20);
  --glass: rgba(7, 15, 21, .60);
  --glass-hi: rgba(14, 26, 35, .82);
  --accent: #4ec9b0;
  --accent-soft: rgba(78, 201, 176, .14);
  --rock: #7d8a96;
  /* 图例上的「绿岛」色块 —— 必须等于 palette.dark.grass（3D 里那层草地的颜色），
     对不上图例就在说谎。_gtest 里有断言钉着这一条 */
  --grass: #2b6242;
  --warn: #d9a05b;
  /* 天空。画在画布后面，球面以外透出来。
     这四个色要和 home-data.js 的 palette.dark 里那四个对得上 ——
     海面雾化用的 haze 就等于 --sky-horizon，两边一致球面边缘才不会有硬边 */
  --sky-top: #01060f;
  --sky-horizon: #0a2a46;
  --cloud: rgba(212, 231, 248, .16);
  --star-opacity: 1;
  /* 低多边形云整层的开关、天空里那两颗天体的颜色。
     三个都由 home.js 按**真实时刻算出来的天光**写进来（夜 / 朝霞 / 晚霞 / 昼
     四套之间插值），这里只是兜底值 —— 万一 JS 没跑起来，就是夜里这套 */
  --cloud-op: 0;
  --orb-sun: #ffe9c9;
  --orb-moon: #e8f0f8;
  /* 天空带占画面顶部的比例。运行时由 home.js 按视角几何写进来
     （恒等于 viewGeometry 的 skyFraction，也就是 1 − horizonAt）；
     这里只是一个兜底值，万一 JS 没跑起来，天空也有个合理的收边位置。
     它跟主题无关，所以只声明一次，白天主题继承 */
  --sky-h: 50%;
  /* ---- 详情卡里那张海岛插画（globe/illus.js）的配色 ----
     凡是能对上 3D 调色板的，值必须**一模一样** ——
     同一座岛在球上和卡片里是两个颜色，比没画好还糟。
     _gtest 有断言逐个比对（左边是这里的键，右边是 home-data.js palette 的键）：
       --art-sea-deep/deep   --art-sea-mid/mid    --art-sea-foam/foam
       --art-far/haze        --art-sun/sun
       --art-rock/rock       --art-rock-top/rockTop
       --grass/grass         --art-grass-top/grassTop
       --art-wall/wall       --art-roof/roof      --art-trim/trim
       --art-lamp/lamp       --art-glow/glow      --art-wood/wood
       --art-glow-op/glowOpacity
     最后三个（star / canopy / canopy-hi）3D 里没有对应物，是插画专用的。 */
  --art-sea-deep: #04182e;
  --art-sea-mid: #0e4f86;
  --art-sea-foam: #8fd0f0;
  --art-far: #0a2a46;
  --art-sun: #ffe9c9;
  --art-rock: #5b646f;
  --art-rock-top: #79838f;
  --art-grass-top: #3b8256;
  --art-wall: #c9d2db;
  --art-roof: #8d4c3d;
  --art-trim: #e8ecf1;
  --art-lamp: #ffd9a0;
  --art-glow: #ffc46b;
  /* 灯塔光晕的开关。白天必须归零 —— 同 3D 的 glowOpacity：
     只关灯罩不管光晕，会剩下一团自己在发亮的东西 */
  --art-glow-op: .85;
  --art-wood: #7d6047;
  /* 星星的颜色。只声明在夜里这一套就够了 —— 白天整个星群被 --star-opacity
     关掉（见 illus.js 的 stars()），所以白天不需要另一个值。
     ⚠️ 别拿掉那个开关：拿掉之后白天的蓝天上会浮着 26 颗近白的点 */
  --art-star: #dceaf7;
  --art-canopy: #1f4a34;
  --art-canopy-hi: #2f6b4a;
  --font-sans: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  --r: 10px;
  --r-lg: 14px;
  --pill: 999px;
  --ease: .16s ease;
}

[data-theme="light"] {
  --bg: #cfdee6;
  --fg: #0e1720;
  --dim: #46586a;
  --faint: #6b7d8c;
  --line: rgba(9, 26, 38, .14);
  --line-hi: rgba(9, 26, 38, .26);
  --glass: rgba(255, 255, 255, .70);
  --glass-hi: rgba(255, 255, 255, .90);
  --accent: #0f766e;
  --accent-soft: rgba(15, 118, 110, .12);
  --rock: #55636f;
  --grass: #4f9c68;
  --warn: #8a5a0b;
  /* 白天：蓝天白云。星星关掉 —— 大白天不该看见星星 */
  --sky-top: #3f86cf;
  --sky-horizon: #cfe4f2;
  --cloud: rgba(255, 255, 255, .92);
  --star-opacity: 0;
  /* 插画换白天那一套。凡是与 3D 调色板同源的键，值必须等于 palette.light ——
     _gtest 逐个比对的是 dark 那一套（`:root` 里那批），这里是它的对照，
     改一边就得把另一边一起改，否则切到白天岛会变成另一个颜色 */
  --art-sea-deep: #2f7db4;
  --art-sea-mid: #5ea9d8;
  --art-sea-foam: #ffffff;
  --art-far: #cfe4f2;                   /* = haze */
  --art-sun: #fff4dd;
  --art-rock: #8b939b;
  --art-rock-top: #a8b0b8;
  --art-grass-top: #7cc78f;
  --art-wall: #ffffff;
  --art-roof: #b06a52;
  --art-trim: #f0f3f6;
  --art-lamp: #e39325;
  --art-glow: #e8a33d;
  /* 白天灯是灭的 —— palette.light.glowOpacity 就是 0（不是 0.1）。
     只关灯罩不管光晕，大太阳底下会剩一团自己在发亮的东西 */
  --art-glow-op: 0;
  --art-wood: #9c7a56;
  --art-canopy: #3f8a5c;
  --art-canopy-hi: #57a874;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

/* ---------- 天空 ---------- */
/* 画在画布后面。画布带 alpha，球面以外的像素是透明的，于是透出这一层。
   白天是蓝天白云，夜里是星空 —— 两套跟着 data-theme 走。

   --sky-h 是「天空占画面顶部的几分之几」，由 home.js 按 viewGeometry 算出的
   horizonAt 实时写进来（天空带高度 === skyFraction，两者恒等）。
   渐变必须正好在 --sky-h 处收到 --sky-horizon ——
   收早了或收晚了，球面边缘的雾色（palette.haze === --sky-horizon）
   就会和天空对不上，地平线上会露出一道硬边。 */
.sky {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background: linear-gradient(to bottom,
    var(--sky-top) 0%,
    var(--sky-horizon) var(--sky-h, 12%),
    var(--sky-horizon) 100%);
}

/* 星星：一个径向渐变就是一颗星，用 background-size 平铺出去。
   两层不同尺寸的瓦片叠在一起，重复的周期就被打散了。
   位置写在瓦片里靠 repeat 铺满 —— 比手写几十个百分比位置稳，换分辨率也不会忽然变稀。
   铺满整屏没关系：地平线以下被球面盖住了，只有顶部那条天空带里看得见 */
.sky__stars {
  position: absolute;
  inset: 0;
  opacity: var(--star-opacity);
  transition: opacity .45s ease;
  background-repeat: repeat;
  background-size: 300px 210px;
  background-image:
    radial-gradient(circle 1.5px at 38px 24px,   rgba(255, 255, 255, .95) 55%, transparent 100%),
    radial-gradient(circle 1.1px at 156px 92px,  rgba(255, 255, 255, .80) 55%, transparent 100%),
    radial-gradient(circle 1.9px at 262px 46px,  rgba(255, 255, 255, 1)   55%, transparent 100%),
    radial-gradient(circle 1px   at 92px 158px,  rgba(255, 255, 255, .62) 55%, transparent 100%),
    radial-gradient(circle 1.3px at 214px 174px, rgba(255, 255, 255, .86) 55%, transparent 100%),
    radial-gradient(circle 1px   at 12px 108px,  rgba(255, 255, 255, .70) 55%, transparent 100%),
    radial-gradient(circle 1.6px at 118px 40px,  rgba(201, 225, 255, .92) 55%, transparent 100%);
}
/* 第二层次要星，尺寸不同 → 两层的重复周期不同，看不出一块块 */
.sky__stars--far {
  background-size: 173px 131px;
  opacity: calc(var(--star-opacity) * .55);
  background-image:
    radial-gradient(circle 1px   at 21px 17px,   rgba(255, 255, 255, .75) 50%, transparent 100%),
    radial-gradient(circle .9px  at 88px 63px,   rgba(255, 255, 255, .60) 50%, transparent 100%),
    radial-gradient(circle 1.1px at 141px 29px,  rgba(255, 255, 255, .85) 50%, transparent 100%),
    radial-gradient(circle .8px  at 57px 106px,  rgba(255, 255, 255, .50) 50%, transparent 100%),
    radial-gradient(circle 1px   at 120px 114px, rgba(255, 255, 255, .68) 50%, transparent 100%),
    radial-gradient(circle .9px  at 163px 88px,  rgba(255, 255, 255, .55) 50%, transparent 100%);
}

/* 云：几个软椭圆叠一层模糊。白天是白云，夜里是压暗的云影（--cloud 换色）。
   高度跟着天空带走 —— 天空只占顶部一小条，云要是按固定 34% 摆，
   就会整片落在天空带下面，被球面盖住、根本看不见。
   上下各多留 3% 让它漫出边界，免得云被地平线一刀切平 */
.sky__clouds {
  position: absolute;
  left: -8%;
  right: -8%;
  top: -3%;
  height: calc(var(--sky-h, 12%) + 6%);
  filter: blur(18px);
  background-repeat: no-repeat;
  background-image:
    radial-gradient(38% 46% at 20% 58%, var(--cloud) 0%, transparent 70%),
    radial-gradient(30% 40% at 43% 46%, var(--cloud) 0%, transparent 72%),
    radial-gradient(46% 44% at 73% 64%, var(--cloud) 0%, transparent 68%),
    radial-gradient(24% 32% at 60% 40%, var(--cloud) 0%, transparent 74%),
    radial-gradient(30% 38% at 5% 52%,  var(--cloud) 0%, transparent 72%),
    radial-gradient(34% 40% at 91% 56%, var(--cloud) 0%, transparent 70%);
}

/* 低多边形云：硬边多边形，没有模糊 —— 和上面那层软云是两种质感，
   所以两层都留着：软云给天空一层雾底，硬云才是「看得见形状」的那几朵。
   夜里整层 opacity 0，和星星正好互斥。
   飘动纯 CSS：每朵云一条横向关键帧，宽度/高度/速度/起始时间各不相同，
   于是一眼看去是五朵各走各的云，而不是同一朵的五个副本。
   负的 animation-delay 让它们一上来就已经在画面里 —— 否则开局是一小时的空天 */
.sky__lowpoly {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--sky-h, 50%);
  /* 开关交给天光（--cloud-op）：夜里 0、白天 1、晨昏半开。
     原来这里写死「白天才露面」，但朝霞晚霞也是有云的，所以改成连续量 */
  opacity: var(--cloud-op, 0);
  transition: opacity .5s ease;
}
[data-theme="light"] .sky__lowpoly { opacity: var(--cloud-op, 1); transition-delay: .12s; }

/* ---------- 太阳和月亮 ---------- */
/* 摆在天空带里。left / top 由 home.js 按真实日期和时间写进来：
     left 方位角 → 0..1 屏宽（画面正中朝南，所以东在左、西在右）
     top  仰角   → 0..1，再乘 --sky-h
   ⚠️ 竖向必须乘 --sky-h：天空只占画面上半，天体若按整屏高度摆会掉到海面上。
   ⚠️ 圆心对齐用 translate(-50%,-50%)，别用负 margin —— 天体大小随屏幕变，
      负 margin 得跟着改两个数。 */
.orbits { position: absolute; inset: 0; }
.orb {
  position: absolute;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity .6s ease;
}
/* 尺寸 2026-09-25 用户要求翻倍（原来太阳 2rem / 月亮 1.35rem）。
   ⚠️ 光晕不用跟着改：drop-shadow 投的是「这个盒子形状」的模糊影子，
      盒子变大，影子的范围自己跟着变大 */
.orb--sun { width: 4rem; height: 4rem; }
.orb--sun i {
  display: block; width: 100%; height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--orb-sun) 0 30%, transparent 72%);
  /* 光晕跟着天光走：晚霞时是橙红的、白天是近白的 —— 换色不用改这里 */
  filter: drop-shadow(0 0 12px var(--orb-sun));
}
.orb--moon { width: 2.7rem; height: 2.7rem; }
.orb--moon svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* 暗的那半边留一个极淡的轮廓 —— 不然月牙看着像凭空飘着一道弧 */
.orb__disc { fill: rgba(255, 255, 255, .10); }
/* 亮的那半：形状是 home.js 按当天月相现算的路径 */
.orb__lit { fill: var(--orb-moon); filter: drop-shadow(0 0 7px var(--orb-moon)); }

.lp {
  position: absolute;
  display: block;
  height: auto;
  will-change: transform;
}
/* 三个面：本体（中间调）、受光面（最亮）、背光面（最暗）。
   低多边形的「体积」全靠这三档色差，所以别把它们调成一个色 */
.lp__b { fill: #e8f2fb; }
.lp__l { fill: #ffffff; }
.lp__d { fill: #c9dcee; }

.lp--a { width: 11rem;   top: 10%; animation: lpdrift 96s  linear -12s  infinite; }
.lp--b { width: 7.5rem;  top: 46%; animation: lpdrift 74s  linear -40s  infinite; }
.lp--c { width: 9rem;    top: 24%; animation: lpdrift 118s linear -70s  infinite; }
.lp--d { width: 6rem;    top: 60%; animation: lpdrift 64s  linear -22s  infinite; }
.lp--e { width: 12.5rem; top: 5%;  animation: lpdrift 134s linear -100s infinite; }

@keyframes lpdrift {
  0%   { transform: translate3d(-26vw, 0, 0); }
  50%  { transform: translate3d(50vw, -1.6vh, 0); }
  100% { transform: translate3d(126vw, 0, 0); }
}
/* 不动的时候也得摆得开：把每朵钉在自己那一格上，不然会全叠在左边缘 */
@media (prefers-reduced-motion: reduce) {
  .lp { animation: none; }
  .lp--a { transform: translate3d(8vw, 0, 0); }
  .lp--b { transform: translate3d(56vw, 0, 0); }
  .lp--c { transform: translate3d(30vw, 0, 0); }
  .lp--d { transform: translate3d(74vw, 0, 0); }
  .lp--e { transform: translate3d(44vw, 0, 0); }
}
#sea {
  position: fixed;
  inset: 0;
  z-index: 1;                  /* 压在 .sky 之上；球面以外的像素是透明的 */
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;          /* 手机上拖动旋转而不是滚动页面 */
  cursor: grab;
}
#sea.is-grabbing { cursor: grabbing; }

/* 四角压暗一点，让中央的小船更突出，也压住 HUD 的边缘 */
.veil {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(130% 110% at 50% 42%, transparent 42%, rgba(0, 0, 0, .38) 100%);
}
[data-theme="light"] .veil {
  background: radial-gradient(130% 110% at 50% 42%, transparent 46%, rgba(20, 40, 55, .20) 100%);
}

/* ---------- 通用玻璃块 ---------- */
.glass {
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

/* ---------- HUD 容器 ---------- */
.hud {
  position: fixed;
  z-index: 5;
  pointer-events: none;
}
.hud > * { pointer-events: auto; }

/* 天空带：一块和天空等高、横贯画面的 hud，站名在里面居中。
   高度用 --sky-h —— 和 .sky 的渐变收边处是同一个值，所以站名永远
   落在天空正中，换视角（--sky-h 变了）不用回来调这里 */
.hud--sky {
  top: 0; left: 0; right: 0;
  height: var(--sky-h, 50%);
  min-height: 5.5rem;
  display: flex; align-items: center; justify-content: center;
}
/* 右上角那一列：天光读数在上、明暗开关在下 */
.hud--tr {
  top: 1.15rem; right: 1.25rem;
  display: flex; flex-direction: column; align-items: flex-end; gap: .5rem;
}

/* 天光读数：现在是几点、算哪一段天、月亮什么相。
   天光是自动的，所以必须有个地方说清楚它现在算到哪儿了 ——
   不然太阳月亮一直在动，看着像随机的。指针悬停能看到日出日落时刻 */
.skyinfo {
  display: flex; flex-direction: column; align-items: flex-end; gap: .05rem;
  padding: .4rem .7rem;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--r);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  text-align: right; line-height: 1.5;
  color: var(--dim);
}
.skyinfo b { font-size: 12px; font-weight: 600; color: var(--fg); }
.skyinfo em { font-style: normal; font-size: 11px; color: var(--faint); }
/* 左下这一列是有可能比窗口还高的（两张地图 + 图例 + 页脚），
   所以给它自己的滚动，别让内容顶出画面 */
.hud--bl {
  bottom: 1.15rem; left: 1.25rem;
  width: 23rem; max-width: calc(100vw - 2.5rem);
  max-height: calc(100dvh - 3rem);
  display: flex; flex-direction: column; gap: .75rem;
  overflow-y: auto; overscroll-behavior: contain;
  pointer-events: auto;
  scrollbar-width: thin;
}
.hud--bl::-webkit-scrollbar { width: 6px; }
.hud--bl::-webkit-scrollbar-thumb { background: var(--line-hi); border-radius: 3px; }
/* .hud--br（右下角）2026-09 随漂流瓶盒子一起删掉了 —— 盒子换成独立页之后，
   本页再没有元素挂这个定位类。别为了「以后可能用」把它留在那儿。 */
/* 天空正中：岛屿详情卡。
   它占的就是站名原来那块地方 —— 所以同一条消息里站名缩到左上角去（.is-panel）。

   ⚠️ 高度必须**定死**，不能用 max-height + 百分比：
      这个容器的父级是视口（它是 fixed），所以 height 里的百分比有确定含义；
      而换成 max-height 让子元素去算 100%，父级高度是 auto（不定），
      百分比就会退化成 none —— 卡片于是没有上限，内容多了直接长出画面。
      底部再兜一个下限：万一有人把预设换成天空 12% 那套，
      「12% 的天空 − 4.4rem」会算成几像素，卡片就缩成一条缝了。
   容器本身不吃指针（.hud 的规矩），所以卡片以外的空白照样能拖动地球 */
.hud--top {
  top: 3.6rem;                             /* 让开左上角那个缩小后的站名 */
  left: 0; right: 0;
  /* 高度 = 「天空带 − 4.4rem」的 **90%**（用户 2026-09 定的）。
     ⚠️ 0.9 这个乘数只能写在 calc 里面 —— 写在外面的话（比如外面套一层 height 百分比）
        会变成「百分比相对一个 auto 高的父级」，直接退化成 none。 */
  height: max(11.7rem, calc((var(--sky-h, 50%) - 4.4rem) * 0.9));
  display: flex; justify-content: center; align-items: flex-start;
}
/* 底部中间：提示在上，地图 / 主岛两个按钮并排在下面 */
/* 底部中间：提示在上，四个按钮并排，最下面是版权 + 备案那一行。
   ⚠️ width: max-content —— 不然 fixed + left:50% 的元素宽度会被「从 50% 到右边缘」
      那半屏卡住：实测 900px 窗口下可用宽只有 450px，比备案那一行本身还窄，
      于是它**折成两行**、把整条 bar 又往上顶了一截。这是量出来的，不是猜的。
      max-width 兜底：窄到放不下时才允许折行 */
.hud--bc {
  bottom: 1.4rem; left: 50%; transform: translateX(-50%);
  width: max-content; max-width: calc(100vw - 2rem);
  display: flex; flex-direction: column; align-items: center; gap: .7rem;
}
/* 两个按钮并排。DOM 里地图在前、主岛在后 ⇒ 地图就在主岛的左边 */
.bar { display: flex; align-items: center; gap: .55rem; }

/* ---------- 天空里的站名 ---------- */
/* 绝对定位在天空带正中（原来靠 flex 居中，现在要能动，所以改成定位 +
   只靠 transform / left / top 三个可过渡的量）。
   transform-origin 钉在左上角：缩小时是「往左上角收」，而不是原地变小。

   ⚠️ 详情卡展开时会占用站名这块地方（它在天空正中），
      所以那时站名要缩到左上角去；卡一关就自己回来。
      用 scale 而不是改字号 —— 字号过渡会触发逐帧重排，scale 不会。 */
.hero {
  position: absolute;
  left: 50%; top: 50%;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  transform-origin: left top;
  transform: translate(-50%, -50%) scale(1);
  transition: transform .34s cubic-bezier(.22, .61, .36, 1),
              left .34s cubic-bezier(.22, .61, .36, 1),
              top .34s cubic-bezier(.22, .61, .36, 1);
}
/* 标题本身没有可点的东西，但它那个（没被 scale 影响的）布局盒还在：
   scale 只动画面、不动布局 —— 缩到左上角之后，那块透明的盒子正好压在一片
   空地上，会把「按住拖动地球」吃掉。既然它不需要指针，就别接 */
.is-panel .hero {
  left: 1.25rem; top: .85rem;
  transform: translate(0, 0) scale(.46);
  pointer-events: none;
}
/* 缩到 46% 之后底下那句说明只有原来的一半大，读不了 —— 淡出，别留着占地方 */
.hero__tag { transition: opacity .22s ease; }
.is-panel .hero__tag { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .hero, .hero__tag { transition: none; }
}
/* 顶部中央那行小字：站名（学鹏的知识小站，来自 SITE.site.name）。
   ⚠️ 它是**站名**，不是下面那个大字（品牌名 / 世界名）——
      两者数据源不同（SITE.site.name 与 HOME.brand.zh），所以字号要差得明显：
      小字是「这个站是谁」，大字是「这个世界叫什么」，一眼分得开 */
.hero__site {
  margin: 0 0 clamp(.5rem, 1.1vw, .8rem);
  font-size: clamp(11px, 1.15vw, 13px);
  letter-spacing: .3em;
  /* 字距同样会在最后一个字后面加一份 —— 用等量缩进顶回来，不然会看着偏左 */
  text-indent: .3em;
  color: var(--faint);
  text-shadow: 0 1px 12px rgba(0, 0, 0, .45);
}
[data-theme="light"] .hero__site { text-shadow: 0 1px 10px rgba(255, 255, 255, .7); }

.hero__zh {
  margin: 0;
  font-size: clamp(30px, 6vw, 74px);
  font-weight: 600;
  letter-spacing: .16em;
  /* 字距会在最后一个字后面也加一份，视觉上偏左 —— 用等量的缩进顶回来 */
  text-indent: .16em;
  line-height: 1.12;
  color: var(--fg);
  text-shadow: 0 2px 28px rgba(0, 0, 0, .5), 0 1px 2px rgba(0, 0, 0, .35);
}
[data-theme="light"] .hero__zh { text-shadow: 0 2px 24px rgba(255, 255, 255, .75); }

/* 一条细线，中间一颗菱形光点 —— 灯塔的那点光 */
.hero__div {
  position: relative;
  width: clamp(3.4rem, 8vw, 6rem);
  height: 1px;
  margin: clamp(.7rem, 1.6vw, 1.1rem) 0 clamp(.6rem, 1.3vw, .9rem);
  background: linear-gradient(90deg,
    transparent, var(--line-hi) 22%, var(--accent) 50%, var(--line-hi) 78%, transparent);
}
.hero__div::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  width: 5px; height: 5px;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
  transform: translate(-50%, -50%) rotate(45deg);
}
.hero__en {
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(9.5px, 1.05vw, 12.5px);
  letter-spacing: .42em;
  text-indent: .42em;
  text-transform: uppercase;
  color: var(--faint);
}

/* ---------- 主题按钮 ---------- */
.iconbtn {
  background: var(--glass); border: 1px solid var(--line); color: var(--dim);
  border-radius: var(--pill); width: 2.7rem; height: 2.2rem;
  display: grid; place-items: center; cursor: pointer; font-size: 13px;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  transition: var(--ease);
}
.iconbtn:hover { border-color: var(--line-hi); color: var(--fg); }

/* ---------- 天空里那句话（站名底下） ---------- */
.hero__tag {
  margin: clamp(.7rem, 1.4vw, 1rem) 0 0;
  max-width: 32ch;
  font-size: clamp(12px, 1.1vw, 13.6px);
  line-height: 1.8;
  color: var(--dim);
  text-wrap: pretty;
}

/* ---------- 左下：世界地图 / 藏宝图（默认收起） ---------- */
/* 平时藏在底部那个「岛屿地图」按钮后面；展开时卡片出现在说明文字的下方，
   给它一个短促的入场动画，看得出东西是从下面长出来的。
   ⚠️ [hidden] 要显式写死 display: none —— 卡片挂在 flex 栏里，
      靠 UA 的默认规则容易在某次改动之后被覆盖掉，那时它就会「关不掉」 */
.atlas { padding: .65rem .8rem .75rem; animation: cardin .22s ease; }
.atlas[hidden] { display: none; }
@keyframes cardin {
  from { opacity: 0; transform: translateY(.6rem); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .atlas { animation: none; } }

/* 卡片顶上那一条：左边「N/M 座绿岛」，右边复位。
   （原来左边是页签 —— 藏宝图拆成独立按钮之后页签没了，这条就只剩两个东西，
     所以改成两头撑开。页签那几条样式跟着页签一起删掉，不留死规则） */
.atlas__bar { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .55rem; }
.atlas__stat {
  font-family: var(--font-mono); font-size: 11px; color: var(--faint); white-space: nowrap;
}
.atlas__stat b { font-family: var(--font-sans); font-size: 15px; font-weight: 650; color: var(--accent); }
.atlas__stat i { font-style: normal; }

/* 复位按钮：地图能缩放就必须给一个回得去的出口 */
.atlas__reset {
  background: none; border: 1px solid var(--line); color: var(--faint);
  border-radius: var(--r); padding: .1rem .45rem; margin: 0;
  font: inherit; font-size: 11.5px; line-height: 1.5;
  cursor: pointer; white-space: nowrap; transition: var(--ease);
}
.atlas__reset:hover { color: var(--fg); border-color: var(--line-hi); }
.atlas__reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.atlas__pane[hidden] { display: none; }

/* 地图：一个 viewBox 撑满宽度的 SVG。灰点用一条 path 画完（stroke-linecap: round
   让零长线段变成一个圆点），一千个位置只占一个 DOM 节点 */
.atlasmap {
  display: block; width: 100%; height: auto;
  border-radius: var(--r);
  background: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, 0));
  cursor: crosshair;
  /* 图能按住拖动，所以要吃掉触摸的默认行为 —— 不写的话手指一拖是滚页面，
     地图纹丝不动。放大之后准星换成抓手，一眼看得出「现在可以拖了」 */
  touch-action: none;
}
.atlasmap.is-zoomed  { cursor: grab; }
.atlasmap.is-panning { cursor: grabbing; }
/* 点阵：一条 path，每段是长度 0 的线，圆头线帽把它画成一个圆点 */
.atlasmap .dot  { fill: none; stroke: var(--rock);  stroke-width: 2.4; stroke-linecap: round; opacity: .40; }
.atlasmap .dotg { fill: none; stroke: var(--grass); stroke-width: 5;   stroke-linecap: round; opacity: .95; }
.atlasmap .mk   { fill: var(--grass); stroke: var(--bg); stroke-width: 1.1; }
.atlasmap .mkt  {
  fill: var(--fg); font-family: var(--font-mono); font-size: 7.4px;
  text-anchor: middle; dominant-baseline: middle; pointer-events: none;
}
.atlasmap .lead { stroke: var(--dim); stroke-width: .7; opacity: .5; }
.atlasmap .you  { fill: none; stroke: var(--accent); stroke-width: 1.2; }
.atlasmap .youx { stroke: var(--accent); stroke-width: 1; opacity: .85; }
.atlasmap .rim  { fill: none; stroke: var(--line-hi); stroke-width: 1; }
.atlasmap .cross { fill: none; stroke: var(--warn); stroke-width: 1.4; }

.atlas__read {
  margin: .5rem 0 0;
  font-family: var(--font-mono); font-size: 10.5px; color: var(--faint);
  min-height: 1.2em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 藏宝图的四位数输入 */
.hunt { display: flex; gap: .4rem; margin-top: .6rem; }
.hunt__in {
  flex: 1; min-width: 0;
  font-family: var(--font-mono); font-size: 15px; letter-spacing: .28em;
  text-align: center;
  color: var(--fg); background: rgba(255, 255, 255, .05);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: .3rem .4rem .3rem .68rem;
}
.hunt__in::placeholder { color: var(--faint); }
.hunt__in:focus { outline: none; border-color: var(--accent); }
.hunt__go { padding: .3rem .85rem; font-size: 12.5px; }
.hunt__msg {
  margin: .5rem 0 0; font-size: 11.5px; line-height: 1.6;
  color: var(--faint); min-height: 1.7em;
}
.hunt__msg b { color: var(--fg); font-weight: 600; }

@media (max-height: 660px) {
  .legend { display: none; }
  .atlasmap { max-height: 132px; }
}
.legend { list-style: none; margin: 0 0 .85rem; padding: 0; display: grid; gap: .3rem; }
.lg__i { display: flex; align-items: center; gap: .5rem; font-size: 12.6px; color: var(--dim); }
.lg__i i { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.lg__i--rock i { background: var(--rock); }
.lg__i--grass i {
  background: var(--grass);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), inset 0 -1px 0 rgba(0, 0, 0, .30);
}
.lg__i--boat i {
  background: none; border: 1.5px solid var(--accent); border-radius: 50%;
  width: 11px; height: 11px;
}
.lg__i em { font-style: normal; color: var(--faint); margin-left: .3rem; font-size: 12px; }

.foot { font-size: 11.6px; color: var(--faint); line-height: 1.85; }
.foot p { margin: 0 0 .18rem; }

/* ---------- 底部最下面那一行：版权声明 + 备案号 ----------
   ⚠️ 2026-09 用户要求：把它从左上（左下那一栏的页脚里）搬到四个按钮下方。
      备案号必须**挂在主视线里**，缩在角落容易被当成没有备案 ——
      这一行在画面最底下、正中间，和四个按钮同一条竖轴上。
   ⚠️ 备案号必须一直可见：窄屏那两条规则最多只能收紧字号，
      不许 display: none（ICP 备案号是要展示在站点上的） */
.footbar {
  margin: 0;
  font-size: 11px; line-height: 1.7; color: var(--faint);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0 .45rem;
  text-align: center;
}
.footbar__copy { font-family: var(--font-mono); letter-spacing: .02em; white-space: nowrap; }
.footbar__sep { opacity: .5; }
/* 备案那两串号由 beian.js 塞进来，是一个 <a> 加一个带图标的 <a>，
   所以这里只管排版，字色靠继承 */
.footbar__beian { font-family: var(--font-mono); white-space: nowrap; }

/* 备案行：ICP 号 · 警徽 + 公安联网备案号（内容由 assets/js/beian.js 填）。
   ⚠️ 这两条样式在 style.css 里还有一份 —— home.html 只加载 home.css，
      不引 style.css，所以两边都要有。改高度记得一起改 */
.beian__icp, .beian__ga { color: inherit; }
.beian__icp:hover, .beian__ga:hover { color: var(--accent); text-decoration: underline; }
.beian__sep { opacity: .5; }
.beian__logo {
  /* ⚠️ 必须显式写 inline-block：规矩和 style.css 那份一样（那边第 188 行有
     `img, svg, video { display: block }` 的通用重置）。首页虽然不引 style.css，
     但保留同一条能保证哪天两边合并时行为不变，也让两份样式逐字对齐好对比。 */
  display: inline-block;
  /* 高度用 1em：跟当前字一样大。写死 17px 时，首页 11px 的字配 17px 的徽标，
     图标反而比字还高。用 em 能自动跟着每页各自的字号走。 */
  height: 1em; width: auto;
  /* 徽标中心对汉字视觉中心，比贴基线看着更齐 */
  vertical-align: -.12em;
  /* 和后面的「鲁公网安备」留一点空隙 */
  margin-right: .25em;
}

/* ---------- 底部提示 ---------- */
.hint {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em;
  color: var(--faint); background: var(--glass); backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px); border: 1px solid var(--line);
  border-radius: var(--pill); padding: .3rem .9rem;
  animation: hintout 1.2s ease 7s forwards;
}
@keyframes hintout { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { .hint { animation: none; } }

/* ---------- 底部这条 bar：四个按钮共用一套底子 ---------- */
/* 岛屿地图 / 藏宝图 / 主岛 / 漂流瓶 —— DOM 顺序就是左右顺序。
   ⚠️ 底子只写一份、四个按钮都挂 .navbtn，分开写四份迟早会走样
      （「岛屿地图」和「主岛」原来就是这么绑在一块的，2026-09 把藏宝图、
      漂流瓶也并了进来）。每个按钮剩下的不同之处只有「图标长什么样」。
   一个按钮 = 左边 32px 图标位 + 右边一块两行字（正题 + 一行小注）。 */
.navbtn {
  display: inline-flex; align-items: center; gap: .6rem;
  /* ⚠️ 高度钉死、上下不留内边距 ——「四个一样大」是明确要求，
     不靠各自凑一个内边距去对齐（凑出来的差值肉眼看得出来） */
  height: 2.75rem; padding: 0 .85rem 0 .42rem;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: var(--pill); cursor: pointer; color: var(--dim);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  transition: var(--ease);
}
.navbtn:hover { border-color: var(--accent); color: var(--fg); }
.navbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* 点亮 = 「这个东西 / 这张图现在是开着的」。地图按钮收起来之后，
   这是唯一一眼能看出开没开的地方（em 那行字是第二处） */
.navbtn.is-on {
  border-color: var(--accent); color: var(--fg);
  background: var(--glass-hi); box-shadow: 0 0 0 3px var(--accent-soft);
}
.navbtn__i { width: 32px; height: 32px; flex: none; display: grid; place-items: center; }
.navbtn__i svg { width: 21px; height: 21px; display: block; }
.navbtn__txt { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.navbtn__txt b { font-size: 12.5px; font-weight: 600; letter-spacing: .06em; }
.navbtn__txt em {
  font-style: normal; font-family: var(--font-mono);
  font-size: 10px; color: var(--faint); letter-spacing: .04em;
}

/* 图标一：摊开的地图（岛屿地图） */
.mb__b { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.mb__l { fill: none; stroke: currentColor; stroke-width: 1.2; opacity: .55; }
/* 图标二：一个圈 + 一个叉，宝藏标在这儿（藏宝图）。
   ⚠️ 四个图标必须一眼分得开 —— 长得像的话，四个按钮排在一起就只剩颜色能认了 */
.tb__c { fill: none; stroke: currentColor; stroke-width: 1.2; opacity: .45; }
.tb__x { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
/* 图标三：一只瓶子，瓶里那道横的是卷起来的纸条（漂流瓶） */
.bb__b { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.bb__l { fill: none; stroke: var(--warn); stroke-width: 1.3; stroke-linecap: round; }

/* ---------- 底部：指南针（回到主岛） ---------- */
/* 底子在上面 .navbtn 里，这里只剩「针」这一件它自己的事 */
.compass:active .compass__ring { transform: scale(.94); }
.compass__ring {
  position: relative;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--line-hi);
  background: radial-gradient(circle at 50% 30%, var(--accent-soft), transparent 72%);
  transition: transform .18s ease;
  flex: none;
}
/* 针：两个三角形背靠背。朝主岛的那一半是实色，另一半压暗 ——
   不用图片，切主题时颜色自动跟着走 */
.compass__needle {
  position: absolute; inset: 0;
  will-change: transform;
  transition: transform .38s cubic-bezier(.22, .61, .36, 1);
}
.compass__needle::before,
.compass__needle::after {
  content: "";
  position: absolute; left: 50%;
  width: 0; height: 0;
  transform: translateX(-50%);
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
}
.compass__needle::before { top: 4px; border-bottom: 10px solid var(--accent); }
.compass__needle::after  { bottom: 4px; border-top: 10px solid var(--line-hi); }
.compass__hub {
  position: absolute; left: 50%; top: 50%;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--fg);
  box-shadow: 0 0 0 2px var(--glass);
  transform: translate(-50%, -50%);
}
/* 主岛已经在画面正中时，针收起来、只留一个点亮的圆环。
   ⚠️ 这两条必须排在 .navbtn.is-on 后面（本文件从上往下读，谁的规则在后谁赢）：
      「已在主岛」和「这张图点开了」两件事同时成立时，环上那个点亮归这条管。
      挪到前面去，环就不会亮了 —— 页面不报错，只是看着不对 */
.compass.is-here .compass__needle { opacity: 0; }
.compass.is-here .compass__ring {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
@media (prefers-reduced-motion: reduce) {
  .compass__needle { transition: none; }
}

/* ---------- 屏幕阅读器专用文字 ---------- */
/* 本页只剩藏宝图那个编号输入框在用（见 home.html 的 #huntCode）——
   它没有可见的 label，少了这条就是「一个没名字的输入框」。
   原来右下角那个漂流瓶盒子里也用过一次，盒子 2026-09 撤掉了。 */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* 漂流瓶按钮的底子和图标也在上面 .navbtn / .bb__* 里 ——
   2026-09 用户要求它「按主岛按钮方式重新制作」，所以它不再有自己的
   一套 padding / 字号 / 15px 图标，和另外三个一模一样 */

/* 右下角那个漂流瓶盒子（.bottlebox 一整套）2026-09 已删 ——
   用户把它换成了独立页 bottles.html，首页那个按钮现在是 <a> 跳转。
   留着这些规则的话它们会永远匹配不到元素，而后来的人会以为盒子的样式还在用。
   上面 .bb__* 那两笔是按钮上的瓶子图标，那个还在用，别一起删了 */

.btn {
  background: var(--glass-hi); border: 1px solid var(--line); color: var(--fg);
  border-radius: var(--pill); padding: .4rem .9rem; font: inherit; font-size: 12.8px;
  cursor: pointer; transition: var(--ease);
}
.btn:hover { border-color: var(--line-hi); }
.btn--primary {
  background: var(--accent); border-color: var(--accent); color: #04231f; font-weight: 600;
}
[data-theme="light"] .btn--primary { color: #fff; }
.btn--primary:hover { filter: brightness(1.08); }

/* ---------- 天空正中：岛屿详情 ---------- */
/* 两栏：左边这座岛的插画 + 上岛按钮，右边岛志。
   卡片高度上限由 .hud--top 给定，文字那一栏自己滚 ——
   这样左栏的插画永远是满血的大小，不会被长文案挤扁。
   （⚠️ 正因为右栏会滚，「上岛」按钮才不能放进去 —— 见 .pn__enter）
   宽度 43.4rem = 上一版 62rem 的 **70%**（用户 2026-09 定的）。
   卡片窄了，左栏反而要占更大比例 —— 见 .pnv，不然岛会跟着一起变小 */
.panel {
  position: relative;
  padding: 1rem 1.1rem;
  max-height: 100%;
  display: flex; flex-direction: row; align-items: stretch; gap: 1rem;
  width: min(43.4rem, calc(100vw - 2.5rem));
  overflow: hidden;                        /* 圆角得把两栏一起裁进去 */
}
.panel[hidden] { display: none; }
/* min-height: 0 不能省：flex 子项默认不肯缩到内容以下，那样它就不会滚，只会把卡片顶长 */
.panel__body {
  flex: 1 1 auto; min-width: 0; min-height: 0;
  max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin;
  padding-right: 1.5rem;                   /* 给右上角那个 × 让位 */
}
.panel__x {
  position: absolute; top: .6rem; right: .7rem; background: none; border: 0;
  color: var(--faint); font-size: 18px; line-height: 1; cursor: pointer; padding: 0;
  z-index: 1;
}
.panel__x:hover { color: var(--fg); }

/* ---------- 左边那一栏：插画 + 上岛入口 ---------- */
/* 这一栏从上到下放三样：插画、上岛按钮、一行小字。
   ⚠️ 按钮**不放在右栏**（用户 2026-09 提的交互问题）：
      右栏是要滚的（岛志可能很长），按钮塞在里面就得先滚到卡片底部才点得到 ——
      而「上岛」恰恰是这张卡上最该随手点到的动作。留在左栏、紧贴插画下方，
      就永远不用滚。（按钮和插画在同一个 flex 列里，插画 flex:1 吃掉剩余高度，
      按钮 flex:none 钉在下面 —— 所以无论卡片多高，按钮都在能看见的位置。）
   46% 是跟着卡片变窄一起调上来的：卡片只有 43.4rem 了，
   预览还占三成四的话图会小一圈，而这一版要的正是「岛再大一些」 */
.pnv {
  flex: 0 0 clamp(11rem, 46%, 20rem); min-width: 0; max-height: 100%;
  display: flex; flex-direction: column; gap: .45rem;
}
/* 插画框。⚠️ position: relative + 里面的 svg 绝对定位，是为了让**图撑不大这个框**：
   框的高度由这一栏的 flex 布局算出来，图只负责铺满。不这么写就成了循环依赖 ——
   图要看框来决定画多大，框又要看图的尺寸来定自己多高。
   画幅比例（框的宽 / 高）由 home.js 量出来交给 illus.js 现画，
   所以图铺满时既不裁边也不留黑边 */
.pnv__pic {
  position: relative; flex: 1 1 auto; min-height: 0;
  border-radius: var(--r); overflow: hidden;
  background: var(--sky-horizon);         /* 图还没插进去时先垫一层天色，别闪白 */
}
.pnv__pic svg {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
}
.pnv__note {
  margin: 0; font-family: var(--font-mono); font-size: 10.5px;
  line-height: 1.5; color: var(--faint);
}
/* 插画没画出来（老设备 / 出错）时撤掉那个空框。
   ⚠️ 撤的是**框**，不是整栏 —— 上一版写的是 .pnv { display:none }，
      那会连「上岛」按钮一起藏掉：图没画出来，路也不通了，两件事不该绑在一起 */
.pnv.is-off .pnv__pic { display: none; }
.pn__k {
  margin: 0 0 .3rem; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .08em; color: var(--faint); text-transform: uppercase;
}
.pn__t { margin: 0 0 .7rem; font-size: 20px; font-weight: 650; letter-spacing: .02em; }
.pn__row {
  display: flex; gap: .6rem; margin: 0 0 .3rem; font-size: 12.8px; color: var(--dim);
}
.pn__row span { color: var(--faint); min-width: 3.4rem; }
.pn__row b { color: var(--fg); font-weight: 600; }
.pn__q {
  margin: .7rem 0 0; font-size: 14.6px; line-height: 1.7; color: var(--fg);
  padding-left: .8rem; border-left: 2px solid var(--accent);
}
.pn__p { margin: .6rem 0 0; font-size: 13px; color: var(--dim); }
.pn__gap {
  margin: .7rem 0 0; font-size: 12.8px; color: var(--dim); line-height: 1.7;
  background: rgba(255, 255, 255, .04); border-radius: 8px; padding: .55rem .7rem;
}
.pn__gap b { display: block; color: var(--warn); font-size: 11.5px; margin-bottom: .15rem; }
.pn__meta { margin: .7rem 0 0; font-family: var(--font-mono); font-size: 11.5px; color: var(--faint); }
/* 上岛入口：整行宽的大按钮。
   它是这张卡上唯一一个「往深处走」的动作，缩成一行小字链接太容易被看漏 ——
   所以给足体量：满宽、实底色、左边一个船锚、右边一个箭头。
   标签和副标签都来自 home-data.js 的 panel.*，改文案不用碰这里。

   ⚠️ 它现在是**左栏 flex 列的一个子项**（上一版被拼进右栏的 HTML 里，
      跟着岛志一起滚 —— 那正是用户要改掉的交互）。所以：
        flex: none —— 按内容高，别跟插画抢剩余高度；
        没有 margin-top —— 和插画的间距由 .pnv 的 gap 管 */
.pn__enter {
  flex: none;
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .75rem;
  background: var(--accent); color: #04231f;
  border-radius: var(--r); text-decoration: none;
  transition: var(--ease);
}
/* ⚠️ 不能省：UA 样式表里的 [hidden] { display: none } 打不过上面那条
   display: flex（作者样式优先），没有这一条「该藏起来的按钮」会照常显示 */
.pn__enter[hidden] { display: none; }
[data-theme="light"] .pn__enter { color: #fff; }
.pn__enter:hover { filter: brightness(1.08); }
.pn__enter:active { transform: translateY(1px); }
.pn__enter:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.pn__enter b { font-size: 14.5px; font-weight: 650; letter-spacing: .04em; }
.pn__enter em { font-style: normal; font-size: 11px; opacity: .8; margin-left: auto; }
.pn__enter i { font-style: normal; font-size: 15px; line-height: 1; }
/* 船锚图标：船开到岛边才上岛，这个动作就是图标画的那件事。
   描边用 currentColor ⇒ 跟着按钮的文字色走，白天/黑夜都不用另配一套 */
.pn__ico { flex: none; display: block; width: 15px; height: 15px; }

/* ---------- 启动遮罩 ---------- */
.boot {
  position: fixed; inset: 0; z-index: 40; display: grid; place-content: center;
  gap: .5rem; text-align: center; background: var(--bg);
  transition: opacity .55s ease; padding: 2rem;
}
.boot.is-done { opacity: 0; pointer-events: none; }
.boot__t { margin: 0; font-size: 17px; font-weight: 650; letter-spacing: .04em; }
.boot__p { margin: 0; font-family: var(--font-mono); font-size: 12px; color: var(--faint); }
.boot__bar {
  width: 180px; height: 2px; margin: .6rem auto 0; border-radius: 99px;
  background: var(--line); overflow: hidden;
}
.boot__bar i {
  display: block; width: 40%; height: 100%; background: var(--accent); border-radius: 99px;
  animation: bootmove 1.1s ease-in-out infinite;
}
@keyframes bootmove { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .boot__bar i { animation: none; width: 100%; } }

/* ---------- 窄屏 ---------- */
/* 窗口不够宽的时候，左下那一栏和底部这一整块（四个按钮 + 下面那行版权备案）
   会撞上：两者都贴着画面下沿，只要横向重叠就压住了。
   ⚠️ 断点是**实测量出来的**，两次都量错过，别凭感觉改：
      · 左下栏右缘 = 1.25rem + 23rem = 364px（实测值，不是 23rem 换算出来的 368）
      · 底部最宽的不是四个按钮（449px），是下面那行备案（486px）——
        按按钮宽度算断点，就会漏掉「备案行压住左下栏」这一种重叠
      · 需要 (视口 − 486)/2 ≥ 364 + 8  ⇒  视口 ≥ 1230px
      另外「抬多高」也是量出来的：按钮顶边距画面底边 92px（备案行 20 + 间距 11
      + 按钮 41 + 底 21），所以抬 6.6rem(105.6px) 才够；原来按两个按钮算的
      4.6rem(73.6px) 在加了备案那一行之后**已经不够了**。
   ⚠️ 这条不再挂在 .is-maps 上了 —— 重叠跟地图开没开无关
      （没开的时候左下栏底下是页脚那几行字，照样被压住）。
      挂上去的话收起状态的重叠就没人管了，而那个 class 也就只剩一个读者都没有的 toggle */
@media (max-width: 1260px) {
  /* 抬起来的同时要把高度上限收回来：它是 bottom 定位的，
     只抬 bottom 不改 max-height 的话，顶上会有一截伸到画面外、而且滚不到
     （滚动条只在盒子内部滚） */
  .hud--bl { bottom: 6.6rem; max-height: calc(100dvh - 8.6rem); }
}

@media (max-width: 860px) {
  .hud--bl { max-width: 15rem; }
  .legend { display: none; }
  /* 备案号已经搬到底部那条 .footbar 里了，`.foot` 里现在只剩那几行说明 ——
     所以这条不用再写 :not(.foot__beian) 绕开它（绕开一个不存在的东西，
     读代码的人会以为备案还在这儿） */
  .foot p { display: none; }
  /* 四个按钮在窄屏上排不下，把每个按钮那行小注收起来、内边距收紧 ——
     变成「图标 + 正题字」。⚠️ 收起 em 之后，「哪张图开着」就只剩
     .navbtn.is-on 的边框点亮这一处指示了，所以那条样式不能跟着一起收 */
  .navbtn { gap: .45rem; padding: 0 .62rem 0 .32rem; }
  .navbtn__txt em { display: none; }
  .bar { gap: .4rem; }
  /* 天空不够高了：卡片改成上下两层，往下多借一点地方。
     0.9 这个乘数同样只能留在 calc 里面（理由同上面 .hud--top 那一条注释） */
  .hud--top { top: 3.2rem; height: max(11.7rem, calc((var(--sky-h, 50%) + 7rem) * 0.9)); }
  .panel { flex-direction: column; gap: .7rem; width: min(30rem, calc(100vw - 2rem)); }
  .pnv { flex: 0 0 auto; }
  /* 窄屏变成上下两层，插画占满整行宽 —— 这时候不能用「吃掉剩余高度」，
     否则宽度一大、高度就只剩一条。
     ⚠️ 用 aspect-ratio 而不是写死高度：写死 9rem 的话，行宽 480px 会得到
        3.33 的比例，超出 illus.js 支持的画幅范围，图会被裁掉一截。
        16/9 落在范围内，也不用为每种屏宽再调一次数 */
  .pnv__pic { flex: none; aspect-ratio: 16 / 9; }
  .panel__body { max-height: 32dvh; }
  /* ⚠️ 不能整块藏掉 .hud--bc —— 地图按钮就在里面，藏了地图就再也打不开了。
      藏的是那句提示，按钮留着 */
  .hint { display: none; }
}
@media (max-width: 560px) {
  /* 再窄就换行，2×2 排。按钮上的正题字一个都不删 ——
     光剩四个图标谁都认不出来。max-width 卡在两列宽，
     所以第一行摆两个就会折 */
  .bar { flex-wrap: wrap; justify-content: center; max-width: 15.5rem; }
  /* bar 现在有两行高，左下栏得跟着再抬（实测按钮顶边距画面底边 158px） */
  .hud--bl { bottom: 10.8rem; max-height: calc(100dvh - 13rem); }
  /* 天空窄了，两颗天体跟着收一点，别压到站名上（比桌面那档小，仍是翻倍后的量级） */
  .orb--sun { width: 3.1rem; height: 3.1rem; }
  .orb--moon { width: 2.1rem; height: 2.1rem; }
}

@media (max-width: 520px) {
  /* 这一栏在窄屏上只剩地图卡片（图例、页脚都收起来了），
     卡片没展开时它的高度是 0，自己就看不见 —— 不用再 display: none */
  .hud--bl { left: .6rem; right: .6rem; width: auto; max-width: none; }
  .foot { display: none; }
  .brand__en { display: none; }
  .tagline { display: none; }
}
