/* =====================================================================
   遗忘引擎 · The Forgetting Engine  ——  Visual Upgrade
   主调:深空 #08080c,文字暖白 #ece6d8。
   多层视差:银河 → 星云 → 雾 → 极光 → 月光 → 暖晕 → 粒子 → bokeh → 暗角 → 颗粒
   华丽而克制:像在深夜凝视一段正在风化的记忆。
   ===================================================================== */

:root {
  --bg: #08080c;
  --bg-deep: #050507;
  --ink: #ece6d8;
  --ink-dim: #b3ad9f;
  --ink-faint: rgba(236, 230, 216, 0.32);
  --line: rgba(236, 230, 216, 0.22);

  /* 暖琥珀(烛火 / 暮色) */
  --amber: #ffb677;
  --amber-deep: #ff9a56;
  /* 微量点缀 */
  --aura-cyan: rgba(125, 240, 210, 0.5);
  --aura-violet: rgba(184, 138, 255, 0.45);

  /* 字体:默认英文衬线,html[lang="zh"] 切换为中文手写体 */
  --font-en: 'Cormorant Garamond', 'EB Garamond', Georgia, 'Times New Roman', serif;
  --font-zh: 'LXGW WenKai', 'Songti SC', 'Noto Serif SC', 'Source Han Serif SC',
    'PingFang SC', serif;
  --font: var(--font-en);

  --max-w: 600px;
  --font-size: 22px;
  --line-height: 2.05;

  /* 当前阶段视觉变量(由 JS 切换) */
  --ls: 0.02em;
  --blur: 0px;
  --op: 1;
  --ws: normal;
  --fs-scale: 1;
  --lh: 2.05;

  /* 视差量(ambient.ts 实时写入) */
  --px: 0;
  --py: 0;
}

/* 切换到中文:换字体内核,行距与字号微调 */
html[lang='zh'] {
  --font: var(--font-zh);
  --font-size: 20px;
  --line-height: 2.1;
  --lh: 2.1;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow: hidden;
  overscroll-behavior: none;
  cursor: none;
}

/* 触屏设备:恢复系统光标 */
@media (hover: none) {
  html,
  body {
    cursor: auto;
  }
  .cursor-glow {
    display: none !important;
  }
}

body {
  position: relative;
}

::selection {
  background: rgba(255, 182, 119, 0.22);
  color: var(--ink);
}

/* =====================================================================
   沉浸式背景层
   ===================================================================== */
.bg-layer {
  position: fixed;
  inset: -6%;
  pointer-events: none;
  will-change: transform;
}

/* 1. 深空底色 */
.bg-stars {
  z-index: 0;
  background: radial-gradient(ellipse at 50% 55%, #15131e 0%, #0a0910 62%, #060509 100%);
}
.bg-stars::before {
  content: '';
  position: absolute;
  inset: -8%;
  background-image: url('./assets/milkyway.jpg');
  background-size: cover;
  background-position: center;
  filter: blur(6px) brightness(0.62) saturate(0.7);
  opacity: 0.6;
  transform: translate3d(calc(var(--px) * -14px), calc(var(--py) * -14px), 0) scale(1.12);
  transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* 2. 星云紫红:极淡叠加,为冷调注入一抹暮色 */
.bg-nebula {
  z-index: 0;
  opacity: 0.42;
  mix-blend-mode: screen;
}
.bg-nebula::before {
  content: '';
  position: absolute;
  inset: -10%;
  background-image: url('./assets/nebula.jpg');
  background-size: cover;
  background-position: 60% 40%;
  filter: blur(10px) brightness(0.5) saturate(1.25) hue-rotate(-12deg);
  transform: translate3d(calc(var(--px) * -20px), calc(var(--py) * -16px), 0) scale(1.18);
  transition: transform 1s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: nebula-drift 60s ease-in-out infinite alternate;
}
@keyframes nebula-drift {
  0% {
    background-position: 58% 38%;
    opacity: 0.85;
  }
  100% {
    background-position: 64% 46%;
    opacity: 1;
  }
}

/* 3. 雾气层 */
.bg-fog {
  z-index: 1;
  background-image: url('./assets/fog.jpg');
  background-size: 145% 145%;
  background-position: 50% 50%;
  filter: blur(3px) brightness(0.78) contrast(1.05);
  opacity: 0.36;
  mix-blend-mode: screen;
  transform: translate3d(calc(var(--px) * -30px), calc(var(--py) * -30px), 0) scale(1.16);
  transition: transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: fog-drift 70s ease-in-out infinite alternate;
}
@keyframes fog-drift {
  0% {
    background-position: 46% 42%;
  }
  100% {
    background-position: 54% 58%;
  }
}

/* 4. 极光带:极低透明缓慢流动,横向漂移 */
.bg-aurora {
  z-index: 1;
  opacity: 0.3;
  mix-blend-mode: screen;
  overflow: hidden;
}
.bg-aurora::before {
  content: '';
  position: absolute;
  inset: -15% -25%;
  background-image: url('./assets/aurora.jpg');
  background-size: cover;
  background-position: center;
  filter: blur(8px) brightness(0.55) saturate(1.4) hue-rotate(-8deg);
  transform: translate3d(calc(var(--px) * -42px), calc(var(--py) * -22px), 0) scale(1.25);
  transition: transform 1.1s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: aurora-flow 38s ease-in-out infinite alternate;
}
@keyframes aurora-flow {
  0% {
    transform: translate3d(calc(var(--px) * -42px), calc(var(--py) * -22px), 0) scale(1.25)
      skewX(-3deg);
    opacity: 0.7;
  }
  100% {
    transform: translate3d(calc(var(--px) * -42px), calc(var(--py) * -22px), 0) scale(1.32)
      skewX(3deg);
    opacity: 1;
  }
}

/* 5. 月光:右上偏的暖白光源 + 月相图 */
.bg-moonlight {
  z-index: 2;
  background:
    radial-gradient(
      circle at 82% 18%,
      rgba(244, 240, 230, 0.22) 0%,
      rgba(244, 240, 230, 0.08) 14%,
      rgba(0, 0, 0, 0) 26%
    ),
    radial-gradient(
      circle at 82% 18%,
      rgba(255, 220, 170, 0.12) 0%,
      rgba(0, 0, 0, 0) 40%
    );
  transform: translate3d(calc(var(--px) * 26px), calc(var(--py) * 26px), 0);
  transition: transform 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: moon-pulse 11s ease-in-out infinite;
}
.bg-moonlight::after {
  content: '';
  position: absolute;
  top: 14%;
  right: 16%;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background: url('./assets/moon.jpg') center / cover no-repeat;
  filter: blur(0.4px) brightness(0.85) saturate(0.7);
  opacity: 0.42;
  box-shadow: 0 0 80px 30px rgba(255, 220, 170, 0.18);
}
@keyframes moon-pulse {
  0%,
  100% {
    opacity: 0.85;
  }
  50% {
    opacity: 1;
  }
}

/* 6. 中心暖光晕:烛火径向,呼吸 + 反向视差 */
.bg-glow {
  z-index: 2;
  background: radial-gradient(
    ellipse 60% 52% at 50% 48%,
    rgba(255, 196, 132, 0.14) 0%,
    rgba(255, 168, 104, 0.06) 38%,
    rgba(0, 0, 0, 0) 72%
  );
  transform: translate3d(calc(var(--px) * 22px), calc(var(--py) * 22px), 0);
  transition: transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: glow-breathe 9s ease-in-out infinite;
}
@keyframes glow-breathe {
  0%,
  100% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
}

/* 粒子尘埃 canvas */
.ambient-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 3;
}

/* 7. bokeh 光斑:多个柔焦彩色圆点,缓慢飘移 */
.bg-bokeh {
  z-index: 4;
  mix-blend-mode: screen;
  opacity: 0.55;
}
.bg-bokeh::before,
.bg-bokeh::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(28px);
}
.bg-bokeh::before {
  width: 320px;
  height: 320px;
  left: 12%;
  top: 62%;
  background: radial-gradient(circle, rgba(255, 170, 110, 0.4), rgba(0, 0, 0, 0) 70%);
  transform: translate3d(calc(var(--px) * 30px), calc(var(--py) * 30px), 0);
  transition: transform 1.2s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: bokeh-a 24s ease-in-out infinite alternate;
}
.bg-bokeh::after {
  width: 260px;
  height: 260px;
  right: 14%;
  top: 20%;
  background: radial-gradient(circle, rgba(150, 200, 255, 0.32), rgba(0, 0, 0, 0) 70%);
  transform: translate3d(calc(var(--px) * -26px), calc(var(--py) * -26px), 0);
  transition: transform 1.2s cubic-bezier(0.2, 0.8, 0.2, 1);
  animation: bokeh-b 30s ease-in-out infinite alternate;
}
@keyframes bokeh-a {
  0% {
    transform: translate3d(calc(var(--px) * 30px), calc(var(--py) * 30px), 0) scale(1);
  }
  100% {
    transform: translate3d(calc(var(--px) * 30px), calc(var(--py) * 30px), 0) scale(1.25)
      translateY(-30px);
  }
}
@keyframes bokeh-b {
  0% {
    transform: translate3d(calc(var(--px) * -26px), calc(var(--py) * -26px), 0) scale(1.1);
  }
  100% {
    transform: translate3d(calc(var(--px) * -26px), calc(var(--py) * -26px), 0) scale(0.9)
      translateY(40px);
  }
}

/* 暗角 */
.bg-vignette {
  z-index: 5;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0) 36%,
    rgba(0, 0, 0, 0.52) 80%,
    rgba(0, 0, 0, 0.9) 100%
  );
}

/* 胶片颗粒 */
.bg-noise {
  z-index: 6;
  opacity: 0.05;
  background-repeat: repeat;
  background-size: 140px 140px;
  mix-blend-mode: screen;
  animation: grain 1.8s steps(4) infinite;
}
@keyframes grain {
  0% {
    transform: translate(0, 0);
  }
  33% {
    transform: translate(-6px, 4px);
  }
  66% {
    transform: translate(5px, -7px);
  }
  100% {
    transform: translate(-3px, 6px);
  }
}

/* 文字风化粒子 canvas */
.particle-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 20;
}

/* =====================================================================
   自定义光标光晕
   ===================================================================== */
.cursor-glow {
  position: fixed;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 60;
  /* 亮白实心中心点:深色背景上极高对比度,一眼可见 */
  background: rgba(255, 244, 224, 0.96);
  mix-blend-mode: screen;
  /* 三层散射光:近暖金 → 中暖橙 → 远柔光,营造烛火般的精致光晕 */
  box-shadow:
    0 0 10px 2px rgba(255, 214, 168, 0.95),
    0 0 34px 8px rgba(255, 184, 128, 0.5),
    0 0 80px 18px rgba(255, 162, 102, 0.22);
  transition: width 0.25s ease, height 0.25s ease, margin 0.25s ease,
    box-shadow 0.3s ease, opacity 0.4s ease;
  will-change: transform;
}
.cursor-glow.on-target {
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  box-shadow:
    0 0 14px 3px rgba(255, 226, 184, 1),
    0 0 50px 12px rgba(255, 196, 140, 0.62),
    0 0 120px 28px rgba(255, 170, 110, 0.3);
}

/* =====================================================================
   四角细线装饰框
   ===================================================================== */
.frame {
  position: fixed;
  inset: 26px;
  pointer-events: none;
  z-index: 12;
}
.corner {
  position: absolute;
  width: 26px;
  height: 26px;
  border-color: rgba(236, 230, 216, 0.28);
  border-style: solid;
  border-width: 0;
  opacity: 0.7;
}
.corner.tl {
  top: 0;
  left: 0;
  border-top-width: 1px;
  border-left-width: 1px;
}
.corner.tr {
  top: 0;
  right: 0;
  border-top-width: 1px;
  border-right-width: 1px;
}
.corner.bl {
  bottom: 0;
  left: 0;
  border-bottom-width: 1px;
  border-left-width: 1px;
}
.corner.br {
  bottom: 0;
  right: 0;
  border-bottom-width: 1px;
  border-right-width: 1px;
}

/* =====================================================================
   顶部品牌
   ===================================================================== */
.brand {
  position: fixed;
  top: 34px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 13;
  display: flex;
  align-items: center;
  gap: 16px;
  opacity: 0;
  animation: brand-in 2s ease 0.6s forwards;
}
html[lang='zh'] .brand {
  letter-spacing: 0.3em;
}
@keyframes brand-in {
  to {
    opacity: 1;
  }
}
.brand-line {
  display: block;
  width: 40px;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(236, 230, 216, 0),
    rgba(236, 230, 216, 0.4),
    rgba(236, 230, 216, 0)
  );
}
.brand-mark {
  font-family: var(--font-en);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.42em;
  color: rgba(236, 230, 216, 0.6);
  text-transform: uppercase;
  white-space: nowrap;
}

/* =====================================================================
   右上控件:语言 + 音乐
   ===================================================================== */
.controls {
  position: fixed;
  top: 30px;
  right: 34px;
  z-index: 14;
  display: flex;
  align-items: center;
  gap: 14px;
  opacity: 0;
  animation: brand-in 2s ease 0.9s forwards;
}

.ctrl-btn {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(236, 230, 216, 0.2);
  color: rgba(236, 230, 216, 0.65);
  border-radius: 999px;
  cursor: none;
  font-family: var(--font-en);
  -webkit-tap-highlight-color: transparent;
  transition: color 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease,
    background 0.4s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(4px);
}
@media (hover: none) {
  .ctrl-btn {
    cursor: pointer;
  }
}

/* 语言切换 */
.lang-toggle {
  font-size: 12px;
  letter-spacing: 0.16em;
  padding: 7px 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lang-opt {
  opacity: 0.45;
  transition: opacity 0.3s ease, color 0.3s ease;
}
.lang-opt.active {
  opacity: 1;
  color: var(--amber);
}
.lang-sep {
  opacity: 0.3;
}

/* 音乐按钮 */
.music-toggle {
  width: 36px;
  height: 36px;
  padding: 0;
  overflow: hidden;
  position: relative;
}
.music-toggle .icon-music {
  width: 17px;
  height: 17px;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.music-toggle .eq-bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.music-toggle .eq-bars i {
  width: 2px;
  height: 4px;
  background: var(--amber);
  border-radius: 1px;
  transform-origin: bottom;
}
.music-toggle.is-on .icon-music {
  opacity: 0;
  transform: scale(0.6);
}
.music-toggle.is-on .eq-bars {
  opacity: 1;
}
.music-toggle.is-on .eq-bars i {
  animation: eq 0.9s ease-in-out infinite;
}
.music-toggle.is-on .eq-bars i:nth-child(1) {
  animation-delay: 0s;
}
.music-toggle.is-on .eq-bars i:nth-child(2) {
  animation-delay: 0.2s;
}
.music-toggle.is-on .eq-bars i:nth-child(3) {
  animation-delay: 0.4s;
}
.music-toggle.is-on .eq-bars i:nth-child(4) {
  animation-delay: 0.1s;
}
@keyframes eq {
  0%,
  100% {
    height: 4px;
  }
  50% {
    height: 14px;
  }
}

.ctrl-btn:hover {
  color: var(--ink);
  border-color: rgba(255, 182, 119, 0.5);
  box-shadow: 0 0 24px rgba(255, 170, 110, 0.18), inset 0 0 12px rgba(255, 170, 110, 0.06);
}

/* 主题切换按钮(循环:星河 → 雾海 → 极光) */
.theme-toggle {
  width: 36px;
  height: 36px;
  padding: 0;
}
.theme-dots {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.theme-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(236, 230, 216, 0.32);
  transition: background 0.45s ease, box-shadow 0.45s ease, transform 0.45s ease;
}
.theme-dots i.active {
  transform: scale(1.3);
}
body[data-theme='stardust'] .theme-dots i[data-theme='stardust'],
body[data-theme='mist'] .theme-dots i[data-theme='mist'],
body[data-theme='aurora'] .theme-dots i[data-theme='aurora'] {
  background: var(--amber);
  box-shadow: 0 0 8px var(--amber);
}

/* =====================================================================
   三种氛围主题 —— 契合「记忆遗忘」的三种意境
   stardust 星河(默认):深空银河 + 月光 + 暖晕,记忆如星辰散落
   mist     雾海:冷调浓雾流动,记忆如雾气消散
   aurora   极光:流动光带 + 星点,记忆如极光流转
   切换各背景层显隐/调色 + 点缀色调;粒子色调由 ambient.ts 联动
   ===================================================================== */

/* —— 雾海 Mist:冷青调,浓雾主导 —— */
body[data-theme='mist'] {
  --amber: #a8cce4;
  --amber-deep: #82b4d4;
}
body[data-theme='mist'] .bg-stars::before {
  opacity: 0.28;
  filter: blur(9px) brightness(0.38) saturate(0.35) hue-rotate(175deg);
}
body[data-theme='mist'] .bg-nebula {
  opacity: 0.08;
}
body[data-theme='mist'] .bg-fog {
  opacity: 0.72;
  filter: blur(4px) brightness(0.72) contrast(0.98) saturate(0.45) hue-rotate(160deg);
}
body[data-theme='mist'] .bg-aurora {
  opacity: 0.06;
}
body[data-theme='mist'] .bg-moonlight {
  opacity: 0.4;
  filter: hue-rotate(175deg) brightness(0.85);
}
body[data-theme='mist'] .bg-glow {
  background: radial-gradient(
    ellipse 60% 52% at 50% 48%,
    rgba(176, 210, 234, 0.16) 0%,
    rgba(148, 184, 212, 0.06) 38%,
    rgba(0, 0, 0, 0) 72%
  );
}
body[data-theme='mist'] .bg-bokeh::before {
  background: radial-gradient(circle, rgba(150, 200, 240, 0.36), rgba(0, 0, 0, 0) 70%);
}

/* —— 极光 Aurora:深绿青,流动光带主导 —— */
body[data-theme='aurora'] {
  --amber: #76e8b6;
  --amber-deep: #48c894;
}
body[data-theme='aurora'] .bg-stars::before {
  opacity: 0.5;
  filter: blur(7px) brightness(0.5) saturate(0.55);
}
body[data-theme='aurora'] .bg-nebula {
  opacity: 0.16;
}
body[data-theme='aurora'] .bg-fog {
  opacity: 0.14;
}
body[data-theme='aurora'] .bg-aurora {
  opacity: 0.66;
}
body[data-theme='aurora'] .bg-aurora::before {
  filter: blur(6px) brightness(0.72) saturate(1.55);
}
body[data-theme='aurora'] .bg-moonlight {
  opacity: 0.28;
}
body[data-theme='aurora'] .bg-glow {
  background: radial-gradient(
    ellipse 60% 52% at 50% 48%,
    rgba(120, 238, 186, 0.15) 0%,
    rgba(96, 210, 158, 0.06) 38%,
    rgba(0, 0, 0, 0) 72%
  );
}
body[data-theme='aurora'] .bg-bokeh::before {
  background: radial-gradient(circle, rgba(110, 240, 180, 0.34), rgba(0, 0, 0, 0) 70%);
}
body[data-theme='aurora'] .bg-bokeh::after {
  background: radial-gradient(circle, rgba(150, 190, 255, 0.26), rgba(0, 0, 0, 0) 70%);
}

/* =====================================================================
   主舞台
   ===================================================================== */
/* =====================================================================
   开场进场序列
   body.revealed 由 main.ts 在字体就绪后注入,触发:
   - 帷幕揭开(全屏遮罩 opacity→0)
   - 中心暖光点绽放后消散
   - 首屏输入框 / 字数 / 按钮错峰升入
   (hint 保留原有 breathe 呼吸,由帷幕遮/揭呈现,不参与 rise-in)
   ===================================================================== */
.entrance-veil {
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at center, #0b0b13 0%, #060609 65%, #000 100%);
  z-index: 100;
  pointer-events: none;
  opacity: 1;
  /* 独立于字体就绪:页面加载即揭开,避免外文字体加载慢时帷幕遮太久 */
  animation: veil-lift 1.8s cubic-bezier(0.4, 0, 0.2, 1) 0.4s forwards;
}
@keyframes veil-lift {
  to { opacity: 0; }
}

.entrance-spark {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: rgba(255, 236, 206, 1);
  box-shadow:
    0 0 18px 5px rgba(255, 206, 158, 0.85),
    0 0 54px 14px rgba(255, 176, 116, 0.42),
    0 0 120px 30px rgba(255, 156, 96, 0.16);
  z-index: 101;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  /* 与帷幕同步:加载即绽放,不依赖字体就绪 */
  animation: spark-bloom 2.4s ease-out 0.4s forwards;
}
@keyframes spark-bloom {
  0% { opacity: 0; transform: scale(0.2); }
  18% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(10); }
}

body:not(.revealed) .writing-view > .memory-input,
body:not(.revealed) .writing-view > .meta-row,
body:not(.revealed) .writing-view > .submit-btn {
  opacity: 0;
}
body.revealed .writing-view > .memory-input {
  animation: rise-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.7s both;
}
body.revealed .writing-view > .meta-row {
  animation: rise-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.9s both;
}
body.revealed .writing-view > .submit-btn {
  animation: rise-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) 1.1s both;
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(18px); filter: blur(8px); }
  to { opacity: 1; transform: translateY(0); filter: blur(0); }
}

@media (prefers-reduced-motion: reduce) {
  .entrance-veil,
  .entrance-spark { display: none; }
  body:not(.revealed) .writing-view > .memory-input,
  body:not(.revealed) .writing-view > .meta-row,
  body:not(.revealed) .writing-view > .submit-btn { opacity: 1; }
}

.app {
  position: relative;
  z-index: 10;
  width: 100%;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 28px;
  transition: opacity 1.2s ease;
}
.app.is-hidden {
  opacity: 0;
  pointer-events: none;
}

.writing-view,
.epilogue-view {
  width: 100%;
  max-width: var(--max-w);
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  animation: view-in 1.1s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.stage-view {
  position: fixed;
  inset: 0;
  display: block;
  animation: view-in 1.1s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes view-in {
  from {
    opacity: 0;
    transform: translateY(8px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* ----- IDLE 呼吸文案 ----- */
.hint {
  font-size: 19px;
  line-height: 2;
  text-align: center;
  color: var(--ink);
  letter-spacing: 0.03em;
  font-weight: 300;
  text-shadow: 0 0 28px rgba(255, 200, 140, 0.28), 0 0 72px rgba(255, 180, 120, 0.12);
  margin: 0;
}
html[lang='zh'] .hint {
  font-size: 17px;
  letter-spacing: 0.05em;
  font-weight: 400;
}

.breathe {
  animation: breathe 5.5s ease-in-out infinite;
}
@keyframes breathe {
  0%,
  100% {
    opacity: 0.45;
  }
  50% {
    opacity: 0.85;
  }
}

/* ----- textarea ----- */
.memory-input {
  width: 100%;
  min-height: 156px;
  resize: none;
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--line);
  outline: none;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--font-size);
  line-height: var(--line-height);
  letter-spacing: 0.02em;
  text-align: center;
  padding: 12px 4px 18px;
  caret-color: var(--amber);
  transition: border-image 0.4s ease, border-bottom-style 0.4s ease;
}
.memory-input::placeholder {
  color: rgba(236, 230, 216, 0.32);
  font-style: italic;
}
.memory-input:focus {
  border-bottom: 1px solid rgba(255, 182, 119, 0.5);
}

.meta-row {
  width: 100%;
  display: flex;
  justify-content: center;
  min-height: 1em;
}
.char-count {
  font-size: 11px;
  letter-spacing: 0.28em;
  color: rgba(236, 230, 216, 0.4);
  text-transform: uppercase;
  font-family: var(--font-en);
  transition: color 0.3s ease;
}
.char-count.ok {
  color: rgba(255, 182, 119, 0.8);
}
.char-count.bad {
  color: rgba(236, 230, 216, 0.32);
}

/* =====================================================================
   圆形按钮:渐变描边 + 发光 + 涟漪
   ===================================================================== */
.round-btn {
  position: relative;
  appearance: none;
  background: transparent;
  border: 1px solid rgba(236, 230, 216, 0.28);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0.2em;
  padding: 14px 34px;
  border-radius: 999px;
  cursor: none;
  opacity: 0.88;
  overflow: hidden;
  transition: opacity 0.5s ease, border-color 0.5s ease, transform 0.4s ease,
    color 0.5s ease, box-shadow 0.5s ease;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  isolation: isolate;
}
@media (hover: none) {
  .round-btn {
    cursor: pointer;
  }
}
html[lang='zh'] .round-btn {
  letter-spacing: 0.16em;
  font-weight: 400;
}

.btn-label {
  position: relative;
  z-index: 2;
}

/* 内部径向发光 */
.btn-glow {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    ellipse at center,
    rgba(255, 182, 119, 0.28),
    rgba(255, 170, 110, 0.05) 60%,
    rgba(0, 0, 0, 0) 75%
  );
  opacity: 0;
  transition: opacity 0.5s ease;
  z-index: 1;
}

.round-btn:hover:not(:disabled) {
  opacity: 1;
  color: #fff6e8;
  border-color: rgba(255, 182, 119, 0.7);
  box-shadow: 0 0 30px rgba(255, 170, 110, 0.28),
    0 0 60px rgba(255, 170, 110, 0.12),
    inset 0 0 18px rgba(255, 170, 110, 0.1);
  letter-spacing: 0.24em;
}
html[lang='zh'] .round-btn:hover:not(:disabled) {
  letter-spacing: 0.2em;
}
.round-btn:hover:not(:disabled) .btn-glow {
  opacity: 1;
}
.round-btn:active:not(:disabled) {
  transform: scale(0.97);
}
.round-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
  border-color: rgba(236, 230, 216, 0.14);
}
@media (hover: none) {
  .round-btn:disabled {
    cursor: not-allowed;
  }
}

/* 按钮描边流光(缓慢转动的渐变边) */
.submit-btn::before,
.stage-btn::before {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    120deg,
    rgba(255, 182, 119, 0) 30%,
    rgba(255, 182, 119, 0.6) 50%,
    rgba(255, 182, 119, 0) 70%
  );
  background-size: 250% 100%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.5s ease;
  animation: border-sweep 4s linear infinite;
  pointer-events: none;
  z-index: 1;
}
.submit-btn:hover:not(:disabled)::before,
.stage-btn:hover:not(:disabled)::before {
  opacity: 1;
}
@keyframes border-sweep {
  0% {
    background-position: 0% 0;
  }
  100% {
    background-position: 250% 0;
  }
}

/* =====================================================================
   中央舞台文字(几何由 main.ts 精确控制,weathering 采样其 rect)
   ===================================================================== */
.stage-text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - 56px));
  text-align: center;
  white-space: pre;
  color: var(--ink);
  font-size: calc(var(--font-size) * var(--fs-scale));
  line-height: var(--lh);
  letter-spacing: var(--ls);
  word-spacing: var(--ws);
  opacity: var(--op);
  filter: blur(var(--blur));
  text-shadow: 0 0 30px rgba(255, 200, 140, 0.32), 0 0 80px rgba(255, 180, 120, 0.16);
  margin: 0;
  transition: letter-spacing 1.2s ease, filter 1.2s ease, opacity 1.2s ease,
    word-spacing 1.2s ease, font-size 1.2s ease, line-height 1.2s ease, color 1.2s ease;
  will-change: opacity, filter, transform;
}

.stage-text[data-stage='2'] .blur-name {
  opacity: 0.55;
  transition: opacity 1.2s ease;
}
.stage-text[data-stage='3'] {
  color: var(--ink-dim);
}
.stage-text[data-stage='4'] .loose-char {
  display: inline-block;
  transform: translateY(var(--dy, 0)) rotate(var(--rot, 0deg));
  transition: transform 1.2s ease;
}
.stage-text[data-stage='5'] .fragment {
  display: inline-block;
  transform: translateY(var(--fy, 0));
  transition: transform 1.2s ease;
}

.stage-foot {
  position: absolute;
  bottom: 16vh;
  left: 0;
  right: 0;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-line {
  font-size: 12px;
  letter-spacing: 0.3em;
  font-family: var(--font-en);
  color: rgba(236, 230, 216, 0.5);
  margin: 0;
  animation: breathe 3s ease-in-out infinite;
}
html[lang='zh'] .loading-line {
  font-family: var(--font-zh);
  letter-spacing: 0.22em;
}

/* =====================================================================
   EPILOGUE
   ===================================================================== */
.epilogue-view {
  gap: 28px;
}
.epilogue-primary {
  font-size: 19px;
  line-height: 2.1;
  text-align: center;
  letter-spacing: 0.06em;
  font-weight: 300;
  color: var(--ink);
  text-shadow: 0 0 28px rgba(255, 200, 140, 0.24);
  opacity: 0;
  margin: 0;
}
html[lang='zh'] .epilogue-primary {
  font-size: 18px;
  font-weight: 400;
}
.epilogue-secondary {
  font-size: 11px;
  letter-spacing: 0.36em;
  font-family: var(--font-en);
  color: rgba(236, 230, 216, 0.5);
  opacity: 0;
  margin: 0;
  text-align: center;
  text-transform: uppercase;
}
html[lang='zh'] .epilogue-secondary {
  font-family: var(--font-zh);
  letter-spacing: 0.28em;
  text-transform: none;
}
.epilogue-primary.shown {
  animation: fade-in-slow 4s ease both;
}
.epilogue-secondary.shown {
  animation: fade-in-slow 4s ease both;
}
@keyframes fade-in-slow {
  from {
    opacity: 0;
    transform: translateY(4px);
    filter: blur(3px);
  }
  to {
    opacity: 0.88;
    transform: translateY(0);
    filter: blur(0);
  }
}

.reset-link {
  margin-top: 18px;
  font-size: 13px;
  letter-spacing: 0.24em;
  font-family: var(--font-en);
  color: rgba(236, 230, 216, 0.55);
  text-decoration: none;
  border-bottom: 1px solid rgba(236, 230, 216, 0.2);
  padding-bottom: 4px;
  cursor: none;
  transition: color 0.4s ease, border-color 0.4s ease, letter-spacing 0.4s ease,
    text-shadow 0.4s ease;
}
@media (hover: none) {
  .reset-link {
    cursor: pointer;
  }
}
html[lang='zh'] .reset-link {
  font-family: var(--font-zh);
  letter-spacing: 0.2em;
}
.reset-link:hover {
  color: var(--amber);
  border-color: rgba(255, 182, 119, 0.6);
  letter-spacing: 0.28em;
  text-shadow: 0 0 18px rgba(255, 170, 110, 0.3);
}

/* =====================================================================
   右侧进度:7 道竖向刻度(由 JS 生成 .dot,样式渲染为刻度)
   ===================================================================== */
.progress {
  position: fixed;
  top: 50%;
  right: 38px;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  z-index: 13;
  opacity: 0;
  transition: opacity 0.8s ease;
  pointer-events: none;
}
.progress::before,
.progress::after {
  content: '';
  width: 1px;
  height: 22px;
  background: linear-gradient(
    rgba(236, 230, 216, 0),
    rgba(236, 230, 216, 0.18),
    rgba(236, 230, 216, 0)
  );
}
.progress.active {
  opacity: 1;
}

.dot {
  width: 2px;
  height: 16px;
  border-radius: 1px;
  background: rgba(236, 230, 216, 0.12);
  transition: background 1.2s ease, box-shadow 1.2s ease, opacity 1.2s ease, height 1.2s ease;
}
.dot.current {
  height: 22px;
  background: linear-gradient(rgba(255, 182, 119, 0.95), rgba(255, 170, 110, 0.5));
  box-shadow: 0 0 10px rgba(255, 170, 110, 0.7), 0 0 22px rgba(255, 170, 110, 0.3);
}
.dot.passed {
  background: rgba(236, 230, 216, 0.04);
  opacity: 0.3;
}

/* =====================================================================
   底部铭文
   ===================================================================== */
.foot-mark {
  position: fixed;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 13;
  font-family: var(--font-en);
  font-size: 10px;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: rgba(236, 230, 216, 0.28);
  opacity: 0;
  animation: brand-in 2s ease 1.2s forwards;
  white-space: nowrap;
}
html[lang='zh'] .foot-mark {
  font-family: var(--font-zh);
  letter-spacing: 0.28em;
  text-transform: none;
}

/* 状态级辅助 */
.fading-out {
  opacity: 0 !important;
  transition: opacity 0.6s ease !important;
}

/* =====================================================================
   响应式
   ===================================================================== */
@media (max-width: 768px) {
  :root {
    --font-size: 18px;
  }
  html[lang='zh'] {
    --font-size: 17px;
  }
  .app {
    padding: 28px 26px;
  }
  .hint {
    font-size: 16px;
  }
  html[lang='zh'] .hint {
    font-size: 15px;
  }
  .progress {
    right: 18px;
    gap: 11px;
  }
  .progress::before,
  .progress::after {
    height: 16px;
  }
  .round-btn {
    font-size: 13px;
    padding: 12px 28px;
    letter-spacing: 0.18em;
  }
  .brand {
    top: 24px;
    gap: 10px;
  }
  .brand-line {
    width: 22px;
  }
  .brand-mark {
    font-size: 9px;
    letter-spacing: 0.32em;
  }
  .controls {
    top: 22px;
    right: 18px;
    gap: 10px;
  }
  .frame {
    inset: 16px;
  }
  .foot-mark {
    bottom: 22px;
    font-size: 9px;
    letter-spacing: 0.3em;
  }
  .bg-moonlight::after {
    width: 64px;
    height: 64px;
  }
}

@media (max-width: 380px) {
  .app {
    padding: 24px 20px;
  }
  .brand-mark {
    font-size: 8px;
  }
}

/* 减弱动效偏好 */
@media (prefers-reduced-motion: reduce) {
  .breathe,
  .noise-layer,
  .bg-fog,
  .bg-aurora,
  .bg-nebula,
  .bg-glow,
  .bg-bokeh::before,
  .bg-bokeh::after,
  .bg-moonlight,
  .brand,
  .foot-mark {
    animation: none;
  }
  * {
    transition-duration: 0.001ms !important;
  }
}

/* =====================================================================
   记忆星层 canvas(封缄记忆化作星,背景层之上、内容之下)
   ===================================================================== */
.memory-stars-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 7;
}

/* =====================================================================
   正在播放(底部曲名,播放时淡入;点击切下一首)
   ===================================================================== */
.now-playing {
  position: fixed;
  left: 34px;
  bottom: 30px;
  z-index: 14;
  font-family: var(--font-en);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(236, 230, 216, 0.45);
  opacity: 0;
  pointer-events: none;
  cursor: none;
  transition: opacity 0.8s ease, color 0.4s ease;
  white-space: nowrap;
  user-select: none;
  transform: translateZ(0);
}
.now-playing.show {
  opacity: 1;
  pointer-events: auto;
}
.now-playing.show:hover {
  color: var(--amber);
}
@media (hover: none) {
  .now-playing {
    cursor: pointer;
  }
}
html[lang='zh'] .now-playing {
  font-family: var(--font-zh);
  letter-spacing: 0.08em;
}

/* =====================================================================
   已封缄记忆面板(右侧可收起):每段放下的记忆留存于此
   ===================================================================== */
.memory-panel {
  position: fixed;
  right: 30px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 15;
  display: flex;
  align-items: flex-start;
  direction: rtl; /* 让 body 在 toggle 左侧 */
}
.memory-panel-toggle {
  appearance: none;
  background: rgba(18, 16, 24, 0.55);
  border: 1px solid rgba(236, 230, 216, 0.18);
  border-radius: 999px;
  color: rgba(236, 230, 216, 0.7);
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: none;
  backdrop-filter: blur(8px);
  position: relative;
  flex-shrink: 0;
  direction: ltr;
  transition: border-color 0.4s ease, box-shadow 0.4s ease, color 0.4s ease;
}
.memory-panel-toggle:hover {
  border-color: rgba(255, 182, 119, 0.5);
  box-shadow: 0 0 24px rgba(255, 170, 110, 0.18);
  color: var(--ink);
}
.memory-panel-toggle .mp-star {
  font-size: 14px;
  color: var(--amber);
  line-height: 1;
  text-shadow: 0 0 8px var(--amber);
}
.memory-panel-toggle .mp-count {
  position: absolute;
  bottom: -5px;
  right: -5px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 999px;
  background: rgba(255, 182, 119, 0.92);
  color: #1a1208;
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  font-family: var(--font-en);
}
.memory-panel-body {
  margin-right: 12px;
  width: 280px;
  max-height: 60vh;
  overflow-y: auto;
  background: rgba(14, 12, 20, 0.72);
  border: 1px solid rgba(236, 230, 216, 0.14);
  border-radius: 14px;
  padding: 20px 18px;
  backdrop-filter: blur(14px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
  direction: ltr;
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.memory-panel.collapsed .memory-panel-body {
  opacity: 0;
  transform: translateX(24px);
  pointer-events: none;
}
.mp-title {
  font-family: var(--font-en);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--amber);
  margin: 0 0 6px;
}
html[lang='zh'] .mp-title {
  font-family: var(--font-zh);
  letter-spacing: 0.22em;
  text-transform: none;
}
.mp-sub {
  font-size: 11px;
  line-height: 1.55;
  color: rgba(236, 230, 216, 0.42);
  margin: 0 0 16px;
  font-style: italic;
}
html[lang='zh'] .mp-sub {
  font-style: normal;
  font-family: var(--font-zh);
}
.memory-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ml-item {
  border-left: 1px solid rgba(236, 230, 216, 0.14);
  padding: 7px 0 7px 12px;
  cursor: none;
  border-radius: 0 6px 6px 0;
  transition: border-color 0.3s ease, background 0.3s ease;
}
.ml-item:hover {
  border-left-color: var(--amber);
  background: rgba(255, 170, 110, 0.05);
}
.ml-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ml-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 6px var(--amber);
  flex-shrink: 0;
}
.ml-preview {
  font-size: 12px;
  color: rgba(236, 230, 216, 0.62);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
html[lang='zh'] .ml-preview,
html[lang='zh'] .ml-full {
  font-family: var(--font-zh);
}
.ml-full {
  font-size: 12px;
  line-height: 1.65;
  color: rgba(236, 230, 216, 0.42);
  margin-top: 0;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.4s ease, opacity 0.4s ease, margin 0.4s ease;
}
.ml-item.open .ml-full {
  max-height: 240px;
  opacity: 1;
  margin-top: 7px;
}

/* 移动端:面板下移避免遮挡 */
@media (max-width: 640px) {
  .memory-panel {
    right: 14px;
    top: auto;
    bottom: 64px;
    transform: none;
  }
  .memory-panel-body {
    width: 240px;
  }
  .now-playing {
    left: 14px;
    bottom: 14px;
    font-size: 10px;
  }
}
