/* AI Tutor — สไตล์ชีตเดียวของแอป
   รวมเมื่อ 2026-09-28 จากสี่ที่ที่เคยเขียนทับกันไปมา: dashboard.css · <style> ใน index.html · refresh.css · reader.css
   ลำดับเดิมคงไว้ทุกบรรทัด (ลำดับคือส่วนหนึ่งของผลลัพธ์ใน CSS) — ตัวเลือกที่เคยประกาศหลายที่ถูกรวมเป็นกฎเดียว
   เฉพาะเมื่อย้ายแล้วไม่มีกฎอื่นที่แรงเท่ากันแทรกอยู่ระหว่างทาง และตรวจแล้วด้วย tools/css_equiv.mjs ว่าทุกหน้า
   ทุกธีม ทุกขนาดจอ ค่าที่เบราว์เซอร์คำนวณได้ตรงกับก่อนรวมทุกค่า
   กฎ: ตัวเลือกเดียวกันในบริบทเดียวกัน (@media เดียวกัน) มีได้กฎเดียว — ด่าน tools/test_css_layers.py */


/* ═══ พื้นที่ผู้สอน (เดิม dashboard.css) ═══════════════════════════════════════ */
/* Shared review design, using the existing light/dark theme tokens. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
[hidden]{display:none!important}
:focus-visible{outline:2px solid var(--brand-ink);outline-offset:2px}
.teacher-page{background:var(--paper);min-height:calc(100vh - 60px)}
.teacher-page[hidden]{display:none}
#teach-body{padding:0;overflow:visible;max-height:none}
body:has(.teacher-page:not([hidden]))>.wrap,body:has(.teacher-page:not([hidden]))>.home{display:none}
body:has(.teacher-page:not([hidden])) #menubtn{display:none}
.td-layout{display:grid;grid-template-columns:224px minmax(0,1fr);max-width:1600px;margin:0 auto;min-height:calc(100vh - 61px)}
.td-nav{background:var(--card);border-right:1px solid var(--rule);padding:30px 16px 20px;display:flex;flex-direction:column;gap:6px;position:sticky;top:61px;height:calc(100vh - 61px)}
.td-nav-brand{display:flex;align-items:center;gap:12px;padding:0 10px 28px;font-weight:700;font-size:16px}
.td-nav-brand>span{display:grid;place-items:center;width:38px;height:38px;border-radius:12px;background:var(--brand);color:var(--on-brand);font-size:13px}
.td-nav-brand small{display:block;color:var(--muted);font-size:12px;font-weight:400;letter-spacing:.1em}
.td-nav-label{color:var(--muted);font-size:12.5px;padding:0 12px;margin:0 0 9px}
.td-nav button{display:flex;align-items:center;gap:11px;width:100%;min-height:45px;padding:11px 12px;border:0;border-radius:9px;background:transparent;color:var(--ink-2);font:inherit;text-align:left;font-size:14px}
.td-nav button>span{width:19px;font-size:19px;text-align:center}
.td-nav button>.ic{width:20px;height:20px}
.td-nav button:hover{background:var(--sunk)}
.td-nav button[aria-current]{background:var(--brand-soft);color:var(--brand-ink);font-weight:600}
.td-nav button>small{margin-left:auto;background:var(--brand);color:white;border-radius:6px;padding:0 6px;font-size:12px}
.td-nav-bottom{margin-top:auto;border-top:1px solid var(--rule);padding-top:16px}
.td-nav-bottom p{font-size:12.5px;color:var(--muted);line-height:1.8;padding:0 10px}
.td-main{padding:36px clamp(20px,3vw,44px) 64px;min-width:0}
.td-page-head{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:26px}
.td-eyebrow{font-size:12.5px;font-weight:600;letter-spacing:.035em;color:var(--brand-ink)}
.td-page-head h1{font-size:clamp(23px,2.2vw,32px);line-height:1.4;letter-spacing:-.04em;margin:6px 0 7px;outline:none}
.td-page-head p{font-size:14px;line-height:1.7;color:var(--muted);margin:0}
.td-toolbar{display:flex;align-items:end;gap:14px;background:var(--card);border:1px solid var(--rule);padding:16px 18px;border-radius:12px}
.td-toolbar label,.td-filters label{display:flex;flex-direction:column;gap:5px;font-size:12.5px;color:var(--muted)}
.td-toolbar select,.td-filters select,.td-filters input{font:inherit;font-size:14px;border:1px solid var(--rule);border-radius:9px;padding:9px 12px;min-height:44px;background:var(--paper);color:var(--ink)}
.td-toolbar label:first-child{min-width:200px}
.td-fresh{margin-left:auto;display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--muted);padding-bottom:12px}
.td-fresh i{width:6px;height:6px;border-radius:50%;background:var(--ok)}
.td-data-note{font-size:13px;color:var(--muted);margin:11px 2px 23px;line-height:1.7}
.td-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-bottom:23px}
.td-stats>div{border:1px solid var(--rule);border-radius:12px;background:var(--card);padding:20px}
.td-stats>div>span{color:var(--ink-2);font-size:13.5px;font-weight:500}
.td-stats>div>b{display:block;font-family:var(--sans);font-size:34px;line-height:1.25;margin:12px 0 9px;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.td-stats small{font-size:13px;font-weight:400;color:var(--muted);margin-left:8px;letter-spacing:0}
.td-stats p{font-size:12.5px;line-height:1.6;color:var(--muted);margin:0}
.td-card{padding:24px;border:1px solid var(--rule);border-radius:13px;background:var(--card);min-width:0;margin-bottom:22px}
.td-card h2{font-size:18px;line-height:1.5;letter-spacing:-.02em;margin:4px 0 18px}
.td-section-head{display:flex;justify-content:space-between;align-items:center;gap:16px}
.td-section-head>span{font-size:13px;color:var(--muted)}
.td-section-head h2{margin-bottom:17px}
.td-text-btn{font:inherit;font-size:13px;color:var(--brand-ink);padding:9px 0;border:0;background:transparent;font-weight:600;min-height:40px}
.td-overview-grid{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(270px,1fr);gap:20px}
.td-focus{display:grid;grid-template-columns:27px 1fr auto;gap:12px;align-items:start;padding:18px 0;border-top:1px solid var(--rule-2)}
.td-focus-index{font-size:13px;color:var(--muted);padding-top:1px}
.td-focus b{font-size:14.5px;font-weight:600}
.td-focus p{font-size:13px;line-height:1.65;color:var(--muted);margin:4px 0 11px}
.td-focus strong{font-size:21px;font-weight:600;color:var(--brand-ink);text-align:right}
.td-focus strong small{display:block;font-size:12px;font-weight:400;color:var(--muted)}
.td-bar{display:block;height:5px;background:var(--sunk-2);border-radius:6px;overflow:hidden;min-width:68px;max-width:330px;margin-top:6px}
.td-bar i{display:block;height:100%;background:var(--brand-ink);border-radius:6px}
.td-footnote{font-size:12.5px;color:var(--muted);line-height:1.8;margin:10px 0 0}
.td-follow{width:100%;text-align:left;display:flex;align-items:center;gap:13px;font:inherit;padding:16px 0;background:transparent;border:0;border-top:1px solid var(--rule-2);color:var(--ink)}
.td-follow strong{font-size:25px;min-width:32px;font-weight:600;color:var(--brand-ink)}
.td-follow span{font-size:14px}
.td-follow small{display:block;font-size:12.5px;line-height:1.6;color:var(--muted);margin-top:3px}
.td-follow i{font-style:normal;margin-left:auto;color:var(--brand-ink)}
.td-follow:hover span{text-decoration:underline;text-underline-offset:3px}
.td-table-scroll{overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch}
.td-table{border-collapse:collapse;width:100%;font-size:14px;text-align:left;min-width:620px}
.td-table th{padding:12px 14px;color:var(--muted);font-size:12.5px;font-weight:500;background:var(--paper);white-space:nowrap}
.td-table td{padding:15px 14px;border-bottom:1px solid var(--rule-2);font-variant-numeric:tabular-nums;vertical-align:middle}
.td-table td:first-child{width:33%}
.td-table td:first-child b{font-weight:500}
.td-table small{display:block;color:var(--muted);font-size:12px;margin-top:3px}
.td-table .td-bar{max-width:85px}
.td-pill{display:inline-block;white-space:nowrap;font-size:12px;padding:4px 9px;border-radius:6px;color:var(--ink-2);background:var(--sunk)}
.td-pill.warn{color:var(--warn);background:var(--warn-soft)}
.td-pill.ok{color:var(--ok);background:var(--ok-soft)}
/* แผนที่ความร้อน — สีจาก --heat (อัตราถูก 0–100) ผสมแดง→เขียวใน oklch ให้ความสว่างคงที่ ตัวหนังสือจึงอ่านออกทุกช่อง */
.td-heat{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:6px 0 14px}
.td-heat-cell{display:flex;flex-direction:column;gap:3px;padding:10px 11px;border-radius:9px;text-decoration:none;color:#1a1a1a;min-height:64px;
  background:color-mix(in oklch, #e4572e calc(100% - var(--heat) * 1%), #3aa56b calc(var(--heat) * 1%));
  background:color-mix(in oklch, oklch(72% 0.17 32) calc(100% - var(--heat) * 1%), oklch(72% 0.14 150) calc(var(--heat) * 1%))}
.td-heat-cell.thin{opacity:.55}
.td-heat-cell b{font-size:17px;font-weight:600;line-height:1}
.td-heat-cell span{font-size:12.5px;line-height:1.35}
.td-heat-cell small{font-size:11.5px;opacity:.85;margin-top:auto;padding-top:4px;border-top:1px solid rgba(0,0,0,.12)}
.td-heat-cell:hover,.td-heat-cell:focus-visible{outline:2px solid var(--brand-ink);outline-offset:2px}
.td-slip{display:inline-flex;align-items:center;gap:5px;font-size:12px;padding:3px 8px;border-radius:6px;background:var(--warn-soft);color:var(--warn);white-space:nowrap;margin:2px 0}
.td-slip small{font-size:11px;opacity:.85}
.td-slip-rest{display:block;color:var(--muted);font-size:12px;margin-top:3px}
.td-focus em{font-style:normal;color:var(--warn)}
.td-filters{display:flex;gap:16px;margin:2px 0 17px;align-items:end}
.td-search{flex:1}
.td-result-count{color:var(--muted);font-size:12.5px;margin:12px 0}
.td-empty{padding:30px 16px;color:var(--muted);text-align:center;font-size:14px;line-height:1.9}
.td-empty b{color:var(--ink-2);font-weight:500}
.td-empty p{margin:5px 0}
.learn-start{
  border:1px solid var(--rule); padding:25px; margin:0 0 25px; display:flex; gap:20px; align-items:center;
  justify-content:space-between; border-color:var(--rule-2); border-radius:var(--r); box-shadow:var(--shadow);
  background:linear-gradient(120deg, var(--card) 55%, var(--brand-soft));
}
.learn-start h2{font-size:21px;margin:5px 0 7px}
.learn-start p{font-size:14px;color:var(--muted);margin:0}
.learn-start .btn{white-space:nowrap;min-height:44px}
.sync-state{font-size:11px;color:var(--muted);padding:4px 0;border:0;background:none;cursor:pointer;white-space:nowrap}
.sync-state[data-status="pending"]{color:var(--warn)}
.reportlink,.dash-link{min-height:32px;padding:6px 2px;font-size:12px}
@media(max-width:1180px){
  .td-layout{grid-template-columns:190px minmax(0,1fr)}
  .td-main{padding:26px 22px 40px}
  .td-overview-grid{grid-template-columns:1fr}
  .td-stats{grid-template-columns:repeat(2,1fr)}
  .td-fresh{display:none}
}
@media(max-width:760px){
  .td-layout{display:block}
  .td-nav{position:static;height:auto;border-right:0;border-bottom:1px solid var(--rule);padding:10px 14px;display:flex;flex-direction:row;overflow-x:auto;gap:4px}
  .td-nav-brand,.td-nav-label,.td-nav-bottom{display:none}
  .td-nav>button{width:auto;white-space:nowrap;min-height:42px;font-size:13px;padding:8px 12px;flex:none}
  .td-nav>button>span,.td-nav>button>.ic{display:none}
  .td-main{padding:23px 16px 40px}
  .td-page-head{align-items:start}
  .td-page-head h1{font-size:23px}
  .td-page-head #td-refresh{font-size:0;padding:10px}
  .td-page-head #td-refresh:before{content:'↻';font-size:20px}
  .td-toolbar{padding:12px;gap:10px}
  .td-toolbar label{flex:1;min-width:0!important}
  .td-toolbar select{width:100%;max-width:100%;font-size:13px}
  .td-stats{gap:10px}
  .td-stats>div{padding:15px}
  .td-stats>div>b{font-size:28px}
  .td-stats p{font-size:12px}
  .td-card{padding:18px 15px}
  .td-section-head{align-items:start}
  .td-section-head h2{font-size:16px}
  .td-text-btn{font-size:12.5px}
  .td-focus{grid-template-columns:22px 1fr auto;gap:8px}
  .td-focus b{font-size:14px}
  .td-focus p{font-size:12.5px}
  .td-filters{flex-direction:column;align-items:stretch}
  .learn-start{display:block;padding:20px}
  .learn-start .btn{margin-top:16px;width:100%}
  .sync-state{max-width:160px;white-space:normal;font-size:11.5px}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}
/* ผู้ที่ยังไม่เริ่มวิชานี้ — จำนวนแยกสาขา/หมู่ ไม่มีชื่อ */
.td-idle{display:flex;flex-direction:column;gap:3px;margin:0 0 14px;padding:12px 14px;border-radius:10px;
         background:var(--warn-soft);border:1px solid color-mix(in srgb, var(--warn) 35%, transparent)}
.td-idle b{font-size:14px;color:var(--ink)}
.td-idle span{font-size:13px;color:var(--ink-2)}
.td-idle small{font-size:12.5px;color:var(--muted)}
/* ── เทียบหัวข้อที่ทั้งห้องยังติด ── แท่งอัตราตอบถูก + จำนวนคน เส้นประที่ 70% */
.td-cmp{display:flex;flex-direction:column;gap:12px;margin:4px 0 6px}
.td-cmp-row{display:grid;grid-template-columns:minmax(120px,1.1fr) minmax(0,2fr) 48px minmax(96px,auto);
            gap:12px;align-items:center;font-size:14px}
.td-cmp-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.td-cmp-track{position:relative;height:12px;border-radius:99px;background:var(--sunk-2);overflow:hidden}
.td-cmp-track::after{content:"";position:absolute;top:-2px;bottom:-2px;left:70%;border-left:2px dashed var(--ink-2);opacity:.55}
.td-cmp-track i{display:block;height:100%;border-radius:99px;background:var(--ok)}
.td-cmp-track i.mid{background:var(--warn)}
.td-cmp-track i.low{background:var(--bad)}
.td-cmp-row b{font-variant-numeric:tabular-nums;text-align:right}
.td-cmp-row small{font-size:12.5px;color:var(--muted);white-space:nowrap}
@media(max-width:760px){
  .td-cmp-row{grid-template-columns:minmax(0,1fr) 44px;gap:4px 10px}
  .td-cmp-name{grid-column:1 / -1;white-space:normal}
  .td-cmp-row small{grid-column:1 / -1}
}
/* ── หน้าเครื่องมือ/จัดการระบบ: หมวดงานแยกด้วยหัวข้อและระยะห่าง ไม่ใช่กรอบซ้อนกรอบ ── */
/* แถบหมวดงาน — เห็นทีละหมวด เส้นใต้บอกหมวดที่เปิดอยู่ */
.td-jump{display:flex;gap:4px;margin:-6px 0 24px;border-bottom:1px solid var(--rule);overflow-x:auto;scrollbar-width:none}
.td-jump::-webkit-scrollbar{display:none}
.td-jump [role=tab]{flex:none;padding:10px 14px 11px;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;
  background:none;color:var(--muted);font:inherit;font-size:14px;font-weight:600;cursor:pointer;white-space:nowrap}
.td-jump [role=tab]:hover{color:var(--ink)}
.td-jump [role=tab][aria-selected=true]{color:var(--brand-ink);border-bottom-color:var(--brand-ink)}
.td-card .tsub[hidden], .td-pane[hidden]{display:none}
.td-card .tsub:not([hidden]){border-bottom:0;margin-bottom:0;padding-bottom:0}
/* หน้าจัดการระบบไม่ได้ขึ้นกับวิชาหรือช่วงเวลา — ซ่อนตัวเลือกที่ไม่มีผลกับหน้านี้ */
.td-main--admin .td-toolbar, .td-main--admin .td-data-note{display:none}
.td-card .tsub{border:0;border-radius:0;padding:0 0 26px;margin:0 0 26px;border-bottom:1px solid var(--rule-2)}
.td-card .tsub:last-child{border-bottom:0;margin-bottom:0;padding-bottom:0}
.td-card .tsub-h{font-size:18px;letter-spacing:-.01em;margin-bottom:10px;scroll-margin-top:84px}
.td-card .tsec{scroll-margin-top:84px}
.td-card .tnote{border:0;background:var(--sunk);font-size:13.5px;line-height:1.75}
/* ── รายงาน CLO: หน้าดูก่อนส่งออก ──────────────────────────────────
   กระดาษ A4 บนพื้นเทา หน้าตาเดียวกับที่พิมพ์ออกไป — ตัวอักษรสีดำบนขาวเสมอ ไม่เปลี่ยนตามธีมมืด
   เพราะเป็นเอกสารที่จะแนบไปกับเอกสารหลักสูตร ไม่ใช่หน้าจอของแอป */
.clo-pv{position:fixed;inset:0;z-index:70;display:flex;flex-direction:column;background:var(--sunk-2)}
html.clo-pv-on, html.clo-pv-on body{overflow:hidden}
.clo-pv-bar{display:flex;align-items:center;gap:10px 16px;flex-wrap:wrap;padding:12px 20px;
            background:var(--card);border-bottom:1px solid var(--rule)}
.clo-pv-bar b{font-size:15px}
.clo-pv-opt{display:flex;align-items:center;gap:7px;font-size:13.5px;color:var(--ink-2)}
.clo-pv-acts{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}
.clo-pv-acts .btn{margin:0;display:inline-flex;align-items:center;gap:6px}
.clo-pv-acts .ic{width:15px;height:15px}
#clo-preview{display:inline-flex;align-items:center;gap:6px}
#clo-preview .ic{width:15px;height:15px}
.clo-pv-scroll{flex:1;overflow:auto;padding:28px 16px 60px}
.clo-paper{--ink:#1d1a1b;--mut:#5d5557;--line:#d9d3d4;
  width:210mm;min-height:297mm;margin:0 auto;padding:18mm 17mm 16mm;box-sizing:border-box;
  background:#fff;color:var(--ink);box-shadow:0 2px 14px rgba(0,0,0,.18);
  font-family:var(--sans);font-size:10.5pt;line-height:1.65}
.clo-paper h1{margin:2px 0 10px;font-size:17pt;line-height:1.3;letter-spacing:-.01em}
.clo-paper h2{margin:0 0 6px;font-size:11.5pt}
.cp-kicker{margin:0;font-size:9.5pt;font-weight:600;letter-spacing:.03em;color:#8c1c34}
.cp-head{padding-bottom:10px;border-bottom:1.5pt solid var(--ink);margin-bottom:14px}
.cp-meta{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px 18px;margin:0}
.cp-meta div{display:flex;gap:8px;min-width:0}
.cp-meta dt{color:var(--mut);flex:none}
.cp-meta dd{margin:0;font-weight:600;overflow-wrap:anywhere}
.cp-sec{margin:0 0 14px;break-inside:avoid}
.cp-sec p{margin:0 0 6px}
.cp-note{color:var(--mut);font-size:9.5pt}
.cp-sec ul{margin:0;padding-left:18px}
.cp-sec li{margin:2px 0}
.cp-table{width:100%;border-collapse:collapse;font-size:9.5pt;font-variant-numeric:tabular-nums}
.cp-table th, .cp-table td{border:.6pt solid var(--line);padding:5px 7px;text-align:left;vertical-align:top}
.cp-table th{background:#f3f0f0;font-weight:600}
.cp-table .n{text-align:right;white-space:nowrap}
.cp-table small{display:block;color:var(--mut);font-size:8.5pt}
.cp-appx{break-before:page}
.cp-people td:first-child{white-space:nowrap}
.cp-foot{margin-top:26px;display:flex;flex-direction:column;gap:14px}
.cp-sign{align-self:flex-end;display:flex;flex-direction:column;align-items:center;gap:6px;font-size:10pt}
.cp-foot p{margin:0;padding-top:8px;border-top:.6pt solid var(--line);color:var(--mut);font-size:8.5pt}
@media (max-width:820px){
  /* จอแคบกว่ากระดาษ — กระดาษยังกว้าง A4 เท่าเดิม เลื่อนดูได้ทั้งแนวตั้งและแนวนอน
     (เคยลองให้กระดาษกว้างเท่าจอ ตารางสรุป 8 คอลัมน์บีบจนคอลัมน์ขวาหลุดจอ ไม่ตรงกับที่จะพิมพ์ออกไป) */
  .clo-pv-scroll{padding:16px 12px 40px}
  .clo-pv-acts{margin-left:0}
}
@media print{
  @page{size:A4;margin:0}
  html.clo-pv-on body > *:not(.clo-pv){display:none !important}
  html.clo-pv-on, html.clo-pv-on body{overflow:visible;background:#fff}
  html.clo-pv-on .clo-pv{position:static;display:block;background:#fff}
  html.clo-pv-on .clo-pv-bar{display:none}
  html.clo-pv-on .clo-pv-scroll{overflow:visible;padding:0}
  html.clo-pv-on .clo-paper{box-shadow:none;margin:0;width:210mm}
}
/* สรุปราย CLO ในแผงรายงาน — แถบสามสี (บรรลุ · ยังไม่บรรลุ · ข้อมูลไม่พอ) ต่อ CLO */
.clo-bars{display:flex;flex-direction:column;gap:18px;margin:18px 0 22px}
.clo-bar{min-width:0}
.clo-bar-h{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:baseline;gap:4px 12px;margin-bottom:8px}
.clo-bar-h b{font-size:14px}
.clo-bar-h span{font-size:14px;color:var(--ink-2)}
.clo-bar-h small{font-size:12.5px;color:var(--muted)}
.clo-bar-h strong{font-size:20px;font-variant-numeric:tabular-nums;text-align:right;line-height:1.1}
.clo-bar-h strong small{display:block;font-size:12px;font-weight:400}
.clo-track{display:flex;height:12px;border-radius:99px;overflow:hidden;background:var(--sunk)}
.clo-track i{display:block;height:100%}
.clo-track .p, .clo-bar-n .p::before{background:var(--ok)}
.clo-track .f, .clo-bar-n .f::before{background:var(--bad)}
.clo-track .t, .clo-bar-n .t::before{background:var(--rule)}
.clo-bar-n{display:flex;gap:16px;flex-wrap:wrap;margin-top:7px;font-size:12.5px;color:var(--ink-2);font-variant-numeric:tabular-nums}
.clo-bar-n span::before{content:"";display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:6px;vertical-align:0}
@media (max-width:640px){
  .clo-bar-h{grid-template-columns:auto minmax(0,1fr) auto}
  .clo-bar-h small:not(strong small){grid-column:2}
}

/* ═══ แอปหลัก (เดิม <style> ใน index.html) ════════════════════════════════ */
:root{
  --sans:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono","IBM Plex Sans Thai",ui-monospace,Menlo,monospace; --paper:#f7f5f4; --card:#ffffff;
  --sunk:#f2eeed; --sunk-2:#e8e2e1; --ink:#1d1517; --ink-2:#4d4144; --muted:#6c5f62; --rule:#e3dcdb;
  --rule-2:#eee9e8; --brand:#8a1c35; --brand-2:#a0263f; --brand-soft:#f6e7ea; --brand-ink:#8a1c35;
  --on-brand:#fff; --ok:#23704a; --ok-soft:#e5f3eb; --warn:#7d6608; --warn-soft:#fbf5d8; --bad:#b83e17;
  --bad-soft:#fcebe3; --accent:#2d3190; --accent-soft:#e9eaf7; --grid:rgba(138,28,53,.07);
  --shadow:0 1px 2px rgba(29,21,23,.05), 0 10px 28px -16px rgba(29,21,23,.18);
  --shadow-lift:0 2px 4px rgba(29,21,23,.05), 0 18px 40px -18px rgba(29,21,23,.28);
  --ring:0 0 0 3px color-mix(in srgb, var(--brand) 26%, transparent); --r:14px; --r-sm:10px;
  /* สีรองประจำวิชา — แยกวิชาด้วยไอคอนเท่านั้น สีหลักของระบบยังเป็นแดงเลือดหมู (≥ 4.5:1 บนการ์ด) */
  --hue-indigo:#3f4aa8; --hue-teal:#0f6a74; --hue-amber:#855400; --hue-green:#2d6a3e; --hue-orange:#9a4217;
}
/* ธีมมืดมีสองทางที่ต้องรองรับ
   1. ผู้ใช้ไม่ได้เลือกอะไร  → ตามการตั้งค่าของเครื่อง (prefers-color-scheme)
   2. ผู้ใช้เลือกเอง        → data-theme บน <html> ต้องชนะการตั้งค่าเครื่องทั้งสองทาง
   ตัวแปรสีทั้งหมดจึงต้องประกาศซ้ำในทั้งสองที่ ห้ามประกาศสีไว้ในบล็อกเดียว */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;font-family:var(--sans);font-size:15px;line-height:1.62;
  color:var(--ink);background:var(--paper);
  /* ลิ้นชักสารบัญซ่อนตัวไว้นอกจอด้านขวา ทำให้หน้าเลื่อนแนวนอนได้
     ซึ่งบนแท็บเล็ตคือปัดแล้วเจอแถบว่าง ใช้ clip ไม่ใช่ hidden
     เพราะ hidden จะทำให้หัวเว็บแบบ sticky ค้างไม่ทำงาน */
  overflow-x:clip;
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),
                   linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:28px 28px;-webkit-font-smoothing:antialiased;
}
button,input{font:inherit}
button{cursor:pointer}
.katex{font-size:1.04em}
.hidden{display:none!important}
/* ── หัวแอป ─────────────────────────────────────────── */
.logo{
  font-weight:700; display:flex; align-items:center; letter-spacing:-.01em; background:transparent; border:0;
  padding:0; color:inherit; font-size:16px; gap:10px;
}
.logo .sig{
  display:grid; place-items:center; color:var(--on-brand); font-size:16px; width:30px; height:30px;
  border-radius:9px; flex:none; background:linear-gradient(145deg, var(--brand-2), var(--brand));
  box-shadow:0 1px 0 rgba(255,255,255,.2) inset, 0 2px 6px -2px color-mix(in srgb, var(--brand) 60%, transparent);
}
.logo .sig.txt{font-size:11px;font-weight:700;letter-spacing:.5px}
.course{font-size:13px;color:var(--muted);padding-left:12px;border-left:1px solid var(--rule)}
.tier{
  margin-left:auto; display:flex; align-items:center; gap:7px; color:var(--ink-2); border:1px solid var(--rule);
  border-radius:99px; cursor:help; background:transparent; border-color:var(--rule); padding:5px 12px;
  font-size:12px;
}
.dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:none}
.dot.t0{background:var(--muted)}
/* ── หน้าแรกเลือกวิชา ───────────────────────────────── */
.home{display:none;padding:56px 22px 88px}
.home[data-open="true"]{display:block}
.homewrap{margin:0 auto;max-width:960px}
.home h1{margin:0 0 6px;font-size:clamp(28px,4.4vw,40px);letter-spacing:-.022em;line-height:1.15;margin-bottom:10px}
.home .lead{margin:0 0 30px;font-size:15.5px;color:var(--ink-2);max-width:64ch;margin-bottom:34px;text-wrap:pretty}
.subjects{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:16px}
.subj:hover{transform:translateY(-3px);box-shadow:var(--shadow-lift);border-color:var(--rule)}
.subj-ic{
  display:grid; place-items:center; font-family:Georgia,serif; flex:none; width:48px; height:48px;
  border-radius:13px; font-size:24px; background:var(--brand);
  background:color-mix(in srgb, var(--hue) 13%, var(--card)); color:var(--hue);
}
.subj-h{min-width:0;flex:1}
.subj-h span{color:var(--muted);font-family:var(--mono);font-size:12px;letter-spacing:.01em}
.subj-stats{display:flex;gap:0;background:transparent;border-top:1px solid var(--rule-2);margin:0 20px}
.subj-stats div{flex:1;border-right:0;padding:12px 0;text-align:left}
.subj-stats div:last-child{border-right:0}
.subj-stats b{display:block;font-family:var(--mono);font-size:16px;font-variant-numeric:tabular-nums}
.subj-stats span{font-size:11px;color:var(--muted)}
.subj-foot{
  display:flex; align-items:center; gap:9px; font-size:12.5px; color:var(--ink-2); padding:13px 20px 16px;
  border-top:0;
}
.subj-foot .have{color:var(--ok)}
.subj-foot .go{margin-left:auto;color:var(--brand-ink);font-weight:600;display:inline-flex;align-items:center;gap:6px}
.bar{height:4px;background:var(--rule-2);border-radius:99px;overflow:hidden;flex:1;max-width:120px}
.bar i{display:block;height:100%;background:var(--ok);border-radius:99px}
/* แถบบอกว่าตอนนี้พร้อมใช้ตอนไม่มีเน็ตหรือยัง — ผู้เรียนไม่ควรต้องเดาเอง */
.ready{
  display:flex; align-items:center; gap:11px; padding:12px 15px; border:1px solid var(--rule); font-size:13px;
  margin-bottom:16px; border-radius:var(--r-sm); border-color:var(--rule-2); background:var(--card);
}
.ready .rdot{width:9px;height:9px;border-radius:50%;flex:none;background:var(--ok)}
.ready[data-ok="false"] .rdot{background:var(--warn)}
.ready b{font-weight:600}
.ready span{color:var(--muted)}
.ready a{color:var(--brand-ink);font-weight:600;white-space:nowrap}
/* ── หน้าเข้าสู่ระบบ ────────────────────────────────── */
/* จัดกลางด้วย margin:auto ของการ์ด ไม่ใช่ align-items:center — ฟอร์มลงทะเบียนสูงกว่าจอ 1280×720
   แล้ว align-items:center ดันหัวการ์ดขึ้นไปเหนือจุดเริ่มเลื่อน 244px เลื่อนขึ้นไปดูไม่ได้เลย */
.gate{
  position:fixed; inset:0; z-index:80; background:var(--paper); display:flex; align-items:flex-start;
  justify-content:center; padding:20px; overflow-y:auto; background-color:var(--paper);
  background-image:radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--brand) 9%, transparent), transparent 60%),
                       linear-gradient(var(--grid) 1px,transparent 1px),
                       linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:100% 100%, 28px 28px, 28px 28px;
}
.gate[hidden]{display:none}
.gate-card{
  margin:auto; background:var(--card); border:1px solid var(--rule); width:min(420px,100%); border-radius:18px;
  border-color:var(--rule-2); padding:32px 30px 26px; box-shadow:var(--shadow-lift);
}
.gate-head{display:flex;align-items:center;gap:12px;margin-bottom:22px}
.gate-head .sig{
  display:grid; place-items:center; color:var(--on-brand); font-weight:700; width:44px; height:44px;
  border-radius:12px; font-size:15px; flex:none;
  background:linear-gradient(145deg, var(--brand-2), var(--brand));
}
.gate-head span{display:block;color:var(--muted);font-size:12px}
.gate h2{margin:0 0 5px;font-size:22px;letter-spacing:-.015em}
.gate-lead{margin:0 0 18px;color:var(--muted);font-size:13px;line-height:1.7}
.fld{display:block;margin-bottom:13px}
.fld span{display:block;font-size:12.5px;color:var(--ink-2);margin-bottom:5px;font-weight:600}
.fld span i{font-style:normal;font-weight:400;color:var(--muted)}
.role{font-size:11px;font-weight:700;padding:2px 8px;border-radius:99px;
      background:var(--brand-soft);color:var(--brand-ink);letter-spacing:.3px}
.fld input{width:100%;padding:11px 13px;border-radius:9px;border:1px solid var(--rule);
           background:var(--paper);color:var(--ink);font:inherit;font-size:14.5px}
.fld input:focus{outline:2px solid var(--brand-ink);outline-offset:1px;border-color:var(--brand-ink)}
/* คำอธิบายใต้ช่องกรอก — อาจารย์ไม่มีรหัสนักศึกษา ต้องบอกให้ชัดว่าใส่อะไรได้ */
.fld .fhint{display:block;font-style:normal;font-size:11.5px;color:var(--muted);
            margin-top:5px;line-height:1.55}
.fld .fhint b{color:var(--ink-2);font-family:var(--mono);font-weight:600}
.btn.wide{width:100%;justify-content:center;margin-top:6px;padding:13px;font-size:15px}
.gate-err{background:var(--bad-soft);border:1px solid var(--bad);color:var(--bad);border-radius:8px;
          padding:9px 12px;font-size:12.5px;margin:2px 0 10px}
.gate-alt{margin:14px 0 0;text-align:center;font-size:13px;color:var(--muted)}
.gate-alt a{color:var(--brand-ink);font-weight:600}
.gate-sep{margin:20px 0 10px;color:var(--muted);font-size:12px;text-align:center}
.whos{display:flex;flex-direction:column;gap:7px}
.who{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:10px 12px;
     border-radius:9px;border:1px solid var(--rule);background:var(--sunk);color:inherit}
.who:hover{border-color:var(--brand-ink)}
.who b{font-size:13.5px}
.who span{color:var(--muted);font-family:var(--mono);font-size:11.5px;margin-left:auto}
.gate-note{margin:20px 0 0;color:var(--muted);font-size:11.5px;line-height:1.75;
           border-top:1px solid var(--rule);padding-top:14px}
.gate-note a{color:var(--brand-ink)}
/* กล่องข้อมูลส่วนตัวในหน้าบัญชี — แยกจากส่วนรหัสผ่านให้ชัดว่าเป็นคนละเรื่อง */
.acct-sec{padding:14px 15px;margin-bottom:18px;border:1px solid var(--rule);
          border-radius:10px;background:var(--sunk)}
.acct-sec[hidden]{display:none}
.acct-sec .fld{margin-bottom:10px}
.acct-h{font-size:13px;font-weight:600;color:var(--ink-2);margin:0 0 10px}
.acct-h[hidden]{display:none}
.pf-ok{margin-left:10px;font-size:12.5px;color:var(--ok)}
.pf-ok[hidden]{display:none}
.fld select{width:100%;padding:11px 12px;border-radius:9px;border:1px solid var(--rule);
            background:var(--card);color:var(--ink);font:inherit;font-size:14px}
.fld select:focus{outline:2px solid var(--brand-ink);outline-offset:1px}
.pw-warn{margin:-4px 0 12px;font-size:11.5px;line-height:1.7;color:var(--warn)}
.fld[hidden]{display:none}
.fld-err{display:block;font-style:normal;font-size:12.5px;line-height:1.55;color:var(--bad);margin:-6px 0 12px}
.gate [aria-invalid="true"]{border-color:var(--bad)!important}
.pw-wrap{position:relative;display:block}
.fld .pw-wrap input{padding-right:64px}
.pw-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);border:0;background:transparent;
        color:var(--brand-ink);font:inherit;font-size:12.5px;font-weight:600;padding:6px 8px;border-radius:7px;cursor:pointer}
.pw-eye:hover{background:var(--brand-soft)}
.rg-teacher{margin:0 0 12px}
.rg-teacher summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--ink-2);padding:4px 0}
.rg-teacher[open] summary{margin-bottom:8px}
.chk{display:flex;gap:9px;align-items:flex-start;margin:4px 0 12px;font-size:12.5px;
     line-height:1.65;color:var(--ink-2);cursor:pointer}
.chk input{width:17px;height:17px;flex:none;margin-top:1px;accent-color:var(--brand-ink)}
.chk a{color:var(--brand-ink);font-weight:600}
.tms h4{font-size:13.5px;margin:16px 0 5px;color:var(--ink)}
.tms h4:first-of-type{margin-top:4px}
.tms p{margin:0 0 8px;font-size:12.5px;line-height:1.85;color:var(--ink-2)}
.tms ul{margin:0 0 8px;padding-left:19px}
.tms li{font-size:12.5px;line-height:1.85;color:var(--ink-2);margin-bottom:3px}
.tms-v{color:var(--muted);font-family:var(--mono);font-size:11.5px}
.tms-warn{background:var(--warn-soft);border:1px solid var(--warn);border-radius:8px;padding:9px 12px;
          color:var(--warn)}
.dangerlink{background:transparent;border:0;color:var(--warn);font:inherit;font-size:12px;
            text-decoration:underline;padding:0;margin-top:12px}
/* ปุ่มแจ้งเนื้อหาผิด — ต้องหาเจอเมื่อต้องการ แต่ไม่แย่งความสนใจจากการทำโจทย์ */
.reportlink{background:transparent;border:0;color:var(--muted);font:inherit;font-size:11.5px;
            cursor:pointer;padding:0;text-decoration:underline;text-underline-offset:3px}
.reportlink:hover{color:var(--bad)}
/* กล่องเรื่องที่ผู้เรียนแจ้ง — อ่านเร็วและกดปิดได้ในคลิกเดียว */
.rplist{display:flex;flex-direction:column;gap:9px;margin-bottom:8px}
.rp{border:1px solid var(--rule);border-left:3px solid var(--bad);border-radius:10px;
    background:var(--card);padding:11px 13px}
.rp-h{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:5px}
.rp-h b{font-size:13.5px}
.rp-who{color:var(--muted);font-size:11.5px}
.rp-done{margin-left:auto;background:transparent;border:0;color:var(--ok);font:inherit;
         font-size:11.5px;cursor:pointer;padding:0}
.rp-done:hover{text-decoration:underline}
.rp-note{margin:0;font-size:13.5px;line-height:1.6}
.rp-detail{margin:6px 0 0;font-family:var(--mono);font-size:12px;color:var(--ink-2);
           background:var(--sunk);border-radius:7px;padding:7px 9px;overflow-x:auto;white-space:pre-wrap}
.rp-ref{margin:5px 0 0;font-family:var(--mono);font-size:11px;color:var(--muted)}
.toast{
  position:fixed; left:50%; bottom:26px; transform:translateX(-50%); z-index:120; background:var(--ink);
  color:var(--paper); padding:11px 18px; border-radius:99px; font-size:13px; transition:opacity .4s ease;
  box-shadow:var(--shadow-lift);
}
/* แถบบอกว่าหน้าเว็บเป็นรุ่นเก่า — ต้องเห็นแน่ ๆ แต่ไม่บังเนื้อหา */
.updbar{position:fixed;left:12px;right:12px;bottom:12px;z-index:130;display:flex;
        align-items:center;gap:12px;flex-wrap:wrap;padding:12px 15px;border-radius:12px;
        background:var(--warn-soft);border:1px solid var(--warn);color:var(--ink);
        font-size:13px;line-height:1.6;box-shadow:var(--shadow)}
.updbar .btn{margin-left:auto}
.toast.out{opacity:0}
@media (prefers-reduced-motion:reduce){
  .toast{transition:none}
}
/* กล่องลบบัญชี — ต้องเห็นชัดว่าอันตราย แต่ไม่ควรเด่นกว่าปุ่มบันทึกรหัสใหม่ */
.gate-danger{margin-top:20px;padding:13px 15px;border:1px solid var(--bad);
             border-radius:10px;background:var(--bad-soft)}
.gate-danger b{display:block;font-size:13.5px;color:var(--bad);margin-bottom:4px}
.gate-danger p{margin:0 0 9px;font-size:12.5px;color:var(--ink-2);line-height:1.65}
.gate-danger .dangerlink{color:var(--bad);text-decoration:underline}
.me{position:relative;display:flex;align-items:center;font-size:12.5px;color:var(--muted)}
.me b{color:var(--ink-2);font-weight:600}
/* ปุ่มบัญชี — ตัวเดียวแทนสี่ปุ่มเดิม กดแล้วกางเมนูลงมา */
.acctbtn{display:inline-flex;align-items:center;gap:8px;padding:5px 11px 5px 6px;
         border-radius:99px;border:1px solid var(--rule);background:var(--card);
         color:var(--ink-2);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer}
.acctbtn:hover{border-color:var(--brand-ink)}
.acctbtn[aria-expanded="true"]{border-color:var(--brand-ink);background:var(--sunk)}
.ava{width:24px;height:24px;flex:none;border-radius:50%;background:var(--brand);
     color:var(--on-brand);display:grid;place-items:center;font-size:11px;font-weight:700}
.caret{font-size:10px;color:var(--muted)}
.acctmenu{
  position:absolute; top:calc(100% + 8px); right:0; z-index:60; min-width:190px; display:flex;
  flex-direction:column; padding:6px; background:var(--card); border:1px solid var(--rule);
  border-radius:var(--r); border-color:var(--rule-2); box-shadow:var(--shadow-lift);
}
.acctmenu[hidden]{display:none}
.acctmenu button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
                 padding:10px 11px;border:0;border-radius:8px;background:transparent;
                 color:var(--ink-2);font:inherit;font-size:13px;font-weight:500;cursor:pointer}
/* display:flex ด้านบนแรงกว่ากฎ [hidden] ของเบราว์เซอร์ ถ้าไม่เขียนบรรทัดนี้
   ปุ่มที่ซ่อนไว้จะโผล่ออกมา — เคยทำให้นักศึกษาเห็นปุ่ม "หน้าอาจารย์" */
.acctmenu button[hidden]{display:none}
.acctmenu button:hover{background:var(--sunk);color:var(--ink)}
.acctmenu button.danger{color:var(--bad)}
.acctmenu .themebtn{border:0;background:transparent;padding:10px 11px;border-radius:8px}
.acctmenu .themebtn:hover{background:var(--sunk);border:0}
/* จอแคบซ่อนชื่อไว้ เหลือแค่วงกลมย่อกับลูกศร ไม่ให้หัวเว็บตกสองแถว */
@media(max-width:820px){
  .acctbtn .nm{display:none}
  .acctbtn .role{display:none}
}
.howcard{display:flex;align-items:center;gap:14px;width:100%;text-align:left;margin-top:14px;
         padding:16px 18px;border-radius:12px;border:1px solid var(--rule);background:var(--card);
         color:inherit;box-shadow:var(--shadow);transition:border-color .15s,transform .15s}
.howcard:hover{border-color:var(--brand-ink);transform:translateY(-2px)}
.how-ic{width:38px;height:38px;flex:none;border-radius:11px;background:var(--brand-soft);
        color:var(--brand-ink);display:flex;align-items:center;justify-content:center;
        font-size:19px;font-weight:700}
.how-t{display:block;min-width:0}
.how-t b{display:block;font-size:15px}
.how-t span{display:block;color:var(--muted);font-size:12.5px;margin-top:2px}
.how-go{margin-left:auto;color:var(--brand-ink);font-weight:600;font-size:13px;white-space:nowrap}
@media(max-width:560px){
  .how-go{display:none}
}
.soon{margin-top:26px;padding:18px 20px;border:1px dashed var(--rule);border-radius:12px;
      color:var(--muted)}
.soon-t{font-weight:600;color:var(--ink-2);margin-bottom:5px;font-size:14px}
.soon p{margin:0;font-size:13px;max-width:62ch}
.logo:hover .sig{background:var(--brand-2)}
/* ── โครงหน้า ───────────────────────────────────────── */
.wrap{display:grid;grid-template-columns:280px minmax(0,1fr);gap:20px;
      max-width:1240px;margin:0 auto;padding:20px}
.helpbtn{display:inline-flex;align-items:center;gap:7px;flex:none;padding:5px 12px 5px 6px;
         border-radius:99px;border:1px solid var(--rule);background:var(--sunk);
         color:var(--ink-2);font-size:12.5px;font-weight:600;line-height:1}
.helpbtn .qm{width:19px;height:19px;border-radius:50%;background:var(--brand);color:var(--on-brand);
             display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}
.helpbtn:hover{border-color:var(--brand-ink);color:var(--brand-ink)}
/* กล่องวิธีใช้งาน — อ่านได้ตอนออฟไลน์เพราะอยู่ในหน้าเว็บเลย ไม่ได้โหลดจากที่อื่น */
/* ต้องสูงกว่า .gate (z-index 80) เพราะต้องอ่านข้อตกลงจากหน้าลงทะเบียนได้ */
.modal{
  position:fixed; inset:0; z-index:90; display:flex; align-items:center; justify-content:center; padding:18px;
  background:rgba(19,16,18,.5); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
}
/* display:flex ข้างบนแรงกว่าค่า display:none ที่มากับ [hidden] ถ้าไม่เขียนบรรทัดนี้
   กล่องจะเปิดค้างตลอดเวลาแม้จะตั้ง hidden ไว้ */
.modal[hidden]{display:none}
.modal-card{
  border:1px solid var(--rule); width:min(660px,100%); max-height:min(86vh,780px); display:flex;
  flex-direction:column; box-shadow:0 30px 70px -30px #000; border-radius:18px; border-color:var(--rule-2);
  background:var(--card);
}
.modal-card.wide{width:min(780px,100%)}
.tnote{background:var(--brand-soft);border:1px solid var(--rule);border-radius:10px;
       padding:11px 13px;font-size:12.5px;line-height:1.75;color:var(--ink-2);margin-bottom:16px}
.tbar{display:flex;gap:9px;flex-wrap:wrap;align-items:center;margin-bottom:16px}
.tsum{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px}
.tstat{flex:1;min-width:110px;background:var(--card);border:1px solid var(--rule);
       border-radius:10px;padding:11px 13px}
.tstat b{display:block;font-size:21px;color:var(--ink)}
.tstat span{font-size:11.5px;color:var(--muted)}
.ttab{width:100%;border-collapse:collapse;font-size:13px}
.ttab-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
/* ตารางบัญชีบนมือถือ — แต่ละบัญชีเป็นการ์ด ปุ่มจัดการอยู่ในการ์ดของคนนั้น ไม่ต้องเลื่อนหาทางขวา */
@media (max-width:640px){
  .acc-table, .acc-table tbody{display:block}
  .acc-table tr:first-child{display:none}
  .acc-table tr{display:grid;grid-template-columns:minmax(84px,auto) minmax(0,1fr);gap:2px 12px;
                padding:12px 2px;border-bottom:1px solid var(--rule)}
  .acc-table td{display:contents}
  .acc-table td::before{content:attr(data-label);color:var(--muted);font-size:12px}
  .acc-table td.acts{display:flex;grid-column:1 / -1;gap:14px;margin-top:6px;padding:0}
  .acc-table td.acts::before{content:none}
  .acc-table td.acts button{padding:8px 0;font-size:13.5px}
}
.ttab th{text-align:left;color:var(--muted);font-weight:600;font-size:11.5px;
         padding:0 9px 7px;border-bottom:1px solid var(--rule)}
.ttab td{padding:9px;border-bottom:1px solid var(--rule);vertical-align:top}
.ttab tr:last-child td{border-bottom:0}
.ttab .num{font-family:var(--mono);white-space:nowrap}
.ttab .del{background:transparent;border:0;color:var(--warn);font:inherit;font-size:11.5px;
           text-decoration:underline;padding:0}
.tempty{color:var(--muted);font-size:13px;text-align:center;padding:26px 0}
.tsec{font-size:13px;font-weight:600;margin:20px 0 9px;color:var(--ink-2)}
.tsub{border:1px solid var(--rule);border-radius:12px;padding:15px 16px;margin-bottom:16px}
.tsub-h{display:flex;align-items:center;gap:10px;font-size:15px;font-weight:600;
        margin-bottom:13px;color:var(--brand-ink)}
.tsub-h .btn{margin-left:auto}
.tinput{flex:1;min-width:180px;padding:8px 11px;border-radius:8px;border:1px solid var(--rule);
        background:var(--paper);color:var(--ink);font:inherit;font-size:13px}
/* แดชบอร์ดผู้สอน — สรุปให้ตัดสินใจได้ก่อน แล้วค่อยมีตารางรายละเอียดอยู่ด้านล่าง
   ไม่ใช้กราฟที่ต้องตีความเพิ่ม: ทุกเปอร์เซ็นต์จึงแสดงจำนวนคนและจำนวนครั้งเสมอ */
.dash{border:1px solid var(--rule);border-radius:13px;background:var(--card);padding:16px;
      margin-bottom:16px}
.dash-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
           margin-bottom:14px}
.dash-kicker{margin:0 0 3px;color:var(--brand-ink);font-size:11px;font-weight:700;
             letter-spacing:.07em;text-transform:uppercase}
.dash-head h2{margin:0;color:var(--ink);font-size:18px;letter-spacing:-.01em}
.dash-head p{margin:4px 0 0;color:var(--muted);font-size:12px;line-height:1.55}
.dash-fresh{flex:none;padding:5px 8px;border-radius:99px;background:var(--sunk);color:var(--muted);
            font-size:11px;white-space:nowrap}
.dash-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:12px}
.dash-stat{min-width:0;padding:11px 12px;border:1px solid var(--rule-2);border-radius:10px;
           background:var(--paper)}
.dash-stat b{display:block;overflow:hidden;text-overflow:ellipsis;color:var(--ink);font-size:20px;
             font-variant-numeric:tabular-nums;line-height:1.15}
.dash-stat span{display:block;margin-top:3px;color:var(--muted);font-size:11.5px;line-height:1.35}
.dash-grid{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(220px,1fr);gap:10px}
.dash-card{border:1px solid var(--rule);border-radius:11px;padding:13px 14px;background:var(--paper)}
.dash-card-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:8px}
.dash-card h3{margin:0;color:var(--ink);font-size:13.5px}
.dash-card-h span{color:var(--muted);font-size:11px}
.dash-focus-list{display:flex;flex-direction:column;gap:2px}
.dash-focus-row{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:10px;row-gap:5px;
                padding:10px 0;border-top:1px solid var(--rule-2)}
.dash-focus-row:first-child{border-top:0;padding-top:3px}
.dash-focus-title{min-width:0;color:var(--ink-2);font-size:12.5px;font-weight:600}
.dash-focus-meta{color:var(--muted);font-size:11.5px;white-space:nowrap}
.dash-rate{font-family:var(--mono);font-size:13px;font-weight:600;color:var(--warn);white-space:nowrap}
.dash-focus-row.steady .dash-rate{color:var(--ok)}
.dash-signal{grid-column:1 / -1;display:flex;align-items:center;gap:8px}
.dash-signal .pbar{flex:1;min-width:0}
.dash-signal .dash-link{flex:none}
.dash-follow-list{display:flex;flex-direction:column;gap:9px;margin:3px 0 0}
.dash-follow{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px;align-items:start}
.dash-follow b{min-width:22px;color:var(--ink);font-family:var(--mono);font-size:17px;line-height:1.15}
.dash-follow span{color:var(--ink-2);font-size:12px;line-height:1.45}
.dash-follow small{display:block;color:var(--muted);font-size:11px;line-height:1.45;margin-top:1px}
.dash-link{appearance:none;border:0;background:transparent;color:var(--brand-ink);font:inherit;
           font-size:11.5px;font-weight:600;cursor:pointer;padding:0;text-decoration:underline;
           text-underline-offset:3px}
.dash-link:hover{color:var(--brand-2)}
.dash-foot{margin:10px 0 0;color:var(--muted);font-size:11px;line-height:1.55}
.dash-alert{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:-4px 0 13px;
            padding:10px 12px;border:1px solid var(--warn);border-radius:10px;background:var(--warn-soft);
            color:var(--ink-2);font-size:12.5px;line-height:1.5}
.dash-alert b{color:var(--warn);font-size:13px}
.dash-alert .dash-link{margin-left:auto}
@media(max-width:680px){
  .dash{padding:14px}
  .dash-head{display:block}
  .dash-fresh{display:inline-block;margin-top:8px}
  .dash-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dash-grid{grid-template-columns:1fr}
}
/* หน้าผู้ช่วย AI ของผู้สอน */
.drop{border:2px dashed var(--rule);border-radius:12px;padding:26px 16px;text-align:center;
      color:var(--muted);font-size:13px;cursor:pointer;transition:border-color .15s,background .15s}
.drop:hover,.drop.over{border-color:var(--brand-ink);background:var(--brand-soft);color:var(--ink-2)}
.drop b{display:block;color:var(--ink);font-size:14px;margin-bottom:4px}
.tarea{width:100%;min-height:150px;max-height:320px;padding:11px;border-radius:9px;
       border:1px solid var(--rule);background:var(--paper);color:var(--ink);
       font:inherit;font-size:12.5px;line-height:1.65;resize:vertical}
.pick{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:12px}
.pick button{flex:1;min-width:200px;text-align:left;padding:11px 13px;border-radius:10px;
             border:1px solid var(--rule);background:var(--card);color:var(--ink);
             font:inherit;cursor:pointer}
.pick button:hover{border-color:var(--brand-ink)}
.pick button[aria-pressed=true]{border-color:var(--brand-ink);background:var(--brand-soft)}
.pick b{display:block;font-size:13px;margin-bottom:3px}
.pick span{font-size:11.5px;color:var(--muted)}
.card-t{border:1px solid var(--rule);border-radius:11px;padding:13px 14px;margin-bottom:10px}
.card-t.no{border-color:var(--warn);background:var(--warn-soft)}
.card-t.yes{border-color:var(--ok)}
.card-t h4{margin:0 0 3px;font-size:13.5px}
.card-t .meta{font-size:11.5px;color:var(--muted);font-family:var(--mono);
              word-break:break-all;margin-bottom:8px}
.card-t ul{margin:7px 0 0;padding-left:19px;font-size:12px;color:var(--warn)}
.card-t .row{display:flex;gap:8px;align-items:center;margin-top:9px;flex-wrap:wrap}
.qnote{font-size:11.5px;color:var(--muted);margin-top:3px;line-height:1.5}
/* ตัวอย่างสไลด์ในหน้ารีวิว — ให้เห็นว่าอะไรจะขึ้นสไลด์จริงก่อนกดดาวน์โหลด */
.dpv{margin:6px 0 0;padding-left:18px;font-size:12.5px;color:var(--ink-2);line-height:1.6}
.dpv li{margin-bottom:2px}
.dpv2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:6px}
.dpv2 b{font-size:12px;color:var(--brand-ink)}
.dpv-f{margin-top:7px;padding:11px 13px;border-radius:9px;background:var(--sunk);
       font-size:15px;text-align:center;color:var(--ink)}
.dpv-c{margin:7px 0 0;padding:10px 12px;border-radius:9px;background:var(--sunk);
       font-family:var(--mono);font-size:11.5px;line-height:1.55;color:var(--ink);
       white-space:pre-wrap;overflow-x:auto;max-height:230px}
/* โจทย์เขียนโค้ด — ช่องเขียนต้องเป็นฟอนต์ความกว้างเท่ากัน ไม่งั้นย่อหน้าไม่ตรง
   ซึ่งในไพทอนคือความผิดพลาดจริง ไม่ใช่แค่เรื่องความสวย */
.codearea{width:100%;min-height:190px;padding:12px 13px;border-radius:10px;
          border:1px solid var(--rule);background:var(--sunk);color:var(--ink);
          font-family:var(--mono);font-size:13.5px;line-height:1.65;resize:vertical;
          tab-size:4;white-space:pre;overflow-wrap:normal;overflow-x:auto}
.codearea:focus{outline:2px solid var(--accent);outline-offset:1px}
.codepanel{margin-top:9px}
.coderow{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.codeout{margin:8px 0 0;padding:10px 12px;border-radius:9px;background:var(--sunk-2);
         font-family:var(--mono);font-size:12.5px;line-height:1.6;color:var(--ink);
         white-space:pre-wrap;overflow-x:auto;max-height:220px}
.codeout.bad{color:var(--bad);background:var(--bad-soft)}
/* รูปประกอบโจทย์ — วาดจากพิกัดที่ engine คิดมาให้ (app/static/figure.js)
   สีอ้างตัวแปรธีม รูปจึงสลับโหมดสว่าง/มืดตามแอปโดยไม่ต้องวาดใหม่ */
.figwrap{margin:12px 0 14px;padding:10px 8px 6px;border-radius:11px;
         background:var(--card);border:1px solid var(--rule)}
.fig{display:block;width:100%;max-width:430px;margin:0 auto;height:auto}
.figcap{margin-top:4px;font-size:11.5px;color:var(--muted);text-align:center;line-height:1.5}
.fg-grid{stroke:var(--rule-2);stroke-width:1}
.fg-axis{stroke:var(--muted);stroke-width:1.3}
.fg-tick{font-size:9.5px;fill:var(--muted)}
.fg-note{font-size:10px;fill:var(--muted)}
.fg-label{font-size:10.5px;font-weight:600}
.fg-curve{fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.fg-vline{stroke:var(--muted);stroke-width:1}
.fg-shade{fill:var(--brand-soft);stroke:none}
.fg-dot{stroke-width:2}
.fg-arrow{stroke-width:2.2;stroke-linecap:round}
.dash,.fg-curve.dash,.fg-arrow.dash,.fg-vline.dash{stroke-dasharray:5 4}
.fg-ground,.fg-beam{stroke:var(--ink);stroke-width:2;fill:none}
.fg-hatch{stroke:var(--muted);stroke-width:1.1;fill:none}
.fg-box{fill:var(--sunk);stroke:var(--ink);stroke-width:1.6}
.fg-boxtext{font-size:11px;font-weight:600;fill:var(--ink)}
.fg-wedge{fill:var(--sunk);stroke:var(--ink);stroke-width:1.6}
.fg-rope{stroke:var(--ink);stroke-width:1.4}
.fg-spring{fill:none;stroke:var(--accent);stroke-width:1.8;stroke-linejoin:round}
.fg-path{fill:none;stroke:var(--muted);stroke-width:1.3;stroke-dasharray:5 4}
.fg-ball{fill:var(--brand-ink);stroke:none}
.fg-water{fill:var(--accent-soft);stroke:none}
/* ตัวอย่างผังงาน — วาดด้วย CSS ให้เห็นรูปทรงจริง ไม่ใช่แค่รายการข้อความ
   ผู้สอนต้องเห็นว่ากล่องไหนเป็นกล่องตัดสินใจก่อนกดดาวน์โหลด */
.dflow{display:flex;flex-wrap:wrap;align-items:stretch;gap:5px;margin-top:8px}
.dflow-n{flex:1 1 108px;min-width:92px;max-width:190px;padding:9px 8px;border-radius:8px;
         background:var(--card);border:1px solid var(--rule);font-size:11.5px;
         line-height:1.4;color:var(--ink);text-align:center;display:flex;
         align-items:center;justify-content:center}
.dflow-n.term{background:var(--brand-ink);border-color:var(--brand-ink);
              color:var(--on-brand);font-weight:600}
.dflow-n.dec{background:var(--accent-soft);border-color:var(--accent);
             border-radius:4px;transform:skewX(-9deg)}
.dflow-n.dec span{display:block;transform:skewX(9deg)}
.dflow-a{flex:0 0 auto;align-self:center;color:var(--accent);font-size:14px}
.dflow-no{margin-top:6px;padding:7px 9px;border-radius:8px;background:var(--sunk);
          border:1px dashed var(--rule);font-size:11.5px;color:var(--ink-2)}
.dflow-no b{color:var(--accent);font-weight:600}
/* ตัวเลือกของชุดโจทย์ — แถวเดียวบนจอกว้าง ตกบรรทัดเองบนมือถือ */
.sheetopt{display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin:14px 0 4px;
          font-size:13px;color:var(--ink-2)}
.sheetopt label{display:flex;align-items:center;gap:7px}
.sheetopt select{font:inherit;font-size:13px;padding:7px 9px;border-radius:8px;
                 border:1px solid var(--rule);background:var(--card);color:var(--ink)}
.sheetopt input{accent-color:var(--brand-ink);width:16px;height:16px}
/* เลือกรูปแบบสไลด์ — ต้องเห็นว่าต่างกันยังไงตั้งแต่ยังไม่กดสร้าง
   จึงวาดตัวอย่างหน้าปกย่อไว้ในปุ่ม ไม่ใช่มีแต่ชื่อให้เดาเอง */
.themepick{display:flex;gap:10px;flex-wrap:wrap;width:100%}
.themepick button{flex:1 1 190px;display:flex;flex-direction:column;gap:8px;text-align:left;
                  font:inherit;padding:10px;border-radius:var(--r);cursor:pointer;
                  border:1px solid var(--rule);background:var(--card);color:var(--ink)}
.themepick button:hover{border-color:var(--brand-ink)}
.themepick button[aria-pressed="true"]{border-color:var(--brand-ink);
                  box-shadow:inset 0 0 0 1px var(--brand-ink);background:var(--brand-soft)}
.themepick b{font-size:13.5px}
.themepick .qnote{font-size:11.5px;line-height:1.45}
.themepick .themebrand{color:var(--ink);font-weight:500;margin:-2px 0 3px}
.themepick svg{width:100%;height:auto;display:block;border-radius:6px;border:1px solid var(--rule-2)}
.aitag{display:inline-block;margin-left:8px;padding:1px 8px;border-radius:999px;font-size:11px;
       font-weight:500;background:var(--warn-soft);color:var(--warn);vertical-align:middle}
/* หน้าตรวจเนื้อหาเสริม — แก้ได้ในที่ ไม่ต้องเปิดหน้าต่างใหม่ */
.en-card .en-title{width:100%;font:inherit;font-weight:600;font-size:14px;padding:7px 9px;
                   border:1px solid var(--rule);border-radius:8px;background:var(--card);
                   color:var(--ink);margin:6px 0}
.en-card .en-body{width:100%;font:inherit;font-size:13px;line-height:1.6;padding:8px 10px;
                  border:1px solid var(--rule);border-radius:8px;background:var(--card);
                  color:var(--ink);resize:vertical;min-height:120px}
.en-formulas{display:flex;flex-direction:column;gap:6px;margin:8px 0;padding:8px 10px;
             background:var(--sunk);border-radius:8px;overflow-x:auto}
.en-f{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.en-tex{font-size:15px;color:var(--ink)}
.en-meta{font-size:12.5px;color:var(--ink-2);line-height:1.6;margin:6px 0}
.en-meta b{color:var(--ink);margin-right:4px}
/* เครื่องส่วนกลาง — ตัวเลือกความเป็นส่วนตัวที่ต้องเห็นก่อนเริ่มงานทุกงานในแผง */
.sharedpc{display:flex;gap:9px;align-items:flex-start;margin:10px 0 2px;padding:9px 11px;
          border:1px solid var(--rule);border-radius:9px;background:var(--sunk);font-size:12.5px;
          line-height:1.5;cursor:pointer}
.sharedpc input{margin-top:3px;accent-color:var(--brand-ink);flex:none}
.sharedpc .qnote{display:block;margin-top:3px}
/* ชุดรูปแบบที่ผู้สอนเอามาเอง — เลือกสีจากพาเลตต์ของไฟล์ตัวเองได้โดยตรง */
.bk-wrap{width:100%;margin-top:10px;border-top:1px solid var(--rule);padding-top:9px}
.bk-wrap summary{cursor:pointer;font-size:12.5px;color:var(--ink-2)}
.bk-wrap summary:hover{color:var(--ink)}
#bk-host{margin-top:9px;display:flex;flex-direction:column;gap:9px}
.bk-pick{display:flex;align-items:center;gap:8px}
.bk-pick button{font:inherit;font-size:12.5px;padding:7px 12px;border-radius:8px;
                border:1px solid var(--rule);background:var(--card);color:var(--ink);
                cursor:pointer}
.bk-pick button:hover{border-color:var(--brand-ink)}
/* ต้องกำหนดความสูงเองด้วย ไม่ใช่แค่ความกว้าง — .sheetopt input บังคับ 16x16 ไว้
   สำหรับ checkbox ถ้าเขียนแต่ width ช่องกรอกจะเตี้ยเหลือ 16px จนพิมพ์ไม่เห็นตัวอักษร */
.bk-head input[type=text]{width:100%;max-width:260px;height:auto;font:inherit;
                          font-size:13px;padding:7px 9px;border-radius:8px;
                          border:1px solid var(--rule);background:var(--card);color:var(--ink)}
.bk-wrap .bk-head label{display:flex;flex-direction:column;gap:5px;font-size:12.5px;
                        align-items:flex-start}
.bk-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
        padding:7px 0;border-bottom:1px solid var(--rule)}
/* ต้องเจาะจงกว่า .sheetopt label ซึ่งตั้ง align-items:center ไว้ให้ checkbox
   ไม่งั้นป้ายกับคำอธิบายจะถูกจัดกึ่งกลางคอลัมน์ อ่านแล้วเหมือนชิดขวาผิด ๆ */
.bk-row label.bk-lab{display:flex;flex-direction:column;gap:2px;min-width:118px;
                     font-size:12.5px;text-align:left;align-items:flex-start}
.bk-row input[type=color]{width:38px;height:28px;padding:0;border:1px solid var(--rule);
                          border-radius:6px;background:none;cursor:pointer}
.bk-chips{display:flex;gap:5px;flex-wrap:wrap}
.bk-chip{width:22px;height:22px;border-radius:5px;cursor:pointer;padding:0;
         border:1px solid var(--rule-2)}
.bk-chip:hover{outline:2px solid var(--brand-ink);outline-offset:1px}
.bk-fix{background:var(--sunk);border-radius:8px;padding:9px 11px;font-size:12px}
.bk-fix ul{margin:6px 0 0;padding-left:18px;line-height:1.6}
.bk-fix code{font-family:var(--mono);font-size:11.5px}
.bk-warn{background:var(--warn-soft);border:1px solid var(--rule);
         border-radius:8px;padding:9px 11px;font-size:12.5px;color:var(--ink)}
.bk-act{display:flex;gap:8px}
.bk-saved{display:flex;flex-direction:column;gap:6px;font-size:12.5px}
.bk-item{display:flex;align-items:center;gap:9px}
.bk-dots{display:inline-flex;gap:3px}
.bk-dots i{width:13px;height:13px;border-radius:4px;border:1px solid var(--rule-2)}
/* ตารางเทียบสีของสไลด์เดิม — ต้องเห็นสีจริงทั้งสองฝั่ง ไม่ใช่แค่รหัสตัวอักษร */
.ctrow{display:flex;align-items:center;gap:9px;padding:7px 0;border-bottom:1px solid var(--rule);
       flex-wrap:wrap}
.ctrow:last-of-type{border-bottom:0}
.ctrow code{font-family:var(--mono);font-size:12px;color:var(--ink-2);min-width:66px}
.csw{width:26px;height:26px;border-radius:7px;border:1px solid var(--rule);flex:none}
.csw.off{background-image:linear-gradient(45deg,var(--rule) 25%,transparent 25%,transparent 75%,
         var(--rule) 75%);background-size:9px 9px}
.ccount{font-size:11.5px;color:var(--muted);min-width:56px}
.carrow{color:var(--muted)}
.ctsel{width:auto;min-width:130px;margin:0;flex:1}
@media(max-width:520px){
  .ctrow{gap:7px}
  .ctsel{flex:1 1 100%}
}
/* คลังรูปประกอบ — ภาพย่อเรียงแถวเดียว เลื่อนดูได้ */
.figrow{display:flex;gap:8px;overflow-x:auto;padding:4px 2px 8px;margin-top:8px}
.figthumb{flex:none;width:92px;padding:5px;border:1px solid var(--rule);border-radius:9px;
          background:var(--card);cursor:pointer;display:flex;flex-direction:column;gap:4px}
.figthumb:hover{border-color:var(--brand-ink)}
.figthumb.on{border-color:var(--brand-ink);background:var(--brand-soft)}
.figthumb img{width:100%;height:54px;object-fit:contain;background:#fff;border-radius:5px}
.figthumb span{font-size:10.5px;color:var(--muted);text-align:center}
.figthumb.big{width:128px}
.figthumb.big img{height:76px}
.figadd{flex:none;width:92px;border:1px dashed var(--rule);border-radius:9px;background:none;
        color:var(--muted);cursor:pointer;display:flex;flex-direction:column;align-items:center;
        justify-content:center;gap:3px;font-size:18px}
.figadd span{font-size:11px}
.figadd:hover{border-color:var(--brand-ink);color:var(--brand-ink)}
.figgrid{display:flex;gap:9px;flex-wrap:wrap;max-height:46vh;overflow-y:auto;margin-bottom:12px}
.figbig{max-width:100%;max-height:60vh;object-fit:contain;background:#fff;border-radius:8px}
/* รูปที่เลือกใส่สไลด์แล้ว โชว์บนการ์ดให้เห็นว่าจะได้อะไร */
.figon{display:flex;align-items:center;gap:9px;margin-top:8px;padding:7px 9px;
       border:1px solid var(--rule);border-radius:9px;background:var(--sunk)}
.figon img{width:74px;height:44px;object-fit:contain;background:#fff;border-radius:5px;flex:none}
.figon span{font-size:11.5px;color:var(--muted)}
/* ตัวเลือกตราสัญลักษณ์ — ต้องเห็นตราจริง ไม่ใช่อ่านแต่ชื่อ */
.logopick{display:flex;gap:10px;flex-wrap:wrap;margin:10px 0 4px}
.logoopt{flex:1;min-width:190px;display:flex;align-items:center;gap:10px;
         padding:10px 12px;border:1px solid var(--rule);border-radius:10px;cursor:pointer}
.logoopt:has(input:checked){border-color:var(--brand-ink);background:var(--brand-soft)}
.logoopt input{accent-color:var(--brand-ink);width:16px;height:16px;flex:none}
.logoopt img{height:26px;width:auto;max-width:96px;object-fit:contain;flex:none;
             background:#fff;border-radius:4px;padding:2px}
.logoopt span{font-size:12.5px;color:var(--ink-2);line-height:1.35}
#rt-out{text-align:left;line-height:1.65}
@media(max-width:520px){
  .dpv2{grid-template-columns:1fr}
}
.ttab .acts{white-space:nowrap;display:flex;gap:10px}
.ttab .reset{background:transparent;border:0;color:var(--brand-ink);font:inherit;
             font-size:11.5px;cursor:pointer;padding:0}
.ttab .reset:hover{text-decoration:underline}
.ttab .acc{background:transparent;border:0;color:var(--brand-ink);font:inherit;
           font-size:11.5px;cursor:pointer;padding:0}
.ttab .acc:hover{text-decoration:underline}
/* ตัวเลือกสิทธิ์ — แถวละบรรทัด กดโดนง่ายบนมือถือ */
.acc-roles{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0 4px}
.acc-list{display:flex;flex-direction:column;gap:2px;margin:10px 0 4px}
.acc-list.off{opacity:.45}
.acc-opt{display:flex;align-items:center;gap:9px;padding:9px 11px;cursor:pointer;
         border:1px solid var(--rule);border-radius:9px;font-size:13.5px}
.acc-opt:has(input:checked){border-color:var(--brand-ink);background:var(--brand-soft)}
.acc-opt:has(input:disabled){cursor:default;opacity:.6}
.acc-opt input{accent-color:var(--brand-ink);width:16px;height:16px;flex:none}
.acc-sel{width:100%;margin:10px 0 4px;padding:11px 12px;border-radius:9px;
         border:1px solid var(--rule);background:var(--card);color:var(--ink);
         font:inherit;font-size:13.5px}
.acc-sel:focus{outline:2px solid var(--brand-ink);outline-offset:1px}
.acc-sel[hidden]{display:none}
/* ภาคเรียนกับหมู่เรียนอยู่คู่กันเสมอ วางข้างกันบนจอกว้าง */
.fld-pair{display:flex;gap:10px;flex-wrap:wrap}
.fld-pair > *{flex:1;min-width:150px}
.fld-pair .acc-sel{margin:10px 0 4px}
/* รหัสชั่วคราวต้องอ่านออกทีละตัว ตัว l กับ 1 ต้องแยกกันได้ */
.tempbox{display:flex;flex-direction:column;gap:9px;margin:14px 0;padding:14px;
         border:1px solid var(--rule);border-radius:10px;background:var(--sunk)}
.tempbox div{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.tempbox span{font-size:12px;color:var(--muted);min-width:110px}
.tempbox b{font-family:var(--mono);font-size:17px;letter-spacing:.06em;
           color:var(--ink);user-select:all}
.tag{font-size:11px;padding:2px 8px;border-radius:99px;border:1px solid var(--rule);
     color:var(--muted);white-space:nowrap}
.tag.yes{color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
.tag.no{color:var(--warn);border-color:var(--warn);background:var(--warn-soft)}
.tag.wait{color:var(--brand-ink);border-color:var(--brand-ink);background:var(--brand-soft)}
.pbar{display:block;height:6px;border-radius:99px;background:var(--sunk);
      overflow:hidden;min-width:90px}
.pbar i{display:block;height:100%;background:var(--brand)}
.modal-top{display:flex;align-items:center;gap:12px;padding:14px 16px;
           border-bottom:1px solid var(--rule)}
.modal-top b{font-size:15.5px}
.modal-top .btn{margin-left:auto}
.modal-body{overflow-y:auto;padding:16px}
.gsec{margin-bottom:18px}
.gsec:last-child{margin-bottom:0}
.gsec h3{font-size:13px;color:var(--ink);margin:0 0 9px;text-transform:none}
.gsec ol,.gsec ul{list-style:none;margin:0;padding:0}
.gsec li{display:flex;gap:11px;margin-bottom:11px}
.gsec li b{font-size:13.5px;display:block}
.gsec li p{margin:2px 0 0;color:var(--muted);font-size:12.5px;line-height:1.75}
.gnum{width:21px;height:21px;flex:none;border-radius:50%;background:var(--brand);color:var(--on-brand);
      display:flex;align-items:center;justify-content:center;font-size:11.5px;font-weight:700;
      margin-top:2px}
.gdot{width:6px;height:6px;flex:none;border-radius:50%;background:var(--brand);margin-top:8px}
.gwarn{background:var(--brand-soft);border:1px solid var(--rule);border-radius:10px;
       padding:12px 14px;margin-bottom:18px}
.gwarn b{color:var(--ink);font-size:13px}
.gwarn p{margin:4px 0 0;font-size:12.5px;color:var(--ink-2);line-height:1.75}
.menubtn{display:none;align-items:center;gap:7px;padding:6px 12px;border-radius:99px;
         border:1px solid var(--rule);background:var(--sunk);color:var(--ink-2);font-size:12.5px}
.menubtn:hover{color:var(--ink)}
.closebtn{display:none;width:100%;margin-bottom:10px;padding:9px;border-radius:9px;
          border:1px solid var(--rule);background:var(--card);color:var(--ink-2);font-size:13px}
@media(prefers-reduced-motion:reduce){
  aside,.scrim{transition:none}
}
.panel{
  background:var(--card); border:1px solid var(--rule); border-color:var(--rule-2); border-radius:var(--r);
  box-shadow:var(--shadow);
}
.panel-h{
  display:flex; align-items:center; gap:8px; padding:14px 16px 10px; border-bottom:0; font-size:12px;
  font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--muted);
}
.panel-h .n{color:var(--muted);font-weight:400;margin-left:auto;font-family:var(--mono);font-size:11.5px}
/* ── ค้นหา ──────────────────────────────────────────── */
.searchbar{display:flex;gap:8px;border-bottom:0;padding:4px 12px 12px}
.searchbar input{
  flex:1; min-width:0; padding:10px 13px; border:1px solid var(--rule); color:var(--ink); font-size:14px;
  background:var(--sunk); border-color:transparent; border-radius:var(--r-sm);
}
.searchbar input:focus{
  outline-offset:1px; background:var(--card); border-color:var(--brand-ink); outline:none;
  box-shadow:var(--ring);
}
.results{padding:8px;display:flex;flex-direction:column;gap:6px}
.res{
  border:1px solid var(--rule-2);border-radius:9px;padding:11px 13px;background:var(--paper);
  cursor:pointer;text-align:left;width:100%;color:inherit;
}
.res:hover{border-color:var(--brand-ink);background:var(--brand-soft)}
.res .k{font-size:10.5px;font-family:var(--mono);letter-spacing:.05em;text-transform:uppercase;
        color:var(--brand-ink);margin-bottom:3px;display:flex;gap:8px}
.res .k .from{color:var(--muted);margin-left:auto;text-transform:none;letter-spacing:0}
.res .t{font-size:13.5px;line-height:1.5}
.res .m{margin-top:7px;overflow-x:auto}
/* ── รายการ pack และหัวข้อ ──────────────────────────── */
.packs,.topics{padding:7px}
.pack{
  width:100%; display:block; background:transparent; color:inherit; text-align:left; transition:.12s;
  padding:11px 12px; border-radius:var(--r-sm); border:1px solid transparent;
}
.pack:hover{background:var(--sunk)}
.pack-t{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;line-height:1.4}
.pack-m{color:var(--muted);font-family:var(--mono);font-size:11.5px;margin-top:3px}
.pack .dl{
  margin-left:auto; border-radius:6px; flex:none; cursor:pointer; border:0; padding:2px 0; background:none;
  font-family:var(--sans); font-size:11.5px; color:var(--muted); text-decoration:underline;
  text-decoration-color:var(--rule); text-underline-offset:3px;
}
.pack .dl:hover{background:var(--brand);color:var(--on-brand);border-color:var(--brand-ink)}
/* ปุ่มลบต้องไม่หน้าตาเหมือนปุ่มอัปเดต เพราะกดผิดแล้วเสียของที่โหลดมา */
.pack .dl.rm{color:var(--muted);margin-left:6px}
.pack .dl.rm:hover{border-color:var(--bad);background:none;color:var(--bad)}
.pack .state{margin-left:auto;font-size:11px;color:var(--muted);font-family:var(--mono);flex:none}
.pack.stale .state{color:var(--warn)}
.pack.locked .pack-t{color:var(--muted)}
.pack.stale{border-color:var(--warn)}
/* เรื่องที่ยังไม่ได้เก็บลงเครื่องแต่เปิดอ่านจากเน็ตได้ — ไม่ควรดูเหมือนถูกล็อก */
.pack.live .dl{color:var(--muted);border-color:var(--rule)}
.pack.live .dl:hover{color:var(--on-brand);background:var(--brand);border-color:var(--brand-ink)}
.streamnote{
  display:flex; align-items:center; gap:10px; color:var(--ink-2); margin:12px 14px 0; border-radius:var(--r-sm);
  border:0; background:var(--sunk); font-size:12.5px; padding:9px 12px;
}
.streamnote[hidden]{display:none}
.notex{margin-left:auto;flex:none;background:transparent;border:0;color:var(--muted);
       font:inherit;font-size:14px;line-height:1;cursor:pointer;padding:2px 4px}
.notex:hover{color:var(--ink)}
.pack.stale .tick{color:var(--warn)}
.pack.offline{opacity:.55}
.pack.offline .dl{border-style:dashed}
.pack .tick{color:var(--ok);font-size:12px}
.srcbadge{
  font-size:11px; font-family:var(--mono); color:var(--muted); border:1px solid var(--rule); border-radius:99px;
  padding:2px 8px; border-color:var(--rule-2);
}
.topics{display:flex;flex-direction:column;gap:2px;padding:4px 8px 8px}
.topic{
  width:100%; text-align:left; background:transparent; border:0; color:var(--ink-2); display:flex;
  align-items:center; gap:8px; border-radius:var(--r-sm); padding:10px 12px; font-size:14px;
}
.topic:hover{background:var(--sunk);color:var(--ink)}
.topic[aria-current="true"]{
  color:var(--on-brand); font-weight:600; background:var(--brand);
  box-shadow:0 2px 8px -3px color-mix(in srgb, var(--brand) 70%, transparent);
}
.topic .cnt{margin-left:auto;font-family:var(--mono);font-size:11px;opacity:.7;flex:none}
.topic .prog{width:5px;height:5px;border-radius:50%;background:var(--ok);flex:none}
/* ── แท็บ ───────────────────────────────────────────── */
.stack{display:flex;flex-direction:column;gap:14px}
.tabs{display:flex;gap:4px;padding:12px 14px;border-bottom:1px solid var(--rule-2)}
/* ── ชีตหน้าเดียว ──
   กระดาษ A4 ขนาดจริงบนจอ (ย่อเมื่อจอแคบ) เนื้อหาไหลเป็น 3 คอลัมน์ ขนาดตัวอักษรเป็น --s1
   ซึ่ง fitSheet() ลดลงทีละขั้นจนพอดีหน้า — ทุกระยะในนี้ผูกกับ em จะได้ย่อตามกัน */
.seg{display:inline-flex;border:1px solid var(--rule);border-radius:99px;overflow:hidden}
.seg button{font:inherit;font-size:12.5px;padding:5px 12px;border:0;background:transparent;
            color:var(--ink-2);cursor:pointer}
.seg button[aria-pressed="true"]{background:var(--brand);color:#fff}
.s1-wrap{overflow:hidden;margin-top:6px}
.s1-page{--s1:8.5pt;width:194mm;height:278mm;box-sizing:border-box;padding:0;
         print-color-adjust:exact;-webkit-print-color-adjust:exact;
         background:#fff;color:#111;font-size:var(--s1);line-height:1.32;overflow:hidden;
         transform-origin:top left;border:1px solid var(--rule);box-shadow:var(--shadow)}
.s1-cols{columns:3;column-gap:4mm;column-fill:auto;overflow:hidden;height:250mm}
.s1-page.s1-over{height:auto}
.s1-page.s1-over .s1-cols{height:auto !important;column-fill:balance}
.s1-head{display:block;border-bottom:1.5px solid #8c1c34;
         padding-bottom:.3em;margin-bottom:.6em;line-height:1.3;overflow:hidden}
.s1-head b{font-size:1.35em}
.s1-head span{float:right;font-size:.85em;color:#555;text-align:right;max-width:70%;margin-top:.3em}
.s1-g{break-inside:avoid-column}
.s1-g h3{margin:.55em 0 .3em;font-size:.82em;font-weight:700;letter-spacing:.08em;
         text-transform:uppercase;color:#8c1c34;border-bottom:1px solid #ddd;padding-bottom:.15em}
.s1-t{break-inside:avoid;margin:0 0 .55em;padding:0 0 .3em;border-bottom:1px dotted #e3e3e3}
.s1-t h4{margin:0 0 .15em;font-size:1em;font-weight:700;line-height:1.25}
.s1-fs{display:flex;flex-wrap:wrap;gap:.15em .9em;margin:.1em 0 .15em;overflow:hidden}
/* สูตรที่กว้างกว่าคอลัมน์ถูกย่อด้วย transform ใน fitSheet() — กล่องยังกว้างเท่าเดิม
   แต่ .s1-fs ตัดส่วนเกินทิ้ง ภาพที่ย่อแล้วจึงจบพอดีขอบคอลัมน์ ไม่ทับคอลัมน์ข้าง ๆ */
.s1-f{font-size:1em;white-space:nowrap;display:inline-block;transform-origin:left center}
.s1-f .katex{font-size:1.02em}
.s1-code{margin:.15em 0;padding:.25em .45em;background:#f4f2f2;border-radius:3px;
         font-family:var(--mono);font-size:.86em;line-height:1.35;white-space:pre-wrap;
         overflow:hidden}
.s1-w{margin:0;font-size:.86em;line-height:1.3;color:#5a4d08;background:#fbf8dd;
      padding:.15em .4em;border-radius:3px}
.s1-w::before{content:"พลาดบ่อย ";font-weight:700;color:#6a5c0c}
.s1-note{margin:10px 0 0;font-size:12.5px;color:var(--warn)}
@media print{
  /* โหมดชีต: พิมพ์แค่กระดาษ A4 ไม่มีหัว ไม่มีปุ่ม ไม่ย่อ
     กล่องกระดาษสูง 278mm บนพื้นที่พิมพ์ 281mm — เผื่อ 3mm ไว้ ไม่งั้น padding ของหน้าเว็บ
     ที่เหลือรอดมาแค่พิกเซลเดียวก็ทำให้เบราว์เซอร์เปิดแผ่นที่สองที่ว่างเปล่า (เจอจริงตอนพิมพ์) */
  .cram--sheet .cram-head, .cram--sheet .s1-note{display:none !important}
  .cram--sheet, .cram--sheet .s1-wrap{margin:0 !important;padding:0 !important}
  .cram--sheet .s1-wrap{overflow:hidden;height:278mm !important}
  .cram--sheet .s1-page{transform:none !important;border:0;box-shadow:none;margin:0}
  /* ไม่พอแผ่นเดียวที่ขนาดอ่านออก (s1-over) ต้องได้แผ่นสองจริง ๆ ไม่ใช่ถูกตัดทิ้งที่ 278mm
     เจอตอนพิมพ์วิชาไพทอน: ได้แผ่นเดียวสวย ๆ แต่หัวข้อท้าย ๆ หายไปเงียบ ๆ */
  .cram--sheet .s1-page.s1-over{height:auto !important}
  .cram--sheet .s1-wrap:has(.s1-over){height:auto !important;overflow:visible}
  html, body, main{margin:0 !important;padding:0 !important}
  @page{size:A4 portrait;margin:8mm}
}
/* พิมพ์แล้วต้องได้ชีตล้วน ไม่มีเมนู ไม่มีสารบัญ และเป็นสีเข้มบนขาวเสมอ */
@media print{
  body{background:#fff}
  header, .tabs, aside, .streamnote{display:none !important}
  main, .body{overflow:visible !important;height:auto !important}
}
/* ── โจทย์ ──────────────────────────────────────────── */
.meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:14px}
.chip{
  font-size:11.5px; border-radius:99px; background:var(--brand-soft); color:var(--brand-ink); border:0;
  padding:4px 11px; font-weight:500;
}
.chip.grey{background:var(--sunk);color:var(--muted)}
.seed{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--muted)}
.problem[hidden]{display:none}
.answer{display:flex;flex-wrap:wrap;margin-top:0;gap:8px}
.answer input{flex:1;min-width:200px;font-family:var(--mono);font-size:15px;padding:11px 14px;
              border-radius:9px;border:1px solid var(--rule);background:var(--card);color:var(--ink)}
.answer input:focus{outline:2px solid var(--brand-ink);outline-offset:1px;border-color:var(--brand-ink)}
/* โจทย์ที่เป็นข้อความ (ฟิสิกส์และวิชาอื่นที่ไม่ใช่นิพจน์เปล่า) */
.backorg{background:transparent;border:0;color:var(--brand-ink);font:inherit;font-size:13px;
         cursor:pointer;padding:0;margin-bottom:10px}
.backorg:hover{text-decoration:underline}
.joinorg{margin-top:26px;padding:16px 18px;border:1px dashed var(--rule);border-radius:12px}
.joinorg-h{font-weight:600;font-size:14px;margin-bottom:3px}
.joinorg p{margin:0 0 11px;font-size:12.5px;color:var(--muted)}
.orgcard{
  width:100%; text-align:left; border:1px solid var(--rule); background:var(--card); color:var(--ink);
  cursor:pointer; box-shadow:var(--shadow); border-radius:var(--r); border-color:var(--rule-2);
  padding:22px 22px 18px; transition:box-shadow .18s, transform .18s;
}
.orgcard:hover{transform:translateY(-3px);box-shadow:var(--shadow-lift);border-color:var(--rule)}
.orgcard .o-top{display:flex;align-items:center;gap:13px}
.orgcard .o-ic{
  font-size:24px; width:46px; height:46px; display:grid; place-items:center; background:var(--brand-soft);
  border-radius:13px;
}
.orgcard b{display:block;font-size:16px}
.orgcard .o-sub{font-size:12px;color:var(--muted);font-family:var(--mono)}
.orgcard .o-note{margin-top:11px;font-size:12.5px;color:var(--ink-2)}
.orgcard .o-foot{margin-top:12px;display:flex;gap:14px;align-items:center;
                 font-size:12.5px;color:var(--muted)}
.orgcard .o-foot .go{margin-left:auto;color:var(--brand-ink);font-weight:600}
.themebtn{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;
          border-radius:99px;border:1px solid var(--rule);background:var(--card);
          color:var(--ink-2);font:inherit;font-size:12px;cursor:pointer}
.themebtn:hover{border-color:var(--brand-ink);color:var(--brand-ink)}
.themebtn span:first-child{font-size:14px;line-height:1}
@media(max-width:700px){
  .themebtn .lbl{display:none}
}
/* โค้ดต้องอ่านทีละบรรทัดและเว้นวรรคตรงตามจริง จึงใช้ pre กับฟอนต์ความกว้างเท่ากัน */
.codebox{font-family:var(--mono);font-size:13.5px;line-height:1.7;margin:0 0 12px;
         padding:14px 16px;border-radius:10px;background:var(--sunk);
         border:1px solid var(--rule);color:var(--ink);overflow-x:auto;
         white-space:pre;tab-size:4}
/* ช่องตอบของวิชาเขียนโปรแกรม ต้องพิมพ์หลายบรรทัดได้ */
.ansarea{width:100%;min-height:76px;padding:11px 13px;border-radius:9px;
         border:1px solid var(--rule);background:var(--paper);color:var(--ink);
         font-family:var(--mono);font-size:14px;line-height:1.65;resize:vertical}
.ansarea:focus{outline:2px solid var(--brand-ink);outline-offset:1px;border-color:var(--brand-ink)}
.unit-tip{font-size:12px;color:var(--muted);margin-top:6px}
.unit-tip b{color:var(--ink-2);font-family:var(--mono)}
.hint-syntax{color:var(--muted);font-family:var(--mono);font-size:11.5px;margin-top:9px;line-height:1.6}
/* แป้นสัญลักษณ์ — บนแท็บเล็ตที่ใช้แป้นไทย พิมพ์ ^ กับ √ ไม่ได้ง่าย ๆ */
.keypad{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.keypad button{
  font-family:var(--mono); font-size:14px; min-width:38px; padding:8px 10px; color:var(--ink); line-height:1;
  border-radius:9px; border:1px solid var(--rule-2); background:var(--sunk);
  transition:background .12s, border-color .12s;
}
.keypad button:active{background:var(--brand-soft)}
.keypad .wide{min-width:52px}
/* แป้นตัวเลขต้องเรียงเป็นตารางเหมือนเครื่องคิดเลข ไม่ใช่ไหลตามความกว้าง */
.keypad.num{display:grid;grid-template-columns:repeat(4,minmax(38px,56px));justify-content:start}
.keypad.num button{min-width:0;width:100%}
@media(max-width:960px){
  .keypad button{flex:1;min-height:42px;font-size:15px}
}
.btn{
  border:1px solid var(--brand); background:var(--brand); color:var(--on-brand); font-size:14px;
  white-space:nowrap; border-radius:var(--r-sm); padding:11px 18px; font-weight:600; letter-spacing:.005em;
  box-shadow:0 1px 0 rgba(255,255,255,.12) inset, 0 1px 2px rgba(29,21,23,.12);
  transition:background .15s, box-shadow .15s, transform .08s;
}
.btn:hover{background:var(--brand-2);border-color:var(--brand-2)}
.btn.ghost{box-shadow:none;border-color:var(--rule);color:var(--ink-2);background:var(--card)}
.btn.ghost:hover{border-color:var(--brand-ink);color:var(--brand-ink);background:var(--brand-soft)}
.btn.tiny{padding:5px 11px;font-size:12px;font-weight:500;margin-top:9px;border-radius:8px}
.btn:disabled{opacity:.4;cursor:not-allowed}
.hintbar{
  display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-top:16px; padding-top:14px;
  border-top:1px solid var(--rule-2);
}
/* ── ขนาดที่นิ้วกดถูก ────────────────────────────────
   วัดบนของจริงแล้วมีปุ่ม 24 จุดที่เล็กกว่า 40px เช่นปุ่มสลับธีม 38x28
   และเมนู "เปลี่ยนรหัสผ่าน" สูงแค่ 22px — เกณฑ์ของ Apple คือ 44x44
   ขยายเฉพาะเครื่องที่ใช้นิ้ว ส่วนเมาส์ยังได้ความหนาแน่นเท่าเดิม
   ใช้วิธียืดพื้นที่กดด้วย padding ไม่ใช่ขยายตัวหนังสือ หน้าตาจึงไม่เปลี่ยน */
@media (pointer:coarse){
  header{padding:6px 16px;gap:6px}
  .me{gap:2px}
  .me button, .themebtn, .helpbtn, .backorg, .btn.tiny, .menubtn, .tab, .logo,
  .reportlink, .dangerlink, .gate-alt a, .rp-done, .notex,
  .ttab .del, .ttab .reset, .ttab .acc{
    min-height:44px;display:inline-flex;align-items:center;justify-content:center;
  }
  .me button{padding:0 10px}
  .menubtn{padding:0 14px}
  .tab{padding:0 16px}
  .themebtn{min-width:44px}
  .notex{min-width:44px}
  .backorg, .reportlink, .dangerlink, .gate-alt a{padding:0 6px}
  .btn.tiny{padding:0 14px;margin-top:0}
  .sheetbar, .tbar{gap:8px;align-items:center}
  /* หัวข้อในสารบัญด้านซ้ายกดบ่อยที่สุด ต้องกดง่ายที่สุด */
  .topic, .pack{min-height:48px}
  .keypad button{min-height:46px;min-width:46px}
  /* เป้ากดอย่างน้อย 24×24 (WCAG 2.2 · 2.5.8) — วัดด้วย tools/test_a11y.mjs บนมือถือที่เปิดจอสัมผัส
     ปุ่มจัดการบัญชีคำสั้น ("ลบ") กว้างแค่ 16px · ปุ่มเก็บไว้ใช้ออฟไลน์สูง 20px · หัวข้อใส่รหัสสถาบันสูง 23px */
  .ttab .del, .ttab .reset, .ttab .acc{min-width:44px;padding:0 8px}
  .pack .dl{min-height:30px;display:inline-flex;align-items:center;padding:0 6px}
  .joinorg-h{min-height:44px;display:flex;align-items:center}
}
.hintbar .lab{font-size:12px;color:var(--muted);margin-left:auto;font-family:var(--mono)}
/* ── โหมดทดสอบ ──────────────────────────────────────── */
.quizbar{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.qprog{font-weight:600;font-size:14px}
.qtime{font-family:var(--mono);font-size:14px;color:var(--ink-2);
       font-variant-numeric:tabular-nums;margin-left:auto}
.qdots{display:flex;gap:5px;margin-top:14px;flex-wrap:wrap}
.qdots i{border-radius:99px;background:var(--rule);display:block;height:6px;width:24px}
.qdots i.ok{background:var(--ok)}
.qdots i.no{background:var(--bad)}
.qdots i.now{background:var(--brand)}
.qsum{margin-top:18px;border:1px solid var(--rule);overflow:hidden;border-color:var(--rule-2);border-radius:var(--r)}
.qsum-top{padding:20px;text-align:center;background:var(--sunk)}
.qsum-top .big{line-height:1.1;font-family:var(--sans);font-weight:600;font-size:44px;letter-spacing:-.02em}
.qsum-top .big.good{color:var(--ok)}
.qsum-top .big.mid{color:var(--warn)}
.qsum-top .big.low{color:var(--bad)}
.qsum-top .meta{color:var(--muted);font-size:13px;margin-top:6px}
.qsum-list{padding:14px 16px}
.qsum-list h4{margin:0 0 10px;font-size:13.5px}
.qrow{display:grid;grid-template-columns:26px minmax(0,1fr);gap:10px;padding:11px 0;
      border-top:1px solid var(--rule-2);align-items:start}
.qrow:first-of-type{border-top:0}
.qrow .mk{font-size:15px;line-height:1.4}
.qrow .mk.ok{color:var(--ok)}
.qrow .mk.no{color:var(--bad)}
.qrow .yours{font-family:var(--mono);font-size:12.5px;color:var(--muted);margin-top:5px}
.qsum-act{display:flex;gap:9px;padding:0 16px 16px;flex-wrap:wrap}
/* ── ผลตรวจ ─────────────────────────────────────────── */
.verdict{
  display:flex; margin-top:12px; border:0; border-radius:var(--r-sm); padding:12px 14px; gap:12px;
  align-items:center;
}
.verdict .mark{
  line-height:1.35; flex:none; width:30px; height:30px; border-radius:50%; display:grid; place-items:center;
  font-size:15px; font-weight:700; background:currentColor; color:inherit;
}
.verdict.ok{background:var(--ok-soft);border-color:var(--ok);color:var(--ok)}
.verdict.warn{background:var(--warn-soft);border-color:var(--warn);color:var(--warn)}
.verdict.bad{background:var(--bad-soft);border-color:var(--bad);color:var(--bad)}
.verdict small{color:var(--ink-2);display:block;margin-top:3px;font-size:13px;line-height:1.6}
/* ── คำใบ้ ──────────────────────────────────────────── */
.hints{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.hint{
  border-left:3px solid var(--brand-ink); animation:in .18s ease-out; border:1px solid var(--rule-2);
  border-radius:var(--r-sm); background:var(--card); padding:13px 15px;
}
@keyframes in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .hint{animation:none}
}
.hint .lv{
  font-weight:600; text-transform:uppercase; color:var(--brand-ink); margin-bottom:4px; display:flex; gap:8px;
  align-items:center; font-size:11px; letter-spacing:.06em;
}
.hint .src{color:var(--muted);font-weight:400;letter-spacing:0;text-transform:none;
           font-family:var(--mono);font-size:10px;margin-left:auto}
.hint .math{margin-top:9px;overflow-x:auto}
.hint .htext{white-space:pre-line}
.ph-topics{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:14px}
/* ใบ้จากคำตอบล่าสุด — สีเตือน ให้ต่างจากคำใบ้สามขั้นปกติ ผู้เรียนรู้ว่านี่พูดถึงคำตอบของตัวเอง */
.hint.targeted{
  border-left-color:var(--warn); background:var(--warn-soft);
  border-color:color-mix(in srgb, var(--warn) 40%, transparent);
}
.hint.targeted .lv{color:var(--warn)}
/* เฉลย — กล่องแยกจากคำใบ้ สีเขียวของ "คำตอบที่ถูก" ไม่ใช่สีแบรนด์ของคำใบ้ */
.solution{
  margin-top:16px; border:1px solid var(--ok); background:var(--card); padding:14px 16px;
  border-radius:var(--r-sm); border-color:color-mix(in srgb, var(--ok) 55%, transparent);
}
.solution[hidden]{display:none}
.sol-h{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.sol-h b{font-size:15px;color:var(--ok)}
.sol-h span{font-size:12px;color:var(--muted)}
.sol-ans{margin-top:12px;padding:10px 13px;border-radius:9px;background:var(--ok-soft);
         display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.sol-ans > span{font-size:12px;font-weight:600;color:var(--ok)}
.sol-ans .math{overflow-x:auto;min-width:0;max-width:100%}
.sol-ans .fx-code{margin:0;min-width:0;max-width:100%}
.sol-note{margin:10px 0 0;font-size:12.5px;color:var(--ink-2);line-height:1.7}
.solution > .btn{margin-top:10px}
.steps{list-style:none;margin:10px 0 0;padding:0;counter-reset:s}
.steps li{
  counter-increment:s; display:grid; grid-template-columns:24px minmax(0,1fr); gap:11px; padding:10px 0;
  border-top:1px solid var(--rule-2); align-items:start; border-top-color:var(--rule-2);
}
.steps li > div{min-width:0}
.steps li .katex-display{margin:0;text-align:left;overflow-x:auto;overflow-y:hidden;padding-bottom:2px}
.steps li::before{
  content:counter(s); font-family:var(--mono); font-size:11.5px; border-radius:6px; width:23px; height:23px;
  display:grid; place-items:center; background:var(--brand-soft); color:var(--brand-ink); font-weight:600;
}
.steps .why{color:var(--ink-2);font-size:12.5px;margin-top:5px;white-space:pre-wrap}
.rephrase{margin-top:10px;padding:11px 13px;border-radius:8px;background:var(--sunk);
          border:1px solid var(--rule-2);font-size:14px}
.rephrase .who{font-size:10.5px;color:var(--muted);font-family:var(--mono);margin-bottom:5px}
.rephrase .body{white-space:pre-line;overflow-wrap:anywhere}
.rephrase.blocked{border-color:var(--warn);background:var(--warn-soft)}
.rephrase.blocked .who{color:var(--warn)}
/* ── บทเรียน — ส่วนที่ใช้ร่วมกับคำใบ้และเฉลย (ส่วนของหน้าอ่านอยู่ใน reader.css) ── */
/* ตัวอย่างที่ไม่ใช่นิพจน์ล้วน: โค้ด (วิชาเขียนโปรแกรม) */
.fx-code{font-family:var(--mono);font-size:12.5px;line-height:1.55;margin:6px 0;padding:10px 12px;
  border-radius:8px;background:var(--sunk);color:var(--ink);white-space:pre;overflow-x:auto;tab-size:4}
/* สองตัวนี้ต้องเขียนคู่กับ .fx-code — กฎ border-color ของ .fx-code ท้ายไฟล์ทับสีขอบซ้ายไปหมด */
.fx-code.fx-out{border-left:3px solid var(--ok)}
/* โค้ดตัวอย่างที่ตั้งใจให้คอมไพล์ไม่ผ่าน (```ts-error ในบทเรียน) */
.fx-code.fx-err{border-left:3px solid var(--bad)}
.fx-err::before{content:"คอมไพล์ไม่ผ่าน";display:block;margin-bottom:4px;font:600 11px/1.4 var(--sans);color:var(--bad)}
.prose{margin-top:9px;font-size:15px;line-height:1.8;color:var(--ink-2);max-width:72ch}
.prose p{margin:0 0 11px}
.prose p:last-child{margin-bottom:0}
.prose b{color:var(--ink);font-weight:600}
.prose ul{margin:0 0 10px;padding-left:0;list-style:none}
.prose li{position:relative;margin-bottom:7px;padding-left:17px}
.prose li::before{
  content:""; position:absolute; left:3px; width:4px; height:4px; border-radius:50%; background:var(--brand);
  top:11px;
}
.prose .numline{display:grid;grid-template-columns:20px minmax(0,1fr);gap:8px;align-items:start}
.prose .num{font-family:var(--mono);font-size:11.5px;color:var(--brand-ink);
            background:var(--brand-soft);border-radius:5px;text-align:center;line-height:19px}
.srcref{font-family:var(--mono);color:var(--muted);margin-left:auto;flex:none;font-size:11px}
.empty{color:var(--muted);text-align:center;padding:48px 20px;font-size:14px;line-height:1.9}
.empty b{display:block;color:var(--ink-2);font-size:15px;margin-bottom:4px}
.empty .btn{margin-top:14px}
.spin{display:inline-block;width:13px;height:13px;border:2px solid var(--rule);
      border-top-color:var(--brand-ink);border-radius:50%;animation:sp .7s linear infinite;
      vertical-align:-2px;margin-right:6px}
@keyframes sp{to{transform:rotate(360deg)}}
/* ── ความคืบหน้า ────────────────────────────────────── */
.sheetbar{
  display:flex; gap:7px; align-items:center; border-top:1px solid var(--rule-2); flex-wrap:wrap;
  font-size:12.5px; color:var(--ink-2); border-top-color:var(--rule-2); padding:12px 14px;
}
.sheetbar .rvnote{font-size:11px;color:var(--muted);flex:1;min-width:0}
.weak{margin-top:4px;color:var(--warn);font-size:11.5px}
.sheetbar select{font:inherit;font-size:12.5px;padding:5px 8px;border-radius:7px;
                 border:1px solid var(--rule);background:var(--paper);color:var(--ink)}
.sheetbar .btn{margin-top:0}
.score{
  display:flex; border-top:1px solid var(--rule-2); font-size:12.5px; color:var(--ink-2); flex-wrap:wrap; gap:0;
  padding:14px 8px 12px; border-top-color:var(--rule-2);
}
.score b{font-family:var(--mono);color:var(--ink)}
/* ── จอแคบ ──────────────────────────────────────────
   ต้องอยู่ท้ายสุดของ CSS: กฎในมีเดียคิวรีมี specificity เท่ากับกฎปกติ
   ถ้าวางไว้ก่อน กฎปกติที่มาทีหลังจะทับ เช่น .answer input ที่เคยกว้างไม่เต็มแถว */
@media(max-width:960px){
  /* minmax(0,1fr) ไม่ใช่ 1fr — 1fr มีขั้นต่ำเป็น min-content ของคอลัมน์ ซึ่งคือความกว้างสูตร KaTeX
     ที่ตัดบรรทัดไม่ได้ (เช่น m = 18 kg, g = 9.8 m/s², h = 7 m ≈ 400px) บนจอ 375px ทั้งหน้าเลยกว้างเกินจอ
     โจทย์ฟิสิกส์ทุกข้อบนมือถือถูกตัดขอบขวาโดยไม่มีใครเห็น error — พอเป็น 0 กล่องสูตรจะเลื่อนข้างในเอง */
  .wrap{grid-template-columns:minmax(0,1fr);padding:12px;gap:12px}
  /* เนื้อหาหลักต้องมาก่อน ไม่งั้นต้องเลื่อนผ่าน sidebar 1,300px กว่าจะถึงโจทย์ */
  main{order:1}
  aside{
    order:2; position:fixed; inset:0 0 0 auto; width:min(88vw,340px); z-index:40; background:var(--paper);
    border-left:1px solid var(--rule); padding:12px; overflow-y:auto; transform:translateX(100%);
    transition:transform .22s ease; box-shadow:-18px 0 40px -30px #000;
  }
  /* sidebar กลายเป็นลิ้นชัก เปิดจากปุ่มบนหัว */
  aside[data-open="true"]{transform:none}
  .scrim{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:39;
         opacity:0;pointer-events:none;transition:opacity .2s}
  .scrim[data-open="true"]{opacity:1;pointer-events:auto}
  .menubtn{display:inline-flex}
  .course{display:none}
  .closebtn{display:block}
  .body{padding:16px 14px 20px}
  .problem{padding:26px 14px;font-size:20px}
  .answer input{min-width:0;flex:1 1 100%}
  .answer .btn{flex:1}
}
/* ── หน้าจอใหญ่พอ (แท็บเล็ตขึ้นไป) ────────────────────
   วัดบน iPad แนวตั้งแล้วพบว่าโจทย์สูงแค่ 119px แต่ท้ายหน้าว่าง 362px
   คือหัวใจของแอปเล็กนิดเดียว ส่วนพื้นที่ที่เหลือไม่ได้ใช้ทำอะไร
   จอที่สูงพอจึงขยายตัวโจทย์ให้เต็มที่ แล้วดันคำตอบกับแป้นตัวเลขลงไปอยู่ล่าง
   ให้นิ้วโป้งเอื้อมถึงตอนถือแท็บเล็ตสองมือ */
@media (min-width:700px) and (min-height:820px){
  /* ต้องเขียน :not(.hidden) เพราะ id มีน้ำหนักมากกว่า .hidden
     ถ้าไม่กัน หน้าฝึกทำโจทย์จะโผล่ทับแท็บอื่นตลอดเวลา */
  #practice:not(.hidden){flex-direction:column;display:block;min-height:0}
  /* #work ต้องยืดเต็มก่อน ลูกข้างในถึงจะจัดพื้นที่กันเองได้
     ไม่งั้น margin/flex ของ .problem จะทำงานอยู่ในกล่องเล็ก ๆ เท่าเนื้อหา */
  #work:not(.hidden){flex:1;display:flex;flex-direction:column}
  /* ให้กล่องโจทย์กินพื้นที่ที่เหลือ แล้ววางสูตรไว้กลางกล่อง
     สูตรจึงใหญ่และอยู่ระดับสายตา ส่วนคำตอบกับแป้นตัวเลขไปอยู่ล่างพอดี */
  .problem{flex:1;min-height:150px;max-height:42vh;display:flex;align-items:center;
           justify-content:center;padding:34px 26px;font-size:30px}
  .probtext{font-size:16.5px}
  .answer{padding-top:18px}
  .answer input{font-size:17px;padding:14px 16px}
  .keypad button{font-size:16px}
  .hintbar{padding-bottom:4px}
}
/* จอกว้างมาก (iPad แนวนอนและคอมพิวเตอร์) ให้สูตรใหญ่ขึ้นอีกขั้น */
@media (min-width:1000px){
  .problem{font-size:30px;padding:52px 30px}
}

/* ═══ ชุดดีไซน์ปรับปรุง (เดิม refresh.css — ลำดับนี้มาหลังแอปหลัก จึงชนะเมื่อแรงเท่ากัน) ═══ */
/* ─────────────────────────────────────────────────────────────────
   ชุดดีไซน์ใหม่ — "สมุดแบบฝึกหัดที่สงบ"
   ─────────────────────────────────────────────────────────────────
   ไฟล์นี้โหลดหลัง <style> หลักใน index.html จึงทับได้โดยไม่ต้องแก้กฎเดิมทีละบรรทัด
   ถอดลิงก์ในหน้าเว็บออกบรรทัดเดียว = กลับเป็นหน้าตาเดิมทั้งหมด

   หลักที่ใช้ตัดสินทุกบรรทัดในไฟล์นี้
   1. ช่องตอบต้องอยู่ในจอเสมอ — เดิมบนโน้ตบุ๊ก 1280×820 ช่องตอบอยู่ที่ y=827 (ใต้ขอบจอทุกข้อ)
      และผลตรวจอยู่ที่ y=1148 จอกว้างจึงวางโจทย์กับโต๊ะทำงานข้างกัน
   2. เส้นกรอบน้อยลง ใช้พื้นสีแทน — เดิมมีกล่องซ้อนกล่องซ้อนกล่อง ตาต้องไล่ข้ามเส้นตลอดเวลา
   3. ลายกระดาษกราฟอยู่เฉพาะที่ที่มีการคิดเลขจริง (กล่องค่าที่โจทย์ให้) ไม่ใช่ทั้งหน้า
   4. ตัวหนังสือบทเรียนใหญ่ขึ้นและบรรทัดสั้นลง — เดิม 13–13.5px บรรทัดยาวเต็มกล่อง
   5. สีแบรนด์ยังเป็นแดงเลือดหมูเดิม ไม่เปลี่ยนตัวตนของแอป แค่ใช้ให้น้อยลงและตรงจุดขึ้น
   ───────────────────────────────────────────────────────────────── */
/* ── ตัวแปรสี ──────────────────────────────────────────────────
   ต้องประกาศครบทั้งสามสถานะ: ไม่ได้เลือก (ตามเครื่อง) · เลือกสว่าง · เลือกมืด
   กฎ :root ของไฟล์นี้มาทีหลัง จึงทับ :root เดิม แต่บล็อก media ของเดิมที่ตั้งสีมืดไว้
   มี specificity สูงกว่า (:root:not(...)) — ต้องเขียนซ้ำด้วย selector เดียวกันจึงจะทับได้ */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#131012; --card:#1c1719; --sunk:#241e20; --sunk-2:#2e2629; --ink:#f2ebe9; --ink-2:#cbbebb;
    --muted:#a09290; --rule:#342b2d; --rule-2:#282123; --brand:#b5304f; --brand-2:#c93f60; --brand-soft:#2d171d;
    --brand-ink:#ee8a9d; --on-brand:#fff; --ok:#6fcb98; --ok-soft:#12251c; --warn:#dccf5a; --warn-soft:#272310;
    --bad:#f39472; --bad-soft:#2d1812; --accent:#9296ec; --accent-soft:#1c1d3a; --grid:rgba(238,138,157,.06);
    --shadow:0 1px 2px rgba(0,0,0,.45), 0 14px 32px -20px rgba(0,0,0,.9);
    --shadow-lift:0 2px 4px rgba(0,0,0,.5), 0 22px 44px -20px #000; --hue-indigo:#a3aaf2; --hue-teal:#62c5ce;
    --hue-amber:#e3b45a; --hue-green:#85c898; --hue-orange:#f19d72;
  }
}
:root[data-theme="dark"]{
  --paper:#131012; --card:#1c1719; --sunk:#241e20; --sunk-2:#2e2629; --ink:#f2ebe9; --ink-2:#cbbebb;
  --muted:#a09290; --rule:#342b2d; --rule-2:#282123; --brand:#b5304f; --brand-2:#c93f60; --brand-soft:#2d171d;
  --brand-ink:#ee8a9d; --on-brand:#fff; --ok:#6fcb98; --ok-soft:#12251c; --warn:#dccf5a; --warn-soft:#272310;
  --bad:#f39472; --bad-soft:#2d1812; --accent:#9296ec; --accent-soft:#1c1d3a; --grid:rgba(238,138,157,.06);
  --shadow:0 1px 2px rgba(0,0,0,.45), 0 14px 32px -20px rgba(0,0,0,.9);
  --shadow-lift:0 2px 4px rgba(0,0,0,.5), 0 22px 44px -20px #000; --hue-indigo:#a3aaf2; --hue-teal:#62c5ce;
  --hue-amber:#e3b45a; --hue-green:#85c898; --hue-orange:#f19d72;
}
/* ── พื้นฐาน ─────────────────────────────────────────────────── */
/* ลายกระดาษกราฟทั้งหน้าแย่งสายตากับเนื้อหา ย้ายไปอยู่ในกล่องโจทย์ที่เดียว */
body{background-image:none;font-size:15px;line-height:1.65;text-rendering:optimizeLegibility}
::selection{background:color-mix(in srgb, var(--brand) 22%, transparent)}
/* วงโฟกัสใช้ outline ไม่ใช่ box-shadow — ปุ่มทุกชนิดตั้ง box-shadow ของตัวเอง (.btn, .btn.ghost …)
   ซึ่งมาทีหลังแล้วทับวงโฟกัสจนกด Tab แล้วมองไม่เห็นว่าอยู่ปุ่มไหน (เจอที่ปุ่ม "อัปเดตข้อมูล")
   ช่องกรอกยังใช้กรอบสี + วงแหวนของตัวเองตามเดิม */
input:focus-visible, textarea:focus-visible, select:focus-visible{box-shadow:var(--ring)}
h1,h2,h3{text-wrap:balance}
.num, .subj-stats b, .tstat b, .score b, .qtime{font-variant-numeric:tabular-nums}
/* ── ปุ่ม ───────────────────────────────────────────────────── */
.btn:active{transform:translateY(1px)}
/* ── หัวแอป ─────────────────────────────────────────────────── */
/* ติดขอบบนและโปร่งนิดหน่อย เนื้อหาที่เลื่อนผ่านจึงไม่ถูกตัดขาดเป็นแถบทึบ */
header{
  display:flex; align-items:center; flex-wrap:wrap; position:sticky; top:0; z-index:30; padding:10px 22px;
  gap:12px; min-height:60px; background:var(--card);
  background:color-mix(in srgb, var(--card) 86%, transparent); -webkit-backdrop-filter:saturate(1.4) blur(12px);
  backdrop-filter:saturate(1.4) blur(12px); border-bottom:1px solid var(--rule-2);
}
.helpbtn, .acctbtn, .menubtn{background:var(--card);border-color:var(--rule)}
.helpbtn:hover, .acctbtn:hover, .menubtn:hover{border-color:var(--brand-ink)}
/* ── ไอคอน ── ชุดเดียวทั้งแอป (sprite ต้น <body>) เส้น 1.8 ปลายมน สีตามตัวอักษร */
.svg-sprite{position:absolute;width:0;height:0;overflow:hidden}
.ic{width:1.25em;height:1.25em;flex:none;vertical-align:-.22em;fill:none;stroke:currentColor;
    stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.logo .sig .ic{width:18px;height:18px}
.o-ic .ic{width:26px;height:26px}
/* ── หน้าแรก: เลือกสถาบันและวิชา ───────────────────────────────── */
/* การ์ดวิชาสูงเท่ากันทุกใบ — เดิมชื่อวิชาที่ยาวสองบรรทัดทำให้แถวเดียวกันสูงไม่เท่ากัน */
.subj{
  width:100%; text-align:left; padding:0; border:1px solid var(--rule); background:var(--card); color:inherit;
  overflow:hidden; display:flex; flex-direction:column; border-radius:var(--r); border-color:var(--rule-2);
  box-shadow:var(--shadow); transition:box-shadow .18s, transform .18s, border-color .18s;
  --hue:var(--brand-ink);
}
.subj-top{display:flex;gap:13px;padding:20px 20px 16px;align-items:flex-start;flex:1}
.subj[data-hue="indigo"]{--hue:var(--hue-indigo)}
.subj[data-hue="teal"]{--hue:var(--hue-teal)}
.subj[data-hue="amber"]{--hue:var(--hue-amber)}
.subj[data-hue="green"]{--hue:var(--hue-green)}
.subj[data-hue="orange"]{--hue:var(--hue-orange)}
.subj-ic .ic{width:26px;height:26px}
/* สถานะของผู้เรียนก่อน ข้อมูลของวิชาเป็นบรรทัดรองเล็ก ๆ */
.subj-prog{padding:0 20px 12px}
.sp-line{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:8px}
.sp-line b{font-size:14.5px;font-weight:600}
.sp-line span{font-size:13px;color:var(--muted);white-space:nowrap}
.subj-prog .bar{display:block;max-width:none;height:6px}
.subj-prog .bar i{background:var(--hue)}
.subj-meta{padding:0 20px;font-size:12.5px;color:var(--muted);line-height:1.6}
.subj-foot .go .ic{width:16px;height:16px;margin-left:6px}
.subj-h b{
  letter-spacing:-.01em; font-size:17.5px; line-height:1.35; display:-webkit-box; -webkit-line-clamp:2;
  -webkit-box-orient:vertical; overflow:hidden;
}
.subj-stats b{font-size:18px;font-family:var(--sans);font-weight:600;letter-spacing:-.01em}
.howcard, .joinorg{border-radius:var(--r)}
/* ── โครงหน้าเรียน ───────────────────────────────────────────── */
/* ต้องอยู่ในมีเดียคิวรี — ไฟล์นี้มาทีหลังกฎจอแคบของเดิม ถ้าเขียนลอย ๆ จะทับกฎมือถือ
   แล้วเนื้อหาหลักบนมือถือจะถูกบีบเหลือคอลัมน์ 292px (เจอจริงตอนทำตัวอย่างนี้) */
@media (min-width:961px){
  .wrap{max-width:1320px;grid-template-columns:292px minmax(0,1fr);gap:22px;padding:22px}
}
/* รายการบท — ปุ่ม "เก็บไว้ใช้ออฟไลน์" เดิมเป็นกรอบทุกแถว 21 แถวติดกันจนรกตา
   เปลี่ยนเป็นลิงก์เงียบ ๆ ยังอ่านออกว่าทำอะไร แต่ไม่แย่งความสนใจจากชื่อบท */
.packs{padding:4px 8px 8px}
.pack .dl:hover, .pack.live .dl:hover{background:none;color:var(--brand-ink);
          text-decoration-color:currentColor;border:0}
.pack[aria-current="true"]{
  background:var(--brand-soft); border-color:transparent;
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brand-ink) 35%, transparent);
}
.pack.have{border-color:transparent}
.pack.have .pack-t .tick{color:var(--ok)}
/* แถบคะแนน — เดิมตัดบรรทัดกลางวงเล็บจนเหลือ ")" อยู่บรรทัดเดียว */
.score .sc{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px;white-space:nowrap;
           font-size:11px;color:var(--muted);min-width:0}
.score .sc b{font-family:var(--sans);font-size:19px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.score .weak{flex:1 1 100%;text-align:center;margin-top:8px;padding:0 6px}
/* ── แท็บ: เปลี่ยนจากแฟ้มมีหูเป็นสวิตช์แบบแคปซูล ────────────────────── */
.tab{
  border:0; background:transparent; position:relative; bottom:-1px; border-radius:99px; padding:8px 16px;
  font-size:13.5px; font-weight:500; color:var(--muted);
}
.tab:hover{color:var(--ink);background:var(--sunk)}
.tab[aria-selected="true"]{background:var(--ink);color:var(--paper);box-shadow:none;border:0}
.body{padding:22px 24px 28px}
/* ── หน้าฝึกทำโจทย์ ────────────────────────────────────────────── */
#practice{container-type:inline-size;container-name:practice}
.probtext{font-size:17px;line-height:1.75;color:var(--ink);margin-bottom:14px;max-width:68ch}
/* รูปประกอบเดิมสูง 307px ดันช่องตอบลงใต้จอ — เพดานไว้พอให้อ่านป้ายได้ */
#probfig .figwrap, #qprobfig .figwrap{margin:4px 0 14px;border-radius:var(--r-sm);
      border-color:var(--rule-2);background:var(--card)}
#probfig svg, #qprobfig svg{max-height:230px;width:100%}
/* กล่อง "ค่าที่โจทย์ให้" = กระดาษกราฟ ที่เดียวในแอปที่มีลายนี้ เพราะเป็นที่เดียวที่คิดเลขจริง
   เดิมสูง 207px ตัวอักษร 30px อยู่กลางกล่องใหญ่ ๆ — เล็กลงแต่ยังอ่านชัด */
.problem{
  background:var(--sunk); overflow-x:auto; flex:none; min-height:0; max-height:none; display:block;
  text-align:center; font-size:23px; padding:22px 20px; border-radius:var(--r-sm);
  border:1px solid var(--rule-2); background-color:var(--card);
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),
                          linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:22px 22px; background-position:-1px -1px;
}
.problem .katex-display{margin:0}
/* สองคอลัมน์ของหน้าฝึก — min-width:0 จำเป็น: ลูกของ grid ค่าตั้งต้นคือ min-width:auto
   สูตรยาวที่ตัดบรรทัดไม่ได้จะดันคอลัมน์โจทย์ให้กว้างจนเบียดโต๊ะทำงาน แทนที่จะเลื่อนอยู่ในกล่องตัวเอง */
.pq, .pw{min-width:0}
/* โต๊ะทำงาน: ช่องตอบ ผลตรวจ แป้น และคำใบ้ อยู่เป็นก้อนเดียว */
.answer input, .ansarea{border-radius:var(--r-sm);border:1.5px solid var(--rule);background:var(--card);
         font-size:17px;padding:13px 15px;transition:border-color .15s, box-shadow .15s}
.answer input:focus, .ansarea:focus{outline:none;border-color:var(--brand-ink);box-shadow:var(--ring)}
.answer .btn{padding:12px 18px}
.pw > .answer + #verdict:empty{display:none}
#verdict:empty{margin:0}
/* ไม่ตั้ง min-height ที่นี่ — กฎเดิมของจอสัมผัสตั้งไว้ 46px ให้นิ้วกดถูก ไฟล์นี้มาทีหลังจะทับจนเล็กลง */
.keypad button:hover{color:var(--brand-ink);background:var(--card);border-color:var(--brand-ink)}
.hintbar .btn{padding:9px 14px;font-size:13.5px}
/* ลำดับปุ่ม: "ตรวจคำตอบ" เด่นสุด · หลังตอบถูก "โจทย์ใหม่" ขึ้นมาเป็นปุ่มหลักแทน */
#work.solved #newq{background:var(--brand);color:var(--on-brand);border-color:var(--brand)}
#work.solved #submit{background:var(--card);color:var(--ink-2);border-color:var(--rule);box-shadow:none}
@keyframes vpop{from{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:none}}
.verdict.ok, .verdict.bad, .verdict.warn{animation:vpop .22s ease-out}
@media (prefers-reduced-motion:reduce){
  .verdict.ok, .verdict.bad, .verdict.warn{animation:none}
}
/* ผลตรวจ — อยู่ใต้ช่องตอบทันที ไม่ต้องเลื่อนลงไปหา */
.verdict.ok .mark{background:var(--ok);color:var(--ok-soft)}
.verdict.warn .mark{background:var(--warn);color:var(--warn-soft)}
.verdict.bad .mark{background:var(--bad);color:var(--bad-soft)}
.verdict b{display:block;font-size:14.5px}
/* คำใบ้ — ใช้พื้นสีกับป้ายระดับ แทนแถบสีด้านซ้าย */
.hint .lv::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--brand-ink);flex:none}
.hint.targeted .lv::before{background:var(--warn)}
/* ปุ่มดูเฉลยเบากว่าปุ่มคำใบ้ — อยากให้ลองคำใบ้ก่อน แต่ยังหาเจอเมื่อต้องการ */
.hintbar .solvebtn{color:var(--muted);border-color:var(--rule-2);background:transparent}
.hintbar .solvebtn:hover:not(:disabled){color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
/* จอกว้างพอ: โจทย์ซ้าย โต๊ะทำงานขวา และโต๊ะทำงานเลื่อนตามลงมา
   วัดจากความกว้างของกล่องหน้าฝึกเอง (container query) ไม่ใช่ความกว้างจอ
   เพราะแถบสารบัญด้านซ้ายกินที่ไปแล้ว 292px */
@container practice (min-width:760px){
  #work:not(.hidden){display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,360px);
                     gap:28px;align-items:start}
  .pw{position:sticky;top:78px;padding:18px;border-radius:var(--r);background:var(--sunk);
      border:1px solid var(--rule-2)}
  .pw .answer input{flex:1 1 100%}
  .pw .answer .btn{flex:1}
  .pw .keypad:not(.num){display:grid;grid-template-columns:repeat(auto-fill,minmax(44px,1fr))}
  .pw .keypad.num{grid-template-columns:repeat(4,minmax(0,1fr))}
  /* โต๊ะทำงานเป็นพื้นสีเดียวกับปุ่มแป้น — ต้องยกปุ่มขึ้นเป็นสีการ์ด ไม่งั้นในธีมมืดเห็นเป็นตัวหนังสือลอย ๆ */
  .pw .keypad button{background:var(--card);border-color:var(--rule)}
  .pw .keypad button:hover{border-color:var(--brand-ink)}
  .pw .hintbar .lab{flex:1 1 100%;margin:4px 0 0;text-align:left}
  .pw .hintbar .reportlink{margin-left:auto}
  .problem{font-size:24px;padding:26px 22px}
}
/* จอสูงพอบนแท็บเล็ต — กฎเดิมยืดกล่องโจทย์เต็มจอและดันช่องตอบลงล่าง ยกเลิกเพราะเปลี่ยนโครงแล้ว */
@media (min-width:700px) and (min-height:820px){
  .problem{flex:none;max-height:none}
}
/* ── บทเรียน: ข้อความยาว (ใช้ร่วมกับคำใบ้/เฉลย) — ส่วนของหน้าอ่านทั้งหมดอยู่ใน reader.css ── */
/* บทเรียนเดิม 13–13.5px บรรทัดยาวเต็มกล่อง ~120 ตัวอักษร — ขยายเป็น 15px จำกัด ~72 ตัวอักษร */
.fx-code, .codebox{border-radius:var(--r-sm);border-color:var(--rule-2)}
/* ── โหมดทดสอบ ──────────────────────────────────────────────────── */
/* ── หน้าเข้าสู่ระบบ ────────────────────────────────────────────── */
/* ลายกระดาษกราฟจาง ๆ เป็นพื้นหลังหน้าแรกที่คนเห็น — บอกตั้งแต่ประตูว่านี่คือที่ฝึกคิดเลข */
/* โลโก้เดิมถูกบีบเป็นวงรีแคบ เพราะไม่ได้กันไม่ให้หดในแถว flex */
.gate-head b{display:block;font-size:18px;letter-spacing:-.01em}
.fld input, .fld select{border-radius:var(--r-sm);border:1.5px solid var(--rule);background:var(--card);padding:12px 14px}
.fld input:focus, .fld select:focus{outline:none;border-color:var(--brand-ink);box-shadow:var(--ring)}
/* ── กล่องและเมนู ─────────────────────────────────────────────── */
/* ── พื้นที่ผู้สอน ── ตัวแปรสีใหม่ไหลเข้าไปเอง ปรับแค่ความโค้งกับเส้นให้เข้าชุด */
.td-card, .td-stats > div, .td-toolbar{border-color:var(--rule-2)!important;border-radius:var(--r)!important}
.td-stats > div > b{letter-spacing:-.02em}
.td-nav > button[aria-current="page"]{box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brand-ink) 30%, transparent)}
/* ── จอแคบ (มือถือ) ─────────────────────────────────────────────── */
/* หัวแอปเดิมตกสองแถว กินจอไป ~120px ก่อนจะเห็นอะไรเลย — บีบให้เหลือแถวเดียว */
@media(max-width:640px){
  header{padding:8px 12px;gap:8px;min-height:56px;flex-wrap:nowrap}
  #apptitle{display:none}
  .tier{padding:6px;border:0;background:transparent}
  .tier #tier{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .sync-state:not([data-status="pending"]){display:none}
  .helpbtn{padding:5px}
  .helpbtn .lbl{display:none}
  .menubtn{padding:6px 12px;margin-left:auto}
  .me{margin-left:0}
  .home{padding:30px 16px 64px}
  .home .lead{margin-bottom:24px}
  .wrap{padding:10px;gap:10px}
  .tabs{padding:10px;overflow-x:auto;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tab{white-space:nowrap;flex:none}
  .streamnote{margin:10px 10px 0}
  .body{padding:18px 16px 22px}
  .probtext{font-size:16px}
  .problem{font-size:20px;padding:18px 12px}
  #probfig svg, #qprobfig svg{max-height:190px}
  .answer input{font-size:17px}
  .gate-card{padding:26px 20px 22px}
}
@media (prefers-reduced-motion:reduce){
  .subj, .orgcard, .btn, .keypad button{transition:none}
  .subj:hover, .orgcard:hover{transform:none}
}
/* ── หน้าแนะนำระบบ (ก่อนเข้าสู่ระบบ) ──────────────────────────────
   หน้าแรกต้องสื่อแบรนด์และประโยชน์ทั้งต่อผู้เรียนและผู้สอน ก่อนชวนลองโจทย์จริง
   ลำดับ DOM ตรงกับมือถือ: แบรนด์/คุณค่า → สองกลุ่มผู้ใช้ → ทดลองใช้ → รายละเอียด
   ส่วนอื่นเงียบไว้ ใช้ชิ้นส่วนหน้าจอจริงของแอป (ผลตรวจ คำใบ้ แถบทบทวน) แทนไอคอน
   ทับหน้าเข้าสู่ระบบ (80) แต่ต่ำกว่ากล่องข้อตกลง/วิธีใช้ (90) ซึ่งเปิดจากหน้านี้ได้ */
.welcome{position:fixed;inset:0;z-index:85;overflow-y:auto;overscroll-behavior:contain;
         background-color:var(--paper);color:var(--ink);
         background-image:radial-gradient(ellipse 80% 55% at 78% 0%, color-mix(in srgb, var(--brand) 8%, transparent), transparent 70%)}
.welcome[hidden]{display:none}
html.wl-on, html.wl-on body{overflow:hidden}
/* ชั้นที่อยู่ใต้หน้านี้ (หัวแอป · หน้าเลือกวิชา · หน้าเข้าสู่ระบบ) ถูกปิดทับเต็มจอ — ไม่ต้องวาด
   เดิมแอปบูตเสร็จแล้ววาดข้อความของชั้นเหล่านี้ไว้ข้างหลัง (~2.8 วินาทีบนมือถือ 4G ช้า) Chrome นับเป็น LCP
   เพราะ LCP ไม่ดูว่าโดนทับ ทั้งที่ผู้ใช้เห็นหน้าแนะนำตั้งแต่ 1.2 วินาที (วัดเว็บจริง 2026-09-28)
   กดเข้าสู่ระบบ/ลงทะเบียน → welcome.js hide() ถอด wl-on แล้วทุกชั้นกลับมาเอง
   เพิ่มชั้นใหม่ใต้หน้านี้ต้องใส่ในรายการนี้ด้วย — test_welcome ตรวจว่าไม่มีข้อความข้างใต้ถูกวาด */
html.wl-on body > :is(header, .home, .gate){visibility:hidden}
.welcome > *{max-width:1120px;margin-inline:auto;padding-inline:28px}
.wl-top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-block:22px;border-bottom:1px solid var(--rule-2)}
.wl-brand{display:flex;align-items:center;gap:12px}
.wl-brand b{font-size:23px;letter-spacing:-.04em}
.wl-brand .sig{width:44px;height:44px;display:grid;place-items:center;border-radius:13px;flex:none;
               color:var(--on-brand);font-size:18px;font-weight:700;
               background:linear-gradient(145deg, var(--brand-2), var(--brand))}
.wl-inapp{margin-top:4px;padding:14px 16px;border-radius:var(--r);
          background:var(--warn-soft);border:1px solid color-mix(in srgb, var(--warn) 45%, transparent)}
.wl-inapp[hidden]{display:none}
.wl-notewrap:has(> .wl-inapp[hidden]){display:none}
.wl-inapp b{display:block;font-size:14px;color:var(--ink)}
.wl-inapp p{margin:4px 0 10px;font-size:13px;line-height:1.7;color:var(--ink-2)}
.wl-inapp-act{display:flex;gap:8px;flex-wrap:wrap}
.wl-inapp-act .btn{word-break:break-all}
.wl-hero{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:64px;
         align-items:center;padding-block:60px 64px}
.wl-copy{padding-top:0}
.wl-identity{display:flex;align-items:center;gap:18px;margin-bottom:28px}
.wl-emblem{position:relative;display:grid;place-items:center;flex:none;width:86px;height:86px;
           border-radius:25px;background:linear-gradient(145deg,var(--brand-2),var(--brand));color:var(--on-brand);
           font-size:37px;line-height:1;font-weight:700;letter-spacing:-.055em;
           box-shadow:0 12px 28px -12px color-mix(in srgb,var(--brand) 65%,transparent),inset 0 1px 0 #ffffff30}
.wl-emblem>span{position:absolute;width:21px;height:3px;background:currentColor;opacity:.6;border-radius:9px;bottom:17px;right:18px}
.wl-wordmark{font-size:clamp(48px,5.1vw,65px);line-height:1.15;letter-spacing:-.065em;font-weight:500;white-space:nowrap}
.wl-wordmark strong{font-weight:700;color:var(--brand-ink)}
/* ลูกของ grid ค่าตั้งต้น min-width:auto — สูตรยาวในกล่องโจทย์จะดันคอลัมน์ให้กว้างเกินจอ */
.wl-copy, .wl-demo-wrap{min-width:0}
.wl-eyebrow{margin:0 0 14px;font-size:12.5px;font-weight:600;letter-spacing:.04em;color:var(--brand-ink)}
/* แยกวลีผู้เรียน/ผู้สอนให้ครบความหมายทั้งสองบรรทัด */
.wl-hero h1{margin:0;font-size:clamp(32px,3.6vw,42px);line-height:1.35;font-weight:600;letter-spacing:-.025em}
.wl-hero h1 > span{display:block}
/* ขีดเน้นแบบปากกาเน้นข้อความ — อยู่ครึ่งล่างของบรรทัด ไม่ทับสระบน */
.wl-hero h1 mark{color:inherit;padding:0 .08em;border-radius:3px;
                 background:linear-gradient(transparent 58%, color-mix(in srgb, var(--brand) 22%, transparent) 58%, color-mix(in srgb, var(--brand) 22%, transparent) 92%, transparent 92%)}
.wl-lead{margin:18px 0 0;font-size:16px;line-height:1.85;color:var(--ink-2);max-width:40em;text-wrap:pretty}
.wl-audiences{min-width:0}
.wl-overline{margin:0 0 14px;font-size:12px;letter-spacing:.045em;color:var(--muted)}
.wl-role{padding:24px;border:1px solid var(--rule);border-radius:20px;background:var(--card);box-shadow:var(--shadow)}
.wl-role+.wl-role{margin-top:16px}
.wl-role-teacher{background:linear-gradient(120deg,var(--brand-soft),var(--card));border-color:color-mix(in srgb,var(--brand-ink) 23%,var(--rule))}
.wl-role-head{display:flex;gap:10px;align-items:center;color:var(--brand-ink);font-size:13px;font-weight:600}
.wl-role-icon{display:grid;place-items:center;width:36px;height:36px;background:var(--brand-soft);border-radius:10px}
.wl-role-icon svg{width:23px;height:23px}
.wl-role-number{margin-left:auto;color:var(--muted);font:12px var(--mono)}
.wl-role h2{font-size:20px;line-height:1.55;letter-spacing:-.015em;margin:14px 0 5px;text-wrap:pretty}
.wl-role-head h2{font-size:17px;line-height:1.5;margin:0;color:var(--ink)}
.wl-benefits{list-style:none;padding:0;margin:15px 0 0;display:grid;gap:10px}
.wl-benefits li{display:flex;align-items:baseline;gap:10px;font-size:14px;line-height:1.7;color:var(--ink-2)}
.wl-benefits li::before{content:"";width:5px;height:5px;flex:none;border-radius:50%;background:var(--brand-ink);align-self:start;margin-top:10px}
.wl-role p{font-size:14px;line-height:1.8;color:var(--ink-2);margin:0}
.wl-learning-path{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:18px;font-size:12px;color:var(--ink-2)}
.wl-learning-path span{background:var(--sunk);padding:5px 9px;border-radius:7px}
.wl-learning-path i{font-style:normal;color:var(--muted)}
.wl-audience-note{font-size:11.5px;color:var(--muted);margin:12px 3px 0;line-height:1.7}
.wl-try{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);align-items:center;gap:64px;border-top:1px solid var(--rule)}
.wl-try-copy{min-width:0}
.wl-try-copy>p:not(.wl-eyebrow){font-size:15px;line-height:1.8;color:var(--ink-2);max-width:38ch}
.wl-cta{display:flex;gap:10px;flex-wrap:wrap;margin-top:28px}
.wl-cta .btn{padding:14px 22px;font-size:15.5px}
.wl-fine{margin:12px 0 0;font-size:12.5px;color:var(--muted);line-height:1.7}
/* โจทย์ตัวอย่าง — หน้าตาเดียวกับหน้าฝึกทำโจทย์ในแอป */
.wl-demo{background:var(--card);border:1px solid var(--rule-2);border-radius:18px;
         padding:22px 22px 18px;box-shadow:var(--shadow-lift);animation:wl-up .5s ease-out both}
@keyframes wl-up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.wl-demo-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:14px}
.wl-demo-top b{display:block;font-size:15px}
.wl-demo-top span{display:block;font-size:12px;color:var(--muted)}
.wl-new{background:var(--sunk);border:0;border-radius:99px;padding:7px 13px;font:inherit;
        font-size:12.5px;color:var(--ink-2);cursor:pointer;white-space:nowrap}
.wl-new:hover{background:var(--sunk-2);color:var(--ink)}
.wl-q{margin:0 0 12px;font-size:15.5px;line-height:1.75;color:var(--ink)}
.wl-given{text-align:center;font-size:19px;padding:18px 14px;border-radius:var(--r-sm);
          border:1px solid var(--rule-2);overflow-x:auto;background-color:var(--paper);
          background-image:linear-gradient(var(--grid) 1px,transparent 1px),
                           linear-gradient(90deg,var(--grid) 1px,transparent 1px);
          background-size:22px 22px;background-position:-1px -1px}
.wl-ans{display:flex;gap:8px;margin-top:14px}
.wl-field{position:relative;flex:1;min-width:0}
.wl-field input{width:100%;box-sizing:border-box;padding:13px 40px 13px 15px;font:inherit;font-size:17px;
                font-variant-numeric:tabular-nums;color:var(--ink);background:var(--card);
                border:1.5px solid var(--rule);border-radius:var(--r-sm);transition:border-color .15s, box-shadow .15s}
.wl-field input:focus{outline:none;border-color:var(--brand-ink);box-shadow:var(--ring)}
.wl-unit{position:absolute;right:14px;top:50%;transform:translateY(-50%);color:var(--muted);
         font-family:var(--mono);font-size:14px;pointer-events:none}
.wl-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.wl-ans .btn{flex:none;padding:12px 18px}
.wl-demo .verdict[hidden]{display:none}
.wl-demo .hints:empty{display:none}
.wl-demo .hint{background:var(--paper)}
.wl-helpbar{display:flex;gap:8px;margin-top:14px}
.wl-hintbtn{flex:1;min-width:0;padding:11px;border-radius:var(--r-sm);font:inherit;font-size:13.5px;
            font-weight:600;color:var(--brand-ink);background:transparent;cursor:pointer;
            border:1.5px dashed color-mix(in srgb, var(--brand-ink) 40%, transparent)}
.wl-hintbtn:hover:not(:disabled){background:var(--brand-soft);border-style:solid}
.wl-hintbtn:disabled{color:var(--muted);border-color:var(--rule);cursor:default}
/* เฉลยเป็นปุ่มแยก สีเขียวของ "คำตอบ" ไม่ใช่สีแบรนด์ของคำใบ้ และเบากว่าปุ่มคำใบ้ */
.wl-solve{flex:none;padding:11px 16px;border-radius:var(--r-sm);font:inherit;font-size:13.5px;font-weight:600;
          color:var(--muted);background:transparent;border:1.5px solid var(--rule);cursor:pointer}
.wl-solve:hover:not(:disabled){color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
.wl-solve:disabled{cursor:default;opacity:.6}
.wl-demo .solution{margin-top:14px}
.wl-sec{padding-block:48px}
.wl-sec h2{margin:0 0 26px;font-size:clamp(24px,3vw,32px);line-height:1.3;letter-spacing:-.01em;
                       text-wrap:balance}
/* สามขั้นเริ่มต้น — เป็นลำดับจริง (ต้องลงทะเบียนก่อนใส่รหัสสถาบัน) จึงใส่เลข */
/* พื้นเต็มความกว้างจอด้วยเงา — เงาไม่นับเป็นขนาดกล่อง จึงไม่เกิดแถบเลื่อนแนวนอน */
.wl-band{background:var(--sunk);box-shadow:0 0 0 100vmax var(--sunk);clip-path:inset(0 -100vmax)}
.wl-steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
          gap:28px;counter-reset:st}
.wl-steps li{counter-increment:st;position:relative;padding-top:48px}
.wl-steps li::before{content:counter(st);position:absolute;top:0;left:0;width:34px;height:34px;
                     display:grid;place-items:center;border-radius:50%;font-weight:700;font-size:15px;
                     background:var(--card);color:var(--brand-ink);
                     box-shadow:inset 0 0 0 1.5px color-mix(in srgb, var(--brand-ink) 45%, transparent)}
.wl-steps li:not(:last-child)::after{content:"";position:absolute;top:17px;left:46px;right:-16px;
                     height:1.5px;background:var(--rule)}
.wl-steps b{display:block;font-size:16px;margin-bottom:6px}
.wl-steps p{margin:0;font-size:14px;line-height:1.75;color:var(--ink-2)}
.wl-tip{margin:30px 0 0;padding:13px 16px;border-radius:var(--r-sm);background:var(--card);
        font-size:13.5px;line-height:1.75;color:var(--ink-2);max-width:72ch}
.wl-tip b{color:var(--ink)}
.wl-teach-card{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px 40px;align-items:end;
               padding:28px 30px;border-radius:var(--r);background:var(--card);border:1px solid var(--rule-2)}
.wl-teach h2{margin-bottom:10px}
.wl-teach p{margin:0;font-size:14.5px;line-height:1.8;color:var(--ink-2);max-width:60ch}
.wl-teach .wl-eyebrow{margin-bottom:8px}
.wl-teach-act{text-align:right}
.wl-teach-act .wl-fine{margin-top:8px}
.wl-foot{padding-block:26px 40px;border-top:1px solid var(--rule-2);font-size:12.5px;line-height:1.8;
         color:var(--muted)}
.wl-foot p{margin:0 0 4px}
.wl-foot a{color:var(--brand-ink)}
/* อีเมลติดต่อยาว — ให้ตัดบรรทัดได้บนจอแคบ ไม่ดันหน้าให้กว้างเกินจอ */
.wl-teach a, .wl-fine a, .wl-foot a{color:var(--brand-ink);font-weight:600;overflow-wrap:anywhere}
@media (max-width:980px){
  .wl-hero{grid-template-columns:minmax(0,1fr);gap:36px;padding-block:36px 48px}
  .wl-copy{max-width:620px}
  .wl-audiences{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
  .wl-overline,.wl-audience-note{grid-column:1/-1;margin:0}
  .wl-role+.wl-role{margin:0}
  .wl-try{grid-template-columns:minmax(0,1fr);gap:28px}
  .wl-try-copy>p:not(.wl-eyebrow){max-width:60ch}
  .wl-teach-card{grid-template-columns:minmax(0,1fr)}
  .wl-teach-act{text-align:left}
}
@media (max-width:640px){
  .welcome > *{padding-inline:16px}
  .wl-top{padding-block:12px}
  .wl-brand b{font-size:20px}
  .wl-brand .sig{width:38px;height:38px;font-size:16px;border-radius:11px}
  .wl-top>.btn{min-height:42px;padding:8px 13px}
  .wl-hero{padding-block:28px 36px;gap:30px}
  .wl-identity{gap:14px;margin-bottom:24px}
  .wl-emblem{width:66px;height:66px;border-radius:20px;font-size:30px}
  .wl-emblem>span{bottom:12px;right:13px;width:17px}
  .wl-wordmark{font-size:clamp(43px,12.5vw,58px)}
  .wl-eyebrow{font-size:12px;margin-bottom:10px;letter-spacing:0}
  .wl-hero h1{font-size:clamp(29px,8vw,35px);line-height:1.4}
  .wl-lead{font-size:15px;margin-top:14px;line-height:1.8}
  .wl-audiences{grid-template-columns:minmax(0,1fr);gap:12px}
  .wl-role{padding:19px 20px;border-radius:16px}
  .wl-role h2{font-size:17px}
  .wl-role-head h2{margin:0}
  .wl-benefits{gap:8px;margin-top:12px}
  .wl-benefits li{font-size:13.5px}
  .wl-role p{font-size:13.5px}
  .wl-learning-path{margin-top:13px;gap:6px}
  .wl-learning-path span{font-size:11.5px;padding:4px 7px}
  .wl-cta{margin-top:22px}
  .wl-cta .btn{flex:1 1 100%;justify-content:center}
  /* มือถือมีเข้าสู่ระบบอยู่ที่หัวหน้าแล้ว ไม่ให้ปุ่มซ้ำดันประโยชน์ของทั้งสองบทบาทลงไป */
  .wl-hero .wl-cta [data-go="login"]{display:none}
  .wl-demo{padding:18px 16px 14px;border-radius:16px}
  .wl-given{font-size:16.5px;padding:14px 8px}
  .wl-sec{padding-block:40px}
  .wl-steps{grid-template-columns:minmax(0,1fr);gap:22px}
  .wl-steps li{padding:0 0 0 50px}
  .wl-steps li:not(:last-child)::after{top:42px;bottom:-16px;left:17px;right:auto;width:1.5px;height:auto}
  .wl-teach-card{padding:20px}
  .wl-copy{padding-top:0}
  .wl-teach-act .btn{width:100%;justify-content:center}
}
@media (prefers-reduced-motion:reduce){
  .wl-demo{animation:none}
}

/* ═══ หน้าอ่าน: บทเรียน · สรุปก่อนสอบ (เดิม reader.css) ═══════════════════════════ */
/* หน้าอ่าน — บทเรียนทั้งเล่ม · บทเรียนรายหัวข้อ · หน้าสรุปก่อนสอบ (โค้ดอยู่ที่ reader.js)
   รวมไว้ที่เดียว (2026-09-27) — เดิมกฎของสองหน้านี้กระจายอยู่ใน <style> ของ index.html และ refresh.css
   ที่ทับกันเองหลายชั้น แก้ที่หนึ่งแล้วไม่เห็นผลเพราะอีกที่ชนะอยู่
   ส่วนที่ใช้ร่วมกับหน้าอื่น (.prose .fx-code .steps .srcref) ยังอยู่ที่เดิม

   สี่ชนิดของเนื้อหา — สีเดียวกันทุกที่ ทั้งบทเรียนและหน้าสรุป
     แนวคิด   = แดงเลือดหมู (สีหลัก)
     สูตร     = น้ำเงิน
     ตัวอย่าง = เขียว
     จุดที่พลาดบ่อย = เหลือง (เหมือนปากกาไฮไลต์) */
/* ── หัวบท ─────────────────────────────────────────── */
.readerhead{padding-bottom:20px;margin-bottom:26px;border-bottom:1px solid var(--rule-2)}
.readerhead .rh-eye{margin:0 0 4px;font-size:12.5px;font-weight:600;color:var(--brand-ink);letter-spacing:.02em}
.readerhead h2{margin:0 0 6px;font-size:26px;line-height:1.25;letter-spacing:-.018em;text-wrap:balance}
.readerhead .sub{margin:0 0 14px;color:var(--muted);font-size:14px}
.toc{display:flex;flex-wrap:wrap;gap:6px}
.tocitem{display:flex;align-items:center;gap:8px;padding:7px 13px;border-radius:99px;
         border:1px solid var(--rule-2);background:var(--card);color:var(--ink-2);font-size:13.5px}
.tocitem:hover{border-color:var(--brand-ink);color:var(--brand-ink);background:var(--brand-soft)}
.tocitem .no{font-family:var(--mono);font-size:12px;color:var(--muted)}
.tocitem .q{font-family:var(--mono);font-size:12px;color:var(--muted);border-left:1px solid var(--rule);padding-left:8px}
.rh-resume{margin-top:14px;display:inline-flex;align-items:center;gap:7px}
.rh-resume .ic{width:16px;height:16px}
/* ── แถบบอกตำแหน่ง ──
   ติดใต้แถบบนของแอป (สูง 60px) และไม่กินที่ตอนซ่อน (margin ติดลบเท่าความสูง) หน้าจึงไม่กระตุกตอนมันโผล่ */
.rd-bar{position:sticky;top:60px;z-index:6;height:48px;margin:0 -24px -48px;padding:0 24px;
        display:flex;align-items:center;gap:10px;background:color-mix(in srgb, var(--card) 94%, transparent);
        border-bottom:1px solid var(--rule-2);backdrop-filter:blur(6px);
        visibility:hidden;opacity:0;transform:translateY(-6px);
        transition:opacity .16s ease, transform .16s ease, visibility 0s linear .16s}
.rd-bar.on{visibility:visible;opacity:1;transform:none;transition:opacity .16s ease, transform .16s ease}
.rd-pos{font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums;flex:none}
.rd-jump{flex:1;min-width:0;max-width:420px;font:inherit;font-size:14px;font-weight:600;color:var(--ink);
         padding:6px 10px;border-radius:var(--r-sm);border:1px solid var(--rule-2);background:var(--card)}
.rd-bar .btn{margin:0 0 0 auto;flex:none}
.rd-practice{white-space:nowrap}
@media (prefers-reduced-motion:reduce){
  .rd-bar, .rd-bar.on{transition:none;transform:none}
}
/* ── เรื่องในบท ────────────────────────────────────── */
.topicsec{margin-bottom:40px;scroll-margin-top:118px}
.topicsec.flash{animation:hl 1s ease-out}
@keyframes hl{from{background:var(--brand-soft)}to{background:transparent}}
@media (prefers-reduced-motion:reduce){
  .topicsec.flash{animation:none}
}
.sechead{display:flex;align-items:center;gap:12px;margin-bottom:6px}
.sechead h3{flex:1;min-width:0;margin:0;font-size:19px;letter-spacing:-.01em}
.sechead .secno{display:grid;place-items:center;flex:none;width:28px;height:28px;border-radius:8px;
                background:var(--brand);color:var(--on-brand);font-family:var(--mono);font-size:13px}
.sechead .btn{margin-top:0;flex:none}
/* ── ป้ายชนิดของเนื้อหา ── */
.kind{--k:var(--brand-ink);--k-soft:var(--brand-soft);
      display:flex;align-items:center;gap:9px;margin:26px 0 10px;font-size:14px;font-weight:600;color:var(--ink)}
.kind small{font-size:12.5px;font-weight:400;color:var(--muted)}
.kind::after{content:"";flex:1;height:1px;background:var(--rule-2)}
.kind-ic{display:grid;place-items:center;flex:none;width:26px;height:26px;border-radius:7px;
         background:var(--k-soft);color:var(--k)}
.kind-ic .ic{width:16px;height:16px}
.k-concept{--k:var(--brand-ink);--k-soft:var(--brand-soft)}
.k-formula{--k:var(--accent);--k-soft:var(--accent-soft)}
.k-example{--k:var(--ok);--k-soft:var(--ok-soft)}
.k-watch{--k:var(--warn);--k-soft:var(--warn-soft)}
/* ── กล่องเนื้อหา ── */
.fx{border:1px solid var(--rule-2);border-radius:var(--r-sm);padding:16px 18px;margin-bottom:10px;background:var(--card)}
.fx .nm{display:flex;flex-wrap:wrap;gap:4px 9px;align-items:baseline;margin-bottom:8px;font-weight:600;font-size:14.5px}
/* ที่มา (ชื่อไฟล์ · รหัสแม่แบบ) ยาวได้มาก — ห้ามดันกล่องให้ล้นจอบนมือถือ ให้ขึ้นบรรทัดใหม่แทน */
.fx .nm .srcref{flex:0 1 auto;min-width:0;overflow-wrap:anywhere;font-weight:400}
.fx .note{margin-top:8px;color:var(--ink-2);font-size:13.5px;line-height:1.7}
.fx .note.tip b{color:var(--ok);margin-right:8px}
.fx-text{margin:2px 0 8px;font-size:15px;line-height:1.8;color:var(--ink-2);max-width:72ch}
/* บทเรียนที่ AI เสนอ — ป้ายต้องเห็นก่อนอ่าน ไม่ใช่ซ่อนไว้ท้ายย่อหน้า */
.fx-ai{border-left:3px solid var(--warn);padding-left:15px}
.fx-concept .prose{margin-top:4px}
.fx-example .steps{margin-top:12px}
/* สูตรทั้งหัวข้อในกล่องเดียว คั่นด้วยเส้นบาง ๆ แทนกล่องซ้อนกล่อง */
.fx-formulas{padding:4px 18px}
.fml{padding:14px 0;border-top:1px solid var(--rule-2)}
.fml:first-child{border-top:0}
.fml .katex-display{margin:6px 0 2px;overflow-x:auto;overflow-y:hidden}
.fx-ans{display:flex;align-items:baseline;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--rule-2);font-size:14px}
.fx-ans b{color:var(--ok);flex:none}
.fx-watch{background:var(--warn-soft);border-color:transparent;display:flex;gap:12px;align-items:baseline}
.fx-watch p{margin:0;flex:1;font-size:14.5px;line-height:1.75;color:var(--ink)}
/* ── ปลายบท ── */
.rd-next{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:8px;padding-top:22px;border-top:1px solid var(--rule-2)}
.rd-go{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:10px;text-align:left;
       padding:13px 15px;border-radius:var(--r-sm);border:1px solid var(--rule-2);background:var(--card);color:var(--ink)}
.rd-go small{grid-column:1;font-size:12.5px;color:var(--muted)}
.rd-go span{grid-column:1;font-size:15px;font-weight:600;overflow-wrap:anywhere}
.rd-go .ic{grid-column:2;grid-row:1 / span 2;width:18px;height:18px;color:var(--brand-ink)}
.rd-go.prev{grid-template-columns:auto minmax(0,1fr)}
.rd-go.prev small, .rd-go.prev span{grid-column:2}
.rd-go.prev .ic{grid-column:1;transform:scaleX(-1)}
.rd-go:hover{border-color:var(--brand-ink);background:var(--brand-soft)}
/* ── หน้าสรุปก่อนสอบ ─────────────────────────────────
   ตั้งใจให้อ่านยาวรวดเดียวและพิมพ์ออกมาได้
   การ์ดเรียงคอลัมน์เดียว ป้ายอยู่ซ้าย เนื้ออยู่ขวา ทุกใบลำดับเดียวกัน — เดิมจัดเป็น 2–3 คอลัมน์แบบ columns
   ซึ่งลำดับการอ่านวิ่งลงคอลัมน์ซ้ายก่อน และการ์ดสูงไม่เท่ากันทิ้งช่องว่างเป็นแถบยาว */
.cram-head{padding:4px 2px 16px;max-width:70ch}
.cram-head h2{margin:0 0 4px;font-size:26px;letter-spacing:-.018em;text-wrap:balance}
.cram-head p{margin:0 0 12px;color:var(--muted);font-size:14px}
.cram-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cram-bar .rvnote{font-size:13px}
/* ค้นหา + ไปที่บท — ติดอยู่บนสุดขณะเลื่อน */
.cram-tools{position:sticky;top:60px;z-index:6;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
            margin:0 -24px 22px;padding:12px 24px;border-bottom:1px solid var(--rule-2);
            background:color-mix(in srgb, var(--card) 94%, transparent);backdrop-filter:blur(6px)}
.cram-find{flex:1 1 260px;min-width:0;display:flex;align-items:center;gap:8px;padding:0 12px;border-radius:var(--r-sm);
           background:var(--sunk);color:var(--muted)}
.cram-find:focus-within{outline:2px solid var(--brand-ink);outline-offset:1px}
.cram-find .ic{width:17px;height:17px}
.cram-find input{flex:1;min-width:0;width:0;border:0;background:transparent;font:inherit;font-size:14.5px;color:var(--ink);padding:10px 0}
.cram-find input:focus{outline:none}
#cram-jump{flex:0 1 240px;min-width:0;font:inherit;font-size:14px;padding:9px 10px;border-radius:var(--r-sm);
           border:1px solid var(--rule-2);background:var(--card);color:var(--ink)}
.cram-count{font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
.cram-none{padding:36px 12px;text-align:center;color:var(--muted);font-size:14.5px}
.cram-g{margin-bottom:34px;scroll-margin-top:136px;max-width:860px}
.cram-g h3{display:flex;align-items:baseline;gap:10px;margin:0 0 12px;font-size:17px;letter-spacing:-.005em}
.cram-g h3 span{font-size:12.5px;font-weight:400;color:var(--muted)}
.cram-c{--lb:7.4rem;border:1px solid var(--rule-2);border-radius:var(--r-sm);background:var(--card);
        padding:16px 18px 12px;margin-bottom:12px;break-inside:avoid}
.cram-c h4{margin:0 0 12px;font-size:16px;line-height:1.4}
.cram-fs{display:flex;flex-direction:column;gap:8px;margin:0 0 12px}
.cram-f{background:var(--accent-soft);border-radius:var(--r-sm);padding:11px 14px;overflow-x:auto}
.cram-f .katex-display{margin:0}
.cram-f>span{display:block;margin-top:6px;font-size:13px;color:var(--ink-2)}
/* แถวมีป้ายทางซ้าย — แนวคิด · สัญลักษณ์และหน่วย · ลำดับคิด */
.cram-row, .cram-symbols{display:grid;grid-template-columns:var(--lb) minmax(0,1fr);gap:12px;
                         padding:10px 0;border-top:1px solid var(--rule-2)}
.cram-lb, .cram-symbols h5{margin:0;font-size:12.5px;font-weight:600;color:var(--muted);line-height:1.9}
.cram-idea{margin:0;color:var(--ink);font-size:14.5px;line-height:1.75}
.cram-symbols dl{margin:0}
.cram-symbol{display:grid;grid-template-columns:minmax(3.5rem,max-content) minmax(0,1fr);gap:10px;
             padding:4px 0;font-size:13.5px;line-height:1.6}
.cram-symbol dt{align-self:start;color:var(--accent)}
.cram-symbol dt .katex{font-size:1.05em}
.cram-symbol dd{margin:0;overflow-wrap:anywhere;color:var(--ink-2)}
.cram-symbol small{display:block;color:var(--muted);font-size:12.5px}
.cram-code{margin:0 0 12px;border:1px solid var(--rule-2);border-radius:var(--r-sm);overflow:hidden}
.cram-code>pre{margin:0;padding:11px 13px;background:var(--sunk);font-family:var(--mono);
               font-size:13px;line-height:1.65;overflow-x:auto}
.cram-out{display:flex;gap:11px;align-items:baseline;padding:9px 13px;border-top:1px solid var(--rule-2)}
.cram-out span{font-size:12px;color:var(--muted);letter-spacing:.04em;flex:none}
.cram-out pre{margin:0;font-family:var(--mono);font-size:13px;white-space:pre-wrap;color:var(--ok)}
.cram-note{display:block;padding:0 13px 10px;font-size:13px;color:var(--muted)}
.cram-s{margin:0;padding-left:20px;font-size:14px;line-height:1.7;color:var(--ink-2)}
.cram-s li{margin:1px 0}
.cram-s li::marker{color:var(--accent);font-weight:600}
.cram-w{margin:10px 0 0;padding:10px 13px;border-radius:var(--r-sm);background:var(--warn-soft);
        font-size:14px;line-height:1.7;color:var(--ink)}
.cram-w b{color:var(--warn);margin-right:8px}
.cram-c .reportlink{margin-top:10px}
/* ── จอสัมผัส — ปุ่มสารบัญสูงพอให้นิ้วกดได้ (เกณฑ์ 44px) ── */
@media (pointer:coarse){
  .tocitem{min-height:46px}
  .rd-go, #cram-jump, .rd-jump{min-height:44px}
}
/* ── จอแคบ ── */
@media (max-width:640px){
  /* ขอบในของกล่องเนื้อหาเหลือ 16px และแถบบนของแอปเตี้ยลงเหลือ 56px */
  .rd-bar, .cram-tools{top:56px;margin-left:-16px;margin-right:-16px;padding-left:16px;padding-right:16px}
  .cram-tools{padding-top:10px;padding-bottom:10px;gap:8px}
  .cram-find{flex:1 1 0}
  #cram-jump{flex:0 0 40%}
  .cram-count:empty{display:none}
  .readerhead h2, .cram-head h2{font-size:22px}
  .sechead h3{font-size:17px}
  .rd-pos{display:none}
  .kind{flex-wrap:wrap}
  .kind::after{display:none}
  .rd-next{grid-template-columns:1fr}
  /* ป้ายขึ้นบรรทัดของตัวเองเหนือเนื้อ — จอแคบเกินกว่าจะวางสองคอลัมน์แล้วยังอ่านไทยได้ */
  .cram-row, .cram-symbols{grid-template-columns:minmax(0,1fr);gap:2px}
  .cram-c{padding:14px 14px 10px}
}
@media print{
  .rd-bar, .rd-next, .rh-resume, .cram-tools, .cram-none, .cram-bar{display:none !important}
  .cram-c{border-color:#ccc;box-shadow:none}
  .cram-g, .cram-c{max-width:none}
  .cram-g[hidden], .cram-c[hidden]{display:block !important}
}
/* ปุ่มที่ซ่อนด้วย hidden — .btn ตั้ง display เองจึงชนะ [hidden] ของเบราว์เซอร์ */
.rd-bar .btn[hidden]{display:none}

/* ═══ พิมพ์ใช้สีสว่างเสมอ ════════════════════════════════════════════════════
   ต้องอยู่ท้ายสุดของไฟล์และครอบทั้งสามทางของธีม (ปกติ · เลือกธีมมืดเอง · โหมดมืดตามเครื่อง)
   เดิมอยู่กลางไฟล์ แล้วชุดสีที่มาทีหลังทับ — คนที่ใช้ธีมมืดพิมพ์ชีตสรุป/ชุดโจทย์ออกมาเป็นพื้นดำ (แก้ 2026-09-28) */
@media print{
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]){
    --sans:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
    --mono:"IBM Plex Mono","IBM Plex Sans Thai",ui-monospace,Menlo,monospace; --paper:#fff; --card:#fff;
    --sunk:#f4f2f2; --sunk-2:#eae6e6; --ink:#111; --ink-2:#333; --muted:#666; --rule:#ccc; --rule-2:#e2e2e2;
    --brand:#8c1c34; --brand-2:#a0263f; --brand-soft:#f6e7ea; --brand-ink:#8a1c35; --on-brand:#fff;
    --ok:#1f5233; --ok-soft:#e5f3eb; --warn:#6a5c0c; --warn-soft:#fbf8dd; --bad:#b83e17; --bad-soft:#fcebe3;
    --accent:#2e3192; --accent-soft:#e9eaf7; --grid:rgba(138,28,53,.07); --shadow:none;
    --shadow-lift:0 2px 4px rgba(29,21,23,.05), 0 18px 40px -18px rgba(29,21,23,.28);
    --ring:0 0 0 3px color-mix(in srgb, var(--brand) 26%, transparent); --r:14px; --r-sm:10px;
    --hue-indigo:#3f4aa8; --hue-teal:#0f6a74; --hue-amber:#855400; --hue-green:#2d6a3e; --hue-orange:#9a4217;
  }
}
