/* ============================================================
   IT-WMS — สไตล์เฉพาะหน้า (Login · Change password · Coming soon)
   ============================================================ */

/* ---------- Login / Change password (หน้าที่ไม่มี app shell) ---------- */
.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; background: var(--c-surface); }
/* แผงซ้าย = พื้นสีแบรนด์เข้ม (U-13 · หน้า Login ใช้สีแบรนด์ได้เต็มที่)
   ใช้ --brand-deep ไม่ใช่ส้มสด เพราะตัวอักษรบนส้มสดไม่ผ่าน WCAG AA (2.78:1) */
.auth-side {
  background: var(--brand-deep); color: var(--brand-on-deep);
  padding: var(--sp-10); display: flex; flex-direction: column; justify-content: center;
}
.auth-side h2 { color: var(--c-text-invert); font-size: var(--fs-3xl); line-height: 1.3; font-weight: var(--fw-semibold); }
.auth-side p { margin-top: var(--sp-4); font-size: var(--fs-lg); line-height: 1.7; }
.auth-side ul { margin-top: var(--sp-8); display: grid; gap: var(--sp-3); }
.auth-side li { display: flex; gap: var(--sp-3); font-size: var(--fs-base); }
.auth-main { display: grid; place-items: center; padding: var(--sp-6); }
.auth-card { width: 100%; max-width: 380px; }
.auth-card h1 { font-size: var(--fs-2xl); font-weight: var(--fw-semibold); }
/* แบรนด์เหนือฟอร์ม — พื้นหลังฝั่งนี้สว่าง จึงใช้โลโก้เต็มได้เลย (U-13) */
.auth-brand {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
/* กำหนดความกว้าง + ปล่อยความสูงตามสัดส่วน (attribute width/height บน <img> กันหน้ากระตุก) */
.auth-brand .auth-logo { width: var(--logo-w-login); height: auto; display: block; }
.auth-brand .brand-name b { display: block; font-size: var(--fs-lg); line-height: 1.2; }

/* ปุ่ม/โฟกัสของหน้า auth ใช้สีแบรนด์ — **จำกัดขอบเขตด้วย .auth-card เท่านั้น**
   ปุ่มในหน้าเนื้อหายังเป็นสีการกระทำเดิม (ถ้าปุ่มทั่วไปเป็นส้ม จะสับสนกับงาน High) */
.auth-card .btn-primary {
  background: var(--brand-strong); border-color: var(--brand-strong);
}
.auth-card .btn-primary:hover { background: var(--brand-deep); border-color: var(--brand-deep); }
.auth-card .input:focus {
  border-color: var(--brand-strong); box-shadow: 0 0 0 3px var(--brand-weak);
}

/* กล่องข้อความผลลัพธ์ของฟอร์ม — ต้องมีที่ทางถาวร ไม่ให้เลย์เอาต์กระโดดตอนขึ้น error */
.form-alert {
  display: none; margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  font-size: var(--fs-md); border-left: 3px solid var(--c-critical);
  background: var(--c-critical-bg); color: #7a1a12;
}
.form-alert.on { display: block; }
.form-alert.ok { background: var(--c-done-bg); border-left-color: var(--c-done); color: #0b5c3c; }
.form-alert.warn { background: var(--c-high-bg); border-left-color: var(--c-high); color: #7a3d00; }

/* ---------- หน้าแจ้งข้อผิดพลาด (403 / 404) ---------- */
.error-page { min-height: 100vh; display: grid; place-items: center; padding: var(--sp-6); }
.error-page .box { max-width: 520px; text-align: center; }
.error-page .code { font-size: var(--fs-3xl); font-weight: var(--fw-bold); color: var(--c-text-3); }

/* ---------- หน้า "กำลังพัฒนา" ---------- */
.soon { max-width: 760px; }
.soon .ico { font-size: 40px; }
.soon h2 { font-size: var(--fs-2xl); font-weight: var(--fw-semibold); margin-top: var(--sp-2); }
.soon .phase {
  display: inline-flex; align-items: center; gap: 6px; margin-top: var(--sp-3);
  padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--c-brand-weak); color: var(--c-brand-dark);
  font-size: var(--fs-sm); font-weight: var(--fw-medium);
}
.soon ul { margin-top: var(--sp-4); display: grid; gap: var(--sp-2); }
.soon li { display: flex; gap: var(--sp-2); font-size: var(--fs-md); color: var(--c-text-2); }

/* ---------- Task Detail (04-UI-SITEMAP.md §7.3) ---------- */
.detail-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--sp-5); align-items: start; }
.detail-grid > div { min-width: 0; }

/* แถบ SLA — ความกว้างตั้งผ่าน CSSOM ไม่ใช่ style attribute (§5.1 ข้อ 4) */
.sla-bar { height: 8px; border-radius: var(--r-pill); background: var(--c-surface-3); overflow: hidden; }
.sla-bar > i { display: block; height: 100%; background: var(--c-done); border-radius: var(--r-pill); }
.sla-bar.at-risk > i { background: var(--c-high); }
.sla-bar.breached > i { background: var(--c-critical); }

/* แถวการแจ้งเตือนใน dropdown 🔔 */
.noti-item.unread { background: var(--c-brand-weak); }
.noti-item .when { color: var(--c-text-3); font-size: var(--fs-xs); }
.noti-actions { display: flex; gap: var(--sp-2); padding: var(--sp-2) var(--sp-4); border-top: 1px solid var(--c-border); }

/* ============================================================
   Phase 3 — Today · Dashboard · Team · Reports
   ⛔ ห้ามใช้ --brand-* ในบล็อกนี้ (ส้ม = ความสำคัญ High เท่านั้น)
   ============================================================ */

/* ---------- ตัวชี้ WIP (ต้องเห็นตลอดเวลาบนหน้า Today) ---------- */
.wip-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 5px 12px; border-radius: var(--r-pill);
  border: 1px solid var(--c-border-strong); background: var(--c-surface);
  font-size: var(--fs-md); color: var(--c-text);
}
.wip-chip b { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }
.wip-chip .slots { display: inline-flex; gap: 3px; }
.wip-chip .slots i { width: 9px; height: 9px; border-radius: 2px; background: var(--c-surface-3); }
.wip-chip .slots i.on { background: var(--c-progress); }
.wip-chip.at_limit { border-color: var(--c-high); background: var(--c-high-bg); color: var(--c-high); }
.wip-chip.at_limit .slots i.on { background: var(--c-high); }
.wip-chip.over { border-color: var(--c-critical); background: var(--c-critical-bg); color: var(--c-critical); }
.wip-chip.over .slots i.on { background: var(--c-critical); }

/* ---------- แถบจับเวลา ---------- */
.timer-bar { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.timer-clock {
  font-family: var(--font-mono); font-size: var(--fs-2xl); font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums; color: var(--c-progress);
}
.timer-bar.idle .timer-clock { color: var(--c-text-3); }

/* ---------- แถบ "งานที่แนะนำให้ทำวันนี้" ---------- */
.rec-list { display: grid; gap: var(--sp-3); }
.rec-item {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3); border: 1px solid var(--c-border); border-radius: var(--r-md);
  background: var(--c-surface-2);
}
.rec-item .rank {
  width: 26px; height: 26px; flex: none; border-radius: 50%;
  background: var(--c-progress-bg); color: var(--c-progress);
  display: grid; place-items: center; font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
.rec-item .why { display: flex; flex-wrap: wrap; gap: 4px; margin-top: var(--sp-2); }
.why-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px; border-radius: var(--r-pill);
  background: var(--c-surface-3); color: var(--c-text-2); font-size: var(--fs-xs);
}
.why-chip b { color: var(--c-text); font-weight: var(--fw-medium); }
.score-pill {
  padding: 2px 9px; border-radius: var(--r-pill); white-space: nowrap;
  background: var(--c-surface-3); color: var(--c-text-2); font-size: var(--fs-xs);
}

/* ---------- รายการงานที่ไม่เข้าแผน (ห้ามให้หายเงียบ) ---------- */
.reason-list { display: grid; gap: var(--sp-2); }
.reason-row {
  display: flex; gap: var(--sp-3); align-items: baseline;
  padding: var(--sp-2) 0; border-bottom: 1px dashed var(--c-border); font-size: var(--fs-md);
}
.reason-row:last-child { border-bottom: 0; }
.reason-row .who { flex: 1; min-width: 0; }
.reason-row .why-txt { color: var(--c-text-2); font-size: var(--fs-sm); }

/* ---------- กราฟ CSS ล้วน (ห้ามใช้ library) ---------- */
.chart-row { display: flex; gap: var(--sp-5); align-items: center; flex-wrap: wrap; }
.donut {
  width: 132px; height: 132px; flex: none; border-radius: 50%;
  background: var(--c-surface-3);
  -webkit-mask: radial-gradient(circle, transparent 54%, #000 55%);
  mask: radial-gradient(circle, transparent 54%, #000 55%);
}
.legend { display: grid; gap: 5px; font-size: var(--fs-md); }
.legend .lg-row { display: flex; align-items: center; gap: var(--sp-2); }
.legend .sw { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.legend .lg-val { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--c-text-2); }

.bar-list { display: grid; gap: var(--sp-3); }
.bar-row { display: grid; grid-template-columns: 150px 1fr 76px; gap: var(--sp-3); align-items: center; font-size: var(--fs-md); }
.bar-track { height: 10px; border-radius: var(--r-pill); background: var(--c-surface-3); overflow: hidden; }
.bar-track > i { display: block; height: 100%; background: var(--c-progress); border-radius: var(--r-pill); }
.bar-track.warn > i { background: var(--c-medium); }
.bar-track.danger > i { background: var(--c-critical); }
.bar-track.alt > i { background: var(--c-done); }
.bar-row .bar-val { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- ตารางตรวจรับ 12 คำถาม ---------- */
.q-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-3); }
.q-item {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3); border: 1px solid var(--c-border); border-radius: var(--r-md);
}
.q-item .q-no {
  width: 22px; height: 22px; flex: none; border-radius: 50%;
  background: var(--c-surface-3); color: var(--c-text-2);
  display: grid; place-items: center; font-size: var(--fs-xs);
}
.q-item .q-val { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.q-item.pending .q-val { color: var(--c-text-3); }

/* ---------- U-20 · การ์ดตัวเลข Dashboard แบบจัดกลุ่ม ----------
   เดิมเป็นการ์ดเดี่ยว 9 ใบ + คำอธิบายยาวใต้ทุกใบ → ต้องเลื่อนจอหาตัวเลข
   ตอนนี้: 3 กลุ่มเรียงข้างกัน · ตัวเลขยังใหญ่อ่านจากไกลได้ · คำอธิบายอยู่ใน
   tooltip + <details> (ข้อมูลไม่หาย แค่ย้ายที่เก็บ) */
.dash-groups {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
/* จอกว้าง: แบ่งความกว้างตาม "จำนวนตัวเลขในกลุ่ม" (4 · 2 · 3) เพื่อให้ทุกช่องกว้างเท่ากัน
   และไม่มีกลุ่มไหนตกบรรทัดที่สองโดยไม่จำเป็น */
@media (min-width: 1200px) {
  .dash-groups { grid-template-columns: 4fr 2fr 3fr; }
}
.dash-group .card-head { padding: var(--sp-2) var(--sp-4); min-height: 0; }
.dash-group .card-head h3 { font-size: var(--fs-base); }
.mini-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); }
.mini {
  display: block; padding: var(--sp-3) var(--sp-4);
  border-right: 1px solid var(--c-border); color: inherit;
}
.mini:last-child { border-right: 0; }
a.mini:hover { background: var(--c-surface-3); text-decoration: none; }
.mini-val {
  font-size: var(--fs-2xl); font-weight: var(--fw-semibold);
  line-height: 1.15; font-variant-numeric: tabular-nums;
}
.mini-lbl { font-size: var(--fs-xs); color: var(--c-text-2); margin-top: 2px; }
.mini-sub { font-size: var(--fs-2xs); color: var(--c-text-3); margin-top: 1px; }
.mini.t-critical .mini-val { color: var(--c-critical); }
.mini.t-blocked  .mini-val { color: var(--c-blocked); }
.mini.t-done     .mini-val { color: var(--c-done); }
.mini.t-progress .mini-val { color: var(--c-progress); }

/* การ์ดที่พับเก็บได้ (ตารางตรวจรับ 12 คำถาม) — หัวการ์ดทำหน้าที่เป็นปุ่มเปิด/ปิด */
.details-card > summary { cursor: pointer; list-style: none; }
.details-card > summary::-webkit-details-marker { display: none; }
.details-card > summary::before { content: '▸ '; color: var(--c-text-3); }
.details-card[open] > summary::before { content: '▾ '; }

/* คำอธิบายที่ถูกย่อ — ต้องยังเปิดอ่านได้ด้วยคีย์บอร์ด/มือถือ ไม่ใช่มีแค่ tooltip */
.dash-explain {
  margin-top: var(--sp-2); border: 1px solid var(--c-border);
  border-radius: var(--r-md); background: var(--c-surface);
}
.dash-explain > summary {
  cursor: pointer; padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm); color: var(--c-text-2);
}
.dash-explain-body { padding: 0 var(--sp-4) var(--sp-3); display: grid; gap: var(--sp-2); }

/* ---------- ป้ายกำกับตัวเลขระหว่างงวด (T-38) ---------- */
.period-flag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-pill);
  background: var(--c-medium-bg); color: var(--c-medium); font-size: var(--fs-xs);
}

/* ---------- ปุ่มสลับโหมด (แนบไฟล์ / แนบลิงก์) ---------- */
.seg {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--c-surface-3); border-radius: var(--r-md);
}
.seg [role="tab"] {
  border: 0; background: transparent; color: var(--c-text-2);
  padding: 4px 14px; border-radius: var(--r-sm);
  font-size: var(--fs-md); font-weight: var(--fw-medium);
}
.seg [role="tab"][aria-selected="true"] {
  background: var(--c-surface); color: var(--c-text); box-shadow: var(--sh-sm);
}
.seg-note { font-size: var(--fs-sm); color: var(--c-text-2); }
.seg-more { margin-top: var(--sp-2); }
.seg-more > summary {
  cursor: pointer; font-size: var(--fs-sm); color: var(--c-text-2);
  list-style: none; display: inline-flex; align-items: center; gap: 4px;
}
.seg-more > summary::-webkit-details-marker { display: none; }
.seg-more > summary::before { content: '▸'; }
.seg-more[open] > summary::before { content: '▾'; }
.seg-more ul { margin: var(--sp-2) 0 0; padding-left: 18px; list-style: disc; }
.seg-more li { font-size: var(--fs-sm); color: var(--c-text-2); line-height: 1.7; }

@media (max-width: 1200px) {
  .detail-grid { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .auth-wrap { grid-template-columns: 1fr; }
  .auth-side { display: none; }
  .bar-row { grid-template-columns: 110px 1fr 64px; }
}

/* ============================================================
   Kanban Board (Phase 4 · /kanban)
   คอลัมน์ทั้งหมดมาจาก API — CSS ที่นี่ไม่ผูกกับ "จำนวนคอลัมน์" หรือรายชื่อสถานะ
   ============================================================ */
/* คำอธิบายวิธีเลื่อนกระดาน — ต้องอ่านได้ก่อนถึงตัวกระดาน */
.board-help {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  font-size: var(--fs-xs); color: var(--c-text-2); line-height: 1.6;
  margin-bottom: var(--sp-2);
}
.board-help .ico { flex: none; }

/* ⭐ แถบเลื่อนแนวนอน "ด้านบน" ของกระดาน
   🔴 หัวแถบวาดเอง ไม่ใช้ scrollbar ของเบราว์เซอร์ — วัดจริงแล้วพบว่ากล่อง overflow
   ที่ซ้อนไว้ด้านบนได้แต่ "ราง" ส่วนหัวแถบไม่ถูกวาด (overlay scrollbar โผล่เฉพาะตอนเลื่อน
   และไม่โผล่เลยบนมือถือ) → กลายเป็นแถบเปล่าที่กดอะไรไม่ได้ ซึ่งแย่กว่าเดิม */
.kanban-topbar {
  position: sticky; z-index: 2;
  /* เกาะไว้ใต้แถบหัวเว็บ — กระดานยาวแค่ไหน แถบเลื่อนก็ยังอยู่ในสายตาเสมอ
     (สำคัญมากบนมือถือ ที่กระดานเริ่มต่ำกว่าขอบจอแรกอยู่แล้ว) */
  top: calc(var(--topbar-h) + var(--sp-2));
  height: 14px; margin-bottom: var(--sp-2); overflow: hidden;
  background: var(--c-surface-3); border: 1px solid var(--c-border);
  border-radius: var(--r-pill); cursor: pointer;
}
.kanban-topbar:focus-visible { outline: 2px solid var(--c-progress); outline-offset: 2px; }
.kanban-topbar-thumb {
  height: 100%; width: 44px; min-width: 44px;
  background: var(--c-text-3); border-radius: var(--r-pill); cursor: grab;
}
.kanban-topbar-thumb:hover { background: var(--c-text-2); }
.kanban-topbar.dragging { cursor: grabbing; }
.kanban-topbar.dragging .kanban-topbar-thumb { background: var(--c-text-2); cursor: grabbing; }

/* แถบเลื่อนย้ายไปอยู่ด้านบนแล้ว → ซ่อนของเดิมที่อยู่ใต้กระดาน (ยังเลื่อนด้วยวิธีอื่นได้ครบ) */
.kanban-scroll {
  overflow-x: auto; padding-bottom: var(--sp-2);
  scrollbar-width: none;
}
.kanban-scroll::-webkit-scrollbar { display: none; }
/* ⭐ พื้นที่ที่ "ลากแล้วกระดานเลื่อน" — เคอร์เซอร์ต้องบอกได้ว่าตรงไหนลากได้ */
.kanban, .kcol-head, .kcol-body { cursor: grab; }
.kanban-scroll.panning { user-select: none; }
.kanban-scroll.panning, .kanban-scroll.panning * { cursor: grabbing; }

.kanban { display: flex; gap: var(--sp-3); align-items: flex-start; min-height: 220px; }
.kcol {
  flex: 0 0 268px; width: 268px;
  background: var(--c-surface-2); border: 1px solid var(--c-border);
  border-radius: var(--r-lg); display: flex; flex-direction: column;
  transition: opacity var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.kcol-head {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-lg) var(--r-lg) 0 0;
  font-size: var(--fs-md); font-weight: var(--fw-medium);
}
.kcol-head .nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kcol-head .cnt {
  background: rgba(255, 255, 255, .55); border-radius: var(--r-pill);
  padding: 0 7px; font-size: var(--fs-xs); font-variant-numeric: tabular-nums;
}
.kcol-head .spacer { flex: 1; }
/* 🔴 เพดานความสูงของคอลัมน์ (แก้บั๊กที่ผู้สั่งงานเห็นเป็น "พื้นที่ว่างขาวโล่ง")
   ไม่มีเพดาน = คอลัมน์ที่การ์ดเยอะ (Done 14 ใบ) ดันกระดานสูง 1,847px บนจอสูง 805px
   → ข้าง ๆ คอลัมน์ที่สั้นกว่ากลายเป็นพื้นที่ว่างสูงกว่า 1,500px และแถบเลื่อนหายไปใต้จอ
   มีเพดาน = คอลัมน์ยาวเลื่อนในตัวเอง กระดานพอดีจอ และยังลากการ์ดข้ามคอลัมน์ได้ปกติ */
.kcol-body {
  padding: var(--sp-2); display: grid; gap: var(--sp-2); min-height: 76px;
  max-height: min(62vh, 720px); overflow-y: auto;
  align-content: start;
}
.kcol-empty {
  padding: var(--sp-4) 0; text-align: center;
  color: var(--c-text-3); font-size: var(--fs-xs);
}
.kcol-more { margin: 0 var(--sp-2) var(--sp-2); }

/* ระหว่างลาก: คอลัมน์ที่ไปไม่ได้จะหรี่ · ต้นทางมีเส้นประ · ปลายทางที่รับได้จะเน้น */
.kcol.no-drop { opacity: .35; }
.kcol.is-source { border-style: dashed; }
.kcol.drag-over { border-color: var(--c-progress); background: var(--c-progress-bg); }

/* ---------- การ์ด ---------- */
.kcard {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-left: 3px solid var(--c-low);
  border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3);
  box-shadow: var(--sh-sm); cursor: grab; display: grid; gap: 6px;
}
.kcard:active { cursor: grabbing; }
.kcard.p-critical { border-left-color: var(--c-critical); }
.kcard.p-high     { border-left-color: var(--c-high); }
.kcard.p-medium   { border-left-color: var(--c-medium); }
.kcard.p-low      { border-left-color: var(--c-low); }
.kcard.locked { cursor: not-allowed; background: var(--c-surface-2); }
.kcard.dragging { opacity: .55; }
/* รอเซิร์ฟเวอร์ยืนยัน — ยังไม่ถือว่าย้ายสำเร็จ */
.kcard.pending { opacity: .65; outline: 2px dashed var(--c-border-strong); }
/* เซิร์ฟเวอร์ไม่รับ → เด้งกลับที่เดิม แล้วกะพริบให้เห็นว่าไม่ได้ย้าย */
.kcard.bounced { outline: 2px solid var(--c-critical); animation: kcard-bounce var(--dur-base) var(--ease) 2; }
@keyframes kcard-bounce {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(-5px); }
}
@media (prefers-reduced-motion: reduce) {
  .kcard.bounced { animation: none; }
}

.kcard .kc-top { display: flex; align-items: center; gap: 6px; }
.kcard .kc-top .spacer { flex: 1; }
.kc-id { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--c-text-2); }
.kc-title { font-size: var(--fs-md); font-weight: var(--fw-medium); line-height: 1.4; }
.kc-title a { color: var(--c-text); }
.kc-dept { font-size: var(--fs-xs); color: var(--c-text-2); }
.kc-blocked {
  font-size: var(--fs-xs); color: var(--c-blocked);
  background: var(--c-blocked-bg); border-radius: var(--r-sm); padding: 3px 6px;
}
.kc-foot { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--c-text-2); }
.kc-foot .spacer { flex: 1; }
.kc-foot .who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 96px; }
.kc-counts { display: inline-flex; gap: 5px; color: var(--c-text-3); }
.kc-due { font-variant-numeric: tabular-nums; }
.kc-due.late { color: var(--c-critical); font-weight: var(--fw-medium); }
.board-error { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-lg); width: 100%; }

/* ============================================================
   Calendar (Phase 4 · /calendar)
   ช่องวัน/ขอบสัปดาห์/ขอบเดือนมาจากเซิร์ฟเวอร์ — CSS ไม่คำนวณปฏิทินเอง
   ============================================================ */
.cal-bar {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap; margin-bottom: var(--sp-3);
}
.cal-bar .spacer { flex: 1; }
.cal-bar > b { font-size: var(--fs-base); }

.cal { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-lg); overflow: hidden; }
.cal-dow {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--c-surface-2); border-bottom: 1px solid var(--c-border);
}
.cal-dow span {
  padding: 6px var(--sp-2); font-size: var(--fs-xs); color: var(--c-text-2);
  text-align: center; border-right: 1px solid var(--c-border);
}
.cal-dow span:last-child { border-right: 0; }

.cal-grid { display: grid; }
.cal-grid.cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-grid.cols-1 { grid-template-columns: minmax(0, 1fr); }
.cal-cell {
  min-height: 116px; padding: var(--sp-2);
  border-right: 1px solid var(--c-border); border-bottom: 1px solid var(--c-border);
  display: flex; flex-direction: column; gap: 4px; min-width: 0;
}
.cal-grid.cols-7 > .cal-cell:nth-child(7n) { border-right: 0; }
.cal-grid.cols-1 > .cal-cell { border-right: 0; min-height: 320px; }
.cal-week .cal-cell { min-height: 260px; }
.cal-cell.blank { background: var(--c-surface-2); }
.cal-cell.is-weekend { background: var(--c-surface-2); }
.cal-cell.is-today { box-shadow: inset 0 3px 0 var(--c-progress); }
.cal-cell.drag-over { background: var(--c-progress-bg); }
.cal-date { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-xs); color: var(--c-text-2); }
.cal-date b { font-size: var(--fs-base); color: var(--c-text); font-variant-numeric: tabular-nums; }
.cal-date .spacer { flex: 1; }
.cal-cell.is-today .cal-date b { color: var(--c-progress); }
.cal-evs { display: grid; gap: 3px; min-height: 24px; }
.cal-more { font-size: var(--fs-xs); color: var(--c-text-2); text-decoration: underline; }

/* ⭐⭐ ปฏิทินมุมมองเดือน — ตัวเลขต่อวัน (ดู `components/calendarCounts.js`)
   ⚠ ช่องเตี้ยกว่าเดิมได้เพราะไม่มีชิปงาน ⇒ ทั้งเดือนพอดีหน้าจอเดียวไม่ต้องเลื่อน */
.cal-counts .cal-cell { min-height: 92px; }
.cal-count { justify-content: flex-start; }
.cal-count .cnt-main {
  display: flex; align-items: baseline; gap: 4px; margin-top: 2px;
  text-decoration: none; color: var(--c-text);
}
.cal-count .cnt-main b { font-size: var(--fs-2xl); font-variant-numeric: tabular-nums; }
.cal-count .cnt-main span { font-size: var(--fs-xs); color: var(--c-text-2); }
.cal-count .cnt-main:hover b { color: var(--c-brand); text-decoration: underline; }
.cal-count .cnt-sub {
  display: flex; flex-wrap: wrap; gap: 2px 8px;
  font-size: var(--fs-xs); color: var(--c-text-2); font-variant-numeric: tabular-nums;
}
/* 🔴 สีแดง = เลยกำหนด (สถานะ) ⛔ ไม่ใช่การตกแต่ง */
.cal-count .cnt-sub .late { color: var(--c-critical); font-weight: var(--fw-semibold); }
.cal-count .cnt-none { color: var(--c-text-3); font-size: var(--fs-lg); }
.cal-cell.is-empty { background: var(--c-surface-2); }

.cal-ev {
  display: flex; align-items: center; gap: 4px; min-width: 0;
  border-left: 3px solid var(--c-low); border-radius: var(--r-sm);
  background: var(--c-surface-3); padding: 2px 5px; font-size: var(--fs-xs);
  cursor: grab;
}
.cal-ev.locked { cursor: default; }
.cal-ev.p-critical { border-left-color: var(--c-critical); }
.cal-ev.p-high     { border-left-color: var(--c-high); }
.cal-ev.p-medium   { border-left-color: var(--c-medium); }
.cal-ev.p-low      { border-left-color: var(--c-low); }
.cal-ev.s-done { opacity: .62; }
.cal-ev .tm { font-variant-numeric: tabular-nums; color: var(--c-text-2); flex: none; }
.cal-ev .kind { flex: none; }
.cal-ev .ttl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--c-text); }
.cal-ev .who { flex: none; color: var(--c-text-3); max-width: 74px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-ev.late .tm { color: var(--c-critical); font-weight: var(--fw-medium); }
.cal-ev.dragging { opacity: .5; }
.cal-ev.pending { outline: 2px dashed var(--c-border-strong); }
.cal-ev.bounced { outline: 2px solid var(--c-critical); }

@media (max-width: 1000px) {
  .cal-grid.cols-7 { grid-template-columns: repeat(7, minmax(96px, 1fr)); }
  .cal { overflow-x: auto; }
  .cal-ev .who { display: none; }
}

/* ============================================================
   Settings (Phase 4 · /settings) — ฟอร์มจัดการข้อมูลหลัก
   ============================================================ */
.form-grid {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  align-items: start; margin-bottom: var(--sp-4);
}
.form-grid .field { margin-bottom: 0; }
.form-grid .field-actions { display: flex; align-items: flex-end; gap: var(--sp-2); padding-top: 18px; }
.danger-text { color: var(--c-critical); }

/* ---------- หน้ารวมทางเข้าการตั้งค่า (`/settings`) ---------- */
.settings-hub {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.settings-hub-card {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--r-lg); padding: var(--sp-4); color: var(--c-text);
}
.settings-hub-card:hover {
  border-color: var(--c-border-strong); box-shadow: var(--sh-sm); text-decoration: none;
}
.settings-hub-card .ico { font-size: var(--fs-2xl); line-height: 1; }
.settings-hub-card b { font-size: var(--fs-lg); }
.settings-hub-card .dsc { font-size: var(--fs-xs); color: var(--c-text-2); line-height: 1.55; }
.settings-hub-card .dsc-req {
  font-size: var(--fs-xs); color: var(--c-text-3);
  display: inline-flex; align-items: center; gap: 4px;
}
.settings-hub-card .dsc-req::before { content: "🔑"; font-size: var(--fs-2xs); }
.settings-hub-card.locked { background: var(--c-surface-2); }
.settings-hub-card .dsc.lock { color: var(--c-text-3); }

/* ============================================================
   Export CSV — ปุ่มอยู่ "มุมขวาบน" ของหน้ารายการงาน (/tasks) คู่กับ "สร้างงานใหม่"
   คำกำกับ (จำนวนแถว · งานที่ปิดแล้วไม่อยู่ในไฟล์) วางไว้ซ้ายปุ่ม ชิดขวา
   จึงไม่กินความสูงเหนือตาราง — ผู้ใช้เห็นตัวเลขสรุปกับแถวแรกเร็วขึ้น
   ============================================================ */
.export-box {
  display: flex; flex-direction: row-reverse; align-items: center;
  gap: var(--sp-2); flex-wrap: wrap; justify-content: flex-end;
}
.export-box .export-note {
  flex: 0 1 250px; line-height: 1.45; text-align: right;
}
.export-box .export-note b { color: var(--c-text-2); }

@media (max-width: 900px) {
  /* จอแคบ: ให้ปุ่มขึ้นก่อน แล้วคำกำกับอยู่ใต้ปุ่มชิดซ้ายตามปกติ */
  .export-box { flex-direction: column; align-items: flex-start; }
  .export-box .export-note { flex: 1 1 auto; text-align: left; }
  .page-head .head-actions { flex-basis: 100%; justify-content: flex-start; }
}

/* ============================================================
   นำเข้างานจากไฟล์ CSV (Phase 5 · /settings/import · U-22 · U-23 · U-24)
   ตารางตรวจสอบต้องอ่านง่ายพอที่คนจะไล่ตาทีละแถวจริง ๆ ได้ 40 แถวรวด
   ============================================================ */
.step-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-right: 6px; border-radius: 50%;
  background: var(--c-surface-3); color: var(--c-text-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums;
}

/* ---------- กล่องลากวางไฟล์ ---------- */
.imp-drop {
  border: 2px dashed var(--c-border-strong); border-radius: var(--r-lg);
  background: var(--c-surface-2); padding: var(--sp-6) var(--sp-4);
  text-align: center; cursor: pointer;
}
.imp-drop:hover, .imp-drop.is-over { border-color: var(--c-progress); background: var(--c-progress-bg); }
.imp-drop .ico { font-size: 34px; line-height: 1; }
.imp-drop b { display: block; margin-top: var(--sp-2); font-size: var(--fs-lg); }

/* ---------- ตารางคอลัมน์ที่ต้องกรอก (ขั้นที่ 1) ---------- */
.imp-cols { min-width: 0; width: 100%; }
.imp-cols td, .imp-cols th { white-space: normal; vertical-align: top; }

/* ---------- ค่าที่ระบบยอมรับ (ย้ายมาจากท้ายไฟล์เทมเพลต) ---------- */
.imp-ref-grid {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.imp-ref-group {
  border: 1px solid var(--c-border); border-radius: var(--r-md);
  background: var(--c-surface-2); padding: var(--sp-3);
}
.imp-ref-head { display: flex; align-items: center; gap: var(--sp-2); }
.imp-ref-head b { font-size: var(--fs-md); }
.imp-ref-chips { display: flex; flex-wrap: wrap; gap: 5px; max-height: 190px; overflow: auto; }
.imp-ref-chips .badge { cursor: pointer; font-weight: var(--fw-regular); }
.imp-ref-chips .badge:hover { border-color: var(--c-progress); color: var(--c-text); }
#refSearch { max-width: 280px; }

/* ---------- มุมมองแถว ---------- */
.imp-filters { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.imp-filters .btn.on {
  background: var(--c-brand); border-color: var(--c-brand); color: var(--c-text-invert);
}

/* ---------- ตารางตรวจสอบทุกแถว ---------- */
.imp-table { min-width: 1180px; }
.imp-table th { vertical-align: bottom; }
.imp-table th .th-note,
.imp-table .tid .th-note {
  display: block; font-size: var(--fs-2xs); color: var(--c-text-3);
  font-weight: var(--fw-regular); text-transform: none; letter-spacing: 0;
}
.imp-table td { white-space: normal; vertical-align: top; padding-top: var(--sp-3); }
.imp-table .imp-status { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.imp-table .imp-shift { display: block; font-size: var(--fs-2xs); color: var(--c-high); }

/* หนึ่งช่องข้อมูล = ป้ายเล็ก + ค่าที่ระบบตีความได้ (+ ค่าดิบในไฟล์ถ้าต่างกัน) */
.imp-f { padding: 3px 5px; border-radius: var(--r-sm); margin-bottom: 3px; max-width: 260px; }
.imp-f .imp-k { display: block; font-size: var(--fs-2xs); color: var(--c-text-3); }
.imp-f .imp-val { display: block; font-size: var(--fs-md); color: var(--c-text); overflow-wrap: anywhere; }
.imp-f.big .imp-val { font-weight: var(--fw-medium); }
/* 🔴 ค่าที่ผู้ใช้พิมพ์มาเอง เมื่อระบบตีความได้ต่างออกไป — จุดที่คนจับผิดระบบได้ */
.imp-f .imp-raw {
  display: block; font-size: var(--fs-2xs); color: var(--c-medium);
  background: var(--c-medium-bg); border-radius: var(--r-sm); padding: 1px 4px; margin-top: 2px;
}
/* ⛔ ไฮไลต์เฉพาะ "ช่อง" ที่มีปัญหา ไม่ใช่ทั้งแถว */
.imp-f.bad { background: var(--c-critical-bg); box-shadow: inset 0 0 0 1px var(--c-critical); }
.imp-f.bad .imp-k, .imp-f.bad .imp-val { color: var(--c-critical); }

/* ---------- แถวรายละเอียด: ต้องแก้ (แดง) vs ข้อสังเกต (เทา) ---------- */
.imp-detail td { padding-top: 0; padding-bottom: var(--sp-3); }
.imp-detail .imp-issues, .imp-detail .imp-notes { font-size: var(--fs-md); line-height: 1.6; }
.imp-detail .imp-issues {
  background: var(--c-critical-bg); border-left: 3px solid var(--c-critical);
  border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-2);
}
.imp-detail .imp-issues b { color: var(--c-critical); }
.imp-detail .imp-notes {
  background: var(--c-surface-2); border-left: 3px solid var(--c-border-strong);
  border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3); color: var(--c-text-2);
}
.imp-detail ul { margin: 3px 0 0; padding-left: 18px; }
.imp-detail .imp-fix { color: var(--c-text-2); }

/* ---------- ผลการนำเข้า ---------- */
.imp-links { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.imp-links a.badge:hover { border-color: var(--c-brand); text-decoration: none; }

/* ---------- ฟอร์มแก้ไขรายแถว (ในหน้าต่างซ้อน) ---------- */
.imp-form { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.imp-form .field.span-2 { grid-column: 1 / -1; }

@media (max-width: 640px) {
  .imp-table { min-width: 900px; }
  .imp-f { max-width: none; }
  .imp-form { grid-template-columns: 1fr; }
}

/* ============================================================
   🔁 งานโอนย้าย (U-41) — กล่องพักงานที่ "ยังไม่ใช่ของเรา"
   🔴 กติกาสีของหมวดนี้: สถานะ "รอตอบรับ" ต้องเป็น **เหลือง** (`--c-medium`)
      ⛔ ห้ามใช้เขียวเด็ดขาด — เขียวคือภาษาของ "เสร็จแล้ว" ซึ่งเป็นความเข้าใจผิด
      ที่ทำให้เจ้าของเดิมเลิกทำทั้งที่ยังไม่มีใครกดรับ (= งานลอย)
   ============================================================ */
.tr-list { display: grid; }
.tr-item {
  display: grid; gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--c-border);
}
.tr-item:last-child { border-bottom: 0; }
.tr-top { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.tr-code { font-size: var(--fs-md); }
.tr-title { font-size: var(--fs-lg); font-weight: var(--fw-semibold); line-height: 1.4; }
.tr-who { font-size: var(--fs-md); color: var(--c-text-2); }

/* เหตุผลที่ส่งมา = ข้อมูลที่ทำให้ "ตัดสินใจได้ในกล่องเลย" (U-41 ข้อ 4) จึงต้องเด่น */
.tr-reason {
  background: var(--c-surface-2); border-left: 3px solid var(--c-medium);
  border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3);
}
.tr-reason .k { display: block; font-size: var(--fs-2xs); color: var(--c-text-3); }
.tr-reason .v { display: block; font-size: var(--fs-md); line-height: 1.6; overflow-wrap: anywhere; }

.tr-facts { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); }
.tr-facts .k { display: block; font-size: var(--fs-2xs); color: var(--c-text-3); }
.tr-facts .v { display: block; font-size: var(--fs-md); }

.tr-foot { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.tr-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.tr-when { font-size: var(--fs-md); color: var(--c-text-2); margin-right: var(--sp-3); }
/* นับถอยหลัง — สื่อความเร่งด่วนได้โดยไม่ต้องมี push (docs/07 §5.8 ข้อ 4) */
.tr-when.urgent {
  color: var(--c-medium); background: var(--c-medium-bg);
  border-radius: var(--r-pill); padding: 2px var(--sp-3); font-weight: var(--fw-medium);
}
.tr-outcome { font-size: var(--fs-md); color: var(--c-text-2); }

/* กล่องว่างคือสภาพปกติ — ต้องดู "ตั้งใจ" ไม่ใช่เหมือนโหลดพัง (U-41 ข้อ 7) */
.tr-empty { padding: var(--sp-10) var(--sp-6); }
.tr-empty .ico { opacity: .85; }
.tr-empty p { max-width: 46ch; margin-left: auto; margin-right: auto; line-height: 1.7; }

/* ---------- ป้าย "รอตอบรับ" บนแถวงาน / การ์ด Kanban / หน้ารายละเอียด ---------- */
.tr-badge { margin-left: var(--sp-2); white-space: nowrap; }
.kc-transfer { margin-top: 4px; }
.kc-transfer .tr-badge { margin-left: 0; white-space: normal; }

/* ---------- แถบเตือนบนหน้ารายละเอียดงาน ---------- */
.tr-callout .tr-actions { margin-top: var(--sp-2); }
.tr-readonly {
  margin-top: var(--sp-2); font-size: var(--fs-md); color: var(--c-text-2);
}

/* ---------- ประวัติการโยกงาน ---------- */
.tr-hist { display: grid; gap: var(--sp-3); }
.tr-hist-row {
  border: 1px solid var(--c-border); border-radius: var(--r-md);
  padding: var(--sp-3); display: grid; gap: 4px;
}
.tr-hist-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.tr-hist-who { font-size: var(--fs-md); font-weight: var(--fw-medium); }
.tr-hist-reason { font-size: var(--fs-md); line-height: 1.6; overflow-wrap: anywhere; }

@media (max-width: 640px) {
  .tr-item { padding: var(--sp-3) var(--sp-4); }
  .tr-facts { gap: var(--sp-2) var(--sp-4); }
  .tr-actions .btn { flex: 1 1 auto; }
}

/* ============================================================
   ผู้ใช้และบทบาท (/settings/users) · ทะเบียนความสามารถ (/settings/skills)
   ============================================================ */

/* ป้ายกำกับของกลุ่มช่องติ๊ก (ไม่ใช่ <label for>) — ให้หน้าตาเท่ากับ .field > label */
.field > .lbl {
  display: block; font-size: var(--fs-md); font-weight: var(--fw-medium);
  margin-bottom: var(--sp-1);
}

/* ช่องกรอกเหตุผลในหน้าต่างยืนยัน — ต้องสูงพอให้เห็นสิ่งที่พิมพ์จริง 3 บรรทัด */
.textarea.ta-3 { height: auto; min-height: 78px; padding: 8px 10px; line-height: 1.55; }

/* ---------- ตารางช่องติ๊ก (บทบาท · สิทธิ์ · ความสามารถ) ---------- */
.perm-grid, .check-grid {
  display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.check-item {
  display: grid; grid-template-columns: auto 1fr; gap: 2px var(--sp-2);
  align-items: baseline; padding: 6px 8px;
  border: 1px solid var(--c-border); border-radius: var(--r-md);
  background: var(--c-surface); cursor: pointer;
}
.check-item:hover { border-color: var(--c-border-strong); }
.check-item input { grid-row: span 2; align-self: center; }
.check-item .t { font-size: var(--fs-md); }
.check-item .h {
  grid-column: 2; font-size: var(--fs-2xs); color: var(--c-text-3);
  font-family: var(--font-mono); overflow-wrap: anywhere;
}
/* 🔴 ช่องที่ผู้ใช้ให้ไม่ได้ — หรี่ + กดไม่ได้ตั้งแต่แรก (⛔ ไม่ปล่อยให้เจอ 403 ทีหลัง) */
.check-item.locked {
  background: var(--c-surface-2); border-style: dashed; cursor: not-allowed; opacity: .62;
}
.check-item.locked .t { color: var(--c-text-2); }

.perm-group { margin-bottom: var(--sp-4); }
.perm-group h4 {
  font-size: var(--fs-md); color: var(--c-text-2);
  margin-bottom: var(--sp-2); padding-bottom: 4px;
  border-bottom: 1px solid var(--c-border);
}
.perm-group .check-grid, .perm-group .perm-grid { margin-bottom: 0; }

/* ---------- รายการติ๊กความสามารถ + ช่องเลือกระดับ ---------- */
.skill-pick {
  display: grid; grid-template-columns: 1fr 150px; gap: var(--sp-2);
  align-items: center; margin-bottom: var(--sp-2);
}
.skill-pick .check-item { margin: 0; }

/* ---------- ตาราง คน × ทักษะ ---------- */
.matrix-table th .th-note {
  display: block; font-size: var(--fs-2xs); color: var(--c-text-3);
  font-weight: var(--fw-regular); text-transform: none; letter-spacing: 0;
}

@media (max-width: 640px) {
  .perm-grid, .check-grid { grid-template-columns: 1fr; }
  .skill-pick { grid-template-columns: 1fr; }
  .skill-pick .select-sm { max-width: none; }
}

/* ============================================================
   ค่าใช้จ่ายผูกพัน (U-29 · /expenses) — docs/08 §6
   🔴 ตัวเลขเงินต้องเรียงหลักตรงกันเสมอ (tabular-nums) และไม่ถูกย่อ
   ============================================================ */
/* ช่องกรอกที่ต้องกินความกว้างเต็มแถวของ .form-grid (ชื่อรายการ · รายละเอียด · ตัวอย่างงวด) */
.form-grid .field.span-2 { grid-column: 1 / -1; }

/* ยอดเงินบนการ์ดสรุป — ตัวเลขคนละความยาวต้องเรียงหลักตรงกัน */
.stat .value.num { font-variant-numeric: tabular-nums; }
/* หลายสกุลเงินในการ์ดใบเดียว: เว้นระยะให้แต่ละยอดอ่านแยกออกจากกัน */
.stat .value.num + .foot + .value.num { margin-top: 6px; }
/* ช่องกรอกยอดเงินในฟอร์ม (ไม่ได้อยู่ในตาราง จึงต้องประกาศแยกจาก .table .num) */
.input.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ตัวอย่างวันครบกำหนด 3 งวดแรก (แสดงสดขณะกรอก — docs/08 §6.5) */
.exp-preview-list { display: grid; gap: 4px; margin-top: 6px; }
.exp-preview-row {
  display: grid; grid-template-columns: 62px 1fr; gap: var(--sp-2);
  align-items: baseline; font-size: var(--fs-md);
}
.exp-preview-row .pn { color: var(--c-text-3); font-size: var(--fs-xs); }
.exp-preview-row .dt { font-variant-numeric: tabular-nums; font-weight: var(--fw-medium); }
.exp-preview-row .clamped { color: var(--c-high); }

/* ตารางแบบ "ป้าย → ค่า" ของหัวรายการค่าใช้จ่าย (ไม่ใช่ตารางข้อมูลหลายคอลัมน์
   จึงไม่ต้องกว้าง 960px และต้องตัดบรรทัดได้เพราะมีช่องรายละเอียดแบบข้อความยาว) */
.table.kv-table { min-width: 0; }
.table.kv-table th[scope='row'] { width: 210px; }
.table.kv-table td { white-space: normal; }

/* 🔴 กล่องตัวอย่างวันครบกำหนด — ติดก้นหน้าต่างไว้เสมอ (docs/08 §6.5)
   ฟอร์มสร้างรายการยาวเกินหนึ่งจอ ถ้ากล่องนี้ไหลไปอยู่ท้ายสุด ผู้ใช้จะกรอกเสร็จ
   แล้วกดบันทึกโดยไม่เคยเห็นการหนีบสิ้นเดือนเลย = เท่ากับไม่ได้ทำข้อนี้ */
.exp-preview-dock {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--c-surface);
  margin-top: var(--sp-3); padding: var(--sp-2) 0;
  border-top: 1px solid var(--c-border);
}
.exp-preview-dock .lbl {
  font-size: var(--fs-md); font-weight: var(--fw-medium); margin-bottom: var(--sp-1);
}
.exp-preview-dock .callout { margin-bottom: 0; }

/* ============================================================
   งานประจำและแผนบำรุงรักษา (U-56 · /operations)
   ============================================================ */
/* หัวข้อคั่นกลางฟอร์ม — ฟอร์มแผนงานมี 2 เรื่องในหน้าต่างเดียว
   ("รอบการทำงาน" กับ "งานที่จะถูกสร้าง") ถ้าไม่คั่น ผู้ใช้จะแยกไม่ออกว่า
   ช่อง "ชื่อ" อันไหนคือชื่อแผน อันไหนคือชื่องาน */
.form-sec {
  margin: var(--sp-2) 0 0; padding-top: var(--sp-3);
  border-top: 1px solid var(--c-border);
  font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--c-text-2);
}
.switch-row { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); padding-top: 4px; }

/* 🔴 กล่องรอบถัดไป — ติดก้นหน้าต่างไว้ (เหตุผลเดียวกับ `.exp-preview-dock`) */
.pm-preview-dock {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--c-surface);
  margin-top: var(--sp-2); padding: var(--sp-2) 0;
  border-top: 1px solid var(--c-border);
}
.pm-preview-dock .lbl {
  font-size: var(--fs-md); font-weight: var(--fw-medium); margin-bottom: var(--sp-1);
}
.pm-upcoming { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.pm-upcoming li {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-border); border-radius: var(--r-md);
}
/* ตัวเลขสรุปหน้างานประจำ = 2 กลุ่ม (3 ช่อง · 5 ช่อง) จึงใช้สัดส่วนของตัวเอง
   ⛔ ใช้ `.dash-groups` ไม่ได้ — มันตรึงไว้ที่ 3 กลุ่ม (4fr 2fr 3fr) แล้วกลุ่มที่ 2 จะแคบ */
.pm-groups { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
@media (min-width: 1200px) { .pm-groups { grid-template-columns: 3fr 5fr; } }
