:root{
  --bg:#f6f7fb; --panel:#ffffff; --ink:#1a2233; --muted:#5b6577;
  --line:#e3e6ee; --green:#0e9f6e; --red:#d64545; --current-bg:#fff3cd;
  --current-border:#f0d48a; --accent:#2563eb; --accent-ink:#ffffff;
  --radius:14px; --font-size:22px;
  --card-hover-shadow:0 2px 10px rgb(37 99 235 / .10);
  --input-bg:#ffffff; --input-disabled:#eef1f6; --kbd-bg:#eef1f6;
  --progress-track:#e8ebf2; --modal-bg:#ffffff; --overlay-bg:rgba(0, 0, 0, 0.45);
  --active-line-bg:rgba(37, 99, 235, 0.08); --pending-char:#9aa3b2;
}

[data-theme="dark"]{
  --bg:#0f172a; --panel:#1e293b; --ink:#f8fafc; --muted:#94a3b8;
  --line:#334155; --green:#10b981; --red:#f87171; --current-bg:#3d3215;
  --current-border:#856404; --accent:#3b82f6; --accent-ink:#ffffff;
  --card-hover-shadow:0 4px 14px rgb(0 0 0 / .40);
  --input-bg:#0b1120; --input-disabled:#1e293b; --kbd-bg:#0b1120;
  --progress-track:#334155; --modal-bg:#1e293b; --overlay-bg:rgba(0, 0, 0, 0.70);
  --active-line-bg:rgba(59, 130, 246, 0.16); --pending-char:#64748b;
}

*{box-sizing:border-box}

/* ===== 9 challenge color themes (light) — practice view via body[data-mode] ===== */
body[data-mode="words"]{--accent:#2563eb;--current-bg:#dbeafe;--current-border:#93c5fd;--active-line-bg:rgba(37,99,235,.08)}
body[data-mode="sentences"]{--accent:#059669;--current-bg:#d1fae5;--current-border:#6ee7b7;--active-line-bg:rgba(5,150,105,.08)}
body[data-mode="articles_punct"]{--accent:#7c3aed;--current-bg:#ede9fe;--current-border:#c4b5fd;--active-line-bg:rgba(124,58,237,.08)}
body[data-mode="long_articles"]{--accent:#d97706;--current-bg:#fef3c7;--current-border:#fcd34d;--active-line-bg:rgba(217,119,6,.08)}
body[data-mode="mixed_zh_en"]{--accent:#0891b2;--current-bg:#cffafe;--current-border:#67e8f9;--active-line-bg:rgba(8,145,178,.08)}
body[data-mode="life_situations"]{--accent:#db2777;--current-bg:#fce7f3;--current-border:#f9a8d4;--active-line-bg:rgba(219,39,119,.08)}
body[data-mode="general_legal_docs"]{--accent:#475569;--current-bg:#e2e8f0;--current-border:#94a3b8;--active-line-bg:rgba(71,85,105,.08)}
body[data-mode="litigation_legal_docs"]{--accent:#c2410c;--current-bg:#ffedd5;--current-border:#fdba74;--active-line-bg:rgba(194,65,12,.08)}
body[data-mode="classical_texts"]{--accent:#b91c1c;--current-bg:#fee2e2;--current-border:#fca5a5;--active-line-bg:rgba(185,28,28,.08)}
body[data-mode="custom_text"]{--accent:#9333ea;--current-bg:#f3e8ff;--current-border:#d8b4fe;--active-line-bg:rgba(147,51,234,.08)}
/* ===== 9 themes (dark) ===== */
html[data-theme="dark"] body[data-mode="words"]{--accent:#60a5fa;--current-bg:#1e3a5f;--current-border:#3b82f6;--active-line-bg:rgba(96,165,250,.16)}
html[data-theme="dark"] body[data-mode="sentences"]{--accent:#34d399;--current-bg:#064e3b;--current-border:#059669;--active-line-bg:rgba(52,211,153,.16)}
html[data-theme="dark"] body[data-mode="articles_punct"]{--accent:#a78bfa;--current-bg:#2e1065;--current-border:#7c3aed;--active-line-bg:rgba(167,139,250,.16)}
html[data-theme="dark"] body[data-mode="long_articles"]{--accent:#fbbf24;--current-bg:#422006;--current-border:#b45309;--active-line-bg:rgba(251,191,36,.16)}
html[data-theme="dark"] body[data-mode="mixed_zh_en"]{--accent:#22d3ee;--current-bg:#083344;--current-border:#0e7490;--active-line-bg:rgba(34,211,238,.16)}
html[data-theme="dark"] body[data-mode="life_situations"]{--accent:#f472b6;--current-bg:#500724;--current-border:#be185d;--active-line-bg:rgba(244,114,182,.16)}
html[data-theme="dark"] body[data-mode="general_legal_docs"]{--accent:#94a3b8;--current-bg:#1e293b;--current-border:#475569;--active-line-bg:rgba(148,163,184,.16)}
html[data-theme="dark"] body[data-mode="litigation_legal_docs"]{--accent:#fb923c;--current-bg:#431407;--current-border:#c2410c;--active-line-bg:rgba(251,146,60,.16)}
html[data-theme="dark"] body[data-mode="classical_texts"]{--accent:#f87171;--current-bg:#450a0a;--current-border:#b91c1c;--active-line-bg:rgba(248,113,113,.16)}
html[data-theme="dark"] body[data-mode="custom_text"]{--accent:#c084fc;--current-bg:#3b0764;--current-border:#9333ea;--active-line-bg:rgba(192,132,252,.16)}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font-family:"Noto Sans TC","PingFang TC","Microsoft JhengHei","Noto Sans","Segoe UI",sans-serif;
  line-height:1.6;
  transition:background-color .2s ease, color .2s ease;
}
.hidden{display:none!important}
.topbar{
  position:sticky; top:0; z-index:10;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 18px; background:var(--panel); border-bottom:1px solid var(--line);
  transition:background-color .2s ease, border-color .2s ease;
}
.brand{display:flex; align-items:center; gap:10px}
.brand-mark{
  width:40px;height:40px;border-radius:10px;background:var(--accent);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;
}
.brand-title{font-weight:700;font-size:18px;line-height:1.2}
.topbar-actions{display:flex;align-items:center;gap:8px}
.theme-btn{display:inline-flex;align-items:center;gap:5px;cursor:pointer}
.font-size-label{color:var(--muted);font-size:14px}
select{
  padding:6px 8px;border:1px solid var(--line);border-radius:8px;
  background:var(--panel);color:var(--ink);font-size:14px;
}
.btn{
  padding:10px 16px;border:1px solid var(--line);border-radius:10px;
  background:var(--panel);color:var(--ink);cursor:pointer;font-size:15px;
  transition:border-color .15s ease, background-color .15s ease;
}
.btn:hover{border-color:var(--accent)}
.btn.ghost{background:transparent}
.btn.small{padding:6px 10px;font-size:13px}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn.primary:hover{filter:brightness(1.08)}

/* Expandable square icon buttons in topbar (e.g. 📊 stats, 🗑️ clear records) */
.btn-expandable{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  height:34px;
  width:34px;
  padding:0;
  border-radius:8px;
  overflow:hidden;
  white-space:nowrap;
  position:relative;
  transition:width .28s cubic-bezier(0.4, 0, 0.2, 1), padding .28s cubic-bezier(0.4, 0, 0.2, 1), border-color .15s ease, background-color .15s ease;
}
.btn-expandable .btn-icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:32px;
  height:32px;
  flex:0 0 32px;
  font-size:15px;
  line-height:1;
}
.btn-expandable .btn-expand-text{
  display:inline-block;
  max-width:0;
  opacity:0;
  font-size:13px;
  font-weight:600;
  line-height:1;
  overflow:hidden;
  transition:max-width .28s cubic-bezier(0.4, 0, 0.2, 1), opacity .2s ease, margin .28s cubic-bezier(0.4, 0, 0.2, 1);
  margin-left:0;
  margin-right:0;
}
.btn-expandable:hover,
.btn-expandable:focus-visible{
  width:auto;
  padding-right:12px;
}
.btn-expandable:hover .btn-expand-text,
.btn-expandable:focus-visible .btn-expand-text{
  max-width:100px;
  opacity:1;
  margin-left:2px;
}
.container{max-width:900px;margin:0 auto;padding:28px 18px 48px}
/* Home: full-bleed carousel, practice view keeps the narrow column */
#homeView.container{max-width:none;padding-left:0;padding-right:0}
#homeView .hero,#homeView .footer{max-width:900px;margin-left:auto;margin-right:auto;padding-left:18px;padding-right:18px}
.hero h1{font-size:30px;margin:8px 0 10px}
.hero-sub{font-size:16px;color:var(--muted);margin:0 0 22px}
kbd{
  background:var(--kbd-bg);color:var(--ink);border:1px solid var(--line);border-bottom-width:2px;border-radius:6px;
  padding:1px 6px;font-family:monospace;font-size:13px;
}
/* 3D carousel (coverflow): dynamic 3D projection + scroll snapping + inertia */
.carousel-shell{margin-bottom:4px}
.carousel-viewport{
  position:relative;height:360px;overflow:hidden;
  perspective:1200px;perspective-origin:50% 38%;
  touch-action:pan-y;user-select:none;-webkit-user-select:none;cursor:grab;
}
.carousel-viewport.dragging{cursor:grabbing}
.carousel-light{
  position:absolute;left:50%;top:50%;width:min(520px,90vw);height:280px;
  transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(ellipse at center,rgb(255 255 255 / .55),transparent 70%);
}
[data-theme="dark"] .carousel-light{
  background:radial-gradient(ellipse at center,rgb(148 197 255 / .18),transparent 70%);
}
.mode-carousel{position:absolute;inset:0;transform-style:preserve-3d}
.mode-card{
  --card-accent:#2563eb;--card-soft:rgba(37,99,235,.14);
  position:absolute;left:50%;top:50%;
  width:min(360px,44vw);height:250px;
  padding:22px 18px 18px;margin:0;font:inherit;text-align:left;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  color:var(--ink);cursor:pointer;overflow:hidden;
  transform:translate(-50%,-50%);
  transform-style:preserve-3d;backface-visibility:hidden;
  will-change:transform,opacity;
  display:flex;flex-direction:column;
  transition:border-color .2s ease,box-shadow .2s ease,translate .18s ease;
  translate:0 0;
}
.mode-card-bar{position:absolute;top:0;left:0;right:0;height:5px;background:var(--card-accent)}
.mode-card.is-center{border-color:var(--card-accent);box-shadow:0 10px 28px var(--card-soft)}
.mode-card:hover,.mode-card:focus-visible{border-color:var(--card-accent);box-shadow:0 14px 36px var(--card-soft);translate:0 -4px}
.mode-card:focus-visible{outline:2px solid var(--card-accent);outline-offset:2px}
.carousel-viewport.dragging .mode-card:hover{translate:0 0;box-shadow:0 10px 28px var(--card-soft)}
@media (prefers-reduced-motion: reduce){.mode-card{transition:border-color .2s ease,box-shadow .2s ease}.mode-card:hover,.mode-card:focus-visible{translate:0 0}}
.mode-card h3{margin:6px 0 6px;font-size:20px;color:var(--card-accent)}
.mode-card p{margin:0 0 10px;color:var(--muted);font-size:14px;flex:1}
.mode-meta{display:flex;justify-content:space-between;gap:8px;font-size:13px;color:var(--muted)}
.mode-meta strong{color:var(--ink)}
.mode-card-go{display:inline-block;margin-top:12px;font-size:14px;font-weight:700;color:var(--card-accent)}
.mode-glare{
  position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(115deg,transparent 35%,rgb(255 255 255 / .38) 50%,transparent 65%);
  background-size:250% 100%;background-position:120% 0;
}
.mode-card.just-centered .mode-glare{animation:glare-sweep .8s ease-out}
@keyframes glare-sweep{from{background-position:120% 0}to{background-position:-20% 0}}
.carousel-nav{display:flex;align-items:center;justify-content:center;gap:16px;margin:4px 0 20px}
.carousel-nav .btn.small{width:36px;height:36px;padding:0;font-size:20px;line-height:1}
.carousel-nav .btn:disabled{opacity:.35;cursor:default}
.carousel-dots{display:flex;gap:8px}
.carousel-dot{width:10px;height:10px;border-radius:50%;border:1px solid var(--line);background:var(--panel);padding:0;cursor:pointer}
.carousel-dot.active{background:var(--accent);border-color:var(--accent)}
.mode-card.m-words{--card-accent:#2563eb;--card-soft:rgba(37,99,235,.14)}
.mode-card.m-sentences{--card-accent:#059669;--card-soft:rgba(5,150,105,.14)}
.mode-card.m-articles_punct{--card-accent:#7c3aed;--card-soft:rgba(124,58,237,.14)}
.mode-card.m-long_articles{--card-accent:#d97706;--card-soft:rgba(217,119,6,.14)}
.mode-card.m-mixed_zh_en{--card-accent:#0891b2;--card-soft:rgba(8,145,178,.14)}
.mode-card.m-life_situations{--card-accent:#db2777;--card-soft:rgba(219,39,119,.14)}
.mode-card.m-general_legal_docs{--card-accent:#475569;--card-soft:rgba(71,85,105,.14)}
.mode-card.m-litigation_legal_docs{--card-accent:#c2410c;--card-soft:rgba(194,65,12,.14)}
.mode-card.m-classical_texts{--card-accent:#b91c1c;--card-soft:rgba(185,28,28,.14)}
.mode-card.m-custom_text{--card-accent:#9333ea;--card-soft:rgba(147,51,234,.14)}
html[data-theme="dark"] .mode-card.m-words{--card-accent:#60a5fa;--card-soft:rgba(96,165,250,.20)}
html[data-theme="dark"] .mode-card.m-sentences{--card-accent:#34d399;--card-soft:rgba(52,211,153,.20)}
html[data-theme="dark"] .mode-card.m-articles_punct{--card-accent:#a78bfa;--card-soft:rgba(167,139,250,.20)}
html[data-theme="dark"] .mode-card.m-long_articles{--card-accent:#fbbf24;--card-soft:rgba(251,191,36,.20)}
html[data-theme="dark"] .mode-card.m-mixed_zh_en{--card-accent:#22d3ee;--card-soft:rgba(34,211,238,.20)}
html[data-theme="dark"] .mode-card.m-life_situations{--card-accent:#f472b6;--card-soft:rgba(244,114,182,.20)}
html[data-theme="dark"] .mode-card.m-general_legal_docs{--card-accent:#94a3b8;--card-soft:rgba(148,163,184,.20)}
html[data-theme="dark"] .mode-card.m-litigation_legal_docs{--card-accent:#fb923c;--card-soft:rgba(251,146,60,.20)}
html[data-theme="dark"] .mode-card.m-classical_texts{--card-accent:#f87171;--card-soft:rgba(248,113,113,.20)}
html[data-theme="dark"] .mode-card.m-custom_text{--card-accent:#c084fc;--card-soft:rgba(192,132,252,.20)}
.footer{margin-top:26px;color:var(--muted);font-size:13px;text-align:center}
.footer-github{display:inline-flex;align-items:center;gap:5px;color:var(--accent);text-decoration:none;font-weight:600;transition:opacity .15s ease;text-underline-offset:3px}
.footer-github:hover{text-decoration:underline;opacity:.85}
.footer-github:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.footer-github-icon{flex:none;display:block}
code{background:var(--kbd-bg);color:var(--ink);padding:1px 6px;border-radius:6px;font-size:13px}
.practice-head{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:12px}
.practice-title{font-size:18px;font-weight:700}
.hud{margin-left:auto;display:flex;gap:16px;flex-wrap:wrap;font-size:14px;color:var(--muted)}
.hud-item strong{color:var(--ink);font-variant-numeric:tabular-nums}
.progress-track{height:8px;background:var(--progress-track);border-radius:99px;overflow:hidden;margin-bottom:12px}
.progress-bar{height:100%;width:0%;background:var(--accent);transition:width .15s linear}
/* 拆字提示（右上角）：目標文字右上角，隨目前要打的字即時更新。
   橫向反向環滾輪（三個完整方塊）：倉頡 一：一 m / 嘸蝦米 一：E / 速成 一：一 m。
   與首頁 coverflow 的差異：首頁是平面 translateX + rotateY(-off*42deg)；
   這裡是圓柱 sin/cos 投影 + rotateY(+off*26deg)（角度反向），側卡繞環往後收。
   拖曳、滾輪、點側卡、點左右箭頭皆可切換；組字時凍結不重畫。 */
.cangjie-bar{display:flex;justify-content:flex-end;margin-bottom:6px}
.cangjie-hint{
  display:inline-flex;align-items:center;gap:8px;flex-wrap:nowrap;justify-content:flex-end;
  background:transparent;border:none;border-radius:10px;
  padding:0;font-size:14px;color:var(--muted);max-width:100%;
}
.cangjie-hint strong{color:var(--ink);font-size:17px}
.cangjie-hint .cj-radicals{color:var(--accent);font-weight:700;font-size:15px;letter-spacing:.08em}
.cangjie-hint .cj-letters{color:var(--accent);font-weight:700;font-family:monospace;font-size:16px;letter-spacing:.18em}
.cangjie-hint .cj-code{font-family:monospace;font-size:13px;color:var(--muted)}
.cangjie-hint.is-done{color:var(--green);font-weight:700}
.decomp-wheel{
  position:relative;flex:0 0 auto;width:268px;height:46px;overflow:hidden;
  perspective:500px;perspective-origin:50% 50%;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  cursor:grab;touch-action:pan-y;user-select:none;-webkit-user-select:none;
}
.decomp-wheel.dragging{cursor:grabbing}
.decomp-wheel-track{position:absolute;inset:0;pointer-events:none}
.decomp-wheel-card{
  position:absolute;left:50%;top:50%;width:246px;height:36px;margin:0;
  padding:2px 10px;background:var(--panel);border:1px solid var(--line);border-radius:8px;
  color:var(--muted);font-size:13.5px;line-height:1.35;white-space:nowrap;text-align:center;overflow:hidden;
  transform:translate(-50%,-50%);backface-visibility:hidden;
  will-change:transform,opacity;
  display:flex;align-items:center;justify-content:center;gap:4px;
  cursor:pointer;pointer-events:auto;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.decomp-wheel-card .decomp-name{color:var(--muted);font-size:13.5px}
.decomp-wheel-card strong{color:var(--ink);font-size:16px;font-weight:700;margin:0 2px}
.decomp-wheel-card .cj-radicals{color:var(--accent);font-weight:700;font-size:15px;letter-spacing:.06em}
.decomp-wheel-card .cj-letters{color:var(--accent);font-weight:700;font-family:monospace;font-size:15px;letter-spacing:.12em}
.decomp-wheel-card .cj-code{font-family:monospace;font-size:13px;color:var(--muted);margin-left:2px}
.decomp-wheel-card.is-center{
  border-color:var(--accent);
  box-shadow:0 2px 10px rgb(37 99 235 / .18);
}
[data-theme="dark"] .decomp-wheel-card.is-center{
  box-shadow:0 2px 10px rgb(96 165 250 / .22);
}
.decomp-wheel-nav{display:flex;flex-direction:column;gap:2px;flex:0 0 auto}
.decomp-wheel-nav button{
  width:24px;height:21px;padding:0;border:1px solid var(--line);border-radius:6px;
  background:var(--panel);color:var(--ink);cursor:pointer;font-size:14px;line-height:1;
  display:flex;align-items:center;justify-content:center;transition:border-color .15s ease, background .15s ease;
}
.decomp-wheel-nav button:hover{border-color:var(--accent);background:var(--active-line-bg)}
.decomp-body{display:none}

/* Custom Text Modal & Elements */
.modal.custom-modal{
  max-width:600px;width:92%;display:flex;flex-direction:column;
}
.custom-modal-sub{
  font-size:14px;color:var(--muted);margin:0 0 10px;
}
.custom-textarea{
  width:100%;box-sizing:border-box;padding:12px;border:1px solid var(--line);
  border-radius:10px;background:var(--bg);color:var(--ink);font-family:inherit;
  font-size:15px;line-height:1.6;resize:vertical;min-height:160px;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.custom-textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-glare);
}
.custom-textarea.is-invalid{
  border-color:var(--red);box-shadow:0 0 0 2px rgba(239, 68, 68, 0.2);
}
.custom-meta-row{
  display:flex;justify-content:space-between;align-items:center;margin-top:6px;
  font-size:13px;color:var(--muted);
}
.btn-link{
  background:none;border:none;padding:0;color:var(--muted);font-size:12px;
  cursor:pointer;text-decoration:underline;
}
.btn-link:hover{color:var(--accent)}
.custom-error{
  color:var(--red);font-size:13px;margin-top:8px;padding:6px 10px;
  background:rgba(239, 68, 68, 0.08);border-radius:6px;
}

/* Boshiamy Dropzone & Modal Elements */
.boshiamy-dropzone{
  border:2px dashed var(--line);border-radius:12px;padding:28px 16px;text-align:center;
  background:var(--bg);cursor:pointer;transition:border-color .15s ease, background-color .15s ease;
  display:flex;flex-direction:column;align-items:center;gap:8px;
}
.boshiamy-dropzone:hover, .boshiamy-dropzone:focus-visible{
  border-color:var(--accent);outline:none;
}
.boshiamy-dropzone.dragover{
  border-color:var(--accent);background:var(--active-line-bg);
}
.dropzone-icon{font-size:32px;line-height:1}
.dropzone-text{font-size:15px;font-weight:600;color:var(--ink)}
.dropzone-sub{font-size:12px;color:var(--muted);max-width:340px}
.hidden-file-input{display:none}
.boshiamy-status{
  font-size:13px;margin-top:10px;padding:8px 12px;border-radius:6px;
}
.boshiamy-status.error{
  color:var(--red);background:rgba(239, 68, 68, 0.08);
}
.boshiamy-status.success{
  color:var(--green);background:rgba(16, 185, 129, 0.08);
}

/* In-place Call-to-Action for Boshiamy */
.decomp-import-btn{
  border-bottom:1px dashed var(--accent);
  padding:2px 4px;
  cursor:pointer;
  transition:background-color .15s ease, color .15s ease;
  border-radius:4px;
}
.decomp-import-btn:hover{
  background-color:var(--active-line-bg);
  color:var(--accent);
}
.decomp-reload-btn{
  background:none;
  border:none;
  cursor:pointer;
  font-size:12px;
  padding:0 2px;
  opacity:0.4;
  transition:opacity .15s ease;
}
.decomp-reload-btn:hover{
  opacity:1;
}

/* Keyboard uninitialized disabled / overlay state */
.on-kb-wrap{
  position:relative;
}
.on-kb-wrap.is-uninitialized .on-kb{
  opacity:0.4;
  filter:grayscale(1);
  transition:opacity .25s ease, filter .25s ease;
}
.on-kb-wrap.is-uninitialized .on-kb .on-kb-key{
  pointer-events:none;
}
.on-kb-overlay{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  display:flex;
  align-items:center;
  justify-content:center;
  background:rgba(0, 0, 0, 0.08);
  border-radius:10px;
  pointer-events:auto;
  z-index:5;
  cursor:pointer;
}
html[data-theme="dark"] .on-kb-overlay{
  background:rgba(0, 0, 0, 0.25);
}
.on-kb-overlay-btn{
  background:var(--panel);
  border:2px dashed var(--accent);
  color:var(--accent);
  font-weight:700;
  font-size:15px;
  padding:12px 24px;
  border-radius:10px;
  box-shadow:0 6px 18px rgba(0, 0, 0, 0.12);
  cursor:pointer;
  transition:transform .15s ease, background-color .15s ease;
}
.on-kb-overlay-btn:hover{
  transform:scale(1.03);
  background-color:var(--active-line-bg);
}
.mode-card-edit{
  position:absolute;top:10px;right:10px;width:28px;height:28px;border-radius:6px;
  border:1px solid var(--line);background:var(--panel);color:var(--muted);
  display:flex;align-items:center;justify-content:center;font-size:14px;
  cursor:pointer;z-index:10;transition:all .15s ease;
}
.mode-card-edit:hover{
  color:var(--accent);border-color:var(--accent);
}

@media (max-width:680px){
  .decomp-wheel{width:220px;height:44px}
  .decomp-wheel-card{width:200px;height:34px;font-size:12px}
}
.target-box{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px;font-size:var(--font-size);line-height:2;min-height:120px;cursor:text;
  font-family:"Noto Sans TC","PingFang TC","Microsoft JhengHei",monospace;
  letter-spacing:.04em;white-space:pre-wrap;word-break:break-word;
}
.target-line{
  padding:2px 8px;border-radius:8px;margin:2px 0;transition:background-color .15s ease;
}
.target-line.current-line{
  background:var(--active-line-bg);
}
.char{border-radius:6px;padding:0 1px}
.char.pending{color:var(--pending-char)}
.char.current{background:var(--current-bg);box-shadow:0 0 0 1px var(--current-border)}
.char.correct{color:var(--green)}
.char.error{color:var(--red);background:rgb(214 69 69 / .15)}

/* ===== 生活情境題：LINE 回合聊天（只做 LINE） ===== */
/* 官方配色：LINE Green #06C755、聊窗預設藍色牆紙、對手白泡、自己淺綠泡。 */
.chat-target{padding:0;overflow:hidden;min-height:0;display:flex;flex-direction:column;flex:none;width:100%;max-width:680px;margin:0 auto}
#practiceView .chat-target{height:auto;max-height:calc(2 * calc(var(--font-size) * 1.7 + 18px) + 62px + 32px + 54px)}
.chat-body{scrollbar-width:thin}
.chat-header{
  display:flex;align-items:center;gap:10px;padding:10px 14px;
  font-size:15px;font-weight:700;background:#fff;color:#1f1f1f;
  border-bottom:1px solid #e8e8e8;
}
.chat-back{font-size:26px;line-height:1;color:#1f1f1f;font-weight:400}
.chat-avatar{
  width:34px;height:34px;border-radius:50%;background:#06c755;color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:700;flex:none;
}
.chat-name{flex:1}
.chat-icons{color:#3f3f3f;font-size:15px;letter-spacing:2px}
.chat-body{display:flex;flex-direction:column;gap:10px;padding:14px 16px 18px;overflow-y:auto;background:#8ea9db}
.chat-msg{display:flex;flex-direction:column;max-width:82%}
.chat-msg.chat-left{align-self:flex-start;align-items:flex-start}
.chat-msg.chat-right{align-self:flex-end;align-items:flex-end}
.chat-speaker{font-size:12px;font-weight:700;margin:0 4px 3px;line-height:1.4;color:#3f3f3f}
.chat-bubble{
  padding:9px 13px;border-radius:16px;font-size:var(--font-size);line-height:1.7;
  white-space:pre-wrap;word-break:break-word;box-shadow:0 1px 2px rgb(0 0 0 / .12);
}
.chat-msg.chat-left .chat-bubble{background:#fff;color:#1f1f1f;border-radius:4px 16px 16px 16px}
.chat-msg.chat-right .chat-bubble{background:#a5d6a7;color:#10231a;border-radius:16px 4px 16px 16px}
.chat-msg.chat-right .chat-bubble .char.pending{color:#35584a}
.chat-msg.chat-right .chat-bubble .char.current{background:#fff;border-radius:4px}
.chat-msg.chat-right .chat-bubble .char.correct{color:#065f46}
.chat-msg.chat-right .chat-bubble .char.error{color:#b91c1c;background:rgb(0 0 0 / .08)}
.chat-meta{font-size:11px;color:#2f3f5f;margin-top:3px}
.chat-msg.chat-left .chat-meta{align-self:flex-start}
.chat-msg.chat-right .chat-meta{align-self:flex-end}
.chat-draft .chat-bubble{border:2px dashed #06c755;opacity:.92}
/* 入場：氣泡浮現 */
@keyframes chatBubbleIn{
  from{opacity:0;transform:translateY(10px) scale(.94)}
  to{opacity:1;transform:translateY(0) scale(1)}
}
.chat-msg.msg-enter{animation:chatBubbleIn .45s cubic-bezier(.22,1,.36,1)}
.chat-msg.chat-right.msg-enter{transform-origin:bottom right}
.chat-msg.chat-left.msg-enter{transform-origin:bottom left}
/* 對手輸入中：三個跳動點 */
.chat-typing{display:inline-flex;gap:5px;align-items:center;padding:12px 16px}
.chat-typing span{width:8px;height:8px;border-radius:50%;background:#8a8a8a;animation:chatDot 1.1s infinite}
.chat-typing span:nth-child(2){animation-delay:.18s}
.chat-typing span:nth-child(3){animation-delay:.36s}
@keyframes chatDot{0%,60%,100%{transform:translateY(0);opacity:.5}30%{transform:translateY(-5px);opacity:1}}
/* 生活情境題的輸入框長得很像 LINE 的圓角列 */
body[data-mode="life_situations"] .input-box input{border-radius:999px}
body[data-mode="life_situations"] .hint-line{color:#4b5563}
.input-box{margin-top:14px;display:flex;flex-direction:column;gap:10px}
.input-box input{
  width:100%;padding:12px 14px;font-size:var(--font-size);border-radius:10px;border:2px solid var(--line);
  background:var(--input-bg);color:var(--ink);font-family:inherit;
}
.input-box input:focus{outline:none;border-color:var(--accent)}
.input-box input:disabled{background:var(--input-disabled);color:var(--muted)}
.input-box input.done{border-color:var(--green)}
@keyframes inputShake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-5px); }
  40%, 80% { transform: translateX(5px); }
}
.input-box input.input-shake {
  animation: inputShake 0.4s ease-in-out;
  border-color: #ef4444 !important;
  box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.25);
}
.hint-line{min-height:1.5em;color:var(--muted);font-size:14px;margin:10px 2px}
.practice-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.auto-advance-label{
  display:inline-flex;align-items:center;gap:6px;font-size:14px;color:var(--muted);cursor:pointer;user-select:none;
}
.auto-advance-label input[type="checkbox"]{
  cursor:pointer;width:16px;height:16px;accent-color:var(--accent);
}

.endless-group {
  gap: 6px;
}
.settle-count-input {
  width: 52px;
  padding: 2px 6px;
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--input-bg);
  color: var(--ink);
  transition: all 0.2s ease;
}
.settle-count-input:focus {
  outline: none;
  border-color: var(--accent);
}
.settle-count-input:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  border-color: transparent;
  background: rgba(128, 128, 128, 0.1);
  color: var(--muted);
}
/* 當無盡模式開啟時 (is-endless)："否則在第 [ 輸入框 ] 結算" 暗掉灰掉 */
.endless-group.is-endless .endless-text {
  opacity: 1;
  color: var(--ink);
  font-weight: 600;
}
.endless-group.is-endless .endless-settle-sep,
.endless-group.is-endless .endless-settle-suffix {
  opacity: 0.4;
  color: var(--muted);
}

/* 當無盡模式關閉時 (is-finite)："無盡模式" 四個字暗掉，其餘亮起來 */
.endless-group.is-finite .endless-text {
  opacity: 0.45;
  color: var(--muted);
  font-weight: normal;
}
.endless-group.is-finite .endless-settle-sep,
.endless-group.is-finite .endless-settle-suffix {
  opacity: 1;
  color: var(--ink);
  font-weight: 500;
}
/* Practice view fills the viewport height so the target text and the
   on-screen keyboard never push each other off screen. The target box
   takes the remaining space and scrolls internally when needed; the
   topbar is 61px tall (40px brand + 20px padding + 1px border). */
/* 鍵位提示開啟時（#practiceView.onkb-on）：鍵盤 position:fixed 固定喺視窗底部、
   往上約一行（底邊離視窗底約一行鍵高），位置唔跟題目走。
   題目唔因開鍵盤而變長／變短：短題同平時一樣高（min-height 120px，只跟內容
   長度變）；文章太長時題目收起嚟，只佔「鍵盤上方剩返嘅空間」，多出嚟嘅
   內容喺題目框入面捲動（唔會頂到鍵盤）。練習視窗底部留出「鍵盤高 +
   上移一行 + 間距」嘅空間，輸入框／選項固定貼喺鍵盤上方，唔會被題目
   推出去或蓋住鍵盤。
   鍵位提示關閉時（無 .onkb-on），題目維持原本上下厚度，唔撐滿整屏。 */
#practiceView{display:flex;flex-direction:column;height:auto;min-height:0}
#practiceView:not(.onkb-on) .target-box:not(.chat-target){flex:none}
#practiceView.onkb-on{display:flex;flex-direction:column;height:calc(100vh - 61px);height:calc(100dvh - 61px);padding-bottom:calc(48px * 6 + 5px * 5 + 18px);overflow:hidden}
#practiceView.onkb-on>*{flex-shrink:0}
#practiceView.onkb-on #onKeyboardWrap{position:fixed;left:0;right:0;bottom:calc(48px + 5px);margin-top:0;z-index:20}
/* 文章太長時收起題目：題目框 flex:1 收縮、內部捲動，只佔鍵盤上方
   剩返嘅空間；固定嘅其餘項目（標題／進度／拆字／輸入框／提示／選項）
   以 flex-basis:auto 唔縮，題目先收，選項唔會被推出去。
   短題未用到上限時自然高度（同關鍵盤時一樣），唔會被扯長。
   內容大於可用空間時固定項目會齊齊響應式縮小（`min-height:0` 允許
   題目框跌到 0 以下捲動），確保選項一律喺鍵盤上方，唔會溢出。 */
#practiceView .target-box:not(.chat-target){flex:none}
#practiceView.onkb-on .target-box:not(.chat-target){flex:1 1 0;min-height:0;overflow-y:auto;scrollbar-width:thin}
/* 矮視窗固定項目縮小一階，留返足夠位畀題目框，免溢出。 */
@media (max-height:700px){
  #practiceView.onkb-on .practice-head{margin-bottom:6px}
  #practiceView.onkb-on .practice-head .btn{padding:4px 10px}
  #practiceView.onkb-on .progress-track{margin-bottom:6px}
  #practiceView.onkb-on .cangjie-bar{margin-bottom:0}
  #practiceView.onkb-on .decomp-wheel{height:30px}
  #practiceView.onkb-on .decomp-wheel-card{height:24px}
  #practiceView.onkb-on .input-box{margin-top:8px;gap:6px}
  #practiceView.onkb-on .input-box input{padding:8px 12px}
  #practiceView.onkb-on .hint-line{margin:4px 2px;min-height:1.2em}
}
@media (max-height:900px){
  #practiceView.onkb-on{padding-bottom:calc(42px * 6 + 3px * 5 + 18px)}
  #practiceView.onkb-on #onKeyboardWrap{bottom:calc(42px + 3px)}
}
/* 矮視窗（≤700px）：只縮鍵盤，練習版面（題目厚度、按鈕、輸入框）維持原狀，
   題目高度唔因開鍵盤而變；內容唔夠位時練習視窗可捲動，選項喺鍵盤上方。 */
@media (max-height:700px){
  #practiceView.onkb-on{padding-bottom:calc(34px * 6 + 2px * 5 + 10px)}
  #practiceView.onkb-on #onKeyboardWrap{bottom:calc(34px + 2px)}
  #practiceView.onkb-on .on-kb{gap:2px}
  #practiceView.onkb-on .on-kb-row{gap:2px}
  #practiceView.onkb-on #onKeyboardWrap .on-kb-key{height:34px}
}
body[data-mode="life_situations"] .input-box{margin-top:8px}
body[data-mode="life_situations"] .on-kb-wrap{margin-top:10px}
@media (max-height:900px){
  .container{padding-top:12px}
  .on-kb{gap:3px}
  .on-kb-row{gap:3px}
  #onKeyboardWrap .on-kb-key{height:42px}
  .cangjie-bar{margin-bottom:2px}
  .decomp-wheel{height:38px}
  .decomp-wheel-card{height:30px}
}
/* On-screen key hint keyboard (under the input, opt-in via checkbox) */
.on-kb-wrap{margin-top:18px}
.on-kb{position:relative;display:flex;flex-direction:column;gap:5px;user-select:none;-webkit-user-select:none;max-width:960px;margin:0 auto}
.on-kb-row{display:flex;gap:5px;width:100%}
.on-kb-key{
  flex: calc(var(--u, 1) * 10) 1 0px;
  min-width: 0;
  height: 48px;
  padding: 2px 3px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.15;
  position: relative;
  transition: background-color .1s ease, border-color .1s ease, box-shadow .1s ease;
  overflow: hidden;
}
.on-kb-key:hover{border-color:var(--accent);background:var(--active-line-bg)}
.on-kb-key:active{transform:translateY(1px)}
.on-kb-key .k-main{font-size:15px;font-weight:600;white-space:nowrap}
.on-kb-key .k-sub{font-size:10px;color:var(--muted);white-space:nowrap}
.on-kb-key.is-fn{font-size:12px;font-weight:600;color:var(--muted)}
.on-kb-key.is-fn .k-main{font-size:12px}
.on-kb-key.is-space{font-size:13px}
.on-kb-key.is-next{
  border-color:var(--accent);background:var(--active-line-bg);
  box-shadow:0 0 0 1px var(--accent) inset;
}
.on-kb-key.is-next .k-main{color:var(--accent)}
.on-kb-key.flash-white{animation:keyFlashWhite .35s ease-out}
.on-kb-key.flash-red{animation:keyFlashRed .35s ease-out}
[data-theme="dark"] .on-kb-key.flash-white{animation:keyFlashWhiteDark .28s ease-out}
[data-theme="dark"] .on-kb-key.flash-red{animation:keyFlashRedDark .35s ease-out}

.on-kb-key.is-error{
  border-color:#ef4444!important;
  box-shadow:0 0 0 2px #ef4444 inset,0 0 12px 2px rgba(239,68,68,.5)!important;
  background-color:rgba(239,68,68,.18)!important;
}
.on-kb-key.is-error .k-main{color:#ef4444!important}
.on-kb-key.is-error .k-sub{color:#dc2626!important}
[data-theme="dark"] .on-kb-key.is-error{
  border-color:#f87171!important;
  box-shadow:0 0 0 2px #f87171 inset,0 0 14px 3px rgba(248,113,113,.5)!important;
  background-color:rgba(239,68,68,.25)!important;
}
[data-theme="dark"] .on-kb-key.is-error .k-main{color:#fca5a5!important}
[data-theme="dark"] .on-kb-key.is-error .k-sub{color:#f87171!important}

/* Light mode white flash: soft glowing white */
@keyframes keyFlashWhite{
  0%{
    background-color:#ffffff;
    border-color:#94a3b8;
    box-shadow:0 0 0 2px #ffffff inset, 0 0 14px 4px rgba(255,255,255,.9), 0 0 6px 1px rgba(100,116,139,.35);
  }
  100%{
    box-shadow:none;
  }
}

/* Dark mode white flash: clean internal white highlight / invert (反白), no outer glow */
@keyframes keyFlashWhiteDark{
  0%{
    background-color:rgba(255,255,255,.24);
    border-color:rgba(255,255,255,.5);
    box-shadow:none;
  }
  100%{
    box-shadow:none;
  }
}

/* Light mode red flash */
@keyframes keyFlashRed{
  0%{
    background-color:#fee2e2;
    border-color:#ef4444;
    box-shadow:0 0 0 2px #ef4444 inset, 0 0 14px 4px rgba(239,68,68,.6);
  }
  100%{
    box-shadow:none;
  }
}

/* Dark mode red flash */
@keyframes keyFlashRedDark{
  0%{
    background-color:rgba(239,68,68,.36);
    border-color:#f87171;
    box-shadow:0 0 0 2px #f87171 inset, 0 0 16px 5px rgba(248,113,113,.65);
  }
  100%{
    box-shadow:none;
  }
}
@media (max-width:680px){
  .on-kb{gap:3px}
  .on-kb-row{gap:3px}
  .on-kb-key{height:38px;padding:1px;border-radius:5px}
  .on-kb-key .k-main{font-size:12px}
  .on-kb-key .k-sub{font-size:8px}
  .on-kb-key.is-fn{font-size:10px}
  .on-kb-key.is-fn .k-main{font-size:10px}
}

.overlay{
  position:fixed;inset:0;background:var(--overlay-bg);display:flex;align-items:center;justify-content:center;padding:20px;z-index:20;
}
.modal{
  background:var(--modal-bg);color:var(--ink);border:1px solid var(--line);border-radius:18px;
  max-width:460px;width:100%;padding:24px;
}
.modal h2{margin:0 0 14px}
.result-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px}
.result-grid .cell{border:1px solid var(--line);border-radius:12px;padding:12px;background:var(--panel)}
.result-grid .cell .k{font-size:13px;color:var(--muted)}
.result-grid .cell .v{font-size:24px;font-weight:700;color:var(--ink)}
.new-record{color:#f59e0b;font-weight:700}
.anomaly-line{color:#b45309;font-size:13px;margin:0 0 6px}
.anomaly-line.hidden{display:none !important;margin:0 !important}
html[data-theme="dark"] .anomaly-line{color:#fbbf24}
.modal-actions{display:flex;gap:10px;margin-top:16px}

/* Stats Modal */
.modal.stats-modal{
  max-width:620px;max-height:90vh;display:flex;flex-direction:column;overflow-y:auto;padding-bottom:20px;
}
.stats-modal-head{
  display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;
}
.stats-modal-head h2{margin:0;font-size:20px}
.stats-overview{
  display:grid;grid-template-columns:repeat(3, 1fr);gap:10px;margin-bottom:14px;
}
.stats-overview .cell{
  border:1px solid var(--line);border-radius:10px;padding:10px;background:var(--panel);text-align:center;
}
.stats-overview .cell .k{font-size:12px;color:var(--muted);margin-bottom:2px}
.stats-overview .cell .v{font-size:20px;font-weight:700;color:var(--accent)}
.stats-section-title{
  font-size:14px;font-weight:700;color:var(--muted);margin:10px 0 6px;display:flex;align-items:center;gap:6px;
}
.stats-best-grid{
  display:grid;grid-template-columns:repeat(3, 1fr);gap:10px;margin-bottom:14px;
}
.stats-best-card{
  border:1px solid var(--line);border-radius:10px;padding:10px;background:var(--panel);
  display:flex;flex-direction:column;gap:4px;
}
.stats-best-card .mode-name{font-size:13px;font-weight:700;color:var(--ink)}
.stats-best-card .best-wpm{font-size:16px;font-weight:700;color:var(--accent)}
.stats-best-card .best-sub{font-size:12px;color:var(--muted)}
.stats-hist-wrap{
  flex:1;min-height:140px;max-height:220px;overflow-y:auto;border:1px solid var(--line);
  border-radius:10px;background:var(--panel);padding:6px;
}
.stats-hist-list{display:flex;flex-direction:column;gap:6px}
.stats-hist-item{
  display:flex;align-items:center;justify-content:space-between;padding:8px 12px;
  background:var(--bg);border-radius:8px;font-size:13px;gap:8px;
}
.stats-hist-item .hist-mode{font-weight:600;min-width:55px}
.stats-hist-item .hist-wpm{font-weight:700;color:var(--ink)}
.stats-hist-item .hist-meta{color:var(--muted);font-size:12px}
.stats-empty{padding:24px;text-align:center;color:var(--muted);font-size:14px}
.stats-msg{
  margin-top:10px;padding:8px 12px;border-radius:8px;font-size:13px;line-height:1.4;
  border:1px solid transparent;transition:all .2s ease;
}
.stats-msg.is-success{
  background:rgba(16, 185, 129, 0.12);color:#059669;border-color:rgba(16, 185, 129, 0.3);
}
html[data-theme="dark"] .stats-msg.is-success{
  background:rgba(16, 185, 129, 0.18);color:#34d399;border-color:rgba(16, 185, 129, 0.4);
}
.stats-msg.is-error{
  background:rgba(239, 68, 68, 0.12);color:#dc2626;border-color:rgba(239, 68, 68, 0.3);
}
html[data-theme="dark"] .stats-msg.is-error{
  background:rgba(239, 68, 68, 0.18);color:#f87171;border-color:rgba(239, 68, 68, 0.4);
}
.stats-modal-foot{justify-content:space-between;align-items:center;margin-top:14px;padding-top:4px;flex-wrap:wrap;gap:8px}
.stats-transfer-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ==========================================================================
   Profiler Dashboard & Telemetry Visualizer (三段式工業風 Telemetry Layout)
   ========================================================================== */
.modal.result-profiler-modal {
  max-width: 820px;
  width: 95vw;
  padding: 16px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.profiler-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 12px;
}

.profiler-title-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
}

.profiler-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
}

.profiler-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.3);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  letter-spacing: 0.05em;
}

.profiler-meta {
  display: flex;
  gap: 14px;
  font-size: 13px;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

/* 1. 頂部 KPI Grid */
.profiler-kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.kpi-card {
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}

.kpi-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}

.kpi-value {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 26px;
  font-weight: 800;
  line-height: 1.15;
  margin-top: 2px;
}

.kpi-unit {
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
}

.kpi-sub {
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}

.text-amber { color: #f59e0b; }
.text-emerald { color: #10b981; }
.text-sky { color: #38bdf8; }
.text-indigo { color: #818cf8; }

/* 2. 中間核心圖表區 */
.profiler-chart-panel {
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--bg);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.chart-tabs {
  display: inline-flex;
  background: var(--panel);
  padding: 3px;
  border-radius: 8px;
  border: 1px solid var(--line);
}

.chart-tab {
  background: transparent;
  border: none;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s ease;
}

.chart-tab.active {
  background: var(--bg);
  color: var(--ink);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.chart-legend {
  display: flex;
  gap: 14px;
  font-size: 12px;
  color: var(--muted);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}

.legend-dot.bg-amber { background: #f59e0b; }
.legend-dot.bg-sky {
  background: #38bdf8;
}
.legend-dot.bg-zinc {
  background: #71717a;
  border-radius: 2px;
}

.chart-canvas-container {
  position: relative;
  width: 100%;
  height: 190px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

html[data-theme="light"] .chart-canvas-container {
  background: rgba(0, 0, 0, 0.03);
}

#resultChartCanvas {
  width: 100%;
  height: 100%;
  display: block;
}

/* Tooltip */
.chart-tooltip {
  position: absolute;
  pointer-events: none;
  z-index: 50;
  background: rgba(24, 24, 27, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 12px;
  color: #f4f4f5;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(6px);
  min-width: 150px;
  transition: opacity 0.1s ease, transform 0.1s ease;
}

html[data-theme="light"] .chart-tooltip {
  background: rgba(255, 255, 255, 0.96);
  border-color: rgba(0, 0, 0, 0.15);
  color: #18181b;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.15);
}

.tooltip-char-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  padding-bottom: 4px;
  margin-bottom: 4px;
}

html[data-theme="light"] .tooltip-char-line {
  border-bottom-color: rgba(0, 0, 0, 0.08);
}

.tooltip-char {
  font-size: 15px;
  font-weight: 700;
  color: #fbbf24;
}

.tooltip-duration {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-weight: 600;
}

.tooltip-detail-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11px;
  color: #a1a1aa;
}

html[data-theme="light"] .tooltip-detail-grid {
  color: #71717a;
}

.tooltip-detail-grid strong {
  color: #f4f4f5;
}

html[data-theme="light"] .tooltip-detail-grid strong {
  color: #18181b;
}

.tooltip-range-row {
  margin-top: 2px;
  color: #a1a1aa;
}

.tooltip-range-chars {
  color: #f4f4f5;
  font-weight: 500;
}

html[data-theme="light"] .tooltip-range-row {
  color: #000000 !important;
  font-weight: 600;
}

html[data-theme="light"] .tooltip-range-chars {
  color: #000000 !important;
  font-weight: 600;
}

.tooltip-decomp {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px dashed rgba(255, 255, 255, 0.1);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 11px;
  color: #38bdf8;
}

html[data-theme="light"] .tooltip-decomp {
  border-top-color: rgba(0, 0, 0, 0.08);
  color: #0284c7;
}

.tooltip-err {
  margin-top: 2px;
  color: #ef4444;
  font-weight: 600;
  font-size: 11px;
}

/* 3. 底部診斷與重練區 */
.profiler-bottom-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 10px;
}

.profiler-bottlenecks-card {
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--bg);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bottlenecks-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.bottlenecks-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 6px;
}

.pulse-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #ef4444;
  display: inline-block;
  box-shadow: 0 0 8px rgba(239, 68, 68, 0.6);
}

.bottlenecks-subtitle {
  font-size: 11px;
  color: var(--muted);
}

.bottlenecks-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.bottlenecks-empty {
  padding: 12px 0;
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  width: 100%;
}

.bottleneck-card {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 8px;
  background: var(--panel);
  border: 1px solid rgba(239, 68, 68, 0.3);
  position: relative;
}

.bottleneck-rank {
  font-size: 10px;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

.bottleneck-char {
  font-size: 17px;
  font-weight: 800;
  color: #f87171;
}

.bottleneck-info {
  display: flex;
  flex-direction: column;
  font-size: 11px;
}

.bottleneck-duration {
  font-weight: 700;
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

.bottleneck-decomp {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

/* 操作按鈕組 */
.profiler-actions-card {
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--bg);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}

.btn-action-focus {
  background: rgba(245, 158, 11, 0.15) !important;
  color: #f59e0b !important;
  border: 1px solid rgba(245, 158, 11, 0.4) !important;
  font-weight: 700 !important;
}

.btn-action-focus:hover {
  background: rgba(245, 158, 11, 0.25) !important;
}

.btn-action-next {
  background: var(--accent) !important;
  color: #fff !important;
  font-weight: 600 !important;
}

.btn-action-subtle {
  background: transparent !important;
  color: var(--muted) !important;
  border: 1px solid var(--line) !important;
}

.btn-action-subtle:hover {
  background: var(--panel) !important;
  color: var(--ink) !important;
}

.shortcut-badge {
  font-size: 10px;
  opacity: 0.75;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  margin-left: 4px;
}

@media (max-width: 680px) {
  .carousel-viewport { height: 290px; }
  .hero h1 { font-size: 24px; }
  .hud { gap: 10px; }
  .stats-overview { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .stats-best-grid { grid-template-columns: 1fr; gap: 6px; }
  .stats-hist-wrap { max-height: 150px; min-height: 100px; }

  .profiler-kpi-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .profiler-bottom-grid {
    grid-template-columns: 1fr;
  }
}
