/* ── PunPun design tokens ── the ONE knob that drives the whole look ───────────
   Source of truth: the design handoff (design-handoff/project/tokens/*) for
   surfaces/type/space, and the PunPun brand kit for the accent ladder.
   LIGHT is the default (:root); dark is an override on [data-theme="dark"] —
   only colour/shadow/glass tokens differ between themes, type/space/radius/
   layout are shared.
   Reskin = edit this file only (app.css consumes these vars, no literals).

   สีแบรนด์ PunPun = gradient 3 stop: #03D8CD (teal) → #00A8F8 (blue, theme_color)
   → #7928FF (violet). ตัว #00A8F8 "ห้าม" เป็นพื้นปุ่มที่มีตัวหนังสือขาว —
   contrast แค่ 2.64 (ต้อง ≥ 4.5) จึงแยกหน้าที่ชัด ๆ:
     · --brand-* = สีแบรนด์ดิบ ใช้กับโลโก้/gradient/ภาพประดับ ไม่ใช่ที่รองข้อความ
     · --accent* = บันไดสีที่ derive ลงมาบน hue เดียวกัน (OKLCH H≈241) ให้ผ่าน
       WCAG AA ทุกคู่ที่ใช้จริง — ตัวเลขที่วัดได้อยู่ใน docs/brand/PALETTE.md

   Fonts are self-hosted (css/fonts.css + /fonts/*.woff2) — no render-blocking
   @import here; keep it that way for time-to-pixel. */

:root {
  /* ── surfaces — ชุด Light v2 (จาก mockup neolightthemev2*) ── */
  --canvas: #ffffff;                 /* main content background */
  --sidebar: #f2f4f9;                /* gray-blue rail/canvas the cards sit on */
  --surface: #ffffff;                /* flat cards: hairline border, no shadow */
  --surface-2: #f0f2f7;              /* inset fills: chips, wells, user bubble */
  --surface-raised: #fbfbfd;         /* hover-tint for cards */
  /* stage ของเดโม่: gradient เอียง + แสงแบรนด์จาง ๆ มุมขวาบน — พื้นทั้งแอปนั่งบนนี้
     ใช้ --brand-blue ดิบ (ไม่ใช่ --accent) เพราะเป็นบรรยากาศ ไม่มีข้อความทับ */
  --stage:
    radial-gradient(circle at 66% 16%, rgba(0, 168, 248, .07), transparent 34%),
    linear-gradient(135deg, #f7f8fb, #eef1f7 56%, #f7f8fb);

  /* ── interaction tints ── */
  --pill-bg: rgba(255, 255, 255, .76);
  --hover: rgba(24, 31, 48, .05);
  --active: rgba(24, 31, 48, .08);

  /* ── lines ── */
  --line: rgba(24, 31, 48, .1);
  --line-2: rgba(24, 31, 48, .17);   /* strong variant on hover */

  /* ── text (3-step hierarchy) ── */
  --text: #151a24;
  --muted: #667085;
  --faint: #98a0b1;

  /* ── brand stops (ค่าดิบจาก brand kit — ไม่มี dark override, แบรนด์คือแบรนด์) ──
     ใช้กับโลโก้ / gradient / ภาพประดับเท่านั้น · ห้ามเอาไปเป็นพื้นที่มีข้อความทับ
     หรือเป็นสีตัวหนังสือ (ทั้งสามค่าตกเกณฑ์ AA เมื่อวางคู่ข้อความ) */
  --brand-teal: #03d8cd;             /* stop 0%   */
  --brand-blue: #00a8f8;             /* stop 46%  = manifest theme_color */
  --brand-violet: #7928ff;           /* stop 100% */
  --brand-gradient: linear-gradient(135deg,
    var(--brand-teal) 0%, var(--brand-blue) 46%, var(--brand-violet) 100%);

  /* ── สีพื้นแบบ "ทึบตัวแทน" สำหรับที่ที่ใช้ gradient ไม่ได้ ────────────────────
     `<meta name="theme-color">` กับ PWA manifest ต้องการสีเดียว แต่ `--stage`
     เป็น gradient · สองค่านี้คือสีตัวแทนของ stage แต่ละธีม และ **server อ่านไฟล์นี้
     ไปใช้จริง** (`brand_colors()` ใน bootstrap/http/mod.rs) — เปลี่ยนสีแอปจึงแก้
     ที่นี่ที่เดียว ไม่ต้องตามไปแก้ HTML/manifest
     ⚠️ ทั้งคู่อยู่ใน :root (ไม่ใช่ใน dark block) เพราะ server ต้องอ่านได้ทั้งสองค่า
     พร้อมกันโดยไม่ต้องรู้เรื่องธีม */
  --page-light: #f4f6fa;             /* ตัวแทน --stage ธีมสว่าง */
  --page-dark: #0b0d13;              /* ตัวแทน --stage ธีมมืด (= stop แรกของ gradient มืด) */

  /* ── brand — บันได accent ที่ derive จาก --brand-blue (OKLCH H≈241 ตรึงไว้)
     ลด lightness ลงจนตัวหนังสือขาวผ่าน AA แล้วดัน chroma ชนขอบ sRGB ที่ L นั้น
     (= ฟ้าที่สดที่สุดเท่าที่ยังอ่านออก) ── */
  --accent: #0071a9;                 /* พื้น interactive + ตัวหนังสือบนพื้นอ่อน (white 5.34) */
  --accent-hover: #006395;           /* hover ปุ่ม primary — hue เดิมเข้มขึ้น (ไม่เปลี่ยนสี) */
  --accent-2: var(--brand-violet);   /* คู่ gradient เท่านั้น — ห้ามใช้เป็น hover */
  --accent-soft: #e5f3fe;            /* chip / agent-icon backgrounds */
  /* line/tint เป็นงานบรรยากาศ ไม่มีข้อความทับ → ใช้ฟ้าแบรนด์ดิบให้สีสด ไม่หม่น */
  --accent-line: rgba(0, 168, 248, .28);
  --accent-tint: rgba(0, 168, 248, .08);
  --on-accent: #ffffff;              /* ตัวหนังสือ/ไอคอนบนพื้น --accent */

  /* ── status ── */
  --ok: #179b60;
  --warn: #bd7600;
  /* สีเตือนสำหรับ **ตัวหนังสือบนพื้นสว่าง** — `--warn` เองวัดได้ 3.32 บนพื้นหน้าเพจ
     ซึ่งต่ำกว่า 4.5 ที่ AA ต้องการ · มันถูกออกแบบมาสำหรับไอคอนกับป้ายบนพื้นทึบ
     (พื้นที่สี อ่านออกที่คอนทราสต์ต่ำได้ ตัวหนังสือไม่ได้)
     เจอตอนกวาดผิวประตู — หลุดมาหลายรอบเพราะข้อความผิดพลาดถูกซ่อนไว้ตอนตรวจ */
  --warn-ink: #8a5600;
  --err: #d83a3a;
  --ok-glow: rgba(23, 155, 96, .12);
  --warn-glow: rgba(189, 118, 0, .13);
  --modal-backdrop: rgba(21, 26, 36, .28);   /* scrim หมึกบาง — เห็นเนื้อหาเดิมใต้ modal */

  /* ── elevation 3 ชั้น (e1 วางกับพื้น · e2 ลอย · e3 ทับสุด) — เงาสองชั้น
     contact+ambient โทนหมึกเดียวกัน ตามมาตรฐาน Light v2 ── */
  --shadow: 0 1px 2px rgba(21, 26, 36, .05), 0 3px 10px rgba(29, 40, 70, .05);          /* e1 */
  --shadow-float: 0 2px 6px rgba(21, 26, 36, .06), 0 14px 34px rgba(29, 40, 70, .11);   /* e2: composer */
  --shadow-modal: 0 6px 16px rgba(21, 26, 36, .08), 0 24px 56px rgba(29, 40, 70, .18);  /* e3 */
  /* เงาแบรนด์ใช้ rgb ของ --accent (ไม่ใช่ --brand-blue) — เงาต้องมีน้ำหนัก
     ฟ้าสดที่ alpha ต่ำจะกลายเป็นหมอกจาง ๆ ไม่อ่านเป็นความลึก */
  --shadow-brand: 0 8px 20px rgba(0, 113, 169, .24);   /* under brand mark */
  --shadow-cta: 0 16px 44px rgba(0, 113, 169, .22);    /* primary CTA glow */

  /* ── glass (floating chrome: composer, modal, route preview) ── */
  --glass-bg: rgba(255, 255, 255, .94);
  --glass-blur: 18px;
  /* ── glass ที่ทึบ — สำหรับแผงที่ "มีตัวหนังสือ" ────────────────────────────
     กฎที่วัดได้ (docs/brand/tools/audit_lcd_matrix.mjs · chrome 150 · win11):
       backdrop-filter **ตอนพื้นของตัวเองไม่ทึบ**  → subpixel AA = 0%
       backdrop-filter ตอนพื้นทึบ                  → 71.6% (เท่าฐาน ไม่กระทบ)
       พื้นโปร่งเฉย ๆ ไม่มี blur                     → 72.2% (ไม่กระทบ)
     ตัวการจึงไม่ใช่ "blur" แต่คือ **layer ที่ chrome พิสูจน์ไม่ได้ว่าทึบ** — ซึ่ง
     คือวิธีใช้ glass ตามปกติเป๊ะ ๆ (พื้น alpha .88–.94 + blur) · ตัวที่ฆ่าเหมือนกัน
     อีกสามตัวจากตารางเดียวกัน: opacity < 1 · will-change: transform · filter
     (border-radius · overflow · fixed · box-shadow · transform ไม่กระทบเลย)
     ค่าตรงนี้ = --glass-bg ผสมทับพื้นที่มันลอยอยู่จริง (คำนวณไว้ ไม่ใช่ประมาณ)
       สว่าง: rgba(255,255,255,.94) ทับ --sidebar #f2f4f9 = #fefeff
              (ทับ --canvas #ffffff ได้ #ffffff — ต่าง 1/255 มองไม่เห็น ใช้ค่าเดียว)
     glass ที่ไม่มีตัวหนังสือทับ (--modal-backdrop) ยังเบลอเหมือนเดิม ไม่เสียอะไร */
  --glass-solid: #fefeff;

  /* ── type ── */
  --font-ui: 'Inter', 'IBM Plex Sans Thai', 'Segoe UI', system-ui, sans-serif;
  /* เนื้อความแชท/เอกสาร — ฟอนต์ระบบของแต่ละ OS แล้วต่อท้ายด้วยตัวที่เรา self-host
     ⚠️ **ลำดับในบรรทัดนี้คือทั้งหมดของเรื่อง** — เบราว์เซอร์ไล่ทีละ family ตามลำดับ
     แล้วหยุดที่ตัวแรกที่มี "อักขระตัวนั้น" ไม่ใช่ตัวแรกที่ติดตั้งอยู่ · Segoe UI, Roboto,
     Noto Sans, Ubuntu, Cantarell, Helvetica Neue ไม่มีอักษรไทยสักตัว ตัวที่ได้จริง
     สำหรับไทยจึงเป็น "ตัวแรกในลิสต์ที่มีอักษรไทย" — จะสลับลำดับต้องรู้ข้อนี้ก่อน
     ผลลัพธ์ที่ตั้งใจ: ละติน  → Segoe UI (mac ได้ San Francisco ผ่าน -apple-system)
                      ไทย    → Noto Sans Thai Looped ที่เรา self-host — **ทุก OS เหมือนกัน**
     ไทยเลือกปักชื่อไว้เอง ไม่ปล่อยให้ OS เลือก เพราะฟอนต์ไทยที่ระบบแถมมาต่างกันทุก
     แพลตฟอร์ม (Windows ให้ Tahoma · mac ให้ Thonburi · Android ให้ Noto Sans Thai)
     = หน้าตาคุมไม่ได้ · Tahoma ที่คงไว้ท้าย ๆ เป็นแค่ตาข่ายรองเผื่อ webfont โหลดไม่ติด
     ค่าที่วัดได้ตอนเลือก (font-size 16 · หมึกกรณีเลวสุด "ฟื้ปี๊ญั๋" ซ้อน "ญฐุปฏิ"):
       Tahoma 19px/กว้าง 212.7 · Noto Sans Thai Looped 23px/216.3 · IBM Plex Sans Thai 23px/215.6
     เมนู/หัวข้อ/ป้าย ยังเป็น --font-ui (Inter) เหมือนเดิม — เปลี่ยนแค่ "เนื้อความ"
     ⚠️ หมึก 23px คู่กับ line-height 26 เหลือช่องว่างระหว่างบรรทัด 3px — ถ้าลด
        line-height ต่ำกว่า 26 เมื่อไหร่ สระบน/ล่างของสองบรรทัดจะชนกันจริง (ดู 07-chat.css) */
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, Roboto,
    'Noto Sans Thai Looped', Tahoma, 'Noto Sans', Ubuntu, Cantarell,
    'Helvetica Neue', sans-serif;
  --font-mono: 'Cascadia Code', ui-monospace, SFMono-Regular, Menlo, monospace;
  /* mono is for ALL metric numbers, codes and percentages — no exceptions */
  /* ฟอนต์แบรนด์ CPF — ใช้เฉพาะที่ผู้ใช้ "รู้ว่ากำลังใช้ PunPun ของ CPF": เมนูฝั่งซ้าย
     และคำทักหน้าแรก · ไม่ใช้กับเนื้อความหรือข้อมูล ตรงนั้นต้องอ่านง่ายมาก่อนแบรนด์ */
  --font-brand: 'CPF Imm Sook', 'Inter', 'IBM Plex Sans Thai', system-ui, sans-serif;

  --fs-2xs: 10px;   /* micro labels (uppercase, tracked) */
  --fs-xs: 11px;    /* metadata, session meta */
  --fs-sm: 12px;    /* chips, tags, secondary copy */
  --fs-base: 13px;  /* list titles, crumbs */
  --fs-md: 14px;    /* body default */
  --fs-lg: 15px;    /* card titles (h3) */
  --fs-xl: 16px;    /* panel titles (h2) */
  --fs-2xl: 18px;   /* brand, settings/modal heads */
  --fs-3xl: 22px;   /* gauge value */
  --fs-4xl: 24px;   /* page title (h1) */

  --lh-body: 1.55;
  --lh-tight: 1.2;
  --lh-snug: 1.35;

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-heavy: 800;

  --label-tracking: .04em;   /* uppercase micro-label treatment */

  /* ── spacing — 4px base; design grid uses the 8/12/16/24/32 steps ── */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;

  /* ── radii — pills for controls, 12 nested tiles, 16 primary cards ── */
  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 26px; --r-full: 999px;

  /* ── control heights ── */
  --h-pill: 36px;    /* topbar pill actions */
  --h-nav: 40px;     /* sidebar nav rows */
  --h-input: 40px;   /* search inputs */
  --h-chip: 32px;    /* composer scope chips — ลงกริด 4 (เดิม 30 หลุด) */
  --h-tab: 32px;     /* process tabs / segmented */
  --h-field: 44px;   /* form fields (login) */

  /* ── motion — border-color/background only, no transform/scale ── */
  --ease-ui: ease;
  --dur-fast: .16s;

  /* ── layout ── */
  --sidebar-w: 264px;
  --topbar-h: 52px;       /* design spec: 76px — flips with the shell reskin */
  /* คอลัมน์เนื้อหามี 2 ระยะมาตรฐาน — ทุกหน้าเลือกใช้จากสองค่านี้เท่านั้น */
  --content-max: 720px;   /* ระยะอ่าน: แชท + ลิสต์ (ความรู้/งาน/ภาพรวม) = กว้างเท่า composer */
  --content-wide: 960px;  /* ระยะข้อมูลเยอะ: ศูนย์ปฏิบัติการ/โรงงาน/เครื่องมือ/ตั้งค่า */
  --composer-clear: 152px; /* ที่ว่างท้าย scroller ให้เนื้อหาลอดพ้น composer ลอย */
  /* คอลัมน์เนื้อหาตอนมีแผงเปิด — เดิมตรึง 420 ทุกจอ ซึ่งแปลว่าจอยิ่งใหญ่ แผงยิ่งได้เปรียบ
     ฝ่ายเดียว (จอ 1600: แผง 880 · เนื้อหา 420 เท่าจอ 1100) แล้วรายการ/ต้นไม้ฝั่งซ้าย
     ถูกบีบจนชื่อไฟล์เหลือ …110px · ให้มันโตตามจอด้วย แต่มีทั้งพื้นและเพดาน
     360 = ขั้นต่ำที่ยังอ่านรายการออก · 560 = เพดาน ไม่งั้นแผงที่เป็นของหลักโดนเบียดแทน */
  --chat-rail: clamp(360px, 34vw, 560px);
  --doc-read: 860px;      /* comfortable reading width inside the doc panel */

  /* the sheet the whole app sits on: gray in light (cards read as white),
     near-black in dark (cards read as raised panels) */
  --shell-bg: var(--sidebar);
  /* accent สำหรับข้อความบนพื้นอ่อน (chip route, ลิงก์ในเนื้อความ ฯลฯ)
     เข้มกว่า --accent อีกขั้น เพื่อให้ผ่าน AA แม้บน --accent-soft ที่จาง */
  --accent-ink: #005e8e;

  color-scheme: light;
}

/* ไม่ต้องมีกฎ 1280 แยกแล้ว — clamp() ข้างบนลงมาชนพื้น 360 เองที่ราว 1060px
   (34vw = 360 เมื่อ vw ≈ 1059) ซึ่งเป็นจุดเดียวกับที่แผงเปลี่ยนไปคลุมเต็มผืนพอดี */
/* แถบข้างแคบลงก่อนถึงจุดที่มันกลายเป็น drawer (760) — บนจอ 900–1180 แถบข้าง 264
   กิน 29% ของจอไปให้เมนูที่ป้ายยาวสุดคือ "ค้นหาบทสนทนา" ซึ่งพอดีที่ 220 อยู่แล้ว
   ที่ได้คืนคือ 44px ของ *พื้นที่เนื้อหา* ซึ่งเป็นด้านที่ขาดจริงในช่วงความกว้างนี้ */
@media (max-width: 1180px) { :root { --sidebar-w: 220px; } }

/* ── DARK theme — hue เดิม (H≈241) แต่ไม่ใช่การกลับ lightness แบบกลไก ─────────
   บนพื้นเกือบดำ ฟ้าสด ๆ จะแสบตา จึงยก lightness ขึ้นแล้ว "หั่น chroma ลง"
   ตาม L ที่สูงขึ้น (accent C .150 → hover C .132 → ink C .109)
   และพลิกสัญญาปุ่ม: ธีมสว่างใช้ตัวหนังสือ "ขาว" บน accent เข้ม ธีมมืดใช้
   ตัวหนังสือ "หมึกน้ำเงินเข้ม" (--on-accent) บน accent สว่าง — เพราะขาวบน
   ฟ้าสว่างได้แค่ 2.6 ไม่มีทางผ่าน AA (accent ธีมมืดชุดเก่าคู่ขาวก็ได้แค่ 3.28 — ตกอยู่แล้ว)
   Activate: document.documentElement.setAttribute('data-theme','dark'). */
[data-theme="dark"] {
  --canvas: #0e0f13;
  --sidebar: #15161c;
  /* แสงแบรนด์บนพื้นมืดต้อง "สว่างขึ้น" กว่าพื้น ไม่ใช่คล้ำลง — ฟ้าแบรนด์ที่หรี่แล้ว */
  --stage:
    radial-gradient(circle at 66% 16%, rgba(20, 71, 102, .18), transparent 34%),
    linear-gradient(135deg, #0b0d13, #0e1017 56%, #0b0d13);
  --accent-ink: #7bc8ff;
  --surface: #15161c;
  --surface-2: #1e2027;
  --surface-raised: #1a1c23;

  --pill-bg: rgba(30, 32, 39, .76);
  --hover: rgba(255, 255, 255, .05);
  --active: rgba(255, 255, 255, .09);

  --line: rgba(255, 255, 255, .1);
  --line-2: rgba(255, 255, 255, .18);

  /* ── ตัวหนังสือหลักธีมมืด — หรี่จาก #ececf1 (contrast 16.27) มาที่ 13.78 ─────────
     เหตุผลไม่ใช่รสนิยม แต่มาจากที่วัดได้ใน docs/brand/RASTER-AND-DPI.md §4:
     ขาวบนดำ "ลงหมึกจริง" หนากว่าดำบนขาวที่ contrast เดียวกัน และยิ่ง contrast สูง
     ยิ่งถ่างออก — 4.5 เท่ากันเป๊ะ · 7 หนากว่า 7.9% · 12 หนากว่า 21.3%
     ที่ 16.27 (ค่าเดิม) หนากว่า **26.9%** และฟุ้ง 53.8% ซึ่งเป็นจุดที่แย่ที่สุดของเส้นโค้ง
     ที่ 13.78 → หนากว่า 21.3% · ฟุ้ง 50.9% — คมขึ้นวัดได้ โดยยัง **สูงกว่า AAA (7:1) เกือบเท่าตัว**
       บน --canvas 13.78 · บน --sidebar 12.99 · บน --surface-2 11.70
     ลดต่ำกว่านี้ไม่คุ้ม: เส้นโค้งแบนลง (c=10 ยังหนากว่า 15.4% · c=6 ยังหนากว่า 10.1%)
     แปลว่า contrast ไม่ใช่คันโยกที่พา gamma กลับมาเท่ากันได้ แค่ถอยจากจุดที่แย่ที่สุด
     คันโยกที่ตรงกว่าคือน้ำหนักฟอนต์ที่บางกว่า 400 — แต่ชุดฟอนต์ที่โหลดไม่มี 300
     คืนค่าเดิม: เปลี่ยนกลับเป็น #ececf1 บรรทัดเดียว ไม่มีอะไรอื่นผูกอยู่ */
  --text: #dadae2;
  --muted: #9d9eab;
  --faint: #6b6c78;

  --accent: #2aa8f2;                 /* = --brand-blue หรี่ chroma ลงเล็กน้อยกันแสบตา */
  --accent-hover: #54b7f8;           /* ธีมมืด hover สว่างขึ้นใน hue เดิม */
  --accent-2: #9373ff;               /* --brand-violet ยก L ขึ้นให้เข้าคู่ accent ที่สว่าง */
  --accent-soft: rgba(42, 168, 242, .14);
  --accent-line: rgba(42, 168, 242, .38);
  --accent-tint: rgba(42, 168, 242, .1);
  /* หมึกบนพื้น accent ของธีมมืด — ไม่ใช่ขาว (ดูหัวบล็อก) · ทำงานกับทั้ง
     --accent, --accent-hover และปลาย gradient --accent-2 */
  --on-accent: #001322;

  --ok: #2fbf7f;
  --warn: #dfa032;
  /* ธีมมืดวัดได้ 8.52 อยู่แล้ว ไม่ต้องหรี่ลง — ใช้ค่าเดียวกัน */
  --warn-ink: #dfa032;
  --err: #ef6363;
  --ok-glow: rgba(47, 191, 127, .16);
  --warn-glow: rgba(223, 160, 50, .16);
  --modal-backdrop: rgba(10, 11, 14, .5);

  --shadow: 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-float: 0 18px 54px rgba(0, 0, 0, .55);
  --shadow-modal: 0 24px 80px rgba(0, 0, 0, .6);
  /* ต้อง override — เดิมธีมมืดตกทอดเงาสีของธีมสว่างมาใช้ (ผิด hue) · บนพื้นมืด
     เงาสีต้องเป็น "แสงเรือง" จึงใช้ rgb ของ accent ธีมมืดและดัน alpha ขึ้นนิด */
  --shadow-brand: 0 8px 20px rgba(42, 168, 242, .28);
  --shadow-cta: 0 16px 44px rgba(42, 168, 242, .24);
  --glass-bg: rgba(21, 22, 28, .88);
  /* มืด: rgba(21,22,28,.88) ทับ --canvas #0e0f13 = #14151b (พื้นของ sidebar และ
     composer เป็น --canvas ตัวเดียวกันในธีมนี้ จึงได้ค่าเดียว) */
  --glass-solid: #14151b;

  --shell-bg: var(--canvas);

  color-scheme: dark;
}


/* ══════════════════════════════════════════════════════════════════
   จากแพตช์พรีวิว docs/brand/palette-fixes.css — ผ่านการวัดจริงบนหน้าจอ
   (contrast · กริด 4px · line-height ไทย · หมึกจริงจากพิกเซล)
   รายละเอียดการวัดอยู่ใน docs/brand/SPACING-COLOR-AUDIT.md
   ══════════════════════════════════════════════════════════════════ */
/* ── A · สีข้อความ ────────────────────────────────────────────────────────────
   หลักที่ใช้: ลำดับชั้นของข้อความต้องมาจาก "ขนาด/น้ำหนัก/ที่วาง" ไม่ใช่ "ความจางจน
   อ่านไม่ออก" · --faint จึงถูกลดหน้าที่เหลือแค่ไอคอน/เส้น (เกณฑ์ 3.0) และข้อความ
   ทุกจุดที่เคยใช้ --faint ย้ายมา --muted (เกณฑ์ 4.5)
   ค่าทุกตัวคำนวณจาก OKLCH hue/chroma เดิม ขยับแค่ lightness จนผ่านทุกพื้นที่ใช้จริง */
:root {
  --muted: #656f84;   /* เดิม #667085 — บน surface-2 ได้ 4.44 (ตก) → 4.51 */
  --faint: #858c9d;   /* เดิม #98a0b1 — 2.39 แม้เกณฑ์ไอคอน 3.0 ก็ไม่ผ่าน → 3.01 */
  /* สีสถานะตอน "เป็นตัวหนังสือ" ต้องเข้มกว่าตอนเป็นจุด/แถบ (จุดเป็นกราฟิก เกณฑ์ 3.0) */
  --ink-ok: #007f4c;    /* จาก --ok #179b60 (3.24 → 4.53) */
  --ink-warn: #9d6100;  /* จาก --warn #bd7600 */
  --ink-err: #cf3133;   /* จาก --err #d83a3a */
}
[data-theme="dark"] {
  --muted: #9d9eab;   /* ผ่านอยู่แล้ว (6.13–7.22) — คงเดิม */
  --faint: #6b6c78;   /* ไอคอน/เส้น 3.13–3.69 ผ่านเกณฑ์ 3.0 — คงเดิม */
  --ink-ok: #2fbf7f;  /* ธีมมืดสีสถานะผ่าน 4.5 ทั้งชุด — คงเดิม */
  --ink-warn: #dfa032;
  --ink-err: #ef6363;
}
/* ── E · แถบหัว (topbar) — แนวเดียวกับหัว sidebar + ปุ่มแชร์เป็นไอคอน ────────────
   วัดได้: หัว sidebar เป็นแถบ 12–72 (สูง 60) แกนกลาง **42** · ปุ่มย่อแถบข้างก็ mid 42
   แต่ topbar เป็นแถบสูง 36 เริ่มที่ 20 → แกนกลาง **38** เหลื่อมกัน 4px
   แก้: ทำ topbar เป็นแถบ 12–72 เท่ากัน (แกนกลาง 42 ตรงกันทั้งซ้าย-ขวา)
   และ --topbar-h 60 ทำให้เนื้อหาเริ่มที่ 60+12 = 72 = ขอบล่างแถบพอดี (ลงกริด) */
:root { --topbar-h: 60px; }
/* ── J · เงา + เส้นขอบ (ทบทวนด้วยการวัดพิกเซล ไม่ใช่ความรู้สึก) ────────────────────
   **เงาธีมมืด**: ประกาศไว้แรงมาก (0 10px 30px rgba(0,0,0,.45) / composer .55 ที่ 54px)
   แต่วัดจากพิกเซลจริงได้แค่ **มืดลง 4 ระดับ** (พื้น 15 → 11) แผ่ออก 14–27px
   เพราะพื้นเกือบดำอยู่แล้ว จะดำกว่านั้นไม่ได้ → สิ่งที่ได้จริงคือ "รอยเปื้อนกว้าง ๆ"
   ไม่ใช่ความลึก (ธีมสว่างวัดได้ 15 ระดับ ใน 23px = อ่านเป็นชั้นได้จริง)
   แก้ตามหลักที่ dark UI ใช้จริง: ลด alpha/รัศมีลง แล้วบอกความสูงด้วย
   (ก) พื้นที่สว่างขึ้น (--surface-raised) และ (ข) เส้นสว่าง 1px ที่ขอบบน (แสงมาจากด้านบน) */
[data-theme="dark"] {
  --shadow: 0 2px 8px rgba(0, 0, 0, .30);
  --shadow-float: 0 8px 24px rgba(0, 0, 0, .36);
  --shadow-modal: 0 16px 48px rgba(0, 0, 0, .50);
}
/* ของลอย (ช่องพิมพ์/โมดัล/popover) ในธีมมืด: พื้นยกขึ้นหนึ่งขั้น + ขอบบนสว่าง 1px */
[data-theme="dark"] .composer,
[data-theme="dark"] .modal,
[data-theme="dark"] .pop {
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, .06);
}
/* **เส้นขอบ**: WCAG 1.4.11 กำหนดว่าถ้า "ขอบ" เป็นสิ่งเดียวที่บอกว่านี่คือช่องกรอก/ปุ่ม
   ต้องมี contrast ≥ 3:1 กับพื้นรอบข้าง · วัดของเดิม:
     --line   สว่าง 1.22 · มืด 1.28   ← ตกไกล
     --line-2 สว่าง 1.41 · มืด 1.68   ← ตกไกล
   แต่ถ้าดัน --line ทั้งระบบเป็น 3:1 หน้าตาจะกลายเป็นตารางเส้นหนา (hairline ตกแต่งไม่ต้อง 3:1)
   จึงเพิ่ม token แยกสำหรับ "ขอบเขตของสิ่งที่กดได้/กรอกได้" แล้วใช้เฉพาะจุดนั้น
   ค่าที่คำนวณ: จางที่สุดที่ยังผ่าน 3:1 ทุกพื้นในธีมสว่าง = #878c98 (3.01–3.37)
                เข้มที่สุดที่ยังผ่านในธีมมืด = #666a75 (3.01–3.59) */
:root { --line-ui: #878c98; }
[data-theme="dark"] { --line-ui: #666a75; }
[data-theme="dark"] .composer:focus-within {
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, .06), 0 0 0 3px var(--accent-tint);
}
/* ══ M · รากของ "การ์ดข้อมูล" — วางระบบใหม่ทั้งชุด (แทนการแก้ทีละใบ) ══════════════
   ปัญหาที่วัดได้: โครงในการ์ดถูกออกแบบให้อยู่ในกล่องขาว —
     · ทุกบล็อกมี padding 12 ของตัวเอง (.kpi-row .vbar .wgauge .vtimeline .ptree .cgraph)
     · ราง/ขอบใช้ --line ซึ่งเป็นหมึกโปร่ง → บนพื้น stage วัด contrast ได้ 1.22 (มองไม่เห็น)
     · pill/tile/node ทุกตัวมี border 1px --line → พอเอาพื้นการ์ดออก เหลือเส้นผี
     · gap 6/7px หลุดกริด
   ทางแก้: ตั้ง token ของ "พื้นผิวข้อมูล" + ชุดสีหมวด + กฎระยะข้อเดียว แล้วให้ทุกการ์ดใช้ร่วม

   ── token ──
   --data-well : พื้นราง/ฐานแท่ง — วัดแล้วต่างจาก stage 17/9 ระดับ (สว่าง) และ 18 ระดับ (มืด)
   --data-ink  : สีแท่งเมื่อมี series เดียว — **ไม่ใช้ accent** เพื่อไม่ให้แท่งอ่านเป็นปุ่ม
                 (สว่าง ΔE 0.124 จาก accent · contrast 7.12 · มืด ΔE 0.134 · contrast 7.29)
   --seg-1..6  : ชุดสีหมวดข้อมูล เว้นช่วงฟ้าของ accent ทั้งหมด
                 ΔE จาก accent ≥ 0.124 (สว่าง) / ≥ 0.21 (มืด) · ใกล้สุดกันเอง 0.131 */
:root {
  --data-well: #e4e8f0;
  --data-ink: #4b5563;
  --seg-1: #c77400; --seg-2: #00846a; --seg-3: #b3628e;
  --seg-4: #c4551f; --seg-5: #4b5563; --seg-6: #8a7f1f;
}
[data-theme="dark"] {
  --data-well: #22242c;
  --data-ink: #9aa0ab;
  --seg-1: #e6a020; --seg-2: #00a586; --seg-3: #c579a3;
  --seg-4: #d96a35; --seg-5: #a8aeb9; --seg-6: #a89a2a;
}
/* ══ N · กลับมาใช้ "การ์ดมีพื้น + มีกรอบ" ตามที่ผู้ใช้เลือก — แต่เด่นน้อยกว่าช่องพิมพ์ ══
   วัดระดับความสว่างเทียบพื้น stage (เพื่อไม่ให้การ์ดแย่งความเด่นกับ composer ที่ลอยอยู่):
     ช่องพิมพ์ (ขาว .97)  → +15 ระดับ   ← ตัวที่ต้องเด่นสุด
     การ์ด (ขาว .50)      → +4/+8 ระดับ ← เลือกค่านี้: เห็นเป็นแผ่น แต่ไม่แย่งสายตา
     ธีมมืด การ์ด (ขาว .03) → +6 ระดับ  (composer +6 แต่มีเส้นแสงบนขอบ จึงยังเด่นกว่า)
   ระยะในการ์ดจัดใหม่ทั้งชุดบนกริด 4: pad 12/16 · หัว 24 + เว้น 8 · ระหว่างการ์ด 16 */
:root { --card-bg: rgba(255, 255, 255, .5); }
[data-theme="dark"] { --card-bg: rgba(255, 255, 255, .03); }
/* พื้นรางข้อมูลต้องเข้มกว่าพื้นการ์ด (ไม่ใช่เทียบ stage อีกแล้ว) — ปรับให้ต่างชัดในทั้งสองธีม */
:root { --data-well: #e8ebf2; }
[data-theme="dark"] { --data-well: #262932; }
