/* ---------------------------------------------------------------------------
   BIZPLUS design tokens (TVP web/app standard) — see ~/.claude/skills/bizplus-ui
   --------------------------------------------------------------------------- */
:root {
  --brand-purple: #34008d; --brand-purple-dark: #1d005b; --brand-purple-light: #532bc7;
  --brand-yellow: #f9d100; --brand-yellow-dark: #e1b100; --brand-gray: #5d5d5d;
  --navbar-from: #010009; --navbar-via: #09002c;
  --background: #fbfbfe; --foreground: #0a0a13;
  --card: #fff; --card-foreground: #0a0a13;
  --popover: #fff; --popover-foreground: #0a0a13;
  --primary: #34008d; --primary-foreground: #fcfcfc;
  --secondary: #f3f3f7; --secondary-foreground: #191924;
  --muted: #f3f3f7; --muted-foreground: #5d5d5d;
  --accent: #f1f1f7; --accent-foreground: #191924;
  --destructive: #e62c2c; --destructive-foreground: #fcfcfc;
  --warning: #f59300; --warning-foreground: #fff;
  --success: #00ab6d; --success-foreground: #fff;
  --border: #e4e4e8; --input: #e4e4e8; --ring: #34008d;
  --chart-1: #532bc7; --chart-2: #e8b700; --chart-3: #0074c9;
  --chart-4: #00ab6d; --chart-5: #c841a5;
  --status-reviewed: #0f766e;
  --badge-success-bg: #e3f8ef; --badge-success-fg: #007a50;
  --badge-info-bg: #e5f2fc; --badge-info-fg: #0074c9;
  --badge-warning-bg: #fff4e0; --badge-warning-fg: #b35f00;
  --badge-destructive-bg: #fde7e7; --badge-destructive-fg: #c21e1e;
  --badge-purple-bg: #efe9fb; --badge-purple-fg: #532bc7;
  --badge-muted-bg: #f1f1f7; --badge-muted-fg: #5d5d5d;
  --badge-teal-bg: #e6f6f4; --badge-teal-fg: #0f766e;
  --radius: .625rem;
  --sidebar: #11101a; --sidebar-foreground: #c4c4c4;
  --sidebar-primary: #f9d100; --sidebar-primary-foreground: #060606;
  --sidebar-accent: #23232e; --sidebar-accent-foreground: #f8f8f8;
  --sidebar-border: #ffffff14; --sidebar-ring: #f9d100;
  --sidebar-active: var(--brand-yellow);
}
.dark {
  --background: #05050d; --foreground: #f1f1f5;
  --card: #0e0d1c; --card-foreground: #f1f1f5;
  --popover: #0e0d1c; --popover-foreground: #f1f1f5;
  --primary: #6c50e9; --primary-foreground: #fcfcfc;
  --secondary: #191928; --secondary-foreground: #f1f1f5;
  --muted: #191928; --muted-foreground: #8e8e95;
  --accent: #191928; --accent-foreground: #f1f1f5;
  --destructive: #ff5149; --destructive-foreground: #0a0a13;
  --warning: #fc9f30; --warning-foreground: #0a0a13;
  --success: #00c47f; --success-foreground: #0a0a13;
  --border: #ffffff14; --input: #ffffff1f; --ring: #6c50e9;
  --chart-1: #7960fb; --chart-2: #fac700; --chart-3: #0f92f7;
  --chart-4: #00c47f; --chart-5: #da52b5;
  --status-reviewed: #2dd4bf;
  --badge-success-bg: #0b2e22; --badge-success-fg: #00c47f;
  --badge-info-bg: #0b2a42; --badge-info-fg: #0f92f7;
  --badge-warning-bg: #3a2504; --badge-warning-fg: #fc9f30;
  --badge-destructive-bg: #3a1414; --badge-destructive-fg: #ff5149;
  --badge-purple-bg: #211a3d; --badge-purple-fg: #9b86f5;
  --badge-muted-bg: #191928; --badge-muted-fg: #8e8e95;
  --badge-teal-bg: #0b2e2c; --badge-teal-fg: #2dd4bf;
}

body { font-family: "Noto Sans Thai", ui-sans-serif, system-ui, sans-serif; }
.font-mono, .tabular-nums { font-family: "IBM Plex Mono", ui-monospace, monospace; }

.badge-success { background: var(--badge-success-bg); color: var(--badge-success-fg); }
.badge-info { background: var(--badge-info-bg); color: var(--badge-info-fg); }
.badge-warning { background: var(--badge-warning-bg); color: var(--badge-warning-fg); }
.badge-destructive { background: var(--badge-destructive-bg); color: var(--badge-destructive-fg); }
.badge-purple { background: var(--badge-purple-bg); color: var(--badge-purple-fg); }
.badge-muted { background: var(--badge-muted-bg); color: var(--badge-muted-fg); }
.badge-teal { background: var(--badge-teal-bg); color: var(--badge-teal-fg); }

[x-cloak] { display: none !important; }

/* ช่องค้นหาในระบบเตรียมปุ่มล้างของตัวเองไว้แล้ว (จัดสไตล์ได้ + ขึ้นเหมือนกันทุกเบราว์เซอร์)
   ถ้าไม่ปิดปุ่มของ WebKit จะเห็นกากบาทซ้อนกันสองอันบน Chrome/Edge */
input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.settings-table thead th {
    background-color: var(--muted);
}

/* หัวตารางค้างไว้ตอนเลื่อนหน้าจอ - ตารางที่ยาวหลายสิบแถว (เช่น Task Template) พอเลื่อนลงไป
   หัวตารางหลุดจอ แล้วไม่รู้ว่าคอลัมน์ไหนคืออะไร
   - top เว้นความสูงแถบบนของหน้า (header h-14 = 3.5rem) ที่ sticky อยู่ก่อนแล้ว ไม่งั้นหัวตาราง
     จะไปมุดอยู่ใต้แถบบน
   - z-index ต้องต่ำกว่าแถบบน (z-30) เพื่อให้เนื้อหาเลื่อนลอดใต้แถบบนไปตามปกติ
   - ต้องมีพื้นหลังทึบ (ได้จาก .settings-table thead th ข้างบน) ไม่งั้นแถวข้างล่างจะทะลุขึ้นมา
   ใช้แบบ opt-in ไม่ใช่ยัดให้ .settings-table ทุกตัว เพราะมีตารางซ้อนอยู่ในแถวที่กางออก
   (ตาราง sub-task) ซึ่งถ้าหัวมันค้างด้วยจะดูเพี้ยน */
.table-sticky-head thead th {
    position: sticky;
    top: 3.5rem;
    /* แค่ต้องอยู่เหนือแถวในตาราง (ซึ่งไม่ได้ตั้ง z-index) จึงใช้เลขต่ำๆ พอ - ตั้งสูงกว่านี้จะไปบัง
       พวก dropdown/popover ในแถว (z-10) และแถบบนของหน้า (z-30) ที่ต้องอยู่เหนือกว่าเสมอ */
    z-index: 2;
    /* ต้องทึบ ไม่งั้นแถวข้างล่างจะทะลุขึ้นมาซ้อนหัวตารางตอนเลื่อน - ตารางส่วนใหญ่ในระบบ
       หัวตารางไม่มีพื้นหลังของตัวเอง (โปร่งใสทับบนการ์ด) */
    background-color: var(--card);
    /* Tailwind preflight ตั้ง border-collapse: collapse ให้ทุก table ซึ่งทำให้เส้นขอบของช่องที่
       sticky หายตอนเลื่อนในบางเบราว์เซอร์ - วาดเส้นใต้ด้วย inset shadow แทนจะไม่หาย */
    box-shadow: inset 0 -1px 0 var(--border);
}
/* ตาราง settings ใช้สีหัวตารางของมันเอง (เทา) ไม่ใช่สีการ์ด - ต้องระบุสองคลาสเพื่อให้ชนะกฎข้างบน
   ที่มี specificity เท่ากันแต่อยู่ทีหลัง */
.settings-table.table-sticky-head thead th {
    background-color: var(--muted);
}

/* กล่องที่ครอบตาราง sticky - ต้องใช้กับ .table-sticky-head เสมอ
   ใช้ clip ไม่ใช่ hidden: hidden ทำให้กล่องกลายเป็น scroll container แล้ว sticky ข้างในจะไป
   ยึดกับกล่อง (ซึ่งไม่มีวันเลื่อน) แทนที่จะยึดกับจอ = หัวตารางไม่ค้าง ส่วน clip ตัดมุมให้เหมือนกัน
   แต่ไม่นับเป็น scroll container จึงได้ทั้งมุมมนและหัวตารางที่ค้างจริง */
.table-sticky-wrap {
    overflow: clip;
}

.gantt .bar-wrapper .bar { stroke-width: 0; }
.bar-wrapper.gantt-status-not_started .bar { fill: var(--muted-foreground) !important; opacity: .55; }
.bar-wrapper.gantt-status-waiting_predecessor .bar { fill: var(--chart-1) !important; }
.bar-wrapper.gantt-status-in_progress .bar { fill: var(--chart-3) !important; }
.bar-wrapper.gantt-status-completed .bar { fill: var(--chart-4) !important; }
.bar-wrapper.gantt-status-reviewed .bar { fill: var(--status-reviewed) !important; }
.bar-wrapper.gantt-status-delayed .bar { fill: var(--destructive) !important; }
.bar-wrapper.gantt-status-blocked .bar { fill: var(--warning) !important; }

/* Dependency arrows: kept subdued at rest (frappe-gantt's default is a heavy solid stroke that
   turns a real closing-period Gantt -- dozens of converging finish-to-start dependencies bunched
   into a few day-columns -- into unreadable overlapping spaghetti). Hovering or clicking a bar
   brightens just that task's own predecessor/successor chain (.gantt-flow-active, set by
   highlightFlow/computeFlow in dashboard.html) while unrelated arrows fade to near-invisible
   instead of competing for attention. !important beats frappe-gantt.css on tied selector
   specificity, which otherwise wins ties since it loads after app.css (see the dark-mode
   .bar-label.big comment below for the same load-order issue). */
.gantt .arrow path { stroke: var(--muted-foreground) !important; stroke-width: 1.25px !important; opacity: .38; }
.gantt .arrow path.gantt-flow-active { stroke: var(--primary) !important; stroke-width: 2.25px !important; opacity: 1 !important; }
.bar-wrapper.gantt-flow-root .bar { stroke: var(--primary) !important; stroke-width: 2px !important; }

/* dependency-flow highlight: dim everything not connected to the hovered/clicked task */
.bar-wrapper, g.arrow > path { transition: opacity 0.15s ease, stroke 0.15s ease, stroke-width 0.15s ease; }
.bar-wrapper.gantt-dimmed { opacity: 0.3 !important; }
g.arrow > path.gantt-dimmed { opacity: 0.06 !important; }

/* Belt-and-suspenders alongside custom_popup_html: () => '' in dashboard.html: frappe-gantt's
   built-in click tooltip can't track page-level scroll (see comment there), so make sure its
   wrapper never renders even if a future frappe-gantt version stops treating an empty string
   as "no popup". */
.popup-wrapper { display: none !important; }

/* frappe-gantt renders its grid/text with hardcoded light-theme fills; repoint them in dark mode */
.dark .gantt .grid-background { fill: var(--card); }
.dark .gantt .grid-row { fill: var(--card); }
.dark .gantt .grid-row:nth-child(even) { fill: var(--muted); }
.dark .gantt .row-line { stroke: var(--border); }
.dark .gantt .tick { stroke: var(--border); }
.dark .gantt .grid-header { fill: var(--card); stroke: var(--border); }
.dark .gantt .upper-text, .dark .gantt .lower-text { fill: var(--foreground); }
.dark .gantt .bar-label { fill: var(--foreground); }
/* frappe-gantt hardcodes fill:#555 on labels that don't fit inside their bar (rendered outside
   it instead, class "big") -- same specificity as the rule above but frappe-gantt.css loads
   after app.css, so it wins the cascade tie without the extra class in this selector */
.dark .gantt .bar-label.big { fill: var(--foreground); }
/* frappe-gantt sets font-weight:lighter (resolves to 100, a weight we never load for Noto Sans
   Thai) on all chart text -- renders as a barely-there synthesized thin face, worse against a
   dark background than a light one. */
.dark .gantt .bar-label, .dark .gantt .upper-text, .dark .gantt .lower-text { font-weight: 500; }
.dark .gantt .today-highlight { fill: var(--warning); opacity: .15; }

/* Header breadcrumb always starts with a "Closing Tracker >" root segment (every page's own
   {% block breadcrumb %} repeats that same span+svg pair before its own page name) -- on a phone
   -width header there isn't room for it next to the hamburger/theme/avatar icons, so `truncate`
   clips it mid-icon into an unreadable sliver. Drop just that redundant root segment on narrow
   screens rather than editing every page's breadcrumb block individually. */
@media (max-width: 640px) {
  header nav.text-xs > span:first-child,
  header nav.text-xs > svg:first-of-type {
    display: none;
  }
}
