/* ============================================================
   SKYLAND 天空岛 · 外刊精读  —— 浅蓝渐变 · 毛玻璃
   ============================================================
   ⚠️ 改玻璃质感前必读（2026-09-19 起）：
   全站玻璃参数已收敛到文件**末尾**的「iOS 材质统一层」，并以 :root 里的
   --ios-* 变量为准。前面各处同名元素上残留的旧 backdrop-filter 字面值
   （如 .chip 的 blur(10px)）已被末尾统一层覆盖、**改了不会生效**。
   要调模糊/边框/内阴影，请改 --ios-* 变量或末尾的统一层。
   ============================================================ */

:root{
  --paper:#EAF5FF;
  /* ---- 天蓝玻璃材质（高级版 · 体积光）----
     思路：不是把框「涂蓝」，而是做出「一块有厚度的玻璃」——
     顶部受光（近白）、底部沉降（天蓝），配发丝白边 + 深投影把它托起来。
     三级：面板 / 控件 / 输入槽（输入槽顶部更暗，像凹进去的槽）。 */
  --sky-hi:linear-gradient(180deg,rgba(255,255,255,.98) 0%,rgba(255,255,255,.55) 6%,rgba(255,255,255,0) 20%), linear-gradient(118deg,rgba(255,255,255,0) 30%,rgba(255,255,255,.22) 42%,rgba(255,255,255,0) 58%);
  --sky-panel:linear-gradient(168deg,rgba(255,255,255,.9) 0%,rgba(255,255,255,.66) 30%,rgba(214,238,253,.78) 62%,rgba(170,220,252,.82) 88%,rgba(222,242,255,.92) 97%,rgba(186,230,253,.8) 100%);
  --sky-ctl:linear-gradient(168deg,rgba(255,255,255,.86) 0%,rgba(228,244,254,.78) 52%,rgba(162,216,252,.74) 86%,rgba(214,240,255,.88) 97%,rgba(176,224,252,.76) 100%);
  --sky-in:linear-gradient(180deg,rgba(56,189,248,.4) 0%,rgba(125,211,252,.48) 46%,rgba(186,230,253,.56) 82%,rgba(224,242,254,.66) 100%);
  --sky-edge:rgba(125,211,252,.6);
  --sky-deep:0 1px 1px rgba(2,32,71,.07), 0 2px 4px rgba(2,132,199,.06), 0 10px 22px -10px rgba(2,132,199,.16), 0 32px 56px -28px rgba(2,90,160,.4);
  --paper-2:var(--sky-hi), var(--sky-panel);
  --surface:var(--sky-hi), var(--sky-panel);
  --surface-2:var(--sky-hi), var(--sky-ctl);
  --glass-brd:rgba(255,255,255,.78);
  --ink:#0B1E33;
  --ink-2:#2A3F58;
  --muted:#587089;
  --faint:#7E96AE;
  --line:rgba(11,30,51,.08);
  --line-2:rgba(11,30,51,.045);

  /* 学习/进度主色：天蓝渐变 */
  --accent:#0EA5E9;
  --accent-2:#38BDF8;
  --accent-ink:#0369A1;
  --accent-soft:rgba(14,165,233,.12);
  --accent-grad:linear-gradient(135deg,#7DD3FC,#38BDF8 50%,#0EA5E9);

  /* 会员/成就点缀：金 */
  --gold:#B08D4F;
  --gold-2:#D9B978;
  --gold-soft:rgba(176,141,79,.14);

  --teal:#0D9488;
  --rose:#E11D48;

  --shadow-s:0 1px 2px rgba(2,132,199,.07);
  --shadow-m:0 2px 6px rgba(2,132,199,.06), 0 14px 34px -14px rgba(2,132,199,.28);
  --shadow-l:0 2px 6px rgba(2,132,199,.07), 0 28px 64px -24px rgba(2,132,199,.38);
  --glass-inset:inset 0 1px 0 rgba(255,255,255,.85);
  --r-s:10px; --r-m:14px; --r-l:20px; --r-xl:26px;

  /* ---- iOS 材质（全站玻璃统一配方 · 2026-09-19 升级）----
     雾面半径：大表面 24px / 小控件 16px；饱和度全站统一 1.8。
     玻璃厚度用三层内阴影表达（顶棱线高光 + 底面反光 + 边缘内晕）。
     注意：只调参数、不新增模糊层，避免拖慢手机滚动。 */
  --ios-blur:24px;
  --ios-blur-sm:16px;
  --ios-sat:1.8;
  --ios-hi:rgba(255,255,255,.92);
  --ios-lo:rgba(255,255,255,.34);
  --ios-hair:rgba(125,211,252,.62);
  --ios-edge:rgba(186,230,253,.55);
  --ios-ring:rgba(56,189,248,.26);
  --ios-glow:0 18px 44px -20px rgba(2,132,199,.38);

  /* 高级感动效曲线 */
  --ease-spring:cubic-bezier(.34,1.56,.64,1);
  --ease-out:cubic-bezier(.2,.8,.3,1);

  --f-display:'Iowan Old Style','Palatino Linotype','Palatino','Georgia','Times New Roman',serif;
  --f-read:'Charter','Iowan Old Style','Georgia','Cambria',serif;
  --f-ui:-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
  --f-mono:'SFMono-Regular','JetBrains Mono',Consolas,'Courier New',monospace;
}
[data-theme="dark"]{
  --paper:#0A1120;
  --sky-hi:linear-gradient(180deg,rgba(186,225,253,.3) 0%,rgba(186,225,253,.08) 7%,rgba(186,225,253,0) 22%), linear-gradient(118deg,rgba(186,225,253,0) 32%,rgba(186,225,253,.07) 44%,rgba(186,225,253,0) 58%);
  --sky-panel:linear-gradient(168deg,rgba(125,211,252,.22) 0%,rgba(30,90,130,.38) 40%,rgba(10,60,96,.5) 84%,rgba(56,150,210,.42) 96%,rgba(12,74,110,.48) 100%);
  --sky-ctl:linear-gradient(168deg,rgba(125,211,252,.18) 0%,rgba(20,80,120,.3) 56%,rgba(10,60,96,.42) 86%,rgba(56,150,210,.34) 96%,rgba(12,74,110,.4) 100%);
  --sky-in:linear-gradient(180deg,rgba(56,189,248,.28) 0%,rgba(14,116,144,.36) 50%,rgba(12,74,110,.46) 82%,rgba(30,100,150,.5) 100%);
  --sky-edge:rgba(56,189,248,.42);
  --sky-deep:0 1px 1px rgba(0,0,0,.5), 0 2px 4px rgba(0,0,0,.4), 0 10px 24px -10px rgba(0,0,0,.55), 0 32px 60px -28px rgba(2,132,199,.5);
  --paper-2:var(--sky-hi), var(--sky-panel);
  --surface:var(--sky-hi), var(--sky-panel);
  --surface-2:var(--sky-hi), var(--sky-ctl);
  --glass-brd:rgba(120,150,200,.18);
  --ink:#E9EFF8;
  --ink-2:#CBD7E6;
  --muted:#93A2B8;
  --faint:#64748B;
  --line:rgba(148,175,220,.14);
  --line-2:rgba(148,175,220,.07);
  --accent:#38BDF8;
  --accent-2:#7DD3FC;
  --accent-ink:#7DD3FC;
  --accent-soft:rgba(56,189,248,.16);
  --gold:#D9B978;
  --gold-2:#F0D9A6;
  --gold-soft:rgba(217,185,120,.16);
  --teal:#5EEAD4;
  --rose:#FB7185;
  --shadow-s:0 1px 2px rgba(0,0,0,.4);
  --shadow-m:0 2px 6px rgba(0,0,0,.3), 0 14px 34px -14px rgba(0,0,0,.6);
  --shadow-l:0 2px 6px rgba(0,0,0,.3), 0 28px 64px -24px rgba(0,0,0,.7);
  --glass-inset:inset 0 1px 0 rgba(255,255,255,.08);
  /* iOS 材质的深色对应值（模糊半径/饱和度沿用 :root，不重复定义） */
  --ios-hi:rgba(186,225,253,.22);
  --ios-lo:rgba(186,225,253,.07);
  --ios-hair:rgba(56,189,248,.34);
  --ios-edge:rgba(56,189,248,.22);
  --ios-ring:rgba(56,189,248,.30);
  --ios-glow:0 18px 44px -22px rgba(2,132,199,.55);
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
/* v2.6.3：把「下拉刷新」彻底关死（body 已经 overflow:hidden、.main 也有 overscroll-behavior:contain，
   但旧版 iOS Safari 不认 .main 上那条，手指在正文顶部继续下拉仍会触发整页刷新 ——
   正在读的文章会被一次误触刷掉，看起来就是「网页重启」）。 */
html,body{overscroll-behavior:none;overscroll-behavior-y:none}
body{
  font-family:var(--f-ui);
  color:var(--ink);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow:hidden;
  /* 天蓝渐变 + 柔雾光斑（ins 风空气感） */
  background:
    radial-gradient(900px 480px at 50% -8%, rgba(255,255,255,.85), transparent 60%),
    radial-gradient(1100px 700px at 10% 6%, rgba(125,211,252,.26), transparent 60%),
    radial-gradient(920px 660px at 90% 12%, rgba(147,213,255,.24), transparent 62%),
    radial-gradient(760px 560px at 78% 88%, rgba(56,189,248,.13), transparent 64%),
    radial-gradient(1200px 820px at 50% 112%, rgba(125,211,252,.17), transparent 66%),
    radial-gradient(1500px 1050px at 50% 45%, transparent 62%, rgba(120,170,220,.12) 100%),
    linear-gradient(170deg, #FAFDFF 0%, #F2F9FE 50%, #EAF4FD 100%);
  background-attachment:fixed;
}
[data-theme="dark"] body{
  background:
    radial-gradient(1000px 520px at 50% -10%, rgba(56,189,248,.14), transparent 60%),
    radial-gradient(1100px 720px at 12% 8%, rgba(14,165,233,.22), transparent 60%),
    radial-gradient(950px 680px at 88% 14%, rgba(56,189,248,.13), transparent 62%),
    radial-gradient(1200px 820px at 50% 108%, rgba(2,132,199,.16), transparent 66%),
    radial-gradient(1500px 1050px at 50% 45%, transparent 58%, rgba(0,0,0,.38) 100%),
    linear-gradient(160deg, #0A1120 0%, #0B1424 50%, #0C1226 100%);
  background-attachment:fixed;
}
button,input,select{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:none}
button:focus-visible,.btn:focus-visible,.chip:focus-visible,.navbtn:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:8px;
}
.btn[disabled]{cursor:default}
svg{display:block}
::selection{background:var(--accent-soft);color:var(--ink)}

/* hidden 必须压过任何 display 设置 */
[hidden]{display:none !important}

/* 颗粒（伪元素承载，极淡） */
.grain{position:fixed;inset:0;z-index:9999;pointer-events:none}
.grain::after{
  content:"";position:absolute;inset:0;opacity:.18;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
}

/* 毛玻璃通用表面（大面板统一走 --ios-blur：2026-09-19 由 20px/1.7 升级为 24px/1.8）
   这一条是全站大面板的雾面总闸，改这里即可统一 .card/.rail/.modal__box 等 14 类表面。
   各面板自己的背景/边框/阴影仍在各自规则里定义，不受此处影响。 */
.card,.quote,.acard,.stat,.vcard,.plan,.reader__donecard,.modal__box,.fallback__box,.viphero,.rail,.timerpill,.wordcard{
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
}

/* ============ 按钮 ============ */
.btn{
  position:relative;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  height:41px;padding:0 21px;border-radius:999px;
  font-size:14px;font-weight:600;letter-spacing:.02em;
  transition:transform .28s var(--ease-spring), box-shadow .25s, background .25s, color .2s, border-color .2s, filter .2s;
  white-space:nowrap;
  -webkit-tap-highlight-color:transparent;
}
.btn:active{transform:translateY(1px) scale(.965)}
.btn--ink{background:var(--accent-grad);color:#fff;box-shadow:0 2px 6px rgba(2,132,199,.18), 0 12px 28px -12px rgba(14,165,233,.65)}
.btn--ink:hover{box-shadow:0 2px 6px rgba(2,132,199,.2), 0 18px 40px -14px rgba(14,165,233,.8);transform:translateY(-1.5px);filter:brightness(1.06)}
.btn--gold{
  background:linear-gradient(135deg,#C7A35F 0%,#EAD3A1 45%,#D9B978 60%,#B98F4E 100%);
  background-size:200% 100%;
  color:#241B0B;box-shadow:0 1px 2px rgba(30,58,138,.12), 0 12px 30px -14px rgba(176,141,79,.7), inset 0 1px 0 rgba(255,255,255,.55), inset 0 -1px 0 rgba(120,85,30,.28);
}
.btn--gold:hover{background-position:100% 0;transform:translateY(-1.5px);box-shadow:0 1px 2px rgba(30,58,138,.12), 0 18px 40px -14px rgba(176,141,79,.85)}
.btn--ghost{background:var(--surface);border:1px solid var(--glass-brd);color:var(--ink);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.btn--ghost:hover{border-color:var(--accent-2);color:var(--accent);transform:translateY(-1px);box-shadow:var(--shadow-m)}
.btn--plain{color:var(--muted);padding:0 12px}
.btn--plain:hover{color:var(--ink)}
.btn--sm{height:32px;padding:0 14px;font-size:12.5px}
.btn--lg{height:50px;padding:0 40px;font-size:15px;letter-spacing:.08em}
.btn--block{width:100%}
.btn[disabled]{opacity:.45;pointer-events:none}
.linkbtn{position:relative;overflow:hidden;border-radius:6px;color:var(--accent);font-size:12.5px;font-weight:600;letter-spacing:.03em;transition:transform .2s var(--ease-spring), color .18s;-webkit-tap-highlight-color:transparent;
  /* ⚠️ v2.6.5：必须禁止折行 —— 金句卡底部那行按钮在手机上被挤过：
     「收藏 / 收藏夹 / 换一句」被逐字折成竖排单字（站里 .seg__btn 踩过同一个坑）。
     加 nowrap 后宁可整行换到下一行，也不竖排。 */
  white-space:nowrap}
.linkbtn:hover{text-decoration:underline;text-underline-offset:3px}
.linkbtn:active{transform:scale(.94)}
.linkbtn.is-on{color:var(--accent-ink)}

.iconbtn{
  position:relative;overflow:hidden;
  width:34px;height:34px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;
  color:var(--muted);border:1px solid transparent;transition:.22s var(--ease-spring);
  -webkit-tap-highlight-color:transparent;
}
.iconbtn svg{width:17px;height:17px}
.iconbtn:hover{background:var(--surface);border-color:var(--glass-brd);color:var(--ink);transform:translateY(-1px)}
.iconbtn:active{transform:scale(.9)}
.iconbtn--text{width:auto;padding:0 12px 0 8px;gap:4px;font-size:13px;font-weight:600;color:var(--muted)}
.iconbtn--text:hover{color:var(--ink)}
.iconbtn[disabled]{opacity:.4;pointer-events:none}
[data-theme="light"] .i-moon{display:none}
[data-theme="dark"] .i-sun{display:none}

/* ============ 入口页（v2.5.17 起已删除，样式一并移除） ============ */
@media (prefers-reduced-motion: reduce){
  .app,.view{animation:none !important;opacity:1 !important;transform:none !important;filter:none !important}
  /* v2.5.3 读完动画：尊重「减弱动态效果」—— 直接给终态，不做位移/缩放/绘制。
     svg path 必须补 dashoffset:0，否则勾停在未绘制的空白状态。 */
  .reader__donecard,
  .reader__donecard > *{animation:none !important;opacity:1 !important;transform:none !important;filter:none !important}
  .reader__doneicon svg path{animation:none !important;stroke-dashoffset:0 !important}
  .reader__doneicon::before,.reader__doneicon::after{animation:none !important;opacity:0 !important}
  .ripplewave,.cf{animation:none !important;opacity:0 !important}
}

/* ============ 静态兜底页 ============ */
.fallback{
  position:fixed;inset:0;z-index:250;display:flex;align-items:center;justify-content:center;
  background:var(--paper);padding:24px;
}
.fallback__box{
  max-width:420px;text-align:center;background:var(--surface);
  border:1px solid var(--glass-brd);border-radius:var(--r-l);padding:34px 30px;box-shadow:var(--shadow-m), var(--glass-inset);
}
.fallback__t{font-family:var(--f-display);font-size:22px;letter-spacing:.14em;color:var(--accent);margin-bottom:18px}
.fallback__p{font-size:13px;line-height:2;color:var(--muted);margin-bottom:12px}
.fallback__btn{margin-top:8px}

/* ============ 布局 ============ */
/* 100dvh：iOS 上地址栏收起/展开时高度是变化的，100vh 会把底部推出屏幕；
   写两行做渐进增强 —— 不认 dvh 的老浏览器仍用上一行的 100vh。 */
.app{display:flex;height:100vh;height:100dvh;animation:fade .5s ease backwards}
@keyframes fade{from{opacity:0}to{opacity:1}}

.rail{
  width:224px;flex:0 0 224px;height:100%;
  display:flex;flex-direction:column;
  background:var(--paper-2);
  border-right:1px solid var(--glass-brd);
  padding:22px 14px 16px;
}
/* 侧栏顶端 = 个人名片（v2.6.13：站长要求删掉品牌 logo，换成可自定义的头像 + 名称） */
.rail__profile{position:relative;margin:0 2px 18px}

.rail__nav{display:flex;flex-direction:column;gap:3px;flex:1}
.navbtn{
  display:flex;align-items:center;gap:11px;
  height:42px;padding:0 12px;border-radius:12px;
  font-size:14.5px;font-weight:500;color:var(--muted);
  transition:.24s var(--ease-spring);position:relative;overflow:hidden;
  -webkit-tap-highlight-color:transparent;
}
.navbtn svg{width:18px;height:18px;flex:0 0 18px;opacity:.85}
.navbtn:hover{background:var(--surface-2);color:var(--ink);transform:translateX(2px)}
.navbtn:active{transform:scale(.97)}
.navbtn.is-active{
  background:var(--surface);color:var(--ink);font-weight:600;
  border:1px solid var(--glass-brd);box-shadow:var(--shadow-s), var(--glass-inset);
}
.navbtn.is-active::before{
  content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:3.5px;height:18px;border-radius:0 4px 4px 0;background:var(--accent-grad);
}
.navbtn__dot{
  margin-left:auto;min-width:19px;height:19px;padding:0 5px;border-radius:999px;
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:10.5px;font-weight:700;font-style:normal;
  display:flex;align-items:center;justify-content:center;
}
.navbtn__crown{
  margin-left:auto;font-style:normal;font-size:9.5px;font-weight:800;letter-spacing:.08em;
  padding:2px 6px;border-radius:5px;
  background:linear-gradient(135deg,var(--gold),var(--gold-2));color:#241B0B;
}
.rail__foot{display:flex;gap:4px;padding-top:12px;border-top:1px solid var(--line-2)}

.main{
  flex:1;height:100%;overflow-y:auto;overflow-x:hidden;
  scroll-behavior:smooth;
  /* iOS 滑动体验：惯性滚动 + 阻止滚动链（滚到底继续拖时，不会把浏览器手势/整页带出来） */
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
}
/* v2.6.19：「侧面滑动栏明显一点」这条要求在两大引擎上都要成立 —— Firefox / 不支持
   ::-webkit-scrollbar 的引擎看不见下面那套玻璃配方，那里交给系统自己的常显滚动条。
   ⚠️⚠️ 必须用 @supports selector() 圈住！在 Chrome 里只要出现 scrollbar-color / scrollbar-width，
   Chrome 就会改走「标准滚动条」渲染路径，把下面整套 ::-webkit-scrollbar 配方**整段忽略** ——
   实测后果：胶囊从多层玻璃变成一条 (131,211,251) 的实心蓝杠，v2.6.16/17 做的液态玻璃质感全丢。
   （这个坑是 v2.6.19 出「改前/改后」对比图时用取色器量出来的：前后两张图逐像素完全相同才暴露出来。
     已在 Chrome 实测 CSS.supports('selector(::-webkit-scrollbar)') === true，所以下面的 not() 判定是准的。） */
@supports not selector(::-webkit-scrollbar){
  .main{scrollbar-width:thin;scrollbar-color:rgba(110,205,251,.85) transparent}
  [data-theme="dark"] .main{scrollbar-color:rgba(96,140,190,.9) transparent}
}
/* 滚动条 · iOS 液态玻璃（v2.6.16 做质感 → v2.6.19 改成**常显**）
   ------------------------------------------------------------
   站长 2026-09-28：「用你的最高审美升级一下这个界面最右边的滑动条，ios液态玻璃风」→ 上线后
   站长 2026-09-29：「侧面滑动栏明显一点」—— 上一版**默认完全隐形、鼠标移进主滚动区才浮现**，
   本色胶囊又太淡，实机上基本「找不到滚动条在哪」。本版把可见性整体提上来：
     ① 常态就有一枚天蓝玻璃胶囊（不再等 hover），一眼能看见、知道这页还能往下滑；
     ② hover 仍按上一版的浓配方再亮一档（悬停=「我注意到它了」）；
     ③ 拖动（:active）最浓 —— 液态呼吸感保留，三档层次比以前更清楚。
   玻璃感 = 多层渐变（顶部受光白 → 中段天蓝玻璃 → 底部沉降）+ 发丝白内高光 + 天蓝内晕 + 柔和外发光；
   注意一：浏览器对滚动条伪元素不支持 backdrop-filter，模糊感用渐变+内阴影模拟，这是纯 CSS 的最高还原度。
   注意二：保留 10px 槽位不动，显隐/加宽都在槽内进行（border 3px→2px 是**向内**加宽），零布局跳动；
           触屏设备交给系统 overlay 指示条（@media (hover:none) 里宽度归零）。
   注意三：颜色一律半透明玻璃而非实色 —— 常态也不能变成一条扎眼的灰杠，那会毁掉整站的通透感。 */
.main::-webkit-scrollbar{width:10px}
.main::-webkit-scrollbar-track{background:transparent}
.main::-webkit-scrollbar-thumb{
  border-radius:99px;border:3px solid transparent;background-clip:padding-box;
  /* 常态这一档的配方（v2.6.19 调过一轮，别再照抄下面 hover 那套）：
     ① 顶部白色受光带收窄到 16% —— 原来铺到 38%，把胶囊上段洗成了近白色，
        整条看起来「头没了」，实测上段与页面底色只差 20 来个色阶（肉眼基本看不见）；
     ② 主体天蓝整体压深一格，中下段稳定落在与底色差 70~80 色阶 —— 一眼能看见，又不至于
        变成一条扎眼的实心蓝杠。 */
  background-image:
    linear-gradient(180deg,rgba(255,255,255,.88) 0%,rgba(255,255,255,.3) 6%,rgba(255,255,255,0) 16%),
    linear-gradient(168deg,rgba(206,236,253,.68) 0%,rgba(178,222,252,.66) 34%,rgba(96,196,250,.72) 72%,rgba(150,216,252,.8) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.92),
    inset 0 -1px 1px rgba(56,189,248,.34),
    inset 0 0 2px rgba(255,255,255,.5),
    0 1px 5px rgba(2,132,199,.26),
    0 0 0 1px rgba(125,211,252,.4);
  transition:border-width .22s var(--ease-out);
}
.main:hover::-webkit-scrollbar-thumb{
  background-image:
    linear-gradient(180deg,rgba(255,255,255,.95) 0%,rgba(255,255,255,.3) 18%,rgba(255,255,255,0) 36%),
    linear-gradient(168deg,rgba(255,255,255,.72) 0%,rgba(206,236,253,.56) 40%,rgba(110,205,251,.58) 76%,rgba(170,224,252,.74) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 -1px 1px rgba(56,189,248,.32),
    inset 0 0 2px rgba(255,255,255,.55),
    0 1px 5px rgba(2,132,199,.26),
    0 0 0 1px rgba(125,211,252,.3);
}
.main::-webkit-scrollbar-thumb:hover{
  border-width:2px;
  background-image:
    linear-gradient(180deg,rgba(255,255,255,.98) 0%,rgba(255,255,255,.34) 18%,rgba(255,255,255,0) 36%),
    linear-gradient(168deg,rgba(255,255,255,.88) 0%,rgba(214,238,253,.62) 40%,rgba(96,196,250,.62) 76%,rgba(162,220,252,.78) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -1px 1px rgba(14,165,233,.38),
    inset 0 0 3px rgba(255,255,255,.6),
    0 1px 6px rgba(2,132,199,.3),
    0 0 0 1px rgba(125,211,252,.35);
}
.main::-webkit-scrollbar-thumb:active{
  border-width:2px;
  background-image:
    linear-gradient(180deg,rgba(255,255,255,.95) 0%,rgba(255,255,255,.3) 18%,rgba(255,255,255,0) 36%),
    linear-gradient(168deg,rgba(226,244,255,.9) 0%,rgba(186,230,253,.7) 40%,rgba(56,189,248,.68) 76%,rgba(125,211,252,.82) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -1px 1px rgba(14,165,233,.45),
    inset 0 0 3px rgba(255,255,255,.65),
    0 1px 8px rgba(2,132,199,.34),
    0 0 0 1px rgba(56,189,248,.45);
}
/* 暗色主题：冰蓝玻璃（受光改冰蓝、投影加深，避免浅胶囊浮在深底上发白）。
   v2.6.19 起「常态 / 悬停·拖动」两档都在这里补齐 —— 常态那档写在基础态之后，
   靠 [data-theme="dark"] 提高特异性压过浅色配方（顺序不能颠倒，v2.6.15 记过这个坑）。 */
[data-theme="dark"] .main::-webkit-scrollbar-thumb{
  background-image:
    linear-gradient(180deg,rgba(186,225,253,.5) 0%,rgba(186,225,253,.16) 6%,rgba(186,225,253,0) 16%),
    linear-gradient(168deg,rgba(160,205,255,.44) 0%,rgba(110,152,205,.4) 42%,rgba(56,132,220,.44) 78%,rgba(125,180,240,.5) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(186,225,253,.5),
    inset 0 -1px 1px rgba(56,189,248,.24),
    inset 0 0 2px rgba(186,225,253,.2),
    0 1px 4px rgba(0,0,0,.42);
}
[data-theme="dark"] .main:hover::-webkit-scrollbar-thumb{
  background-image:
    linear-gradient(180deg,rgba(186,225,253,.5) 0%,rgba(186,225,253,.14) 20%,rgba(186,225,253,0) 38%),
    linear-gradient(168deg,rgba(148,197,255,.34) 0%,rgba(96,140,190,.3) 45%,rgba(56,132,220,.34) 78%,rgba(125,180,240,.4) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(186,225,253,.5),
    inset 0 -1px 1px rgba(56,189,248,.22),
    inset 0 0 2px rgba(186,225,253,.2),
    0 1px 4px rgba(0,0,0,.45);
}
[data-theme="dark"] .main::-webkit-scrollbar-thumb:hover,
[data-theme="dark"] .main::-webkit-scrollbar-thumb:active{
  background-image:
    linear-gradient(180deg,rgba(186,225,253,.6) 0%,rgba(186,225,253,.18) 20%,rgba(186,225,253,0) 38%),
    linear-gradient(168deg,rgba(160,205,255,.44) 0%,rgba(110,152,205,.4) 45%,rgba(56,132,220,.46) 78%,rgba(125,180,240,.52) 100%);
  background-clip:padding-box;
  box-shadow:
    inset 0 1px 0 rgba(186,225,253,.6),
    inset 0 -1px 1px rgba(56,189,248,.3),
    inset 0 0 3px rgba(186,225,253,.26),
    0 1px 6px rgba(0,0,0,.5),
    0 0 0 1px rgba(125,211,252,.22);
}
@media (hover:none){
  .main::-webkit-scrollbar{width:0;height:0}
}

/* 底部留白叠加 iPhone 安全区（Home 指示条）；桌面 env() 恒为 0，不会改变现有观感 */
.view{max-width:940px;margin:0 auto;padding:38px 40px calc(100px + env(safe-area-inset-bottom));animation:rise .45s cubic-bezier(.2,.8,.3,1) backwards}
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* ============ 头部 ============ */
.vhead{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:26px}
.vhead__acts{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.vhead__kicker{font-family:var(--f-display);font-size:11px;letter-spacing:.34em;color:var(--accent);margin-bottom:7px}
.vhead__title{font-family:var(--f-display);font-size:34px;font-weight:600;letter-spacing:.02em;line-height:1.15}
.headtools{display:flex;align-items:center;gap:10px}

.sechead{
  font-family:var(--f-display);font-size:19px;font-weight:600;margin:38px 0 16px;
  display:flex;align-items:baseline;gap:12px;
}
.sechead span{font-family:var(--f-ui);font-size:12px;font-weight:500;color:var(--faint);letter-spacing:.06em}
.muted{font-size:13px;color:var(--faint)}

.seg{display:inline-flex;padding:3px;border-radius:999px;background:var(--surface);border:1px solid var(--glass-brd);backdrop-filter:blur(14px) saturate(1.6);-webkit-backdrop-filter:blur(14px) saturate(1.6)}
.seg__btn{
  position:relative;overflow:hidden;
  padding:0 16px;height:32px;border-radius:999px;font-size:13.5px;font-weight:500;color:var(--muted);
  transition:.24s var(--ease-spring);
  -webkit-tap-highlight-color:transparent;
  white-space:nowrap;   /* 窄屏下缺这条会被逐字折行（「全部」竖成「全/部」） */
}
.seg__btn:hover{color:var(--ink)}
.seg__btn:active{transform:scale(.93)}
.seg__btn.is-active{background:var(--accent-grad);color:#fff;font-weight:600;box-shadow:0 3px 12px -4px rgba(14,165,233,.55);animation:segPop .3s var(--ease-spring)}
@keyframes segPop{0%{transform:scale(.88)}100%{transform:scale(1)}}
.seg--sm .seg__btn{height:27px;padding:0 13px;font-size:12.5px}

.streakchip{
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 15px 8px 12px;border-radius:999px;
  background:var(--gold-soft);
  border:1px solid rgba(176,141,79,.3);color:var(--gold);
}
.streakchip svg{width:17px;height:17px}
.streakchip b{font-family:var(--f-display);font-size:19px;line-height:1;color:var(--ink)}
.streakchip span{font-size:11.5px;font-weight:600;letter-spacing:.05em}

/* ============ 卡片 ============ */
.card{
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-l);
  padding:22px;box-shadow:var(--shadow-s), var(--glass-inset);margin-bottom:18px;
}
.card__hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.card__hd h3{font-size:14.5px;font-weight:650;letter-spacing:.01em}
.card__note{font-size:11.5px;color:var(--faint);text-align:center;margin-top:12px;line-height:1.7}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
/* 2026-09-20：专注计时搬去「进度」后，今日页这个格子里只剩打卡一张卡。
   站长要的是「打卡卡跟其他卡片左右对齐」，所以单列铺满整行（跟金句卡、
   今日推荐列表同宽）。但卡片一宽，里面的周条（space-between）会散成
   一大排、按钮拉成一条过长金条，所以把这两样限宽居中，让它们维持
   原来的比例 —— 卡片的边框仍然跟别的卡片对齐。 */
.grid2--solo{grid-template-columns:1fr}
.grid2--solo .weekstrip,
.grid2--solo .btn--block{max-width:560px;margin-left:auto;margin-right:auto}

/* 金句 */
.quote{
  position:relative;overflow:hidden;
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-xl);
  padding:34px 38px 26px;margin-bottom:22px;box-shadow:var(--shadow-m), var(--glass-inset);
}
.quote::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--accent-grad);
}
.quote::after{
  content:"";position:absolute;right:-70px;top:-70px;width:220px;height:220px;border-radius:50%;
  background:radial-gradient(circle,rgba(56,189,248,.16),transparent 65%);
  /* ⚠️ v2.6.11：必须关掉指针事件 —— 这团光晕正好盖住卡片右上角，
     而 v2.6.11 把金句朗读按钮挪到了那个角上：不开 pointer-events:none 时
     点击会落到伪元素所属的 .quote 上（不是按钮），表现成「按钮点了没反应」。
     实测抓到：按钮位置全对、audio 却一个事件都没有（B 段的失败提示也不弹）。 */
  pointer-events:none;
}
.quote__tag{
  /* v2.6.11：由 inline-flex 改成 flex —— 这一行要撑满卡片宽度，
     右上角那颗朗读按钮才能用 margin-left:auto 靠到最右（inline-flex 时整行只有内容宽）。 */
  display:flex;align-items:center;gap:7px;
  font-size:10.5px;font-weight:700;letter-spacing:.2em;color:var(--accent);margin-bottom:18px;
}
.quote__tag svg{width:14px;height:14px}
.quote__en{
  font-family:var(--f-read);font-size:26px;line-height:1.55;color:var(--ink);
  font-weight:400;letter-spacing:.005em;
}
.quote__zh{font-size:14px;line-height:2;color:var(--muted);margin-top:14px}
.quote__from{
  display:flex;align-items:center;justify-content:space-between;
  margin-top:20px;padding-top:16px;border-top:1px solid var(--line-2);
  font-size:12px;color:var(--faint);letter-spacing:.03em;
}

/* 打卡 */
.card--checkin{text-align:center}
.checkin__ring{position:relative;width:132px;height:132px;margin:6px auto 18px}
.checkin__ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.ring__bg{fill:none;stroke:var(--line);stroke-width:7}
.ring__fg{
  fill:none;stroke:var(--accent);stroke-width:7;stroke-linecap:round;
  stroke-dasharray:327;stroke-dashoffset:327;
  transition:stroke-dashoffset .9s cubic-bezier(.2,.8,.3,1);
}
.checkin__ringtext{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.checkin__ringtext b{font-family:var(--f-display);font-size:36px;line-height:1;color:var(--ink)}
.checkin__ringtext span{font-size:11px;color:var(--faint);margin-top:5px;letter-spacing:.06em}

.weekstrip{display:flex;justify-content:space-between;gap:6px;margin-bottom:18px}
.wd{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px}
.wd__l{font-size:10.5px;color:var(--faint)}
.wd__d{
  width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:11.5px;font-weight:600;color:var(--muted);
  border:1px solid var(--glass-brd);background:var(--surface-2);transition:.25s;
}
.wd__d.is-on{
  background:var(--accent-grad);color:#fff;
  border-color:transparent;box-shadow:0 4px 12px -4px rgba(2,132,199,.6);
}
.wd__d.is-today{border-color:var(--accent);color:var(--accent)}

/* 专注 */
.card--focus{text-align:center}
/* 时长设置行：预设 + 自定义输入框。justify-content:center 抵消卡片自带的 text-align:center */
.focus__set{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px;
  margin:2px 0 14px;text-align:left;
}
.focus__lb{font-size:10.5px;font-weight:700;letter-spacing:.16em;color:var(--faint)}
.focus__custom{display:inline-flex;align-items:center;gap:5px}
/* 视觉（渐变天蓝毛玻璃）走上面 .input,.focus__num,.ttsbar__sel 的统一规则，这里只留尺寸 */
.focus__num{
  width:58px;height:30px;padding:0 8px;border-radius:9px;text-align:center;
  font-family:inherit;font-size:12.5px;font-variant-numeric:tabular-nums;
}
.focus__unit{font-size:11.5px;color:var(--faint)}
/* Safari/Chrome 的数字微调箭头在窄卡片里会把输入框挤歪，直接去掉 */
.focus__num::-webkit-outer-spin-button,.focus__num::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.focus__num[type=number]{-moz-appearance:textfield}
.focus__time{
  font-family:var(--f-display);font-size:58px;line-height:1;letter-spacing:.02em;
  color:var(--ink);margin:4px 0 16px;font-variant-numeric:tabular-nums;
}
.focus__bar{height:4px;border-radius:99px;background:var(--line);overflow:hidden;margin-bottom:18px}
.focus__bar i{display:block;height:100%;width:0;border-radius:99px;background:var(--accent-grad);transition:width .5s}
.focus__ctrl{display:flex;gap:8px;justify-content:center}
.focus__stat{display:flex;justify-content:space-around;margin-top:20px;padding-top:16px;border-top:1px solid var(--line-2)}
.focus__stat div{display:flex;flex-direction:column;gap:3px}
.focus__stat b{font-family:var(--f-display);font-size:22px;color:var(--ink);line-height:1}
.focus__stat span{font-size:11px;color:var(--faint)}

/* ============ 文章列表 ============ */
.chiprow{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:20px}
.chip{
  position:relative;overflow:hidden;
  height:31px;padding:0 15px;border-radius:999px;font-size:13.5px;font-weight:500;
  border:1px solid var(--glass-brd);background:var(--surface);color:var(--muted);
  transition:.24s var(--ease-spring);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  -webkit-tap-highlight-color:transparent;
}
.chip:hover{border-color:var(--accent-2);color:var(--accent);transform:translateY(-1px)}
.chip:active{transform:scale(.93)}
.chip.is-active{background:var(--accent-grad);border-color:transparent;color:#fff;font-weight:600;box-shadow:0 3px 12px -4px rgba(14,165,233,.55)}

.artlist{display:flex;flex-direction:column;gap:12px}
.artlist--wide{display:grid;grid-template-columns:1fr 1fr;gap:14px}
/* 文库「分批上屏」的哨兵（v2.6.3）：滚到它附近就续下一批，全部上完后 hidden。
   它是 grid 的直接子元素，所以必须跨整行，否则会只占一格、把卡片挤歪。 */
.artlist__more{grid-column:1/-1;text-align:center;padding:18px 0 6px;
  font-size:12px;letter-spacing:.06em;color:var(--faint)}
.artlist__more[hidden]{display:none}

.acard{
  position:relative;text-align:left;
  /* 未读：天蓝渐变毛玻璃，与已读白色明显区分 */
  background:var(--sky-hi), var(--sky-panel);
  border:1px solid rgba(125,211,252,.55);border-radius:var(--r-l);
  padding:20px 22px;box-shadow:var(--shadow-s), var(--glass-inset);
  transition:transform .28s var(--ease-spring), box-shadow .28s, border-color .25s;
  overflow:hidden;
  -webkit-tap-highlight-color:transparent;
  /* v2.5.36 试过但**故意不用** content-visibility:auto（屏外卡片跳过布局绘制）：
     它能把「点阅读」再压到 7ms，但 contain-intrinsic-size 给的高度是**内容盒**
     （不含本卡的 40px 上下内边距 + 2px 边框），实测列表总高被抬高 15.45%
     （74,004px vs 真实 64,098px），滚动条会越往下滑越缩 —— 属于可见变化，不划算。
     实测结论：不加这一条也已经是 249ms → 38~53ms。 */
  /* v2.5.36：入场动画不再写死在这里。原来只要列表被重建，476 张卡就同时重播
     0.5s 错落渐入 —— 站长报的「用一会儿再点阅读，整页像刷新了一下」就是它，
     而且同一瞬间 476 个合成层。改由 .is-anim 按需挂（见 app.js 的 bindCards）。 */
}
/* 入场动画：只有调用方明确说「这次要播」时才挂这个类，观感与原来完全一致 */
.acard.is-anim{animation:cardIn .5s var(--ease-out) backwards}
@keyframes cardIn{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}
.acard:hover{transform:translateY(-3.5px);box-shadow:var(--shadow-l);border-color:var(--accent-2)}
.acard:active{transform:translateY(-1px) scale(.985);transition-duration:.12s}
/* 已读完：白瓷卡（v2.5.19 重做）——与未读天蓝玻璃彻底拉开；
   底更白、字色不变（保持 --ink 深墨），对比度靠「更白的底」拉高；投影减半、视觉后退 */
.acard.is-done{
  background:linear-gradient(168deg,rgba(255,255,255,.98) 0%,rgba(250,253,255,.96) 55%,rgba(242,248,253,.97) 100%);
  border-color:rgba(11,30,51,.08);
  box-shadow:0 2px 10px -4px rgba(2,32,58,.1), inset 0 1px 0 rgba(255,255,255,.9);
}
[data-theme="dark"] .acard{
  background:linear-gradient(150deg,rgba(14,116,233,.22),rgba(56,189,248,.13) 55%,rgba(14,116,233,.1));
  border-color:rgba(56,189,248,.32);
}
[data-theme="dark"] .acard.is-done{background:linear-gradient(168deg,rgba(19,38,58,.94),rgba(13,28,46,.96));border-color:rgba(125,211,252,.14);box-shadow:0 2px 10px -4px rgba(0,0,0,.45), inset 0 1px 0 rgba(186,225,253,.18)}
.acard__top{display:flex;align-items:center;gap:8px;margin-bottom:11px;flex-wrap:wrap}
.acard__src{font-family:var(--f-display);font-size:11.5px;letter-spacing:.16em;color:var(--accent);font-weight:600}
.acard__dot{width:3px;height:3px;border-radius:50%;background:var(--faint)}
.acard__date{font-size:12px;color:var(--faint)}
.tag{
  font-size:10.5px;font-weight:600;padding:3px 8px;border-radius:6px;letter-spacing:.03em;
  background:var(--accent-soft);color:var(--accent-ink);
}
.tag--lv{background:rgba(13,148,136,.12);color:var(--teal)}
.tag--cat{background:rgba(99,102,241,.13);color:#6366F1}
[data-theme="dark"] .tag--cat{background:rgba(129,140,248,.18);color:#A5B4FC}
.tag--vip{background:linear-gradient(135deg,var(--gold),var(--gold-2));color:#241B0B;font-weight:800}
.tag--done{background:rgba(13,148,136,.16);color:var(--teal)}
.acard__title{
  font-family:var(--f-display);font-size:20.5px;line-height:1.42;font-weight:600;
  color:var(--ink);margin-bottom:6px;
}
.acard__zh{font-size:14.5px;color:var(--muted);line-height:1.65;margin-bottom:12px}
.acard__lead{
  font-family:var(--f-read);font-size:15px;line-height:1.78;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.acard__ft{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:13px;border-top:1px solid var(--line-2)}
.acard__meta{font-size:12.5px;color:var(--faint);display:flex;gap:10px;align-items:center}
.acard__bar{position:absolute;left:0;bottom:0;height:2px;background:var(--accent-grad);transition:width .4s}
.acard__lock{
  position:absolute;right:18px;top:18px;width:30px;height:30px;border-radius:50%;
  background:linear-gradient(135deg,var(--gold),var(--gold-2));color:#241B0B;
  display:flex;align-items:center;justify-content:center;
}
.acard__lock svg{width:15px;height:15px}
.acard.is-vip .acard__lead{
  -webkit-mask-image:linear-gradient(180deg,#000 30%,transparent);
  mask-image:linear-gradient(180deg,#000 30%,transparent);
}

/* ============ 阅读器 ============ */
.reader__top{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:14px;flex-wrap:wrap}
.reader__tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.reader__progress{height:2px;background:var(--line);border-radius:99px;overflow:hidden;margin-bottom:34px}
.reader__progress i{display:block;height:100%;width:0;background:var(--accent-grad);transition:width .3s}

.reader{max-width:760px;margin:0 auto}
.reader__head{text-align:center;margin-bottom:38px;padding-bottom:30px;border-bottom:1px solid var(--line-2)}
.reader__src{font-family:var(--f-display);font-size:11.5px;letter-spacing:.3em;color:var(--accent);font-weight:600;margin-bottom:16px}
.reader__title{font-family:var(--f-display);font-size:36px;line-height:1.3;font-weight:600;letter-spacing:.005em;margin-bottom:10px}
.reader__subtitle{font-size:15px;color:var(--muted);line-height:1.7}
.reader__meta{
  display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;
  margin-top:20px;font-size:11.5px;color:var(--faint);letter-spacing:.04em;
}

.para{margin-bottom:26px}
/* v2.5.55：段落自带左右 32px 留槽 —— 右槽给**段落朗读键**（right:-34px），
   左槽留白让正文不贴容器边缘。小笔（句子工具入口）已改为**内联跟在句末**，不再占用边距，
   所以这里不需要再为它预留 58px 左留白（正文因此恢复左右对称，容器也从 782 收回 760）。 */
.para--en{
  position:relative;
  padding:0 32px;
  font-family:var(--f-read);font-size:19px;line-height:1.95;color:var(--ink);
  letter-spacing:.005em;
}
.para--zh{font-size:14.5px;line-height:2.05;color:var(--muted);padding-left:16px;border-left:2px solid var(--accent-soft)}
.para--en.has-drop::first-letter{
  float:left;font-family:var(--f-display);font-size:3.05em;line-height:.86;
  margin:.06em .1em 0 0;color:var(--accent);font-weight:600;
}

/* 单词 */
.w{
  border-radius:3px;padding:.02em 0;
  transition:background .14s, color .14s;
  cursor:default;
}
.w:hover{background:var(--accent-soft);color:var(--ink)}
.w.is-saved{
  background:linear-gradient(180deg,transparent 62%,rgba(56,189,248,.4) 62%);
}
.w.is-saved:hover{background:var(--accent-soft)}
.w.is-hit{background:var(--accent-grad);color:#fff;border-radius:4px;box-shadow:0 0 0 2px var(--accent-soft)}

.reader__done{margin-top:50px;display:flex;justify-content:center}
/* 原来 `hidden=false` 之后是「啪」地硬出现，没有任何入场；补一段克制的浮起 */
.reader__donecard{
  position:relative;text-align:center;background:var(--surface);border:1px solid var(--glass-brd);
  border-radius:var(--r-xl);padding:34px 44px;box-shadow:var(--shadow-m), var(--glass-inset);
  animation:doneIn .62s var(--ease-spring) backwards;
}
@keyframes doneIn{
  0%{opacity:0;transform:translateY(26px) scale(.94);filter:blur(8px)}
  100%{opacity:1;transform:none;filter:blur(0)}
}
/* 卡片里各部分依次浮起，不再是一整块同时蹦出来 */
.reader__donecard > *{animation:doneRise .5s var(--ease-out) backwards}
.reader__donecard > .reader__doneicon{animation-delay:.09s}
.reader__donecard h3{animation-delay:.18s}
.reader__donecard p{animation-delay:.26s}
.reader__donectl{animation-delay:.34s}
.reader__undone{animation-delay:.43s}
@keyframes doneRise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ---- 字体与排版 ----
   ⚠️ v2.5.3 改入场动画时，误删了 h3 / p / .reader__donectl 原有的排版声明
   （font-family、字号、margin，以及 donectl 的 flex + gap）。后果：
   标题回落到浏览器默认 h3 样式、两个按钮退化成 inline 靠空白撑开 —— 站长反馈「太生硬」。
   这里连同改进一起补回。 */
.reader__donecard h3{
  font-family:var(--f-display);font-size:21px;font-weight:600;line-height:1.5;
  letter-spacing:.05em;text-indent:.05em;   /* 中文字距稍拉开，不挤成一坨 */
  margin:0;
}
/* 标题下一道渐隐细线：把标题和下面的数据分开，否则两行糊在一起 */
.reader__donecard h3::after{
  content:'';display:block;width:46px;height:1px;margin:13px auto 0;
  background:linear-gradient(90deg,transparent,var(--accent-2),transparent);
}
.reader__donecard p{
  font-size:12.5px;line-height:1.9;color:var(--muted);
  letter-spacing:.04em;margin:11px 0 0;
}
.reader__donecard p b{color:var(--accent-ink);font-weight:600;font-variant-numeric:tabular-nums}
.reader__donectl{display:flex;gap:12px;justify-content:center;margin-top:24px}
.reader__donectl .btn{min-width:104px}

/* 勾：圆形底 + 向外扩散的两圈水波 + 描边一笔画出来 */
.reader__doneicon{
  position:relative;width:52px;height:52px;border-radius:50%;margin:0 auto 16px;
  background:var(--accent-grad);color:#fff;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 6px 20px -8px var(--accent);
}
.reader__doneicon svg{width:26px;height:26px}
.reader__doneicon svg path{
  stroke-dasharray:20;stroke-dashoffset:20;
  animation:checkDraw .46s var(--ease-out) .26s forwards;
}
@keyframes checkDraw{to{stroke-dashoffset:0}}
/* 水波：两圈错开扩散。必须 forwards —— 否则动画播完会弹回 0% 那帧，
   留下一个看得见的实心圈。 */
.reader__doneicon::before,
.reader__doneicon::after{
  content:'';position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:1.5px solid var(--accent);
  animation:iconWave 2.4s cubic-bezier(.22,.61,.36,1) 3 forwards;
}
.reader__doneicon::after{animation-delay:.8s}
@keyframes iconWave{
  0%{opacity:.5;transform:scale(1)}
  70%{opacity:.14}
  100%{opacity:0;transform:scale(2.4)}
}
[data-theme="dark"] .reader__doneicon::before,
[data-theme="dark"] .reader__doneicon::after{border-color:var(--accent-2)}
/* 取消误标的入口：不抢主按钮的视觉重量，但触屏也要点得到。
   原来字重 600（继承 .linkbtn）比主按钮还粗，是「生硬」的元凶之一，降到 500。 */
.reader__undone{
  display:block;margin:16px auto 0;font-size:12px;font-weight:500;
  letter-spacing:.04em;color:var(--faint);
  padding:6px 10px;border-radius:99px;transition:color .2s, background .2s;
}
.reader__undone:hover{color:var(--rose);background:var(--surface-2)}

/* ============ 生词本 ============ */
.statrow{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:20px}
.statrow--4{grid-template-columns:repeat(4,1fr)}
.stat{
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-m);
  padding:16px 18px;box-shadow:var(--shadow-s), var(--glass-inset);
}
.stat b{display:block;font-family:var(--f-display);font-size:28px;line-height:1;color:var(--ink);margin-bottom:6px;font-variant-numeric:tabular-nums}
.stat span{font-size:12.5px;color:var(--faint);letter-spacing:.03em}
.stat--gold b{color:var(--accent)}

.vocabgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.vcard{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-m);
  padding:20px 22px 17px 25px;box-shadow:var(--shadow-s), var(--glass-inset);
  transition:transform .26s var(--ease-spring), box-shadow .26s, border-color .22s;
  animation:cardIn .45s var(--ease-out) backwards;
}
/* 左侧等级色条：原来 5px 实心、从上通到底，硬邦邦一条。
   改成向下渐隐 —— 等级指示还在，但不再像一道硬边 */
.vcard::before{content:'';position:absolute;left:0;top:0;bottom:0;width:5px;
  background:linear-gradient(180deg,var(--rose),transparent 88%);opacity:.6}
.vcard--lv1::before{background:linear-gradient(180deg,var(--accent),transparent 88%);opacity:.7}
.vcard--lv2::before{background:linear-gradient(180deg,var(--teal),transparent 88%);opacity:.7}
.vcard:hover{transform:translateY(-2px);box-shadow:var(--shadow-m);border-color:var(--accent-2)}
.vcard__hd{display:flex;align-items:center;gap:9px;margin-bottom:9px}
.vcard__w{font-family:var(--f-display);font-size:22.5px;font-weight:700;color:var(--ink);letter-spacing:.005em;line-height:1.2}
/* 发音按钮（与复习模式同款，按卡片尺寸缩小） */
.vcard__say{
  width:27px;height:27px;border-radius:50%;flex:0 0 27px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent-ink);background:var(--accent-soft);border:1px solid var(--accent-2);
  transition:.2s var(--ease-spring);cursor:pointer;
}
.vcard__say svg{width:15px;height:15px}
.vcard__say:hover{transform:scale(1.1);background:var(--accent-grad);color:#fff;border-color:transparent}
.vcard__say:active{transform:scale(.9)}
.vcard__say.is-speaking{background:var(--accent-grad);color:#fff;border-color:transparent;animation:pulse 1s ease infinite}
/* 例句收藏星（v2.6.26 · 站长：「那个生词本收藏是收藏句子不是单词」）
   v2.6.21 那颗星长在**卡片头部**、收的是"这个单词"；本次挪到**例句块右上角**、收的是"这一整句"。
   尺寸从 27px 收到 24px —— 它属于例句，不该比词本身更抢眼。
   选中才变香槟金实心；只用 CSS 填色（fill:currentColor），JS 就地切 class、不重建 DOM。 */
.vcard__egfav{
  position:absolute;right:7px;top:7px;z-index:2;
  width:24px;height:24px;border-radius:50%;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--muted);background:transparent;border:1px solid transparent;
  transition:.2s var(--ease-spring);cursor:pointer;
}
.vcard__egfav svg{width:14px;height:14px}
.vcard__egfav:hover{transform:scale(1.12);color:var(--gold);background:var(--surface-2);border-color:rgba(176,141,79,.5)}
.vcard__egfav:active{transform:scale(.9)}
.vcard__egfav.is-on{
  color:#3A2A08;border-color:transparent;
  background:linear-gradient(135deg,#F4C97A,#E0A64B);
  box-shadow:0 4px 12px -7px rgba(176,141,79,.9), inset 0 1px 0 rgba(255,255,255,.55);
}
.vcard__egfav.is-on svg{fill:currentColor}
[data-theme="dark"] .vcard__egfav.is-on{color:#241B0B}
.vcard__lv{margin-left:auto;font-size:11px;font-weight:700;padding:4px 11px;border-radius:99px;letter-spacing:.06em}
.lv0{background:rgba(225,29,72,.12);color:var(--rose)}
.lv1{background:var(--accent-soft);color:var(--accent-ink)}
.lv2{background:rgba(13,148,136,.14);color:var(--teal)}
.vcard__def{font-size:14.5px;line-height:1.85;color:var(--ink-2)}
/* 例句区：原来靠一条 3px 直边撑结构（还是几乎看不见的浅色），像套了个硬框。
   改成整块圆角 + 左侧一枚圆头短色条，有引号感、也软一些 */
.vcard__ex{
  position:relative;margin-top:12px;padding:11px 15px 12px 19px;
  border-radius:13px;background:var(--surface-2);
  box-shadow:inset 0 0 0 1px var(--line-2);
}
.vcard__ex::before{
  content:'';position:absolute;left:9px;top:12px;bottom:12px;width:3px;
  border-radius:99px;background:var(--accent-2);opacity:.5;
}
.vcard__en{
  margin:0;font-family:var(--f-read);font-size:13.5px;line-height:1.85;color:var(--muted);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
.vcard__en mark{background:var(--accent-soft);color:var(--accent-ink);border-radius:3px;padding:0 2px}
/* 「点击看译文」提示键（v2.6.7）：站长要求例句翻译改成点击才显示，所以收起时必须有明确提示 ——
   一颗小胶囊（小眼睛 + 文案），虚线边表示「这里还藏着东西」；展开后它退成描边样式当「收起」用。 */
.vcard__zhbtn{
  display:inline-flex;align-items:center;gap:5px;margin-top:9px;
  height:25px;padding:0 10px;border-radius:999px;cursor:pointer;
  font:inherit;font-size:11.5px;font-weight:650;letter-spacing:.02em;
  color:var(--accent-ink);background:var(--accent-soft);
  border:1px dashed rgba(56,189,248,.62);
  transition:background .16s ease,border-color .16s ease,transform .16s ease,color .16s ease;
  -webkit-tap-highlight-color:transparent;
}
.vcard__zhbtn svg{width:13px;height:13px;flex:0 0 13px;opacity:.9}
.vcard__zhbtn:hover{background:rgba(56,189,248,.24);border-style:solid}
.vcard__zhbtn:active{transform:scale(.96)}
.vcard__zhbtn[aria-expanded="true"]{background:transparent;border-color:var(--line-2);color:var(--muted);font-weight:600}
.vcard__zh{
  margin:8px 0 0;padding-top:8px;border-top:1px dashed var(--line-2);
  font-size:13px;line-height:1.85;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* 展开时轻轻淡入，别「啪」地跳出来 */
.vcard__zh:not([hidden]){animation:zhIn .2s ease}
@keyframes zhIn{from{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}
.vcard__ft{display:flex;gap:10px;margin-top:auto;padding-top:16px;align-items:center}
.vcard__ft button{
  height:33px;border-radius:999px;font-size:12.5px;font-weight:600;padding:0 16px;
  border:1px solid var(--glass-brd);color:var(--muted);transition:.16s;background:var(--surface-2);
}
/* 主按钮：原来是通体实心渐变长条，压得整张卡很重。改成浅蓝底 + 深蓝字，轻一点。
   ⚠️ 深色主题下 --accent-ink 本身是浅蓝，浅底浅字会看不清，所以深色单独走实心。 */
.vcard__ft .up{
  flex:1;color:var(--accent-ink);border-color:transparent;
  background:linear-gradient(135deg,rgba(125,211,252,.62),rgba(56,189,248,.5));
  box-shadow:none;
}
[data-theme="dark"] .vcard__ft .up{
  color:#fff;
  background:linear-gradient(135deg,rgba(56,189,248,.85),rgba(14,165,233,.8));
}
.vcard__ft .up:hover{filter:brightness(1.07);transform:translateY(-1px)}
.vcard__ft .up--done{
  background:rgba(13,148,136,.12);color:var(--teal);
  border:1px solid rgba(13,148,136,.3);box-shadow:none;
}
.vcard__ft .up--done:hover{background:rgba(13,148,136,.18);filter:none;transform:none}
/* 「移除」降级成纯文字按钮：原来是个描边小方块，跟主按钮并排显得很硬 */
.vcard__ft .del{flex:0 0 auto;border-color:transparent;background:transparent}
.vcard__ft .del:hover{border-color:var(--rose);color:var(--rose);background:rgba(225,29,72,.06)}
.vcard.is-flip .vcard__def{filter:blur(5px);opacity:.5;transition:.2s}
.vcard.is-flip .vcard__def:hover{filter:none;opacity:1}

/* ============ 复习模式卡片 ============ */
.rv{cursor:pointer;user-select:none;position:relative}
.rv__top{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.rv__idx{font-size:11.5px;font-weight:700;letter-spacing:.08em;color:var(--accent-ink);white-space:nowrap}
.rv__bar{flex:1;height:4px;border-radius:99px;background:var(--line);overflow:hidden}
.rv__bar i{display:block;height:100%;border-radius:99px;background:var(--accent-grad);transition:width .45s cubic-bezier(.2,.8,.3,1)}
.rv__word{
  display:flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--f-display);font-size:32px;font-weight:700;letter-spacing:.01em;
  color:var(--ink);text-align:center;margin-bottom:4px;
}
.rv__say{
  width:34px;height:34px;border-radius:50%;flex:0 0 34px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent-ink);background:var(--accent-soft);border:1px solid var(--accent-2);
  transition:.2s var(--ease-spring);cursor:pointer;
}
.rv__say svg{width:17px;height:17px}
.rv__say:hover{transform:scale(1.08)}
.rv__say:active{transform:scale(.92)}
.rv__say.is-speaking{background:var(--accent-grad);color:#fff;border-color:transparent;animation:pulse 1s ease infinite}
.rv__def{
  margin:14px 0 12px;padding:13px 16px;border-radius:var(--r-m);
  background:var(--accent-soft);border:1px solid var(--accent-2);
  font-size:14.5px;line-height:1.85;color:var(--accent-ink);text-align:center;
  filter:blur(6px);opacity:.5;transition:filter .3s, opacity .3s;cursor:pointer;
}
.rv__def.is-open{filter:none;opacity:1}
.rv__def b{color:var(--accent);margin-right:3px}
.rv__ctx{
  padding:13px 16px;border-radius:var(--r-m);
  background:var(--surface-2);border:1px dashed var(--line-2);
  font-family:var(--f-read);font-size:13.5px;line-height:1.85;color:var(--ink-2);
  transition:.24s;cursor:pointer;
}
.rv__ctx:hover{border-color:var(--accent-2)}
.rv__ctx.is-open{border-style:solid;border-color:var(--accent-2);color:var(--ink)}
.rv__zh{
  margin-top:10px;padding:12px 16px;border-radius:var(--r-m);
  background:var(--gold-soft);border:1px solid rgba(176,141,79,.3);
  font-size:13px;line-height:1.9;color:var(--ink-2);
  animation:fade .28s ease backwards;
}
[data-theme="dark"] .rv__zh{background:rgba(176,141,79,.14)}
.rv__hint{
  margin-top:16px;padding:10px 14px;border-radius:var(--r-m);
  background:var(--surface-2);border:1px solid var(--glass-brd);
  font-size:12px;letter-spacing:.03em;color:var(--muted);text-align:center;
  transition:.24s;
}
.rv__hint.is-act{font-weight:600}
.rv__hint.is-ok{background:rgba(13,148,136,.12);border-color:rgba(13,148,136,.4);color:var(--teal)}
.rv__hint.is-no{background:rgba(225,29,72,.08);border-color:rgba(225,29,72,.32);color:var(--rose)}
.rv__ctl{display:flex;gap:10px;margin-top:16px}
.rv__ctl .btn{flex:1}

/* ---- 句子复习卡（v2.6.19 · 收藏的句子和单词一起复习） ----
   与单词卡共用 .rv / .rv__top / .rv__hint / .rv__ctl，只把「中间那块」换掉：
   单词是一枚大词 + 模糊释义，句子是一整段引文 + 出处 + 可揭晓的中译。
   交互刻意不同（单词卡单击/双击判熟，句子卡点句子看译文），所以整卡不再吃 click：
   只有 .rv__sq 是可点区，按钮各自独立 —— 免得跟「点一下看译文」抢同一次点击。 */
.rv--sent{cursor:default}
.rv__kind{
  flex:0 0 auto;font-size:10.5px;font-weight:700;letter-spacing:.1em;
  padding:3px 9px;border-radius:999px;
  background:var(--accent-soft);border:1px solid var(--accent-2);color:var(--accent-ink);
}
.rv__sq{
  position:relative;margin:6px 0 12px;padding:18px 20px 18px 24px;
  border-radius:var(--r-m);background:var(--surface-2);border:1px solid var(--glass-brd);
  font-family:var(--f-read);font-size:17px;line-height:1.95;letter-spacing:.005em;color:var(--ink);
  cursor:pointer;transition:.24s var(--ease-out);
}
/* 引文左侧一道渐隐竖线：一眼看出"这是引用的句子"，比加引号符号轻 */
.rv__sq::before{
  content:'';position:absolute;left:10px;top:16px;bottom:16px;width:2.5px;border-radius:99px;
  background:linear-gradient(180deg,transparent,var(--accent-2) 22%,var(--accent-2) 78%,transparent);
  opacity:.75;transition:.24s;
}
.rv__sq:hover{border-color:var(--accent-2);box-shadow:0 8px 20px -16px rgba(2,32,71,.5)}
.rv__sq:active{transform:scale(.994)}
.rv__sq.is-open{border-style:solid;border-color:var(--accent-2);background:var(--accent-soft)}
.rv__sq.is-open::before{opacity:1}
.rv__smeta{display:flex;align-items:center;gap:10px;padding:0 2px}
.rv__ssrc{
  flex:1;min-width:0;font-size:12px;letter-spacing:.03em;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.rv__smeta em{
  flex:0 0 auto;font-style:normal;font-size:11px;font-weight:700;letter-spacing:.04em;
  color:var(--gold-ink,#8A6A22);background:var(--gold-soft);border-radius:999px;padding:3px 9px;
}
/* 暗色下 #8A6A22 压在深底上看不清 —— 换香槟金（与 .btn--gold 同一支色） */
[data-theme="dark"] .rv__smeta em{color:#EAD3A1}
/* 句子卡上的「我的批注」（v2.6.20 · 站长：「收藏的句子可以加一个能看备注的功能吗」）
   批注在站里一直是金色语义（左侧金锚点 / 金色药丸），这里沿用金色玻璃底 + 左侧一道金色短竖条，
   和引文块的天蓝明确分开 —— 一眼能分辨「这是原句 / 这是我写的话」。长批注在块内滚动，不撑破卡片。 */
.rv__note{
  position:relative;margin:0 0 12px;padding:12px 15px 12px 20px;
  border-radius:var(--r-m);background:var(--gold-soft);border:1px solid rgba(176,141,79,.32);
  font-family:var(--f-read);font-size:13.5px;line-height:1.9;color:var(--ink-2);
  max-height:26vh;overflow-y:auto;overscroll-behavior:contain;
  animation:fade .28s ease backwards;
}
[data-theme="dark"] .rv__note{background:rgba(176,141,79,.16);border-color:rgba(217,185,120,.34)}
.rv__note::before{
  content:'';position:absolute;left:9px;top:13px;bottom:13px;width:2.5px;border-radius:99px;
  background:linear-gradient(180deg,transparent,var(--gold) 22%,var(--gold) 78%,transparent);
  opacity:.8;
}
.rv__note::-webkit-scrollbar{width:6px}
.rv__note::-webkit-scrollbar-thumb{background:rgba(176,141,79,.4);border-radius:99px}
.rv__notelb{
  display:block;margin-bottom:5px;font-family:inherit;font-size:10.5px;font-weight:800;
  letter-spacing:.14em;color:var(--gold-ink,#8A6A22);
}
[data-theme="dark"] .rv__notelb{color:#EAD3A1}
.rv__unfav{
  display:block;margin:12px auto 0;padding:6px 12px;border:0;border-radius:999px;
  background:transparent;font:inherit;font-size:11.5px;letter-spacing:.03em;color:var(--muted);
  cursor:pointer;transition:.2s;
}
.rv__unfav:hover{color:var(--rose);background:rgba(225,29,72,.07)}
.rv__unfav:active{transform:scale(.96)}
@media (max-width:560px){
  .rv__sq{font-size:16px;padding:15px 16px 15px 21px}
  .rv__sq::before{left:8px;top:13px;bottom:13px}
  .rv__note{font-size:13px;padding:11px 13px 11px 18px;max-height:22vh}
  .rv__smeta em{display:none}          /* 窄屏先让给出处，复习次数不是关键信息 */
}

/* 句子收藏页脚注（v2.6.19）：说明这些句子会去哪儿复习 */
.sp-pins__hint{
  margin:12px 2px 0;font-size:11.5px;line-height:1.8;letter-spacing:.02em;color:var(--muted);
  padding-left:14px;position:relative;
}
.sp-pins__hint::before{
  content:'';position:absolute;left:2px;top:.72em;width:5px;height:5px;border-radius:50%;
  background:var(--accent);opacity:.6;
}
/* 收藏列表里的批注（v2.6.20）：紧跟在那句原文下面，金色细竖条 + 略小字号，
   与原文一眼分得开；没有批注的句子这一行不渲染。 */
.sp-pin__note{
  position:relative;margin:0 0 8px !important;padding-left:11px;
  font-size:12px !important;line-height:1.85 !important;color:var(--muted) !important;
}
.sp-pin__note::before{
  content:'';position:absolute;left:0;top:.32em;bottom:.32em;width:2px;border-radius:99px;
  background:linear-gradient(180deg,transparent,var(--gold) 25%,var(--gold) 75%,transparent);
  opacity:.85;
}

.empty{text-align:center;padding:60px 20px;color:var(--faint)}
.empty__icon{font-size:38px;margin-bottom:14px;opacity:.35}
.empty p{font-size:13.5px;line-height:2}

/* ============ 图表 ============ */
.chart{display:flex;align-items:flex-end;gap:6px;padding-top:8px}
.bar{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0}
.bar__t{
  font-size:9.5px;color:var(--accent-ink);font-weight:700;
  font-variant-numeric:tabular-nums;min-height:12px;line-height:12px;
}
/* 空槽：未学习的天只留浅色底槽，柱体清零不显示——整排高度依旧对齐，不会出现误导性小尾巴 */
.bar__plot{
  width:100%;max-width:26px;height:96px;border-radius:7px;
  background:var(--line);display:flex;align-items:flex-end;
  overflow:hidden;transition:background .25s;
}
.bar:hover .bar__plot{background:var(--accent-soft)}
.bar__v{
  display:block;width:100%;border-radius:6px 6px 2px 2px;
  background:var(--accent-grad);
  transition:height .6s cubic-bezier(.2,.8,.3,1);
}
.bar__v.has{box-shadow:0 2px 10px -4px rgba(2,132,199,.6)}
.bar.is-today .bar__plot{box-shadow:0 0 0 1.5px var(--accent-2)}
.bar.is-today .bar__l{color:var(--accent-ink);font-weight:700}
.bar__l{font-size:10px;color:var(--faint);white-space:nowrap}

/* ============ To Do 待办（仿微软 To Do，天蓝毛玻璃） ============ */
.todopanel{
  max-width:720px;margin:0 auto;
  display:flex;flex-direction:column;gap:16px;
}
/* 智能清单切换条 */
.todolists{display:flex;gap:8px;flex-wrap:wrap}
.tlist{
  display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 14px;
  border-radius:999px;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;
  letter-spacing:.01em;color:var(--muted);
  background:var(--surface);border:1px solid var(--glass-brd);
  backdrop-filter:blur(14px) saturate(1.6);-webkit-backdrop-filter:blur(14px) saturate(1.6);
  transition:color .22s,border-color .22s,background .22s,transform .22s var(--ease-spring);
}
.tlist svg{width:14px;height:14px;flex:0 0 14px}
.tlist:hover{color:var(--ink);border-color:var(--accent-2);transform:translateY(-1px)}
.tlist.is-active{color:var(--accent-ink);background:var(--accent-soft);border-color:var(--accent-2)}
.tlist__n{
  font-style:normal;min-width:19px;height:19px;padding:0 6px;border-radius:999px;
  font-size:10.5px;font-weight:700;line-height:19px;text-align:center;
  color:#fff;background:var(--accent-grad);
}
/* 添加任务框：iOS 高光毛玻璃（与 .input 同一套配方，2026-09-20 起同步成天蓝渐变底）
   聚焦时用 :focus-within 让整个框一起亮起 —— 比只亮内层 input 更接近 iOS 的整块控件反馈 */
.todoadd{
  display:flex;align-items:center;gap:12px;padding:10px 14px 10px 12px;border-radius:16px;
  background:var(--sky-hi), var(--sky-in);
  border:1px solid var(--ios-hair);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 var(--ios-hi),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.16),
    0 1px 2px rgba(2,132,199,.07),
    var(--ios-glow);
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  transition:border-color .2s var(--ease-out), box-shadow .28s var(--ease-out);
}
.todoadd:focus-within{
  border-color:var(--accent-2);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.14),
    0 0 0 3px var(--ios-ring),
    0 0 0 7px rgba(56,189,248,.10),
    0 18px 40px -18px rgba(2,132,199,.5);
}
/* 暗色下补一套天蓝底（原来这里没有暗色规则，框会一直是浅色，跟 .input 对不上） */
[data-theme="dark"] .todoadd{
  background:
    linear-gradient(180deg,rgba(186,225,253,.20),rgba(186,225,253,.04) 42%,rgba(186,225,253,0) 60%),
    linear-gradient(165deg,rgba(56,189,248,.30),rgba(14,116,144,.32) 50%,rgba(12,74,110,.44));
}
.todoadd__plus{
  flex:0 0 30px;width:30px;height:30px;border-radius:10px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;color:var(--accent-ink);
  background:var(--accent-soft);border:1px solid rgba(125,211,252,.55);
  transition:transform .2s var(--ease-spring),background .2s;
}
.todoadd__plus svg{width:15px;height:15px}
.todoadd__plus:hover{transform:scale(1.08);background:var(--accent-2);color:#fff}
.todoadd__input{
  flex:1;min-width:0;height:32px;border:none;outline:none;background:transparent;
  font-family:inherit;font-size:14px;color:var(--ink);
}
.todoadd__input::placeholder{color:var(--faint)}
/* 任务列表 */
.todolist{display:flex;flex-direction:column;gap:10px}
.todo{
  display:flex;align-items:center;gap:12px;padding:13px 14px 13px 14px;border-radius:16px;
  /* 天蓝毛玻璃：与会员页 / 金句收藏同一套配方 */
  background:var(--sky-hi), var(--sky-panel);
  border:1px solid rgba(125,211,252,.5);
  box-shadow:0 1px 2px rgba(2,132,199,.07), 0 16px 42px -18px rgba(2,132,199,.32), var(--glass-inset);
  backdrop-filter:blur(20px) saturate(1.7);-webkit-backdrop-filter:blur(20px) saturate(1.7);
  animation:fade .26s ease backwards;
}
.todo.is-done{opacity:.55}
.todo.is-done .todo__text{text-decoration:line-through;color:var(--faint)}
.todo__check{
  flex:0 0 22px;width:22px;height:22px;border-radius:50%;cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:1.5px solid rgba(56,189,248,.65);background:rgba(255,255,255,.45);
  color:transparent;transition:.2s var(--ease-spring);
}
.todo:not(.is-done) .todo__check:hover{border-color:var(--accent-2);background:var(--accent-2)}
.todo.is-done .todo__check{background:var(--accent-grad);border-color:transparent;color:#fff}
.todo__check svg{width:12px;height:12px}
.todo__text{
  flex:1;min-width:0;font-size:14px;color:var(--ink);line-height:1.55;
  word-break:break-word;cursor:default;
}
.todo__edit{
  flex:1;min-width:0;height:26px;font-family:inherit;font-size:14px;color:var(--ink);
  background:transparent;border:none;outline:none;
  border-bottom:1.5px dashed var(--accent-2);padding:0 0 2px;
}
.todo__day,.todo__star,.todo__del{
  flex:0 0 auto;width:27px;height:27px;border-radius:9px;cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;font-size:14px;line-height:1;
  color:var(--faint);background:transparent;border:none;transition:.18s;
}
.todo__day:hover{color:#f59e0b;transform:scale(1.15)}
.todo__star.is-on{color:#f59e0b;text-shadow:0 0 1px rgba(245,158,11,.4)}
.todo__star:hover{transform:scale(1.18)}
.todo__del{opacity:0;font-size:12.5px}
.todo:hover .todo__del,.todo__del:focus-visible{opacity:.6}
.todo__del:hover{opacity:1;color:var(--rose)}
/* 触屏没有 hover：删除按钮常显，避免手机上删不掉 */
@media (hover:none){.todo__del{opacity:.5}}
/* 空状态 */
.todoempty b{display:block;font-size:13.5px;color:var(--ink);margin-top:4px}
.todoempty p{font-size:12px;color:var(--faint);margin-top:6px;line-height:1.7}
/* 暗色：同一套玻璃配方的深色分支 */
[data-theme="dark"] .todoadd,[data-theme="dark"] .todo{
  background:linear-gradient(165deg,rgba(14,116,144,.28),rgba(15,23,42,.5) 62%);
  border-color:rgba(56,189,248,.3);
}
[data-theme="dark"] .todoadd{
  background:
    linear-gradient(180deg,rgba(186,225,253,.16),rgba(186,225,253,.03) 42%,rgba(186,225,253,0) 60%),
    linear-gradient(168deg,rgba(14,116,144,.3),rgba(15,23,42,.52) 58%);
  border-color:var(--ios-hair);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 var(--ios-hi),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.28),
    0 1px 2px rgba(2,132,199,.12),
    var(--ios-glow);
}
/* 深色聚焦：必须单独写 —— 否则会沿用浅色那套白色内阴影，暗色下聚焦会一片惨白 */
[data-theme="dark"] .todoadd:focus-within{
  border-color:rgba(56,189,248,.68);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 rgba(186,225,253,.32),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.26),
    0 0 0 3px var(--ios-ring),
    0 0 0 7px rgba(56,189,248,.11),
    0 16px 38px -18px rgba(2,132,199,.55);
}
[data-theme="dark"] .todo__check{background:rgba(15,23,42,.5);border-color:rgba(56,189,248,.5)}
[data-theme="dark"] .todo:not(.is-done) .todo__check:hover{background:var(--accent-2)}
[data-theme="dark"] .todoadd__input{color:var(--ink)}
[data-theme="dark"] .tlist{background:rgba(15,23,42,.55)}

/* ============ 会员 ============ */
.vipstate{font-size:12.5px;color:var(--muted)}
.vipstate b{color:var(--gold);font-family:var(--f-display);font-size:15px}

.viphero{
  position:relative;overflow:hidden;border-radius:var(--r-xl);
  padding:44px 42px;margin-bottom:22px;
  /* 天蓝毛玻璃：半透明天蓝渐变 + 背景虚化（模糊由通用毛玻璃规则提供） */
  background:var(--sky-hi), var(--sky-panel);
  color:var(--ink);border:1px solid rgba(125,211,252,.55);
  box-shadow:0 2px 6px rgba(2,132,199,.08), 0 28px 64px -24px rgba(2,132,199,.45), var(--glass-inset);
}
.viphero__glow{
  position:absolute;right:-90px;top:-120px;width:380px;height:380px;border-radius:50%;
  background:radial-gradient(circle,rgba(56,189,248,.4),transparent 62%);
}
.viphero__inner{position:relative}
.viphero__badge{
  display:inline-block;font-family:var(--f-display);font-size:10.5px;letter-spacing:.28em;
  color:var(--accent-ink);border:1px solid rgba(14,165,233,.42);border-radius:999px;padding:5px 14px;margin-bottom:18px;
  background:rgba(255,255,255,.38);
}
.viphero h2{font-family:var(--f-display);font-size:31px;line-height:1.35;font-weight:600;margin-bottom:12px;color:var(--ink)}
.viphero p{font-size:13.5px;line-height:2;color:var(--ink-2);max-width:600px}
[data-theme="dark"] .viphero{
  background:linear-gradient(135deg,rgba(8,47,73,.6) 0%,rgba(12,74,110,.42) 52%,rgba(15,23,42,.45) 100%);
  color:#EFF6FF;border-color:rgba(56,189,248,.35);
}
[data-theme="dark"] .viphero h2{color:#EFF6FF}
[data-theme="dark"] .viphero p{color:rgba(239,246,255,.78)}
[data-theme="dark"] .viphero__badge{color:#BAE6FD;border-color:rgba(125,211,252,.4);background:rgba(56,189,248,.12)}

/* auto-fit：只有 1 个套餐时自动铺满整行（与上方 hero、下方卡片左右对齐），加到 3 个时仍自动三列 */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;margin-bottom:20px}
.plan{
  position:relative;border-radius:var(--r-l);
  /* 天蓝毛玻璃质感 */
  background:var(--sky-hi), var(--sky-panel);
  border:1px solid rgba(125,211,252,.5);
  padding:26px 22px;text-align:center;
  box-shadow:0 1px 2px rgba(2,132,199,.07), 0 16px 40px -18px rgba(2,132,199,.34), var(--glass-inset);
  transition:.25s;
}
.plan:hover{transform:translateY(-3px);box-shadow:0 2px 6px rgba(2,132,199,.08), 0 28px 60px -22px rgba(2,132,199,.5), var(--glass-inset)}
.plan.is-hot{
  border-color:rgba(14,165,233,.55);
  background:linear-gradient(165deg,rgba(186,230,253,.78),rgba(224,242,254,.5) 58%,rgba(240,249,255,.46));
  box-shadow:0 1px 2px rgba(30,58,138,.07), 0 24px 54px -24px rgba(2,132,199,.72), var(--glass-inset);
}
[data-theme="dark"] .plan{
  background:linear-gradient(165deg,rgba(14,116,144,.3),rgba(15,23,42,.5) 60%);
  border-color:rgba(56,189,248,.3);
}
[data-theme="dark"] .plan.is-hot{
  background:linear-gradient(165deg,rgba(14,116,144,.45),rgba(12,74,110,.35) 60%,rgba(15,23,42,.5));
  border-color:rgba(56,189,248,.5);
}
.plan__flag{
  position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  font-size:10.5px;font-weight:800;letter-spacing:.1em;padding:4px 13px;border-radius:999px;
  background:var(--accent-grad);color:#fff;white-space:nowrap;
}
.plan__n{font-size:13px;font-weight:650;color:var(--muted);letter-spacing:.06em}
.plan__p{font-family:var(--f-display);font-size:40px;line-height:1;margin:14px 0 4px;color:var(--ink)}
.plan__p small{font-size:16px;color:var(--muted);margin-right:2px}
.plan__u{font-size:11.5px;color:var(--faint)}
.plan__o{font-size:11.5px;color:var(--faint);margin-top:8px;text-decoration:line-through;opacity:.7}
.plan__save{
  display:inline-block;margin-top:12px;font-size:11px;font-weight:700;color:var(--accent-ink);
  background:var(--accent-soft);padding:4px 10px;border-radius:6px;
}
.plan__info{min-width:0}
.plan .btn{width:100%;margin-top:20px}
.plan.is-cur .btn{opacity:.5;pointer-events:none}

/* 只有一个套餐时：横向铺满整行——信息靠左、按钮靠右，避免全宽卡片左右空旷 */
.plan:only-child{
  display:flex;align-items:center;justify-content:space-between;gap:28px;
  text-align:left;padding:26px 28px;
}
.plan:only-child .plan__flag{left:28px;transform:none}
.plan:only-child .plan__info{flex:1 1 auto}
.plan:only-child .plan__p{margin:10px 0 4px}
.plan:only-child .plan__save{margin-top:10px}
.plan:only-child .btn{width:auto;margin-top:0;flex:0 0 auto;min-width:150px}

.benefits{list-style:none;display:flex;flex-direction:column;gap:12px}
.benefits li{display:flex;gap:11px;font-size:13.5px;line-height:1.7;color:var(--ink-2)}
.benefits li::before{
  content:"✓";flex:0 0 18px;width:18px;height:18px;border-radius:50%;
  background:var(--accent-soft);color:var(--accent-ink);font-size:11px;font-weight:800;
  display:flex;align-items:center;justify-content:center;margin-top:2px;
}
.invite{display:flex;align-items:center;gap:10px;margin:14px 0}
.invite code{
  flex:1;height:38px;display:flex;align-items:center;padding:0 14px;border-radius:10px;
  background:var(--surface-2);border:1px dashed var(--glass-brd);color:var(--accent-ink);
  font-family:var(--f-mono);font-size:14px;letter-spacing:.16em;
}
.invite__row{display:flex;gap:8px}
/* ---- 输入控件统一质感：iOS 高光毛玻璃（.input 文本框 / .focus__num 数字框 / .ttsbar__sel 下拉） ----
   iOS 化要点（2026-09-19 升级）：
   ① 顶部高光从「镜面反光」降为「柔雾高光」——原 .92 白过于果冻感，改 .72 并让淡出更早、更缓；
   ② 边框走发丝级：主边框用 --ios-hair，再用 0.5px 外侧 box-shadow 补一道边，做出 iOS 的「双层边」；
   ③ 玻璃厚度 = 顶棱线高光 + 底面反光 + 底部内晕三层叠加（原来只有两层，缺少厚度感）；
   ④ 聚焦改「双圈柔光」：内圈实、外圈散，替代原来单圈硬环。 */
.input,.focus__num,.ttsbar__sel{
  color:var(--ink);outline:none;
  /* 2026-09-20 站长要求「所有文本框升级成渐变天蓝色 + 毛玻璃」。
     旧版主体是 rgba(224,242,254,.66)→白，实机上几乎是白的、天蓝只体现在描边上；
     现在主体换成 sky-400→sky-100 的天蓝渐变（等价色阶 #ABE3FC→#ECF7FE），
     白色高光层保留在最上面当玻璃棱线，毛玻璃的模糊/内阴影/发丝边全不动。 */
  background:var(--sky-hi), var(--sky-in);
  border:1px solid var(--ios-hair);
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 var(--ios-hi),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.16),
    0 1px 2px rgba(2,132,199,.07),
    var(--ios-glow);
  transition:border-color .2s var(--ease-out), box-shadow .28s var(--ease-out), background .28s var(--ease-out);
}
.input:hover,.focus__num:hover,.ttsbar__sel:hover{border-color:rgba(56,189,248,.8)}
.input:focus,.focus__num:focus,.ttsbar__sel:focus{
  border-color:var(--accent-2);
  background:
    linear-gradient(180deg,rgba(255,255,255,.88),rgba(255,255,255,.28) 44%,rgba(255,255,255,.08) 62%),
    linear-gradient(165deg,rgba(125,211,252,.52),rgba(186,230,253,.56) 50%,rgba(224,242,254,.66));
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.14),
    0 0 0 3px var(--ios-ring),
    0 0 0 7px rgba(56,189,248,.10),
    0 18px 40px -18px rgba(2,132,199,.5);
}
.input::placeholder,.focus__num::placeholder{color:var(--faint);opacity:1}
[data-theme="dark"] .input,[data-theme="dark"] .focus__num,[data-theme="dark"] .ttsbar__sel{
  background:var(--sky-hi), var(--sky-in);
  border-color:var(--ios-hair);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 var(--ios-hi),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.3),
    0 1px 2px rgba(2,132,199,.12),
    var(--ios-glow);
}
[data-theme="dark"] .input:hover,[data-theme="dark"] .focus__num:hover,[data-theme="dark"] .ttsbar__sel:hover{border-color:rgba(56,189,248,.62)}
[data-theme="dark"] .input:focus,[data-theme="dark"] .focus__num:focus,[data-theme="dark"] .ttsbar__sel:focus{
  background:
    linear-gradient(180deg,rgba(186,225,253,.24),rgba(186,225,253,.05) 44%,rgba(186,225,253,0) 62%),
    linear-gradient(165deg,rgba(125,211,252,.34),rgba(14,116,144,.40) 52%,rgba(12,74,110,.52));
  border-color:rgba(56,189,248,.68);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 rgba(186,225,253,.32),
    inset 0 -1px 0 var(--ios-lo),
    inset 0 -6px 12px -8px rgba(2,132,199,.26),
    0 0 0 3px var(--ios-ring),
    0 0 0 7px rgba(56,189,248,.11),
    0 16px 38px -18px rgba(2,132,199,.55);
}
.input{flex:1;height:36px;padding:0 14px;border-radius:12px;font-size:13px}
.disclaimer{font-size:11.5px;line-height:2;color:var(--faint);margin-top:22px;padding-top:18px;border-top:1px solid var(--line-2)}

/* 兑换码 / 收款渠道 */
.paystep{margin-bottom:18px}
.paystep>b{display:block;font-size:13px;margin-bottom:10px;color:var(--ink)}
.paych{
  background:var(--surface-2);border:1px dashed var(--glass-brd);border-radius:var(--r-m);
  padding:16px;text-align:center;
}
.paych__qr{width:150px;height:150px;object-fit:cover;border-radius:14px;border:1px solid var(--glass-brd);margin:0 auto 12px;display:block}
.paych__t{font-size:13.5px;font-weight:650;color:var(--ink);margin-bottom:6px}
.paych__c{font-family:var(--f-mono);font-size:15px;color:var(--accent-ink);letter-spacing:.04em;margin-bottom:6px}
.paych__n{font-size:11.5px;color:var(--faint);line-height:1.7}
.payerr{font-size:11.5px;color:var(--rose);margin-top:8px;min-height:16px}
.invitetip{font-size:12px;line-height:1.9;color:var(--muted);padding-top:14px;border-top:1px dashed var(--line-2)}
/* 开通弹窗里的「填入好友邀请码」区（v2.5.46 · 结伴开会员） */
.paywall__ref{font-size:12px;line-height:1.9;color:var(--muted);padding-top:14px;margin-bottom:4px;border-top:1px dashed var(--line-2)}

/* ---- 会员页 · 天蓝毛玻璃质感（仅 #view-vip 作用域，不影响其他页面） ---- */
#view-vip .card{
  background:linear-gradient(165deg,rgba(224,242,254,.62),rgba(240,249,255,.4) 60%,rgba(255,255,255,.46));
  border:1px solid rgba(125,211,252,.5);
  box-shadow:0 1px 2px rgba(2,132,199,.07), 0 16px 42px -18px rgba(2,132,199,.32), var(--glass-inset);
}
#view-vip .vipstate{
  background:rgba(224,242,254,.55);border:1px solid rgba(125,211,252,.5);
  border-radius:999px;padding:8px 16px;
  backdrop-filter:blur(14px) saturate(1.6);-webkit-backdrop-filter:blur(14px) saturate(1.6);
  box-shadow:var(--glass-inset);
}
/* 输入框的质感已由全局统一规则提供，这里不再单独覆盖（保持全站一致） */
#view-vip .invite code{
  background:rgba(240,249,255,.52);border:1px dashed rgba(14,165,233,.45);
  backdrop-filter:blur(14px) saturate(1.6);-webkit-backdrop-filter:blur(14px) saturate(1.6);
}
#view-vip .invitetip{
  background:rgba(224,242,254,.42);border:1px solid rgba(125,211,252,.38);
  border-radius:var(--r-m);padding:12px 14px;margin-top:4px;
}
[data-theme="dark"] #view-vip .card{
  background:linear-gradient(165deg,rgba(14,116,144,.28),rgba(15,23,42,.5) 62%);
  border-color:rgba(56,189,248,.3);
}
[data-theme="dark"] #view-vip .vipstate{background:rgba(14,116,144,.3);border-color:rgba(56,189,248,.32)}
[data-theme="dark"] #view-vip .invite code{background:rgba(12,74,110,.3);border-color:rgba(56,189,248,.4)}
[data-theme="dark"] #view-vip .invitetip{background:rgba(14,116,144,.22);border-color:rgba(56,189,248,.26)}

/* ============ 悬浮词典卡 ============ */
.wordcard{
  position:fixed;z-index:900;width:288px;
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-m);
  box-shadow:var(--shadow-l), var(--glass-inset);padding:15px 16px;
  animation:wcIn .16s cubic-bezier(.2,.8,.3,1) backwards;
  pointer-events:none;
}
@keyframes wcIn{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}
.wordcard.is-pinned{pointer-events:auto;border-color:var(--accent-2)}
.wordcard__hd{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:4px}
.wordcard__w{font-family:var(--f-display);font-size:19px;font-weight:600;color:var(--ink);word-break:break-word}
.wordcard__add{
  flex:0 0 26px;width:26px;height:26px;border-radius:8px;font-size:16px;line-height:1;
  background:var(--accent-soft);color:var(--accent-ink);transition:.16s;
}
.wordcard__add:hover{background:var(--accent-grad);color:#fff}
.wordcard__add.is-on{background:var(--teal);color:#fff}
.wordcard__pos{font-size:11px;color:var(--accent);letter-spacing:.06em;margin-bottom:8px}
.wordcard__def{font-size:13.5px;line-height:1.8;color:var(--ink)}
.wordcard__ctx{
  font-family:var(--f-read);font-size:11.5px;line-height:1.7;color:var(--muted);
  margin-top:10px;padding-top:9px;border-top:1px dashed var(--line);
}
.wordcard__ctx mark{background:var(--accent-soft);color:var(--accent-ink);border-radius:3px;padding:0 2px}
.wordcard__ft{font-size:10.5px;color:var(--faint);margin-top:9px;letter-spacing:.03em}

/* ---- 单词卡里的「讲解 / 批注这句」入口（v2.6.1 · 手机端专用） ----
   站长要求：「手机端改为点击句子中单词时，在单词卡中显示」——
   手机端收起句末小笔后，批注 / 讲解 / 词组 / 收藏的统一入口就是这里。
   ⚠️ 桌面端**不显示**它（display:none 是默认值），桌面走「悬停句子 → 句末小笔」那条路；
   显隐由文件后面那条 @media (hover:none), (max-width:820px) 负责，不要在 JS 里再判一次。
   有批注时整颗按钮转金色 + 右侧角标（与正文里的金笔、左侧金条同一套语义）。 */
.wordcard__note{
  display:none;width:100%;margin-top:11px;height:36px;border-radius:11px;
  align-items:center;justify-content:center;gap:7px;
  font-size:13px;font-weight:600;font-family:inherit;cursor:pointer;
  background:var(--accent-soft);border:1px solid rgba(56,189,248,.45);color:var(--accent-ink);
  transition:background .16s ease,transform .16s ease,border-color .16s ease;
  -webkit-tap-highlight-color:transparent;
}
.wordcard__note svg{width:14px;height:14px;flex:0 0 14px}
.wordcard__note:active{transform:scale(.97)}
.wordcard__note.is-noted{background:linear-gradient(135deg,#F4C97A,#E0A64B);border-color:transparent;color:#3A2A08}
.wordcard__notedot{font-style:normal;font-size:10px;line-height:1;color:#3A2A08}

/* ============ 计时浮标 ============ */
.timerpill{
  position:fixed;right:26px;bottom:26px;z-index:800;
  display:flex;align-items:center;gap:10px;
  height:42px;padding:0 8px 0 16px;border-radius:999px;
  background:var(--surface);border:1px solid var(--glass-brd);box-shadow:var(--shadow-l), var(--glass-inset);
  animation:wcIn .3s backwards;
}
.timerpill__dot{width:7px;height:7px;border-radius:50%;background:var(--accent);animation:pulse 1.8s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.75)}}
.timerpill.is-paused .timerpill__dot{animation:none;opacity:.4}
.timerpill b{font-family:var(--f-mono);font-size:13.5px;font-variant-numeric:tabular-nums;color:var(--ink)}
.timerpill button{
  height:28px;padding:0 12px;border-radius:999px;font-size:11.5px;font-weight:600;
  background:var(--accent-grad);color:#fff;transition:.2s var(--ease-spring);
}
.timerpill button:hover{filter:brightness(1.08);transform:translateY(-1px)}
.timerpill button:active{transform:scale(.92)}

/* ============ 弹层 ============ */
.modal{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px}
.modal__mask{position:absolute;inset:0;background:rgba(10,17,32,.45);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);animation:fade .2s backwards}
.modal__box{
  position:relative;width:100%;max-width:440px;
  background:var(--surface);border:1px solid var(--glass-brd);border-radius:var(--r-xl);
  box-shadow:var(--shadow-l), var(--glass-inset);padding:34px;animation:mIn .28s cubic-bezier(.2,.9,.3,1) backwards;
}
@keyframes mIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}
.modal__title{font-family:var(--f-display);font-size:23px;font-weight:600;margin-bottom:10px;text-align:center}
.modal__text{font-size:13.5px;line-height:1.9;color:var(--muted);text-align:center;margin-bottom:22px}
.modal__ctl{display:flex;gap:10px;margin-top:20px}
.modal__ctl .btn{flex:1}
.modal__price{
  text-align:center;font-family:var(--f-display);font-size:34px;margin:18px 0 4px;
}
.modal__price small{font-size:15px;color:var(--muted)}
.modal__qr{
  width:150px;height:150px;margin:0 auto 14px;border-radius:14px;
  background:
    repeating-conic-gradient(var(--ink) 0 25%, transparent 0 50%) 0 0/15px 15px;
  border:1px solid var(--glass-brd);opacity:.85;
}
.mockpay{display:flex;flex-direction:column;gap:10px;margin-top:6px}
.mockpay .row{display:flex;justify-content:space-between;font-size:12.5px;color:var(--muted)}
.mockpay .row b{color:var(--ink);font-weight:600}

/* ============ Toast ============ */
.toast{
  position:fixed;left:50%;bottom:38px;transform:translate(-50%,20px);z-index:1100;
  padding:12px 22px;border-radius:999px;
  background:rgba(15,27,45,.9);color:#EFF6FF;font-size:13px;font-weight:500;letter-spacing:.02em;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid rgba(125,211,252,.25);
  box-shadow:var(--shadow-l);opacity:0;pointer-events:none;transition:.3s cubic-bezier(.2,.8,.3,1);
}
.toast.is-on{opacity:1;transform:translate(-50%,0)}
/* 可点重试的提示条（朗读音频加载失败时用，见 app.js 的 toast(msg, onRetry)）：
   .toast 默认 pointer-events:none 点不到，这里恢复指针事件并给出可点的手型 */
.toast.is-action{pointer-events:auto;cursor:pointer;border-color:rgba(125,211,252,.62);box-shadow:var(--shadow-l),0 0 0 3px rgba(125,211,252,.14)}

/* ============ 庆祝光点（原「彩带」）============
   v2.5.3：原来是 8px 实心方块（金 / 锈红 / 墨绿 / 米色）往下砸，配色跟站点不搭。
   改成站点色系的半透明柔光点，向上飘散淡出 —— 安静一些，也更耐看。 */
.confetti{position:fixed;inset:0;z-index:1050;pointer-events:none;overflow:hidden}
.cf{
  position:absolute;width:var(--sz,6px);height:var(--sz,6px);border-radius:50%;
  filter:blur(.4px);opacity:0;
  animation:cfRise 1.7s cubic-bezier(.16,.72,.34,1) forwards;
}
@keyframes cfRise{
  0%{opacity:0;transform:translate(0,0) scale(.45)}
  16%{opacity:.92}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(1.2)}
}

/* ============ 读完涟漪 ============
   从读完卡片中心（卡片不在视口时退回视口中心）扩散的水波，取代原来的彩带。
   --s 由 JS 按视口算出来，保证一直扩到铺满整个画面（写死倍数大屏铺不满）。 */
.ripplewave{
  position:fixed;z-index:1040;pointer-events:none;
  width:160px;height:160px;margin:-80px 0 0 -80px;border-radius:50%;
  border:1.5px solid var(--accent);
  box-shadow:0 0 32px -8px var(--accent);
  opacity:0;
  animation:waveOut 1.6s cubic-bezier(.22,.61,.36,1) forwards;
}
@keyframes waveOut{
  0%{opacity:.55;transform:scale(.2)}
  75%{opacity:.18}          /* 大部分行程都保持可见，扫过整个画面时才淡出 */
  100%{opacity:0;transform:scale(var(--s,8))}
}

/* ============ 左侧登录入口 ============ */
.rail__auth{
  position:relative;overflow:hidden;
  display:flex;align-items:center;gap:10px;text-align:left;
  margin:0 2px 16px;padding:10px 12px;border-radius:var(--r-m);
  background:var(--accent-grad);color:#fff;
  box-shadow:0 2px 6px rgba(2,132,199,.16), 0 12px 28px -12px rgba(14,165,233,.6);
  transition:transform .26s var(--ease-spring), box-shadow .25s, filter .2s;
  -webkit-tap-highlight-color:transparent;
}
.rail__auth:hover{transform:translateY(-1.5px);box-shadow:var(--shadow-l);filter:brightness(1.05)}
.rail__auth:active{transform:scale(.97)}
.rail__auth.is-in{background:var(--surface);color:var(--ink);border:1px solid var(--glass-brd);box-shadow:var(--shadow-s)}
.rail__authava{
  width:34px;height:34px;flex:0 0 34px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.22);color:#fff;
}
.rail__authava svg{width:19px;height:19px}
.rail__auth.is-in .rail__authava{background:var(--accent-soft);color:var(--accent);font-weight:700;font-size:14px}
.rail__authtext{display:flex;flex-direction:column;line-height:1.3;min-width:0;flex:1}
.rail__authtext b{font-size:13.5px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:118px}
.rail__authtext span{font-size:10.5px;opacity:.85;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:118px}
.rail__auth.is-in .rail__authtext span{color:var(--faint)}
.rail__authvip{
  font-style:normal;font-size:9.5px;font-weight:800;letter-spacing:.08em;
  padding:2px 7px;border-radius:999px;color:#241B0B;
  background:linear-gradient(135deg,var(--gold-2),var(--gold));
}

/* ---- 可自定义的头像 + 名称（v2.6.13 · 站长：「把这个删除，加一个自定义头像，和名称的功能」）----
   头像两种形态共用同一只圆：传了图就铺满（object-fit:cover），没传就首字母落在天蓝渐变上。
   右上角那颗小笔**独立于 #railAuth**（嵌套 button 会被浏览器拆解，v2.0.1 踩过这个坑）：
   平时半隐，指针靠近整张名片或键盘聚焦时才点亮 —— 不打扰，但一眼看得见「这里能改」。 */
.rail__authava{overflow:hidden;position:relative}
.rail__authava img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}
.rail__auth.is-in .rail__authava{
  background:var(--accent-grad);
  font-family:var(--f-display);font-weight:700;font-size:15px;letter-spacing:.02em;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.55), 0 2px 8px -3px rgba(2,132,199,.55);
}
.rail__edit{
  position:absolute;right:-4px;top:-4px;width:23px;height:23px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  background:var(--surface);border:1px solid var(--glass-brd);color:var(--muted);
  box-shadow:var(--shadow-s), var(--glass-inset);
  opacity:.55;transform:scale(.94);
  transition:.22s var(--ease-spring);
  -webkit-tap-highlight-color:transparent;
}
.rail__edit svg{width:12.5px;height:12.5px}
.rail__profile:hover .rail__edit,.rail__edit:focus-visible{opacity:1;transform:none;color:var(--accent)}
.rail__edit:hover{background:var(--accent-grad);color:#fff;border-color:transparent}
.rail__edit:active{transform:scale(.9)}

/* ---- 「头像与名称」弹窗 ---- */
.pf{display:flex;flex-direction:column;align-items:center;gap:13px;margin:2px 0 20px}
.pf__ava{
  width:88px;height:88px;border-radius:50%;overflow:hidden;position:relative;
  display:flex;align-items:center;justify-content:center;flex:0 0 88px;
  background:var(--accent-grad);color:#fff;
  font-family:var(--f-display);font-size:35px;font-weight:700;letter-spacing:.02em;
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.5), 0 12px 28px -13px rgba(2,132,199,.8);
}
.pf__ava img{width:100%;height:100%;object-fit:cover;display:block}
.pf__acts{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
.pf__row{width:100%}
.pf__hint{font-size:11.5px;line-height:1.85;color:var(--faint);text-align:center}

/* ============ 分类提示 / 筛选层级 ============ */
.catnote{
  margin:0 0 14px;padding:10px 14px;border-radius:var(--r-s);
  background:var(--gold-soft);border:1px solid rgba(176,141,79,.3);
  font-size:12px;line-height:1.8;color:var(--ink-2);
  animation:fade .28s ease backwards;
}
.catnote b{color:var(--gold)}
[data-theme="dark"] .catnote b{color:var(--gold-2)}

/* 一级：板块 —— 独占一行，横向可滑动。
   移动端加上右侧渐隐，明确告诉用户「这一行还能往右滑」，
   不然 7 个板块被截断在「国家…」，后面的时代周刊 / 纽约客根本看不到。 */
.catbar{margin:-4px 0 12px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.catbar::-webkit-scrollbar{display:none}
.seg--cat{width:max-content;min-width:100%;padding:4px;gap:2px}
.seg--cat .seg__btn{height:34px;padding:0 15px;font-size:13.5px;white-space:nowrap}
/* 板块按钮里的篇数：比板块名小一号、更淡，不跟板块名抢视线；选中时反白 */
.seg--cat .seg__n{
  font-style:normal;margin-left:6px;font-size:10.5px;font-weight:600;
  color:var(--faint);letter-spacing:0;
}
.seg--cat .seg__btn.is-active .seg__n{color:rgba(255,255,255,.8)}
/* 悬停时给个浅底：这一行除了当前选中项，其余原本只有文字变色，
   不太看得出「这些也是能点的」 */
.seg--cat .seg__btn:not(.is-active):hover{background:var(--surface-2);color:var(--ink)}
@media (max-width:640px){
  .catbar{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 30px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 30px),transparent)}
}

/* ============ 筛选栏（常驻一行 + 可展开面板） ============ */
.filterbar{
  display:flex;align-items:center;gap:9px;
  margin:0 0 14px;min-height:34px;
}
.fbar__toggle{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
  height:32px;padding:0 11px 0 12px;border-radius:999px;cursor:pointer;
  font-family:inherit;font-size:13.5px;font-weight:600;letter-spacing:.02em;
  color:var(--ink-2);background:var(--surface);border:1px solid var(--glass-brd);
  backdrop-filter:blur(14px) saturate(1.6);-webkit-backdrop-filter:blur(14px) saturate(1.6);
  transition:color .2s,border-color .2s,background .2s,box-shadow .2s;
}
.fbar__toggle svg{width:15px;height:15px;flex:0 0 15px}
.fbar__toggle .fbar__caret{width:14px;height:14px;color:var(--faint);transition:transform .26s var(--ease-spring)}
.fbar__toggle:hover{color:var(--ink);border-color:var(--accent-2)}
.fbar__toggle.is-open{color:var(--accent-ink);border-color:var(--accent-2);background:var(--accent-soft)}
.fbar__toggle.is-open .fbar__caret{transform:rotate(180deg)}
.fbar__toggle.is-on{color:var(--accent-ink);border-color:var(--accent-2)}
.fbar__badge{
  font-style:normal;min-width:17px;height:17px;padding:0 5px;border-radius:999px;
  font-family:var(--f-display);font-size:10.5px;font-weight:700;line-height:17px;text-align:center;
  color:#fff;background:var(--accent-grad);
}
/* 已选条件回显：可横向滑动，不被压缩换行 */
.fbar__sel{
  flex:1;min-width:0;display:flex;align-items:center;gap:7px;
  overflow-x:auto;overflow-y:hidden;scrollbar-width:none;padding:1px 0;
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);
}
.fbar__sel::-webkit-scrollbar{display:none}
.fsel{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  height:26px;padding:0 9px;border-radius:999px;cursor:pointer;
  font-family:inherit;font-size:12px;color:var(--accent-ink);
  background:var(--accent-soft);border:1px solid transparent;
  animation:segPop .26s var(--ease-spring);transition:background .18s,border-color .18s;
}
.fsel:hover{background:var(--accent-2);color:#fff}
.fsel__x{font-size:13px;line-height:1;opacity:.65}
.fsel:hover .fsel__x{opacity:1}
.fbar__all{font-size:12px;color:var(--faint);letter-spacing:.02em}

/* 展开面板：难度 / 来源 / 话题 */
.filters{
  display:flex;flex-direction:column;gap:11px;margin-bottom:20px;
  padding:14px 15px;border-radius:var(--r-m);
  background:var(--surface-2);border:1px solid var(--glass-brd);
  animation:fade .26s ease backwards;
}
.filters[hidden]{display:none}
.frow{display:flex;align-items:center;gap:11px;min-width:0}
.frow__lb{
  flex:0 0 auto;
  font-size:10.5px;font-weight:700;letter-spacing:.16em;
  color:var(--faint);white-space:nowrap;
}
.frow .chiprow{margin-bottom:0;flex:1;min-width:0}
.frow .seg{flex:0 0 auto}
/* 展开后的 chip 行不换行、横向滑动 —— 换行会把面板撑成一长条（手机上原本 5 行） */
.chiprow--slide{
  flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
}
.chiprow--slide::-webkit-scrollbar{display:none}
.chiprow--slide .chip{flex:0 0 auto}
/* ⚠️ 桌面端必须换行（2026-09-22 站长反馈「后面的内容点不到了」）：
   上面那套横滑只对触屏友好 —— 手机上手指能滑，但桌面用鼠标没有横向滚动，
   滚动条又被藏起来了，于是右半边的 chip（话题的「文化与生活 / 教育」等）永远点不到。
   所以 ≥641px 一律改回自动换行，让所有 chip 都看得见、点得到；
   窄屏（触屏）保留横滑 + 右缘渐隐，仍是最省空间的做法。 */
@media (min-width:641px){
  .chiprow--slide{flex-wrap:wrap;overflow:visible;-webkit-overflow-scrolling:auto;-webkit-mask-image:none;mask-image:none}
}

/* 结果计数 */
.listcount{
  font-size:12.5px;color:var(--muted);letter-spacing:.02em;white-space:nowrap;
  padding:6px 13px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--glass-brd);
}
.listcount b{font-family:var(--f-display);font-size:16px;color:var(--accent-ink);margin-right:1px}

@media (max-width:640px){
  .frow{flex-direction:column;gap:6px}
  .frow__lb{padding-top:0}
  .frow .chiprow{width:100%}
  .listcount{display:none}
}

/* ============ 朗读控制条 ============ */
.ttsbar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin:0 0 14px;padding:8px 12px;border-radius:999px;
  background:var(--surface);border:1px solid var(--glass-brd);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:var(--shadow-s);
  animation:fade .3s ease backwards;
}
.ttsbar .iconbtn{background:var(--surface-2);border-color:var(--glass-brd);color:var(--accent-ink)}
.ttsbar .iconbtn:hover{background:var(--accent-soft)}
/* 视觉同上统一规则，这里只留尺寸（下拉保持胶囊形） */
.ttsbar__sel{
  height:32px;padding:0 12px;border-radius:999px;font-size:12px;max-width:210px;
  cursor:pointer;
}
.ttsbar__sel--rate{max-width:120px}
.ttsbar__hint{font-size:11px;color:var(--faint);margin-left:auto;white-space:nowrap}

/* 句子高亮（朗读中） */
.sent{border-radius:4px;transition:background .25s;cursor:pointer}
.sent:hover{background:var(--accent-soft)}
.sent.is-reading{
  background:linear-gradient(90deg,var(--accent-soft),rgba(99,102,241,.12));
  box-shadow:inset 2.5px 0 0 var(--accent);
}
.sent.is-read{opacity:.62}

/* 段落朗读按钮：悬浮在英文段落右侧，不干扰阅读
   注意：按钮在 .parabox 中，不是 .para--en 内部（<button> 不能嵌在 <p> 里） */
.parabox{position:relative}
/* v2.5.55：不再给 .parabox 加左内边距（那份留白只在 ≥821px 生效，窄屏等于没有，
   正是小笔压字的根源）。左右留槽改由 .para--en 自己的 padding 提供，见上。 */
.parabox .para__say{
  position:absolute;top:0;right:-34px;
  width:26px;height:26px;border-radius:8px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent);background:var(--accent-soft);
  opacity:0;transition:.18s;
}
.parabox .para__say svg{width:14px;height:14px}
.parabox:hover .para__say{opacity:.75}
.parabox .para__say:hover{opacity:1;background:var(--accent-grad);color:#fff}
.parabox .para__say.is-speaking{opacity:1;animation:pulse 1s ease infinite}
/* 窄屏没有右侧空间，改为贴段落右下角内嵌 */
@media (max-width:920px){
  .parabox .para__say{right:0;top:0;background:transparent}
  .parabox .para__say:hover{background:var(--accent-soft);color:var(--accent)}
}

/* 单词卡发音按钮 */
.wordcard__say{
  width:26px;height:26px;border-radius:8px;flex:0 0 26px;margin-left:auto;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent);background:var(--accent-soft);transition:.18s;
}
.wordcard__say svg{width:14px;height:14px}
.wordcard__say:hover{background:var(--accent-grad);color:#fff}
.wordcard__say.is-speaking{animation:pulse 1s ease infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}

/* ============ 响应式 ============ */
@media (max-width:1080px){
  .statrow--4{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:920px){
  .rail{width:70px;flex:0 0 70px;padding:18px 10px}
  .rail__profile{margin-bottom:16px}
  .rail__auth{justify-content:center;padding:8px}
  .rail__authtext,.rail__authvip{display:none}
  .rail__edit{right:-3px;top:-3px;width:20px;height:20px}
  .rail__edit svg{width:11px;height:11px}
  .navbtn{justify-content:center;padding:0}
  .navbtn span{display:none}
  .navbtn__dot,.navbtn__crown{position:absolute;top:4px;right:4px;margin:0;font-size:9px;min-width:15px;height:15px}
  .rail__foot{flex-direction:column}
  .view{padding:28px 20px 90px}
  .grid2,.artlist--wide,.plans{grid-template-columns:1fr}
  /* 窄屏放不下「信息 + 按钮」并排，回到纵向居中 */
  .plan:only-child{flex-direction:column;align-items:stretch;text-align:center;padding:26px 22px;gap:0}
  .plan:only-child .plan__flag{left:50%;transform:translateX(-50%)}
  .plan:only-child .btn{width:100%;margin-top:20px;min-width:0}
  .vocabgrid{grid-template-columns:1fr}
  .statrow{grid-template-columns:repeat(2,1fr)}
  .quote__en{font-size:21px}
  /* v2.6.6（为 iPhone 加）：iOS Safari 在**字号小于 16px 的输入框**获得焦点时会把整页自动放大 ——
     登录时页面被放大、键盘再一挡，就变成「看不到登录按钮 / 输一半跑偏」。
     弹窗里的输入框（登录、兑换码、邀请码等要打字的地方）在手机上统一给到 16px。 */
  .modal .input{font-size:16px}
  /* v2.6.5：金句卡底部（作者 + 四颗操作按钮）窄屏并排会挤成一团，
     改为纵向：作者一行、按钮一行，按钮仍可再换行（配合 .linkbtn 的 nowrap） */
  .quote__from{flex-direction:column;align-items:flex-start;gap:10px}
  .quote__acts{justify-content:flex-start}
  .reader__title{font-size:27px}
  .vhead{flex-direction:column;align-items:flex-start}
  /* 生词本头部：窄屏放不下「筛选器 + 复习模式」一行，让复习模式换到第二行 */
  .headtools{flex-wrap:wrap;width:100%}
}

/* ============================================================
   v2.1 追加：涟漪反馈 · 金句收藏 · 微交互
   ============================================================ */

/* 点击涟漪（JS 注入 span.ripple） */
.ripple{
  position:absolute;border-radius:50%;pointer-events:none;
  transform:translate(-50%,-50%) scale(0);
  /* 调柔：原来 .75/.45 亮度偏高，扩散后像一块白斑；降到 .55/.3 更像水光。
     调快：.68s → .5s，跟手更快，不再拖出一段尾巴。 */
  background:radial-gradient(circle,rgba(255,255,255,.55) 0%,rgba(186,230,253,.3) 44%,transparent 70%);
  mix-blend-mode:screen;
  animation:rip .5s var(--ease-out) forwards;
}
@keyframes rip{
  0%{transform:translate(-50%,-50%) scale(0);opacity:.95}
  100%{transform:translate(-50%,-50%) scale(1);opacity:0}
}
@media (prefers-reduced-motion: reduce){
  .ripple{display:none}
  .acard,.vcard{animation:none !important}
}

/* 小控件按压回弹 */
.vcard__ft button{transition:.2s var(--ease-spring);position:relative;overflow:hidden}
.vcard__ft button:active{transform:scale(.94)}
.wd__d{transition:.24s var(--ease-spring)}
.wd__d:active{transform:scale(.86)}
.wordcard__add,.wordcard__say{position:relative;overflow:hidden}
.wordcard__add:active,.wordcard__say:active{transform:scale(.88)}
.plan .btn:active{transform:scale(.96)}

/* 打卡按钮达成态呼吸光 */
#btnCheckin:not([disabled]):hover{filter:brightness(1.05)}

/* ============ 每日金句：收藏 ============ */
.quote__acts{display:inline-flex;align-items:center;gap:14px;
  /* v2.6.5：窄屏放不下时整行换行（配合 .linkbtn 的 nowrap），不要压成竖排单字 */
  flex-wrap:wrap;justify-content:flex-end;row-gap:8px}
/* 金句朗读（v2.6.11 · 站长要求「放在右上角」）：
   从底部操作行挪到卡片右上角的**小喇叭图标按钮** —— 图标即语义，不必再占一行文字。
   `margin-left:auto` 把它推到那一行的最右；播放中图标脉冲（pulse 是站里通用的朗读动画）。
   旧的文字按钮样式（.quote__say，v2.6.5）已随 DOM 一起移除。 */
.quote__sayicon{
  margin-left:auto;flex:0 0 auto;width:30px;height:30px;border-radius:50%;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent-ink);background:var(--accent-soft);
  border:1px solid var(--accent-2);box-shadow:var(--glass-inset);
  transition:.2s var(--ease-spring);cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.quote__sayicon svg{width:15px;height:15px}
.quote__sayicon:hover{background:var(--accent-grad);color:#fff;border-color:transparent;transform:scale(1.08)}
.quote__sayicon:active{transform:scale(.92)}
.quote__sayicon.is-speaking{background:var(--accent-grad);color:#fff;border-color:transparent;animation:pulse 1s ease infinite}
.quote__fav{transition:.22s var(--ease-spring)}
.quote__fav.is-on{
  color:#fff;background:var(--accent-grad);
  padding:4px 12px;border-radius:999px;text-decoration:none !important;
  box-shadow:0 3px 12px -4px rgba(14,165,233,.55);
  animation:favPop .38s var(--ease-spring);
}
@keyframes favPop{0%{transform:scale(.7)}55%{transform:scale(1.12)}100%{transform:scale(1)}}

/* 金句收藏夹弹窗 */
.qfavhd{text-align:center;margin-bottom:18px}
.qfavhd__t{font-family:var(--f-display);font-size:24px;font-weight:600;letter-spacing:.02em}
.qfavhd__s{font-size:12.5px;color:var(--muted);margin-top:6px;letter-spacing:.02em}
.qfavhd__s b{color:var(--accent-ink);font-family:var(--f-display);font-size:15px}
.qfavlist{
  display:flex;flex-direction:column;gap:14px;
  max-height:58vh;overflow-y:auto;overscroll-behavior:contain;
  margin:0 -4px 6px 0;padding:2px 8px 4px 2px;
  scroll-behavior:smooth;
}
.qfavlist::-webkit-scrollbar{width:6px}
.qfavlist::-webkit-scrollbar-track{background:transparent}
.qfavlist::-webkit-scrollbar-thumb{background:var(--line);border-radius:99px}
.qfavlist::-webkit-scrollbar-thumb:hover{background:var(--line-2)}
.qfav{
  position:relative;flex:0 0 auto;   /* 关键修复：flex 纵向列表超高时不许压缩卡片（否则出处行被裁掉） */
  padding:16px 22px 15px 24px;border-radius:18px;
  /* 天蓝毛玻璃：与会员页同一套玻璃配方 */
  background:var(--sky-hi), var(--sky-panel);
  border:1px solid rgba(125,211,252,.5);
  box-shadow:0 1px 2px rgba(2,132,199,.07), 0 16px 42px -18px rgba(2,132,199,.32), var(--glass-inset);
  backdrop-filter:blur(20px) saturate(1.7);-webkit-backdrop-filter:blur(20px) saturate(1.7);
  overflow:hidden;
  transition:transform .28s var(--ease-spring), box-shadow .28s, border-color .24s, background .24s;
  animation:cardIn .38s var(--ease-out) backwards;
}
.qfav::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:4px;
  background:var(--accent-grad);
}
.qfav:hover{
  transform:translateY(-3px);
  background:linear-gradient(165deg,rgba(224,242,254,.9),rgba(240,249,255,.66) 58%,rgba(255,255,255,.72));
  box-shadow:0 2px 6px rgba(2,132,199,.09), 0 26px 54px -20px rgba(2,132,199,.45), var(--glass-inset);
  border-color:rgba(56,189,248,.7);
}
.qfav__hd{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:11px}
.qfav__no{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:26px;height:20px;padding:0 7px;border-radius:6px;
  font-family:var(--f-display);font-size:11px;font-weight:700;letter-spacing:.05em;
  color:#0369A1;background:rgba(255,255,255,.72);
  border:1px solid rgba(125,211,252,.55);
}
/* 朗读这句：与右下角删除按钮一左一右呼应 */
.qfav__say{
  flex:0 0 30px;width:30px;height:30px;border-radius:50%;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent-ink);background:rgba(255,255,255,.68);
  border:1px solid rgba(125,211,252,.55);
  box-shadow:var(--glass-inset);
  transition:.2s var(--ease-spring);cursor:pointer;
}
.qfav__say svg{width:16px;height:16px}
.qfav__say:hover{background:var(--accent-grad);color:#fff;border-color:transparent;transform:scale(1.06)}
.qfav__say.is-speaking{background:var(--accent-grad);color:#fff;border-color:transparent;animation:pulse 1s ease infinite}
.qfav__en{
  font-family:var(--f-read);font-size:17px;line-height:1.72;color:var(--ink);
  letter-spacing:.003em;margin:0;
}
/* 句首 / 句尾装饰引号：随文字排版（不浮动、不压字、不会把出处行顶出卡片） */
.qfav__en::before{
  content:"\201C";font-family:Georgia,var(--f-display),serif;
  font-size:1.55em;line-height:0;vertical-align:-.16em;
  color:var(--accent);opacity:.6;margin-right:2px;
}
.qfav__en::after{
  content:"\201D";font-family:Georgia,var(--f-display),serif;
  font-size:1.55em;line-height:0;vertical-align:-.16em;
  color:var(--accent);opacity:.6;margin-left:2px;
}
.qfav__zh{font-size:13.5px;line-height:1.85;color:var(--muted);margin:11px 0 0}
.qfav__ft{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  clear:both;   /* 防御：任何浮动装饰都不允许把出处行顶出卡片 */
  margin-top:14px;padding-top:11px;border-top:1px dashed rgba(125,211,252,.5);
}
.qfav__from{
  display:flex;align-items:center;gap:7px;min-width:0;
  font-size:11.5px;color:#0C4A6E;opacity:.72;letter-spacing:.04em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.qfav__from::before{
  content:"";width:5px;height:5px;border-radius:50%;
  background:var(--accent-2);flex:0 0 5px;
}
.qfav__del{
  flex:0 0 28px;width:28px;height:28px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  color:#0C4A6E;opacity:.5;
  background:rgba(255,255,255,.6);border:1px solid rgba(125,211,252,.5);padding:0;
  transition:.2s var(--ease-spring);cursor:pointer;
}
.qfav__del svg{width:14px;height:14px}
.qfav:hover .qfav__del{opacity:1}
.qfav__del:hover{color:#fff;background:var(--rose);border-color:transparent;opacity:1;transform:scale(1.06)}
.qfavempty{text-align:center;padding:26px 10px 36px;color:var(--faint)}
.qfavempty__q{
  font-family:Georgia,var(--f-display);font-size:72px;line-height:1;
  background:linear-gradient(180deg,var(--accent),var(--accent-2));
  -webkit-background-clip:text;background-clip:text;color:transparent;
  margin-bottom:6px;opacity:.9;
}
.qfavempty p{font-size:15px;color:var(--ink-2);margin:0 0 9px}
.qfavempty span{font-size:12.5px;line-height:1.9;display:block;max-width:290px;margin:0 auto}
/* 暗色：与会员页同一套深蓝玻璃 */
[data-theme="dark"] .qfav{
  background:linear-gradient(165deg,rgba(14,116,144,.3),rgba(15,23,42,.52) 62%);
  border-color:rgba(56,189,248,.32);
}
[data-theme="dark"] .qfav:hover{
  background:linear-gradient(165deg,rgba(14,116,144,.42),rgba(15,23,42,.64) 62%);
  border-color:rgba(56,189,248,.5);
}
[data-theme="dark"] .qfav__no{color:#7DD3FC;background:rgba(56,189,248,.18);border-color:rgba(56,189,248,.35)}
[data-theme="dark"] .qfav__say{background:rgba(56,189,248,.16);border-color:rgba(56,189,248,.35)}
[data-theme="dark"] .qfav__from{color:var(--muted);opacity:1}
[data-theme="dark"] .qfav__del{background:rgba(56,189,248,.16);border-color:rgba(56,189,248,.35);color:var(--muted)}
@media (max-width:520px){
  .qfav{padding:15px 18px 14px 20px;border-radius:15px}
  .qfav__en{font-size:15.5px}
  .qfav__zh{font-size:13px}
  .qfavlist{max-height:52vh;gap:11px}
}

/* ============ 阅读界面：流动云朵背景 ============ */
/* v2.5.42→43：与 #skyScene 同步改 left:0（云铺满全窗，无接缝）；z-index 保持 0
   （原 v2.1.1 起就是 0：绘在静态内容之上、位于 z1 抬举的阅读内容之下——
   v2.5.42 试过 z-1 垫到玻璃后，代价是 backdrop-filter 逐帧重模糊动态背景，
   iPhone 上卡死，已回；阅读内容早在 v2.1.1 就已 position:relative;z-index:1 压在云上）。 */
.clouds{
  position:fixed;top:0;right:0;bottom:0;left:0;z-index:0;pointer-events:none;overflow:hidden;
}
.cloud{
  position:absolute;left:0;
  fill:#FFFFFF;
  filter:drop-shadow(0 22px 34px rgba(147,197,253,.4));
  animation:cloudDrift linear infinite;
  will-change:transform;
}
/* 近景云：大而清晰，90-120s 飘过 */
.cloud.c1{width:340px;top:7%;opacity:.95;animation-duration:110s;animation-delay:-18s}
.cloud.c2{width:260px;top:30%;opacity:.8;fill:#F3FAFF;animation-duration:95s;animation-delay:-64s}
/* 中景云 */
.cloud.c3{width:200px;top:55%;opacity:.6;fill:#EAF5FF;filter:blur(.6px) drop-shadow(0 18px 28px rgba(147,197,253,.32));animation-duration:130s;animation-delay:-42s}
/* 远景云：小而淡，轻雾感，最慢 */
.cloud.c4{width:150px;top:16%;opacity:.45;fill:#E4F2FE;filter:blur(1.6px) drop-shadow(0 14px 22px rgba(147,197,253,.25));animation-duration:170s;animation-delay:-96s}
.cloud.c5{width:180px;top:74%;opacity:.5;fill:#EDF7FF;filter:blur(1.2px) drop-shadow(0 16px 26px rgba(147,197,253,.28));animation-duration:150s;animation-delay:-130s}
@keyframes cloudDrift{
  from{transform:translate3d(-32vw,0,0)}
  to{transform:translate3d(112vw,0,0)}
}
/* 云朵漂浮时微微起伏（真实感） */
.cloud.c1,.cloud.c3,.cloud.c5{animation-name:cloudDrift,cloudBob;animation-timing-function:linear,ease-in-out;animation-iteration-count:infinite,infinite}
.cloud.c1{animation-duration:110s,9s}
.cloud.c3{animation-duration:130s,11s}
.cloud.c5{animation-duration:150s,10s}
@keyframes cloudBob{0%,100%{margin-top:0}50%{margin-top:-14px}}
/* 阅读内容压在云朵之上 */
#reader .reader__top,#reader .ttsbar,#reader .reader__progress,#reader .reader,#reader .reader__done{
  position:relative;z-index:1;
}
/* 深色模式：云化作淡淡月光雾 */
[data-theme="dark"] .cloud{opacity:.16;filter:blur(2px) drop-shadow(0 18px 30px rgba(2,132,199,.25))}
[data-theme="dark"] .cloud.c4,[data-theme="dark"] .cloud.c5{opacity:.1}
@media (prefers-reduced-motion: reduce){
  .cloud{animation:none !important;opacity:.35}
}

/* ============================================================
   v2.2 追加：悬停翻译开关 · 生词小技巧 · 语音试听
   ============================================================ */

/* ---- 阅读器工具：胶囊小开关（悬停翻译） ---- */
.htool{
  display:inline-flex;align-items:center;gap:7px;height:30px;padding:0 12px;
  border-radius:999px;border:1px solid var(--glass-brd);
  background:var(--surface-2);color:var(--muted);
  font-size:12px;letter-spacing:.02em;white-space:nowrap;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  transition:.22s var(--ease-out);position:relative;overflow:hidden;
}
.htool svg{width:14px;height:14px;flex:0 0 14px}
.htool:hover{color:var(--ink);border-color:var(--accent-2);transform:translateY(-1px)}
.htool:active{transform:scale(.95)}
.htool__sw{
  width:26px;height:15px;border-radius:99px;background:var(--line);
  position:relative;transition:.25s;flex:0 0 26px;
}
.htool__knob{
  position:absolute;top:2px;left:2px;width:11px;height:11px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(11,30,51,.28);
  transition:left .25s var(--ease-spring);
}
.htool.is-on{color:var(--accent-ink);border-color:var(--accent-2);background:var(--accent-soft)}
.htool.is-on .htool__sw{background:var(--accent-grad)}
.htool.is-on .htool__knob{left:13px}

/* ---- 生词小技巧（文章上方，可关闭，关闭后记住） ---- */
.rtip{
  display:flex;align-items:center;gap:12px;
  margin:0 0 18px;padding:11px 14px 11px 12px;border-radius:var(--r-m);
  background:var(--surface);border:1px solid var(--glass-brd);
  backdrop-filter:blur(16px) saturate(1.6);-webkit-backdrop-filter:blur(16px) saturate(1.6);
  box-shadow:var(--shadow-s), var(--glass-inset);
  animation:tipIn .5s var(--ease-spring) backwards .15s;
  position:relative;z-index:1;
}
@keyframes tipIn{0%{opacity:0;transform:translateY(-10px) scale(.97)}100%{opacity:1;transform:none}}
.rtip__ic{
  width:32px;height:32px;flex:0 0 32px;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  color:#fff;background:var(--accent-grad);
  box-shadow:0 4px 12px -4px rgba(14,165,233,.55);
}
.rtip__ic svg{width:17px;height:17px}
.rtip__tx{font-size:13px;color:var(--ink-2);line-height:1.55}
.rtip__tx b{color:var(--accent-ink);font-weight:600}
.rtip__tx em{display:block;font-style:normal;font-size:11.5px;color:var(--faint);margin-top:1px}
.rtip__x{
  margin-left:auto;width:24px;height:24px;flex:0 0 24px;border-radius:8px;
  color:var(--faint);font-size:11px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;transition:.18s;
}
.rtip__x:hover{color:var(--ink);background:var(--accent-soft)}

/* ---- 语音试听按钮：播放中呼吸脉冲 ---- */
.ttsbar .iconbtn.is-speaking{animation:pulse 1s ease infinite;color:#fff;background:var(--accent-grad);border-color:transparent}

@media (max-width:640px){
  .rtip__tx em{display:none}
  .htool span:not(.htool__sw):not(.htool__knob){display:none}
  .htool{padding:0 9px}
}

/* ============================================================
   iOS 材质统一层（2026-09-19 新增）
   ------------------------------------------------------------
   目的：把全站原本各写各的玻璃参数收敛成同一套 iOS 配方。
   收敛前的乱象：模糊半径有 8/10/12/14/16/18/20 共 6 种，饱和度 3 种。

   三条原则：
   ① 只统一「雾面参数 + 发丝边框 + 内阴影层次」，不动尺寸、圆角、配色语义；
   ② 不新增任何模糊层 —— 层数不变、只是参数更精细，手机滚动不会因此变慢；
   ③ 大面板走 --ios-blur(24px)，小控件走 --ios-blur-sm(16px)。

   放在文件末尾是为了稳定覆盖前面各处的分散定义。安全性说明：
   · 选中态（.is-active / .is-on / .is-open）都是双类选择器，特异性更高，不受影响；
   · 深色主题的 [data-theme="dark"] .x 覆盖同样特异性更高，也不受影响。
   ============================================================ */

/* ---- ① 小控件：胶囊 / 按钮 / 开关 —— 统一 16px 雾面 + 发丝边 + 玻璃厚度 ---- */
.btn--ghost,.seg,.chip,.tlist,.fbar__toggle,.ttsbar,.htool,.rtip,
#view-vip .vipstate,#view-vip .invite code{
  backdrop-filter:blur(var(--ios-blur-sm)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur-sm)) saturate(var(--ios-sat));
  border-color:var(--ios-hair);
  box-shadow:
    0 0 0 .5px var(--ios-edge),
    inset 0 1px 0 var(--ios-hi),
    inset 0 -1px 0 var(--ios-lo),
    0 1px 2px rgba(2,132,199,.06),
    0 8px 22px -14px rgba(2,132,199,.34);
}

/* ---- ② 天蓝玻璃卡片族：背景配方本就一致，此处补进 24px 雾面 + 发丝边 ---- */
.todo,.qfav{
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  border-color:var(--ios-hair);
}

/* ---- ③ 遮罩与浮层 ---- */
.modal__mask{backdrop-filter:blur(12px) saturate(1.3);-webkit-backdrop-filter:blur(12px) saturate(1.3)}
.toast{
  backdrop-filter:blur(var(--ios-blur-sm)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur-sm)) saturate(var(--ios-sat));
}

/* ---- ④ 卡片 iOS 按压（用户选定：小控件留涟漪，大卡片走 iOS 式按压）----
   手感来源：按下瞬间到位（.1s），松手时由基础规则的弹性曲线回弹。
   ⚠️ 刻意不用 filter:brightness() 做「按下变暗」—— filter 会给元素建立 backdrop root，
   会让卡片自身的 backdrop-filter（毛玻璃）在部分浏览器上失效。缩放已足够表达按压。
   顺带给原本没有过渡的卡片补上弹性曲线，否则按下与回弹都是硬切、没有弹性。 */
.todo,.wordcard{
  transition:transform .38s var(--ease-spring), box-shadow .3s var(--ease-out), border-color .24s;
}
.acard:active,.vcard:active,.todo:active,.qfav:active,.wordcard:active{
  transform:scale(.972);
  transition-duration:.1s;
}

/* ---- ⑤ iPhone 安全区：底部给 Home 指示条留空，避免侧栏底部内容被压住 ----
   桌面端 env(safe-area-inset-bottom) 恒为 0，不改变现有观感。
   放在文件末尾是为了同时压过基础规则和 920px 断点里的 .rail padding。 */
.rail{padding-bottom:calc(16px + env(safe-area-inset-bottom))}
@media (max-width:920px){
  .rail{padding-bottom:calc(18px + env(safe-area-inset-bottom))}
}

/* ---- ⑥ 尊重系统「减弱动态效果」：iOS 开启后全站不做位移/缩放。
   （涟漪的隐藏已由上面的 prefers-reduced-motion 块处理，此处只补新增的按压缩放。） ---- */
@media (prefers-reduced-motion: reduce){
  .acard:active,.vcard:active,.todo:active,.qfav:active,.wordcard:active{transform:none}
}


/* ============================================================
   天蓝玻璃 · 统一层（2026-09-20 高级版）
   把大面板的投影加深、内高光提亮 —— 让玻璃块真正浮起来，
   而不是「涂成蓝色」贴在背景上。放在文件末尾以便覆盖各组件原值。
   ============================================================ */
.card,.quote,.acard,.stat,.vcard,.plan,.reader__donecard,.modal__box,.fallback__box,
.viphero,.todo,.qfav{
  border-color:var(--sky-edge);
  box-shadow:var(--sky-deep), inset 0 1px 0 rgba(255,255,255,.95), inset 0 -1px 0 rgba(255,255,255,.65), inset 0 -8px 16px -12px rgba(2,132,199,.28);
}
[data-theme="dark"] .card,[data-theme="dark"] .quote,[data-theme="dark"] .acard,[data-theme="dark"] .stat,
[data-theme="dark"] .vcard,[data-theme="dark"] .plan,[data-theme="dark"] .reader__donecard,
[data-theme="dark"] .modal__box,[data-theme="dark"] .viphero,
[data-theme="dark"] .todo,[data-theme="dark"] .qfav{
  box-shadow:var(--sky-deep), inset 0 1px 0 rgba(186,225,253,.3), inset 0 -1px 0 rgba(147,213,255,.28), inset 0 -10px 18px -14px rgba(0,0,0,.5);
}

/* ============================================================
   天蓝厚玻璃 · 精修层（2026-09-20 v2.5.15）
   ------------------------------------------------------------
   在「清透」基础上把玻璃做厚：半透明材质（见 :root --sky-*）+
   侧栏独立成板、导航选中态点亮、选中块/主按钮补受光棱线。
   只改材质表现，不动尺寸、布局、程序逻辑。
   ============================================================ */

/* ① 侧栏：独立毛玻璃竖板 —— 右缘受光细线，往内容区投一道淡蓝影 */
.rail{
  border-right-color:rgba(125,211,252,.5);
  box-shadow:18px 0 40px -30px rgba(2,132,199,.5), inset -1px 0 0 rgba(255,255,255,.6);
}
[data-theme="dark"] .rail{
  border-right-color:rgba(56,189,248,.26);
  box-shadow:18px 0 40px -30px rgba(0,0,0,.7), inset -1px 0 0 rgba(125,211,252,.18);
}

/* ② 导航选中态：点亮的玻璃 pill（整体受光 + 淡蓝投影），左角色条保留 */
.navbtn.is-active{
  background:linear-gradient(135deg,rgba(255,255,255,.94),rgba(224,242,254,.88) 60%,rgba(186,230,253,.82));
  border-color:rgba(125,211,252,.65);
  box-shadow:0 1px 2px rgba(2,132,199,.08), 0 10px 22px -12px rgba(2,132,199,.45), inset 0 1px 0 rgba(255,255,255,.95), inset 0 -1px 0 rgba(255,255,255,.7);
}
[data-theme="dark"] .navbtn.is-active{
  background:linear-gradient(135deg,rgba(125,211,252,.22),rgba(14,116,144,.3));
  border-color:rgba(56,189,248,.4);
  box-shadow:0 1px 2px rgba(0,0,0,.4), 0 10px 22px -12px rgba(2,132,199,.6), inset 0 1px 0 rgba(186,225,253,.25), inset 0 -1px 0 rgba(147,213,255,.22);
}

/* ③ 分段控件 / 筛选 chip 选中态：accent 渐变上补一道顶部受光棱线（iOS 选中块） */
.seg__btn.is-active,.chip.is-active{
  box-shadow:0 3px 12px -4px rgba(14,165,233,.55), inset 0 1px 0 rgba(255,255,255,.35);
}

/* ④ 主按钮：顶部受光棱线，像一颗玻璃扣子 */
.btn--ink{
  box-shadow:0 2px 6px rgba(2,132,199,.18), 0 12px 28px -12px rgba(14,165,233,.65), inset 0 1px 0 rgba(255,255,255,.32);
}

/* ============================================================
   进入动画 · 云上俯冲 v5（2026-09-21 v2.5.22 · 整体重做）
   3.4s 四镜头电影感航拍：① 悬停（0–0.45s）→ ② 压机头俯冲（0.45–1.10s）→
   ③ 穿云拨雾（1.10–2.35s，约 80ms 全白 =「拨开」节拍）→ ④ 落地余韵（2.35–3.40s）。
   真 3D：.intro 上 perspective:60vh（视点 50% 38%），六朵云以 translateZ(-160vh~-45vh)
   分远/中/近三档摆在三维空间，各按不同时长（远 2.2s / 中 1.7s / 近 1.35s）先后掠过镜头——
   视差来自各自的时间轴，不是同一根轴一起动；世界容器 rotateX(0→-10°) 压机头
   （不取更大的 -26°：云是贴在倾斜平面里的薄片，大倾角会把近云压扁成线、并推过透视平面消失）。
   云朵 = 每朵 5 层 radial-gradient 软斑（三团受光棉球 + 腹部高光 + 底部灰蓝阴影），
   零滤镜（v2.5.20 教训：全屏滤镜逐帧重栅格化必掉帧）；远景云掺白雾降不透明度。
   动画属性仅 transform/opacity（标题 letter-spacing 与一次性 blur(6px→0) 为例外）。
   类名独立为 .cl —— 与阅读页流动云 .cloud（SVG 背景，上方 1728 行）彻底解耦。
   pointer-events:none 不挡交互；节点由 index.html 内联脚本播完后移除。
   ============================================================ */
.intro{position:fixed;inset:0;z-index:2000;overflow:hidden;pointer-events:none;
  perspective:60vh;perspective-origin:50% 38%;
  animation:introOut .45s ease 2.95s both}
@keyframes introOut{to{opacity:0;visibility:hidden}}
/* 高空天光：上略深、下近白；顶部白色光晕 62% 处收干净；拨云后整片渐隐透出主界面 */
.intro__sky{position:absolute;inset:0;
  background:
    radial-gradient(ellipse 90% 62% at 50% -8%,rgba(255,255,255,.55) 0%,rgba(255,255,255,0) 62%),
    linear-gradient(180deg,rgba(255,255,255,0) 30%,rgba(190,220,244,.3) 44%,rgba(255,255,255,0) 58%),
    linear-gradient(180deg,#EAF6FF 0%,#FBFDFF 100%);
  animation:skyOut .8s ease 1.95s both}
@keyframes skyOut{to{opacity:0}}
/* 顶部斜向光带：只作「空气里有光」的暗示，极低透明度缓慢平移 */
.intro__ray{position:absolute;left:-12%;right:-12%;top:0;height:42%;
  background:linear-gradient(105deg,transparent 22%,rgba(255,255,255,.09) 44%,rgba(255,255,255,.06) 56%,transparent 78%);
  animation:rayDrift 3.4s linear both}
@keyframes rayDrift{0%{transform:translateX(-5%);opacity:.8}55%{opacity:1}80%,100%{transform:translateX(5%);opacity:0}}
/* 云层世界：preserve-3d 共享 .intro 透视；压机头 = rotateX(0 → -4° → -10°)，1.10s 后保持俯角 */
.intro__world{position:absolute;inset:0;transform-style:preserve-3d;will-change:transform;
  animation:worldTilt 3.4s cubic-bezier(.55,.06,.28,1) both}
@keyframes worldTilt{0%{transform:rotateX(0deg)}14%{transform:rotateX(-4deg)}32%,100%{transform:rotateX(-10deg)}}
/* 云朵本体：三团受光棉球 + 腹部高光 + 底部灰蓝阴影——有受光面和底面，不是白圆片。
   每朵 5 层 radial-gradient 天生软边、零滤镜；类名 .cl 与阅读页流动云 .cloud 彻底解耦 */
.intro .cl{position:absolute;left:0;top:0;display:block;border-radius:50%;
  background:
    radial-gradient(ellipse 40% 58% at 27% 36%,rgba(255,255,255,.98) 0%,rgba(255,255,255,.92) 45%,rgba(255,255,255,0) 72%),
    radial-gradient(ellipse 36% 52% at 54% 28%,rgba(255,255,255,.96) 0%,rgba(255,255,255,.9) 44%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 38% 54% at 75% 44%,rgba(252,253,255,.93) 0%,rgba(252,253,255,.88) 45%,rgba(255,255,255,0) 72%),
    radial-gradient(ellipse 34% 36% at 44% 52%,rgba(255,255,255,.9) 0%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 72% 42% at 50% 72%,rgba(206,226,242,.8) 0%,rgba(206,226,242,.45) 46%,rgba(255,255,255,0) 74%);
  animation:clFly var(--dur) cubic-bezier(.55,.06,.28,1) var(--del,0s) both}
/* 每朵云沿自己的纵深航线冲向镜头：远 2.2s / 中 1.7s / 近 1.35s 不同时长 = 视差；
   末段 opacity 收掉，避免越过透视平面（translateZ ≥ 60vh）造成闪灭 */
@keyframes clFly{
  0%{transform:translate3d(var(--x0),var(--y0),var(--z0));opacity:var(--op,1)}
  82%{opacity:var(--op,1)}
  100%{transform:translate3d(var(--x1),var(--y1),var(--z1));opacity:0}}
/* 远景档（-150vh 档，2.2s）：小而淡，多叠一层白雾；悬停拍里极远处缓慢漂移的小云 */
.intro .cl--f1,.intro .cl--f2{
  background:
    radial-gradient(ellipse 100% 100% at 50% 50%,rgba(255,255,255,.5) 0%,rgba(255,255,255,.5) 100%),
    radial-gradient(ellipse 40% 58% at 27% 36%,rgba(255,255,255,.98) 0%,rgba(255,255,255,.92) 45%,rgba(255,255,255,0) 72%),
    radial-gradient(ellipse 36% 52% at 54% 28%,rgba(255,255,255,.96) 0%,rgba(255,255,255,.9) 44%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 38% 54% at 75% 44%,rgba(252,253,255,.93) 0%,rgba(252,253,255,.88) 45%,rgba(255,255,255,0) 72%),
    radial-gradient(ellipse 34% 36% at 44% 52%,rgba(255,255,255,.9) 0%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 72% 42% at 50% 72%,rgba(206,226,242,.8) 0%,rgba(206,226,242,.45) 46%,rgba(255,255,255,0) 74%)}
.cl--f1{width:24vmax;height:9vmax;--x0:10vw;--y0:13vh;--z0:-150vh;--x1:6vw;--y1:11vh;--z1:42vh;--dur:2.2s;--op:.55}
.cl--f2{width:20vmax;height:8vmax;--x0:64vw;--y0:20vh;--z0:-160vh;--x1:68vw;--y1:18vh;--z1:42vh;--dur:2.2s;--del:.06s;--op:.5}
/* 中景档（-90vh 档，1.7s）：体量渐显，从两翼掠过（透视投影自动送出画面边缘） */
.cl--m1{width:46vmax;height:17vmax;--x0:-14vw;--y0:36vh;--z0:-95vh;--x1:-14vw;--y1:36vh;--z1:42vh;--dur:1.7s;--op:.92}
.cl--m2{width:42vmax;height:16vmax;--x0:68vw;--y0:44vh;--z0:-88vh;--x1:68vw;--y1:44vh;--z1:42vh;--dur:1.7s;--del:.07s;--op:.92}
/* 近景档（-45vh 档，1.35s）：屏高 20–30% 的巨物冲向镜头，透视自然把它们送出四角裁切 */
.cl--n1{width:68vmax;height:26vmax;--x0:-12vw;--y0:60vh;--z0:-52vh;--x1:-12vw;--y1:60vh;--z1:43vh;--dur:1.35s}
.cl--n2{width:60vmax;height:23vmax;--x0:58vw;--y0:6vh;--z0:-45vh;--x1:58vw;--y1:6vh;--z1:43vh;--dur:1.35s;--del:.05s}
/* 穿身云：中心云团屏底升起 → 糊满镜头（34%→41% ≈ 80ms 全白 =「拨开」节拍）→ 从中心向外裂开 */
.intro__punch{position:absolute;inset:0;will-change:transform,opacity;
  animation:punch 1.25s cubic-bezier(.2,.7,.3,1) 1.12s both}
.intro__punch .cl{width:200vmax;height:160vmax;left:50%;top:50%;margin-left:-100vmax;margin-top:-80vmax;animation:none;
  background:
    radial-gradient(ellipse 78% 78% at 50% 50%,rgba(255,255,255,1) 0%,rgba(255,255,255,1) 58%,rgba(255,255,255,0) 80%),
    radial-gradient(ellipse 40% 34% at 30% 30%,rgba(255,255,255,.98) 0%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 44% 36% at 68% 26%,rgba(255,255,255,.96) 0%,rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 60% 30% at 50% 78%,rgba(206,226,242,.7) 0%,rgba(255,255,255,0) 72%)}
@keyframes punch{
  0%{transform:translateY(78vh) scale(.5);opacity:0}
  16%{opacity:1}
  34%,41%{transform:translateY(0) scale(1.02);opacity:1}
  72%{transform:translateY(-5vh) scale(1.8);opacity:0}
  100%{transform:translateY(-6vh) scale(2);opacity:0}}
/* 片名：Skyland 压轴亮相（v2.5.23 站长要求最后才出现）——全程潜到最后一刻：拨云裂开时从雾中聚焦浮出
   （1.77s→2.11s，blur(6px→0) + scale 1.05→1），定格到 2.58s，再把主界面让出来（→2.99s 淡尽）；
   渐变天蓝（background-clip:text + 顶部高光）+ 背光白晕托底；字距 .18em → .52em 只在亮相段撑开 */
.intro__title{position:absolute;left:50%;top:33%;transform:translate(-50%,-50%);text-align:center;
  animation:tLife 3.4s ease both}
@keyframes tLife{
  0%,52%{opacity:0;transform:translate(-50%,-50%) translateY(10px) scale(1.05)}
  62%{opacity:1;transform:translate(-50%,-50%) translateY(0) scale(1)}
  76%{opacity:1}
  88%,100%{opacity:0;transform:translate(-50%,-50%) translateY(-2.5vh) scale(.97)}}
.intro__title::before{content:"";position:absolute;left:50%;top:50%;width:60vmax;height:24vmax;z-index:-1;
  transform:translate(-50%,-50%);
  background:radial-gradient(ellipse 50% 50% at 50% 50%,rgba(255,255,255,.9) 0%,rgba(255,255,255,0) 68%)}
.intro__title span{display:block;font-family:var(--f-display);font-weight:600;
  font-size:clamp(30px,7.2vw,74px);letter-spacing:.18em;text-indent:.18em;
  background:linear-gradient(180deg,#FFFFFF 0%,#D8EFFD 20%,#92D9FA 42%,#4EBBF1 62%,#1D90D2 82%,#0A6DA9 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  text-shadow:0 1px 12px rgba(11,73,120,.22);
  filter:blur(6px);
  animation:tTrack 3.4s ease both,tFocus .75s ease 1.8s both}
@keyframes tTrack{0%,50%{letter-spacing:.18em;text-indent:.18em}88%,100%{letter-spacing:.52em;text-indent:.52em}}
@keyframes tFocus{to{filter:blur(0)}}
/* 轻暗角：开画把视线收进中轴，拨云后散开 */
.intro__vig{position:absolute;inset:0;box-shadow:inset 0 0 22vmax rgba(11,38,66,.16);animation:vigOut 3.4s ease both}
@keyframes vigOut{0%,58%{opacity:1}80%,100%{opacity:0}}
/* v2.5.26：删除主界面 appDive「落地」动画与 .intro-dive 机制——它全程遮在不透明遮罩下本不可见（2.3s 起播时遮罩
   尚未淡出），而 3.08s 摘类会让 #app 回落到 .app 的自然 fade .5s 重新播放：遮罩 3.4s 淡尽后全屏二次淡入，
   正是用户看到的「结束后跳一下」根因。落地感由遮罩自身淡出（introOut）承接；#app 的自然 fade 在片头 0.5s
   内于不透明遮罩下完成并自然结束，无需任何收尾卸载。 */
@media (prefers-reduced-motion: reduce){.intro{display:none !important}}

/* ============ 抽拉式台灯主题开关（v2.5.37） ============
   替换原 #themeToggle 图标开关（按钮已撤，rail__foot 只剩设置键并靠右让位）。
   #skyLamp 固定于视口左下角、与侧栏底脚同区；z-index 46 = 在交叉淡化遮罩(45)之上、
   弹层(modal 1000 / toast 1100 / wordcard 900 / timerpill 800)之下。
   除 .lamp__hit 外全部 pointer-events:none —— 灯体绝不挡站点点击。
   光晕全部是「柔边径向渐变 + JS 只动 opacity/transform」，零 CSS filter（延续 v2.5.0
   「不新增模糊层」的滚动性能约束；径向渐变天然软边，视觉效果与模糊等价）。 */
#skyLamp{position:fixed;left:26px;bottom:14px;width:min(108px,14vh);z-index:46;pointer-events:none;-webkit-user-select:none;user-select:none}
#skyLamp .lamp__svg{display:block;width:100%;height:auto;position:relative}
.lamp__glow{position:absolute;pointer-events:none;opacity:0}
.lamp__halo{left:41.6%;top:42%;width:230%;aspect-ratio:1/1;border-radius:50%;transform:translate(-50%,-50%);
  background:radial-gradient(circle, rgba(255,198,122,.28) 0%, rgba(255,180,104,.11) 42%, rgba(255,180,104,0) 68%)}
.lamp__core{left:41.6%;top:40%;width:80%;aspect-ratio:1/1;border-radius:50%;transform:translate(-50%,-50%);
  background:radial-gradient(circle, rgba(255,219,158,.5) 0%, rgba(255,205,130,0) 62%)}
.lamp__pool--w{left:50%;bottom:1%;width:200%;height:15%;transform:translateX(-50%);border-radius:50%;
  background:radial-gradient(ellipse, rgba(255,200,128,.2) 0%, rgba(255,200,128,0) 68%)}
.lamp__pool--c{left:50%;bottom:2.5%;width:115%;height:9%;transform:translateX(-50%);border-radius:50%;
  background:radial-gradient(ellipse, rgba(255,208,140,.4) 0%, rgba(255,208,140,0) 66%)}
.lamp__pulse{left:41.6%;top:42%;width:150%;aspect-ratio:1/1;border-radius:50%;transform:translate(-50%,-50%) scale(.75);
  background:radial-gradient(circle, rgba(255,208,140,.5) 0%, rgba(255,208,140,0) 62%)}
/* 拉绳命中区：桌面精确落在绳/珠范围；触屏放大到整灯下段（48px 小灯也好点） */
.lamp__hit{position:absolute;left:40%;top:40%;width:36%;height:28%;cursor:pointer;touch-action:none;pointer-events:auto;outline:none;border-radius:12px;-webkit-tap-highlight-color:transparent}
.lamp__hit:focus-visible{outline:2px solid rgba(176,141,79,.85);outline-offset:2px}
@media (max-width:920px){
  #skyLamp{left:11px;bottom:12px;width:48px}
  .lamp__hit{left:-10%;top:32%;width:120%;height:42%}
  .rail__foot{padding-bottom:76px}  /* 窄栏：设置键抬到台灯上方，互不重叠 */
}
/* 原 #themeToggle 撤掉后，设置按钮靠右，给台灯留出左下角落 */
.rail__foot{justify-content:flex-end}

/* 全屏主题交叉淡化（盖旧主题 → 罩下翻 data-theme → 淡出；背景与 body 两版逐字一致） */
.themefade{position:fixed;inset:0;z-index:45;pointer-events:none;opacity:0}
.themefade--light{
  background:
    radial-gradient(900px 480px at 50% -8%, rgba(255,255,255,.85), transparent 60%),
    radial-gradient(1100px 700px at 10% 6%, rgba(125,211,252,.26), transparent 60%),
    radial-gradient(920px 660px at 90% 12%, rgba(147,213,255,.24), transparent 62%),
    radial-gradient(760px 560px at 78% 88%, rgba(56,189,248,.13), transparent 64%),
    radial-gradient(1200px 820px at 50% 112%, rgba(125,211,252,.17), transparent 66%),
    radial-gradient(1500px 1050px at 50% 45%, transparent 62%, rgba(120,170,220,.12) 100%),
    linear-gradient(170deg, #FAFDFF 0%, #F2F9FE 50%, #EAF4FD 100%);
  background-attachment:fixed;
}
.themefade--dark{
  background:
    radial-gradient(1000px 520px at 50% -10%, rgba(56,189,248,.14), transparent 60%),
    radial-gradient(1100px 720px at 12% 8%, rgba(14,165,233,.22), transparent 60%),
    radial-gradient(950px 680px at 88% 14%, rgba(56,189,248,.13), transparent 62%),
    radial-gradient(1200px 820px at 50% 108%, rgba(2,132,199,.16), transparent 66%),
    radial-gradient(1500px 1050px at 50% 45%, transparent 58%, rgba(0,0,0,.38) 100%),
    linear-gradient(160deg, #0A1120 0%, #0B1424 50%, #0C1226 100%);
  background-attachment:fixed;
}
@media (prefers-reduced-motion: reduce){.themefade{display:none !important}}

/* 夜空场景（v2.5.38：站长反馈「看不到月亮和星星」——把设计稿的月亮/星星/银河/白云补进正站）
   与台灯同一 progress 驱动（themelamp.js render() 逐帧写入 opacity/transform）。
   pointer-events 全免、aria-hidden、零滤镜（云/月晕全靠径向渐变的天然软边）。
   ── v2.5.42→43：满宽，但 z-index 回到 0 ──
   ① left:0：天空铺满整个视口（brief「全屏沉浸式背景」），不再有侧栏接缝。
   ② z-index 回到 0（v2.5.42 曾改 -1 让场景垫到玻璃后面）：-1 时所有毛玻璃面
      （侧栏 blur 24px + 全站 14 类卡片）的 backdrop-filter 每一帧都要重新模糊
      **正在动的星空**（星星闪/云飘/月晕呼吸）——iPhone Safari 上这是致命伤，
      表现为页面卡死、标签页被系统杀掉（站长实测「进不去 + 卡」）。
      z0 = 场景绘在静态内容之上（v2.5.37~41 跑一整天的 cheap 路径）：
      backdrop-filter 背后只有静态的 body 渐变，合成成本与改前一致。
      代价：星星/云会飘在玻璃表面上（它们本就是高透柔边、pointer-events 全免，
      观感是「整窗都是天空」；台灯 z46/遮罩 z45/弹层 z1000 全部仍在场景之上）。 */
#skyScene{position:fixed;top:0;right:0;bottom:0;left:0;z-index:0;pointer-events:none;overflow:hidden}
.sc-milky{position:absolute;left:-10%;top:-6%;width:120%;height:44%;transform:rotate(-14deg);opacity:0;
  background:linear-gradient(100deg, transparent 22%, rgba(196,210,238,.09) 40%, rgba(216,226,246,.13) 52%, rgba(196,210,238,.09) 64%, transparent 80%)}
.sc-static{position:absolute;inset:0;opacity:0}
.sc-static i{position:absolute;border-radius:50%;background:radial-gradient(circle, #E9F1FF 0%, rgba(200,216,244,.45) 42%, transparent 72%)}
/* 银河星尘：沿带分布的微小尘点（静态，极淡） */
.sc-dust{position:absolute;inset:0;opacity:0}
.sc-dust i{position:absolute;border-radius:50%;background:radial-gradient(circle, #F4F7FF 0%, rgba(214,224,246,.35) 45%, transparent 72%)}
/* 主星：小亮点 + 朦胧光晕（径向渐变软边；闪烁 1↔.25 更像「一闪一闪」） */
.sc-star{position:absolute;border-radius:50%}
.sc-star__tw{position:relative;display:block;width:100%;height:100%;border-radius:50%;animation:scTwinkle 3s ease-in-out infinite}
.sc-star--spark .sc-star__tw::before,.sc-star--spark .sc-star__tw::after{content:"";position:absolute;left:50%;top:50%;opacity:.45;border-radius:1px}
.sc-star--spark .sc-star__tw::before{width:calc(var(--r)*6);height:1px;transform:translate(-50%,-50%);background:linear-gradient(90deg, transparent, rgba(255,255,255,.6), transparent)}
.sc-star--spark .sc-star__tw::after{width:1px;height:calc(var(--r)*6);transform:translate(-50%,-50%);background:linear-gradient(180deg, transparent, rgba(255,255,255,.6), transparent)}
/* v2.5.41：闪烁深度逐星不同（--tw-min 由 JS 按星写入，亮星稳、微星闪） */
@keyframes scTwinkle{0%,100%{opacity:1}50%{opacity:var(--tw-min,.25)}}
/* 地平线残光（夜晚低空的紫罗兰余晖） */
.sc-dusk{position:absolute;left:0;right:0;bottom:0;height:36%;opacity:0;
  background:linear-gradient(180deg, transparent 0%, rgba(96,80,148,.10) 55%, rgba(122,96,164,.15) 100%)}
.sc-moon{position:absolute;right:7%;top:9%;width:88px;aspect-ratio:1/1;opacity:0}
.sc-moon i{position:absolute;display:block}
/* v2.5.41 月亮真实化：双层柔和辉光（外晕大而淡、近冕暖而聚）+ 月海暗斑 + 环形山 + 明暗交界 */
.sc-moon__halo{inset:-78%;border-radius:50%;background:radial-gradient(circle, rgba(248,238,205,.20) 0%, rgba(248,238,205,.06) 44%, transparent 66%)}
.sc-moon__corona{inset:-22%;border-radius:50%;background:radial-gradient(circle, rgba(252,244,214,.5) 0%, rgba(252,244,214,.12) 48%, transparent 68%)}
.sc-moon__disc{inset:0;border-radius:50%;overflow:hidden;background:radial-gradient(circle at 38% 34%, #FFFEF8 0%, #F8F0D6 48%, #E9DBB4 78%, #DCCBA0 100%);
  box-shadow:0 0 34px rgba(250,240,205,.45), inset -12px -14px 30px rgba(160,138,96,.34), inset 4px 6px 12px rgba(255,255,255,.5)}
/* 月海：大片低对比暗斑（风暴洋/雨海/静海的意象），全部极克制 */
.sc-moon__maria{inset:0;border-radius:50%;
  background:
    radial-gradient(36% 30% at 37% 42%, rgba(168,150,116,.20), transparent 72%),
    radial-gradient(28% 26% at 62% 58%, rgba(168,150,116,.16), transparent 72%),
    radial-gradient(20% 18% at 47% 70%, rgba(168,150,116,.13), transparent 72%),
    radial-gradient(16% 15% at 66% 30%, rgba(168,150,116,.11), transparent 72%)}
/* 明暗交界：右下侧柔和阴影，球体立体感 */
.sc-moon__shade{inset:0;border-radius:50%;background:linear-gradient(118deg, transparent 40%, rgba(120,100,140,.09) 70%, rgba(88,74,118,.19) 100%)}
.sc-moon__disc b{position:absolute;border-radius:50%;background:rgba(178,162,124,.16);
  box-shadow:inset 1px 1px 1.5px rgba(140,120,86,.28), inset -0.5px -0.5px 1px rgba(255,252,240,.35)}
.sc-moon__disc b:nth-of-type(1){left:26%;top:30%;width:15%;height:15%;background:rgba(178,162,124,.17)}
.sc-moon__disc b:nth-of-type(2){left:56%;top:52%;width:10%;height:10%}
.sc-moon__disc b:nth-of-type(3){left:42%;top:64%;width:7.5%;height:7.5%;background:rgba(178,162,124,.12)}
.sc-moon__disc b:nth-of-type(4){left:64%;top:36%;width:6%;height:6%;background:rgba(178,162,124,.13)}
.sc-moon__disc b:nth-of-type(5){left:34%;top:52%;width:5%;height:5%;background:rgba(178,162,124,.12)}
.sc-moon__disc b:nth-of-type(6){left:52%;top:24%;width:4%;height:4%;background:rgba(178,162,124,.11)}
.sc-moon__disc b:nth-of-type(7){left:60%;top:70%;width:3.4%;height:3.4%;background:rgba(178,162,124,.10)}
/* ============================================================
   白天模式的太阳（v2.6.23 初版 → v2.6.24 重做 · 站长：「太阳太大了，而且好丑，用你的最高审美」）
   ------------------------------------------------------------
   初版三宗罪（都改掉了，别再犯）：
     ①**太大**：日面 104px、大晕铺到 350px，还压着一层 600px 的暖"天光" —— 右上天空糊成一团黄，
       连卡片都被染黄。太阳的"大"应该由**光晕**表达，不该由球体尺寸表达。
     ②**太脏**：光芒用硬边 repeating-conic-gradient（2.4° 实色 → 13° 透明），小尺寸下就是一圈锯齿脏斑。
     ③**太像贴纸**：高饱和橙黄 + 三团米粒暖斑，在清透的天蓝玻璃站里显廉价。
   重做原则：**小而干净、克制而暖** ——
     日面 68px（比月亮 88px 更小）；删掉"天光"与"米粒斑"两层；
     光芒改成 **12 瓣平滑三角波**（每瓣 0 → .085 → 0，没有硬边），再被径向遮罩切成窄环；
     大晕只留很淡的一圈、呼吸幅度也收小。
     颜色从"橙黄"退到**暖象牙 → 淡金收边**（核心近白、只有边缘显金）—— 读起来是"晨光"而不是 emoji。
   --sun-o 由 JS 跟着昼夜进度写进来：光芒层的固有淡度乘上它，入夜随透明度一起收干净。 */
.sc-sun{position:absolute;right:8%;top:1.2%;width:68px;aspect-ratio:1/1;opacity:0;--sun-o:1}
.sc-sun i{position:absolute;display:block}
/* 大气散射：三层同心、过渡刻意拉长（越外越淡）—— 只做"光"，不做色块 */
.sc-sun__halo{inset:-168%;border-radius:50%;animation:scSunBreath 10s ease-in-out infinite;
  background:radial-gradient(circle,
    rgba(255,244,216,.22) 0%,
    rgba(255,240,208,.11) 30%,
    rgba(255,238,206,.04) 56%,
    transparent 74%)}
/* 光芒：12 瓣、每瓣平滑进出（0 → .085 → 0），没有硬边；遮罩只留 45%~80% 那一圈 */
.sc-sun__rays{inset:-52%;border-radius:50%;opacity:calc(var(--sun-o) * .5);
  background:repeating-conic-gradient(from 4deg,
    rgba(255,246,222,0) 0deg, rgba(255,246,222,.085) 5deg, rgba(255,246,222,0) 13deg, rgba(255,246,222,0) 30deg);
  -webkit-mask-image:radial-gradient(circle, transparent 45%, #000 56%, #000 66%, transparent 80%);
  mask-image:radial-gradient(circle, transparent 45%, #000 56%, #000 66%, transparent 80%);
  animation:scSunRays 300s linear infinite}
/* 暖光冠：紧贴日面的一圈暖，把球体"烘"进天空 */
.sc-sun__corona{inset:-46%;border-radius:50%;
  background:radial-gradient(circle, rgba(255,250,236,.62) 0%, rgba(255,240,200,.26) 44%, transparent 72%)}
/* 日面：核心近白、边缘收金；上左受光 + 边缘减光（球体感）；**没有米粒斑**（小尺寸下只会变脏） */
.sc-sun__disc{inset:0;border-radius:50%;
  background:radial-gradient(circle at 40% 36%,
    #FFFEF8 0%, #FFF8E2 34%, #FFEDC2 62%, #FFDF9E 84%, #F4CB84 100%);
  box-shadow:
    0 0 14px rgba(255,232,172,.5),
    0 0 34px rgba(255,224,152,.22),
    inset 0 -1.5px 5px rgba(226,168,80,.26),
    inset 2px 3px 6px rgba(255,255,255,.8)}
@keyframes scSunBreath{0%,100%{transform:scale(1);opacity:.94}50%{transform:scale(1.028);opacity:1}}
@keyframes scSunRays{to{transform:rotate(360deg)}}
@media (max-width:920px){.sc-sun{width:52px}}

/* v2.5.41 修复云朵截断：旧版固定 height:64px + px 尺寸渐变，背景被元素盒子硬裁
   （顶部 -7px、底部 +6px、小云左右更被 120px 半径的底层渐变切平）。
   现改「等比盒子 + 百分比半径渐变」：形状随宽度缩放，所有渐变可见区都在盒内，零截断 */
.sc-cloud{position:absolute;aspect-ratio:2.5}
/* 横贯式漂移（v2.5.39）：左屏外(-45vw)入、右屏外(90vw)出，linear 匀速 + 三个航点轻微上下浮动；
   端点 opacity 0↔1 掩住循环跳变；与 JS 昼夜窗口、云体固有淡度三层相乘 */
.sc-cloud__drift{width:100%;height:100%;animation:scTraverse 140s linear infinite}
@keyframes scTraverse{
  0%{transform:translate3d(-45vw,0,0);opacity:0}
  7%{opacity:1}
  30%{transform:translate3d(-4.5vw,-5px,0)}
  55%{transform:translate3d(29vw,2px,0)}
  80%{transform:translate3d(63vw,-3px,0)}
  93%{opacity:1}
  100%{transform:translate3d(90vw,0,0);opacity:0}
}
.sc-cloud i{display:block;width:100%;height:100%;
  background:
    radial-gradient(26% 46% at 30% 58%, rgba(255,255,255,.96), transparent 72%),
    radial-gradient(30% 56% at 52% 42%, rgba(255,255,255,.96), transparent 72%),
    radial-gradient(24% 42% at 72% 58%, rgba(255,255,255,.92), transparent 72%),
    radial-gradient(44% 50% at 50% 40%, rgba(255,255,255,.5), transparent 75%),
    radial-gradient(52% 38% at 50% 72%, rgba(176,205,235,.85), transparent 72%)}
/* 亮星呼吸式星芒脉冲（scale 连带光晕一起呼吸） */
.sc-star--spark .sc-star__tw{animation:scTwinkle 3s ease-in-out infinite, scSparkPulse 4.8s ease-in-out infinite}
@keyframes scSparkPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.25)}}
/* 月晕缓慢呼吸 */
.sc-moon__halo{animation:scHalo 7s ease-in-out infinite}
@keyframes scHalo{0%,100%{transform:scale(1);opacity:.85}50%{transform:scale(1.05);opacity:1}}
/* 流星：亮头在前拖尾在后，rotate(-33deg) 沿轴向自右上向左下划过 */
.sc-meteor{position:absolute;height:2px;border-radius:2px;opacity:0;transform:rotate(-33deg);
  background:linear-gradient(90deg, rgba(255,255,255,.95) 0%, rgba(210,226,250,.5) 25%, transparent 75%)}
.sc-meteor::after{content:"";position:absolute;left:-2px;top:-1.5px;width:5px;height:5px;border-radius:50%;
  background:#FFF;box-shadow:0 0 8px 2px rgba(255,255,255,.75)}
.sc-meteor.is-go{animation:scMeteor 1.15s cubic-bezier(.32,.42,.58,1) forwards}
@keyframes scMeteor{
  0%{opacity:0;transform:rotate(-33deg) translateX(0)}
  12%{opacity:1}
  68%{opacity:.9}
  100%{opacity:0;transform:rotate(-33deg) translateX(-52vw)}
}
@media (max-width:920px){.sc-moon{width:64px}}
@media (prefers-reduced-motion: reduce){
  .sc-star__tw,.sc-cloud__drift,.sc-moon__halo,.sc-sun__halo,.sc-sun__rays,.sc-meteor{animation:none !important}
}

/* ============================================================
   句子工具 / 长难句讲解 / 句子批注 / 句子收藏（v2.5.49；v2.5.51 重做交互）
   ------------------------------------------------------------
   ⚠️ v2.5.49 第一版的三个体验硬伤（站长反馈「好多 bug」，对抗测试也印证了）：
     ① 点句子就弹工具条 —— 阅读时随手一点就冒出浮层盖住正文，且没有关闭按钮；
     ② 点句子不再能朗读（工具条抢了点击优先级），把站里原有的便利弄丢了；
     ③ 批注标记只是右上角一个小点，right:-7px 压在字上、句子换行时会被切掉。
   现在的做法（阅读优先）：
     · 正文里**悬停**句子 → 左侧留白浮现一个小笔图标；**点它**才开面板（`.sentgutter`）。
       不再劫持句子点击 ⇒ 点句子仍然只是「选中这句」，朗读条展开时照旧点句朗读。
     · 面板改成**右滑式侧栏**（不是居中弹窗）—— 句子在上、批注/讲解在下，同屏可见，
       这才是 WPS 批注的用法：看着句子写批注。
     · 批注标记改为**左侧竖色条**（像 WPS 的批注锚点），不压字、不受换行影响；
       收藏仍是虚线下划（这个语义合适，保留）。
   ============================================================ */

/* ---- 小笔图标（v2.5.55 最终版：**内联跟在句子末尾**）----
   ⚠️ 为什么放弃「贴边留白」这条路：实测三种视口的可用边距 ——
      1280：左 58（我特意留的）/ 右 142；820：左 **0** / 右 30；390：左 **0** / 右 30。
      窄屏两条边都不够放一个 24px 的按钮；而且手机那条 `left:2px` 的老规则会与
      新写的 `right:-30px` **同时生效**（浏览器把 left/right 都算进去），把小笔直接拉进正文里
      —— 这就是"批注标志挡到文本"的真根因（计算样式里 left 与 right 并存可证）。
   与其继续在边距上打补丁，不如把图标放进句内：`inline-block` 跟在句号之后，
   **任何设备、任何宽度都不会压到文字**，而且"点它"天然就是"点这一句"，手机也好点。
   形态：小圆点芯片（铅笔 SVG）；正文里密度高，所以手机压到 .5 透明度、更小更淡，
   悬停 / 已选中 / 已批注时完全显形。 */
.sentgutter{position:relative;display:inline-block;width:20px;height:20px;margin:0 2px;
  border-radius:50%;vertical-align:-3px;cursor:pointer;padding:0;
  background:rgba(255,255,255,.9);
  border:1px solid rgba(56,189,248,.55);
  color:#0B72A8;
  box-shadow:0 1px 3px -1px rgba(12,74,124,.35);
  /* v2.6.1（站长：「电脑端把那个批注的笔改为只在鼠标移动到句子上时显示」）：
     默认**完全隐形**（旧版是 .45 半透明常显）。pointer-events 一起关掉 ——
     隐形却仍可点，等于在正文里埋了一圈看不见的按钮，鼠标划过句末可能误触。 */
  opacity:0;
  pointer-events:none;
  transition:opacity .16s ease,transform .16s ease,background .16s ease,color .16s ease,box-shadow .16s ease}
/* 显形的四种情形：悬停这一句 / 已批注（站长选「金笔 + 角标常显」）/ 面板正开在这句 / 键盘聚焦 */
#readerBody .sent:hover .sentgutter,
#readerBody .sent.is-noted .sentgutter,
#readerBody .sent.is-picked .sentgutter,
.sentgutter:focus-visible{opacity:1;pointer-events:auto;transform:none}
.sentgutter:hover{background:linear-gradient(135deg,#38BDF8,#4F8DF7);color:#fff;
  border-color:transparent;transform:scale(1.16);
  box-shadow:0 4px 12px -4px rgba(12,74,124,.6)}
.sentgutter svg{width:13px;height:13px;overflow:visible;display:block;margin:0 auto}
[data-theme="dark"] .sentgutter{background:rgba(20,40,62,.9);color:#7DD3FC;
  border-color:rgba(125,211,252,.5);box-shadow:0 1px 4px -1px rgba(0,0,0,.5)}
[data-theme="dark"] .sentgutter:hover{background:linear-gradient(135deg,#38BDF8,#4F8DF7);color:#fff}
#readerBody .sent.is-noted .sentgutter{background:linear-gradient(135deg,#F4C97A,#E0A64B);
  border-color:transparent;color:#3A2A08;opacity:1;
  box-shadow:0 1px 4px -1px rgba(150,105,20,.55), 0 0 0 2px rgba(224,166,75,.22)}
[data-theme="dark"] #readerBody .sent.is-noted .sentgutter{background:linear-gradient(135deg,#F4C97A,#E0A64B);color:#3A2A08}
/* 句末芯片的左右留白（v2.5.57）：左侧 3px 让铅笔离开句号（旧版 2px 几乎贴着 `.`），
   右侧保持 2px —— 芯片是 inline-block，右侧就是它与下一句之间的那道缝。 */
#readerBody .sent .sentgutter{margin:0 2px 0 3px}
/* 系统「减弱动态效果」：不做放大动画 */
@media (prefers-reduced-motion: reduce){ .sentgutter, .sentgutter:hover{transform:none} }
/* 手机 / 触屏（v2.6.1 站长要求「手机端改为点击句子中单词时，在单词卡中显示」）：
   **不再有句末小笔** —— 触屏没有 hover，而常显的小圆点在手机上又密又分心；
   批注入口搬到单词卡里那颗 `.wordcard__note` 上（点单词 → 卡里点它 → 开面板）。
   元素仍留在 DOM 里（自检脚本与 sentIndexOf 的序号对齐都依赖它），只是 display:none。 */
@media (hover: none), (max-width:820px){
  .sentgutter{display:none}
  .wordcard__note{display:flex}
}
/* 句子自身作为定位参照（批注锚点用；小笔已改为内联，不再依赖它做绝对定位） */
#readerBody .sent{position:relative;scroll-margin-top:70px}

/* ---- 句子的状态表达（v2.5.54 强化「醒目」）----
   站长要「醒目方便」：旧版已批注的句子只有一条 2px 金色左竖条 + 金色小笔，
   在长段落里仍然容易划过去。现在给整句**淡金色底 + 左侧渐变竖条 + 小笔上的批注数角标**，
   三处同时提示，扫一眼就能看出哪句写过；hover 再加深一档。 */
#readerBody .sent.is-pinned{border-bottom:1.5px dashed rgba(56,189,248,.7);cursor:pointer}
#readerBody .sent.is-noted{
  background:linear-gradient(90deg, rgba(244,201,122,.22), rgba(244,201,122,.07) 62%, transparent);
  padding:2px 6px 2px 8px;border-radius:0 6px 6px 0;
  box-shadow:inset 3px 0 0 0 rgba(224,166,75,.95)}
#readerBody .sent.is-noted:hover{
  background:linear-gradient(90deg, rgba(244,201,122,.3), rgba(244,201,122,.1) 62%, transparent)}
[data-theme="dark"] #readerBody .sent.is-noted{
  background:linear-gradient(90deg, rgba(224,166,75,.22), rgba(224,166,75,.06) 62%, transparent)}
#readerBody .sent.is-picked{background:rgba(56,189,248,.14);border-radius:6px}
#readerBody .sent.is-picked.is-noted{background:linear-gradient(90deg, rgba(244,201,122,.28), rgba(56,189,248,.16))}
/* 小笔上的批注数角标：一条批注显示 ●，多条显示数字 */
.sentgutter__n{position:absolute;right:-5px;top:-5px;min-width:13px;height:13px;padding:0 3px;
  border-radius:999px;background:linear-gradient(135deg,#F4C97A,#DFA33F);color:#3A2A08;
  font-size:9.5px;line-height:13px;font-weight:700;text-align:center;
  box-shadow:0 1px 3px rgba(120,80,10,.45);pointer-events:none}
[data-theme="dark"] .sentgutter__n{color:#2A1D05}

/* ---- 右滑式面板（替代居中弹窗） ---- */
.ssheet{position:fixed;z-index:1000;top:0;right:0;height:100%;width:min(460px,94vw);
  display:flex;flex-direction:column;
  background:var(--sky-panel,rgba(255,255,255,.94));
  border-left:1px solid var(--glass-brd,rgba(125,211,252,.6));
  box-shadow:-26px 0 60px -30px rgba(12,44,72,.55);
  backdrop-filter:blur(22px) saturate(1.7);-webkit-backdrop-filter:blur(22px) saturate(1.7);
  animation:ssheetIn .28s cubic-bezier(.22,.7,.3,1);padding:16px 18px calc(16px + env(safe-area-inset-bottom,0px))}
@keyframes ssheetIn{from{transform:translateX(102%)}to{transform:none}}
.ssheet.is-out{animation:ssheetOut .22s ease forwards}
@keyframes ssheetOut{to{transform:translateX(102%);opacity:.6}}
[data-theme="dark"] .ssheet{background:rgba(14,28,46,.95)}
/* 面板标题行：左边标出「这一句」，右边是「上一句 / 下一句 / 关闭」—— 长文里逐句看批注不用来回滚 */
.ssheet__hd{display:flex;align-items:center;gap:8px;flex:0 0 auto;padding-bottom:10px}
.ssheet__who{display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:650;color:var(--ink,#123);
  letter-spacing:.02em}
.ssheet__who i{width:8px;height:8px;border-radius:50%;background:linear-gradient(135deg,#F4C97A,#DFA33F);
  box-shadow:0 0 0 3px rgba(224,166,75,.18)}
.ssheet__nav{margin-left:auto;display:flex;gap:4px;align-items:center}
.ssheet__nb{font:inherit;font-size:12.5px;width:30px;height:30px;border:0;border-radius:9px;cursor:pointer;
  background:rgba(148,163,184,.14);color:var(--muted,#5b6c82);display:flex;align-items:center;justify-content:center}
.ssheet__nb:hover{background:rgba(56,189,248,.2);color:var(--accent-ink,#0B5C86)}
.ssheet__nb:disabled{opacity:.35;cursor:default}
.ssheet__tabs{position:relative;display:flex;gap:4px;align-items:center;padding-bottom:10px;flex:0 0 auto;
  border-bottom:1px dashed var(--line-2,rgba(148,163,184,.35))}
/* 滑动药丸（v2.6.2）：整条页签只有这一块渐变胶囊，切页签时它**滑**过去，而不是各自跳一下。
   位置 / 尺寸由 JS（paintTabInk）按当前选中页签量出来写进 style，这里只管外观与过渡。
   ⚠️ 只动 transform / width，不加滤镜、不加新模糊层 —— 守站里 `v2.5.0 / v2.5.43` 的性能约束。 */
.ssheet__ink{position:absolute;left:0;top:0;width:0;height:0;border-radius:999px;
  background:linear-gradient(135deg,#38BDF8,#6366F1);
  box-shadow:0 4px 12px -6px rgba(56,120,248,.65), inset 0 1px 0 rgba(255,255,255,.35);
  /* 位移走 0.36s 的弹性曲线；宽度只给 0.2s —— 切页签时药丸先「撑开」再滑到位，
     而页签文案里计数变化（批注 • / 收藏 · 3）时宽度能立刻跟上文字，不会出现
     「字已经变宽、药丸还窄着一截」的空档（白字落在浅色面板上会看不见）。 */
  transition:transform .36s cubic-bezier(.34,1.06,.36,1), width .2s ease, height .2s ease;
  will-change:transform,width;pointer-events:none}
.ssheet__ink.is-instant{transition:none}     /* 首帧落位 / 窗口尺寸变化：不播滑动 */
.ssheet__tab{position:relative;z-index:1;
  font:inherit;font-size:12.5px;padding:7px 12px;border:0;border-radius:999px;cursor:pointer;
  background:transparent;color:var(--muted,#5b6c82);
  /* 文字变色故意**滞后**约 .14s：药丸还在路上时，旧页签别急着变灰、新页签也别急着变白
     （白字落在浅色面板上会闪一下看不见），等药丸基本到位再一起换色。 */
  transition:color .16s ease .14s}
.ssheet__tab:not(.is-on):hover{background:rgba(56,189,248,.14)}
.ssheet__tab.is-on{color:#fff;font-weight:650}
.ssheet__x{margin-left:auto;font:inherit;font-size:13px;width:30px;height:30px;border:0;border-radius:9px;
  background:rgba(148,163,184,.14);color:var(--muted,#5b6c82);cursor:pointer;flex:0 0 auto}
.ssheet__x:hover{background:rgba(148,163,184,.26);color:var(--ink,#123)}
/* 内容层：装在一个相对定位的容器里，两层内容绝对定位叠起来做交叉淡化（v2.6.2）。
   为什么要叠：切页签时旧内容要「边淡出边往反方向退」、新内容同时滑入 —— 两个动作必须同屏发生。
   旧版是先把旧内容整块删掉、再让新内容滑入，中间那一帧是空的，看着就是「闪一下」。 */
.ssheet__bodywrap{position:relative;flex:1 1 auto;min-height:0;overflow:hidden}
.ssheet__body{position:absolute;inset:0;z-index:1;overflow:auto;-webkit-overflow-scrolling:touch;padding-top:12px}
/* 进场：按页签顺序滑入（新内容 z-index 更高，压在上层） */
.ssheet__body.is-anim-next{animation:spInNext .3s cubic-bezier(.2,.72,.24,1) both;z-index:2}
.ssheet__body.is-anim-prev{animation:spInPrev .3s cubic-bezier(.2,.72,.24,1) both;z-index:2}
/* 非切页签的重绘（保存批注 / 收藏切换 / 上一句下一句）：只做一次很轻的淡入 */
.ssheet__body.is-anim-soft{animation:spInSoft .22s ease both;z-index:2}
/* 退场：旧内容向反方向退并淡出 —— 点右边页签时旧内容向左退，与新的滑入合成一次连贯位移 */
.ssheet__body.is-leave-left{animation:spLeaveLeft .26s cubic-bezier(.4,0,.6,1) both;pointer-events:none}
.ssheet__body.is-leave-right{animation:spLeaveRight .26s cubic-bezier(.4,0,.6,1) both;pointer-events:none}
.ssheet__body.is-leave-soft{animation:spLeaveSoft .22s ease both;pointer-events:none}
@keyframes spInNext{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
@keyframes spInPrev{from{opacity:0;transform:translateX(-24px)}to{opacity:1;transform:none}}
@keyframes spInSoft{from{opacity:0}to{opacity:1}}
@keyframes spLeaveLeft{from{opacity:1;transform:none}to{opacity:0;transform:translateX(-16px)}}
@keyframes spLeaveRight{from{opacity:1;transform:none}to{opacity:0;transform:translateX(16px)}}
@keyframes spLeaveSoft{from{opacity:1}to{opacity:0}}
@media (prefers-reduced-motion: reduce){
  /* 系统开了「减弱动态效果」：不做位移，直接换内容（功能一样，只是不晃） */
  .ssheet__ink{transition:none}
  .ssheet__body.is-anim-next,.ssheet__body.is-anim-prev,.ssheet__body.is-anim-soft,
  .ssheet__body.is-leave-left,.ssheet__body.is-leave-right,.ssheet__body.is-leave-soft{animation:none}
}
.ssheet__none{font-size:13px;line-height:2;color:var(--muted,#5b6c82);padding:18px 4px;text-align:center}
/* 面板顶部固定显示「正在批注的那一句」——句子与批注同屏，这才是 WPS 的用法 */
.ssheet__sent{flex:0 0 auto;font-size:13px;line-height:1.95;color:var(--ink,#123);
  padding:10px 12px;margin-bottom:2px;border-radius:12px;background:rgba(56,189,248,.12);
  border-left:3px solid rgba(56,189,248,.8);max-height:7.2em;overflow:auto}
[data-theme="dark"] .ssheet__sent{background:rgba(56,189,248,.12)}
/* 面板内的收藏开关：小胶囊，压在句子右上角（不抢正文、不占一行） */
.sp-pintoggle{display:block;margin:8px 0 0;font:inherit;font-size:11.5px;padding:4px 10px;border-radius:999px;
  cursor:pointer;border:1px solid rgba(125,211,252,.8);background:rgba(255,255,255,.7);color:#0B5C86;
  transition:background .16s ease,color .16s ease}
.sp-pintoggle:hover{background:#fff}
.sp-pintoggle.is-on{background:linear-gradient(135deg,#F4C97A,#E0A64B);border-color:transparent;color:#3A2A08;font-weight:650}
[data-theme="dark"] .sp-pintoggle{background:rgba(255,255,255,.14);color:#CFE7FF}
[data-theme="dark"] .sp-pintoggle.is-on{background:linear-gradient(135deg,#F4C97A,#E0A64B);color:#3A2A08}

/* ---- 长难句讲解 ---- */
.sp-stars{font-size:12.5px;color:#E0A64B;letter-spacing:.08em;margin-bottom:10px}
.sp-anno{font-size:15.5px;line-height:2.15;color:var(--ink,#123);letter-spacing:.01em;
  padding:14px 16px;border-radius:14px;background:rgba(255,255,255,.55);
  border:1px solid rgba(125,211,252,.4)}
[data-theme="dark"] .sp-anno{background:rgba(12,26,44,.5);border-color:rgba(125,211,252,.22)}
.sp-m{border-radius:4px;padding:1px 1px;background:transparent;color:inherit;cursor:help}
.sp-anno .sp-c0{background:rgba(56,189,248,.22)}
.sp-anno .sp-c1{background:rgba(244,201,122,.28)}
.sp-anno .sp-c2{background:rgba(94,234,212,.24)}
.sp-anno .sp-c3{background:rgba(165,180,252,.26)}
.sp-anno .sp-c4{background:rgba(251,182,206,.26)}
.sp-anno .sp-c5{background:rgba(190,242,100,.22)}
.sp-frame{font-size:13px;line-height:2;margin:12px 0 4px;color:var(--ink,#123)}
.sp-frame code{font-family:var(--f-mono,ui-monospace,monospace);font-size:12.5px;
  background:rgba(56,189,248,.16);border-radius:6px;padding:2px 6px}
.sp-chunks{list-style:none;margin:12px 0 0;padding:0;counter-reset:none}
.sp-chunks li{font-size:12.5px;line-height:1.85;color:var(--muted,#5b6c82);padding:8px 0 8px 0;
  border-top:1px dashed var(--line-2,rgba(148,163,184,.3))}
.sp-chunks li b{color:var(--ink,#123)}
.sp-chunks li div{margin-top:3px;color:var(--faint,#8498ae);word-break:break-word}
.sp-legend{margin-top:14px}
.sp-legend__i{font-size:12.5px;line-height:1.9;padding:9px 0;border-top:1px dashed var(--line-2,rgba(148,163,184,.28))}
.sp-legend__i i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:8px;vertical-align:-1px}
.sp-legend__i i.sp-c0{background:rgba(56,189,248,.5)}
.sp-legend__i i.sp-c1{background:rgba(244,201,122,.6)}
.sp-legend__i i.sp-c2{background:rgba(94,234,212,.55)}
.sp-legend__i i.sp-c3{background:rgba(165,180,252,.6)}
.sp-legend__i i.sp-c4{background:rgba(251,182,206,.6)}
.sp-legend__i i.sp-c5{background:rgba(190,242,100,.5)}
.sp-legend__i b{color:var(--ink,#123);margin-right:6px}
.sp-legend__i span{color:var(--muted,#5b6c82);display:block;margin:3px 0 0 18px;word-break:break-word}
.sp-legend__i em{display:block;margin:4px 0 0 18px;font-style:normal;font-size:12px;color:var(--faint,#8498ae)}
.sp-phr{font-family:var(--f-mono,ui-monospace,monospace);font-size:13px;color:var(--accent-ink,#0B5C86)}
.sp-addv{margin:6px 0 0 18px}
/* 批注页：标题行 + 大文本框 + 保存按钮沉底（手指够得着，且不跟键盘抢位） */
.sp-note{display:flex;flex-direction:column;min-height:100%}
.sp-note__lbl{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted,#5b6c82);margin:0 0 8px}
.sp-note__lbl i{width:7px;height:7px;border-radius:50%;background:linear-gradient(135deg,#F4C97A,#DFA33F)}
.sp-note textarea{width:100%;padding:14px 15px;font-size:14px;line-height:1.95;min-height:190px;resize:vertical;
  background:linear-gradient(170deg,rgba(255,255,255,.9),rgba(255,250,240,.78));
  border:1px solid rgba(224,166,75,.5);border-radius:14px}
.sp-note textarea:focus{outline:none;border-color:rgba(224,166,75,.9);
  box-shadow:0 0 0 3px rgba(224,166,75,.16)}
[data-theme="dark"] .sp-note textarea{background:rgba(24,34,50,.85);border-color:rgba(224,166,75,.4);color:#EAF2FB}
.sp-note__ft{display:flex;gap:8px;margin-top:auto;padding-top:14px}
.sp-note__ft .btn{flex:1 1 auto}
.sp-note__meta{font-size:11.5px;color:var(--faint,#8498ae);margin-top:10px;text-align:right}
.sp-note code{font-family:var(--f-mono,ui-monospace,monospace);font-size:12px;
  background:rgba(56,189,248,.14);border-radius:5px;padding:1px 5px}
.sp-pins{display:flex;flex-direction:column;gap:10px}
.sp-pin{position:relative;padding:12px 14px 12px 34px;border-radius:12px;
  background:rgba(255,255,255,.55);border:1px solid rgba(125,211,252,.4)}
[data-theme="dark"] .sp-pin{background:rgba(12,26,44,.5);border-color:rgba(125,211,252,.22)}
.sp-pin__no{position:absolute;left:10px;top:12px;font-size:11px;color:var(--faint,#8498ae)}
.sp-pin p{font-size:13px;line-height:1.95;color:var(--ink,#123);margin:0 0 8px}
.sp-pin .btn{margin-right:6px}
@media (max-width:920px){
  /* v2.6.2：内容层改成绝对定位填满 .ssheet__bodywrap 后，这里原来的 max-height 已无意义
     （高度由容器决定），留着只会让人以为还有另一条高度规则 */
  .sp-anno{font-size:15px;line-height:2}
  .sentbar button{padding:9px 10px;font-size:12px}
}
/* 手机：面板改为**底部抽屉**（上滑出现，高度 76vh）—— 比整屏侧栏更顺手，拇指够得到，
   也让上方的句子仍然可见（批注时能看着句子写）。 */
@media (max-width:700px){
  .ssheet{top:auto;bottom:0;left:0;right:0;width:auto;height:76vh;
    border-left:0;border-top:1px solid var(--glass-brd,rgba(125,211,252,.6));
    border-radius:20px 20px 0 0;
    box-shadow:0 -22px 54px -26px rgba(12,44,72,.55);
    animation:ssheetUp .3s cubic-bezier(.22,.7,.3,1)}
  .ssheet.is-out{animation:ssheetDown .24s ease forwards}
  @keyframes ssheetUp{from{transform:translateY(102%)}to{transform:none}}
  @keyframes ssheetDown{to{transform:translateY(102%);opacity:.6}}
  /* 抽屉顶部的抓手条，提示「可以下滑关掉」 */
  .ssheet::before{content:"";position:absolute;left:50%;top:8px;width:42px;height:4px;margin-left:-21px;
    border-radius:2px;background:rgba(148,163,184,.5)}
  .ssheet{padding-top:22px}
  .sp-note textarea{min-height:150px}
}

/* ============================================================
   番茄钟 · 飘云休息提醒（v2.5.48，站长要求「时间到了过后，天上飘来一朵云朵，提醒休息」）
   沿用站内已有的云笔法，不新增滤镜层：
     · 云体 5 层百分比 radial-gradient 软边（与 .sc-cloud i / .intro .cl 同一配方）
     · 横贯位移 + 三航点轻微上下浮动（与 @keyframes scTraverse 同一节奏感）
     · 动画只走 transform / opacity（不触发布局，手机不卡）
   入场：云从屏幕左侧外飘入 → 停在画面中上 → 停留数秒（可点任意处提前收起）→ 向右飘出并淡出。
   #restVeil 负责呼吸式明暗与轻微柔化（backdrop-filter 一层，挂载期间才有）；点 veil / 按钮 / Esc 均可关闭。
   ⚠️ 与 `.clouds`（阅读页云层）、`.sc-cloud`（夜空场景云）、`.intro .cl`（开场云）三套笔法同源但类名独立，
      互不干扰 —— 这也是站里一直遵守的约定。 */
#restVeil{position:fixed;inset:0;z-index:60;display:none;overflow:hidden;
  pointer-events:none;
  opacity:1;transition:opacity .5s ease}
#restVeil.is-on{display:block;pointer-events:auto}
#restVeil.is-fading{opacity:0}
/* ⚠️ 出图核对（2026-09-23）后的两次修正：
   第一版遮罩是浅天蓝 → 白云在亮毛玻璃上完全没明度差（截图里只剩文案在飘）；
   第二版压到 slate .34~.50 → 像素实测「云 vs 页面蓝底」差 84/189 已达标，但云一旦压在
   **白色卡片**上，局部对比仍然不够。故再压深一档（白天 .52~.64、夜晚 .62~.74），
   让白色底衬也被压下去，白云在全页面都能立住。 */
#restVeil::before{content:"";position:absolute;inset:0;
  background:radial-gradient(120% 82% at 50% 40%, rgba(30,62,96,.5), rgba(24,54,86,.58) 46%, rgba(18,44,74,.66) 100%);
  backdrop-filter:blur(7px) saturate(1.12);-webkit-backdrop-filter:blur(7px) saturate(1.12);
  opacity:0;animation:restVeil .95s cubic-bezier(.2,.6,.3,1) .18s forwards}
@keyframes restVeil{from{opacity:0}to{opacity:1}}

/* 云：外层负责淡入淡出与缩放，内层负责上下呼吸（与站内「一层管一件事」的写法一致） */
.rest-cloud{position:absolute;left:50%;top:0;display:block;
  width:min(74vw,620px);aspect-ratio:2.5;margin-top:31vh;
  transform:translate3d(-132%,0,0);opacity:0;
  will-change:transform,opacity}
.rest-cloud__bob{display:block;width:100%;height:100%;animation:restBob 6.4s ease-in-out infinite}
/* 云体：5 层百分比 radial-gradient —— 与 .sc-cloud i 同一配方。
   下缘那层（第 5 层）是云「坐在」天光上的体积来源，这里比夜空云更重一些。 */
.rest-cloud i{display:block;width:100%;height:100%;
  background:
    radial-gradient(26% 46% at 30% 58%, rgba(255,255,255,1), transparent 72%),
    radial-gradient(30% 56% at 52% 42%, rgba(255,255,255,1), transparent 72%),
    radial-gradient(24% 42% at 72% 58%, rgba(255,255,255,.98), transparent 72%),
    radial-gradient(44% 50% at 50% 40%, rgba(255,255,255,.7), transparent 75%),
    radial-gradient(52% 40% at 50% 74%, rgba(168,201,234,.92), transparent 72%)}
@keyframes restBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-11px)}}

/* 云上文案：与云同组，随云一起进场、一起离场（压在云的亮部上，用深蓝字 + 冷调光晕） */
.rest-cloud__msg{position:absolute;left:0;right:0;top:34%;z-index:2;margin:0;text-align:center;
  font-family:var(--f-display);font-size:clamp(19px,3.4vw,27px);font-weight:800;letter-spacing:.045em;
  color:#0E3A57;text-shadow:0 1px 0 rgba(255,255,255,.95), 0 6px 20px rgba(180,214,245,.9)}
.rest-cloud__sub{position:absolute;left:0;right:0;top:calc(34% + 40px);z-index:2;margin:0;text-align:center;
  font-size:12.5px;letter-spacing:.1em;color:#40607E;text-shadow:0 1px 0 rgba(255,255,255,.95)}
.rest-cloud__ctl{position:absolute;left:0;right:0;top:calc(34% + 78px);z-index:2;text-align:center}
.rest-cloud__btn{font-size:12.5px;padding:7px 20px;border-radius:999px;cursor:pointer;
  color:#0B5C86;background:rgba(255,255,255,.9);border:1px solid rgba(125,211,252,.95);
  box-shadow:0 8px 20px -10px rgba(12,44,72,.75);transition:background .22s ease,transform .18s ease}
.rest-cloud__btn:hover{background:#FFF;transform:translateY(-1px)}

/* 整场编排：0.95s 飘入落位 → 中段停住（云内文案一直可见）→ 末尾 1.15s 向右飘出并淡出 */
#restVeil.is-on .rest-cloud{animation:restCloudIn .95s cubic-bezier(.22,.68,.3,1) forwards, restCloudOut 1.15s cubic-bezier(.45,0,.55,1) forwards}
#restVeil.is-on .rest-cloud{animation-delay:0s, calc(var(--rest-hold, 7.2s))}
@keyframes restCloudIn{
  0%{transform:translate3d(-132%,14px,0) scale(.9);opacity:0}
  55%{opacity:1}
  100%{transform:translate3d(-50%,0,0) scale(1);opacity:1}
}
@keyframes restCloudOut{
  0%{transform:translate3d(-50%,0,0) scale(1);opacity:1}
  100%{transform:translate3d(52%,-16px,0) scale(1.04);opacity:0}
}
/* 暗色主题：底子更暗（白云才立得住），文案与按钮保持浅色以免糊在云上 */
[data-theme="dark"] #restVeil::before{
  background:radial-gradient(120% 82% at 50% 40%, rgba(10,22,38,.52), rgba(8,18,32,.58) 50%, rgba(5,12,24,.64) 100%)}
[data-theme="dark"] .rest-cloud__msg{color:#0B2740;text-shadow:0 1px 0 rgba(255,255,255,.95), 0 6px 22px rgba(150,190,235,.85)}
[data-theme="dark"] .rest-cloud__sub{color:#33526E;text-shadow:0 1px 0 rgba(255,255,255,.9)}
[data-theme="dark"] .rest-cloud__btn{color:#0B3A57;background:rgba(255,255,255,.94);border-color:rgba(186,230,253,.95)}

/* 系统「减弱动态效果」：不飘不闪，直接静态显示，再点任意处收起（不牺牲功能） */
@media (prefers-reduced-motion: reduce){
  #restVeil::before{animation:none;opacity:1}
  #restVeil.is-on .rest-cloud{animation:none;transform:translate3d(-50%,0,0);opacity:1}
  .rest-cloud__bob{animation:none}
}

/* ============================================================
   页脚 · 备案信息（v2.5.60 · 2026-09-24 自有域名备案通过后新增；
                    v2.6.33 · 2026-10-24 追加公安备案号）
   ------------------------------------------------------------
   合规要求：境内网站首页底部要展示 ICP 备案号（链工信部查询页）与公安备案号
             （链全国互联网安全管理服务平台查询页），两枚并列、都要能点开核验。
   做法：
     ① `.main` 改竖向 flex —— 让页脚能用 `margin-top:auto` 贴住页面底部，
        内容不足一屏时（如会员页）也落在底部，不会浮在屏幕中间；
        `.main` 的两个既有职责（overflow-y:auto 滚动、绝对定位后代锚点）不受影响。
     ⚠️ 必须配套下面那条 `.view{width:100%;min-width:0}` —— 2026-09-24 实测踩到的坑：
        竖向 flex 里 `.view` 原本靠 `margin:0 auto` 居中，而**弹性项的横向 auto 外边距会吃掉
        stretch 拉伸、把宽度压成 fit-content**：桌面端 940 变成 today 819 / vocab 518 /
        todo 447 / progress 495（居中偏移跟着乱），手机端 progress 447、vip 426
        比 310 的可视区还宽、横向溢出到 137px。
        （自检 _check-sitefoot.js 的「视图宽度/居中未变」「无横向溢出」两项就是拦这条的。）
        补上 `width:100%` + `min-width:0` 后：桌面 7 个视图全部回到 940 居中，
        手机端回到 310 且不再溢出，与改动前逐项一致 —— 依据 tools/_diag-foot-flex.js 的 A/B 实测
        （同一页面里切换 flex / block / 修法三种模式，逐视图量 viewW·centerΔ·overflow·bottomGap）。
     ② 只用文字 + 1px 发丝线（渐变两端淡出），**不新增任何模糊层**，
        守 v2.5.0 / v2.5.43 定下的滚动性能约束（backdrop-filter 是 iPhone 卡顿的病根）。
     ③ 颜色走既有令牌（--faint / --line / --accent），明暗两套主题自动适配。
   ============================================================ */
.main{display:flex;flex-direction:column}
/* 让 .view 在竖向 flex 里重新撑满（原因见上面 ⚠️）；min-width:0 挡住内容撑出的横向溢出 */
.view{width:100%;min-width:0}
.sitefoot{
  margin-top:auto;width:100%;max-width:940px;
  margin-left:auto;margin-right:auto;position:relative;
  padding:16px 40px calc(34px + env(safe-area-inset-bottom));
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:10px;
  font-size:11.5px;letter-spacing:.05em;color:var(--faint);
}
.sitefoot::before{
  content:"";position:absolute;left:40px;right:40px;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 16%,var(--line) 84%,transparent);
}
.sitefoot a{color:inherit;text-decoration:none;transition:color .2s}
.sitefoot a:hover{color:var(--accent)}
.sitefoot__sep{opacity:.4}
@media (max-width:920px){
  .sitefoot{padding:14px 20px calc(30px + env(safe-area-inset-bottom))}
  .sitefoot::before{left:20px;right:20px}
  /* v2.6.33：手机端页脚会折成 3 行，两个「·」分隔点会孤零零挂在行尾（像脏点）。
     窄屏直接不显示分隔点，靠 gap 分行 —— 桌面端仍是一行，分隔点保留。 */
  .sitefoot__sep{display:none}
}

/* ============================================================
   生词本 · iOS 分组列表（v2.6.8 · 2026-09-24 站长从三版效果图里选定「A」）
   ------------------------------------------------------------
   站长要求：「用最高审美把单词本升级成极简 iOS 风、液态玻璃感」。
   三版效果图送审（A 分组列表 / B 液态玻璃 / C 极简通透），他选了 A。选它的两个好处：
     ① **最像 iOS 系统设置**：整页＝一整块玻璃面板，词与词之间只用一根发丝线分隔，
        等级从彩色胶囊降级成「● 生疏」小圆点，操作按钮收敛成右侧文字按钮；
     ② **顺手省了性能**：玻璃层数从「每张卡各一层 backdrop-filter」降到「整页一层」，
        手机滚动时少掉 N 个模糊层（守 v2.5.0 / v2.5.43 的性能约束，这次是反向受益）。
   ⚠️ 每个选择器都带 `#view-vocab` 前缀 —— 改动只落在生词本这一页：
      `.statrow`（进度页也在用）、`.vcard`、`.seg` 在别处的既有样式完全不受影响
      （`#view-vocab .x` 特异性高于统一层的 `.x`，所以放在文件末尾也不必再抢顺序）。
   ⚠️ 观感类改动一律「先出效果图再落地」——这是 v2.5.14 定下的规矩，本版照办
      （三版效果图与对比图在 桌面\天空岛\预览-v2.6.8-单词本三版\）。
   ============================================================ */

/* ① 统计条：从「三张独立卡片」并成一条玻璃带，格与格之间一根发丝线 */
#view-vocab .statrow{gap:0;background:var(--surface);border:1px solid var(--sky-edge);
  border-radius:18px;overflow:hidden;
  box-shadow:var(--sky-deep), inset 0 1px 0 rgba(255,255,255,.95);
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  margin-bottom:18px}
#view-vocab .stat{background:transparent;border:0;border-radius:0;box-shadow:none;padding:14px 18px;
  backdrop-filter:none;-webkit-backdrop-filter:none}
#view-vocab .stat+.stat{box-shadow:inset 1px 0 0 var(--line)}
#view-vocab .stat b{font-size:24px;margin-bottom:4px}
/* 手机端也保持一行三格（否则第三格会单独换行、发丝线孤零零地贴在左边） */
@media (max-width:920px){ #view-vocab .statrow{grid-template-columns:repeat(3,1fr)} }

/* ② 列表主体：一整块玻璃，行与行之间发丝线；卡片自己不再各自模糊 */
#view-vocab .vocabgrid{display:block;background:var(--surface);border:1px solid var(--sky-edge);
  border-radius:18px;overflow:hidden;
  box-shadow:var(--sky-deep), inset 0 1px 0 rgba(255,255,255,.95);
  backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat));
  -webkit-backdrop-filter:blur(var(--ios-blur)) saturate(var(--ios-sat))}
#view-vocab .vcard{background:transparent;border:0;border-radius:0;box-shadow:none;
  padding:15px 18px 13px;backdrop-filter:none;-webkit-backdrop-filter:none;
  animation:rowIn .34s var(--ease-out) backwards}
#view-vocab .vcard+.vcard{box-shadow:inset 0 1px 0 var(--line)}
#view-vocab .vcard::before{display:none}          /* 去掉左侧等级色条：等级改用小圆点 */
#view-vocab .vcard:hover{transform:none;box-shadow:none;border-color:transparent}
@keyframes rowIn{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

/* ③ 词头：字号收一档，等级变「● 生词 / ● 已掌握」小圆点
   （v2.6.12：站长把三档改成两档，中间那档「熟悉」的 `.lv1` 规则已删；见文件末尾那一块） */
#view-vocab .vcard__w{font-size:20px;font-weight:650}
#view-vocab .vcard__lv{margin-left:auto;background:transparent;padding:0;box-shadow:none;
  display:inline-flex;align-items:center;gap:7px;color:var(--muted);font-weight:600;font-size:11.5px}
#view-vocab .vcard__lv::before{content:'';width:7px;height:7px;border-radius:99px;
  background:var(--rose);flex:0 0 7px}
#view-vocab .vcard__lv.lv2::before{background:var(--teal)}
#view-vocab .lv0,#view-vocab .lv2{background:transparent;color:var(--muted)}

/* ④ 例句：从「内嵌小盒子」改成引文式（只留一根细色条），更贴 iOS 的正文排版。
   右侧多留 30px —— 给 v2.6.26 那颗「收藏这句例句」的星让位，否则长例句会钻到星底下。 */
#view-vocab .vcard__ex{background:transparent;border-radius:0;box-shadow:none;
  padding:2px 30px 0 14px;margin-top:9px}
#view-vocab .vcard__ex::before{left:0;top:5px;bottom:5px;width:2px;opacity:.32;border-radius:99px}
/* 「点击看译文」：小眼睛换成更轻的折叠箭头（亮起＝可展开，收起＝朝上） */
#view-vocab .vcard__zhbtn{background:transparent;border:0;padding:0;height:22px;
  color:var(--accent);font-weight:600}
#view-vocab .vcard__zhbtn svg{display:none}
#view-vocab .vcard__zhbtn::after{content:'⌄';margin-left:4px;opacity:.65;font-size:12px}
#view-vocab .vcard__zhbtn[aria-expanded="true"]{color:var(--faint)}
#view-vocab .vcard__zhbtn[aria-expanded="true"]::after{content:'⌃'}
#view-vocab .vcard__zh{border-top:0;padding-top:3px;color:var(--muted)}

/* ⑤ 操作行：右对齐的文字按钮（主操作保留强调色），不再是两条实心长条 */
#view-vocab .vcard__ft{padding-top:11px;gap:16px;justify-content:flex-end}
#view-vocab .vcard__ft button{background:transparent;border:0;height:auto;padding:0;
  font-size:12.5px;font-weight:600;color:var(--accent)}
#view-vocab .vcard__ft .up{background:transparent;border:0;color:var(--accent);
  flex:0 0 auto;box-shadow:none;filter:none}
#view-vocab .vcard__ft .up--done{background:transparent;color:var(--teal)}
#view-vocab .vcard__ft .del{color:var(--faint)}

/* ⑥ 分段控件：贴合这层玻璃的底色 */
#view-vocab .seg{background:rgba(255,255,255,.55);border-color:var(--line)}
[data-theme="dark"] #view-vocab .seg{background:rgba(255,255,255,.06)}

/* ============================================================
   生词本「收藏」档 = 收藏的**例句**（v2.6.26 · 站长：「那个生词本收藏是收藏句子不是单词」）
   ------------------------------------------------------------
   这一档列的不是词卡，而是**句子**：整行沿用同一块玻璃面板（父级 `#view-vocab .vocabgrid` 提供背景），
   行与行之间一根发丝线、入场动画沿用 `rowIn` —— 和词卡行完全同一套观感语言，看不出是两套东西。
   排版把「英文例句」当主角（f-read 衬线、15.5px/1.9），译文退一档（灰、13px），
   出处与「取消收藏」收进底部一行（12px 文字按钮），别抢句子的戏。 */
#view-vocab .sfav{
  background:transparent;border:0;border-radius:0;box-shadow:none;
  padding:15px 18px 13px 22px;position:relative;
  animation:rowIn .34s var(--ease-out) backwards;
}
#view-vocab .sfav+.sfav{box-shadow:inset 0 1px 0 var(--line)}
/* 左侧一根金色细条：收藏在站里一直是金色语义（金句收藏 / 批注锚点），一眼认得出这行是"收进来的句子" */
#view-vocab .sfav::before{
  content:'';position:absolute;left:8px;top:16px;bottom:16px;width:2px;border-radius:99px;
  background:linear-gradient(180deg,transparent,var(--gold) 22%,var(--gold) 78%,transparent);
  opacity:.7;
}
#view-vocab .sfav__en{
  margin:0;font-family:var(--f-read);font-size:15.5px;line-height:1.9;
  letter-spacing:.004em;color:var(--ink);
}
#view-vocab .sfav__zh{margin:5px 0 0;font-size:13px;line-height:1.85;color:var(--muted)}
#view-vocab .sfav__ft{display:flex;align-items:center;gap:12px;margin-top:9px;justify-content:flex-end}
#view-vocab .sfav__from{
  margin-right:auto;min-width:0;font-size:11.5px;letter-spacing:.02em;color:var(--faint);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
#view-vocab .sfav__del{
  flex:0 0 auto;background:transparent;border:0;padding:0;cursor:pointer;
  font:inherit;font-size:12.5px;font-weight:600;color:var(--faint);
  transition:.2s var(--ease-spring);
}
#view-vocab .sfav__del:hover{color:var(--rose)}
#view-vocab .sfav__del:active{transform:scale(.94)}
@media (max-width:920px){
  #view-vocab .sfav{padding:14px 18px 12px 20px}
  #view-vocab .sfav::before{left:7px}
  #view-vocab .sfav__en{font-size:15px}
}

/* ============================================================
   生词本 · 两档制 + 文字对比度（v2.6.12 · 2026-09-26）
   ------------------------------------------------------------
   站长反馈：「单词本上面的单词文本框颜色太浅了」——
   指的是①顶部那排分类胶囊、②词条里那些**次要文字**。实测（昼 / 夜）：
     · 胶囊未选中态  #587089 / #93A2B8（--muted），底还是 rgba(255,255,255,.55) 的淡玻璃
     · 例句 .vcard__en 同样是 --muted —— 整页最浅的一行字
     · 「点击看译文」与「标为已掌握」用的是 --accent #0EA5E9，在浅蓝玻璃上只有 2.8:1
   改法：只把**被读的内容**往上提一档色阶（muted → ink-2、accent → accent-ink），
   并且把胶囊的底与描边做实一点；**尺寸 / 间距 / 层级一律不动** ——
   观感还是站长选定的那套极简 iOS 风，只是看得清了。
   ⚠️ 全部选择器带 #view-vocab 前缀：`.seg` 在文库筛选、设置弹窗也在用，
       `.statrow` 进度页也在用 —— 改动只落在生词本这一页。
   ============================================================ */
#view-vocab .seg{background:rgba(255,255,255,.8);border-color:rgba(11,30,51,.1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95), 0 2px 10px -6px rgba(2,32,71,.34)}
#view-vocab .seg__btn{color:var(--ink-2)}
#view-vocab .seg__btn:not(.is-active):hover{color:var(--ink);background:rgba(255,255,255,.62)}
[data-theme="dark"] #view-vocab .seg{background:rgba(255,255,255,.1);border-color:rgba(148,175,220,.28);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12), 0 2px 12px -6px rgba(0,0,0,.5)}
[data-theme="dark"] #view-vocab .seg__btn{color:var(--ink-2)}
[data-theme="dark"] #view-vocab .seg__btn:not(.is-active):hover{color:var(--ink);background:rgba(255,255,255,.08)}
#view-vocab .vcard__en{color:var(--ink-2)}
#view-vocab .vcard__lv{color:var(--ink-2)}
#view-vocab .vcard__zh{color:var(--ink-2)}
#view-vocab .vcard__zhbtn{color:var(--accent-ink)}
#view-vocab .vcard__ft .up{color:var(--accent-ink)}
#view-vocab .vcard__ft .del{color:var(--muted)}
#view-vocab .stat span{color:var(--muted)}
/* ⚠️ 只动「文字颜色」，**不动**例句框的形态 —— v2.6.8 那版「引文式、只留一根细色条」
   是站长从三版效果图里挑的 A 版，这里不去给它加描边/底色（`_check-vocab-ios.js` 专门
   钉着「例句没有内嵌盒子」这条，别顺手破坏它）。 */

/* ============================================================
   复习模式 · 「双击斩词」特效（v2.6.12 · 2026-09-26）
   ------------------------------------------------------------
   站长要求：「复习时加一个双击斩掉单词，用你的最高审美做个特效」。
   语义 = 从生词本**彻底删除**（不是标记），所以 JS 那边配了一条 9 秒可撤销的提示条。
   四层特效：刀光 → 切口 → 断词 → 火星。全部只动 transform / opacity / mask：
     **零新增模糊层、零布局动画**（守 v2.5.0 起的滚动性能约束）。
   动效一律挂在 `#rvCard.is-slashing` 下 —— 卡片每张都是 step() 新建的，
   所以天然不会像常驻节点那样「重播」，JS 里不需要重置 animation。
   「减弱动态效果」下 JS 直接不建这些节点，这里再兜一层 animation:none。
   ============================================================ */
.rv__word{position:relative}
/* 舞台：自带 overflow:hidden，刀光只在卡片内部横穿，不会糊到弹窗外；不挡点击 */
.rv__cut{position:absolute;inset:0;overflow:hidden;pointer-events:none;border-radius:inherit;z-index:4}
.rv__blade,.rv__seam{position:absolute;left:50%;top:var(--cut-y,50%);pointer-events:none;opacity:0}
/* ① 刀光：两端渐隐的冷白亮线，从单词中心向两侧爆开（16° ＝ 刀口角度） */
.rv__blade{
  width:190%;height:2.5px;border-radius:99px;transform:translate(-50%,-50%) rotate(16deg) scaleX(.02);
  background:linear-gradient(90deg,transparent 0%,rgba(186,240,255,.06) 16%,rgba(186,240,255,.9) 42%,#fff 50%,rgba(186,240,255,.9) 58%,rgba(186,240,255,.06) 84%,transparent 100%);
  box-shadow:0 0 12px 1px rgba(125,211,252,.62), 0 0 34px 7px rgba(56,189,248,.3);
}
/* ② 切口：同一角度的发丝线，亮一下再收（刀走过的痕） */
.rv__seam{
  width:170%;height:1px;transform:translate(-50%,-50%) rotate(16deg);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.92) 45%,rgba(125,211,252,.92) 55%,transparent);
}
/* ③ 断词：两个替身各截一半 —— 164° 渐变线 ＝ 与刀光同一条 16° 斜切口，上下两半严丝合缝 */
.rv__half{
  position:absolute;display:flex;align-items:center;justify-content:center;
  pointer-events:none;will-change:transform,opacity;
}
.rv__half--up{-webkit-mask-image:linear-gradient(164deg,#000 48.4%,transparent 51.6%);
  mask-image:linear-gradient(164deg,#000 48.4%,transparent 51.6%)}
.rv__half--dn{-webkit-mask-image:linear-gradient(164deg,transparent 48.4%,#000 51.6%);
  mask-image:linear-gradient(164deg,transparent 48.4%,#000 51.6%)}
/* ④ 火星：极短的亮屑，沿切口法线迸出（方向/长度/延时由 JS 逐颗写入） */
.rv__spark{
  position:absolute;left:50%;top:var(--cut-y,50%);
  width:var(--len,14px);height:1.6px;border-radius:99px;
  margin:-0.8px 0 0 calc(var(--len,14px) / -2);
  background:linear-gradient(90deg,rgba(255,255,255,.12),#fff);
  box-shadow:0 0 6px rgba(125,211,252,.85);
  opacity:0;pointer-events:none;will-change:transform,opacity;
}
@keyframes rvBlade{
  0%{opacity:0;transform:translate(-50%,-50%) rotate(16deg) scaleX(.02)}
  10%{opacity:1}
  62%{opacity:1;transform:translate(-50%,-50%) rotate(16deg) scaleX(1)}
  100%{opacity:0;transform:translate(-50%,-50%) rotate(16deg) scaleX(1.06)}
}
@keyframes rvSeam{0%{opacity:0}14%{opacity:.92}100%{opacity:0}}
@keyframes rvUp{0%{opacity:1;transform:none}
  100%{opacity:0;transform:translate(-13px,-15px) rotate(-2.6deg) scale(.985)}}
@keyframes rvDn{0%{opacity:1;transform:none}
  100%{opacity:0;transform:translate(14px,17px) rotate(2.9deg) scale(.985)}}
@keyframes rvSpark{
  0%{opacity:1;transform:translate(0,0) rotate(var(--rot,16deg)) scaleX(.5)}
  100%{opacity:0;transform:translate(var(--dx,30px),var(--dy,0)) rotate(var(--rot,16deg)) scaleX(1)}
}
/* 卡片收势：刀过去之后整张卡轻轻一沉再化开（刀光 0.46s，这里紧接着起） */
@keyframes rvCutOut{to{opacity:0;transform:scale(.965) translateY(5px)}}
#rvCard.is-slashing{animation:rvCutOut .3s cubic-bezier(.4,0,.7,.4) .46s both}
#rvCard.is-slashing .rv__blade{animation:rvBlade .46s cubic-bezier(.12,.82,.2,1) both}
#rvCard.is-slashing .rv__seam{animation:rvSeam .58s ease-out .1s both}
#rvCard.is-slashing .rv__half--up{animation:rvUp .58s cubic-bezier(.22,.7,.28,1) .12s both}
#rvCard.is-slashing .rv__half--dn{animation:rvDn .6s cubic-bezier(.22,.7,.28,1) .12s both}
#rvCard.is-slashing .rv__spark{animation:rvSpark .62s cubic-bezier(.16,.7,.3,1) both}

@media (prefers-reduced-motion:reduce){
  #rvCard.is-slashing{animation:rvCutOut .2s ease both}
  #rvCard.is-slashing .rv__blade,#rvCard.is-slashing .rv__seam,
  #rvCard.is-slashing .rv__half--up,#rvCard.is-slashing .rv__half--dn,
  #rvCard.is-slashing .rv__spark{animation:none}
}

/* ============================================================
   习惯养成（2026-09-26 · 站长：「在 to do 里面加一个习惯养成功能」）
   玻璃与 To Do 同一套配方（--sky-hi / --sky-panel / --accent-*），
   添加框直接复用 .todoadd / .todoadd__plus / .todoadd__input，这里只写习惯列表。
   全部选择器带 #view-todo 前缀，不污染其它视图；动效只动 transform/opacity。
   ============================================================ */
#view-todo .habitpanel{max-width:720px;margin:0 auto 18px;display:flex;flex-direction:column;gap:12px}
#view-todo .habithead{display:flex;align-items:baseline;justify-content:space-between;padding:0 4px}
#view-todo .habithead__kicker{font-size:11px;font-weight:700;letter-spacing:.14em;color:var(--faint)}
#view-todo .habithead__sum{font-size:12px;color:var(--muted)}
#view-todo .habithead__sum b{color:var(--accent-ink);font-size:13px}
#view-todo .habitlist{display:flex;flex-direction:column;gap:10px}
#view-todo .habit{
  display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:16px;
  background:var(--sky-hi), var(--sky-panel);
  border:1px solid rgba(125,211,252,.5);
  box-shadow:0 1px 2px rgba(2,132,199,.07), 0 16px 42px -18px rgba(2,132,199,.32), var(--glass-inset);
  backdrop-filter:blur(20px) saturate(1.7);-webkit-backdrop-filter:blur(20px) saturate(1.7);
  animation:fade .26s ease backwards;
}
/* 今日勾选钮：空心圈 → 渐变实心 + 对勾渐显 */
#view-todo .habit__check{
  position:relative;flex:0 0 26px;width:26px;height:26px;border-radius:50%;cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border:1.5px solid rgba(56,189,248,.65);background:rgba(255,255,255,.45);
  color:transparent;transition:background .2s,border-color .2s;
}
#view-todo .habit__check svg{width:13px;height:13px;opacity:0;transform:scale(.5);transition:.18s var(--ease-spring)}
#view-todo .habit:not(.is-done) .habit__check:hover{border-color:var(--accent-2);background:var(--accent-2)}
#view-todo .habit.is-done .habit__check{background:var(--accent-grad);border-color:transparent;color:#fff}
#view-todo .habit.is-done .habit__check svg{opacity:1;transform:scale(1)}
/* 勾选瞬间：对勾描边 + 一圈涟漪（.is-pop 只挂一次，整表重绘不重播） */
#view-todo .habit.is-pop .habit__check svg{opacity:1;transform:scale(1)}
#view-todo .habit.is-pop .habit__check svg path{stroke-dasharray:26;stroke-dashoffset:26;animation:habitDraw .3s .05s ease-out forwards}
@keyframes habitDraw{to{stroke-dashoffset:0}}
#view-todo .habit.is-pop .habit__check::after{
  content:'';position:absolute;inset:-5px;border-radius:50%;border:1.5px solid var(--accent-2);
  pointer-events:none;animation:habitRipple .55s ease-out forwards;
}
@keyframes habitRipple{from{transform:scale(.72);opacity:.85}to{transform:scale(1.65);opacity:0}}
/* 中部：习惯名 + 本周 7 天小格 */
#view-todo .habit__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}
#view-todo .habit__text{font-size:14px;color:var(--ink);line-height:1.5;word-break:break-word;cursor:default}
#view-todo .habit.is-done .habit__text{color:var(--muted)}
#view-todo .habit__edit{
  flex:1;min-width:0;height:26px;font-family:inherit;font-size:14px;color:var(--ink);
  background:transparent;border:none;outline:none;border-bottom:1.5px dashed var(--accent-2);padding:0 0 2px;
}
#view-todo .habit__week{display:flex;gap:5px}
#view-todo .habit__day{
  width:22px;height:22px;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;
  font-size:10.5px;color:var(--faint);background:rgba(125,211,252,.14);
  border:1px solid transparent;transition:.18s;
}
#view-todo .habit__day.is-done{background:var(--accent-grad);color:#fff}
#view-todo .habit__day.is-today{border-color:var(--accent-2);box-shadow:0 0 0 2px rgba(56,189,248,.18)}
/* 右侧：连续天数徽章（火苗用 currentColor，吃 accent 色） */
#view-todo .habit__streak{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:4px;height:26px;padding:0 10px;border-radius:999px;
  font-size:11.5px;font-weight:600;color:var(--accent-ink);white-space:nowrap;
  background:var(--accent-soft);border:1px solid rgba(125,211,252,.5);
}
#view-todo .habit__streak b{font-size:12.5px}
#view-todo .habit__flame{width:12px;height:12px;flex:0 0 12px}
#view-todo .habit__streak.is-zero{color:var(--faint);background:rgba(125,211,252,.10);border-style:dashed;border-color:rgba(125,211,252,.45)}
#view-todo .habit__del{
  flex:0 0 auto;width:27px;height:27px;border-radius:9px;cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;font-size:12.5px;line-height:1;
  color:var(--faint);background:transparent;border:none;opacity:0;transition:.18s;
}
#view-todo .habit:hover .habit__del,#view-todo .habit__del:focus-visible{opacity:.6}
#view-todo .habit__del:hover{opacity:1;color:var(--rose)}
#view-todo .habitempty{padding:34px 10px 40px}
#view-todo .habitempty b{display:block;font-size:13.5px;color:var(--ink);margin-top:4px}
#view-todo .habitempty p{font-size:12px;color:var(--faint);margin-top:6px;line-height:1.7}
/* 触屏没有 hover：删除按钮常显 */
@media (hover:none){#view-todo .habit__del{opacity:.5}}
/* 暗色：同一套玻璃配方的深色分支 */
[data-theme="dark"] #view-todo .habit{
  background:linear-gradient(165deg,rgba(14,116,144,.28),rgba(15,23,42,.5) 62%);
  border-color:rgba(56,189,248,.3);
}
[data-theme="dark"] #view-todo .habit__check{background:rgba(15,23,42,.35)}
/* ⚠️ 必须排除 .is-done：本规则与 #view-todo .habit__day.is-done 的特异性同为 (1,2,0)，
   写在后面会把它「天蓝渐变 + 白字」的完成态背景整条压掉（只剩白字落在浅蓝底上，几乎看不见）。
   v2.6.15 上线前实测（computed backgroundImage=none）发现并修掉。 */
[data-theme="dark"] #view-todo .habit__day:not(.is-done){background:rgba(56,189,248,.12)}
/* 减少动态：勾选只切状态、不播描边与涟漪 */
@media (prefers-reduced-motion:reduce){
  #view-todo .habit.is-pop .habit__check svg path{animation:none;stroke-dashoffset:0}
  #view-todo .habit.is-pop .habit__check::after{animation:none}
}
/* 窄屏微调 */
@media (max-width:520px){
  #view-todo .habit{padding:12px 12px;gap:10px}
  #view-todo .habit__day{width:20px;height:20px;font-size:10px}
  /* 连续徽章收紧成「火苗+数字」，给习惯名腾地方（「待开始」是文字态、不压） */
  #view-todo .habit__streak{height:24px;padding:0 8px;gap:3px;font-size:0}
  #view-todo .habit__streak b{font-size:12px}
  #view-todo .habit__streak.is-zero{font-size:10.5px}
}

/* ============================================================
   公告（v2.6.16 · 2026-09-26）
   ------------------------------------------------------------
   站长：「在头像旁边加一个公告小功能，用来提示用户一些可能比较隐藏的功能」。
   两件事：①阅读时双击单词自动进生词本；②手机 / 电脑都能把网站放到桌面。
   这一块是**追加**在文件末尾的独立分段，不改任何既有规则：
     · 入口 .rail__notice 紧贴侧栏头像名片下方（#railNotice）；
     · 面板走全站既有的 #modal 弹层（openModal），只给 #modalBox 加 .is-notice 放宽宽度；
     · 遵守 v2.5.0 / v2.5.43 的性能约束：**不新增任何 backdrop-filter 层**，
       卡片靠一层半透明底 + 发丝边 + 内高光做出「玻璃里的凹槽」，动效只走 transform/opacity。
   ============================================================ */

/* ---- 侧栏入口 ---- */
.rail__notice{
  position:relative;overflow:hidden;
  display:flex;align-items:center;gap:10px;text-align:left;width:calc(100% - 4px);
  margin:0 2px 16px;padding:9px 11px;border-radius:var(--r-m);
  background:var(--surface-2);border:1px solid var(--glass-brd);
  box-shadow:var(--glass-inset), var(--shadow-s);
  transition:transform .26s var(--ease-spring), box-shadow .25s, border-color .22s;
  -webkit-tap-highlight-color:transparent;
}
.rail__notice:hover{transform:translateY(-1.5px);border-color:var(--accent-2);box-shadow:var(--glass-inset), var(--shadow-m)}
.rail__notice:active{transform:scale(.975)}
.rail__noticeic{
  width:30px;height:30px;flex:0 0 30px;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--accent-ink);background:var(--accent-soft);
  transition:.26s var(--ease-spring);
}
.rail__noticeic svg{width:16px;height:16px}
.rail__notice:hover .rail__noticeic{background:var(--accent-grad);color:#fff;box-shadow:0 4px 12px -4px rgba(14,165,233,.6)}
.rail__noticetx{display:flex;flex-direction:column;line-height:1.32;min-width:0;flex:1}
.rail__noticetx b{font-size:13.5px;font-weight:700}
/* 副标题用 --muted 而不是 --faint：v2.6.12 站长反馈过「浅色玻璃上的淡字看不清」 */
.rail__noticetx span{font-size:10.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
/* 未读金点：呼吸光晕，读过即消失（由 renderNoticeEntry() 控制 hidden） */
.rail__noticedot{
  flex:0 0 8px;width:8px;height:8px;border-radius:50%;
  background:linear-gradient(135deg,var(--gold-2),var(--gold));
  animation:noticeDot 2.6s ease-out infinite;
}
@keyframes noticeDot{
  0%{box-shadow:0 0 0 0 rgba(217,185,120,.55)}
  70%{box-shadow:0 0 0 7px rgba(217,185,120,0)}
  100%{box-shadow:0 0 0 0 rgba(217,185,120,0)}
}
/* 有未读时：一道柔光缓慢扫过整条（播 2 次即停，不循环打扰） */
.rail__notice.is-new::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 34%,rgba(255,255,255,.6) 50%,transparent 66%);
  transform:translateX(-130%);
  animation:noticeSheen 2.3s var(--ease-out) .7s 2;
}
@keyframes noticeSheen{to{transform:translateX(130%)}}
[data-theme="dark"] .rail__notice.is-new::after{
  background:linear-gradient(105deg,transparent 34%,rgba(186,225,253,.22) 50%,transparent 66%);
}

/* ---- 面板：#modalBox 加宽 + 「正文滚动、按钮常驻」----
   ⚠️ 不能只给整个 box 加 overflow:auto —— 实测 390×844 下内容 962px、可见 794px，
      底部的「知道了」被推到折线以下，用户得先滚动才找得到关闭键（公告这种一屏就该读完的东西尤其别扭）。
      所以改成三段式弹性布局：头部与底部固定，只有中间的 .ntc__body 滚动。 */
.modal__box.is-notice{
  display:flex;flex-direction:column;
  max-width:560px;padding:0;
  max-height:calc(100vh - 48px);
  max-height:calc(100dvh - 48px);
  overflow:hidden;
}
.ntc{display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
.ntc__head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:30px 30px 0;flex:0 0 auto}
.ntc__body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:0 30px;scrollbar-width:none}
/* 滚动条一律隐形（与 .catbar 同一做法）：面板只有 560px 宽，
   一条常驻的灰色实心滚动条在玻璃面上很扎眼；正文被裁掉半张卡片本身就是「还能往下滚」的提示。 */
.ntc__body::-webkit-scrollbar{width:0;height:0}
.ntc__kick{font-family:var(--f-display);font-size:10.5px;letter-spacing:.34em;color:var(--accent);margin-bottom:6px}
.ntc__title{font-family:var(--f-display);font-size:25px;font-weight:600;letter-spacing:.02em;line-height:1.15}
.ntc__lead{font-size:13px;line-height:1.9;color:var(--muted);margin:10px 0 0}
.ntc__x{
  flex:0 0 30px;width:30px;height:30px;border-radius:50%;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--faint);background:transparent;border:1px solid transparent;
  font-size:12px;line-height:1;transition:.2s var(--ease-spring);
  -webkit-tap-highlight-color:transparent;
}
.ntc__x:hover{color:var(--ink);background:var(--accent-soft);border-color:var(--glass-brd)}
.ntc__x:active{transform:scale(.9)}
.ntc__rule{height:1px;margin:16px 0 18px;background:linear-gradient(90deg,var(--accent-soft),transparent)}
.ntc__list{display:flex;flex-direction:column;gap:13px}

/* ---- 条目卡：玻璃里的「凹槽」（纯半透明底，不加模糊层） ---- */
.ntc__card{
  padding:15px 16px 16px;border-radius:var(--r-m);
  background:rgba(255,255,255,.5);border:1px solid var(--glass-brd);
  box-shadow:var(--glass-inset), 0 1px 2px rgba(2,132,199,.05);
  animation:ntcIn .5s var(--ease-spring) backwards;
}
.ntc__card:nth-child(1){animation-delay:.06s}
.ntc__card:nth-child(2){animation-delay:.14s}
@keyframes ntcIn{from{opacity:0;transform:translateY(11px) scale(.985)}to{opacity:1;transform:none}}
[data-theme="dark"] .ntc__card{
  background:rgba(125,211,252,.06);border-color:rgba(120,150,200,.2);
  box-shadow:var(--glass-inset), 0 1px 2px rgba(0,0,0,.25);
}
.ntc__row{display:flex;align-items:center;gap:11px}
.ntc__badge{
  width:31px;height:31px;flex:0 0 31px;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;color:#fff;
  background:var(--accent-grad);box-shadow:0 4px 12px -4px rgba(14,165,233,.55);
}
.ntc__badge svg{width:17px;height:17px}
.ntc__ht{min-width:0;display:flex;flex-direction:column}
.ntc__h{font-size:15px;font-weight:700;letter-spacing:.01em;line-height:1.35}
.ntc__tag{font-size:10.5px;font-weight:600;letter-spacing:.04em;color:var(--accent-ink);margin-top:3px}
.ntc__p{font-size:12.5px;line-height:1.95;color:var(--muted);margin:11px 0 0}
.ntc__p b{color:var(--ink);font-weight:600}

/* ---- ① 双击加生词：可以真的双击的小演示（只做动效，不写进用户生词本） ---- */
.ntc__demo{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:12px;padding:10px 12px;border-radius:var(--r-s);
  background:linear-gradient(160deg,rgba(224,242,254,.62),rgba(240,249,255,.4));
  border:1px dashed var(--ios-hair);
}
[data-theme="dark"] .ntc__demo{background:rgba(56,189,248,.08);border-color:rgba(56,189,248,.32)}
.ntc__demohint{font-size:11px;color:var(--muted)}
.ntc__word{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  font-family:var(--f-read);font-size:16.5px;color:var(--ink);
  padding:4px 11px 5px;border-radius:9px;
  background:rgba(255,255,255,.75);border:1px solid var(--glass-brd);
  box-shadow:var(--glass-inset);
  user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
  touch-action:manipulation;   /* 手机上允许双击，不被「双击缩放」吃掉 */
  transition:.24s var(--ease-spring);
}
[data-theme="dark"] .ntc__word{background:rgba(186,225,253,.1)}
.ntc__word:hover{border-color:var(--accent-2);transform:translateY(-1px)}
.ntc__word.is-on{
  background:var(--accent-soft);color:var(--accent-ink);border-color:transparent;
  box-shadow:0 0 0 1px var(--ios-ring), 0 6px 18px -8px rgba(14,165,233,.7);
  animation:ntcPop .5s var(--ease-spring);
}
@keyframes ntcPop{0%{transform:scale(1)}34%{transform:scale(1.09)}100%{transform:scale(1)}}
.ntc__word i{
  font-style:normal;font-size:12px;font-weight:700;color:var(--accent-ink);
  opacity:0;transform:scale(.4);transition:.26s var(--ease-spring);
}
.ntc__word.is-on i{opacity:1;transform:none}
.ntc__ok{
  font-size:11.5px;font-weight:600;color:var(--accent-ink);
  opacity:0;transform:translateX(-5px);transition:.3s var(--ease-out) .07s;
}
.ntc__ok.is-on{opacity:1;transform:none}

/* ---- ② 装到桌面：电脑 / 手机 两档说明 ---- */
.ntc__seg{
  display:inline-flex;gap:3px;margin-top:13px;padding:3px;border-radius:var(--r-s);
  background:var(--surface-2);border:1px solid var(--glass-brd);box-shadow:var(--glass-inset);
}
.ntc__segbtn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;cursor:pointer;
  height:29px;padding:0 13px;border-radius:8px;
  font-size:12.5px;font-weight:600;color:var(--muted);
  transition:.24s var(--ease-spring);
  -webkit-tap-highlight-color:transparent;
}
.ntc__segbtn svg{width:14px;height:14px}
.ntc__segbtn:hover{color:var(--ink)}
.ntc__segbtn.is-on{background:var(--accent-grad);color:#fff;box-shadow:0 3px 12px -4px rgba(14,165,233,.55)}
.ntc__panes{margin-top:13px}
.ntc__steps{display:flex;flex-direction:column;gap:9px;animation:ntcIn .36s var(--ease-out) backwards}
.ntc__step{display:flex;gap:10px;align-items:flex-start;font-size:12.5px;line-height:1.8;color:var(--muted)}
.ntc__step i{
  flex:0 0 19px;width:19px;height:19px;margin-top:2.5px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;font-style:normal;
  font-size:10.5px;font-weight:700;
  background:var(--accent-soft);color:var(--accent-ink);
}
.ntc__step b{color:var(--ink);font-weight:600}
.ntc__plat{
  display:flex;align-items:center;gap:8px;margin:15px 0 9px;
  font-size:10.5px;font-weight:700;letter-spacing:.06em;color:var(--faint);
}
.ntc__plat:first-child{margin-top:0}
.ntc__plat::after{content:"";flex:1;height:1px;background:var(--line)}
.ntc__tip{
  display:flex;gap:8px;align-items:flex-start;margin-top:12px;
  padding:9px 11px;border-radius:var(--r-s);
  background:var(--gold-soft);border:1px solid rgba(176,141,79,.3);
  font-size:11.5px;line-height:1.8;color:var(--ink-2);
}
.ntc__tip svg{width:14px;height:14px;flex:0 0 14px;margin-top:3px;color:var(--gold)}

/* ---- 收尾：常驻底栏（正文在它上方滚动，不会被压住） ---- */
.ntc__foot{flex:0 0 auto;margin-top:0;padding:16px 30px 24px;border-top:1px solid var(--line-2)}
.ntc__note{margin-top:11px;font-size:11.5px;line-height:1.8;color:var(--muted);text-align:center}

/* 窄栏（≤920px）：侧栏只剩 70px，公告收成一颗图标键 */
@media (max-width:920px){
  .rail__notice{justify-content:center;padding:9px 0;gap:0}
  .rail__noticetx{display:none}
  .rail__noticedot{position:absolute;right:6px;top:6px;width:7px;height:7px}
}
/* 小屏：面板收边距、按钮撑满，说明文字不挤 */
@media (max-width:520px){
  .ntc__head{padding:22px 17px 0}
  .ntc__body{padding:0 17px}
  .ntc__foot{padding:14px 17px 18px}
  .ntc__title{font-size:22px}
  .ntc__card{padding:13px 13px 14px}
  .ntc__seg{width:100%}
  .ntc__segbtn{flex:1}
  .ntc__h{font-size:14px}
  .ntc__lead{font-size:12.5px}
}
/* 尊重系统「减弱动态效果」：金点不呼吸、柔光不扫、条目不上浮 */
@media (prefers-reduced-motion:reduce){
  .rail__noticedot{animation:none}
  .rail__notice.is-new::after{animation:none;opacity:0}
  .ntc__card,.ntc__steps,.ntc__word.is-on,.modal__box.is-notice{animation:none}
}

/* ============================================================
   v2.6.30（2026-10-18）· 手机端阅读排版 + 朗读悬浮遥控 + 金句卡手机适配
   ------------------------------------------------------------
   站长：「优化一下全栈使用效果，用你的最高审美」。
   审计（390×844 真机尺寸实测）发现的三个「用了但难受」的点：
     · 正文只有 206px 宽 —— .para--en 左右各 32px 留槽（本来是给桌面段落朗读键 /
       句末小笔留的），但手机上小笔 display:none、段落键也改成内嵌右上角，留槽纯浪费；
       加上 .view 左右 20px、侧栏 70px，390 的屏有近一半没放字。
     · 阅读顶栏 117px / 3 行，其中「悬停翻译」在触屏上没有 hover，这个开关按了
       不会有任何效果，却占掉一整行。
     · 朗读条 157px 高，且朗读一开始 #ttsBar 就被标题贴顶滚出视野 —— 想暂停 /
       停止 / 调速只能往回滚，正文正读到哪儿还得再找回来。
   原则：只动尺寸 / 间距 / 显隐，**不改任何数据与朗读逻辑**；桌面 ≥921px 排版原样不动。
   ============================================================ */

/* ---- 1. 窄屏：把留槽还给正文（桌面 760px 阅读栏、32px 留槽保持原样） ---- */
@media (max-width:920px){
  .view{padding-left:14px;padding-right:14px}
  .para--en{padding:0 2px}
  .para--zh{padding-left:13px}
}
@media (max-width:560px){
  .view{padding-left:12px;padding-right:12px}
  .reader__title{font-size:26px}
  .reader__tools{gap:6px}
  .reader__tools .iconbtn{width:32px;height:32px}
}
/* 触屏没有「悬停」：这颗开关在手机上永远是摆设，收起（鼠标环境 <820px 时仍可见） */
@media (hover:none){
  #btnHoverDict{display:none}
}

/* ---- 2. 手机朗读条：从 157px 压到两行以内（状态提示交给底部悬浮遥控） ---- */
@media (max-width:640px){
  .ttsbar{flex-wrap:wrap;gap:6px;padding:8px 10px;border-radius:16px}
  .ttsbar .iconbtn{width:34px;height:34px;flex:0 0 34px}
  .ttsbar__sel{min-width:0;max-width:126px;height:34px;font-size:12.5px;flex:1 1 96px}
  .ttsbar__sel--rate{max-width:100px;flex:0 1 100px}
  .ttsbar__hint{display:none}
  #ttsPreview{display:none}
}

/* ---- 3. 金句卡：手机上左右 38px 的内边距太奢侈（内容只剩 192px） ---- */
@media (max-width:560px){
  .quote{padding:26px 20px 20px}
  .quote__tag{letter-spacing:.12em;margin-bottom:13px}
  .quote__tagEn{display:none}
  .quote__en{font-size:21px;line-height:1.62}
  .quote__zh{font-size:13.5px;line-height:1.95;margin-top:12px}
  .quote__from{margin-top:16px;padding-top:13px}
}
/* 触屏上可以再放松一点：金句是首屏主角，别让它挤成一条竖排 */
@media (hover:none) and (max-width:560px){
  .quote{padding:24px 18px 18px}
  .quote__en{font-size:20.5px}
}

/* ---- 4. 朗读悬浮遥控（ttsdock）----
   朗读条滚出视野后，这颗胶囊是唯一的播 / 停 / 语速入口：
     · 只在「正在朗读」时存在；默认低透明度**完全隐形**，不打扰录屏与阅读；
     · 鼠标移到屏幕下方 200px / 手指点屏幕，才淡入（3.5 秒后再隐去）；
     · 桌面贴在底部正中，手机抬到计时胶囊上方 74px，两者不打架。 */
.ttsdock{
  position:fixed;z-index:900;left:50%;bottom:22px;
  display:flex;align-items:center;gap:4px;height:42px;padding:0 8px 0 5px;
  border-radius:999px;border:1px solid var(--glass-brd);
  background:var(--surface-2,rgba(255,255,255,.82));
  box-shadow:var(--shadow-m),var(--glass-inset);
  backdrop-filter:blur(18px) saturate(1.7);-webkit-backdrop-filter:blur(18px) saturate(1.7);
  opacity:0;pointer-events:none;transform:translate(-50%,10px);
  transition:opacity .26s var(--ease-out),transform .26s var(--ease-out);
}
.ttsdock[hidden]{display:none}
.ttsdock.is-awake{opacity:1;pointer-events:auto;transform:translate(-50%,0)}
.ttsdock__b{
  width:30px;height:30px;flex:0 0 30px;border:0;border-radius:50%;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;background:transparent;color:var(--ink);
  transition:background .16s;
}
.ttsdock__b:hover{background:var(--accent-soft)}
.ttsdock__b:active{transform:scale(.94)}
.ttsdock__b svg{width:15px;height:15px;display:block}
.ttsdock__stop{color:var(--muted)}
.ttsdock__sep{width:1px;height:16px;background:var(--line);margin:0 3px;flex:0 0 1px}
.ttsdock__meta{
  font-size:11.5px;line-height:1;letter-spacing:.05em;color:var(--muted);
  font-variant-numeric:tabular-nums;padding:0 2px;white-space:nowrap;
}
.ttsdock__rate{
  height:24px;padding:0 9px;border:0;border-radius:999px;cursor:pointer;
  font-size:11.5px;font-weight:650;color:var(--accent-ink);background:var(--accent-soft);
  transition:background .16s,color .16s;
}
.ttsdock__rate:hover{background:var(--accent-grad);color:#fff}
[data-theme="dark"] .ttsdock{
  background:rgba(14,30,48,.86);border-color:rgba(125,211,252,.28);
  box-shadow:0 12px 34px -14px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,255,255,.06);
}
[data-theme="dark"] .ttsdock__b{color:#DCEFFE}
[data-theme="dark"] .ttsdock__stop{color:#8FB4D2}
[data-theme="dark"] .ttsdock__rate{color:#9BD8FF;background:rgba(56,189,248,.16)}
@media (max-width:640px){
  .ttsdock{bottom:calc(74px + env(safe-area-inset-bottom,0px));height:40px;padding:0 7px 0 4px}
  .ttsdock__b{width:29px;height:29px;flex-basis:29px}
  .ttsdock__meta{font-size:11px}
}
@media (prefers-reduced-motion:reduce){
  .ttsdock{transition:opacity .12s linear}
}
/* ---- 5. 细节收口（v2.6.30）---- */
/* 朗读中：手机上把计时胶囊让给遥控胶囊（否则底部两颗胶囊挤在一起）；桌面 1440 两者离得远，保持原样 */
@media (max-width:640px){
  #timerpill{transition:opacity .2s var(--ease-out),transform .2s var(--ease-out)}
  body.is-tts #timerpill{opacity:0;pointer-events:none;transform:translateY(6px)}
}
/* 手机上顶栏分两行时，第一行的语言挡位铺满整行、第二行把「标记读完」推到最右，视觉上更齐 */
@media (max-width:560px){
  #modeSeg{flex:1 1 100%}
  #modeSeg .seg__btn{flex:1}
  #btnFinish{margin-left:auto}
}
@media (max-width:640px){
  /* 手机上语速下拉独占一行时铺满，别在右边留一条空白 */
  .ttsbar__sel--rate{flex:1 1 100%;max-width:none}
}