/* Alice 官网改版预览稿 · 按生成设计稿还原
 * 每个章节先由生图模型出整版设计稿，再把稿里的实物（信纸、对话气泡、礼物架、日历、手账本、邮票、
 * 便签、信封、按钮颜料、铅笔笔触）逐件单独生成为透明素材。CSS 不画装饰，只负责把素材摆回设计稿的位置。
 * 桌面端每章是一块 3:2 画板（.board），子元素按设计稿坐标用百分比定位，字号用 cqw 跟画板一起缩放；
 * 900px 以下画板拆成纵向流式排版。
 * 笔触、按钮描边等单色素材以 mask 渲染，颜色由 background-color 决定；字标同理（--wm）。 */

:root {
  --paper: #F3EDE2;
  --paper-2: #EAE1D2;
  --card: #FBF8F1;
  --ink: #2A2320;
  --ink-soft: #6E625A;
  --line: rgba(42, 35, 32, 0.16);
  --rose: #A8475A;
  --rose-deep: #7A2E3A;
  --rose-soft: #EBD3D1;
  --pencil: #8C6F62;
  --serif: "Noto Serif SC", "Songti SC", "STSong", serif;
  --latin: "Cormorant Garamond", "Times New Roman", serif;
  --hand: "LXGW WenKai Screen", "LXGW WenKai", "Kaiti SC", "STKaiti", "KaiTi", serif;
  --sans: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  /* 书签标签：手写体压在纸纹彩色底上，要比正文更实、更深。
     文楷屏幕版只有常规字重，强调用描边，不用 font-weight（合成粗体会糊） */
  --tab-font: var(--hand);
  --tab-ink: #1d1612;
  --tab-halo: 0 0 3px rgba(255, 250, 238, 0.8), 0 0 1px rgba(255, 250, 238, 0.95);
  --tab-stroke-on: 0.35px;
  --tab-fs: clamp(15px, 1.32vw, 19px); /* 04 手账书签与 05 橱窗书签共用 */
  --tab-vis: clamp(25px, 2.1vw, 30px); /* 未选中书签露出纸页的高度，两处共用 */
  --shadow-paper: 0 1px 1px rgba(60, 40, 25, 0.06), 0 14px 30px -14px rgba(60, 40, 25, 0.32);
  --shadow-lift: 0 2px 4px rgba(60, 40, 25, 0.08), 0 30px 60px -24px rgba(60, 40, 25, 0.42);
  --drop: drop-shadow(0 10px 14px rgba(70, 45, 25, 0.16));
  --wrap: 1180px;
  /* 画板宽度上限。视口窄于它时画板铺满屏宽，底图左右直接出血，不再淡出；宽于它时两侧是页面纸色，画板左右淡出 */
  --board-max: 2560px;
  /* 相框素材的宽高比与照片窗位置，按 polaroid.webp、stamp-frame.webp 实测；窗口略收进边框，避免露缝 */
  --frame-ar: 0.767; --win-l: 7%; --win-t: 10.7%; --win-r: 7.1%; --win-b: 25.5%;
  --stamp-ar: 0.772; --sw-l: 8.6%; --sw-t: 6.8%; --sw-r: 8.7%; --sw-b: 6.6%;
  --wf-ar: 0.773; --wf-l: 7.6%; --wf-t: 6.3%; --wf-r: 7.6%; --wf-b: 22.1%;
  /* 动态卡顶部留出图钉，吊牌上方留出绳子；百分比内边距会按外层宽度算，所以换算成画板宽度单位 */
  --fc-ar: 0.653; --fc-pad: 1.75cqw 1cqw 1cqw;
  --ht-x: 68.2%; --ht-y: 10.3%; --ht-w: 16%; --ht-ar: 1.695; --ht-pad: 4cqw 1cqw 0.3cqw 2.6cqw;
  --fs-ar: 2.929; --fs-t: 19.8%; --fs-b: 12.3%; --fs-w: 22.4%; --fs-1: 3.7%; --fs-2: 26.6%; --fs-3: 50.5%; --fs-4: 73.9%;
  /* 问题卡按九宫格拉伸，撕边厚度不随卡片高度变形 */
  --fq-slice: 34; --fq-bw: 1.1cqw;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans); font-size: 16px; line-height: 1.75; color: var(--ink);
  background: var(--paper) url("img/paper.webp") repeat;
  background-size: 640px;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* clip 不把 body 变成滚动容器，手账章的 sticky 才能钉住。
     不支持 clip 的浏览器停在上面的 hidden，这一章退回点击切换。 */
  overflow-x: clip;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { list-style: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.hand { font-family: var(--hand); }
.wrap { width: min(var(--wrap), calc(100% - 64px)); margin: 0 auto; }
:focus-visible { outline: 2px solid var(--rose); outline-offset: 4px; }

/* ══ 字标与笔触（单色素材，mask 上色） ═══════════════════════ */
.wordmark {
  display: block; aspect-ratio: 1092 / 519;
  background-color: var(--wm, var(--rose-deep));
  -webkit-mask: url("img/wordmark.png") center / contain no-repeat;
  mask: url("img/wordmark.png") center / contain no-repeat;
}
.wordmark-sm { width: 78px; }
.wordmark-hero { width: clamp(300px, 27vw, 520px); animation: write 1.8s cubic-bezier(.6, .1, .3, 1) 0.2s both; }
.wordmark-foot { width: 110px; }
@keyframes write { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 -5% 0 0); } }

.stroke {
  display: block; background-color: var(--stroke, var(--rose));
  -webkit-mask: var(--m) center / 100% 100% no-repeat;
  mask: var(--m) center / 100% 100% no-repeat;
}
.stroke-under { --m: url("img/stroke-under.webp"); }
.stroke-rule { --m: url("img/stroke-rule.webp"); }
.stroke-ring { --m: url("img/stroke-ring.webp"); }
.stroke-arrow { --m: url("img/stroke-arrow.webp"); }
.stroke-flourish { --m: url("img/stroke-flourish.webp"); }

/* 手写下划线：铅笔笔触贴在文字下方 */
.pen-under { position: relative; display: inline-block; }
.pen-under::after {
  content: ""; position: absolute; left: -4%; right: -4%; bottom: -0.32em; height: 0.36em;
  background-color: var(--rose);
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}

/* ══ 按钮：手刷颜料块与笔写链接 ═════════════════════════════ */
.paint-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  height: 54px; padding: 0 40px; color: #FBF3EA;
  font-family: var(--serif); font-size: 17px; font-weight: 600; letter-spacing: 0.16em;
  background: url("img/btn-paint.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 6px 10px rgba(90, 30, 40, 0.18));
  transition: transform 0.25s, filter 0.25s;
}
.paint-btn:hover { transform: translateY(-2px) rotate(-0.6deg); filter: drop-shadow(0 10px 14px rgba(90, 30, 40, 0.26)) brightness(1.08); }
.paint-btn-sm { height: 40px; padding: 0 26px; font-size: 14px; letter-spacing: 0.12em; }
.pen-link {
  position: relative; display: inline-flex; align-items: center; gap: 12px; padding-bottom: 6px;
  font-family: var(--serif); font-size: 16px; font-weight: 600; letter-spacing: 0.06em; color: var(--ink);
  transition: gap 0.25s, color 0.2s;
}
.pen-link::before { content: "→"; order: 2; font-family: var(--latin); font-size: 22px; line-height: 1; }
.pen-link::after {
  content: ""; position: absolute; left: -2%; right: 18%; bottom: -2px; height: 9px;
  background-color: var(--rose);
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}
.pen-link:hover { gap: 18px; color: var(--rose-deep); }

/* ══ 刊头：页顶撕边纸条 ══════════════════════════════════════ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50; height: 78px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 0 3.6vw 8px;
  /* nav-paper.webp 共 175 行：第 0–6 行全透明，第 7–8 行是半透明撕边，第 9–19 行只有左右两角各 2 个像素未实心，第 20 行起才整行实心。
     只推走全透明的 7 行不够，撕边的半透明像素会漏出页面底色，在视口顶边形成一条浅色缝。
     把图拉高到 110% 并贴底对齐，顶部约 16 行被推出盒子之外，纸面实心部分就与视口顶边严丝合缝。 */
  background: url("img/nav-paper.webp") center bottom / 100% 110% no-repeat;
  filter: drop-shadow(0 4px 6px rgba(70, 45, 25, 0.12));
}
/* 与原版官网导航同一套入口（共 10 项），条目多，间距比早期 6 项版本收紧；文字不换行 */
.nav-links { display: flex; align-items: center; gap: clamp(14px, 1.9vw, 30px); font-family: var(--serif); font-size: 14px; font-weight: 500; letter-spacing: 0.04em; white-space: nowrap; }
.nav-links a { position: relative; padding: 4px 0; }
.nav-links .nav-handbook-link { color: var(--rose-deep); font-weight: 600; }
.nav-links .nav-careers-link { color: var(--rose); }
/* 二创大赛入口：圆形图标 + 纸色胶囊，位于导航第二位，与原版同位置 */
.nav-links a.nav-fanart-link {
  display: inline-flex; align-items: center; gap: 7px; padding: 3px 13px 3px 3px;
  border-radius: 999px; color: var(--ink); font-weight: 600;
  background: rgba(251, 248, 241, 0.72); box-shadow: inset 0 0 0 1px rgba(140, 90, 60, 0.28);
  transition: transform 0.25s, box-shadow 0.25s, background 0.25s;
}
.nav-links a.nav-fanart-link::after { display: none; }
.nav-links a.nav-fanart-link:hover { transform: translateY(-1px); background: rgba(251, 248, 241, 0.95); box-shadow: inset 0 0 0 1px var(--rose); }
.nav-fanart-avatar { width: 24px; height: 24px; flex: none; border-radius: 50%; object-fit: cover; background: #fff; }
.nav-fanart-label { line-height: 1; }
.nav-links a::after {
  content: ""; position: absolute; left: -6%; right: -6%; bottom: -4px; height: 6px;
  background-color: var(--rose); transform: scaleX(0); transform-origin: left; transition: transform 0.3s;
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}
.nav-links a:hover::after { transform: scaleX(1); }

/* ══ 首屏 ══════════════════════════════════════════════════ */
/* 文案在上、时刻条在下，中间多余高度交给时刻条的 margin-top: auto。
   宽屏矮窗口里字标和按钮会变高，绝对定位的纸条会从下往上盖住按钮；
   改成同一列之后，装不下就让首屏变高，按钮始终露在纸条上面。 */
.hero { position: relative; display: flex; flex-direction: column; min-height: max(700px, 100svh); overflow: hidden; isolation: isolate; }
.hero-scene { position: absolute; inset: 0; z-index: -2; transform-origin: var(--ox, 79%) var(--oy, 43%); will-change: transform; }
.scene-layer {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--pos-x, 70%) 40%;
  opacity: 0; transition: opacity 1.4s ease;
}
.scene-layer.is-on { opacity: 1; }
/* 窗内贴片：底图的窗是空的，她在窗边的那几段时间才叠上去；坐标与尺寸由脚本按插画换算 */
.win-patch { position: absolute; display: block; max-width: none; opacity: 0; transition: opacity 1.4s ease; pointer-events: none; }
.win-patch.is-on { opacity: 1; }
/* 插画底部自带纸面收笔，但插画里的纸比页面纸更白更平。底部叠一层与 body 同一张纸纹、同一原点的纸，
 * 按缓动曲线渐显，首屏下沿直接融进页面纸；淡到纯色纸色会和带纹理的页面纸之间留一道横线 */
.hero-fade {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(250, 238, 222, 0.5), transparent 46%);
}
.hero.is-night .hero-fade { background: linear-gradient(90deg, rgba(14, 18, 40, 0.42), transparent 50%); }
.hero-fade::after {
  content: ""; position: absolute; inset: 0;
  background: var(--paper) url("img/paper.webp") 0 0 / 640px repeat;
  -webkit-mask: linear-gradient(180deg, transparent 82%, rgba(0, 0, 0, 0.07) 85%, rgba(0, 0, 0, 0.26) 88%, rgba(0, 0, 0, 0.5) 91%, rgba(0, 0, 0, 0.74) 94%, rgba(0, 0, 0, 0.93) 97%, #000 100%);
  mask: linear-gradient(180deg, transparent 82%, rgba(0, 0, 0, 0.07) 85%, rgba(0, 0, 0, 0.26) 88%, rgba(0, 0, 0, 0.5) 91%, rgba(0, 0, 0, 0.74) 94%, rgba(0, 0, 0, 0.93) 97%, #000 100%);
}

.hero-copy { position: relative; z-index: 2; flex: 0 0 auto; padding: calc(78px + 9vh) 0 28px 3.8vw; max-width: 46vw; }
.hero-dateline { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-family: var(--serif); font-size: 13px; letter-spacing: 0.1em; color: var(--ink-soft); }
.dot::before { content: "·"; font-weight: 700; }
.live { display: inline-flex; align-items: center; gap: 7px; font-family: var(--latin); font-style: italic; font-size: 18px; letter-spacing: 0.02em; color: var(--ink); }
.live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--rose); box-shadow: 0 0 0 0 rgba(168, 71, 90, 0.5); animation: pulse 2.4s infinite; }
.live-dot.is-paused { background: var(--ink-soft); animation: none; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(168, 71, 90, 0.5); } 70% { box-shadow: 0 0 0 9px rgba(168, 71, 90, 0); } 100% { box-shadow: 0 0 0 0 rgba(168, 71, 90, 0); } }
.hero-title { margin: 2.4vh 0 0 -0.6vw; }
.hero-slogan { margin-top: 2.6vh; font-family: var(--serif); font-weight: 600; font-size: clamp(22px, 2.25vw, 36px); line-height: 1.4; letter-spacing: 0.04em; white-space: nowrap; }
.hero-sub { margin-top: 1.4vh; font-family: var(--serif); font-size: clamp(13px, 1.05vw, 16px); line-height: 1.9; letter-spacing: 0.06em; color: var(--ink-soft); }
.hero-actions { display: flex; align-items: center; gap: 2.6vw; margin-top: 4.4vh; }
.hero .paint-btn { height: clamp(48px, 6.4vh, 62px); padding: 0 clamp(32px, 3.4vw, 56px); font-size: clamp(16px, 1.3vw, 20px); }

.hero.is-night .hero-copy { color: #F6EEE4; --wm: #F2DCD2; }
.hero.is-night .hero-dateline, .hero.is-night .hero-sub { color: rgba(246, 238, 228, 0.82); }
.hero.is-night .live, .hero.is-night .pen-link { color: #F6EEE4; }
.hero.is-night .pen-link::after { background-color: #F2C9C9; }

/* 窗边批注：坐标由脚本写入（--wx/--wy 为窗心，--u 为插画宽度的 1%，--px/--py 为拍立得左上角） */
.window-note { position: absolute; inset: 0; z-index: 2; pointer-events: none; color: #FFF6EA; --u: 16px; }
.hero.is-morning .window-note, .hero.is-noon .window-note { color: #FFFBF4; }
.window-note .stroke { position: absolute; background-color: currentColor; filter: drop-shadow(0 1px 1px rgba(60, 30, 20, 0.25)); }
.stroke-ring.stroke {
  left: calc(var(--wx) - 7.6 * var(--u)); top: calc(var(--wy) - 7 * var(--u));
  width: calc(15.2 * var(--u)); height: calc(14 * var(--u));
  clip-path: inset(0 100% 0 0); animation: reveal-x 1.2s ease 1.6s forwards;
}
.stroke-arrow.stroke {
  left: calc(var(--px) + 16.4 * var(--u)); top: calc(var(--wy) - 4.6 * var(--u));
  width: max(40px, calc(var(--wx) - 7.8 * var(--u) - var(--px) - 16.4 * var(--u))); height: calc(4.4 * var(--u));
  clip-path: inset(0 0 0 100%); animation: reveal-x 0.9s ease 2.5s forwards;
}
@keyframes reveal-x { to { clip-path: inset(0 0 0 0); } }
.peek {
  position: absolute; left: var(--px); top: var(--py); width: calc(15 * var(--u)); aspect-ratio: var(--frame-ar, 0.84);
  color: var(--ink); transform: rotate(7deg); transform-origin: 50% 4%;
  opacity: 0; animation: settle 0.9s cubic-bezier(.2, .9, .3, 1.2) 2.9s forwards;
  filter: drop-shadow(0 14px 18px rgba(40, 25, 15, 0.32));
}
.peek-photo { position: absolute; left: var(--win-l, 8%); top: var(--win-t, 10%); right: var(--win-r, 8%); bottom: var(--win-b, 25%); overflow: hidden; background: #E6D6C2; }
.peek-photo img { width: 100%; height: 100%; object-fit: cover; transition: opacity 0.3s; }
.peek.is-swapping img { opacity: 0; }
.peek-frame { position: absolute; inset: 0; background: url("img/polaroid.webp") center / 100% 100% no-repeat; }
.peek figcaption {
  position: absolute; left: 9%; right: 6%; bottom: 5%; height: calc(100% - 100% + var(--win-b, 25%) - 6%);
  display: flex; flex-direction: column; justify-content: center; font-family: var(--hand); line-height: 1.25;
  font-size: calc(1.45 * var(--u));
}
.peek figcaption b { font-family: var(--latin); font-style: italic; font-weight: 600; font-size: calc(1.5 * var(--u)); color: var(--ink-soft); }
@keyframes settle { from { opacity: 0; transform: translateY(16px) rotate(12deg); } to { opacity: 1; transform: rotate(7deg); } }

/* 时刻切换：撕边纸条上的五个时刻 */
.timebar {
  position: relative; z-index: 3; flex: 0 0 auto; margin: auto 0 4.5vh 3.8vw; width: clamp(440px, 41vw, 680px); aspect-ratio: 3.97;
  display: grid; grid-template-columns: 1.1fr repeat(4, 1fr); align-items: center;
  padding: 2.05vw 2.05vw 0.6vw 3.7vw;
  background: url("img/timebar.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 10px 14px rgba(60, 40, 25, 0.22));
}
.time-stop {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  height: 64%; font-family: var(--serif); font-size: clamp(14px, 1.22vw, 20px); color: var(--ink);
  transition: color 0.2s;
}
.time-stop + .time-stop::before {
  content: ""; position: absolute; left: 0; top: 18%; bottom: 18%; width: 5px;
  background-color: var(--pencil); opacity: 0.55;
  -webkit-mask: url("img/stroke-vline.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-vline.webp") center / 100% 100% no-repeat;
}
.time-stop b { font-family: var(--latin); font-weight: 600; font-size: clamp(17px, 1.5vw, 25px); color: var(--ink); line-height: 1.2; }
.time-stop span { position: relative; }
.time-stop:hover { color: var(--rose); }
.time-stop[aria-pressed="true"], .time-stop[aria-pressed="true"] b { color: var(--rose); }
.time-stop[aria-pressed="true"] span::after {
  content: ""; position: absolute; left: -24%; right: -24%; bottom: -7px; height: 7px; background-color: var(--rose);
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}
.time-stop.is-live { font-family: var(--hand); font-size: clamp(18px, 1.6vw, 26px); font-weight: 600; color: var(--ink); }

/* ══ 画板：每章一块 3:2 设计稿 ══════════════════════════════ */
.board-sec { position: relative; padding: 28px 0; }
/* 底图上下沿按 smoothstep 曲线淡出到页面纸色。底图自带的纸色比页面纸更暖更深，淡出段短于画板高度的一成半
 * 就会在两种纸之间留下一条横线；--fade-t / --fade-b / --fade-x 是淡出段占画板高或宽的比例，各章可单独调。
 * 左右默认不淡出：画板铺满屏宽时，边缘就是视口边缘，淡出只会在两侧留一条发白的纸色带 */
.board { position: relative; width: min(100%, var(--board-max)); margin: 0 auto; aspect-ratio: 3 / 2; container-type: inline-size; --fade-t: 0.18; --fade-b: 0.18; --fade-x: 0; }
.plate {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; user-select: none;
  --mask-x: linear-gradient(90deg,
    transparent, rgba(0, 0, 0, 0.26) calc(var(--fade-x) * 33.3%), rgba(0, 0, 0, 0.74) calc(var(--fade-x) * 66.7%), #000 calc(var(--fade-x) * 100%),
    #000 calc(100% - var(--fade-x) * 100%), rgba(0, 0, 0, 0.74) calc(100% - var(--fade-x) * 66.7%), rgba(0, 0, 0, 0.26) calc(100% - var(--fade-x) * 33.3%), transparent);
  --mask-y: linear-gradient(180deg,
    transparent, rgba(0, 0, 0, 0.07) calc(var(--fade-t) * 16.7%), rgba(0, 0, 0, 0.26) calc(var(--fade-t) * 33.3%), rgba(0, 0, 0, 0.5) calc(var(--fade-t) * 50%),
    rgba(0, 0, 0, 0.74) calc(var(--fade-t) * 66.7%), rgba(0, 0, 0, 0.93) calc(var(--fade-t) * 83.3%), #000 calc(var(--fade-t) * 100%),
    #000 calc(100% - var(--fade-b) * 100%), rgba(0, 0, 0, 0.93) calc(100% - var(--fade-b) * 83.3%), rgba(0, 0, 0, 0.74) calc(100% - var(--fade-b) * 66.7%),
    rgba(0, 0, 0, 0.5) calc(100% - var(--fade-b) * 50%), rgba(0, 0, 0, 0.26) calc(100% - var(--fade-b) * 33.3%), rgba(0, 0, 0, 0.07) calc(100% - var(--fade-b) * 16.7%), transparent);
  -webkit-mask: var(--mask-x), var(--mask-y);
  -webkit-mask-composite: source-in;
  mask: var(--mask-x), var(--mask-y);
  mask-composite: intersect;
}
/* 朋友们的底图下沿与 06 的上沿是同一片晚霞，但两张图的霞色并不完全一致，首尾直接对接会露出一条色差线。
 * 改为让 06 向上叠进朋友们底部 --xfade（画板高度的比例），朋友们底图在重叠段保持不透明，06 底图在同一段从透明渐显，
 * 两张图在这一段交叉淡化。重叠段内两章都没有正文与可点元素，叠放不会挡住朋友们的邮票 */
#friends, #world { --xfade: 0.12; }
#friends { padding-bottom: 0; }
#friends .board { --fade-t: 0.2; --fade-b: 0; }
#world { z-index: 1; padding-top: 0; margin-top: calc(min(100%, var(--board-max)) * -2 / 3 * var(--xfade)); }
#world .board { --fade-t: var(--xfade); --fade-b: 0.24; }
/* 下载章：底图下沿不再淡出，直接铺到页脚撕边之下，由页脚的剪贴撕边盖住底图下缘 */
#download { padding-bottom: 0; }
#download .board { --fade-b: 0; }

/* 视口宽过画板上限（2560）的超宽屏：两侧是页面纸色，画板左右才需要淡出；
 * 上限以内画板铺满屏宽，底图左右直接出血 */
@media (min-width: 2561px) {
  .board { --fade-x: 0.05; }
}
.at { position: absolute; }

.board .chap { display: flex; align-items: baseline; gap: 2.2cqw; }
.board .chap-no { font-family: var(--latin); font-style: italic; font-weight: 500; font-size: 5.4cqw; line-height: 0.8; color: var(--rose); font-variant-numeric: lining-nums; }
.board .chap-en { font-family: var(--latin); font-style: italic; font-size: 1.55cqw; color: var(--rose); letter-spacing: 0.01em; white-space: nowrap; }
.board .chap-title { font-family: var(--serif); font-weight: 600; font-size: 3.4cqw; line-height: 1.32; letter-spacing: 0.04em; white-space: nowrap; }
.board .chap-sub { font-family: var(--serif); font-size: max(13px, 1.25cqw); line-height: 2.05; letter-spacing: 0.04em; color: var(--ink-soft); }
.note-fine { font-size: 12px; color: var(--ink-soft); opacity: 0.85; }
.board .note-fine { font-size: max(11px, 0.85cqw); }

/* ── 01 和她说话 ─────────────────────────────────────────── */
.board-chat .at-chap { left: 8%; top: 17%; width: 30%; }
.board-chat .stroke-rule { flex: 1; height: 0.5cqw; align-self: center; }
.board-chat .at-title { left: 8%; top: 25.5%; font-size: 3.6cqw; line-height: 1.42; letter-spacing: 0.05em; }
.board-chat .at-sub { left: 8%; top: 43.5%; width: 30%; line-height: 2.1; }
.board-chat .at-modes { left: 8%; top: 62%; width: 34%; font-family: var(--serif); font-size: max(12px, 1.1cqw); letter-spacing: 0.04em; color: var(--ink); }
.modes span:not(:last-child)::after { content: "·"; margin: 0 0.9em; color: var(--rose); font-weight: 700; }
/* 桌面端与 02、03 对齐：左缘 10%、标题组与 02 同档字号（标题 3.05cqw）。
 * 右侧背景里的老宅窗在画板 87% 到 94% 处，对话纸右缘最多推到 85%，再往右会遮住窗里的白艾莉，
 * 所以右边距收不到 10%，只把对话纸整体右移 2%，让文字列与对话纸之间的空隙与左边距匹配。 */
@media (min-width: 901px) {
  .board-chat .chap-no { font-size: 4.8cqw; }
  .board-chat .chap-en { font-size: 1.4cqw; }
  .board-chat .chap-sub { font-size: max(13px, 1.12cqw); }
  .board-chat .at-chap { left: 10%; top: 17%; width: 28%; }
  .board-chat .at-title { left: 10%; top: 25.5%; font-size: 3.05cqw; }
  .board-chat .at-sub { left: 10%; top: 41.5%; width: 31%; }
  .board-chat .at-modes { left: 10%; top: 60%; width: 33%; white-space: nowrap; }
  .board-chat .chat-sheet { left: 45%; width: 40%; }
}

.chat-sheet {
  left: 43%; top: 10.5%; width: 40.5%; height: 67%;
  display: flex; flex-direction: column; padding: 8.5% 6.5% 5.5%;
  background: url("img/chat-sheet.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 18px 22px rgba(60, 40, 25, 0.22));
}
.chat-head { display: flex; align-items: center; gap: 1.3cqw; padding-bottom: 1cqw; }
.chat-head img { width: 5.2cqw; height: 5.2cqw; border-radius: 50%; box-shadow: 0 0 0 0.25cqw rgba(140, 110, 90, 0.35); }
.chat-name { font-family: var(--serif); font-weight: 600; font-size: 1.6cqw; line-height: 1.3; letter-spacing: 0.06em; }
.chat-state { display: flex; align-items: center; gap: 0.5cqw; font-family: var(--serif); font-size: max(11px, 1cqw); color: var(--ink-soft); }
.chat-state i { width: 0.6cqw; height: 0.6cqw; border-radius: 50%; background: #6F9A62; }
.chat-demo-tag { margin-left: auto; align-self: flex-start; font-family: var(--latin); font-style: italic; font-size: 1.2cqw; color: var(--ink-soft); }
.chat-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0.6cqw 0.2cqw; display: flex; flex-direction: column; gap: 1.2cqw; scrollbar-width: none; }
.chat-body::-webkit-scrollbar { display: none; }
.msg {
  max-width: 78%; padding: 1.15cqw 2cqw 1.6cqw; font-family: var(--hand); font-size: max(14px, 1.38cqw); line-height: 1.6;
  background: center / 100% 100% no-repeat; animation: pop 0.35s cubic-bezier(.2, .9, .3, 1.3);
}
.msg-her { align-self: flex-start; background-image: url("img/bubble-her.webp"); padding-left: 2.2cqw; }
.msg-me { align-self: flex-end; background-image: url("img/bubble-me.webp"); padding-right: 2.4cqw; }
.msg-typing { display: flex; gap: 0.45cqw; padding: 1.3cqw 2cqw 1.7cqw; }
.msg-typing i { width: 0.5cqw; height: 0.5cqw; border-radius: 50%; background: var(--ink-soft); animation: blink 1.2s infinite; }
.msg-typing i:nth-child(2) { animation-delay: 0.15s; }
.msg-typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes blink { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }
@keyframes pop { from { opacity: 0; transform: translateY(6px) scale(0.97); } }
.chat-chips { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6cqw 2.6cqw; padding-top: 1.2cqw; min-height: 4.6cqw; }
.chip { position: relative; font-family: var(--hand); font-size: max(14px, 1.4cqw); color: var(--ink); padding: 0.3cqw 0 0.7cqw; transition: color 0.2s; }
.chip::after {
  content: ""; position: absolute; left: -6%; right: -6%; bottom: 0; height: 0.62cqw; background-color: var(--rose);
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}
.chip:hover { color: var(--rose); }
.chip:disabled { opacity: 0.4; cursor: default; }
.msg-end { font-family: var(--hand); font-size: max(14px, 1.4cqw); }
.msg-end a { color: var(--rose); }

/* ── 02 送她点什么 ───────────────────────────────────────── */
.board-gift .at-chap { left: 6%; top: 8%; }
.board-gift .at-title { left: 6%; top: 15.8%; }
.board-gift .at-sub { left: 6%; top: 24.4%; }

.gift-shelf { left: 0.6%; top: 30%; width: 57.5%; height: 52%; }
.shelf-board { position: absolute; left: 0; top: 70.5%; width: 100%; pointer-events: none; filter: drop-shadow(0 14px 14px rgba(70, 45, 25, 0.2)); }
.gift { position: absolute; bottom: 26.8%; display: block; }
.gift img { width: 100%; height: 100%; object-fit: contain; object-position: center bottom; filter: var(--drop); transition: transform 0.45s cubic-bezier(.2, .9, .3, 1.2); }
.gift-dress { left: 1.6%; width: 44%; height: 70%; bottom: 25.6%; }
.gift-ticket { left: 42.3%; width: 28.8%; height: 57%; }
.gift-book { left: 70.8%; width: 26.6%; height: 64%; bottom: 18.6%; }
/* 书靠架子右端。说明若跟标题一起居中，末字「完」会压上右侧铜托架。
   标题仍对准书；说明行单独右缘对齐，停在托架左侧，多出来的字往左排。 */
.gift-book .gift-tag {
  top: calc(100% + 1.75cqw); left: 0; width: 100%; transform: none;
  display: flex; flex-direction: column; align-items: stretch;
}
/* 行比按钮窄时，右缘停在托架左侧；行比按钮宽时，多出来的字往左溢出，不盖住托架。 */
.gift-book .gift-line {
  align-self: flex-end; width: max-content; margin-right: 36%;
  white-space: nowrap;
}
.gift:hover img { transform: translateY(-1cqw) rotate(-1.5deg); }
.gift[aria-checked="true"] img { transform: translateY(-1.6cqw) rotate(-2.5deg); }
.gift-tag {
  position: absolute; left: 50%; top: calc(100% + 4.6cqw); width: 160%; transform: translateX(-50%);
  text-align: center; font-family: var(--serif); font-size: max(11px, 0.92cqw); line-height: 1.5; color: var(--ink-soft);
}
.gift-tag b { display: block; font-weight: 600; font-size: max(14px, 1.32cqw); letter-spacing: 0.08em; color: var(--ink); margin-bottom: 0.2cqw; transition: color 0.2s; }
.gift[aria-checked="true"] .gift-tag b { color: var(--rose); }
.shelf-hint { left: 13%; top: 82.5%; width: 34%; text-align: center; font-size: max(15px, 1.75cqw); color: var(--rose); transform: rotate(-2deg); }
.shelf-hint .stroke { width: 100%; height: 1.5cqw; margin-top: 0.2cqw; }

.calendar {
  left: 66.2%; top: 4.6%; width: 13.8%; height: 32.9%;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding-top: 4.2cqw;
  background: url("img/calendar.webp") center / 100% 100% no-repeat;
  filter: var(--drop); transform: rotate(2deg);
}
.calendar-top { font-family: var(--serif); font-weight: 600; font-size: 1.3cqw; letter-spacing: 0.2em; color: var(--rose-deep); }
.calendar-day { font-family: var(--latin); font-weight: 600; font-size: 5.6cqw; line-height: 0.95; color: var(--rose-deep); }
.calendar-week { margin-top: 0.5cqw; font-family: var(--serif); font-size: max(11px, 0.88cqw); color: var(--ink-soft); letter-spacing: 0.08em; }

.moment {
  left: 58.6%; top: 34.2%; width: 37.3%; height: 62%;
  padding: 5.6% 6.5% 4.2%;
  background: url("img/moment-card.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 16px 20px rgba(60, 40, 25, 0.2));
}
.moment-body { display: flex; flex-direction: column; height: 100%; }
.moment[data-empty="true"] { display: grid; place-items: center; }
.moment-empty { font-size: max(16px, 1.8cqw); color: var(--ink-soft); }
.moment[data-empty="true"] .moment-body, .moment[data-empty="false"] .moment-empty { display: none; }
.moment.is-dropping .moment-body { animation: drop 0.6s cubic-bezier(.2, .9, .3, 1.15); }
@keyframes drop { from { opacity: 0; transform: translateY(-14px); } }
.moment-head { display: flex; align-items: center; gap: 1cqw; }
.moment-head img { width: 3.3cqw; height: 3.3cqw; border-radius: 50%; }
.moment-name { font-family: var(--serif); font-weight: 600; font-size: max(13px, 1.15cqw); line-height: 1.3; }
.moment-time { font-family: var(--serif); font-size: max(11px, 0.92cqw); color: var(--ink-soft); }
.moment-text { margin-top: 1cqw; font-family: var(--serif); font-size: max(13px, 1.12cqw); line-height: 1.7; }
.moment-photo { flex: 1; min-height: 0; margin-top: 1cqw; overflow: hidden; border-radius: 2px; }
.moment-photo img { width: 100%; height: 100%; object-fit: cover; }
.moment-likes { margin-top: 0.9cqw; font-family: var(--serif); font-size: max(12px, 1cqw); color: var(--ink-soft); }
/* 信纸里的入口沿用铅笔链接：衬线、玫瑰下划线、拉丁箭头。字号跟这条动态的正文走，不另做一颗按钮。 */
.moment-jump {
  align-self: flex-start; margin-top: 0.45cqw; max-width: 100%;
  font-size: max(13px, 1.12cqw); gap: 0.45em; padding-bottom: 0.28em;
}
.moment-jump::before { font-size: 1.25em; }
.moment-jump::after { height: 0.42em; right: 1.35em; bottom: 0; }
.moment-jump:hover { gap: 0.75em; }
/* 素材里信封下沿是一条直边，正好落在画板底部，下段晕开到纸面，避免整章以一道横切线收尾 */
.gift-deco {
  left: 76%; top: 62.5%; width: 25%; pointer-events: none; filter: var(--drop);
  -webkit-mask: linear-gradient(180deg, #000 72%, rgba(0, 0, 0, 0.5) 86%, transparent 99%);
  mask: linear-gradient(180deg, #000 72%, rgba(0, 0, 0, 0.5) 86%, transparent 99%);
}
.board-gift .at-fine { left: 6%; top: 95%; }
.board-gift { overflow: hidden; }
/* 桌面端内容整体缩小，底图不动：标题组与 03、04 同档字号；货架、日历、动态卡、信封装饰与提示
 * 以画板水平中线、纵向 --gy 处为中心，用同一个 --gk 等比缩小，左右留白变大。
 * 每个元素原来的位置与尺寸写成未缩放值再乘 --gk；想调大小只改 --gk。窄屏纵向排版不进这段。 */
@media (min-width: 901px) {
  .board-gift { --gk: 0.86; --gy: 8%; }
  .board-gift .chap-no { font-size: 4.8cqw; }
  .board-gift .chap-en { font-size: 1.4cqw; }
  .board-gift .chap-title { font-size: 3.05cqw; }
  .board-gift .chap-sub { font-size: max(13px, 1.12cqw); }
  .board-gift .at-chap { left: 10%; top: 6.4%; }
  .board-gift .at-title { left: 10%; top: 13.6%; }
  .board-gift .at-sub { left: 10%; top: 20.6%; }
  .board-gift .gift-shelf {
    left: calc(50% + (0.6% - 50%) * var(--gk)); top: calc(var(--gy) + (30% - var(--gy)) * var(--gk));
    width: calc(57.5% * var(--gk)); height: calc(52% * var(--gk));
  }
  .board-gift .gift-tag { top: calc(100% + 4.6cqw * var(--gk)); font-size: max(11px, calc(0.92cqw * var(--gk))); }
  .board-gift .gift-tag b { font-size: max(14px, calc(1.32cqw * var(--gk))); }
  .board-gift .gift-book .gift-tag { top: calc(100% + 1.75cqw * var(--gk)); }
  .board-gift .shelf-hint {
    left: calc(50% + (13% - 50%) * var(--gk)); top: calc(var(--gy) + (82.5% - var(--gy)) * var(--gk));
    width: calc(34% * var(--gk)); font-size: max(15px, calc(1.75cqw * var(--gk)));
  }
  .board-gift .shelf-hint .stroke { height: calc(1.5cqw * var(--gk)); }
  .board-gift .calendar {
    left: calc(50% + (66.2% - 50%) * var(--gk)); top: calc(var(--gy) + (4.6% - var(--gy)) * var(--gk));
    width: calc(13.8% * var(--gk)); height: calc(32.9% * var(--gk)); padding-top: calc(4.2cqw * var(--gk));
  }
  .board-gift .calendar-top { font-size: calc(1.3cqw * var(--gk)); }
  .board-gift .calendar-day { font-size: calc(5.6cqw * var(--gk)); }
  .board-gift .calendar-week { margin-top: calc(0.5cqw * var(--gk)); font-size: max(11px, calc(0.88cqw * var(--gk))); }
  .board-gift .moment {
    left: calc(50% + (58.6% - 50%) * var(--gk)); top: calc(var(--gy) + (34.2% - var(--gy)) * var(--gk));
    width: calc(37.3% * var(--gk)); height: calc(62% * var(--gk));
  }
  .board-gift .moment-empty { font-size: max(16px, calc(1.8cqw * var(--gk))); }
  .board-gift .moment-head { gap: calc(1cqw * var(--gk)); }
  .board-gift .moment-head img { width: calc(3.3cqw * var(--gk)); height: calc(3.3cqw * var(--gk)); }
  .board-gift .moment-name { font-size: max(13px, calc(1.15cqw * var(--gk))); }
  .board-gift .moment-time { font-size: max(11px, calc(0.92cqw * var(--gk))); }
  .board-gift .moment-text { margin-top: calc(1cqw * var(--gk)); font-size: max(13px, calc(1.12cqw * var(--gk))); }
  .board-gift .moment-photo { margin-top: calc(1cqw * var(--gk)); }
  .board-gift .moment-likes { margin-top: calc(0.9cqw * var(--gk)); font-size: max(12px, calc(1cqw * var(--gk))); }
  .board-gift .moment-jump { margin-top: calc(0.45cqw * var(--gk)); font-size: max(13px, calc(1.12cqw * var(--gk))); }
  .board-gift .gift-deco {
    left: calc(50% + (76% - 50%) * var(--gk)); top: calc(var(--gy) + (62.5% - var(--gy)) * var(--gk));
    width: calc(25% * var(--gk));
  }
  .board-gift .at-fine { left: 10%; top: calc(var(--gy) + (95% - var(--gy)) * var(--gk)); }
  /* 02 内容上移后，画板下沿多出一段空白：让 03 向上叠进来（03 底图顶部是透明渐变，不会盖住 02 的内容），
   * 章与章的间距与 03 到 04 相当 */
  #day { margin-top: calc(min(100%, var(--board-max)) * -2 / 3 * 0.1); }
}

/* ── 04 手账本 ───────────────────────────────────────────── */
/* 标题组左缘对齐本子左缘（.book 的 left: 14.8%），字号与 03 同档（比其他章略小），
 * 标题底到书签顶留出约一行字的呼吸，不再贴着书签 */
.board-book .at-chap { left: 14.8%; top: 4%; }
.board-book .at-title { left: 14.8%; top: 10.8%; }
@media (min-width: 901px) {
  .board-book .chap-no { font-size: 4.8cqw; }
  .board-book .chap-en { font-size: 1.4cqw; }
  .board-book .chap-title { font-size: 3.05cqw; }
}
#inside { scroll-margin-top: 96px; }
.book { left: 14.8%; top: 22%; width: 69.6%; height: 76%; }
/* 书签尺寸与 05 橱窗区（.wld-tab）共用同一套变量（见 :root 的 --tab-fs）：
   两个本子宽度不同，按各自宽度折算会在窄屏上出现一大一小，所以字号按视口取值，
   最小宽、内边距、间距全部写成 em，跟着字号走。
   窗口较矮时 main.js 会把整个 .book 用 scale 缩小（--book-fit 就是缩放比例），书签是它的子元素，
   不处理的话会比 05 橱窗的书签小一圈，所以字号、间距、露出高度都除以 --book-fit，抵消缩放。 */
.book-tabs { position: absolute; left: 10%; right: 6%; top: 0; height: 9%; display: flex; align-items: flex-start; gap: calc(var(--tab-fs) * 0.76 / var(--book-fit, 1)); }
.book-tab {
  position: relative; flex: 0 0 auto; min-width: 4.4em; height: calc(100% + 2.6cqw); padding: 0 0.78em; /* 下沿伸进本子内页后面，任何状态下都不留缝 */
  display: grid; place-items: start center; padding-top: 0.45em;
  /* 书签底是水彩纸纹，细宋体的笔画会被纹理吃掉：改手写文楷，加大字号，描一圈纸色轻晕 */
  font-family: var(--tab-font); font-size: calc(var(--tab-fs) / var(--book-fit, 1)); font-weight: 400; letter-spacing: 0.06em; line-height: 1.2; white-space: nowrap; color: var(--tab-ink);
  text-shadow: var(--tab-halo);
  background: var(--tab) center / 100% 100% no-repeat;
  /* 未选中的书签露出 --tab-vis 这么高（页边在 3.04cqw 处）；两个本子共用同一个露出高度 */
  --tab-y: calc(3.04cqw - var(--tab-vis) / var(--book-fit, 1));
  transform: translateY(var(--tab-y)); transition: transform 0.25s;
  filter: drop-shadow(0 2px 2px rgba(60, 40, 25, 0.12));
}
.book-tab:hover { transform: translateY(calc(var(--tab-y) - 0.4em)); }
/* 选中的书签只是从本子里多抽出一截，仍留在内页后面，不压到页面前面 */
.book-tab[aria-selected="true"] { transform: translateY(calc(var(--tab-y) - 1.25em)); -webkit-text-stroke: var(--tab-stroke-on) currentColor; min-width: 5.5em; }
.book-spread { position: absolute; left: 0; right: 0; top: 6%; bottom: 0; background: url("img/notebook.webp") center / 100% 100% no-repeat; filter: drop-shadow(0 22px 26px rgba(60, 40, 25, 0.26)); }
.book-left { position: absolute; left: 10.4%; top: 15%; width: 34%; }
.book-idx { font-family: var(--latin); font-style: italic; font-weight: 500; font-size: 4.5cqw; line-height: 1; color: var(--rose); }
.book-idx::after { content: ""; display: block; width: 4.2cqw; height: 0.5cqw; margin-top: 0.4cqw; background-color: var(--rose); -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat; mask: url("img/stroke-under.webp") center / 100% 100% no-repeat; }
.book-title { font-family: var(--serif); font-weight: 600; font-size: 2cqw; letter-spacing: 0.1em; margin-top: 1.4cqw; }
.book-text { font-family: var(--hand); font-size: max(15px, 1.75cqw); line-height: 1.95; margin-top: 1.8cqw; }
.book-left .note-fine { margin-top: 2.4cqw; }
.book-right { position: absolute; left: 52.4%; top: 9.6%; width: 40.6%; height: 79%; }
.book-shot { position: relative; display: block; width: 100%; height: 100%; transform: rotate(-1.2deg); transition: transform 0.3s; }
.book-shot:hover { transform: rotate(0deg) scale(1.015); }
.book-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: 0.8cqw; box-shadow: var(--shadow-paper); transition: opacity 0.25s; }
.book-shot.is-swapping img { opacity: 0; }
/* 胶带中心锚在截图左上角，斜跨页角；跟随截图旋转和缩放。 */
.book-shot .tape { top: 0; left: 0; width: 8cqw; height: 2.3cqw; transform: translate(-50%, -50%) rotate(-35deg); }
.book-shot .tape-tail { top: auto; bottom: -1cqw; left: auto; right: -2.4cqw; transform: rotate(-24deg); }

/* 滚动手账时整块画板钉在视口里，继续滚动只切书签。高度由脚本按书签数撑开。 */
#inside.is-scrolly .board-book { position: sticky; z-index: 2; }

/* ── 05 朋友 ─────────────────────────────────────────────── */
.board-friends .at-chap { left: 15%; top: 8.2%; }
.board-friends .at-title { left: 15%; top: 14.6%; }
.board-friends .at-sub { left: 15%; top: 23.6%; }
.board-friends .at-hint { left: 15%; top: 28.6%; font-size: max(13px, 1.3cqw); color: var(--rose); }
.stamps {
  /* 横向滚动容器必然裁切纵向溢出：顶部留 1.2cqw 内边距，容纳邮票的投影与悬停上浮（0.4cqw）；
     左右同理：首张与末张邮票的侧边投影需要 1.2cqw 余量，不然贴着容器边缘被截断。
     top / left / width / height 同步补偿，邮票与下方姓名的实际位置保持不变。 */
  left: calc(9.6% - 1.2cqw); top: calc(37.6% - 1.2cqw); width: calc(66.6% + 2.4cqw); height: calc(43% + 1.2cqw);
  display: flex; gap: 2cqw; padding: 1.2cqw 1.6cqw 0;
  overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none;
}
/* 桌面鼠标可按住拖动邮票带（触屏与触控板本来就能滑）；拖动中的状态由 main.js 加 is-grabbing */
@media (hover: hover) and (pointer: fine) {
  .stamps { cursor: grab; }
}
.stamps.is-grabbing, .stamps.is-grabbing * { cursor: grabbing; user-select: none; -webkit-user-select: none; }
.stamps::-webkit-scrollbar { display: none; }
/* 还有没露出来的朋友时，对应一侧淡出，看得出邮票带没到头 */
.stamps {
  --fade-l: 0px; --fade-r: 0px; scroll-padding-inline: 1.6cqw;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
}
.stamps.can-prev { --fade-l: 3.2cqw; }
.stamps.can-next { --fade-r: 3.2cqw; }
.stamp-pager { right: 17.6%; top: 28.4%; display: flex; align-items: center; gap: 0.8cqw; }
.stamp-pager[hidden] { display: none; }
.stamp-count { margin-right: 0.6cqw; font-family: var(--serif); font-size: max(12px, 1.05cqw); color: var(--ink-soft); white-space: nowrap; }
.stamp-count b { font-family: var(--latin); font-style: italic; font-weight: 600; font-size: 1.3em; color: var(--ink); font-variant-numeric: lining-nums; margin-right: 0.15em; }
.stamp-nav {
  display: grid; place-items: center; width: max(30px, 2.6cqw); aspect-ratio: 1; border-radius: 50%;
  border: 1px solid rgba(110, 98, 90, 0.4); background: rgba(251, 248, 241, 0.55); color: var(--ink);
  transition: color 0.2s, border-color 0.2s, background-color 0.2s, opacity 0.2s;
}
.stamp-nav svg { width: 46%; height: 46%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.stamp-nav:hover:not(:disabled) { color: var(--rose); border-color: var(--rose); background: rgba(251, 248, 241, 0.9); }
.stamp-nav:disabled { opacity: 0.32; cursor: default; }
.stamp { position: relative; flex: 0 0 11.7cqw; height: 100%; perspective: 900px; scroll-snap-align: start; text-align: left; }
.stamp-inner { position: absolute; left: 0; right: 0; top: 0; aspect-ratio: var(--stamp-ar, 0.72); transform-style: preserve-3d; transition: transform 0.7s cubic-bezier(.3, .9, .3, 1.1); }
.stamp.is-flipped .stamp-inner { transform: rotateY(180deg); }
.stamp:hover .stamp-inner { transform: translateY(-0.4cqw); }
.stamp.is-flipped:hover .stamp-inner { transform: rotateY(180deg) translateY(-0.4cqw); }
.stamp-face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; filter: drop-shadow(0 6px 8px rgba(60, 40, 25, 0.2)); }
.stamp-back { transform: rotateY(180deg); }
.stamp-back::before {
  content: ""; position: absolute; inset: 0; background: #F7F0E3 url("img/paper.webp") center / 320px;
  -webkit-mask: url("img/stamp-shape.webp") center / 100% 100% no-repeat;
  mask: url("img/stamp-shape.webp") center / 100% 100% no-repeat;
}
.stamp-art { position: absolute; left: var(--sw-l, 12%); top: var(--sw-t, 10%); right: var(--sw-r, 12%); bottom: var(--sw-b, 10%); overflow: hidden; background: var(--tint, var(--rose-soft)); }
.stamp-art img { width: 100%; height: 100%; object-fit: cover; object-position: center 25%; }
.stamp-frame { position: absolute; inset: 0; background: url("img/stamp-frame.webp") center / 100% 100% no-repeat; }
.stamp-postmark {
  position: absolute; right: 2%; bottom: 3%; width: 44%; aspect-ratio: 1; transform: rotate(-12deg);
  display: grid; place-items: center; text-align: center;
  font-family: var(--serif); font-weight: 700; font-size: max(10px, 0.92cqw); line-height: 1.2; color: rgba(150, 50, 62, 0.92);
}
.stamp-postmark::before {
  content: ""; position: absolute; inset: 0; background-color: rgba(150, 50, 62, 0.85);
  -webkit-mask: url("img/postmark.webp") center / contain no-repeat;
  mask: url("img/postmark.webp") center / contain no-repeat;
}
.stamp-postmark span { position: relative; }
.stamp-meta { position: absolute; left: 0; right: 0; top: calc(11.7cqw / var(--stamp-ar, 0.72) + 1.2cqw); }
.stamp-name { display: block; font-family: var(--serif); font-weight: 600; font-size: max(13px, 1.3cqw); line-height: 1.3; letter-spacing: 0.04em; white-space: nowrap; }
.stamp-name small { font-family: var(--latin); font-style: italic; font-weight: 500; font-size: 1.2em; color: var(--ink-soft); margin-left: 0.5em; letter-spacing: 0; }
.stamp-role { display: block; margin-top: 0.3cqw; font-family: var(--serif); font-size: max(11px, 0.92cqw); color: var(--ink-soft); }
.stamp-back .stamp-art { bottom: 46%; }
.stamp-quote { position: absolute; left: 10%; right: 10%; top: 57%; bottom: 8%; overflow: hidden; font-family: var(--hand); font-size: max(11px, 0.92cqw); line-height: 1.5; }
.stamp-add { left: 78.4%; top: 37.6%; width: 11.7cqw; }
/* 底图右上角干花便签。文字收在撕边以内：左边距纸边约一字，右边停在干花和胶带之前。
 * 纸面几乎是平的，只留一点手写倾斜；旧坐标偏左、转角过大，字会落在纸外的底色上。 */
.pin-note { left: 81.6%; top: 8.2%; width: 11.6%; font-size: max(10px, 0.98cqw); line-height: 1.68; color: var(--ink); transform: rotate(-1.2deg); pointer-events: none; }
.pin-note span { display: block; margin-top: 0.4cqw; text-align: right; color: var(--ink-soft); }
/* 待认识的新朋友：和其他朋友同款邮票，画面是生图的剪影与问号（img/stamp-unknown.webp）。
 * 鼠标移上去邮票轻轻抬起，画面提亮 */
.stamp-add-card {
  position: relative; display: block; width: 100%; aspect-ratio: var(--stamp-ar);
  filter: drop-shadow(0 6px 8px rgba(60, 40, 25, 0.2)); transition: transform 0.35s cubic-bezier(.3, .9, .3, 1.1), filter 0.35s;
}
.stamp-add-card .stamp-art { --tint: var(--rose-soft); }
.stamp-add-card .stamp-art img { object-position: center; transition: filter 0.35s; filter: saturate(0.9) brightness(0.98); }
.stamp-add:hover .stamp-add-card { transform: translateY(-0.4cqw) rotate(-1deg); filter: drop-shadow(0 10px 12px rgba(60, 40, 25, 0.26)); }
.stamp-add:hover .stamp-add-card .stamp-art img { filter: saturate(1.05) brightness(1.03); }
.stamp-add:focus-visible .stamp-add-card { outline: 2px solid var(--rose); outline-offset: 4px; }
.stamp-add-label { display: block; margin-top: 1.2cqw; font-family: var(--serif); font-size: max(12px, 0.95cqw); color: var(--ink-soft); }
.stamp-add-label b { font-family: var(--latin); font-size: 1.4em; font-weight: 500; margin-right: 0.3em; }
.stamp-add:hover .stamp-add-label { color: var(--rose); }

/* ── 评价 ────────────────────────────────────────────────── */
.board-notes .at-chap { left: 0; right: 0; top: 5.8%; justify-content: center; }
.board-notes .at-title { left: 0; right: 0; top: 10.6%; text-align: center; }
.board-notes .at-flourish { left: 43%; top: 18.6%; width: 14%; height: 1.4cqw; --stroke: var(--rose); }
.notes { left: 10%; top: 21.6%; width: 80%; height: 64.5%; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 3.2cqw 2.6cqw; }
.note {
  position: relative; display: flex; flex-direction: column; padding: 3.4cqw 2.4cqw 2cqw;
  background: var(--note) center / 100% 100% no-repeat; transform: rotate(var(--r, 0deg));
  filter: drop-shadow(0 10px 12px rgba(60, 40, 25, 0.16));
  transition: transform 0.3s, filter 0.3s;
}
.note:hover { transform: rotate(0deg) translateY(-0.4cqw); filter: drop-shadow(0 16px 18px rgba(60, 40, 25, 0.22)); }
.note-text { flex: 1; min-height: 0; overflow: hidden; font-family: var(--hand); font-size: max(13px, 1.15cqw); line-height: 1.9; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; }
.note-who { display: flex; align-items: center; gap: 0.8cqw; margin-top: 0.8cqw; font-family: var(--serif); font-size: max(11px, 0.95cqw); color: var(--ink-soft); }
.note-who img { width: 2.4cqw; height: 2.4cqw; min-width: 22px; min-height: 22px; border-radius: 50%; object-fit: cover; }
.board-notes .at-more { left: 0; right: 0; top: 89.5%; text-align: center; }
/* 观猹评分贴在板块右上角，与英文眉题同一高度，不压标题和便签。图由观猹接口实时下发，分数变化不用改页面 */
.board-notes .watcha-badge {
  right: 4.6%; top: 4.2%; width: 20%; z-index: 3;
  transform: rotate(1.5deg); filter: drop-shadow(0 8px 12px rgba(60, 40, 25, 0.2));
  transition: transform 0.3s, filter 0.3s;
}
.board-notes .watcha-badge:hover { transform: rotate(0deg) translateY(-2px); filter: drop-shadow(0 12px 16px rgba(60, 40, 25, 0.26)); }
.board-notes .watcha-badge img { display: block; width: 100%; height: auto; }

/* ── 下载：一封封好的信，点开后封盖翻起、信纸抽出来，读完还能放回去 ───────────── */
/* 提示是一个切换按钮：信封合着时写「拆开看看」，拆开后写「把信放回信封」，点火漆印、信封或这行字都能切换 */
.board-letter .letter-hint { left: 30%; top: 11.5%; width: 40%; padding: 0; text-align: center; font-size: max(16px, 1.75cqw); color: var(--rose); transform: rotate(-2deg); cursor: pointer; transition: color 0.2s; }
.board-letter .letter-hint:hover { color: var(--rose-deep); }
.board-letter .letter-hint:disabled { cursor: default; }
.letter-hint .stroke { width: 76%; height: 1.2cqw; margin: 0.2cqw auto 0; }
/* 合着的信封上方留白：纸飞机飞向中间，旁边飘着花瓣和星光。拆开后信纸会升进这块空白，装饰随之淡出 */
.letter-deco { left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; transition: opacity 0.45s ease; }
.board-letter.is-open .letter-deco { opacity: 0; transition-duration: 0.25s; }
.letter-deco > * { position: absolute; display: block; height: auto; user-select: none; }
.letter-deco .ld-plane { left: 33.5%; top: 25%; width: 13cqw; rotate: 3deg; animation: ld-float 5.2s ease-in-out infinite; }
.letter-deco .ld-stars { left: 49.9%; top: 22%; width: 5.4cqw; animation: ld-twinkle 3.4s ease-in-out infinite; }
.letter-deco .ld-petals { left: 57.7%; top: 25.5%; width: 9.4cqw; rotate: -6deg; animation: ld-drift 6.4s ease-in-out -2s infinite; }
@keyframes ld-float { 0%, 100% { translate: 0 0; } 50% { translate: 0.9cqw 0.7cqw; } }
@keyframes ld-twinkle { 0%, 100% { opacity: 1; scale: 1; } 50% { opacity: 0.55; scale: 0.92; } }
@keyframes ld-drift { 0%, 100% { translate: 0 0; rotate: -6deg; } 50% { translate: -0.5cqw 1.1cqw; rotate: 2deg; } }
.letter-hint .hint-open { display: none; }
.board-letter.is-open .letter-hint .hint-open { display: inline; }
.board-letter.is-open .letter-hint .hint-closed { display: none; }
/* 信封素材 envelope.webp 是「封盖翻开」的样子（819×857）：封盖折痕在 40.8% 高度处，盖尖在顶部，口袋口在 64% 处。
 * 这里把它拆成三层：信封体（折痕以下，常驻）、封盖（折痕以上，绕折痕翻转 180 度）、前片（口袋形状，盖住信纸下半截）。
 * 合上时封盖翻到前片上方，盖尖落在口袋口以下；翻起时封盖躺回原来的位置，画面与整张素材一致。
 * 自下而上：信封体 0，翻起后的封盖 1，信纸 2，前片 3，合上的封盖 4，下载按钮 4，火漆印 5。 */
.board-letter { --pocket: polygon(0 40.4%, 28.2% 64%, 72.2% 64%, 100% 41.8%, 100% 100%, 0 100%); --fold: 40.8%; --lift: 0.9s; --ease: cubic-bezier(.4, 0, .2, 1); }
/* 在屏高自适应的阅读尺寸上整体放大 40%，画板居中，纵向内容允许正常滚动。
 * 底图仍独立铺满页面，封盖、信纸与下载按钮沿用同一坐标系；窄屏维持纵向排版。 */
@media (min-width: 901px) {
  .board-letter { width: calc(min(100%, 1600px, max(960px, calc((100svh - 100px) * 1.65))) * 1.4); left: 50%; margin-inline: 0; translate: -50% 0; }
  .board-letter > .plate { left: 50%; width: min(100vw, var(--board-max)); max-width: none; translate: -50% 0; }
}
.env-back, .env-front { left: 26%; top: 16.5%; width: 48%; cursor: pointer; }
.env-back { filter: drop-shadow(0 22px 26px rgba(60, 40, 25, 0.26)); clip-path: inset(40.5% -80px -80px -80px); }
.env-front { z-index: 3; clip-path: var(--pocket); }
.env-box { position: absolute; left: 26%; top: 16.5%; width: 48%; aspect-ratio: 819 / 857; pointer-events: none; transform-style: preserve-3d; transform-origin: 50% var(--fold); }
.flap-face, .seal-face { position: absolute; inset: 0; transform-origin: 50% var(--fold); -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.flap-face img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
/* 封盖与火漆印同一套翻转：合上是 0 度（盖尖朝下压在前片上），拆开是 180 度（盖尖朝上）。
 * 外面（合上时看到的一面）与里面（翻起后看到的一面）各画一份，翻到 90 度侧立的瞬间换面，看不出跳变 */
.flap, .seal-pivot { transform: perspective(110cqw) rotateX(0deg); }
.flap { z-index: 4; transition: transform 0.8s var(--ease) 0.45s, z-index 0.01s linear 0.85s; }
.seal-pivot { z-index: 5; transition: transform 0.8s var(--ease) 0.45s; }
.board-letter.is-open .flap { z-index: 1; transform: perspective(110cqw) rotateX(180deg); transition: transform var(--lift) var(--ease), z-index 0.01s linear 0.45s; }
.board-letter.is-open .seal-pivot { transform: perspective(110cqw) rotateX(180deg); transition: transform var(--lift) var(--ease); }
/* 外面：素材的封盖部分沿折痕翻到下方，再按「盖住口袋」的外形裁成封盖。两条斜边与口袋两侧的折边重合，
 * 盖尖落在口袋口（64%）以下 6.6% 处，带圆角 */
.flap-out { filter: drop-shadow(0 0.5cqw 0.9cqw rgba(50, 30, 15, 0.34)); }
.flap-clip { position: absolute; inset: 0; pointer-events: auto; cursor: pointer;
  clip-path: polygon(0 40.3%, 100% 40.3%, 100% 41.8%, 72.2% 64%, 66% 67.3%, 60% 69.4%, 55% 70.3%, 50% 70.6%, 45% 70.3%, 40% 69.4%, 34% 67.3%, 27.8% 64%, 0 40.4%); }
.flap-clip img { transform-origin: 50% var(--fold); transform: scaleY(-1); clip-path: inset(0 0 58.9% 0); }
/* 里面：素材的封盖原样放在折痕上方，翻到 180 度时正好落回原位；在折痕上多留 0.3% 与信封体重叠，避免接缝出现发丝线 */
.flap-in { transform: rotateX(180deg); }
.flap-in img { clip-path: inset(-60px -60px 58.9% -60px); filter: drop-shadow(0 0.4cqw 0.9cqw rgba(60, 40, 25, 0.2)); }
.seal-face { pointer-events: none; }
.seal-in { transform: rotateX(180deg); }
/* 火漆印：合上时压在盖尖上（半个印悬在盖尖外），拆开后落在翻起的封盖顶端，与信纸上沿略有重叠 */
.seal { position: absolute; left: 40.8%; width: 18.33%; aspect-ratio: 1; background: url("img/seal-alice.webp") center / contain no-repeat; filter: var(--drop); pointer-events: auto; cursor: pointer; }
.seal-out .seal { top: 57.25%; transform: rotate(-6deg); }
.seal-in .seal { top: 0.66%; transform: rotate(-6deg); }
/* 信纸夹在信封里：槽位铺满画板，下沿按信封不透明像素的下边（约在画板高度 91.15% 处）略往里裁切，
 * 信纸塞回口袋时伸出信封底边的那一截不会露在信封外面；槽位自己不接收点击，只有信纸可点 */
.letter-slot { z-index: 2; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; clip-path: inset(0 0 9.3% 0); }
/* 信纸默认整张塞在口袋里（下沉 26cqw，上沿落到口袋口 43.2cqw 以下），合上的封盖与前片把它完全盖住；
 * 拆开时等封盖翻过 90 度再抽出，收回时先把信纸塞进去、再合上封盖 */
.letter {
  position: absolute; left: 29.8%; top: 27%; width: 40.4%; height: 46%; pointer-events: auto; cursor: pointer;
  padding: 2.6cqw 3.8cqw; background: url("img/letter-paper.webp") center top / 100% auto no-repeat;
  transform: translateY(26cqw); transition: transform 0.7s cubic-bezier(.5, 0, .3, 1);
}
/* 信纸抽出后是阅读状态：点信纸不再收回，避免读字或选文字时误触；收回走提示按钮、火漆印或信封 */
.board-letter.is-open .letter { transform: none; transition: transform 1.1s cubic-bezier(.2, .8, .2, 1) 0.55s; cursor: auto; }
/* 下载按钮常驻：合上时压在火漆印下方的前片上（火漆印下沿约在画板高度 72.8%，按钮从 74% 起），
 * 拆开后随封盖翻起升到口袋口。点任何一个按钮都会直接下载并顺手拆开信封 */
.board-letter .dl { transform: translateY(4.8cqw); transition: transform 0.8s var(--ease) 0.45s; }
.board-letter.is-open .dl { transform: none; transition: transform var(--lift) var(--ease); }
.letter-greet { font-size: max(12px, 1.12cqw); color: var(--ink-soft); }
.letter-title { margin-top: 0.8cqw; font-family: var(--serif); font-weight: 600; font-size: 2.45cqw; letter-spacing: 0.06em; white-space: nowrap; }
.letter-body { margin-top: 1.2cqw; font-size: max(13px, 1.42cqw); line-height: 1.85; }
.letter-sign { margin-top: 0.4cqw; margin-right: 16%; text-align: right; font-size: max(14px, 1.6cqw); color: var(--ink); }
.letter-sign i { font-family: var(--latin); font-style: italic; }
/* 附言：选不准版本、要装手机版或装完打不开的人，去独立下载页看芯片说明、二维码与首次启动提示。
 * 口袋口两侧是斜边、只有中段最低，附言居中并保持一行短句，才不会被前片盖住开头 */
.letter-ps { margin-top: 0.5cqw; text-align: center; white-space: nowrap; font-size: max(12px, 1.12cqw); color: var(--ink-soft); }
.letter-ps a { color: var(--rose); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; transition: color 0.2s; }
.letter-ps a:hover { color: var(--rose-deep); }
.dl { z-index: 4; left: 33%; top: 66.8%; width: 34%; display: flex; flex-direction: column; align-items: center; gap: 1.8cqw; }
.dl-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  height: 3.2cqw; min-height: 36px; padding: 0 1.6cqw; font-family: var(--serif); font-size: max(12px, 1.02cqw); color: var(--ink); white-space: nowrap;
  transition: color 0.2s, transform 0.2s;
}
.board-letter .dl-btn { gap: 0.4cqw; padding: 0 1.35cqw; }
.board-letter .dl-ico { display: inline-flex; flex: none; transition: transform 0.2s; }
.board-letter .dl-ico svg { width: 1.05em; height: 1.05em; display: block; }
.board-letter .dl-btn:hover .dl-ico { transform: translateY(2px); }
.dl-btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background-color: rgba(42, 35, 32, 0.85);
  -webkit-mask: url("img/ink-frame.webp") center / 100% 100% no-repeat;
  mask: url("img/ink-frame.webp") center / 100% 100% no-repeat;
}
.dl-btn:hover { color: var(--rose-deep); transform: translateY(-2px); }
.dl-btn:hover::before { background-color: var(--rose-deep); }
.dl-main { height: 3.8cqw; min-width: 52%; padding: 0 2.4cqw; font-size: max(14px, 1.38cqw); color: #F6EEE4; letter-spacing: 0.04em; }
.dl-main::before { background-color: transparent; -webkit-mask: none; mask: none; background: url("img/btn-paint-ink.webp") center / 100% 100% no-repeat; }
.dl-main:hover { color: #fff; }
.dl-main:hover::before { background-color: transparent; filter: brightness(1.15); }
.dl-row { display: flex; gap: 1.2cqw; isolation: isolate; }
.dl-main { isolation: isolate; }

/* ── 03 照片墙：六张拍立得、一张牛皮纸条、一条甜点胶片，桌面端都能拖 ──
 * 第三张「和闺蜜视频」自己演一遍：铅笔箭头从相纸上沿指向右上方，「按住拖一拖」贴在笔尖。
 * 手抓稳后拖向右上，松手即弹回，手势同时离开。
 * 这只是引导。悬停时摊开的手跟着指针，按住换成握拳，都不露出系统手型。
 * 访客真正拖动后示例停掉，照片留在放下的位置。 */
/* 示范的位置、手势与提示共用 main.js 中的时间线。 */
/* 标题组与照片墙内容左缘对齐（第一张相纸缩放后的左缘约在画板 10.5% 处），字号比其他章略小，和缩小后的照片墙比例一致 */
.board-wall .at-chap { left: 10.5%; top: 6.4%; width: 30%; }
.board .chap .stroke-rule { flex: 1; height: 0.5cqw; align-self: center; }
.board-wall .at-title { left: 10.5%; top: 13.6%; }
@media (min-width: 901px) {
  .board-wall .chap-no { font-size: 4.8cqw; }
  .board-wall .chap-en { font-size: 1.4cqw; }
  .board-wall .chap-title { font-size: 3.05cqw; }
}
.board-wall .at-hint { left: 58.6%; top: 7.4%; width: 15%; font-size: max(14px, 1.5cqw); line-height: 1.45; color: var(--rose); text-align: center; transform: rotate(-7deg); }
.board-wall .at-hint .stroke { width: 92%; height: 1cqw; margin: 0.1cqw auto 0; }
/* 照片墙内容整体缩放：底图不动，相纸、纸条、甜点胶片与引导提示以画板水平中线、纵向 --wy 处为中心等比缩小，
 * 左右边距随之变大。各元素原来的位置和尺寸写成未缩放值，再乘 --wk；想调大小只改这一个数。
 * --wy 取 5.8% 是让缩小后的第一排相纸上沿落在标题下方约 4cqw 处：标题与照片的间距由它决定，数越小照片越靠上 */
.board-wall { --wk: 0.85; --wy: 5.8%; }
/* 与相邻章节的衔接：内容整体上移后，画板下方留白变大。桌面端让下一章向上叠进本章下沿的空白段
 * （两章底图在这一段都是透明渐变，叠放不会挡住正文），章与章的间距和上一章到本章的间距相当 */
@media (min-width: 901px) {
  #inside { margin-top: calc(min(100%, var(--board-max)) * -2 / 3 * 0.12); }
}
.wall { inset: 0; pointer-events: none; }
.wall-item { transform: rotate(var(--r, 0deg)); transition: filter 0.25s; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.wall-item img { -webkit-user-drag: none; }
/* 拖动期间整页不出现选区：指针移出相纸后经过的正文也不会被蓝色选中 */
html.wall-dragging, html.wall-dragging * { user-select: none !important; -webkit-user-select: none !important; }
.wall-item.is-draggable { cursor: grab; }
.wall-item.is-dragging { cursor: grabbing; transition: none; z-index: 20; filter: drop-shadow(0 22px 24px rgba(60, 40, 25, 0.3)); }
/* 拖出相纸时指针已不在照片上，系统手型会从底下的元素冒出来，整页一起藏掉 */
html.wall-hand, html.wall-hand * { cursor: none !important; }
.wall-item:hover { z-index: 10; }
.wall-pol {
  position: absolute; aspect-ratio: var(--wf-ar);
  left: calc(50% + (var(--x) - 50%) * var(--wk)); top: calc(var(--wy) + (var(--y) - var(--wy)) * var(--wk)); width: calc(16% * var(--wk));
  pointer-events: auto; filter: drop-shadow(0 10px 12px rgba(60, 40, 25, 0.2));
}
.wall-pol-photo { position: absolute; left: var(--wf-l); top: var(--wf-t); right: var(--wf-r); bottom: var(--wf-b); overflow: hidden; background: #E6D6C2; }
.wall-pol-photo img { width: 100%; height: 100%; object-fit: cover; }
.wall-pol::after { content: ""; position: absolute; inset: 0; z-index: 1; background: url("img/wall-frame.webp") center / 100% 100% no-repeat; pointer-events: none; }
.wall-pol figcaption {
  position: absolute; z-index: 2; left: 8%; right: 6%; bottom: 0; height: var(--wf-b);
  display: flex; align-items: center; justify-content: center; gap: 0.5em;
  font-family: var(--hand); font-size: max(12px, calc(1.05cqw * var(--wk))); white-space: nowrap;
}
.wall-pol figcaption { white-space: nowrap; }
.wall-pol figcaption b { font-family: var(--latin); font-weight: 600; font-size: 1.08em; color: var(--ink-soft); }
.wall-pol .tape { top: -5%; width: 46%; height: calc(2.3cqw * var(--wk)); }
.wall-note {
  left: calc(50% + (3.7% - 50%) * var(--wk)); top: calc(var(--wy) + (68.4% - var(--wy)) * var(--wk)); width: max-content; min-width: calc(36% * var(--wk)); height: calc(22.6% * var(--wk));
  display: flex; flex-direction: column; justify-content: center; padding: 3.4% 4.5% 2.4% 6.5%;
  background: url("img/wall-note.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 10px 12px rgba(60, 40, 25, 0.18));
}
.wall-note .hand { font-size: max(14px, calc(1.38cqw * var(--wk))); line-height: 1.75; white-space: nowrap; }
.wall-note .stroke { width: 38%; height: calc(0.9cqw * var(--wk)); margin-top: calc(0.4cqw * var(--wk)); --stroke: var(--ink-soft); }
.food-strip {
  left: calc(50% + (42.7% - 50%) * var(--wk)); top: calc(var(--wy) + (71.8% - var(--wy)) * var(--wk)); width: calc(33.2% * var(--wk)); aspect-ratio: var(--fs-ar);
  filter: drop-shadow(0 10px 12px rgba(60, 40, 25, 0.18));
}
.food-strip img { position: absolute; top: var(--fs-t); width: var(--fs-w); height: calc(100% - var(--fs-t) - var(--fs-b)); object-fit: cover; }
.food-strip img:nth-child(1) { left: var(--fs-1); }
.food-strip img:nth-child(2) { left: var(--fs-2); }
.food-strip img:nth-child(3) { left: var(--fs-3); }
.food-strip img:nth-child(4) { left: var(--fs-4); }
.food-strip::after { content: ""; position: absolute; inset: 0; background: url("img/food-strip.webp") center / 100% 100% no-repeat; pointer-events: none; }

/* 铅笔箭头素材本身指向左，笔尾在右侧。先绕笔尾抬起，再水平翻转，笔尖指向右上方的「按住拖一拖」，
   笔尾贴着第三张相纸的上沿。选择器必须压过首屏的 .stroke-arrow.stroke，否则会套用窗边批注的 --px/--u，宽高被算成 0。 */
.wall .wall-coach.stroke {
  position: absolute; z-index: 12;
  left: calc(50% + (33.2% - 50%) * var(--wk)); top: calc(var(--wy) + (30.6% - var(--wy)) * var(--wk));
  width: calc(13cqw * var(--wk)); height: calc(5.4cqw * var(--wk)); pointer-events: none; opacity: 0;
  transform: scaleX(-1) rotate(22deg); transform-origin: 98.5% 23%;
  clip-path: none;
  animation: none;
  filter: drop-shadow(0 2px 2px rgba(60, 30, 20, 0.32));
}
.wall-cue {
  position: absolute; z-index: 22; margin: 0;
  left: calc(50% + (58.7% - 50%) * var(--wk)); top: calc(var(--wy) + (27.8% - var(--wy)) * var(--wk));
  font-size: max(16px, calc(1.85cqw * var(--wk))); line-height: 1; color: var(--rose); letter-spacing: 0.06em;
  white-space: nowrap; pointer-events: none; opacity: 0;
  transform: rotate(-4deg); transform-origin: 0% 50%;
}
/* 提示文字与箭头共用同一位移，保留笔尖与文字的相对位置。 */
.wall .wall-coach.stroke, .wall-cue { translate: 0 calc(-1.2cqw * var(--wk)); }
/* 手是引导元素：示例里按住照片再松开。访客悬停时同一只摊开的手跟着指针，按住换成握拳。
   两张图的手掌中心对齐，袖口跟着同一只手。 */
/* 手必须是画板的直接子元素，排在相纸、纸条和甜点胶片之后。
   它原先放在 .wall 里，胶片在 .wall 后面，拖动时整条胶片会盖住这只手。 */
.wall-paw {
  /* 胶带上那只手原来是 1.38cqw。抓紧、松开和悬停共用这一档，在它的基础上放大 50%。 */
  --hand-w: 2.07cqw;
  position: absolute; z-index: 40; left: 42.7%; top: 33.2%;
  width: var(--hand-w); height: calc(var(--hand-w) * 795 / 701);
  margin-left: calc(var(--hand-w) * -0.42);
  margin-top: calc(var(--hand-w) * 795 / 701 * -0.56);
  pointer-events: none; opacity: 0; transform: rotate(-8deg); transform-origin: 42% 56%;
  filter: drop-shadow(0 3px 2px rgba(80, 30, 40, 0.22));
  transition: opacity 0.22s ease;
}
.wall-paw img { position: absolute; display: block; user-select: none; -webkit-user-drag: none; }
.wall-paw .paw-open { inset: 0; width: 100%; height: 100%; object-fit: contain; }
.wall-paw .paw-shut { opacity: 0; width: 72%; height: auto; left: 12.6%; top: 28%; }
.wall-paw.is-live { opacity: 1; translate: none; scale: 1; }
.wall-paw.is-clenched .paw-open { opacity: 0; }
.wall-paw.is-clenched .paw-shut { opacity: 1; }
/* 演示不再分别播放六组 CSS 动画，避免各轨道的节拍和悬停覆盖互相争抢。
   只合成位移、缩放与透明度，保留相纸原有角度，不逐帧重绘大范围模糊阴影。 */
.board-wall.is-coaching .wall-demo { z-index: 18; will-change: translate; }
.board-wall.is-coaching .wall-paw { transition: none; will-change: translate, opacity; }
@media (prefers-reduced-motion: reduce) {
  .wall-paw, .wall-item { transition: none; }
  .wall-cue { opacity: 1; }
}

/* ── 06 世界：软木板上钉着别人家的白艾莉，底下一条模型纸条 ── */
.board-world .at-chap { left: 7.6%; top: 21%; width: 32%; }
.board-world .at-title { left: 7.6%; top: 28.6%; font-size: 3.3cqw; line-height: 1.38; }
.board-world .at-sub { left: 7.6%; top: 45%; width: 34%; }
.board-world .at-link { left: 7.6%; top: 56.5%; font-size: max(14px, 1.3cqw); }
/* 软木板整体缩小约 10%，右边缘从 98.4% 收到 95.4%，给右侧留出更宽的边距。
   --fc-pad 与相纸头部字号按同一比例收小，相纸内部比例保持不变。 */
.cork { left: 43.4%; top: 16.2%; width: 49%; height: 46%; --fc-pad: 1.58cqw 0.9cqw 0.9cqw; background: url("img/cork.webp") center / 100% 100% no-repeat; filter: drop-shadow(0 18px 22px rgba(60, 40, 25, 0.26)); }
.feed {
  position: absolute; left: var(--x); top: var(--y); width: 23%; aspect-ratio: var(--fc-ar);
  display: flex; flex-direction: column; padding: var(--fc-pad);
  background: url("img/feed-card.webp") center / 100% 100% no-repeat; transform: rotate(var(--r));
  filter: drop-shadow(0 8px 10px rgba(60, 40, 25, 0.2)); transition: transform 0.3s;
}
.feed:hover { transform: rotate(0deg) translateY(-0.4cqw); z-index: 2; }
.feed-head { display: flex; align-items: center; gap: 0.45cqw; font-family: var(--serif); font-size: max(10px, 0.7cqw); }
.feed-head img { width: 1.55cqw; height: 1.55cqw; border-radius: 50%; }
.feed-head small { margin-left: auto; font-size: 0.92em; color: var(--ink-soft); }
.feed-photo { flex: 1; min-height: 0; margin-top: 0.6cqw; overflow: hidden; }
.feed-photo img { width: 100%; height: 100%; object-fit: cover; }
.hang-tag {
  left: var(--ht-x); top: var(--ht-y); width: var(--ht-w); aspect-ratio: var(--ht-ar);
  display: flex; align-items: center; justify-content: center; padding: var(--ht-pad);
  font-size: max(12px, 1.12cqw); white-space: nowrap; color: var(--ink);
  background: url("img/hang-tag.webp") center / 100% 100% no-repeat; transform: rotate(-4deg); transform-origin: 30% 0;
  filter: drop-shadow(0 6px 8px rgba(60, 40, 25, 0.2));
}
.model-strip {
  left: 1.2%; top: 75.2%; width: 96.5%; height: 16.4%;
  display: flex; align-items: center; padding: 0 5% 0 8.4%;
  background: url("img/model-strip.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 10px 14px rgba(60, 40, 25, 0.2));
}
.model-title { font-family: var(--serif); font-weight: 600; font-size: max(14px, 1.5cqw); letter-spacing: 0.04em; white-space: nowrap; }
.model-copy p { margin-top: 0.3cqw; font-family: var(--serif); font-size: max(11px, 0.95cqw); color: var(--ink-soft); white-space: nowrap; }
.model-divider { width: 0.45cqw; height: 52%; margin: 0 2.2cqw; --m: url("img/stroke-vline.webp"); --stroke: var(--pencil); opacity: 0.6; }
.model-tags { display: flex; flex-wrap: wrap; gap: 0.9cqw 1.1cqw; }
.model-tags li {
  position: relative; padding: 0.45cqw 0.95cqw; font-family: var(--serif); font-size: max(12px, 1.12cqw); color: var(--c); white-space: nowrap;
}
.model-tags li::before {
  content: ""; position: absolute; inset: 0; background-color: var(--c); opacity: 0.85;
  -webkit-mask: url("img/ink-frame.webp") center / 100% 100% no-repeat;
  mask: url("img/ink-frame.webp") center / 100% 100% no-repeat;
}

/* ── 她的世界：左侧圆环装订页。书签横排在页顶，文案在上，横版截图铺在下面。 ── */
.wld { position: relative; z-index: 2; padding: 48px 0 96px; scroll-margin-top: 96px; isolation: isolate; }
/* 轨道高度由脚本按书签数撑开。钉住的是本子，标题留在轨道上方，滚进画面后先离开。 */
.wld-scrolly { margin-top: 28px; }
/* 本子左右留白：窄窗口至少 72px，随视口加宽，宽屏上限 1000px（两侧各 220px 以上） */
.wld-pin { width: min(1000px, calc(100% - clamp(72px, 12vw, 240px))); margin: 0 auto; }
/* 选中的书签会向上抽出标签栏约 18px。本子钉住时顶边贴着导航栏下沿，抽出的这截要有地方放，否则文字上半被导航栏盖住。
   这 10px 计入 pin 的高度，脚本算「放不放得下」时自动扣除。 */
@media (min-width: 901px) { .wld-pin { padding-top: 10px; } }
.wld-pin .wld-stage { margin-top: 0; }
#worldLive.is-scrolly .wld-pin { position: sticky; z-index: 2; }
/* 书签轨道会把这一章拉高。底图若铺在整章上，cover 会把四角的照片裁掉，滚动时底图还在滑。
   桌面钉住时，用一屏纸纹承接装饰底图，整层一起 sticky；纸纹延伸到导航下方，
   只让装饰图上下淡出，避免透明处露出随整页滚动的 body 纸纹。窄屏仍用 .wld::before。 */
.wld-bg { display: none; }
#worldLive.is-scrolly .wld-bg {
  display: block; position: absolute; inset: 0; z-index: 0; pointer-events: none;
}
#worldLive.is-scrolly::before { content: none; }
#worldLive.is-scrolly .wld-bg-sticky {
  position: sticky; top: 0; height: 100vh;
  background: var(--paper) url("img/paper.webp") repeat;
  background-size: 640px;
}
#worldLive.is-scrolly .wld-bg-sticky::before {
  content: ""; position: absolute; inset: 78px 0 0;
  background: url("img/plate-wld.webp") center / cover no-repeat;
  --mask-y: linear-gradient(180deg,
    transparent, rgba(0, 0, 0, 0.2) 7%, rgba(0, 0, 0, 0.7) 14%, #000 22%,
    #000 78%, rgba(0, 0, 0, 0.7) 88%, rgba(0, 0, 0, 0.2) 95%, transparent);
  -webkit-mask: var(--mask-y);
  mask: var(--mask-y);
}
.wld::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: url("img/plate-wld.webp") center / cover no-repeat;
  --mask-y: linear-gradient(180deg,
    transparent, rgba(0, 0, 0, 0.2) 7%, rgba(0, 0, 0, 0.7) 14%, #000 22%,
    #000 78%, rgba(0, 0, 0, 0.7) 88%, rgba(0, 0, 0, 0.2) 95%, transparent);
  -webkit-mask: var(--mask-y);
  mask: var(--mask-y);
}
.wld-sheet { position: relative; z-index: 1; width: min(1000px, calc(100% - clamp(72px, 12vw, 240px))); margin: 0 auto; container-type: inline-size; }
.wld-kicker { display: flex; align-items: center; gap: 14px; }
.wld-en { font-family: var(--latin); font-style: italic; font-weight: 500; font-size: clamp(20px, 2.2cqw, 26px); color: var(--rose); white-space: nowrap; }
.wld-kicker .stroke-rule { width: 92px; height: 7px; flex: none; }
.wld-title {
  margin-top: 10px; font-family: var(--serif); font-weight: 600;
  font-size: clamp(28px, 3.5cqw, 42px); line-height: 1.32; letter-spacing: 0.04em;
  white-space: nowrap;
}
.wld-sub { max-width: 28em; margin-top: 12px; font-family: var(--serif); font-size: max(15px, 1.45cqw); line-height: 1.9; color: var(--ink-soft); }
.wld-stage { margin-top: 28px; }
.wld-book {
  display: flex; flex-direction: column; align-items: stretch;
  width: 90%; margin-inline: auto;
  container-type: inline-size;
}
.wld-tabs {
  /* 七个书签一排的总宽约 43em。--tab-fs 只跟视口走，而书本宽度封顶 900px、窗口较矮时还会被脚本收窄，
     宽屏上字号涨到 19px 时总宽（823px）会超过标签栏（810px），最后一个书签被挤出去。
     所以这里的字号再按书本宽度封顶：总宽始终约等于书本宽度的 91%，标签栏两侧只留 2%，任何宽度都放得下。 */
  --wld-tab-fs: min(var(--tab-fs), 2.1cqw);
  position: relative; z-index: 1;
  display: flex; flex-direction: row; align-items: flex-start; justify-content: center; gap: calc(var(--wld-tab-fs) * 0.76);
  margin: 0 2% -5.35cqw 2%; padding: 0;
}
.wld-tab {
  /* 宽高比跟 04 手账书签一致：短标签也有最小宽度，下沿伸进纸页，选中的更宽、再抽出一截。
     字不贴上沿。未选中时露出的只有 2.8cqw（页边在 4cqw，书签又下沉 1.2cqw），
     上内边距把字的中线放到这截里，和手账书签同一高度；选中后字跟着书签上沿一起抽出。 */
  position: relative; flex: 0 0 auto; min-width: 4.4em; height: 9.35cqw; padding: 0.45em 0.78em 0;
  display: grid; place-items: start center;
  writing-mode: horizontal-tb;
  font-family: var(--tab-font); font-size: var(--wld-tab-fs, var(--tab-fs)); font-weight: 400; letter-spacing: 0.06em; line-height: 1.2; color: var(--tab-ink); white-space: nowrap;
  text-shadow: var(--tab-halo);
  background: var(--tab) center / 100% 100% no-repeat;
  --tab-y: calc(4cqw - var(--tab-vis)); /* 页边在 4cqw 处，露出高度与 04 手账书签相同 */
  transform: translateY(var(--tab-y)); transition: transform 0.25s;
  filter: drop-shadow(0 2px 2px rgba(60, 40, 25, 0.12));
}
.wld-tab:nth-child(1) { --tab: url("img/tab-1.webp"); }
.wld-tab:nth-child(2) { --tab: url("img/tab-2.webp"); }
.wld-tab:nth-child(3) { --tab: url("img/tab-3.webp"); }
.wld-tab:nth-child(4) { --tab: url("img/tab-4.webp"); }
.wld-tab:nth-child(5) { --tab: url("img/tab-5.webp"); }
.wld-tab:nth-child(6) { --tab: url("img/tab-6.webp"); }
.wld-tab:nth-child(7) { --tab: url("img/tab-3.webp"); }
/* 「歌」只有一个字，书签收窄到刚好容下它：七个书签一排时总宽不再超出书本，第一个书签不会被挤出左边 */
.wld-tab:nth-child(7) { min-width: 3.2em; }
.wld-tab:nth-child(7).is-on { min-width: 3.8em; }
.wld-tab:hover { transform: translateY(calc(var(--tab-y) - 0.4em)); }
.wld-tab.is-on { min-width: 5.5em; transform: translateY(calc(var(--tab-y) - 1.25em)); -webkit-text-stroke: var(--tab-stroke-on) currentColor; z-index: 1; }
.wld-tab.is-on:hover { transform: translateY(calc(var(--tab-y) - 1.25em)); }
.wld-leaf {
  position: relative; z-index: 2; width: 100%; min-width: 0;
  pointer-events: none;
  background: none;
  filter: drop-shadow(0 18px 22px rgba(60, 40, 25, 0.22));
}
.wld-ring { display: block; width: 100%; height: auto; pointer-events: none; user-select: none; }
.wld-inner {
  position: absolute; inset: 5.2% 6.2% 3.4% 13%;
  display: flex; flex-direction: column; gap: 6px;
  min-height: 0; overflow: hidden;
}
.wld-page { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; flex: 0 0 auto; min-height: 0; pointer-events: auto; }
.wld-caps { display: grid; width: 100%; }
.wld-cap {
  grid-area: 1 / 1; align-self: start;
  display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 16px; align-items: start;
  opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.wld-cap.is-on { opacity: 1; transform: none; pointer-events: auto; }
.wld-idx {
  grid-row: 1 / span 2; display: block; font-family: var(--latin); font-style: italic; font-weight: 500;
  font-size: clamp(44px, 4.6cqw, 60px); line-height: 0.9; color: var(--rose);
}
.wld-idx::after {
  content: ""; display: block; width: 52px; height: 7px; margin-top: 6px; background-color: var(--rose);
  -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
}
.wld-cap h3 {
  margin: 2px 0 6px; font-family: var(--serif); font-weight: 600;
  font-size: clamp(20px, 2.1cqw, 26px); line-height: 1.3; letter-spacing: 0.08em;
}
.wld-cap p { margin: 0; max-width: 36em; font-family: var(--hand); font-size: max(16px, 1.65cqw); line-height: 1.75; color: var(--ink); }
.wld-note { max-width: 36em; margin: 2px 0 0; font-size: 12px; line-height: 1.6; color: var(--ink-soft); }
.wld-photo { position: relative; margin-top: 0; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; pointer-events: auto; container-type: size; }
.wld-frame {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; flex: 1 1 auto; min-height: 0; text-align: left; cursor: zoom-in;
}
.wld-polaroid {
  position: relative; flex: none;
  /* 单图、多图共用留边；叠放层和翻页控件不再挤占主图高度。 */
  width: min(calc(100cqw - 12px), calc((100cqh - 46px) * 1600 / 1118));
  max-height: calc(100cqh - 46px);
  aspect-ratio: 1600 / 1118;
}
.wld-back {
  position: absolute; inset: 0; display: block; overflow: hidden;
  border-radius: 8px; background: var(--paper); box-shadow: var(--shadow-paper);
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.wld-back img { display: block; width: 100%; height: 100%; object-fit: contain; }
.wld-back-far { transform: translate(6px, -5px) rotate(2deg); }
.wld-back-near { transform: translate(-5px, -2px) rotate(-1.5deg); }
.wld-photo.is-stack .wld-back-near,
.wld-photo.is-deep-stack .wld-back-far { opacity: 1; }
.wld-shots {
  /* 外框已经按截图原比例收好，这里铺满，整张界面不再被裁切 */
  position: relative; z-index: 1; display: block; width: 100%; height: 100%; flex: none; min-height: 0;
  overflow: hidden;
  border-radius: 8px; background: #f3e6d4;
  box-shadow: var(--shadow-paper), inset 0 0 0 1px rgba(120, 90, 60, 0.16);
  transform: rotate(-0.4deg); transition: transform 0.3s;
}
.wld-frame:hover .wld-shots { transform: rotate(0deg) scale(1.008); }
.wld-shot {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center;
  border-radius: 5px; opacity: 0; transition: opacity 0.55s ease;
}
.wld-shot.is-on { opacity: 1; }
.wld-photo-tools { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex: 0 0 44px; width: min(calc(100cqw - 12px), calc((100cqh - 46px) * 1600 / 1118)); margin-inline: auto; }
.wld-pager { display: flex; align-items: center; gap: 4px; color: var(--rose-deep); }
/* 单图仍保留同一行高度，切换书签时图片不跳尺寸。 */
.wld-pager[hidden] { display: flex; visibility: hidden; }
.wld-pager button { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; transition: background-color 0.2s ease; }
.wld-pager button:hover { background-color: rgba(168, 71, 90, 0.1); }
.wld-count { min-width: 4ch; text-align: center; font-family: var(--latin); font-size: 16px; font-variant-numeric: tabular-nums; }
.wld-look { min-height: 44px; flex-shrink: 0; padding: 0 4px; text-align: right; white-space: nowrap; font-size: max(15px, 1.45cqw); color: var(--rose); transform: rotate(-1deg); cursor: zoom-in; }
.wld-pager button:focus-visible, .wld-look:focus-visible, .wld-frame:focus-visible { outline: 2px solid var(--rose-deep); outline-offset: 2px; }
/* 斜跨截图角：中段压住角，两头都落在本子纸面。 */
.wld-polaroid .tape {
  top: -2px; left: calc(100% + 10px); right: auto; width: 18%; height: 26px;
  transform: translate(-50%, -50%) rotate(42deg);
}
.wld-polaroid .tape-tail {
  top: calc(100% + 4px); left: -10px; right: auto; bottom: auto; width: 56px; height: 24px;
  transform: translate(-50%, -50%) rotate(50deg);
}

.wld-lb {
  position: fixed; inset: 0; z-index: 80; display: flex; align-items: stretch; justify-content: center;
  background: rgba(18, 12, 10, 0.92);
}
.wld-lb[hidden] { display: none; }
.wld-lb-scroll { flex: 1; overflow: auto; display: flex; justify-content: center; align-items: flex-start; padding: 56px 72px 72px; cursor: zoom-out; }
.wld-lb-scroll img { display: block; width: min(1280px, 100%); height: auto; border-radius: 10px; background: #efe9de; box-shadow: 0 20px 80px rgba(0, 0, 0, 0.55); cursor: default; }
.wld-lb-close, .wld-lb-nav {
  position: absolute; z-index: 2; display: grid; place-items: center;
  border-radius: 50%; background: rgba(255, 255, 255, 0.12); color: #fff;
  transition: background 0.2s ease;
}
.wld-lb-close:hover, .wld-lb-nav:hover { background: rgba(255, 255, 255, 0.26); }
.wld-lb-close { top: 14px; right: 18px; width: 42px; height: 42px; }
.wld-lb-nav { top: 50%; width: 48px; height: 48px; margin-top: -24px; }
.wld-lb-prev { left: 18px; }
.wld-lb-next { right: 18px; }
.wld-lb-count {
  position: absolute; left: 0; right: 0; bottom: 18px; margin: 0; text-align: center;
  font-size: 13px; letter-spacing: 0.06em; color: rgba(255, 255, 255, 0.74); pointer-events: none;
}

/* ── 常见问题：信箱旁边一叠问题卡，一次只展开一张 ─────────── */
/* 文字块整体居中：标题左缘 12.4%，卡片右缘 87.6%，左右各留 12.4% */
.board-faq .at-chap { left: 12.4%; top: 23.4%; width: 26%; }
.board-faq .at-title { left: 12.4%; top: 28.6%; font-size: 3.15cqw; line-height: 1.32; }
/* 与上一章（评价）的衔接：FAQ 底图上半部分是大片留白，文字块又落在 23% 处，叠上评价章下沿的留白，
 * 评价末尾的「在观猹看全部评价」到本章标题的间距过大。桌面端让本章整体向上叠进评价章下沿的空白段
 * （叠入段只有本章底图顶部的透明渐变与纸色，不碰评价章的链接）。想再收紧调大 0.15，想放松调小 */
@media (min-width: 901px) {
  #faq { margin-top: calc(min(100%, var(--board-max)) * -2 / 3 * 0.15); }
}
.faq-cards { left: 41.6%; top: 23.2%; width: 46%; display: flex; flex-direction: column; gap: 0.9cqw; }
.faq-card {
  border: var(--fq-bw) solid transparent; border-image: url("img/faq-card.webp") var(--fq-slice) fill / var(--fq-bw) stretch;
  filter: drop-shadow(0 6px 8px rgba(60, 40, 25, 0.14));
}
.faq-card summary {
  display: flex; align-items: center; gap: 1cqw; list-style: none; cursor: pointer;
  padding: 0.4cqw 0.4cqw 0.4cqw 0.8cqw; font-family: var(--serif); font-weight: 600; font-size: max(13px, 1.12cqw); letter-spacing: 0.03em;
  transition: color 0.2s;
}
.faq-card summary::-webkit-details-marker { display: none; }
.faq-card summary::after { content: "+"; font-family: var(--latin); font-size: 1.5em; font-weight: 500; line-height: 1; color: var(--ink-soft); transition: transform 0.3s; }
.faq-card[open] summary::after { transform: rotate(45deg); }
.faq-card summary:hover { color: var(--rose); }
.faq-rose { flex: 0 0 auto; width: 1.6cqw; aspect-ratio: 1; margin-left: auto; background: url("img/rose.webp") center / contain no-repeat; }
.faq-card p { padding: 0.2cqw 6% 0.6cqw 0.8cqw; font-size: max(12.5px, 0.9cqw); line-height: 1.85; color: var(--ink-soft); }

/* 纸胶带：生成素材 */
.tape {
  position: absolute; z-index: 3; top: -16px; left: 50%; width: 112px; height: 32px;
  transform: translateX(-50%) rotate(-3deg);
  background: center / 100% 100% no-repeat; pointer-events: none;
}
.tape-1 { background-image: url("img/tape-1.webp"); }
.tape-2 { background-image: url("img/tape-2.webp"); transform: translateX(-50%) rotate(4deg); }
.tape-3 { background-image: url("img/tape-3.webp"); transform: translateX(-50%) rotate(-5deg); }
.tape-4 { background-image: url("img/tape-4.webp"); transform: translateX(-50%) rotate(2deg); }
.tape-5 { background-image: url("img/tape-5.webp"); }
.tape-6 { background-image: url("img/tape-6.webp"); transform: translateX(-50%) rotate(5deg); }

/* ══ 滚动进场 ══════════════════════════════════════════════
 * 脚本确认支持 IntersectionObserver、且访客没有开启「减少动态效果」时才给 <html> 加 .motion；
 * 没有 .motion 时全部内容直接可见，脚本加载失败也不会留下空白画板。
 * 元素进入视口后加 .is-in；同一批进入视口的按文档顺序错开（--d），容器里的一组实物再按 --i 依次出场。
 * 位移、旋转、缩放一律用独立的 translate / rotate / scale 属性，叠加在元素原有的 transform 之上，
 * 不改照片、便签、邮票的摆放角度；关键帧只写 from、用 backwards 填充，动画结束即交还原值，
 * 照片墙拖动写入的 style.translate 不会被动画终态压住。
 * 信封由信封体、封盖、信纸槽、前片、火漆印五层叠成，五层必须同一帧出现，否则会先露出塞在口袋里的信纸，
 * 所以整组挂在画板的 .is-env-in 上，不逐个观察。 */
:root { --rv-ease: cubic-bezier(.2, .8, .2, 1); --rv-spring: cubic-bezier(.2, .9, .3, 1.25); }

.motion .board .plate:not(.is-in),
.motion .board .at:not(.is-in):not(.wall):not(.notes):not(.stamps):not(.faq-cards):not(.gift-shelf):not(.env-back):not(.env-front):not(.letter-slot),
.motion .wall-pol:not(.is-in),
.motion .note:not(.is-in),
.motion :is(.gift-shelf, .stamps, .faq-cards):not(.is-in) > *,
.motion .board-letter:not(.is-env-in) :is(.env-back, .env-front, .env-box, .letter-slot),
.motion .wld-head:not(.is-in),
.motion .wld-stage:not(.is-in) { opacity: 0; }

@keyframes rv-ink { from { opacity: 0; translate: 0 18px; filter: blur(6px); } }
@keyframes rv-rise { from { opacity: 0; translate: 0 36px; } }
@keyframes rv-place { from { opacity: 0; translate: 0 40px; rotate: var(--rv-tilt, -1.5deg); scale: 1.02; } }
@keyframes rv-drop { from { opacity: 0; translate: 0 -30px; rotate: var(--rv-spin, -5deg); scale: 1.06; } }
@keyframes rv-press { from { opacity: 0; rotate: var(--rv-spin, -5deg); scale: 1.18; } }
@keyframes rv-pop { from { opacity: 0; translate: 0 24px; scale: 0.9; } }
@keyframes rv-slide { from { opacity: 0; translate: var(--rv-from, 36px) 0; } }
@keyframes rv-swing { 0% { opacity: 0; rotate: 10deg; } 35% { opacity: 1; rotate: -4deg; } 65% { rotate: 2deg; } 85% { rotate: -0.6deg; } }
@keyframes rv-stick { from { opacity: 0; scale: 1.35; } }
@keyframes rv-postmark { from { opacity: 0; scale: 1.6; } }
@keyframes rv-draw { from { clip-path: inset(0 100% 0 0); } }
@keyframes rv-draw-y { from { clip-path: inset(0 0 100% 0); } }
@keyframes rv-plate { from { opacity: 0; scale: 1.04; } }
@keyframes rv-wiggle { 0%, 100% { rotate: 0deg; } 20% { rotate: -9deg; } 45% { rotate: 7deg; } 70% { rotate: -3deg; } }

/* 底图慢慢显影；文字像墨迹在纸上洇开 */
.board .plate.is-in { animation: rv-plate 1.6s var(--rv-ease) backwards; }
.board .at.is-in { animation: rv-ink 0.9s var(--rv-ease) var(--d, 0s) backwards; }
.wld-head.is-in { animation: rv-ink 0.9s var(--rv-ease) var(--d, 0s) backwards; }
.wld-stage.is-in { animation: rv-rise 1s var(--rv-ease) var(--d, 0s) backwards; }
/* 纸张、本子、软木板这类实物：带一点角度落到桌面上 */
.board :is(.chat-sheet, .moment, .book, .cork, .model-strip, .wall-note, .gift-deco, .stamp-add).is-in { animation-name: rv-place; animation-duration: 1s; }
.board .moment { --rv-tilt: 2deg; }
.board .dl.is-in { animation-name: rv-rise; }
.board .food-strip.is-in { animation-name: rv-slide; animation-duration: 1s; --rv-from: -48px; }
.board .calendar.is-in { animation-name: rv-drop; animation-duration: 0.9s; animation-timing-function: var(--rv-spring); --rv-spin: 6deg; }
.board .hang-tag.is-in { animation-name: rv-swing; animation-duration: 1.4s; animation-timing-function: ease-out; }
/* 只当容器、本身不出场的几组：交给里面的实物逐个出场 */
.board :is(.gift-shelf, .stamps, .faq-cards).is-in { animation: none; }

/* 手绘笔触在文字出现后再描出来 */
.board .stroke.at.is-in { animation: rv-draw 1.1s ease-in-out var(--d, 0s) backwards; }
.board .is-in .stroke,
.board .is-in .pen-under::after,
.board .is-in .pen-link::after { animation: rv-draw 0.9s ease-in-out calc(var(--d, 0s) + 0.45s) backwards; }
.board .is-in .model-divider { animation-name: rv-draw-y; }

/* 照片、便签、朋友圈卡片带着角度钉上去，相邻两张朝相反方向转；胶带随后贴上 */
.wall-pol, .note, .feed, .stamp { --rv-spin: -5deg; }
:is(.wall-pol, .note, .feed, .stamp):nth-child(even) { --rv-spin: 5deg; }
.wall-pol.is-in, .note.is-in { animation: rv-drop 0.85s var(--rv-spring) var(--d, 0s) backwards; }
.wall-pol.is-in .tape, .book.is-in .tape { animation: rv-stick 0.5s var(--rv-spring) calc(var(--d, 0s) + 0.5s) backwards; }
.cork.is-in .feed { animation: rv-drop 0.8s var(--rv-spring) calc(var(--d, 0s) + 0.35s + var(--i, 0) * 0.1s) backwards; }

/* 礼物架：木板先落位，三件礼物依次从架上弹起 */
.gift-shelf.is-in .shelf-board { animation: rv-place 0.9s var(--rv-ease) var(--d, 0s) backwards; }
.gift-shelf.is-in .gift { animation: rv-pop 0.8s var(--rv-spring) calc(var(--d, 0s) + 0.25s + var(--i, 0) * 0.12s) backwards; }
/* 邮票像盖章一样压下来，邮戳随后补盖 */
.stamps.is-in .stamp { animation: rv-press 0.7s var(--rv-spring) calc(var(--d, 0s) + var(--i, 0) * 0.08s) backwards; }
.stamps.is-in .stamp-postmark { animation: rv-postmark 0.45s ease-out calc(var(--d, 0s) + 0.4s + var(--i, 0) * 0.08s) backwards; }
/* 问题卡从信箱里一张张抽出来 */
.faq-cards.is-in .faq-card { animation: rv-slide 0.8s var(--rv-ease) calc(var(--d, 0s) + var(--i, 0) * 0.08s) backwards; }
.model-strip.is-in .model-tags li { animation: rv-pop 0.6s var(--rv-spring) calc(var(--d, 0s) + 0.4s + var(--i, 0) * 0.06s) backwards; }

/* 信封整组升起，落定后火漆印晃一下，提示可以拆 */
.board-letter.is-env-in :is(.env-back, .env-front, .env-box, .letter-slot) { animation: rv-rise 1s var(--rv-ease) backwards; }
.board-letter.is-env-in .seal-out .seal { animation: rv-wiggle 0.8s ease-in-out 1.3s; }

/* ══ 页脚 ══════════════════════════════════════════════════ */
.foot { position: relative; z-index: 1; margin-top: calc(var(--foot-lap, 16px) * -1); padding: 46px 0 34px; background: url("img/foot-strip.webp") center top / 100% 100% no-repeat; }
.foot-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; }
.foot-links { display: flex; flex-wrap: wrap; gap: 6px 22px; font-size: 13px; color: var(--ink-soft); }
.foot-links a:hover { color: var(--rose); }
.foot-copy { width: 100%; font-size: 12px; color: var(--ink-soft); }

/* ══ 响应式 ════════════════════════════════════════════════ */
@media (max-width: 1100px) {
  .nav-links { gap: 14px; font-size: 13px; letter-spacing: 0.02em; }
  .nav .paint-btn-sm { padding: 0 20px; }
}
/* 900–1000px 之间装不下 10 项：先收起「公告」（页脚仍有），900px 以下整排收起，与改版前一致 */
@media (max-width: 1000px) {
  .nav-links .nav-links-extra { display: none; }
}

/* 900px 以下：画板拆成纵向流式排版，素材保留，坐标与 cqw 字号全部改为常规尺寸 */
@media (max-width: 900px) {
  .nav { height: 64px; padding: 0 18px 6px; }
  .nav-links { display: none; }

  .hero { min-height: auto; padding-bottom: 40px; }
  .hero-copy { padding: 96px 22px 0; max-width: none; }
  .hero-slogan { white-space: normal; font-size: 24px; }
  .hero-fade { background: linear-gradient(180deg, rgba(250, 240, 228, 0.62), rgba(250, 240, 228, 0.25) 46%, transparent 62%, rgba(243, 237, 226, 0.8) 92%, var(--paper)); }
  .hero.is-night .hero-fade { background: linear-gradient(180deg, rgba(14, 18, 40, 0.55), transparent 55%, rgba(243, 237, 226, 0.6) 92%, var(--paper)); }
  .scene-layer { --pos-x: 78%; }
  .hero-actions { gap: 26px; margin-top: 26px; }
  .window-note { position: relative; inset: auto; height: auto; padding: 36px 22px 0; --u: 12px; }
  .window-note .stroke { display: none; }
  .peek { position: relative; left: auto; top: auto; width: 200px; transform: rotate(4deg); margin-left: auto; margin-right: 10%; }
  .peek figcaption { font-size: 16px; }
  .peek figcaption b { font-size: 17px; }
  @keyframes settle { from { opacity: 0; transform: translateY(16px) rotate(8deg); } to { opacity: 1; transform: rotate(4deg); } }
  .timebar { position: relative; left: auto; bottom: auto; margin: 28px 16px 0; width: auto; aspect-ratio: auto; height: 96px; padding: 14px 4% 2px 9%; }
  .time-stop:not(.is-live) span { display: none; }
  .time-stop[aria-pressed="true"] b::after {
    content: ""; position: absolute; left: 10%; right: 10%; bottom: 10px; height: 6px; background-color: var(--rose);
    -webkit-mask: url("img/stroke-under.webp") center / 100% 100% no-repeat; mask: url("img/stroke-under.webp") center / 100% 100% no-repeat;
  }

  .board-sec { padding: 56px 0; }
  .board { aspect-ratio: auto; container-type: normal; width: calc(100% - 40px); display: flex; flex-direction: column; }
  .board > .at { position: relative; left: auto; top: auto; right: auto; width: auto; height: auto; }
  /* 底图出血铺满屏宽，需解除全局 img 的 max-width，否则右侧留一道竖边；窄条底图只做上下淡出 */
  .plate { position: relative; order: 99; inset: auto; width: calc(100% + 40px); max-width: none; height: auto; aspect-ratio: 2 / 1; margin: 28px -20px 0; object-position: center bottom;
    --fade-t: 0.4; --fade-b: 0.3; --fade-x: 0; }
  /* 窄屏各章纵向排开，朋友们与 06 不再首尾相接，恢复普通间距与上下淡出 */
  #friends { padding: 44px 0 8px; margin-top: 0; }
  #world { padding: 12px 0 8px; margin-top: 0; }
  #download { padding-bottom: 0; }
  #download .plate { --fade-b: 0; }
  .board .chap { gap: 14px; }
  .board .chap-no { font-size: 46px; }
  .board .chap-en { font-size: 18px; }
  .board .chap-title, .board-chat .at-title { font-size: 27px; line-height: 1.4; white-space: normal; margin-top: 14px; }
  .board .chap-sub { font-size: 15px; margin-top: 12px; }
  .board .note-fine { font-size: 12px; }

  .board-chat .stroke-rule { height: 6px; }
  .board-chat .at-modes { width: auto; margin-top: 14px; font-size: 13px; line-height: 2; }
  .board > .chat-sheet { height: 560px; margin-top: 30px; padding: 56px 26px 30px; }
  .chat-head { gap: 12px; padding-bottom: 12px; }
  .chat-head img { width: 48px; height: 48px; }
  .chat-name { font-size: 17px; }
  .chat-state { font-size: 12px; gap: 6px; }
  .chat-state i { width: 7px; height: 7px; }
  .chat-demo-tag { font-size: 15px; }
  .chat-body { gap: 12px; }
  .msg { font-size: 15px; padding: 11px 18px 15px; }
  .msg-typing { gap: 5px; padding: 14px 18px 18px; }
  .msg-typing i { width: 6px; height: 6px; }
  .chat-chips { gap: 8px 22px; padding-top: 14px; min-height: 52px; }
  .chip, .msg-end { font-size: 16px; }
  .chip::after { height: 6px; }

  .gift-shelf { width: 100%; aspect-ratio: 470 / 300; margin-top: 30px; }
  .gift-tag { top: calc(100% + 24px); font-size: 11px; }
  .gift-book .gift-tag { top: calc(100% + 6px); }
  .gift-tag b { font-size: 14px; }
  .shelf-hint { width: auto; margin-top: 44px; font-size: 18px; }
  .shelf-hint .stroke { height: 12px; width: 70%; margin: 4px auto 0; }
  .board > .calendar { align-self: flex-end; width: 112px; height: 178px; padding-top: 34px; margin: 36px 10px -70px 0; z-index: 2; }
  .calendar-top { font-size: 13px; }
  .calendar-day { font-size: 52px; }
  .calendar-week { font-size: 11px; }
  .board > .moment { height: 560px; padding: 64px 28px 30px; }
  .moment-head { gap: 10px; }
  .moment-head img { width: 40px; height: 40px; }
  .moment-text, .moment-photo, .moment-likes { margin-top: 10px; }
  .moment-jump { margin-top: 12px; font-size: 16px; }
  #inside { scroll-margin-top: 80px; }
  .moment-empty { font-size: 20px; }
  .gift-deco { display: none; }
  .board-gift .at-fine { margin-top: 12px; }

  .book { width: auto; height: auto; margin-top: 30px; }
  .book-tabs { position: relative; left: auto; right: auto; height: 40px; gap: 4px; overflow-x: auto; scrollbar-width: none; padding: 0 6px; }
  .book-tab { height: 100%; min-width: 76px; font-size: 15px; padding: 7px 12px 0; transform: translateY(8px); }
  .book-tab:hover { transform: translateY(4px); }
  .book-tab[aria-selected="true"] { min-width: 86px; transform: none; }
  .book-spread { position: relative; top: auto; padding: 36px 26px 34px; background-image: url("img/letter-paper.webp"); }
  .book-left, .book-right { position: relative; left: auto; top: auto; width: auto; height: auto; }
  .book-idx { font-size: 54px; }
  .book-idx::after { width: 50px; height: 6px; margin-top: 6px; }
  .book-title { font-size: 24px; margin-top: 12px; }
  .book-text { font-size: 18px; margin-top: 12px; }
  .book-left .note-fine { margin-top: 14px; }
  .book-right { margin-top: 26px; aspect-ratio: 4 / 5; }
  .book-shot .tape { width: 80px; height: 24px; top: 0; }
  .book-shot .tape-tail { top: auto; bottom: -10px; right: -16px; }

  .board-friends .at-hint { margin-top: 10px; font-size: 16px; }
  .stamps { width: auto; height: auto; margin: 26px -20px 0; padding: 14px 20px 8px; gap: 18px; scroll-padding-inline: 20px; }
  .stamps.can-prev { --fade-l: 28px; }
  .stamps.can-next { --fade-r: 28px; }
  .board > .stamp-pager { right: auto; justify-content: flex-end; gap: 10px; margin-top: 18px; }
  .stamp-count { margin-right: 4px; font-size: 13px; }
  .stamp-nav { width: 36px; }
  .stamp { flex-basis: 132px; height: auto; min-height: calc(132px / var(--stamp-ar) + 64px); }
  .stamp-meta { top: calc(132px / var(--stamp-ar, 0.72) + 12px); }
  .stamp-name { font-size: 15px; }
  .stamp-role, .stamp-postmark, .stamp-quote { font-size: 11px; }
  .board > .stamp-add { width: 132px; margin-top: 10px; }
  .board > .stamps { margin: 18px -20px 0; }
  .stamp-add-label { margin-top: 10px; font-size: 13px; }
  .pin-note { display: none; }

  .board-notes .at-chap { justify-content: center; }
  .board-notes .at-title { text-align: center; }
  .board-notes .at-flourish { width: 120px; height: 12px; margin: 10px auto 0; }
  .notes { width: auto; height: auto; margin-top: 30px; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; gap: 24px 16px; }
  .note { padding: 34px 20px 20px; min-height: 220px; }
  .note-text { font-size: 14px; }
  .note-who { font-size: 12px; gap: 8px; margin-top: 10px; }
  .board-notes .at-more { margin-top: 30px; }
  /* 窄屏画板改成纵向排列，右上角没有空位：徽章居中，放在花饰和便签之间 */
  .board-notes .watcha-badge { align-self: center; width: min(300px, 86%); margin: 22px auto 0; transform: rotate(-1deg); }

  .wall-coach, .wall-cue, .wall-paw { display: none; }
  .board-wall .at-hint { width: auto; margin-top: 14px; font-size: 18px; text-align: left; transform: rotate(-3deg); }
  .board-wall .at-hint br { display: none; }
  .board-wall .at-hint .stroke { width: 200px; height: 8px; margin: 2px 0 0; }
  .board > .wall { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px 16px; margin-top: 34px; pointer-events: auto; }
  .wall-pol { position: relative; left: auto; top: auto; width: auto; }
  .wall-pol figcaption { font-size: 14px; }
  .wall-pol .tape { height: 22px; }
  .board > .wall-note { margin-top: 30px; padding: 26px 24px 22px 30px; }
  .board > .wall-note { width: auto; min-width: 0; }
  .wall-note .hand { font-size: clamp(14px, 4.4vw, 17px); }
  .wall-note .stroke { height: 7px; margin-top: 6px; }
  .board > .food-strip { margin-top: 26px; }
  .board .model-divider { display: none; }

  .board-world .at-title { font-size: 27px; }
  .board-world .at-link { margin-top: 18px; font-size: 16px; }
  .board > .cork { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 14px; margin-top: 30px; padding: 26px 22px; }
  .feed { position: relative; left: auto; top: auto; width: auto; padding: 24px 12px 12px; }
  .feed-head { font-size: 11px; gap: 6px; }
  .feed-head img { width: 20px; height: 20px; }
  .feed-photo { margin-top: 6px; }
  .board > .hang-tag { display: none; }
  .board > .model-strip { flex-direction: column; align-items: flex-start; gap: 16px; margin-top: 30px; padding: 30px 26px 32px; }
  .model-title { font-size: 17px; white-space: normal; }
  .model-copy p { font-size: 13px; white-space: normal; margin-top: 6px; }
  .model-tags { gap: 10px; }
  .model-tags li { padding: 5px 11px; font-size: 14px; }

  .board-faq .at-title { font-size: 27px; }
  .board > .faq-cards { gap: 10px; margin-top: 26px; --fq-bw: 12px; }
  .faq-card summary { gap: 10px; padding: 8px 4px 8px 8px; font-size: 15px; }
  .faq-rose { width: 22px; }
  .faq-card p { padding: 2px 4% 10px 8px; font-size: 14px; }
}
@media (max-width: 560px) {
  .wrap { width: calc(100% - 40px); }
  .wordmark-hero { width: min(300px, 80vw); }
  .hero .paint-btn { height: 50px; padding: 0 34px; font-size: 17px; }
  .chat-sheet { height: 520px; padding: 50px 20px 26px; }
  .notes { grid-template-columns: 1fr; }
  .note { min-height: 0; }
}

@media (max-width: 900px) {
  .wld { padding: 48px 0 64px; }
  .wld-sheet, .wld-pin { width: calc(100% - 32px); }
  .wld-scrolly { margin-top: 22px; }
  .wld-en { font-size: 20px; }
  .wld-title { font-size: 28px; white-space: normal; }
  .wld-sub { font-size: 15px; }
  .wld-book { display: flex; flex-direction: column; align-items: stretch; width: 100%; }
  .wld-tabs {
    grid-column: auto; grid-row: auto; align-self: auto;
    flex-direction: row; align-items: flex-end; justify-content: flex-start; gap: 6px;
    /* 只压进纸页 6px。再深的话未选中书签只剩一条，文案会埋进装订页，对不齐手账书签。 */
    margin: 0 0 -6px 8px; padding: 0 4px;
    overflow-x: auto; scrollbar-width: none;
  }
  .wld-tabs::-webkit-scrollbar { display: none; }
  .wld-tab,
  .wld-tab:hover {
    container-type: normal; flex: none; width: auto; min-width: 76px; height: 40px; padding: 7px 12px 0;
    writing-mode: horizontal-tb; white-space: nowrap; font-size: 15px; letter-spacing: 0.06em;
    background: var(--tab) center / 100% 100% no-repeat;
    transform: translateY(8px); filter: drop-shadow(0 2px 2px rgba(60, 40, 25, 0.12));
  }
  .wld-tab::before { content: none; }
  .wld-tab.is-on,
  .wld-tab.is-on:hover { min-width: 86px; transform: translateY(-2px); }
  .wld-leaf { background: none; padding: 0; height: auto; }
  .wld-ring { position: absolute; inset: 0; height: 100%; }
  .wld-inner { position: relative; inset: auto; padding: 28px 20px 24px clamp(44px, 8vw, 72px); gap: 12px; }
  .wld-photo, .wld-page { width: 100%; }
  .wld-photo { flex: none; container-type: normal; }
  .wld-photo-tools { width: 100%; }
  .wld-frame { container-type: normal; height: auto; flex: none; align-items: stretch; }
  .wld-polaroid { width: calc(100% - 24px); margin: 12px auto; max-height: none; height: auto; aspect-ratio: 1600 / 1118; }
  .wld-shots { width: 100%; max-height: none; height: auto; aspect-ratio: 1600 / 1118; }
  .wld-idx { font-size: 44px; }
  .wld-cap h3 { font-size: 22px; }
  .wld-cap p, .wld-look { font-size: 17px; }
  .wld-look { transform: rotate(-1deg); }
  .wld-polaroid .tape { height: 20px; width: 28%; }
  .wld-polaroid .tape-tail { width: 56px; height: 22px; }
  .wld-lb-scroll { padding: 60px 12px 64px; }
  .wld-lb-nav { top: auto; bottom: 12px; margin-top: 0; width: 42px; height: 42px; }
  .wld-lb-prev { left: 12px; }
  .wld-lb-next { right: 12px; }
}

/* ══ 手机端细节 ═══════════════════════════════════════════════
 * 上面 900px 以下的块负责把画板拆成纵向流式排版；这一段只补手机上的使用问题：
 * 导航入口、标题断行、触控尺寸、礼物说明重叠、评价横滑、下载按钮按手机访客的去向排序。 */
.nav-toggle { display: none; }
.hint-touch { display: none; }
/* 信封舞台：桌面端不生成盒子（封盖、信纸、提示、下载按钮仍以画板为坐标系）；手机端见下方「下载」段 */
.env-stage { display: contents; }
/* 触屏设备没有鼠标，照片墙拖不动：提示换成不依赖拖动的说法（桌面宽度的触屏平板同样适用） */
@media (pointer: coarse) {
  .board-wall .hint-drag { display: none; }
  .board-wall .hint-touch { display: inline; }
}
/* 首屏第二个按钮：手机（窄屏触屏）显示「下载安卓版」，其余显示「下载到桌面」；iOS 由脚本隐藏 */
.hero-dl .dl-phone { display: none; }
.hero-dl[hidden] { display: none; }
@media (max-width: 900px) and (pointer: coarse) {
  .hero-dl .dl-desk { display: none; }
  .hero-dl .dl-phone { display: inline; }
}

@media (max-width: 900px) {
  /* 导航：整排链接收进纸条菜单，按钮在页顶右侧 */
  .nav { gap: 10px; }
  .nav .paint-btn-sm { margin-left: auto; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 44px; height: 44px; margin-right: -8px; border-radius: 50%; color: var(--ink);
    transition: background 0.2s, color 0.2s;
  }
  .nav-toggle:active, .nav.is-open .nav-toggle { background: rgba(168, 71, 90, 0.1); color: var(--rose-deep); }
  .nav-toggle-close, .nav.is-open .nav-toggle-open { display: none; }
  .nav.is-open .nav-toggle-close { display: block; }
  .nav-links {
    position: absolute; left: 12px; right: 12px; top: 100%; margin-top: -2px;
    flex-direction: column; align-items: stretch; gap: 0; padding: 6px 8px 10px;
    max-height: calc(100svh - 80px); overflow-y: auto; overscroll-behavior: contain;
    white-space: normal; font-size: 16px; letter-spacing: 0.06em;
    background: var(--card) url("img/paper.webp") 0 0 / 640px repeat;
    border-radius: 4px 4px 16px 16px; box-shadow: inset 0 0 0 1px var(--line);
  }
  .nav.is-open .nav-links { display: flex; animation: nav-drop 0.22s ease-out; }
  .nav-links .nav-links-extra { display: block; }
  .nav-links li + li { border-top: 1px dashed var(--line); }
  .nav-links a { display: flex; align-items: center; min-height: 48px; padding: 0 12px; border-radius: 8px; }
  .nav-links a::after { display: none; }
  .nav-links a:active { background: rgba(168, 71, 90, 0.08); }
  .nav-links a.nav-fanart-link { display: flex; gap: 10px; padding: 0 12px; border-radius: 8px; background: none; box-shadow: none; }
  .nav-links a.nav-fanart-link:hover { transform: none; background: none; box-shadow: none; }
  .nav-fanart-avatar { width: 28px; height: 28px; }
  @keyframes nav-drop { from { opacity: 0; transform: translateY(-6px); } }
  .board-sec, .wld { scroll-margin-top: 16px; }

  /* 标题与正文断行：平衡每行字数，避免末行只剩一个字 */
  .hero-slogan, .board .chap-title, .letter-title, .wld-title, .model-title { text-wrap: balance; word-break: keep-all; }
  /* inline-block 会让逗号被挤到下一行行首，窄屏改回行内元素，下划线仍相对它定位 */
  .board .chap-title .pen-under { display: inline; }
  .board .chap-title .pen-under::after { bottom: -0.1em; }

  /* 朋友邮票：新朋友入口不再是落单在第二行的一枚空白邮票，改成一条通栏的手写入口 */
  .board > .stamp-add { width: auto; margin-top: 4px; align-self: stretch; }
  .board > .stamp-add .stamp-add-card { display: none; }
  .board > .stamp-add .stamp-add-label {
    display: flex; align-items: center; justify-content: center; min-height: 48px; margin: 0; padding: 0 16px;
    font-size: 16px; color: var(--rose); border: 1.5px dashed rgba(168, 71, 90, 0.55); border-radius: 14px;
  }

  /* 世界展示册：左右边距与其他章节统一为 20px；说明文字只保留当前页，避免按最长一条预留出一片空白 */
  .wld-sheet, .wld-pin { width: calc(100% - 40px); }
  .wld-cap:not(.is-on) { display: none; }
  .hero-sub, .chap-sub, .book-text, .wld-sub, .moment-text { text-wrap: pretty; }

  /* 首屏：窄屏上两个按钮不折行；夜里字压在窗光上，补一层暗影保证可读 */
  .hero-actions { flex-wrap: wrap; gap: 14px 24px; }  .hero .paint-btn, .hero .pen-link { white-space: nowrap; }
  .hero.is-night .hero-slogan, .hero.is-night .hero-sub, .hero.is-night .hero-dateline { text-shadow: 0 1px 10px rgba(8, 12, 34, 0.65); }

  /* 01：功能清单整词折行，用小圆点分隔；示例问句放大点按区域 */
  .board-chat .at-modes { display: flex; flex-wrap: wrap; gap: 6px 20px; }
  .modes span { display: inline-flex; align-items: center; white-space: nowrap; }
  .modes span:not(:last-child)::after { content: none; }
  .modes span::before { content: ""; width: 5px; height: 5px; margin-right: 7px; border-radius: 50%; background: var(--rose); }
  .board > .chat-sheet { height: 480px; }
  .chip { display: inline-flex; align-items: center; min-height: 44px; padding: 6px 4px 14px; }
  .chip::after { bottom: 8px; }

  /* 02：三件礼物的说明各占一栏，换行显示，不再互相压住；日历文字留在纸面上半部分 */
  /* 架子下只留物件名，一句话说明已在上方副标题里；三列说明挤不下，硬排会互相压住 */
  .board-gift .gift .gift-tag { width: auto; white-space: nowrap; font-size: 0; line-height: 1.4; }
  .board-gift .gift .gift-tag b { font-size: 15px; }
  .board-gift .gift-book .gift-tag { left: calc(50% - 8px); transform: translateX(-50%); display: block; }
  .board-gift .gift-book .gift-line { display: none; }
  .board > .calendar { height: 190px; padding-top: 30px; }
  .calendar-top { font-size: 12px; }
  .calendar-day { font-size: 44px; }
  .calendar-week { margin-top: 2px; font-size: 10px; letter-spacing: 0.04em; }
  /* 「挑一件」提示与小日历同排：提示占左侧剩余宽度，日历缩成一枚便签大小贴在右边；其余子项仍各占一行（底图除外） */
  .board-gift { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .board-gift > :not(.shelf-hint):not(.calendar):not(.plate) { flex: 0 0 100%; min-width: 0; }
  .board-gift > .shelf-hint { flex: 1 1 160px; min-width: 0; margin-top: 28px; font-size: 17px; line-height: 1.45; text-wrap: balance; }
  .board-gift > .shelf-hint .stroke { width: 80%; height: 10px; }
  .board > .calendar.calendar { flex: 0 0 70px; align-self: center; width: 70px; height: 112px; padding-top: 19px; margin: 28px 4px 0 12px; }
  .board-gift .calendar-top { font-size: 10px; letter-spacing: 0.12em; }
  .board-gift .calendar-day { font-size: 28px; }
  .board-gift .calendar-week { margin-top: 1px; font-size: 8px; letter-spacing: 0; white-space: nowrap; }

  /* 03：触屏上没有拖动，提示换文案 */
  .board-wall .hint-drag { display: none; }
  .board-wall .hint-touch { display: inline; }

  /* 评价：八张便签改成横向滑动，不再竖排一长串 */
  .board > .notes {
    display: flex; grid-template-columns: none; gap: 18px; width: auto; height: auto;
    margin: 26px -20px 0; padding: 14px 20px 26px;
    overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 20px;
    overscroll-behavior-x: contain; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .board > .notes::-webkit-scrollbar { display: none; }
  .board > .notes > .note { flex: 0 0 min(78%, 300px); min-height: 250px; scroll-snap-align: center; }
  .board-notes .at-more { margin-top: 8px; }

  /* 底图：不再作为一条独立的色带摆在章节下面，改为垫在最后一块内容的下沿之后（内容压在底图上），
   * 章节之间只剩一份留白。flex 的 order 会改变绘制顺序，所以显式给底图 z-index 0、内容 1。 */
  .board > .plate { z-index: 0; margin: -96px -20px 0; --fade-t: 0.5; --fade-b: 0.36; }
  .board > :not(.plate) { position: relative; z-index: 1; }
  .board-sec { padding: 44px 0 0; }
  .board-sec:has(> .board > .plate) { padding-bottom: 8px; }

  /* 下载：信封沿用桌面端同一套封盖、信纸与火漆印动画，整体放大到信封与内容区等宽，点信封、火漆印或提示拆开。
   * 舞台宽度 = 画板宽 ÷ 0.48（信封在桌面画板里占 48%），左右各溢出的部分由 #download 裁掉；
   * 底图跟着舞台同尺寸同位置，信封与晚霞的相对位置和桌面端一致，只露出中间一段，不再单独摆在下面。 */
  #download { overflow-x: clip; padding: 24px 0 0; }
  .board-letter > .plate { order: 0; position: absolute; top: 0; left: 50%; translate: -50% 0; width: 208.4%; height: auto; aspect-ratio: 3 / 2; margin: 0; --fade-t: 0.14; --fade-b: 0; }
  .env-stage { display: block; position: relative; z-index: 1; order: 1; width: 208.4%; margin-left: -54.2%; aspect-ratio: 3 / 2; container-type: inline-size; }
  .board-letter .letter-hint { top: 4.5%; font-size: max(15px, 2.6cqw); }
  .letter-hint .stroke { height: 9px; }
  /* 信封体的阴影只留在下方：桌面端画板很宽，两侧的阴影不显眼；手机上信封与屏宽几乎等宽，侧边阴影会在折痕处切出一条横带 */
  .env-back { clip-path: inset(40.5% 0 -80px 0); }
  /* 信纸上移一截，口袋口以上能完整露出附言 */
  .letter { top: 21%; padding: 2.4cqw 3.6cqw; }
  /* 信纸字号跟着舞台等比缩放（729px 宽的舞台上约等于 13/14/15/11px），320 宽的小屏也排得下 */
  .letter-greet { font-size: max(10px, 1.78cqw); }
  .letter-body { font-size: max(11px, 1.92cqw); line-height: 1.6; }
  .letter-sign { font-size: max(12px, 2.06cqw); }
  .letter-ps { font-size: max(9px, 1.5cqw); }
  /* 下载按钮压在信封前片上，随舞台等比缩放；四个按钮同一款墨框、没有重点色块，手机上不放网页版（首屏已有入口）。
   * 整组在火漆印与封盖尖以下：上排 Android 与 Windows 收窄并靠近中线，让出左右两条折痕线；下排两个 macOS 用满整组宽度。
   * 合上与拆开位置不变，信纸只露到口袋口，不会盖住按钮。 */
  .board-letter .dl { left: 28%; top: 75%; width: 44%; transform: none; transition: none; display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; gap: 0.9cqw; }
  .dl-row { display: contents; }
  .board-letter .dl-btn { height: max(28px, 4.1cqw); min-height: 0; min-width: 0; padding: 0 3px; font-size: max(9.5px, 1.45cqw); letter-spacing: 0; white-space: normal; text-align: center; line-height: 1.15; color: var(--ink); }
  .board-letter .dl-ico, .board-letter .dl-web { display: none; }
  .board-letter .dl-main::before { background: none; background-color: rgba(42, 35, 32, 0.85); -webkit-mask: url("img/ink-frame.webp") center / 100% 100% no-repeat; mask: url("img/ink-frame.webp") center / 100% 100% no-repeat; }
  .board-letter .dl-android { order: 1; justify-self: end; }
  #btn-download-win { order: 2; justify-self: start; }
  .board-letter .dl-android, #btn-download-win { width: 70%; }
  .board-letter .dl-main { order: 3; }
  #btn-download-x64 { order: 4; }
  /* 底图下沿不再留一条纸色缝：不淡出，页脚的橙色撕边横栏上移盖住底图下缘，与桌面端做法一致；
   * 手机上页脚去掉大字标识、收短高度，只留链接与版权 */
  .board-letter { padding-bottom: 0; }
  .foot { --foot-lap: 54px; padding: 38px 0 22px; }
  .foot-inner { gap: 10px; }
  .wordmark-foot { display: none; }

  /* 触控尺寸与页脚 */
  .stamp-nav { width: 44px; height: 44px; }
  .foot-links { gap: 0 22px; }
  .foot-links a { display: inline-block; padding: 9px 0; }
}
/* 320–360 宽的小屏：首屏按钮收紧，避免「体验网页版」折成两行 */
@media (max-width: 360px) {
  .hero .paint-btn { padding: 0 24px; font-size: 16px; }
  .hero-actions { gap: 12px 18px; }
  .board .chap-no { font-size: 40px; }
  .board .chap-title, .board-chat .at-title { font-size: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; }
  .hero-scene { transform: none !important; }
}
