/* ============================================================================
   สนามหมู — Design Tokens + Primitives
   ----------------------------------------------------------------------------
   ธีสิส: หน้าจอคือ "กระดาษคำตอบ" ไม่ใช่ "แอปควิซ"

   สีเส้นโครงสร้างทั้งเว็บใช้ "ฟ้าหลุดสแกน" (dropout blue) — สีที่กระดาษคำตอบ
   OMR ใช้พิมพ์เส้น เพราะเครื่องสแกนมองไม่เห็นสีนี้ เป็นสีที่มาจากโลกของ
   เรื่องนี้จริง ไม่ใช่สีที่หยิบมาลอย ๆ

   ตัวอย่างเรนเดอร์เต็ม ๆ ดูได้ที่ data/brand/design_preview.html
   ============================================================================ */

/* --- โหมดสว่าง (ค่าเริ่มต้น) ---------------------------------------------- */
:root {
  --paper:      #EFF2F3;  /* พื้น — เทาอมฟ้า "กระดาษคำตอบใต้ไฟฟลูออเรสเซนต์"
                             จงใจไม่ใช้ขาว 100% เพราะคนใช้เว็บนี้ตอนสี่ทุ่ม
                             บนมือถือ ขาวสนิทบนจอ OLED กลางคืน = แสงแยงตา */
  --sheet:      #FBFCFC;  /* การ์ด — แผ่นกระดาษที่วางบนพื้น */
  --ink:        #16243B;  /* ตัวอักษรหลัก — น้ำเงินเข้มเกือบดำ ไม่ใช่ดำสนิท */
  --ink-soft:   #5C6B7E;
  --ink-faint:  #93A1B0;
  --dropout:    #C7DDE8;  /* ฟ้าหลุดสแกน — เส้นคั่น ขอบวงฝน รางเวลา */
  --dropout-dp: #A8C9DA;
  --accent:     #F4703A;  /* ส้ม (สีเดียวกับมาสคอต) — ปุ่มหลักเท่านั้น ใช้ให้น้อย */
  --accent-dim: #FCE9E0;
  --good:       #0E8A6A;  /* เขียวอมฟ้า — ตอบถูก (ไม่ใช่เขียวสด) */
  --good-dim:   #DDF0E9;
  --warm:       #C77A1E;  /* ★ เหลืองอำพัน — "ยังไม่ผ่าน" จงใจไม่ใช้แดง
                             ตลาดนี้ผ่านแค่ ~4% หน้าตอบผิดคือหน้าที่คนเห็นบ่อยที่สุด
                             ถ้ากระแทกแดงทุกครั้ง คนเลิกใช้ก่อนเก่ง
                             และแดง/เขียวเป็นคู่สีที่ผู้ชายราว 8% แยกไม่ออก */
  --warm-dim:   #FBEEDA;
  --danger:     #B3392F;  /* ใช้เฉพาะปุ่มทำลายข้อมูลจริง ๆ เท่านั้น */
  --pencil:     #3D4451;  /* เทาดินสอ 2B — สีที่ฝนวงคำตอบ */

  /* ★ แถบเข้มเต็มความกว้าง (full-bleed) ของหน้าบ้าน — ใช้คั่นจังหวะหน้ายาว ๆ
     ★★ ต้องเป็น token ของตัวเอง ห้ามยืม --ink มาเป็นพื้น
        เพราะโหมดมืด --ink กลายเป็นสีเกือบขาว → แถบจะเป็นแผ่นขาวแยงตา
        กลางหน้าจอมืด ซึ่งตรงข้ามกับเหตุผลที่เรามีโหมดมืด
     โหมดสว่าง = น้ำเงินหมึกเข้ม · โหมดมืด = เข้มกว่าพื้นลงไปอีกขั้น */
  --band:       #16243B;
  --band-ink:   #EFF2F3;
  --band-soft:  #93A1B0;

  --shadow-1: 0 1px 2px rgba(22,36,59,.06);
  --shadow-2: 0 1px 2px rgba(22,36,59,.06), 0 6px 20px rgba(22,36,59,.06);

  --radius-sm: 9px;
  --radius:    14px;
  --radius-lg: 20px;
  --tap:       52px;      /* เป้ากดขั้นต่ำ — เว็บนี้ถูกใช้มือเดียวบนรถไฟฟ้า */

  /* ขั้นขนาดตัวอักษร */
  --fs-xs: 12px; --fs-sm: 13px; --fs-md: 15px;
  --fs-base: 17px; --fs-lg: 19px; --fs-xl: 24px; --fs-2xl: 30px;

  /* ★ line-height ของไทยต้องสูงกว่าละติน — สระบน/ล่างและวรรณยุกต์ซ้อนกันได้
     ถึง 4 ชั้น ถ้าใช้ 1.5 แบบมาตรฐานฝรั่ง ตัวอักษรจะชนกันจนอ่านนาน ๆ แล้วล้า */
  --lh-tight: 1.45;
  --lh-base:  1.85;
  --lh-loose: 2.0;

  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 22px; --sp-6: 30px; --sp-7: 44px; --sp-8: 64px;
}

/* --- โหมดมืด ---------------------------------------------------------------
   ผู้ใช้ส่วนใหญ่ทำข้อสอบตอนกลางคืนหลังเลิกงาน โหมดมืดไม่ใช่ของแถม
   ห้ามกลับสีแบบตรงไปตรงมา — ปรับให้คอนทราสต์ยังอ่านได้และสีเน้นยังทำงาน */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:#121A20; --sheet:#1A242C; --ink:#E4EAEC; --ink-soft:#9AAAB4;
    --ink-faint:#687883; --dropout:#2E4A58; --dropout-dp:#3E6070;
    --accent:#F0793F; --accent-dim:#3A2318;
    --good:#3FBF97;   --good-dim:#12312A;
    --warm:#E0A44A;   --warm-dim:#382A15;
    --danger:#E06A5E; --pencil:#C3CCD3;
    --band:#0B1116; --band-ink:#E4EAEC; --band-soft:#8A9AA5;
    --shadow-1: 0 1px 2px rgba(0,0,0,.4);
    --shadow-2: 0 1px 2px rgba(0,0,0,.4), 0 8px 26px rgba(0,0,0,.34);
  }
}
/* ปุ่มสลับธีมของผู้ใช้ต้องชนะ media query ทั้งสองทิศทาง */
:root[data-theme="dark"] {
  --paper:#121A20; --sheet:#1A242C; --ink:#E4EAEC; --ink-soft:#9AAAB4;
  --ink-faint:#687883; --dropout:#2E4A58; --dropout-dp:#3E6070;
  --accent:#F0793F; --accent-dim:#3A2318;
  --good:#3FBF97;   --good-dim:#12312A;
  --warm:#E0A44A;   --warm-dim:#382A15;
  --danger:#E06A5E; --pencil:#C3CCD3;
  --band:#0B1116; --band-ink:#E4EAEC; --band-soft:#8A9AA5;
  --shadow-1: 0 1px 2px rgba(0,0,0,.4);
  --shadow-2: 0 1px 2px rgba(0,0,0,.4), 0 8px 26px rgba(0,0,0,.34);
}

/* ============================================================================
   ฟอนต์ — self-host เท่านั้น ห้ามลิงก์ Google Fonts CDN
   (คนใช้เว็บนี้เน็ตมือถือ + เราอยากคุมความเร็วเอง + PWA ต้องใช้ offline ได้)

   คู่ฟอนต์ที่เลือก — เป็นตระกูลเดียวกันแต่คนละสายพันธุ์โดยตั้งใจ:
     หัวข้อ = IBM Plex Sans Thai (ไม่มีหัว)  → คมชัด ทันสมัย
     เนื้อหา = IBM Plex Sans Thai Looped (มีหัว) → หัวช่วยให้กวาดสายตาอ่านยาว ๆ ได้เร็ว
   วางไฟล์ woff2 ที่ static/fonts/ แล้วปลด @font-face ข้างล่าง
   ============================================================================ */
/*
@font-face { font-family:"IBM Plex Sans Thai Looped"; font-weight:400; font-display:swap;
             src:url("/static/fonts/IBMPlexSansThaiLooped-Regular.woff2") format("woff2"); }
@font-face { font-family:"IBM Plex Sans Thai Looped"; font-weight:600; font-display:swap;
             src:url("/static/fonts/IBMPlexSansThaiLooped-SemiBold.woff2") format("woff2"); }
@font-face { font-family:"IBM Plex Sans Thai"; font-weight:700; font-display:swap;
             src:url("/static/fonts/IBMPlexSansThai-Bold.woff2") format("woff2"); }
*/

/* ============================================================================
   Base
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "IBM Plex Sans Thai Looped", "IBM Plex Sans Thai",
               -apple-system, BlinkMacSystemFont, "Noto Sans Thai", "Segoe UI", sans-serif;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  /* ★ iOS: แถบล่างของ Safari ทำให้ 100vh สูงเกินจริงจนเนื้อหาโดนบัง ใช้ dvh แทน */
  min-height: 100dvh;
  padding-bottom: env(safe-area-inset-bottom);
}

h1, h2, h3, h4 {
  font-family: "IBM Plex Sans Thai", "IBM Plex Sans Thai Looped",
               -apple-system, "Noto Sans Thai", sans-serif;
  line-height: var(--lh-tight);
  text-wrap: balance;
  margin: 0 0 var(--sp-3);
}
h1 { font-size: var(--fs-2xl); font-weight: 700; }
h2 { font-size: var(--fs-xl);  font-weight: 700; }
h3 { font-size: var(--fs-lg);  font-weight: 700; }

p { margin: 0 0 var(--sp-4); }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* ปุ่มในฟอร์ม POST ที่หน้าตาเป็นลิงก์ (สลับค่าตั้ง ฯลฯ — GET แก้ข้อมูลไม่ได้) */
.linklike { background: none; border: 0; padding: 0; font: inherit; color: var(--accent);
            text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; cursor: pointer; }

/* คีย์บอร์ดต้องเห็นโฟกัสเสมอ — คนใช้ iPad ต่อคีย์บอร์ดทำข้อสอบก็มี */
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* ★ iOS ซูมหน้าเองทุกครั้งที่แตะ input ที่ font-size < 16px */
input, select, textarea, button { font: inherit; font-size: max(16px, 1em); }

/* ตัวเลขที่ต้องเรียงเป็นคอลัมน์ (คะแนน เวลา จำนวนข้อ) ต้องกว้างเท่ากันทุกตัว */
.tnum, table, .score, .timer-text { font-variant-numeric: tabular-nums; }

/* ตารางกว้างเกินจอต้องเลื่อนในกล่องตัวเอง ห้ามให้ body เลื่อนแนวนอน
   ★★ position: relative จำเป็นจริง ไม่ใช่ของแถม — วัดแล้วว่าถ้าไม่มี หน้าจะเลื่อน
      แนวนอนได้ทั้งหน้าโดยที่ตารางเองถูก clip อยู่ดี (หาต้นเหตุยากมาก)
      สาเหตุ: .sr-only ใช้ position:absolute · ถ้ากล่อง scroll ไม่ใช่ positioned
      ancestor, containing block ของมันจะกระโดดออกไปข้างนอกกล่อง → **ไม่ถูก clip**
      แล้ว span ที่อยู่ในคอลัมน์ขวาสุดของตารางกว้าง 456px ก็ไปยืด document
      ให้กว้าง 449px ทั้งที่จอ 390px (เจอจริงในตารางเทียบของหน้าแรก)
      ตัว relative นี้ดึง containing block กลับเข้ามาในกล่อง → ถูก clip ตามที่ควร */
.scroll-x { position: relative; overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ============================================================================
   Layout
   ============================================================================ */
.wrap { max-width: 640px; margin-inline: auto; padding-inline: var(--sp-4); }

/* ★ iPad ไม่ใช่ "มือถือที่ยืดกว้าง" — ใช้พื้นที่ให้เป็นประโยชน์
   โจทย์ซ้าย เฉลยขวา เทียบไปมาได้โดยไม่ต้องเลื่อน */
@media (min-width: 900px) {
  .wrap { max-width: 1080px; }
  .split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); align-items: start; }
}

.sheet {
  background: var(--sheet);
  border: 1px solid var(--dropout);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  padding: var(--sp-5) var(--sp-4);
}

/* ============================================================================
   ปุ่ม
   ============================================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--tap); padding-inline: var(--sp-5);
  border: 1.5px solid transparent; border-radius: 12px;
  font-weight: 700; cursor: pointer;
  /* ★ ปุ่มที่เป็น <a> ต้องไม่มีเส้นใต้ — กฎ a{} ด้านบนใส่เส้นใต้ให้ทุกลิงก์
     ซึ่งถูกต้องสำหรับลิงก์ในเนื้อความ แต่บนปุ่มสีทึบมันดูเหมือนหลุด
     (ไม่กระทบการเข้าถึง เพราะปุ่มแยกจากพื้นด้วยสี+กรอบ+ขนาด ไม่ได้แยกด้วยสีเดียว) */
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, border-color .15s;
}
.btn-primary { background: var(--accent); color: #fff; width: 100%; }
.btn-primary:disabled { background: var(--dropout); color: var(--ink-faint); cursor: default; }
.btn-quiet { background: var(--sheet); color: var(--ink); border-color: var(--dropout); }
.btn-ghost { background: transparent; color: var(--ink-soft); border-color: transparent; }

/* ============================================================================
   ตัวเลือกคำตอบ = แถววงฝน OMR
   กดแล้ววงฝนดำเหมือนใช้ดินสอ 2B — คนที่เคยลงสนามสอบไทยจำสัมผัสนี้ได้ทันที
   และทำให้การเลือกคำตอบรู้สึกเป็นการ "ลงมือ" ไม่ใช่แค่กดปุ่ม
   ============================================================================ */
.choices { display: flex; flex-direction: column; gap: 10px; }

.choice {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; min-height: var(--tap);
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-3);
  background: var(--sheet); color: inherit;
  border: 1.5px solid var(--dropout); border-radius: 12px;
  text-align: start; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: border-color .15s, background .15s;
}
.choice:hover:not(:disabled) { border-color: var(--dropout-dp); }
.choice:disabled { cursor: default; }

.choice__bubble {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid var(--dropout-dp);
  display: grid; place-items: center;
  font-size: var(--fs-sm); font-weight: 700; color: var(--ink-soft);
  transition: background .18s, color .18s, border-color .18s;
}
.choice__text { flex: 1; }
.choice__mark { flex: none; font-size: 18px; font-weight: 700; opacity: 0; transition: opacity .2s; }

.choice.is-picked .choice__bubble {
  background: var(--pencil); border-color: var(--pencil); color: var(--sheet);
}

/* ── ขั้น "เลือกแล้ว รอยืนยัน" ────────────────────────────────────────────
   ต้องเห็นชัดว่ายังไม่ส่ง ไม่งั้นผู้ใช้จะนึกว่าตอบไปแล้วแล้วนั่งรอ
   ป้ายยืนยันซ่อนไว้จนกว่าจะเลือก — ★ ใช้ visibility ไม่ใช่ display
   เพื่อให้ปุ่มจองที่ไว้เท่าเดิมตั้งแต่แรก ถ้าปล่อยให้ความสูงเปลี่ยนตอนเลือก
   ของข้างล่างจะขยับหนีนิ้วพอดีจังหวะแตะครั้งที่สอง = สร้างการกดพลาดเสียเอง */
.choice__confirm {
  flex: none; visibility: hidden;
  font-size: var(--fs-sm); font-weight: 700; color: var(--pencil);
  white-space: nowrap;
}
.choice.is-picked { border-color: var(--pencil); }
.choice.is-picked .choice__confirm { visibility: visible; }
/* ระหว่างรอเซิร์ฟเวอร์ตอบ — บอกว่ารับแล้ว และกันแตะซ้ำด้วยสายตาอีกชั้น
   (ชั้นที่กันจริงคือธงใน JS ไม่ใช่ pointer-events อันนี้แค่ทำให้ไม่สับสน) */
.is-sending .choice { opacity: .55; pointer-events: none; }
.choices__hint { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--ink-soft); }

/* จอแคบ: ป้ายยืนยันกินที่จนข้อความตัวเลือกบีบ → ให้ลงบรรทัดใหม่แทน
   ★ ยังคง visibility (ไม่ใช่ display:none) ด้วยเหตุผลเดียวกับข้างบน —
     บรรทัดนี้ต้องจองที่ไว้ตลอด ไม่ใช่โผล่มาตอนเลือกแล้วดันของข้างล่าง */
@media (max-width: 480px) {
  .choice { flex-wrap: wrap; }
  .choice__confirm { width: 100%; padding-inline-start: calc(30px + var(--sp-3)); }
}
.choice.is-correct { border-color: var(--good); background: var(--good-dim); }
.choice.is-correct .choice__bubble { background: var(--good); border-color: var(--good); color: #fff; }
.choice.is-correct .choice__mark { opacity: 1; color: var(--good); }

/* "ยังไม่ผ่าน" ไม่ใช่ "ผิด" — สีและคำต้องไปด้วยกัน */
.choice.is-missed { border-color: var(--warm); background: var(--warm-dim); }
.choice.is-missed .choice__bubble { background: var(--warm); border-color: var(--warm); color: #fff; }
.choice.is-missed .choice__mark { opacity: 1; color: var(--warm); }

/* ============================================================================
   รางเวลา — เส้นบาง ไม่ใช่ตัวเลขนับถอยหลังสีแดง
   จังหวะคือครึ่งหนึ่งของเกม ก.พ. (100 ข้อจับเวลา) แต่ตัวเลขวิ่งถอยหลัง
   ทำให้คนตื่นตระหนกจนคิดไม่ออก รางที่ค่อย ๆ ลดเห็นได้แต่ไม่ทวงถาม
   ============================================================================ */
.timer { height: 3px; background: var(--dropout); position: relative; overflow: hidden; }
.timer__fill { position: absolute; inset: 0 auto 0 0; background: var(--dropout-dp); transition: width 1s linear; }
.timer--over .timer__fill { background: var(--warm); }

/* ============================================================================
   เฉลยขั้นบันได — เปิดทีละชั้น ไม่เทลงมาทั้งกำแพง
   ============================================================================ */
.layer { border: 1px solid var(--dropout); border-radius: var(--radius); background: var(--sheet); overflow: hidden; }
.layer + .layer { margin-top: 10px; }

/* ชั้น 0 — กระจกสะท้อนความผิด (ขึ้นทันที ไม่ต้องกด)
   บอกว่า "ทำไม*คุณ*ถึงตอบข้อนั้น" ไม่ใช่ "เฉลยข้อ ข." */
.layer--mirror { border-color: var(--warm); background: var(--warm-dim); padding: var(--sp-4); }
.layer--mirror.is-correct { border-color: var(--good); background: var(--good-dim); }

.layer__label { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em; color: var(--warm); }
.layer--mirror.is-correct .layer__label { color: var(--good); }

/* ชั้น 1 — ขั้นบันได */
.step { display: flex; gap: var(--sp-3); padding: var(--sp-4) 0; border-top: 1px dashed var(--dropout); }
.step:first-of-type { border-top: 0; }
.step__no {
  flex: none; width: 26px; height: 26px; border-radius: 50%; margin-top: 3px;
  background: var(--paper); border: 1px solid var(--dropout);
  display: grid; place-items: center; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-soft);
}
.calc {
  margin-top: var(--sp-2); padding: 9px var(--sp-3);
  background: var(--paper); border: 1px solid var(--dropout); border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums; overflow-x: auto; white-space: nowrap;
}

/* ชั้น 3 — ข้อฝาแฝด (ตัวที่แปลง "รู้" เป็น "ทำได้") */
.layer--twin { border-color: var(--good); background: var(--good-dim); padding: var(--sp-4); }

/* ============================================================================
   ป้ายสถานะ
   ============================================================================ */
.tag {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  background: var(--paper); border: 1px solid var(--dropout);
  font-size: var(--fs-xs); color: var(--ink-soft); line-height: 1.7;
}
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px;
        border-radius: 999px; font-size: var(--fs-sm); font-weight: 600; }
.pill--streak { background: var(--accent-dim); color: var(--accent); }
.pill--good   { background: var(--good-dim);   color: var(--good); }
.pill--warm   { background: var(--warm-dim);   color: var(--warm); }

/* จุดบอกความคืบหน้าของชุด */
.dots { display: flex; gap: 4px; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dropout); }
.dot--done { background: var(--good); }
.dot--miss { background: var(--warm); }
.dot--now  { background: var(--ink); }

/* ============================================================================
   แถบบน — ต้องเผื่อ notch ของ iPhone
   ============================================================================ */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--dropout);
  padding-top: env(safe-area-inset-top);
}

/* แถบล่างแบบติดจอ (โหมดทำข้อสอบ) — ปุ่มต้องไม่โดนแถบ home indicator ทับ */
.bottombar {
  position: sticky; bottom: 0; z-index: 20;
  background: var(--paper);
  border-top: 1px solid var(--dropout);
  padding: var(--sp-3) var(--sp-4);
  padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom));
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
