/* ==========================================================================
   HighHR Payroll — Design System
   --------------------------------------------------------------------------
   ระบบนี้มี "สองธีมในไฟล์เดียว" และตั้งใจให้ต่างกัน:

     หน้าทำงาน 19 หน้า  →  เทาอ่อน–ขาว นุ่มตา มุมมนใหญ่ เงาฟุ้งบาง
                            สีเน้นเป็นน้ำเงินที่ดูดมาจากโลโก้บริษัท
     หน้าเข้าสู่ระบบ      →  ดำสนิท มีคลิปวิ่งข้างหลัง สีเน้นเขียวนีออน

   ทำไมต่างกันได้โดยไม่ดูเป็นคนละระบบ: ทั้งสองใช้ฟอนต์เดียวกัน ทรงแคปซูลเดียวกัน
   จังหวะการเคลื่อนไหวเดียวกัน และโลโก้ในกรอบขาวเหมือนกัน — ต่างแค่ "แสง"
   เหมือนห้องเดียวกันตอนกลางวันกับตอนกลางคืน

   วิธีที่ใช้: ตัวแปรสีชุดหลักอยู่ที่ :root (ธีมสว่าง)
   แล้วเขียนทับทั้งชุดอีกครั้งที่ body.signin-page (ธีมมืด)
   ส่วนประกอบทุกตัวจึงเขียนครั้งเดียวแล้วใช้ได้ทั้งสองหน้า ไม่ต้องมี CSS สองชุด

   หลักการของหน้าทำงาน:
   • สีเป็นกลางทั้งหน้า — ให้ "ตัวเลขเงิน" กับ "สถานะที่ต้องตรวจ" เป็นสิ่งเดียวที่มีสี
   • ตัวเลขเงินต้องอ่านง่ายที่สุด — tabular-nums, ชิดขวา, แยกบวก/ลบชัดเจน
   • ตารางยาวหลักพันแถวต้องไม่หลงตา — หัวตารางติดบน (พื้นทึบเสมอ), เส้นคั่นบาง
   • ใช้ได้ทั้งจอ 13" และ 27" — คอนเทนต์กว้างเต็มแต่มีเพดาน
   • ไทยต้องสมบูรณ์ — IBM Plex Sans Thai โฮสต์เอง วรรณยุกต์/สระซ้อนไม่เพี้ยน
   • เร็วที่สุดสำหรับคนใช้พร้อมกันหลายร้อยคน — ไม่มี dependency ภายนอกแม้แต่ตัวเดียว
     ไม่มี blur ในจุดที่ต้องวาดซ้ำถี่ ๆ อนิเมชันใช้แค่ transform/opacity (ไม่ทำ reflow)
   • พิมพ์ลงกระดาษได้ทันที — มีสไตล์พิมพ์แยกไว้ท้ายไฟล์
   ========================================================================== */

/* ฟอนต์อยู่ในไฟล์ fonts.css แยกต่างหาก และโหลดด้วย <link> ในหน้า HTML
   ไม่ใช้ @import ที่นี่ เพราะ @import บังคับให้เบราว์เซอร์รอโหลด app.css ให้เสร็จก่อน
   แล้วค่อยเริ่มโหลดฟอนต์ (ต่อคิวกัน) — ใช้ <link> สองอันจะโหลดพร้อมกันได้ เร็วกว่า */

/* ══════════════════════════════════════════════════════════════════════
   ชุดสีที่ 1 — ธีมสว่างของหน้าทำงาน (ค่าเริ่มต้นของทั้งระบบ)
   ══════════════════════════════════════════════════════════════════════ */
:root {
  /* ธีมสว่างอย่างเดียว ไม่สลับตามโหมดของเครื่องผู้ใช้
     เพราะหน้าจอเงินเดือนต้องหน้าตาเหมือนกันทุกเครื่องและพิมพ์ลงกระดาษได้ทันที */
  color-scheme: light;

  /* บันไดสีเทา — อมฟ้าจาง ๆ ให้ดูสะอาดและเย็นตา ไม่ใช่เทากลางที่ดูหม่น
     ไล่จากขาว (0) ไปเข้มสุด (900) */
  --n-0:   #ffffff;
  --n-25:  #fcfcfd;
  --n-50:  #f7f8fa;
  --n-100: #f1f3f7;
  --n-150: #eaedf3;
  --n-200: #e2e6ee;
  --n-300: #cfd5e2;
  /* ★ สองค่านี้ตั้งจากการวัดความคมชัดจริง ไม่ใช่กะเอาว่าสวย ★
     --n-500 คือ --ink-3 ที่ใช้กับคำอธิบายและตัวเลขรองทั้งระบบ
     ต้องได้อย่างน้อย 4.5:1 บนพื้นขาว (เกณฑ์ WCAG AA สำหรับตัวอักษรขนาดปกติ)
     คนอ่านหน้านี้คือ HR อายุ 40+ ในโรงงาน ไม่ใช่นักออกแบบที่นั่งจอ 27" ในห้องมืด
     ถ้าทำให้อ่อนลงเพื่อความ "นุ่มตา" จะกลายเป็นอ่านไม่ออกทันที */
  --n-400: #848fa3;   /* 3.18:1 — ใช้กับ placeholder และตัวเลขศูนย์ที่จงใจให้จาง
                         ไม่ใช่ตัวอักษรเนื้อหา จึงไม่ต้องถึง 4.5:1 แต่ต้องไม่ต่ำกว่า 3:1
                         ไม่งั้น placeholder จะจางจนคนไม่รู้ว่าช่องนั้นต้องกรอกอะไร */
  --n-500: #697285;   /* 4.83:1 บนขาว · 4.55:1 บนพื้นหน้า — ผ่าน AA ทั้งสองพื้น
                         (ตัวหนังสือจางโผล่บนทั้งพื้นการ์ดขาวและพื้นหน้าเทาอ่อน
                          จึงต้องผ่านเกณฑ์บนพื้นที่เข้มกว่าด้วย ไม่ใช่แค่บนขาว) */
  --n-600: #5c6478;
  --n-700: #434a5c;
  --n-800: #2e3446;
  --n-900: #1b2030;

  /* สีเน้น — น้ำเงินที่ดูดมาจากโลโก้บริษัทจริง ๆ
     (โลโก้ไล่จากกรมท่า #0f2f5e ไปฟ้าอ่อน #9db3e0 — เอาช่วงกลางมาเป็นสีหลัก) */
  --brand-50:  #eef3fd;
  --brand-100: #dee8fa;
  --brand-200: #c4d6f4;
  --brand-300: #9db3e0;
  --brand-500: #3f6bc4;
  --brand-600: #33589f;
  --brand-700: #274677;
  --brand-800: #1c3862;
  --brand-900: #0f2f5e;

  --accent:      var(--brand-500);
  --accent-soft: var(--brand-50);
  --accent-bd:   var(--brand-300);
  --accent-glow: rgba(63, 107, 196, .35);
  --accent-ink:  var(--brand-600);

  /* ความหมาย — พาสเทลนุ่ม ๆ ไม่ฉูดฉาด
     พื้นเป็นสีทึบ (ไม่ใช่โปร่งแสง) เพราะต้องใช้กับหัวตารางติดบนและคอลัมน์ติดซ้าย
     ถ้าโปร่งแสงจะเห็นแถวอื่นทะลุขึ้นมาให้อ่านผิด */
  --ok-bg:   #edfaf1;  --ok-bd:   #bfe6cd;  --ok-fg:   #1c7a4a;
  --warn-bg: #fff7e9;  --warn-bd: #f6dfb4;  --warn-fg: #96660f;
  --bad-bg:  #fef1f2;  --bad-bd:  #f6ccd1;  --bad-fg:  #b03349;
  --info-bg: #eff4fd;  --info-bd: #d2e0f6;  --info-fg: #33589f;

  /* พื้นผิว */
  --canvas:    var(--n-50);
  --surface:   var(--n-0);
  --surface-2: var(--n-25);
  --surface-3: var(--n-100);
  --border:        var(--n-200);
  --border-soft:   var(--n-150);
  --border-strong: var(--n-300);
  --ink:     var(--n-800);
  --ink-2:   var(--n-600);
  --ink-3:   var(--n-500);
  --ink-inv: var(--n-0);

  /* พื้นจาง ๆ ที่วางทับพื้นผิว — ใช้กับปุ่มรอง ชิป และตอนวางเมาส์
     ต้องแยกเป็นตัวแปร เพราะธีมมืดใช้ "ขาวโปร่ง" ส่วนธีมสว่างใช้ "เทาทึบ" */
  --fill-1: var(--n-100);
  --fill-2: var(--n-150);
  --fill-3: var(--n-200);

  /* แถบเมนู — ขาวสะอาด เมนูที่เลือกเป็นแคปซูลฟ้าอ่อน */
  --side-bg: var(--n-0);
  --side-fg: var(--n-600);
  --side-fg-strong: var(--n-900);
  --side-hover: var(--n-100);
  --side-active: var(--brand-50);
  --side-accent: var(--brand-500);
  --side-sep: var(--n-150);

  /* จังหวะ */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 26px; --s7: 34px; --s8: 46px;

  /* มุมมน — มนกว่ามาตรฐานหนึ่งขั้นทั้งระบบ ให้หน้าตาดูนุ่มและเป็นมิตร
     ปุ่ม ชิป ป้าย ใช้ radius เต็ม (แคปซูล) เป็นลายเซ็นของแบรนด์ */
  --r-sm: 11px; --r: 15px; --r-md: 15px; --r-lg: 20px; --r-xl: 26px; --r-full: 9999px;

  /* เงา — ฟุ้ง โปร่ง อมน้ำเงินนิด ๆ ตามสีตัวหนังสือ ไม่ใช่เงาเทาดำที่ดูหนัก */
  --sh-sm:  0 1px 2px rgba(27, 32, 48, .04);
  --sh-1:   0 1px 2px rgba(27, 32, 48, .04);
  --sh-2:   0 1px 2px rgba(27, 32, 48, .04), 0 4px 14px -6px rgba(27, 32, 48, .10);
  --sh-3:   0 2px 6px rgba(27, 32, 48, .05), 0 18px 40px -16px rgba(27, 32, 48, .18);
  --sh-pop: 0 6px 16px rgba(27, 32, 48, .08), 0 32px 64px -24px rgba(27, 32, 48, .28);
  --sh-lift:0 2px 4px rgba(27, 32, 48, .05), 0 12px 28px -12px rgba(27, 32, 48, .16);

  /* วงโฟกัส — ฟ้านุ่ม มองเห็นชัดแต่ไม่จ้า ใช้คีย์บอร์ดล้วนได้ทั้งระบบ */
  --ring: 0 0 0 3px rgba(63, 107, 196, .18);

  /* ── ฟอนต์ ──────────────────────────────────────────────────────
     --font        : ตัวหลักของทั้งแอป — ไทย+อังกฤษอยู่ในฟอนต์เดียวกัน
                     ความสูงตัวอักษรจึงเท่ากันเสมอ ตารางไม่กระตุก
     --font-display: General Sans — ใช้เฉพาะคำอังกฤษล้วน (ชื่อแบรนด์)
     --font-serif  : Playfair + Noto Serif Thai — คู่เซริฟที่มีทั้งสองภาษา */
  --font: "IBM Plex Sans Thai", "Leelawadee UI", "Sarabun", "Noto Sans Thai",
          "Segoe UI", Tahoma, system-ui, sans-serif;
  --font-display: "General Sans", "IBM Plex Sans Thai", system-ui, sans-serif;
  --font-serif: "Playfair Display", "Noto Serif Thai", Georgia, serif;
  --font-mono: ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;

  --sidebar-w: 254px;
  --topbar-h: 68px;
  --content-max: 1680px;

  /* จังหวะการเคลื่อนไหวของแบรนด์ — ออกตัวเร็ว ค่อย ๆ หยุดนิ่ง */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --ease-reveal: cubic-bezier(.05, .9, .1, 1);
}

/* ══════════════════════════════════════════════════════════════════════
   ชุดสีที่ 2 — ธีมมืดเฉพาะหน้าเข้าสู่ระบบ
   --------------------------------------------------------------------
   เขียนทับตัวแปรทั้งชุดที่ body ทีเดียว ลูกหลานทุกตัวจึงเปลี่ยนตามหมด
   ส่วนประกอบ (ปุ่ม · ช่องกรอก · กล่องแจ้งเตือน · เคอร์เซอร์) ไม่ต้องเขียนซ้ำเลย
   ══════════════════════════════════════════════════════════════════════ */
body.signin-page {
  color-scheme: dark;

  --n-0:   #000000;
  --n-25:  #070707;
  --n-50:  #0a0a0a;
  --n-100: #0f0f0f;
  --n-150: #141414;
  --n-200: #1a1a1a;
  --n-300: #242424;
  --n-400: #6b6b6b;
  --n-500: #8a8a8a;
  --n-600: #a9a9a9;
  --n-700: #c8c8c8;
  --n-800: #ededed;
  --n-900: #ffffff;

  /* ฟ้าสว่าง — สีเน้นของหน้าเข้าสู่ระบบ
     เป็นน้ำเงินตัวเดียวกับหน้าทำงาน แต่ยกความสว่างขึ้นเพราะอยู่บนพื้นดำ
     (#3f6bc4 ของหน้าทำงานได้แค่ 4.11:1 บนดำ · #4da3ff ได้ 8.00:1) */
  --accent:      #4da3ff;
  --accent-soft: rgba(77, 163, 255, .14);
  --accent-bd:   rgba(77, 163, 255, .48);
  --accent-glow: rgba(77, 163, 255, .45);
  --accent-ink:  #8cc4ff;

  --ok-bg:   #08170f;  --ok-bd:   rgba(94, 224, 148, .32);  --ok-fg:   #6ee7a8;
  --warn-bg: #221a08;  --warn-bd: rgba(255, 186, 84, .30);  --warn-fg: #ffc06b;
  --bad-bg:  #240f0f;  --bad-bd:  rgba(255, 106, 106, .32); --bad-fg:  #ff9090;
  --info-bg: #131313;  --info-bd: rgba(255, 255, 255, .14); --info-fg: #c8c8c8;

  --canvas:    #000000;
  --surface:   #0c0c0c;
  --surface-2: #111111;
  --surface-3: #191919;
  --border:        rgba(255, 255, 255, .14);
  --border-soft:   rgba(255, 255, 255, .08);
  --border-strong: rgba(255, 255, 255, .26);
  --ink:     #ededed;
  --ink-2:   #b6b6b6;
  --ink-3:   #8a8a8a;
  --ink-inv: #000000;

  --fill-1: rgba(255, 255, 255, .05);
  --fill-2: rgba(255, 255, 255, .1);
  --fill-3: rgba(255, 255, 255, .16);

  /* "เงา" บนพื้นดำ = แสงขอบบน + ม่านดำใต้กล่อง ไม่ใช่เงาเทาแบบธีมสว่าง */
  --sh-sm:  inset 0 1px 0 0 rgba(255, 255, 255, .05);
  --sh-1:   inset 0 1px 0 0 rgba(255, 255, 255, .05);
  --sh-2:   inset 0 1px 0 0 rgba(255, 255, 255, .06), 0 1px 2px rgba(0, 0, 0, .8);
  --sh-3:   inset 0 1px 0 0 rgba(255, 255, 255, .08), 0 12px 34px -12px rgba(0, 0, 0, .95);
  --sh-pop: inset 0 1px 0 0 rgba(255, 255, 255, .10), 0 24px 64px -18px rgba(0, 0, 0, 1);
  --sh-lift:inset 0 1px 0 0 rgba(255, 255, 255, .10), 0 8px 26px -12px rgba(0, 0, 0, .9);

  --ring: 0 0 0 2px #000, 0 0 0 4px var(--accent-bd), 0 0 14px rgba(77, 163, 255, .38);
}

/* ── Reset / base ──────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; background: var(--canvas); }
/* html อยู่เหนือ body จึงมองไม่เห็นตัวแปรที่เขียนทับใน body.signin-page
   ต้องบอกมันตรง ๆ ว่าหน้านี้พื้นดำ ไม่งั้นจะเห็นขอบสว่างโผล่ตอนหน้ายืดเกินจอ */
html:has(body.signin-page) { background: #000; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.6;              /* ไทยมีสระบน–ล่าง ต้องการที่หายใจมากกว่าอังกฤษ */
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.35; letter-spacing: -.01em; color: var(--n-900); }
p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

a { color: var(--brand-600); text-decoration: none; transition: color .18s var(--ease); }
a:hover { color: var(--brand-500); text-decoration: underline; text-underline-offset: 3px; }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

::selection { background: var(--brand-100); color: var(--brand-900); }

/* scrollbar ให้กลืนกับธีม */
* { scrollbar-width: thin; scrollbar-color: var(--n-300) transparent; }
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--n-300); border-radius: var(--r-full);
  border: 3px solid transparent; background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--n-400); background-clip: content-box; }

.icon { width: 18px; height: 18px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.icon.sm { width: 15px; height: 15px; }
.icon.lg { width: 22px; height: 22px; }

/* ══════════════════════════════════════════════════════════════════════
   โครงหน้า
   ══════════════════════════════════════════════════════════════════════ */
.app {
  display: flex; min-height: 100vh;
  /* วาดแถบขาวของเมนูให้ยาวเต็มหน้า — .sidebar สูงแค่ 100vh (sticky)
     ถ้าไม่วาดพื้นตรงนี้ เลื่อนลงไปจะเห็นขอบสีตัดกลางคัน */
  background: linear-gradient(to right,
    var(--side-bg) 0, var(--side-bg) var(--sidebar-w), var(--canvas) var(--sidebar-w));
}

/* ── Sidebar ───────────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--side-bg);
  color: var(--side-fg);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 30;
  border-right: 1px solid var(--side-sep);
}

.brand {
  display: flex; align-items: center; gap: 11px;
  padding: var(--s5) var(--s4) var(--s4);
  border-bottom: 1px solid var(--side-sep);
}
.brand-mark {
  width: 36px; height: 36px; flex: 0 0 36px;
  border-radius: var(--r); background: var(--brand-900); color: #fff;
  display: grid; place-items: center;
}
.brand img { border-radius: 10px; }
.brand-text { min-width: 0; }
.brand-text b {
  display: block; color: var(--side-fg-strong);
  font-family: var(--font-display);
  font-size: 15px; font-weight: 600; letter-spacing: -.02em;
}
.brand-text span {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--ink-3); letter-spacing: .01em;
}

.nav { padding: var(--s4) var(--s3) var(--s5); overflow-y: auto; flex: 1; }
.nav-group { margin-top: var(--s5); }
.nav-group:first-child { margin-top: 0; }
.nav-label {
  padding: 0 12px 8px;
  font-size: 10px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3);
}
.nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px;
  margin-bottom: 3px;
  color: var(--side-fg);
  font-size: 13.5px;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  text-decoration: none;
  position: relative;
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.nav a:hover { background: var(--side-hover); color: var(--side-fg-strong); text-decoration: none; }
.nav a.on {
  background: var(--side-active);
  border-color: var(--brand-200);
  color: var(--brand-700);
  font-weight: 600;
}
/* ขีดสั้น ๆ หน้าเมนูที่เลือกอยู่ — บอกตำแหน่งได้ในพริบตาโดยไม่ต้องระบายสีทั้งแถบ */
.nav a.on::before {
  content: "";
  position: absolute; left: -7px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 18px; border-radius: var(--r-full);
  background: var(--side-accent);
}
.nav a .icon { opacity: .62; transition: opacity .18s var(--ease); }
.nav a:hover .icon { opacity: .85; }
.nav a.on .icon { opacity: 1; color: var(--brand-500); }
.nav .count {
  margin-left: auto; font-size: 11px; font-weight: 600;
  background: var(--fill-1); color: var(--ink-2);
  padding: 1px 9px; border-radius: var(--r-full);
}

.side-foot { padding: var(--s3); border-top: 1px solid var(--side-sep); }
.side-user {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: var(--r-full);
  border: 1px solid transparent;
  color: var(--side-fg); text-decoration: none;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.side-user:hover { background: var(--side-hover); border-color: var(--border-soft); text-decoration: none; color: var(--side-fg); }
.avatar {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: 50%;
  background: var(--brand-500); color: #fff;
  display: grid; place-items: center; font-weight: 700; font-size: 13px;
  font-family: var(--font-display);
  box-shadow: var(--sh-1);
}
.side-user .who { min-width: 0; }
.side-user .who b { display: block; color: var(--side-fg-strong); font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-user .who span { display: block; font-size: 11px; color: var(--ink-3); }
.side-foot form { margin-top: var(--s2); }
.btn-signout {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 7px;
  background: transparent; color: var(--ink-3);
  border: 1px solid transparent; border-radius: var(--r-full);
  padding: 9px; font: inherit; font-family: var(--font); font-size: 12.5px; cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.btn-signout:hover { background: var(--fill-1); color: var(--ink); border-color: var(--border-soft); }

/* ── พื้นที่หลัก ───────────────────────────────────────────────────── */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  min-height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s3) var(--s6);
  /* ทึบเสมอ — ตารางเลื่อนอยู่ใต้แถบนี้ ถ้าโปร่งแสงตัวเลขจะทะลุขึ้นมาอ่านผิด
     และ backdrop-filter ต้องวาดใหม่ทุกเฟรมที่เลื่อน ทำให้ตารางพันแถวหนืด */
  background: var(--canvas);
  border-bottom: 1px solid var(--border-soft);
}
.topbar h1 { font-size: 19px; font-weight: 600; letter-spacing: -.025em; }
.topbar .sub { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.topbar .grow { flex: 1; min-width: 0; }
.topbar-actions { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }

.content { padding: var(--s5) var(--s6) var(--s8); max-width: var(--content-max); width: 100%; }

.sidebar-toggle { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   ส่วนประกอบ
   ══════════════════════════════════════════════════════════════════════ */

/* ── Card ──────────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
  margin-bottom: var(--s5);
  overflow: hidden;
}
.card-head {
  display: flex; align-items: center; gap: var(--s3);
  padding: 15px var(--s5) 13px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--surface);
}
.card-head h2 { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 9px; }
.card-head h2 > .icon { color: var(--brand-500); }
.card-head .grow { flex: 1; }
.card-head .hint { font-size: 12px; color: var(--ink-3); font-weight: 400; }
.card-body { padding: var(--s5); }
.card-body.flush { padding: 0; }
.card-foot {
  padding: var(--s4) var(--s5); border-top: 1px solid var(--border-soft);
  background: var(--surface-2); display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
}

.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--s5); }

/* ── KPI ───────────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(166px, 1fr)); gap: var(--s3); margin-bottom: var(--s5); }
.stat {
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--r-lg); padding: var(--s4) var(--s5) var(--s5);
  box-shadow: var(--sh-2);
  position: relative; overflow: hidden;
  transition: border-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.stat:hover { border-color: var(--border); transform: translateY(-2px); box-shadow: var(--sh-lift); }
.stat .label {
  font-size: 11.5px; color: var(--ink-3); display: flex; align-items: center; gap: 9px;
  font-weight: 500;
}
/* ไอคอนอยู่ในชิปกลมนุ่ม ๆ ตามความหมาย — จุดที่ทำให้หน้าดูเป็นมิตร */
.stat .label > .icon {
  box-sizing: content-box; width: 14px; height: 14px; padding: 7px;
  border-radius: var(--r-full); background: var(--fill-1); color: var(--ink-2);
  border: 1px solid var(--border-soft);
}
.stat.is-ok    .label > .icon { background: var(--ok-bg);   color: var(--ok-fg);   border-color: var(--ok-bd); }
.stat.is-warn  .label > .icon { background: var(--warn-bg); color: var(--warn-fg); border-color: var(--warn-bd); }
.stat.is-bad   .label > .icon { background: var(--bad-bg);  color: var(--bad-fg);  border-color: var(--bad-bd); }
.stat.is-brand .label > .icon { background: var(--brand-50);color: var(--brand-600); border-color: var(--brand-200); }
.stat .value {
  font-size: 27px; font-weight: 600; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; margin-top: 10px; line-height: 1.1;
  color: var(--n-900);
}
.stat.is-ok .value   { color: var(--ok-fg); }
.stat.is-warn .value { color: var(--warn-fg); }
.stat.is-bad .value  { color: var(--bad-fg); }
.stat .foot { font-size: 11.5px; color: var(--ink-3); margin-top: 4px; }
.stat .foot a { font-weight: 600; }

/* ── ปุ่ม ──────────────────────────────────────────────────────────── */
/* ทรงแคปซูลทั้งระบบ — เป็นลายเซ็นเดียวกับปุ่มบนหน้าเข้าสู่ระบบ */
.btn {
  --btn-bg: var(--surface); --btn-fg: var(--ink); --btn-bd: var(--border);
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 17px; border-radius: var(--r-full);
  border: 1px solid var(--btn-bd); background: var(--btn-bg); color: var(--btn-fg);
  font: inherit; font-family: var(--font); font-size: 13px; font-weight: 500;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  box-shadow: var(--sh-1);
  transition: background .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), transform .14s var(--ease), box-shadow .18s var(--ease);
}
.btn .icon { color: var(--ink-3); transition: color .18s var(--ease); }
.btn:hover {
  background: var(--surface); border-color: var(--border-strong);
  box-shadow: var(--sh-lift); transform: translateY(-2px); text-decoration: none;
}
.btn:hover .icon { color: var(--ink-2); }
.btn:active { transform: translateY(0); box-shadow: var(--sh-1); }
.btn[disabled], .btn.is-busy { opacity: .45; pointer-events: none; box-shadow: none; transform: none; }

.btn.primary { --btn-bg: var(--brand-500); --btn-fg: #fff; --btn-bd: var(--brand-500); font-weight: 600; box-shadow: var(--sh-2); }
.btn.primary .icon, .btn.primary:hover .icon { color: rgba(255, 255, 255, .78); }
.btn.primary:hover { --btn-bg: var(--brand-600); --btn-bd: var(--brand-600); box-shadow: 0 8px 22px -8px rgba(63, 107, 196, .55); }

.btn.danger { --btn-fg: var(--bad-fg); --btn-bd: var(--bad-bd); }
.btn.danger .icon { color: var(--bad-fg); }
.btn.danger:hover { background: var(--bad-bg); border-color: var(--bad-fg); color: var(--bad-fg); }
.btn.danger:hover .icon { color: var(--bad-fg); }

.btn.danger-solid { --btn-bg: #c0455c; --btn-fg: #fff; --btn-bd: #c0455c; font-weight: 600; }
.btn.danger-solid .icon { color: rgba(255, 255, 255, .8); }
.btn.danger-solid:hover { --btn-bg: #a83b50; --btn-bd: #a83b50; --btn-fg: #fff; }

.btn.ghost { --btn-bd: transparent; --btn-bg: transparent; color: var(--ink-2); box-shadow: none; }
.btn.ghost:hover {
  background: var(--fill-1); border-color: transparent; color: var(--ink);
  box-shadow: none; transform: none;
}

.btn.sm, .btn.xs { padding: 5px 12px; font-size: 12px; gap: 5px; box-shadow: none; }
.btn.ghost.sm, .btn.ghost.xs { padding: 5px 10px; }
.btn.sm:hover, .btn.xs:hover { box-shadow: var(--sh-1); }
.btn.icon-only { padding: 9px; }
.btn.icon-only.sm { padding: 5px; }
.btn-row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }

/* ── ฟอร์ม ─────────────────────────────────────────────────────────── */
label { display: block; font-size: 12px; font-weight: 500; color: var(--ink-2); margin-bottom: 6px; }
.field { margin-bottom: var(--s4); }
.field:last-child { margin-bottom: 0; }
.field .hint { font-size: 11.5px; color: var(--ink-3); margin-top: 6px; line-height: 1.55; }

/* เลือกแบบ "ยกเว้น" ไม่ใช่ไล่ทีละ type — ลืมใส่ type ในหน้าไหน ช่องนั้นก็ยังสวย */
/* :where() ทำให้ selector นี้ specificity = 0 — กฎเฉพาะจุดข้างล่างจึงเขียนทับได้
   (เคยพลาด: .search-wrap input สู้ไม่ได้ ไอคอนค้นหาเลยทับข้อความ) */
:where(input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]):not([type=hidden])),
:where(select), :where(textarea) {
  width: 100%; padding: 10px 13px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  font: inherit; font-family: var(--font); font-size: 13px;
  background: var(--surface-2); color: var(--ink);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--n-400); opacity: 1; }
input:hover:not([readonly]):not([disabled]), select:hover:not([disabled]), textarea:hover:not([readonly]) { border-color: var(--border-strong); }
input:focus, select:focus, textarea:focus {
  outline: none; background: var(--surface);
  border-color: var(--brand-300); box-shadow: var(--ring);
}
input[readonly], input[disabled], select[disabled], textarea[readonly] {
  background: var(--fill-1); color: var(--ink-3); cursor: not-allowed; border-color: var(--border-soft);
}
input[type=number] { font-variant-numeric: tabular-nums; }
input[type=date], input[type=time], input[type=datetime-local], input[type=month] {
  font-variant-numeric: tabular-nums;
}
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5' fill='none' stroke='%237c8598' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 12px;
  padding-right: 30px;
}

/* ช่องเลือกไฟล์ — เบราว์เซอร์วาดเองไม่เข้าธีม จึงจัดใหม่ให้เหมือนกล่องวางไฟล์ */
input[type=file] {
  width: 100%; font: inherit; font-family: var(--font); font-size: 12.5px; color: var(--ink-3);
  padding: 9px 11px; cursor: pointer;
  background: var(--surface-2);
  border: 1px dashed var(--border-strong); border-radius: var(--r-sm);
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
input[type=file]:hover { border-color: var(--brand-300); background: var(--brand-50); }
input[type=file]:focus { outline: none; box-shadow: var(--ring); border-color: var(--brand-300); }
input[type=file]::file-selector-button {
  font: inherit; font-family: var(--font); font-size: 12.5px; font-weight: 600;
  margin: -1px 12px -1px -2px; padding: 6px 15px;
  color: #fff; background: var(--brand-500);
  border: 1px solid var(--brand-500); border-radius: var(--r-full);
  cursor: pointer;
  transition: background .18s var(--ease), transform .14s var(--ease);
}
input[type=file]::file-selector-button:hover { background: var(--brand-600); transform: translateY(-1px); }

/* ช่องติ๊กทุกช่องในระบบ — รวมช่องเลือกคนพิมพ์สลิป (.slip-pick) ที่อยู่ในตารางลอย ๆ
   ไม่ได้อยู่ในกล่อง .check เบราว์เซอร์จะวาดเป็นสีฟ้าเริ่มต้นซึ่งหลุดธีมทันที */
input[type=checkbox], input[type=radio] {
  accent-color: var(--brand-500);
  width: 16px; height: 16px;
  cursor: pointer;
}
input[type=checkbox]:disabled, input[type=radio]:disabled { cursor: not-allowed; opacity: .45; }

.check { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--ink); font-weight: 400; margin-bottom: 0; cursor: pointer; }
.check input { margin: 2px 0 0; flex: 0 0 auto; }
.check-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px var(--s4); }

.row { display: grid; gap: var(--s4); }
.row.c2 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.row.c3 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.row.c4 { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* ── แถบแท็บ (กลุ่มตั้งค่าระบบ) ─────────────────────────────────────
   ใช้แทนเมนู 4 บรรทัดที่เคยอยู่ในแถบซ้าย — ของที่เปิดดูนาน ๆ ครั้ง
   ไม่ควรกินพื้นที่เมนูเท่ากับงานที่ทำทุกวัน

   ทรงเป็นแคปซูลซ้อนแคปซูล: กล่องนอกพื้นเทาอ่อน แท็บที่เลือกเป็นแผ่นขาวลอยขึ้นมา
   เป็นภาษาเดียวกับเมนูซ้ายและปุ่มทั้งระบบ */
.tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  background: var(--surface-3);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-full);
  padding: 5px;
  margin-bottom: var(--s5);
  width: fit-content; max-width: 100%;
}
.tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  border-radius: var(--r-full);
  border: 1px solid transparent;
  color: var(--ink-2);
  font-size: 13px; font-weight: 500;
  text-decoration: none; white-space: nowrap;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.tab .icon { color: var(--ink-3); transition: color .18s var(--ease); }
.tab:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.tab:hover .icon { color: var(--ink-2); }
.tab.on {
  background: var(--surface);
  border-color: var(--border);
  color: var(--brand-700);
  font-weight: 600;
  box-shadow: var(--sh-1);
}
.tab.on .icon { color: var(--brand-500); }

/* แถบตัวกรอง */
.filters { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.filters .field { margin-bottom: 0; }
.filters .grow { flex: 1 1 200px; min-width: 170px; }
.filters .actions { display: flex; gap: var(--s2); }

.search-wrap { position: relative; }
.search-wrap > .icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  color: var(--n-400); pointer-events: none; z-index: 1;
}
.search-wrap input { padding-left: 38px; }

/* ── แถบตัวกรองรายชื่อ (หน้าสลิป / ปฏิทิน) ─────────────────────────── */
.filterbar {
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--r-lg); padding: var(--s5);
  margin-bottom: var(--s5); box-shadow: var(--sh-2);
  display: flex; flex-direction: column; gap: var(--s4);
}
.filterbar .filter-row { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.filterbar .field { margin-bottom: 0; }
.filterbar .field.grow { flex: 1 1 220px; min-width: 180px; }
.filterbar .field.narrow { flex: 0 0 130px; }
.filterbar .label-txt {
  display: block; font-size: 12px; font-weight: 500;
  color: var(--ink-2); margin-bottom: 6px;
}
.filterbar .filter-foot {
  display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
  border-top: 1px solid var(--border-soft); padding-top: var(--s3);
}
.filterbar .filter-foot .grow { flex: 1; }

.chips { display: flex; gap: 7px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-full); padding: 6px 14px 6px 11px;
  font-size: 12.5px; color: var(--ink-2); user-select: none;
  transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.chip:hover { border-color: var(--brand-300); background: var(--brand-50); color: var(--brand-700); }
.chip input { margin: 0; width: 14px; height: 14px; }
.chip:has(input:checked) {
  background: var(--brand-500); border-color: var(--brand-500); color: #fff; font-weight: 600;
  box-shadow: var(--sh-1);
}
.chip:has(input:checked) input { accent-color: #fff; }

/* ── แถบเลือกงวด ───────────────────────────────────────────────────── */
.periodbar {
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--r-lg); padding: var(--s4) var(--s5);
  margin-bottom: var(--s5); box-shadow: var(--sh-2);
}
.periodbar form { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.periodbar .current {
  margin-left: auto; align-self: center; display: flex; align-items: center; gap: 10px;
  background: var(--brand-50); border: 1px solid var(--brand-100); color: var(--brand-700);
  padding: 8px 16px; border-radius: var(--r-full); font-size: 12.5px;
}
.periodbar .current .icon { color: var(--brand-500); }
.periodbar .current b { color: var(--brand-900); font-size: 13.5px; font-variant-numeric: tabular-nums; }

/* ── ตาราง ─────────────────────────────────────────────────────────── */
.table-scroll { overflow: auto; max-height: 72vh; }
.table-scroll.short { max-height: none; }

table.data { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
table.data th, table.data td {
  padding: 10px 13px; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--border-soft);
}
table.data thead th {
  position: sticky; top: 0; z-index: 2;
  /* ใช้ --ink-2 ไม่ใช่ --ink-3 — หัวตารางเป็นตัวเล็ก ตัวพิมพ์ใหญ่ ระยะห่างอักษรกว้าง
     ซึ่งอ่านยากกว่าตัวหนังสือปกติอยู่แล้ว และมันวางบนพื้นเทา (--surface-3) ไม่ใช่พื้นขาว
     ความคมชัดจึงลดลงสองต่อ ต้องชดเชยด้วยสีที่เข้มขึ้นหนึ่งขั้น (3.34:1 → 5.33:1) */
  background: var(--surface-3); color: var(--ink-2);
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  padding-top: 12px; padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: bottom;
}
table.data thead th .sub {
  display: block; font-weight: 400; font-size: 10px;
  color: var(--ink-3); text-transform: none; letter-spacing: 0;
}
table.data tbody tr td { transition: background .14s var(--ease); }
table.data tbody tr:nth-child(even) td { background: var(--surface-2); }
table.data tbody tr:hover td { background: var(--brand-50); }
table.data tfoot td {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--surface-3); font-weight: 700; color: var(--n-900);
  border-top: 1px solid var(--border-strong); border-bottom: none;
}
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.num { color: var(--n-900); }
table.data td.mono { font-variant-numeric: tabular-nums; letter-spacing: .01em; }
table.data td.wrap { white-space: normal; min-width: 170px; }
table.data td.tight { width: 1%; }
table.data tr.is-muted td { color: var(--ink-3); }
table.data tr.is-flagged td { background: var(--warn-bg) !important; }
table.data tr.is-flagged:hover td { background: #fdf1dd !important; }
table.data .zero { color: var(--n-400); }

/* คอลัมน์แรกติดซ้ายในตารางกว้าง — พื้นต้องทึบ ไม่งั้นเห็นคอลัมน์อื่นวิ่งทะลุ */
table.data.pin-first th:first-child,
table.data.pin-first td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  box-shadow: 1px 0 0 var(--border-soft);
}
table.data.pin-first thead th:first-child { z-index: 3; background: var(--surface-3); }
table.data.pin-first tbody tr:nth-child(even) td:first-child { background: var(--surface-2); }
table.data.pin-first tbody tr:hover td:first-child { background: var(--brand-50); }
table.data.pin-first tr.is-flagged td:first-child { background: var(--warn-bg) !important; }

/* หัวตารางที่เรียงได้ — บอกทิศทางด้วยลูกศรสีแบรนด์ */
table.data thead th[aria-sort] { color: var(--brand-600); }
table.data thead th[aria-sort]::after {
  content: "↑"; margin-left: 6px; color: var(--brand-500); font-size: 11px;
}
table.data thead th[aria-sort=descending]::after { content: "↓"; }

/* ── ป้ายสถานะ ─────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 11px; border-radius: var(--r-full);
  font-size: 11px; font-weight: 600; line-height: 1.8;
  border: 1px solid transparent;
}
.badge.ok    { background: var(--ok-bg);   color: var(--ok-fg);   border-color: var(--ok-bd); }
.badge.warn  { background: var(--warn-bg); color: var(--warn-fg); border-color: var(--warn-bd); }
.badge.bad   { background: var(--bad-bg);  color: var(--bad-fg);  border-color: var(--bad-bd); }
.badge.info  { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-bd); }
.badge.plain { background: var(--fill-1);  color: var(--ink-2);   border-color: var(--border-soft); }
/* ป้ายเข้ม — ใช้บอก "ระดับสูงสุด" โดยไม่สื่อว่าผิดพลาดเหมือนสีแดง */
.badge.solid { background: var(--brand-600); color: #fff; border-color: var(--brand-600); }
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ── แจ้งเตือน ─────────────────────────────────────────────────────── */
.note {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s4) var(--s5); border-radius: var(--r-lg);
  border: 1px solid; margin-bottom: var(--s4); font-size: 13px;
  box-shadow: var(--sh-1);
}
.note > .icon { margin-top: 2px; }
.note-body { min-width: 0; flex: 1; }
.note.ok   { background: var(--ok-bg);   border-color: var(--ok-bd);   color: var(--ok-fg); }
.note.warn { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-fg); }
.note.bad  { background: var(--bad-bg);  border-color: var(--bad-bd);  color: var(--bad-fg); }
.note.info { background: var(--info-bg); border-color: var(--info-bd); color: var(--info-fg); }
.note a { color: inherit; text-decoration: underline; font-weight: 600; }
.note ul { margin: 7px 0 0; padding-left: 20px; }
.note li { margin-bottom: 3px; }
.note b { font-weight: 700; }

/* ── สถานะว่าง ─────────────────────────────────────────────────────── */
.empty { padding: var(--s8) var(--s5); text-align: center; color: var(--ink-3); }
/* > เท่านั้น — ไม่งั้นจะไปโดนไอคอนในปุ่มที่อยู่ในกล่องว่างเดียวกันด้วย */
.empty > .icon {
  box-sizing: content-box; width: 26px; height: 26px; padding: 16px;
  /* ★ ใช้ --brand-500 ไม่ใช่ --brand-300 ★
     brand-300 บนพื้น brand-50 ได้ความคมชัดแค่ 1.90:1 — ไอคอนจะจางจนดูไม่ออกว่ารูปอะไร
     ทั้งที่หน้าสถานะว่างมีหน้าที่บอกผู้ใช้ว่า "ไม่มีข้อมูล ไม่ใช่ระบบพัง"
     brand-500 ได้ 4.59:1 เห็นชัดแต่ยังนุ่มเพราะเส้นบางและอยู่ในวงกลมสีอ่อน */
  color: var(--brand-500); background: var(--brand-50);
  border: 1px solid var(--brand-100);
  border-radius: var(--r-full);
  margin-bottom: var(--s4); stroke-width: 1.4;
}
.empty h3 { font-size: 15px; margin-bottom: 7px; }
.empty p { font-size: 13px; max-width: 440px; margin: 0 auto var(--s4); }

/* ── ปฏิทิน ────────────────────────────────────────────────────────── */
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
.cal .dow { text-align: center; font-size: 11px; color: var(--ink-3); font-weight: 600; letter-spacing: .06em; padding-bottom: var(--s1); }
.cal .cell {
  border: 1px solid var(--border-soft); border-radius: var(--r);
  padding: 9px 10px; min-height: 96px; background: var(--surface);
  font-size: 11.5px; position: relative; text-align: left;
  font-family: inherit; color: var(--ink); width: 100%; display: block;
  transition: border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
button.cell { cursor: pointer; }
button.cell:hover { border-color: var(--brand-300); box-shadow: var(--sh-lift); transform: translateY(-2px); }
.cal .cell.blank { border: 0; background: none; min-height: 0; }
.cal .cell.outside { opacity: .42; }
.cal .cell .d { display: block; font-weight: 700; font-size: 13px; margin-bottom: 5px; color: var(--n-900); font-variant-numeric: tabular-nums; }
.cal .cell .t { display: block; color: var(--ink-2); font-variant-numeric: tabular-nums; line-height: 1.5; }
.cal .cell.worked  { background: var(--ok-bg);   border-color: var(--ok-bd); }
.cal .cell.problem { background: var(--warn-bg); border-color: var(--warn-bd); }
.cal .cell.absent  { background: var(--surface-2); }
.cal .cell .mark { position: absolute; right: 7px; top: 6px; font-size: 10px; color: var(--ink-3); }
.cal-legend { display: flex; gap: var(--s4); flex-wrap: wrap; font-size: 12px; color: var(--ink-3); margin-top: var(--s4); }
.cal-legend span { display: inline-flex; align-items: center; gap: 7px; }
.cal-legend i { width: 12px; height: 12px; border-radius: 4px; border: 1px solid; display: inline-block; }

/* วันหยุดประจำสัปดาห์ในปฏิทิน — ต่างจาก "ขาดงาน" ชัดเจน */
.cal .cell.dayoff {
  background: var(--surface-3);
  border-color: var(--border-strong);
  border-style: dashed;
}
.cal .cell.dayoff .d { color: var(--ink-3); }

/* ── กล่องโต้ตอบ ───────────────────────────────────────────────────── */
dialog {
  border: 1px solid var(--border); border-radius: var(--r-xl); padding: 0;
  box-shadow: var(--sh-pop); max-width: 560px; width: calc(100% - 32px);
  background: var(--surface); color: var(--ink);
}
dialog::backdrop { background: rgba(27, 32, 48, .42); backdrop-filter: blur(3px); }
dialog h3 {
  margin: 0; padding: var(--s4) var(--s5); border-bottom: 1px solid var(--border-soft);
  font-size: 15px; display: flex; align-items: center; gap: 10px;
}
dialog h3 .icon { color: var(--brand-500); }
dialog .dlg-body { padding: var(--s5); }
dialog .dlg-foot {
  padding: var(--s3) var(--s5); border-top: 1px solid var(--border-soft);
  display: flex; gap: var(--s2); align-items: center; background: var(--surface-2);
}
/* กล่องโผล่มาแบบมีน้ำหนัก — ขยายจากเล็กพร้อมจางเข้า */
dialog[open] { animation: dlg-in .3s var(--ease); }
@keyframes dlg-in {
  from { opacity: 0; transform: translateY(10px) scale(.97); }
}

/* ── Toast ─────────────────────────────────────────────────────────── */
.toasts {
  position: fixed; right: var(--s5); bottom: var(--s5); z-index: 100;
  display: flex; flex-direction: column; gap: var(--s2); max-width: 380px;
}
.toast {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s3) var(--s4); border-radius: var(--r-lg);
  border: 1px solid; box-shadow: var(--sh-3); font-size: 13px;
  animation: toast-in .3s var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(14px) scale(.96); } }
.toast.ok  { background: var(--ok-bg);  border-color: var(--ok-bd);  color: var(--ok-fg); }
.toast.bad { background: var(--bad-bg); border-color: var(--bad-bd); color: var(--bad-fg); }
.toast.info{ background: var(--info-bg);border-color: var(--info-bd);color: var(--info-fg); }

/* ── ตัวโหลด ───────────────────────────────────────────────────────── */
.spinner {
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: spin .6s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

.bar-loading {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 200;
  background: linear-gradient(90deg, transparent, var(--brand-500), transparent);
  background-size: 40% 100%; background-repeat: no-repeat;
  animation: bar 1s linear infinite;
}
@keyframes bar { from { background-position: -40% 0; } to { background-position: 140% 0; } }

/* ── รายการเงินได้/เงินหัก (หน้ารายละเอียด) ───────────────────────── */
.ledger { width: 100%; border-collapse: collapse; font-size: 13px; }
.ledger td { padding: 10px 0; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
.ledger td:last-child { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-left: var(--s4); color: var(--n-900); }
.ledger .calc { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.ledger tr.total td { border-bottom: none; border-top: 1px solid var(--border-strong); font-weight: 700; padding-top: 13px; }
.ledger tr.zero td { color: var(--n-400); }
.ledger tr.zero td:last-child { color: var(--n-400); }

/* กล่องยอดสุทธิ — จุดที่สายตาต้องไปหยุด จึงเป็นที่เดียวในหน้าที่พื้นเข้ม */
.net-box {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s5) var(--s6); border-radius: var(--r-xl);
  background: linear-gradient(135deg, var(--brand-700), var(--brand-900));
  color: #fff;
  box-shadow: 0 14px 34px -16px rgba(15, 47, 94, .55);
  margin-bottom: var(--s5);
}
.net-box .k { font-size: 14px; opacity: .72; font-weight: 500; }
.net-box .v { font-size: 28px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.035em; }

/* ── โลโก้บริษัท ───────────────────────────────────────────────────── */
/* โลโก้เป็นหมึกน้ำเงินเข้ม วางบนแผ่นขาวมนเสมอ — ทั้งบนพื้นสว่างและพื้นดำ
   ทำให้จุดนี้เป็นของชิ้นเดียวกันในทั้งสองธีม */
.brand-logo {
  width: 38px; height: 38px; flex: 0 0 38px;
  border-radius: var(--r); background: #fff; padding: 5px;
  display: grid; place-items: center;
  border: 1px solid var(--border-soft);
  box-shadow: var(--sh-1);
}
.brand-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ── ยูทิลิตี้ ─────────────────────────────────────────────────────── */
.muted { color: var(--ink-3); }
.small { font-size: 12px; }
.xs { font-size: 11.5px; }
.strong { font-weight: 600; color: var(--n-900); }
.num { font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.pos { color: var(--ok-fg); }
.neg { color: var(--bad-fg); }
.stack { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.stack.tight { gap: var(--s1); }
.mt { margin-top: var(--s4); }
.mt-lg { margin-top: var(--s6); }
.mb0 { margin-bottom: 0; }
.divider { height: 1px; background: var(--border-soft); border: 0; margin: var(--s5) 0; }
.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;
}
kbd {
  font-family: var(--font-mono); font-size: 11px;
  background: var(--fill-1); border: 1px solid var(--border);
  border-bottom-width: 2px; border-radius: 6px; padding: 1px 6px; color: var(--ink-2);
}
code {
  font-family: var(--font-mono); font-size: 12px; color: var(--brand-700);
  background: var(--brand-50); border: 1px solid var(--brand-100);
  padding: 1px 6px; border-radius: 6px;
}

/* ── แบ่งหน้า — ตารางที่ยาวหลายพันแถวต้องไม่ส่งมาทีเดียวหมด ────────── */
.pager { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.pager .is-off { opacity: .35; pointer-events: none; }
.pager-gap { color: var(--ink-3); padding: 0 3px; }

/* ── รายการผลค้นหาในกล่อง "เพิ่มการสแกนใหม่" ─────────────────────────── */
.pick-list {
  margin-top: 7px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  max-height: 200px;
  overflow-y: auto;
  box-shadow: var(--sh-2);
}
.pick-item {
  display: block;
  width: 100%;
  padding: 9px 13px;
  border: 0;
  border-bottom: 1px solid var(--border-soft);
  background: none;
  font: inherit;
  font-family: var(--font);
  font-size: 13px;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: background .14s var(--ease);
}
.pick-item:last-child { border-bottom: 0; }
.pick-item b { color: var(--n-900); }
.pick-item:hover,
.pick-item:focus-visible { background: var(--brand-50); }
.pick-empty { padding: 11px 13px; font-size: 12.5px; color: var(--ink-3); }
.hint.ok { color: var(--ok-fg); font-weight: 600; }

/* ── กล่องแสดงโลโก้ในหน้าตั้งค่า ─────────────────────────────────────── */
.logo-box {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 78px;
  padding: 8px;
  margin-bottom: 9px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-sm);
  /* โลโก้ที่อัปโหลดมาส่วนใหญ่ทำมาสำหรับพื้นขาว — จึงวางบนแผ่นขาวเสมอ */
  background: #fff;
}
.logo-box img { max-height: 62px; width: auto; object-fit: contain; }
.logo-empty { font-size: 12.5px; color: var(--ink-3); }
.logo-form { display: flex; gap: 7px; align-items: center; margin-bottom: 7px; }
.logo-form input[type="file"] { min-width: 0; flex: 1; font-size: 12px; }

/* ── ช่วงวันที่กำหนดเองในแถบงวด ──────────────────────────────────────── */
.periodbar-custom { margin-top: 11px; border-top: 1px solid var(--border-soft); padding-top: 9px; }
.periodbar-custom > summary {
  cursor: pointer;
  font-size: 12.5px;
  color: var(--ink-3);
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 2px 0;
  transition: color .18s var(--ease);
}
.periodbar-custom > summary::-webkit-details-marker { display: none; }
.periodbar-custom > summary::before { content: "▸"; font-size: .8em; color: var(--brand-500); }
.periodbar-custom[open] > summary::before { content: "▾"; }
.periodbar-custom > summary:hover { color: var(--brand-600); }
.periodbar-custom > form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: flex-end;
  margin-top: 9px;
}
.periodbar-custom > form > .hint { flex: 1 1 100%; margin: 0; }

/* ── กล่องแสดงรหัสผ่านที่ตั้งใหม่ (แสดงครั้งเดียว) ─────────────────── */
.pw-reveal {
  margin: var(--s3) 0; padding: var(--s4);
  background: var(--brand-50); border: 1px dashed var(--brand-300);
  border-radius: var(--r); text-align: center;
}
.pw-reveal code {
  font-size: 19px; font-weight: 700; letter-spacing: .1em;
  background: none; border: 0; padding: 0; color: var(--brand-700); user-select: all;
}

.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 44px; }
.pw-toggle {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; padding: 8px; cursor: pointer;
  color: var(--ink-3); border-radius: var(--r-full); line-height: 0;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.pw-toggle:hover { color: var(--ink); background: var(--fill-1); }

/* ══════════════════════════════════════════════════════════════════════
   จุดกระพริบ — ลายเซ็นของแบรนด์ ใช้บอกว่า "ระบบพร้อมใช้งาน"
   สีมาจาก --accent จึงเป็นฟ้าในหน้าทำงาน และเขียวนีออนในหน้าเข้าสู่ระบบ
   ══════════════════════════════════════════════════════════════════════ */
.blinking-dot {
  width: 8px; height: 8px; flex: 0 0 8px;
  background-color: var(--accent);
  border-radius: 50%;
  position: relative;
  display: inline-block;
  animation: pulse-glow 2s infinite ease-in-out;
}
.blinking-dot::after {
  content: "";
  position: absolute;
  top: -5px; left: -5px; right: -5px; bottom: -5px;
  background-color: var(--accent-glow);
  border-radius: 50%;
  animation: wave-expand 2s infinite ease-in-out;
}
@keyframes pulse-glow {
  0%, 100% { opacity: .5; transform: scale(.85); }
  50%      { opacity: 1;  transform: scale(1.1); }
}
@keyframes wave-expand {
  0%   { transform: scale(.6); opacity: .9; }
  100% { transform: scale(2.3); opacity: 0; }
}

/* เคยมีวงแหวนวิ่งตามเมาส์ทุกหน้า — ถอดออกแล้วตามที่เจ้าของระบบสั่ง
   เคอร์เซอร์ของเครื่องผู้ใช้ทำหน้าที่ของมันได้ดีอยู่แล้ว ไม่ต้องมีของวิ่งตามอีกชั้น
   ถ้าจะเอากลับมา ต้องเพิ่มทั้ง CSS · โค้ดใน app.js/login.js · และแท็กใน foot.ejs/login.ejs */

/* ══════════════════════════════════════════════════════════════════════
   การปรากฏตัวตอนเปิดหน้า
   เลื่อนขึ้น + จางเข้าทีละชั้น ใช้แค่ transform/opacity จึงไม่ทำให้หน้าหนืด
   ตารางพันแถวไม่ถูกแตะ — เคลื่อนไหวเฉพาะ "กล่อง" ไม่ใช่ "แถว"
   ══════════════════════════════════════════════════════════════════════ */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.topbar, .content > .stats, .content > .card, .content > .periodbar,
.content > .filterbar, .content > .note, .content > .grid-2, .content > .tabs {
  animation: rise-in .55s var(--ease-reveal) both;
}
.topbar                { animation-delay: 0s; }
.content > *:nth-child(1) { animation-delay: .04s; }
.content > *:nth-child(2) { animation-delay: .09s; }
.content > *:nth-child(3) { animation-delay: .14s; }
.content > *:nth-child(4) { animation-delay: .19s; }
.content > *:nth-child(n+5) { animation-delay: .23s; }

/* การ์ดที่มีตารางหลายพันแถวอยู่ข้างใน ห้ามเลื่อนตำแหน่ง — การเลื่อนบังคับให้
   เบราว์เซอร์ยกตารางทั้งผืนขึ้นเป็นเลเยอร์ใหม่ เครื่องเก่าจะกระตุกเห็นได้ชัด
   จึงให้จางเข้าเฉย ๆ (ไม่ขยับ) ซึ่งเบากว่ามาก */
.content > .card:has(.table-scroll) {
  animation-name: fade-in;
  animation-duration: .4s;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ══════════════════════════════════════════════════════════════════════
   หน้าเข้าสู่ระบบ
   --------------------------------------------------------------------
   หน้าเข้าระบบขององค์กร ไม่ใช่หน้าโฆษณา — มีของอยู่ 2 ชิ้นเท่านั้น:
   การ์ดฟอร์มตรงกลาง กับแถบข้อเท็จจริงบาง ๆ ด้านล่าง
   ที่เหลือคือความว่างสีดำ ซึ่งเป็นสิ่งที่ทำให้หน้าดูสงบและน่าเชื่อถือ
   ══════════════════════════════════════════════════════════════════════ */
.signin-page {
  background: #000;
  min-height: 100vh;
  position: relative;
  /* ★ z-index: 0 ตรงนี้จำเป็น ห้ามลบ ★
     มันบังคับให้ body สร้าง "ชั้นการวาด" (stacking context) ของตัวเอง
     ถ้าไม่มี ลูกที่ z-index ติดลบ (วิดีโอ -2 · ม่านดำ -1) จะถูกวาดก่อนพื้นดำของ body
     แล้วพื้นดำจะทับวิดีโอจนมองไม่เห็นอะไรเลย
     (ปกติ body ไม่วาดพื้นของตัวเอง เพราะสีจะถูกส่งต่อไปเป็นพื้นจอ —
      แต่ระบบนี้ตั้งพื้นให้ html ไว้ด้วย การส่งต่อจึงไม่เกิด body เลยวาดกล่องสีเอง) */
  z-index: 0;
  display: flex;
  flex-direction: column;
}

/* แสงเรืองจาง ๆ หลังการ์ด — กันไม่ให้พื้นดำล้วนดูแบนเป็นกระดาษ
   ไม่ใช้ filter: blur เพราะกินแรงวาด ใช้ radial-gradient ซึ่งการ์ดจอวาดให้ฟรี */
.signin-page::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(46% 40% at 50% 42%, rgba(255, 255, 255, .05), transparent 68%),
    radial-gradient(38% 34% at 50% 46%, rgba(77, 163, 255, .06), transparent 70%);
}
/* มีวิดีโอแล้วไม่ต้องมีแสงปลอม — แสงเรืองนี้มีไว้แก้ปัญหา "พื้นดำล้วนดูแบน"
   พอมีภาพเคลื่อนไหวจริงอยู่ข้างหลัง มันกลายเป็นฝ้าขาวบังวิดีโอเปล่า ๆ */
.signin-page:has(.video-container)::before { display: none; }

/* ── วิดีโอพื้นหลัง ────────────────────────────────────────────────
   จะมีอยู่ก็ต่อเมื่อผู้ดูแลระบบเอาไฟล์มาวางไว้ที่ src/public/media/
   ถ้าไม่มี แท็กพวกนี้จะไม่ถูกสร้างขึ้นมาเลย หน้าเป็นพื้นดำล้วนตามดีไซน์ */
.video-container {
  position: fixed; inset: 0;
  z-index: -2;                 /* หลังทุกอย่าง รวมถึงหลังม่านดำ (-1) */
  overflow: hidden;
  background: #000;            /* กันจอขาววาบตอนวิดีโอยังมาไม่ถึง */
  pointer-events: none;
}
#bg-video {
  width: 100%; height: 100%;
  object-fit: cover;           /* เต็มจอเสมอ ไม่ว่าสัดส่วนวิดีโอจะเป็นเท่าไร */
  display: block;
  opacity: 0;
  /* ค่อย ๆ จางเข้าเมื่อเล่นได้จริง — ไม่ให้ภาพกระโดดใส่หน้าคนที่กำลังพิมพ์รหัสผ่าน */
  transition: opacity 1.4s ease;
}
#bg-video.ready { opacity: 1; }

/* ★ ม่านดำคลุมวิดีโอ — ชั้นนี้ไม่ใช่ของประดับ แต่เป็นเรื่องความอ่านออก ★
   วิดีโอ 3D มีทั้งเฟรมมืดและเฟรมสว่าง ถ้าไม่มีม่านนี้ พอตัดไปเฟรมสว่าง
   ตัวหนังสือขาวที่แถบล่างจะหายไปทั้งบรรทัด */
.video-scrim {
  position: fixed; inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    /* ① วิญเยตต์ — กลางจอ "ใส" ขอบ "มืด"
       ตรงกลางคือที่ที่อยากให้เห็นคลิปชัดที่สุด ส่วนขอบจอไม่มีอะไรสำคัญอยู่
       การหรี่ขอบลงช่วยดึงสายตาเข้ากลางและกันไม่ให้ขอบคลิปที่สว่างมากวนใจ */
    radial-gradient(ellipse 64% 60% at 50% 46%,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, .30) 56%,
      rgba(0, 0, 0, .74) 100%),
    /* ② แถบบน–ล่าง — สองแถบนี้คือที่ที่มีตัวหนังสือจริง (แถบสถานะ · ลิขสิทธิ์)
       ต้องมืดพอเสมอไม่ว่าคลิปจะตัดไปเฟรมสว่างแค่ไหน ตรงกลางปล่อยใสสนิท */
    linear-gradient(to bottom,
      rgba(0, 0, 0, .88) 0%,
      rgba(0, 0, 0, 0) 20%,
      rgba(0, 0, 0, 0) 76%,
      rgba(0, 0, 0, .90) 100%);
}

/* flex:1 คือหัวใจ: ช่องว่างที่เหลือทั้งหมดตกเป็นของตรงนี้
   การ์ดจึงอยู่กลางจอพอดีเสมอ และแถบล่างถูกดันไปอยู่ล่างสุดพอดี
   ไม่ว่าจอจะสูงเท่าไร — ไม่มีวันล้นตกขอบเหมือนการตรึงตำแหน่งตายตัว */
.signin {
  flex: 1 1 auto;
  position: relative; z-index: 1;
  display: grid; place-items: center;
  padding: var(--s6) var(--s5);
  min-height: 0;
}

/* ══ การ์ดใสสนิท — เหลือแค่กรอบ ═══════════════════════════════════════
   ไม่มีพื้นสีเลย ไม่มีการหรี่แสง ไม่มีเบลอ — คลิปวิ่งผ่านการ์ดไปตรง ๆ
   สิ่งที่บอกว่า "ตรงนี้คือฟอร์ม" มีแค่เส้นกรอบขาวจาง ๆ กับแสงขอบบน

   ★ ผลที่ต้องรู้ไว้: ความอ่านออกขึ้นอยู่กับ "คลิป" ล้วน ๆ แล้ว ★
     ไม่มีชั้นไหนคอยกันความสว่างของคลิปอีกต่อไป ถ้าเปลี่ยนไปใช้คลิปที่สว่าง
     ตัวหนังสือจะกลืนหายทันที — เลือกคลิปโทนมืดเท่านั้น
     เครื่องมือที่เหลือมี 2 อย่างและทั้งคู่ "ไม่ใส่สีดำ" ตามที่สั่ง:
       • เงาตัวอักษร — ทำให้ตัวอักษรมีขอบของตัวเอง ไม่ใช่แผ่นสีทับพื้นหลัง
       • เบลอเฉพาะหลังช่องกรอก — ลบลายละเอียดยิบ ๆ ของคลิปตรงที่ผู้ใช้ต้องอ่าน
         สิ่งที่ตัวเองพิมพ์ (ไม่ได้ทำให้มืดลง แค่ทำให้เนียนขึ้น) */
.signin-card {
  position: relative;
  width: 100%; max-width: 392px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: var(--r-xl);
  /* เงาข้างในบาง ๆ ที่ขอบบน ทำให้กรอบดูเป็น "กระจก" ไม่ใช่เส้นวาด
     เงาข้างนอกช่วยดันการ์ดให้ลอยออกมาจากคลิปโดยไม่ต้องมีพื้นสี */
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, .22),
    0 24px 70px -30px rgba(0, 0, 0, .9);
  overflow: hidden;
}

/* เงาตัวอักษรทุกตัวบนการ์ด — ตาข่ายนิรภัยชั้นเดียวที่เหลืออยู่
   สองชั้น: ชั้นแรกแคบและเข้ม ทำให้ตัวอักษรมีขอบชัด
   ชั้นสองกว้างและจาง ช่วยดันตัวอักษรออกจากพื้นหลังที่มีลายยิบ ๆ */
.signin-card :where(h1, p, label, span, button) {
  text-shadow: 0 1px 2px rgba(0, 0, 0, .95), 0 2px 10px rgba(0, 0, 0, .7);
}
/* ยกเว้นปุ่มหลัก — พื้นขาวตัวอักษรดำ ใส่เงาดำเข้าไปจะเลอะ */
.signin-card .btn.primary, .signin-card .btn.primary span { text-shadow: none; }

/* ปุ่มเข้าสู่ระบบเป็นขาวทึบ ไม่ใช่ฟ้าแบบปุ่มหลักในหน้าทำงาน
   เพราะบนพื้นดำที่มีคลิปวิ่ง สีขาวคือสิ่งที่เด่นและอ่านง่ายที่สุด */
.signin-page .btn.primary { --btn-bg: #fff; --btn-fg: #000; --btn-bd: #fff; }
.signin-page .btn.primary:hover {
  --btn-bg: #fff; --btn-bd: #fff; --btn-fg: #000;
  box-shadow: 0 8px 30px -10px rgba(255, 255, 255, .5);
}
.signin-page .btn.primary .icon { color: rgba(0, 0, 0, .6); }

.signin-head { padding: var(--s6) var(--s5) var(--s4); text-align: center; }
/* โลโก้บริษัทเป็นหมึกน้ำเงินเข้ม — บนพื้นดำจะจมหายไป จึงวางบนแผ่นขาวมนเสมอ */
.signin-mark {
  width: 54px; height: 54px; margin: 0 auto var(--s4);
  border-radius: var(--r); display: grid; place-items: center;
  background: #fff; padding: 7px;
}
.signin-mark img { width: 100%; height: 100%; object-fit: contain; }
.signin-head h1 { font-family: var(--font-display); font-size: 20px; letter-spacing: -.02em; color: #fff; }
.signin-head p { margin: 5px 0 0; font-size: 12.5px; color: rgba(255, 255, 255, .68); }

.signin-body { padding: 0 var(--s5) var(--s5); }
.signin-body label { color: rgba(255, 255, 255, .8); }
/* ช่องกรอกก็ใสเช่นกัน เหลือแค่กรอบ
   แต่ใส่เบลอไว้ข้างหลัง — เบลอ "ไม่ได้ทำให้มืดลง" (จึงไม่ขัดกับที่สั่งว่าไม่เอาสีดำ)
   มันแค่ลบลายละเอียดยิบ ๆ ของคลิปออก ตัวอักษรที่ผู้ใช้พิมพ์จึงไม่ไปทับลายที่ตัดกันถี่ ๆ
   ตรงนี้จำเป็นกว่าที่อื่น เพราะข้อความในช่องนี้ผู้ใช้เป็นคนพิมพ์เอง
   เขาต้องตรวจทานสิ่งที่พิมพ์ไปแล้วได้ โดยเฉพาะตอนกดปุ่มลืมตาดูรหัสผ่าน */
.signin-body :where(input) {
  background: transparent;
  border-color: rgba(255, 255, 255, .34);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.signin-body :where(input):focus {
  background: transparent;
  border-color: var(--accent-bd);
}
/* ขีดพิมพ์เป็นสีนีออน — บนพื้นใสที่มีคลิปวิ่งอยู่ ขีดขาวบาง ๆ หาไม่เจอว่าอยู่ตรงไหน */
.signin-body :where(input) { caret-color: var(--accent); }
.signin-submit { width: 100%; padding: 12px; margin-top: var(--s4); font-size: 14px; }

.signin-foot {
  padding: var(--s3) var(--s5); border-top: 1px solid rgba(255, 255, 255, .1);
  /* ใสเช่นกัน — เหลือแค่เส้นคั่นด้านบน ถ้าใส่พื้นสีตรงนี้
     จะมีแถบทึบพาดขวางการ์ดใสอยู่แถบเดียว ดูเหมือนการ์ดสองใบต่อกัน */
  background: transparent;
  display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap;
  font-size: 11px; color: rgba(255, 255, 255, .58);
}

/* ── แถบล่างสุด ────────────────────────────────────────────────────── */
.signin-bar {
  flex: 0 0 auto;
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
  margin: 0 var(--s5);
  padding: var(--s4) 0;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
}
.signin-bar-status { display: inline-flex; align-items: center; gap: .7rem; color: rgba(255, 255, 255, .74); }
.signin-bar-copy { color: rgba(255, 255, 255, .5); }

/* ══════════════════════════════════════════════════════════════════════
   จอเล็ก
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  :root { --sidebar-w: 224px; }
  .content { padding: var(--s4) var(--s4) var(--s8); }
  .topbar { padding: var(--s3) var(--s4); }
}

@media (max-width: 860px) {
  .app { flex-direction: column; background: var(--canvas); }
  .sidebar {
    width: 100%; flex: none; height: auto; position: sticky; top: 0;
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .sidebar .nav, .sidebar .side-foot { display: none; }
  .sidebar.open .nav, .sidebar.open .side-foot { display: block; }
  .brand { padding: var(--s3) var(--s4); border-bottom: 0; }
  .sidebar-toggle {
    display: inline-flex; margin-left: auto;
    background: var(--fill-1);
    border: 1px solid var(--border); color: var(--ink-2);
    border-radius: var(--r-full); padding: 8px; cursor: pointer;
  }
  .sidebar-toggle:hover { background: var(--fill-2); color: var(--ink); }
  /* แท็บบนจอแคบ — เลื่อนแนวนอนแทนการตกบรรทัด
     ถ้าปล่อยให้ตกบรรทัด แถบจะสูงสามแถวและดันเนื้อหาจริงตกจอไปหมด */
  .tabs {
    width: 100%; flex-wrap: nowrap;
    overflow-x: auto; scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { flex: 0 0 auto; }

  .filterbar .filter-row { gap: var(--s2); }
  .filterbar .field.narrow { flex: 1 1 120px; }
  .nav-group { margin-top: var(--s3); }
  .topbar { position: static; flex-wrap: wrap; }
  .periodbar .current { margin-left: 0; width: 100%; justify-content: center; }
  .table-scroll { max-height: none; }
  table.data thead th { position: static; }
  .cal .cell { min-height: 76px; padding: 6px; }

  /* หน้าเข้าสู่ระบบบนมือถือ — การ์ดชิดขอบน้อยลง แถบล่างซ้อนสองบรรทัดได้ */
  .signin { padding: var(--s5) var(--s4); }
  .signin-bar { margin: 0 var(--s4); justify-content: center; text-align: center; }
  /* จอแคบ = พื้นที่ว่างรอบการ์ดเหลือน้อย วิดีโอจะกวนสายตามากกว่าช่วย จึงหรี่ลง
     (login.js ไม่โหลดวิดีโอบนจอแคบอยู่แล้ว กฎนี้ไว้เผื่อคนย่อหน้าต่างทีหลัง) */
  .video-container { opacity: .45; }
}

/* จอเตี้ย (โน้ตบุ๊ก 13" · เปิด DevTools · ย่อหน้าต่าง)
   ฟอร์มต้องกรอกได้เสมอ — บีบระยะห่างลงก่อน ถ้ายังไม่พอค่อยยอมให้เลื่อน */
@media (max-height: 720px) {
  .signin { padding: var(--s4) var(--s5); }
  .signin-head { padding: var(--s5) var(--s5) var(--s3); }
  .signin-mark { width: 46px; height: 46px; margin-bottom: var(--s3); }
  .signin-bar { padding: var(--s3) 0; }
}
@media (max-height: 560px) {
  .signin-page { min-height: 0; }
  .signin { padding: var(--s5); }
}

/* ══════════════════════════════════════════════════════════════════════
   พิมพ์ — บังคับขาว–ดำเสมอ
   หน้าทำงานเป็นธีมสว่างอยู่แล้ว แต่ยังต้องบังคับอีกชั้นเพื่อกันเรื่องพวกนี้:
   สีพาสเทลที่เปลืองหมึกโดยไม่ช่วยให้อ่านง่ายขึ้น · เงาที่พิมพ์ออกมาเป็นแถบเทา ·
   อนิเมชันตอนเปิดหน้าที่เริ่มจาก opacity 0 (ถ้าไม่ปิด กระดาษอาจออกมาว่างเปล่า)
   ══════════════════════════════════════════════════════════════════════ */
@media print {
  :root {
    --canvas: #fff; --surface: #fff; --surface-2: #fff; --surface-3: #f2f2f2;
    --ink: #000; --ink-2: #333; --ink-3: #555;
    --border: #bbb; --border-soft: #ddd; --border-strong: #888;
    --ok-bg: #fff; --warn-bg: #f6f6f6; --bad-bg: #fff; --info-bg: #fff;
    --ok-fg: #000; --warn-fg: #000; --bad-fg: #000; --info-fg: #000;
    --accent: #000; --fill-1: #fff; --fill-2: #f2f2f2;
  }
  .sidebar, .topbar-actions, .periodbar, .filters, .filterbar, .toasts, .no-print,
  .btn, dialog, .sidebar-toggle, .tabs,
  .signin-bar, .bar-loading, .video-container, .video-scrim { display: none !important; }
  html, body { background: #fff !important; color: #000 !important; }
  .app { display: block; background: #fff !important; }
  .content { padding: 0; max-width: none; }
  .topbar { position: static; border: 0; padding: 0 0 12px; background: none !important; }
  .topbar h1 { color: #000 !important; }
  .card, .stat, .filterbar, .periodbar {
    box-shadow: none !important; border: 1px solid #ccc !important;
    break-inside: avoid; margin-bottom: 12px; background: #fff !important;
  }
  .card-head, .card-foot { background: none !important; }
  .card-head h2, .stat .value, .strong, table.data td.num, .ledger td:last-child,
  .empty h3, .cal .cell .d { color: #000 !important; }
  .table-scroll { max-height: none; overflow: visible; }
  table.data thead th { position: static; background: #eee !important; color: #000 !important; }
  table.data tbody tr td { background: #fff !important; }
  table.data tbody tr:nth-child(even) td { background: #fafafa !important; }
  table.data tr.is-flagged td { background: #f0f0f0 !important; }
  table.data tfoot td { background: #eee !important; color: #000 !important; }
  .badge { border-color: #999 !important; color: #000 !important; background: #fff !important; }
  .net-box { background: none !important; color: #000 !important; border: 2px solid #000; box-shadow: none !important; }
  .note { border-color: #999 !important; color: #000 !important; background: #fff !important; }
  body { font-size: 11px; }
  a { color: inherit; text-decoration: none; }
  /* อนิเมชันตอนเปิดหน้าต้องไม่ค้างอยู่ที่ opacity 0 เวลาสั่งพิมพ์ */
  * { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════
   ผู้ใช้ที่ปิดการเคลื่อนไหว — เคารพค่าของระบบเสมอ
   (เมาแพ้การเคลื่อนไหว / เครื่องเก่าที่อยากได้ความเร็วสูงสุด)
   ══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
