/* 墨小溟 · UI 样式（对齐 04-品牌设计/2026-09-29-IP形象与UI设计规范） */

:root{
  /* —— 页面与表面：染色中性色（暖调，非纯白） —— */
  --bg:#FFF8F0;
  --bg-soft:#FDF3E9;
  --surface:#FFFBF7;            /* 卡片主表面：暖白，微染色，比页面更"挺" */
  --surface-2:#FCF6EF;          /* 凹陷/次级表面（输入框、分组） */
  --surface-3:#F6EFF7;          /* 强调表面（语音盒、高亮块）淡紫白 */

  /* —— 品牌紫 —— */
  --primary:#B8A9E8;
  --primary-deep:#9E8CD8;
  --primary-soft:#F3EDFF;

  /* —— 语义点彩 —— */
  --orange:#FFB88C;
  --mint:#A8D8C8;
  --blue:#A8C8E8;
  --danger:#C98A7A;
  --danger-soft:#FFF4F0;

  /* —— 文字：三级墨色（不用纯黑） —— */
  --ink:#3A3A3A;
  --ink-2:#8A8A8A;
  --ink-3:#B0AAA4;          /* 更柔的第三级文字（不抢焦点） */

  /* —— 描边 —— */
  --line:#EFE6DC;
  --card:#FFFBF7;               /* 卡片表面（暖白，微染色） */
  --card-line:rgba(184,169,232,.18);

  /* —— 圆角阶梯 —— */
  --radius:20px;
  --r-sm:12px;   /* 芯片、小标签 */
  --r-md:18px;   /* 输入框、内分组 */
  --r-lg:24px;   /* 卡片（原 20→24，更柔） */
  --r-xl:32px;   /* 大弹层、语音盒 */
  --r-pill:999px;/* 按钮、药丸导航 */

  /* —— 柔光阴影（4 档 + 内高光，替换原有 2 档） —— */
  --hi:inset 0 1px 0 rgba(255,255,255,.9);            /* 触感内高光：让可点击面"立起来" */
  --hi-soft:inset 0 1px 1px rgba(255,255,255,.7);
  --shadow-xs:0 1px 2px rgba(94,78,140,.05), 0 2px 6px rgba(94,78,140,.06);
  --shadow-sm:0 2px 4px rgba(94,78,140,.06), 0 6px 16px rgba(94,78,140,.08);
  --shadow:0 8px 28px rgba(94,78,140,.12);
  --shadow-md:0 4px 8px rgba(94,78,140,.07), 0 12px 28px rgba(94,78,140,.12);
  --shadow-lg:0 8px 16px rgba(94,78,140,.10), 0 24px 48px rgba(94,78,140,.16);
  --shadow-press:0 1px 2px rgba(94,78,140,.10), inset 0 1px 3px rgba(94,78,140,.14);

  /* —— 动效：时长 + 曲线（克制，服务信息） —— */
  --dur-fast:140ms; --dur:220ms; --dur-slow:340ms;
  --ease-spring:cubic-bezier(.34,1.56,.64,1);  /* 弹性进出/按压 */
  --ease-out:cubic-bezier(.22,1,.36,1);        /* 柔减速 */
  --ease:cubic-bezier(.34,1.3,.64,1);          /* 保留旧引用 */

  /* —— 玻璃（手术式用于临时浮层） —— */
  --glass-bg:rgba(255,251,247,.72); --glass-brd:rgba(255,255,255,.6); --glass-blur:18px;

  /* —— 结构渐变（不是装饰，是"哪里是主操作"的提示） —— */
  --grad-primary:linear-gradient(135deg,#C3B4EE 0%,#9E8CD8 100%);
  --grad-brand:linear-gradient(135deg,#FFF8F0 0%,#F3EDFF 100%);
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei","Segoe UI",Roboto,sans-serif;
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer;border:0;background:none;color:inherit}

.app{
  max-width:480px;margin:0 auto;min-height:100dvh;position:relative;
  background:var(--bg);display:flex;flex-direction:column;
}
.view{flex:1;padding:22px 20px 108px;overflow-x:hidden}
body:not(.has-nav) .view{padding-bottom:28px}
body:not(.has-nav) .tabbar{display:none}

/* ---------- 通用 ---------- */
.page-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}
.page-title{font-size:15px;color:var(--ink-2);letter-spacing:.04em}
.page-title.center{text-align:center;margin:6px 0 20px;font-size:18px;color:var(--ink)}
.ghost{font-size:14px;color:var(--ink-2);padding:6px 2px;min-width:48px;text-align:left}
.ghost:last-child{text-align:right}
.primary{
  display:block;width:100%;padding:15px 18px;margin-top:16px;border:0;border-radius:var(--r-pill);
  background:var(--grad-primary);color:#fff;font-size:16px;font-weight:600;letter-spacing:.3px;
  box-shadow:var(--shadow-md),var(--hi);
  transition:transform var(--dur) var(--ease-spring),box-shadow var(--dur) var(--ease-out),filter var(--dur-fast);
  cursor:pointer;
}
.primary:active{transform:scale(.975) translateY(1px);box-shadow:var(--shadow-press);filter:brightness(1.05)}
.primary.small{display:inline-block;width:auto;padding:11px 22px;font-size:15px}
.linkbtn{color:var(--primary-deep);font-size:14px;padding:8px 4px}
.row-center{text-align:center;margin-top:8px}
.row-end{text-align:right;margin-top:-4px}
.foot-note{text-align:center;color:var(--ink-2);font-size:12.5px;line-height:1.8;margin-top:26px}
.loading{text-align:center;color:var(--ink-2);padding:60px 0}
.muted{color:var(--ink-2)}

/* ---------- 墨小溟 IP（云朵水母 v1.2 升级） ----------
   颜色全部走 --ip-* 变量 ⇒ 切状态只换变量 + 挂动画，SVG 结构零变化。
   状态语义：待机呼吸浮动 / 倾听前倾+触角发光+随声波晃 / 思考淡紫+触角打转 /
             共情暖橙+眼湿润 / 开心弹跳+光点变亮 / 担心灰蓝+触角下垂 /
             愤怒暗红+双眉紧锁+触角震颤 / 焦虑亮紫闪烁+眉头微蹙。

   🔴 v1.2 @property 注册：把 --ip-* 颜色/数值变量注册成「可插值」的自定义属性，
      并在 .mascot 上挂 transition ⇒ 状态切换时颜色像水流般晕染，不再硬跳变。
      数值变量（--ip-vol/pitch/rate/tension/shrink）由录音探针每帧写入 documentElement，
      同样走平滑过渡，墨小溟对声音的反应是连续柔顺的。 */
@property --ip-body-in  { syntax: '<color>';  inherits: true; initial-value: #F3EEFF; }
@property --ip-body-mid { syntax: '<color>';  inherits: true; initial-value: #D9CDF5; }
@property --ip-body-out { syntax: '<color>';  inherits: true; initial-value: #B8A9E8; }
@property --ip-antenna  { syntax: '<color>';  inherits: true; initial-value: #C0B0EC; }
@property --ip-tip      { syntax: '<color>';  inherits: true; initial-value: #FFD9A8; }
@property --ip-glow     { syntax: '<color>';  inherits: true; initial-value: #FFE7C4; }
@property --ip-glow-2   { syntax: '<color>';  inherits: true; initial-value: #CFE4F7; }
@property --ip-eye-top  { syntax: '<color>';  inherits: true; initial-value: #6C6689; }
@property --ip-eye      { syntax: '<color>';  inherits: true; initial-value: #4E4969; }
@property --ip-halo     { syntax: '<color>';  inherits: true; initial-value: #C9BCF0; }
@property --ip-wet      { syntax: '<color>';  inherits: true; initial-value: #EAF4FF; }
@property --ip-blush    { syntax: '<color>';  inherits: true; initial-value: #FFC4A2; }
@property --ip-vol      { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --ip-pitch    { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --ip-rate     { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --ip-tension  { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --ip-shrink   { syntax: '<number>'; inherits: true; initial-value: 0; }
.mascot{
  overflow:visible;display:block;
  --ip-body-in:#F3EEFF;--ip-body-mid:#D9CDF5;--ip-body-out:#B8A9E8;
  --ip-antenna:#C0B0EC;--ip-tip:#FFD9A8;
  --ip-glow:#FFE7C4;--ip-glow-2:#CFE4F7;
  --ip-eye-top:#6C6689;--ip-eye:#4E4969;
  --ip-halo:#C9BCF0;--ip-wet:#EAF4FF;--ip-blush:#FFC4A2;
  /* 颜色变量平滑过渡（@property 让它们可插值，消灭硬跳变）；数值变量响应更快（实时探针每帧写）
     🔴 时长必须落在 state-machine.js 的 TRANSITION.minMs(600) ~ maxMs(1200) 区间内 ——
        规格 §三 明确要求情绪切换是 0.6~1.2s 的柔和晕染，低于 0.6s 就会被读成硬跳变。
        这里取 0.8s（区间中值偏慢）；改这里要同步 `_selftest/ip-state-selftest.cjs` 的区间断言。 */
  transition:
    --ip-body-in .8s ease, --ip-body-mid .8s ease, --ip-body-out .8s ease,
    --ip-antenna .8s ease, --ip-tip .8s ease, --ip-glow .8s ease, --ip-glow-2 .8s ease,
    --ip-eye-top .8s ease, --ip-eye .8s ease, --ip-halo .8s ease, --ip-wet .8s ease, --ip-blush .8s ease,
    --ip-vol .14s linear, --ip-pitch .2s ease, --ip-rate .2s ease, --ip-tension .2s ease, --ip-shrink .4s ease;
}
.mascot__body{transform-origin:100px 116px}
.mascot__antennae{transform-origin:100px 52px}
.mascot__wisps{transform-origin:100px 150px}
.ant{transform-origin:82px 52px}
.ant--r{transform-origin:118px 52px}
.mascot__glows{transform-origin:100px 116px}

/* 待机：缓慢呼吸 + 轻微浮动 —— 6s 一整圈（浮动/呼吸/微光/垂须同周期，才像同一口呼吸） */
.mascot--idle{animation:ip-float var(--mm-float-ms, 6s) ease-in-out infinite}
.mascot--idle .mascot__body{animation:ip-breathe var(--mm-breathe-ms, 6s) ease-in-out infinite}
.mascot--idle .glow{animation:ip-drift 6s ease-in-out infinite}
.mascot--idle .glow--2{animation-duration:7.8s;animation-delay:-1.2s}
.mascot--idle .glow--3{animation-duration:5.8s;animation-delay:-2.4s}
.mascot--idle .glow--4{animation-duration:7s;animation-delay:-3.4s}
.mascot--idle .mascot__wisp{animation:ip-wisp var(--mm-wisp-ms, 6s) ease-in-out infinite}
.mascot--idle .wisp--2{animation-delay:-1.6s}

/* 八条垂须分组时序（v1.6.3 动效配置化）：不统一摆动，模拟真实水生生物不同步的呼吸。
   幅度全部 ≤3deg / ≤2px，无弹跳无冲击。分组只作用于待机（用户 90% 时间看的那一态）。 */
.mascot--idle .tentacle--g2{animation-delay:.5s}                            /* 3/4 号：滞后 0.5s 跟随 */
.mascot--idle .tentacle--g3{animation-name:ip-wisp-tiny}                    /* 5/6 号：仅 2px 呼吸起伏 */
.mascot--idle .tentacle--g4{animation-name:ip-wisp-still;animation-duration:9s;animation-delay:-2s;opacity:.7} /* 7/8 号：几乎不动，作锚定 */
@keyframes ip-wisp-tiny{0%,100%{transform:translateY(0)}50%{transform:translateY(var(--mm-wisp-tiny-amp, 2px))}}
@keyframes ip-wisp-still{0%,100%{transform:rotate(calc(-1 * var(--mm-wisp-still-amp, 1deg)))}50%{transform:rotate(var(--mm-wisp-still-amp, 1deg))}}

/* 总开关沿用既有 body.ip-motion-off（设置项「IP互动动画」）：
   那套规则已经把 .mascot / 涟漪 / 呼吸环全停掉 = 极致省电的极简安静模式。
   🔴 这里**不另造 class**——另造一个就变成"两个开关管同一件事"，关了这个那个还在动。 */

/* 倾听：身体微微前倾 + 触角发光 + 随声波轻晃 */
.mascot--listening{animation:ip-lean 2.8s ease-in-out infinite}
.mascot--listening .ant--l{animation:ip-ant-l 1.5s ease-in-out infinite}
.mascot--listening .ant--r{animation:ip-ant-r 1.5s ease-in-out infinite}
.mascot--listening .mascot__tip{animation:ip-tip 1s ease-in-out infinite}
.mascot--listening .mascot__tip-glow{animation:ip-tipglow 1s ease-in-out infinite}
.mascot--listening .mascot__halo{opacity:.95}
.mascot--listening .glow{animation:ip-sway 1.3s ease-in-out infinite}
.mascot--listening .glow--2{animation-delay:-.32s}
.mascot--listening .glow--3{animation-delay:-.65s}
.mascot--listening .glow--4{animation-delay:-.95s}
.mascot--listening .mascot__wisp{animation:ip-sway 1.1s ease-in-out infinite}
.mascot--listening .wisp--2{animation-delay:-.3s}
.mascot--listening .wisp--3{animation-delay:-.6s}

/* 倾听·微动作增强（v1.2）：点头 + 实时语音特征驱动（--ip-vol/pitch/rate/tension/shrink 由录音流探针每帧写入 documentElement）
   · 音量→发光强度 + 呼吸急促（tip-glow 放大、body 微胀）
   · 音高→触角抖动频率/幅度（pitch 越高，摆动越快）
   · 语速→身体微动（rate 越大，点头幅度越大）
   · 张力→触角前倾紧绷（tension=音量*0.55+语速*0.45，录音中"克制"的提前紧绷信号）
   · 收缩→声音变小+长停顿，身体微缩预备共情（克制，不真下结论） */
.mascot--listening .mascot__body{animation:ip-breathe-nod 3.2s ease-in-out infinite}
.mascot--listening .mascot__antennae{transform:rotate(calc(var(--ip-vol,0) * 4deg + var(--ip-tension,0) * 7deg));transition:transform .15s ease}
.mascot--listening .ant--l{animation:ip-ant-l calc(1.5s - var(--ip-pitch,0) * 1.15s) ease-in-out infinite}
.mascot--listening .ant--r{animation:ip-ant-r calc(1.5s - var(--ip-pitch,0) * 1.15s) ease-in-out infinite}
.mascot--listening .mascot__tip-glow{transform-box:fill-box;transform-origin:center;transform:scale(calc(1 + var(--ip-vol,0) * .9));transition:transform .15s ease}
.mascot--listening .mascot__tip{opacity:calc(.55 + var(--ip-vol,0) * .45)}

/* 共情·落泪（v1.2）：暖橙 + 眼湿润 + 泪滴滑落 */
.mascot--empathy_tears{
  --ip-body-in:#FFF1E0;--ip-body-mid:#FFD2AC;--ip-body-out:#FFBE8C;
  --ip-halo:#FFD0A4;--ip-tip:#FF9E5E;--ip-antenna:#EFB28A;
  --ip-glow:#FFD29A;--ip-glow-2:#FFE7CE;
}
.mascot--empathy_tears .mascot__body{animation:ip-breathe 3.8s ease-in-out infinite}
.mascot--empathy_tears .wet{opacity:.9}
.mascot--empathy_tears .blush{opacity:.5}
.mascot--empathy_tears .mascot__tears{opacity:1;animation:ip-tear 2.6s ease-in infinite}
.mascot--empathy_tears .glow{animation:ip-drift 4.6s ease-in-out infinite}

/* 温柔凝视（v1.2）：柔和偏暖紫 + 轻微前倾 + 缓慢呼吸 */
.mascot--tender{
  --ip-body-in:#F6F0FF;--ip-body-mid:#E2D6FA;--ip-body-out:#C9B9F0;
  --ip-halo:#E6DAFF;--ip-tip:#FFCFA0;--ip-antenna:#CBBBF0;
  --ip-glow:#FFE9CC;--ip-glow-2:#E0ECFA;
}
.mascot--tender{animation:ip-lean 3.4s ease-in-out infinite}
.mascot--tender .mascot__body{animation:ip-breathe 4.6s ease-in-out infinite}
.mascot--tender .blush{opacity:.3}
.mascot--tender .mascot__tip{animation:ip-tip 1.6s ease-in-out infinite}
.mascot--tender .glow{animation:ip-drift 5.6s ease-in-out infinite}

/* 担心·皱眉（v1.2）：眉毛浮现并向内下压 */
.mascot__brow{opacity:0;transition:opacity .3s ease}
.brow{transform-box:fill-box;transform-origin:center;transition:transform .3s ease}
.mascot--worried .mascot__brow{opacity:.85}
.mascot--worried .brow--l{transform:rotate(13deg)}
.mascot--worried .brow--r{transform:rotate(-13deg)}

/* 共情·泪滴（v1.2）：默认隐藏，仅共情落泪态浮现 */
.mascot__tears{opacity:0;transition:opacity .3s ease}

/* 开心·星光鼓励（v1.2）：星光浮现并轻闪 */
.mascot__spark{opacity:0}
.spark{transform-box:fill-box;transform-origin:center;transition:opacity .3s ease}
.mascot--happy .mascot__spark{opacity:1;animation:ip-spark 1.4s ease-in-out infinite}

/* 呼吸引导环（录音停顿>3s）：缓慢张缩，引导用户跟着呼吸 */
.mascot__breath{transition:opacity .4s ease}
body.recording--breath .mascot--listening .mascot__breath{opacity:.55;animation:ip-breath-ring 5.5s ease-in-out infinite}

/* 防呆气泡（等待>10s）：墨小溟主动说一句安心的话（DOM 元素，位于分析页） */
.stuck-bubble{
  display:block;margin:16px auto 0;max-width:248px;text-align:center;padding:10px 16px;
  background:var(--primary-soft);color:var(--primary-deep);border-radius:999px;
  font-size:14px;line-height:1.5;box-shadow:var(--shadow-sm);
  opacity:0;transform:translateY(6px);transition:opacity .4s ease,transform .4s ease;pointer-events:none;
}
body.thinking--stuck .stuck-bubble{opacity:1;transform:translateY(0)}

/* 思考：身体变淡紫 + 触角打转 */
.mascot--thinking{--ip-body-in:#EDE6FF;--ip-body-mid:#D2C4FA;--ip-body-out:#B6A3EF;--ip-halo:#D8CAFF;--ip-tip:#D9C3FF}
.mascot--thinking .mascot__body{animation:ip-breathe 3.2s ease-in-out infinite}
.mascot--thinking .ant--l{animation:ip-stir-l 2.2s ease-in-out infinite}
.mascot--thinking .ant--r{animation:ip-stir-r 2.2s ease-in-out infinite}
.mascot--thinking .mascot__tip-glow{animation:ip-tipglow 1.6s ease-in-out infinite}
.mascot--thinking .glow{animation:ip-drift 3.4s ease-in-out infinite}
.mascot--thinking .mascot__wisp{animation:ip-wisp 2.6s ease-in-out infinite}

/* 共情：身体变暖橙 + 眼睛变湿润 */
.mascot--empathy{
  --ip-body-in:#FFF3E4;--ip-body-mid:#FFD9B6;--ip-body-out:#FFC79B;
  --ip-halo:#FFD9B0;--ip-tip:#FFB27A;--ip-antenna:#F0BE97;
  --ip-glow:#FFD9A8;--ip-glow-2:#FFE9CF;
}
.mascot--empathy .mascot__body{animation:ip-breathe 3.8s ease-in-out infinite}
.mascot--empathy .wet{opacity:.85}   /* 元素类名是 .wet（与 .glow/.blush 一致），写 .mascot__wet 会永不生效 */
.mascot--empathy .blush{opacity:.42}
.mascot--empathy .glow{animation:ip-drift 4.6s ease-in-out infinite}
.mascot--empathy .mascot__wisp{animation:ip-wisp 4s ease-in-out infinite}

/* 开心：轻轻弹跳 + 内部光点变亮 */
.mascot--happy{
  --ip-body-in:#FFF0DC;--ip-body-mid:#FFD3A8;--ip-body-out:#FFC08C;
  --ip-halo:#FFD2A4;--ip-tip:#FFAB6E;--ip-antenna:#EFB98F;
  --ip-glow:#FFE0B0;--ip-glow-2:#FFF0DA;
}
.mascot--happy{animation:ip-hop 1.25s ease-in-out infinite}
.mascot--happy .mascot__tip-glow{animation:ip-tipglow 1.25s ease-in-out infinite}
.mascot--happy .glow{animation:ip-blink 1.4s ease-in-out infinite}
.mascot--happy .glow--2{animation-delay:-.38s}
.mascot--happy .glow--3{animation-delay:-.72s}
.mascot--happy .glow--4{animation-delay:-1.05s}
.mascot--happy .blush{opacity:.5}
.mascot--happy .mascot__wisp{animation:ip-wisp 1.5s ease-in-out infinite}

/* 担心：身体变灰蓝 + 触角下垂（左右分别向外下垂，末端光点跟随） */
.mascot--worried{
  --ip-body-in:#EDF1F6;--ip-body-mid:#CBD8E4;--ip-body-out:#A9BCCD;
  --ip-halo:#C2D0DC;--ip-tip:#9FB3C4;--ip-antenna:#A9BCCD;
  --ip-glow:#DCE7F1;--ip-glow-2:#C9DAE8;
  --ip-eye-top:#5F6A78;--ip-eye:#4C5662;--ip-wet:#DDE9F4;--ip-blush:#C7D4E0;
}
.mascot--worried .ant--l{transform:rotate(-25deg)}
.mascot--worried .ant--r{transform:rotate(25deg)}
.mascot--worried .mascot__eyes{transform:translateY(1.6px)}
.mascot--worried .glow{opacity:.34}
.mascot--worried .mascot__wisp{animation:ip-wisp 6.4s ease-in-out infinite}

@keyframes ip-float{0%,100%{transform:translateY(0)}50%{transform:translateY(calc(-1 * var(--mm-float-range, 6px)))}}
@keyframes ip-breathe{0%,100%{transform:scale(1)}50%{transform:scale(calc(1 + var(--mm-breathe-scale, .035)))}}
@keyframes ip-lean{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-4px) rotate(-2.4deg)}}
@keyframes ip-ant-l{0%,100%{transform:rotate(-2deg)}50%{transform:rotate(5deg)}}
@keyframes ip-ant-r{0%,100%{transform:rotate(2deg)}50%{transform:rotate(-5deg)}}
@keyframes ip-stir-l{0%{transform:rotate(0)}25%{transform:rotate(15deg)}50%{transform:rotate(0)}75%{transform:rotate(-15deg)}100%{transform:rotate(0)}}
@keyframes ip-stir-r{0%{transform:rotate(0)}25%{transform:rotate(-15deg)}50%{transform:rotate(0)}75%{transform:rotate(15deg)}100%{transform:rotate(0)}}
@keyframes ip-tip{0%,100%{opacity:.6;r:4.4}50%{opacity:1;r:6.2}}
@keyframes ip-tipglow{0%,100%{opacity:.14}50%{opacity:.42}}
@keyframes ip-hop{0%,100%{transform:translateY(0)}40%{transform:translateY(-9px)}70%{transform:translateY(0)}}
@keyframes ip-blink{0%,100%{opacity:.4}50%{opacity:.95}}
@keyframes ip-drift{0%,100%{transform:translate(0,0)}33%{transform:translate(3px,-4px)}66%{transform:translate(-3px,3px)}}
@keyframes ip-sway{0%,100%{transform:translateX(-1.6px)}50%{transform:translateX(1.6px)}}
@keyframes ip-wisp{0%,100%{transform:rotate(calc(-1 * var(--mm-wisp-amp, 3deg)))}50%{transform:rotate(var(--mm-wisp-amp, 3deg))}}
@keyframes ip-breathe-nod{0%,100%{transform:scale(calc(1 + var(--ip-vol,0) * .08 + var(--ip-rate,0) * .04 - var(--ip-shrink,0) * .06)) translateY(0)}50%{transform:scale(calc(1 + var(--ip-vol,0) * .08 + var(--ip-rate,0) * .04 - var(--ip-shrink,0) * .06)) translateY(2px)}}
@keyframes ip-tear{0%{transform:translateY(-2px);opacity:0}12%{opacity:.9}100%{transform:translateY(13px);opacity:0}}
@keyframes ip-spark{0%,100%{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1.15)}}
@keyframes ip-breath-ring{0%,100%{transform:scale(.92);opacity:.5}50%{transform:scale(1.08);opacity:.14}}

/* 待机/倾听眨眼（v1.2）：眼睛周期性轻眨，让墨小溟"活"起来 */
@keyframes ip-blink-eye{0%,92%,100%{transform:scaleY(1)}95.5%{transform:scaleY(.08)}98%{transform:scaleY(1)}}
.mascot--idle .mascot__eyes,
.mascot--listening .mascot__eyes{
  transform-box:fill-box;transform-origin:center;
  animation:ip-blink-eye 5.4s ease-in-out infinite;
}

/* 愤怒·暗红（v1.2）：暗红身体 + 双眉下压紧锁 + 触角快速震颤 */
@keyframes ip-shake-l{0%,100%{transform:rotate(0)}25%{transform:rotate(-7deg)}75%{transform:rotate(7deg)}}
@keyframes ip-shake-r{0%,100%{transform:rotate(0)}25%{transform:rotate(7deg)}75%{transform:rotate(-7deg)}}
.mascot--angry{
  --ip-body-in:#FFE6E2;--ip-body-mid:#F2A99E;--ip-body-out:#DC7368;
  --ip-halo:#EF9E92;--ip-tip:#E0624C;--ip-antenna:#D88A7E;
  --ip-glow:#F6C4BA;--ip-glow-2:#F2D2CB;
  --ip-eye-top:#7A4A44;--ip-eye:#5C332E;--ip-wet:#F4D9D2;--ip-blush:#F2A99E;
  animation:ip-float 5s ease-in-out infinite;
}
.mascot--angry .mascot__body{animation:ip-breathe 2.1s ease-in-out infinite}
.mascot--angry .mascot__brow{opacity:.92}
.mascot--angry .brow--l{transform:rotate(22deg)}
.mascot--angry .brow--r{transform:rotate(-22deg)}
.mascot--angry .ant--l{animation:ip-shake-l .16s ease-in-out infinite}
.mascot--angry .ant--r{animation:ip-shake-r .16s ease-in-out infinite}
.mascot--angry .blush{opacity:.16}

/* 焦虑·亮紫/暗紫交替闪烁（v1.2）：身体在亮紫与暗紫间快速呼吸；眉头微蹙 + 触角轻颤 */
.mascot--anxious{
  --ip-body-in:#F1E8FF;--ip-body-mid:#C7B1F4;--ip-body-out:#A88FE0;
  --ip-halo:#D6C2FF;--ip-tip:#C6A6FF;--ip-antenna:#BBA1EC;
  --ip-glow:#E6D6FF;--ip-glow-2:#CFC0F0;
  --ip-eye-top:#675A8C;--ip-eye:#4E4470;--ip-wet:#E5DCFF;--ip-blush:#CDB6F2;
  animation:ip-float 4.4s ease-in-out infinite, ip-anx-flicker 1.05s ease-in-out infinite;
}
.mascot--anxious .mascot__body{animation:ip-breathe 3s ease-in-out infinite}
.mascot--anxious .mascot__brow{opacity:.5}
.mascot--anxious .brow--l{transform:rotate(11deg)}
.mascot--anxious .brow--r{transform:rotate(-11deg)}
.mascot--anxious .ant--l{animation:ip-stir-l 1.6s ease-in-out infinite}
.mascot--anxious .ant--r{animation:ip-stir-r 1.6s ease-in-out infinite}
.mascot--anxious .blush{opacity:.22}
@keyframes ip-anx-flicker{
  0%,100%{--ip-body-mid:#C7B1F4;--ip-body-out:#A88FE0;--ip-halo:#D6C2FF}
  50%{--ip-body-mid:#9377D8;--ip-body-out:#6E50B8;--ip-halo:#A684EA}
}

/* 圆形头像容器（我的页顶部 / 列表小脸） */
.avatar{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  border-radius:50%;overflow:hidden;
  background:radial-gradient(circle at 42% 34%,#FBF6FF,#F1E9FC 72%);
  box-shadow:0 3px 12px rgba(160,140,200,.18), inset 0 0 0 1px rgba(184,169,232,.22);
}
.avatar .mascot{width:84%;height:84%}   /* 留出余量，避免圆形裁掉头顶触角 */
.miniface{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}
.miniface .mascot{width:100%;height:100%}

/* ---------- 首页 / 说 ---------- */
.say{display:flex;flex-direction:column;min-height:calc(100dvh - 150px)}
/* §1.2 排版收紧：问候语 / IP / 按钮三段之间的距离收一收，视觉重心落在「按住说」 */
.say__head{margin-bottom:0}
.say__date{font-size:13px;color:var(--ink-2);letter-spacing:.05em}
.say__greet{font-size:23px;font-weight:600;margin:4px 0 0;line-height:1.4}
.say__mascot{display:flex;justify-content:center;padding:12px 0 2px}
.say__action{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%}
.talkbtn{
  width:176px;height:176px;border-radius:50%;position:relative;
  /* 两层：上层白色高光是球感的来源，下层是「主紫 → 浅紫」的微渐变（不是一块死色） */
  background:
    radial-gradient(circle at 34% 24%,rgba(255,255,255,.46) 0%,rgba(255,255,255,.10) 34%,rgba(255,255,255,0) 62%),
    linear-gradient(158deg,var(--primary) 0%,#C6B9F0 52%,#D9D0F7 100%);
  color:#fff;
  box-shadow:
    0 16px 40px rgba(150,130,200,.34),
    0 4px 12px rgba(150,130,200,.20),
    inset 0 2px 10px rgba(255,255,255,.42),
    inset 0 -8px 18px rgba(140,120,190,.20);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  transition:transform .18s cubic-bezier(.34,1.4,.64,1),box-shadow .22s ease,background .3s ease;
  touch-action:none;user-select:none;
  /* 待机外发光：极缓慢地明暗呼吸，看起来「柔软的、想让人按下去」 */
  animation:btn-halo 4.2s ease-in-out infinite;
}
@keyframes btn-halo{
  0%,100%{filter:drop-shadow(0 10px 18px rgba(184,169,232,.28))}
  50%{filter:drop-shadow(0 15px 30px rgba(184,169,232,.50))}
}
/* 边缘柔光（待机脉冲，吸引点击） */
.talkbtn::before{
  content:"";position:absolute;inset:-9px;border-radius:50%;
  background:radial-gradient(circle,rgba(184,169,232,.34),rgba(184,169,232,0) 68%);
  animation:btn-glow 3.4s ease-in-out infinite;pointer-events:none;
}
/* 呼吸扩散环 */
.talkbtn::after{content:"";position:absolute;inset:-15px;border-radius:50%;border:1.5px solid rgba(184,169,232,.32);animation:ring 3.8s ease-out infinite;pointer-events:none}
@keyframes ring{0%{transform:scale(.94);opacity:.7}100%{transform:scale(1.12);opacity:0}}
@keyframes btn-glow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.035)}}
.talkbtn__label{font-size:22px;font-weight:600;letter-spacing:.08em;text-shadow:0 1px 6px rgba(120,100,170,.28)}
.talkbtn__timer{font-size:12px;opacity:0;height:0}
.talkbtn:active,.talkbtn--press{transform:scale(.955);box-shadow:0 8px 22px rgba(140,120,190,.46),0 0 30px rgba(184,169,232,.55),inset 0 2px 10px rgba(255,255,255,.5)}
.talkbtn--live{transform:scale(1.055);box-shadow:0 18px 44px rgba(230,150,110,.40),0 0 34px rgba(255,184,140,.55),inset 0 2px 10px rgba(255,255,255,.5)}
.talkbtn--live::before{background:radial-gradient(circle,rgba(255,184,140,.42),rgba(255,184,140,0) 68%);animation-duration:1.6s}
.talkbtn--live::after{border-color:rgba(255,184,140,.44);animation-duration:1.5s}
.talkbtn--live .talkbtn__timer{opacity:.96;height:auto;font-size:16px;margin-top:5px;letter-spacing:.04em}
.talkbtn--live .talkbtn__label{font-size:13.5px;opacity:.9;font-weight:500}
.talkbtn--live{background:
  radial-gradient(circle at 34% 24%,rgba(255,255,255,.48) 0%,rgba(255,255,255,.12) 34%,rgba(255,255,255,0) 62%),
  linear-gradient(158deg,var(--orange) 0%,#FFCFA6 52%,#FFE3CB 100%)}
/* 录音波形（放在按钮内，随声波起伏；仅录音时出现） */
.talkbtn .wave{opacity:0;height:0;margin:0;transition:opacity .22s ease,height .22s ease,margin .22s ease}

/* ===== v1.4.5 · 追问页迷你「按住说」（语音优先、文字兜底的双通道） =====
   复用首页 talkbtn 的球体质感与配色（同一套设计令牌），只缩小尺寸、收敛动效幅度，
   视觉上与页面元素同级，不抢主内容的戏。 */
.fu-voice{display:flex;flex-direction:column;align-items:center;gap:8px;margin:0 0 12px}
.talkbtn--mini{width:104px;height:104px;animation-duration:5.6s}
.talkbtn--mini::before{inset:-6px}
.talkbtn--mini::after{inset:-10px;border-width:1px}
.talkbtn--mini .talkbtn__label{font-size:14px;font-weight:600}
.talkbtn--mini .talkbtn__timer{font-size:11px}
.talkbtn--mini.talkbtn--live .talkbtn__timer{font-size:13px;margin-top:3px}
.talkbtn--mini.talkbtn--live .talkbtn__label{font-size:11.5px}
/* 滑出取消的视觉反馈：短暂变灰 + 文案变化（「已取消」），让用户明确知道这次不会提交 */
.talkbtn--cancel{filter:grayscale(.55);opacity:.75}
.fu-voice__hint{font-size:12.5px;color:var(--ink-soft,#8b84a8);min-height:17px;text-align:center;transition:opacity .25s ease}
.talkbtn--live .wave{opacity:1;height:20px;margin-top:8px}
.wave{display:flex;align-items:flex-end;justify-content:center;gap:3px;height:20px}
.wave i{display:block;width:3px;border-radius:2px;background:rgba(255,255,255,.9);height:5px;animation:wave 1.05s ease-in-out infinite}
.wave i:nth-child(2){animation-delay:.12s}
.wave i:nth-child(3){animation-delay:.24s}
.wave i:nth-child(4){animation-delay:.36s}
.wave i:nth-child(5){animation-delay:.48s}
.wave i:nth-child(6){animation-delay:.6s}
.wave i:nth-child(7){animation-delay:.72s}
@keyframes wave{0%,100%{height:5px;opacity:.65}50%{height:19px;opacity:1}}
.say__hint{color:var(--ink-2);font-size:14px;margin:0}
.say__type{color:var(--primary-deep);font-size:14px;padding:8px 10px;border-radius:999px;transition:background .2s,transform .16s}
.say__type:active{transform:scale(.96);background:rgba(184,169,232,.14)}
.say__live{margin-top:14px;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm),var(--hi-soft)}
.live-label{font-size:12px;color:var(--primary-deep);letter-spacing:.08em;margin-bottom:4px}
.live-text{font-size:15px;color:var(--ink);min-height:24px}
.recent{display:block;margin-top:auto;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm),var(--hi-soft)}
.recent__label{font-size:12px;color:var(--ink-2);margin-bottom:8px}
.recent__row{display:flex;gap:12px;align-items:center}
.recent__title{font-size:15px;font-weight:600}
.recent__meta{font-size:12.5px;color:var(--ink-2)}
.empty-hint{margin-top:auto;text-align:center;color:var(--ink-2);font-size:13.5px;padding:18px 0}

/* ---------- 录音 / 输入 ---------- */
.record__mascot,.fu-mascot,.cf-mascot,.stage-mascot{display:flex;justify-content:center;padding:8px 0 14px}
/* 倾听节点要在 IP 下方挂「我在听」常显气泡，故单独改为纵向排列 */
.record__mascot{flex-direction:column;align-items:center}
.big-input{
  width:100%;min-height:150px;border-radius:var(--radius);border:1.5px solid var(--line);
  background:var(--surface-2);box-shadow:var(--hi-soft);padding:16px;font-size:16px;line-height:1.7;color:var(--ink);resize:vertical;
  outline:none;font-family:inherit;
}
.big-input:focus{border-color:var(--primary)}
.rec-live{display:flex;align-items:center;justify-content:center;gap:8px;font-size:20px;font-weight:600;color:var(--primary-deep);margin:8px 0}
.rec-live .dot{width:9px;height:9px;border-radius:50%;background:var(--orange);animation:ip-blink 1.1s ease-in-out infinite}
.record .live-text{text-align:center;color:var(--ink-2);min-height:60px;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:14px;box-shadow:var(--shadow-sm),var(--hi-soft)}

/* ---------- 舞台（分析中） ---------- */
.center-stage{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:66dvh;gap:18px}
.stage-copy{font-size:17px;color:var(--ink-2);letter-spacing:.03em}
/* v1.5 §2.2 流式输出：主分析一边生成一边逐字回显的「温柔总结」；未取到内容时隐藏，避免占位跳动 */
.stage-summary{font-size:15px;line-height:1.75;color:var(--ink);max-width:300px;text-align:left;
  min-height:0;white-space:pre-wrap;word-break:break-word;letter-spacing:.01em;opacity:.96}
.stage-summary:empty{display:none}

/* ---------- 追问 ---------- */
.fu-echo{color:var(--ink-2);font-size:14px;background:var(--surface);border:1px solid var(--card-line);border-radius:16px;padding:12px 14px;box-shadow:var(--shadow-sm),var(--hi-soft);margin:0 0 14px}
.fu-question{font-size:19px;font-weight:600;line-height:1.55;margin:6px 0 16px}

/* ---------- 确认卡片 ---------- */
.cf-lead{font-size:20px;margin:6px 0 4px;text-align:center}
.cf-sub{text-align:center;color:var(--ink-2);font-size:13.5px;margin:0 0 18px}
.fld{display:block;margin-bottom:13px}
.fld__label{display:block;font-size:13px;color:var(--ink-2);margin-bottom:5px}
.fld__input,.fld__range{
  width:100%;border-radius:14px;border:1.5px solid var(--line);background:var(--surface-2);box-shadow:var(--hi-soft);
  padding:12px 13px;font-size:15px;color:var(--ink);outline:none;font-family:inherit;
}
.fld__input:focus{border-color:var(--primary)}
.fld__range{
  -webkit-appearance:none;appearance:none;
  width:100%;height:26px;padding:0;border:0;background:transparent;outline:none;
}
/* 柔和紫轨道（原来依赖 accent-color，Chrome 下会渲染成刺眼深灰） */
.fld__range::-webkit-slider-runnable-track{
  height:8px;border-radius:999px;
  background:linear-gradient(90deg,rgba(184,169,232,.80),rgba(184,169,232,.28));
}
.fld__range::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:22px;height:22px;margin-top:-7px;border-radius:50%;
  background:#fff;border:0;box-shadow:var(--shadow-sm),var(--hi),0 0 0 4px rgba(184,169,232,.18);
}
.fld__range::-moz-range-track{height:8px;border-radius:999px;background:rgba(184,169,232,.5)}
.fld__range::-moz-range-thumb{width:20px;height:20px;border-radius:50%;background:#fff;border:0;box-shadow:var(--shadow-sm),var(--hi),0 0 0 4px rgba(184,169,232,.18)}
.cf-more{margin-top:8px;border-top:1px solid var(--line);padding-top:12px}
.cf-more summary{font-size:13.5px;color:var(--primary-deep);cursor:pointer}
.cf-more__body{margin-top:10px;display:flex;flex-direction:column;gap:8px}
.kv{display:flex;gap:10px;font-size:14px;background:var(--surface);border:1px solid var(--card-line);border-radius:12px;padding:10px 12px;box-shadow:var(--shadow-sm),var(--hi-soft)}
.kv span{color:var(--ink-2);flex:0 0 82px}
.kv b{font-weight:500;color:var(--ink)}

/* ---------- 四类情绪卡片（v1.0.0-RC 升级：场景卡片块） ---------- */
.cf-card{
  background:var(--surface);border-radius:20px;padding:18px 17px 16px;margin:10px 0 6px;
  border:1.5px solid rgba(184,169,232,.55);
  box-shadow:0 10px 28px rgba(150,130,200,.18), inset 0 1px 6px rgba(255,255,255,.5);
}
.cf-card__badge{
  display:inline-block;font-size:12px;font-weight:600;color:var(--primary-deep);
  background:#F3EDFF;border-radius:999px;padding:4px 11px;margin-bottom:10px;letter-spacing:.3px;
}
.cf-card__title{font-size:19px;font-weight:700;line-height:1.5;color:var(--ink);margin:0 0 9px}
.cf-card__body{font-size:15px;line-height:1.85;color:var(--ink);margin:0 0 4px;white-space:pre-wrap}
.cf-card__action{
  margin:13px 0 4px;padding:13px 14px;border-radius:16px;
  background:linear-gradient(135deg,rgba(184,169,232,.16),rgba(214,205,240,.22));
  border:1px solid rgba(184,169,232,.5);
}
.cf-card__action-label{font-size:12.5px;color:var(--primary-deep);margin-bottom:6px;font-weight:600}
.cf-card__action-step{font-size:15px;line-height:1.7;color:var(--ink);font-weight:500}
.cf-card__action-note{font-size:13px;line-height:1.65;color:var(--ink-2);margin-top:6px}
.cf-card__btns{display:flex;gap:11px;margin-top:15px}
.cf-card__btns .primary,.cf-card__btns .ghost-btn{
  flex:1 1 0;width:auto;margin-top:0;padding:13px 10px;font-size:15px;font-weight:600;text-align:center;
}
.cf-card__hint{font-size:12.5px;color:var(--ink-2);text-align:center;margin:11px 2px 0;line-height:1.6}


/* ---------- 卡片列表 ---------- */
.card-list{display:flex;flex-direction:column;gap:12px}
/* v1.6.17 G3：卡片列表筛选档位 + 单卡操作 */
.cchips{display:flex;gap:8px;justify-content:center;margin:10px 0 14px}
.cchip{display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:999px;border:1.5px solid var(--line);
  background:var(--surface);color:var(--ink-2);font-size:13px;cursor:pointer;box-shadow:var(--hi-soft);transition:border-color .18s,color .18s,background .18s}
.cchip i{font-style:normal;font-size:11.5px;color:var(--ink-3)}
.cchip--on{background:var(--primary);border-color:var(--primary);color:#fff}
.cchip--on i{color:rgba(255,255,255,.82)}
.cchip:disabled{opacity:.45;cursor:not-allowed}
.mcard__link{display:flex;gap:12px;flex:1;min-width:0}
.mcard__ops{display:flex;flex-direction:column;justify-content:center;gap:6px;padding-left:2px}
.mop{width:30px;height:30px;border-radius:50%;border:1.5px solid var(--line);background:var(--surface-2);box-shadow:var(--hi-soft);color:var(--ink-3);
  font-size:14px;line-height:1;cursor:pointer;transition:border-color .18s,color .18s,background .18s}
.mop--on{border-color:var(--primary);color:var(--primary);background:#F6F1FF}
.detail-ops{display:flex;flex-direction:column;gap:2px;margin-top:18px;padding-top:14px;border-top:1px solid var(--line)}
.mcard{display:flex;gap:12px;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm),var(--hi-soft);transition:transform .16s}
.mcard:active{transform:scale(.99)}
.mcard__date{font-size:12px;color:var(--ink-2)}
.mcard__title{font-size:15.5px;font-weight:600;margin:2px 0 8px;line-height:1.45}
.mcard__tags{display:flex;flex-wrap:wrap;gap:6px}
.tag{font-size:12px;color:var(--primary-deep);background:var(--surface);border:1px solid var(--card-line);border-radius:var(--r-pill);padding:3px 10px;box-shadow:var(--hi-soft)}
.tag--i{color:#B07A4E;background:#FFF1E2}
.empty-state{display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;color:var(--ink-2);padding:30px 0}
.empty-state p{font-size:14.5px;margin:0}

/* ---------- 卡片详情 ---------- */
.detail-card{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:22px 18px;box-shadow:var(--shadow),var(--hi-soft);text-align:center}
.dc__face{display:flex;justify-content:center;margin-bottom:6px}
.dc__date{font-size:12.5px;color:var(--ink-2)}
.dc__title{font-size:19px;margin:8px 0 12px;line-height:1.5}
.dc__tags{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}
.detail-body{margin-top:14px;display:flex;flex-direction:column;gap:8px}
.detail-body .kv span{flex:0 0 72px}
.voice-box{margin-top:16px;background:linear-gradient(135deg,#FBF4FF,#FFF4E8);border-radius:var(--radius);padding:16px 18px}
.voice-label{font-size:12px;color:var(--primary-deep);letter-spacing:.1em;margin-bottom:6px}
.voice-box p{margin:0;font-size:15px;line-height:1.75}

/* ---------- 周报 ---------- */
.wk-note{text-align:center;color:var(--ink-2);font-size:12.5px;margin:-10px 0 18px}
.wk-block{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow-sm),var(--hi-soft);margin-bottom:12px}
.wk-block--lead{background:linear-gradient(135deg,#F6F0FF,#FFF6EC)}
.wk-block--action{background:linear-gradient(135deg,#EFF8F4,#F6F0FF)}
.wk-label{font-size:12.5px;color:var(--ink-2);letter-spacing:.06em;margin-bottom:8px}
.wk-block p{margin:0;font-size:15px;line-height:1.75}
.wk-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.wk-list li{display:flex;justify-content:space-between;font-size:14.5px;border-bottom:1px dashed var(--line);padding-bottom:7px}
.wk-list li:last-child{border-bottom:0;padding-bottom:0}
.wk-list b{color:var(--primary-deep);font-weight:600}

/* ---------- 我 ---------- */
.me__head{display:flex;gap:14px;align-items:center;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow-sm),var(--hi-soft);margin-bottom:16px}
.me__name{font-size:17px;font-weight:600}
.me__meta{font-size:13px;color:var(--ink-2)}
.mlist{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);box-shadow:var(--shadow-sm),var(--hi-soft);overflow:hidden}
.mrow{display:flex;justify-content:space-between;align-items:center;padding:16px 18px;border-bottom:1px solid var(--line);font-size:15.5px}
.mrow:last-child{border-bottom:0}
.mrow i{color:var(--ink-2);font-style:normal}

/* ---------- 设置 ---------- */
.set-block{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow-sm),var(--hi-soft);margin-bottom:12px}
.set-title{font-size:15px;font-weight:600;margin-bottom:6px}
.set-sub{margin:0;font-size:13.5px;color:var(--ink-2);line-height:1.7}
.switch{display:flex;justify-content:space-between;align-items:center;font-size:15px;gap:12px}
.switch input{width:46px;height:26px;appearance:none;-webkit-appearance:none;background:#E4DCF2;border-radius:var(--r-pill);position:relative;transition:background var(--dur) var(--ease-out);outline:none;flex:0 0 auto}
.switch input::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;box-shadow:var(--shadow-sm),var(--hi);transition:transform var(--dur) var(--ease-spring)}
.switch input:checked{background:var(--grad-primary)}
.switch input:checked::after{transform:translateX(20px)}
.danger{display:block;width:100%;margin-top:12px;padding:13px;border-radius:var(--r-pill);border:1.5px solid #EBD0C8;color:var(--danger);font-size:15px;background:var(--danger-soft);box-shadow:var(--shadow-xs);transition:transform var(--dur) var(--ease-spring),box-shadow var(--dur)}
.danger:active{transform:scale(.985);box-shadow:var(--shadow-press)}

/* ---------- 高风险转介 ---------- */
.risk{display:flex;flex-direction:column;align-items:center;text-align:center;padding-top:8px}
.risk__title{font-size:20px;margin:6px 0 10px}
.risk__lead{font-size:15px;color:var(--ink);line-height:1.8;margin:8px 0}
.risk__ev{font-size:14px;color:var(--ink-2);background:#F2F5F8;border-radius:14px;padding:12px 14px;margin:10px 0}
.risk__list{width:100%;display:flex;flex-direction:column;gap:10px;margin:12px 0}
.risk__item{display:flex;justify-content:space-between;background:var(--surface);border:1px solid var(--card-line);border-radius:14px;padding:14px 16px;box-shadow:var(--shadow-sm),var(--hi-soft);font-size:14.5px}
.risk__item b{color:var(--primary-deep)}

/* ---------- 底部 Tab ---------- */
.tabbar{
  position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  width:auto;max-width:420px;z-index:20;display:flex;gap:4px;
  padding:6px;
  background:var(--glass-bg);
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-brd);border-radius:var(--r-pill);
  box-shadow:var(--shadow-md),var(--hi);
}
.tab{flex:0 0 auto;white-space:nowrap;text-align:center;font-size:13px;color:var(--ink-2);
  padding:8px 14px;border-radius:var(--r-pill);transition:color var(--dur),background var(--dur)}
.tab--on{color:#fff;font-weight:600;background:var(--grad-primary);box-shadow:var(--shadow-sm),var(--hi)}

/* ---------- Toast ---------- */
/* 墨小溟的柔和提示气泡（v1.1.2）：原来是 rgba(58,58,58,.92) 的黑条，真机上像系统报错，
   和「不评判、温柔承接」的产品调性完全相反。改成暖奶油白 + 淡紫描边的圆角气泡。 */
.toast{
  position:fixed;left:50%;bottom:96px;transform:translate(-50%,14px) scale(.96);
  background:var(--glass-bg);
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  color:var(--ink);font-size:14px;line-height:1.65;
  padding:12px 18px;border-radius:var(--r-md);
  border:1px solid var(--glass-brd);
  box-shadow:var(--shadow-md),var(--hi);
  opacity:0;pointer-events:none;
  transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-spring);
  z-index:40;max-width:82vw;text-align:center;
}
.toast--on{opacity:1;transform:translate(-50%,0) scale(1)}

/* ---------- 录音页提示（文案库 §6.2） ---------- */
.rec-hint{text-align:center;color:var(--ink-2);font-size:14px;margin:0 0 14px;min-height:22px}

/* ---------- 追问页（共情 + 过渡语） ---------- */
.fu-empathy{margin:0 0 10px;text-align:center;color:var(--primary-deep);font-size:15px}
.fu-lead{font-size:13px;color:var(--ink-2);letter-spacing:.04em;margin-bottom:6px}
.fu-note{margin-top:18px;font-size:13.5px;color:var(--ink-2);background:var(--surface);border:1px solid var(--card-line);border-radius:14px;padding:12px 14px;box-shadow:var(--shadow-sm),var(--hi-soft);line-height:1.7}

/* ---------- 温和确认（gentle_check） ---------- */
.gentle{display:flex;flex-direction:column;align-items:center;text-align:center;padding-top:6px}
.gentle__mascot{display:flex;justify-content:center;padding:6px 0 10px}
.gentle__title{font-size:21px;margin:6px 0 10px}
.gentle__body{font-size:15.5px;line-height:1.8;color:var(--ink);margin:0 0 20px}
.ghost-btn{display:block;width:100%;padding:13px;margin-top:10px;border-radius:var(--r-pill);border:1.5px solid var(--card-line);background:var(--surface);color:var(--ink);font-size:15px;cursor:pointer;box-shadow:var(--shadow-xs),var(--hi-soft);transition:transform var(--dur) var(--ease-spring),box-shadow var(--dur) var(--ease-out),border-color var(--dur)}
.ghost-btn:active{transform:scale(.985);box-shadow:var(--shadow-press)}

/* ---------- 高风险 / 紧急 ---------- */
.risk--emergency{background:linear-gradient(180deg,#F5F8FB,#FFF8F0 42%)}
.risk--emergency .risk__title{font-size:22px}
.risk__footer{margin:18px 0 0;font-size:14px;color:#5C6B7A;background:#EEF3F7;border-radius:14px;padding:12px 16px;font-weight:600}

/* ---------- 周报补充 ---------- */
.wk-headline{font-size:16.5px;font-weight:600;margin:0 0 8px !important}
.wk-corrs{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.wk-corrs li{font-size:14px;line-height:1.6;border-bottom:1px dashed var(--line);padding-bottom:8px}
.wk-corrs li:last-child{border-bottom:0;padding-bottom:0}
.wk-corrs b{display:inline-block;margin-right:8px;color:var(--primary-deep)}
.wk-corrs span{color:var(--ink-2)}

/* ---------- 标签补充 ---------- */
.tag--soft{color:#6E7B88;background:#F1F4F7}

/* =========================================================
   v1.1 视觉精装修
   ========================================================= */

/* ---------- 页面切换：柔和淡入淡出（不生硬跳转） ---------- */
@keyframes view-in{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.view--enter{animation:view-in .3s ease-out both}
/* 舞台页（分析中）淡入更慢，配呼吸感 */
@keyframes stage-in{from{opacity:0;transform:scale(.965)}to{opacity:1;transform:none}}
.center-stage{animation:stage-in .42s ease-out both}

/* ---------- 左滑返回手势（v1.2.1 攻坚 · 战役二）：跟手 parallax + 暗色叠加 + 返回提示 ---------- */
body.swiping #view{touch-action:none}
#view{position:relative}
#view.swipe-release{transition:transform .26s cubic-bezier(.22,.61,.36,1)}
#view::after{content:'';position:absolute;inset:0;background:#05070f;opacity:var(--swipe-dim,0);
  pointer-events:none;z-index:60;border-radius:inherit}
#swipeHint{position:fixed;left:16px;top:50%;width:38px;height:38px;margin-top:-19px;border-radius:50%;
  background:rgba(255,255,255,.92);color:var(--primary-deep,#6b5bff);display:flex;align-items:center;
  justify-content:center;font-size:22px;line-height:1;opacity:0;pointer-events:none;z-index:70;
  box-shadow:0 4px 16px rgba(0,0,0,.2);transform:translateX(-14px);transition:opacity .12s ease}

/* ---------- 全站按压反馈（所有可点元素都有回应） ---------- */
.primary{
  background:linear-gradient(135deg,#C9BCF0 0%,var(--primary) 46%,var(--primary-deep) 100%);
  box-shadow:0 10px 26px rgba(150,130,200,.26),inset 0 1px 6px rgba(255,255,255,.34);
  transition:transform .18s var(--ease),box-shadow .22s ease,filter .2s;
}
.primary:active{transform:scale(.975);box-shadow:0 5px 16px rgba(150,130,200,.34),0 0 22px rgba(184,169,232,.5);filter:brightness(1.04)}
.ghost-btn,.danger,.risk__item,.mrow,.tab,.linkbtn,.fld__input,.big-input{transition:transform .16s var(--ease),background .2s,box-shadow .2s,border-color .2s}
.ghost-btn:active{transform:scale(.975);background:#FBF7FF;border-color:var(--primary)}
.danger:active{transform:scale(.975);background:#FFEFE9}
.risk__item:active{transform:scale(.985);box-shadow:0 6px 18px rgba(150,130,200,.18)}
.mrow:active{background:linear-gradient(90deg,rgba(184,169,232,.10),rgba(184,169,232,0))}
.linkbtn:active{opacity:.7}
.tab:active{transform:scale(.94)}

/* ---------- 首页：日期按规范用 #8A8A8A，靠字号/字重/字距做"更轻" ---------- */
.say__date{color:var(--ink-2);font-size:12.5px;letter-spacing:.09em;font-weight:400}
.say__greet{font-size:23.5px;letter-spacing:.01em}

/* ---------- 底部空状态提示：柔和、不抢焦点 ---------- */
.empty-hint{margin-top:auto;text-align:center;color:var(--ink-3);font-size:13px;letter-spacing:.02em;padding:18px 0}

/* ---------- 录音页波形 ---------- */
.rec-live{display:flex;align-items:center;justify-content:center;gap:10px;font-size:20px;font-weight:600;color:var(--primary-deep);margin:6px 0}
.wave--live i{background:var(--primary);height:6px}
.wave--live i:nth-child(2){animation-delay:.1s}
.wave--live i:nth-child(3){animation-delay:.2s}
.wave--live i:nth-child(4){animation-delay:.3s}
.wave--live i:nth-child(5){animation-delay:.4s}
.wave--live i:nth-child(6){animation-delay:.5s}
.wave--live i:nth-child(7){animation-delay:.6s}

/* ---------- 卡片页：占位预览（虚线 + 倾斜 + 浮动） ---------- */
.ghost-card{
  position:relative;width:100%;max-width:280px;margin:0 auto 20px;
  border-radius:var(--radius);padding:16px 18px;
  border:1.5px dashed rgba(184,169,232,.55);
  background:linear-gradient(150deg,rgba(255,255,255,.72),rgba(243,237,255,.52));
  box-shadow:0 8px 22px rgba(160,140,200,.10);
  transform:rotate(-1.8deg);animation:ghost-float 5.4s ease-in-out infinite;
}
@keyframes ghost-float{0%,100%{transform:rotate(-1.8deg) translateY(0)}50%{transform:rotate(-1.2deg) translateY(-6px)}}
.ghost-card__face{display:flex;justify-content:center;opacity:.55;margin-bottom:4px}
.ghost-card__bar{height:9px;border-radius:999px;background:rgba(184,169,232,.26);margin:0 auto 9px}
.ghost-card__bar--t{width:62%;background:rgba(184,169,232,.34)}
.ghost-card__bar--s{width:44%}
.ghost-card__tags{display:flex;gap:6px;justify-content:center;margin-top:12px}
.ghost-card__tag{width:38px;height:16px;border-radius:999px;background:rgba(184,169,232,.22)}
.ghost-card__tag--o{background:rgba(255,184,140,.30)}
.ghost-card__tag--b{background:rgba(168,200,232,.30)}
.ghost-card__note{text-align:center;font-size:12px;color:var(--ink-3);margin:12px 0 0;letter-spacing:.04em}
.empty-state{padding:14px 0 8px;gap:12px}
/* 空态在可视区里居中，避免顶部堆叠 + 底部大片空白 */
.cards .empty-state{justify-content:center;min-height:calc(100dvh - 210px)}
.empty-state .primary.small{margin-top:2px;padding:12px 26px;box-shadow:0 10px 24px rgba(150,130,200,.26),inset 0 1px 6px rgba(255,255,255,.34)}

/* ---------- 我的页：头像 + 列表图标 + 层次 ---------- */
.me__head{
  background:var(--card);border-radius:var(--radius);padding:18px;
  box-shadow:0 6px 24px rgba(160,140,200,.13),0 0 0 1px var(--card-line);
  margin-bottom:16px;
}
.me__face{position:relative}
.me__face .avatar{box-shadow:0 4px 16px rgba(160,140,200,.22),inset 0 0 0 1px rgba(184,169,232,.26)}
.me__name{font-size:17.5px;font-weight:600;letter-spacing:.01em}
.me__meta{font-size:12.5px;color:var(--ink-2);margin-top:2px}
.mlist{
  background:var(--card);border-radius:var(--radius);
  box-shadow:0 6px 24px rgba(160,140,200,.13),0 0 0 1px var(--card-line);
  overflow:hidden;
}
.mrow{display:flex;align-items:center;gap:12px;padding:16px 18px;border-bottom:1px solid var(--line);font-size:15.5px}
.mrow:last-child{border-bottom:0}
.mrow__ico{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:11px;background:var(--primary-soft);flex:0 0 auto}
.mrow__ico svg{width:19px;height:19px;stroke-width:1.7;fill:none;stroke-linecap:round;stroke-linejoin:round}
.mrow__txt{flex:1}
.mrow__sub{display:block;font-size:12px;color:var(--ink-3);margin-top:1px}
.mrow__arrow{color:#C6BFD8;font-size:17px;font-style:normal}
/* 三个图标各用一支辅助色，避免整页灰白紫 */
.mrow--weekly .mrow__ico{background:rgba(168,200,232,.20)}
.mrow--weekly .mrow__ico svg{stroke:var(--blue)}
.mrow--cards  .mrow__ico{background:rgba(184,169,232,.18)}
.mrow--cards  .mrow__ico svg{stroke:var(--primary-deep)}
.mrow--settings .mrow__ico{background:rgba(168,216,200,.20)}
.mrow--settings .mrow__ico svg{stroke:#7FBFA8}
.mrow--about .mrow__ico{background:rgba(255,184,140,.22)}
.mrow--about .mrow__ico svg{stroke:var(--orange)}
.foot-note{text-align:center;color:var(--ink-2);font-size:12.5px;line-height:1.8;margin-top:26px}

/* ---------- 卡片生成：「被接住」的柔和动效（不生硬弹出） ---------- */
@keyframes catch-drop{0%{opacity:0;transform:translateY(-16px) scale(.94)}62%{opacity:1;transform:translateY(3px) scale(1.012)}100%{opacity:1;transform:none}}
@keyframes catch-rise{0%{opacity:0;transform:translateY(12px)}100%{opacity:1;transform:none}}
.catch-in{animation:catch-drop .58s cubic-bezier(.22,1.2,.36,1) both}
.cf-mascot.catch-in{animation-delay:.02s}
.cf-lead.catch-in,.detail-card.catch-in{animation-delay:.06s}
.cf-sub.catch-in{animation-delay:.12s}
/* 确认页：仅对「入场时本就该可见」的元素做柔和入场（卡片/引导语/副文案/吉祥物走 .catch-in，主按钮上浮）。
   折叠的 <details class="cf-more"> 内表单是用户主动展开才可见，不再强制 opacity:0 —— 否则展开后字段可能停在透明态。 */
.confirm .primary{opacity:0;animation:catch-rise .38s ease-out both}
.confirm .primary{animation-delay:.45s}
/* 卡片详情页同样柔和进入 */
.detail .detail-card,.detail .kv,.detail .voice-box{opacity:0;animation:catch-rise .38s ease-out both}
.detail .detail-card{animation-delay:.04s}
.detail .kv:nth-child(1){animation-delay:.08s}
.detail .kv:nth-child(2){animation-delay:.12s}
.detail .kv:nth-child(3){animation-delay:.16s}
.detail .kv:nth-child(4){animation-delay:.20s}
.detail .kv:nth-child(5){animation-delay:.24s}
.detail .kv:nth-child(6){animation-delay:.28s}
.detail .kv:nth-child(7){animation-delay:.32s}
.detail .voice-box{animation-delay:.36s}

/* ---------- 色彩校准：辅助色落到标签 / 列表 / 图标 ---------- */
.tag{background:var(--primary-soft);color:var(--primary-deep)}
.tag--i{color:#B07A4E;background:#FFF1E2}
.tag--mint{color:#5F9E86;background:rgba(168,216,200,.24)}
.tag--blue{color:#5E88B8;background:rgba(168,200,232,.24)}
.wk-block--action{background:linear-gradient(135deg,rgba(168,216,200,.22),rgba(243,237,255,.75))}
.wk-block--lead{background:linear-gradient(135deg,rgba(243,237,255,.85),rgba(255,241,226,.72))}
.wk-list b{color:var(--primary-deep)}
.voice-box{background:linear-gradient(135deg,rgba(243,237,255,.85),rgba(255,244,232,.85))}
.voice-label{color:var(--primary-deep)}
.risk__item b{color:var(--primary-deep)}
.set-title{letter-spacing:.01em}
.set-block{background:var(--card);box-shadow:0 5px 20px rgba(160,140,200,.11),0 0 0 1px var(--card-line)}

/* v1.3.0 IP 动效：动画强度 柔和/标准 分段控件 */
.seg{display:flex;align-items:center;justify-content:space-between;margin-top:14px}
.seg__label{font-size:14.5px;color:var(--ink)}
.seg__opts{display:inline-flex;background:rgba(184,169,232,.16);border-radius:999px;padding:3px;gap:2px}
.seg__opts button{border:0;background:none;padding:6px 18px;border-radius:999px;font-size:13.5px;color:var(--ink-2);cursor:pointer;font-family:inherit;transition:background .18s ease,color .18s ease}
.seg__opts button.seg--on{background:#fff;color:var(--primary-deep);box-shadow:0 1px 4px rgba(0,0,0,.08)}
.risk__ev{background:rgba(168,200,232,.14);color:#5C6B7A}

/* ---------- 共情页 / 追问页：更柔的情绪色 ---------- */
.fu-empathy{color:#C08A62;background:rgba(255,184,140,.14);display:inline-block;padding:5px 14px;border-radius:999px;font-size:14.5px}
.followup .fu-empathy{display:block;background:none;padding:0}
.gentle__title{letter-spacing:.01em}
.mcard{box-shadow:0 5px 20px rgba(160,140,200,.11),0 0 0 1px var(--card-line)}
.mcard__face .miniface{border-radius:50%;background:radial-gradient(circle at 42% 34%,#FBF6FF,#F1E9FC 72%)}

/* ---------- 交互反馈补齐：剩下的可点元素 ---------- */
.ghost{transition:opacity .18s,transform .16s var(--ease)}
.ghost:active{opacity:.6;transform:scale(.96)}
.switch input{cursor:pointer}
.primary.small:active,.ghost-btn:active,.danger:active{transform:scale(.97)}
.cf-more summary{transition:color .18s}
.cf-more summary:active{color:var(--primary)}

/* ---------- 转介 / 紧急页：按钮走灰蓝，不用高饱和紫 ---------- */
.risk .primary{
  background:linear-gradient(135deg,#BCD5EC 0%,var(--blue) 46%,#8FB0CF 100%);
  box-shadow:0 10px 26px rgba(150,175,205,.30),inset 0 1px 6px rgba(255,255,255,.36);
}
.risk .primary:active{box-shadow:0 5px 16px rgba(150,175,205,.36),0 0 22px rgba(168,200,232,.5)}
.risk .risk__footer{color:#5C6B7A}

/* ---------- 录音中：按钮内波形已就位，记录页波形用主色 ---------- */
.record .wave i{background:var(--primary)}

/* 弱网/无障碍：尊重系统减弱动效 */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  .confirm .fld,.confirm .cf-more,.confirm .primary,.detail .detail-card,.detail .kv,.detail .voice-box{opacity:1 !important}
  .view--enter{animation:none}
}

/* ---------- v0.7.0 版本更新弹窗（自定义 Modal，非 window.confirm） ---------- */
@keyframes update-fade{from{opacity:0}to{opacity:1}}
@keyframes update-pop{0%{opacity:0;transform:translateY(14px) scale(.94)}62%{opacity:1;transform:translateY(-3px) scale(1.012)}100%{opacity:1;transform:none}}
.update-overlay{
  position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(58,46,78,.34);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:update-fade .22s ease both;
}
.update-card{
  width:100%;max-width:340px;background:var(--bg);border-radius:var(--radius);
  padding:24px 22px 20px;text-align:center;box-shadow:0 18px 50px rgba(90,70,130,.30),0 0 0 1px rgba(184,169,232,.18);
  animation:update-pop .5s cubic-bezier(.22,1.2,.36,1) both;
  /* v1.4.1：更新说明会随版本累积变长，卡片必须自身可滚动。
     否则在小屏（360x640 这类）上「立即更新 / 稍后再说」会被挤到视口外 ——
     强制更新时那就等于**用户关不掉弹窗**，是比"更新失败"严重得多的问题。
     dvh 而非 vh：移动端浏览器地址栏收缩时 vh 会算大，dvh 才跟实际可视区一致。 */
  max-height:calc(100dvh - 48px);overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.update-ip{position:relative;display:inline-block;margin-bottom:6px}
.update-ip .mascot{display:block;margin:0 auto}
/* 墨小溟举的小牌子 */
.update-sign{
  position:absolute;left:50%;bottom:6px;transform:translateX(-50%);
  background:var(--primary-soft);color:var(--primary-deep);
  font-size:12.5px;font-weight:600;letter-spacing:.02em;
  padding:4px 12px;border-radius:999px;white-space:nowrap;
  box-shadow:0 3px 10px rgba(160,140,200,.20);
}
.update-title{font-size:18px;font-weight:600;color:var(--ink);margin:10px 0 6px;letter-spacing:.01em}
.update-sub{font-size:13.5px;color:var(--ink-2);line-height:1.65;margin:0 4px 14px}
.update-sub--ok{color:var(--primary-deep);font-weight:600}
.update-notes{
  text-align:left;list-style:none;margin:0 2px 18px;padding:0;
  max-height:188px;overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.update-notes li{position:relative;font-size:14px;color:var(--ink);line-height:1.7;padding-left:16px;margin:7px 0}
.update-notes li::before{content:"";position:absolute;left:2px;top:9px;width:6px;height:6px;border-radius:50%;
  background:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
.update-actions{display:flex;flex-direction:column;gap:10px}
.update-btn{
  width:100%;padding:13px 18px;border-radius:999px;font-size:15.5px;font-weight:600;
  transition:transform .16s ease,opacity .2s,box-shadow .18s;letter-spacing:.01em;
}
.update-btn--primary{
  background:linear-gradient(135deg,var(--primary),var(--primary-deep));color:#fff;
  box-shadow:0 10px 24px rgba(158,140,216,.34),inset 0 1px 6px rgba(255,255,255,.36);
}
.update-btn--primary:active{transform:scale(.985);box-shadow:0 6px 16px rgba(158,140,216,.40)}
.update-btn--ghost{
  background:var(--bg-soft);color:var(--ink-2);
  box-shadow:inset 0 0 0 1px var(--line);
}
.update-btn--ghost:active{transform:scale(.985);color:var(--ink)}

/* ---------- 墨小溟 · APK 应用内安装指引弹窗（v1.2.0，Task #117） ---------- */
.install-overlay{
  position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(58,46,78,.34);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:update-fade .22s ease both;
}
.install-card{
  width:100%;max-width:340px;background:var(--bg);border-radius:var(--radius);
  padding:24px 22px 20px;text-align:center;box-shadow:0 18px 50px rgba(90,70,130,.30),0 0 0 1px rgba(184,169,232,.18);
  animation:update-pop .5s cubic-bezier(.22,1.2,.36,1) both;
}
.install-steps{text-align:left;margin:4px 2px 16px;padding-left:20px;color:var(--ink);font-size:14px;line-height:1.75}
.install-steps li{margin:7px 0}
.install-steps b{color:var(--primary-deep)}
.install-actions{display:flex;flex-direction:column;gap:10px}
/* v1.6.4 · 应用内下载进度（全程留在产品里，不切浏览器） */
.install-body{margin:8px 2px 16px}
.dl-bar{height:8px;border-radius:999px;background:rgba(158,140,216,.18);overflow:hidden}
.dl-bar__fill{display:block;height:100%;width:0;border-radius:999px;background:linear-gradient(90deg,var(--primary),var(--primary-deep));transition:width .18s linear}
/* 服务器没给 Content-Length 时只让条子呼吸，不给假百分比 */
.dl-bar__fill--indet{width:6%!important;animation:dl-breathe 1.3s ease-in-out infinite}
@keyframes dl-breathe{0%,100%{opacity:.5}50%{opacity:1}}
.update-sub--dim{opacity:.72;font-size:13px;line-height:1.7;margin-top:6px}
@media (prefers-reduced-motion:reduce){.dl-bar__fill{transition:none}.dl-bar__fill--indet{animation:none;opacity:.7}}

/* ---------- 墨小溟 · 首次欢迎弹窗（§3.3 / §4.3） ---------- */
.welcome-overlay{
  position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(58,46,78,.34);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:update-fade .22s ease both;
}
.welcome-card{
  width:100%;max-width:340px;background:var(--bg);border-radius:var(--radius);
  padding:22px 22px 18px;text-align:center;box-shadow:0 18px 50px rgba(90,70,130,.30),0 0 0 1px rgba(184,169,232,.18);
  animation:update-pop .5s cubic-bezier(.22,1.2,.36,1) both;
}
.welcome-ip{position:relative;display:inline-block;margin-bottom:4px}
.welcome-ip .mascot{display:block;margin:0 auto}
.welcome-badge{font-size:14px;font-weight:600;color:var(--primary-deep);margin:6px 0 2px;letter-spacing:.02em}
.welcome-lines{text-align:left;font-size:14.5px;color:var(--ink);line-height:1.85;margin:8px 4px 16px}
.welcome-lines p{margin:5px 0}
.welcome-foot{font-size:12.5px;color:var(--ink-2);line-height:1.6;margin:12px 2px 0}
/* v1.6.0 文档 §二：4 屏新手引导的分页点 / 标题 / 双按钮
   （第 3 屏是边界声明，卡片比单屏默认宽一点，字号也收一档，读得完才叫「告知」） */
.welcome-progress{display:flex;gap:6px;justify-content:center;margin-bottom:2px}
.wdot{width:6px;height:6px;border-radius:999px;background:rgba(184,169,232,.42);display:block;transition:width .2s ease}
.wdot--on{width:20px;background:var(--primary)}
.welcome-title{font-size:17px;font-weight:700;color:var(--ink);line-height:1.6;margin:10px 0 6px;letter-spacing:.01em}
.welcome-overlay--steps .welcome-lines{font-size:13.8px;line-height:1.8;margin:6px 2px 14px}
.welcome-overlay--steps .welcome-card .primary{margin-top:6px}
.welcome-btns{display:flex;gap:14px;justify-content:center;align-items:center;margin-top:12px}
.welcome-btns .linkbtn{font-size:13px;color:var(--ink-2);padding:6px 4px;min-height:34px}
.welcome-card .primary{width:100%;padding:13px 18px;border-radius:999px;font-size:15.5px;font-weight:600;margin-top:4px}
/* v1.6.17 G1 第 5 屏：偏好勾选（默认全关，勾了才生效） */
.welcome-prefs{display:flex;flex-direction:column;gap:2px;margin:2px 0 12px;text-align:left}
.welcome-pref{display:flex;gap:9px;align-items:flex-start;padding:9px 10px;border-radius:12px;
  background:rgba(184,169,232,.10);border:1px solid rgba(184,169,232,.22);cursor:pointer}
.welcome-pref + .welcome-pref{margin-top:6px}
.welcome-pref input[type="checkbox"]{appearance:none;-webkit-appearance:none;flex:none;width:18px;height:18px;margin-top:2px;
  border-radius:50%;border:1.5px solid rgba(120,100,170,.42);position:relative;cursor:pointer;transition:background .18s,border-color .18s}
.welcome-pref input[type="checkbox"]:checked{background:var(--primary);border-color:var(--primary)}
.welcome-pref input[type="checkbox"]:checked::after{content:"";position:absolute;left:5px;top:5px;width:6px;height:6px;
  border-radius:50%;background:#fff}
.welcome-pref span{font-size:13px;line-height:1.55;color:var(--ink);display:block}
/* v1.6.18：不带勾选框的说明条（没有对应长期开关的两条：别说教是默认 / 安静模式怎么进） */
.welcome-note{position:relative;margin:8px 0 0;padding:0 0 0 14px;font-size:12px;line-height:1.6;color:var(--ink-soft,var(--ink));opacity:.82}
.welcome-note::before{content:"";position:absolute;left:2px;top:7px;width:5px;height:5px;border-radius:50%;background:var(--primary);opacity:.6}
/* v1.6.19 P2-2：引导第 3 屏底部的安全边界小字（⚠️ 非心理医生声明）+ 该屏的补充段落 */
.welcome-note--alert{margin-top:10px;padding:8px 10px;border-radius:10px;background:rgba(184,169,232,.12);
  border-left:2px solid var(--primary);font-size:11.5px;line-height:1.65;text-align:left;opacity:.92}
.welcome-note--alert::before{display:none}
.welcome-lines--extra{margin-top:6px;opacity:.86}

/* ---------- v0.7.0 关于墨小溟 / 更新历史 ---------- */
.changelog__ip{text-align:center;margin:6px 0 2px}
.changelog__ver{text-align:center;font-size:15px;font-weight:600;color:var(--ink);margin-top:4px}
.changelog__desc{text-align:center;font-size:13.5px;color:var(--ink-2);line-height:1.7;max-width:300px;margin:10px auto 20px}
.about-persona{text-align:center;font-size:14.5px;color:var(--ink);line-height:1.85;max-width:320px;margin:10px auto;padding:0 4px}
.disclaimer-box{text-align:left;font-size:13px;color:var(--ink-2);line-height:1.75;background:var(--card);border-radius:var(--radius);padding:14px 16px;margin:14px 0;box-shadow:0 0 0 1px var(--card-line)}
/* v1.6.0 文档 §三.2：设置页隐私说明四段（能长读、能翻回去） */
.privacy-box{text-align:left;background:var(--card);border-radius:var(--radius);padding:16px 16px 12px;margin:14px 0;box-shadow:0 0 0 1px var(--card-line)}
.privacy__title{font-size:14.5px;font-weight:700;color:var(--ink);margin-bottom:10px;letter-spacing:.02em}
.privacy__line{font-size:13px;color:var(--ink-2);line-height:1.8;margin:0 0 10px;padding-left:12px;border-left:2px solid rgba(184,169,232,.55)}
.privacy__line:last-child{margin-bottom:0}
.cf-emotion{text-align:center;font-size:15px;color:var(--primary-deep);line-height:1.8;margin:4px 0 14px;font-weight:500}
.changelog__list{margin-bottom:4px}
/* 关于页的安卓安装包入口（v1.1.7）：只在网页版显示，壳里不显示（已经装着 App 了） */
.cl-dl{display:block;text-align:center;margin:16px auto 0;font-size:13.5px;color:var(--primary-deep);font-weight:600}
.cl-item{
  background:var(--card);border-radius:var(--radius);padding:16px 18px;margin-bottom:14px;
  box-shadow:0 6px 22px rgba(160,140,200,.12),0 0 0 1px var(--card-line);
}
.cl-item__head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.cl-item__head b{font-size:15.5px;color:var(--ink);font-weight:600}
.cl-item__head span{font-size:12.5px;color:var(--ink-3)}
.cl-item__title{font-size:14px;color:var(--primary-deep);margin-top:3px;font-weight:600}
.cl-item__notes{list-style:none;margin:10px 0 0;padding:0}
.cl-item__notes li{position:relative;font-size:13.5px;color:var(--ink);line-height:1.7;padding-left:15px;margin:5px 0}
.cl-item__notes li::before{content:"";position:absolute;left:1px;top:8px;width:6px;height:6px;border-radius:50%;
  background:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
}

/* ---------- 墨小溟 · 对话区（v1.1 §3.3 对话区同步输出） ---------- */
.convo{max-width:440px;width:100%;margin:14px auto 0;display:flex;flex-direction:column;gap:10px;padding:0 4px}
.convo__row{display:flex;flex-direction:column;gap:3px}
.convo__who{font-size:12px;color:var(--ink-3);padding:0 4px}
.convo__bubble{padding:11px 14px;border-radius:16px;font-size:14.5px;line-height:1.7;box-shadow:var(--shadow-sm);word-break:break-word}
.convo__user{align-items:flex-end}
.convo__user .convo__who{text-align:right}
.convo__user .convo__bubble{background:var(--primary-soft);color:var(--ink);border-bottom-right-radius:6px;max-width:82%}
.convo__ai{align-items:flex-start}
.convo__ai .convo__bubble{background:#fff;color:var(--ink);border:1px solid var(--card-line);border-bottom-left-radius:6px;max-width:88%}

/* ---------- 墨小溟 · 高危强制弹窗（v1.1 §3.3 / §4.7，低饱和暗紫，禁用红/爆炸/警报） ---------- */
.risk-modal{position:fixed;inset:0;z-index:10001;display:flex;align-items:center;justify-content:center;
  padding:22px;background:rgba(45,35,62,.46);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:update-fade .22s ease both}
.risk-modal__card{width:100%;max-width:340px;background:linear-gradient(180deg,#4A3C66,#3C2F57);border-radius:var(--radius);
  padding:22px 20px 18px;text-align:center;box-shadow:0 18px 50px rgba(40,30,60,.42);
  animation:update-pop .5s cubic-bezier(.22,1.2,.36,1) both;color:#ECE7F6}
.risk-modal__ip{margin-bottom:2px}
.risk-modal__badge{font-size:13px;font-weight:600;color:#C9BBEA;letter-spacing:.08em;margin:2px 0 6px}
.risk-modal__title{font-size:18px;font-weight:600;margin:0 0 8px;color:#F3EEFB;line-height:1.5}
.risk-modal__ev{font-size:13px;color:#C9BBEA;background:rgba(255,255,255,.08);border-radius:12px;padding:9px 12px;margin:6px 0 10px;line-height:1.6;text-align:left}
.risk-modal__body{font-size:14.5px;line-height:1.85;color:#ECE7F6;margin:4px 2px 12px;text-align:left}
.risk-modal__hotlines{display:flex;flex-direction:column;gap:8px;margin:8px 0 14px}
.risk-modal__item{display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.10);border-radius:13px;padding:12px 14px;font-size:14px;color:#F3EEFB}
.risk-modal__item b{color:#FFD9B0;font-size:15px}
.risk-modal__confirm{width:100%;padding:13px 18px;border-radius:999px;font-size:15.5px;font-weight:600;
  background:#ECE7F6;color:#3C2F57;margin-top:2px;box-shadow:0 6px 18px rgba(0,0,0,.18)}
.risk-modal__confirm:active{transform:scale(.985)}
.risk-modal__foot{font-size:12.5px;color:#C9BBEA;line-height:1.6;margin:12px 2px 0}

/* ---------- 首页「结束倾诉」次级入口（v1.1.0） ---------- */
.endvent-btn{
  margin-top:11px;padding:11px 18px;border-radius:999px;width:100%;
  border:1.5px solid var(--line);background:var(--surface);box-shadow:var(--shadow-xs),var(--hi-soft);color:var(--ink-2);font-size:14.5px;
  transition:transform .16s var(--ease),background .2s,border-color .2s,color .2s;
}
.endvent-btn:active{transform:scale(.975);background:#FBF7FF;border-color:var(--primary);color:var(--primary-deep)}
/* v1.6.17 G5：主页「重新开始倾诉」（比「结束倾诉」更轻一级：虚线淡底，别抢主操作的视觉） */
.endvent-btn--ghost{
  margin-top:7px;background:transparent;border:1.5px dashed var(--line);color:var(--ink-3);
  font-size:13.5px;padding:9px 16px;letter-spacing:.01em;
}
.endvent-btn--ghost:active{background:transparent;border-color:var(--primary)}

/* v1.6.17 G6：断网时「真需要 AI 才能答」的按钮置灰（本地卡片/待机动效/音效不受影响，照常跑） */
body.is-offline [data-ai-gated]{opacity:.46;filter:grayscale(.55);cursor:not-allowed}
body.is-offline .talkbtn[data-ai-gated]{background:#F3EEF9;border-color:var(--line);color:var(--ink-3);box-shadow:none}

/* ---------- 情绪时间线卡片（v1.1.0：简约低饱和紫、扁平、柔和水流曲线） ---------- */
.timeline{display:flex;flex-direction:column;padding-top:2px}
.tl-title{font-size:21px;font-weight:700;line-height:1.45;color:var(--ink);margin:2px 0 6px;text-align:center;letter-spacing:.01em}
.tl-sub{font-size:13.5px;color:var(--ink-2);text-align:center;margin:0 0 14px;letter-spacing:.02em}
.tl-card{
  position:relative;background:var(--surface);border-radius:20px;padding:16px 15px 15px;margin:4px 0;
  border:1.5px solid rgba(184,169,232,.5);
  box-shadow:0 10px 28px rgba(150,130,200,.16),inset 0 1px 6px rgba(255,255,255,.5);
}
.tl-card--empty{text-align:center;padding:22px 18px}
/* v1.6.0 文档 §一.1：四档卡片主题（紫/浅蓝/暖黄/灰）
   旧的紫是唯一配色，所以 --primary 相关的 .tl-node 保持原样（.tl-node 即默认紫档）。
   下面四档里，紫档显式重写一遍，是为了「主题 CSS 的顺序依赖」不再成为暗坑——
   谁写在后面谁赢，显式声明比靠顺序猜要可靠。
   🔴 灰档只降饱和与明度，不改成刺眼的红：遇到高危时卡片不该再制造刺激。 */
.tl-card--purple{border-color:rgba(184,169,232,.5)}
.tl-node--purple{background:var(--primary-soft)}
.tl-card--blue{border-color:rgba(120,168,208,.45);box-shadow:0 10px 28px rgba(90,130,175,.14),inset 0 1px 6px rgba(255,255,255,.5)}
.tl-card--blue .tl-node{background:#EAF2FA}
.tl-card--blue .tl-node__no{color:#2F6E9B}
.tl-card--blue .tl-node__emo--dual{background:linear-gradient(135deg,#EAF2FA,#E9F4FB);color:#2F6E9B;box-shadow:0 1px 4px rgba(47,110,155,.18)}
.tl-card--blue .tl-hint{background:linear-gradient(135deg,rgba(120,168,208,.14),rgba(158,196,226,.2));border-color:rgba(120,168,208,.45)}
.tl-card--warm{border-color:rgba(226,178,106,.5);box-shadow:0 10px 28px rgba(196,150,80,.16),inset 0 1px 6px rgba(255,255,255,.5)}
.tl-card--warm .tl-node{background:#FDF3E2}
.tl-card--warm .tl-node__no{color:#96681A}
.tl-card--warm .tl-node__emo--dual{background:linear-gradient(135deg,#FDF3E2,#FCEBD8);color:#96681A;box-shadow:0 1px 4px rgba(150,104,26,.18)}
.tl-card--warm .tl-hint{background:linear-gradient(135deg,rgba(226,178,106,.14),rgba(240,205,150,.2));border-color:rgba(226,178,106,.45)}
.tl-card--ash{border-color:rgba(150,150,158,.4);box-shadow:0 8px 22px rgba(120,120,130,.12),inset 0 1px 6px rgba(255,255,255,.5)}
.tl-card--ash .tl-node{background:#F2F2F4}
.tl-card--ash .tl-node__no{color:#6E6E78}
.tl-card--ash .tl-node__emo--dual{background:linear-gradient(135deg,#F2F2F4,#EAEAEE);color:#5E5E68;box-shadow:none}
.tl-card--ash .tl-hint{background:linear-gradient(135deg,rgba(150,150,158,.1),rgba(180,180,188,.14));border-color:rgba(150,150,158,.35)}
/* 高危：整卡加一圈内描边（不换成红色警告色，避免二次惊吓） */
.tl-card--risk{outline:1.5px solid rgba(150,150,158,.45);outline-offset:2px}
.tl-node--risk .tl-node__emo{color:#5E5E68}
.tl-corner{position:absolute;top:10px;right:10px;opacity:.4}
.tl-curve{width:100%;height:auto;display:block;margin:2px 0 8px}
.tl-curve path{fill:none;stroke:var(--primary);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;opacity:.85}
.tl-curve .tl-dot{fill:var(--primary-deep);stroke:#fff;stroke-width:2.5}
.tl-curve .tl-dot--inner{fill:#fff;stroke:none}
.tl-curve text{font-size:11px;fill:var(--primary-deep);font-weight:600}
.tl-nodes{display:flex;flex-direction:column;gap:9px;margin:6px 0 2px}
.tl-node{background:var(--primary-soft);border-radius:14px;padding:10px 12px}
.tl-node__no{font-size:11.5px;color:var(--primary-deep);font-weight:600;letter-spacing:.03em}
.tl-node__emo{font-size:15px;color:var(--ink);font-weight:600;margin:2px 0;line-height:1.5}
.tl-node__emo--dual{display:inline-block;background:linear-gradient(135deg,#EFE9FF,#FFE9F3);color:#6A4FB0;border-radius:999px;padding:3px 12px;box-shadow:0 1px 4px rgba(122,91,208,.18)}
.tl-node__cap{font-size:12.5px;color:var(--ink-2);line-height:1.6}
.tl-summary{font-size:15px;line-height:1.85;color:var(--ink);margin:12px 3px 4px;white-space:pre-wrap;text-align:left}
.tl-card--empty .tl-summary{margin:6px 3px}
.tl-hint{
  margin:13px 0 4px;padding:13px 14px;border-radius:16px;
  background:linear-gradient(135deg,rgba(184,169,232,.16),rgba(214,205,240,.22));
  border:1px solid rgba(184,169,232,.5);
}
.tl-hint__label{font-size:12.5px;color:var(--primary-deep);margin-bottom:6px;font-weight:600}
.tl-hint__title{font-size:15px;color:var(--ink);font-weight:600}
.tl-hint__step{font-size:14px;line-height:1.7;color:var(--ink);margin-top:3px}
.tl-hint__note{font-size:13px;line-height:1.65;color:var(--ink-2);margin-top:5px}
.tl-disclaimer{font-size:12px;color:var(--ink-3);line-height:1.7;text-align:center;margin:14px 4px 4px;letter-spacing:.01em}
.tl-btns{display:flex;gap:11px;margin-top:14px}
.tl-btns .primary,.tl-btns .ghost-btn{flex:1 1 0;width:auto;margin-top:0;padding:13px 10px;font-size:15px;font-weight:600;text-align:center}
/* v1.1.1：已保存态 —— 主按钮转「已保存 ✓」，副位换成导出图片；下面再补一行文字操作 */
.tl-btns .primary[disabled]{opacity:.62;cursor:default}
.tl-saveline{display:flex;align-items:center;justify-content:center;gap:22px;margin-top:12px}
.tl-saveline .linkbtn{font-size:13px}
.tl-del{color:var(--ink-3)}
/* 时间线列表（回看入口） */
.tl-note{font-size:13px;color:var(--ink-3);margin:0 4px 12px}
/* ---------- v1.6.19 P1-1 时间线按日期筛选 ---------- */
.tl-filter{margin:0 0 12px;padding:12px;border-radius:16px;background:var(--surface);border:1px solid var(--line)}
.tl-filter__dates{display:flex;align-items:center;gap:8px}
.tl-filter__f{flex:1;display:flex;align-items:center;gap:6px;font-size:12px;color:var(--ink-3)}
.tl-filter__f input[type="date"]{flex:1;min-width:0;font:inherit;font-size:12.5px;color:var(--ink);
  background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:6px 8px}
.tl-filter__quick{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.tl-chip{font:inherit;font-size:12.5px;color:var(--ink-2);background:var(--bg);border:1px solid var(--line);
  border-radius:999px;padding:5px 12px;cursor:pointer}
.tl-chip--on{background:var(--primary);border-color:var(--primary);color:#fff}
.tl-filter__sum{margin:9px 0 0;font-size:11.5px;color:var(--ink-3)}
.tl-list{display:flex;flex-direction:column;gap:10px}
.tlrow{display:flex;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:14px 14px;text-decoration:none;color:inherit}
.tlrow__ico{flex:0 0 38px;height:38px;border-radius:12px;background:rgba(184,169,232,.16);display:flex;align-items:center;justify-content:center}
.tlrow__ico svg{width:20px;height:20px;fill:none;stroke:var(--primary-deep);stroke-width:1.9;stroke-linecap:round}
.tlrow__txt{flex:1 1 auto;display:flex;flex-direction:column;gap:3px;font-size:15px;font-weight:600}
.tlrow__sub{font-size:12.5px;font-weight:400;color:var(--ink-3);line-height:1.5}
.tlrow__arrow{color:var(--ink-3);font-style:normal;font-size:18px}
.mrow--timelines .mrow__ico{background:rgba(184,169,232,.18)}
.mrow--timelines .mrow__ico svg{stroke:var(--primary-deep)}

/* ---------------- 链路诊断页（v1.1.3） ---------------- */
.page--diag{padding-bottom:40px}
.page__head{margin-bottom:16px}
.page__title{font-size:21px;font-weight:700;margin:0 0 4px;letter-spacing:.01em}
.page__sub{margin:0;font-size:13px;color:var(--ink-3);line-height:1.6}
.diag-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;margin-bottom:14px}
.diag-card__t{font-size:13px;font-weight:700;color:var(--primary-deep);margin-bottom:8px;letter-spacing:.02em}
.diag-kv{display:flex;justify-content:space-between;gap:14px;font-size:13px;padding:5px 0;border-top:1px dashed var(--line)}
.diag-kv:first-of-type{border-top:0}
.diag-kv span{color:var(--ink-2);flex:0 0 auto}
.diag-kv b{font-weight:600;text-align:right;word-break:break-all;line-height:1.5}
.diag-empty{font-size:13px;color:var(--ink-3);margin:0}
.diag-actions{display:flex;flex-wrap:wrap;gap:10px;margin:16px 0 10px}
.diag-actions .primary{flex:1 1 100%;width:auto;margin:0;padding:13px 10px;font-size:15px;font-weight:600;text-align:center}
.diag-actions .ghost{flex:1 1 31%;width:auto;margin:0;padding:12px 8px;font-size:13.5px;font-weight:600;text-align:center}
.diag-running{font-size:13px;color:var(--primary-deep);margin:0 0 10px}
.diag-log{background:#FBF7F2;border:1px solid var(--line);border-radius:14px;padding:14px;font-size:11.5px;line-height:1.65;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--ink);
  max-height:52vh;overflow:auto;white-space:pre-wrap;word-break:break-all;margin:0}
.set-diaglink{display:inline-block;margin-top:8px;font-size:13.5px;color:var(--primary-deep);font-weight:600}

/* ---------------- 离线浮条（v1.1.10） ---------------- */
.offline-bar{
  position:fixed;left:50%;top:10px;transform:translateX(-50%);
  z-index:60;max-width:92%;padding:9px 16px;border-radius:999px;
  background:rgba(58,58,58,.92);color:#fff;font-size:13px;font-weight:500;
  box-shadow:var(--shadow-sm);backdrop-filter:blur(4px);
  display:flex;align-items:center;gap:8px;white-space:nowrap;
  animation:offbar-in .3s ease both;
}
.offline-bar::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--orange);box-shadow:0 0 0 3px rgba(255,184,140,.25)}
.offline-bar[hidden]{display:none}
body.is-offline .view{padding-top:46px}
@keyframes offbar-in{from{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translateX(-50%)}}

/* ---------------- 柔和紫色 Loading 线条（v1.1.10） ---------------- */
.loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;color:var(--ink-2);padding:60px 0}
.spinner{width:30px;height:30px;border:3px solid var(--primary-soft);border-top-color:var(--primary-deep);border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------------- 温柔确认框（v1.1.10） ---------------- */
.gentle-confirm{position:fixed;inset:0;z-index:80;background:rgba(58,58,58,.32);display:flex;align-items:center;justify-content:center;padding:24px;animation:offbar-in .2s ease both}
.gentle-confirm__card{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:24px 22px;max-width:320px;width:100%;box-shadow:var(--shadow),var(--hi-soft);text-align:center}
.gentle-confirm__ip{display:flex;justify-content:center;margin-bottom:10px}
.gentle-confirm__msg{font-size:15px;line-height:1.7;color:var(--ink);margin:0 0 18px}
.gentle-confirm__btns{display:flex;gap:12px;align-items:center}
.gentle-confirm__btns .ghost{flex:1;text-align:center;color:var(--ink-2);padding:11px 0}
.gentle-confirm__btns .primary{flex:1;margin-top:0;padding:12px 0;font-size:15px}

/* ---------------- 禁用态（防重复点击） ---------------- */
.primary:disabled{opacity:.55;pointer-events:none}
/* 「暂不该点」但仍可用：用于「说完了」这类——空输入时点了要给提示。
   所以只弱化视觉，既不能加 pointer-events:none（会吞掉提示），
   也不能用 disabled / aria-disabled（前者吞点击，后者语义上等于"不可用"）。 */
.primary.is-dim{opacity:.55}

/* ---------------- 我的记忆（v1.3.0 记忆地基） ---------------- */
.memory{padding:0 0 24px}
.mem-list{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow-sm);overflow:hidden;margin:14px 0}
.mem-row{padding:14px 16px;border-bottom:1px solid var(--line)}
.mem-row:last-child{border-bottom:0}
.mem-row__top{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}
.mem-type{font-size:12px;padding:2px 9px;border-radius:999px;background:var(--primary-soft);color:var(--primary-deep)}
.mem-type--event{background:rgba(168,200,232,.20);color:var(--blue)}
.mem-type--knot{background:rgba(255,184,140,.22);color:var(--orange)}
.mem-star{border:0;background:transparent;font-size:17px;color:var(--ink-3);cursor:pointer;line-height:1;padding:2px 4px}
.mem-star.is-on{color:#F0B429}
.mem-title{font-size:15.5px;font-weight:600;line-height:1.5}
.mem-summary{font-size:13.5px;color:var(--ink-2);line-height:1.6;margin-top:3px}
.mem-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:8px}
.mem-tag{font-size:11.5px;padding:1px 8px;border-radius:999px;background:rgba(168,216,200,.20);color:#5FA98C}
.mem-date{font-size:11.5px;color:var(--ink-3);margin-left:auto}
.mem-acts{display:flex;gap:14px;justify-content:flex-end;margin-top:8px}
.mem-acts .linkbtn{font-size:13.5px}
.danger-link{color:var(--danger)}
.mem-empty{padding:34px 18px;text-align:center;color:var(--ink-2);font-size:14px;line-height:1.7;margin:0}
.mem-foot{padding:14px 16px}
.mem-edit{display:flex;flex-direction:column;gap:10px}
.mem-edit-title,.mem-edit-summary{width:100%;border:1.5px solid var(--line);border-radius:12px;padding:10px 12px;font-size:14.5px;font-family:inherit;color:var(--ink);background:var(--surface-2);box-shadow:var(--hi-soft);resize:vertical}
.mem-edit-summary{min-height:64px;line-height:1.6}
.mem-edit-title:focus,.mem-edit-summary:focus{outline:none;border-color:var(--primary-deep)}
.mem-edit-acts{display:flex;gap:12px;justify-content:flex-end}
.mem-edit-acts .linkbtn{font-size:14px}

/* 我的页「记忆」入口图标配色 */
.mrow--memory .mrow__ico{background:rgba(255,184,140,.18)}
.mrow--memory .mrow__ico svg{stroke:var(--orange)}
.mrow--support .mrow__ico{background:rgba(201,138,122,.16)}
.mrow--support .mrow__ico svg{stroke:var(--danger)}

/* ============================================================
   墨小溟 · v1.3.0 IP 情绪视觉引擎（state-machine.js 联动）
   设计红线：低饱和、不闪烁/不频闪、IP 造型固定（只改色与触手姿态）、ease-in-out、拒绝硬弹跳。
   颜色由 state-machine.js 按 L1/L2/L3 内联覆盖；此处类仅给「默认（L2）+ 姿态动画」兜底。
   ============================================================ */

/* —— 新增情绪姿态类（joy/sad/tired/lonely/mixed/vague/danger）—— */
.mascot--joy{
  --ip-body-in:#b5c7ff;--ip-body-mid:#a9b8f0;--ip-body-out:#9fb0ea;
  --ip-halo:#cdd9ff;--ip-tip:#FFCFA0;--ip-antenna:#b8c6f5;--ip-glow:#e8eeff;--ip-glow-2:#d6e4ff;
  animation:ip-relax-sway 4.4s ease-in-out infinite;
}
.mascot--joy .mascot__body{animation:ip-breathe 4.2s ease-in-out infinite}
.mascot--joy .glow{animation:ip-drift 5.4s ease-in-out infinite}
.mascot--joy .mascot__wisp{animation:ip-wisp 4s ease-in-out infinite}

.mascot--sad{
  --ip-body-in:#9e9ebf;--ip-body-mid:#9494b2;--ip-body-out:#8c8cad;
  --ip-halo:#b3b3cd;--ip-antenna:#9a9ab6;--ip-glow:#cfcfdd;--ip-glow-2:#bcbccd;
  animation:ip-fog-float 6s ease-in-out infinite;
}
.mascot--sad .mascot__body{animation:ip-shrink 5.2s ease-in-out infinite;transform-origin:100px 116px}
.mascot--sad .mascot__halo{opacity:.7}
.mascot--sad .glow{animation:ip-drift 7s ease-in-out infinite}

.mascot--tired{
  --ip-body-in:#9c97b0;--ip-body-mid:#928da6;--ip-body-out:#8f8aa3;
  --ip-halo:#b0abc0;--ip-antenna:#9691a8;--ip-glow:#cfccda;--ip-glow-2:#bdb9c9;
}
.mascot--tired .mascot__body{animation:ip-breathe 6s ease-in-out infinite}
.mascot--tired .mascot__antennae{transform:rotate(8deg);transition:transform .4s ease}
.mascot--tired .mascot__halo{opacity:.5}
.mascot--tired .glow{opacity:.4;animation:ip-drift 8s ease-in-out infinite}

.mascot--lonely{
  --ip-body-in:#98a8c0;--ip-body-mid:#8fa6bd;--ip-body-out:#8aa0b5;
  --ip-halo:#b6c6d8;--ip-antenna:#94a8be;--ip-glow:#d2dcea;--ip-glow-2:#c2d2e0;
  animation:ip-drift-x 7s ease-in-out infinite;
}
.mascot--lonely .mascot__body{animation:ip-breathe 5.6s ease-in-out infinite}
.mascot--lonely .glow{opacity:.5;animation:ip-drift 8s ease-in-out infinite}
.mascot--lonely .mascot__wisp{animation:ip-wisp 6s ease-in-out infinite}

.mascot--mixed{
  --ip-body-in:#a78bfa;--ip-body-mid:#8aa0ee;--ip-body-out:#60a5fa;
  --ip-halo:#b9a8f8;--ip-antenna:#9f95ee;--ip-glow:#e6dcff;--ip-glow-2:#cfe4ff;
  animation:ip-dual-sway 5s ease-in-out infinite;
}
.mascot--mixed .mascot__body{animation:ip-breathe 4.6s ease-in-out infinite}
.mascot--mixed .glow{animation:ip-drift 5.4s ease-in-out infinite}
.mascot--mixed .mascot__wisp{animation:ip-wisp 4.4s ease-in-out infinite}

.mascot--vague{
  --ip-body-in:#a8acb8;--ip-body-mid:#9ea4b0;--ip-body-out:#9ca3af;
  --ip-halo:#c2c6d0;--ip-antenna:#a2a8b4;--ip-glow:#dcdee6;--ip-glow-2:#cccfd8;
  animation:ip-fog-float 7s ease-in-out infinite;
}
.mascot--vague .mascot__body{animation:ip-breathe 5.4s ease-in-out infinite}
.mascot--vague .mascot__halo{opacity:.6}

/* danger：停所有情绪动画，只保留柔和警示光圈（缓慢呼吸，不闪烁） */
.mascot--danger{
  --ip-body-in:#442c50;--ip-body-mid:#3a2444;--ip-body-out:#2e1c38;
  --ip-halo:#6b4a7a;--ip-antenna:#4a3056;--ip-glow:#7a5a86;--ip-glow-2:#5a3d66;
  animation:none;
}
.mascot--danger .mascot__body{animation:none}
.mascot--danger .glow,
.mascot--danger .mascot__wisp,
.mascot--danger .mascot__antennae{animation:none}
.mascot--danger .mascot__halo{animation:ip-warn-ring 3.4s ease-in-out infinite;opacity:.5}
.mascot--danger .mascot__breath{stroke:var(--ip-halo);opacity:.5;animation:ip-warn-ring 3.4s ease-in-out infinite}

/* —— v1.3.0 新增关键帧（全部 ease-in-out，缓慢、无硬跳）—— */
@keyframes ip-relax-sway{0%,100%{transform:translateY(0) rotate(-1.6deg)}50%{transform:translateY(-5px) rotate(1.6deg)}}
@keyframes ip-shrink{0%,100%{transform:scale(.96) translateY(3px)}50%{transform:scale(.92) translateY(6px)}}
@keyframes ip-drift-x{0%,100%{transform:translateX(-6px)}50%{transform:translateX(6px)}}
@keyframes ip-dual-sway{0%{transform:rotate(-2.2deg)}50%{transform:rotate(2.2deg)}100%{transform:rotate(-2.2deg)}}
@keyframes ip-fog-float{0%,100%{transform:translateY(0);opacity:.96}50%{transform:translateY(-4px);opacity:1}}
@keyframes ip-warn-ring{0%,100%{opacity:.28;transform:scale(.96)}50%{opacity:.5;transform:scale(1.04)}}

/* —— 背景水墨/水流层（#ipBg，固定全屏、置于内容之上 2px、不挡交互）—— */
.ip-bg{position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.34;transition:opacity .9s ease-in-out}
.ip-bg::before{content:'';position:absolute;inset:0;opacity:.9;animation:ip-bg-breathe 9s ease-in-out infinite}
@keyframes ip-bg-breathe{0%,100%{opacity:.7}50%{opacity:1}}
.ip-bg--steady_water::before{background:radial-gradient(circle at 50% 18%,rgba(201,188,240,.55),rgba(201,188,240,0) 60%)}
.ip-bg--bright_bubble::before{background:radial-gradient(circle at 50% 16%,rgba(181,199,255,.6),rgba(181,199,255,0) 58%)}
.ip-bg--dark_ink_sink::before{background:radial-gradient(circle at 50% 30%,rgba(140,140,173,.55),rgba(140,140,173,0) 62%)}
.ip-bg--heavy_ink_surge::before{background:radial-gradient(circle at 50% 26%,rgba(84,52,97,.55),rgba(84,52,97,0) 64%)}
.ip-bg--more_ripple::before{background:radial-gradient(circle at 50% 20%,rgba(122,111,168,.55),rgba(122,111,168,0) 60%)}
.ip-bg--dim_bg::before{background:radial-gradient(circle at 50% 20%,rgba(143,138,163,.45),rgba(143,138,163,0) 64%);opacity:.6}
.ip-bg--empty_bubble::before{background:radial-gradient(circle at 50% 18%,rgba(138,160,181,.48),rgba(138,160,181,0) 60%)}
.ip-bg--two_color_ink_blend::before{
  background:radial-gradient(circle at 42% 18%,rgba(167,139,250,.55),rgba(167,139,250,0) 62%),
             radial-gradient(circle at 60% 24%,rgba(96,165,250,.45),rgba(96,165,250,0) 60%);
}
.ip-bg--fog_ink::before{background:radial-gradient(circle at 50% 20%,rgba(172,176,191,.5),rgba(172,176,191,0) 66%)}
.ip-bg--soft_warning_ring::before{background:radial-gradient(circle at 50% 22%,rgba(107,74,122,.45),rgba(107,74,122,0) 60%)}
.ip-bg--ink_ripple::before{background:radial-gradient(circle at 50% 22%,rgba(120,100,170,.5),rgba(120,100,170,0) 64%)}

/* 接收情绪：墨汁波纹（一次性缓慢扩散，不频繁触发 → 不闪烁） */
.ip-ripple{position:absolute;left:50%;top:30%;width:120px;height:120px;margin:-60px 0 0 -60px;border-radius:50%;
  border:2px solid rgba(120,100,170,.5);opacity:0;pointer-events:none;z-index:3}
.ip-ripple.is-on{animation:ip-ink-ring 1.6s ease-out}
@keyframes ip-ink-ring{0%{transform:scale(.5);opacity:.55}100%{transform:scale(1.8);opacity:0}}

/* —— 用户可控开关门禁（与 store.settings.ipMotion / ipIntensity 对齐）—— */
/* 总开关：一键关闭全部色彩/动画/特效 */
body.ip-motion-off .mascot,
body.ip-motion-off .mascot *{animation:none !important;transition:none !important}
body.ip-motion-off #ipBg,
body.ip-motion-off .ip-ripple{display:none !important}
body.ip-motion-off .mascot__breath{opacity:0 !important}
/* 强度档：柔和（减速减幅，更安静） */
body.ip-intensity-gentle .mascot,
body.ip-intensity-gentle .mascot *{animation-duration:2.4s !important;animation-timing-function:ease-in-out !important}
body.ip-intensity-gentle #ipBg{opacity:.26 !important}

/* —— 接收情绪气泡 + 分析页定位 —— */
.stage-mascot{position:relative}
.ip-recv-bubble{margin-top:12px;text-align:center;font-size:14px;letter-spacing:.04em;color:var(--primary-deep);opacity:.85;animation:ip-bg-breathe 2.6s ease-in-out infinite}

/* AI 回复微动作：墨鱼缓缓靠近（仅 ai_reply 节点，作用在 body 避免覆盖情绪姿态动画） */
.ip-node-ai_reply .mascot__body{animation:ip-ai-approach 3.6s ease-in-out infinite !important}
@keyframes ip-ai-approach{0%,100%{transform:scale(1) translateY(0)}50%{transform:scale(1.035) translateY(-3px)}}

/* ============================================================
   v1.3.1~1.3.4：IP 点击轻互动 / 安静陪伴 / 我页
   ============================================================ */
/* IP 气泡（点击轻互动） */
.say__mascot{position:relative}
.ip-bubble{position:absolute;left:50%;bottom:-4px;transform:translate(-50%,10px);background:rgba(255,255,255,.96);color:var(--primary-deep);font-size:13.5px;line-height:1;padding:9px 15px;border-radius:14px;box-shadow:0 6px 20px rgba(120,100,170,.2);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .25s ease,transform .25s ease;z-index:5}
.ip-bubble--on{opacity:1;transform:translate(-50%,0)}
/* 常显气泡（倾听节点「我在听」用；不参与点击互动的淡入淡出） */
.ip-bubble--static{opacity:1;transform:translate(-50%,0);position:static;margin:6px auto 0;white-space:normal;display:table}

/* 点击动画（作用在 IP 容器上；总开关/强度档门禁见下） */
.say__mascot.ip-tap1{animation:ip-tap1 .8s ease-in-out}
.say__mascot.ip-tap2{animation:ip-tap2 1.2s ease-in-out}
.say__mascot.ip-tap3{animation:ip-tap3 1.5s ease-in-out}
.say__mascot.ip-tap-over{animation:ip-tap-over 1s ease-in-out}
@keyframes ip-tap1{0%,100%{transform:rotate(0)}30%{transform:rotate(-3.5deg)}62%{transform:rotate(2.6deg)}}
@keyframes ip-tap2{0%,100%{transform:scale(1)}40%{transform:scale(.95)}70%{transform:scale(1.03)}}
@keyframes ip-tap3{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
@keyframes ip-tap-over{0%,100%{transform:rotate(0)}25%{transform:rotate(3deg)}75%{transform:rotate(-3deg)}}
body.ip-motion-off .say__mascot{animation:none !important}
body.ip-intensity-gentle .say__mascot{animation-duration:1.5s !important}

/* 安静陪伴模式：视觉降噪（文字低对比度、背景更柔） */
body.quiet-mode #ipBg{opacity:.2}
body.quiet-mode .say__greet{color:var(--ink-2);font-weight:500;letter-spacing:.02em}
body.quiet-mode .say__hint{opacity:.5}
body.quiet-mode .empty-hint{opacity:.45}
body.quiet-mode .talkbtn{opacity:.84}

/* 我页（v1.3.4）新增结构与样式 */
.me-head2{text-align:center;padding:4px 0 6px}
.me__title2{font-size:20px;margin:8px 0 4px;font-weight:600}
.me__sub2{font-size:13.5px;color:var(--ink-2);margin:0}
.mblock{background:var(--card,#fff);border-radius:var(--radius,18px);padding:16px 18px;box-shadow:var(--shadow-sm,0 5px 20px rgba(160,140,200,.11));margin-bottom:12px}
.mblock__t{font-size:15px;font-weight:600;margin-bottom:6px}
.mblock__d{font-size:13.5px;color:var(--ink-2);margin:0 0 10px;line-height:1.6}
.mblock__n{font-size:12.5px;color:var(--ink-2);opacity:.85;margin:8px 0 0;line-height:1.6}
.mblock--quiet .mblock__n{opacity:.7}
.mblock .switch{margin-top:10px}
.me-export{width:100%;margin-top:4px}
.faq{margin-top:8px;border-top:1px solid var(--line,rgba(0,0,0,.06));padding-top:8px}
.faq summary{cursor:pointer;font-size:14px;color:var(--ink);list-style:none}
.faq summary::-webkit-details-marker{display:none}
.faq p{font-size:13px;color:var(--ink-2);line-height:1.65;margin:6px 0 0}
.danger-link{color:var(--danger,#e06a6a);background:none;border:0;padding:8px 0;font-size:14px;cursor:pointer;font-family:inherit;display:block}
/* v1.3.4 开场回应句：独立于 .fu-empathy（模型共情句），是一条更轻的「先接住你」的引入语 */
.fu-opening{margin:0 0 10px;text-align:center;color:var(--primary-deep);font-size:15px;line-height:1.7}

/* ===== v1.4.0 手动检查更新的结果行 =====
   为什么要有：以前点「检查更新」，在"已是最新版"时页面一字不变 ⇒ 用户体感=功能坏了。
   现在永远给一行可见回话（成功绿底 / 失败红底），失败时把真实原因原样写出来，方便截图定位。 */
.cl-check__result{margin:8px 0 0;padding:9px 11px;border-radius:10px;background:rgba(157,124,216,.10);white-space:normal;word-break:break-all;font-size:13px;line-height:1.6;transition:background .2s}
.cl-check__result[data-state="ok"]{background:rgba(110,180,140,.16)}
.cl-check__result[data-state="fail"]{background:rgba(214,110,110,.16);color:#9c4d4d}
.cl-check__result[data-state="pending"]{opacity:.75}
/* 诊断报告一键复制按钮：比普通 ghost 更醒目一点（真机排障主入口） */
.diag-actions #diagReport{font-weight:600}

/* ── v1.6.2 月度情绪复盘（文档 §追加模块3）────────────────────────
   淡紫主题：与时间线四档（紫/蓝/暖/灰）同族，但更浅更柔，一眼能认出是「总结」不是「一次倾诉」 */
.tl-card--month-purple{border-color:rgba(178,158,232,.5);box-shadow:0 10px 28px rgba(126,108,190,.13),inset 0 1px 6px rgba(255,255,255,.55);background:linear-gradient(160deg,#FBF9FE,#F4EFFB)}
.tl-node--month-purple{background:#F3EEFC}
.tl-card--month-purple .tl-node__no{color:#6B57A8}
.tl-card--month-purple .tl-node__emo{color:#5B4A93}
.tl-card--month-purple .tl-summary{color:#4A3D78}
/* 🔴 别复用 offbar-in：那个关键帧里是 translateX(-50%)（给 left:50% 的居中小浮条用的）。
   复用到 inset:0 的全屏遮罩 ⇒ 整个遮罩左移半个屏宽，只盖住左半屏、卡片也挤到屏幕左边。 */
@keyframes monthly-in{from{opacity:0}to{opacity:1}}
@keyframes monthly-pop{from{opacity:0;transform:translateY(10px) scale(.96)}to{opacity:1;transform:none}}
.monthly-overlay{position:fixed;inset:0;z-index:82;background:rgba(58,58,58,.34);display:flex;align-items:center;justify-content:center;padding:24px;animation:monthly-in .2s ease both}
.monthly-card{background:var(--surface);border:1px solid var(--card-line);border-radius:var(--radius);padding:22px 20px;max-width:330px;width:100%;box-shadow:var(--shadow),var(--hi-soft);text-align:center;animation:monthly-pop .24s cubic-bezier(.2,.8,.3,1) both}
.monthly-card__ip{display:flex;justify-content:center;margin-bottom:8px}
.monthly-card__title{font-size:16px;font-weight:600;color:var(--ink);margin-bottom:10px}
.monthly-card__body{font-size:14px;line-height:1.75;color:var(--ink-2);margin-bottom:18px}
.monthly-card__body p{margin:0 0 6px}
.monthly-card__insight{color:#5B4A93}
.monthly-card__btns{display:flex;gap:12px;align-items:center}
.monthly-card__btns .ghost{flex:1;text-align:center;color:var(--ink-2);padding:11px 0}
.monthly-card__btns .primary{flex:1;margin-top:0;padding:12px 0;font-size:15px}

/* ==================== v1.6.13 情绪动效联动（emotion_motion_map.ip_anim 真落地） ====================
   🔴 背景：moxiaoming_motion_sound_config.json 给七种情绪各声明了一个 ip_anim
   （float_up_relax / sink_quiet / tight_swing_slow / tiny_shiver_slow / super_slow_idle /
   drift_sway_alternate / static_calm），但样式表里从来没有对应的 @keyframes ⇒
   「声明了却没实现」：改配置什么都不会发生（比没有更糟，因为它看起来是权威的）。
   这里补齐七个动画，由 motion.setState() 挂到 IP 外层包裹元素上——
   外层做情绪位移、内层仍跑待机浮沉，两层是嵌套 transform，互不覆盖。 */
@keyframes float_up_relax { 0%,100%{transform:translateY(0) scale(1)} 50%{transform:translateY(-10px) scale(1.02)} }
@keyframes sink_quiet { 0%,100%{transform:translateY(0) scale(1)} 50%{transform:translateY(10px) scale(.985)} }
@keyframes tight_swing_slow { 0%,100%{transform:rotate(-1.6deg)} 50%{transform:rotate(1.6deg)} }
@keyframes tiny_shiver_slow { 0%,100%{transform:translateX(-1.2px)} 50%{transform:translateX(1.2px)} }
@keyframes super_slow_idle { 0%,100%{transform:translateY(-3px)} 50%{transform:translateY(3px)} }
@keyframes drift_sway_alternate { 0%{transform:translateX(-7px)} 50%{transform:translateX(7px)} 100%{transform:translateX(-7px)} }
@keyframes static_calm { 0%,100%{transform:none} }

.float_up_relax { animation: float_up_relax 7s ease-in-out infinite; }
.sink_quiet { animation: sink_quiet 8s ease-in-out infinite; }
.tight_swing_slow { animation: tight_swing_slow 9s ease-in-out infinite; }
.tiny_shiver_slow { animation: tiny_shiver_slow 3.2s ease-in-out infinite; }
.super_slow_idle { animation: super_slow_idle 12s ease-in-out infinite; }
.drift_sway_alternate { animation: drift_sway_alternate 10s ease-in-out infinite; }
.static_calm { animation: none; }

/* ---------- v1.7.0：下载与安装页 ---------- */
.dlpage { padding: 22px 20px 40px; }
.dlpage__ip { display: flex; justify-content: center; margin: 6px 0 14px; }
.dlpage__lead { margin: 0 auto 22px; font-size: 14px; line-height: 1.85; color: var(--ink-2); text-align: center; max-width: 30em; }
.dlpage__note { margin: 10px 2px 0; font-size: 13px; line-height: 1.8; color: var(--ink-2); min-height: 1.8em; }
.dlcard {
  margin: 10px 0 22px; padding: 18px 18px 16px; border-radius: 18px;
  background: var(--primary-soft); border: 1px solid var(--line);
}
.dlcard--ios { background: rgba(168,200,232,.16); }
.dlcard--wechat { background: rgba(255,184,140,.16); }
.dlcard--apk { background: rgba(184,169,232,.14); }
.dlcard__t { font-size: 15px; font-weight: 600; margin-bottom: 8px; }
.dlcard__b { margin: 0 0 14px; font-size: 13.5px; line-height: 1.8; color: var(--ink-2); }
.dlcard__btn { display: block; width: 100%; }
.dlcard__hint { margin: 10px 0 0; font-size: 13px; line-height: 1.8; color: var(--ink-2); }
.dlver { margin: 4px 0 22px; }
.dlver__row { display: flex; justify-content: space-between; align-items: center; padding: 11px 2px; border-bottom: 1px solid var(--line); font-size: 14px; }
.dlver__row:first-child { border-top: 1px solid var(--line); }
.dlver__row span { color: var(--ink-2); font-size: 13.5px; }
.dlver__row b { font-weight: 600; }
.dlver__notes { margin: 12px 2px 0; padding-left: 18px; font-size: 13px; line-height: 1.85; color: var(--ink-2); }
.dlsteps { margin: 0 0 16px; }
.dlsteps summary { font-size: 14px; color: var(--ink-2); padding: 10px 2px; cursor: pointer; }
.dlsteps ol { margin: 0; padding-left: 20px; font-size: 13.5px; line-height: 1.95; color: var(--ink-2); }
.dlsteps ol li { margin: 4px 0; }
.me-install { display: block; width: 100%; margin-top: 10px; }
