/* ============================================================
   exam-frontend 設計系統
   依據:design-system/exam-platform/MASTER.md
        + landing-page-design skill(elayadesign/ai-design-skills)Part B
   規則要點:
   - 字型:Manrope(自架 woff2)+ 系統 CJK;不用 Inter/Roboto/Arial/Helvetica;
     不用斜體(例外:.qstem .math 的數學變數);字重上限 bold(700)
   - 字級:一律落在 Tailwind 型階(12/14/16/18/20/24/30/36/48),不整的往下靠
   - 間距:只許 2/4/8/12/16/24/32/40/48/64/80/96
   - 圓角:只用 Tailwind 值(6/8/12/16/24);巢狀圓角 = 外層圓角 − 間距(>2 才適用)
   - 背景一律平面,不用漸層;邊框整圈或沒有,不做單邊
   - 動效:base curve cubic-bezier(0.22,1,0.36,1);位移/佈局 500ms,
     hover 色彩 300ms;只動 transform/opacity;尊重 prefers-reduced-motion
   token 變更請同步 MASTER.md
   ============================================================ */
@font-face{
  font-family:"Manrope";font-style:normal;font-weight:400;font-display:swap;
  src:url("../fonts/manrope-400.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Manrope";font-style:normal;font-weight:500;font-display:swap;
  src:url("../fonts/manrope-500.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Manrope";font-style:normal;font-weight:600;font-display:swap;
  src:url("../fonts/manrope-600.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Manrope";font-style:normal;font-weight:700;font-display:swap;
  src:url("../fonts/manrope-700.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
:root{
  /* 色彩(Knowledge blue 家族) */
  --bg:#f5f7fb; --surface:#ffffff;
  --ink:#141b2d; --ink2:#4a5468; --ink3:#5b6577;
  --line:#e3e8f0; --line2:#c9d3e0;
  --pri:#1d4ed8; --pri-d:#16379e; --pri-soft:#e8eefd;
  --ok:#177a4c; --ok-soft:#e3f2ea;
  --warn:#b45309; --warn-soft:#fbf0dc; --warn-ink:#92400e;
  --bad:#dc2626; --bad-soft:#fce9e9; --bad-ink:#b91c1c;
  /* 字型:Manrope(latin 自架)+ 系統 CJK fallback */
  --sans:"Manrope",-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang TC","Noto Sans TC","Microsoft JhengHei","Heiti TC",sans-serif;
  --mono:ui-monospace,"SF Mono","Cascadia Mono",Menlo,Consolas,monospace;
  --math:Georgia,"Times New Roman",serif;
  /* 字級(Tailwind 型階,含配對行高) */
  --fs-xs:12px;  --lh-xs:16px;
  --fs-sm:14px;  --lh-sm:20px;
  --fs-base:16px; --lh-base:24px;
  --fs-lg:18px;  --lh-lg:28px;
  --fs-xl:20px;  --lh-xl:28px;
  --fs-2xl:24px; --lh-2xl:32px;
  --fs-4xl:36px; --lh-4xl:40px;
  /* 圓角(Tailwind 值:md 6 / lg 8 / xl 12 / 2xl 16 / 3xl 24) */
  --r:16px; --r-s:12px; --r-xs:8px; --r-xxs:6px;
  /* 間距(只許這些值) */
  --sp-2:2px; --sp-4:4px; --sp-8:8px; --sp-12:12px; --sp-16:16px;
  --sp-24:24px; --sp-32:32px; --sp-40:40px; --sp-48:48px; --sp-64:64px; --sp-80:80px; --sp-96:96px;
  /* 動效(skill B7:base curve;佈局 500ms,色彩/透明度 300ms) */
  --ease-premium:cubic-bezier(0.22,1,0.36,1);
  --dur-layout:500ms;
  --dur-color:300ms;
  /* 陰影(克製) */
  --sh-sm:0 1px 2px rgba(20,27,45,.04);
  --sh-md:0 1px 3px rgba(20,27,45,.06),0 8px 24px -12px rgba(20,27,45,.12);
  --sh-lg:0 12px 40px -8px rgba(20,27,45,.22);
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html{scroll-behavior:smooth}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font:var(--fs-sm)/var(--lh-sm) var(--sans);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
a{color:var(--pri);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3{margin:0 0 12px;line-height:1.25;font-weight:700}
h1{font-size:var(--fs-2xl);line-height:var(--lh-2xl);letter-spacing:-0.02em;text-wrap:balance}
h2{font-size:var(--fs-xl);line-height:var(--lh-xl);letter-spacing:-0.01em;text-wrap:balance}
h3{font-size:var(--fs-base);line-height:var(--lh-base)}
p{text-wrap:pretty}
code,.mono{font-family:var(--mono);font-size:var(--fs-xs)}
/* 全域 a11y(技能要求:可見 focus) */
:focus-visible{outline:2px solid var(--pri);outline-offset:2px}
input:focus-visible,textarea:focus-visible,select:focus-visible{outline:none}
/* 動效尊重 reduced motion */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none !important;transition:none !important}
}

/* 原型標記 */
.proto{
  background:#141b2d;color:#c4cede;font-size:var(--fs-xs);letter-spacing:.4px;
  padding:4px 16px;text-align:center;
}
.proto b{color:#fff}

/* 頁首 */
.topbar{
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:12px 24px;display:flex;align-items:center;gap:12px;
  position:sticky;top:0;z-index:20;box-shadow:var(--sh-sm);
}
.topbar .brand{font-weight:700;font-size:var(--fs-base);display:flex;align-items:center;gap:8px}
.topbar .brand .logo{
  width:28px;height:28px;border-radius:var(--r-xxs);background:var(--pri);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-sm);font-weight:700;
}
.topbar .spacer{flex:1}
.topbar .user{font-size:var(--fs-xs);color:var(--ink2)}
.topbar .user b{color:var(--ink)}

/* 導覽(admin 獨立頁下劃線式;排除 portal 的 #tabs — 它用 chip 式) */
.tabs:not(#tabs){
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:0 24px;display:flex;gap:2px;overflow-x:auto;position:sticky;top:48px;z-index:19;
}
#tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}
#tabs button{
  border:1px solid var(--line2);background:var(--surface);border-radius:var(--r-xs);padding:12px 16px;min-height:44px;
  font-size:var(--fs-xs);font-weight:600;font-family:inherit;color:var(--ink2);cursor:pointer;
  transition:background var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium);
}
#tabs button:hover{border-color:var(--pri);color:var(--pri)}
#tabs button:active{transform:scale(.98)}
#tabs button.active{background:var(--pri);border-color:var(--pri);color:#fff}
.tabs:not(#tabs) a{
  padding:12px 16px;font-size:var(--fs-sm);min-height:44px;color:var(--ink2);border-bottom:2px solid transparent;
  white-space:nowrap;transition:color var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium);
}
.tabs:not(#tabs) a:hover{text-decoration:none;color:var(--ink)}
.tabs:not(#tabs) a:active{transform:translateY(1px)}
.tabs:not(#tabs) a.on{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}

/* 版面 */
.page{max-width:1120px;margin:0 auto;padding:24px 24px 64px}
.page.narrow{max-width:720px}
.page .crumb{font-size:var(--fs-xs);color:var(--ink3);margin-bottom:12px}
.page .crumb a{color:var(--ink3)}
.page-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:24px}
.page-head h1{font-size:var(--fs-xl);margin:0}
.page-head .sub{color:var(--ink2);font-size:var(--fs-xs)}

/* 卡片(外層 16px;內層元件依「外圓角−間距」) */
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh-md);padding:24px;margin-bottom:16px;
}
.card h3{font-size:var(--fs-sm);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.card .muted{color:var(--ink3);font-size:var(--fs-xs)}

/* 按鈕(主按鈕 padding 8/12;hover 300ms base curve;active 實體回饋) */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;
  border-radius:var(--r-xs);border:1px solid var(--line2);background:var(--surface);color:var(--ink);
  padding:8px 12px;font-size:var(--fs-sm);font-weight:600;font-family:inherit;min-height:44px;
  transition:background var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.btn:hover{border-color:var(--pri);color:var(--pri)}
.btn:active{transform:scale(.98)}
.btn.primary{background:var(--pri);border-color:var(--pri);color:#fff}
.btn.primary:hover{background:var(--pri-d);border-color:var(--pri-d);color:#fff}
.btn.danger{color:var(--bad);border-color:#efc9c9}
.btn.danger:hover{background:var(--bad-soft);border-color:var(--bad);color:var(--bad-ink)}
.btn.ok{background:var(--ok);border-color:var(--ok);color:#fff}
.btn.ok:hover{filter:brightness(.93);color:#fff}
.btn.sm{padding:4px 8px;font-size:var(--fs-xs);min-height:32px;border-radius:var(--r-xxs)}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* 表單(12px 圓角:外層卡片 16 − 間距) */
.field{margin-bottom:16px}
.field label{display:block;font-size:var(--fs-xs);font-weight:600;color:var(--ink2);margin-bottom:8px}
.field .hint{font-size:var(--fs-xs);color:var(--ink3);margin-top:4px}
.field .err{font-size:var(--fs-xs);color:var(--bad);margin-top:4px}
.input,.select,textarea.input{
  width:100%;padding:12px;border:1px solid var(--line2);border-radius:var(--r-xs);
  font-size:var(--fs-sm);font-family:inherit;background:#fff;color:var(--ink);min-height:44px;
  transition:border-color var(--dur-color) var(--ease-premium),box-shadow var(--dur-color) var(--ease-premium);
}
.input:focus,.select:focus,textarea.input:focus{
  outline:none;border-color:var(--pri);box-shadow:0 0 0 3px var(--pri-soft);
}
.input.invalid{border-color:var(--bad)}
.input.invalid:focus{box-shadow:0 0 0 3px var(--bad-soft)}
textarea.input{resize:vertical;min-height:96px}
.input.mono{font-family:var(--mono);font-size:var(--fs-xs)}
.row{display:flex;gap:16px;flex-wrap:wrap}
.row .field{flex:1;min-width:140px}

/* 徽章(狀態必含文字,不 color-only) */
.badge{
  display:inline-flex;align-items:center;gap:4px;padding:4px 12px;border-radius:999px;
  font-size:var(--fs-xs);font-weight:600;background:var(--pri-soft);color:var(--pri-d);white-space:nowrap;
}
.badge.ok{background:var(--ok-soft);color:var(--ok)}
.badge.warn{background:var(--warn-soft);color:var(--warn-ink)}
.badge.bad{background:var(--bad-soft);color:var(--bad-ink)}
.badge.gray{background:#eef1f6;color:var(--ink2)}
.badge.mono{font-family:var(--mono);font-weight:500;letter-spacing:0}

/* 題型色(低飽和,語意固定) */
.t-single_choice,.t-true_false{background:#e8eefd;color:#16379e}
.t-multiple_choice{background:#efeafe;color:#5b21b6}
.t-fill_blank{background:#e0f0ee;color:#0f5f58}
.t-calc{background:#fbf0dc;color:#92400e}
.t-proof{background:#fbe7ec;color:#9f1239}
.d-basic{background:#e3f2ea;color:#177a4c}
.d-advanced{background:#fbf0dc;color:#92400e}
.d-difficult{background:#fce9e9;color:#b91c1c}

/* 表格 */
.tbl-wrap{overflow-x:auto}
.tbl{width:100%;border-collapse:collapse;font-size:var(--fs-xs)}
.tbl th{
  text-align:left;color:var(--ink3);font-weight:600;font-size:var(--fs-xs);letter-spacing:.2px;
  padding:8px 12px;border-bottom:1px solid var(--line2);white-space:nowrap;background:var(--surface);
}
.tbl td{padding:12px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl tbody tr:nth-child(even){background:#fafbfd}
.tbl tbody tr:last-child td{border-bottom:none}
.tbl tr.clickable{cursor:pointer}
.tbl tr.clickable:hover td{background:#f3f6fb}
.tbl .num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--mono)}
.tbl td .sub{display:block;font-size:var(--fs-xs);color:var(--ink3)}

/* KPI */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:16px;margin-bottom:24px}
.kpi{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:16px 24px;box-shadow:var(--sh-md);position:relative;overflow:hidden;
}
.kpi::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;border-radius:0 3px 3px 0;background:var(--pri)}
.kpi.k-ok::before{background:var(--ok)} .kpi.k-warn::before{background:var(--warn)} .kpi.k-bad::before{background:var(--bad)}
.kpi .v{font-size:var(--fs-2xl);font-weight:700;font-variant-numeric:tabular-nums;font-family:var(--mono)}
.kpi .k{font-size:var(--fs-xs);color:var(--ink2);margin-top:4px}
.kpi .d{font-size:var(--fs-xs);color:var(--ink3);margin-top:4px}

/* 分佈條 */
.bar{height:8px;border-radius:999px;background:#edf0f6;overflow:hidden;min-width:70px}
.bar i{display:block;height:100%;border-radius:999px;background:var(--pri);transition:width .3s var(--ease-premium)}
.bar.ok i{background:var(--ok)}
.bar.warn i{background:var(--warn)}
.bar.bad i{background:var(--bad)}
.dist{display:flex;flex-wrap:wrap;gap:8px}
.dist .chip{
  display:inline-flex;align-items:center;gap:4px;padding:4px 12px;border-radius:999px;
  background:#f0f3f9;font-size:var(--fs-xs);font-family:var(--mono);color:var(--ink2);
}
.dist .chip b{font-weight:700;color:var(--ink)}
.dist .chip.miss{background:var(--bad-soft);color:var(--bad-ink)}
.dist .chip.miss b{color:var(--bad-ink)}

/* 一體化題目導覽列(靠近題目,與上一題/下一題整合成一個操作組) */
.qpager{margin-top:16px;border-top:1px solid var(--line);padding-top:12px;display:flex;align-items:center;gap:8px}
.pg-arrow{
  flex:none;min-width:72px;height:44px;border-radius:var(--r-s);border:1.5px solid var(--line2);
  background:#fff;color:var(--ink2);font-size:var(--fs-xs);font-weight:700;font-family:inherit;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  transition:background var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.pg-arrow:hover{border-color:var(--pri);color:var(--pri)}
.pg-arrow:active{transform:scale(.98)}
.pg-arrow:disabled{opacity:.4;cursor:not-allowed}
.qnav{flex:1;display:flex;gap:8px;overflow-x:auto;scrollbar-width:thin;padding:4px 0}
.qnav::-webkit-scrollbar{height:6px}
.qnav::-webkit-scrollbar-thumb{background:var(--line2);border-radius:3px}
.qnav button{
  flex:none;min-width:44px;height:44px;padding:0 8px;border-radius:var(--r-xs);border:1.5px solid var(--line2);
  background:#fff;font-size:var(--fs-xs);font-weight:600;font-family:inherit;color:var(--ink2);cursor:pointer;
  font-variant-numeric:tabular-nums;position:relative;
  transition:border-color var(--dur-color) var(--ease-premium),background var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.qnav button:hover{border-color:var(--pri);color:var(--pri)}
.qnav button:active{transform:scale(.98)}
.qnav button.cur{background:var(--pri);border-color:var(--pri);color:#fff}
.qnav button.done{background:var(--ok-soft);border-color:#b5dcc9;color:var(--ok)}
.qpager-foot{display:flex;align-items:center;gap:16px;margin-top:12px;flex-wrap:wrap}
.qpager-foot .legend{display:flex;gap:16px;flex-wrap:wrap}
.qpager-foot .legend span{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-xs);color:var(--ink3)}
.qpager-foot .legend i{display:inline-block;width:9px;height:9px;border-radius:3px}

/* 答題頁 */
.exam-top{
  position:sticky;top:0;z-index:20;background:var(--surface);border-bottom:1px solid var(--line);
  padding:12px 16px;display:flex;align-items:center;gap:12px;
}
.exam-top .t{font-weight:700;font-size:var(--fs-sm);line-height:var(--lh-sm)}
.exam-top .t small{display:block;font-weight:400;font-size:var(--fs-xs);color:var(--ink3)}
.exam-top .spacer{flex:1}
.timer{
  font-family:var(--mono);font-size:var(--fs-lg);font-weight:700;padding:8px 16px;border-radius:var(--r-s);
  background:#eef1f6;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:.5px;
}
.timer.low{background:var(--bad);color:#fff;animation:pulse 1s ease-in-out infinite}
@keyframes pulse{50%{opacity:.6}}
.qcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-md);padding:24px;margin-bottom:16px}
.qmeta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.qmeta .no{font-weight:700;font-size:var(--fs-sm);color:var(--ink3)}
.qmeta .pts{margin-left:auto;font-size:var(--fs-xs);color:var(--ink2);font-weight:600;font-variant-numeric:tabular-nums}
.qstem{font-size:var(--fs-base);line-height:var(--lh-base);margin-bottom:16px}
.qstem .math{font-style:italic;font-family:var(--math)} /* 例外:數學變數斜體(內容,非 UI 字型) */
/* 選項(整列可點 ≥44px) */
.opts{display:flex;flex-direction:column;gap:8px}
.opt{
  display:flex;align-items:flex-start;gap:8px;border:1.5px solid var(--line2);border-radius:var(--r-s);
  padding:12px 16px;cursor:pointer;font-size:var(--fs-sm);background:#fff;min-height:44px;
  transition:border-color var(--dur-color) var(--ease-premium),background var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.opt:hover{border-color:var(--pri)}
.opt:active{transform:scale(.985)}
.opt .key{
  flex:none;width:24px;height:24px;border-radius:50%;background:#eef1f6;color:var(--ink2);
  display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:700;margin-top:2px;
}
.opt.sel{border-color:var(--pri);background:var(--pri-soft)}
.opt.sel .key{background:var(--pri);color:#fff}
.opt.tf{flex:1;justify-content:center;font-size:var(--fs-sm);font-weight:600}
/* 數值輸入 */
.nval{display:flex;align-items:center;gap:8px}
.nval .input{max-width:220px;font-family:var(--mono);font-size:var(--fs-sm)}
.nval .unit{color:var(--ink3);font-size:var(--fs-xs)}
/* 手寫畫布(一體化:工具列 + 畫布 + 換頁同處一個框,取代鍵盤輸入) */
.hwpad{margin-top:16px;border-top:1px dashed var(--line2);padding-top:12px}
.hwpad .ph{font-size:var(--fs-xs);font-weight:600;color:var(--ink2);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.hw-shell{border:1.5px solid var(--line2);border-radius:var(--r-s);background:#fbfcfe;overflow:hidden}
.hw-toolbar{
  display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  padding:8px 12px;border-bottom:1px solid var(--line);background:#f4f6fa;
}
.tool{
  border:1px solid var(--line2);background:#fff;border-radius:var(--r-xxs);
  padding:8px 12px;font-size:var(--fs-xs);font-weight:600;font-family:inherit;color:var(--ink2);
  cursor:pointer;min-height:32px;transition:background var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.tool:hover{border-color:var(--pri);color:var(--pri)}
.tool:active{transform:scale(.98)}
.tool.on{background:var(--pri);border-color:var(--pri);color:#fff}
.hw-frame{position:relative;background:#fff;height:clamp(300px,52vh,440px);perspective:1200px;overflow:hidden}
.hw-canvas{position:absolute;inset:0;width:100%;height:100%;touch-action:none;cursor:crosshair;display:block;z-index:2}
/* 鐵環筆記本(上裝):一排彈簧式金屬線圈(大圈、大傾角)沿上緣把頁面圈住 */
.hw-rings{position:absolute;top:0;left:0;right:0;height:38px;z-index:6;pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='36' viewBox='0 0 60 36'%3E%3Cdefs%3E%3ClinearGradient id='m' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23f2f6fb'/%3E%3Cstop offset='.3' stop-color='%23c3d0de'/%3E%3Cstop offset='.6' stop-color='%238b9db3'/%3E%3Cstop offset='.82' stop-color='%235f7288'/%3E%3Cstop offset='1' stop-color='%23aebdcd'/%3E%3C/linearGradient%3E%3Cg id='l'%3E%3Cellipse cx='0' cy='27.5' rx='7' ry='1.8' fill='rgba(23,32,55,0.18)'/%3E%3Cellipse cx='0' cy='16' rx='9' ry='13.5' fill='none' stroke='%2364778f' stroke-width='2.4' transform='rotate(18 0 16)'/%3E%3Cpath d='M -9 24 A 9 13.5 0 1 1 9 24' fill='none' stroke='url(%23m)' stroke-width='3' stroke-linecap='round' transform='rotate(15 0 17)'/%3E%3C/g%3E%3C/defs%3E%3Crect x='0' y='25' width='60' height='1.2' fill='rgba(23,32,55,0.12)'/%3E%3Cpath d='M 0 24 L 60 24' stroke='%238b9db3' stroke-width='2.4'/%3E%3Cuse href='%23l' x='-10'/%3E%3Cuse href='%23l' x='10'/%3E%3Cuse href='%23l' x='30'/%3E%3Cuse href='%23l' x='50'/%3E%3Cuse href='%23l' x='70'/%3E%3C/svg%3E") repeat-x 0 2px / 60px 36px;
  box-shadow:inset 0 -4px 8px -5px rgba(23,32,55,.28)}
/* 換頁:下頁=舊頁自上方翻起;上頁=新頁自上方翻下蓋住 */
.hw-flip{position:absolute;inset:0;pointer-events:none;overflow:hidden;
  transform-origin:50% 0;backface-visibility:hidden;will-change:transform;z-index:4;
  animation:hwFlipUp .55s cubic-bezier(.42,.12,.6,1) forwards}
.hw-flip img{position:absolute;inset:0;width:100%;height:100%;display:block}
.hw-flip.rev{z-index:1;animation:none}
.hw-flip.rev::after{animation:none;opacity:0}
.hw-flip::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg, rgba(23,32,55,0) 25%, rgba(23,32,55,.32));opacity:0;
  animation:hwShadeUp .55s cubic-bezier(.42,.12,.6,1) forwards}
@keyframes hwFlipUp{0%{transform:rotateX(0)}78%{opacity:1}100%{transform:rotateX(94deg);opacity:0}}
@keyframes hwShadeUp{0%{opacity:0}60%{opacity:.75}100%{opacity:.15}}
.hw-canvas.hw-new{animation:hwReveal .4s .08s ease-out both}
.hw-canvas.hw-new.rev{transform-origin:50% 0;backface-visibility:hidden;
  animation:hwFlipDown .55s cubic-bezier(.25,.75,.35,1) both}
@keyframes hwReveal{from{opacity:0}to{opacity:1}}
@keyframes hwFlipDown{0%{transform:rotateX(94deg);opacity:0}30%{opacity:1}100%{transform:rotateX(0);opacity:1}}
@media (prefers-reduced-motion: reduce){
  .hw-flip{display:none}
  .hw-canvas.hw-new, .hw-canvas.hw-new.rev{animation:none}
}
/* 手寫換頁:上頁 | 1/6 | 下頁 同一頁尾列(與畫布同框) */
.hw-foot{display:flex;gap:8px;align-items:center;justify-content:center;padding:8px 12px;border-top:1px solid var(--line);background:#f4f6fa}
.hw-foot .pg-arrow{min-width:64px;height:44px}
.hw-pgnum{flex:none;min-width:52px;text-align:center;font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:var(--fs-sm);font-weight:700;color:var(--ink);display:inline-flex;align-items:center;justify-content:center;gap:4px}
.hw-pgnum .dot{width:6px;height:6px;border-radius:50%;background:var(--ok);display:inline-block}
.pg-arrow.hw span{font-weight:700;font-size:var(--fs-sm);line-height:1}
/* viz 3D(由 exam3d 模組依 viz 描述子渲染) */
.viz{
  border:1.5px solid var(--line2);border-radius:var(--r-s);background:#fbfcfe;margin-bottom:16px;
  padding:12px;
}
.viz .frame{border-radius:var(--r-xs);background:#fff;border:1px solid var(--line);display:flex;align-items:center;justify-content:center}
.viz .frame.viz3d{width:100%;height:280px;position:relative;overflow:hidden;background:#f3f6fc} /* 平面背景(禁漸層) */
.viz .frame.viz3d canvas{display:block;width:100%!important;height:100%!important;border-radius:var(--r-xs)}
.viz .frame.viz3d .viz3d-hint{
  position:absolute;right:8px;bottom:8px;font-size:var(--fs-xs);color:var(--ink3);
  background:rgba(255,255,255,.8);padding:4px 12px;border-radius:999px;pointer-events:none;
}
.viz .txt{font-size:var(--fs-xs);color:var(--ink2);line-height:1.5;margin-top:12px}
/* 結果頁 */
.score-hero{display:flex;align-items:center;gap:24px;flex-wrap:wrap}
.score-hero .num{font-size:var(--fs-4xl);font-weight:700;font-variant-numeric:tabular-nums;font-family:var(--mono);line-height:var(--lh-4xl)}
.score-hero .num small{font-size:var(--fs-lg);color:var(--ink3);font-weight:600}
.rq{border:1px solid var(--line);border-radius:var(--r-s);padding:16px;margin-bottom:12px;background:#fff}
.rq .rq-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.rq .stem{font-size:var(--fs-sm);margin-bottom:8px}
.rq .ans{font-size:var(--fs-xs);display:flex;gap:16px;flex-wrap:wrap}
.rq .ans b{font-family:var(--mono)}
.rq .expl{font-size:var(--fs-xs);color:var(--ink2);background:#f8f9fc;border-radius:var(--r-xs);padding:8px 12px;margin-top:8px}
.rq.wrong{border-color:#f0c4c4}
.rq.right{border-color:#b5dcc9}
.rq.blank{border-color:var(--line2)}
/* 對話框(外層 16px) */
.overlay{position:fixed;inset:0;background:rgba(20,27,45,.5);display:flex;align-items:center;justify-content:center;z-index:50;padding:24px}
.dialog{background:#fff;border-radius:var(--r);max-width:440px;width:100%;padding:24px;box-shadow:var(--sh-lg)}
.dialog h3{margin-bottom:12px}
.dialog .acts{display:flex;justify-content:flex-end;gap:8px;margin-top:24px}
.unlist{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.unlist span{width:32px;height:32px;border-radius:var(--r-xxs);background:var(--warn-soft);color:var(--warn);display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:700;font-variant-numeric:tabular-nums}
/* 通知 */
.note{border-radius:var(--r-s);padding:12px 16px;font-size:var(--fs-xs);display:flex;gap:8px;align-items:flex-start;margin-bottom:12px}
.note.info{background:var(--pri-soft);color:#16379e}
.note.warn{background:var(--warn-soft);color:#7c3d06}
.note.ok{background:var(--ok-soft);color:#0d5c38}
.note.bad{background:var(--bad-soft);color:#a02529}
/* 分頁小工具 */
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  border:1px solid var(--line2);background:#fff;border-radius:999px;padding:8px 16px;
  font-size:var(--fs-xs);cursor:pointer;font-family:inherit;color:var(--ink2);
  transition:border-color var(--dur-color) var(--ease-premium),background var(--dur-color) var(--ease-premium),color var(--dur-color) var(--ease-premium),transform 150ms var(--ease-premium);
}
.chip:hover{border-color:var(--pri);color:var(--pri)}
.chip:active{transform:scale(.98)}
.chip.on{background:var(--pri);border-color:var(--pri);color:#fff;font-weight:600}
/* 版本時間軸 */
.versions{display:flex;flex-direction:column;gap:8px}
.ver{display:flex;gap:12px;align-items:center;border:1px solid var(--line);border-radius:var(--r-s);padding:12px 16px;background:#fff;flex-wrap:wrap}
.ver .rid{font-family:var(--mono);font-size:var(--fs-xs);flex:1;min-width:200px}
/* 上傳區 */
.dropzone{
  border:2px dashed var(--line2);border-radius:var(--r-s);padding:32px 24px;text-align:center;
  color:var(--ink2);background:#fbfcfe;
}
.dropzone .big{font-size:var(--fs-sm);font-weight:600;color:var(--ink)}
/* 圖例 */
.legend-row{display:flex;gap:16px;flex-wrap:wrap;font-size:var(--fs-xs);color:var(--ink2)}
.legend-row span{display:inline-flex;align-items:center;gap:4px}
/* 通用 */
.mt0{margin-top:0}.mb0{margin-bottom:0}
.flex{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.spacer{flex:1}
.muted{color:var(--ink3)}
.small{font-size:var(--fs-xs)}
.right{text-align:right}
hr{border:none;border-top:1px solid var(--line);margin:16px 0}

/* 響應式 */
@media (max-width:720px){
  .page{padding:16px 16px 48px}
  .card{padding:16px}
  .btn.sm{min-height:44px}
  .tbl{min-width:640px}
  .exam-top .t small{display:none}
  .timer{font-size:var(--fs-sm);padding:8px 12px}
  .pg-arrow{min-width:60px}
  .qcard{padding:16px}
  /* 手機:手寫上/下頁加大,觸控友善 */
  .hw-foot .pg-arrow{min-width:76px;height:44px;font-size:var(--fs-sm)}
  .hw-pgnum{font-size:var(--fs-sm)}
  .tool{padding:8px 16px;min-height:44px;font-size:var(--fs-xs)}
}

/* ===== API 模式新增 ===== */
/* 切題進場(base curve,只動 transform/opacity) */
.qcard.enter{animation:qenter var(--dur-layout) var(--ease-premium)}
@keyframes qenter{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
/* 載入 spinner */
.spin{width:22px;height:22px;border:2.5px solid var(--line2);border-top-color:var(--pri);border-radius:50%;margin:0 auto 12px;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
/* 3D 場景首次渲染淡入(每題 render 重建,自然重播) */
.viz .frame.viz3d{animation:qenter 300ms var(--ease-premium)}
/* toast */
#toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);background:var(--ink);color:#fff;
  padding:8px 16px;border-radius:var(--r-xs);font-size:var(--fs-xs);max-width:88%;z-index:50;box-shadow:0 6px 20px rgba(15,30,60,.18);
  display:none}
#toast.err{background:var(--bad)}
#toast.warn{background:#b45309}
.toast-dim{opacity:.75}

/* live / demo 徽章 */
.badge.live{background:#ecfdf5;color:#047857;border:1px solid #a7f3d0}
.badge.demo{background:#fffbeb;color:#b45309;border:1px solid #fde68a}
/* 已撤銷 token 列(淡色) */
tr.tok-off td{opacity:.55}

/* 手寫回看(成績頁) */
.hw-rev{margin-top:12px;border:1px solid var(--line);border-radius:var(--r-xs);background:#fff;overflow:hidden}
.hw-rev canvas{display:block;width:100%;height:170px}
.hw-rev .cap{font-size:var(--fs-xs);color:var(--ink2);padding:8px 12px;border-bottom:1px solid var(--line);background:#fbfcfe}
.hw-rev .pno{font-size:var(--fs-xs);color:var(--ink3);padding:4px 12px 8px}

/* 表格 */
.tr-blank td{color:var(--ink3);background:#fafbfe}
.tbl .num b{font-variant-numeric:tabular-nums}

/* 表單行(portal 用) */
.formrow{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
.formrow .field{flex:1;min-width:150px}
.mini{font-size:var(--fs-xs);color:var(--ink2)}
.mono{font-family:var(--mono);font-size:var(--fs-xs)}
.spec-table{width:100%;border-collapse:collapse;margin:8px 0}
.spec-table th,.spec-table td{border:1px solid var(--line);padding:8px;font-size:var(--fs-xs);text-align:left}
.spec-table input,.spec-table select{width:100%;border:1px solid var(--line2);border-radius:var(--r-xxs);padding:8px;font-size:var(--fs-xs)}

/* 完整 token 彈窗(教師端) */
#tkModal{background:rgba(15,30,60,.5)}
.tk-modal{background:#fff;border-radius:var(--r);padding:24px;max-width:560px;width:100%;
  box-shadow:0 16px 48px rgba(15,30,60,.3)}
.tk-modal h3{margin:0 0 12px;font-size:var(--fs-base)}
.tk-full{background:#f4f6fa;border:1px solid var(--line);border-radius:var(--r-xs);padding:12px;
  font-family:var(--mono);font-size:var(--fs-xs);word-break:break-all;max-height:130px;overflow:auto;user-select:all}

/* ---- 題庫管理(bankmgr:瀏覽 / 預覽 / 細節 / 編輯) ---- */
.ovl{position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:60;display:flex;align-items:center;justify-content:center;padding:24px}
.ovl.none{display:none}
.bm-panel{background:#fff;border-radius:var(--r);width:min(1100px,100%);max-height:94vh;display:flex;flex-direction:column;box-shadow:0 24px 64px rgba(15,23,42,.3)}
.bm-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 24px;border-bottom:1px solid var(--line)}
.bm-tabs{display:flex;gap:4px;padding:12px 24px 0;border-bottom:1px solid var(--line)}
.bm-tabs button{border:none;background:transparent;padding:8px 12px;font-size:var(--fs-xs);color:var(--ink2);cursor:pointer;border-bottom:2px solid transparent;font-family:inherit;
  transition:color var(--dur-color) var(--ease-premium),border-color var(--dur-color) var(--ease-premium)}
.bm-tabs button.on{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}
.bm-body{overflow-y:auto;padding:24px;flex:1;min-height:0}
.bm-subpane.none{display:none}
.bm-foot{display:flex;align-items:center;gap:8px;padding:12px 24px;border-top:1px solid var(--line)}
.bm-foot .spacer{flex:1}
.bm-kv{width:100%;border-collapse:collapse;font-size:var(--fs-xs)}
.bm-kv th{text-align:left;color:var(--ink3);font-weight:500;width:170px;padding:8px 12px;border-bottom:1px solid var(--line);vertical-align:top;white-space:nowrap}
.bm-kv td{padding:8px 12px;border-bottom:1px solid var(--line);word-break:break-word;line-height:1.6}
.bm-json{background:#0f172a;color:#d7e2f2;font-family:var(--mono);font-size:var(--fs-xs);border-radius:var(--r-xs);padding:12px;overflow:auto;max-height:300px;white-space:pre;margin:0}
/* 考試預覽框(模擬學生端答題頁) */
.exam-frame{max-width:660px;margin:0 auto;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-md);overflow:hidden}
.ex-top{display:flex;align-items:center;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line);background:#f7f9fc;font-size:var(--fs-xs);color:var(--ink2)}
.ex-nav{display:flex;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line);background:var(--surface);flex-wrap:wrap}
.ex-nav i{width:24px;height:24px;border-radius:var(--r-xxs);background:#eef1f6;display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--ink3);font-style:normal}
.ex-nav i.done{background:var(--ok-soft);color:var(--ok)}
.ex-nav i.cur{background:var(--pri);color:#fff}
.ex-body{padding:16px}
.hwph{border:1.5px dashed var(--line2);border-radius:var(--r-s);padding:12px;font-size:var(--fs-xs);color:var(--ink2);display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
/* 編輯表單 */
.bm-edit{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.bm-edit .full{grid-column:1/-1}
.bm-edit label{display:block;font-size:var(--fs-xs);font-weight:600;color:var(--ink2);margin-bottom:4px}
.bm-edit .input{width:100%}
.bm-edit select.input{width:100%}
.bm-opts{font-size:var(--fs-xs)}
.bm-opts td{padding:4px}
.bm-opts .input{padding:8px}
@media (max-width:760px){.bm-edit{grid-template-columns:1fr}}
/* 工具類放最後:蓋過前面所有 display 規則(含 .btn/.ovl 等) */
.none{display:none !important}
/* S1-19:手機版(≤640px)頁籤改固定底部導覽列
   註:.tabs.stu-nav 需加 :not(#tabs) 鏡照 base rule(其 :not(#tabs) 帶 id 特異度),否則贏不了 */
@media (max-width: 640px){
  .tabs.stu-nav:not(#tabs){position:fixed;left:0;right:0;bottom:0;top:auto;z-index:30;margin:0!important;
    padding:0 0 env(safe-area-inset-bottom,0);display:grid;grid-template-columns:repeat(5,1fr);
    border-top:1px solid var(--line);border-bottom:0;overflow:visible}
  .tabs.stu-nav:not(#tabs) a{padding:8px 2px;font-size:12px;text-align:center;border-bottom:0;border-top:2px solid transparent;min-height:56px;display:flex;align-items:center;justify-content:center}
  .tabs.stu-nav:not(#tabs) a.on{border-top-color:var(--pri)}
  body:has(.stu-nav){padding-bottom:calc(64px + env(safe-area-inset-bottom,0))}
}

/* ADR-0013 課本/章節:題庫管理掛點 chip、組卷章節勾選、批次勾選欄 */
.ch-chip{display:inline-block;font-size:var(--fs-xs);background:var(--pri-soft);color:var(--pri-d);border:1px solid var(--line);border-radius:6px;padding:1px 6px;margin:0 4px 3px 0;white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.ch-links{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px}
.ch-links li{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:var(--fs-sm,14px)}
.ch-pick{max-height:260px;overflow:auto;border:1px solid var(--line);border-radius:8px;padding:8px 10px;display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm,14px)}
.ch-pick label{display:flex;gap:6px;align-items:center;cursor:pointer;font-weight:400}
.bm-ck{width:34px;text-align:center}
/* 年級與科目(admin-portal) */
.of-sub{border:1px solid var(--line);border-radius:10px;margin-bottom:10px;overflow:hidden}
.of-sub-h{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;padding:8px 12px;background:var(--pri-soft)}
.of-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:8px 12px;border-top:1px solid var(--line)}
.of-name{flex:1 1 220px;min-width:0}
.of-act{display:flex;gap:6px}
/* 會員方案(admin-portal) */
.pl-seg{display:flex;gap:4px;flex-wrap:wrap;padding:4px;margin-bottom:16px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-xs)}
.pl-seg button{flex:1 1 auto;border:0;background:transparent;border-radius:calc(var(--r-xs) - 2px);padding:9px 12px;min-height:40px;
  font:600 var(--fs-xs)/1.2 inherit;font-family:inherit;color:var(--ink2);cursor:pointer;white-space:nowrap}
.pl-seg button:hover{color:var(--pri);background:var(--pri-soft)}
.pl-seg button.active{background:var(--pri-soft);color:var(--pri-d)}
.pl-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;align-items:start}
.pl-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px 14px}
.pl-form label{display:block;font-size:var(--fs-xs);color:var(--ink2);margin-bottom:4px}
.pl-list .of-row:first-child{border-top:0}
.pl-h{font-size:var(--fs-sm,14px);margin:18px 0 8px;padding-top:12px;border-top:1px solid var(--line)}
.pl-bar{display:grid;grid-template-columns:64px 1fr auto;gap:10px;align-items:center;padding:4px 0}
.pl-bar-track{height:10px;border-radius:5px;background:var(--line);overflow:hidden}
.pl-bar-track>span{display:block;height:100%;background:var(--ok);border-radius:5px}
