/* =============================================================
   Math KU — A-Level Pre-test Registration
   Design system v2 · 2026
   ============================================================= */

/* ---------- 1. Tokens ---------- */
:root {
  color-scheme: light;

  /* Brand — KU leaf green, deepened for print-grade contrast */
  --ku-950:#04170f;  --ku-900:#062a1b;  --ku-800:#0a3f28;
  --ku-700:#0f5a37;  --ku-600:#157a4a;  --ku-500:#1c9a5d;
  --ku-400:#4dbb85;  --ku-300:#8ad6ae;  --ku-200:#c2e9d4;
  --ku-100:#e0f4e9;  --ku-50:#f1faf5;

  /* Accent — muted antique gold, used sparingly */
  --gold-700:#8a6318; --gold-600:#a97c22; --gold-500:#c2952f;
  --gold-200:#f0dfb4; --gold-100:#f8efd8; --gold-50:#fdf9ef;

  /* Ink — very slightly green-cast neutrals so nothing looks grey-on-grey */
  --ink-950:#080d0b; --ink-900:#111815; --ink-800:#1c2622;
  --ink-700:#2e3c36; --ink-600:#465650; --ink-500:#64766e;
  --ink-400:#8a9a93; --ink-300:#b3c0ba; --ink-200:#d7e0db;
  --ink-150:#e5ebe7; --ink-100:#eef2f0; --ink-50:#f6f9f7;

  /* Semantic */
  --ok-fg:#0f5a37;    --ok-bg:#e0f4e9;    --ok-br:#a9dcc1;
  --warn-fg:#8a6318;  --warn-bg:#fdf3dd;  --warn-br:#eed9a4;
  --bad-fg:#9b2c22;   --bad-bg:#fdeceb;   --bad-br:#f2c2bd;
  --info-fg:#1b4f8a;  --info-bg:#e8f1fb;  --info-br:#bcd6f0;

  /* Surfaces */
  --canvas:#f2f6f3;
  --paper:#ffffff;
  --paper-2:#fbfdfc;
  --sunken:#f6f9f7;
  --line:#e5ebe7;
  --line-strong:#d7e0db;

  --fg:#111815;
  --fg-muted:#64766e;
  --fg-subtle:#8a9a93;
  --accent:#0f5a37;
  --accent-hover:#0a3f28;
  --accent-soft:#e0f4e9;
  --focus:rgba(28,154,93,.34);

  /* Radii */
  --r-xs:6px; --r-sm:9px; --r-md:12px; --r-lg:16px; --r-xl:22px; --r-full:999px;

  /* Elevation — one soft ambient + one tight contact shadow */
  --sh-1:0 1px 1px rgba(8,13,11,.04), 0 1px 3px rgba(8,13,11,.05);
  --sh-2:0 2px 4px -2px rgba(8,13,11,.06), 0 8px 20px -8px rgba(8,13,11,.12);
  --sh-3:0 4px 8px -4px rgba(8,13,11,.08), 0 24px 48px -20px rgba(8,13,11,.22);
  --sh-inset:inset 0 1px 0 rgba(255,255,255,.6);

  /* Type */
  /* ★ ทั้งระบบใช้ตระกูลเดียว: IBM Plex Sans Thai
     เดิมใช้ Anuphan สำหรับหัวเรื่องคู่กับ Plex Thai สำหรับเนื้อความ
     แต่สองตัวนี้เป็นฟอนต์ไทยไม่มีหัวที่หน้าตาใกล้กันมาก
     คนอ่านแทบแยกไม่ออกว่าสลับฟอนต์ตรงไหน เว็บจึงจ่ายค่าโหลดสองตระกูล
     แลกกับความต่างที่มองไม่เห็น

     ตระกูลเดียวยังทำให้ทุกหน้าดูมาจากชุดเดียวกันจริง ๆ
     ลำดับความสำคัญสร้างด้วยน้ำหนัก ขนาด และระยะห่างตัวอักษรแทน
     ซึ่งควบคุมได้แม่นกว่าการสลับฟอนต์อยู่แล้ว

     ตัว Plex Thai มีทั้งอักษรไทยและอังกฤษในไฟล์เดียว
     หน้าเว็บนี้ปนสองภาษาตลอด (Math Pre-test A-Level 2570 / Portfolio / PDF)
     การใช้ตระกูลเดียวจึงทำให้ความสูงและน้ำหนักของสองภาษาเข้ากันพอดี  */
  --f-display:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
  --f-body:"IBM Plex Sans Thai",system-ui,-apple-system,sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,monospace;

  --dur:170ms;
  --ease:cubic-bezier(.32,.72,.35,1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --canvas:#0a100d;
    --paper:#121a16;
    --paper-2:#161f1a;
    --sunken:#0e1512;
    --line:#22302a;
    --line-strong:#2d3d36;

    --fg:#e6ede9;
    --fg-muted:#9aaba3;
    --fg-subtle:#75867e;
    --accent:#4dbb85;
    --accent-hover:#6bcd9c;
    --accent-soft:#122e21;
    --focus:rgba(77,187,133,.32);

    --ok-fg:#7ed4a6;   --ok-bg:#0f2c1e;   --ok-br:#1e5238;
    --warn-fg:#e0bd6e; --warn-bg:#2c2413; --warn-br:#54441f;
    --bad-fg:#f0a49b;  --bad-bg:#2e1614;  --bad-br:#5b2a25;
    --info-fg:#8fbdf0; --info-bg:#12233a; --info-br:#254468;

    --sh-1:0 1px 2px rgba(0,0,0,.4);
    --sh-2:0 2px 6px -2px rgba(0,0,0,.45), 0 10px 24px -10px rgba(0,0,0,.6);
    --sh-3:0 4px 10px -4px rgba(0,0,0,.5), 0 28px 56px -22px rgba(0,0,0,.75);
    --sh-inset:inset 0 1px 0 rgba(255,255,255,.04);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --canvas:#0a100d; --paper:#121a16; --paper-2:#161f1a; --sunken:#0e1512;
  --line:#22302a; --line-strong:#2d3d36;
  --fg:#e6ede9; --fg-muted:#9aaba3; --fg-subtle:#75867e;
  --accent:#4dbb85; --accent-hover:#6bcd9c; --accent-soft:#122e21;
  --focus:rgba(77,187,133,.32);
  --ok-fg:#7ed4a6;   --ok-bg:#0f2c1e;   --ok-br:#1e5238;
  --warn-fg:#e0bd6e; --warn-bg:#2c2413; --warn-br:#54441f;
  --bad-fg:#f0a49b;  --bad-bg:#2e1614;  --bad-br:#5b2a25;
  --info-fg:#8fbdf0; --info-bg:#12233a; --info-br:#254468;
  --sh-1:0 1px 2px rgba(0,0,0,.4);
  --sh-2:0 2px 6px -2px rgba(0,0,0,.45), 0 10px 24px -10px rgba(0,0,0,.6);
  --sh-3:0 4px 10px -4px rgba(0,0,0,.5), 0 28px 56px -22px rgba(0,0,0,.75);
  --sh-inset:inset 0 1px 0 rgba(255,255,255,.04);
}

/* ---------- 2. Reset & base ---------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}
body{
  font-family:var(--f-body);
  font-size:15px;
  line-height:1.65;
  color:var(--fg);
  background:var(--canvas);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  min-height:100vh;
}
img,svg,video{display:block;max-width:100%}
button,input,select,textarea{font:inherit;color:inherit}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-xs)}
::selection{background:var(--ku-200);color:var(--ku-900)}
hr{border:0;border-top:1px solid var(--line)}
[hidden]{display:none!important}

h1,h2,h3,h4{font-family:var(--f-display);font-weight:600;line-height:1.25;letter-spacing:-.015em;color:var(--fg)}
h1{font-size:clamp(1.9rem,1.3rem + 2.4vw,2.85rem);letter-spacing:-.028em}
h2{font-size:clamp(1.35rem,1.1rem + 1vw,1.75rem)}
h3{font-size:1.1rem}
h4{font-size:.98rem}

.num{font-variant-numeric:tabular-nums}
.mono{font-family:var(--f-mono);font-variant-numeric:tabular-nums}

/* ---------- 3. Layout ---------- */
.wrap{width:100%;max-width:1160px;margin-inline:auto;padding-inline:20px}
.wrap-narrow{max-width:800px}
.wrap-wide{max-width:1380px}
.row{display:flex;align-items:center;gap:10px}
.row-between{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
.grid{display:grid;gap:16px}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.span2{grid-column:span 2}
@media (max-width:860px){.g3,.g4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.g2,.g3,.g4{grid-template-columns:1fr}.span2{grid-column:auto}}
.spacer{flex:1}
.sr{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* เนื้อหาหลัก + แถบข้าง — ยุบเป็นคอลัมน์เดียวบนจอแคบ */
.split{display:grid;gap:22px;align-items:start;grid-template-columns:1fr var(--rail,340px)}
.split-even{display:grid;gap:24px;align-items:start;grid-template-columns:1fr 1fr}
/* ให้การ์ดในแถวเดียวกันสูงเท่ากัน — ท้ายการ์ดจะได้อยู่ระดับเดียวกัน */
.split-even.stretch{align-items:stretch}
.split-even.stretch>*{height:100%}
@media(max-width:900px){
  .split,.split-even{grid-template-columns:1fr}
  .summary{position:static!important}
}

/* ---------- 4. Text helpers ---------- */
.muted{color:var(--fg-muted)}
.subtle{color:var(--fg-subtle)}
.tiny{font-size:.78rem;line-height:1.5}
.small{font-size:.86rem;line-height:1.55}
.lead{font-size:1.05rem;color:var(--fg-muted);line-height:1.7}
.strong{font-weight:600}
.center{text-align:center}
.right{text-align:right}
.eyebrow{
  font-family:var(--f-display);font-size:.72rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--fg-subtle);
}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- 5. Card / panel ---------- */
.card{
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-1);
}
.card-pad{padding:22px}
@media(min-width:640px){.card-pad{padding:28px}}
.card-hd{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:16px 22px;border-bottom:1px solid var(--line);
}
.card-hd h3{font-size:1rem;letter-spacing:-.01em}
.card-bd{padding:22px}
.card-ft{padding:16px 22px;border-top:1px solid var(--line);background:var(--sunken);border-radius:0 0 var(--r-lg) var(--r-lg)}
.card-raised{box-shadow:var(--sh-2)}
.panel{background:var(--sunken);border:1px solid var(--line);border-radius:var(--r-md);padding:16px}

/* ---------- 6. Buttons ---------- */
.btn{
  --btn-bg:var(--paper); --btn-fg:var(--fg); --btn-br:var(--line-strong);
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--f-display);font-weight:600;font-size:.92rem;line-height:1;
  padding:0 18px;height:44px;border-radius:var(--r-md);
  background:var(--btn-bg);color:var(--btn-fg);border:1px solid var(--btn-br);
  cursor:pointer;white-space:nowrap;text-decoration:none;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease),transform var(--dur) var(--ease),color var(--dur) var(--ease);
  box-shadow:var(--sh-1);
}
.btn:hover{text-decoration:none;transform:translateY(-1px);box-shadow:var(--sh-2)}
.btn:active{transform:translateY(0);box-shadow:var(--sh-1)}
.btn[disabled],.btn.is-disabled{opacity:.5;pointer-events:none;box-shadow:none}
.btn svg{width:17px;height:17px;flex:none}

.btn-primary{
  --btn-bg:linear-gradient(180deg,#1c9a5d,#0f5a37);
  --btn-fg:#fff;--btn-br:#0a3f28;
  box-shadow:var(--sh-1),var(--sh-inset);
}
.btn-primary:hover{--btn-bg:linear-gradient(180deg,#22ac6a,#157a4a)}
.btn-ghost{--btn-bg:transparent;--btn-br:transparent;box-shadow:none}
.btn-ghost:hover{--btn-bg:var(--sunken);box-shadow:none;transform:none}
.btn-quiet{--btn-bg:var(--sunken);--btn-br:var(--line)}
.btn-danger{--btn-bg:var(--bad-bg);--btn-fg:var(--bad-fg);--btn-br:var(--bad-br)}
.btn-ok{--btn-bg:var(--ok-bg);--btn-fg:var(--ok-fg);--btn-br:var(--ok-br)}
.btn-sm{height:34px;padding:0 12px;font-size:.83rem;border-radius:var(--r-sm)}
.btn-sm svg{width:15px;height:15px}
.btn-lg{height:52px;padding:0 26px;font-size:1rem}
.btn-block{width:100%}
.btn-icon{width:38px;height:38px;padding:0}
.btn-icon.btn-sm{width:32px;height:32px}

/* ---------- 7. Forms ---------- */
.label{
  display:flex;align-items:center;gap:6px;
  font-family:var(--f-display);font-weight:500;font-size:.88rem;
  color:var(--fg);margin-bottom:7px;
}
.label .req{color:var(--bad-fg);font-weight:600}
.hint{font-size:.78rem;color:var(--fg-subtle);margin-top:6px;line-height:1.5}
.err{font-size:.78rem;color:var(--bad-fg);margin-top:6px;display:none}
.field.invalid .err{display:block}

.input,.select,.textarea{
  width:100%;height:46px;padding:0 13px;
  background:var(--paper);color:var(--fg);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background var(--dur) var(--ease);
  font-size:.95rem;
}
.textarea{height:auto;padding:11px 13px;min-height:96px;resize:vertical;line-height:1.6}
.input::placeholder,.textarea::placeholder{color:var(--fg-subtle)}
.input:hover,.select:hover,.textarea:hover{border-color:var(--ink-300)}
.input:focus,.select:focus,.textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3.5px var(--focus);
}
.field.invalid .input,.field.invalid .select,.field.invalid .textarea{
  border-color:var(--bad-br);box-shadow:0 0 0 3.5px rgba(155,44,34,.14);
}
.input:disabled,.select:disabled,.textarea:disabled{
  background:var(--sunken);color:var(--fg-subtle);cursor:not-allowed;border-style:dashed;
}
.select{
  appearance:none;padding-right:38px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364766e' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center;
}
.input-icon{position:relative}
.input-icon .input{padding-left:42px}
.input-icon>svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);width:17px;height:17px;color:var(--fg-subtle);pointer-events:none}

/* choice cards (checkbox / radio) */
.choice{
  display:flex;align-items:flex-start;gap:13px;padding:15px 16px;cursor:pointer;
  background:var(--paper);border:1px solid var(--line-strong);border-radius:var(--r-md);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
  position:relative;
}
.choice:hover{border-color:var(--ink-300);background:var(--paper-2)}
.choice input{
  appearance:none;width:20px;height:20px;flex:none;margin-top:2px;
  border:1.5px solid var(--ink-300);background:var(--paper);cursor:pointer;
  border-radius:var(--r-xs);transition:all var(--dur) var(--ease);
}
.choice input[type=radio]{border-radius:var(--r-full)}
.choice input:checked{background-color:#157a4a;border-color:#0f5a37}
.choice input[type=checkbox]:checked{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-position:center;background-repeat:no-repeat;
}
.choice input[type=radio]:checked{box-shadow:inset 0 0 0 3.5px var(--paper)}
.choice:has(input:checked){border-color:#1c9a5d;background:var(--accent-soft);box-shadow:0 0 0 1px #1c9a5d}
.choice:has(input:disabled){opacity:.55;pointer-events:none}
.choice-body{flex:1;min-width:0}
.choice-title{font-family:var(--f-display);font-weight:600;font-size:.95rem}
.choice-sub{font-size:.83rem;color:var(--fg-muted);margin-top:2px}

/* dropzone */
.drop{
  position:relative;display:grid;place-items:center;text-align:center;
  min-height:190px;padding:24px;cursor:pointer;
  border:1.5px dashed var(--line-strong);border-radius:var(--r-lg);
  background:var(--sunken);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.drop:hover,.drop.dragging{border-color:var(--accent);background:var(--accent-soft)}
.drop input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer}
.drop.has-file{border-style:solid;background:var(--paper);padding:12px}
.drop-preview{max-height:300px;border-radius:var(--r-md);box-shadow:var(--sh-1);margin-inline:auto}

/* ---------- 8. Stepper ---------- */
.stepper{display:flex;align-items:flex-start;position:relative}
.stepper .stp{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px;position:relative;text-align:center}
.stepper .stp::before,.stepper .stp::after{
  content:"";position:absolute;top:16px;height:2px;background:var(--line-strong);z-index:0;
}
.stepper .stp::before{left:0;right:50%}
.stepper .stp::after{left:50%;right:0}
.stepper .stp:first-child::before,.stepper .stp:last-child::after{display:none}
.stepper .stp.done::before,.stepper .stp.done::after,.stepper .stp.active::before{background:#1c9a5d}
.stp-dot{
  position:relative;z-index:1;width:34px;height:34px;border-radius:var(--r-full);
  display:grid;place-items:center;font-family:var(--f-display);font-weight:600;font-size:.88rem;
  background:var(--paper);color:var(--fg-subtle);border:2px solid var(--line-strong);
  transition:all var(--dur) var(--ease);
}
.stp-dot svg{width:16px;height:16px}
.stp.active .stp-dot{background:#157a4a;border-color:#157a4a;color:#fff;box-shadow:0 0 0 4px var(--accent-soft)}
.stp.done .stp-dot{background:#157a4a;border-color:#157a4a;color:#fff}
.stp-label{font-size:.82rem;color:var(--fg-subtle);font-weight:500;max-width:12ch}
.stp.active .stp-label,.stp.done .stp-label{color:var(--fg)}
@media(max-width:520px){.stp-label{font-size:.72rem}}

/* ---------- 9. Badges & status ---------- */
.badge{
  display:inline-flex;align-items:center;gap:5px;
  padding:3px 9px;border-radius:var(--r-full);
  font-family:var(--f-display);font-size:.75rem;font-weight:600;line-height:1.5;
  border:1px solid transparent;white-space:nowrap;
}
.badge svg{width:13px;height:13px}
.badge-ok{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-br)}
.badge-warn{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-br)}
.badge-bad{background:var(--bad-bg);color:var(--bad-fg);border-color:var(--bad-br)}
.badge-info{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-br)}
.badge-neutral{background:var(--sunken);color:var(--fg-muted);border-color:var(--line-strong)}
.badge-lg{padding:5px 13px;font-size:.85rem}
.dot{width:7px;height:7px;border-radius:var(--r-full);background:currentColor;flex:none}

.note{
  display:flex;gap:13px;padding:15px 17px;border-radius:var(--r-md);
  border:1px solid var(--line-strong);background:var(--sunken);
}
.note svg{width:19px;height:19px;flex:none;margin-top:2px}
.note-ok{background:var(--ok-bg);border-color:var(--ok-br);color:var(--ok-fg)}
.note-warn{background:var(--warn-bg);border-color:var(--warn-br);color:var(--warn-fg)}
.note-bad{background:var(--bad-bg);border-color:var(--bad-br);color:var(--bad-fg)}
.note-info{background:var(--info-bg);border-color:var(--info-br);color:var(--info-fg)}
.note-title{font-family:var(--f-display);font-weight:600;font-size:.92rem}
.note-body{font-size:.85rem;opacity:.92;margin-top:2px;line-height:1.6}
/* กล่องคำอธิบายประกอบ — พูดให้ครบแต่ไม่แย่งสายตาจากสิ่งที่ผู้ใช้ต้องเลือก */
.note-sm{padding:12px 14px;gap:10px}
.note-sm svg{width:16px;height:16px;margin-top:1px;color:var(--fg-muted)}
.note-sm .note-title{font-size:.86rem}
.note-sm .note-body{font-size:.8rem;color:var(--fg-muted);opacity:1}

/* ---------- 10. Stat tiles ---------- */
.stat{padding:18px 20px;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md)}
.stat-k{font-size:.78rem;color:var(--fg-muted);font-weight:500}
.stat-v{font-family:var(--f-display);font-size:1.85rem;font-weight:600;line-height:1.15;margin-top:5px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.stat-d{font-size:.76rem;color:var(--fg-subtle);margin-top:3px}

/* ---------- 11. Definition list ---------- */
.dl{display:grid;grid-template-columns:minmax(120px,190px) 1fr}
.dl dt,.dl dd{padding:12px 0;border-bottom:1px solid var(--line);min-width:0}
.dl dt{font-size:.85rem;color:var(--fg-muted);font-weight:500;padding-right:16px}
.dl dd{font-size:.93rem}
.dl>:nth-last-child(1),.dl>:nth-last-child(2){border-bottom:0}
@media(max-width:560px){
  .dl{grid-template-columns:1fr}
  .dl dt{padding-bottom:2px;border-bottom:0}
  .dl dd{padding-top:0}
}

/* ---------- 12. Table ---------- */
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-md);background:var(--paper)}
table.tbl{width:100%;border-collapse:collapse;font-size:.88rem;min-width:760px}
.tbl thead th{
  text-align:left;font-family:var(--f-display);font-weight:600;font-size:.75rem;
  letter-spacing:.05em;text-transform:uppercase;color:var(--fg-subtle);
  padding:11px 14px;background:var(--sunken);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:1;white-space:nowrap;
}
.tbl tbody td{padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr{transition:background var(--dur) var(--ease);cursor:pointer}
.tbl tbody tr:hover{background:var(--sunken)}
.tbl tbody tr.sel{background:var(--accent-soft)}

/* ---------- 13. Segmented control ---------- */
.seg{display:inline-flex;padding:3px;gap:2px;background:var(--sunken);border:1px solid var(--line);border-radius:var(--r-md);flex-wrap:wrap}
.seg button{
  border:0;background:transparent;cursor:pointer;border-radius:var(--r-sm);
  padding:0 14px;height:32px;font-family:var(--f-display);font-weight:500;font-size:.85rem;
  color:var(--fg-muted);transition:all var(--dur) var(--ease);display:inline-flex;align-items:center;gap:6px;
}
.seg button:hover{color:var(--fg)}
.seg button[aria-selected=true]{background:var(--paper);color:var(--fg);font-weight:600;box-shadow:var(--sh-1)}
.seg .count{font-size:.72rem;padding:1px 6px;border-radius:var(--r-full);background:var(--line);color:var(--fg-muted);font-variant-numeric:tabular-nums}
.seg button[aria-selected=true] .count{background:var(--accent-soft);color:var(--accent)}

/* ---------- 14. App shell ---------- */
.topbar{
  position:sticky;top:0;z-index:40;
  background:var(--paper);
  border-bottom:1px solid var(--line);
}
@supports (backdrop-filter:blur(1px)){
  .topbar{background:color-mix(in srgb,var(--paper) 84%,transparent);
    backdrop-filter:saturate(1.6) blur(12px);-webkit-backdrop-filter:saturate(1.6) blur(12px)}
}
.topbar-in{display:flex;align-items:center;gap:16px;height:62px}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none;color:var(--fg);min-width:0}
.brand:hover{text-decoration:none}
.brand-mark{
  width:36px;height:36px;border-radius:10px;flex:none;display:grid;place-items:center;
  background:linear-gradient(145deg,#1c9a5d,#0a3f28);
  color:#fff;font-family:var(--f-display);font-weight:700;font-size:.88rem;letter-spacing:-.03em;
  box-shadow:var(--sh-1),var(--sh-inset);
}
.brand-name{font-family:var(--f-display);font-weight:600;font-size:.95rem;line-height:1.25;letter-spacing:-.01em}
.brand-sub{font-size:.72rem;color:var(--fg-subtle);line-height:1.2}
.nav{display:flex;align-items:center;gap:2px}
.nav a{
  padding:7px 12px;border-radius:var(--r-sm);font-size:.87rem;font-weight:500;
  color:var(--fg-muted);transition:all var(--dur) var(--ease);
}
.nav a:hover{background:var(--sunken);color:var(--fg);text-decoration:none}
.nav a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.nav a{white-space:nowrap}

/* ★ ช่วงจอกลาง — บีบให้พอดีแทนที่จะปล่อยให้ลิงก์ล้นออกนอกแถบ
   พอเพิ่มลิงก์ที่ห้าเข้ามา แถบบนจะแน่นในช่วงราว 760–1100px
   ซึ่งเป็นความกว้างของแท็บเล็ตแนวนอนและหน้าต่างเบราว์เซอร์ที่ไม่ได้ขยายเต็มจอ
   ตัดคำบรรยายใต้ชื่อโครงการออกก่อน เพราะเป็นข้อความประกอบ ไม่ใช่ทางไปไหน
   แล้วค่อยลดระยะห่างของลิงก์ ซึ่งยังกดง่ายอยู่ */
@media (min-width:761px) and (max-width:1100px){
  .brand-sub{display:none}
  .nav a{padding:7px 9px;font-size:.84rem}
  .topbar-in{gap:10px}
}
@media(max-width:760px){
  /* ★ แถบลิงก์ถูกซ่อนบนจอแคบ แล้วใช้ปุ่มเปิดเมนูแทน (.navtoggle → .navsheet)
     เคยมีกฎ "ย่อ nav แทนที่จะซ่อน" เขียนอยู่ตรงนี้ แต่ไม่เคยทำงานเลย
     เพราะมาร์กอัปใส่ class="nav hide-sm" ซึ่งสั่ง display:none!important ทับไว้
     ผลคือบนมือถือไม่มีเมนูให้กดจริง ๆ มาตลอด */
  .hide-sm{display:none!important}
  .navtoggle{display:inline-grid!important}
  .topbar-in{gap:8px}
}

/* sidebar (admin) */
.shell{display:grid;grid-template-columns:238px 1fr;min-height:calc(100vh - 62px)}
.side{border-right:1px solid var(--line);background:var(--paper);padding:18px 12px}
.side-group+.side-group{margin-top:22px}
@media(max-width:980px){
  /* กลายเป็นแถบเลื่อนแนวนอนใต้ topbar แทนที่จะหายไป */
  .shell{grid-template-columns:1fr}
  .side{
    border-right:0;border-bottom:1px solid var(--line);padding:8px 12px;
    display:flex;gap:4px;overflow-x:auto;scrollbar-width:none;
    position:sticky;top:62px;z-index:30;
  }
  .side::-webkit-scrollbar{display:none}
  .side-group{display:contents}
  .side-group+.side-group{margin-top:0}
  .side-title{display:none}
  .side a{white-space:nowrap;padding:8px 12px;flex:none}
  .main{padding:20px 16px 60px}
}
.side-title{font-size:.7rem;letter-spacing:.13em;text-transform:uppercase;color:var(--fg-subtle);font-weight:600;padding:0 10px;margin-bottom:7px}
.side a{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);
  font-size:.88rem;color:var(--fg-muted);font-weight:500;transition:all var(--dur) var(--ease);
}
.side a:hover{background:var(--sunken);color:var(--fg);text-decoration:none}
.side a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.side a svg{width:17px;height:17px;flex:none}
.side a .tail{margin-left:auto;font-size:.74rem;font-variant-numeric:tabular-nums;
  background:var(--line);color:var(--fg-muted);padding:1px 7px;border-radius:var(--r-full)}
.main{padding:26px 22px 60px;min-width:0;background:var(--canvas)}

/* ---------- 15. Overlays ---------- */
.scrim{
  position:fixed;inset:0;z-index:80;background:rgba(8,13,11,.5);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:grid;place-items:center;padding:20px;overflow:auto;
  animation:fade var(--dur) var(--ease);
}
.modal{
  width:100%;max-width:470px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-xl);box-shadow:var(--sh-3);
  animation:pop 220ms var(--ease);

  /* ★ กล่องต้องไม่สูงเกินจอ และต้องเลื่อนดูข้างในได้

     บักที่แก้: ฉากหลังใช้ place-items:center ซึ่งจัดกล่องไว้กึ่งกลาง
     พอเนื้อหาสูงกว่าจอ ส่วนที่ล้นจะไปโผล่ทั้งบนและล่างเท่า ๆ กัน
     แต่การเลื่อนหน้าจอลงไปได้อย่างเดียว ส่วนที่ล้นออก "ด้านบน" จึงเข้าไม่ถึงตลอดกาล
     ในหน้าต่างตรวจสลิปคือชื่อผู้สมัคร ปุ่มปิด และปุ่มเลื่อนไปใบถัดไป — หายไปทั้งแถบ

     จำกัดความสูงไม่ให้เกินจอ แล้วให้เลื่อนข้างในกล่องแทน
     กล่องจึงพอดีจอเสมอ ปัญหาการจัดกึ่งกลางก็หมดไปเอง */
  max-height:calc(100dvh - 40px);
  overflow:auto;
}
/* ★ หัวกล่องติดอยู่กับที่เวลาเลื่อน
   เจ้าหน้าที่ต้องกดปิดหรือกดไปใบถัดไปได้ตลอด ไม่ต้องเลื่อนกลับขึ้นไปหาปุ่ม
   ใช้ตัวเลือกแบบลูกหลาน เพราะหัวกล่องอยู่ลึกลงไปอีกชั้นในบางหน้าต่าง */
.modal .card-hd{
  position:sticky;top:0;z-index:2;
  background:var(--paper);border-radius:var(--r-xl) var(--r-xl) 0 0;
}
.modal-lg{max-width:1000px}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}

#toasts{position:fixed;bottom:20px;right:20px;z-index:100;display:flex;flex-direction:column;gap:10px;max-width:min(380px,calc(100vw - 40px))}
.toast{
  display:flex;gap:11px;align-items:flex-start;padding:13px 15px;
  background:var(--paper);border:1px solid var(--line-strong);border-radius:var(--r-md);
  box-shadow:var(--sh-3);animation:slidein 260ms var(--ease);
}
.toast.out{animation:slideout 200ms var(--ease) forwards}
.toast svg{width:18px;height:18px;flex:none;margin-top:2px}
.toast-ok svg{color:var(--ok-fg)} .toast-bad svg{color:var(--bad-fg)}
.toast-warn svg{color:var(--warn-fg)} .toast-info svg{color:var(--info-fg)}
.toast-t{font-family:var(--f-display);font-weight:600;font-size:.9rem}
.toast-m{font-size:.82rem;color:var(--fg-muted);line-height:1.5;margin-top:1px}
@keyframes slidein{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
@keyframes slideout{to{opacity:0;transform:translateX(24px)}}

.spinner{
  width:18px;height:18px;border:2.2px solid var(--line-strong);border-top-color:var(--accent);
  border-radius:var(--r-full);animation:spin .7s linear infinite;flex:none;
}
.spinner-lg{width:34px;height:34px;border-width:3px}
@keyframes spin{to{transform:rotate(360deg)}}

.progress{height:6px;border-radius:var(--r-full);background:var(--line);overflow:hidden}
.progress>i{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,#1c9a5d,#0f5a37);transition:width 340ms var(--ease)}

/* ---------- 16. Misc ---------- */
.divider{display:flex;align-items:center;gap:14px;color:var(--fg-subtle);font-size:.8rem}
.divider::before,.divider::after{content:"";flex:1;height:1px;background:var(--line)}
.kbd{font-family:var(--f-mono);font-size:.75rem;padding:2px 6px;border:1px solid var(--line-strong);
  border-bottom-width:2px;border-radius:var(--r-xs);background:var(--sunken)}
.copyable{display:inline-flex;align-items:center;gap:7px}
.copyable button{border:0;background:transparent;cursor:pointer;color:var(--fg-subtle);padding:3px;border-radius:var(--r-xs);display:grid;place-items:center}
.copyable button:hover{color:var(--accent);background:var(--accent-soft)}
.copyable svg{width:15px;height:15px}
.fade-in{animation:fade 260ms var(--ease)}
.rise{animation:rise 340ms var(--ease) both}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* =============================================================
   17. Components used by more than one page
   (กระดานที่นั่ง / ตารางเทียบรอบ / รายการสิทธิ / การ์ดรูปแบบ)
   ============================================================= */

/* ---------- กระดานโจทย์คณิตศาสตร์ ----------
   ★ เดิมตรงนี้เป็นตารางที่นั่ง 2x2
     พอเลิกบอกจำนวนที่นั่งคงเหลือ ทุกช่องก็เขียนเหมือนกันหมดว่า "ยังเปิดรับ"
     ตารางมีไว้เทียบค่าที่ต่างกัน เมื่อไม่มีอะไรต่างกันแล้ว รูปแบบตารางก็ไม่คุ้มพื้นที่

   ★ แล้วอะไรควรอยู่ตรงนี้แทน
     ช่องขวาของหัวหน้าแรกคือที่ที่คนมองเป็นที่สองรองจากหัวเรื่อง
     สิ่งที่ควรอยู่คือสิ่งที่บอกว่า "เว็บนี้เกี่ยวกับอะไร" ได้เร็วที่สุด
     สำหรับเว็บสอบคณิตศาสตร์ คำตอบนั้นคือคณิตศาสตร์เอง

   ★ สูตรถูกเรนเดอร์ไว้ตั้งแต่ตอนประกอบไฟล์ (build-formulas.mjs)
     หน้าแรกจึงไม่ต้องโหลดตัวเรนเดอร์สูตรเลย ใช้แค่ไฟล์สไตล์ของ KaTeX */
.board{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-xl);
  box-shadow:var(--sh-2);overflow:hidden}
.board-hd{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:15px 20px;border-bottom:1px solid var(--line)}
.board-hd h3{font-size:.95rem}
.live{display:inline-flex;align-items:center;gap:6px;font-size:.72rem;color:var(--ok-fg);font-weight:600}
.live i{width:7px;height:7px;border-radius:50%;background:var(--ok-fg);animation:pulse 2s var(--ease) infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}

/* ── เวทีที่สูตรปรากฏ ──
   ★ เคยมีของขยับเก้าอย่างในกล่องนี้ — ลอย เอียงตามเมาส์ แสงตามเมาส์ แสงกวาด
     ลำแสงขอบบน แสงเรืองลอย กระดาษกราฟไหล วินาทีเต้น และปลายปากกากะพริบ
     ถอดออกเหลืออย่างเดียว คือการเขียนสูตรตอนเปลี่ยนข้อ

     เหตุผลไม่ใช่เรื่องประสิทธิภาพ แต่เป็นเรื่องน้ำเสียง
     นี่คือเว็บรับสมัครสอบของภาควิชาในมหาวิทยาลัย ผู้อ่านคือนักเรียนที่กำลังตัดสินใจ
     และผู้ปกครองที่กำลังจะจ่ายเงิน สิ่งที่ทำให้คนกลุ่มนี้เชื่อถือคือความนิ่ง
     ไม่ใช่ความหวือหวา

     และการเติมเอฟเฟกต์ไม่เคยแก้ปัญหาที่แท้จริงของกล่องนี้ได้เลย
     ปัญหาคือกล่องใหญ่เกินกว่าเนื้อหาที่มี ไม่ใช่กล่องนิ่งเกินไป
     ของที่ว่างแล้วขยับ ยิ่งดูว่างกว่าเดิม เพราะมันเรียกร้องความสนใจโดยไม่มีอะไรจะบอก
     จึงแก้ด้วยการย่อกล่องให้พอดีกับสูตร แทนที่จะเติมของเข้าไปกลบ */
.fstage{
  position:relative;min-height:178px;display:grid;place-items:center;
  padding:24px 22px 34px;overflow:hidden;
  background:
    radial-gradient(120% 92% at 50% 0%, color-mix(in srgb,var(--accent) 9%,transparent), transparent 72%),
    var(--sunken);
}
/* กระดาษกราฟ — บอกบริบทว่านี่คือกระดานคำนวณ นิ่งอยู่กับที่ */
.fstage::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.8;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:28px 28px;
  -webkit-mask-image:radial-gradient(76% 76% at 50% 44%,#000,transparent 82%);
  mask-image:radial-gradient(76% 76% at 50% 44%,#000,transparent 82%);
}

.fslides{position:absolute;inset:24px 22px 34px}
.fslide{
  position:absolute;inset:0;display:grid;place-items:center;align-content:center;
  gap:14px;opacity:0;visibility:hidden;text-align:center;
}
.fslide.on{opacity:1;visibility:visible}
/* ★ กล่องนี้กว้างเท่าสูตรพอดี ไม่ใช่กว้างเต็มเวที
   เอฟเฟกต์เขียนเปิดจาก "ขอบซ้ายของสูตร" ไม่ใช่จากขอบซ้ายของกล่อง
   ถ้ากว้างเต็มเวที ครึ่งแรกของเวลาจะเปิดแต่ที่ว่าง แล้วสูตรเพิ่งโผล่ตอนท้าย
   ซึ่งอ่านออกว่า "โหลดไม่เสร็จ" ไม่ใช่ "กำลังเขียน" */
.frow{display:inline-flex;align-items:center;max-width:100%}
.fslide .katex-display{margin:0;font-size:clamp(1.2rem,1.6vw,1.5rem)}
.fslide .katex{color:var(--fg)}

.ftopic{
  font-size:.75rem;letter-spacing:.04em;color:var(--fg-muted);
  display:inline-flex;align-items:center;gap:9px;
}
.ftopic::before,.ftopic::after{content:"";width:16px;height:1px;background:var(--line-strong)}

/* จุดบอกลำดับสูตร — บอกว่ายังมีอีก และทำให้ขอบล่างของเวทีไม่ว่างเปล่า */
.fdots{position:absolute;left:0;right:0;bottom:14px;display:flex;justify-content:center;gap:6px}
.fdots i{
  width:5px;height:5px;border-radius:99px;background:var(--line-strong);
  transition:width var(--dur) var(--ease),background var(--dur) var(--ease);
}
.fdots i.on{width:18px;background:var(--accent)}

/* ── เอฟเฟกต์เดียวที่เหลือไว้: เขียนสูตรขึ้นทีละบรรทัด ──
   ★ ทำไมเก็บอันนี้ไว้อันเดียว
     มันไม่ใช่ของประดับ — มันสื่อความหมายตรงกับสิ่งที่กำลังเกิด
     คือสูตรใหม่กำลังถูกเขียนลงบนกระดาน เหมือนอาจารย์เขียนกระดานจริง
     และมันขยับเฉพาะตอนเปลี่ยนข้อ ไม่ได้ขยับตลอดเวลาให้รำคาญสายตา */
@keyframes fwrite{
  from{clip-path:inset(0 100% 0 0);opacity:.2}
  to  {clip-path:inset(0 -6px 0 0);opacity:1}
}
@keyframes ffade{ from{opacity:0;transform:translateY(7px)} to{opacity:1;transform:none} }
.fslide.on .frow{animation:fwrite 820ms var(--ease) both;will-change:clip-path}
.fslide.on .ftopic{animation:ffade 560ms var(--ease) 420ms both}

/* ── แถบล่าง: นับถอยหลัง + สถานะการรับสมัคร ── */
.ffoot{padding:15px 20px;border-top:1px solid var(--line);background:var(--paper)}
.cdown{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
.cdown-k{font-size:.75rem;color:var(--fg-subtle);margin-bottom:3px}
.cdown-v{display:flex;align-items:baseline;gap:4px;font-family:var(--f-display);font-weight:600;
  font-variant-numeric:tabular-nums;font-size:1.4rem;letter-spacing:-.01em}
.cdown-v small{font-size:.68rem;font-weight:400;color:var(--fg-subtle);margin-right:5px}
.cdown-v em{font-style:normal;color:var(--line-strong);font-weight:400;margin:0 1px}
/* ★ วินาทีจางกว่าตัวอื่น เพราะมันเปลี่ยนตลอดเวลา
   ถ้าเข้มเท่ากันหมด สายตาจะถูกดึงไปที่ตัวที่ไม่สำคัญที่สุดตลอดเวลา */
/* ★ วินาทีจางกว่าตัวอื่น เพราะมันเปลี่ยนตลอดเวลา
   ถ้าเข้มเท่ากันหมด สายตาจะถูกดึงไปที่ตัวที่ไม่สำคัญที่สุดตลอดเวลา
   ตัวเลขที่เดินเองอยู่แล้วไม่ต้องมีแอนิเมชันช่วยอีก */
.cdown-s{color:var(--fg-subtle)}

.seat-line{
  display:flex;align-items:center;gap:8px;margin-top:11px;
  font-size:.78rem;color:var(--fg-muted);
}
.seat-line>i{flex:none;width:7px;height:7px;border-radius:99px;background:var(--ok-fg)}
.seat-line.low>i{background:var(--warn-fg)}
.seat-line.full>i{background:var(--bad-fg)}
.seat-line.low{color:var(--warn-fg)}
.seat-line.full{color:var(--bad-fg)}

/* ★ ปิดทุกการเคลื่อนไหวในกล่องนี้ให้ผู้ที่ตั้งค่าไว้
   กล่องนี้มีของที่ขยับสี่ชั้น จึงเป็นจุดที่รบกวนคนกลุ่มนี้มากที่สุดในทั้งเว็บ */
@media (prefers-reduced-motion:reduce){
  .fslide.on .frow,.fslide.on .ftopic,.live i{animation:none}
}
@media (max-width:640px){
  .fstage{min-height:156px;padding:20px 16px 32px}
  .fslides{inset:20px 16px 32px}
  .fslide .katex-display{font-size:1.06rem}
  .cdown-v{font-size:1.22rem}
}


/* ---------- ตารางเทียบรูปแบบการสอบ ---------- */
.cmp{width:100%;border-collapse:collapse;font-size:.88rem;min-width:620px}
.cmp th,.cmp td{padding:13px 18px;border-bottom:1px solid var(--line);text-align:center;vertical-align:middle}
.cmp tr:last-child th,.cmp tr:last-child td{border-bottom:0}
.cmp thead th{background:var(--sunken);font-family:var(--f-display);font-size:.88rem;
  font-weight:600;position:sticky;top:0;white-space:nowrap;z-index:1}
.cmp thead th:first-child{text-align:left;color:var(--fg-subtle);font-size:.74rem;
  letter-spacing:.06em;text-transform:uppercase}
.cmp tbody th{text-align:left;font-family:var(--f-body);font-weight:500;color:var(--fg);
  width:44%;min-width:210px}
.cmp tbody th small{display:block;font-weight:400;color:var(--fg-subtle);font-size:.75rem;
  line-height:1.5;margin-top:2px}
.cmp tbody tr:hover{background:var(--sunken)}
.cmp .yes,.cmp .no{display:inline-grid;place-items:center;width:24px;height:24px;border-radius:50%}
.cmp .yes{background:var(--ok-bg);color:var(--ok-fg)}
.cmp .no{background:var(--paper);color:var(--fg-subtle);border:1px solid var(--line-strong)}
.cmp .yes svg,.cmp .no svg{width:14px;height:14px}
.cmp .val{font-family:var(--f-display);font-weight:600;font-variant-numeric:tabular-nums}
.cmp .grp th{background:var(--sunken);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--fg-subtle);font-weight:600;padding:8px 18px;text-align:left}
.cmp-head{display:flex;flex-direction:column;align-items:center;gap:5px}
.cmp-head i{width:30px;height:30px;border-radius:9px;display:grid;place-items:center}
.cmp-head i svg{width:16px;height:16px}

/* ---------- รายการสิทธิที่ได้รับ ---------- */
.getlist{display:grid;gap:8px;margin-top:12px}
.get{display:flex;gap:10px;align-items:flex-start;font-size:.86rem;line-height:1.5}
.get i.m{width:18px;height:18px;border-radius:50%;display:grid;place-items:center;flex:none;margin-top:2px}
.get i.m svg{width:11px;height:11px}
.get.y i.m{background:var(--ok-bg);color:var(--ok-fg)}
.get.n i.m{background:var(--paper);color:var(--fg-subtle);border:1px solid var(--line-strong)}
.get.n span{color:var(--fg-subtle)}

/* ---------- การ์ดรูปแบบการสอบ ---------- */
.mode-col{position:relative;border:1px solid var(--line-strong);border-radius:var(--r-lg);
  background:var(--paper);overflow:hidden;display:flex;flex-direction:column}
.mode-col-hd{padding:22px 22px 18px;color:#fff;position:relative;overflow:hidden}
.mode-col-hd::after{content:"";position:absolute;inset:0;
  background:radial-gradient(70% 100% at 88% 0%,rgba(255,255,255,.18),transparent 62%)}

/* ★ ลายกระดาษกราฟบนหัวการ์ด
   พื้นที่สีทึบผืนใหญ่ทำให้การ์ดดูแข็งและว่างเปล่า
   เลือกลายตารางเพราะเป็นภาษาภาพของวิชาคณิตศาสตร์โดยตรง
   ไม่ใช่ลวดลายตกแต่งที่ไม่เกี่ยวกับเนื้อหา
   ไล่ให้จางหายไปด้วย mask เพื่อไม่ให้แย่งสายตาจากราคาและชื่อรอบ
   ใช้ภาษาภาพเดียวกับแผงเข้าสู่ระบบในหน้าตรวจสอบสถานะ จึงดูเป็นชุดเดียวกัน */
.mode-col-hd::before{
  content:"";position:absolute;inset:0;opacity:.18;
  background-image:linear-gradient(rgba(255,255,255,.6) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.6) 1px,transparent 1px);
  background-size:32px 32px;
  -webkit-mask-image:radial-gradient(78% 96% at 84% 4%,#000,transparent 74%);
  mask-image:radial-gradient(78% 96% at 84% 4%,#000,transparent 74%);
}
.mode-col-hd>*{position:relative}
.mode-ic{width:40px;height:40px;border-radius:11px;display:grid;place-items:center;
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.2);margin-bottom:12px}
.mode-ic svg{width:20px;height:20px}
.mode-col-hd h3{color:#fff;font-size:1.15rem}
.mode-col-hd p{font-size:.82rem;opacity:.82;margin-top:3px}
.mode-price{display:flex;align-items:baseline;gap:5px;margin-top:14px}
.mode-price b{font-family:var(--f-display);font-size:2rem;font-weight:600;letter-spacing:-.03em;line-height:1}
.mode-price span{font-size:.8rem;opacity:.8}
.mode-col-bd{padding:20px 22px;flex:1}
.mode-li{display:flex;gap:10px;font-size:.87rem;padding:6px 0;align-items:flex-start}
.mode-li svg{width:15px;height:15px;flex:none;margin-top:4px;color:var(--ok-fg)}
.mode-li.req svg{color:var(--warn-fg)}
.mode-col-ft{padding:14px 22px;border-top:1px solid var(--line);background:var(--sunken);
  display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:.82rem}
.mode-li.no{color:var(--fg-subtle)}
.mode-li.no svg{color:var(--fg-subtle)}

/* ---------- ช่องเลือกโรงเรียน (combobox) ---------- */
.picker{position:relative}
.picker-menu{
  position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:50;
  max-height:290px;overflow-y:auto;overscroll-behavior:contain;
  background:var(--paper);border:1px solid var(--line-strong);
  border-radius:var(--r-md);box-shadow:var(--sh-3);padding:5px;
}
.picker-row{
  display:flex;gap:11px;align-items:flex-start;padding:9px 11px;
  border-radius:var(--r-sm);cursor:pointer;font-size:.88rem;line-height:1.4;
}
.picker-row svg{width:16px;height:16px;flex:none;margin-top:2px;color:var(--fg-subtle)}
.picker-row small{display:block;font-size:.75rem;color:var(--fg-subtle);margin-top:1px}
.picker-row.on{background:var(--accent-soft)}
.picker-row.on svg{color:var(--accent)}
.picker-custom{border-top:1px solid var(--line);margin-top:4px;padding-top:11px}
.picker-custom svg{color:var(--warn-fg)}
.picker-empty{padding:16px;text-align:center;font-size:.85rem;color:var(--fg-subtle)}
.picker-note{
  display:flex;align-items:center;gap:8px;justify-content:center;
  padding:9px 11px;margin-top:4px;border-top:1px solid var(--line);
  font-size:.75rem;color:var(--fg-subtle);
}
.picker-note .spinner{width:13px;height:13px;border-width:1.8px}

/* =============================================================
   18. Refinement pass — ความน่าเชื่อถือแบบสถาบันวิชาการ
   ============================================================= */

/* แถบสถาบันด้านบนสุด — สัญญะของหน่วยงานทางการ */
body::before{
  content:"";position:fixed;inset:0 0 auto 0;height:3px;z-index:60;pointer-events:none;
  background:linear-gradient(90deg,#0a3f28 0%,#157a4a 26%,#1c9a5d 46%,#c2952f 74%,#8a6318 100%);
}
.topbar{top:3px}
.side{top:calc(62px + 3px)}

/* ตัวอักษร — คมและแน่นขึ้นเล็กน้อย ให้อ่านเป็นเอกสารทางการ */
h1{letter-spacing:-.032em;line-height:1.16}
h2{letter-spacing:-.022em;line-height:1.24}
h3{letter-spacing:-.012em}
/* ★ เคยใช้ 300 (Light) — ตัวไทยน้ำหนัก 300 เส้นบางจนอ่านยากบนจอสว่าง
   และเป็นน้ำหนักเดียวในทั้งระบบที่ต้องโหลดไฟล์ฟอนต์เพิ่มอีกชุด
   ใช้ 400 แล้วเปิดระยะบรรทัดแทน ได้ความโปร่งเหมือนเดิมแต่อ่านง่ายกว่า */
.lead{font-weight:400;letter-spacing:-.004em;line-height:1.75}

/* หัวข้อรอง — มีขีดนำหน้า อ่านเป็นลำดับชั้นชัดขึ้น */
.eyebrow{display:inline-flex;align-items:center;gap:9px}
.eyebrow::before{
  content:"";width:22px;height:2px;flex:none;border-radius:2px;
  background:linear-gradient(90deg,var(--accent),transparent);
}
.center .eyebrow,.section-head .eyebrow{justify-content:center}
.section-head .eyebrow::after{
  content:"";width:22px;height:2px;flex:none;border-radius:2px;
  background:linear-gradient(270deg,var(--accent),transparent);
}

/* การ์ด — ขอบบางลง เงานุ่มขึ้น มีเส้นสว่างด้านบนในโหมดสว่าง */
.card,.mode-col,.board,.table-wrap,.yr{
  transition:box-shadow 240ms var(--ease),border-color 240ms var(--ease),transform 240ms var(--ease);
}
:root:not([data-theme="dark"]) .card::after,
:root:not([data-theme="dark"]) .board::after{
  content:"";position:absolute;inset:0 0 auto 0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.9),transparent);
}
.card,.board{position:relative}
.card-raised:hover{box-shadow:var(--sh-3)}

/* ปุ่มหลัก — ประกายบาง ๆ ตอน hover */
.btn-primary{position:relative;overflow:hidden}
.btn-primary::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,transparent 35%,rgba(255,255,255,.22) 50%,transparent 65%);
  transform:translateX(-70%);transition:opacity 180ms var(--ease);
}
.btn-primary:hover::after{opacity:1;animation:sheen 780ms var(--ease)}
@keyframes sheen{to{transform:translateX(70%)}}

/* ══════════════════════════════════════════════════════════
   ชั้นเคลื่อนไหวและสีเน้น

   ★ ปัญหาที่แก้: ทั้งเว็บเป็นสีเขียวเฉดเดียวเกือบทั้งหมด
     ตาจึงไม่มีจุดพัก และไม่รู้ว่าควรมองอะไรก่อน

     ไม่ได้แก้ด้วยการเติมสีให้ฉูดฉาด แต่ใช้สองอย่าง
       1. สีทองเป็นสีเน้นลำดับที่สอง ใช้เฉพาะจุดที่ต้องการให้สะดุดตาจริง ๆ
       2. การเคลื่อนไหวเบา ๆ แทนการใช้สีจัด เพื่อดึงสายตาโดยไม่เสียความน่าเชื่อถือ

     ทุกอย่างปิดเองเมื่อผู้ใช้ตั้งค่าให้ลดการเคลื่อนไหว
   ══════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════
   กติกาการใช้สีของทั้งเว็บ

   ★ ปัญหาที่แก้: ก่อนหน้านี้ใส่สีตามความรู้สึกว่าจะได้ไม่จำเจ
     ผลคือในการ์ดเดียวมีสี่สี ตาไม่รู้ว่าสีไหนแปลว่าอะไร
     "ไม่จำเจ" กับ "มั่ว" ต่างกันตรงที่สีต้องมีความหมายเดียวตลอดทั้งระบบ

   ★ กติกา — สีหนึ่งความหมายหนึ่ง และปรากฏที่เดียวต่อองค์ประกอบ
       เขียว (accent)  ปุ่มหลักและสิ่งที่ต้องกดทำต่อ
       เขียว / น้ำเงิน  บอกว่าเป็นรายวิชา 61 หรือ 62 เท่านั้น
                        และแสดงที่ "หัวการ์ดรายวิชา" ที่เดียว
       อำพัน (warn)     เส้นตายและคำเตือน
       แดง (bad)        ข้อผิดพลาด
       เทา (neutral)    ทุกอย่างที่เหลือ รวมถึงไอคอนประกอบ

   ★ ไอคอนประกอบต้องเป็นสีเทาเสมอ
     ไอคอนไม่ได้บอกสถานะ มันบอกแค่ว่าแถวนี้คืออะไร
     ตัวไอคอนกับข้อความบอกครบอยู่แล้ว การใส่สีให้จึงเป็นเสียงรบกวน
   ══════════════════════════════════════════════════════════ */
.ic-tile{
  display:grid;place-items:center;flex:none;
  width:34px;height:34px;border-radius:9px;
  background:var(--sunken);border:1px solid var(--line);color:var(--fg-muted);
}
.ic-tile svg{width:16px;height:16px}
.ic-tile.lg{width:40px;height:40px;border-radius:11px}
.ic-tile.lg svg{width:19px;height:19px}
/* ใช้เฉพาะจุดที่สีมีความหมายจริง — เส้นตาย คำเตือน */
.ic-tile.warn{background:var(--warn-bg);border-color:var(--warn-br);color:var(--warn-fg)}

/* ══════════════════════════════════════════════════════════
   หัวหน้าเว็บมาตรฐาน  .pagehead

   ★ ปัญหาที่แก้: ห้าหน้าเคยมีหัวเรื่องคนละแบบ
       หน้าแรก      แถบใหญ่มีแสงหลังฉาก
       คลังข้อสอบ   แถบเล็กมีไล่สีคนละชุด
       ใบสมัคร      หัวเรื่องกลางหน้าไม่มีพื้นหลัง
       ตรวจสถานะ    ชื่อคนกับปุ่มออกจากระบบวางชิดกัน
     ใช้โทเคนสีชุดเดียวกันก็จริง แต่จังหวะ ระยะ และพื้นหลังคนละอย่าง
     เปิดสลับหน้าแล้วรู้สึกเหมือนคนละเว็บ

   ★ ทางแก้: หัวเรื่องทุกหน้าใช้โครงเดียวกัน
       พื้นหลัง     แสงจาง ๆ ทับด้วยลายกระดาษกราฟ (ภาษาภาพของทั้งเว็บ)
       ลำดับ        eyebrow → หัวเรื่อง → คำโปรย
       ระยะขอบ      เท่ากันทุกหน้า
     ต่างกันได้แค่ขนาด (.lg สำหรับหน้าแรก) และช่องขวาสำหรับปุ่ม
   ══════════════════════════════════════════════════════════ */
.pagehead{
  position:relative;overflow:hidden;
  padding:40px 0 34px;background:var(--paper);border-bottom:1px solid var(--line);
}
.pagehead::before{
  content:"";position:absolute;inset:-40% -10% auto -10%;height:170%;pointer-events:none;
  background:
    radial-gradient(52% 44% at 18% 4%, rgba(28,154,93,.13), transparent 62%),
    radial-gradient(44% 38% at 86% 18%, rgba(27,79,138,.10), transparent 60%);
}
.pagehead::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.45;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:58px 58px;
  -webkit-mask-image:radial-gradient(66% 62% at 50% 26%,#000,transparent 78%);
  mask-image:radial-gradient(66% 62% at 50% 26%,#000,transparent 78%);
}
.pagehead-in{position:relative;z-index:1;display:flex;align-items:flex-end;gap:24px;flex-wrap:wrap}
.pagehead-in>div:first-child{flex:1;min-width:min(100%,300px)}
.pagehead h1{font-size:clamp(1.45rem,1.2rem + 1.1vw,1.95rem);margin-top:8px;letter-spacing:-.02em}
.pagehead .lead,.pagehead .sub{margin-top:10px;max-width:56ch}
.pagehead .sub{font-size:.88rem;color:var(--fg-muted)}
.pagehead-act{display:flex;gap:9px;align-items:center;flex-wrap:wrap}

/* หน้าแรกใช้ตัวใหญ่กว่า แต่เป็นโครงเดียวกัน */
.pagehead.lg{padding:56px 0 64px}

@media (max-width:640px){
  .pagehead{padding:26px 0 22px}
  .pagehead.lg{padding:34px 0 40px}
  .pagehead-in{gap:16px}
}

/* ══════════════════════════════════════════════════════════
   การตัดบรรทัดของภาษาไทย

   ★ ปัญหา: ภาษาไทยเขียนติดกันไม่มีช่องว่างระหว่างคำ
     เบราว์เซอร์จึงตัดบรรทัดโดยเดาจากพจนานุกรมของมันเอง
     ผลคือบรรทัดสุดท้ายมักเหลือคำเดียวโดด ๆ หรือฉีกกลางชื่อหน่วยงาน
     อ่านแล้วสะดุด และทำให้หน้าดูไม่เรียบร้อยทั้งที่เนื้อหาถูกต้อง

   ★ วิธีแก้
       text-wrap: balance  ใช้กับหัวข้อ — เกลี่ยให้ทุกบรรทัดยาวใกล้เคียงกัน
       text-wrap: pretty   ใช้กับย่อหน้า — กันไม่ให้บรรทัดสุดท้ายเหลือคำเดียว
       .nw                 ครอบข้อความที่ห้ามฉีกกลาง เช่น วันที่ ชื่อหน่วยงาน

     เบราว์เซอร์ที่ยังไม่รองรับจะข้ามไปเฉย ๆ ไม่พัง
   ══════════════════════════════════════════════════════════ */
h1,h2,h3,.stat-v,.empty-t{text-wrap:balance}
p,.lead,.muted,.small,.tiny,.note-body,.faq-body,.dl-h,.fact-v,.mode-li{text-wrap:pretty}

/* ข้อความที่ต้องอยู่ครบเป็นชุด ห้ามฉีกกลาง */
.nw{white-space:nowrap}

/* แถบที่นั่งยืดออกจากศูนย์ */

/* ตัวเลขสำคัญใช้ตัวเลขความกว้างคงที่ จะได้ไม่กระตุกตอนไต่ขึ้น */
[data-count],.trust b,.stat-v{font-variant-numeric:tabular-nums}

/* เส้นสีทองใต้หัวข้อหมวด — จุดพักสายตาจากสีเขียวทั้งหน้า */
.section-head .eyebrow::after{background:linear-gradient(90deg,var(--gold-500),transparent)}

/* ป้ายสถานะบนหัวเรื่อง ให้จุดกะพริบช้า ๆ บอกว่าข้อมูลนี้เป็นปัจจุบัน */
.badge .dot{animation:pulseDot 2.4s ease-in-out infinite}
@keyframes pulseDot{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:.45;transform:scale(.82)}
}

/* การ์ดยกตัวเล็กน้อยเมื่อชี้ — บอกว่ากดได้ */
.card.lift{transition:transform 240ms var(--ease),box-shadow 240ms var(--ease),border-color 240ms var(--ease)}
.card.lift:hover{transform:translateY(-3px);box-shadow:var(--sh-2);border-color:var(--line-strong)}

@media (prefers-reduced-motion: reduce){
  .badge .dot{animation:none}
  .card.lift:hover{transform:none}
  .btn-primary:hover::after{animation:none;opacity:0}
}

/* ปรากฏตอนเลื่อนถึง — เคลื่อนไหวน้อย ๆ พอให้รู้สึกมีชีวิต */
[data-reveal]{opacity:0;transform:translateY(14px)}
[data-reveal].in{opacity:1;transform:none;
  transition:opacity 620ms var(--ease),transform 620ms var(--ease)}
@media (prefers-reduced-motion:reduce){
  [data-reveal]{opacity:1!important;transform:none!important}
}

/* ตราสถาบันบนแถบด้านบน */
.brand-mark{position:relative;overflow:hidden}
.brand-mark::after{
  content:"";position:absolute;inset:0;
  background:radial-gradient(70% 70% at 30% 20%,rgba(255,255,255,.28),transparent 60%);
}

/* ตารางอ่านง่ายขึ้นเมื่อข้อมูลเยอะ */
.tbl tbody tr:nth-child(even){background:color-mix(in srgb,var(--sunken) 55%,transparent)}
.tbl tbody tr:hover{background:var(--accent-soft)}

/* ป้ายสถานะ — ตัวหนาขึ้นนิด อ่านชัดในตารางยาว */
.badge{letter-spacing:.005em}

/* ---------- แถบค้นหาและตัวกรอง ----------
   ★ ย้ายมาจากสไตล์เฉพาะหน้าเจ้าหน้าที่
     หน้าประกาศรายชื่อเขียน class="toolbar" ไว้เหมือนกัน แต่คลาสนั้นมีอยู่แค่ในหน้าเจ้าหน้าที่
     ตัวกรองจึงลอยเรียงกันเองโดยไม่มีระยะห่างและไม่มีการขึ้นบรรทัดใหม่บนจอแคบ
     สองหน้าใช้ของหน้าตาเดียวกัน จึงต้องมีนิยามเดียวที่ใช้ร่วมกัน */
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:16px}
.searchbox{position:relative;flex:1;min-width:220px;max-width:380px}
.searchbox .input{padding-left:40px;height:40px}
.searchbox svg{
  position:absolute;left:13px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;color:var(--fg-subtle);pointer-events:none;
}
/* หน้าที่มีงานเดียวคือ "หาชื่อตัวเองให้เจอ" ให้ช่องค้นหาเด่นกว่าตัวกรองที่อยู่ข้าง ๆ */
.searchbox-lg{max-width:none;flex:2 1 300px}
.searchbox-lg .input{height:44px;font-size:.95rem}
@media (max-width:640px){
  .toolbar{gap:8px}
  .searchbox{max-width:none;min-width:0;flex:1 1 100%}
}

/* ★ ท้ายหน้าต้องอยู่ล่างสุดของจอเสมอ แม้เนื้อหาจะสั้น
   หน้าประกาศรายชื่อที่ค้นแล้วเจอไม่กี่ชื่อ ท้ายหน้าจะไปลอยกลางจอ
   แล้วมีพื้นที่ว่างเปล่าอยู่ข้างล่างอีกครึ่งจอ ซึ่งอ่านออกมาเหมือนหน้าเว็บโหลดไม่ครบ

   ★ จำกัดขอบเขตด้วย :has(footer.foot)
     มีแค่สามหน้าที่มีท้ายหน้า (หน้าแรก คลังข้อสอบ ประกาศรายชื่อ)
     หน้าเจ้าหน้าที่ใช้ .shell เป็นกริดเต็มจอ และหน้าสมัคร/ตรวจสอบสถานะไม่มีท้ายหน้า
     จึงไม่ควรไปเปลี่ยนวิธีจัดวางของหน้าเหล่านั้นโดยไม่จำเป็น

   ★ เบราว์เซอร์เก่าที่ไม่รู้จัก :has จะข้ามกฎนี้ไปทั้งก้อน
     ได้พฤติกรรมเดิมคือท้ายหน้าต่อจากเนื้อหา ซึ่งใช้งานได้ปกติ ไม่ได้พัง */
body:has(> footer.foot){
  min-height:100vh;
  min-height:100dvh;      /* บนมือถือ 100vh นับรวมแถบเบราว์เซอร์ที่ซ่อนได้ด้วย */
  display:flex;flex-direction:column;
}
body:has(> footer.foot) > *{flex-shrink:0}
body:has(> footer.foot) > footer.foot{margin-top:auto}

/* ท้ายเอกสาร
   ★ กระชับและเหมือนกันทุกหน้า
     เดิมแต่ละหน้าเขียน padding ของตัวเอง บางหน้าไม่เขียนเลย
     ท้ายหน้าจึงสูงไม่เท่ากันและกินพื้นที่เนื้อหาโดยไม่ได้ให้ข้อมูลเพิ่ม
     ท้ายหน้าเป็นที่สำหรับข้อมูลติดต่อ ไม่ใช่ส่วนที่ต้องแย่งสายตา */
footer.foot{
  position:relative;margin-top:44px;padding:22px 0;
  background:var(--paper);border-top:1px solid var(--line);
}
footer.foot .row-between{gap:14px;flex-wrap:wrap;align-items:center}
footer.foot .strong{font-size:.88rem}
@media (max-width:760px){
  footer.foot{margin-top:32px;padding:18px 0}
  footer.foot .row-between{flex-direction:column;align-items:flex-start;gap:12px}
}
footer.foot::before{
  content:"";position:absolute;inset:0 0 auto 0;height:2px;
  background:linear-gradient(90deg,transparent,var(--line-strong),transparent);
}


/* ลิงก์เข้าส่วนของเจ้าหน้าที่ในท้ายหน้า
   ★ วางไว้ท้ายหน้าโดยตั้งใจ ไม่ใช่บนแถบเมนู
     ผู้สมัครไม่มีวันต้องใช้ ถ้าเอาขึ้นไปอยู่ด้านบนจะกลายเป็นเสียงรบกวน
     และชวนให้คนสุ่มกดเข้าไปลองรหัสผ่านเล่น
     การซ่อนลิงก์ไม่ใช่ระบบความปลอดภัยอยู่แล้ว ตัวจริงคือ RLS ที่ฐานข้อมูล
     ลิงก์นี้จึงมีไว้เพื่อความสะดวก ไม่ได้ลดความปลอดภัยลง */
.staff-link{
  display:inline-flex;align-items:center;gap:5px;vertical-align:-2px;
  color:var(--fg-subtle);font-weight:500;
  transition:color var(--dur) var(--ease);
}
.staff-link svg{width:12px;height:12px}
.staff-link:hover{color:var(--accent);text-decoration:none}


/* ══════════════════════════════════════════════════════════
   เมนูสำหรับจอแคบ

   ★ ปัญหาเดิม: แถบลิงก์ถูกซ่อนบนมือถือโดยไม่มีอะไรมาแทน
     ผู้ใช้บนมือถือจึงข้ามไปหน้าอื่นไม่ได้เลย ต้องกดปุ่มที่บังเอิญอยู่ในเนื้อหา
     ซึ่งบางหน้าก็ไม่มี
   ══════════════════════════════════════════════════════════ */
.navtoggle{display:none}

.navsheet{
  display:flex;flex-direction:column;
  border-top:1px solid var(--line);background:var(--paper);
  padding:6px;gap:2px;
  animation:sheetIn 180ms var(--ease) both;
}
.navsheet a{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 14px;border-radius:var(--r-sm);
  font-size:.94rem;font-weight:500;color:var(--fg-muted);
}
.navsheet a:hover{background:var(--sunken);color:var(--fg);text-decoration:none}
.navsheet a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.navsheet a svg{width:16px;height:16px}

@keyframes sheetIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){ .navsheet{animation:none} }

/* จอกว้างไม่ต้องใช้แผงนี้ — แถบลิงก์ปกติแสดงอยู่แล้ว
   จุดตัดต้องตรงกับ 760px ที่ใช้ซ่อนแถบลิงก์ ไม่งั้นจะมีช่วงที่ไม่มีเมนูทั้งสองแบบ */
@media (min-width:761px){ .navsheet{display:none!important} }


/* กล่องแจ้งเมื่อโหลดข้อมูลตั้งต้นไม่สำเร็จ — ต้องเห็นก่อนเนื้อหาอื่นทั้งหมด */
.bootfail{position:sticky;top:0;z-index:120;padding:12px 16px;background:var(--canvas)}
.bootfail .note{max-width:1160px;margin-inline:auto;align-items:center}
