/* ============================================================
   korStudy · 한국어 每日跟读
   Design tokens — 2026-08-04 换肤（设计稿见 docs/design/2026-08-04_*.html）
     亮色 = A안 「오늘의 필사」쑥빛 鼠尾草纸：米纸底 + 奶油卡片 + 暖墨字，
            无描边靠柔投影，纸片按钮 3px 实心下沿，15px 网点纸底纹。
     暗色 = C안 「야간열람실」深夜自习室：夜蓝绿底 + 台灯琥珀，
            玻璃卡片（上亮下暗渐变 + 1px 半透明白受光边），主按钮外发光。
   两套只在令牌层 + 十几个质感选择器上分叉，组件结构与交互零改动。

   ⚠ 语义拆分（换肤引入，勿混用）：
     --ok      = "答对 / 读对 / 完成"  → 逐词标注绿、选择题正确、句子完成
     --award   = "成绩 / 达标 / 连续天数" → 琥珀金；亮色的金呼应暗色的台灯琥珀
   原来两者共用 --ok，换肤后若把"读对"也刷成金，会和"漏读"的黄撞车。
   四色（读对绿 / 读错红 / 漏读黄 / 达标金）的对比度与两两色差
   由 tools/check_contrast.py 出数，改色值必须重跑该脚本。
   ============================================================ */

/* — 开屏花体韩文（只用于 _splash.html 的开屏句；学习正文一律系统字体，
     理由：毛笔连笔会吃掉받침 收音，而这个 App 的核心任务就是看清每个音节）。
     自托管，不引 CDN；KS X 1001 2350 常用音节子集，加句子不用重跑子集。
     产物与 OFL 许可原文见 static/fonts/，重建脚本 tools/build_splash_fonts.py — */
@font-face{
  font-family:"KorPen";                 /* 나눔펜스크립트 Nanum Pen Script · 钢笔手写 · 白天 */
  src:url("/static/fonts/NanumPenScript-ks2350.woff2?v=32") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"KorBrush";               /* 나눔붓글씨 Nanum Brush Script · 毛笔书法 · 夜晚 */
  src:url("/static/fonts/NanumBrushScript-ks2350.woff2?v=32") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}

:root{
  /* — type — */
  --font-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue","PingFang SC","Noto Sans SC","Microsoft YaHei",sans-serif;
  --font-ko:-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",sans-serif;
  --font-script:"KorPen",var(--font-ko);   /* 白天=钢笔；暗色块里换成毛笔 */
  --fs-xs:12px; --fs-sm:13px; --fs-ms:14px; --fs-md:15px; --fs-base:16px;
  --fs-lg:18px; --fs-xl:20px; --fs-2xl:24px; --fs-3xl:28px; --fs-4xl:34px;

  /* — space — */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s8:32px;

  /* — radius（A안：卡片 20 / 小控件 13）— */
  --r-sm:9px; --r-md:13px; --r-lg:20px; --r-pill:999px;

  /* — neutrals（쑥빛 米纸 · 暖中带一点草绿）— */
  --paper:#F2F1E5; --surface:#FCFBF3; --surface-2:#EBEADC; --surface-3:#F5F4E7;
  --ink:#2F332B; --strong:#4A5044; --muted:#676D5E; --faint:#848B79;
  --line:#E0DFCE; --line-2:#EBEADB; --line-strong:#D0CFB9;

  /* — accent（鼠尾草绿）— --accent-deep 专供纸片按钮的实心下沿 — */
  --accent:#5C7F5A; --accent-ink:#3D5C3B; --accent-wash:#E7EEE4; --accent-line:#C3D3C0;
  --accent-deep:#3E5C3C;

  /* — semantic（不等于 accent）— */
  --ok:#4E8B4A; --ok-ink:#2F6B2D; --ok-wash:#E4F0DC; --ok-line:#BFDCB4;
  /* --warn-line 与 --ok-line/--accent-line 同族：wash 当边框看不见，语义色都得有描边色 */
  --warn:#A85E14; --warn-ink:#733E08; --warn-wash:#F6E9D6; --warn-line:#E6CFA9;
  --danger:#B03A34; --danger-ink:#8E2A25; --danger-wash:#F8E6E2; --danger-line:#EFC9C2;
  /* 达标 / 成绩 / 连续天数（琥珀金，与暗色的台灯琥珀同族）；--award-deep 用于打卡完成的渐变。
     ⚠ --award-deep 不能随便加深：「今日全部完成」横幅的字直接压在渐变上，15.5px/600 属正文档（要 4.5:1）。
     原值 #96691B 配 #2E2205 只有 3.22:1（横幅居中，实际落点约 3.98:1）—— 提亮到 #A2731F，
     配下面加深过的 --on-award 后渐变两端 5.85 / 4.52 都过线，且与 --award 仍有 ΔE00 7.1 的可见落差。 */
  --award:#B8862C; --award-ink:#7E5A16; --award-wash:#F6EEDA; --award-line:#E5D2A2; --award-deep:#A2731F;
  --gold:#B5811A;             /* 收藏星（实心填充图标，与达标金分开留一档更亮的） */

  /* — 填充块上的文字色：暗色下强调色是浅琥珀，白字会糊掉，必须走令牌 — */
  --on-accent:#FFFFFF;        /* .btn / .tb.on / tab pill 等 accent 填充上的字 */
  --on-award:#180F02;         /* 金底太浅，两套皮肤都用深墨字；要同时压得住 --award 与 --award-deep 两端 */
  --on-sem:#FFFFFF;           /* danger / warn 填充上的字（徽章） */

  /* — heatmap ramp（沿 accent 的鼠尾草绿铺 5 档；l0=没学，l1..l4=当天练得越多越深）—
     l1/l2/l3 = l0→l4 之间按 CIELAB 等距取的三点，不是随手挑的：热力图唯一要传达的信息就是
     "这格比那格深多少"，只靠彩度铺档在红绿色盲眼里会整片塌掉。原来的
     #CFDEC6/#A6C39C/#7BA372 与 l0 几乎等亮（l0/l1 亮度比仅 1.09），
     绿色盲 ΔE00 只有 2.4、红色盲 2.5（<2 就是"看不出差别"）—— 也就是"今天没学"和
     "今天学了一点"在色盲用户那儿是同一个格子。改成等亮度步进后每档亮度比 1.33~1.43，
     不靠辨色也能读：绿色盲最小 ΔE00 7.5 / 红色盲 7.3，正常视觉最小 9.2（原来 7.3）。
     暗色那套本来就是按亮度铺的（绿色盲最小 7.3），不动。 */
  --l0:#E4E3D2; --l1:#BEC9AE; --l2:#98B08B; --l3:#739769; --l4:#4E7F49;

  /* — chrome / overlays（顶栏底栏毛玻璃 / 录音模糊遮罩）— */
  --chrome:rgba(252,251,243,.86); --mask:rgba(242,241,229,.45);

  /* — 卡片质感：亮色无描边 + 柔投影；暗色靠 --glass 渐变 + 受光细边 — */
  --card-line:transparent; --glass:none;

  /* — 页面底纹：亮色 15px 网点纸；暗色换成顶部琥珀灯晕（见暗色块）— */
  --paper-tex:radial-gradient(circle at 1px 1px,rgba(122,90,70,.10) 1px,transparent 0);
  --paper-tex-size:15px 15px; --paper-tex-repeat:repeat; --paper-tex-attach:scroll;

  /* — 荧光笔（话题标题下半划线）— */
  --hl:#E9EFA6;

  /* — 开屏句的墨色（比正文墨稍暖一点，让手写体像是写上去的）— */
  --splash-ink:#333A2E;

  /* — 主按钮：纸片被按下去的 3px 实心下沿（暗色改外发光）— */
  --btn-lift:0 3px 0 var(--accent-deep);
  --btn-lift-a:0 1px 0 var(--accent-deep);

  /* — elevation（暖褐投影，跟着纸走）— */
  --shadow-sm:0 1px 2px rgba(58,46,40,.06);
  --shadow-card:0 1px 1px rgba(58,46,40,.05),0 6px 16px rgba(122,90,70,.10);
  --shadow-stage:0 2px 4px rgba(58,46,40,.06),0 12px 28px rgba(122,90,70,.14);

  /* — motion — */
  --ease:cubic-bezier(.2,.7,.3,1); --dur-fast:.12s; --dur:.25s; --dur-slow:.35s;

  /* — layout — */
  --topbar-h:50px;
  --tabbar-h:60px;            /* 底部 tab 栏内容高度，不含 safe-area */
  --r:var(--r-lg); --shadow:var(--shadow-card);
}

/* ============ dark mode · 야간열람실（token-level override only）============ */
@media (prefers-color-scheme:dark){
  :root{
    --font-script:"KorBrush",var(--font-ko);   /* 夜里换毛笔 */
    --r-sm:8px; --r-md:12px; --r-lg:18px;

    --paper:#0B1317; --surface:#16222A; --surface-2:#1D2C35; --surface-3:#101B21;
    --ink:#E9F0F2; --strong:#C6D5DA; --muted:#93A7AE; --faint:#7E939B;
    --line:rgba(255,255,255,.09); --line-2:rgba(255,255,255,.055); --line-strong:rgba(255,255,255,.16);

    --accent:#E4A857; --accent-ink:#F0C489; --accent-wash:rgba(228,168,87,.14); --accent-line:rgba(228,168,87,.38);
    --accent-deep:rgba(228,168,87,.3);
    /* 暗色的"读对"用青薄荷，和琥珀强调色拉开；"漏读"改亮黄，避免和琥珀糊成一块 */
    --ok:#59C2A6; --ok-ink:#83DCC0; --ok-wash:rgba(89,194,166,.15); --ok-line:rgba(89,194,166,.4);
    --warn:#E8C46A; --warn-ink:#F2D98A; --warn-wash:rgba(232,196,106,.16); --warn-line:rgba(232,196,106,.4);
    --danger:#E27B7B; --danger-ink:#F0A5A5; --danger-wash:rgba(226,123,123,.18); --danger-line:rgba(226,123,123,.42);
    --award:#E4A857; --award-ink:#F0C489; --award-wash:rgba(228,168,87,.14); --award-line:rgba(228,168,87,.38);
    --award-deep:#C08A3C;
    --gold:#E8B931;

    --on-accent:#241703; --on-award:#241703; --on-sem:#2A0C0C;

    /* --l0 比设计稿的 #1B2A32 提亮一档：热力图落在玻璃卡片(#16222A)上而不是页面底色上，
       原值和卡片几乎同色，"还没学的格子"整片消失，看不出网格。 */
    --l0:#26373F; --l1:#2E4A45; --l2:#417A63; --l3:#59A87E; --l4:#7ACF9C;
    --chrome:rgba(11,19,23,.78); --mask:rgba(11,19,23,.5);

    /* 玻璃面板：上亮下暗的极淡白渐变 + 1px 受光细边 */
    --card-line:rgba(255,255,255,.085);
    --glass:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012));

    /* 网点纸换成顶部那盏台灯的琥珀灯晕（固定在视口顶，滚动不跟走） */
    --paper-tex:radial-gradient(130% 55% at 50% 0%,rgba(228,168,87,.13),transparent 68%);
    --paper-tex-size:100% 100%; --paper-tex-repeat:no-repeat; --paper-tex-attach:fixed;

    --hl:transparent;         /* 夜里不划荧光笔 */
    --splash-ink:#F6EBDA;     /* 毛笔字落在灯光里，是暖奶白不是纯白 */

    --btn-lift:0 0 18px rgba(228,168,87,.3);      /* 外发光取代实心下沿 */
    --btn-lift-a:0 0 10px rgba(228,168,87,.24);

    --shadow-sm:0 1px 2px rgba(0,0,0,.45);
    --shadow-card:0 4px 14px rgba(0,0,0,.42);
    --shadow-stage:0 8px 24px rgba(0,0,0,.5);
  }
}

*{box-sizing:border-box}
[x-cloak]{display:none!important}
/* 作者侧兜底：UA 的 [hidden] 优先级低于任何作者 display 规则（如 .rv-rate{display:flex}会压掉它） */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
/* 底纹走令牌：亮色 = 15px 网点纸（随内容滚动，像真的纸）；
   暗色 = 顶部一团琥珀灯晕（attachment:fixed，灯不跟着内容跑）。 */
body{margin:0;color:var(--ink);
  background-color:var(--paper);background-image:var(--paper-tex);
  background-size:var(--paper-tex-size);background-repeat:var(--paper-tex-repeat);
  background-attachment:var(--paper-tex-attach);
  font-family:var(--font-ui);line-height:1.7;font-size:var(--fs-base);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
main{max-width:720px;margin:0 auto;padding:18px 16px 96px}
a{color:var(--accent-ink);text-decoration:none}
h2{font-size:var(--fs-xl);font-weight:650;letter-spacing:-.2px;margin:14px 0 8px;text-wrap:balance}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* Korean shadowing text — dedicated face + keep-all (防止韩文词中折行) */
.sent-text,.rv-word,.spell-slot,.spell-block,.match-tile.ko,.type-answer,.type-input,
.s-ko,.speaker,.vocab .ko,.gram b{font-family:var(--font-ko)}
.sent-text,.rv-word,.type-answer{word-break:keep-all}

/* 顶栏：克制的白底 + 细底线 + 毛玻璃 */
.topbar{position:sticky;top:0;z-index:20;min-height:var(--topbar-h);background:var(--chrome);
  -webkit-backdrop-filter:saturate(1.4) blur(10px);backdrop-filter:saturate(1.4) blur(10px);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;padding:11px 18px}
.topbar .brand{color:var(--ink);font-weight:700;font-size:15.5px;letter-spacing:.2px;font-family:var(--font-ko)}
.topbar .brand small{color:var(--faint);font-weight:500;margin-left:6px;font-size:var(--fs-xs);font-family:var(--font-ui)}
.topbar nav{display:flex;align-items:center;gap:var(--s1)}
.topbar nav a{color:var(--muted);font-size:var(--fs-ms);padding:6px 11px;border-radius:var(--r-sm)}
.topbar nav a:hover{background:var(--accent-wash);color:var(--accent-ink)}
/* 连续天数 = 奖励语义 → 琥珀金（不是强调色，不是"答对"的绿） */
.topbar .streak{color:var(--award-ink);background:var(--award-wash);border:1px solid var(--award-line);
  font-size:var(--fs-sm);font-weight:600;padding:4px 11px;border-radius:var(--r-pill)}

/* 日期条：前一天 | 日期(居中,占余量) | 后一天+模式切换钮（三段 flex，窄屏不换行不挤压） */
.daybar{display:flex;align-items:center;gap:var(--s2);margin:16px 0 6px}
.daybar .nav{font-size:13.5px;color:var(--muted);padding:6px 8px;border-radius:var(--r-sm);white-space:nowrap}
.daybar .nav:hover{background:var(--line-2)}
.daymeta{flex:1;min-width:0;text-align:center}
/* 右段：后一天 + 紧凑模式切换钮（取代旧 .modebar 整行，省一整行竖向空间） */
.daybar-end{display:flex;align-items:center;gap:var(--s1);flex:none}
.modetoggle{border:1px solid var(--line-strong);background:var(--surface);color:var(--accent-ink);
  border-radius:var(--r-pill);padding:5px 12px;font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap;
  transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.modetoggle:hover{border-color:var(--accent);background:var(--accent-wash)}
.modetoggle:active{transform:translateY(1px)}
.daymeta .date{font-weight:650;font-size:var(--fs-base);font-variant-numeric:tabular-nums}
.daymeta .sub{color:var(--muted);font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.degraded{background:var(--warn-wash);border-left:3px solid var(--warn);border-radius:var(--r-sm);
  padding:8px 12px;margin:10px 0;font-size:var(--fs-sm);color:var(--warn-ink)}

/* 话题卡：亮色无描边（靠柔投影 + 底色差分离），暗色靠 --glass 渐变 + 受光细边 */
.topic{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r);
  padding:18px 18px 10px;margin:14px 0;box-shadow:var(--shadow-card)}
.topic-head .cat{color:var(--faint);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.5px;font-weight:600}
.topic-head .ko{font-size:var(--fs-lg);font-weight:650;margin:5px 0 2px;line-height:1.4;font-family:var(--font-ko);word-break:keep-all}
/* 荧光笔划线：只覆盖字的下半截（58%→94%），像用马克笔划过；夜里 --hl 是透明的 */
.topic-head .ko .hl{background:linear-gradient(transparent 58%,var(--hl) 58%,var(--hl) 94%,transparent 94%);
  box-decoration-break:clone;-webkit-box-decoration-break:clone}
.topic-head .zh{color:var(--muted);font-size:var(--fs-ms);margin-bottom:8px}

/* 话题进度条 */
.tprog{display:flex;align-items:center;gap:10px;margin:2px 0 10px}
.tprog-track{flex:1;height:7px;background:var(--surface-2);border-radius:var(--r-pill);overflow:hidden}
.tprog-fill{height:100%;background:var(--accent);border-radius:var(--r-pill);width:0;
  transition:width .5s var(--ease)}
.tprog-text{color:var(--faint);font-size:var(--fs-xs);font-variant-numeric:tabular-nums;min-width:34px;text-align:right}

/* 句子 / 跟读单元 */
.sentences{margin:6px 0}
.sent{padding:12px 10px;border-radius:var(--r-sm);border-bottom:1px solid var(--line-2)}
.sent:last-child{border-bottom:none}
.sent.done{background:var(--ok-wash)}
.sent-line{position:relative;font-size:17px;line-height:1.85;min-height:1.6em;font-family:var(--font-ko)}
.speaker{display:inline-block;background:var(--accent-wash);color:var(--accent-ink);
  border-radius:7px;padding:0 8px;font-size:12.5px;margin-right:7px;font-weight:600}
.sent-text{word-break:keep-all}
/* 盲听提示 = 可点"显示原文"区域：虚线框 + 浅填充 + 手型（克制，不花哨）；字号固定不随聚焦大字放大 */
.sent-blind{display:inline-flex;align-items:center;vertical-align:middle;font-family:var(--font-ui);
  font-size:13.5px;line-height:1.4;color:var(--muted);background:var(--surface-3);
  border:1px dashed var(--line-strong);border-radius:var(--r-pill);padding:3px 12px;cursor:pointer;
  transition:border-color var(--dur-fast),color var(--dur-fast),background var(--dur-fast),transform var(--dur-fast)}
.sent-blind:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-wash)}
.sent-blind:active{transform:translateY(1px)}
.sent-done{display:none;color:var(--ok);margin-left:8px;vertical-align:-2px}
.sent-done svg{width:16px;height:16px}
.sent.done .sent-done{display:inline-flex}
.sent-zh{color:var(--accent-ink);font-size:14.5px;margin:4px 0 2px;padding-left:2px}

/* 正在播放的音浪指示（3 根跳动小柱） */
.eq{display:none;align-items:flex-end;gap:2px;height:14px;margin-left:8px;vertical-align:-2px}
.sent.playing .eq{display:inline-flex}
.eq i{width:3px;background:var(--accent);border-radius:2px;animation:eqb 1s ease-in-out infinite}
.eq i:nth-child(1){height:60%;animation-delay:0s}
.eq i:nth-child(2){height:100%;animation-delay:.2s}
.eq i:nth-child(3){height:75%;animation-delay:.4s}
@keyframes eqb{0%,100%{transform:scaleY(.4)}50%{transform:scaleY(1)}}

/* 彩带粒子 */
.confetti{position:fixed;width:8px;height:8px;border-radius:2px;pointer-events:none;z-index:99}

/* 工具按钮：情境自适应（聚焦=一体分段控件；列表=听/录音 + ▾折叠慢速·循环），触控高度 ≥40px */
.sent-tools{display:flex;flex-direction:column;gap:var(--s2);margin-top:10px}
.tb-row{display:flex;gap:var(--s2);flex-wrap:wrap;align-items:center}
.tb{display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--strong);
  border-radius:var(--r-md);height:44px;min-height:44px;padding:0 14px;font-size:var(--fs-md);
  font-weight:500;cursor:pointer;transition:border-color var(--dur-fast),color var(--dur-fast),background var(--dur-fast),transform var(--dur-fast)}
.tb-row.primary .tb{flex:1 1 88px;font-weight:600}
/* 播放分段组：列表模式 seg 透明（听独占，慢速/循环折叠）；聚焦模式（下方）为一体分段控件 */
.seg{display:contents}
.seg .tb{order:0}
.tb-row.primary>.rec{order:2}
.tb-row.primary>.more-toggle{order:3;flex:0 0 auto;width:46px;padding:0;color:var(--muted);font-size:var(--fs-lg)}
.sent-tools.more-open .more-toggle{transform:rotate(180deg);color:var(--accent-ink);border-color:var(--accent)}
/* 慢速/循环：列表折叠（more-open 展开为 mini 按钮，节点始终在 DOM，不影响 resetPlayButtons/clearLoop）。
   高度与主键一致（44px），消除原 40px 的 4px 落差。 */
.seg-extra{display:none;height:44px;min-height:44px;font-size:var(--fs-ms);font-weight:500}
/* 展开后：显示 + order:5 排到 ▾(order:3) 之后，靠 flex-wrap 落到主行下一行。
   order 必须写在这条更高权重的选择器上——基础 .seg-extra{order} 会被 .seg .tb{order:0} 压死成死代码。 */
.sent-tools.more-open .seg-extra{display:inline-flex;order:5}
/* 译文：原文显示后才出现的行尾小链接（盲听时 x-show 隐藏，不占位） */
.zh-link{display:inline-block;margin-left:8px;padding:0;border:none;background:none;
  color:var(--accent-ink);font-size:var(--fs-sm);cursor:pointer;vertical-align:1px}
.zh-link:active{color:var(--accent-ink)}
/* 收起：与「看译文」同款行尾小链接，色更淡以作区分（点=show=false 回盲听） */
.zh-link.collapse-link{color:var(--faint)}
.zh-link.collapse-link:active{color:var(--muted)}
.tb:hover{border-color:var(--accent);color:var(--accent-ink)}
.tb:active{transform:translateY(1px)}
.tb.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.tb.rec.on{background:var(--danger);border-color:var(--danger);color:var(--on-sem)}
/* 录音进行中拒绝切卡：让"停止"按钮抖一下作提示 */
@keyframes recShake{10%,90%{transform:translateX(-1px)}20%,80%{transform:translateX(2px)}
  30%,50%,70%{transform:translateX(-4px)}40%,60%{transform:translateX(4px)}}
.tb.rec.rec-shake{animation:recShake .5s cubic-bezier(.36,.07,.19,.97)}
.tb:disabled{opacity:.42;cursor:default}
.tb:disabled:hover{border-color:var(--line-strong);color:var(--strong)}
.rec-result{margin-top:9px}

/* 录音专注：原文可见时毛玻璃模糊 + 可点遮罩（点击临时揭开/再点重新模糊）；
   盲听中不强制显示，只给"看原文"救急按钮。模糊纯视觉层，不动 Alpine 的 show 状态。 */
.sent.rec-focus:not(.rec-revealed) .sent-text,
.sent.rec-focus:not(.rec-revealed) .sent-zh{filter:blur(5px);opacity:.5;
  transition:filter .2s,opacity .2s}
.rec-mask{position:absolute;inset:-3px -5px;z-index:3;display:flex;align-items:center;
  justify-content:center;border:none;border-radius:var(--r-sm);padding:0;cursor:pointer;
  background:var(--mask);-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}
.rec-mask-hint{font-size:12.5px;color:var(--muted);font-weight:600;letter-spacing:.2px}
/* F2: 揭开态遮罩只剩"再点一下重新模糊"的透明点击区，不再挂任何常驻标签——
   标签绝对定位在句行右上角，长句第一行文字会被压住（F1 的 34/44px 让位只避开了 ★，避不开文字）。
   提示改走一过性 toast（app.js applyRecFocus → korToast），零占位、零遮挡，深浅主题共用。
   ★ 仍靠 .starbtn 的 z-index:4 浮在遮罩（z3）之上，点星=收藏不受影响。 */
.sent.rec-revealed .rec-mask{background:transparent;-webkit-backdrop-filter:none;
  backdrop-filter:none}
.sent.rec-revealed .rec-mask-hint{display:none}
/* 盲听录音进行中：「点击显示原文」胶囊保持可点（点了正常揭示，录音继续）——已删去 rec-live 禁用与「看原文」救急钮 */

/* 识别中转圈 */
.asr-spin{display:inline-block;width:14px;height:14px;border:2px solid var(--line);
  border-top-color:var(--accent);border-radius:50%;vertical-align:-2px;margin-right:7px;
  animation:asrspin .7s linear infinite}
@keyframes asrspin{to{transform:rotate(360deg)}}
.retry-row{margin-top:7px}
.retry-row .tb{height:38px;min-height:38px;font-size:var(--fs-ms);padding:0 16px}

/* ASR 结果 */
.asr{border-radius:var(--r-sm);padding:10px 13px;font-size:var(--fs-ms);background:var(--surface-2)}
/* 达标块 = 成绩语义 → 金；不用"读对绿"，免得和逐词标注的绿混为一谈 */
.asr.pass{background:var(--award-wash);border-left:3px solid var(--award)}
.asr.fail{background:var(--warn-wash);border-left:3px solid var(--warn)}
.asr.err{background:var(--danger-wash);color:var(--danger-ink);display:flex;align-items:center;gap:8px}
.asr.err svg{width:18px;height:18px;flex:none}
.asr .score{display:inline-flex;align-items:center;gap:4px;font-weight:700;margin-right:8px;
  padding:2px 10px;border-radius:var(--r-pill);color:var(--on-sem);font-size:var(--fs-sm);
  font-variant-numeric:tabular-nums}
.asr .score svg{width:13px;height:13px}
/* 分数徽章 = 成绩 → 金底深墨字（金太浅，白字上去只有 3:1 出头，读不清） */
.asr .score.ok{background:var(--award);color:var(--on-award)}
.asr .score.low{background:var(--warn)}
.asr-heard{color:var(--muted);font-size:var(--fs-sm);margin-top:4px}
.retry-tip{color:var(--warn-ink);font-size:var(--fs-sm);margin-top:6px}
/* 精简结果块：分数徽章下的错误解释（仅有错时出现）/ 全对肯定语 */
.asr-explain{margin-top:5px;font-size:var(--fs-sm);line-height:1.65}
.asr-explain .ex-line{margin-top:1px;color:var(--muted)}
.asr-explain .ex-wrong{color:var(--danger-ink)}
.asr-explain .ex-missed{color:var(--warn-ink)}
.asr-ok-note{color:var(--ok-ink);font-size:var(--fs-sm)}

/* 逐词原句标注（多邻国式，令牌复用语义色，深浅主题自动适配；克制不花哨） */
.sent-text .w-ok{color:var(--ok-ink)}
.sent-text .w-wrong{color:var(--danger-ink);background:var(--danger-wash);
  border-radius:5px;padding:0 3px;
  text-decoration-line:underline;text-decoration-color:var(--danger);
  text-decoration-thickness:2px;text-underline-offset:3px}
.sent-text .w-missed{color:var(--warn-ink);opacity:.8;
  text-decoration-line:line-through;text-decoration-style:dashed;
  text-decoration-color:var(--warn);text-decoration-thickness:2px}

/* 折叠区 */
.fold{margin:6px 0;border-top:1px solid var(--line-2)}
.fold-h{width:100%;text-align:left;background:none;border:none;padding:11px 2px;
  font-size:14.5px;color:var(--ink);font-weight:600;cursor:pointer;
  display:flex;justify-content:space-between;align-items:center;gap:8px}
.fold-h .chev{color:var(--faint);font-size:var(--fs-xs);font-weight:500}
.fold-b{padding:2px 2px 12px;font-size:14.5px;color:var(--ink)}
.vocab,.gram,.sight{padding:8px 0;border-bottom:1px solid var(--line-2)}
.vocab:last-child,.gram:last-child,.sight:last-child{border-bottom:none}
.vocab .ko,.gram b{color:var(--ink);font-weight:650}
.rom{color:var(--muted);font-size:var(--fs-sm)}   /* 同 .rv-rom：罗马音是内容 */
.ex{color:var(--muted);font-size:var(--fs-sm);margin-top:3px}
.sight .s-zh{font-size:var(--fs-md)}
.sight .s-ko{margin-top:5px;color:var(--accent-ink)}
.mini{background:var(--accent-wash);border:none;border-radius:var(--r-sm);padding:4px 12px;
  font-size:12.5px;color:var(--accent-ink);font-weight:600;cursor:pointer;margin-top:6px}
.retell,.fluency{padding:6px 0;font-size:14.5px}
ul{padding-left:20px;margin:4px 0}

/* 按钮：主键带 3px 实心下沿（纸片被按下去的感觉）；暗色下 --btn-lift 换成外发光 */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  background:var(--accent);color:var(--on-accent);border:none;border-radius:var(--r-md);
  padding:11px 18px;font-size:var(--fs-md);cursor:pointer;font-weight:600;
  box-shadow:var(--btn-lift);
  transition:background var(--dur-fast),transform var(--dur-fast),box-shadow var(--dur-fast)}
.btn:hover{background:var(--accent-ink)}
.btn:active{transform:translateY(2px);box-shadow:var(--btn-lift-a)}
.btn.wide{width:100%;padding:14px;font-size:var(--fs-base)}

/* 打卡状态：打卡 / 全部完成都是"达标"语义 → 走琥珀金，不用答对绿 */
.checkin-wrap{margin:24px 0 8px}
.checkin-line{text-align:center;font-size:15.5px;font-weight:600;padding:14px;
  border-radius:var(--r);background:var(--surface-2);color:var(--strong);border:1px solid var(--line)}
.checkin-wrap.checked .checkin-line{background:var(--award-wash);color:var(--award-ink);border-color:var(--award-line)}
.checkin-wrap.complete .checkin-line{background:linear-gradient(120deg,var(--award),var(--award-deep));
  color:var(--on-award);border-color:transparent;box-shadow:var(--shadow-card)}
.checkin-hint{text-align:center;color:var(--faint);font-size:var(--fs-xs);margin-top:8px}
.empty{text-align:center;color:var(--muted);margin:56px 0}

/* 日历热力图 */
.cal-head h2{margin:16px 0 6px}
.cal-stats{display:flex;gap:18px;color:var(--muted);font-size:var(--fs-ms);flex-wrap:wrap;margin-bottom:6px}
.cal-stats b{color:var(--ink);font-variant-numeric:tabular-nums}
.heat-wrap{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r);
  padding:16px;margin:12px 0;overflow-x:auto;box-shadow:var(--shadow-card)}
.months{display:flex;gap:3px;margin-bottom:5px;font-size:10px;color:var(--faint);min-width:max-content}
.months .m{width:13px;flex:none;white-space:nowrap}
.heat{display:flex;gap:3px;min-width:max-content}
.wk{display:grid;grid-template-rows:repeat(7,13px);gap:3px}
.cell{width:13px;height:13px;border-radius:3px;background:var(--l0)}
.cell.empty{background:transparent}
.cell.l0{background:var(--l0)} .cell.l1{background:var(--l1)}
.cell.l2{background:var(--l2)} .cell.l3{background:var(--l3)} .cell.l4{background:var(--l4)}
/* 本周列轻微高亮 + 今天格蓝框（outline 不占位、不挤动网格） */
.wk.wk-current{background:var(--accent-wash);border-radius:4px}
.cell.today{outline:2px solid var(--accent);outline-offset:1px}
.legend{display:flex;align-items:center;gap:3px;justify-content:flex-end;margin-top:9px;
  font-size:11px;color:var(--faint)}
.legend .cell{display:inline-block}
.cal-tip{color:var(--faint);font-size:12.5px}

/* 词汇复习 */
.rv-head{display:flex;align-items:baseline;justify-content:space-between;margin:16px 0 4px;flex-wrap:wrap}
.rv-stats{color:var(--muted);font-size:var(--fs-ms)}
.rv-stats b{color:var(--ink);font-variant-numeric:tabular-nums}
.rv-progress{text-align:center;color:var(--faint);font-size:var(--fs-sm);margin:8px 0;font-variant-numeric:tabular-nums;scroll-margin-top:64px}
.rv-card{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-stage);padding:22px 20px;margin:10px 0 18px;text-align:center;min-height:96px;
  display:flex;flex-direction:column;justify-content:center}
/* 听音题：题面只有喇叭图标，卡片更矮 */
.rv-card--audio{min-height:80px}
.rv-word{font-size:var(--fs-4xl);font-weight:700;letter-spacing:-.5px;line-height:1.25}
.rv-word svg{width:44px;height:44px;color:var(--accent)}
/* 罗马音是"要读的内容"不是装饰，所以走 --muted（4.5:1+）而不是 --faint */
.rv-rom{color:var(--muted);font-size:var(--fs-ms)}
.rv-ex{color:var(--muted);font-size:var(--fs-md);margin-top:10px}
.rv-actions{max-width:460px;margin:0 auto}
.rv-rate{display:flex;gap:10px}
.rate{flex:1;border:1px solid var(--line-strong);background:var(--surface);border-radius:var(--r-md);
  padding:14px 0;font-size:var(--fs-md);font-weight:600;cursor:pointer;transition:transform var(--dur-fast)}
.rate.again{color:var(--danger-ink);border-color:var(--danger-line)}
.rate.good{color:var(--accent-ink);border-color:var(--accent-line)}
.rate.easy{color:var(--ok-ink);border-color:var(--ok-line)}
.rate:active{transform:translateY(1px)}
.rv-finish{text-align:center;color:var(--muted);margin:30px 0}
.rv-finish-title{font-size:var(--fs-xl);font-weight:700;color:var(--ok-ink)}
.rv-finish-line{font-size:var(--fs-md);margin:6px 0}

/* 复习模式 tab：手机上可横滑的 pill 行，当前项高亮，不换行不挤压 */
/* 外层容器：右缘渐隐提示"还能往右滑"（深浅主题走 --paper 令牌） */
.rv-tabs-wrap{position:relative}
.rv-tabs-wrap::after{content:"";position:absolute;top:0;bottom:0;right:0;width:26px;pointer-events:none;
  background:linear-gradient(to right,transparent,var(--paper))}
.rv-tabs{display:flex;gap:var(--s2);margin:14px 0 2px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;padding-bottom:2px}
.rv-tabs::-webkit-scrollbar{display:none}
.rv-tab{flex:0 0 auto;white-space:nowrap;border:1px solid var(--line-strong);background:var(--surface);
  border-radius:var(--r-pill);padding:8px 12px;font-size:13.5px;font-weight:600;color:var(--muted);
  cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.rv-tab.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.rv-tab:active{transform:translateY(1px)}
.rv-modetag{background:var(--accent-wash);color:var(--accent-ink);border-radius:var(--r-pill);
  padding:2px 10px;font-size:var(--fs-xs);font-weight:600}
.rv-modetag:empty{display:none}
.rv-next{max-width:460px;display:block;margin:14px auto 0}

/* 选择题 */
.quiz-opts{display:flex;flex-direction:column;gap:10px;max-width:460px;margin:0 auto}
.quiz-opt{border:1px solid var(--line-strong);background:var(--surface);border-radius:var(--r-md);
  padding:11px 16px;font-size:15.5px;text-align:left;cursor:pointer;color:var(--ink);
  transition:border-color var(--dur-fast),background var(--dur-fast),transform var(--dur-fast)}
/* 仅在真有悬停设备上应用 hover（手机 tap 会把 :hover 粘在选项上，下一题同位置显得"被预选"） */
@media (hover: hover){.quiz-opt:hover{border-color:var(--accent)}}
.quiz-opt:active{transform:translateY(1px)}
.quiz-opt:focus{outline:none}
.quiz-opt:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.quiz-opt.right{background:var(--ok-wash);border-color:var(--ok);color:var(--ok-ink);font-weight:600}
.quiz-opt.wrong{background:var(--danger-wash);border-color:var(--danger);color:var(--danger-ink)}
.quiz-opt:disabled{cursor:default;opacity:.92}
#quiz-next{max-width:460px;display:block;margin:14px auto 0}

/* 打字挑战 */
.type-start{max-width:460px;margin:20px auto;text-align:center}
.type-lead{font-size:var(--fs-base);font-weight:600}
.type-rules{text-align:left;color:var(--muted);font-size:var(--fs-ms);margin:12px 0 18px}
.type-top{display:flex;align-items:center;justify-content:space-between;margin:12px 0 6px}
.type-combo{background:var(--accent-wash);color:var(--accent-ink);font-weight:700;
  font-size:var(--fs-sm);padding:4px 11px;border-radius:var(--r-pill)}
.type-score{font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent-ink)}
.type-timer{height:6px;background:var(--surface-2);border-radius:var(--r-pill);overflow:hidden;margin-bottom:10px}
.type-tfill{height:100%;width:100%;background:linear-gradient(90deg,var(--ok),var(--award),var(--danger));
  background-size:300% 100%;background-position:left;transition:width .1s linear}
.type-card{padding:26px 20px;min-height:120px}
.type-zh{font-size:var(--fs-3xl);font-weight:700}
.type-ex{color:var(--muted);font-size:14.5px;margin-top:8px}
.type-hint{color:var(--warn-ink);font-size:14.5px;margin-top:10px;font-weight:600}
.type-answer{color:var(--accent-ink);font-size:var(--fs-2xl);font-weight:700;margin-top:12px}
.type-input{width:100%;max-width:460px;display:block;margin:0 auto;box-sizing:border-box;
  border:2px solid var(--line-strong);border-radius:var(--r-md);padding:13px 15px;font-size:var(--fs-xl);
  text-align:center;outline:none;background:var(--surface);color:var(--ink)}
.type-input:focus{border-color:var(--accent)}
.type-tools{display:flex;gap:10px;justify-content:center;margin-top:10px}
.type-note{text-align:center;font-size:14.5px;margin-top:10px;font-weight:600}
.type-note.ok{color:var(--ok-ink)}
.type-note.bad{color:var(--danger-ink)}

/* 录音环境自检 */
.diag-lead{color:var(--muted);font-size:14.5px}
.diag-list{margin:14px 0}
.diag-row{padding:10px 14px;border-radius:var(--r-md);margin:7px 0;font-size:14.5px;font-weight:500}
.diag-row.ok{background:var(--ok-wash);color:var(--ok-ink)}
.diag-row.bad{background:var(--danger-wash);color:var(--danger-ink)}
.diag-row.info{background:var(--accent-wash);color:var(--accent-ink)}
.diag-verdict{padding:13px 16px;border-radius:var(--r-md);font-size:var(--fs-md);font-weight:600;
  white-space:pre-wrap;word-break:break-all;margin-top:6px;line-height:1.65}
.diag-verdict.ok{background:var(--ok-wash);color:var(--ok-ink)}
.diag-verdict.bad{background:var(--warn-wash);color:var(--warn-ink)}
.diag-verdict:empty{display:none}

/* 复习动效：进牌/出牌/释义浮现 + 顶部进度 */
.rv-bar{height:6px;background:var(--surface-2);border-radius:var(--r-pill);overflow:hidden;margin:14px 0 4px}
#rv-fill,.rv-fill{height:100%;width:0;background:var(--accent);
  border-radius:var(--r-pill);transition:width var(--dur-slow) ease}
.rv-card.in{animation:cardIn .28s var(--ease)}
.rv-card.out{animation:cardOut .22s ease-in forwards}
@keyframes cardIn{from{opacity:0;transform:translateX(36px) scale(.97)}to{opacity:1;transform:none}}
@keyframes cardOut{to{opacity:0;transform:translateX(-46px) scale(.96)}}

/* ===== 底部拇指导航（固定底栏，全站） ===== */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;
  background:var(--chrome);-webkit-backdrop-filter:saturate(1.4) blur(10px);backdrop-filter:saturate(1.4) blur(10px);
  border-top:1px solid var(--line);padding-bottom:env(safe-area-inset-bottom,0)}
.tabbar a{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 0 7px;font-size:11.5px;color:var(--muted);text-decoration:none}
.tabbar a .ti{display:inline-flex;line-height:1}
.tabbar a .ti svg{width:22px;height:22px}
.tabbar a.on{color:var(--accent-ink);font-weight:600}
.tabbar a:active{background:var(--line-2)}

/* 模式切换钮已移到日期条右段（见 .daybar-end / .modetoggle），旧 .modebar 整行删除 */

/* ===== 顶部常驻今日进度（sticky 迷你条） ===== */
.miniprog{position:sticky;top:var(--topbar-h);z-index:15;display:flex;align-items:center;gap:10px;
  background:var(--chrome);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  padding:8px 6px 9px;margin:2px -4px 4px;border-radius:var(--r-sm)}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .miniprog{background:var(--paper)}
}
.miniprog-track{flex:1;height:8px;background:var(--surface-2);border-radius:var(--r-pill);overflow:hidden}
.miniprog-fill{height:100%;width:0;background:var(--accent);
  border-radius:var(--r-pill);transition:width .4s var(--ease)}
.miniprog-text{color:var(--muted);font-size:12.5px;font-weight:600;
  font-variant-numeric:tabular-nums;white-space:nowrap}

/* ===== 今日难度反馈（低调 pill，不抢打卡视觉；深浅双主题走令牌） ===== */
.difficulty{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s2);margin:6px 0 2px}
.diff-ask{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.diff-q{color:var(--muted);font-size:var(--fs-sm);margin-right:2px}
.diff-pill{border:1px solid var(--line-strong);background:var(--surface);color:var(--muted);
  border-radius:var(--r-pill);padding:4px 12px;font-size:var(--fs-sm);font-weight:600;cursor:pointer;
  transition:border-color var(--dur-fast),color var(--dur-fast),background var(--dur-fast),transform var(--dur-fast)}
.diff-pill:hover{border-color:var(--accent);color:var(--accent-ink)}
.diff-pill:active{transform:translateY(1px)}
.diff-pill:disabled{opacity:.5;cursor:default}
.diff-recorded{color:var(--muted);font-size:var(--fs-sm)}
.diff-chosen{font-weight:700}
.diff-chosen-hard{color:var(--warn-ink)}
.diff-chosen-ok{color:var(--accent-ink)}
.diff-chosen-easy{color:var(--ok-ink)}
.diff-err{color:var(--danger);font-size:var(--fs-xs);margin-left:6px}

/* ===== 学习资料总折叠（二级手风琴） ===== */
.fold.materials{margin-top:12px;border-top:2px solid var(--line)}
.fold.materials>.fold-h{font-size:var(--fs-md)}
.fold.materials .fold-b{padding-top:0}
.fold.materials .fold{margin:0}

/* ===== 聚焦练习模式 ===== */
.focus-head{display:none;margin:6px 0}
.fh-topic{font-size:var(--fs-ms);color:var(--muted);font-weight:600;margin-bottom:6px}
.fh-prog{display:flex;align-items:center;gap:10px}
.fh-count{font-size:12.5px;color:var(--faint);font-variant-numeric:tabular-nums;white-space:nowrap}
.fh-track{flex:1;height:7px;background:var(--surface-2);border-radius:var(--r-pill);overflow:hidden}
.fh-fill{height:100%;width:0;background:var(--accent);
  border-radius:var(--r-pill);transition:width var(--dur-slow) ease}
.focus-nav{display:none}
.fn-btn{flex:1;border:1px solid var(--line-strong);background:var(--surface);color:var(--accent-ink);
  border-radius:var(--r-md);padding:13px 0;font-size:var(--fs-md);font-weight:600;cursor:pointer;
  transition:transform var(--dur-fast)}
.fn-btn:disabled{opacity:.38;cursor:default}
.fn-btn:active{transform:translateY(1px)}

body.focus-mode .focus-head{display:block}
/* 底部导航贴住 tabbar（去掉 +12px 裂缝）；不透明面板 + 上边线，间距做进 padding */
body.focus-mode .focus-nav{position:fixed;left:0;right:0;
  bottom:calc(env(safe-area-inset-bottom,0px) + var(--tabbar-h));z-index:25;
  display:flex;align-items:center;gap:12px;max-width:720px;margin:0 auto;
  padding:10px 16px;background:var(--surface);border-top:1px solid var(--line)}
body.focus-mode .checkin-wrap{display:none}
body.focus-mode .topic{display:none}
body.focus-mode .topic.has-current{display:block;background:transparent;border:none;
  box-shadow:none;padding:0;margin:8px 0 0}
body.focus-mode .topic.has-current .topic-head,
body.focus-mode .topic.has-current .fold{display:none}
body.focus-mode .topic.has-current .sentences{margin:0}
body.focus-mode .topic.has-current .sent{display:none;border:none}
body.focus-mode .topic.has-current .sent.focus-current{display:block;
  background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-stage);padding:24px 20px}
body.focus-mode .topic.has-current .sent.focus-current.done{background:var(--ok-wash)}
/* 聚焦是"一次只念一句"的场景，韩文该更大更稳；字距 -.02em 让长句不散架 */
body.focus-mode .sent.focus-current .sent-line{font-size:21.5px;line-height:1.85;
  letter-spacing:-.02em;min-height:2em}
/* 聚焦模式两行按钮区：①听/慢速/循环 一体分段控件 ②录音独立最大键。
   原文改由盲听提示区点击 / 「收起」链接切换，不再占一整行（卡片明显变矮）。 */
/* 聚焦模式：分段控件占余量，右侧留给倍速徽标（flex:1 1 0 而非 100%，让徽标同行） */
body.focus-mode .seg{display:inline-flex;flex:1 1 0;order:0;gap:0;
  border:1px solid var(--line-strong);border-radius:var(--r-md);overflow:hidden;background:var(--surface)}
body.focus-mode .seg .tb{flex:1 1 0;border:none;border-radius:0;height:46px;min-height:46px;
  border-left:1px solid var(--line);font-weight:600}
body.focus-mode .seg .tb:first-child{border-left:none}
body.focus-mode .seg-extra{display:inline-flex}
body.focus-mode .more-toggle{display:none}
body.focus-mode .tb-row.primary>.rec{flex:1 1 100%;order:1;height:52px;min-height:52px;font-size:var(--fs-base)}
/* ASR 评分块（.rec-result 异步撑高）不被固定底部导航压住；卡片变矮后 140px 余量仍够 rec-result + 难度 widget 滚出 */
body.focus-mode main{padding-bottom:calc(env(safe-area-inset-bottom,0px) + var(--tabbar-h) + 140px)}

/* ===== 音节拼词 ===== */
.spell-card{padding:22px 18px}
.spell-slots{display:flex;flex-wrap:wrap;gap:var(--s2);justify-content:center;margin:18px 0 2px}
.spell-slot{min-width:48px;height:54px;padding:0 6px;display:flex;align-items:center;
  justify-content:center;font-size:var(--fs-3xl);font-weight:700;border-radius:var(--r-md)}
.spell-slot.blank{border:2px dashed var(--line-strong);color:var(--ink);background:var(--surface)}
.spell-slot.blank.filled{border-style:solid;border-color:var(--accent);
  background:var(--accent-wash);color:var(--accent-ink);cursor:pointer}
.spell-slot.fixed{color:var(--muted)}
.spell-slot.right{border:2px solid var(--ok);background:var(--ok-wash);color:var(--ok-ink)}
.spell-slot.wrong{border:2px solid var(--danger);background:var(--danger-wash);color:var(--danger-ink)}
.spell-pool{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;max-width:460px;margin:12px auto 0}
.spell-block{min-width:54px;height:56px;padding:0 8px;font-size:var(--fs-3xl);font-weight:700;
  border:1px solid var(--line-strong);background:var(--surface);border-radius:var(--r-md);cursor:pointer;
  transition:border-color var(--dur-fast),background var(--dur-fast),transform var(--dur-fast),opacity var(--dur-fast)}
.spell-block:active{transform:translateY(1px)}
.spell-block.used{opacity:0;pointer-events:none}
.spell-block.hintlit{border-color:var(--warn);background:var(--warn-wash);
  box-shadow:0 0 0 3px var(--warn-wash)}
.spell-tools{display:flex;justify-content:center;margin-top:16px}

/* ===== 配对消除（连连看）===== */
.match-top{display:flex;align-items:center;justify-content:space-between;
  margin:14px 0 8px;font-size:13.5px;color:var(--muted)}
.match-time{font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent-ink)}
.match-miss b{color:var(--danger)}
.match-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.match-tile{min-height:62px;border:1px solid var(--line-strong);background:var(--surface);border-radius:var(--r-md);
  padding:10px 8px;font-size:var(--fs-md);font-weight:600;cursor:pointer;display:flex;color:var(--ink);
  align-items:center;justify-content:center;text-align:center;word-break:break-all;
  transition:border-color var(--dur-fast),background var(--dur-fast),color var(--dur-fast),transform var(--dur-fast)}
.match-tile.ko{font-size:19px}
.match-tile:active{transform:translateY(1px)}
.match-tile.sel{border-color:var(--accent);background:var(--accent-wash);color:var(--accent-ink)}
.match-tile.matched{border-color:var(--ok);background:var(--ok-wash);color:var(--ok-ink)}
.match-tile.miss{border-color:var(--danger);background:var(--danger-wash);color:var(--danger-ink);animation:matchShake .4s}
@keyframes matchShake{10%,90%{transform:translateX(-2px)}30%,70%{transform:translateX(4px)}
  50%{transform:translateX(-4px)}}

/* ===== R6 ★ 收藏钮（幽灵星：空心→金色实心；设计稿 40×40 触达 / svg 22 / stroke 1.7） ===== */
.starbtn{border:none;background:none;cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;color:var(--faint);
  transition:transform var(--dur-fast),color var(--dur-fast)}
.starbtn svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linejoin:round;transition:fill var(--dur-fast),stroke var(--dur-fast)}
.starbtn.on{color:var(--gold)}
.starbtn.on svg{fill:var(--gold);stroke:var(--gold)}
.starbtn:active{transform:scale(.88)}
/* 列表模式：句行尾同款小星（行内，不占按钮行）。
   S5: position:relative + z-index:4 把星提到录音遮罩（.rec-mask z3）之上——录音期间点星=收藏（不再被遮罩吞成"揭开/重新模糊"）；
   relative 不脱流，vertical-align:-9px 的行内基线不受影响，与聚焦模式（z4）行为一致。 */
.sent-line .starbtn{width:32px;height:32px;vertical-align:-9px;margin-left:2px;position:relative;z-index:4}
.sent-line .starbtn svg{width:18px;height:18px}
/* 聚焦模式：卡右上角 40×40 幽灵星（借 .sent-line 的 relative 定位到卡角：
   卡 padding 24px/20px，-16/-12 偏移 = 距卡缘 8px，与设计稿一致）；行尾留白防文字压星 */
body.focus-mode .sent.focus-current .sent-line{padding-right:36px}
body.focus-mode .sent.focus-current .sent-line .starbtn{position:absolute;top:-16px;right:-12px;
  width:40px;height:40px;margin:0;z-index:4}
body.focus-mode .sent.focus-current .sent-line .starbtn svg{width:22px;height:22px}
/* F1（聚焦模式）：卡右上角为 ★ 专属（40px 贴角）——后续再往卡右上角新增任何角元素，
   一律向左让位、不与 ★ 抢角。（F2 起揭开态遮罩已无常驻标签，原 padding-right:44px 让位规则随之删除。） */

/* ===== R6 句子本页（收藏 + 错句本，样式规格照搬设计稿 C） ===== */
.page-sub{color:var(--muted);font-size:var(--fs-ms);margin:0 0 8px}
/* 分区 pill（收藏 / 错句） */
.seg-tabs{display:flex;gap:8px;margin:12px 0 10px}
.seg-tab{flex:0 0 auto;border:1px solid var(--line-strong);background:var(--surface);
  border-radius:var(--r-pill);padding:8px 16px;font-size:13.5px;font-weight:600;color:var(--muted);
  cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast)}
.seg-tab.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.seg-tab:active{transform:translateY(1px)}
.seg-tab .n{font-variant-numeric:tabular-nums;opacity:.85;margin-left:3px}
/* 收藏卡 */
.bk-card{position:relative;background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-card);padding:14px 16px;margin:10px 0;transition:opacity var(--dur)}
.bk-card.unstarred{opacity:.45}
.bk-card .starbtn{position:absolute;top:6px;right:6px;width:40px;height:40px}
.bk-ko{font-family:var(--font-ko);font-size:17px;line-height:1.75;word-break:keep-all;
  padding-right:40px;color:var(--ink)}
.bk-zh{color:var(--muted);font-size:14px;margin-top:3px}
.bk-meta{display:flex;align-items:center;gap:10px;margin-top:10px}
.bk-src{flex:1;min-width:0;color:var(--faint);font-size:12px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.bk-src .ko{font-family:var(--font-ko)}
.bk-card .tb{height:36px;min-height:36px;padding:0 13px;font-size:13.5px;border-radius:var(--r-sm)}
.unstar-note{font-size:11.5px;color:var(--faint);margin-top:8px}
/* 错句卡 */
.wr-card{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-card);padding:14px 16px;margin:10px 0}
.wr-ko{font-family:var(--font-ko);font-size:17px;line-height:1.85;word-break:keep-all;color:var(--ink)}
.wr-ko .w-wrong{color:var(--danger-ink);background:var(--danger-wash);border-radius:5px;padding:0 3px;
  text-decoration:underline wavy var(--danger);text-decoration-thickness:2px;text-underline-offset:4px}
.wr-ko .w-missed{color:var(--warn-ink);background:var(--warn-wash);border-radius:5px;padding:0 3px;
  text-decoration:line-through dashed var(--warn);text-decoration-thickness:2px}
.wr-meta{display:flex;align-items:center;gap:8px;margin-top:8px;flex-wrap:wrap}
.wr-when{color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums}
.wr-badge{margin-left:auto;font-weight:700;font-size:12.5px;padding:2px 10px;border-radius:var(--r-pill);
  color:var(--on-sem);font-variant-numeric:tabular-nums}
.wr-badge.low{background:var(--warn)} .wr-badge.bad{background:var(--danger)}
.wr-diag{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.wr-chip{font-size:12px;border-radius:var(--r-pill);padding:2px 10px;font-family:var(--font-ko);word-break:keep-all}
.wr-chip.c-wrong{background:var(--danger-wash);color:var(--danger-ink)}
.wr-chip.c-missed{background:var(--warn-wash);color:var(--warn-ink)}
.wr-act{display:flex;gap:8px;margin-top:11px}
.wr-go{flex:1;display:flex;align-items:center;justify-content:center;border:1px solid var(--accent-line);
  background:var(--accent-wash);color:var(--accent-ink);border-radius:var(--r-sm);height:38px;
  font-size:13.5px;font-weight:600;cursor:pointer;text-decoration:none}
.wr-go:active{transform:translateY(1px)}

/* ===== 低分录音抽检页（/asr_review）=====
   卡片骨架直接复用错句卡 .wr-*（同一套逐词标注色 + 错词 chip），
   这里只加：统计条 / 识别文本行 / 原始录音播放器 / 三选一结论按钮。 */
.ar-stats{display:flex;gap:18px;color:var(--muted);font-size:var(--fs-ms);flex-wrap:wrap;margin:10px 0 14px}
.ar-stats b{color:var(--ink);font-variant-numeric:tabular-nums}
.ar-head{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.ar-when{color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums}
.ar-head .wr-badge{margin-left:auto}
/* 识别文本：与原句同一字体，但压一档字号/色，一眼看出"这是机器听到的" */
.ar-asr{display:flex;gap:8px;align-items:baseline;margin-top:9px;font-size:var(--fs-ms);
  color:var(--muted);line-height:1.7}
.ar-asr .ko{font-family:var(--font-ko);word-break:keep-all;flex:1;min-width:0}
.ar-tag{flex:none;font-size:var(--fs-xs);font-weight:600;padding:1px 8px;border-radius:var(--r-pill);
  background:var(--surface-2);color:var(--muted);border:1px solid var(--line)}
/* color-scheme 只加在播放器本身：Chrome 的原生控件配色跟它走，夜读皮肤下才不会杵着一条白条。
   不写在 :root —— 那会顺带改掉全站的滚动条/表单控件配色，超出这一页的范围。 */
.ar-audio{display:block;width:100%;height:34px;margin-top:11px;color-scheme:light dark}
.ar-noaudio{margin-top:11px;font-size:12.5px;color:var(--faint)}
.ar-verdict{display:flex;gap:8px;margin-top:11px}
.ar-vb{flex:1;height:38px;border-radius:var(--r-sm);cursor:pointer;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--muted);
  font-size:13.5px;font-weight:600;font-family:var(--font-ui);
  transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast)}
.ar-vb:active{transform:translateY(1px)}
.ar-vb:disabled{opacity:.6;cursor:default}
/* 选中态：我读错了 = 琥珀提醒；它听错了 = 红（机器的锅）；不确定 = 中性强调 */
.ar-vb.v-me.on{background:var(--warn-wash);border-color:var(--warn-line);color:var(--warn-ink)}
.ar-vb.v-asr.on{background:var(--danger-wash);border-color:var(--danger-line);color:var(--danger-ink)}
.ar-vb.v-unsure.on{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-ink)}
.wr-chip.c-extra{background:var(--accent-wash);color:var(--accent-ink)}

/* ===== 轻 toast（收藏反馈；JS 按需创建 #kor-toast） ===== */
.toast{position:fixed;left:50%;transform:translateX(-50%) translateY(8px);
  bottom:calc(env(safe-area-inset-bottom,0px) + var(--tabbar-h) + 20px);z-index:40;
  background:var(--ink);color:var(--paper);font-size:13px;font-weight:600;
  border-radius:var(--r-pill);padding:8px 18px;opacity:0;pointer-events:none;
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease);white-space:nowrap}
.toast.show{opacity:.94;transform:translateX(-50%) translateY(0)}
/* 聚焦模式底部还压着 .focus-nav（上/下一句，约 66px 高）→ toast 再抬高，别骑在按钮上 */
body.focus-mode .toast{bottom:calc(env(safe-area-inset-bottom,0px) + var(--tabbar-h) + 82px)}

/* ============================================================
   R1 倍速 / R2 语法着色 / R5 双语 · 设置面板（忠实设计稿 A v2）
   ============================================================ */

/* — R2 六色语法成分令牌（色值原样搬自设计稿；浅色 + 深色两套）+ 设置面板遮罩 — */
:root{
  --g-subj:#DAE6F0; --g-obj:#D2EAE6; --g-verb:#F6DFE4;
  --g-mod:#F7E9C6; --g-conn:#E4DEF0; --g-etc:#E9E8D9;
  --scrim:rgba(47,51,43,.42);
}
@media (prefers-color-scheme:dark){
  :root{
    --g-subj:#223A50; --g-obj:#16414A; --g-verb:#452436;
    --g-mod:#41341C; --g-conn:#32294D; --g-etc:#1F2C34;
    --scrim:rgba(0,0,0,.6);
  }
}

/* — R2 语法块底色：默认与纯文本无异，仅 body.grammar-on 时上淡底色；圆角 3px、块内 keep-all — */
.gc{word-break:keep-all}
body.grammar-on .sent-text .gc{border-radius:3px;padding:1px 2px;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;
  transition:background var(--dur) var(--ease)}
body.grammar-on .sent-text .gc-subj{background:var(--g-subj)}
body.grammar-on .sent-text .gc-obj{background:var(--g-obj)}
body.grammar-on .sent-text .gc-verb{background:var(--g-verb)}
body.grammar-on .sent-text .gc-mod{background:var(--g-mod)}
body.grammar-on .sent-text .gc-conn{background:var(--g-conn)}
body.grammar-on .sent-text .gc-etc{background:var(--g-etc)}
/* 双通道共存：着色开时录音正误只走线条/字色通道，块底色透出（着色关时保持现网背景样式，逐字节一致） */
body.grammar-on .sent-text .w-wrong,
body.grammar-on .sent-text .w-missed{background:transparent;padding:0;border-radius:0}

/* — R2 图例：仅着色开启时出现的「图例 ?」小链，点开就地展开 6 色图例，可收起 — */
.gram-legend{margin:4px 0 2px}
.leg-link{display:inline-block;padding:2px 0;border:none;background:none;
  color:var(--faint);font-size:var(--fs-xs);cursor:pointer;text-decoration:underline dotted;
  text-underline-offset:3px;font-family:var(--font-ui)}
.leg-link:active{color:var(--muted)}
.glegend{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:6px;padding:8px 0 2px;border-top:1px solid var(--line-2)}
.gl{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);white-space:nowrap}
.gl i{width:14px;height:14px;border-radius:4px;flex:none}
.gl.i-subj i{background:var(--g-subj)} .gl.i-obj i{background:var(--g-obj)} .gl.i-verb i{background:var(--g-verb)}
.gl.i-mod i{background:var(--g-mod)} .gl.i-conn i{background:var(--g-conn)} .gl.i-etc i{background:var(--g-etc)}

/* — 顶栏设置齿轮 — */
.gearbtn{width:36px;height:36px;border:none;background:none;border-radius:50%;color:var(--muted);
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:background var(--dur-fast),color var(--dur-fast),transform var(--dur-slow) var(--ease)}
.gearbtn:hover{background:var(--line-2);color:var(--accent-ink)}
.gearbtn:active{transform:rotate(40deg)}
.gearbtn svg{width:21px;height:21px}

/* — 设置面板（bottom sheet）：遮罩 + 圆角把手 + 两开关 — */
.sheet-mask{position:fixed;inset:0;z-index:40;background:var(--scrim);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease)}
.sheet-mask.in{opacity:1;pointer-events:auto}
.settings-sheet{position:fixed;left:0;right:0;bottom:0;z-index:41;max-width:720px;margin:0 auto;
  background:var(--surface);border:1px solid var(--line);border-bottom:none;
  border-radius:var(--r-lg) var(--r-lg) 0 0;box-shadow:var(--shadow-stage);
  padding:8px 20px calc(env(safe-area-inset-bottom,0px) + 18px);
  transform:translateY(105%);transition:transform var(--dur-slow) var(--ease)}
.settings-sheet.in{transform:none}
.grab{width:36px;height:4px;border-radius:2px;background:var(--line-strong);margin:4px auto 8px}
.sheet-head{display:flex;align-items:center;justify-content:space-between;padding:2px 0 6px}
.sheet-title{font-size:var(--fs-md);font-weight:700}
.sheet-close{border:none;background:none;color:var(--faint);font-size:17px;cursor:pointer;
  width:34px;height:34px;border-radius:50%;line-height:1}
.sheet-close:hover{background:var(--line-2)}
.sw-row{display:flex;align-items:flex-start;gap:14px;padding:13px 0;border-top:1px solid var(--line-2)}
.sw-main{flex:1;min-width:0}
.sw-name{font-size:var(--fs-md);font-weight:650;color:var(--ink)}
.sw-desc{font-size:12.5px;color:var(--muted);line-height:1.55;margin-top:1px}
.tgl{flex:none;width:48px;height:28px;border-radius:var(--r-pill);border:1px solid var(--line-strong);
  background:var(--surface-2);position:relative;cursor:pointer;margin-top:2px;padding:0;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.tgl::after{content:"";position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25);transition:left var(--dur) var(--ease)}
.tgl.on{background:var(--accent);border-color:var(--accent)}
.tgl.on::after{left:23px}
/* 设置面板里的「跳转」行（开关之外的第二种右侧控件，如录音抽检入口）：与 .tgl 同高，纸片按钮质感 */
.sw-link{flex:none;display:inline-flex;align-items:center;height:28px;padding:0 13px;
  border-radius:var(--r-pill);border:1px solid var(--accent-line);background:var(--accent-wash);
  color:var(--accent-ink);font-size:13px;font-weight:600;text-decoration:none;white-space:nowrap}
.sw-link:active{transform:translateY(1px)}

/* — 难度三档（입문 / 초급 / 중급）：设置面板顶部的三选一 —
   与 .sp（倍速四档）同一套 pill 语言，只是每格两行（韩文档名 + 中文），够大好点（44px 触控） */
.lv-block .sw-main{width:100%}
.lv-pills{display:flex;gap:8px;margin-top:10px}
.lv{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--muted);
  border-radius:var(--r-md);height:52px;min-height:52px;cursor:pointer;padding:0 4px;
  transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.lv:active{transform:translateY(1px)}
.lv[disabled]{opacity:.55;cursor:default}
.lv.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.lv-ko{font-size:15px;font-weight:700;line-height:1.1}
.lv-zh{font-size:11px;opacity:.78;line-height:1.1}
.lv-desc{font-size:12.5px;color:var(--muted);line-height:1.55;margin-top:8px}

/* — 升档建议确认框：居中卡片（不是 bottom sheet——它是个必须回答的问题，不该像面板一样滑走） — */
.lv-mask{position:fixed;inset:0;z-index:60;background:var(--scrim);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease)}
.lv-mask.in{opacity:1;pointer-events:auto}
.lv-dialog{position:fixed;z-index:61;left:50%;top:50%;transform:translate(-50%,-46%);
  width:min(380px,calc(100vw - 44px));background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-stage);padding:20px 20px 16px;
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
.lv-dialog.in{opacity:1;pointer-events:auto;transform:translate(-50%,-50%)}
.lv-dlg-title{font-size:var(--fs-lg);font-weight:700;color:var(--ink)}
.lv-dlg-body{font-size:13.5px;color:var(--muted);line-height:1.65;margin:8px 0 16px}
.lv-dlg-body b{color:var(--ink)}
.lv-dlg-acts{display:flex;gap:10px}
.lv-dlg-acts button{flex:1;height:42px;border-radius:var(--r-pill);font-size:14px;font-weight:600;cursor:pointer}
.lv-dlg-no{border:1px solid var(--line-strong);background:var(--surface);color:var(--muted)}
.lv-dlg-yes{border:1px solid var(--accent);background:var(--accent);color:var(--on-accent)}
.lv-dlg-acts button:active{transform:translateY(1px)}

/* — R1 倍速徽标（chip）：默认列表模式收进 ▾ 展开行，聚焦模式贴分段控件右侧常显 — */
.spbadge{flex:none;min-width:52px;height:44px;min-height:44px;padding:0 8px;
  border:1px solid var(--line-strong);border-radius:var(--r-md);background:var(--surface);color:var(--muted);
  font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;cursor:pointer;
  display:none;align-items:center;justify-content:center;
  transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.spbadge:active{transform:translateY(1px)}
.spbadge.hot{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.spbadge.open{border-color:var(--accent);color:var(--accent-ink)}
.spbadge.hot.open{color:var(--on-accent)}
/* 列表模式：徽标随慢速/循环一起收进 ▾ 展开行（more-open 才现，排在最后） */
.sent-tools.more-open .spbadge{display:inline-flex;order:6}
/* 聚焦模式：徽标常显，贴 seg 右侧，同高 46px */
body.focus-mode .spbadge{display:inline-flex;order:0;height:46px;min-height:46px;min-width:54px}
/* 倍速四档行：点徽标滑出、选完自动收回 */
.sp-pills{display:none;gap:6px;overflow:hidden;margin-top:2px}
.sp-pills.open{display:flex;animation:spDrop var(--dur) var(--ease)}
@keyframes spDrop{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
.sp{flex:1;border:1px solid var(--line-strong);background:var(--surface);color:var(--muted);
  border-radius:var(--r-pill);height:38px;min-height:38px;font-size:13px;font-weight:600;cursor:pointer;
  font-variant-numeric:tabular-nums;transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.sp:active{transform:translateY(1px)}
.sp.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

/* ===== 动效克制：尊重系统"减少动态效果" ===== */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* ============================================================
   R7 点词看意思 · 可点词节 + 词典卡（bottom sheet）
   —— 纯追加的新规则块，未改动本文件既有任何一行（与并行的录音/复习改动零冲突）。
   设计语言对齐：设置面板 .settings-sheet（圆角 + 把手 + 滑入，.grab/.sheet-close 直接复用）
   与复习页 .rv-panel（毛玻璃 + @supports 不透明兜底）。深浅双主题全走既有 token。
   ============================================================ */

/* — 可点词节（어절）：默认零装饰，不打扰跟读阅读；按下/选中才给反馈。
     .tw 是服务端渲染的词节 span；录音标注重建后 token span 没有 .tw，
     故选中态 .tw-on 不与 .tw 绑定，两种结构通用。 — */
.sent-text .tw{cursor:pointer;border-radius:4px;padding:0 1px;margin:0 -1px;
  -webkit-tap-highlight-color:transparent;
  transition:background var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
@media (hover:hover){.sent-text .tw:hover{background:var(--line-2)}}
.sent-text .tw:active{background:var(--accent-wash)}
.sent-text .tw-on{background:var(--accent-wash);border-radius:4px;
  box-shadow:inset 0 -2px 0 var(--accent-line)}

/* — 遮罩：独立于设置面板的 #sheet-mask，互不干扰（层级更高，压住 tabbar 的 z-index:30）。
     刻意**不吃点击**（pointer-events 恒 none）：查词典本就是一个词接一个词地点，
     卡开着还能直接点下一个词就地换内容；"点卡外区域关卡"由 app.js 的文档级委托实现。
     因此压暗也做得比设置面板的模态遮罩轻（opacity .55），示意聚焦而非"锁屏" — */
.dict-mask{position:fixed;inset:0;z-index:42;background:var(--scrim);
  opacity:0;pointer-events:none;transition:opacity var(--dur) var(--ease)}
.dict-mask.in{opacity:.55}

/* — 词典卡本体：底部滑入，长释义/长例句卡内滚动（overscroll-behavior 防滚动穿透）— */
.dictsheet{position:fixed;left:0;right:0;bottom:0;z-index:43;max-width:720px;margin:0 auto;
  background:var(--chrome);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);
  border:1px solid var(--line);border-bottom:none;border-radius:var(--r-lg) var(--r-lg) 0 0;
  box-shadow:var(--shadow-stage);
  padding:8px 20px calc(env(safe-area-inset-bottom,0px) + 18px);
  max-height:70vh;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  transform:translateY(105%);transition:transform var(--dur-slow) var(--ease)}
.dictsheet.in{transform:none}
/* 不支持 backdrop-filter 的旧 WebView：退不透明底，绝不透叠（同 review.css 的兜底思路） */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .dictsheet{background:var(--surface)}
}

/* — 卡头：词（原形）+ 罗马音 | 发音 | 关闭 — */
.dict-head{display:flex;align-items:flex-start;gap:8px;padding:2px 0 0}
.dict-title{flex:1;min-width:0}
.dict-word{font-family:var(--font-ko);font-size:var(--fs-2xl);font-weight:700;line-height:1.3;
  color:var(--ink);word-break:keep-all}
.dict-rom{color:var(--muted);font-size:var(--fs-sm);margin-top:1px;letter-spacing:.2px}
/* .dict-surface 是原文形态（韩文内容），同理从 --faint 提到 --muted，见下方规则 */
.dict-spk{flex:none;width:38px;height:38px;border-radius:50%;border:1px solid var(--line-strong);
  background:var(--surface);color:var(--muted);cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background var(--dur-fast),color var(--dur-fast),border-color var(--dur-fast)}
.dict-spk svg{width:19px;height:19px}
.dict-spk:hover{border-color:var(--accent);color:var(--accent-ink)}
.dict-spk.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

/* — 卡身：原文形态 / 释义 / 例句 / 未收录提示 — */
.dict-surface{font-family:var(--font-ko);font-size:var(--fs-sm);color:var(--muted);margin-top:6px}
.dict-zh{font-size:var(--fs-lg);font-weight:650;color:var(--ink);line-height:1.5;margin-top:8px}
.dict-zh.dict-dim{font-size:var(--fs-md);font-weight:500;color:var(--muted)}
.dict-ex{font-family:var(--font-ko);font-size:var(--fs-md);color:var(--strong);line-height:1.7;
  margin-top:10px;padding:9px 12px;background:var(--surface-3);border-radius:var(--r-sm);
  word-break:keep-all}
/* 未收录时的形态素分析兜底（「분석: 뉴욕 · 고유명사 专有名词」）：韩文内容，比 hints 略重一档，
   让"词典没收但认得出是什么词"这件事看得见；与 .dict-hints 同列，不抢释义行的位置。 */
.dict-ana{font-family:var(--font-ko);font-size:var(--fs-ms);color:var(--strong);margin-top:8px;
  padding:6px 11px;background:var(--surface-3);border-radius:var(--r-sm);word-break:keep-all}
.dict-hints{font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:8px}

/* — 卡脚：来源标记 + 加入复习 — */
.dict-foot{display:flex;align-items:center;gap:10px;margin-top:14px}
.dict-src{flex:none;font-size:var(--fs-xs);font-weight:600;padding:3px 10px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface-2);color:var(--muted)}
.dict-src.src-today{color:var(--accent-ink);background:var(--accent-wash);border-color:var(--accent-line)}
.dict-src.src-deck{color:var(--ok-ink);background:var(--ok-wash);border-color:var(--ok-line)}
.dict-src.src-dict{color:var(--warn-ink);background:var(--warn-wash);border-color:var(--warn-line)}
.dict-add{margin-left:auto;height:42px;min-height:42px;padding:0 18px;border-radius:var(--r-pill);
  box-shadow:var(--btn-lift);
  border:1px solid var(--accent);background:var(--accent);color:var(--on-accent);
  font-size:var(--fs-ms);font-weight:600;cursor:pointer;
  transition:transform var(--dur-fast),background var(--dur-fast),color var(--dur-fast)}
.dict-add:active{transform:translateY(2px);box-shadow:var(--btn-lift-a)}
.dict-add.done,.dict-add:disabled{background:var(--surface-2);border-color:var(--line-strong);
  color:var(--muted);cursor:default;box-shadow:none}

/* ---- 录音上传的失败分类块 & 耗时小字（2026-07-27 录音提速线新增，只服务 .asr 结果块）---- */
/* .asr.err 基础样式是 display:flex（图标+一行字）；分类失败块要放"消息 + 两颗按钮"两行，故改块级 */
.asr.err.asr-net{display:block}
.asr.err.asr-net .asr-err-msg{display:block;line-height:1.6}
.asr.err.asr-net .retry-row{display:flex;gap:8px}
/* 只在这次真的慢（≥3.5s）时出现：告诉用户耗时花在网络上传还是识别，省得反复猜"是不是网络问题" */
.asr-timing{color:var(--muted);font-size:var(--fs-sm);margin-top:6px;opacity:.85}

/* ==== [译文对齐线 2026-08-01] 起 —— 本块仅一条 .zh-none 规则，勿与其它并行改动混用 ==== */
/* s.zh 为空（中韩句数对不齐、三级降级后仍无译文）时替代「看译文」链接的占位：
   同款行尾小字，灰、不可点——让"没有译文"是个明确状态，而不是一片空白。 */
.zh-none{display:inline-block;margin-left:8px;font-size:var(--fs-sm);color:var(--faint);
  vertical-align:1px;cursor:default;user-select:none}
/* ==== [译文对齐线 2026-08-01] 止 ==== */

/* ============================================================
   开屏 overlay（_splash.html）—— 本轮唯一新增的界面
   —— 纯展示层：不新增路由、不碰任何既有 JS 函数、不参与任何学习状态。
   版式照 docs/design/2026-08-04_ui-redesign-round2.html §01：
   句块垂直居中（core 带 30px 下补白 → 视觉重心略高于几何中点）、
   顶部一行日期、底部一行提示 + 呼吸圆环、整屏可点、无按钮。
   样机是 268px 宽的缩略机身，这里按真机 ~390px 等比放大了字号
   （样机 9px ≈ 真机 12.5px），圆环仍按设计稿写死 15px。
   ============================================================ */
.splash{position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:0 26px;
  background-color:var(--paper);background-image:var(--paper-tex);
  background-size:var(--paper-tex-size);background-repeat:var(--paper-tex-repeat);
  color:var(--ink);cursor:pointer;-webkit-tap-highlight-color:transparent;
  opacity:1;transition:opacity var(--dur-slow) var(--ease)}
.splash.out{opacity:0;pointer-events:none}
.splash:focus{outline:none}          /* 整屏就是按钮，描个框反而突兀 */
.splash-top{position:absolute;top:calc(env(safe-area-inset-top,0px) + 18px);left:0;right:0;
  font-family:var(--font-ko);font-size:12px;letter-spacing:.13em;color:var(--faint);font-weight:600}
.splash-core{width:100%;max-width:520px;padding-bottom:30px}
/* 全屏唯一的一点强调色：句子上方那道 40px 短横 */
.splash-orn{width:40px;height:2px;border-radius:2px;background:var(--accent);opacity:.45;margin:0 auto 22px}
/* 花体只出现在这一处（白天钢笔 / 夜里毛笔，随 --font-script 切换） */
.splash-q{font-family:var(--font-script);font-weight:400;font-size:clamp(28px,8.6vw,40px);
  line-height:1.34;letter-spacing:.005em;word-break:keep-all;text-wrap:balance;
  margin:0;color:var(--splash-ink)}
.splash-zh{font-family:var(--font-ui);font-size:15px;color:var(--muted);margin-top:16px;line-height:1.6}
.splash-src{font-size:12.5px;color:var(--faint);margin-top:12px;letter-spacing:.05em}
.splash-streak{font-size:13px;color:var(--faint);margin-top:22px;font-variant-numeric:tabular-nums}
.splash-tap{position:absolute;bottom:calc(env(safe-area-inset-bottom,0px) + 26px);left:0;right:0;
  font-family:var(--font-ko);font-size:12.5px;color:var(--faint);letter-spacing:.02em;
  animation:splashBreath 3.2s ease-in-out infinite}
.splash-tap::before{content:"";display:block;width:15px;height:15px;border-radius:50%;
  border:1px solid var(--faint);opacity:.4;margin:0 auto 9px;
  animation:splashRipple 3.2s ease-in-out infinite}
@keyframes splashBreath{0%,100%{opacity:.72}50%{opacity:1}}
@keyframes splashRipple{0%,100%{transform:scale(.86);opacity:.28}50%{transform:scale(1.06);opacity:.5}}
/* 开屏期间锁滚动（JS 往 <html> 和 <body> 都加这个类：
   脚本在 body 顶部同步执行时 document.body 可能还没解析出来） */
html.splash-on,body.splash-on{overflow:hidden}

/* ============================================================
   新手引导（just-in-time）+ 定级测试
   —— 纯追加的规则块，未改动本文件既有任何一行。
   设计语言对齐：气泡走 .toast 的反色墨底（同一种"系统在跟你说话"的语气），
   卡片走 .heat-wrap / .settings-sheet 的纸片 / 玻璃质感。深浅双主题全走既有令牌，
   没有一处写死色值 —— 暗色下 --ink 是浅色、--paper 是深色，气泡自动反过来。
   ============================================================ */

/* — 引导气泡：贴着某个控件说一句话，点屏幕任意处消失。没有按钮、没有遮罩、没有"第 N 步"。
     层级 44：压得住底部 tab(30) 与设置遮罩(40)，但让开档位确认框(60/61) —— 那是必须回答的问题。 */
.onb-bubble{position:fixed;z-index:44;max-width:min(300px,calc(100vw - 24px));
  background:var(--ink);color:var(--paper);font-size:13px;font-weight:600;line-height:1.6;
  border-radius:var(--r-md);padding:10px 14px;box-shadow:var(--shadow-stage);
  opacity:0;transform:translateY(4px);pointer-events:none;
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease)}
.onb-bubble.in{opacity:.97;transform:none}
/* 箭头：--ax 由 JS 按锚点中心算好（气泡被夹回视口时箭头仍指着控件） */
.onb-bubble::after{content:"";position:absolute;left:var(--ax,24px);margin-left:-6px;
  border:6px solid transparent}
.onb-bubble.below::after{top:-12px;border-bottom-color:var(--ink)}
.onb-bubble.above::after{bottom:-12px;border-top-color:var(--ink)}

/* — 幽灵手势：半透明圆点缩放落到某个词上（约 0.7s），随后那个词短暂高亮。
     pointer-events:none —— 演示期间用户想点什么就点什么，手势绝不吃掉他的操作。 */
.onb-ghost{position:fixed;z-index:44;left:0;top:0;width:34px;height:34px;margin:-17px 0 0 -17px;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 38% 34%,rgba(255,255,255,.5),transparent 62%),var(--accent);
  opacity:0;box-shadow:0 0 0 6px var(--accent-wash);
  animation:onbTap .9s var(--ease) forwards}
@keyframes onbTap{
  0%  {opacity:0;transform:scale(2.4) translateY(-14px)}
  45% {opacity:.55;transform:scale(1) translateY(0)}
  62% {opacity:.62;transform:scale(.74)}      /* 按下去 */
  78% {opacity:.5;transform:scale(1)}         /* 弹回来 */
  100%{opacity:0;transform:scale(1.5)}
}
/* 被演示到的那个词：和真点词的选中态（.tw-on）同一套视觉，学到的手势才对得上 */
.onb-word{background:var(--accent-wash);border-radius:4px;box-shadow:inset 0 -2px 0 var(--accent-line)}

/* — 词典卡底的一次性说明（只在第一次打开时出现） — */
.dict-onb{margin-top:10px;padding-top:10px;border-top:1px dashed var(--line);
  font-size:12.5px;color:var(--muted);line-height:1.6}
.dict-onb b{color:var(--accent-ink)}

/* — 空状态引导：把"这里是空的"改成"这里以后会有什么 / 现在去做什么能填上" — */
.empty .empty-h{font-size:var(--fs-md);font-weight:650;color:var(--ink);margin:0 0 6px}
.empty .empty-tip{font-size:13px;line-height:1.75;max-width:34em;margin:0 auto}
.empty .btn{margin-top:14px}

/* ============================================================
   定级测试：今日页轻横幅 + 独立测试页
   ============================================================ */

/* — 轻横幅：整条可点进测试，右侧 ✕ 关掉就不再出现。**不遮挡任何东西**，
     就是列表里的一张卡；用 accent-wash 而不是实心强调色，不跟"今天要练的句子"抢眼。 */
.pl-banner{display:flex;align-items:center;gap:11px;margin:10px 0 4px;padding:11px 12px;
  background:var(--accent-wash);border:1px solid var(--accent-line);border-radius:var(--r-md);
  color:var(--ink);text-decoration:none}
.pl-banner:active{transform:translateY(1px)}
.pl-bn-ic{font-size:18px;line-height:1;flex:none}
.pl-bn-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.pl-bn-tx b{font-family:var(--font-ko);font-size:14px;font-weight:700;color:var(--accent-ink)}
.pl-bn-tx small{font-size:12px;color:var(--muted);line-height:1.5}
.pl-bn-x{flex:none;width:30px;height:30px;border:none;background:none;border-radius:50%;
  color:var(--faint);font-size:14px;line-height:1;cursor:pointer}
.pl-bn-x:hover{background:var(--line-2);color:var(--muted)}

/* — 测试页：一屏一张卡，三个阶段（开场 / 答题 / 结果）复用同一张卡的外观 — */
.pl-wrap{max-width:520px;margin:0 auto}
.pl-card{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r);box-shadow:var(--shadow-card);
  padding:22px 20px;margin:14px 0}
.pl-kicker{font-family:var(--font-ko);font-size:12px;letter-spacing:.12em;color:var(--faint);
  font-weight:700;text-transform:uppercase}
.pl-title{font-size:var(--fs-2xl);font-weight:700;letter-spacing:-.3px;margin:6px 0 10px;text-wrap:balance}
.pl-lead{font-size:var(--fs-ms);color:var(--muted);line-height:1.75;margin:0 0 14px}
.pl-notes{margin:0 0 20px;padding-left:18px;color:var(--muted);font-size:13px;line-height:1.85}
.pl-notes b{color:var(--ink)}
.pl-back{display:block;text-align:center;margin-top:14px;color:var(--faint);
  font-size:13px;text-decoration:underline dotted;text-underline-offset:3px}

/* 进度：细条 + 「第 N / 6」，克制到几乎看不见 —— 6 题的测试不需要被强调"还剩几题" */
.pl-bar{height:4px;border-radius:2px;background:var(--surface-2);overflow:hidden}
.pl-fill{height:100%;width:0;background:var(--accent);border-radius:2px;
  transition:width var(--dur-slow) var(--ease)}
.pl-step{text-align:right;font-size:12px;color:var(--faint);margin-top:6px;font-variant-numeric:tabular-nums}
.pl-q{font-family:var(--font-ko);font-size:var(--fs-xl);font-weight:700;line-height:1.5;
  margin-top:14px;word-break:keep-all}
.pl-qsub{font-size:13px;color:var(--muted);margin-top:4px}

/* 播放钮：听力题的主要动作，做得大而明确（44px 触控） */
.pl-play{display:inline-flex;align-items:center;gap:8px;margin:16px 0 4px;
  height:46px;min-height:46px;padding:0 20px;cursor:pointer;
  border:1px solid var(--accent-line);background:var(--accent-wash);color:var(--accent-ink);
  border-radius:var(--r-pill);font-size:var(--fs-ms);font-weight:650;font-family:var(--font-ui)}
.pl-play:active{transform:translateY(1px)}
.pl-play-ic{font-size:12px}

/* 选项：三个大块，点了先给一下选中态再翻页（不报对错——这是定级不是测验） */
.pl-opts{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.pl-opt{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;
  min-height:52px;padding:11px 15px;cursor:pointer;text-align:left;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);
  border-radius:var(--r-md);font-size:var(--fs-ms);line-height:1.55;font-family:var(--font-ui);
  transition:background var(--dur-fast),border-color var(--dur-fast),transform var(--dur-fast)}
.pl-opt:active{transform:translateY(1px)}
.pl-opt.picked{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.pl-opt-ko{font-family:var(--font-ko);font-size:var(--fs-md);font-weight:650}
.pl-opt.picked .pl-opt-zh{opacity:.85}
.pl-opt-zh{font-size:13.5px;color:var(--muted)}
.pl-opt.picked .pl-opt-zh{color:var(--on-accent)}

/* 结果：档位名压成一行大字，解释一句，然后两个出口 */
.pl-verdict{display:flex;align-items:baseline;gap:8px;margin:10px 0 6px;flex-wrap:wrap}
.pl-lv-ko{font-family:var(--font-ko);font-size:var(--fs-3xl);font-weight:700;color:var(--accent-ink)}
.pl-lv-zh{font-size:var(--fs-md);color:var(--muted)}
.pl-reason{font-size:var(--fs-ms);color:var(--ink);line-height:1.75;margin:6px 0 8px}
.pl-desc{font-size:13px;color:var(--muted);line-height:1.75;margin:0 0 12px}
.pl-hangul{font-size:13px;line-height:1.75;margin:0 0 14px;padding:10px 12px;
  background:var(--warn-wash);border-left:3px solid var(--warn);border-radius:var(--r-sm);
  color:var(--warn-ink)}
.pl-acts{margin-top:18px}
.pl-foot{font-size:12px;color:var(--faint);line-height:1.7;margin:16px 0 0;text-align:center}
.pl-foot b{color:var(--muted)}

/* ============================================================
   访客通道（公开页）+ 全站页脚 + 开屏花体的显隐门
   —— 2026-08-06 新增，纯追加块，未改本文件既有任何一行。
   所有色值走既有令牌，深浅两套自动跟随（公开页也一样要暗色好看：
   朋友圈点进来的人一半以上是晚上躺床上刷到的）。
   ============================================================ */

/* ---- 开屏花体：就绪之前先藏起来（配合 _splash.html 的 revealQuote）----
   默认 hidden：JS 那边有三条路都会把类加上（就绪 / 600ms 超时 / 出异常），
   所以不存在"永远看不到句子"的分支。 */
.splash-q{visibility:hidden}
.splash.font-instant .splash-q{visibility:visible}            /* 已缓存 → 直显，一点动画都不给 */
.splash.font-ready   .splash-q{visibility:visible;animation:splashQIn .34s var(--ease) both}
@keyframes splashQIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .splash.font-ready .splash-q{animation:none}
}

/* ---- 全站页脚（KRDict 署名，许可证义务）----
   两个 base 都 include 它。小字 + --faint，够看清但绝不抢戏。 */
.site-foot{margin:34px auto 0;padding:16px 4px 0;border-top:1px solid var(--line);
  text-align:center;font-size:11.5px;line-height:1.85;color:var(--faint)}
.site-foot p{margin:0}
.site-foot a{color:var(--muted);text-decoration:underline dotted;text-underline-offset:2px}
.site-foot a:hover{color:var(--accent-ink)}

/* ============ 公开页（/start /about /welcome + 两个闸门页）============ */
/* 没有底部 tab 栏，所以把 base.html 那 96px 让位补白收回来 */
body.page-public main.pub{max-width:560px;padding:24px 18px 34px}

.pub-hero{text-align:center;padding:14px 2px 4px}
.pub-kicker{font-family:var(--font-ko);font-size:12px;letter-spacing:.14em;color:var(--faint);font-weight:700}
/* 落地页唯一一处花体：和开屏是同一个"手写便签"的语气，第一印象靠它立住 */
.pub-script{font-family:var(--font-script);font-weight:400;color:var(--splash-ink);
  font-size:clamp(30px,9vw,42px);line-height:1.3;letter-spacing:.005em;
  word-break:keep-all;text-wrap:balance;margin:14px 0 4px}
.pub-h1{font-size:var(--fs-2xl);font-weight:700;letter-spacing:-.3px;line-height:1.4;
  margin:8px 0 10px;text-wrap:balance}
.pub-lead{font-size:var(--fs-ms);color:var(--muted);line-height:1.8;margin:0 auto;max-width:34em}
.pub-lead b{color:var(--ink)}
.pub-note{font-size:12.5px;color:var(--faint);line-height:1.8;margin:14px 0 0}
.pub-note b{color:var(--muted)}

/* 三步用法：纯 CSS 的编号圆点，不用图不用图标字体（这页要能离线秒开） */
.pub-steps{margin:22px 0 4px}
.pub-steps ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.pub-steps li{display:flex;gap:14px;align-items:flex-start;padding:12px 2px;position:relative}
/* 竖直连线：把三步串成一条流程，而不是三个孤立的段落 */
.pub-steps li:not(:last-child)::before{content:"";position:absolute;left:16px;top:42px;bottom:-2px;
  width:2px;background:var(--accent-line);opacity:.6}
.ps-n{flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent-wash);color:var(--accent-ink);border:1px solid var(--accent-line);
  font-size:15px;font-weight:700;font-variant-numeric:tabular-nums}
.ps-b{display:flex;flex-direction:column;gap:3px;padding-top:5px}
.ps-b b{font-size:var(--fs-md);font-weight:650}
.ps-b span{font-size:13px;color:var(--muted);line-height:1.7}

/* 卡片：与 .pl-card 同一质感（亮色纸片投影 / 暗色玻璃渐变） */
.pub-card{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--card-line);border-radius:var(--r);box-shadow:var(--shadow-card);
  padding:20px 18px;margin:20px 0}

.pub-form{display:flex;flex-direction:column;gap:0}
.pub-label{font-size:var(--fs-ms);font-weight:650;margin-bottom:8px}
.pub-input{width:100%;box-sizing:border-box;height:50px;padding:0 14px;
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  background:var(--surface-3);color:var(--ink);font-size:var(--fs-base);font-family:var(--font-ui)}
.pub-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.pub-input::placeholder{color:var(--faint)}
.pub-help{font-size:12px;color:var(--faint);margin:8px 0 16px}
.pub-err{margin:0 0 14px;padding:10px 12px;border-radius:var(--r-sm);
  background:var(--danger-wash);border-left:3px solid var(--danger);color:var(--danger-ink);
  font-size:13px;line-height:1.7}

/* 常见问题：原生 details，零 JS。收起时几乎不占地方，想看的人才展开 */
.pub-faq{margin:26px 0 0}
.pub-faq details{border-top:1px solid var(--line);padding:2px 0}
.pub-faq summary{cursor:pointer;list-style:none;padding:12px 2px;font-size:13.5px;font-weight:600;
  color:var(--strong);display:flex;align-items:center;gap:8px}
.pub-faq summary::-webkit-details-marker{display:none}
.pub-faq summary::before{content:"+";color:var(--accent);font-weight:700;font-size:15px;width:12px}
.pub-faq details[open] summary::before{content:"–"}
.pub-faq p{margin:0 0 14px;padding-left:20px;font-size:13px;color:var(--muted);line-height:1.8}
.pub-faq p b{color:var(--ink)}

/* ---- 欢迎页 ---- */
.wc-top{text-align:center;padding:10px 2px 0}
.wc-linkcard{margin-top:18px}
.wc-linkrow{margin-bottom:14px}
/* 链接要能被长按选中 → 用 <code> 并允许任意位置换行（slug 是一长串无空格字符） */
.wc-link{display:block;padding:12px 13px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px dashed var(--line-strong);color:var(--strong);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;line-height:1.7;
  word-break:break-all;user-select:all;-webkit-user-select:all}
.wc-tips{font-size:12.5px;color:var(--muted);line-height:1.8;margin:14px 0 0}
.wc-tips b{color:var(--ink)}
.wc-go{margin-top:18px;text-align:center}
.wc-warn{margin:22px 0 0;padding:11px 13px;border-radius:var(--r-sm);
  background:var(--warn-wash);border-left:3px solid var(--warn);color:var(--warn-ink);
  font-size:12.5px;line-height:1.8}
/* 次要按钮：与主按钮同尺寸，但不抢它的位置（"进入练习"排在"复制链接"之后） */
.btn.ghost{background:transparent;color:var(--accent-ink);border:1px solid var(--accent-line);
  box-shadow:none;text-decoration:none}
.btn.ghost:hover{background:var(--accent-wash);color:var(--accent-ink)}
.btn.ok{background:var(--ok);}

/* ---- 署名页 ---- */
.ab-hero{padding-bottom:0}
.ab-block h2{font-size:var(--fs-lg);font-weight:700;margin:0 0 10px}
.ab-block p{font-size:13.5px;color:var(--muted);line-height:1.85;margin:0 0 10px}
.ab-block a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:2px}
.ab-meta{margin:0 0 10px;padding-left:18px;font-size:13px;color:var(--muted);line-height:1.9}
.ab-meta b{color:var(--ink)}
.ab-note{font-size:12px;color:var(--faint);line-height:1.8}
.ab-block code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;
  background:var(--surface-2);padding:1px 5px;border-radius:4px}
.ab-back{text-align:center;margin:26px 0 0}
.ab-back a{color:var(--muted);font-size:13px;text-decoration:underline dotted;text-underline-offset:3px}

/* ---- 两个闸门页（满员 / 限流）---- */
.gate-hero{padding-top:40px}
.gate-ic{width:56px;height:56px;margin:0 auto 18px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-wash);border:1px solid var(--accent-line);color:var(--accent-ink)}
.gate-ic svg{width:28px;height:28px}
.gate-note-ko{font-family:var(--font-ko);font-size:12px;color:var(--faint);line-height:1.8;
  margin:16px 0 0;word-break:keep-all}

/* ============================================================
   生活场景对话库（列表页 + 场景页专属两块 + 今日页入口卡）
   —— 结构上完全寄生在 day.html 既有的句卡/工具条上，这里只补三样：
      ① 今日页顶部的入口卡 .scentry
      ② 列表页的簇分组网格 .sc-*
      ③ 场景页的「对面会问你什么 / 救命句」两块 .scblock
   ============================================================ */

/* ---- ① 今日页入口细条 ----
   原先是两行大卡（图标 + 标题 + 描述文案），压在日期栏之前，手机上把第一张句卡挤出首屏。
   现在压成 44px 单行：图标 + 标题 + 数量徽标 + 箭头，整条可点（<a> 本身就是 flex 容器）。
   高度用 min-height 而不是 height —— 万一以后标题变长换行，不至于把文字挤出条外。 */
.scentry{display:flex;align-items:center;gap:9px;margin:8px 0 2px;padding:0 12px;min-height:44px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  box-shadow:var(--shadow-sm);color:inherit}
.scentry:active{transform:translateY(1px)}
.scentry-ic{flex:none;width:26px;height:26px;border-radius:8px;display:flex;
  align-items:center;justify-content:center;font-size:15px;line-height:1;
  background:var(--accent-wash);border:1px solid var(--accent-line)}
.scentry-tx{flex:1;min-width:0;font-size:var(--fs-ms);font-weight:650;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 数量徽标：等宽数字，避免 9→10 时后面的箭头左右跳 */
.scentry-n{flex:none;font-size:12.5px;font-weight:600;color:var(--muted);
  font-variant-numeric:tabular-nums}
.scentry-go{flex:none;color:var(--faint);font-size:18px;line-height:1}
/* 聚焦（逐句）模式是沉浸练习，入口不该出现在跟读区之上 */
body.focus-mode .scentry{display:none}

/* ---- ② 列表页 ---- */
.sc-hero{margin:18px 0 6px}
.sc-hero h2{font-size:var(--fs-xl);font-weight:700;margin:0 0 6px}
.sc-building{font-size:12.5px;color:var(--warn-ink);background:var(--warn-wash);
  border:1px solid var(--warn-line);border-radius:var(--r-sm);padding:7px 10px;margin:8px 0 0}
.sc-cluster{margin:22px 0 0}
.sc-ch{display:flex;align-items:baseline;gap:7px;font-size:var(--fs-ms);font-weight:650;
  margin:0 0 9px;color:var(--strong)}
.sc-ch .ko{font-family:var(--font-ko)}
.sc-emoji{font-size:15px}
.sc-ch-zh{font-size:12px;color:var(--faint);font-weight:500}
.sc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:9px}
.sc-card{display:flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow-sm);overflow:hidden}
.sc-card.off{opacity:.55}
.sc-main{display:flex;flex-direction:column;gap:3px;padding:11px 11px 8px;color:inherit;flex:1}
.sc-ko{font-family:var(--font-ko);font-size:13.5px;font-weight:600;color:var(--ink);
  line-height:1.45;word-break:keep-all}
.sc-zh{font-size:11.5px;color:var(--muted);line-height:1.4}
.sc-foot{display:flex;align-items:center;justify-content:space-between;gap:6px;
  padding:7px 10px;border-top:1px solid var(--line-2);background:var(--surface-3)}
.sc-lvs,.sc-lvswitch{display:flex;gap:5px}
.sc-lv{font-family:var(--font-ko);font-size:11.5px;padding:3px 8px;border-radius:var(--r-pill);
  border:1px solid var(--accent-line);color:var(--accent-ink);background:var(--accent-wash);
  display:inline-flex;align-items:center;gap:4px}
.sc-lv.off{border-color:var(--line);color:var(--faint);background:var(--surface-2);cursor:default}
/* 选中态的字必须走 var(--on-accent)，不能写死 #fff：夜间皮肤的 --accent 是浅琥珀
   (#E4A857)，白字压上去只有 2.09:1，11.5px 的档位名基本看不清；--on-accent 在夜间
   是深墨 (#241703) → 8.37:1。全站的选中态 pill（.tb.on / .rv-tab.on / .seg-tab.on）
   本来就是这么写的，这里是新写的时候漏掉了那条约定。 */
.sc-lv.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.sc-dot{width:5px;height:5px;border-radius:50%;background:var(--award);display:inline-block}
.sc-done{font-size:11px;color:var(--faint);white-space:nowrap}
.scenebar .daymeta .date{font-family:var(--font-ko);font-size:var(--fs-ms)}

/* ---- ③ 场景页两块：对面会问你什么 / 救命句 ---- */
.scblock{margin:14px 0 0;padding:11px 12px 8px;border-radius:var(--r-md);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm)}
.scblock.asks{background:var(--accent-wash);border-color:var(--accent-line)}
.scblock.rescue{background:var(--warn-wash);border-color:var(--warn-line)}
.scb-h{display:flex;align-items:baseline;flex-wrap:wrap;gap:6px;margin:0 0 8px}
.scb-h b{font-size:var(--fs-ms);font-weight:650;color:var(--ink)}
.scb-h small{font-size:11.5px;color:var(--muted)}
.scb-ic{font-size:14px}
/* 分隔线走 var(--line)：写死 rgba(0,0,0,.06) 在夜间皮肤（深底）上等于没有，
   救命句那 5-8 条会糊成一整块。两套皮肤各自的 --line 都是压在 wash 底上看得见的。 */
.scb-row{display:flex;align-items:flex-start;gap:9px;padding:7px 0;
  border-top:1px solid var(--line)}
.scb-row:first-of-type{border-top:0}
.scb-play{flex:none;margin-top:1px}
.scb-tx{flex:1;min-width:0}
.scb-tx .ko{font-family:var(--font-ko);font-size:var(--fs-ms);line-height:1.6;
  color:var(--ink);word-break:keep-all}
.scb-zh{font-size:12px;color:var(--muted);line-height:1.6;margin-top:2px}

/* ============================================================
   首页 hub（v30 导航重构·第一段）—— 纯追加块，未改本文件既有任何一行。
   设计稿：docs/design/2026-08-09_nav-redesign-mockups.html 方案 C（轨 1 两张样机）。

   版式：上半屏是开屏那块花体金句原样落地（同一套 --font-script / --splash-ink 令牌，
   视觉与 overlay 逐像素同源），下半屏一个「继续学」主按钮 + 2×2 四个次级入口。
   色值全部走令牌，亮暗两套自动跟随，一处没写死。
   ============================================================ */

/* 首页不要顶栏：金句要顶到屏幕上沿，多一条 50px 的 chrome 就把版面压散了。
   品牌位的功能（回首页）在这一页本来也没有意义。 */
body.page-home .topbar{display:none}
body.page-home main{padding-top:calc(env(safe-area-inset-top,0px) + 10px)}
/* 首页不铺网点纸/灯晕以外的东西，但要够高，让四个入口落在拇指区而不是屏幕中央 */
.home{display:flex;flex-direction:column;min-height:calc(100svh - var(--tabbar-h) - 42px)}
@supports not (height:100svh){
  .home{min-height:calc(100vh - var(--tabbar-h) - 42px)}
}
.hb-date{font-family:var(--font-ko);font-size:12px;letter-spacing:.13em;
  color:var(--faint);font-weight:600;text-align:center}

/* ---- 上半屏：今日金句（与开屏 overlay 同一句、同一套字与色）---- */
.hb-quote{flex:1;display:flex;flex-direction:column;justify-content:center;
  text-align:center;padding:18px 6px 22px;max-width:520px;width:100%;margin:0 auto}
.hb-orn{width:40px;height:2px;border-radius:2px;background:var(--accent);opacity:.45;margin:0 auto 18px}
.hb-ko{font-family:var(--font-script);font-weight:400;font-size:clamp(26px,7.6vw,36px);
  line-height:1.34;letter-spacing:.005em;word-break:keep-all;text-wrap:balance;
  margin:0;color:var(--splash-ink)}
.hb-zh{font-family:var(--font-ui);font-size:14.5px;color:var(--muted);margin:14px 0 0;line-height:1.6}
.hb-src{font-size:12px;color:var(--faint);margin:10px 0 0;letter-spacing:.05em}
/* 花体就绪前不显示（同 .splash-q 的规矩，探测脚本在 home.html 的 head_extra 里）。
   三条路都会把类加上（就绪 / 600ms 超时 / 出异常），不存在"永远看不到句子"的分支。 */
.hb-ko{visibility:hidden}
html.fs-instant .hb-ko{visibility:visible}
html.fs-ready   .hb-ko{visibility:visible;animation:splashQIn .34s var(--ease) both}
@media (prefers-reduced-motion:reduce){
  html.fs-ready .hb-ko{animation:none}
}

/* ---- 主行动：继续学 ---- */
.hb-main{display:block;margin:0 0 10px;padding:14px 16px 15px;border-radius:var(--r-lg);
  background:var(--accent);color:var(--on-accent);box-shadow:var(--btn-lift);
  transition:transform var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease)}
.hb-main:active{transform:translateY(2px);box-shadow:var(--btn-lift-a)}
.hb-main.is-done{background:var(--award);box-shadow:none;color:var(--on-award)}
.hm-k{font-size:12px;font-weight:700;letter-spacing:.06em;opacity:.85}
.hm-t{font-family:var(--font-ko);font-size:var(--fs-lg);font-weight:700;line-height:1.35;
  margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hm-s{font-size:12.5px;margin-top:3px;opacity:.9;font-variant-numeric:tabular-nums}
.hm-bar{height:5px;border-radius:var(--r-pill);margin-top:10px;overflow:hidden;
  background:rgba(255,255,255,.28)}
.hm-fill{height:100%;border-radius:var(--r-pill);background:var(--on-accent);opacity:.92}
.hb-main.is-done .hm-fill{background:var(--on-award)}

/* ---- 四个次级入口（2×2）---- */
.hb-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.hb-c{display:flex;flex-direction:column;gap:2px;padding:11px 12px 12px;
  border-radius:var(--r-md);background:var(--surface);border:1px solid var(--line);
  background-image:var(--glass);box-shadow:var(--shadow-sm);color:var(--ink)}
.hb-c:active{transform:translateY(1px)}
.hc-ic{font-size:17px;line-height:1.2}
.hc-t{font-family:var(--font-ko);font-size:var(--fs-ms);font-weight:650;color:var(--ink)}
.hc-z{font-size:11.5px;color:var(--muted);line-height:1.5}
.hc-n{font-size:12px;color:var(--faint);margin-top:4px;font-variant-numeric:tabular-nums}
.hc-n em{font-style:normal;font-weight:700;color:var(--strong)}
.hc-n em.acc{color:var(--accent-ink)}

/* ---- 开屏 → 首页的交接动画（纯 CSS，不加一行 JS）----
   开屏脚本点掉 overlay 时会给它加 .out（既有行为，本轮没动）。#splash 是 <body> 的第一块、
   main 是它后面的兄弟，于是一个 ~ 选择器就够了：overlay 淡出的同时，下半屏按
   金句 → 主按钮 → 四入口的次序浮起来，两块画面在同一次绘制里交接，没有第二次导航
   ⇒ 不可能闪白。JS 没跑起来（overlay 从来不出现）时 body 上没有 .splash-on，
   下面的预隐藏规则整条不生效，首页就是普通的静态页。 */
.home-fx{transition:opacity .42s var(--ease),transform .42s var(--ease)}
body.splash-on .home-fx{opacity:0;transform:translateY(18px)}
.splash.out ~ main .home-fx{opacity:1;transform:none}
/* 三段延迟不是为了好看才错开的：首页金句与开屏那一句是**同一句**，落点却差半屏。
   两边同时在场就会看见同一行字在两个位置各印一遍（实测 t≈100ms 那一帧很明显）。
   所以让开屏那句先走干净（下面 .splash-core 的淡出压到 .22s），首页这句 .16s 之后再进场，
   重叠窗口里两边都已经低于 ~15% 不透明度，看上去就是一句话"换了个位置落下来"。 */
.splash.out ~ main .hb-quote{transition-delay:.11s}
.splash.out ~ main .hb-main{transition-delay:.19s}
.splash.out ~ main .hb-grid{transition-delay:.26s}
/* 金句那块自己上滑淡出（只在首页这么做：其它页开屏之后是另一套内容，没有"交接"可言）。
   字比底色先消失：底色还在 .35s 地淡，字已经在 .22s 内走完 —— 交接期只剩一层正在变透明的纸。 */
body.page-home .splash-core{transition:opacity .2s ease-out,transform .44s var(--ease)}
body.page-home .splash.out .splash-core{opacity:0;transform:translateY(-32px)}
@media (prefers-reduced-motion:reduce){
  .home-fx{transition:none}
  body.splash-on .home-fx{opacity:1;transform:none}
  body.page-home .splash-core,
  body.page-home .splash.out .splash-core{transition:none;transform:none}
}

/* ---- 5 格底部 tab（4→5）----
   5 个字段挤在 360px 的机器上：字号 11.5→11px、图标 22→21px、左右各留 1px 呼吸。
   再窄（iPhone SE 的 320px）就靠 flex 均分自然收缩，文字仍是完整的两个字。 */
.tabbar a{font-size:11px;padding:7px 1px 6px}
.tabbar a .ti svg{width:21px;height:21px}

/* ============================================================
   v30 第二段：练完总结页 / 今日页工具条（连续听 + 今天到这）/ 录音 A-B 对比
   —— 纯追加块，未改本文件既有任何一行。色值全部走令牌，亮暗两套自动跟随。
   设计稿：docs/design/2026-08-09_nav-redesign-mockups.html 轨 3
   ============================================================ */

/* ---- 今日页工具条：进度条下面那一行（连续听 / 今天到这）----
   刻意做成"次级"：34px 高、无填充、字比句卡小两号。它必须够得着，但绝不能和句卡抢眼。 */
.daytools{display:flex;align-items:center;gap:8px;margin:0 0 8px;min-height:30px}
.dt-btn{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 11px;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--muted);
  border-radius:var(--r-pill);font-size:12.5px;font-weight:600;cursor:pointer;
  transition:border-color var(--dur-fast),color var(--dur-fast),background var(--dur-fast)}
.dt-btn:hover{border-color:var(--accent);color:var(--accent-ink)}
.dt-btn.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.dt-ic{font-size:13px;line-height:1}
.dt-exit{margin-left:auto;font-size:12.5px;color:var(--faint);text-decoration:none;
  padding:6px 2px 6px 8px}
.dt-exit:active{color:var(--accent-ink)}
/* 连续听进行中：「循环」灰掉。两者抢同一个 <audio>，循环一开就再没有 ended 事件，
   连播会静静卡在这一句上（korLoop 里还有一道逻辑守卫，这里只是让它看起来就点不动）。 */
body.autoplay-on .tb.loop{opacity:.4;pointer-events:none}

/* ---- 录音 A/B 对比：结果块里的一行 [🎙 我的][🔊 原声] ----
   高度 34px（比句卡工具键 44px 矮一档）—— 它是"评分之后的补充动作"，不是主行动。 */
.ab{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:8px}
.ab-lab{font-size:var(--fs-xs);color:var(--muted);margin-right:2px}
.tb.ab-b{height:34px;min-height:34px;padding:0 12px;font-size:var(--fs-sm);font-weight:600}

/* ---- 练完总结页 ---- */
.fin{max-width:520px;margin:0 auto;padding:2px 0 10px}
.fin-date{font-family:var(--font-ko);font-size:12px;letter-spacing:.13em;
  color:var(--faint);font-weight:600;text-align:center}
.fin-k{font-family:var(--font-ko);font-size:12.5px;letter-spacing:.1em;color:var(--muted);
  font-weight:700;text-align:center;padding:16px 0 0}
.fin-big{text-align:center;margin-top:10px}
.fin-big b{font-size:clamp(40px,13vw,54px);font-weight:700;letter-spacing:-.03em;
  color:var(--ink);font-variant-numeric:tabular-nums;line-height:1}
.fin-big b span{font-size:.5em;color:var(--muted);font-weight:600}
.fin-big-s{display:block;font-size:13px;color:var(--muted);margin-top:6px}

/* 连续天数 + 本周打卡格：达标语义 → 琥珀金（同 .checkin-wrap.complete 那条渐变） */
.fin-band{margin-top:16px;border-radius:var(--r-md);padding:13px 15px;text-align:center;
  background:linear-gradient(120deg,var(--award),var(--award-deep));color:var(--on-award);
  box-shadow:var(--shadow-card)}
.fb-line{font-family:var(--font-ko);font-size:15px;font-weight:700}
.fb-sub{font-size:12px;opacity:.88;margin-top:2px}
.fb-week{display:flex;justify-content:center;gap:6px;margin-top:10px}
/* 格子压在金底上：没打卡的格子用半透明白描边（写死 rgba 是有意的——它压的是渐变本身，
   不是页面底色，两套皮肤下这条渐变是同一条）。 */
.fw-c{width:26px;height:26px;border-radius:8px;display:flex;align-items:center;
  justify-content:center;border:1px solid rgba(255,255,255,.34);
  background:rgba(255,255,255,.12)}
.fw-c i{font-style:normal;font-size:10.5px;font-weight:700;opacity:.72}
.fw-c.on{background:var(--on-award);border-color:transparent}
.fw-c.on i{opacity:1;color:var(--award)}
.fw-c.now{outline:2px solid var(--on-award);outline-offset:1px}
.fw-c.fut{opacity:.42}

/* 三个小格（没数据的整格不渲染，列数由服务端按实际格数写在 style 里） */
.fin-stats{display:grid;gap:8px;margin-top:10px}
.fin-s{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--line);border-radius:var(--r-md);padding:10px 6px;text-align:center;
  box-shadow:var(--shadow-sm)}
.fin-s b{display:block;font-size:17px;font-weight:700;color:var(--ink);
  font-variant-numeric:tabular-nums}
.fin-s span{display:block;font-size:11px;color:var(--faint);margin-top:3px}

/* 明天：左侧强调竖条（与稿子一致），文字左对齐——它是"信息"，不是"成绩" */
.fin-next{margin-top:12px;border-left:3px solid var(--accent);background:var(--accent-wash);
  border-radius:0 var(--r-md) var(--r-md) 0;padding:10px 13px}
.fin-next .fk{font-size:11px;letter-spacing:.1em;color:var(--accent-ink);font-weight:700}
.fin-next .ft2{font-family:var(--font-ko);font-size:15px;font-weight:700;color:var(--ink);
  margin-top:3px;line-height:1.45;word-break:keep-all}
.fin-next .fz{font-size:12px;color:var(--muted);margin-top:2px;line-height:1.5}

.fin-acts{display:flex;flex-direction:column;gap:9px;margin-top:16px}
.fin-go{display:block;text-align:center;padding:14px 16px;border-radius:var(--r-lg);
  background:var(--accent);color:var(--on-accent);font-size:var(--fs-md);font-weight:650;
  text-decoration:none;box-shadow:var(--btn-lift)}
.fin-go:active{transform:translateY(2px);box-shadow:var(--btn-lift-a)}
.fin-ghost{display:block;text-align:center;padding:10px;color:var(--muted);
  font-size:var(--fs-ms);text-decoration:none}
.fin-bye{text-align:center;font-family:var(--font-ko);font-size:12.5px;color:var(--faint);
  margin:14px 0 0}

/* 空状态（今天一句没练就点进来了）：不假装有成绩，只给一条回去的路 */
.fin-empty{text-align:center;margin:44px 0 0}
.fin-emp-k{font-family:var(--font-ko);font-size:12.5px;letter-spacing:.1em;color:var(--faint);font-weight:700}
.fin-emp-t{font-size:var(--fs-lg);font-weight:700;color:var(--ink);margin:8px 0 0}
.fin-emp-s{font-size:13px;color:var(--muted);margin:6px 0 20px}

/* 入场：从下往上滑进来一小段（"练完 → 总结滑上来"是同一个动作的延续，不是新开一页）。
   逐块错开 60ms，眼睛跟着数字→连续天数→明天走一遍。 */
@keyframes finIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.fin-fx{animation:finIn .42s var(--ease) both}
.fin-big{animation-delay:.06s}
.fin-band{animation-delay:.12s}
.fin-stats{animation-delay:.18s}
.fin-next{animation-delay:.24s}
.fin-hooks{animation-delay:.3s}
.fin-acts{animation-delay:.36s}

@media (prefers-reduced-motion:reduce){
  .fin-fx{animation:none}
}

/* ---- 署名的两个新落点（v31：练习页不再挂整站页脚，理由见 base.html 的长注释）----
   词典卡底的一行 + 复习页顶的一行。都走 --faint 小字，与 .site-foot 同一个语气与字号。 */
.dict-lic{margin-top:10px;padding-top:9px;border-top:1px solid var(--line-2);
  font-size:11px;line-height:1.7;color:var(--faint);text-align:center}
.dict-lic a{color:var(--muted);text-decoration:underline dotted;text-underline-offset:2px}
/* text-wrap:balance：这行在 390px 上必然折行，不平衡的话会孤零零掉下来一个"用"字 */
.rv-lic{margin:2px 0 8px;font-size:10.5px;line-height:1.6;color:var(--faint);text-wrap:balance}
.rv-lic a{color:var(--muted);text-decoration:underline dotted;text-underline-offset:2px}

/* ---- 回访钩子四块（练完总结页 #fin-hooks）· v32 ----
   与上面 .fin-* 的关系：那些是"报成绩"，这四块是"下次还来"，所以视觉上要**降一档**
   —— 不用金底、不用大字号，走和 .fin-s 同一套纸片卡，看得见但不抢那个大数字。 */
.fin-hooks{margin-top:18px;display:flex;flex-direction:column;gap:9px}
.fin-hooks[hidden]{display:none}
.hk-kicker{font-family:var(--font-ko);font-size:11px;letter-spacing:.12em;color:var(--faint);
  font-weight:700;text-align:center;margin-bottom:1px}
.hk{background-color:var(--surface);background-image:var(--glass);
  border:1px solid var(--line);border-radius:var(--r-md);padding:12px 14px;
  box-shadow:var(--shadow-sm)}
.hk[hidden]{display:none}
.hk-h{display:flex;align-items:center;gap:8px}
.hk-h b{font-size:14.5px;font-weight:650;color:var(--ink)}
.hk-ic{font-size:15px;line-height:1;flex:none}
/* 开关贴右：标题行本身当成一条 flex，开关用 margin-left:auto 顶到最右 */
.hk-tgl{margin-left:auto;margin-top:0}
.hk-tgl[hidden]{display:none}
.hk-d{font-size:12.5px;color:var(--muted);line-height:1.6;margin:5px 0 0}
.hk-d b{color:var(--strong)}
.hk-btn{display:inline-flex;align-items:center;justify-content:center;margin-top:10px;
  min-height:40px;padding:0 18px;border-radius:var(--r-pill);border:1px solid var(--accent-line);
  background:var(--accent-wash);color:var(--accent-ink);font-size:var(--fs-ms);font-weight:650;
  text-decoration:none;cursor:pointer}
.hk-btn:active{transform:translateY(1px)}
.hk-btn[hidden]{display:none}
.hk-btn.sm{min-height:38px;padding:0 15px;margin-top:0}
/* 「不再提示」/「清除」：故意做成最轻的一档——它是出口，不该和主行动抢眼 */
.hk-x{display:block;margin:9px 0 0;padding:4px 0;border:0;background:none;
  color:var(--faint);font-size:12px;text-decoration:underline dotted;
  text-underline-offset:2px;cursor:pointer}
.hk-mail-f{display:flex;gap:7px;margin-top:10px}
.hk-mail-f input{flex:1;min-width:0;height:38px;padding:0 12px;border-radius:var(--r-sm);
  border:1px solid var(--line-strong);background:var(--surface-3);color:var(--ink);
  font-size:var(--fs-ms);font-family:inherit}
.hk-mail-f input:focus{outline:2px solid var(--accent);outline-offset:1px}
.hk-mail-v{word-break:break-all}

/* iOS 的「添加到主屏」三步图示。**必须画给他看**：WebKit 上没有 beforeinstallprompt，
   也没有任何 API 能唤起分享面板，用户得自己点底部分享键、往下滚、找那一条
   —— 没有图示基本无人完成（设计稿 §回访通道 현실 1）。
   三个小图全部是纯 CSS：为三个 20px 的示意图去引一套图标字体或三个 PNG 不划算，
   而且它们要跟着深浅色变，用 currentColor 画最省事。 */
.hk-steps{list-style:none;margin:11px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
.hk-steps[hidden]{display:none}
.hk-steps li{display:flex;align-items:center;gap:10px;font-size:12.5px;color:var(--muted);
  line-height:1.5}
.hk-steps li b{color:var(--strong);font-weight:650}
.hk-si{flex:none;width:30px;height:30px;border-radius:9px;position:relative;
  background:var(--surface-3);border:1px solid var(--line-strong);color:var(--accent-ink)}
/* ① 分享：一个开口向上的方盒 + 一支从盒里向上出去的箭（iOS 分享键的通用画法） */
.hk-si.share::before{content:"";position:absolute;left:7px;right:7px;bottom:6px;height:10px;
  border:1.7px solid currentColor;border-top:0;border-radius:0 0 3px 3px}
.hk-si.share::after{content:"";position:absolute;left:13.2px;top:7px;width:1.7px;height:11px;
  background:currentColor;border-radius:1px}
.hk-si.share i{position:absolute;left:10px;top:8px;width:8px;height:8px;
  border-left:1.7px solid currentColor;border-top:1.7px solid currentColor;
  transform:rotate(45deg);border-radius:1px}
/* ② 加号方框：菜单里「添加到主屏幕」那一行左边的图标 */
.hk-si.plus i{position:absolute;left:7px;top:7px;right:7px;bottom:7px;
  border:1.7px solid currentColor;border-radius:4px}
.hk-si.plus::before{content:"";position:absolute;left:11px;top:13.6px;width:8px;height:1.7px;
  background:currentColor;border-radius:1px}
.hk-si.plus::after{content:"";position:absolute;left:14.2px;top:10.5px;width:1.7px;height:8px;
  background:currentColor;border-radius:1px}
/* ③ 对勾：最后那一下「추가 · 添加」 */
.hk-si.check i{position:absolute;left:9px;top:10px;width:11px;height:6px;
  border-left:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(-45deg)}

/* 分享成绩卡按钮：主行动（再练几句 / 去复习）之下的第二顺位，所以是描边不是实心 */
.fin-share{display:block;width:100%;text-align:center;padding:12px 16px;border-radius:var(--r-lg);
  border:1px solid var(--accent-line);background:var(--accent-wash);color:var(--accent-ink);
  font-size:var(--fs-ms);font-weight:650;cursor:pointer;font-family:inherit}
.fin-share .ko{font-family:var(--font-ko)}
.fin-share:active{transform:translateY(1px)}
.fin-share[hidden]{display:none}
.fin-share:disabled{opacity:.6;cursor:default}
