/* style.css — the design system.
 *
 * :root is the SINGLE source of truth for colour: kit.js resolves the chart palette from these
 * custom properties at boot (see config.js `colorVars`), so JS and CSS can never disagree.
 * To re-brand a new dashboard you change the :root block and its [data-theme="dark"] twin — nothing
 * else in this file, and nothing in kit.js, hardcodes a colour.
 */
@font-face {
  font-family: "Kanit";
  src: url("/assets/fonts/Kanit-Light.ttf") format("truetype");
  font-weight: normal; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Kanit";
  src: url("/assets/fonts/Kanit-Bold.ttf") format("truetype");
  font-weight: bold; font-style: normal; font-display: swap;
}

:root {
  /* brand ramp */
  --brand: #2A6EBB;
  --brand-deep: #143C6B;
  --brand-hero: #1B5290;
  --brand-mid: #5C9BD6;
  --brand-soft: #A8C9EA;
  --brand-pale: #E7F0FA;
  /* categorical accents */
  --green: #4E9C6F;
  --mint: #9FD3B4;
  --teal: #2E9AA5;
  --coral: #E97F76;
  --plum: #7B5EA7;
  --gold: #D9A441;
  --grey: #8F8B8B;
  --seafoam: #CDE6DA;
  /* the activity-progress ramp: green → yellow → orange → red, then two greys for the
     "nothing to report yet" states. Named by hue because that is how they are specified. */
  --yellow: #E8B93E;
  --orange: #ED7D31;
  --red: #D64545;
  --grey-light: #CFCFD4;
  --accent: #F26D21;            /* underline / focus accent */
  /* Fixed identity colours for the two breakdown dimensions. Supplied by the programme, so they are
     the SAME in light and dark (no [data-theme="dark"] twin below) — a PMU must not change colour
     when the reader flips the theme. DASH.keyColors maps each PMU / กลุ่มผลิตภัณฑ์ onto one of these. */
  --pmu-tilsna: #82BB8D;
  --pmu-nia: #2D2A4A;
  --pmu-hsri: #354EA0;
  --grp-stroke: #00B050;        /* กลุ่มโรคหลอดเลือดสมอง */
  --grp-cell: #CC99FF;          /* ด้านเซลล์ภูมิคุ้มกันบำบัด */
  --grp-ai: #FF6161;            /* AI ทางการแพทย์ */
  --grp-other: #D4D3DD;         /* กลุ่มอื่น ๆ */
  /* semantic states */
  --ok: #2F7A4D;
  --warn: #8A6A08;
  --bad: #C0392B;
  --idle: #6E7A80;
  /* surfaces + ink */
  --ink: #1c1c1c;
  --ink-soft: #3a3a3a;
  --muted: #6e6e6e;
  --bg: #f4f4f4;
  --line: #e4e4e4;
  --card: #ffffff;
  --surface-2: #fbfcfe;
  --zebra: #f4f7fb;
  --th-bg: #2F79C4;
  --th-text: #ffffff;
  --shadow: rgba(0,0,0,.05);
  --tip-bg: #ffffff;
  --tip-text: #333333;
  /* chart chrome — read by kit.js, never used directly in this file */
  --chart-label: #143C6B;
  --chart-label-deep: #143C6B;
  --chart-axis: #cbd5d8;
  --chart-split: #eef2f3;
  --chart-map-area: #eef3f7;
  --chart-map-border: #ffffff;
}

* { box-sizing: border-box; margin: 0; }
/* 18px root keeps Kanit at the intended optical size; kit.js overrides this per font-step */
html { font-size: 18px; }
/* Thai stacks vowel/tone marks above AND below the base glyph — 1.2 line-height makes wrapped
   lines collide. 1.5 body / 1.55 table is the minimum that reads cleanly. */
body { font-family: "Kanit", "Segoe UI", "Noto Sans Thai", Tahoma, sans-serif;
       background: var(--bg); color: var(--ink); line-height: 1.5; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 20px; }

/* ---------- header: white topbar + hero band ---------- */
.topbar { background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
.topbar-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px 18px; padding: 12px 20px 8px; flex-wrap: wrap; }
.topbar-nav { padding: 0 20px 3px; }
/* the brand doubles as the site-outline trigger, so it is a <button> styled back to plain text */
.brand { display: flex; flex-direction: column; line-height: 1.2; align-items: flex-start;
         font: inherit; background: none; border: 0; padding: 0; text-align: left; cursor: pointer;
         /* as a flex item a <button> neither wraps nor shrinks by default — restore both */
         white-space: normal; flex: 1 1 auto; min-width: 0; max-width: 100%; }
.brand-b { font-weight: bold; color: var(--brand-deep); font-size: calc(1.05rem + 6px); letter-spacing: .01em; }
.brand-l { color: var(--muted); font-size: calc(.74rem + 6px); margin-top: 1px;
           display: inline-flex; align-items: center; gap: 5px; }
.brand-caret { flex: 0 0 auto; transition: transform .18s ease; opacity: .8; }
.brand:hover .brand-b, .brand:hover .brand-l { color: var(--brand); }
.brand[aria-expanded="true"] .brand-caret { transform: rotate(180deg); }
.brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
/* Each tab pads 8px either side of its text so the active underline extends past the word. That
   padding also pushed the FIRST tab's text 8px right of the brand title above it, which the two
   share a .wrap gutter with. Pulling the row back by exactly that padding puts the first tab's
   text on the brand's left edge while every tab keeps identical geometry. */
nav { display: flex; gap: 2px; flex-wrap: wrap; margin-left: -8px; }
nav a { text-decoration: none; color: var(--brand); font-size: calc(.84rem + 6px); font-weight: 600;
        padding: 9px 8px 7px; border-bottom: 3px solid transparent; }
nav a:hover { color: var(--brand-deep); }
nav a.on { color: var(--brand-deep); border-bottom-color: var(--accent); }

/* hero gradient is pinned to literals: --brand-* flip for dark, but white hero text must stay
   readable in both themes, so the band itself never changes */
.hero { color: #fff; padding: 40px 0 44px; position: relative; overflow: hidden;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cg fill='rgba(255,255,255,0.28)'%3E%3Ccircle cx='10' cy='10' r='1.8'/%3E%3Ccircle cx='40' cy='10' r='1.8'/%3E%3Ccircle cx='70' cy='10' r='1.8'/%3E%3Ccircle cx='10' cy='40' r='1.8'/%3E%3Ccircle cx='40' cy='40' r='1.8'/%3E%3Ccircle cx='70' cy='40' r='1.8'/%3E%3Ccircle cx='10' cy='70' r='1.8'/%3E%3Ccircle cx='40' cy='70' r='1.8'/%3E%3Ccircle cx='70' cy='70' r='1.8'/%3E%3C/g%3E%3C/svg%3E") right 8% bottom -20px / 160px no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1400 260' preserveAspectRatio='none'%3E%3Cpath d='M0,200 C360,120 620,260 1400,150' stroke='rgba(255,255,255,0.14)' stroke-width='44' fill='none'/%3E%3Cpath d='M0,240 C420,170 760,290 1400,205' stroke='rgba(255,255,255,0.10)' stroke-width='70' fill='none'/%3E%3C/svg%3E") center bottom / 100% 100% no-repeat,
    linear-gradient(100deg, #143C6B 0%, #1B5290 55%, #2A6EBB 100%);
}
.hero h1 { font-size: 2.1rem; font-weight: bold; letter-spacing: .01em; }
.hero-sub { margin-top: 8px; font-size: .84rem; color: rgba(255,255,255,.85); }

/* ---------- sections + cards ---------- */
section { padding-top: 26px; }
.sec-t { font-size: 1.18rem; margin-bottom: 14px; color: var(--brand-deep); }
.sec-t::after { content: ""; display: block; width: 54px; height: 3px; background: var(--accent); margin-top: 6px; }
.sec-sub { color: var(--muted); font-weight: normal; font-size: .78em; margin-left: 8px; }

.card { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 4px;
        padding: 18px; box-shadow: 0 1px 3px var(--shadow); }
.card h3 { font-size: .95rem; margin-bottom: 8px; font-weight: 600; }
.card h4 { font-size: .9rem; font-weight: 600; color: var(--brand-deep); }
.t-unit { display: block; color: var(--muted); font-weight: normal; font-size: .86em; margin-top: 2px; }
/* unified N badge — same style + position on every figure. NEVER render this as an in-plot ECharts
   `graphic`: a graphic on a hidden chart throws during resize and freezes the page. */
.n-badge { position: absolute; top: 16px; right: 16px; z-index: 3;
  font-size: .92rem; font-weight: 700; color: var(--brand); background: var(--brand-pale);
  border-radius: 12px; padding: 3px 13px; white-space: nowrap; }
.n-badge:empty { display: none; }
.n-badge.inline { position: static; margin-left: auto; }
/* Excel download pill — same corner as .n-badge, which shifts left to make room via :has().
   Injected by kit.js setExport(), so it only appears on cards that actually have data to export. */
.dl-btn { position: absolute; top: 14px; right: 16px; z-index: 4;
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font: inherit; font-size: .78rem; font-weight: 700; line-height: 1;
  color: var(--brand-deep); background: var(--card); border: 1px solid var(--brand-soft);
  border-radius: 12px; padding: 5px 11px; }
.dl-btn:hover { background: var(--brand-pale); border-color: var(--brand-mid); }
.dl-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dl-btn[disabled] { opacity: .55; cursor: progress; }
.dl-btn.err { border-color: var(--bad); color: var(--bad); }
/* a figure with its own h4 carries the button on that heading instead of the card corner */
.dl-btn.inline { position: static; float: right; margin: -2px 0 0 10px; }
.card:has(> .dl-btn) .n-badge:not(.inline) { right: 104px; }
@media (max-width: 620px) { .dl-btn span { display: none; } .dl-btn { padding: 5px 8px; }
  .card:has(> .dl-btn) .n-badge:not(.inline) { right: 58px; } }
.mt { margin-top: 14px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.card.is-off { display: none; }

.chart { height: 300px; }
.chart.tall { height: 380px; }
.chart.xtall { height: 520px; }
.chart.gantt { height: 560px; }
.chart.huge { height: 700px; }

/* page sub-selector */
.subnav { margin-top: 24px; display: flex; gap: 2px; border-bottom: 2px solid var(--line); }
.subnav .pill { border: none; background: none; border-radius: 0; color: var(--muted);
  font-family: inherit; font-size: .95rem; font-weight: 600; padding: 9px 16px 8px; cursor: pointer;
  border-bottom: 3px solid transparent; margin-bottom: -2px; }
.subnav .pill:hover { color: var(--brand-deep); }
.subnav .pill.on { color: var(--brand-deep); border-bottom-color: var(--accent); background: none; }
.pills { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.pill { border: 1px solid var(--brand-mid); background: var(--card); color: var(--brand); font-family: inherit;
  font-size: .84rem; font-weight: 600; border-radius: 3px; padding: 6px 14px; cursor: pointer; }
.pill.on { background: var(--brand); border-color: var(--brand); color: #fff; }

/* ---------- hero value cards + KPI tiles ---------- */
.fund-hero { background: linear-gradient(100deg, #143C6B 0%, #2A6EBB 100%); color: #fff;
  border-radius: 4px; padding: 22px 30px; display: flex; align-items: baseline; gap: 22px; flex-wrap: wrap; }
.fund-hero.alt { background: linear-gradient(100deg, #1F5E4A 0%, #4E9C6F 100%); }
.hero-l { font-size: 1.05rem; font-weight: 600; opacity: .92; }
.hero-v { font-size: 2.3rem; font-weight: bold; }
.hero-v small { font-size: 1.05rem; font-weight: 600; margin-left: 8px; opacity: .92; }

/* ---------- วัตถุประสงค์และที่มา page ---------- */
/* the two programme goals: .fund-hero stacked instead of baseline-aligned, with a much larger figure */
.goal-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.fund-hero.goal { flex-direction: column; align-items: flex-start; gap: 10px; padding: 26px 30px; }
.fund-hero.goal .hero-v { font-size: 3.2rem; line-height: 1.1; letter-spacing: -.5px; }
.fund-hero.goal .hero-v small { display: block; margin: 2px 0 0; font-size: 1.15rem; opacity: .95; }
.fund-hero.goal .hero-l { font-size: .97rem; font-weight: 500; line-height: 1.6; opacity: .95; }
.goal-sub { color: var(--muted); font-size: .92rem; font-weight: 600; margin: -2px 0 14px; }
.goal-sub .adj { font-size: .82rem; font-weight: 400; opacity: .85; }

/* narrative prose blocks — the only long-form copy on the site */
.prose p { margin: 0 0 10px; line-height: 1.75; color: var(--ink-soft); }
.prose p:last-child { margin-bottom: 0; }
.prose ul { margin: 6px 0 0; padding-left: 1.15rem; }
.prose li { line-height: 1.75; color: var(--ink-soft); margin-bottom: 4px; }
.prose b { color: var(--brand-deep); }

/* the one sentence that carries the argument, set larger than the body copy around it */
.lede { font-size: 1.12rem; line-height: 1.7; color: var(--ink); font-weight: 500;
        border-left: 4px solid var(--accent); padding: 4px 0 4px 16px; margin-bottom: 14px; }
.lede b { color: var(--brand-deep); font-weight: bold; }
.lede .big { font-size: 1.9rem; font-weight: bold; line-height: 1; letter-spacing: -.5px; }
.lede .coral { color: var(--coral); }
.prose .aside { color: var(--muted); font-size: .92em; font-style: italic; }

/* the four reasons, as numbered cards rather than a bullet list */
.why-lead { font-weight: 600; color: var(--brand-deep) !important; margin-bottom: 12px !important; }
.why-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.why { position: relative; background: var(--surface-2); border: 1px solid var(--line);
       border-top: 3px solid var(--brand); border-radius: 6px; padding: 12px 14px 14px; }
.why-n { font-size: 1.5rem; font-weight: bold; color: var(--brand-soft); line-height: 1; margin-bottom: 6px; }
.why-t { font-size: .92rem; font-weight: bold; color: var(--brand-deep); line-height: 1.45; }
.why-s { font-size: .78rem; color: var(--muted); line-height: 1.55; margin-top: 4px; }
@media (max-width: 900px) { .why-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .why-grid { grid-template-columns: 1fr; } }

/* the import/export totals strip above the trade chart */
.trade-tot { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 16px 0 4px; }
.trade-tot.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* PMU budget tiles: the name leads, the figure takes that PMU's identity colour, and a top rule
   in the same colour ties the tile to its segment in the stacked bar underneath */
.pmu-tot { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 10px 0 16px; }
.pt { background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; }
.pt-k { font-size: .82rem; font-weight: bold; letter-spacing: .01em; margin-bottom: 2px; }
.pt-v { font-size: 1.5rem; font-weight: bold; line-height: 1.2; }
.pt-v .u { font-size: .74rem; font-weight: 600; color: var(--muted); }
.pt-l { font-size: .74rem; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.pt.all { background: var(--brand-pale); border-color: var(--brand-soft); }
.pt.all .pt-k, .pt.all .pt-v { color: var(--brand-deep); }
@media (max-width: 820px) { .pmu-tot { grid-template-columns: 1fr 1fr; } }
.trade-tot.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tt { background: var(--surface-2); border: 1px solid var(--line); border-radius: 4px; padding: 12px 16px; }
.tt-v { font-size: 1.6rem; font-weight: bold; color: var(--brand-deep); line-height: 1.2; }
.tt-v.imp { color: var(--coral); }
.tt-v.exp { color: var(--teal); }
.tt-v .u { font-size: .8rem; font-weight: 600; color: var(--muted); }

/* the "so what" half of a section heading, played up against the neutral first half */
.h4-em { color: var(--accent); font-weight: bold; }

/* Start-up milestone flow, drawn as one right-pointing arrow: the shaft is a clipped polygon so
   the head is part of the same shape rather than a separate triangle that can drift out of line. */
.flow { position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
        align-items: center; gap: 0; margin: 14px 0 4px; padding: 20px 64px 20px 24px; }
.flow::before { content: ""; position: absolute; inset: 12px 0 12px 0;
  background: linear-gradient(90deg, var(--brand-pale) 0%, var(--brand-mid) 100%);
  clip-path: polygon(0 22%, calc(100% - 52px) 22%, calc(100% - 52px) 0,
                     100% 50%, calc(100% - 52px) 100%, calc(100% - 52px) 78%, 0 78%); }
.fl-step { position: relative; text-align: center; padding: 0 6px; }
.fl-l { font-size: .84rem; font-weight: 600; color: var(--brand-deep); line-height: 1.4; margin-bottom: 8px; }
.fl-dot { width: 13px; height: 13px; border-radius: 50%; margin: 0 auto;
          border: 2px solid var(--card); box-shadow: 0 0 0 1px var(--line); }
.fl-dot.a { background: var(--brand); }
.fl-dot.b { background: var(--accent); }
.fl-w { font-size: .78rem; color: var(--muted); margin-top: 8px; line-height: 1.4; }

@media (max-width: 700px) {
  .flow { grid-auto-flow: row; grid-auto-columns: auto; gap: 14px; padding: 16px 20px; }
  .flow::before { inset: 0 auto 0 34px; width: 3px; clip-path: none; }
  .fl-step { text-align: left; padding-left: 30px; }
  .fl-dot { margin: 6px 0; }
}
.tt-l { font-size: .8rem; color: var(--muted); margin-top: 2px; line-height: 1.45; }

@media (max-width: 820px) {
  .goal-grid, .trade-tot { grid-template-columns: 1fr; }
  .fund-hero.goal .hero-v { font-size: 2.6rem; }
}

.kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; }
.kpi { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 4px;
  padding: 16px 18px; box-shadow: 0 1px 3px var(--shadow); border-top: 4px solid var(--brand); }
.kpi .v { font-size: 1.55rem; font-weight: bold; color: var(--brand-deep); line-height: 1.15; }
.kpi .v .u { font-size: .82rem; font-weight: 600; color: var(--muted); margin-left: 6px; }
.kpi .l { font-size: .88rem; font-weight: 600; color: var(--ink); margin-top: 4px; }
.kpi .kpi-sub { font-size: .72rem; color: var(--muted); margin-top: 4px; line-height: 1.3; }
@media (max-width: 820px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .kpis { grid-template-columns: 1fr; } }

/* ---------- tables ---------- */
/* No word-break:break-all anywhere — cells must break at native ICU Thai word boundaries. */
.tbl-scroll { overflow: auto; max-height: 380px; }
.tbl-scroll.xtall { max-height: 620px; }
.tbl-scroll.auto { max-height: none; }
table { width: 100%; border-collapse: collapse; font-size: .85rem; }
th { text-align: left; color: var(--th-text); background: var(--th-bg); font-weight: 600;
     padding: 7px 9px; position: sticky; top: 0; line-height: 1.5; }
td { padding: 6px 9px; border-bottom: 1px solid var(--line); vertical-align: top; line-height: 1.55; }
tbody tr:nth-child(even) td { background: var(--zebra); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.ctr, th.ctr { text-align: center; }
td.pre { white-space: pre-line; }
tfoot td, tr.tot td { font-weight: 700; background: var(--brand-pale) !important;
  color: var(--brand-deep); border-top: 2px solid var(--brand-mid); }
.k-tbl tbody tr:hover td { background: var(--brand-pale); }

/* master/detail table: a clickable summary row that expands sub-rows underneath */
.exp-tbl tbody.exp-grp .exp-detail { display: none; }
.exp-tbl tbody.exp-grp.open .exp-detail { display: table-row; }
.exp-tbl tr.exp-row { cursor: pointer; }
.exp-tbl tr.exp-row:hover td { background: var(--brand-pale); }
.exp-tbl tr.exp-row td:first-child { font-weight: 600; color: var(--brand-deep); }
.exp-caret { display: inline-block; width: 1.1em; color: var(--brand-deep); }
.exp-tbl .exp-detail > td { padding: 0 0 6px 22px; background: var(--zebra); }
.exp-sub { width: 100%; }
.exp-sub th { background: transparent; color: var(--muted); font-weight: 600; font-size: .8rem; position: static; }
.exp-sub td { border-bottom: 1px dashed var(--line); }

/* ---------- filters + pickers ---------- */
.pick { font-family: inherit; font-size: .92rem; padding: 8px 12px; border: 1px solid var(--brand-mid);
  border-radius: 3px; min-width: 320px; max-width: 100%; color: var(--ink); background: var(--card); }
.pick.sm { min-width: 0; max-width: 48%; padding: 6px 10px; font-size: .84rem; }
.pick-l { font-size: .88rem; font-weight: 600; margin-right: 10px; }
.filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.filters .pick.sm { max-width: none; }
.filters .f-l { font-size: .86rem; font-weight: 600; color: var(--brand-deep); }
.mi-head { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin: 2px 0 6px; }
.mi-head .f-l { font-size: .86rem; font-weight: 600; color: var(--brand-deep); }

/* multi-select chip picker (goal page) — toggleable, never allowed to reach an empty selection */
.chip-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
.chip-pick .f-l { font-size: .86rem; font-weight: 600; color: var(--brand-deep); }
.chip-pick .cp { font: inherit; font-size: .82rem; cursor: pointer; padding: 5px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink-soft); line-height: 1.4; }
.chip-pick .cp:hover { border-color: var(--brand-mid); color: var(--brand-deep); }
.chip-pick .cp.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.chip-pick .cp.all { background: transparent; border-style: dashed; color: var(--muted); }
.chip-pick .cp.all:hover { color: var(--brand-deep); border-color: var(--brand-mid); }

/* tick-chip filter groups (filterBar) — several values on at once */
.fchips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fchips .fc { font: inherit; font-size: .8rem; cursor: pointer; padding: 4px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink-soft); line-height: 1.4;
  display: inline-flex; align-items: center; gap: 5px; }
.fchips .fc:hover { border-color: var(--brand-mid); color: var(--brand-deep); }
.fchips .fc.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.fchips .fc .tick { display: inline-block; width: .72em; font-size: .82em; line-height: 1; }
.fchips .fc.all { background: transparent; border-style: dashed; color: var(--muted); }
.fchips .fc.all:hover { color: var(--brand-deep); border-color: var(--brand-mid); }
/* single-select group reads as a segmented control rather than tick boxes */
.fchips.single .fc.on { background: var(--brand-deep); border-color: var(--brand-deep); }

/* the section title + picker freeze to the top of the viewport on the per-project page.
   kit.js measures .sec-sticky .sec-t into --sect-h. */
.sec-sticky .sec-t { position: sticky; top: 0; z-index: 26;
  margin: 0 -20px 0; padding: 14px 20px 10px; background: var(--brand-pale);
  border-bottom: 1px solid var(--brand-mid); }
.sec-sticky .sec-t::after { margin-top: 8px; }
.pick-bar { position: sticky; top: var(--sect-h, 52px); z-index: 25;
  margin: 0 -20px; padding: 13px 20px; border-radius: 0;
  border: 0; border-bottom: 1px solid var(--brand-mid);
  background: var(--brand-pale); box-shadow: 0 6px 16px -8px rgba(0,0,0,.22);
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.pick-bar .pick { min-width: 280px; }

/* ---------- chips + status ---------- */
.chip { display: inline-block; border-radius: 10px; padding: 2px 9px; font-size: .72rem;
        font-weight: 700; white-space: nowrap; }
.chip-ok   { background: #E4F2E9; color: var(--ok); }
.chip-part { background: #FDF5DB; color: var(--warn); }
.chip-none { background: #ECEFF1; color: var(--idle); }
.chip-info { background: var(--brand-pale); color: var(--brand-deep); }
.chip-bad  { background: #FBE7E4; color: var(--bad); }
/* project status — one class per config.js `statuses` entry */
.st-run  { background: #E7EDF6; color: #2F5B8C; }
.st-done { background: #E4F2E9; color: var(--ok); }
.st-wait { background: #FDF5DB; color: var(--warn); }
.st-stop { background: #FBE7E4; color: var(--bad); }
.st-na   { background: #ECEFF1; color: var(--idle); }
/* activity progress — one class per config.js `activityStatuses` entry, plus activityStatusNone.
   Tinted backgrounds of the same ramp the charts use (green · yellow · orange · red · light grey ·
   grey), so a chip and its bar segment read as the same thing.
   .as-none is the matrix's "no such activity" cell, so it is deliberately the faintest of the set. */
.as-done { background: #E4F2E9; color: var(--ok); }
.as-run  { background: #FBF0D4; color: #8A6A08; }
.as-late { background: #FDEBDD; color: #B35415; }
.as-wait { background: #FAE2E2; color: #A32E2E; }
.as-soon { background: #F0F0F3; color: #6E6E78; }
.as-na   { background: #ECEFF1; color: var(--idle); }
.as-none { background: transparent; color: var(--idle); opacity: .38; font-weight: 400; }

/* progress bar used for target achievement */
.pbar { height: 8px; background: #e8eef4; border-radius: 4px; overflow: hidden; margin-bottom: 3px; min-width: 90px; }
.pfill { height: 100%; background: var(--green); border-radius: 4px; }
.pfill.part { background: var(--gold); }
.pfill.none { background: #cfd6db; }
.ppct { font-size: .78rem; font-weight: 700; color: var(--ink); margin-bottom: 3px; }

/* big number strip under a gauge */
/* One equal column per stat, so each figure sits directly under its own gauge — the gauges are
   centred at 1/2n, 3/2n … of the chart width, which is exactly where equal grid columns centre. */
.gauge-stats { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 20px; margin: 4px 0 2px; }
.gauge-stats .gs { text-align: center; min-width: 0; }
.gauge-stats .gs .gv { font-size: 1.5rem; font-weight: bold; color: var(--brand-deep); }
.gauge-stats .gs .gv .u { font-size: .8rem; font-weight: 600; color: var(--muted); margin-left: 5px; }
.gauge-stats .gs .gl { font-size: .84rem; color: var(--muted); margin-top: 2px; }
.gauge-stats .gs.alt .gv { color: var(--green); }
/* Set by app.js when it stacks the gauges one per row — the figures must follow, or column 2 of the
   text would sit under gauge 1. A class rather than a media query because the chart decides from its
   CONTAINER width: a viewport breakpoint would disagree with it in the band where the card is already
   narrow but the window is not. */
.gauge-stats.stacked { grid-auto-flow: row; gap: 14px; }

/* a titled sub-figure inside a card — tinted panel so two stacked charts read as separate figures */
.subfig { background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px;
          padding: 14px 16px 6px; margin-top: 14px; }
.subfig > h4 { margin-bottom: 6px; }
.subfig .chart { height: 340px; }

/* three small target-vs-actual charts side by side on the project page */
.tri-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.tri { background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px 8px; }
.tri > h4 { font-size: .88rem; margin-bottom: 4px; }
.tri .chart { height: 250px; }
.tri-note { border-top: 0; padding-top: 2px; margin-top: 0; font-style: italic; }
.tri-empty { display: flex; align-items: center; justify-content: center; height: 250px;
             text-align: center; color: var(--muted); font-size: .82rem; line-height: 1.6; padding: 0 10px; }
@media (max-width: 900px) { .tri-grid { grid-template-columns: 1fr; } }

/* ---------- per-project info block ---------- */
.proj-info { display: flex; flex-direction: column; gap: 12px; }
.pi-row { display: flex; gap: 12px; flex-wrap: wrap; }
.pi-row .pi { flex: 1 1 0; min-width: 180px; }
.pi { background: var(--surface-2); border: 1px solid var(--line); border-radius: 4px; padding: 12px 14px; }
.pi .l { font-size: .76rem; color: var(--muted); }
.pi .v { font-size: .95rem; font-weight: 600; margin-top: 3px; line-height: 1.4; }
.pi.wide { flex-basis: 100%; }
.pi .v.long { font-weight: 400; font-size: .88rem; }

/* clickable project references anywhere on the site */
.proj-link { color: var(--brand); text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.proj-link:hover { color: var(--brand-deep); text-decoration-style: solid; }

.note { color: var(--muted); font-size: .8rem; margin-top: 8px; line-height: 1.5;
        border-top: 1px dashed var(--line); padding-top: 7px; }
.note.pre { white-space: pre-line; }
.sub-block { margin-top: 18px; padding-top: 14px; border-top: 2px solid var(--line); }

/* hover tooltip (kit.js `data-tip` / `data-tip-html`) */
#hoverTip { position: fixed; display: none; z-index: 999; max-width: 520px; pointer-events: none;
  background: var(--tip-bg); border: 1px solid var(--line); border-radius: 4px; box-shadow: 0 3px 14px rgba(0,0,0,.18);
  padding: 10px 14px; font-size: .82rem; line-height: 1.55; color: var(--tip-text); white-space: pre-line; }
#hoverTip.rich { white-space: normal; min-width: 210px; }
.tip-t { font-weight: 700; color: var(--brand-deep); font-size: .88rem; margin-bottom: 5px; }
.tip-sub { color: var(--muted); font-size: .78rem; }
.tip-v { font-weight: 700; color: var(--accent); margin-top: 2px; }

footer { margin-top: 40px; background: #143C6B; color: rgba(255,255,255,.85);
  font-size: .8rem; text-align: center; padding: 22px 20px 24px; white-space: pre-line; }
/* sections get flex/order values; without this the footer can be reordered above them */
#pageFooter { order: 999; }

@media (max-width: 900px) {
  .grid2 { grid-template-columns: 1fr; }
  .hero h1 { font-size: 1.5rem; }
}

/* ==================== top-right toolbar ==================== */
.topbar-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.seg { display: inline-flex; border: 1px solid var(--brand-mid); border-radius: 6px; overflow: hidden; background: var(--card); }
.seg button { font-family: inherit; font-size: .82rem; font-weight: 600; line-height: 1;
  border: 0; background: transparent; color: var(--brand); padding: 7px 11px; cursor: pointer;
  border-left: 1px solid var(--line); white-space: nowrap; }
.seg button:first-child { border-left: 0; }
.seg button:hover { background: var(--brand-pale); color: var(--brand-deep); }
.seg button.on { background: var(--brand); color: #fff; }
.seg button:disabled { opacity: .4; cursor: default; }
.seg.fontsize button { min-width: 34px; text-align: center; }
.seg.fontsize button#fsDown { font-size: .72rem; }
.seg.fontsize button#fsUp { font-size: .95rem; }
.logout-btn { display: inline-flex; align-items: center; gap: 6px; font-family: inherit;
  font-size: .82rem; font-weight: 600; color: var(--brand); background: var(--card);
  border: 1px solid var(--brand-mid); border-radius: 6px; padding: 7px 12px; cursor: pointer; }
.logout-btn:hover { background: var(--coral); border-color: var(--coral); color: #fff; }
.logout-btn svg { flex: 0 0 auto; }
@media (max-width: 760px) {
  .logout-btn span { display: none; }     /* icon-only on narrow screens */
  .logout-btn { padding: 7px 9px; }
}

/* ==================== site outline (สารบัญเว็บไซต์) ==================== */
/* Above the sticky topbar (z 20) and sticky section titles (z 26), below #hoverTip (z 999). */
#outlineBackdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 900; }
#outlinePanel {
  position: fixed; z-index: 901; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(1000px, calc(100vw - 32px)); max-height: 82vh; display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 18px 48px rgba(0,0,0,.28);
}
#outlinePanel[hidden], #outlineBackdrop[hidden] { display: none; }
body.ol-open { overflow: hidden; }
.ol-head { display: flex; align-items: center; justify-content: space-between; gap: 12px;
           padding: 14px 18px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.ol-head h2 { font-size: calc(1rem + 6px); color: var(--brand-deep); font-weight: bold; }
.ol-close { display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
            width: 32px; height: 32px; border: 1px solid var(--line); border-radius: 6px;
            background: var(--card); color: var(--muted); }
.ol-close:hover { background: var(--brand-pale); color: var(--brand-deep); border-color: var(--brand-mid); }
.ol-body { overflow-y: auto; padding: 16px 18px 20px; flex: 1 1 auto;
           display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 8px 22px; }
.ol-col { padding: 10px 12px 12px; border: 1px solid transparent; border-radius: 8px; }
.ol-col.on { border-color: var(--brand-soft); background: var(--surface-2); }
.ol-page, .ol-sec, .ol-item { font: inherit; background: none; border: 0; cursor: pointer;
                              text-align: left; display: block; width: 100%; padding: 0; }
.ol-page { display: flex; align-items: baseline; gap: 8px; font-weight: bold; color: var(--brand-deep);
           font-size: calc(.92rem + 6px); line-height: 1.35; margin-bottom: 6px; }
.ol-page:hover { color: var(--accent); }
.ol-n { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
        min-width: 1.55em; height: 1.55em; border-radius: 5px; font-size: .8em;
        background: var(--brand-pale); color: var(--brand-deep); }
.ol-col.on .ol-n { background: var(--brand); color: #fff; }
.ol-sec { color: var(--muted); font-size: calc(.76rem + 6px); font-weight: 600; margin: 8px 0 3px; padding-left: 2px; }
.ol-sec:hover { color: var(--brand); }
.ol-list { list-style: none; margin: 0 0 2px; padding: 0 0 0 10px; border-left: 2px solid var(--line); }
.ol-item { color: var(--ink-soft); font-size: calc(.74rem + 6px); line-height: 1.45; padding: 3px 0 3px 8px; }
.ol-item:hover { color: var(--brand); background: var(--brand-pale); border-radius: 4px; }
.ol-page:focus-visible, .ol-sec:focus-visible, .ol-item:focus-visible, .ol-close:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
@media (max-width: 760px) {
  .ol-body { grid-template-columns: 1fr; }
  #outlinePanel { max-height: 88vh; }
}
.ol-target { animation: olFlash 1.6s ease-out; }
@keyframes olFlash {
  0%, 30% { box-shadow: 0 0 0 3px var(--brand-mid); }
  100% { box-shadow: 0 0 0 3px rgba(92,155,214,0); }
}

/* ==================== DARK theme ==================== */
/* Only tokens are redefined here. Anything that needed a literal (hero/footer gradients) was pinned
   above, so this block stays short and no rule has its only definition inside it. */
:root[data-theme="dark"] {
  --ink: #e7eaec; --ink-soft: #c5ccd0; --muted: #9aa4a9;
  --bg: #12171a; --line: #333d43;
  --card: #1c2429; --surface-2: #232c31; --zebra: #222b30;
  --th-bg: #1F4F7E; --th-text: #eaf3ff; --shadow: rgba(0,0,0,.5);
  --tip-bg: #232c31; --tip-text: #e7eaec;
  /* brand family: lighten the ones used as ON-CARD text/tint */
  --brand: #5A9EE0; --brand-deep: #9CC8F0; --brand-pale: #1B2A3A; --brand-mid: #3F6C99; --brand-soft: #3E5C7C;
  --green: #57b57f; --coral: #e98b82; --teal: #46b3bd; --plum: #9d86c7; --gold: #e3b95d;
  --ok: #63b98a; --warn: #d9b25e; --bad: #e07d70; --idle: #93a0a7;
  --chart-label: #cdd4d8; --chart-label-deep: #e7eaec;
  --chart-axis: #3a444a; --chart-split: #2a3237;
  --chart-map-area: #232c31; --chart-map-border: #12171a;
}
/* light-tinted chips need darkening to read on dark cards */
:root[data-theme="dark"] .chip-ok,   :root[data-theme="dark"] .st-done { background: #1d3327; color: #7fd0a2; }
:root[data-theme="dark"] .chip-part, :root[data-theme="dark"] .st-wait { background: #34301c; color: #e6c877; }
:root[data-theme="dark"] .chip-bad,  :root[data-theme="dark"] .st-stop { background: #3a2320; color: #f0b0a5; }
:root[data-theme="dark"] .chip-none, :root[data-theme="dark"] .st-na   { background: #2b3237; color: #aab4b9; }
:root[data-theme="dark"] .st-run { background: #1e2c3d; color: #94b9e5; }
:root[data-theme="dark"] .as-done { background: #1d3327; color: #7fd0a2; }
:root[data-theme="dark"] .as-run  { background: #34301c; color: #e6c877; }
:root[data-theme="dark"] .as-late { background: #382719; color: #f0ab72; }
:root[data-theme="dark"] .as-wait { background: #3a2222; color: #f09b9b; }
:root[data-theme="dark"] .as-soon { background: #2c2e33; color: #b4b4bd; }
:root[data-theme="dark"] .as-na   { background: #2b3237; color: #aab4b9; }
:root[data-theme="dark"] .as-none { background: transparent; color: #aab4b9; }
:root[data-theme="dark"] .pbar { background: #313b40; }
:root[data-theme="dark"] .dl-btn { background: transparent; border-color: #33465c; color: #94b9e5; }
:root[data-theme="dark"] .dl-btn:hover { background: #1e2c3d; border-color: #4a6a94; }
:root[data-theme="dark"] #outlineBackdrop { background: rgba(0,0,0,.62); }
:root[data-theme="dark"] #outlinePanel { box-shadow: 0 18px 48px rgba(0,0,0,.6); }
