/* ============================================================
   app.css — ระบบดีไซน์เว็บแผนการฝึกอาชีพ (ทวิภาคี)
   จัดเรียงตาม docs/11 §8: 1)tokens light 2)dark 3)base 4)layout
   5)components 6)utilities 7)responsive — ทุกสีผ่าน token
   ============================================================ */

/* ---------- 0) FONTS (local, ออฟไลน์) ---------- */
@font-face{ font-family:"Sarabun"; src:url("../fonts/thsarabunnew.woff2") format("woff2"); font-weight:400; font-display:swap; }
@font-face{ font-family:"Sarabun"; src:url("../fonts/thsarabunnew_bold.woff2") format("woff2"); font-weight:700; font-display:swap; }
@font-face{ font-family:"Prompt"; src:url("../fonts/Prompt-Regular.ttf") format("truetype"); font-weight:500; font-display:swap; }
@font-face{ font-family:"Prompt"; src:url("../fonts/Prompt-SemiBold.ttf") format("truetype"); font-weight:600; font-display:swap; }
/* PKMaehongson — เวอร์ชันเต็ม (สระ/วรรณยุกต์ไทยครบ) · Medium=ปกติ, SemiBold=600, Bold=หนา, Italic=เอียง */
@font-face{ font-family:"PKMaehongson"; font-weight:400; font-style:normal; font-display:swap;
  src:url("../fonts/PK-Maehongson-Medium.woff2") format("woff2"),
      url("../fonts/PK-Maehongson-Medium.woff") format("woff"),
      url("../fonts/PK-Maehongson-Medium.ttf") format("truetype"); }
@font-face{ font-family:"PKMaehongson"; font-weight:600; font-style:normal; font-display:swap;
  src:url("../fonts/PK-Maehongson-SemiBold.woff2") format("woff2"),
      url("../fonts/PK-Maehongson-SemiBold.woff") format("woff"); }
@font-face{ font-family:"PKMaehongson"; font-weight:700; font-style:normal; font-display:swap;
  src:url("../fonts/PK-Maehongson-Bold.woff2") format("woff2"),
      url("../fonts/PK-Maehongson-Bold.woff") format("woff"),
      url("../fonts/PK-Maehongson-Bold.ttf") format("truetype"); }
@font-face{ font-family:"PKMaehongson"; font-weight:400; font-style:italic; font-display:swap;
  src:url("../fonts/PK-Maehongson-Italic.woff2") format("woff2"),
      url("../fonts/PK-Maehongson-Italic.woff") format("woff"),
      url("../fonts/PK-Maehongson-Italic.ttf") format("truetype"); }

/* ---------- 1) TOKENS (LIGHT) ---------- */
/* ⭐⭐ 7 ก.ย. 2569 — โทน "ของเดิมปรับให้เนี้ยบ" (ครูเลือกเอง) + แบบ 06 นุ่มมีมิติ
   สีทุกตัวยังเป็นตระกูลเดิมของ VPLAN แค่ทำน้ำเงินเข้มขึ้นและพื้นหลังนิ่งขึ้น
   ตรวจค่าความต่างสีแล้วทุกคู่ผ่าน 4.5:1 · เกือบทุกคู่ผ่าน 7:1 (เกณฑ์สูงสุด)
   ⛔ --k --s --a --ap และ --st-* ไม่แตะ — เป็นสีความหมายของ K/S/A/Ap และแถบขั้นตอนที่ทำไว้ดีแล้ว
   ย้อนกลับทั้งหมด: คืนไฟล์จาก _backup_20260907_ui1/css/app.css */
:root{
  --brand:#014a7c; --brand2:#2e86c1; --brand-d:#01395e;
  --ink:#17232f; --muted:#5b6b7a; --line:#dbe4ee;
  --bg:#eef2f7; --surface:#ffffff; --surface2:#f5f8fc;
  /* ⛔ --ok --okbg คืนค่าเดิมแล้ว (7 ก.ย. รอบตรวจ) — ยาม tests/test_stepper_ui.js ข้อ [0]
     ล็อกสีวงขั้นปัจจุบันไว้ที่ rgb(30,126,70) ผมเผลอทำให้เข้มขึ้นเป็น #146b3c ยามจับได้
     ค่าเดิมผ่านเกณฑ์อยู่แล้ว: ขาวบนเขียว 5.09:1 · เขียวบนพื้นเขียวอ่อน 4.55:1 (ผ่าน AA)
     ⛔ ห้ามแตะ 2 ตัวนี้อีก ถ้าไม่ได้แก้ยามพร้อมกัน */
  --ok:#1e7e46; --okbg:#e6f6ec; --warn:#8a5008; --warnbg:#fbf1e3;
  --err:#a41f27; --errbg:#fbeaea; --info:#014a7c; --infobg:#e8f1f8;
  --k:#2563eb; --s:#0891b2; --a:#db2777; --ap:#7c3aed;
  /* แถบขั้นตอน (24 ส.ค. 2569) — วงที่ยังไม่ถึง / สีของเครื่องหมายบนวงเขียว */
  --st-pend:#dfe4ea; --st-fg:#ffffff;
  /* สีปุ่มผู้ช่วย AI — ม่วงทึบสีเดียวทั้งระบบ · ตัวหนังสือขาวบนสีนี้ได้ 7.10:1 (ผ่าน AAA)
     เลือก #6d28d9 เพราะเป็นม่วงที่ระบบใช้อยู่แล้วใน plan-lesson.css (12 จุด) */
  --accent:#6d28d9;
  /* แบบ 06 นุ่มมีมิติ — มุมมนค่าเดียวทั้งระบบ · เงา 2 ชั้น · ทุกอย่างที่กดได้สูง 44px */
  --radius:12px; --radius-sm:9px; --btn-radius:10px; --tap:44px;
  --shadow:0 1px 2px rgba(20,45,70,.07), 0 14px 30px -16px rgba(20,45,70,.34);
  --shadow-sm:0 1px 2px rgba(20,45,70,.06), 0 6px 14px -8px rgba(20,45,70,.26);
  --font:"PKMaehongson","Sarabun","Segoe UI",Tahoma,sans-serif;
  --font-head:"PKMaehongson","Sarabun",sans-serif;
}
/* ---------- 2) TOKENS (DARK) ---------- */
:root[data-theme="dark"]{
  --brand:#4a9fd4; --brand2:#5cb0e0; --brand-d:#3b83b0;
  --ink:#e6edf3; --muted:#9aa7b4; --line:#26313d;
  --bg:#0f171e; --surface:#18222c; --surface2:#1d2a35;
  --ok:#4ade80; --okbg:#123020; --warn:#e0a44a; --warnbg:#332614;
  --err:#f87171; --errbg:#3a1a1a; --info:#7ab8e6; --infobg:#14283a;
  /* โหมดมืด --ok เป็นเขียวสด เครื่องหมายบนวงจึงต้องเป็นสีเข้ม ไม่ใช่ขาว ไม่งั้นจะจ้าอ่านไม่ออก */
  --st-pend:#2b3743; --st-fg:#08150e;
  --accent:#9d7cf0;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 14px 30px -16px rgba(0,0,0,.75);
  --shadow-sm:0 1px 2px rgba(0,0,0,.35), 0 6px 14px -8px rgba(0,0,0,.6);
}
/* ⚠️ 7 ก.ย. 2569 — บล็อกโหมดมืดข้างบนนี้ "เก็บไว้ครบ ไม่ได้ลบ"
   ตอนนี้ปุ่มสลับธีมถูกซ่อนใน partials/header.php และ head.php ล้าง cookie ทิ้ง
   ⇒ ไม่มีทางเข้าถึงโหมดมืดได้ จนกว่าจะเปิดปุ่มคืน
   ⛔ ก่อนเปิดคืน ต้องไล่แก้สีที่พิมพ์ตายตัวให้หมดก่อน (712 จุด · ดูบันทึก audit_uxui_20260907.md)
      ต้นเหตุคือกฎที่ผสม "พื้นพิมพ์ตายตัว + ตัวหนังสือใช้ตัวแปร" เช่น .inp เดิมที่แก้ไปแล้วในรอบนี้ */

.pav9-box{ margin-top:14px; background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:18px 18px 16px; box-shadow:var(--shadow-sm); position:relative; overflow:hidden; }
.pav9-box::before{ content:''; position:absolute; top:0; left:0; right:0; height:3px;
  background:linear-gradient(90deg,#6b7280,#2f6f9f,#d97706,#7c3aed,#db2777); opacity:.85; }
.pav0-box{ margin-top:14px;  border:1px solid var(--line); border-radius:var(--radius);
  padding:18px 18px 16px; box-shadow:var(--shadow-sm); position:relative; overflow:hidden; }
.pav0-box::before{ content:''; position:absolute; top:0; left:0; right:0; height:3px;
  background:linear-gradient(90deg,#6b7280,#2f6f9f,#d97706,#7c3aed,#db2777); opacity:.85; }

/* ---------- 3) BASE ---------- */
*{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; text-size-adjust:100%; -webkit-tap-highlight-color:transparent; }
html,body{ margin:0; }
body{ font-family:var(--font); color:var(--ink); background:var(--bg); font-size:1.2rem; line-height:1.5;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; overflow-wrap:break-word; word-break:break-word; }
h1,h2,h3,h4,.font-head{ font-family:var(--font-head); }
a{ color:var(--brand); }
img,svg,video,canvas{ max-width:100%; height:auto; }
button{ font-family:inherit; }
:focus-visible{ outline:2px solid var(--brand2); outline-offset:1px; }
/* เคารพผู้ใช้ที่ตั้งค่าลดการเคลื่อนไหว */
@media(prefers-reduced-motion:reduce){ *{ animation-duration:.001ms !important; transition-duration:.001ms !important; } }
.bshadows{box-shadow: 0 6px 18px rgba(31, 95, 139, .10);}
/* ---------- 4) LAYOUT (APP SHELL) ---------- */
.app{ display:grid; grid-template-columns:236px 1fr; min-height:100vh; }
.side{ background:var(--surface); border-right:1px solid var(--line); position:sticky; top:0; height:100vh; overflow:auto; }
.side .brand{ display:flex; align-items:center; gap:10px; padding:10px; border-bottom:1px solid var(--line); font-weight:700; font-family:var(--font-head); }
.side .brand .mk{ width:36px; height:36px; border-radius:var(--radius-sm); background:var(--brand); display:grid; place-items:center; color:#fff; font-size:17px; }
.side .brand small{ display:block; font-weight:400; font-size:0.9rem; color:var(--muted); font-family:var(--font); }
.nav{ padding:10px; }
.nav a{ display:flex; align-items:center; gap:11px; padding:0 12px; min-height:var(--tap); border-radius:var(--radius-sm); color:var(--ink); text-decoration:none; font-size:1.1rem; margin-bottom:2px; cursor:pointer; }
.nav a .i{ width:20px; text-align:center; color:var(--muted); }
.nav a:hover{ background:var(--surface2); }
/* แบบ 06 — เมนูที่เลือกเปลี่ยนจากไล่เฉดเป็นสีทึบ ไล่เฉดเหลือที่เดียวคือปุ่มหลัก */
.nav a.sel{ background:var(--brand); color:#fff; box-shadow:var(--shadow-sm); }
.nav a.sel .i{ color:#fff; }
.nav .cap{ font-size:0.85rem; letter-spacing:.5px; color:var(--muted); padding:14px 12px 4px; text-transform:uppercase; }
.content{ display:flex; flex-direction:column; min-width:0; }
.topbar{ background:var(--surface); border-bottom:1px solid var(--line); position:sticky; top:0; z-index:20; }
.topbar .inner{ display:flex; align-items:center; gap:12px; padding:11px 20px; }
.topbar .menu-btn{ display:inline-flex; align-items:center; justify-content:center; width:var(--tap); height:var(--tap); background:none; border:1px solid var(--line); border-radius:var(--radius-sm); font-size:18px; color:var(--ink); cursor:pointer; }
.topbar .menu-btn:hover{ background:var(--surface2); }
.main{ padding:22px 26px 60px; max-width:100%; width:100%; margin:0 auto; }

/* ---------- 5) COMPONENTS ---------- */
.card{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:20px 22px; margin-bottom:18px; box-shadow:var(--shadow-sm); }
.card h3{ margin:0 0 14px; font-size:1.25rem; display:flex; align-items:center; gap:8px; }
/* แบบ 06 — หัวเรื่องเป็นสีทึบ ไม่ไล่เฉด (ดูบล็อก 8 ท้ายไฟล์ ที่เอาแสงวิ่งออกด้วย) */
.hero{ margin-bottom:10px; background:var(--brand); color:#fff; border-radius:var(--radius); padding:24px 26px; box-shadow:var(--shadow); }
.hero h1{ margin:0 0 6px; font-size:22px; } .hero p{ margin:0; opacity:.93; }

label.f{ display:flex; align-items:center; flex-wrap:wrap; gap:6px; min-height:30px; font-size:1.1rem; font-weight:600; margin-bottom:6px; color:var(--ink); }
/* ⚠️ background เดิมเป็น #fff พิมพ์ตายตัว คู่กับ color:var(--ink) — เป็นต้นเหตุที่โหมดมืดอ่านไม่ออก
   เปลี่ยนเป็น var(--surface) แล้ว โหมดสว่างได้สีขาวเท่าเดิมทุกประการ (#ffffff) แต่โหมดมืดจะถูกต้องด้วย */
.inp,select.inp,textarea.inp{line-height: 1.1; width:100%; padding:10px 10px; min-height:var(--tap); border:1px solid var(--line); border-radius:var(--radius-sm); font:inherit; font-size:1.1rem; background:var(--surface); color:var(--ink); }
.inp:focus{ outline:2px solid var(--brand2); border-color:var(--brand2); }

/* ⚠️ 7 ก.ย. รอบแก้คืน — ถอด justify-content:center ที่ผมเผลอเติมตอนเช้าออก
   มันไม่ได้อยู่ในแผน และทำให้การจัดวางเนื้อในปุ่มบางตัวเปลี่ยนไปจากเดิม
   (ปุ่มหลักบนมือถือยังได้ justify-content:center จากกฎ @media(max-width:560px) เหมือนเดิม) */
.btn{ text-decoration: none; font:inherit; font-size:1.05rem; border:none; border-radius:var(--btn-radius); padding:9px 20px; min-height:var(--tap); cursor:pointer; font-weight:600; display:inline-flex; align-items:center; gap:7px; }
.btn.primary{ background:linear-gradient(135deg,var(--brand),var(--brand2)); color:#fff; box-shadow:var(--shadow-sm); }
.btn.ghost{ background:var(--surface); border:1px solid var(--line); color:var(--ink); }
.btn.soft{ background:var(--infobg); color:var(--brand); }
/* ปุ่มเล็กในตาราง/แถบเครื่องมือ — ยกจาก 3px เป็น 36px กดง่ายขึ้นโดยไม่ดันตารางจนเทอะทะ */
.btn.sm{ padding:3px 12px; min-height:36px; font-size:1rem; border-radius:8px; }
.btn:hover{ filter:brightness(.97); }

.pill{ display:inline-block; font-size:0.9rem; padding:2px 9px; border-radius:20px; font-weight:600; }
.pill.ok{ background:var(--okbg); color:var(--ok); } .pill.next{ background:var(--warnbg); color:var(--warn); } .pill.draft{ background:var(--line); color:var(--muted); }

.banner{ border-radius:11px; padding:12px 15px; font-size:1.05rem; display:flex; gap:10px; align-items:flex-start; margin-bottom:16px; }
.banner.ok{ background:var(--okbg); color:var(--ok); } .banner.warn{ background:var(--warnbg); color:var(--warn); } .banner.info{ background:var(--infobg); color:var(--info); } .banner.err{ background:var(--errbg); color:var(--err); }

.table-wrap{ width:100%; overflow-x:auto; -webkit-overflow-scrolling:touch; border-radius:10px; }
table.tb{ width:100%; border-collapse:collapse; font-size:1.1rem; }
/* ── responsive: ตารางคงความกว้างอ่านได้ แล้วเลื่อนแนวนอนบนจอแคบ (แทนการบีบคอลัมน์จนอ่านไม่ออก) ── */
.table-wrap > table.tb{ min-width:640px; }
.table-wrap.tw-wide > table.tb{ min-width:860px; }   /* ตารางคอลัมน์เยอะ (ผู้ใช้/รายละเอียด) */
.table-wrap.tw-narrow > table.tb{ min-width:480px; } /* ตารางคอลัมน์น้อย */
table.tb th,table.tb td{ border:1px solid var(--line); padding:8px 9px; text-align:left; vertical-align:top; }
table.tb th{ background:var(--surface2); font-weight:600; color:var(--ink); font-size:0.9rem; }

.who{ display:flex; align-items:center; gap:10px; }
.who .av{ width:32px; height:32px; border-radius:50%; background:var(--brand2); color:#fff; display:grid; place-items:center; font-size:0.95rem; font-weight:600; }
.who small{ color:var(--muted); font-size:0.9rem; }
.badge{ display:inline-block; font-size:0.9rem; padding:1px 8px; border-radius:20px; background:var(--infobg); color:var(--brand); border:1px solid var(--line); }

.theme-btn{ background:none; border:1px solid var(--line); border-radius:var(--radius-sm); width:var(--tap); height:var(--tap); cursor:pointer; color:var(--ink); font-size:1.2rem; }
.out{ border:1px solid var(--line); background:var(--surface); border-radius:var(--radius-sm); padding:8px 13px; min-height:var(--tap); display:inline-flex; align-items:center; cursor:pointer; font:inherit; color:var(--err); }

/* login */
.login-wrap{ min-height:100vh; display:grid; place-items:center; background:linear-gradient(135deg,var(--bg),var(--infobg)); padding:20px; }
.login-card{ width:min(420px,94vw); background:var(--surface); border:1px solid var(--line); border-radius:18px; box-shadow:var(--shadow); padding:38px 34px 30px; text-align:center; }
.login-logo{ width:64px; height:64px; border-radius:var(--radius); margin:0 auto 14px; background:var(--brand); display:grid; place-items:center; color:#fff; font-size:28px; }
.login-card h1{ font-size:1.55rem; margin:6px 0 2px; }
.gbtn{ display:flex; align-items:center; justify-content:center; gap:11px; width:100%; padding:12px 16px; min-height:var(--tap); border:1px solid var(--line); border-radius:var(--btn-radius); background:var(--surface); color:var(--ink); font-size:1.2rem; font-weight:600; text-decoration:none; cursor:pointer; margin-top:6px; }
.gbtn:hover{ background:var(--surface2); }

/* ---------- 6) UTILITIES ---------- */
.row{ display:grid; gap:14px; } .row.c2{ grid-template-columns:1fr 1fr; } .row.c3{ grid-template-columns:1fr 1fr 1fr; } .row.c4{ grid-template-columns:repeat(4,1fr); }
.grid-tiles{ display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:16px; }
.kpis{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:18px; }
.kpi{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:15px 16px; box-shadow:var(--shadow-sm); }
.kpi .v{ font-size:24px; font-weight:700; font-family:var(--font-head); color:var(--brand); } .kpi .l{ font-size:0.9rem; color:var(--muted); }
.muted{ color:var(--muted); } .sp{ flex:1; } .mt0{ margin-top:0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Stepper — แถบขั้นตอนของหน้าสร้างแผน (ใช้ 2 หน้า: แผนฝึก 5 ขั้น · แผนการสอน 7 ขั้น)
   ───────────────────────────────────────────────────────────────────────────
   ⭐ 24 ส.ค. 2569 — ครูส่งภาพตัวอย่างมาแล้วขอให้ปรับหน้าตาเป็นแบบนั้น
      เปลี่ยนจากเดิม (วงอยู่บน · เส้นประ · คลื่นกระจายรอบวงปัจจุบัน) เป็น
        · ป้ายชื่อขั้นอยู่ "บน" วงกลมอยู่ "ล่าง"   ← สลับด้วย column-reverse ไม่ได้แก้ HTML
        · เส้นเชื่อมหนา 4px ต่อเนื่อง เขียว = ผ่านมาแล้ว · เทา = ยังไม่ถึง
        · วงที่ทำเสร็จ  = เขียวทึบ + เครื่องหมายถูกสีขาว
        · วงที่กำลังทำ  = เขียวทึบ + วงโดนัทหมุนช้า ๆ (สื่อว่า "กำลังทำอยู่ตรงนี้")
        · วงที่ยังไม่ถึง = โดนัทเทา ไม่มีตัวเลข
        · ป้ายขั้นปัจจุบันตัวหนาสีเข้ม · ขั้นอื่นสีจาง — สายตาวิ่งไปที่ขั้นปัจจุบันทันที
   ⚠️ ตัวเลขในวงยังอยู่ใน HTML เหมือนเดิม แค่ทำให้โปร่งใส โปรแกรมอ่านหน้าจอจึงยังอ่านได้
   ⚠️ ชื่อคลาส .st .b .t .done .on ไม่เปลี่ยนแม้แต่ตัวเดียว — JS ทุกตัวที่สลับคลาสยังทำงานเหมือนเดิม
   ═══════════════════════════════════════════════════════════════════════════ */
.steps{ display:flex; flex-wrap:nowrap; gap:0; margin:10px 0 26px; }
.steps .st{ flex:1; min-width:0; position:relative; padding:0; background:none; border:0; border-radius:10px;
  display:flex; flex-direction:column-reverse; align-items:center; text-align:center; gap:13px; }

/* เส้นเชื่อม — อยู่หลังวง สูง 4px ตรงกึ่งกลางวงพอดี (วง 32px ⇒ กึ่งกลาง 16px จากขอบล่าง) */
.steps .st::before{ content:""; position:absolute; z-index:0; bottom:14px; height:4px; border-radius:2px;
  left:calc(-50% + 18px); width:calc(100% - 36px); background:var(--st-pend); }
.steps .st:first-child::before{ display:none; }
.steps .st.on::before, .steps .st.done::before{ background:var(--ok); }

/* วงกลม — ค่าตั้งต้นคือ "ยังไม่ถึง" = โดนัทเทา
   รูตรงกลาง "โปร่งใส" ไม่ได้ทาสีพื้นทับ จึงถูกต้องเองทั้งโหมดสว่าง โหมดมืด และตอนโฮเวอร์
   ทำได้เพราะเส้นเชื่อมด้านบนหยุดห่างจากขอบวง 2px ไม่ได้ลอดใต้วง จึงไม่มีอะไรโผล่ขึ้นมาในรู */
.steps .st .b{ position:relative; z-index:1; width:32px; height:32px; border-radius:50%; flex:0 0 auto;
  display:grid; place-items:center; font-weight:700; font-size:0.78rem; color:transparent; margin:0;
  background:radial-gradient(circle, transparent 0 5.5px, var(--st-pend) 6px 100%);
  transition:background .18s ease, transform .15s ease, box-shadow .18s ease; }

/* ทำเสร็จแล้ว — เขียวทึบ + เครื่องหมายถูก (วาดด้วยขอบ 2 ด้านแล้วหมุน 45°) */
.steps .st.done .b{ background:var(--ok); }
.steps .st.done .b::before{ content:""; position:absolute; left:50%; top:48%;
  width:6px; height:11px; border:solid var(--st-fg); border-width:0 2.4px 2.4px 0;
  transform:translate(-50%,-55%) rotate(45deg); }

/* กำลังทำอยู่ — เขียวทึบ + วงโดนัทหมุน */
.steps .st.on .b{ background:var(--ok);
  box-shadow:0 4px 12px color-mix(in srgb, var(--ok) 40%, transparent); }
.steps .st.on .b::after{ content:""; position:absolute; inset:6px; border-radius:50%;
  border:3px solid color-mix(in srgb, var(--st-fg) 32%, transparent);
  border-top-color:color-mix(in srgb, var(--st-fg) 92%, transparent);
  animation:stepSpin 1.4s linear infinite; }
@keyframes stepSpin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce){ .steps .st.on .b::after{ animation:none; } }

/* ป้ายชื่อขั้น — ขั้นปัจจุบันเด่นขึ้นมาขั้นเดียว ที่เหลือถอยไปเป็นฉากหลัง */
/* กล่องที่ห่อป้าย (<div> ตัวที่สองใน .st) ต้องกว้างเท่าคอลัมน์
   ถ้าไม่บังคับ flex จะให้มันกว้างตามเนื้อหา พอสั่ง nowrap ตอนจอแคบ
   ข้อความจะล้นไปทับขั้นข้าง ๆ แทนที่จะตัดท้ายด้วย … (เจอตอนทดสอบจอ 360px) */
.steps .st > div{ min-width:0; width:100%; }
.steps .st .t{ font-weight:500; font-size:clamp(0.74rem, 1.7vw, 1rem); line-height:1.2;
  color:var(--muted); transition:color .18s ease, font-weight .18s ease; }
.steps .st.on .t{ color:var(--ink); font-weight:700; }
.steps .st small{ display:none; }

/* ── จอแคบ ─────────────────────────────────────────────────────────────────
   ⚠️ ภาษาไทยไม่มีช่องว่างระหว่างคำ พอบีบคอลัมน์แคบ ๆ เบราว์เซอร์จะตัดกลางคำ
      ("เทียบมาตรฐา / น") อ่านไม่รู้เรื่องและดูเหมือนระบบพัง
      จึงบังคับให้ชื่อขั้นอยู่บรรทัดเดียวเสมอ ยาวเกินก็ตัดท้ายด้วย …
      ครูยังรู้ตำแหน่งตัวเองจากวงกลมและจากชื่อขั้นปัจจุบันที่เป็นตัวหนา
      (หน้าแผนการสอนมีแถบย่อติดขอบบนบอกชื่อขั้นเต็ม ๆ อยู่แล้วเมื่อเลื่อนจอ) */
@media (max-width:760px){
  .steps{ margin:8px 0 20px; }
  .steps .st{ gap:10px; }
  .steps .st .t{ font-size:0.72rem; white-space:nowrap; overflow:hidden;
    text-overflow:ellipsis; max-width:100%; }
}
@media (max-width:560px){
  .steps .st{ gap:9px; }
  .steps .st .t{ font-size:0.66rem; }
  .steps .st .b{ width:28px; height:28px; }
  .steps .st .b{ width:26px; height:26px;
    background:radial-gradient(circle, transparent 0 4.5px, var(--st-pend) 5px 100%); }
  .steps .st.done .b, .steps .st.on .b{ background:var(--ok); }
  .steps .st.done .b::before{ width:5px; height:9px; border-width:0 2px 2px 0; }
  .steps .st.on .b::after{ inset:5px; border-width:2.5px; }
  /* เส้นเชื่อมต้องขยับตามวงที่เล็กลง (วง 26px ⇒ กึ่งกลาง 13px · เว้นขอบวง 2px ⇒ 15px) */
  .steps .st::before{ bottom:11px; left:calc(-50% + 15px); width:calc(100% - 30px); }
}
/* จอจิ๋ว (มือถือแนวตั้ง) — 7 ขั้นบีบจนป้ายเหลือ 3-4 ตัวอักษรแล้วก็ยังอ่านไม่ออก
   จึงซ่อนป้ายทิ้ง เหลือแค่วงกลมซึ่งบอกความคืบหน้าได้ครบ
   ชื่อขั้นไม่ได้หายไปไหน — อยู่ในหัวการ์ดข้างล่างทันที ("3 เทียบมาตรฐานอาชีพ")
   หน้าแผนการสอนยังมีแถบย่อบอกชื่อขั้นเต็มเมื่อเลื่อนจอ และแตะค้างที่วงก็เห็น title */
@media (max-width:480px){
  .steps{ margin:6px 0 16px; }
  .steps .st{ gap:0; }
  .steps .st .t, .steps .st > div{ display:none; }
  /* ...ยกเว้นแถบที่มีไม่เกิน 5 ขั้น (หน้าแผนฝึกอาชีพ) คอลัมน์ยังกว้างพอให้อ่านชื่อได้
     เขียนแบบ "ซ่อนก่อน แล้วค่อยเปิดคืนด้วย :has()" ตั้งใจให้เบราว์เซอร์เก่าที่ไม่รู้จัก :has()
     ทิ้งกฎนี้แล้วตกไปอยู่ที่ "ซ่อนป้าย" ซึ่งปลอดภัยกว่าปล่อยให้ป้ายทับกัน */
  .steps:not(:has(.st:nth-child(6))) .st > div{ display:block; }
  .steps:not(:has(.st:nth-child(6))) .st .t{ display:block; font-size:0.62rem; }
  .steps:not(:has(.st:nth-child(6))) .st{ gap:8px; }
  .steps .st .b{ width:24px; height:24px;
    background:radial-gradient(circle, transparent 0 4px, var(--st-pend) 4.5px 100%); }
  .steps .st.done .b, .steps .st.on .b{ background:var(--ok); }
  .steps .st.done .b::before{ width:4px; height:8px; border-width:0 2px 2px 0; }
  .steps .st.on .b::after{ inset:4px; border-width:2.5px; }
  .steps .st::before{ bottom:10px; left:calc(-50% + 14px); width:calc(100% - 28px); }
}

/* form helpers */
.sect{ background: #e9e9e9;
    padding: 5px 10px;
    border-radius: 8px;
	font-size:1.1rem; font-weight:600; color:#001a53; letter-spacing:.4px; margin:16px 0 8px; padding-bottom:4px; border-bottom:1px solid var(--line); }
.sect:first-child{ margin-top:15; }
.fhint{ font-size:0.9rem; color:var(--muted); margin-top:5px; } .fhint i{ margin-right:3px; }
.fnote{ font-size:0.9rem; color:var(--ink); background:var(--surface2); border:1px solid var(--line); border-radius:8px; padding:8px 10px; line-height:1.45; }
.aibadge{ display:inline-block; background:#ede9fe; color:#6d28d9; border:1px solid #ddd6fe; font-size:0.8rem; font-weight:700; padding:0 5px; border-radius:5px; }
.hint{ font-size:0.9rem; color:var(--muted); line-height:1.5; }

/* หมายเลขขั้น (หัวการ์ด) */
.stepnum{ width:24px; height:24px; border-radius:50%; background:var(--brand); color:#fff; display:inline-grid; place-items:center; font-size:0.85rem; }
/* แถวปุ่มท้ายการ์ด */
.form-actions{ margin-top:18px; display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; }

/* โซนอัปโหลด PDF */
.upzone{ border:2px dashed var(--line); border-radius:12px; background:var(--surface2); padding:15px 20px; text-align:center; transition:.15s; cursor:pointer; }
.upzone:hover,.upzone:focus,.upzone.drag{ border-color:var(--brand2); background:var(--infobg); outline:none; }
.upzone > i{ font-size:34px; color:var(--brand); }
.upzone-t{ margin:8px 0 4px; font-size:1.05rem; }

/* ลิสต์ข้อ (จุดประสงค์/สมรรถนะ) แก้ไขได้ */
.itemlist{ display:flex; flex-direction:column; gap:8px; }
.itemrow{ display:flex; gap:8px; align-items:flex-start; }
.itemrow .no{ flex:0 0 auto; width:26px; height:38px; display:grid; place-items:center; color:var(--muted); font-weight:600; }
.itemrow textarea{ flex:1; min-height:38px; resize:vertical; }
.itemrow .del{ flex:0 0 auto; width:38px; height:38px; border:1px solid var(--line); background:var(--surface); color:var(--err); border-radius:9px; cursor:pointer; }
.itemrow .del:hover{ background:var(--errbg); }

/* ตารางงานฝึก (Step 4 / M4) */
#job-table td{ vertical-align:middle; }
#job-table .mainrow{ /*background:var(--surface2);*/ background: linear-gradient(341deg, #e4e5e8, #e4effd); }
#job-table .mainrow > td{ font-weight:600; border-top:2px solid var(--brand2); }
.jobcode{ display:inline-block; font-size:1rem; font-weight:700; padding:3px 12px; border-radius:20px; background:#0060b4; color:#fff; border:1px solid var(--line); }
.subcode{ color:var(--muted); font-weight:700; }
.jt-title{ width:100%; padding:7px 10px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink); font:inherit; font-size:1rem; }
.jt-title.main{ font-weight:600; }
.jt-dept{ width:100%; margin-top:6px; padding:5px 10px; border:1px dashed var(--line); border-radius:8px; background:var(--surface); color:var(--muted); font:inherit; font-size:0.9rem; }
.jt-hours{ width:72px; padding:7px 8px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink); font:inherit; font-size:1rem; text-align:center; }
.jt-subtotal{ font-weight:700; color:var(--brand); }
.jt-del{ border:1px solid var(--line); background:var(--surface); color:var(--err); border-radius:8px; padding:6px 10px; cursor:pointer; }
.jt-del:hover{ background:var(--errbg); }
.jt-addsub{ margin:5px; border:1px solid #bdd6e5; background:var(--infobg); color:var(--brand); border-radius:8px; padding:5px 3px; cursor:pointer; font:inherit; font-size:0.8rem; width: 70px; font-weight:600; }
.jt-addsub:hover{ filter:brightness(.97); }
.banner.hours-ok{ background:var(--okbg); color:var(--ok); }
.banner.hours-bad{ background:var(--warnbg); color:var(--warn); }

/* ตารางงานฝึก M4b: KSA / วิธีสอน / drawer / coverage */
.ksa{ display:inline-flex; gap:3px; flex-wrap:wrap; }
.ksa .kc{ min-width:26px; height:26px; padding:0 7px; border-radius:6px; border:1px solid var(--line); background:var(--surface); color:var(--muted); font-size:0.8rem; font-weight:700; cursor:pointer; display:inline-grid; place-items:center; }
.ksa .kc.on.kK{ background:var(--k); color:#fff; border-color:var(--k); }
.ksa .kc.on.kS{ background:var(--s); color:#fff; border-color:var(--s); }
.ksa .kc.on.kA{ background:var(--a); color:#fff; border-color:var(--a); }
.ksa .kc.on.kAp{ background:var(--ap); color:#fff; border-color:var(--ap); }
.subrow.needA .kc.kA{ box-shadow:0 0 0 2px var(--err); }

.methodcell{ display:flex; align-items:center; gap:6px; }
.methodcell select{ flex:1; min-width:0; padding:6px 8px; border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink); font:inherit; font-size:0.9rem; }
.mbadge{ flex:0 0 auto; font-size:0.72rem; font-weight:700; padding:1px 6px; border-radius:5px; background:#ede9fe; color:#6d28d9; border:1px solid #ddd6fe; }
.mbadge.teacher{ background:var(--okbg); color:var(--ok); border-color:#cfe7d6; }

.btn-edit{margin:5px; border:1px solid #bdd6e5; background:var(--infobg); color:var(--brand); border-radius:8px; padding:3px 8px; cursor:pointer; font:inherit; font-size:0.85rem; font-weight:600; }
.btn-edit.open{ background:var(--brand); color:#fff; }
.jt-en{padding: 5px 10px; border-radius: 8px; border: 1px dashed var(--line);}
.jt-occ{padding: 5px 10px; border-radius: 8px; border: 1px dashed var(--line);}
.jt-drawer > td{ padding:0 !important; }
.jt-drawer .inner{ padding:14px 16px; border-left:3px solid var(--brand2); background:var(--surface2); }
.jt-drawer .dwtitle{ font-weight:600; margin-bottom:10px; }
.jt-drawer .grid3{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:12px; }
.jt-drawer textarea{ width:100%; font-size:0.95rem; resize:vertical; }
.jt-covsel{ display:flex; flex-wrap:wrap; gap:10px; margin-top:8px; padding-top:10px; border-top:1px dashed var(--line); }
.jt-covsel > b{ font-size:0.9rem; }
.jt-covsel label{ font-size:0.9rem; display:inline-flex; gap:5px; align-items:center; cursor:pointer; background:var(--surface); border:1px solid var(--line); border-radius:7px; padding:3px 9px; }
@media(max-width:900px){ .jt-drawer .grid3{ grid-template-columns:1fr; } }

.covmap{ border:1px solid var(--line); border-radius:12px; background:var(--surface2); padding:14px 16px; margin-bottom:14px; }
.covmap h4{ margin:0 0 8px; font-size:1.05rem; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.covrow{ display:flex; align-items:center; gap:10px; padding:6px 0; border-top:1px dashed var(--line); }
.covrow .cc{ flex:1; font-size:0.95rem; }
.covrow.miss .cc{ color:var(--err); font-weight:600; }
.chipc{ display:inline-block; font-size:0.8rem; font-weight:700; padding:1px 8px; border-radius:20px; background:var(--infobg); color:var(--brand); border:1px solid var(--line); margin-left:3px; }
.chipc.none{ background:var(--errbg); color:var(--err); }

/* การ์ดไฟล์ดาวน์โหลด (Step 5) */
.file-tile{ display:flex; align-items:center; gap:12px; padding:14px 16px; border:1px solid var(--line); border-radius:12px; background:var(--surface); color:var(--ink); text-decoration:none; transition:.15s; }
.file-tile:hover{ border-color:var(--brand2); box-shadow:0 6px 16px rgba(46,134,193,.15); transform:translateY(-1px); }
.file-tile .fi{ width:42px; height:42px; border-radius:9px; background:linear-gradient(135deg,#2b579a,#1e3d6b); color:#fff; display:grid; place-items:center; font-weight:700; font-size:1.1rem; flex:0 0 auto; }
.file-tile .fi.zip{ background:linear-gradient(135deg,#b45309,#92400e); font-size:0.8rem; }
.file-tile .fi.pdf{ background:linear-gradient(135deg,#c0392b,#922b21); font-size:0.8rem; }
/* แถบความคืบหน้าตอนสร้างเอกสาร */
.genp-head{ display:flex; align-items:center; gap:10px; margin-bottom:8px; font-size:1.05rem; color:var(--ink); }
.genp-head b{ margin-left:auto; color:var(--brand2); font-variant-numeric:tabular-nums; }
.genp-bar{ height:12px; background:var(--line); border-radius:8px; overflow:hidden; position:relative; }
.genp-fill{ height:100%; width:0; border-radius:8px; background:linear-gradient(90deg,var(--brand),var(--brand2)); transition:width .5s ease; background-size:200% 100%; animation:genp-shim 1.4s linear infinite; }
@keyframes genp-shim{ 0%{ background-position:200% 0; } 100%{ background-position:-200% 0; } }
.file-tile.zip-tile{ border-color:var(--brand2); background:var(--infobg); }

/* Modal พรีวิว PDF */
.pv-modal{ position:fixed; inset:0; z-index:60; background:rgba(0,0,0,.5); display:flex; align-items:center; justify-content:center; padding:20px; }
.pv-modal[hidden]{ display:none; }   /* ให้ attribute hidden ชนะ display:flex (กันกล่องพรีวิวเด้งเองตอนเข้าหน้า 5) */
.pv-box{ background:var(--surface); border-radius:14px; width:min(920px,96vw); height:min(88vh,900px); display:flex; flex-direction:column; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.4); }
.pv-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 16px; border-bottom:1px solid var(--line); }
.pv-close{ background:none; border:1px solid var(--line); border-radius:8px; width:36px; height:36px; cursor:pointer; color:var(--ink); font-size:1.1rem; }
.pv-close:hover{ background:var(--errbg); color:var(--err); }
.pv-box iframe{ flex:1; width:100%; border:none; background:#525659; }

/* ปุ่ม AI (ทางเลือก) */
/* ปุ่มผู้ช่วย AI — เดิมไล่เฉดม่วงสองสีฝังตายตัว เปลี่ยนเป็นสีเดียวจากตัวแปร --accent
   (แบบ 06: ไล่เฉดเหลือที่เดียวคือปุ่มหลัก) · ยังเป็นสีม่วงเหมือนเดิม ครูยังจำได้ว่านี่คือปุ่ม AI */
.ai-btn{ font:inherit; font-size:1rem; font-weight:500; border:1px solid transparent; background:var(--accent); color:#ffffff; border-radius:var(--btn-radius); padding:5px 15px; min-height:36px; display:inline-flex; align-items:center; gap:6px; cursor:pointer; margin-left:6px; }
.ai-btn:hover{ filter:brightness(.97); }
.ai-btn:disabled{ opacity:.5; cursor:not-allowed; }
:root[data-theme="dark"] .ai-btn{ background:#2a2140; color:#c4b5fd; border-color:#3b2f5c; }

/* ===== ปุ่ม "AI วิเคราะห์งานทั้งตาราง" (data-ai=table): แบบ 5 ไล่เฉดสีเลื่อนไหล ===== */
/* พื้นไล่เฉดม่วง-ชมพูเลื่อนไหลต่อเนื่อง · สดใสเท่ากันทั้ง 2 ธีม · รองรับทุกเบราว์เซอร์ (ใช้ background-position ไม่พึ่ง @property/mask) */
.ai-btn[data-ai="table"], .ai-btn[data-ai="nature"]{
  border:0; padding:6px 15px; color:#fff;
  background:linear-gradient(90deg,#33007f,#7c3aed,#ae10ed,#ec4899,#7c3aed,#33007f);
  background-size:300% 100%;
  /* ⛔ ยกเลิกอนิเมชั่นไล่เฉดไหลบนปุ่ม — ครูสั่ง 8 ก.ย. 2569 (รอบ 110) */
  box-shadow:0 6px 18px rgba(124,58,237,.42);
}
:root[data-theme="dark"] .ai-btn[data-ai="table"], :root[data-theme="dark"] .ai-btn[data-ai="nature"]{   /* คงความสดใสในธีมมืด (ไม่ให้ทึบ) */
  color:#fff; border:0;
  background:linear-gradient(90deg,#33007f,#7c3aed,#ae10ed,#ec4899,#7c3aed,#33007f);
  background-size:300% 100%;
}
@keyframes ai-tbl-flow{ to{ background-position:300% 0; } }
@media (prefers-reduced-motion:reduce){ .ai-btn[data-ai="table"], .ai-btn[data-ai="nature"]{ animation:none; } }  /* เคารพผู้ปิดอนิเมชั่น */

/* ปุ่มชิปเล็ก (เช่น + เพิ่มใหม่) */
.chip-btn{ margin: 5px; margin-top: -3px; font:inherit; font-size:0.85rem; font-weight:600; border:1px solid #cfe7d6; background:var(--okbg); color:var(--ok); border-radius:7px; padding:3px 10px; cursor:pointer; display:inline-flex; align-items:center; gap:4px; }
.chip-btn:hover{ filter:brightness(.97); }

/* ============ Select2 — ธีมสวยงาม (light/dark) ============ */
/* กว้าง 100% เฉพาะ "ตัว widget" (ที่มี .selection) — ไม่ยุ่งกับกล่อง dropdown ที่แปะบน body
   ถ้าใช้ !important กับทุก .select2-container กล่อง dropdown จะกว้างเต็มจอ → เกิด scrollbar แนวนอน */
.select2-container:has(> .selection){ width:100% !important; }
.select2-container .selection{ font-size:1rem; display:block; }

/* กล่องที่เลือก (single) — สูง/ขอบ/พื้น ให้เท่าช่อง .inp */
.select2-container--default .select2-selection--single{
  height:42px; border:1px solid var(--line); border-radius:9px; background:var(--surface2);
  transition:border-color .15s, box-shadow .15s; padding:5px 5px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered{
  line-height:40px; color:var(--ink); padding-left:14px; padding-right:52px; font-size:1rem;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder{ color:var(--muted); }
.select2-container--default .select2-selection--single .select2-selection__arrow{ height:40px; right:8px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b{ border-color:var(--muted) transparent transparent; }
/* ปุ่มล้างค่า (x) */
.select2-container--default .select2-selection--single .select2-selection__clear{
  color:var(--muted); font-weight:700; margin-right:22px; cursor:pointer; font-size:1.1rem;
}
.select2-container--default .select2-selection--single .select2-selection__clear:hover{ color:var(--err); }
/* โฟกัส/เปิด — ขอบสีแบรนด์ + ring */
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--single{
  border-color:var(--brand2); box-shadow:0 0 0 3px rgba(46,134,193,.15);
}
.select2-container--default.select2-container--disabled .select2-selection--single{ background:var(--bg); opacity:.6; cursor:not-allowed; }

/* กล่อง dropdown — มุมมน เงา เว้นจากช่อง */
.select2-dropdown{
  background:var(--surface); border:1px solid var(--line); border-radius:11px; overflow:hidden;
  box-shadow:0 12px 30px rgba(31,95,139,.16); color:var(--ink);
}
.select2-container--open .select2-dropdown--below{ margin-top:5px; }
.select2-container--open .select2-dropdown--above{ margin-bottom:5px; border-radius:11px; }

/* ช่องค้นหาในกล่อง */
.select2-search--dropdown{ padding:9px; }
.select2-search--dropdown .select2-search__field{
  background:var(--surface2); color:var(--ink); border:1px solid var(--line); border-radius:8px;
  font-size:1rem; padding:8px 11px; outline:none;
  font-family: inherit;
}
.select2-search--dropdown .select2-search__field:focus{ border-color:var(--brand2); box-shadow:0 0 0 3px rgba(46,134,193,.15); }

/* รายการตัวเลือก */
.select2-results{ padding:4px; }
.select2-results__option{ font-size:1rem; padding:9px 12px; line-height:1.45; border-radius:8px; margin:1px 0; }
.select2-container--default .select2-results__option--highlighted[aria-selected]{ background:linear-gradient(135deg,var(--brand),var(--brand2)); color:#fff; }
.select2-container--default .select2-results__option[aria-selected=true]{ background:var(--surface2); color:var(--brand); font-weight:600; }
.select2-container--default .select2-results__option--highlighted[aria-selected=true]{ color:#fff; }
.select2-results__message{ color:var(--muted); padding:10px 12px; }
/* scrollbar ในรายการ */
.select2-results__options{ max-height:260px; }
.select2-results__options::-webkit-scrollbar{ width:9px; }
.select2-results__options::-webkit-scrollbar-thumb{ background:var(--line); border-radius:20px; }

/* ตัวเลือกแบบ 2 บรรทัด (ชื่อ + ที่อยู่) เช่น สถานประกอบการ */
.wp-opt .wp-name{ font-weight:600; }
.wp-opt .wp-addr{ font-size:0.85rem; color:var(--muted); margin-top:2px; }
.select2-results__option--highlighted .wp-opt .wp-addr{ color:rgba(255,255,255,.85); }
.select2-container--default.select2-container--disabled .select2-selection--single{ background:var(--bg); opacity:.6; }

/* ============ SweetAlert2 — ใช้ฟอนต์/สีโปรเจกต์ ============ */
.swal2-popup{ font-family:var(--font) !important; border-radius:16px; background:var(--surface); color:var(--ink); }
.swal2-title{ font-family:var(--font-head) !important; color:var(--ink); font-size:1.4rem !important; line-height:1.3; }
.swal2-html-container{ color:var(--ink); font-size:1.1rem !important; }
.swal2-input, .swal2-textarea, .swal2-select{
  font-family:var(--font) !important; font-size:1.1rem !important; border:1px solid var(--line); border-radius:9px;
  background:var(--surface2); color:var(--ink); box-shadow:none;
}
.swal2-label{ font-size:1.1rem !important; }
.swal2-input::placeholder, .swal2-textarea::placeholder{ color:var(--muted); }
.swal2-input:focus, .swal2-textarea:focus, .swal2-select:focus{ border-color:var(--brand2); box-shadow:0 0 0 3px rgba(46,134,193,.15); }
.swal2-validation-message{ font-family:var(--font) !important; background:var(--errbg); color:var(--err); border-radius:8px; }
.swal2-actions{ gap:8px; }
.swal2-confirm.swal2-styled{
  font-family:var(--font) !important; font-weight:600; font-size:1.1rem !important; border-radius:10px; padding:10px 22px;
  background:linear-gradient(135deg,var(--brand),var(--brand2)) !important; color:#fff !important;
  box-shadow:0 6px 16px rgba(46,134,193,.28);
}
.swal2-cancel.swal2-styled{
  font-family:var(--font) !important; font-weight:600; font-size:1.1rem !important; border-radius:10px; padding:10px 22px;
  background:var(--surface) !important; border:1px solid var(--line) !important; color:var(--ink) !important;
}
.swal2-styled:focus{ box-shadow:0 0 0 3px rgba(46,134,193,.25) !important; }
.swal2-icon{ font-family:var(--font) !important; }
/* toast (window.ui.toast) */
.swal2-toast{ font-family:var(--font) !important; border-radius:12px; }
.swal2-toast .swal2-title{ font-size:1rem; font-family:var(--font) !important; }

/* ---------- 7) RESPONSIVE ---------- */
/* แท็บเล็ต / จอกลาง */
@media(max-width:900px){
  .app{ grid-template-columns:1fr; }
  .side{ position:fixed; z-index:40; left:0; top:0; width:236px; max-width:82vw; transform:translateX(-100%); transition:transform .2s ease; }
  .side.open{ transform:translateX(0); box-shadow:0 0 40px rgba(0,0,0,.3); }
  .topbar .menu-btn{ display:inline-flex; }
  .backdrop{ display:none; position:fixed; inset:0; background:rgba(0,0,0,.4); z-index:35; }
  .backdrop.show{ display:block; }
  .row.c3,.row.c4{ grid-template-columns:1fr 1fr; }  /* แท็บเล็ต: 2 คอลัมน์ */
  .kpis{ grid-template-columns:1fr 1fr; }
  .main{ padding:18px 16px 50px; }
}
/* มือถือจอเล็ก */
@media(max-width:560px){
  .row.c2,.row.c3,.row.c4{ grid-template-columns:1fr; }  /* มือถือ: 1 คอลัมน์ */
  body{ font-size:1.1rem; }
  .main{ padding:14px 12px 46px; }
  .card{ padding:16px 15px; border-radius:12px; }
  .hero{ padding:18px 18px; } .hero h1{ font-size:1.3rem; }
  .kpis{ grid-template-columns:1fr 1fr; gap:10px; }
  /* .steps เป็น timeline แถวเดียวทุกขนาดจอ — ไม่ต้อง stack */
  .who > div{ display:none; }                               /* ซ่อนชื่อ/อีเมลบนจอจิ๋ว เหลือรูปโปรไฟล์ */
  .topbar .inner{ padding:9px 13px; gap:8px; }
  .btn{ padding:9px 14px; } .btn.primary{ width:100%; justify-content:center; }  /* ปุ่มหลักเต็มความกว้าง กดง่าย */
  .login-card{ padding:28px 20px 24px; }
}
/* จอกว้างมาก — คงเต็มความกว้าง (ตามที่ผู้ใช้เลือก) + เว้นขอบซ้ายขวาให้หายใจ
   (แก้ค่าเดิม max-width:100 ที่ไม่มีหน่วย → เบราว์เซอร์ทิ้งกฎ ใช้ไม่ได้) */
@media(min-width:1600px){ .main{ padding-left:40px; padding-right:40px; } }
@media(min-width:1920px){ .main{ padding-left:56px; padding-right:56px; } }

/* ============================================================
   เมนูซ้ายย่อเป็นแถบไอคอน — กดปุ่ม ☰ ย่อ/ขยาย (ผู้ใช้ขอ 23 ก.ค. 69)
   • เฉพาะเดสก์ท็อป (>900px) · ใช้ class html.side-rail (จำสถานะ localStorage, กัน flash)
   • มือถือ (<=900px) ปุ่ม ☰ ยังเลื่อนเมนูเข้า/ออกแบบเดิม (ไม่กระทบ)
   วิธีย้อนกลับ: ลบบล็อกนี้ + คืน .menu-btn/head.php/app.js/header.php จาก storage/backups
   ============================================================ */
.app{ transition:grid-template-columns .18s ease; }
@media(min-width:901px){
  html.side-rail .app{ grid-template-columns:64px 1fr; }
  html.side-rail .side .brand{ justify-content:center; padding:10px 6px; gap:0; }
  html.side-rail .side .brand > div{ display:none; }
  html.side-rail .nav a{ justify-content:center; padding:10px 0; gap:0; font-size:0; }
  html.side-rail .nav a .i{ font-size:1.15rem; width:auto; }
  html.side-rail .nav .cap{ display:none; }
}

/* ============================================================
   8) POLISH & MOTION — ยกระดับดีไซน์ให้พรีเมียม (เพิ่ม 10 ส.ค. 69)
   append ล้วน · ไม่แก้ token/สไตล์เดิม · เคารพ prefers-reduced-motion
   ย้อนกลับ: ลบทั้งบล็อกนี้ (backup: storage/backups/responsive_design_20260810_161119)
   ============================================================ */
@keyframes uxFadeUp{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
@keyframes uxHeroSheen{ 0%{ background-position:0% 50%; } 100%{ background-position:200% 50%; } }

/* --- entrance: การ์ด/hero/kpi ค่อย ๆ โผล่ (stagger เล็กน้อย) --- */
.hero,.card,.kpi,.adm-kpi,.file-tile,.choose-tile{ animation:uxFadeUp .38s ease both; }
.kpis .kpi:nth-child(2),.adm-kpis .adm-kpi:nth-child(2){ animation-delay:.05s; }
.kpis .kpi:nth-child(3),.adm-kpis .adm-kpi:nth-child(3){ animation-delay:.10s; }
.kpis .kpi:nth-child(4),.adm-kpis .adm-kpi:nth-child(4){ animation-delay:.15s; }

/* --- card: ความลึกนุ่มขึ้น + transition --- */
.card{ transition:box-shadow .26s ease, border-color .26s ease; }
.card:hover{ box-shadow:var(--shadow); }

/* --- kpi: ยกลอยเล็กน้อยเมื่อ hover --- */
.kpi,.adm-kpi{ transition:transform .2s ease, box-shadow .2s ease; }
.kpi:hover,.adm-kpi:hover{ transform:translateY(-3px); box-shadow:var(--shadow); }

/* --- ปุ่ม: micro-interaction (hover ยก / active กด / แสงวิ่งบนปุ่มหลัก) --- */
.btn{ transition:transform .15s ease, box-shadow .2s ease, filter .15s ease; }
.btn:hover{ transform:translateY(-1px); }
.btn:active{ transform:translateY(1px) scale(.99); }
.btn.primary{ position:relative; overflow:hidden; }
.btn.primary::after{ content:""; position:absolute; inset:0; background:linear-gradient(120deg,transparent 32%,rgba(255,255,255,.35) 50%,transparent 68%); transform:translateX(-130%); transition:transform .6s ease; pointer-events:none; }
.btn.primary:hover::after{ transform:translateX(130%); }

/* --- hero: สีทึบ + วงแสงนุ่ม + ค่อย ๆ โผล่ตอนเปิดหน้า ---
   ⭐ 7 ก.ย. 2569 — เอา "แสงวิ่ง 16 วินาที" (uxHeroSheen) ออก ตามกติกาแบบ 06
      ที่ว่าไล่เฉดเหลือที่เดียวคือปุ่มหลัก · วงแสงมุมขวาบนกับการค่อย ๆ โผล่ยังอยู่ครบ
   คืนแสงวิ่ง: ใส่ background:linear-gradient(120deg,var(--brand),var(--brand2),var(--brand));
               background-size:200% 100%;  แล้วต่อ , uxHeroSheen 16s linear infinite ท้าย animation */
.hero{ animation:uxFadeUp .4s ease both; position:relative; overflow:hidden; }
.hero::after{ content:""; position:absolute; top:-45%; right:-8%; width:300px; height:300px; border-radius:50%; background:radial-gradient(circle,rgba(255,255,255,.15),transparent 70%); pointer-events:none; }
.hero > *{ position:relative; z-index:1; }

/* --- เมนูซ้าย: ขยับนิดเมื่อ hover --- */
.nav a{ transition:background .18s ease, color .18s ease, transform .12s ease; }
.nav a:not(.sel):hover{ transform:translateX(2px); }

/* --- banner: แถบ accent ซ้าย --- */
.banner{ border-left:4px solid currentColor; }

/* --- upzone: ยกนุ่มเมื่อ hover/drag --- */
.upzone{ transition:border-color .18s ease, background .18s ease, transform .18s ease, box-shadow .18s ease; }
.upzone:hover,.upzone.drag{ transform:translateY(-2px); box-shadow:0 10px 24px rgba(46,134,193,.14); }

/* --- scrollbar แบรนด์ (ตารางเลื่อนแนวนอน) --- */
.table-wrap::-webkit-scrollbar{ height:10px; }
.table-wrap::-webkit-scrollbar-thumb{ background:linear-gradient(var(--brand2),var(--brand)); border-radius:20px; }
.table-wrap::-webkit-scrollbar-track{ background:transparent; }

/* --- guard เฉพาะจุด (เสริม global reduce-motion) --- */
@media (prefers-reduced-motion:reduce){
  .hero,.card,.kpi,.adm-kpi,.file-tile,.choose-tile{ animation:none !important; }
  .btn:hover,.kpi:hover,.adm-kpi:hover,.upzone:hover,.nav a:not(.sel):hover{ transform:none !important; }
  .btn.primary::after{ display:none; }
}

/* ============================================================
   9) MOTION รวมศูนย์ — ครูสั่งเอง 7 ก.ย. 2569
      "อนิเมชั่นตามปุ่มต่างๆผมอยากให้คงไว้ และอยากทำให้เป็นไปในทิศทางเดียวกัน"
   ───────────────────────────────────────────────────────────
   ปัญหาเดิม: บล็อก 8 ให้อนิเมชั่นเฉพาะ .btn เท่านั้น
   ปุ่มอื่นอีกหลายสิบตัวในระบบ (.ai-btn .gbtn .out .theme-btn .menu-btn .chip-btn
   .btn-edit .lsn-s6btn .lsn-jchip .pe-add .pe-x .lsn-x ฯลฯ) นิ่งสนิท
   ⇒ กดแล้วรู้สึกไม่เหมือนกัน ทั้งที่เป็นปุ่มเหมือนกัน

   รอบนี้ใช้กติกาเดียวกับปุ่มหลักให้ครบทุกปุ่มในระบบ:
     ชี้  = ยกขึ้น 1px   ·   กด = ยุบลง 1px + ย่อ 1%   ·   เร็ว 150 มิลลิวินาที
   ทำด้วยการจับที่แท็ก <button> ตรง ๆ + ลิงก์ที่ทำหน้าที่เป็นปุ่ม
   ⇒ ปุ่มใหม่ที่เขียนทีหลังได้อนิเมชั่นนี้อัตโนมัติ ไม่ต้องมาไล่เพิ่มทีละคลาสอีก

   ⛔ ยกเว้นไว้ตั้งใจ 3 กลุ่ม (ขยับแล้วจะดูแปลก/ชนของเดิม):
      · ปุ่มของ SweetAlert2 และ Select2 — ไลบรารีคุมเอง
      · .steps (แถบขั้นตอน) — ทำไว้ดีแล้วตั้งแต่ 24 ส.ค. ห้ามแตะ
      · ปุ่มที่ปิดใช้งานอยู่ (:disabled) — ต้องรู้สึกว่ากดไม่ได้จริง ๆ
   ย้อนกลับ: ลบทั้งบล็อก 9 นี้ทิ้ง ของเดิมกลับมาครบ
   ============================================================ */
/* ⚠️⚠️ 7 ก.ย. รอบแก้คืน — ของเดิมที่ผมเขียนตอนเช้าใช้ button:not():not():not()
   ซึ่ง "นับน้ำหนัก" ได้สูงมาก (0,4,1) สูงกว่ากฎเดิมของปุ่มเฉพาะทางเกือบทุกตัวในระบบ
   ⇒ ไปทับดีไซน์เดิมโดยไม่ตั้งใจ เช่น ปุ่ม Google หน้า login เด้ง 1px แทน 2px ที่ออกแบบไว้
      และปุ่ม AI หน้าโครงการตอน busy ยังเด้งเมื่อชี้ ทั้งที่ตั้งใจให้นิ่ง
   ✅ แก้เป็น :where() ซึ่งมีน้ำหนักเป็น "ศูนย์" ⇒ เหลือน้ำหนักแค่ (0,1,1) เท่าแท็ก
      กฎเดิมของแต่ละปุ่มจึงกลับมาชนะเหมือนเดิมทุกตัว
      ส่วนกฎนี้ทำงานเฉพาะปุ่มที่ไม่เคยมีใครกำหนดไว้ — ได้ทั้งสองอย่างที่ครูขอ */
button:where(:not(.swal2-styled):not(.select2-selection):not(:disabled)),
:where(a.btn, a.gbtn, a.ai-btn, .chip-btn, .btn-edit, .upzone){
  transition:transform .15s ease, box-shadow .2s ease, filter .15s ease,
             background .18s ease, border-color .18s ease;
}
button:where(:not(.swal2-styled):not(.select2-selection):not(:disabled)):hover,
:where(a.btn, a.gbtn, a.ai-btn, .chip-btn, .btn-edit):hover{
  transform:translateY(-1px);
}
button:where(:not(.swal2-styled):not(.select2-selection):not(:disabled)):active,
:where(a.btn, a.gbtn, a.ai-btn, .chip-btn, .btn-edit):active{
  transform:translateY(1px) scale(.99);
}
/* แถบขั้นตอนกับปุ่มในนั้น — ของเดิมทำไว้ดีแล้ว กันไม่ให้กฎข้างบนไปโดน */
.steps button, .steps .st{ transform:none !important; }
/* ปุ่มที่กดไม่ได้ ต้องดูรู้ว่ากดไม่ได้ — ใช้ :where() เช่นกัน กฎเดิมของแต่ละปุ่มชนะ */
button:where(:disabled){ opacity:.55; cursor:not-allowed; }

@media (prefers-reduced-motion:reduce){
  button, a.btn, a.gbtn, a.ai-btn, .chip-btn, .btn-edit{ transform:none !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   10) ระบบปุ่ม AI ชุดเดียวทั้งระบบ — ครูเคาะ 7 ก.ย. 2569
   ────────────────────────────────────────────────────────────────────────
   ⛔ ปัญหาเดิม: ปุ่มที่เรียก AI มี 12 แบบ ไม่เหมือนกันสักแบบเดียว
      มุมมน 8 ค่า (6·9·10·11·20·25·30·999) · ตัวอักษร 10 ค่า (13.12 → 19.2px)
      ชุดสีพื้น 10 ชุด (ม่วง 4 คู่ · ส้ม · เทาอมน้ำเงิน · โปร่งใส 2 · ขาว · ทึบ)
      ไอคอน 3 แบบ (ไม้กายสิทธิ์ 50 จุด · หุ่นยนต์/หลอดไฟ/ดาว/สายฟ้า 15 จุด · อีโมจิ ✨ ในข้อความ)
      ความจางตอนกดไม่ได้ 3 ค่า (.5 / .6 / .7)

   🔴 สาเหตุจริง: สไตล์ปุ่ม AI กระจายอยู่ 3 ที่
      ① ไฟล์ .css  ② style แปะติดแท็กในไฟล์ .php  ③ ข้อความสไตล์ในไฟล์ .js ที่สร้างปุ่ม
      สไตล์ที่แปะติดแท็กชนะไฟล์ CSS เสมอ ⇒ รอบนี้จึงจำเป็นต้องใช้ !important
      🔁 รอบหน้า: ไล่ลบ style ที่แปะออกทีละไฟล์ แล้วค่อยถอด !important ทิ้ง

   ⭐ กติกาที่ครูเคาะหลังคุยกัน (ครูเห็นด้วยว่า "ไหลทุกปุ่มแล้วลายตาจริง"):
      · ม่วง + ไอคอนไม้กายสิทธิ์ = "ปุ่มนี้เรียก AI" — เอกลักษณ์ ห้ามใช้สีอื่น
      · ปุ่ม AI ทั่วไป = ม่วง "ทึบเรียบ" ไม่ไหล
      · ไล่เฉดไหล เก็บไว้ให้ "ปุ่ม AI ตัวหลักของหน้า" เท่านั้น (ขนาดใหญ่)
        เหตุผล: หน้าแผนฝึกอาชีพมีปุ่ม AI 25 ปุ่ม ถ้าไหลหมดจะลายตาและแย่งสายตา
        จากปุ่มหลักของหน้า ⇒ การไหลกลายเป็น "ข้อมูล" ว่านี่คือตัวใหญ่ ไม่ใช่ของตกแต่ง
      · การเคลื่อนไหวที่เหลือไปอยู่ตอนที่มีความหมายจริง: ชี้ กับ กำลังคิด
   ย้อนกลับทั้งหมด: ลบบล็อก 10 นี้ทิ้ง ของเดิมกลับมาครบทุกปุ่ม
   ════════════════════════════════════════════════════════════════════════ */
@keyframes aiFlow{ to{ background-position:300% 0; } }
@keyframes aiSpin{ to{ transform:rotate(360deg); } }

/* ── บัญชีปุ่ม AI — มีปุ่ม AI ใหม่ให้เติมชื่อในบัญชีนี้ที่เดียว ──
   ⚠️ .lsn-add มีหลายแบบ ส่วนใหญ่เป็นปุ่มธรรมดา (ลบทิ้ง · เพิ่มผู้มีส่วนร่วม · ยกเลิก)
      จึงระบุเฉพาะตัวที่เรียก AI จริง ห้ามใส่ .lsn-add เปล่า ๆ */
.ai-btn, .lsn-ai-lg, .lsn-ai-sm, .ud-rec, .chal-ai, .pav-gen, .jt-aim,
.lsn-add.cd-pick, .lsn-add.gap-innov, .lsn-add.gap-redraft, .lsn-add.cl-ai, .lsn-add.ac-ai,
.pj-aibtn, .pj-btn-ai,
.dsd-card .dsd-btn, .dsd-btn, .tpqi-btn,
#btn-moral-ai, #btn-tpqi-measure, #btn-gapfill{
  --aib-h:36px; --aib-fs:.95rem; --aib-pad:16px;   /* ค่าตั้งต้น = ขนาดกลาง */
  font-family:var(--font) !important;
  font-weight:600 !important;
  font-size:var(--aib-fs) !important;
  line-height:1 !important;
  color:#fff !important;
  background:var(--accent) !important;
  border:0 !important;
  border-radius:var(--btn-radius) !important;
  height:var(--aib-h) !important;
  min-height:var(--aib-h) !important;
  padding:0 var(--aib-pad) !important;
  display:inline-flex !important;
  align-items:center !important;
  justify-content:center !important;
  gap:7px !important;
  white-space:nowrap !important;
  cursor:pointer;
  box-shadow:var(--shadow-sm) !important;
  animation:none !important;
  transition:filter .15s ease, transform .15s ease, box-shadow .2s ease !important;
}
/* ไอคอน — FontAwesome 7 วาดจากตัวแปร --fa จึงเปลี่ยนเป็นไม้กายสิทธิ์ได้จาก CSS
   ไม่ต้องแก้ HTML หรือ JS สักบรรทัด (\e2ca = fa-wand-magic-sparkles) */
.ai-btn > i, .lsn-ai-lg > i, .lsn-ai-sm > i, .ud-rec > i, .chal-ai > i, .pav-gen > i, .jt-aim > i,
.lsn-add.cd-pick > i, .lsn-add.gap-innov > i, .lsn-add.gap-redraft > i,
.lsn-add.cl-ai > i, .lsn-add.ac-ai > i,
.pj-aibtn > i, .pj-btn-ai > i,
.dsd-card .dsd-btn > i, .dsd-btn > i, .tpqi-btn > i,
#btn-moral-ai > i, #btn-tpqi-measure > i, #btn-gapfill > i{
  --fa:"\e2ca" !important; font-size:1em !important; margin:0 !important;
}

/* ── ขนาดใหญ่ — "ปุ่ม AI ตัวหลักของหน้า" · เฉพาะกลุ่มนี้เท่านั้นที่ได้ไล่เฉดไหล ──
   ครูสั่งเองว่า "ให้ AI คิดหน่วย+งานให้" และ "ให้ AI ร่างแผนรายหน่วย (6–12)"
   (ทั้งคู่คือ .lsn-ai-lg) ต้องใหญ่เท่าของเดิม */
.lsn-ai-lg, .pj-btn-ai{
  --aib-h:44px; --aib-fs:1.05rem; --aib-pad:22px;
  background:linear-gradient(90deg,#33007f,#7c3aed,#ae10ed,#ec4899,#7c3aed,#33007f) !important;
  background-size:300% 100% !important;
  animation:none !important;   /* ⛔ ยกเลิกอนิเมชั่นไล่เฉดไหลบนปุ่ม — ครูสั่ง 8 ก.ย. 2569 (รอบ 110) */
  box-shadow:0 6px 18px rgba(124,58,237,.38) !important;
}
/* ── ขนาดเล็ก — ปุ่มในตารางวิเคราะห์งาน (.jt-aim มี 17 ปุ่มในหน้าเดียว) ── */
.jt-aim{ --aib-h:30px; --aib-fs:.85rem; --aib-pad:11px; }

/* ── ตอนชี้ — ยกขึ้น 1px มาจากบล็อก 9 อยู่แล้ว ตรงนี้เพิ่มแค่ความสว่าง ── */
.ai-btn:hover, .lsn-ai-lg:hover, .lsn-ai-sm:hover, .ud-rec:hover, .chal-ai:hover,
.pav-gen:hover, .jt-aim:hover, .lsn-add.cd-pick:hover, .lsn-add.gap-innov:hover,
.lsn-add.gap-redraft:hover, .lsn-add.cl-ai:hover, .lsn-add.ac-ai:hover,
.pj-aibtn:hover, .pj-btn-ai:hover,
.dsd-card .dsd-btn:hover, .dsd-btn:hover, .tpqi-btn:hover,
#btn-moral-ai:hover, #btn-tpqi-measure:hover, #btn-gapfill:hover{ filter:brightness(1.08); }

/* ── กำลังคิดอยู่ — คลาส is-ai-busy ใส่ให้โดยตัวเฝ้าดูใน app.js ──
   ครูสั่ง: "ปุ่ม ai ทุกปุ่มถ้ากดแล้ว ต้องมีอนิเมชั่นให้รู้ว่ากำลังทำงานอยู่"
   ไอคอนถูกซ่อน แล้วเอาตัวหมุนมาแทนที่เดิม ⇒ ปุ่มไม่กระตุกเพราะความกว้างเท่าเดิม */
.is-ai-busy{
  opacity:.62 !important; box-shadow:none !important;
  animation:none !important; filter:none !important; cursor:progress !important;
}
.is-ai-busy > i, .is-ai-busy > svg{ display:none !important; }
.is-ai-busy::before{
  content:"" !important; width:1em; height:1em; flex:0 0 auto; box-sizing:border-box;
  border:2px solid rgba(255,255,255,.42); border-top-color:#fff; border-radius:50%;
  animation:aiSpin .8s linear infinite;
}
/* ── กดไม่ได้จริง ๆ (โควตาหมด / ยังกรอกไม่พอ) — ต้องดูต่างจาก "กำลังคิด" ── */
.ai-btn:disabled:not(.is-ai-busy), .lsn-ai-lg:disabled:not(.is-ai-busy),
.lsn-ai-sm:disabled:not(.is-ai-busy), .ud-rec:disabled:not(.is-ai-busy),
.chal-ai:disabled:not(.is-ai-busy), .pav-gen:disabled:not(.is-ai-busy),
.jt-aim:disabled:not(.is-ai-busy), .pj-aibtn:disabled:not(.is-ai-busy),
.pj-btn-ai:disabled:not(.is-ai-busy), #btn-moral-ai:disabled:not(.is-ai-busy),
.dsd-card .dsd-btn:disabled:not(.is-ai-busy), .dsd-btn:disabled:not(.is-ai-busy),
.tpqi-btn:disabled:not(.is-ai-busy),
#btn-tpqi-measure:disabled:not(.is-ai-busy), #btn-gapfill:disabled:not(.is-ai-busy){
  opacity:.45 !important; box-shadow:none !important;
  animation:none !important; filter:none !important; cursor:not-allowed !important;
}

@media (prefers-reduced-motion:reduce){
  .lsn-ai-lg, .pj-btn-ai{ animation:none !important; }
  .is-ai-busy::before{ animation:none !important; }
}


/* ════════════════════════════════════════════════════════════════════════
   บล็อก 11 — แถบหัวเรื่องบนจอมือถือ (7 ก.ย. 2569)
   ครูสั่ง: "ปุ่มบันทึกแผนด้านบน ในหน้าจอมือถือ ให้ซ่อนข้อความชื่อหน้า"
   อาการเดิม: จอแคบ ชื่อหน้ายาวกินที่จนปุ่ม "บันทึกแผน" ถูกบีบเหลือ 65px
              ตัวอักษรเลยเรียงลงมาเป็นแนวตั้งทีละตัว
   .top มีแค่ 2 หน้า: public/plan_new.php · public/plan_new_lesson.php (ตรวจแล้ว ไม่มีที่อื่น)
   ⛔ ไม่แตะ HTML/JS สักบรรทัด · ชื่อหน้ายังอยู่ในโค้ด แค่ไม่แสดงบนจอเล็ก
   ย้อนกลับ: ลบบล็อก 11 นี้ทิ้ง
   ════════════════════════════════════════════════════════════════════════ */
/* ── ใช้ทุกขนาดจอ — แถวหัวเรื่องต้องไม่ดันจอจนมีแถบเลื่อนแนวนอน ──
   ⚠️ ปุ่ม "บันทึกแผน" ไม่ได้เป็นลูกโดยตรงของ .top — plan_save.js ห่อไว้ใน <div> ที่ไม่มีคลาส
      ถ้าห้ามบีบเฉพาะตัวปุ่ม กล่องครอบจะโดนบีบแทน แล้วปุ่มล้นออกนอกกล่อง = เลยขอบขวา
   กติกา: ชื่อหน้ายอมให้ยืด/หดได้ · ปุ่มกับลิงก์ห้ามถูกบีบ · ถ้าไม่พอให้ตกบรรทัดใหม่ ไม่ใช่ดันจอ */
.main > .top{ flex-wrap:wrap; }
/* ⛔ ห้ามใส่ flex-grow ให้ h2 — จะไปดันลิงก์/ปุ่มออกจากตำแหน่งเดิมบนจอใหญ่
     ปล่อยเป็นค่าปริยาย flex:0 1 auto (หดได้ ไม่ยืด) แค่เปิดให้หดต่ำกว่าเนื้อหาได้ */
.main > .top > h2{ min-width:0; }
.main > .top > :not(h2){ flex:0 0 auto; }
.main > .top .btn,
.main > .top button{ white-space:nowrap; }

@media (max-width:640px){
  .main > .top > h2{ display:none; }
}


/* ════════════════════════════════════════════════════════════════════════
   บล็อก 12 — ชิป "เอกสารประจำหน่วย" 11 ชนิด (7 ก.ย. 2569)
   ครูเลือก "แบบ 1 · ชิปบอกสถานะด้วยสี" จากแบบร่าง 5 แบบ
   ────────────────────────────────────────────────────────────────────────
   อาการเดิม: ชิปสูง 44px เพราะบล็อกก่อนหน้าตั้ง .btn{min-height:44px} ให้ทุกปุ่มในระบบ
              แต่ชิปชุดนี้เป็น "ป้ายชนิดเอกสาร" ไม่ใช่ปุ่มสั่งงานหลัก และมี 11 ชิป × ทุกหน่วย
              แผนหนึ่งมี 6–12 หน่วย ⇒ ครูเห็นชิปชุดนี้ 66–132 ชิปต่อแผน จึงต้องเตี้ยและอ่านเร็ว
   กติกาใหม่: เตี้ยลงเหลือ 30px · ตัดป้าย "✓ ทำแล้ว" ออกจากสายตา แล้วให้ "สีทั้งชิป" บอกสถานะแทน
              เขียว = ทำแล้ว · ส้ม = ควรทำ (AI แนะนำ) · ขาว/เทา = ยังไม่ทำ
   ⛔ ป้าย .ud-bdg ไม่ได้ลบ — ซ่อนแบบ "ตามองไม่เห็น แต่โปรแกรมอ่านหน้าจอยังอ่านได้"
      เพราะสีอย่างเดียวไม่พอสำหรับคนตาบอดสี/คนใช้โปรแกรมอ่านหน้าจอ
   ค่าความต่างสีวัดแล้ว: ทำแล้ว 8.4:1 · ควรทำ 7.4:1 · ยังไม่ทำ 5.5:1 (ผ่าน AA ทุกสถานะ)
   คู่กับ: plan_unit_docs.js ที่เลิกทาสีในบรรทัดแล้ว และตั้ง data-st ให้แทน
   ย้อนกลับ: ลบบล็อก 12 + คืน plan_unit_docs.js จาก _backup_20260907_ui3/
   ════════════════════════════════════════════════════════════════════════ */
.lsn-docs{
  --ud-done-bg:#e6f6ec; --ud-done-line:#b6d8c4; --ud-done-ink:#12512f;
  --ud-rec-bg:#fbf1e3;  --ud-rec-line:#f0cf9c;  --ud-rec-ink:#7c3d05;
}
:root[data-theme="dark"] .lsn-docs{
  --ud-done-bg:#12301f; --ud-done-line:#1f5537; --ud-done-ink:#8ef0b4;
  --ud-rec-bg:#33260f;  --ud-rec-line:#5c451c;  --ud-rec-ink:#f0c483;
}
.lsn-docs .ud-gen{
  height:30px; min-height:30px; padding:0 11px;
  border:1px solid var(--line); border-radius:8px;
  background:var(--surface); color:var(--muted);
  font-size:.92rem; font-weight:600; line-height:1;
  display:inline-flex; align-items:center; gap:7px;
  white-space:nowrap; box-shadow:none;
}
.lsn-docs .ud-gen > i{ font-size:.95em; opacity:.85; }
.lsn-docs .ud-gen[data-st="done"]{
  background:var(--ud-done-bg); border-color:var(--ud-done-line); color:var(--ud-done-ink);
}
.lsn-docs .ud-gen[data-st="rec"]{
  background:var(--ud-rec-bg); border-color:var(--ud-rec-line); color:var(--ud-rec-ink);
}
/* เครื่องหมายท้ายชิป — ย้ำสถานะอีกชั้นสำหรับคนแยกสีไม่ออก */
.lsn-docs .ud-gen[data-st="done"]::after{ content:"\2713"; font-weight:700; color:var(--ok); }
.lsn-docs .ud-gen[data-st="rec"]::after{ content:"\25CF"; font-size:.62em; color:var(--warn); }
/* ป้ายข้อความ — ซ่อนจากสายตา แต่ยังอยู่ในสารบบให้โปรแกรมอ่านหน้าจอ */
.lsn-docs .ud-bdg{
  position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}
@media (max-width:640px){
  .lsn-docs .ud-gen{ height:38px; min-height:38px; }   /* จอสัมผัส — นิ้วต้องกดโดน */
}


/* ════════════════════════════════════════════════════════════════════════
   บล็อก 13 — คอลัมน์ "Ver" ในหน้าคลังแผน (history.php) · 7 ก.ย. 2569
   อาการ: เลขรุ่นตั้งแต่ 2 หลักขึ้นไป (V.36) ตกบรรทัดเป็น "V.3" / "6"
   เหตุ: หัวตารางกำหนด width:56px ไว้ในบรรทัด · ป้าย .pill มีระยะขอบในตัว
         พอเลขยาวขึ้นเนื้อหาจึงเกิน 56px แล้วเบราว์เซอร์ตัดบรรทัดให้
   แก้: สั่งห้ามตัดบรรทัดที่ช่องแรก — ตารางเป็น table-layout:auto อยู่แล้ว
        คอลัมน์จะขยายตามเนื้อหาเอง ไม่ต้องไปแก้ตัวเลข 56px ในบรรทัด
   ⛔ ไม่แตะ HTML/PHP · ไม่แตะคอลัมน์อื่น
   ย้อนกลับ: ลบบล็อก 13 นี้ทิ้ง
   ════════════════════════════════════════════════════════════════════════ */
.hist-tb th:first-child,
.hist-tb td:first-child{ white-space:nowrap; }
