/* tables.css — Excel-like data tables (สำหรับคนที่คุ้นกับ Excel)
   - header ติดบน + footer (แถวรวม) ติดล่าง
   - freeze คอลัมน์แรก (เหมือน Freeze Panes)
   - scroll ได้ 2 แกนในกล่องเดียว + สลับสีแถว (zebra)

   เป็น plain CSS โหลด "หลัง" tailwind.css → รอดจาก `make css` (แบบเดียวกับ
   components.css / responsive.css). ทุกกฎ scope ที่ `.xltable` ซึ่ง JS
   `wrapResponsiveTables()` ใส่ให้ทุก `.data-table` ใน <main> (ยกเว้น matrix และ
   ตารางที่ติด [data-no-excel]). ตัว `.table-scroll` wrapper ได้คลาส `.xl-scroll`
   เพื่อกลายเป็น "กล่อง scroll เดียว" ที่ header/footer/คอลัมน์ freeze ยึดเทียบ.

   ── ทำไมต้องเป็นกล่อง max-height (ไม่ใช่ sticky เทียบทั้งหน้า) ──
   ตาม CSS spec: `overflow-x:auto` บังคับ `overflow-y` เป็น auto ด้วย → ตัว
   .table-scroll จึงเป็น scroll container แกนตั้งไปในตัว ถ้าไม่มี max-height มัน
   "ไม่ scroll" จริง ทำให้ position:sticky top ของ header ถูก trap (ไม่ติด).
   การให้ max-height ทำให้กล่อง scroll จริง → header/footer ยึดกับกล่องได้. */

/* ── Implementation Progress matrix (project detail) — เพิ่ม sticky header (top) ──
   matrix มี freeze คอลัมน์แรก (.sticky-l z3 · corner z4) + heatmap + tfoot + header bg
   ทึบ (surface-2/3) อยู่แล้ว · เพิ่ม max-height ให้ .ch-matrix-wrap เลื่อนในตัว + thead
   sticky top → เลื่อนลงหัว milestone ค้างบน (JS project_detail ปรับ max-height ตาม
   viewport จริงตอนเปิด tab/หลัง hx-swap · CSS calc เป็น fallback ก่อน JS) */
.ch-matrix-wrap { max-height: calc(100vh - 14rem); }
.ch-matrix thead th { position: sticky; top: 0; z-index: 3; }

/* ── Matrix: คอลัมน์กว้างคงที่ (fixed) + ตัดข้อความล้นด้วย … + กดดูข้อความเต็ม/copy ──
   เดิมคอลัมน์ auto-grow (input.css: .ch-matrix { width:100%; min-width:1100px }) → คอลัมน์ที่มี
   ข้อความยาวดันตารางเบ้ ไม่เป็นระเบียบ. เปลี่ยนเป็น table-layout:fixed + กว้างคงที่ →
   ทุกคอลัมน์เท่ากัน · เนื้อหายาวตัดด้วย … (span .ch-mx-trunc) · คลิกเซลล์ที่ตัด → popup
   ข้อความเต็ม + ปุ่มคัดลอก (JS ใน project_detail.html). ตารางกว้าง = ผลรวมคอลัมน์
   (width:max-content) → เลื่อนแนวนอนเมื่อ milestone เยอะ (.ch-matrix-wrap overflow-x มีอยู่แล้ว).
   sticky header/freeze คอลัมน์แรก ไม่กระทบ (พึ่ง position:sticky ไม่ใช่ table-layout).
   ⚠️ s129 fix: เดิม width:auto → Chrome size table = **max-content** → intrinsic width ของ
   content (input ที่ default size≈20ch ~150px / ข้อความ overflow:hidden ที่ max-content=เต็ม)
   รั่วเข้ามาขยายคอลัมน์เกิน 130 (number/text col กว้างกว่า system · refcode col ไม่ตัด). แก้เป็น
   width:min-content = ผลรวม column width ที่กำหนด (table-layout:fixed → แต่ละคอลัมน์ floor ที่
   first-row th width 130/240 · content หดได้ด้วย min-width:0/.ch-mx-trunc) → ทุกคอลัมน์ "คงที่
   เป๊ะ" 130/240 ไม่ size ตาม content · milestone น้อย: ตารางแคบกว่าจอ · เยอะ: เลื่อนแนวนอน.
   min-width:0 ลบล้าง min-width:1100 (input.css). */
.ch-matrix { table-layout: fixed; width: min-content; min-width: 0; }
.ch-matrix thead th { width: 130px; }                 /* คอลัมน์ milestone (s128: fix เป๊ะ 130px ไม่ยืด) */
.ch-matrix thead th.sticky-l { width: 240px; }        /* คอลัมน์แรก (refcode + job desc) */
.ch-matrix .ch-mx-trunc {
  display: block; max-width: 100%; min-width: 0;       /* min-width:0 = ตัดได้ใน flex (header name) */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ch-matrix [data-mx-full] { cursor: pointer; }
.ch-matrix [data-mx-full]:hover { text-decoration: underline dotted; text-underline-offset: 2px; }
/* input/select ในเซลล์ fixed → ไม่ให้ขยายเกินคอลัมน์ (inline min-width 82-95 < 130 content ~114px) */
.ch-matrix td input, .ch-matrix td select { max-width: 100%; box-sizing: border-box; }

/* ── อ่าน/แก้ไขข้อความยาวในเซลล์ TEXT (popover) — คอลัมน์แคบ 130px อ่าน input บรรทัดเดียวลำบาก ──
   เซลล์ text ที่แก้ได้มีไอคอน ⤢ มุมขวา (โชว์จาง · ชัดตอน hover/focus) → คลิกเปิด popover
   textarea อ่าน/แก้ได้เต็ม (JS project_detail.html) แล้วเซฟผ่าน hx-trigger=change ของ input
   เดิม (ไม่แตะ backend · ไม่มี migration). พิมพ์ inline สั้น ๆ ได้เหมือนเดิม. */
.ch-mx-textcell { position: relative; display: block; }
.ch-mx-textcell > input { width: 100%; padding-right: 1.4rem; }    /* เว้นที่ขวาให้ไอคอน ไม่ทับตัวอักษร (รวม text-align:right) */
.ch-mx-expand {
  position: absolute; top: 50%; right: 2px; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; padding: 0; border: 0; border-radius: 4px;
  background: transparent; color: var(--ch-text-4); cursor: pointer;
  opacity: .42; transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.ch-mx-expand svg { width: 12px; height: 12px; }
.ch-mx-textcell:hover .ch-mx-expand,
.ch-mx-textcell:focus-within .ch-mx-expand { opacity: 1; }
.ch-mx-expand:hover { background: var(--ch-surface-3); color: var(--ch-text-2); }
.ch-mx-expand:focus-visible { outline: 2px solid var(--ch-accent); outline-offset: 1px; }  /* keyboard ring (ตาม .ch-info-btn) */
/* touch (ไม่มี hover) → ไอคอนชัดพอให้เห็นว่ากดได้ (desktop คงจาง .42 ชัดตอน hover) */
@media (hover: none) { .ch-mx-expand { opacity: .82; color: var(--ch-text-3); } }

/* popover แก้ไขข้อความ — reuse กรอบ .ch-info-pop (components.css · position:fixed + .is-open) */
.ch-mx-editpop { max-width: min(92vw, 380px); }
.ch-mx-editpop .ch-info-pop-inner { width: 320px; max-width: 100%; padding: 11px 12px; }
.ch-mx-editpop-ta {
  width: 100%; box-sizing: border-box; min-height: 130px; max-height: 50vh;
  resize: vertical; padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--ch-line); background: var(--ch-surface-2);
  color: var(--ch-text); font-family: inherit; font-size: 13px; line-height: 1.55;
  outline: none;
}
.ch-mx-editpop-ta:focus { border-color: var(--ch-accent); }

/* ── s130: วันที่ (date column) จัดชิดซ้าย/ขวา/กลางไม่ได้ — fix ──
   flatpickr (altInput:true) สร้าง <input> ตัวใหม่ที่ "มองเห็น" โดย copy เฉพาะ class ของ
   source ไม่ copy inline style → `text-align:{{ align }}` ที่ template ตั้งบน source input
   หายไป (source ถูกซ่อน display:none). ซ้ำร้าย UA stylesheet reset text-align ของ <input>
   เป็น `start` (ไม่ inherit จาก td เหมือน element ทั่วไป) → วันที่ชิดซ้ายเสมอไม่ว่าตั้ง align
   อะไร (s128 alignment ใช้ไม่ได้กับ date).
   แก้: ใส่ marker class `.ch-cell-date` บน source date input ใน _matrix_cell.html — flatpickr
   copy class ไป altInput ให้ → กฎนี้จับ altInput แล้วบังคับ inherit text-align จาก td (ที่
   template ใส่ text-align ตาม align ไว้แล้ว) → วันที่จัดตามที่ผู้ใช้ตั้ง.
   ใช้ marker class (ไม่ใช่ `.ch-matrix td input`) เพราะ Progress Board ก็ render date cell
   ด้วย _matrix_cell.html แต่ตารางเป็น `.data-table` ไม่ใช่ `.ch-matrix` → marker class ครอบ
   ทั้ง 2 surface และ scope เป๊ะเฉพาะ date (ไม่แตะ input/select ชนิดอื่นที่มี inline ta อยู่แล้ว). */
.ch-cell-date { text-align: inherit; }

/* ── P8: progress bar ในเซลล์ NUMBER (config progress_bar) ──
   แถบบาง ๆ ใต้/แทนตัวเลข · width = ms_progress_pct (clamp 0-100 ที่ filter กัน injection). */
.ch-progress {
  height: 6px; width: 100%; margin-top: 3px;
  border-radius: 9999px; background: var(--ch-surface-3); overflow: hidden;
}
.ch-progress-fill {
  height: 100%; border-radius: 9999px;
  background: var(--ch-accent); transition: width .2s ease; min-width: 0;
}
/* P8: checkbox cell — ใช้สี accent ของระบบ */
.ch-cell-check { accent-color: var(--ch-accent); vertical-align: middle; }

/* ── P8: แถวสรุปท้ายคอลัมน์ (footer SUM/AVG/COUNT) — ติดล่าง pane เหมือน thead ติดบน ──
   matrix ใช้ internal-scroll pane (.ch-matrix-wrap max-height) → sticky bottom ทำงานในกล่อง.
   bg ทึบ (surface-2 ที่ inline) กัน tbody เลื่อนทะลุ · corner (sticky-l) z สูงสุด. */
.ch-matrix tfoot th, .ch-matrix tfoot td { position: sticky; bottom: 0; z-index: 3; }
.ch-matrix tfoot th.sticky-l { left: 0; z-index: 5; }  /* มุมซ้ายล่าง — เหนือ footer + freeze */

/* ── s129: สีของ option ใน DROPDOWN (.ch-opt-<key>) ───────────────────────────────
   โทน soft (โปร่งใส) เหมือน status badge — bg = token *-soft · text = token สีเข้ม ·
   border = สีเข้มจาง. ใช้ทั้ง (1) <select>/badge ในเซลล์ matrix (2) swatch ใน modal editor.
   reuse token *-soft (light+dark มีครบใน input.css) · เพิ่ม sky ที่นี่ (plain CSS ไม่ต้อง make css).
   key มาจาก MILESTONE_OPTION_COLORS (models.py) ที่ whitelist กัน class injection. */
:root { --ch-sky: #0369a1; --ch-sky-soft: #f0f9ff; }
:root[data-theme="dark"] { --ch-sky: #38bdf8; --ch-sky-soft: rgba(3,105,161,.22); }

.ch-opt-neutral { background: var(--ch-surface-3); color: var(--ch-text-4);
  border-color: var(--ch-line); }
.ch-opt-rose    { background: var(--ch-rose-soft);    color: var(--ch-rose);
  border-color: color-mix(in srgb, var(--ch-rose) 22%, transparent); }
.ch-opt-orange  { background: var(--ch-orange-soft);  color: var(--ch-orange);
  border-color: color-mix(in srgb, var(--ch-orange) 22%, transparent); }
.ch-opt-amber   { background: var(--ch-amber-soft);   color: var(--ch-amber);
  border-color: color-mix(in srgb, var(--ch-amber) 22%, transparent); }
.ch-opt-emerald { background: var(--ch-emerald-soft); color: var(--ch-emerald);
  border-color: color-mix(in srgb, var(--ch-emerald) 22%, transparent); }
.ch-opt-sky     { background: var(--ch-sky-soft);     color: var(--ch-sky);
  border-color: color-mix(in srgb, var(--ch-sky) 22%, transparent); }
.ch-opt-accent  { background: var(--ch-accent-soft);  color: var(--ch-accent);
  border-color: color-mix(in srgb, var(--ch-accent) 22%, transparent); }
.ch-opt-violet  { background: var(--ch-violet-soft);  color: var(--ch-violet);
  border-color: color-mix(in srgb, var(--ch-violet) 22%, transparent); }

/* swatch สีใน modal editor — วงกลมสีเล็ก กดเลือก (.is-sel = วงแหวนรอบ) */
.ms-dd-sw { width: 20px; height: 20px; border-radius: 9999px; border: 1px solid var(--ch-line);
  cursor: pointer; padding: 0; flex: none; box-sizing: border-box; }
.ms-dd-sw.is-sel { box-shadow: 0 0 0 2px var(--ch-surface), 0 0 0 4px var(--ch-accent); }

/* scroll-shadow pseudo ของ .table-scroll (::before/::after) เป็น inline sticky → สร้าง
   line-box ดัน table ลง ~21px = ช่องว่างเหนือหัวคอลัมน์. ปิดสำหรับ xl-scroll (มี
   freeze-edge shadow ที่คอลัมน์แรกเป็น cue แนวนอนแทนแล้ว) → หัวคอลัมน์ชนขอบบน pane พอดี */
.table-scroll.xl-scroll::before,
.table-scroll.xl-scroll::after { display: none; }

/* กล่อง scroll เดียว — ยึดทั้ง 2 แกน. ใช้ max-height (ไม่ใช่ height) → ตารางสั้น
   ไม่เกิด scroll, ตารางยาวได้กล่อง scroll พร้อม header/footer ปักหมุด.
   max-height ตรงนี้เป็นแค่ fallback ก่อน JS ทำงาน (vh = รองรับทุก browser) —
   ค่าจริงคำนวณด้วย JS `fitXlScrollHeight()` (วัดพื้นที่เหลือใต้หัวตาราง → fit จอเป๊ะ
   ทุกหน้า ไม่ว่าเหนือตารางจะมีของสูงเท่าไหร่). */
.table-scroll.xl-scroll {
  overflow: auto;
  max-height: calc(100vh - 13rem);
}

/* ── Header ติดบน ── (thead th มีพื้นหลังทึบจาก .data-table อยู่แล้ว)
   ⚠️ ใช้ `.data-table.xltable` (specificity 0,2,2) เพื่อชนะ rule เดิมใน input.css
   `.data-table thead th[data-filter-key]{position:relative}` (0,2,2) — ไม่งั้นหัวคอลัมน์
   ที่กรองได้ (มี ▾) จะถูกตั้ง relative ทับ → ไม่ติด ("freeze หัว column ไม่ครบ") */
.data-table.xltable thead th {
  position: sticky;
  top: 0;
  z-index: 3;
}
/* sticky header ต้อง "ทึบ" เสมอ — บาง header (คอลัมน์เงิน) ใช้ inline bg แบบโปร่ง
   (rose-soft/accent-soft = rgba ใน dark mode) → พอ sticky แล้วค่าจากแถวที่ scroll
   ทะลุขึ้นมาเห็นผ่าน header (bug นายเจอ "60,000.00" โผล่ใต้ "จำนวนเงิน"). บังคับ bg
   ทึบ override inline (!important เพราะ inline specificity สูงสุด) · คง color เดิมไว้
   (text ยังไฮไลต์สีคอลัมน์เงินได้ตามปกติ) */
.data-table.xltable thead th { background-color: var(--ch-surface-2) !important; }

/* ── แถบสรุปท้ายตาราง list (s114) ── "แสดง X จาก Y รายการ · รวม Z"
   วางใต้ pane (sibling หลัง .table-scroll) · ตรึงล่างสุด (sticky bottom) เป็นแถบ footer
   ชัดเจน (surface-3 + เส้นบนเข้ม) · หน้า list ที่ล็อก main จะตัด padding ล่างออก (main.xl-locked)
   ให้แถบแนบขอบล่างจอพอดี */
.ch-list-summary {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.15rem 0.95rem;
  line-height: 1.15;
  font-size: 0.8rem;
  color: var(--ch-text-2);
  border-top: 1px solid var(--ch-line-strong);
  background: var(--ch-surface-3);
  white-space: nowrap;
  overflow-x: auto;
}
.ch-list-summary b { color: var(--ch-text); font-weight: 600; }

/* หน้า list ที่ล็อก (ตารางเดียวเต็มหน้า) → ตัด padding ล่างของ main ออก
   เพื่อให้แถบสรุปแนบขอบล่างจอพอดี (ไม่ลอยเหนือขอบ ~56px) */
main.xl-locked { padding-bottom: 0; }

/* ── Footer (แถวรวม) ติดล่าง ── ทำงานเฉพาะตารางที่มี <tfoot> จริง */
.xltable tfoot td {
  position: sticky;
  bottom: 0;
  z-index: 3;
}

/* ── สลับสีแถว (zebra) ── ใช้ token → ใช้ได้ทั้ง light/dark.
   แถวที่ระบายสีเองด้วย inline style (เช่น เกินกำหนด/สต็อกต่ำ = rose) จะคงสีไว้
   เพราะ inline style มี specificity สูงกว่ากฎพวกนี้. */
.xltable tbody tr { background: var(--ch-surface); }
.xltable tbody tr:nth-child(even) { background: var(--ch-surface-2); }
.xltable tbody tr:hover { background: var(--ch-surface-3); }
/* hover แบบทึบใน dark mode (override กฎ hover แบบโปร่งใน input.css เพื่อให้
   freeze cell ที่ inherit สีแถวยังทึบ ไม่ทะลุ) */
:root[data-theme="dark"] .xltable tbody tr:hover { background: var(--ch-surface-3); }

/* ── Freeze คอลัมน์แรก ── ติดซ้ายของกล่อง scroll */
.xltable thead th:first-child,
.xltable tbody td:first-child,
.xltable tfoot td:first-child { position: sticky; left: 0; }
.xltable thead th:first-child { z-index: 4; }  /* มุมซ้ายบน — เหนือ header */
.xltable tfoot td:first-child { z-index: 4; }  /* มุมซ้ายล่าง — เหนือ footer */
.xltable tbody td:first-child { z-index: 2; }  /* เหนือ cell ปกติ ใต้ header */
/* freeze cell ของ body ลอยเหนือเนื้อหาที่ scroll ผ่าน → ต้องทึบ. `inherit`
   ดึงสีพื้นปัจจุบันของแถว (zebra / hover / สี inline สถานะ) มาตรงเป๊ะ. */
.xltable tbody td:first-child { background: inherit; }

/* เส้นขอบ freeze — เงาขวานุ่มๆ โชว์ "เฉพาะตอน scroll แนวนอน" เท่านั้น
   (เหมือน Excel/Sheets; ตารางแคบที่ไม่ scroll จะสะอาด ไม่มีเส้น). */
.table-scroll.xl-scroll[data-xscroll] .xltable thead th:first-child,
.table-scroll.xl-scroll[data-xscroll] .xltable tbody td:first-child,
.table-scroll.xl-scroll[data-xscroll] .xltable tfoot td:first-child {
  box-shadow: 6px 0 8px -6px rgba(0, 0, 0, .22);
}
:root[data-theme="dark"] .table-scroll.xl-scroll[data-xscroll] .xltable thead th:first-child,
:root[data-theme="dark"] .table-scroll.xl-scroll[data-xscroll] .xltable tbody td:first-child,
:root[data-theme="dark"] .table-scroll.xl-scroll[data-xscroll] .xltable tfoot td:first-child {
  box-shadow: 6px 0 8px -6px rgba(0, 0, 0, .55);
}

/* ── ปุ่มไอคอน "กรอง" บนหัวคอลัมน์ matrix (แทนปุ่ม "กรอง" เต็มแถวเดิม — ประหยัดพื้นที่) ── */
.ch-filter-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: 0; border-radius: 5px;
  background: none; color: var(--ch-text-4); cursor: pointer; line-height: 1;
  flex: none;
}
.ch-filter-ico:hover { color: var(--ch-text-2); background: var(--ch-surface-3); }
.ch-filter-ico.is-active { color: var(--ch-accent); background: var(--ch-accent-soft); }
.ch-filter-ico svg { width: 14px; height: 14px; display: block; }
