/* ============================================================
   Pawlo Stories · 兔佩洛 AI 互动睡前故事
   夜间月色主题 · 温暖橙色点缀
   移动端优先 (max-width: 440px 居中)
   ============================================================ */

/* ---------- 1. 设计系统 / CSS 变量 ---------- */
:root {
  --night-0: #0b0e22;
  --night-1: #161c3d;
  --night-2: #243259;
  --paper: #f3e9d0;
  --paper-deep: #e9dcba;
  --ink: #3a3126;
  --ink-soft: rgba(58, 49, 38, 0.72); /* WCAG AA: 对比度 ≥4.5:1（日间浅色背景） */
  --moon: #ffdf9e;
  --warm: #ff9a52;
  --warm-deep: #f07f33;
  --mut: rgba(234, 233, 246, 0.6);
  --mut-strong: rgba(240, 238, 250, 0.86);
  --line: rgba(255, 223, 158, 0.16);
  --done: #b9cf92;

  /* 字体 */
  --ff-sans: -apple-system, BlinkMacSystemFont, "PingFang SC",
    "Microsoft YaHei", "Helvetica Neue", sans-serif;
  --ff-serif: Georgia, "Songti SC", "Noto Serif SC", "STSong", serif;

  /* 尺寸 */
  --frame-w: 440px;
  --radius-lg: 22px;
  --radius-md: 16px;
  --radius-sm: 10px;
  --ease: cubic-bezier(0.22, 0.7, 0.3, 1);
}

/* ---------- 2. 基础重置 ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: var(--ff-sans);
  background: #05060f;
  color: var(--paper);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img {
  max-width: 100%;
  display: block;
}

button,
input {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  border: none;
  background: none;
}

button {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

::selection {
  background: var(--warm);
  color: #fff;
}

/* ---------- 3. 全局框架 .frame ---------- */
.frame {
  position: relative;
  width: 100%;
  max-width: var(--frame-w);
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  background: var(--night-0);
  box-shadow: 0 0 60px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 223, 158, 0.04);
  overflow-x: hidden;
  isolation: isolate;
}

/* ---------- 4. 关键帧动画 ---------- */
@keyframes twinkle {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.85;
  }
}

@keyframes drift {
  0% {
    transform: translate(0, 0);
    opacity: 0;
  }
  15% {
    opacity: 0.9;
  }
  50% {
    transform: translate(18px, -26px);
    opacity: 0.7;
  }
  85% {
    opacity: 0.9;
  }
  100% {
    transform: translate(-12px, -52px);
    opacity: 0;
  }
}

@keyframes breathe {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.55;
  }
  50% {
    transform: scale(1.06);
    opacity: 0.85;
  }
}

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

@keyframes fill {
  from {
    transform: translateX(-100%) scaleX(0.4);
  }
  50% {
    transform: translateX(50%) scaleX(0.6);
  }
  to {
    transform: translateX(250%) scaleX(0.4);
  }
}

@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

@keyframes bob {
  0%,
  100% {
    transform: translateY(0) rotate(0);
  }
  50% {
    transform: translateY(-5px) rotate(-3deg);
  }
}

@keyframes glowPulse {
  0%,
  100% {
    opacity: 0.45;
  }
  50% {
    opacity: 1;
  }
}

/* glowPulseShadow：用于 overflow:hidden 元素（伪元素 box-shadow 会被裁切），
   保留 box-shadow 动画但配合 will-change 优化 */
@keyframes glowPulseShadow {
  0%,
  100% {
    box-shadow: 0 0 0 2px rgba(255, 154, 82, 0.4),
      0 8px 30px rgba(255, 154, 82, 0.2);
  }
  50% {
    box-shadow: 0 0 0 2px rgba(255, 154, 82, 0.6),
      0 8px 34px rgba(255, 154, 82, 0.4);
  }
}

@keyframes stonePop {
  0% {
    transform: scale(0.2);
    opacity: 0;
  }
  60% {
    transform: scale(1.18);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes sweep {
  0% {
    transform: translateX(-120%);
  }
  100% {
    transform: translateX(220%);
  }
}

@keyframes pageTurn {
  from {
    opacity: 0;
    transform: perspective(1200px) rotateY(-7deg) translateX(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-7px);
  }
  40% {
    transform: translateX(7px);
  }
  60% {
    transform: translateX(-5px);
  }
  80% {
    transform: translateX(5px);
  }
}

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

@keyframes spark {
  0% {
    transform: translate(0, 0) scale(0.4);
    opacity: 0;
  }
  30% {
    opacity: 1;
  }
  100% {
    transform: translate(var(--sx, 20px), var(--sy, -30px)) scale(0.9);
    opacity: 0;
  }
}

/* ---------- 5. 星空与萤火虫 ---------- */
.stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

.stars::before,
.stars::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
      1.4px 1.4px at 12% 18%,
      var(--moon) 50%,
      transparent 51%
    ),
    radial-gradient(1.2px 1.2px at 28% 42%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 46% 12%, var(--moon) 50%, transparent 51%),
    radial-gradient(1.6px 1.6px at 62% 30%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 78% 22%, var(--moon) 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 88% 48%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 18% 62%, var(--moon) 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 36% 78%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 54% 66%, var(--moon) 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 72% 82%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 92% 72%, var(--moon) 50%, transparent 51%),
    radial-gradient(1px 1px at 8% 88%, #fff 50%, transparent 51%);
  background-repeat: no-repeat;
  animation: twinkle 4.5s ease-in-out infinite;
  will-change: opacity;
}

.stars::after {
  animation-delay: 2.2s;
  opacity: 0.6;
  transform: scale(1.1);
}

.firefly {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--moon) 0%, rgba(255, 223, 158, 0.4) 60%, transparent 70%);
  box-shadow: 0 0 8px 2px rgba(255, 223, 158, 0.5);
  pointer-events: none;
  animation: drift 9s ease-in-out infinite;
  z-index: 1;
  will-change: transform, opacity;
}

/* 萤火虫位置。注意：这些值原先被 app.js 的行内 style 覆盖，
   此处已改为行内实际生效的值（46/14、64/82、80/30），
   以保证移除行内样式后视觉不变。 */
.firefly:nth-child(1) {
  top: 46%;
  left: 14%;
  animation-delay: 0s;
}
.firefly:nth-child(2) {
  top: 64%;
  left: 82%;
  animation-delay: 4s;
  animation-duration: 11s;
}
.firefly:nth-child(3) {
  top: 80%;
  left: 30%;
  animation-delay: 7.5s;
  animation-duration: 8s;
}

/* ---------- 6. 月亮石 .pearl ---------- */
.pearl {
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: radial-gradient(
    circle at 35% 30%,
    #fff7e0 0%,
    var(--moon) 45%,
    var(--warm) 100%
  );
  box-shadow: 0 0 12px 2px rgba(255, 223, 158, 0.55),
    inset -2px -2px 4px rgba(240, 127, 51, 0.25);
  flex-shrink: 0;
}

.pearl.off {
  background: radial-gradient(
    circle at 35% 30%,
    rgba(255, 223, 158, 0.18) 0%,
    rgba(36, 50, 89, 0.6) 60%,
    rgba(11, 14, 34, 0.8) 100%
  );
  box-shadow: inset -2px -2px 4px rgba(0, 0, 0, 0.4);
}

.pearl.lg {
  width: 64px;
  height: 64px;
  box-shadow: 0 0 30px 6px rgba(255, 223, 158, 0.6),
    0 0 60px 14px rgba(255, 154, 82, 0.3),
    inset -4px -4px 8px rgba(240, 127, 51, 0.25);
}

/* ---------- 7. 系统屏 .s-screen ---------- */
.s-screen {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  padding: calc(28px + env(safe-area-inset-top)) 22px calc(40px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  overflow: hidden;
  isolation: isolate;
}

.s-screen.brand {
  background: linear-gradient(180deg, #0b0e22 0%, #161c3d 55%, #243259 100%);
}

.s-screen.stage {
  background: radial-gradient(130% 60% at 50% -6%, #2c3a6e 0%, #161c3d 48%, #0a0d1f 100%);
}

.s-stars {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* 头像光球 .s-orb */
.s-orb {
  position: relative;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  overflow: visible;
  z-index: 2;
  margin: 8px 0 4px;
}

.s-orb img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid rgba(255, 223, 158, 0.35);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
  position: relative;
  z-index: 2;
}

.s-orb .halo {
  position: absolute;
  inset: -18px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(255, 223, 158, 0.35) 0%,
    rgba(255, 154, 82, 0.18) 45%,
    transparent 70%
  );
  animation: breathe 4s ease-in-out infinite;
  z-index: 1;
  will-change: transform, opacity;
}

/* 按钮 .s-btn */
.s-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  max-width: 320px;
  padding: 15px 24px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: #fff;
  background: linear-gradient(135deg, var(--warm) 0%, var(--warm-deep) 100%);
  box-shadow: 0 8px 22px rgba(240, 127, 51, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.25);
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease),
    opacity 0.18s var(--ease);
}

.s-btn:active {
  transform: translateY(1px) scale(0.99);
  box-shadow: 0 4px 12px rgba(240, 127, 51, 0.4);
}

.s-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.s-btn.ghost {
  background: transparent;
  color: var(--mut-strong);
  border: 1px solid var(--line);
  box-shadow: none;
}

.s-btn.ghost:active {
  background: rgba(255, 223, 158, 0.06);
}

/* 小标签 .s-pill */
.s-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--moon);
  background: rgba(255, 223, 158, 0.1);
  border: 1px solid var(--line);
}

/* 圆形图标按钮 .s-icon */
.s-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: var(--mut-strong);
  background: rgba(255, 223, 158, 0.08);
  border: 1px solid var(--line);
  transition: background 0.18s var(--ease), transform 0.18s var(--ease);
  flex-shrink: 0;
}

.s-icon:active {
  transform: scale(0.92);
  background: rgba(255, 223, 158, 0.16);
}

/* 纸张卡片 .s-paper */
.s-paper {
  width: 100%;
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper-deep) 100%);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
  color: var(--ink);
  text-align: left;
}

/* 兴趣标签 .s-chip */
.s-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 10px 16px;
  min-height: 44px;
  border-radius: 999px;
  font-size: 13.5px;
  color: var(--ink-soft);
  background: rgba(58, 49, 38, 0.06);
  border: 1px solid rgba(58, 49, 38, 0.12);
  transition: all 0.18s var(--ease);
}

.s-chip.on {
  color: #fff;
  background: linear-gradient(135deg, var(--warm), var(--warm-deep));
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(240, 127, 51, 0.35);
}

/* ---------- 8. 落地页 .landing ---------- */
.landing {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  /* 此前被 app.js 的行内 style="padding:60px 30px 36px" 覆盖，
     现取行内实际生效的值，以保证移除行内样式后视觉不变。 */
  padding: 60px 30px 36px;
  z-index: 2;
}

.landing .orb-wrap {
  position: relative;
  margin-bottom: 26px;
}

.landing h1 {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--paper);
  margin-bottom: 10px;
  text-shadow: 0 2px 18px rgba(255, 154, 82, 0.25);
}

.landing .sub {
  font-size: 15px;
  color: var(--mut);
  max-width: 300px;
  line-height: 1.7;
  margin-bottom: 30px;
}

.landing .props {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 24px;
}

.prop {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.06);
  border: 1px solid var(--line);
  text-align: left;
}

.prop .ico {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  background: linear-gradient(135deg, rgba(255, 154, 82, 0.25), rgba(255, 223, 158, 0.12));
  border: 1px solid var(--line);
}

.prop .pt {
  font-size: 15px;
  font-weight: 600;
  color: var(--mut-strong);
  line-height: 1.3;
  margin-bottom: 2px;
}

.prop .pd {
  font-size: 12.5px;
  color: var(--mut);
  line-height: 1.55;
}

.landing .trust {
  font-size: 12px;
  color: var(--mut);
  margin-bottom: 22px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.landing .cta-row {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
}

/* P3-1：落地页登录入口与已登录状态显示 */
.landing .auth-entry {
  margin-top: 16px;
  max-width: 320px;
}

.landing .auth-status {
  margin-top: 18px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 13px;
  color: var(--moon);
  background: rgba(255, 223, 158, 0.1);
  border: 1px solid var(--line);
}

.landing .auth-status-dot {
  color: var(--done);
  font-size: 10px;
  line-height: 1;
}

.landing .auth-logout-btn {
  margin-left: 4px;
  padding: 0;
  min-width: 44px;
  min-height: 44px;
  border: none;
  background: none;
  color: var(--mut);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  transition: color 0.18s var(--ease), background 0.18s var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.landing .auth-logout-btn:hover,
.landing .auth-logout-btn:focus-visible {
  color: var(--warm);
  background: rgba(255, 154, 82, 0.12);
}

/* ---------- 8.1 登录页 ---------- */
/* 以下规则原先是 app.js 模板里的行内 style，为收紧 CSP 的
   style-src（移除 unsafe-inline）而迁入此处，样式值保持不变。 */
.login-wrap {
  padding: 48px 24px 32px;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  z-index: 2;
}

.login-wrap .orb-wrap {
  margin-bottom: 20px;
}

.login-title {
  font-size: 24px;
  color: var(--paper);
  margin-bottom: 8px;
  text-align: center;
}

.login-sub {
  font-size: 14px;
  color: var(--mut);
  text-align: center;
  max-width: 280px;
  margin-bottom: 28px;
  line-height: 1.6;
}

.wechat-btn {
  background: linear-gradient(135deg, #1aad19, #179b16);
  box-shadow: 0 8px 22px rgba(23, 155, 22, 0.35);
  margin-bottom: 16px;
}

.login-divider {
  display: flex;
  align-items: center;
  width: 100%;
  max-width: 320px;
  margin-bottom: 16px;
  color: var(--mut);
  font-size: 12px;
}

.login-divider .divider-line {
  flex: 1;
  height: 1px;
  background: var(--line);
}

.login-divider .divider-text {
  padding: 0 12px;
}

.login-form {
  width: 100%;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.login-form .field-caption {
  display: block;
  font-size: 13px;
  color: var(--mut-strong);
  margin-bottom: 6px;
}

.login-form .text-field {
  width: 100%;
  padding: 13px 16px;
  border-radius: 12px;
  background: rgba(255, 223, 158, 0.06);
  border: 1px solid var(--line);
  color: var(--paper);
  font-size: 15px;
}

.login-form .form-row.row-inline {
  display: flex;
  gap: 10px;
  align-items: flex-end;
}

.login-form .row-grow {
  flex: 1;
}

.login-form .send-code-btn {
  width: 120px;
  flex-shrink: 0;
  padding: 13px 12px;
  font-size: 13px;
  white-space: nowrap;
}

.login-form .submit-btn {
  margin-top: 6px;
}

.login-footer {
  margin-top: 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  width: 100%;
  max-width: 320px;
}

.login-footer .full-width {
  width: 100%;
}

.link-btn {
  background: none;
  border: none;
  color: var(--mut);
  font-size: 13px;
  padding: 8px;
  cursor: pointer;
}

/* 登录页表单获得焦点样式 */
.login-form input:focus {
  outline: none;
  border-color: var(--warm);
  box-shadow: 0 0 0 3px rgba(255, 154, 82, 0.18);
}

/* ---------- 9. 设置页 .setup ---------- */
.setup {
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 2;
  /* 此前被 app.js 的行内 style="padding:54px 22px 34px" 覆盖，
     现取行内实际生效的值，以保证移除行内样式后视觉不变。 */
  padding: 54px 22px 34px;
}

.setup .hello {
  font-size: 14px;
  color: var(--mut);
  margin: 16px 0 4px;
}

.setup .hello strong {
  color: var(--moon);
  font-weight: 600;
}

.setup .ask-line {
  font-size: 20px;
  font-weight: 600;
  color: var(--paper);
  margin-bottom: 22px;
  text-align: center;
}

.setup .s-paper {
  margin-bottom: 22px;
}

.setup .field-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.setup .nick-input {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: rgba(58, 49, 38, 0.05);
  border: 1px solid rgba(58, 49, 38, 0.14);
  color: var(--ink);
  font-size: 15px;
  outline: none;
  transition: border 0.18s var(--ease), background 0.18s var(--ease);
}

.setup .nick-input:focus {
  border-color: var(--warm);
  background: #fff;
}

.setup .chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.setup .section-gap {
  height: 18px;
}

/* ---------- 10. 故事地图 .map ---------- */
.map {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  padding-bottom: calc(40px + env(safe-area-inset-bottom));
  z-index: 2;
}

/* 顶部栏 .bar */
.map .bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: calc(14px + env(safe-area-inset-top)) 18px 14px;
  background: linear-gradient(180deg, var(--night-0) 60%, rgba(11, 14, 34, 0));
  backdrop-filter: blur(6px);
}

.bar .bar-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--paper);
  letter-spacing: 0.5px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar .bar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.bar .pearl-count {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px 5px 7px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--moon);
  background: rgba(255, 223, 158, 0.1);
  border: 1px solid var(--line);
  white-space: nowrap;
  flex-shrink: 0;
}

.bar .pearl-count .pearl {
  width: 16px;
  height: 16px;
}

.bar .icon-group {
  display: flex;
  gap: 6px;
}

/* 问候气泡 .greet */
.map .greet {
  margin: 6px 18px 16px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.07);
  border: 1px solid var(--line);
  font-size: 14px;
  color: var(--mut-strong);
  line-height: 1.6;
  display: flex;
  align-items: center;
  gap: 10px;
}

.map .greet .g-ava {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--line);
}

.map .greet strong {
  color: var(--moon);
}

/* 讲给谁听 .who */
.map .who {
  margin: 0 18px 14px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: rgba(36, 50, 89, 0.5);
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.map .who .who-l {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.map .who .who-t {
  font-size: 12px;
  color: rgba(240, 238, 250, 0.7);
}

.map .who .who-n {
  font-size: 15px;
  font-weight: 600;
  color: var(--paper);
}

.map .who .who-edit {
  font-size: 12px;
  color: var(--warm);
  padding: 10px 16px;
  min-height: 44px;
  border-radius: 999px;
  background: rgba(255, 154, 82, 0.12);
  border: 1px solid rgba(255, 154, 82, 0.3);
  display: inline-flex;
  align-items: center;
}

/* 配额提示 .quota */
.map .quota {
  margin: 0 18px 18px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  color: rgba(240, 238, 250, 0.82);
  background: rgba(185, 207, 146, 0.08);
  border: 1px solid rgba(185, 207, 146, 0.2);
  display: flex;
  align-items: center;
  gap: 8px;
}

.map .quota .q-num {
  color: var(--done);
  font-weight: 700;
}

/* 蜿蜒小径 .trail */
.trail {
  position: relative;
  padding: 10px 0 20px;
}

.trail-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.trail-svg path {
  fill: none;
  stroke: var(--line);
  stroke-width: 2;
  stroke-dasharray: 6 8;
  stroke-linecap: round;
}

/* 关卡节点 .node */
.node {
  position: relative;
  z-index: 2;
  margin: 0 18px 22px;
  padding: 16px;
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(36, 50, 89, 0.7), rgba(22, 28, 61, 0.7));
  border: 1px solid var(--line);
  display: flex;
  gap: 14px;
  align-items: center;
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.node:nth-child(even) {
  /* 蜿蜒效果：偶数节点右移 */
  transform: translateX(14px);
}

.node:nth-child(odd) {
  transform: translateX(-14px);
}

.node .art {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--line);
  background: var(--night-2);
}

.node .nb {
  flex: 1;
  min-width: 0;
}

.node .t {
  font-size: 15.5px;
  font-weight: 700;
  color: var(--paper);
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.node .s {
  font-size: 12.5px;
  color: rgba(240, 238, 250, 0.82);
  line-height: 1.5;
  margin-bottom: 8px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.node .cta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 10px 18px;
  min-height: 44px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, var(--warm), var(--warm-deep));
  box-shadow: 0 4px 10px rgba(240, 127, 51, 0.3);
}

/* 当前关卡 .cur */
.node.cur {
  border-color: rgba(255, 154, 82, 0.5);
  box-shadow: 0 0 0 1px rgba(255, 154, 82, 0.2),
    0 10px 30px rgba(240, 127, 51, 0.18);
}

/* glowPulse 优化：用伪元素承载静态 box-shadow，动画 opacity 避免每帧重绘 */
.node.cur::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 4px rgba(255, 154, 82, 0.4),
    0 0 28px 6px rgba(255, 154, 82, 0.5);
  animation: glowPulse 2.6s ease-in-out infinite;
  pointer-events: none;
  will-change: opacity;
}

.node.cur .art {
  border-color: var(--warm);
  box-shadow: 0 0 18px rgba(255, 154, 82, 0.5);
}

.node.cur .cta {
  animation: bob 2.4s ease-in-out infinite;
}

/* 完成关卡 .done */
.node.done {
  opacity: 0.92;
}

.node.done .art {
  border-color: var(--done);
  position: relative;
}

.node.done .art::after {
  content: "✓";
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--done);
  color: var(--night-0);
  font-size: 13px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.node.done .cta {
  background: rgba(185, 207, 146, 0.18);
  color: var(--done);
  box-shadow: none;
}

/* 锁定关卡 .lock */
.node.lock {
  opacity: 0.5;
  filter: grayscale(0.4);
}

.node.lock .art {
  filter: brightness(0.6);
}

.node.lock .cta {
  background: rgba(255, 255, 255, 0.08);
  color: var(--mut);
  box-shadow: none;
  cursor: not-allowed;
}

.node.lock .lock-mark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 22px;
}

/* ---------- 11. 编织过渡 .weave ---------- */
.weave {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  background: radial-gradient(120% 80% at 50% 40%, #1a2350 0%, #0b0e22 70%);
  text-align: center;
}

.weave .w-orb {
  position: relative;
  width: 120px;
  height: 120px;
}

.weave .w-rays {
  position: absolute;
  inset: -30px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgba(255, 223, 158, 0.35) 30deg,
    transparent 60deg,
    transparent 180deg,
    rgba(255, 154, 82, 0.3) 210deg,
    transparent 240deg
  );
  animation: spin 6s linear infinite;
  filter: blur(2px);
  will-change: transform;
}

.weave .w-ava {
  position: relative;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid rgba(255, 223, 158, 0.4);
  box-shadow: 0 0 40px rgba(255, 154, 82, 0.4);
  z-index: 2;
}

.weave .w-txt {
  font-size: 16px;
  color: var(--moon);
  font-weight: 600;
  letter-spacing: 1px;
}

.weave .w-sub {
  font-size: 13px;
  color: var(--mut);
  margin-top: -18px;
}

.weave .w-bar {
  width: 200px;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 223, 158, 0.12);
  overflow: hidden;
  position: relative;
}

.weave .w-bar .w-fill {
  height: 100%;
  width: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--warm), var(--moon));
  animation: fill 1.8s var(--ease) infinite;
  position: relative;
  will-change: transform;
}

.weave .w-bar .w-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.5),
    transparent
  );
  animation: sweep 1.4s ease-in-out infinite;
  will-change: transform;
}

/* ---------- 12. 故事播放器 .player ---------- */
.player {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  z-index: 2;
}

/* 顶部栏 */
.player .bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(14px + env(safe-area-inset-top)) 16px 14px;
  background: linear-gradient(180deg, var(--night-0) 70%, rgba(11, 14, 34, 0));
  backdrop-filter: blur(6px);
}

.player .bar .b-back {
  flex-shrink: 0;
}

.player .bar .b-mid {
  flex: 1;
  min-width: 0;
  text-align: center;
}

.player .bar .b-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--paper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player .bar .b-page {
  font-size: 11.5px;
  color: var(--mut);
  margin-top: 1px;
}

.player .bar .b-read {
  flex-shrink: 0;
}

.player .bar .b-read.on {
  color: var(--warm);
  background: rgba(255, 154, 82, 0.14);
  border-color: rgba(255, 154, 82, 0.4);
}

/* 进度点 .dots */
.dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 4px 0 14px;
}

.dots .pearl {
  width: 12px;
  height: 12px;
  transition: transform 0.3s var(--ease);
}

.dots .pearl.cur {
  transform: scale(1.35);
  box-shadow: 0 0 10px 2px rgba(255, 223, 158, 0.6);
}

/* 故事页 .page */
.page {
  margin: 0 16px 16px;
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper-deep) 100%);
  border-radius: var(--radius-lg);
  padding: 18px 18px 22px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.32);
  color: var(--ink);
  position: relative;
  overflow: hidden;
}

.page::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--warm), var(--moon), var(--warm));
  opacity: 0.7;
}

/* 场景图 .scene / .drawing-slot */
.scene {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: 16px;
  background: linear-gradient(135deg, #e9dcba, #d8c9a3);
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(58, 49, 38, 0.08);
}

.scene img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.drawing-slot {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-md);
  margin-bottom: 16px;
  background: linear-gradient(110deg, #e9dcba 25%, #f3e9d0 50%, #e9dcba 75%);
  background-size: 200% 100%;
  animation: sweep 1.6s ease-in-out infinite;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.drawing-slot::after {
  content: "✨ 画面绘制中…";
  font-size: 13px;
  color: var(--ink-soft);
  letter-spacing: 1px;
}

/* 正文 .prose */
.prose {
  font-family: var(--ff-serif);
  font-size: 17.5px;
  line-height: 2.05;
  color: var(--ink);
  letter-spacing: 0.3px;
  min-height: 80px;
}

/* 提问高亮 .ask */
.ask {
  color: var(--warm-deep);
  font-weight: 600;
  background-image: linear-gradient(
    transparent 78%,
    rgba(255, 154, 82, 0.35) 78%
  );
  padding: 0 1px;
}

/* 流式光标 .caret */
.caret {
  display: inline-block;
  width: 2px;
  height: 1.1em;
  margin-left: 1px;
  vertical-align: text-bottom;
  background: var(--warm-deep);
  animation: blink 1s step-end infinite;
}

/* 选项 .choices */
.choices {
  margin: 0 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.choice {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.07);
  border: 1px solid var(--line);
  text-align: left;
  transition: transform 0.16s var(--ease), background 0.16s var(--ease),
    border-color 0.16s var(--ease);
}

.choice:active {
  transform: scale(0.985);
  background: rgba(255, 154, 82, 0.12);
  border-color: rgba(255, 154, 82, 0.4);
}

.choice .c-emoji {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  background: rgba(255, 223, 158, 0.12);
  border: 1px solid var(--line);
}

.choice .c-body {
  flex: 1;
  min-width: 0;
}

.choice .c-label {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--paper);
  line-height: 1.35;
  margin-bottom: 2px;
}

/* 选项区提示行（迁移自 inline style，便于英文环境控制换行） */
.choices .c-prompt {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--moon);
  padding: 0 2px;
  margin-bottom: 2px;
  line-height: 1.5;
}
.choices .c-prompt-hint {
  font-weight: 400;
  font-size: 11px;
  color: var(--mut);
  margin-left: 5px;
}

.choice .c-hint {
  font-size: 12px;
  color: var(--mut);
  line-height: 1.45;
}

/* 完成按钮 .btn */
.player .btn {
  margin: 4px 16px 28px;
  padding: 15px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(135deg, var(--warm), var(--warm-deep));
  box-shadow: 0 8px 22px rgba(240, 127, 51, 0.4);
  transition: transform 0.16s var(--ease);
}

.player .btn:active {
  transform: translateY(1px) scale(0.99);
}

.player .btn.ghost {
  background: transparent;
  color: var(--mut-strong);
  border: 1px solid var(--line);
  box-shadow: none;
}

/* ---------- 13. 结局页 .ending ---------- */
.ending {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  padding: calc(20px + env(safe-area-inset-top)) 18px calc(36px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  z-index: 2;
}

.ending .ehead {
  font-size: 24px;
  font-weight: 700;
  color: var(--paper);
  margin: 8px 0 4px;
  text-shadow: 0 2px 16px rgba(255, 154, 82, 0.25);
}

.ending .ehead-sub {
  font-size: 13.5px;
  color: var(--mut);
  margin-bottom: 24px;
}

/* 月亮石舞台 .stage */
.ending .stage {
  position: relative;
  width: 180px;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
}

.ending .stage .pearl.lg {
  animation: stonePop 0.7s var(--ease) both;
  position: relative;
  z-index: 2;
}

.ending .stage .spark {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--moon);
  box-shadow: 0 0 8px 2px rgba(255, 223, 158, 0.7);
  animation: spark 1.8s ease-out infinite;
}

.ending .stage .spark:nth-child(2) {
  --sx: 60px;
  --sy: -40px;
  animation-delay: 0s;
}
.ending .stage .spark:nth-child(3) {
  --sx: -55px;
  --sy: -30px;
  animation-delay: 0.3s;
}
.ending .stage .spark:nth-child(4) {
  --sx: 50px;
  --sy: 45px;
  animation-delay: 0.6s;
}
.ending .stage .spark:nth-child(5) {
  --sx: -50px;
  --sy: 40px;
  animation-delay: 0.9s;
}
.ending .stage .spark:nth-child(6) {
  --sx: 0;
  --sy: -60px;
  animation-delay: 1.2s;
}

.ending .reward {
  font-size: 15px;
  color: var(--moon);
  margin-bottom: 24px;
  line-height: 1.7;
  max-width: 300px;
}

.ending .reward strong {
  color: var(--warm);
}

/* 三张卡片 .ecard */
.ending .ecards {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 20px;
}

.ecard {
  width: 100%;
  padding: 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.06);
  border: 1px solid var(--line);
  text-align: left;
}

.ecard .ec-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--moon);
  margin-bottom: 8px;
}

.ecard .ec-body {
  font-size: 13.5px;
  color: var(--mut-strong);
  line-height: 1.6;
}

.ecard .ec-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.ecard .ec-tag {
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 999px;
  color: var(--done);
  background: rgba(185, 207, 146, 0.12);
  border: 1px solid rgba(185, 207, 146, 0.25);
}

/* 评价说明 .eval-note */
.ending .eval-note {
  font-size: 11.5px;
  color: var(--mut);
  margin-bottom: 22px;
  line-height: 1.6;
  max-width: 300px;
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.ending .eval-note::before {
  content: "ℹ";
  flex-shrink: 0;
}

.ending .e-actions {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ending .e-actions .s-btn {
  max-width: none;
  width: 100%;
}

.ending .e-actions .row {
  display: flex;
  gap: 10px;
}

.ending .e-actions .row .s-btn {
  flex: 1;
  max-width: none;
  font-size: 14px;
  padding: 13px 12px;
}

/* ---------- 14. 家长门 .s-overlay ---------- */
.s-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(5, 6, 15, 0.7);
  backdrop-filter: blur(4px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s var(--ease), visibility 0.25s var(--ease);
}

.s-overlay.show {
  opacity: 1;
  visibility: visible;
}

.s-overlay .gate {
  width: 100%;
  max-width: var(--frame-w);
  max-height: 100dvh;
  overflow-y: auto;
  background: linear-gradient(180deg, var(--night-1), var(--night-0));
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 18px 22px calc(20px + env(safe-area-inset-bottom));
  transform: translateY(100%);
  transition: transform 0.32s var(--ease);
  border-top: 1px solid var(--line);
  -webkit-overflow-scrolling: touch;
}

.s-overlay.show .gate {
  transform: translateY(0);
}

.s-overlay .gate-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--paper);
  text-align: center;
  margin-bottom: 4px;
}

.s-overlay .gate-sub {
  font-size: 12.5px;
  color: var(--mut);
  text-align: center;
  margin-bottom: 18px;
}

/* 数学题 .eq */
.s-overlay .eq {
  text-align: center;
  font-size: 30px;
  font-weight: 700;
  color: var(--moon);
  letter-spacing: 2px;
  padding: 18px;
  margin-bottom: 18px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.06);
  border: 1px solid var(--line);
  font-family: var(--ff-serif);
}

.s-overlay .eq.bad {
  color: #ff7a7a;
  border-color: rgba(255, 122, 122, 0.4);
  animation: shake 0.4s ease;
}

/* 数字键盘 .keypad */
.keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}

.keypad .key {
  padding: 16px 0;
  border-radius: var(--radius-md);
  font-size: 20px;
  font-weight: 600;
  color: var(--paper);
  background: rgba(255, 223, 158, 0.07);
  border: 1px solid var(--line);
  transition: background 0.14s var(--ease), transform 0.14s var(--ease);
}

.keypad .key:active {
  transform: scale(0.95);
  background: rgba(255, 154, 82, 0.2);
}

.keypad .key.fn {
  color: var(--mut);
  font-size: 16px;
  background: rgba(255, 255, 255, 0.03);
}

.keypad .key.fn:active {
  background: rgba(255, 122, 122, 0.15);
  color: #ff9a9a;
}

/* ---------- 15. 页面切换动画 ---------- */
.page-enter-active {
  animation: pageTurn 0.5s var(--ease);
}

.page-enter {
  /* 起始态由 keyframes from 定义 */
}

.rise {
  animation: riseIn 0.5s var(--ease) both;
}

.rise.d1 {
  animation-delay: 0.06s;
}
.rise.d2 {
  animation-delay: 0.12s;
}
.rise.d3 {
  animation-delay: 0.18s;
}
.rise.d4 {
  animation-delay: 0.24s;
}

/* ---------- 16. 日夜主题 ----------
   核心策略：在 body.theme-day 上重定义语义化 CSS 变量，
   使全站使用 var(--paper)/var(--mut)/var(--moon) 等变量的组件
   自动获得深色文字，从根本上避免逐组件补丁遗漏。 */

/* === 16.1 变量重定义（body 级别，覆盖 frame 内外所有组件） === */
body.theme-day {
  /* 背景色阶：夜间深蓝 → 日间米黄 */
  --night-0: #fdf6e3;
  --night-1: #f7edd4;
  --night-2: #efe2bf;

  /* 文字色阶：夜间浅色 → 日间深色 */
  --paper: #3a3126;
  --mut: rgba(58, 49, 38, 0.62);
  --mut-strong: rgba(58, 49, 38, 0.82);
  --moon: #c97b22;

  /* 边框/分隔线 */
  --line: rgba(58, 49, 38, 0.12);

  background: #f3e9d0;
  color: var(--ink);
}

.frame.theme-day {
  background: linear-gradient(180deg, #fdf6e3 0%, #f3e9d0 100%);
  box-shadow: 0 0 60px rgba(240, 127, 51, 0.15), 0 0 0 1px rgba(58, 49, 38, 0.06);
}

/* === 16.2 星空/萤火虫隐藏 === */
.frame.theme-day .stars,
.frame.theme-day .s-stars,
.frame.theme-day .firefly {
  display: none;
}

/* === 16.3 顶栏 === */
.frame.theme-day .bar {
  background: linear-gradient(180deg, #fdf6e3 60%, rgba(253, 246, 227, 0));
}

/* === 16.4 系统屏背景 === */
.frame.theme-day .s-screen.brand {
  background: linear-gradient(180deg, #fdf6e3 0%, #f3e9d0 55%, #e9dcba 100%);
}

.frame.theme-day .s-screen.stage {
  background: radial-gradient(130% 60% at 50% -6%, #fff8e0 0%, #f3e9d0 48%, #e9dcba 100%);
}

/* === 16.5 卡片背景：问候/讲给谁听/关卡节点 === */
.frame.theme-day .greet,
.frame.theme-day .who,
.frame.theme-day .node {
  background: rgba(255, 255, 255, 0.6);
  border-color: rgba(58, 49, 38, 0.1);
}

/* === 16.6 药丸/图标按钮 === */
.frame.theme-day .s-pill,
.frame.theme-day .pearl-count,
.frame.theme-day .s-icon {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.12);
  color: var(--ink);
}

/* === 16.7 落地页 === */
.frame.theme-day .landing .sub,
.frame.theme-day .landing .trust,
.frame.theme-day .prop .pd {
  color: var(--ink-soft);
}

.frame.theme-day .prop {
  background: rgba(255, 255, 255, 0.5);
  border-color: rgba(58, 49, 38, 0.08);
}

.frame.theme-day .s-btn.ghost {
  color: var(--ink-soft);
  border-color: rgba(58, 49, 38, 0.15);
}

/* === 16.8 编织过渡 === */
.frame.theme-day .weave {
  background: radial-gradient(120% 80% at 50% 40%, #fff8e0 0%, #f3e9d0 70%);
}

.frame.theme-day .weave .w-txt {
  color: var(--warm-deep);
}

/* === 16.9 高亮强调色 === */
.frame.theme-day .ending .reward,
.frame.theme-day .map .greet strong {
  color: var(--warm-deep);
}

/* ============================================================
   16.10  新增组件日间适配（P0 布局重构后引入的组件）
   ============================================================ */

/* 月亮石罐子 */
.frame.theme-day .jar {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.1);
}

.frame.theme-day .jar-quota {
  border-top-color: rgba(58, 49, 38, 0.1);
}

/* 今晚设置面板 */
.frame.theme-day .sumrow {
  background: rgba(255, 255, 255, 0.5);
  border-color: rgba(58, 49, 38, 0.08);
}

.frame.theme-day .sumrow-toggle {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.12);
  color: var(--warm-deep);
}

.frame.theme-day .sumrow-ava {
  border-color: rgba(58, 49, 38, 0.15);
}

/* 今晚可讲卡片 */
.frame.theme-day .featured {
  background: linear-gradient(135deg, #fff8e8 0%, #f7edd4 100%);
  box-shadow: 0 0 0 2px rgba(255, 154, 82, 0.3), 0 8px 24px rgba(240, 127, 51, 0.12);
}

.frame.theme-day .featured-tag {
  background: rgba(255, 154, 82, 0.15);
  color: var(--warm-deep);
}

/* 故事筛选器 */
.frame.theme-day .wd-filter {
  background: rgba(58, 49, 38, 0.06);
}

.frame.theme-day .wd-filter-btn.active {
  color: var(--ink);
  background: rgba(255, 154, 82, 0.2);
}

/* 世界卡片遮罩：日间使用暖深色遮罩，保持白字可读 */
.frame.theme-day .wcard-overlay {
  background: linear-gradient(90deg,
    rgba(58, 49, 38, 0.72) 0%,
    rgba(58, 49, 38, 0.42) 50%,
    rgba(58, 49, 38, 0.06) 100%);
}

.frame.theme-day .wcard-lock {
  background: rgba(58, 49, 38, 0.45);
}

.frame.theme-day .wcard-sub {
  color: rgba(255, 223, 158, 0.8);
}

/* 世界详情封面遮罩 */
.frame.theme-day .wd-cover-overlay {
  background: linear-gradient(180deg,
    rgba(58, 49, 38, 0.2) 0%,
    rgba(58, 49, 38, 0.4) 50%,
    rgba(58, 49, 38, 0.9) 100%);
}

.frame.theme-day .wd-cover-top .pearl-count {
  background: rgba(58, 49, 38, 0.5);
  color: #ffdf9e;
}

/* 世界卡片/封面上的辅助文字在深色遮罩上，日间仍需保持浅色 */
.frame.theme-day .pips-count {
  color: rgba(240, 238, 250, 0.7);
}

/* 网格节点锁定遮罩 */
.frame.theme-day .gnode-lock {
  background: rgba(58, 49, 38, 0.45);
}

.frame.theme-day .gnode-label {
  background: rgba(58, 49, 38, 0.7);
}

/* 选项卡片 */
.frame.theme-day .choice {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.1);
}

.frame.theme-day .choice:active {
  background: rgba(255, 154, 82, 0.12);
  border-color: rgba(255, 154, 82, 0.3);
}

.frame.theme-day .choice .c-emoji {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.1);
}

/* 结局卡片 */
.frame.theme-day .ecard {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.08);
}

.frame.theme-day .ecard .ec-head {
  color: var(--warm-deep);
}

/* 孩子切换器 */
.frame.theme-day .child-switcher {
  border-bottom-color: rgba(58, 49, 38, 0.1);
}

.frame.theme-day .child-avatar {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.12);
  color: var(--ink);
}

.frame.theme-day .child-avatar.active {
  border-color: var(--warm);
  background: rgba(255, 154, 82, 0.12);
}

.frame.theme-day .child-avatar-add {
  color: var(--ink-soft);
}

/* 连续打卡点 */
.frame.theme-day .streak-dot {
  background: rgba(58, 49, 38, 0.12);
}

/* 月亮石 off 状态 */
.frame.theme-day .pearl.off {
  background: radial-gradient(
    circle at 35% 30%,
    rgba(58, 49, 38, 0.12) 0%,
    rgba(58, 49, 38, 0.06) 60%,
    rgba(58, 49, 38, 0.03) 100%
  );
  box-shadow: inset -2px -2px 4px rgba(58, 49, 38, 0.08);
}

/* 锁定关卡 CTA */
.frame.theme-day .node.lock .cta {
  background: rgba(58, 49, 38, 0.08);
  color: var(--ink-soft);
}

/* 登录页表单 */
.frame.theme-day .login-form .text-field {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.1);
}

.frame.theme-day .login-form .text-field:focus {
  background: #fff;
}

.frame.theme-day .login-divider .divider-line {
  background: rgba(58, 49, 38, 0.1);
}

/* 家长门遮罩（body 级别，在 frame 外） */
body.theme-day .s-overlay {
  background: rgba(243, 233, 208, 0.7);
}

body.theme-day .s-overlay .gate {
  background: linear-gradient(180deg, #fdf6e3, #f3e9d0);
  border-top-color: rgba(58, 49, 38, 0.1);
}

body.theme-day .s-overlay .eq {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.1);
  color: var(--warm-deep);
}

body.theme-day .keypad .key {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.1);
  color: var(--ink);
}

body.theme-day .keypad .key:active {
  background: rgba(255, 154, 82, 0.18);
}

body.theme-day .keypad .key.fn {
  background: rgba(58, 49, 38, 0.03);
  color: var(--ink-soft);
}

/* === 16.11 设置面板日间适配（面板在 gate 内，body 级别） === */
body.theme-day .settings-panel .sp-head,
body.theme-day .settings-panel .sp-row,
body.theme-day .settings-panel .sp-history-head,
body.theme-day .settings-panel .voice-name,
body.theme-day .settings-panel .voice-preview,
body.theme-day .settings-panel .lang-row {
  color: var(--ink);
}

body.theme-day .settings-panel .sp-row {
  border-bottom-color: rgba(58, 49, 38, 0.08);
}

body.theme-day .settings-panel .sp-history-item {
  border-bottom-color: rgba(58, 49, 38, 0.08);
}

body.theme-day .settings-panel .sp-history-empty,
body.theme-day .settings-panel .sp-history-time,
body.theme-day .settings-panel .sp-history-more,
body.theme-day .settings-panel .sp-section-title,
body.theme-day .settings-panel .voice-desc {
  color: var(--ink-soft);
}

body.theme-day .settings-panel .voice-row,
body.theme-day .settings-panel .lang-row {
  background: rgba(58, 49, 38, 0.04);
  border-color: rgba(58, 49, 38, 0.1);
}

body.theme-day .settings-panel .voice-row:hover,
body.theme-day .settings-panel .lang-row:hover {
  background: rgba(58, 49, 38, 0.08);
  border-color: rgba(58, 49, 38, 0.15);
}

body.theme-day .settings-panel .voice-row.selected,
body.theme-day .settings-panel .lang-row.selected {
  background: rgba(255, 154, 82, 0.1);
  border-color: rgba(255, 154, 82, 0.35);
}

body.theme-day .settings-panel .voice-preview {
  background: rgba(58, 49, 38, 0.06);
  border-color: rgba(58, 49, 38, 0.12);
}

body.theme-day .settings-panel .voice-preview:hover {
  background: rgba(58, 49, 38, 0.1);
}

body.theme-day .settings-panel .voice-preview.playing {
  background: rgba(255, 154, 82, 0.15);
  border-color: rgba(255, 154, 82, 0.4);
  color: var(--warm-deep);
}

body.theme-day .settings-panel .sp-history-tag {
  background: rgba(255, 154, 82, 0.1);
}

/* === 16.12 图片懒加载占位色 === */
body.theme-day img[loading="lazy"],
body.theme-day img[loading="eager"] {
  background-color: var(--night-2);
}

/* M9 修复：配额用完的节点禁用样式 */
.node.quota-done {
  opacity: 0.45;
  filter: grayscale(0.5);
  cursor: not-allowed;
}

.node.quota-done:hover {
  transform: none;
}

/* ---------- 17. 通用辅助类 ---------- */
.mut {
  color: var(--mut);
}
.mut-strong {
  color: var(--mut-strong);
}
.moon {
  color: var(--moon);
}
.warm {
  color: var(--warm);
}
.center {
  text-align: center;
}
.mt-auto {
  margin-top: auto;
}
.hidden {
  display: none !important;
}
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
.gap-8 {
  gap: 8px;
}
.gap-12 {
  gap: 12px;
}
.items-center {
  align-items: center;
}
.justify-center {
  justify-content: center;
}

/* ---------- 18. 响应式适配 ---------- */
@media (max-width: 380px) {
  .s-screen {
    padding: 24px 18px 36px;
  }

  .landing h1 {
    font-size: 26px;
  }

  .landing .sub {
    font-size: 14px;
  }

  .prop {
    padding: 12px 14px;
  }

  .prop .pt {
    font-size: 14px;
  }

  .node {
    margin: 0 14px 20px;
    padding: 14px;
    gap: 12px;
  }

  .node:nth-child(even) {
    transform: translateX(8px);
  }
  .node:nth-child(odd) {
    transform: translateX(-8px);
  }

  .node .art {
    width: 64px;
    height: 64px;
  }

  .page {
    margin: 0 12px 14px;
    padding: 16px;
  }

  .prose {
    font-size: 16.5px;
  }

  .choices {
    margin: 0 12px 14px;
  }

  .player .btn {
    margin: 4px 12px 24px;
  }
}

@media (min-width: 441px) {
  .frame {
    margin-top: 0;
    border-radius: 0;
    min-height: 100vh;
  }
}

/* ---------- 19. 减少动画偏好 ---------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .stars::before,
  .stars::after,
  .firefly,
  .s-orb .halo,
  .node.cur::after,
  .node.cur .cta,
  .featured,
  .weave .w-rays,
  .weave .w-bar .w-fill,
  .weave .w-bar .w-fill::after,
  .drawing-slot,
  .caret,
  .ending .stage .spark {
    animation: none !important;
  }

  .page-enter-active {
    animation: none !important;
  }
}

/* ==================== 体验优化新增样式 ==================== */

/* 页面离场动画 */
.page-leaving {
  animation: pageLeave 0.18s ease-out forwards;
}

@keyframes pageLeave {
  to {
    opacity: 0;
    transform: translateX(-12px);
  }
}

/* Toast 提示 */
.toast {
  position: fixed;
  bottom: calc(80px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: rgba(20, 26, 56, 0.95);
  color: var(--moon);
  padding: 12px 24px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 500;
  z-index: 9999;
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.3s ease;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
  border: 1px solid var(--line);
  max-width: 320px;
  text-align: center;
  line-height: 1.5;
  pointer-events: none;
}

.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* 选项选中高亮 */
.choice.selected {
  border-color: var(--warm) !important;
  background: rgba(255, 154, 82, 0.12) !important;
  transform: scale(0.98);
  transition: all 0.2s ease;
}

/* 禁用按钮 */
.s-btn.disabled {
  opacity: 0.4;
  cursor: not-allowed;
  filter: grayscale(0.3);
}

/* 故事正文区域：自然撑开，不使用内部滚动框 */
.prose {
  word-break: break-word;
  overflow-wrap: break-word;
}

/* 家长设置面板 */
.settings-panel {
  text-align: center;
}

.settings-panel .sp-head {
  font-size: 18px;
  font-weight: 700;
  color: #f0eeea;
  margin-bottom: 16px;
}

.settings-panel .sp-list {
  text-align: left;
  margin-bottom: 16px;
}

.settings-panel .sp-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 223, 158, 0.1);
  font-size: 14px;
  color: #e8e6f0;
}

.settings-panel .sp-row:last-child {
  border-bottom: none;
}

.settings-panel .sp-val {
  font-weight: 700;
  color: var(--warm-deep);
}

/* 阅读历史 */
.settings-panel .sp-history {
  text-align: left;
  margin-bottom: 16px;
  max-height: 280px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.settings-panel .sp-history-empty {
  padding: 20px 0;
  text-align: center;
  font-size: 13px;
  color: rgba(240, 238, 250, 0.5);
}

.settings-panel .sp-history-item {
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 223, 158, 0.1);
}

.settings-panel .sp-history-item:last-child {
  border-bottom: none;
}

.settings-panel .sp-history-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: #e8e6f0;
}

.settings-panel .sp-history-emoji {
  font-size: 16px;
  flex-shrink: 0;
}

.settings-panel .sp-history-title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-panel .sp-history-time {
  flex-shrink: 0;
  font-size: 11px;
  color: rgba(240, 238, 250, 0.5);
}

.settings-panel .sp-history-traits {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
  padding-left: 22px;
}

.settings-panel .sp-history-tag {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(255, 223, 158, 0.12);
  color: var(--warm-deep);
  white-space: nowrap;
}

.settings-panel .sp-history-more {
  padding: 10px 0 4px;
  text-align: center;
  font-size: 11px;
  color: rgba(240, 238, 250, 0.5);
}

.settings-panel .sp-actions {
  display: flex;
  gap: 10px;
  margin-top: 12px;
}

.settings-panel .sp-actions .s-btn {
  flex: 1;
  max-width: none;
}

/* 声线选择 */
.settings-panel .sp-section-title {
  font-size: 13px;
  color: rgba(240, 238, 250, 0.7);
  margin-bottom: 8px;
  font-weight: 600;
}

.settings-panel .voice-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}

.settings-panel .voice-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  min-height: 44px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s;
}

.settings-panel .voice-row:hover {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.15);
}

.settings-panel .voice-row.selected {
  background: rgba(255,223,158,0.12);
  border-color: rgba(255,223,158,0.4);
}

.settings-panel .voice-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.settings-panel .voice-name {
  font-size: 14px;
  color: #f0eeea;
  font-weight: 600;
}

.settings-panel .voice-desc {
  font-size: 11px;
  color: rgba(240, 238, 250, 0.7);
}

.settings-panel .voice-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.settings-panel .voice-preview {
  font-size: 12px;
  padding: 10px 16px;
  min-height: 44px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 20px;
  color: #e8e6f0;
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
}

.settings-panel .voice-preview:hover {
  background: rgba(255,255,255,0.15);
}

.settings-panel .voice-preview.playing {
  background: rgba(255,223,158,0.2);
  border-color: rgba(255,223,158,0.5);
  color: var(--moon);
}

.settings-panel .voice-check {
  font-size: 16px;
  color: var(--moon);
  width: 20px;
  text-align: center;
  font-weight: 700;
}

/* 语言选择列表 */
.settings-panel .lang-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}

.settings-panel .lang-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  min-height: 44px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s;
  font-size: 14px;
  color: #f0eeea;
  font-weight: 500;
}

.settings-panel .lang-row:hover {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.15);
}

.settings-panel .lang-row.selected {
  background: rgba(255,223,158,0.12);
  border-color: rgba(255,223,158,0.4);
}

/* 顶栏语言切换按钮 */
.lang-toggle {
  font-size: 12px !important;
  font-weight: 700;
  letter-spacing: 0.5px;
  min-width: 44px;
}

/* 流式光标优化 */
.caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  background: var(--warm);
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: blink 0.8s step-end infinite;
  pointer-events: none;
  user-select: none;
}

/* 编织过渡页返回按钮 */
.weave .s-icon {
  background: rgba(255, 223, 158, 0.15);
  border-color: rgba(255, 223, 158, 0.3);
  color: var(--moon);
}

/* 流式文字容器最小高度，防止布局抖动 */
.prose p {
  min-height: 1.2em;
}

/* 流式文字渲染优化 */
#streamText {
  display: inline;
  word-break: break-word;
}

/* 减少动画偏好下的新增样式 */
@media (prefers-reduced-motion: reduce) {
  .page-leaving {
    animation: none !important;
  }

  .toast {
    transition: none;
  }

  .choice.selected {
    transform: none;
    transition: none;
  }

  .caret {
    animation: none;
  }

  /* P4-4：多孩子切换器禁用动画 */
  .child-avatar,
  .child-avatar-del {
    transition: none !important;
  }

  .child-avatar:hover {
    transform: none;
  }
}

/* ============================================================
   14. 世界书架 + 世界详情（P0-1 布局重构）
   ============================================================ */

/* ---------- 月亮石罐子（单卡片） ---------- */
.jar {
  margin: 0 18px 12px;
  border-radius: var(--radius-md);
  padding: 12px 16px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
}

.jar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.jar-stones {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pearl.md {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #fff6d8, #ffd599 50%, #f09a33 100%);
  box-shadow: 0 0 14px 3px rgba(255, 223, 158, 0.5),
    inset -2px -2px 4px rgba(240, 127, 51, 0.25);
  flex-shrink: 0;
}

.jar-num {
  font-size: 22px;
  font-weight: 700;
  color: var(--moon);
  line-height: 1;
}

.jar-streak {
  display: flex;
  align-items: center;
  gap: 6px;
}

.jar-streak-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--moon);
  white-space: nowrap;
}

.jar-dots {
  display: flex;
  gap: 3px;
}

.streak-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,223,158,0.15);
  transition: all 0.3s var(--ease);
}

.streak-dot.on {
  background: var(--warm);
  box-shadow: 0 0 4px rgba(255,154,82,0.5);
}

/* ---------- 配额行（罐子内底部） ---------- */
.jar-quota {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  font-weight: 600;
  color: var(--warm);
  text-align: center;
}

.jar-quota .q-num {
  font-size: 15px;
  font-weight: 700;
  color: var(--moon);
  margin: 0 2px;
}

.jar-quota.done {
  opacity: 0.6;
}

/* ---------- 今晚设置面板 ---------- */
.sumrow {
  margin: 0 18px 16px;
  border-radius: var(--radius-md);
  background: rgba(255,223,158,0.06);
  border: 1px solid var(--line);
  overflow: hidden;
}

.sumrow-main {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
}

.sumrow-ava {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  border: 1.5px solid rgba(255,223,158,0.3);
  flex-shrink: 0;
}

.sumrow-info {
  flex: 1;
  min-width: 0;
}

.sumrow-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--mut-strong);
}

.sumrow-interests {
  font-size: 11px;
  color: var(--mut);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sumrow-toggle {
  font-size: 12px;
  color: var(--moon);
  padding: 10px 16px;
  min-height: 44px;
  border-radius: 999px;
  background: rgba(255,223,158,0.1);
  border: 1px solid var(--line);
  white-space: nowrap;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}

.sumrow-panel {
  padding: 0 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 折叠态。原先由行内 style="display:none" 控制，
   改为 class 以便移除 CSP 的 style-src unsafe-inline。 */
.sumrow-panel.is-collapsed {
  display: none;
}

.sumrow-edit {
  width: 100%;
  font-size: 13px;
  padding: 10px 16px;
  min-height: 44px;
}

/* ---------- P4-4: 多孩子切换器 ---------- */
.child-switcher {
  padding: 6px 0 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}

.child-switcher-label {
  font-size: 12px;
  color: var(--mut-strong);
  margin-bottom: 8px;
  font-weight: 500;
}

.child-avatar-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.child-avatar {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: rgba(255, 223, 158, 0.08);
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s, background 0.2s, transform 0.15s;
  flex-shrink: 0;
  padding: 0;
}

.child-avatar:hover {
  border-color: var(--pearl);
  transform: scale(1.05);
}

.child-avatar:focus-visible {
  outline: 2px solid var(--pearl);
  outline-offset: 2px;
}

.child-avatar.active {
  border-color: var(--pearl);
  background: rgba(255, 223, 158, 0.2);
  box-shadow: 0 0 8px rgba(255, 223, 158, 0.3);
}

.child-avatar-initial {
  pointer-events: none;
  line-height: 1;
}

.child-avatar-del {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #e53e3e;
  color: #fff;
  font-size: 13px;
  line-height: 22px;
  text-align: center;
  cursor: pointer;
  border: 1px solid #fff;
  padding: 0;
  opacity: 0.7;
  transition: opacity 0.2s;
}

/* 扩展删除按钮触摸区域至 44px（视觉保持 24px） */
.child-avatar-del::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
}

.child-avatar:hover .child-avatar-del,
.child-avatar.active .child-avatar-del {
  opacity: 1;
}

.child-avatar-add {
  border-style: dashed;
  color: var(--mut);
  font-size: 22px;
  font-weight: 300;
}

.child-avatar-add:hover {
  border-color: var(--pearl);
  color: var(--pearl);
}

/* 暗色主题适配 */
.theme-night .child-avatar {
  background: rgba(255, 255, 255, 0.06);
}

.theme-night .child-avatar.active {
  background: rgba(255, 223, 158, 0.15);
}

/* ---------- 世界书架 ---------- */
.shelf {
  padding: 0 18px;
}

.shelf-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--mut-strong);
  margin-bottom: 12px;
  letter-spacing: 0.3px;
}

.wcard {
  position: relative;
  width: 100%;
  height: 152px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 12px;
  cursor: pointer;
  transition: transform 0.2s var(--ease);
  box-shadow: 0 6px 20px rgba(0,0,0,0.3);
}

.wcard:active {
  transform: scale(0.98);
}

.wcard-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.wcard-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(11,14,34,0.85) 0%, rgba(11,14,34,0.5) 50%, rgba(11,14,34,0.1) 100%);
  pointer-events: none;
}

.wcard-lock {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(11,14,34,0.55);
  backdrop-filter: blur(2px);
  font-size: 32px;
  pointer-events: none;
}

.wcard-body {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 60%;
  padding: 20px 18px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  pointer-events: none;
}

.wcard-emoji {
  font-size: 28px;
  margin-bottom: 6px;
}

.wcard-title {
  font-size: 18px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,0.4);
  margin-bottom: 4px;
}

.wcard-sub {
  font-size: 12px;
  color: rgba(255,223,158,0.7);
  margin-bottom: 10px;
}

.wcard-pips {
  display: flex;
  align-items: center;
  gap: 4px;
}

.pip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255,223,158,0.2);
  transition: all 0.3s var(--ease);
}

.pip.on {
  background: var(--warm);
  box-shadow: 0 0 5px rgba(255,154,82,0.5);
}

.pips-count {
  font-size: 11px;
  color: var(--mut);
  margin-left: 6px;
}

.wcard.locked {
  opacity: 0.7;
  cursor: not-allowed;
}

/* ---------- 骨架屏 .skel ---------- */
@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

.skel {
  background: linear-gradient(
    90deg,
    rgba(255, 223, 158, 0.06) 25%,
    rgba(255, 223, 158, 0.14) 50%,
    rgba(255, 223, 158, 0.06) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius-sm);
}

/* 骨架屏容器 */
.skel-screen {
  min-height: 100vh;
  padding: 28px 22px 40px;
}

.skel-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.skel-bar-l {
  width: 100px;
  height: 18px;
}

.skel-bar-r {
  width: 110px;
  height: 34px;
  border-radius: 999px;
}

.skel-greet {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  margin-bottom: 16px;
}

.skel-greet-ava {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex-shrink: 0;
}

.skel-greet-txt {
  flex: 1;
  height: 16px;
}

.skel-jar {
  height: 72px;
  border-radius: var(--radius-md);
  margin-bottom: 16px;
}

.skel-shelf {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.skel-card {
  display: flex;
  gap: 14px;
  padding: 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 223, 158, 0.03);
  border: 1px solid rgba(255, 223, 158, 0.06);
}

.skel-card-img {
  width: 80px;
  height: 80px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.skel-card-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  justify-content: center;
}

.skel-card-line {
  height: 14px;
}

.skel-card-line.w60 { width: 60%; }
.skel-card-line.w40 { width: 40%; }
.skel-card-line.w30 { width: 30%; }

/* 日间主题骨架屏适配 */
.frame.theme-day .skel {
  background: linear-gradient(
    90deg,
    rgba(58, 49, 38, 0.05) 25%,
    rgba(58, 49, 38, 0.10) 50%,
    rgba(58, 49, 38, 0.05) 75%
  );
  background-size: 200% 100%;
}

.frame.theme-day .skel-card {
  background: rgba(255, 255, 255, 0.4);
  border-color: rgba(58, 49, 38, 0.06);
}

/* ---------- 错误页 .err-screen ---------- */
.err-screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 32px;
  text-align: center;
}

.err-moon {
  position: relative;
  width: 88px;
  height: 88px;
  margin-bottom: 28px;
}

.err-moon::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    circle at 35% 30%,
    #fff7e0 0%,
    var(--moon) 45%,
    var(--warm) 100%
  );
  box-shadow: 0 0 30px 6px rgba(255, 223, 158, 0.4),
    0 0 60px 14px rgba(255, 154, 82, 0.2);
  animation: breathe 4s ease-in-out infinite;
}

.err-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--paper);
  margin-bottom: 10px;
}

.frame.theme-day .err-title {
  color: var(--ink);
}

.err-hint {
  font-size: 14px;
  color: var(--mut);
  max-width: 300px;
  line-height: 1.6;
  margin-bottom: 28px;
}

.frame.theme-day .err-hint {
  color: var(--ink-soft);
}

/* ---------- 世界详情：沉浸式封面 ---------- */
.world-detail {
  background: var(--night-0);
}

.wd-cover {
  position: relative;
  width: 100%;
  height: 218px;
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

.wd-cover-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11,14,34,0.3) 0%, rgba(11,14,34,0.5) 50%, rgba(11,14,34,0.95) 100%);
}

.wd-cover-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  z-index: 2;
}

.wd-cover-top .pearl-count {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--moon);
  background: rgba(11,14,34,0.5);
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
}

.wd-cover-body {
  position: absolute;
  bottom: 20px;
  left: 22px;
  right: 22px;
  z-index: 2;
}

.wd-emoji {
  font-size: 36px;
  margin-bottom: 6px;
}

.wd-title {
  font-size: 24px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0,0,0,0.5);
  line-height: 1.25;
  margin-bottom: 4px;
}

.wd-sub {
  font-size: 14px;
  color: rgba(255,223,158,0.75);
  margin-bottom: 10px;
}

.wd-pips {
  display: flex;
  align-items: center;
  gap: 5px;
}

/* ---------- 今晚可讲卡片 ---------- */
.featured {
  position: relative;
  margin: -28px 18px 16px;
  height: 162px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  cursor: pointer;
  box-shadow: 0 0 0 2px rgba(255,154,82,0.4), 0 8px 30px rgba(255,154,82,0.2);
  animation: glowPulseShadow 3s ease-in-out infinite;
  background: var(--night-1);
  will-change: box-shadow;
}

.featured-img {
  width: 40%;
  height: 100%;
  object-fit: cover;
  flex-shrink: 0;
}

.featured-body {
  flex: 1;
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.featured-tag {
  position: absolute;
  top: 12px;
  right: 14px;
  font-size: 10px;
  font-weight: 600;
  color: var(--warm-deep);
  background: rgba(255,223,158,0.9);
  padding: 3px 10px;
  border-radius: 999px;
  z-index: 2;
}

.featured-emoji {
  font-size: 22px;
  margin-bottom: 4px;
}

.featured-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--paper);
  line-height: 1.3;
  margin-bottom: 4px;
}

.featured-sub {
  font-size: 12px;
  color: var(--mut);
  margin-bottom: 8px;
}

.featured-cta {
  font-size: 13px;
  font-weight: 600;
  color: var(--warm);
}

.featured-done {
  cursor: default;
  animation: none;
  box-shadow: 0 4px 16px rgba(0,0,0,0.2);
  opacity: 0.7;
}

/* ---------- 故事网格 ---------- */
.wd-grid-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--mut-strong);
  padding: 0 18px;
  margin-bottom: 10px;
}

/* P2-6: 故事筛选标签栏 */
.wd-grid-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 18px;
  margin-bottom: 10px;
}

.wd-grid-head .wd-grid-title {
  padding: 0;
  margin-bottom: 0;
}

.wd-filter {
  display: flex;
  gap: 4px;
  background: rgba(11, 14, 34, 0.5);
  border-radius: 999px;
  padding: 3px;
}

.wd-filter-btn {
  min-height: 28px;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: var(--mut);
  white-space: nowrap;
  transition: color 0.18s var(--ease), background 0.18s var(--ease);
}

.wd-filter-btn.active {
  color: var(--paper);
  background: rgba(255, 154, 82, 0.25);
}

.wd-filter-btn:active {
  transform: scale(0.96);
}

.wd-grid-empty {
  text-align: center;
  padding: 40px 18px;
  font-size: 14px;
  color: var(--mut);
  line-height: 1.7;
}

.wd-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 0 18px;
}

.gnode {
  position: relative;
  height: 112px;
  border-radius: var(--radius-md);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.18s var(--ease);
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
}

.gnode:active {
  transform: scale(0.96);
}

.gnode-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gnode-lock {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(11,14,34,0.55);
  backdrop-filter: blur(1px);
  font-size: 22px;
  pointer-events: none;
}

.gnode-label {
  position: absolute;
  bottom: 8px;
  left: 8px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  background: rgba(11,14,34,0.7);
  border: 1px solid var(--line);
}

.gnode.done::after {
  content: '✓';
  position: absolute;
  top: 8px;
  right: 8px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #fff;
  background: var(--done);
}

.gnode.cur {
  box-shadow: 0 0 0 2px var(--warm), 0 4px 16px rgba(255,154,82,0.3);
}

.gnode.quota-done {
  opacity: 0.45;
  cursor: not-allowed;
}

.gnode.lock {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ============================================================
   英文环境排版优化
   英文文案比中文长 2-3 倍，以下规则在 .lang-en 下收紧字号、
   缩小图标、优化行高，避免大面积 2-3 行换行导致的视觉松散。
   ============================================================ */

/* 落地页：标题与副标题 */
.lang-en .landing h1 {
  font-size: 25px;
  letter-spacing: 0.2px;
  line-height: 1.25;
}
.lang-en .landing .sub {
  font-size: 13.5px;
  line-height: 1.65;
  max-width: 320px;
}
.lang-en .landing .trust {
  font-size: 11px;
  line-height: 1.55;
}

/* 落地页卖点卡片：标题与描述 */
.lang-en .prop .pt {
  font-size: 13.5px;
}
.lang-en .prop .pd {
  font-size: 12px;
  line-height: 1.5;
}

/* 故事选项：英文 label 普遍 50-68 字符，需缩小字号+图标给文字让空间 */
.lang-en .choice {
  gap: 10px;
  padding: 12px 14px;
}
.lang-en .choice .c-emoji {
  width: 32px;
  height: 32px;
  font-size: 16px;
}
.lang-en .choice .c-label {
  font-size: 13px;
  line-height: 1.4;
}
.lang-en .choice .c-hint {
  font-size: 11.5px;
  line-height: 1.45;
}

/* 今晚可讲卡片：英文标题偏长（如 Luna and the Forgetful Nightingale） */
.lang-en .featured-title {
  font-size: 14.5px;
  line-height: 1.3;
}
.lang-en .featured-sub {
  font-size: 11.5px;
  line-height: 1.45;
}
.lang-en .featured-cta {
  font-size: 12px;
}

/* 世界封面标题 */
.lang-en .wd-title {
  font-size: 22px;
}
.lang-en .wd-sub {
  font-size: 13px;
}

/* 播放器顶栏：英文朗读按钮更宽，标题需让出空间 */
.lang-en .player .bar .b-title {
  font-size: 13px;
}
.lang-en .player .bar .b-read {
  font-size: 11.5px;
  padding: 10px 12px;
  min-height: 44px;
}

/* 地图页顶栏：英文标题偏长，缩小字号避免挤压月亮石计数器 */
.lang-en .map .bar .bar-title {
  font-size: 14px;
  letter-spacing: 0.2px;
}

/* 结局页：卡片标题与正文 */
.lang-en .ehead {
  font-size: 21px;
}
.lang-en .ec-head {
  font-size: 13px;
}
.lang-en .ec-body {
  font-size: 13px;
  line-height: 1.6;
}

/* ---------- 图片懒加载占位 + 失败降级 ---------- */
/* 加载期间显示占位底色，避免空白闪烁 */
img[loading="lazy"],
img[loading="eager"] {
  background-color: var(--night-2);
}

/* 加载失败降级图：轻微降低不透明度，提示非原始配图 */
img.img-fallback {
  opacity: 0.85;
}

/* ---------- 无障碍：skip link ---------- */
/* 默认隐藏，键盘 Tab 聚焦时显示，用于跳过导航直达主内容 */
.skip-link {
  position: fixed;
  top: -60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 99999;
  padding: 10px 20px;
  border-radius: 0 0 12px 12px;
  background: var(--warm);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: top 0.2s var(--ease);
}
.skip-link:focus {
  top: 0;
  outline: 2px solid var(--moon);
  outline-offset: 2px;
}

/* 全局焦点样式：确保键盘用户可见焦点位置 */
*:focus-visible {
  outline: 2px solid var(--moon);
  outline-offset: 2px;
  border-radius: 4px;
}


/* ==================== 19. 模板工具类 ==================== */
/* 以下类替代 app.js 模板中的静态行内 style，
   为移除 CSP 的 style-src 'unsafe-inline' 而迁入，样式值保持不变。 */

/* 屏幕左上角返回按钮容器 */
.screen-back {
  position: absolute;
  top: 16px;
  left: 14px;
  z-index: 6;
}

/* 设置页：兴趣标签后的小字提示 */
.field-hint-inline {
  font-weight: 400;
  font-size: 11px;
  opacity: 0.55;
  margin-left: 6px;
}

/* 设置页：隐私说明 */
.setup-privacy {
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 10px;
  line-height: 1.5;
}

/* 设置页：未满足进入条件时的提示 */
.setup-hint {
  font-size: 12px;
  color: var(--mut);
  text-align: center;
  margin-top: 8px;
}

/* 页脚免责/说明文字。三处 padding 不同，用修饰类区分 */
.screen-foot {
  font-size: 11px;
  color: var(--mut);
  text-align: center;
  line-height: 1.7;
}

.screen-foot.foot-map {
  padding: 0 36px 30px;
}

.screen-foot.foot-world {
  padding: 16px 36px 30px;
}

.screen-foot.foot-player {
  padding: 14px 30px 0;
}

/* 世界详情页：全部通关的收尾卡片 */
.featured-body.featured-body-center {
  text-align: center;
  padding: 24px;
}

.featured-icon-lg {
  font-size: 28px;
  margin-bottom: 8px;
}

/* 结局页：奖励副标题 */
.reward-sub {
  font-size: 12px;
  color: var(--mut);
}

/* 结局页：故事卡备注 */
.card-note {
  font-size: 11px;
  color: var(--mut);
  margin-top: 8px;
}

/* 设置面板：非首个分区标题需要顶部间距 */
.sp-section-title.sp-section-gap {
  margin-top: 14px;
}

/* 家长确认弹窗 */
.gate-icon {
  text-align: center;
  font-size: 28px;
  margin-bottom: 6px;
}

.gate-cancel-btn {
  margin-top: 4px;
}

/* ==================== 20. Service Worker 更新提示 ==================== */
/* 由 js/sw-register.js 动态插入。原先该文件用 style.cssText 拼样式、
   并 createElement('style') 注入 @keyframes —— 后者属于 <style> 元素，
   在 style-src 'self' 下会被浏览器丢弃，动画静默失效（swToastIn 此前
   并未定义在任何 css 文件中）。现统一迁到这里。 */

#sw-update-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 99999;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  border-radius: 999px;
  background: rgba(22, 28, 61, 0.95);
  color: #f3e9d0;
  font-size: 14px;
  font-family: inherit;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 223, 158, 0.3);
  backdrop-filter: blur(8px);
  animation: swToastIn 0.3s ease-out;
}

@keyframes swToastIn {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

.sw-toast-btn {
  padding: 6px 16px;
  border-radius: 999px;
  background: linear-gradient(135deg, #ff9a52, #f07f33);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  font-family: inherit;
}

/* 无障碍：尊重系统的减少动效偏好 */
@media (prefers-reduced-motion: reduce) {
  #sw-update-toast {
    animation: none;
  }
}
