/* IELTS 工作台 — 设计令牌 */
:root{
  --bg:#F6F4EF;
  --surface:#FFFFFF;
  --surface-2:#FBFAF6;
  --surface-3:#F1EEE6;
  --line:#EBE6DA;
  --line-strong:#DED7C7;
  --ink:#1E2A24;
  --ink-2:#41514A;
  --muted:#7C8A83;
  --muted-2:#9AA6A0;
  --green-deep:#17453C;
  --green:#12776B;
  --green-soft:#E3F0EB;
  --green-soft-2:#D3E7E0;
  --gold:#A9821C;
  --gold-2:#C9A227;
  --gold-soft:#F6EDD5;
  --rose:#B4503A;
  --rose-soft:#F8E6E0;
  --amber:#9A6B12;
  --amber-soft:#FAEFD6;
  --blue:#33557F;
  --blue-soft:#E5ECF6;
  --radius:16px;
  --radius-sm:10px;
  --shadow-1:0 1px 2px rgba(24,40,34,.05), 0 6px 20px rgba(24,40,34,.045);
  --shadow-2:0 10px 34px rgba(24,40,34,.10);
  --sans:-apple-system,BlinkMacSystemFont,"SF Pro SC","PingFang SC","Hiragino Sans GB","Microsoft YaHei",system-ui,sans-serif;
  --serif:"New York","Iowan Old Style","Songti SC",Georgia,"Times New Roman",serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --rail-w:222px;
  --top-h:58px;
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
/* 顶栏 sticky / 手机端底部 tabbar 都是浮层：滚动与 scrollIntoView 都要把它们的高度算进去，
   否则贴边的按钮会被浮层盖住，看着能点、点下去却没反应。 */
html{
  scroll-padding-top:calc(var(--top-h) + 16px);
  scroll-padding-bottom:calc(88px + env(safe-area-inset-bottom));
}
body{
  background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;
}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
a{color:var(--green);text-decoration:none}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.sprite symbol path,.sprite symbol rect,.sprite symbol circle{fill:none;stroke:currentColor}
.sprite symbol#i-dashboard path,.sprite symbol#i-play path,.sprite symbol#i-pause path,.sprite symbol#i-stop rect,.sprite symbol#i-flame path,.sprite symbol#i-star path,.sprite symbol#i-speak path,.sprite symbol#i-mock path{fill:currentColor;stroke:none}
.sprite symbol#i-mock path:last-child,.sprite symbol#i-star path:first-child{fill:none;stroke:currentColor}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:#DAD4C6;border-radius:20px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

/* ---------- 框架 ---------- */
.app{display:flex;min-height:100vh}
.rail{
  width:var(--rail-w);flex:0 0 var(--rail-w);background:var(--surface);
  border-right:1px solid var(--line);display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;padding:18px 14px 14px;
}
.brand{display:flex;align-items:center;gap:10px;padding:2px 4px 16px}
.brand-mark{
  width:38px;height:38px;border-radius:11px;background:var(--green-deep);color:#fff;
  display:grid;place-items:center;font-size:10px;font-weight:700;letter-spacing:.5px;
}
.brand-text{display:flex;flex-direction:column;line-height:1.25}
.brand-text strong{font-size:14.5px;letter-spacing:.1px}
.brand-text span{font-size:10.5px;color:var(--muted-2)}

.nav{display:flex;flex-direction:column;gap:2px;flex:1;overflow:auto}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:11px;
  color:var(--ink-2);font-size:13.5px;width:100%;text-align:left;transition:background .14s,color .14s;
}
.nav-item svg{width:17px;height:17px;color:var(--muted);flex:0 0 auto}
.nav-item:hover{background:var(--surface-3)}
.nav-item.active{background:var(--green-soft);color:var(--green-deep);font-weight:600}
.nav-item.active svg{color:var(--green)}
.nav-item .nav-label{flex:1}
.badge{
  font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:999px;
  background:var(--gold-soft);color:#6F5406;font-variant-numeric:tabular-nums;
}
.badge.mint{background:var(--green-soft);color:#0C5B51}
.badge.rose{background:var(--rose-soft);color:#8A3A26}

.rail-foot{display:flex;flex-direction:column;gap:10px;padding-top:12px}
.streak{
  background:var(--gold-soft);border-radius:var(--radius-sm);padding:9px 11px;
  display:flex;align-items:center;gap:9px;
}
.streak svg{color:var(--gold);width:16px;height:16px}
.streak b{font-size:14px}
.streak span{display:block;font-size:10.5px;color:#7A5F14}
.rail-user{display:flex;align-items:center;gap:9px;padding:2px 4px}
.avatar{width:28px;height:28px;border-radius:50%;background:var(--green-soft);color:var(--green-deep);
  display:grid;place-items:center;font-weight:700;font-size:12px}
.rail-user-text{display:flex;flex-direction:column;line-height:1.3}
.rail-user-text strong{font-size:12px}
.rail-user-text span{font-size:10.5px;color:var(--muted-2)}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:var(--top-h);display:flex;align-items:center;gap:12px;padding:0 22px;
  border-bottom:1px solid var(--line);background:rgba(246,244,239,.86);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);position:sticky;top:0;z-index:20;
}
.rail-toggle{display:none}
.search{
  flex:1;max-width:420px;display:flex;align-items:center;gap:8px;
  background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:6px 13px;
}
.search svg{width:15px;height:15px;color:var(--muted-2)}
.search input{flex:1;border:0;background:none;outline:none;font-size:13px}
.search input::placeholder{color:var(--muted-2)}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:9px}
.chip{
  display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
  background:var(--surface);border-radius:999px;padding:6px 12px;font-size:12.5px;color:var(--ink-2);
}
.chip svg{width:14px;height:14px;color:var(--muted)}
.chip:hover{border-color:var(--line-strong)}
.chip-timer{font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:12px}
.chip-timer.running{background:var(--green-soft);border-color:var(--green-soft-2);color:var(--green-deep)}
.chip-timer.running svg{color:var(--green)}
.chip-exam .chip-label{font-size:10.5px;color:var(--muted-2)}
.chip-exam strong{font-size:13px;color:var(--ink)}
.chip-exam.warn{background:var(--gold-soft);border-color:#EBDCB2}
.chip-exam.warn strong{color:#7A5F14}

.view{padding:24px 26px 90px;max-width:1240px;width:100%}
/* 被浮层（顶栏 / 手机底部 tabbar）挡住的控件，滚动复现时自动让开 */
.view *{scroll-margin-top:calc(var(--top-h) + 16px);scroll-margin-bottom:calc(88px + env(safe-area-inset-bottom))}

/* ---------- 通用组件 ---------- */
.page-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.page-head h1{margin:0;font-size:26px;letter-spacing:-.4px;font-weight:700}
.page-head h1 .accent{color:var(--green)}
.page-head h1 em{font-family:var(--serif);font-style:normal;font-weight:600}
.page-head p{margin:5px 0 0;color:var(--muted);font-size:12.5px}
.page-head .spacer{flex:1}

.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-1)}
.card-pad{padding:18px 20px}
.grid{display:grid;gap:14px}
.grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid.cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
.stack{display:flex;flex-direction:column;gap:14px}
.row{display:flex;align-items:center;gap:10px}
.row.wrap{flex-wrap:wrap}
.spacer{flex:1}
.muted{color:var(--muted)}
.tiny{font-size:11.5px}
.small{font-size:12.5px}
.tabular{font-variant-numeric:tabular-nums}
h2.sec{margin:0 0 12px;font-size:15px;font-weight:650;display:flex;align-items:center;gap:8px}
h2.sec .spacer{flex:1}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:8px 15px;border-radius:11px;border:1px solid var(--line);
  background:var(--surface);font-size:13px;font-weight:550;color:var(--ink-2);transition:.14s;
}
.btn svg{width:15px;height:15px}
.btn:hover{border-color:var(--line-strong);background:var(--surface-2)}
.btn.primary{background:var(--green-deep);border-color:var(--green-deep);color:#fff}
.btn.primary:hover{background:#0F3A32}
.btn.gold{background:var(--gold-2);border-color:var(--gold-2);color:#3A2C05}
.btn.ghost{background:transparent;border-color:transparent;color:var(--muted)}
.btn.ghost:hover{background:var(--surface-3);color:var(--ink-2)}
.btn.sm{padding:5px 10px;font-size:12px;border-radius:9px}
.btn.lg{padding:11px 20px;font-size:14px;border-radius:12px}
.btn.block{width:100%}
.btn[disabled]{opacity:.45;pointer-events:none}
.btn-group{display:inline-flex;gap:8px;flex-wrap:wrap}

.tag{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:650;
  padding:2px 8px;border-radius:6px;letter-spacing:.3px;background:var(--surface-3);color:var(--ink-2)}
.tag.mint{background:var(--green-soft);color:#0C5B51}
.tag.gold{background:var(--gold-soft);color:#7A5F14}
.tag.rose{background:var(--rose-soft);color:#8A3A26}
.tag.blue{background:var(--blue-soft);color:var(--blue)}

.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:11.5px;color:var(--muted);font-weight:600}
input[type=text],input[type=date],input[type=search],select,textarea{
  border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-sm);
  padding:8px 11px;font-size:13px;outline:none;transition:.14s;width:100%;
}
input:focus,select:focus,textarea:focus{border-color:var(--green);box-shadow:0 0 0 3px rgba(18,119,107,.12)}
textarea{resize:vertical;line-height:1.7}

.bar{height:6px;border-radius:999px;background:var(--surface-3);overflow:hidden}
.bar > span{display:block;height:100%;background:var(--green);border-radius:999px;transition:width .3s}
.bar.gold > span{background:var(--gold-2)}

.stat{padding:15px 16px}
.stat .stat-k{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:6px}
.stat .stat-k svg{width:14px;height:14px}
.stat .stat-v{font-size:25px;font-weight:700;letter-spacing:-.5px;margin-top:5px;font-variant-numeric:tabular-nums}
.stat .stat-v small{font-size:12px;font-weight:500;color:var(--muted);margin-left:3px}
.stat .stat-s{font-size:11.5px;color:var(--muted-2);margin-top:2px}

.list{display:flex;flex-direction:column}
.list-item{
  display:flex;align-items:center;gap:13px;padding:13px 16px;border-top:1px solid var(--line);
  transition:background .12s;text-align:left;width:100%;
}
.list-item:first-child{border-top:0}
.list-item:hover{background:var(--surface-2)}
.list-item .li-main{flex:1;min-width:0}
.list-item .li-title{font-weight:600;font-size:13.5px;display:flex;align-items:center;gap:8px}
.list-item .li-sub{color:var(--muted);font-size:11.5px;margin-top:3px;display:flex;gap:12px;flex-wrap:wrap}
.list-item .li-score{font-family:var(--serif);font-weight:700;font-size:17px;color:var(--green-deep)}
.empty{padding:38px 20px;text-align:center;color:var(--muted);font-size:13px}

.stars{display:inline-flex;gap:2px;color:var(--gold-2)}
.stars svg{width:11px;height:11px}
.stars .off{color:var(--line-strong)}

.tabs{display:inline-flex;gap:4px;background:var(--surface-3);padding:3px;border-radius:11px}
.tab{padding:6px 14px;border-radius:8px;font-size:12.5px;color:var(--ink-2);font-weight:550}
.tab.active{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-1)}

.progress-line{height:5px;border-radius:999px;background:var(--surface-3);overflow:hidden}
.progress-line > span{display:block;height:100%;background:var(--green)}

.kbd{font-family:var(--mono);font-size:11px;background:var(--surface-3);padding:1px 6px;border-radius:5px;color:var(--ink-2)}
.divider{height:1px;background:var(--line);margin:14px 0}
.warn-text{color:var(--rose);font-size:12px}
.ok-text{color:var(--green);font-size:12px}

/* ---------- 词汇闪卡 ---------- */
.flash-wrap{max-width:780px;margin:0 auto}
/* 今日计划卡 */
.plan-card{margin-bottom:14px}
.plan-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.plan-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.plan-item{min-width:0}
.plan-k{font-size:11.5px;color:var(--muted);font-weight:600}
.plan-v{font-size:22px;font-weight:700;letter-spacing:-.4px;margin:3px 0 6px}
.plan-v small{font-size:12px;color:var(--muted);font-weight:600;margin-left:2px}
.plan-s{font-size:11.5px;color:var(--muted-2);margin-top:6px}
.plan-s b{color:var(--green-deep)}
.plan-foot{margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
.plan-foot b{color:var(--ink-2)}
.linkbtn{background:none;border:0;padding:0;color:var(--green-deep);font-size:11.5px;
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;font-weight:600}
.flash{
  background:var(--surface);border:1px solid var(--line);border-radius:20px;
  padding:40px 30px 32px;text-align:center;box-shadow:var(--shadow-1);
  min-height:320px;display:flex;flex-direction:column;justify-content:center;gap:12px;cursor:pointer;
  position:relative;
}
.flash .pron{
  position:absolute;top:14px;right:14px;width:34px;height:34px;border-radius:50%;
  border:1px solid var(--line);background:var(--surface-2);display:grid;place-items:center;cursor:pointer;
}
.flash .pron svg{width:16px;height:16px;color:var(--green-deep)}
.flash .pron:hover{background:var(--green-soft);border-color:var(--green-soft-2)}
.flash .pron:active{transform:scale(.94)}
.flash .pron.loading{border-color:var(--green-soft-2);background:var(--green-soft)}
.flash .pron.loading svg{opacity:.25}
.flash .pron.loading::after{
  content:"";position:absolute;width:16px;height:16px;border-radius:50%;
  border:2px solid var(--green-soft-2);border-top-color:var(--green-deep);
  animation:pron-spin .7s linear infinite;
}
.flash .pron.playing{border-color:var(--green-deep);background:var(--green-deep)}
.flash .pron.playing svg{color:#fff}
@keyframes pron-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.flash .pron.loading::after{animation-duration:1.8s}}
.flash .round-tag{font-size:11.5px;color:var(--green-deep);font-weight:650;letter-spacing:.4px}
.flash .flash-tag{font-size:11px;letter-spacing:2.4px;color:var(--muted-2);font-weight:700}
.flash .word{font-family:var(--serif);font-size:50px;line-height:1.1;letter-spacing:-1px;font-weight:600;word-break:break-word}
.flash .phone{font-size:14px;color:var(--muted);font-family:var(--serif)}
.flash .hint{font-size:11.5px;color:var(--muted-2);margin-top:6px}
.flash .back{display:flex;flex-direction:column;gap:10px;text-align:left;
  max-height:min(58vh,520px);overflow:auto;padding-right:2px}
.flash .back .pos{font-size:12px;color:var(--green);font-weight:700}
.flash .back .cn{font-size:20px;line-height:1.5;font-weight:650}
.flash .back .cn.cn-long{font-size:15px;line-height:1.7;font-weight:500}
.flash .back .syn{font-size:12.5px;color:var(--muted);line-height:1.7}
.flash .back .ex{font-size:13px;font-family:var(--serif);color:var(--ink-2);margin-top:4px;line-height:1.7}
.flash .back .ex-cn{font-size:12px;color:var(--muted);line-height:1.7}
.flash .back .srs-line{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:8px;
  padding-top:10px;border-top:1px dashed var(--line)}
.chip.sm{padding:3px 8px;font-size:11px;border-radius:7px}
.flash.flash-done{cursor:default;gap:10px}
.flash .done-ico{width:44px;height:44px;margin:0 auto;border-radius:50%;background:var(--green-soft);
  display:grid;place-items:center}
.flash .done-ico svg{width:22px;height:22px;color:var(--green-deep)}
.flash .done-t{font-size:20px;font-weight:700}
.flash .done-s{font-size:12.5px;color:var(--muted);line-height:1.85}
.rate-cap{text-align:center;margin-top:10px}
.btn em{font-style:normal;font-size:10px;opacity:.6;margin-left:5px;
  border:1px solid currentColor;border-radius:4px;padding:0 3px}
.flash-foot{display:flex;justify-content:center;align-items:center;gap:9px;margin-top:18px;flex-wrap:wrap}
.btn.rate-unknown{background:var(--rose-soft);border-color:#EFD3C9;color:#8A3A26}
.btn.rate-fuzzy{background:var(--amber-soft);border-color:#EFDDB6;color:#7A5F14}
.btn.rate-known{background:var(--green-soft);border-color:var(--green-soft-2);color:#0C5B51}
.flash-progress{margin-top:20px}
.flash-progress .row{justify-content:space-between;font-size:11.5px;color:var(--muted);margin-bottom:6px}

/* ---------- 题目 ---------- */
.q{display:flex;gap:12px;padding:14px 16px;border-top:1px solid var(--line)}
.q:first-child{border-top:0}
.q-num{width:24px;height:24px;flex:0 0 auto;border-radius:7px;background:var(--surface-3);
  display:grid;place-items:center;font-size:11.5px;font-weight:700;color:var(--ink-2)}
.q-body{flex:1;min-width:0}
.q-text{font-size:13.5px;line-height:1.75}
.q-text .blank{display:inline-block;min-width:96px;border-bottom:1.5px solid var(--line-strong);margin:0 4px}
.q-answer-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:9px}
.opt{
  border:1px solid var(--line);background:var(--surface);border-radius:9px;padding:6px 12px;
  font-size:12.5px;color:var(--ink-2);transition:.12s;
}
.opt:hover{border-color:var(--line-strong);background:var(--surface-2)}
.opt.sel{background:var(--green-soft);border-color:var(--green-soft-2);color:var(--green-deep);font-weight:600}
.opt.right{background:var(--green-soft);border-color:var(--green);color:#0C5B51;font-weight:600}
.opt.wrong{background:var(--rose-soft);border-color:#E4B7A8;color:#8A3A26}
.q-explain{margin-top:9px;font-size:12px;color:var(--ink-2);background:var(--surface-2);
  border-left:3px solid var(--green);border-radius:0 8px 8px 0;padding:8px 11px}
.q-explain b{color:var(--green-deep)}
.input-gap{
  border:1px solid var(--line);border-radius:8px;padding:5px 10px;font-size:13px;
  width:auto;min-width:150px;background:var(--surface);
}
.input-gap.right{border-color:var(--green);background:#F1F8F5}
.input-gap.wrong{border-color:#E4B7A8;background:#FCF3F0}

/* ---------- 阅读 ---------- */
.read-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:start}
.passage{max-height:72vh;overflow:auto;padding:20px 22px}
.passage h3{margin:0 0 4px;font-size:16px}
.passage .passage-sub{font-size:11.5px;color:var(--muted);margin-bottom:14px}
.passage p{font-family:var(--serif);font-size:14.5px;line-height:1.85;color:var(--ink-2);margin:0 0 13px}
.passage .para-label{font-family:var(--sans);font-weight:700;color:var(--green-deep);margin-right:6px}
.questions{max-height:72vh;overflow:auto}
.read-start{max-width:520px;margin:7vh auto 0;text-align:center;padding:40px 30px}

/* ---------- 写作 / 口语 ---------- */
.editor-layout{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:16px;align-items:start}
.editor textarea{min-height:46vh;border:0;background:none;font-family:var(--serif);font-size:15px;line-height:1.9;padding:18px 20px;border-radius:0}
.editor textarea:focus{box-shadow:none;border-color:transparent}
.editor-head{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.editor-foot{display:flex;align-items:center;gap:10px;padding:12px 16px;border-top:1px solid var(--line);flex-wrap:wrap}
.timer-display{font-family:var(--mono);font-size:15px;font-variant-numeric:tabular-nums}
.timer-display.over{color:var(--rose)}
.checklist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.checklist li{display:flex;gap:8px;font-size:12.5px;color:var(--ink-2);line-height:1.6}
.checklist li::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--green-soft-2);margin-top:7px;flex:0 0 auto}
.prompt-text{font-family:var(--serif);font-size:14.5px;line-height:1.8}
.cue-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px}
.cue-card .cue-title{font-family:var(--serif);font-size:19px;font-weight:600;margin-bottom:8px}
.cue-card ul{margin:10px 0 0;padding-left:18px;font-size:13px;color:var(--ink-2);line-height:1.8}
.rec-dot{width:8px;height:8px;border-radius:50%;background:var(--rose);display:inline-block}
.rec-dot.live{animation:pulse 1s infinite}
@keyframes pulse{50%{opacity:.25}}
.wave{display:flex;align-items:flex-end;gap:3px;height:28px}
.wave i{width:3px;background:var(--green-soft-2);border-radius:2px}

/* ---------- 模考 / 进度 ---------- */
.mock-hero{background:linear-gradient(135deg,#17453C,#12776B);color:#fff;border:0}
.mock-hero .card-pad{padding:26px 28px}
.mock-hero h2{margin:0 0 6px;font-size:22px;letter-spacing:-.3px}
.mock-hero p{margin:0;font-size:12.5px;color:rgba(255,255,255,.78)}
.mock-hero .btn{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.25);color:#fff}
.mock-hero .btn:hover{background:rgba(255,255,255,.22)}
.mod-card{border-radius:var(--radius);padding:18px 20px;color:#fff;position:relative;overflow:hidden;text-align:left;border:0}
.mod-card h3{margin:0 0 4px;font-size:16.5px;display:flex;align-items:center;gap:8px}
.mod-card p{margin:0;font-size:12px;opacity:.85;line-height:1.6}
.mod-card .mod-go{margin-top:14px;font-size:12px;display:inline-flex;align-items:center;gap:5px;opacity:.95}
.mod-card svg{width:17px;height:17px}
/* 剑桥真题面板收起时隐藏 64 个 Test 按钮 */
.cb-hidden{display:none}
.mod-teal{background:linear-gradient(140deg,#17695E,#0E5B52)}
.mod-gold{background:linear-gradient(140deg,#C9A227,#A9821C)}
.mod-ink{background:linear-gradient(140deg,#2C3A35,#1B2622)}
.mod-blue{background:linear-gradient(140deg,#3B6390,#2A4A6E)}
.mod-rose{background:linear-gradient(140deg,#B4503A,#8E3B29)}
.mod-plum{background:linear-gradient(140deg,#6B4A7A,#4E3559)}
.chart-wrap{position:relative;height:190px}
canvas{max-width:100%}
.table{width:100%;border-collapse:collapse;font-size:12.5px}
.table th,.table td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line)}
.table th{font-size:11px;color:var(--muted);font-weight:650;text-transform:uppercase;letter-spacing:.4px}
.table td.tabular{font-variant-numeric:tabular-nums}

/* ---------- 弹层 ---------- */
.modal-root{position:fixed;inset:0;pointer-events:none;z-index:60}
.modal-root.on{pointer-events:auto}
.modal-bg{position:absolute;inset:0;background:rgba(24,32,28,.36);opacity:0;transition:.18s}
.modal-root.on .modal-bg{opacity:1}
.modal{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-46%);width:min(560px,calc(100vw - 32px));
  background:var(--surface);border-radius:18px;box-shadow:var(--shadow-2);padding:22px 24px;
  opacity:0;transition:.18s;max-height:86vh;overflow:auto;
}
.modal-root.on .modal{opacity:1;transform:translate(-50%,-50%)}
.modal h3{margin:0 0 4px;font-size:17px}
.modal .modal-sub{color:var(--muted);font-size:12px;margin-bottom:16px}
.modal-foot{display:flex;gap:9px;justify-content:flex-end;margin-top:20px}
.toast{
  position:fixed;left:50%;bottom:26px;transform:translate(-50%,20px);background:var(--ink);color:#fff;
  padding:9px 16px;border-radius:999px;font-size:12.5px;opacity:0;transition:.2s;z-index:80;pointer-events:none;
}
.toast.on{opacity:1;transform:translate(-50%,0)}
.net-bar{
  position:fixed;left:50%;top:0;transform:translate(-50%,-120%);z-index:90;
  display:flex;align-items:center;gap:8px;max-width:calc(100% - 24px);
  padding:8px 15px;border-radius:0 0 12px 12px;
  background:#B23A3A;color:#fff;font-size:12.5px;line-height:1.3;
  box-shadow:0 6px 18px rgba(120,30,30,.34);transition:transform .24s cubic-bezier(.22,.61,.36,1);
  pointer-events:none;
}
.net-bar svg{width:15px;height:15px;flex:none}
.net-bar.on{transform:translate(-50%,0)}
.drawer{display:none}

/* ---------- 联网词书选择（net.vocab.js） ---------- */
.nv-list{display:flex;flex-direction:column;gap:8px}
.nv-group{font-size:11px;letter-spacing:.08em;color:var(--muted-2);margin:12px 0 2px;font-weight:600}
.nv-item{
  display:flex;align-items:center;gap:12px;width:100%;text-align:left;cursor:pointer;
  background:var(--surface-2);border:1px solid var(--line);border-radius:12px;padding:11px 13px;
  transition:.15s;color:var(--ink);font:inherit;
}
.nv-item:hover{border-color:var(--line-strong);background:var(--surface-3)}
.nv-item.on{border-color:var(--green);background:var(--green-soft)}
.nv-main{flex:1;min-width:0}
.nv-title{display:flex;align-items:center;gap:8px;font-size:13.5px;font-weight:600;flex-wrap:wrap}
.nv-sub{color:var(--muted);font-size:11.5px;margin-top:3px}
.nv-go{color:var(--muted);display:flex;flex:0 0 auto}
.nv-go svg{width:16px;height:16px}
.nv-item.on .nv-go{color:var(--green-deep)}

/* ---------- 手机端 ---------- */
.tabbar{display:none}
@media (max-width:1080px){
  .grid.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .editor-layout{grid-template-columns:1fr}
  .read-layout{grid-template-columns:1fr}
  .passage,.questions{max-height:none}
}
@media (max-width:820px){
  :root{--top-h:54px}
  body{padding-bottom:calc(78px + env(safe-area-inset-bottom))}
  .rail{
    position:fixed;z-index:70;left:0;top:0;height:100vh;transform:translateX(-100%);
    transition:transform .22s ease;box-shadow:var(--shadow-2);padding-top:20px;
  }
  .rail.open{transform:none}
  .rail-toggle{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
    border-radius:10px;border:1px solid var(--line);background:var(--surface)}
  .drawer{display:block;position:fixed;inset:0;background:rgba(24,32,28,.34);z-index:65;opacity:0;pointer-events:none;transition:.2s}
  .drawer.on{opacity:1;pointer-events:auto}
  .topbar{padding:0 14px;gap:8px}
  .search{max-width:none}
  .chip-exam .chip-label{display:none}
  .view{padding:18px 14px calc(86px + env(safe-area-inset-bottom))}
  .page-head h1{font-size:21px}
  .grid.cols-3,.grid.cols-2{grid-template-columns:1fr}
  /* 手机端 4 张统计卡改成两列，首屏就能看到今日任务和模块入口 */
  .grid.cols-4{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  /* 模块入口手机端两列，6 个入口 3 行排完 */
  .grid.mods-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .mod-card{padding:14px 13px}
  .mod-card h3{font-size:14.5px;gap:6px}
  .mod-card p{font-size:11.5px;line-height:1.5}
  .mod-card .mod-go{margin-top:10px;font-size:11.5px}
  .stat{padding:12px 12px}
  .stat .stat-v{font-size:21px;margin-top:4px}
  .stat .stat-s{font-size:11px;line-height:1.5}
  .flash{padding:30px 18px 24px;min-height:262px}
  .flash .word{font-size:34px}
  .flash .back{max-height:62vh}
  .flash .back .cn{font-size:18px}
  .flash .back .cn.cn-long{font-size:14px;line-height:1.75}
  .flash-foot{gap:7px;margin-top:14px}
  .flash-foot .btn{padding:6px 10px}
  .plan-grid{grid-template-columns:1fr 1fr;gap:10px}
  .plan-grid .plan-item:last-child{grid-column:1 / -1}
  .plan-v{font-size:19px}
  .rate-cap{font-size:10.5px;line-height:1.7}
  .tabbar{
    display:flex;position:fixed;bottom:0;left:0;right:0;z-index:60;background:#fff;
    -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-top:1px solid var(--line);
    padding:7px 4px calc(7px + env(safe-area-inset-bottom));pointer-events:none;
  }
  .tabbar button{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;
    font-size:10px;color:var(--muted);padding:3px 0;border-radius:10px;pointer-events:auto}
  .tabbar button svg{width:19px;height:19px}
  .tabbar button.active{color:var(--green-deep);font-weight:650}
}

/* 联网精读 / 精听（net.content.js） */
.w{border-radius:4px;cursor:pointer;transition:background .12s ease}
.w:hover{background:var(--green-soft)}
.sent{
  margin:0 0 10px;padding:8px 10px;border-radius:8px;line-height:1.75;cursor:pointer;
  border:1px solid transparent;transition:background .12s ease,border-color .12s ease;
}
.sent:hover{background:var(--surface-3)}
.sent.on{background:var(--green-soft);border-color:var(--green);font-weight:600}
/* 听力原文逐句高亮（views.practice.js 网络音频播放） */
.vpline{transition:background .12s ease}
.vpline.on{background:var(--green-soft);box-shadow:inset 3px 0 0 var(--green)}
/* 网上真人原声句子列表（net.audio.js） */
.na-row{
  display:flex;gap:10px;align-items:flex-start;padding:10px 10px;margin-bottom:8px;
  border:1px solid var(--line);border-radius:10px;background:var(--surface-2);
  transition:background .12s ease,border-color .12s ease;
}
.na-row:hover{border-color:var(--green)}
.na-row.on{background:var(--green-soft);border-color:var(--green);box-shadow:inset 3px 0 0 var(--green)}
.na-body{flex:1;min-width:0}
.na-en{font-size:14.5px;line-height:1.7}
.na-cn{margin-top:3px;font-size:12.5px;color:var(--muted)}
.na-meta{margin-top:4px;font-size:11px;color:var(--muted);opacity:.8}
.na-w{border-radius:4px;cursor:pointer;transition:background .12s ease}
.na-w:hover{background:var(--green-soft)}
/* 听力文章（真人原声 + LRC 逐句同步，net.listen.js） */
.nl-items{display:grid;gap:8px}
.nl-item{
  display:block;width:100%;text-align:left;padding:11px 12px;border-radius:10px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface-2);font-family:inherit;
  transition:background .12s ease,border-color .12s ease;
}
.nl-item:hover{border-color:var(--green);background:var(--green-soft)}
.nl-item-t{display:block;font-size:14.5px;font-weight:600;color:var(--ink)}
.nl-item-d{display:block;margin-top:4px;font-size:11.5px;color:var(--muted)}
.nl-ctrl{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.nl-bar{position:relative;height:8px;border-radius:5px;background:var(--surface-3);cursor:pointer;overflow:hidden}
.nl-bar > i{display:block;height:100%;width:0;border-radius:5px;background:linear-gradient(90deg,var(--green),var(--green-soft-2))}
.nl-time{font-variant-numeric:tabular-nums}
.nl-mini{
  padding:1px 7px;border-radius:6px;font-size:11px;cursor:pointer;font-family:inherit;
  border:1px solid var(--line);background:var(--surface);color:var(--muted);
}
.nl-mini:hover{color:var(--green-deep);border-color:var(--green);background:var(--green-soft)}
.na-row.nl-blind .na-en{filter:blur(5px);transition:filter .15s ease}
.na-row.nl-blind:hover .na-en{filter:none}
.na-row.nl-loop{border-color:var(--gold-2);box-shadow:inset 3px 0 0 var(--gold-2)}
.passage .word{font-weight:650}
.cn-toggle{
  display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;margin-left:6px;border-radius:5px;
  font-size:11px;line-height:1;color:var(--muted);background:var(--surface-3);
  border:1px solid var(--line);cursor:pointer;vertical-align:2px;
}
.cn-toggle:hover{color:var(--green-deep);border-color:var(--green);background:var(--green-soft)}
.para-cn{
  display:block;margin:6px 0 0;padding:8px 10px;border-left:3px solid var(--green-soft);
  border-radius:0 8px 8px 0;background:var(--surface-3);color:var(--muted);
  font-size:13.5px;line-height:1.8;
}

/* ============================================================
   深色主题 —— 设置页「外观」切换（html[data-theme]）
   只覆盖设计令牌，组件规则不用改
   ============================================================ */
html[data-theme="dark"]{
  --bg:#101518;
  --surface:#181F24;
  --surface-2:#1C242A;
  --surface-3:#222C33;
  --line:#2A353C;
  --line-strong:#3A464E;
  --ink:#E8EDEA;
  --ink-2:#C2CDC8;
  --muted:#8E9BA1;
  --muted-2:#77848A;
  --green-deep:#8FD8CB;
  --green:#4FBFAE;
  --green-soft:#16302D;
  --green-soft-2:#1B3A35;
  --gold:#E0B94E;
  --gold-2:#E8C868;
  --gold-soft:#33291A;
  --rose:#E2917C;
  --rose-soft:#3A241F;
  --amber:#E0B44E;
  --amber-soft:#33290F;
  --blue:#93B4E4;
  --blue-soft:#1E2939;
  --shadow-1:0 1px 2px rgba(0,0,0,.28), 0 6px 20px rgba(0,0,0,.24);
  --shadow-2:0 10px 34px rgba(0,0,0,.42);
}
html[data-theme="dark"] body{background:var(--bg);color:var(--ink)}
html[data-theme="dark"] ::-webkit-scrollbar-thumb{
  background:#3A464E;background-clip:content-box;
}
html[data-theme="dark"] .brand-mark{background:var(--green-soft);color:var(--green-deep)}
html[data-theme="dark"] input,html[data-theme="dark"] select,html[data-theme="dark"] textarea{
  background:var(--surface-2);color:var(--ink);border-color:var(--line);
}
html[data-theme="dark"] .sprite symbol path,
html[data-theme="dark"] .sprite symbol rect,
html[data-theme="dark"] .sprite symbol circle{stroke:currentColor}
/* 浅色令牌里写死的深色文字：深色主题下换成亮色，否则糊在一起 */
html[data-theme="dark"] .badge.gold,
html[data-theme="dark"] .tag.gold,
html[data-theme="dark"] .streak span,
html[data-theme="dark"] .chip-exam.warn strong,
html[data-theme="dark"] .btn.rate-fuzzy{color:var(--gold)}
html[data-theme="dark"] .badge.mint,
html[data-theme="dark"] .tag.mint,
html[data-theme="dark"] .btn.rate-known,
html[data-theme="dark"] .opt.right,
html[data-theme="dark"] .input-gap.right{color:var(--green-deep)}
html[data-theme="dark"] .badge.rose,
html[data-theme="dark"] .tag.rose,
html[data-theme="dark"] .btn.rate-unknown,
html[data-theme="dark"] .opt.wrong{color:var(--rose)}
html[data-theme="dark"] .btn.primary{background:var(--green);border-color:var(--green);color:#0B1F1B}
html[data-theme="dark"] .btn.primary:hover{background:var(--green-deep);border-color:var(--green-deep)}
html[data-theme="dark"] .input-gap.right{background:var(--green-soft)}
html[data-theme="dark"] .input-gap.wrong{background:var(--rose-soft)}
html[data-theme="dark"] .tabbar{background:var(--surface);border-top:1px solid var(--line)}

/* ---------- 回到顶部（长页面滑到中段才出现） ---------- */
.to-top{
  position:fixed;right:18px;bottom:26px;z-index:55;
  width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-strong);background:var(--surface);
  color:var(--muted);box-shadow:var(--shadow-2);
  opacity:0;pointer-events:none;transform:translateY(8px);
  transition:opacity .18s ease,transform .18s ease;
}
.to-top svg{width:18px;height:18px}
.to-top.on{opacity:1;pointer-events:auto;transform:none}
.to-top:hover{color:var(--green-deep);border-color:var(--green)}
@media (max-width:820px){
  .to-top{right:12px;bottom:calc(84px + env(safe-area-inset-bottom))}
}

/* ---------- 动效与交互反馈（换页过渡 / 按压回弹 / 悬停浮起） ---------- */
/* 只在「换了路由」时播一次，同页重绘（进度自动刷新等）不重播，避免页面一直闪 */
@keyframes view-in{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.view.view-enter{animation:view-in .24s cubic-bezier(.22,.61,.36,1) both}

/* 触摸/点击反馈：位移+缩放都在 transform 上，不触发布局重排 */
.btn,.chip,.tabbar button,.mod-card,.list-item,.to-top,.search{
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.btn:active{transform:translateY(1px) scale(.985)}
.chip:active,.to-top:active{transform:scale(.97)}
.tabbar button{transition:color .16s ease,transform .12s ease}
.tabbar button:active{transform:scale(.93)}
.list-item:active{background:var(--surface-3)}

.mod-card{transition:transform .18s cubic-bezier(.22,.61,.36,1),box-shadow .18s ease}
.mod-card:active{transform:scale(.99)}
@media (hover:hover){
  .mod-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-2)}
}

/* 剑桥真题面板展开时淡入，而不是「啪」地弹出来 */
.cb-books{animation:view-in .2s cubic-bezier(.22,.61,.36,1) both}

/* ---------- 剑桥真题「展开 64 套」入口：收起时做成显眼的金色主按钮 ---------- */
.cb-toggle{gap:7px}
.cb-toggle svg{width:15px;height:15px;transition:transform .22s cubic-bezier(.22,.61,.36,1)}
/* i-up 图标掉头朝下 = 「点我展开」；展开后朝上 = 「收起」 */
.cb-toggle-open svg{transform:rotate(180deg)}
.cb-toggle-open{
  border-radius:999px;padding:9px 18px;font-size:13.5px;font-weight:650;
  box-shadow:0 4px 14px rgba(201,162,39,.34);
}
.cb-toggle-open:hover{background:#E2B34A;border-color:#E2B34A}
.cb-toggle-n{
  margin-left:7px;font-size:11px;font-weight:650;padding:1px 8px;border-radius:999px;
  background:rgba(58,44,5,.16);color:#3A2C05;
}
@media (max-width:820px){
  /* 手机上占满一整行，不会被标题挤成不起眼的小字 */
  .cb-toggle-open{flex:1 1 100%;justify-content:center}
}

/* 尊重系统「减少动态效果」：保留加载转圈的辨识度，其余动效降到瞬时 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  .flash .pron.loading::after{animation-duration:1.8s !important;animation-iteration-count:infinite !important}
}
