/* ============================================================
   心尘的私家工坊 — 液态玻璃 · 天依蓝
   ------------------------------------------------------------
   配色取自洛天依：天依蓝 #66CCFF 为主，青碧 #66CCAA 为瞳色点缀，
   银白为底。整体收敛为 蓝 — 青 — 白 三色系。
   ------------------------------------------------------------
   目录
   01 设计变量
   02 基础重置
   03 背景 / 光晕（含背景开关）
   04 玻璃材质（核心）
   05 顶部导航
   06 首屏
   07 区块通用
   08 音乐播放器
   09 博客
   10 工具
   11 照片墙 + 灯箱
   12 联系方式 + 页脚
   13 iOS Dock
   14 阅读浮层
   15 提示 / 动效 / 响应式
   ============================================================ */

/* ---------- 01 设计变量 ---------- */
:root {
  /* 天依蓝（主色阶） */
  --brand-100: #eaf7ff;
  --brand-200: #cceaff;
  --brand-300: #a3dbff;
  --brand-400: #66ccff;   /* 洛天依主题色 */
  --brand-500: #3ab8f5;
  --brand-600: #1e9be0;
  --brand-700: #1478b4;

  /* 青碧（瞳色点缀） */
  --aqua: #66ccaa;
  --aqua-soft: #b8ebdc;

  /* 银白 / 中灰（发色语汇） */
  --silver: #e6ecf5;
  --silver-2: #f4f8fc;

  /* 底 / 面板 */
  --tint-50: #f2faff;
  --tint-100: #e4f4ff;
  --tint-200: #d3edfd;

  /* 文字：冷调深灰，不用纯黑 */
  --ink: #2b3a4a;
  --ink-soft: #5a6b7d;
  --ink-mute: #93a3b4;

  /* 玻璃 —— 光学参数都抽成变量，改这里就能整体调浓淡 */
  /* 填充越淡，玻璃越"透"、越靠边缘的光去撑质感；调大就更像磨砂白面板。
     三档是给不同用途分级的：普通卡片 / 需要更实一点的面板 / 长文阅读。
     图片模式下会再整体降一档（见文件下方 body[data-bg="image"]）。 */
  --glass-bg: rgba(255, 255, 255, 0.3);
  --glass-bg-strong: rgba(255, 255, 255, 0.46);
  --glass-bg-reader: rgba(255, 255, 255, 0.54);
  /* 冷灰发丝边。玻璃的"棱"要靠一道很淡的暗线定义，
     纯白描边会把边缘烧白，反而没有厚度。 */
  --glass-line: rgba(120, 164, 200, 0.26);
  --glass-line-soft: rgba(255, 255, 255, 0.4);
  --glass-shadow: 0 18px 44px -22px rgba(60, 110, 150, 0.4);
  --glass-blur: 22px;
  /* 折射对比放大强度，只用在"图片背景"模式下（渐变背景看不出效果）。
     调大 = 玻璃底下那层明暗差被拉得更开，边缘的"镜头感"更强。 */
  --glass-contrast: 1.42;
  /* 深色内圈强度 —— 玻璃的"壁"。没有它，玻璃只是一团雾。 */
  --glass-rim: 0.13;
  /* 角部高光收束：越大越集中在两个对角，中间越干净 */
  --glass-tr: 24%;

  /* 尺寸 */
  --radius-xl: 32px;
  --radius-lg: 24px;
  --radius-md: 16px;
  --radius-sm: 11px;
  --page: min(1140px, 92vw);
  --dock-h: 70px;

  /* 动效 */
  --ease: cubic-bezier(0.22, 0.68, 0.32, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  color-scheme: light;
}

/* ---------- 02 基础重置 ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Noto Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
  background: var(--tint-50);
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img { max-width: 100%; display: block; }
/* padding:0 是必须的 —— 浏览器给 <button> 的默认值是 1px 6px。
   不清掉的话，凡是把 <button> 当容器用的地方（照片墙的格子就是），
   内容会被左右各挤进 6px，看着就像没填满。 */
button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  border: 0;
  padding: 0;
  background: none;
}
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.25; }
p { margin: 0; }

:focus-visible {
  outline: 2.5px solid var(--brand-500);
  outline-offset: 3px;
  border-radius: 6px;
}

/* 统一图标描边风格 */
.ic {
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
.ic--fill { fill: currentColor; stroke: none; }

.svg-defs { position: absolute; width: 0; height: 0; }

/* 墨迹标题字体：霞鹜文楷（由 index.html 的 <link> 引入；失败自动回退系统楷体/宋体） */

/* ---------- 03 背景 / 樱花 ---------- */
.bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}

.bg__wash {
  position: absolute;
  inset: -8%;
  background:
    linear-gradient(160deg,
      #f4fbff 0%,
      #e8f6ff 34%,
      #ecf9ff 62%,
      #f2fbff 100%);
  transition: opacity 0.7s var(--ease);
}

/* 图片背景层：默认隐藏；body[data-bg="image"] 时显现。
   图片路径由 data.js 的 background.image 提供（写进 --bg-image）。 */
.bg__photo {
  position: absolute;
  inset: 0;
  opacity: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  background-image: var(--bg-image, none);
  transition: opacity 0.7s var(--ease);
  transform: scale(1.04);
}
.bg__photo::after {
  /* 图上盖一层薄雾。玻璃填充调淡之后，这层雾就是文字可读性的主要保障 ——
     所以它不是均匀的：顶部（顶栏固定压着的那一条）给得实一些，
     因为照片顶部常常是深色的，顶栏又是全站最需要看清的一处；
     中部给得薄，让照片尽量保持原味。
     想让照片更"生"可以把中间几档调小，但低于 0.24 左右大段文字会开始发飘。 */
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      rgba(246, 252, 255, 0.58) 0%,
      rgba(242, 250, 255, 0.46) 7%,
      rgba(236, 248, 255, 0.3) 18%,
      rgba(232, 246, 255, 0.24) 55%,
      rgba(238, 249, 255, 0.3) 100%);
}
body[data-bg="image"] .bg__photo { opacity: 1; }
body[data-bg="image"] .bg__wash { opacity: 0; }

/* 光晕：只留两团（蓝 + 青），弱化处理，保持通透 */
.blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(86px);
  opacity: 0.5;
  will-change: transform;
  transition: opacity 0.7s var(--ease);
}
body[data-bg="image"] .blob { opacity: 0.22; }

.blob--brand {
  width: 54vw; height: 54vw; max-width: 700px; max-height: 700px;
  top: -16vw; left: -8vw;
  background: radial-gradient(circle at 42% 42%, #9fdcff, #66ccff 46%, transparent 72%);
  animation: drift1 30s var(--ease) infinite alternate;
}
.blob--aqua {
  width: 48vw; height: 48vw; max-width: 620px; max-height: 620px;
  bottom: -18vw; right: -10vw;
  background: radial-gradient(circle at 55% 45%, #b8ebdc, #66ccaa 48%, transparent 74%);
  animation: drift2 36s var(--ease) infinite alternate;
}

@keyframes drift1 {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(5vw, 4vh, 0) scale(1.1); }
}
@keyframes drift2 {
  from { transform: translate3d(0, 0, 0) scale(1.05); }
  to   { transform: translate3d(-5vw, -5vh, 0) scale(1); }
}

/* 细颗粒，避免大面积渐变出现色带 */
.bg__grain {
  position: absolute;
  inset: 0;
  opacity: 0.38;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

#petals {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  transition: opacity 0.7s var(--ease);
}
body[data-bg="image"] #petals { opacity: 0.5; }

/* 鼠标拖尾：浮在内容之上、UI 之下，不挡任何交互 */
#trail {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 55;
}

/* ---------- 04 玻璃材质（核心） ----------
   统一光照模型，向 iOS 新版液态玻璃看齐。四层叠出质感：
     ① 基底    —— 背景模糊 + 提饱和
     ② 内壁高光 —— 顶部一道受光、底部一道反光（模拟玻璃厚度）
     ③ 边缘折射 —— ::before，带轻微的色散（蓝/青边缘），统一光向
     ④ 镜面反光 —— ::after，跟随指针走
   变量：
     --light  光线方向（全站统一，从上偏左打下来）
     --depth  这块玻璃的厚度，由 app.js 随机化，让每块不完全一样
     --mx/--my 指针位置（0~100%），由 app.js 写入
   ---------------------------------------- */
.glass {
  position: relative;
  --light: 145deg;
  --depth: 1;
  background-color: var(--glass-bg);
  /* 45° 对角扫光：两个对角各抓到一道光，中间收干净。
     这一层是常驻的 —— 玻璃搁在那儿就在反光，不是只有鼠标移上去才亮。
     --glass-tr 控制收束：值越大，光越往角上聚、中间越空。
     放在元素自身的 background 上（而不是伪元素），
     这样它和"跟随鼠标的镜面反光"就能各用各的透明度，互不牵连。 */
  background-image: linear-gradient(45deg,
    rgba(255, 255, 255, 0.5) 0%,
    rgba(255, 255, 255, 0.05) calc(var(--glass-tr) * 0.5),
    transparent var(--glass-tr),
    transparent calc(100% - var(--glass-tr)),
    rgba(255, 255, 255, 0.05) calc(100% - var(--glass-tr) * 0.5),
    rgba(255, 255, 255, 0.5) 100%);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.75);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.75);
  border: 1px solid var(--glass-line);
  box-shadow:
    /* 外投影：玻璃是"浮"在页面上的 */
    var(--glass-shadow),

    /* ── ① 主斜面 ──
       光在左上 / 右下两个对角各切出一道锐利的亮边。
       同时点亮对角、而不是只给单侧打光，是液态玻璃最标志性的一笔：
       真实的玻璃棱从任何角度看，都会同时抓到两处光，
       这两道锐边是整块玻璃"硬"的来源。 */
    inset calc(2.1px * var(--depth)) calc(-2.1px * var(--depth))
          calc(1.2px * var(--depth)) calc(-1.1px * var(--depth)) rgba(255, 255, 255, 0.95),
    inset calc(-2.1px * var(--depth)) calc(2.1px * var(--depth))
          calc(1.2px * var(--depth)) calc(-1.1px * var(--depth)) rgba(255, 255, 255, 0.9),

    /* ── ② 次斜面 ──
       更宽更柔的第二道，从锐边往里扩散，
       做出"棱最亮、往里迅速变薄"的截面，而不是一圈均匀白框。 */
    inset calc(7px * var(--depth)) calc(-7px * var(--depth))
          calc(2.4px * var(--depth)) calc(-6.4px * var(--depth)) rgba(255, 255, 255, 0.5),
    inset calc(-7px * var(--depth)) calc(7px * var(--depth))
          calc(2.4px * var(--depth)) calc(-6.4px * var(--depth)) rgba(255, 255, 255, 0.44),

    /* ── ③ 厚度扩散 ──
       由边缘向内一层层变薄，宽度递增、强度递减。 */
    inset 0 0 calc(5px * var(--depth)) calc(-0.6px * var(--depth)) rgba(255, 255, 255, 0.4),
    inset 0 0 calc(16px * var(--depth)) calc(-5px * var(--depth)) rgba(255, 255, 255, 0.34),
    inset 0 0 calc(40px * var(--depth)) calc(-16px * var(--depth)) rgba(255, 255, 255, 0.38),

    /* ── ④ 深色内圈 ──
       紧贴在亮边内侧的一道暗线 —— 玻璃的"壁"。
       少了它，玻璃就只是一团发白的雾，没有面。 */
    inset 0 0 calc(2.6px * var(--depth)) calc(0.2px * var(--depth)) rgba(24, 56, 86, var(--glass-rim)),

    /* ── ⑤ 色散 ──
       背光侧（右下）玻璃更厚、泛冷蓝；受光侧（左上）偏一丝青。
       这点极淡的偏色就是玻璃边界特有的折射感。 */
    inset calc(-1.3px * var(--depth)) calc(-1.5px * var(--depth))
          calc(15px * var(--depth)) calc(-4px * var(--depth)) rgba(118, 188, 252, 0.3),
    inset calc(1.3px * var(--depth)) calc(1.5px * var(--depth))
          calc(15px * var(--depth)) calc(-4px * var(--depth)) rgba(150, 228, 226, 0.22);

  border-radius: var(--radius-lg);
  overflow: hidden;
  isolation: isolate;
}

/* 背景换成照片时，透过来的细节多了，"对比放大"才真的有东西可放大，
   于是给 backdrop-filter 追加一个 contrast：它会拉开玻璃下面那层的明暗差，
   看上去就像玻璃边缘把背景微微掰弯了。
   （参考视频里是给整页套 filter:contrast()；这里写在 backdrop-filter 内部，
     只作用于透过来的背景，不会连文字和内容一起放大。
     渐变背景几乎没有细节可放大，所以默认不挂 —— 既看不出效果，又白花性能。） */
/* 图片模式下玻璃整体再透一档 —— 背景是特意挑的，不该被一块白板盖住。
   三个填充变量一起降级，靠变量链自动传给每一块玻璃（含 Dock、阅读器）。
   注意：填充越淡，文字就越依赖底下那层压雾，所以下面 .bg__photo::after 不能一起减太狠。 */
body[data-bg="image"] {
  --glass-bg: rgba(255, 255, 255, 0.2);
  --glass-bg-strong: rgba(255, 255, 255, 0.32);
  --glass-bg-reader: rgba(255, 255, 255, 0.44);

  /* 图片模式下的文字色要单独压深：
     玻璃变透之后，透过来的照片是中间调，原本那两档浅灰（次要说明、小标签）
     跟它几乎同亮度，会直接糊在背景里。
     玻璃保持通透、可读性交给文字颜色 —— 这是唯一不牺牲透明度的做法。
     代价是"次要文字"不再那么轻了；想在通透和层次之间换个平衡点，就调这两个值。 */
  --ink-soft: #3a4c60;
  --ink-mute: #4e6076;
}

body[data-bg="image"] .glass {
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.75) contrast(var(--glass-contrast));
  backdrop-filter: blur(var(--glass-blur)) saturate(1.75) contrast(var(--glass-contrast));
}

/* 面板变透了，贴在面板上的这几块大芯片也得跟着降一档，
   否则会变成一块"白贴纸"，跟通透的面板脱节。
   只调大块芯片 —— 小图标的 hover 底色是交互反馈，不能跟着变淡。 */
body[data-bg="image"] .search { background-color: rgba(255, 255, 255, 0.36); }
body[data-bg="image"] .dock__item.is-active { background-color: rgba(255, 255, 255, 0.52); }
body[data-bg="image"] .playlist__item.is-current { background-color: rgba(255, 255, 255, 0.46); }
body[data-bg="image"] .glass-btn { background-color: rgba(255, 255, 255, 0.3); }

/* 最外圈那道 1px 的折射亮环 + 色散。
   主斜面的 box-shadow 已经负责"面上的光"，这一层只补最外侧的一线，
   并把玻璃边界的偏色（受光偏青、背光偏蓝）压在最外面。 */
.glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background:
    linear-gradient(var(--light),
      rgba(255, 255, 255, calc(0.46 + 0.2 * var(--depth))) 0%,
      rgba(255, 255, 255, 0.1) 30%,
      rgba(255, 255, 255, 0.03) 56%,
      rgba(255, 255, 255, calc(0.24 + 0.16 * var(--depth))) 100%),
    linear-gradient(var(--light),
      rgba(150, 230, 255, 0.5) 0%,
      transparent 22%),
    linear-gradient(calc(var(--light) + 180deg),
      rgba(120, 190, 255, 0.42) 0%,
      transparent 20%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
  z-index: 2;
  transform-origin: center;
  transition: transform 0.5s var(--ease), opacity 0.5s var(--ease);
}

/* 跟随指针的镜面反光：指针划到哪，玻璃表面就在哪亮起来。
   只有这一层是悬停才出现的（对角扫光常驻在 .glass 自己的 background 上）。
   用负 z-index 沉到内容之下（.glass 已 isolation:isolate，不会漏到页面背景），
   于是它只照亮玻璃表面，绝不会糊住按钮和文字。
   柔化靠渐变本身的多个停靠点，不用 filter:blur() ——
   这一层每帧都跟着指针重画，再挂一个模糊滤镜会明显吃性能。 */
.glass::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: -1;
  opacity: var(--sheen, 0);
  transition: opacity 0.5s var(--ease);
  background: radial-gradient(
    calc(300px + 90px * var(--depth)) circle at var(--mx, 50%) var(--my, 0%),
    rgba(255, 255, 255, 0.6) 0%,
    rgba(255, 255, 255, 0.34) 16%,
    rgba(255, 255, 255, 0.12) 40%,
    rgba(255, 255, 255, 0.03) 58%,
    transparent 74%);
}

.glass:hover::after { --sheen: 1; }

/* 交互形变：指针进入时玻璃微微"鼓起"，按下时像被压了一下。
   只动边缘层，不动元素本身，避免和卡片自身的悬停位移打架。 */
.glass:hover::before { transform: scale(1.004); }
.glass.is-pressed::before {
  transform: scale(0.982);
  opacity: 0.85;
}
/* 按下时：边缘收一点，玻璃体内的光更弥散（像被压了一下） */
/* 按下时：斜面被压扁（棱往里收、变钝），玻璃体内的光更弥散，
   内圈加深一点，像被指头按进去了一小块。 */
.glass.is-pressed {
  box-shadow:
    var(--glass-shadow),

    inset calc(1.2px * var(--depth)) calc(-1.2px * var(--depth))
          calc(1px * var(--depth)) calc(-0.6px * var(--depth)) rgba(255, 255, 255, 0.72),
    inset calc(-1.2px * var(--depth)) calc(1.2px * var(--depth))
          calc(1px * var(--depth)) calc(-0.6px * var(--depth)) rgba(255, 255, 255, 0.68),

    inset calc(4px * var(--depth)) calc(-4px * var(--depth))
          calc(2px * var(--depth)) calc(-3.5px * var(--depth)) rgba(255, 255, 255, 0.42),
    inset calc(-4px * var(--depth)) calc(4px * var(--depth))
          calc(2px * var(--depth)) calc(-3.5px * var(--depth)) rgba(255, 255, 255, 0.38),

    inset 0 0 calc(8px * var(--depth)) calc(-1px * var(--depth)) rgba(255, 255, 255, 0.4),
    inset 0 0 calc(24px * var(--depth)) calc(-6px * var(--depth)) rgba(255, 255, 255, 0.42),
    inset 0 0 calc(56px * var(--depth)) calc(-18px * var(--depth)) rgba(255, 255, 255, 0.46),

    inset 0 0 calc(3px * var(--depth)) calc(0.3px * var(--depth)) rgba(24, 56, 86, calc(var(--glass-rim) * 1.5)),

    inset calc(-0.8px * var(--depth)) calc(-0.9px * var(--depth))
          calc(17px * var(--depth)) calc(-4px * var(--depth)) rgba(118, 188, 252, 0.26),
    inset calc(0.8px * var(--depth)) calc(0.9px * var(--depth))
          calc(17px * var(--depth)) calc(-4px * var(--depth)) rgba(150, 228, 226, 0.18);
}

/* 光标离开时把形变收回去 */
@media (hover: none) {
  .glass:hover::before { transform: none; }
}

/* 顶栏上的按钮 —— 同一套光学语言，只是缩到 42px 的尺度：
   小控件上最出效果的是内侧那圈暗线，它把"厚壁"讲清楚了。 */
.glass-btn {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border-radius: 14px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.4);
  border: 1px solid var(--glass-line);
  box-shadow:
    /* 对角斜面 */
    inset 1.4px -1.4px 1px -0.7px rgba(255, 255, 255, 0.95),
    inset -1.4px 1.4px 1px -0.7px rgba(255, 255, 255, 0.85),
    /* 内侧暗线：玻璃的厚壁 */
    inset 0 0 2px 0.4px rgba(24, 56, 86, 0.16),
    /* 厚度扩散 */
    inset 0 0 4px -1px rgba(255, 255, 255, 0.5),
    inset 0 0 12px -4px rgba(255, 255, 255, 0.42);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease),
              color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.glass-btn:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.72);
  color: var(--brand-700);
  box-shadow:
    inset 1.4px -1.4px 1px -0.7px rgba(255, 255, 255, 1),
    inset -1.4px 1.4px 1px -0.7px rgba(255, 255, 255, 0.9),
    inset 0 0 2px 0.4px rgba(24, 56, 86, 0.2),
    inset 0 0 5px -1px rgba(255, 255, 255, 0.6),
    inset 0 0 14px -4px rgba(255, 255, 255, 0.5),
    0 8px 18px -10px rgba(60, 110, 150, 0.7);
}
.glass-btn:active { transform: translateY(0) scale(0.95); }

/* ---------- 05 顶部导航 ---------- */
.topbar {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  width: var(--page);
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 10px 12px 10px 18px;
  border-radius: 22px;
  --glass-blur: 20px;
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease), background 0.5s var(--ease);
}
.topbar.is-scrolled {
  /* 只改底色，不用 background 简写 —— 否则会把 .glass 的对角扫光一起清掉 */
  background-color: var(--glass-bg-strong);
  box-shadow: 0 22px 50px -24px rgba(60, 110, 150, 0.55);
}

@keyframes spin-slow { to { transform: rotate(360deg); } }

/* 左侧站名 */
.brand { display: flex; align-items: center; gap: 9px; min-width: 0; flex: none; }
.brand__mark { width: 24px; height: 24px; flex: none; animation: spin-slow 16s linear infinite; }
.brand__mark svg { width: 100%; height: 100%; }
.brand__text {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 时钟（24 小时制） */
.clock {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  padding: 0 2px;
  white-space: nowrap;
}

/* 中段：随所在屏切换（首页天气 / 内容页搜索 / 其余留空） */
.topbar__ctx {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* 语言开关（中 / EN） */
.lang-toggle {
  position: relative;
  display: flex;
  align-items: center;
  width: 80px;
  height: 42px;
  padding: 4px;
  border-radius: 14px;
  flex: none;
  background: rgba(255, 255, 255, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.6);
  transition: background 0.3s var(--ease);
}
.lang-toggle:hover { background: rgba(255, 255, 255, 0.66); }
.lang-toggle__opt {
  position: relative;
  z-index: 2;
  flex: 1;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  line-height: 34px;
  color: var(--ink-mute);
  transition: color 0.32s var(--ease);
}
.lang-toggle__knob {
  position: absolute;
  z-index: 1;
  top: 4px; left: 4px;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: linear-gradient(140deg, #ffffff, #e8f3fc);
  box-shadow: 0 4px 12px -4px rgba(45, 80, 110, 0.5),
              inset 0 1px 0 rgba(255, 255, 255, 0.95);
  transition: transform 0.42s var(--ease);
}
body[data-lang="en"] .lang-toggle__knob { transform: translateX(36px); }
body[data-lang="en"] .lang-toggle__opt[data-lang="en"],
body:not([data-lang="en"]) .lang-toggle__opt[data-lang="zh"] { color: var(--brand-700); }

/* 搜索 */
.search {
  display: flex;
  align-items: center;
  gap: 9px;
  width: min(400px, 100%);
  height: 42px;
  padding: 0 11px 0 13px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.52);
  border: 1px solid rgba(255, 255, 255, 0.72);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.92);
  animation: fade 0.32s var(--ease) both;
}
.search__icon { width: 18px; height: 18px; color: var(--ink-mute); }
.search__input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  outline: none;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
}
.search__input::placeholder { color: var(--ink-mute); }
.search__input::-webkit-search-cancel-button { display: none; }
.search__clear {
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  flex: none;
  color: var(--ink-mute);
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.search__clear:hover { background: rgba(255, 255, 255, 0.85); color: var(--brand-700); }
.search__clear .ic { width: 14px; height: 14px; }

/* 天气条（顶部） */
.wx {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13.5px;
  color: var(--ink-soft);
  min-width: 0;
  overflow: hidden;
  animation: fade 0.45s var(--ease) both;
}
.wx__temp {
  font-size: 21px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1;
}
.wx__cond { font-weight: 600; color: var(--brand-700); white-space: nowrap; }
.wx__div { width: 1px; height: 18px; background: rgba(90, 107, 125, 0.22); flex: none; }
.wx__row {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
}
.wx__row .ic { width: 15px; height: 15px; color: var(--brand-600); flex: none; }
.wx__row b {
  color: var(--ink);
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wx__row i { font-style: normal; color: var(--ink-mute); }

.topbar__actions { display: flex; align-items: center; gap: 8px; flex: none; }

/* 设了 display 的元素，hidden 属性要显式压回去 */
.search[hidden],
.wx[hidden],
.hero__tools[hidden] { display: none !important; }

/* 搜索没有结果时的提示 */
.search-empty {
  margin-top: clamp(20px, 3vw, 34px);
  padding: 26px;
  text-align: center;
  font-size: 14.5px;
  color: var(--ink-mute);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.4);
  border: 1px dashed rgba(255, 255, 255, 0.85);
}

/* 背景开关：两颗图标 + 一枚滑动的玻璃滑块 */
.bg-switch {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  width: 76px;
  height: 42px;
  padding: 4px;
  border-radius: 14px;
  flex: none;
  background: rgba(255, 255, 255, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.6);
  transition: background 0.3s var(--ease);
}
.bg-switch:hover { background: rgba(255, 255, 255, 0.66); }

.bg-switch__icon {
  position: relative;
  z-index: 2;
  flex: 1;
  display: grid;
  place-items: center;
  height: 100%;
  color: var(--ink-mute);
  transition: color 0.32s var(--ease);
}
.bg-switch__icon .ic { width: 18px; height: 18px; }

/* 滑块：默认停在左边（渐变） */
.bg-switch__knob {
  position: absolute;
  z-index: 1;
  top: 4px; left: 4px;
  width: 33px;
  height: 33px;
  border-radius: 10px;
  background: linear-gradient(140deg, #ffffff, #e8f3fc);
  box-shadow: 0 4px 12px -4px rgba(45, 80, 110, 0.5),
              inset 0 1px 0 rgba(255, 255, 255, 0.95);
  transition: transform 0.42s var(--ease);
}

/* 选中态：渐变模式高亮左图标，图片模式高亮右图标 */
body[data-bg="gradient"] .bg-switch__icon--grad,
body:not([data-bg]) .bg-switch__icon--grad { color: var(--brand-700); }
body[data-bg="image"] .bg-switch__icon--img { color: var(--brand-700); }

/* 图片模式：滑块滑到右边 */
body[data-bg="image"] .bg-switch__knob { transform: translateX(33px); }

.sound-toggle .ic--off { display: none; }
.sound-toggle[aria-pressed="false"] .ic--on { display: none; }
.sound-toggle[aria-pressed="false"] .ic--off { display: block; }

/* ---------- 05b 横向分页舞台 ----------
   整站是一排横向的「屏」，一屏一个板块。
   track 负责平移，slide 负责各自的内部纵向滚动。 */
.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
}

.track {
  display: flex;
  width: 100%;
  height: 100%;
  will-change: transform;
  transition: transform 0.85s var(--ease-out);
}
.track.is-dragging { transition: none; }

.slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/* 每屏内部可独立上下滚动（内容超出时），内容不满时垂直居中。
   用 margin-block:auto 而非 justify-content:center，避免超高内容顶部被裁掉。 */
.slide__scroll {
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  padding: 112px 0 calc(var(--dock-h) + 52px);
  scrollbar-width: thin;
  scrollbar-color: rgba(102, 204, 255, 0.45) transparent;
}
.slide__scroll::-webkit-scrollbar { width: 8px; }
.slide__scroll::-webkit-scrollbar-thumb {
  border-radius: 99px;
  background: rgba(102, 204, 255, 0.45);
}
.slide__scroll::-webkit-scrollbar-track { background: transparent; }

.slide__inner {
  width: var(--page);
  margin-inline: auto;
  margin-block: auto;
}

/* 翻页箭头 */
.pager {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  z-index: 65;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.72);
  -webkit-backdrop-filter: blur(16px) saturate(1.6);
  backdrop-filter: blur(16px) saturate(1.6);
  box-shadow: 0 12px 28px -14px rgba(60, 110, 150, 0.6);
  transition: transform 0.35s var(--ease), background 0.35s var(--ease),
              color 0.35s var(--ease), opacity 0.35s var(--ease);
}
.pager:hover { background: #fff; color: var(--brand-700); }
.pager--prev { left: max(18px, calc((100vw - var(--page)) / 2 - 66px)); }
.pager--next { right: max(18px, calc((100vw - var(--page)) / 2 - 66px)); }
.pager--prev:hover { transform: translateY(-50%) translateX(-3px); }
.pager--next:hover { transform: translateY(-50%) translateX(3px); }
.pager[disabled] { opacity: 0.32; pointer-events: none; }

/* 翻页圆点：底部居中，浮在 Dock 上方。
   做成轻量的一排小点（不加深色药丸底），免得和 Dock 抢视觉。 */
.dots {
  position: fixed;
  left: 50%;
  bottom: calc(var(--dock-h) + 26px);
  transform: translateX(-50%);
  z-index: 65;
  display: flex;
  align-items: center;
  gap: 8px;
}
.dots__dot {
  width: 8px;
  height: 8px;
  border-radius: 99px;
  padding: 0;
  background: rgba(90, 107, 125, 0.34);
  box-shadow: 0 1px 3px rgba(255, 255, 255, 0.9), 0 0 0 1px rgba(255, 255, 255, 0.5);
  transition: background 0.35s var(--ease), width 0.35s var(--ease);
}
.dots__dot:hover { background: var(--brand-500); }
.dots__dot.is-active {
  width: 22px;
  background: linear-gradient(90deg, var(--brand-500), var(--aqua));
}

/* ---------- 06 首屏 ---------- */
.slide--hero .slide__scroll {
  padding-top: 104px;
  padding-bottom: calc(var(--dock-h) + 58px);
}

.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(24px, 5vw, 64px);
}

.hero__card {
  padding: clamp(22px, 2.6vw, 32px);
  border-radius: var(--radius-xl);
  --glass-blur: 26px;
  animation: rise 1s var(--ease-out) both;
}

.hero__avatar { position: relative; width: 86px; height: 86px; margin-bottom: 14px; }
.hero__avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 12px 30px -12px rgba(102, 204, 255, 0.6);
}
.hero__ring {
  position: absolute;
  inset: -11px;
  border-radius: 50%;
  border: 1.5px dashed rgba(102, 204, 255, 0.45);
  animation: spin-slow 20s linear infinite reverse;
}
.hero__avatar::after {
  content: "";
  position: absolute;
  right: 4px; bottom: 6px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--aqua);
  border: 3px solid #fff;
  box-shadow: 0 0 0 3px rgba(102, 204, 170, 0.4);
}

.hero__hi {
  font-size: 14px;
  letter-spacing: 0.14em;
  color: var(--brand-700);
  font-weight: 600;
}

.hero__title {
  margin: 6px 0 14px;
  font-size: clamp(34px, 5.2vw, 58px);
  line-height: 1.06;
  letter-spacing: -0.01em;
}
.hero__title-cn {
  font-family: "LXGW WenKai", "Songti SC", "STSong", "STKaiti", "KaiTi", serif;
  background: linear-gradient(96deg, var(--brand-700) 6%, var(--brand-500) 46%, var(--aqua) 94%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: block;
}
.hero__title-sub {
  display: block;
  font-size: 0.42em;
  font-weight: 600;
  color: var(--ink-soft);
  letter-spacing: 0.16em;
  margin-top: 10px;
}

.hero__tagline {
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  font-size: clamp(17px, 2.1vw, 21px);
  color: var(--ink);
  margin-bottom: 14px;
}

.hero__intro {
  font-size: 14.5px;
  line-height: 1.8;
  color: var(--ink-soft);
  max-width: 46ch;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.hero__tags { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 18px; }
.hero__tags span {
  padding: 6px 14px;
  font-size: 13px;
  border-radius: 999px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow: 0 4px 12px -6px rgba(60, 110, 150, 0.35);
}

.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 20px; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 28px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), background 0.35s var(--ease);
  will-change: transform;
}
.btn--primary {
  color: #fff;
  background: linear-gradient(120deg, var(--brand-500), var(--aqua) 58%, var(--brand-400));
  box-shadow: 0 14px 30px -12px rgba(102, 204, 255, 0.78),
              inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.btn--primary:hover {
  transform: translateY(-3px) scale(1.02);
  box-shadow: 0 22px 40px -14px rgba(102, 204, 255, 0.85),
              inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.btn--ghost {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.8);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.btn--ghost:hover { transform: translateY(-3px); background: rgba(255, 255, 255, 0.75); }

/* 首页的工具快捷入口：一排玻璃小卡，点开即用 */
.hero__tools { margin-top: clamp(12px, 1.8vw, 18px); }
.hero__tools-label {
  font-size: 12.5px;
  letter-spacing: 0.16em;
  color: var(--ink-mute);
  margin-bottom: 10px;
}
.hero__tool-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.hero__tool {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px 9px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.46);
  border: 1px solid rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: blur(16px) saturate(1.7);
  backdrop-filter: blur(16px) saturate(1.7);
  box-shadow: 0 10px 24px -16px rgba(60, 110, 150, 0.7),
              inset 0 1px 0 rgba(255, 255, 255, 0.9);
  transition: transform 0.42s var(--ease-out), background 0.35s var(--ease),
              box-shadow 0.42s var(--ease-out);
}
.hero__tool:hover {
  transform: translateY(-4px);
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 20px 34px -18px rgba(60, 110, 150, 0.8),
              inset 0 1px 0 rgba(255, 255, 255, 0.95);
}
.hero__tool-icon {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: 11px;
  flex: none;
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.hero__tool-icon .ic { width: 17px; height: 17px; }
.hero__tool-icon[data-accent="pink"] { background: linear-gradient(135deg, var(--brand-400), var(--aqua-soft)); }
.hero__tool-icon[data-accent="blue"] { background: linear-gradient(135deg, var(--brand-600), var(--brand-300)); }
.hero__tool-icon[data-accent="lilac"] { background: linear-gradient(135deg, var(--brand-700), var(--brand-400)); }
.hero__tool-icon[data-accent="mint"] { background: linear-gradient(135deg, var(--aqua), var(--aqua-soft)); }
.hero__tool-name { font-size: 14.5px; font-weight: 600; }
.hero__tool-desc {
  font-size: 12.5px;
  color: var(--ink-mute);
  max-width: 15ch;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hero__tool-arrow { color: var(--ink-mute); transition: transform 0.4s var(--ease), color 0.4s var(--ease); }
.hero__tool-arrow .ic { width: 15px; height: 15px; }
.hero__tool:hover .hero__tool-arrow { transform: translate(3px, -3px); color: var(--brand-700); }

/* 悬浮唱片 */
.hero__vinyl {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 20px;
  animation: rise 1s 0.15s var(--ease-out) both;
}

.vinyl {
  position: relative;
  width: clamp(210px, 26vw, 320px);
  aspect-ratio: 1;
  border-radius: 50%;
  padding: 0;
  transition: transform 0.6s var(--ease-out);
}
.vinyl:hover { transform: scale(1.04); }

.vinyl__disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  background: conic-gradient(from 0deg, #23303d, #3d5062, #1b252f, #33475a, #23303d);
  box-shadow:
    0 30px 60px -24px rgba(45, 80, 110, 0.7),
    inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  animation: spin-slow 22s linear infinite;
}
.vinyl__disc::before {
  content: "";
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  background: repeating-radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, 0.055) 0 1.5px, transparent 1.5px 5px);
}
.vinyl__cover {
  position: absolute;
  inset: 21%;
  width: 58%; height: 58%;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, 0.5);
}
.vinyl__hole {
  position: absolute;
  left: 50%; top: 50%;
  width: 8%; height: 8%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0 42%, #e4eef7 44%, #b8c6d4);
  box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.4);
  z-index: 2;
}
.vinyl__shine {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: linear-gradient(118deg,
    rgba(255, 255, 255, 0) 34%,
    rgba(255, 255, 255, 0.5) 46%,
    rgba(255, 255, 255, 0) 58%,
    rgba(255, 255, 255, 0.25) 68%,
    rgba(255, 255, 255, 0) 80%);
  mix-blend-mode: screen;
}

.vinyl__meta { padding: 12px 22px; border-radius: 18px; text-align: center; }
.vinyl__now { display: block; font-size: 14px; font-weight: 600; }
.vinyl__hint { display: block; font-size: 12px; color: var(--ink-mute); margin-top: 2px; }

/* 播放中：唱片转快、暂停停转 */
.hero__vinyl.is-playing .vinyl__disc { animation-duration: 6.5s; }
.hero__vinyl:not(.is-playing) .vinyl__disc { animation-play-state: paused; }

@keyframes floaty {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, -7px); }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(26px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- 07 区块通用 ---------- */
/* 各屏共用的标题区（宽度由 .slide__inner 决定） */
.section__head { margin-bottom: clamp(24px, 3.4vw, 40px); max-width: 62ch; }

.section__kicker {
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  font-size: 15px;
  font-style: italic;
  color: var(--brand-700);
  letter-spacing: 0.04em;
}

.section__title {
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  font-size: clamp(30px, 4.4vw, 46px);
  margin: 4px 0 12px;
  letter-spacing: 0.01em;
}

.section__desc { color: var(--ink-soft); font-size: 15px; }

/* 图片模式下，各屏的小标题是直接压在照片上的，没有玻璃垫底，
   照片亮一块暗一块就会把字吃掉。给它们一道很淡的白色光晕，把字托起来。
   玻璃卡片内部的文字不需要 —— 它们本来就有垫底。 */
body[data-bg="image"] .section__kicker,
body[data-bg="image"] .section__title,
body[data-bg="image"] .section__desc,
body[data-bg="image"] .hero__tools-label {
  text-shadow:
    0 1px 3px rgba(255, 255, 255, 0.96),
    0 0 10px rgba(255, 255, 255, 0.88),
    0 0 24px rgba(240, 250, 255, 0.72);
}

/* 标题区带一个右侧控件时用这版：标题在左、控件贴着底线在右 */
.section__head--row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 24px;
  max-width: none;
}
@media (max-width: 620px) {
  .section__head--row { flex-direction: column; align-items: flex-start; }
}

/* 两选一的视图切换（照片墙 / 时间轴） */
.viewswitch {
  display: inline-flex;
  gap: 3px;
  flex: none;
  padding: 4px;
  border-radius: 999px;
  --glass-blur: 16px;
  --depth: 0.8;
}
.viewswitch__btn {
  padding: 7px 15px;
  border-radius: 999px;
  font-size: 13px;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--ink-soft);
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.viewswitch__btn:hover { color: var(--brand-700); }
.viewswitch__btn.is-on {
  color: var(--brand-700);
  font-weight: 700;
  background: rgba(255, 255, 255, 0.85);
  box-shadow: 0 5px 14px -9px rgba(60, 110, 150, 0.9),
              inset 0 1px 0 rgba(255, 255, 255, 0.95);
}

/* 滚动进场 */
.reveal { opacity: 0; transform: translateY(30px); }
.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}

/* ---------- 08 音乐播放器 ---------- */
.player {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 48px);
  padding: clamp(24px, 3.4vw, 40px);
  border-radius: var(--radius-xl);
  --glass-blur: 26px;
}

.player__left { position: relative; display: grid; place-items: center; }

.player__disc {
  position: relative;
  width: min(100%, 280px);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: conic-gradient(from 40deg, #23303d, #3d5062, #1b252f, #33475a, #23303d);
  box-shadow: 0 24px 50px -22px rgba(45, 80, 110, 0.7),
              inset 0 0 0 1px rgba(255, 255, 255, 0.14);
  animation: spin-slow 20s linear infinite;
  animation-play-state: paused;
}
.player__disc::before {
  content: "";
  position: absolute;
  inset: 5%;
  border-radius: 50%;
  background: repeating-radial-gradient(circle at 50% 50%,
    rgba(255, 255, 255, 0.05) 0 1.5px, transparent 1.5px 5.5px);
}
.player__disc img {
  position: absolute;
  inset: 20%;
  width: 60%; height: 60%;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, 0.45);
}
.player__disc-hole {
  position: absolute;
  left: 50%; top: 50%;
  width: 7%; height: 7%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0 40%, #e4eef7 46%, #b8c6d4);
  z-index: 2;
}
.player__disc.is-spinning { animation-play-state: running; }

.player__vinyl-shadow {
  position: absolute;
  bottom: 6%;
  width: 62%;
  height: 26px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(60, 110, 150, 0.32), transparent 72%);
  filter: blur(7px);
  z-index: -1;
}

.player__right { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

.player__label {
  font-size: 12px;
  letter-spacing: 0.2em;
  color: var(--brand-700);
  font-weight: 600;
}
.player__song {
  font-size: clamp(22px, 3vw, 30px);
  margin: 4px 0 4px;
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player__artist { color: var(--ink-mute); font-size: 14px; }

.progress { display: flex; align-items: center; gap: 14px; }
.progress__time {
  font-size: 12.5px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  min-width: 44px;
  text-align: center;
}
.progress__track {
  position: relative;
  flex: 1;
  height: 22px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}
.progress__track::before {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  height: 6px;
  transform: translateY(-50%);
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 2px rgba(60, 110, 150, 0.18);
}
.progress__buffer,
.progress__fill {
  position: absolute;
  left: 0; top: 50%;
  height: 6px;
  transform: translateY(-50%);
  border-radius: 99px;
  pointer-events: none;
}
.progress__buffer { background: rgba(255, 255, 255, 0.75); }
.progress__fill {
  width: 0;
  background: linear-gradient(90deg, var(--brand-400), var(--aqua));
  box-shadow: 0 0 12px rgba(102, 204, 255, 0.6);
}
.progress__thumb {
  position: absolute;
  right: -8px; top: 50%;
  width: 16px; height: 16px;
  transform: translateY(-50%) scale(0.7);
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand-400);
  box-shadow: 0 3px 10px -2px rgba(102, 204, 255, 0.9);
  transition: transform 0.3s var(--ease);
  opacity: 0;
}
.progress__track:hover .progress__thumb,
.progress__track:focus-visible .progress__thumb,
.progress.is-active .progress__thumb { transform: translateY(-50%) scale(1); opacity: 1; }

.player__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 1.6vw, 18px);
  flex-wrap: wrap;
}

.ctrl {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.66);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease);
}
.ctrl:hover { transform: translateY(-3px); background: rgba(255, 255, 255, 0.8); color: var(--brand-700); }
.ctrl[aria-pressed="true"] { color: var(--brand-700); background: rgba(204, 234, 255, 0.85); }

.ctrl--play {
  width: 68px; height: 68px;
  color: #fff;
  background: linear-gradient(130deg, var(--brand-500), var(--aqua) 58%, var(--brand-400));
  box-shadow: 0 16px 34px -14px rgba(102, 204, 255, 0.85),
              inset 0 1px 0 rgba(255, 255, 255, 0.55);
}
.ctrl--play:hover {
  color: #fff;
  background: linear-gradient(130deg, var(--brand-500), var(--aqua) 58%, var(--brand-400));
  transform: translateY(-3px) scale(1.05);
}
.ctrl--play .ic { width: 28px; height: 28px; }
.ctrl--play .ic--pause { display: none; }
.player.is-playing .ctrl--play .ic--play { display: none; }
.player.is-playing .ctrl--play .ic--pause { display: block; }

.volume { display: flex; align-items: center; gap: 10px; }
.ctrl--volume { width: 40px; height: 40px; }
.volume__range {
  -webkit-appearance: none;
  appearance: none;
  width: 88px;
  height: 6px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.6);
  cursor: pointer;
}
.volume__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--brand-400);
  box-shadow: 0 2px 8px -2px rgba(58, 184, 245, 0.9);
}
.volume__range::-moz-range-thumb {
  width: 15px; height: 15px;
  border: 2px solid var(--brand-400);
  border-radius: 50%;
  background: #fff;
}

.playlist {
  display: grid;
  gap: 6px;
  max-height: 232px;
  overflow-y: auto;
  padding-right: 6px;
  margin-top: 2px;
  scrollbar-width: thin;
  scrollbar-color: rgba(102, 204, 255, 0.5) transparent;
}
.playlist::-webkit-scrollbar { width: 7px; }
.playlist::-webkit-scrollbar-thumb {
  border-radius: 99px;
  background: rgba(102, 204, 255, 0.42);
}
.playlist::-webkit-scrollbar-track { background: transparent; }

.playlist__item {
  display: grid;
  grid-template-columns: 24px 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 14px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.28s var(--ease), border-color 0.28s var(--ease), transform 0.28s var(--ease);
}
.playlist__item:hover { background: rgba(255, 255, 255, 0.55); transform: translateX(3px); }
.playlist__item.is-current {
  background: rgba(255, 255, 255, 0.66);
  border-color: rgba(102, 204, 255, 0.4);
  box-shadow: 0 8px 20px -12px rgba(102, 204, 255, 0.8);
}
.playlist__index {
  font-size: 12px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.playlist__cover {
  width: 40px; height: 40px;
  border-radius: 10px;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.7);
}
.playlist__text { min-width: 0; }
.playlist__title {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.playlist__artist {
  display: block;
  font-size: 12.5px;
  color: var(--ink-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.playlist__item.is-current .playlist__title { color: var(--brand-700); }

/* 音频文件缺失时：置灰并标注 */
.playlist__item.is-missing { opacity: 0.5; }
.playlist__item.is-missing .playlist__artist::after {
  content: " · 音频待添加";
  color: var(--brand-700);
}

/* 正在播放的小律动 */
.equalizer { display: flex; align-items: flex-end; gap: 2px; height: 15px; }
.equalizer span {
  width: 3px;
  border-radius: 2px;
  background: var(--brand-400);
  animation: eq 0.9s var(--ease) infinite;
}
.equalizer span:nth-child(1) { height: 40%; animation-delay: 0s; }
.equalizer span:nth-child(2) { height: 100%; animation-delay: 0.22s; }
.equalizer span:nth-child(3) { height: 62%; animation-delay: 0.44s; }
.playlist__item:not(.is-current) .equalizer { display: none; }
@keyframes eq {
  0%, 100% { transform: scaleY(0.4); }
  50% { transform: scaleY(1); }
}

/* ---------- 09 博客 ---------- */
.posts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(16px, 2.4vw, 26px);
}

.post {
  display: flex;
  flex-direction: column;
  text-align: left;
  padding: 0;
  border-radius: var(--radius-lg);
  cursor: pointer;
  --glass-blur: 20px;
  transition: transform 0.5s var(--ease-out), box-shadow 0.5s var(--ease-out);
}
.post:hover {
  transform: translateY(-7px);
  box-shadow: 0 30px 56px -26px rgba(60, 110, 150, 0.55),
              inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.post__cover {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.post__cover img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease-out); }
.post:hover .post__cover img { transform: scale(1.07); }

.post__body { padding: 22px 22px 24px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.post__tags { display: flex; flex-wrap: wrap; gap: 7px; }
.post__tags span {
  font-size: 11.5px;
  padding: 3px 10px;
  border-radius: 999px;
  color: var(--brand-700);
  background: rgba(204, 234, 255, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.7);
}
.post__title {
  font-size: 19px;
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
}
.post__excerpt {
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.75;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 8px;
  font-size: 12.5px;
  color: var(--ink-mute);
}
.post__more { color: var(--brand-500); font-weight: 600; }
.post:hover .post__more { color: var(--brand-700); }

/* ---------- 10 工具 ---------- */
.tools {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(16px, 2.4vw, 24px);
}

.tool {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 24px;
  border-radius: var(--radius-lg);
  --glass-blur: 20px;
  transition: transform 0.5s var(--ease-out), box-shadow 0.5s var(--ease-out);
}
.tool:hover {
  transform: translateY(-7px);
  box-shadow: 0 30px 56px -26px rgba(60, 110, 150, 0.55),
              inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.tool__icon {
  display: grid;
  place-items: center;
  width: 58px; height: 58px;
  border-radius: 18px;
  flex: none;
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5),
              0 12px 24px -12px rgba(60, 110, 150, 0.7);
}
.tool__icon .ic { width: 28px; height: 28px; }
.tool__icon[data-accent="pink"] { background: linear-gradient(135deg, var(--brand-400), var(--aqua-soft)); }
.tool__icon[data-accent="blue"] { background: linear-gradient(135deg, var(--brand-600), var(--brand-300)); }
.tool__icon[data-accent="lilac"] { background: linear-gradient(135deg, var(--brand-700), var(--brand-400)); }
.tool__icon[data-accent="mint"] { background: linear-gradient(135deg, var(--aqua), var(--aqua-soft)); }

.tool__text { flex: 1; min-width: 0; display: block; }
.tool__name {
  display: block;
  font-size: 18px;
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
}
.tool__desc {
  display: block;
  font-size: 13.5px;
  color: var(--ink-soft);
  margin-top: 4px;
  line-height: 1.6;
}
.tool__arrow {
  color: var(--ink-mute);
  transition: transform 0.4s var(--ease), color 0.4s var(--ease);
}
.tool:hover .tool__arrow { transform: translate(4px, -4px); color: var(--brand-700); }

.tools__empty {
  grid-column: 1 / -1;
  padding: 44px;
  text-align: center;
  color: var(--ink-mute);
  font-size: 14.5px;
}

/* ---------- 11 照片墙 + 灯箱 ----------
   有两种视图，共用同一份 DOM，靠 #wall 上的 .is-timeline 切换：
     默认     columns 马赛克墙
     时间轴   「竖轴 + 节点 + 卡片」的两列网格（见本节末尾）
   每个条目都包在 .wall__entry 里 —— 墙模式下它就是 columns 的列单元。 */
.wall {
  columns: 4;
  column-gap: clamp(12px, 1.8vw, 20px);
}
/* 列单元。断列与列间距放在这一层（里面那张卡不再管这些） */
.wall__entry {
  break-inside: avoid;
  margin-bottom: clamp(12px, 1.8vw, 20px);
}
/* 墙模式下把时间轴专用的零件收起来 */
.wall__node,
.wall__yeardiv { display: none; }
.wall__body { display: contents; }
.wall__meta { display: none; }

.wall__item {
  position: relative;
  display: block;
  width: 100%;
  /* 全局 button 重置已经清了 padding，这里再写一次是刻意的防线：
     这个格子是 <button>，一旦它带上内边距，照片和玻璃罩都会对不齐。 */
  padding: 0;
  border-radius: var(--radius-md);
  overflow: hidden;
  cursor: zoom-in;
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 16px 34px -20px rgba(60, 110, 150, 0.5);
  transition: transform 0.55s var(--ease-out), box-shadow 0.55s var(--ease-out);
}
.wall__item:hover {
  transform: translateY(-6px) scale(1.015);
  box-shadow: 0 30px 54px -24px rgba(60, 110, 150, 0.6);
}
/* 照片占满整个圆角框。
   只作用于直接子 img —— 叠放组里垫在下面的那几张也是 img，
   要是被这条规则套上 width/height，它们的绝对定位就散了。 */
.wall__item > img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}
.wall__cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 26px 16px 13px;
  font-size: 12.5px;
  color: #fff;
  text-align: left;
  background: linear-gradient(to top, rgba(45, 80, 110, 0.75), transparent);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.wall__item:hover .wall__cap { opacity: 1; transform: none; }

/* ---------- 照片上的玻璃罩 ----------
   照片不是平贴在页面上的，而是压在一块玻璃下面。
   用的是和页面玻璃同一套光学语言：
     ① 最外一线锐利亮边 —— 玻璃的棱
     ② 紧贴其内一道柔和的暗线 —— 玻璃的厚度（少了它照片就像只是调亮了）
     ③ 对角两道斜面高光 —— 和卡片同一方向、同一逻辑
     ④ 表面 45° 对角扫光 —— 两个角抓到光，中间干净
   注意 z-index:1 让它盖在图片上、但仍在说明文字之下。 */
.wall__item::after,
.post__cover::after,
.reader__hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  box-shadow:
    /* ① 棱：最外那一线亮边 */
    inset 0 0 0 1px rgba(255, 255, 255, 0.72),
    /* ② 厚度：亮边之内迅速转暗，玻璃的"体"就从这里开始 */
    inset 0 0 3px 0.5px rgba(18, 48, 76, 0.2),
    /* ③ 对角斜面 */
    inset 2.2px -2.2px 1.3px -1.1px rgba(255, 255, 255, 0.85),
    inset -2.2px 2.2px 1.3px -1.1px rgba(255, 255, 255, 0.7),
    inset 7px -7px 2.6px -6.4px rgba(255, 255, 255, 0.4),
    inset -7px 7px 2.6px -6.4px rgba(255, 255, 255, 0.32),
    /* ④ 由边缘向内一层层变薄 */
    inset 0 0 6px -1px rgba(255, 255, 255, 0.44),
    inset 0 0 18px -5px rgba(255, 255, 255, 0.32),
    inset 0 0 42px -15px rgba(255, 255, 255, 0.28);
  /* 表面反射光：45° 对角扫光 + 一层很薄的斜向整体光 */
  background:
    linear-gradient(45deg,
      rgba(255, 255, 255, 0.3) 0%,
      rgba(255, 255, 255, 0.05) 16%,
      transparent 34%,
      transparent 66%,
      rgba(255, 255, 255, 0.05) 84%,
      rgba(255, 255, 255, 0.3) 100%),
    linear-gradient(148deg,
      rgba(255, 255, 255, 0.14) 0%,
      rgba(255, 255, 255, 0.04) 22%,
      rgba(255, 255, 255, 0) 46%,
      rgba(255, 255, 255, 0.03) 78%,
      rgba(255, 255, 255, 0.09) 100%);
  transition: opacity 0.45s var(--ease);
}
/* 悬停时玻璃更亮一点，像转动了角度 */
.wall__item:hover::after,
.post:hover .post__cover::after { opacity: 1.4; }

/* 照片说明浮在玻璃罩之上 */
.wall__cap { z-index: 2; }

/* ---------- 一组照片：在墙上叠成一摞 ----------
   最上面那张收小一点、反向转一点角度，后面的几张从底下错开露出来，
   像一叠刚洗好、压在玻璃下面的照片。
   砖块自身给一层很淡的"托盘"底，否则照片悬在页面背景上会显得散。 */
.wall__item--stack { background: rgba(255, 255, 255, 0.5); }

.wall__deck {
  position: absolute;
  inset: 0;
  z-index: 0;                 /* 沉在最上面那张之下 */
  pointer-events: none;
}
.wall__deck-card {
  position: absolute;
  inset: 5%;
  object-fit: cover;
  border-radius: calc(var(--radius-md) - 4px);
  /* 相纸白边 + 投影：几张色调接近的照片叠在一起时，
     全靠这道白边把层与层分开，否则糊成一片认不出是一叠。 */
  border: 3px solid #fff;
  box-shadow: 0 6px 18px -10px rgba(60, 110, 150, 0.9);
  transition: transform 0.55s var(--ease-out);
}
/* 每一层往右下错开一点、再多转一点角度 ——
   于是下面几张在右下角露出一条边，像一手摊开的牌。
   露出来的这条边会被砖块自身的圆角框裁掉一截，那是想要的：
   看上去就像这一叠被收在玻璃框里。 */
.wall__deck-card[data-pos="1"] { transform: translate(1.5%, 1.2%) rotate(4deg); }
.wall__deck-card[data-pos="2"] { transform: translate(3.5%, 2.8%) rotate(7deg); }
.wall__deck-card[data-pos="3"] { transform: translate(5.5%, 4.4%) rotate(10deg); }

/* 最上面那张：缩小些、往左上让开，把底下那叠的边露出来。
   也给它一圈相纸白边，和下面几张统一 —— 一眼就看出这是"一叠照片"。 */
.wall__item--stack > img {
  position: relative;         /* 压过 .wall__deck */
  z-index: 1;
  border: 3px solid #fff;
  transform: translate(-3.4%, -2.8%) rotate(-1.6deg) scale(0.9);
  transition: transform 0.55s var(--ease-out);
}

/* 指针移上去，这一摞轻轻摊开，像用指头拨了一下 */
.wall__item--stack:hover > img { transform: translate(-4.2%, -3.4%) rotate(-2.4deg) scale(0.875); }
.wall__item--stack:hover .wall__deck-card[data-pos="1"] { transform: translate(3%, 2.4%)  rotate(6deg); }
.wall__item--stack:hover .wall__deck-card[data-pos="2"] { transform: translate(6%, 4.8%)  rotate(10deg); }
.wall__item--stack:hover .wall__deck-card[data-pos="3"] { transform: translate(9%, 7.2%)  rotate(14deg); }

/* 右上角的张数角标 */
.wall__count {
  position: absolute;
  z-index: 3;
  top: 9px;
  right: 9px;
  min-width: 23px;
  height: 23px;
  padding: 0 7px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--brand-700);
  background: rgba(255, 255, 255, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.95);
  box-shadow: 0 5px 12px -7px rgba(60, 110, 150, 0.9);
  -webkit-backdrop-filter: blur(8px) saturate(1.6);
  backdrop-filter: blur(8px) saturate(1.6);
  pointer-events: none;
}

/* 触屏上没有悬停，别让这一摞停在被拨开的状态 */
@media (hover: none) {
  .wall__item--stack:hover > img { transform: translate(-3.4%, -2.8%) rotate(-1.6deg) scale(0.9); }
  .wall__item--stack:hover .wall__deck-card[data-pos="1"] { transform: translate(1.5%, 1.2%) rotate(4deg); }
  .wall__item--stack:hover .wall__deck-card[data-pos="2"] { transform: translate(3.5%, 2.8%) rotate(7deg); }
  .wall__item--stack:hover .wall__deck-card[data-pos="3"] { transform: translate(5.5%, 4.4%) rotate(10deg); }
}

/* ---------- 竖版时间轴 ----------
   和照片墙是同一份 DOM，只是把 columns 换成了「轴 + 卡片」两列网格。
   竖轴画在容器上（一条两端渐隐的线），每个条目左边留出 64px 放节点圆点，
   日期浮在卡片上方，遇到换年份再插一条年份分隔。 */
.wall.is-timeline {
  columns: auto;
  position: relative;
  /* 时间轴是单列长条，铺满整页宽会显得空，所以收个宽度。
     左对齐（不加 auto 外边距）—— 站内其他板块的内容都从左边起，
     要是居中，就会和上面左对齐的标题脱节。 */
  max-width: 700px;
}
/* 竖轴本身。两端渐隐，比一条实线柔和 */
.wall.is-timeline::before {
  content: "";
  position: absolute;
  left: 30px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(to bottom,
    transparent 0,
    rgba(102, 204, 255, 0.55) 3%,
    rgba(102, 204, 255, 0.55) 97%,
    transparent 100%);
}

.wall.is-timeline .wall__entry {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 0 clamp(14px, 2vw, 26px);
  margin-bottom: clamp(22px, 3vw, 38px);
}
.wall.is-timeline .wall__entry:last-child { margin-bottom: 0; }

/* 轴上的节点。顶部对齐卡片，圆点正好压在竖轴上 */
.wall.is-timeline .wall__node {
  display: block;
  padding-top: 12px;
}
.wall.is-timeline .wall__dot {
  display: block;
  width: 12px; height: 12px;
  margin-left: 25px;                 /* 让圆心落在 left:31px ≈ 竖轴中线 */
  border-radius: 50%;
  background: #fff;
  border: 2.5px solid var(--brand-400);
  box-shadow: 0 0 0 4px rgba(102, 204, 255, 0.16),
              0 4px 10px -4px rgba(60, 110, 150, 0.8);
}

.wall.is-timeline .wall__body { display: block; }

/* 日期。等宽字形，排起来整齐 */
.wall.is-timeline .wall__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 9px;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--brand-700);
  font-variant-numeric: tabular-nums;
}
/* 日期前的小短横，把它和轴连起来 */
.wall.is-timeline .wall__meta::before {
  content: "";
  width: 16px; height: 1px;
  background: rgba(102, 204, 255, 0.7);
}

/* 时间轴里所有卡片统一成 3:2 ——
   照片原来高矮不一，一条时间轴上会参差不齐、也很难扫读；
   统一比例之后节奏就稳了，代价是竖构图的照片会被裁成横的。
   想保留原比例：把下面 aspect-ratio 那行删掉即可。 */
.wall.is-timeline .wall__item { aspect-ratio: 3 / 2; }
.wall.is-timeline .wall__item > img {
  height: 100%;
  object-fit: cover;
}

/* 换年份时的分隔条：年份药丸骑在竖轴上 */
.wall.is-timeline .wall__yeardiv {
  display: flex;
  align-items: center;
  height: 30px;
  margin: 2px 0 clamp(12px, 1.6vw, 20px);
}
.wall.is-timeline .wall__yeardiv:first-child { margin-top: 0; }
.wall.is-timeline .wall__yeardiv-pill {
  position: relative;
  z-index: 1;
  padding: 3px 13px;
  border-radius: 999px;
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--brand-700);
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid rgba(102, 204, 255, 0.4);
  box-shadow: 0 5px 14px -9px rgba(60, 110, 150, 0.95);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: 5vh 4vw;
}
.lightbox[hidden] { display: none; }
.lightbox__scrim {
  position: absolute;
  inset: 0;
  background: rgba(35, 55, 75, 0.58);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
  animation: fade 0.4s var(--ease) both;
}
.lightbox__figure {
  position: relative;
  margin: 0;
  max-width: min(1040px, 92vw);
  max-height: 86vh;
  display: grid;
  gap: 14px;
  justify-items: center;
  animation: pop 0.5s var(--ease-out) both;
}
.lightbox__figure img {
  max-width: 100%;
  max-height: 76vh;
  border-radius: var(--radius-lg);
  border: 1px solid rgba(255, 255, 255, 0.7);
  box-shadow: 0 40px 80px -30px rgba(25, 45, 65, 0.8);
  object-fit: contain;
}
.lightbox__caption { padding: 10px 20px; border-radius: 999px; font-size: 13.5px; color: var(--ink); }

.lightbox__nav,
.lightbox__close {
  position: absolute;
  display: grid;
  place-items: center;
  width: 50px; height: 50px;
  border-radius: 50%;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.8);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 12px 28px -12px rgba(25, 45, 65, 0.6);
  z-index: 2;
  transition: transform 0.3s var(--ease), background 0.3s var(--ease);
}
.lightbox__nav:hover, .lightbox__close:hover { transform: scale(1.08); background: #fff; }
.lightbox__nav--prev { left: 3vw; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 3vw; top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev:hover { transform: translateY(-50%) scale(1.08); }
.lightbox__nav--next:hover { transform: translateY(-50%) scale(1.08); }
.lightbox__close { top: 3vh; right: 3vw; }

/* ---------- 12 联系方式 + 页脚 ---------- */
.contacts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 4px;
  padding: 14px;
  border-radius: var(--radius-xl);
  --glass-blur: 22px;
}

.contact {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 16px;
  border-radius: var(--radius-md);
  text-align: left;
  transition: background 0.3s var(--ease), transform 0.35s var(--ease);
}
.contact:hover { background: rgba(255, 255, 255, 0.55); transform: translateX(4px); }
.contact__icon {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 14px;
  color: #fff;
  background: linear-gradient(135deg, var(--brand-400), var(--brand-400));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.contact__text { min-width: 0; display: block; }
.contact__label { display: block; font-size: 12px; color: var(--ink-mute); line-height: 1.5; }
.contact__value {
  display: block;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.contact__copy {
  font-size: 12px;
  padding: 5px 11px;
  border-radius: 999px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.8);
  transition: color 0.3s var(--ease), background 0.3s var(--ease);
}
.contact__copy:hover { color: var(--brand-700); background: #fff; }

/* 页脚信息现在并入「联系」屏底部 */
.footer__inner { display: grid; gap: 18px; justify-items: center; text-align: center; }
.footer__inner--slide {
  margin-top: clamp(30px, 4.5vw, 52px);
  padding-top: clamp(22px, 3vw, 32px);
  border-top: 1px solid rgba(255, 255, 255, 0.7);
}
.footer__name { font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif; font-size: 22px; font-weight: 700; }
.footer__slogan { display: block; font-size: 13.5px; color: var(--ink-soft); margin-top: 4px; }
.footer__socials { display: flex; gap: 12px; }
.footer__socials a {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 15px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.75);
  transition: transform 0.35s var(--ease), color 0.35s var(--ease), background 0.35s var(--ease);
}
.footer__socials a:hover { transform: translateY(-4px); color: var(--brand-700); background: #fff; }
.footer__meta { font-size: 12.5px; color: var(--ink-mute); }
.footer__meta a { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- 13 iOS Dock ---------- */
.dock {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 9px 12px;
  border-radius: 24px;
  --glass-blur: 26px;
  /* 只改底色，不用 background 简写 —— 否则会把 .glass 的对角扫光一起清掉 */
  background-color: var(--glass-bg-strong);
  box-shadow: 0 26px 50px -22px rgba(60, 110, 150, 0.6),
              inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.dock__item {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 3px;
  width: 62px;
  padding: 8px 4px 6px;
  border-radius: 17px;
  color: var(--ink-soft);
  transition: color 0.3s var(--ease), background 0.3s var(--ease), transform 0.45s var(--ease-out);
}
.dock__item span { font-size: 10.5px; letter-spacing: 0.02em; }
.dock__item .ic { width: 21px; height: 21px; }
.dock__item:hover { color: var(--brand-700); background: rgba(255, 255, 255, 0.6); transform: translateY(-5px); }
.dock__item.is-active { color: var(--brand-700); background: rgba(255, 255, 255, 0.72); }
.dock__item.is-active::after {
  content: "";
  position: absolute;
  bottom: 2px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--brand-600);
}

/* ---------- 14 阅读浮层 ---------- */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: grid;
  place-items: center;
  padding: 4vh 4vw;
}
.overlay[hidden] { display: none; }
.overlay__scrim {
  position: absolute;
  inset: 0;
  background: rgba(35, 55, 75, 0.5);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  animation: fade 0.4s var(--ease) both;
}

.reader {
  position: relative;
  width: min(880px, 94vw);
  max-height: 90vh;
  border-radius: var(--radius-xl);
  --glass-blur: 28px;
  /* 只改底色，不用 background 简写 —— 否则会把 .glass 的对角扫光一起清掉 */
  background-color: var(--glass-bg-reader);
  animation: pop 0.55s var(--ease-out) both;
}
.reader__scroll {
  max-height: 90vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(102, 204, 255, 0.5) transparent;
}
.reader__scroll::-webkit-scrollbar { width: 8px; }
.reader__scroll::-webkit-scrollbar-thumb { border-radius: 99px; background: rgba(102, 204, 255, 0.42); }

.reader__close {
  position: absolute;
  top: 16px; right: 16px;
  z-index: 5;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border-radius: 50%;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 10px 22px -10px rgba(25, 45, 65, 0.5);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease);
}
.reader__close:hover { transform: rotate(90deg); background: #fff; }

.reader__hero { position: relative; aspect-ratio: 21 / 9; overflow: hidden; }
.reader__hero img { width: 100%; height: 100%; object-fit: cover; }

.reader__head { padding: 30px clamp(24px, 5vw, 56px) 0; }
.reader__tags { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.reader__tags span {
  font-size: 11.5px;
  padding: 3px 11px;
  border-radius: 999px;
  color: var(--brand-700);
  background: rgba(204, 234, 255, 0.8);
}
.reader__title { font-size: clamp(24px, 3.6vw, 34px); font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif; }
.reader__date { font-size: 13px; color: var(--ink-mute); margin-top: 8px; }

.reader__body {
  padding: 24px clamp(24px, 5vw, 56px) 48px;
  font-size: 15.5px;
  line-height: 1.92;
  color: var(--ink-soft);
}
.reader__body > * + * { margin-top: 1.05em; }
.reader__body h2 {
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  font-size: 23px;
  color: var(--ink);
  margin-top: 1.8em;
}
.reader__body h3 { font-size: 18.5px; color: var(--ink); margin-top: 1.5em; }
.reader__body strong { color: var(--ink); font-weight: 700; }
.reader__body em { font-style: italic; color: var(--brand-700); }
.reader__body a { color: var(--brand-500); text-decoration: underline; text-underline-offset: 3px; }

/* 附件下载。正文里写成 [文件名](路径) 时，给 <a> 加个 download 属性，
   就会显示成下面这种"文件药丸"，而不是一条普通链接。
   写法见 content/README-内容.md 第九节。 */
.reader__body a[download] {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 15px 5px 11px;
  border-radius: 999px;
  /* 底色必须带一点蓝 —— 纯白药丸压在本来就接近白色的玻璃上会"隐身"，
     看起来跟普通链接没区别。 */
  background: var(--brand-100);
  border: 1px solid rgba(102, 204, 255, 0.46);
  text-decoration: none;
  color: var(--brand-700);
  font-size: 0.94em;
  transition: background 0.22s var(--ease-out), transform 0.22s var(--ease-out),
              border-color 0.22s var(--ease-out);
}
.reader__body a[download]:hover {
  background: var(--brand-200);
  border-color: rgba(102, 204, 255, 0.7);
  transform: translateY(-1px);
}
.reader__body a[download]::before {
  content: "↓";
  font-weight: 700;
  line-height: 1;
  color: var(--brand-500);
}

.reader__body img { border-radius: var(--radius-md); margin: 1.4em 0; }
.reader__body ul { padding-left: 1.3em; list-style: none; }
.reader__body ul li { position: relative; padding-left: 1.1em; margin-top: 0.5em; }
.reader__body ul li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.72em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-400), var(--brand-400));
}
.reader__body ol { padding-left: 1.4em; }
.reader__body ol li { margin-top: 0.5em; }
.reader__body ol li::marker { color: var(--brand-700); font-weight: 700; }
.reader__body blockquote {
  padding: 14px 22px;
  border-left: 3px solid var(--brand-400);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: rgba(255, 255, 255, 0.6);
  font-family: "LXGW WenKai", "Songti SC", "STKaiti", "KaiTi", serif;
  color: var(--ink);
}
.reader__body code {
  font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.9em;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid rgba(255, 255, 255, 0.9);
  color: var(--brand-700);
}
.reader__body pre {
  padding: 16px 20px;
  border-radius: var(--radius-md);
  background: rgba(45, 80, 110, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.7);
  overflow-x: auto;
}
.reader__body pre code { background: none; border: 0; padding: 0; color: var(--ink); }
.reader__body hr { border: 0; height: 1px; background: rgba(60, 110, 150, 0.16); margin: 2em 0; }

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop {
  from { opacity: 0; transform: scale(0.95) translateY(18px); }
  to { opacity: 1; transform: none; }
}

/* ---------- 15 提示 / 响应式 ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--dock-h) + 34px);
  transform: translate(-50%, 20px);
  z-index: 130;
  padding: 11px 24px;
  border-radius: 999px;
  font-size: 14px;
  color: #fff;
  background: linear-gradient(120deg, var(--brand-400), var(--brand-400));
  box-shadow: 0 18px 36px -14px rgba(102, 204, 255, 0.8);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease), transform 0.4s var(--ease-out);
}
.toast.is-show { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 1024px) {
  .wall { columns: 3; }
  .hero__inner { grid-template-columns: 1fr; gap: 34px; }
  .hero__card { order: 2; }
  .hero__vinyl { order: 1; }
  .player { grid-template-columns: 1fr; }
  .player__left { padding: 6px 0 2px; }
  .player__disc { width: min(260px, 68vw); }
  /* 屏幕窄了就不放左右箭头，用圆点与 Dock 切换 */
  .pager { display: none; }
}

@media (max-width: 720px) {
  .nav--desktop { display: none; }
  .topbar { top: 12px; padding: 8px 10px 8px 14px; border-radius: 18px; gap: 10px; }

  /* 顶栏在手机上收紧：只留站名图标、去掉时钟，开关都缩小一号 */
  .brand { gap: 0; }
  .brand__text { display: none; }
  .brand__mark { width: 22px; height: 22px; }
  .clock { display: none; }
  .topbar__actions { gap: 6px; }
  .lang-toggle { width: 64px; height: 36px; border-radius: 12px; }
  .lang-toggle__opt { font-size: 12px; line-height: 28px; }
  .lang-toggle__knob { width: 28px; height: 28px; border-radius: 9px; }
  body[data-lang="en"] .lang-toggle__knob { transform: translateX(28px); }
  .bg-switch { width: 60px; height: 36px; border-radius: 12px; }
  .bg-switch__icon .ic { width: 16px; height: 16px; }
  .bg-switch__knob { width: 26px; height: 26px; border-radius: 9px; }
  body[data-bg="image"] .bg-switch__knob { transform: translateX(26px); }
  .glass-btn { width: 36px; height: 36px; border-radius: 12px; }
  .glass-btn .ic { width: 19px; height: 19px; }
  .search { width: 100%; height: 36px; border-radius: 12px; }
  /* 手机上顶栏位置有限：只留气温和天气，地点与海拔收进桌面端 */
  .wx { gap: 7px; font-size: 12.5px; }
  .wx__temp { font-size: 18px; }
  .wx__div,
  .wx__row { display: none; }

  /* 横向分页在手机上的留白 */
  .slide__scroll { padding: 88px 0 calc(var(--dock-h) + 44px); }
  .slide--hero .slide__scroll { padding-top: 92px; }
  .dots { bottom: calc(var(--dock-h) + 20px); gap: 7px; }
  .dots__dot { width: 7px; height: 7px; }
  .dots__dot.is-active { width: 19px; }

  .hero__card { padding: 24px 20px 26px; border-radius: 26px; }
  .hero__avatar { width: 78px; height: 78px; }
  .hero__actions .btn { flex: 1; justify-content: center; }
  .hero__tool-desc { display: none; }
  .hero__tool { padding: 8px 14px 8px 9px; }
  .wall { columns: 2; }
  .contacts { grid-template-columns: 1fr; }
  .dock__item { width: 48px; }
  .dock__item span { font-size: 9.5px; }
  .dock { gap: 0; padding: 8px 8px; }
  .volume__range { width: 62px; }
  .ctrl { width: 42px; height: 42px; }
  .ctrl--play { width: 60px; height: 60px; }
  .lightbox__nav { width: 42px; height: 42px; }
  .lightbox__nav--prev { left: 2vw; }
  .lightbox__nav--next { right: 2vw; }
  .overlay { padding: 0; }
  .reader { width: 100%; max-height: 100%; height: 100%; border-radius: 0; }
  .reader__scroll { max-height: 100%; }
  .reader__hero { aspect-ratio: 16 / 9; }
}

@media (max-width: 400px) {
  .wall { columns: 1; }
  .dock__item span { display: none; }
  .dock__item { width: 44px; }
}

/* 无障碍：尊重减弱动效偏好 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  #petals { display: none; }
}
