/* GĐ3: CSS nền DÙNG CHUNG (tách khỏi <style> nội tuyến → CSP style-src không cần
   'unsafe-inline'). Biến --primary/--ring nằm ở theme-<app>.css (nạp kèm). */
:root {
  /* T-1 VÒNG 2 (F2) — --line là màu VIỀN TRUNG TÍNH dùng khắp app (`var(--line)`), nên trỏ THẲNG
     vào token --c-gray-200 bên dưới (một nguồn sự thật — CLAUDE.md §1 luật 11) thay vì tự giữ một
     bản hex riêng sẽ trôi. Giá trị SÁNG y hệt cũ (229 231 235 = #e5e7eb, không đổi 1 pixel); ở nền
     tối tự động ăn theo --c-gray-200 tối (#2E333B) — KHÔNG cần khai lại --line trong hai khối tối
     bên dưới, biến CSS resolve theo giá trị --c-gray-200 tại thời điểm dùng, không theo thứ tự
     khai báo trong file. */
  --line: rgb(var(--c-gray-200));
  /* T-1 VÒNG 2 (F2) — --status-draft là NỀN của một CHIP TRÒN CHỮ TRẮNG (StatusBadge, kl-ui.js
     ~dòng 2553: `background: var(--status-draft)`, `color:"#fff"` LUÔN LUÔN), khác hẳn vai trò
     "chữ trên nền" của các token --c-gray-*. Nếu đổi theo luật "sáng dần ở nền tối" như gray-500
     (vai trò CHỮ) thì nền chip sẽ SÁNG LÊN trong khi chữ vẫn trắng cứng ⇒ VỠ tương phản ngược
     (đúng bẫy vừa tự bắt được ở 3 nút "Đăng nhập"/"Xác nhận"/"Gửi mã" dùng `color:"#fff"` trên nền
     `var(--primary)` — xem báo cáo bàn giao). ⇒ CỐ Ý GIỮ NGUYÊN giá trị này ở CẢ HAI theme (không
     thêm khai báo trong khối tối) — bản thân #6b7280 làm nền cho chữ trắng đã đạt ~4,83:1 (>4,5:1)
     KHÔNG PHỤ THUỘC theme nền trang, vì đây là màu CHIP riêng, không phải bề mặt trang. */
  --status-draft: #6b7280;
  /* --status-confirmed/--status-completed là màu NGỮ NGHĨA (hổ phách/lục, cùng vai trò chip nền +
     chữ trắng như trên) ⇒ thuộc phạm vi T-2, CỐ Ý ĐỂ NGUYÊN ở lô này — không đụng. */
  --status-confirmed: #d97706;
  --status-completed: #059669;

  /* ===== T-1 (NỀN TỐI, v1.83+) — 12 biến màu trung tính ==============================
     Đây là NGUỒN DUY NHẤT cho white/black/gray của Tailwind (tailwind.config.js trỏ vào
     đây qua rgb(var(--c-*) / <alpha-value>)). KHỐI :root TRẦN NÀY LÀ SÁNG — giá trị PHẢI
     y hệt bảng màu gốc của Tailwind (đừng đổi số). Khối tối nằm ở hai nơi bên dưới; thiếu
     một biến ở khối trần này ⇒ trạng thái "theo máy" không có màu (lỗi kinh điển).
     🚨 Định dạng "R G B" ba số kênh rời — KHÔNG phải "#hex" — bắt buộc cho cú pháp
     <alpha-value> của Tailwind (kho có 165 chỗ dùng bg-xxx-50/60, bg-black/50…). */
  --c-white: 255 255 255;
  --c-black: 0 0 0;
  --c-gray-50: 249 250 251;
  --c-gray-100: 243 244 246;
  --c-gray-200: 229 231 235;
  --c-gray-300: 209 213 219;
  --c-gray-400: 156 163 175;
  --c-gray-500: 107 114 128;
  --c-gray-600: 75 85 99;
  --c-gray-700: 55 65 81;
  --c-gray-800: 31 41 55;
  --c-gray-900: 17 24 39;

  /* ===== T-2 (NỀN TỐI, v1.84+) — 5 họ màu NGỮ NGHĨA, ĐÚNG 3 VAI TRÒ =====================
     Chủ chỉ rõ 13/09: thẻ cảnh báo (bg-red-50 + text-red-700 + border-red-200…) vẫn là "mảng
     gần trắng nằm giữa thẻ đen" ở nền tối — CHỈ 3 vai trò dưới đây bị lỗi đó, nên CHỈ 3 vai trò
     này được token hoá (50/100 = NỀN thẻ, 700/800 = CHỮ đậm, 200 = VIỀN). Các shade khác
     (300/400/500/900 — nút/accent đặc màu) tailwind.config.js CỐ Ý không đụng, vẫn ăn theo
     mã Tailwind gốc, không đổi theo theme (đã ổn ở cả hai nền, không phải phạm vi chủ bắt lỗi).
     🚨 Giá trị SÁNG dưới đây PHẢI y hệt bảng màu gốc Tailwind v3 (colors.<họ>[<shade>]) — ràng
     buộc "nền sáng không đổi 1 pixel". Định dạng "R G B" giống dải gray ở trên.
     📌 T-9 VIỆC A (v1.87+, docs/VIEC-DANG-LAM.md §3.29) + T-9 ĐỢT 2 (v1.88+) — NGOẠI LỆ trong 5
     họ: `red-600`/`blue-600`/`violet-600` (đo THẬT bằng getComputedStyle) đứng yên ở nền tối vì
     trước đây KHÔNG có token, rơi về hex tĩnh (3,37–3,66:1 / 3,06–3,32:1 trên nền trung tính, dưới
     ngưỡng 4,5:1). Chỉ BA họ này được thêm bậc 600 ở `tailwind.config.js` (SEMANTIC_FAMILY dùng
     chung cho 9 họ VẪN KHÔNG đụng — xem chú thích ở đó). Tách THEO VAI TRÒ, hai token mỗi họ:
       — `--c-<họ>-600` = vai trò CHỮ/VIỀN trên bề mặt (text-<họ>-600, border-<họ>-600 đứng riêng)
         → LẬT ở nền tối, xem hai khối tối bên dưới.
       — `--c-<họ>-strong` (MỚI) = vai trò NỀN ĐẶC mang chữ trắng (bg-<họ>-600, accent-<họ>-600,
         border-<họ>-600 đi kèm bg) → KHÔNG lật, luôn bằng giá trị sáng gốc (chữ trắng không đổi,
         không đụng các nút/huy hiệu đang tốt). CỐ Ý không khai --c-<họ>-strong ở hai khối tối bên
         dưới — biến resolve về giá trị :root trần (đúng nếp --primary-strong của §3.31:
         theme-*.css cũng chỉ khai ở khối sáng, không lặp ở khối tối). */
  --c-red-50: 254 242 242;
  --c-red-100: 254 226 226;
  --c-red-200: 254 202 202;
  --c-red-600: 220 38 38; /* T-9 VIỆC A — = #DC2626, giữ từng byte (bảng gốc Tailwind v3) */
  --c-red-700: 185 28 28;
  --c-red-800: 153 27 27;
  --c-red-900: 127 29 29;
  --c-red-strong: 220 38 38; /* T-9 VIỆC A — nền đặc mang chữ trắng, KHÔNG lật ở nền tối (xem chú thích trên) */
  --c-blue-50: 239 246 255;
  --c-blue-100: 219 234 254;
  --c-blue-200: 191 219 254;
  --c-blue-600: 37 99 235; /* T-9 ĐỢT 2 — = #2563EB, giữ từng byte (bảng gốc Tailwind v3) */
  --c-blue-700: 29 78 216;
  --c-blue-800: 30 64 175;
  --c-blue-900: 30 58 138;
  --c-blue-strong: 37 99 235; /* T-9 ĐỢT 2 — nền đặc mang chữ trắng, KHÔNG lật ở nền tối (xem chú thích trên) */
  --c-violet-50: 245 243 255;
  --c-violet-100: 237 233 254;
  --c-violet-200: 221 214 254;
  --c-violet-600: 124 58 237; /* T-9 ĐỢT 2 — = #7C3AED, giữ từng byte (bảng gốc Tailwind v3) */
  --c-violet-700: 109 40 217;
  --c-violet-800: 91 33 182;
  --c-violet-900: 76 29 149;
  --c-violet-strong: 124 58 237; /* T-9 ĐỢT 2 — nền đặc mang chữ trắng, KHÔNG lật ở nền tối (xem chú thích trên) */
  --c-amber-50: 255 251 235;
  --c-amber-100: 254 243 199;
  --c-amber-200: 253 230 138;
  --c-amber-700: 180 83 9;
  --c-amber-800: 146 64 14;
  --c-amber-900: 120 53 15;
  --c-emerald-50: 236 253 245;
  --c-emerald-100: 209 250 229;
  --c-emerald-200: 167 243 208;
  --c-emerald-700: 4 120 87;
  --c-emerald-800: 6 95 70;
  --c-emerald-900: 6 78 59;
  /* T-5 (v1.84+, docs/VIEC-DANG-LAM.md §3.22) — họ CAM thêm sau 5 họ trên, cùng khuôn/luật (chỉ
     6 shade 50/100/200/700/800/900, giá trị SÁNG y hệt bảng gốc Tailwind v3 colors.orange). Sinh
     ra vì app-grafik.js dùng #9a3412/#fed7aa/#ffedd5/#fff7ed nội tuyến làm màu cảnh báo "chưa xếp
     ca" — không nằm trong 5 họ T-2 khảo sát ban đầu. */
  --c-orange-50: 255 247 237;
  --c-orange-100: 255 237 213;
  --c-orange-200: 254 215 170;
  --c-orange-700: 194 65 12;
  --c-orange-800: 154 52 18;
  --c-orange-900: 124 45 18;
  /* T-6 (v1.84+, docs/VIEC-DANG-LAM.md §3.26) — BA họ ngữ nghĩa còn thiếu token, phát hiện khi đo
     hết "11 mảng sáng còn lại" trên nền tối (bảng đo thật ở đề bài mục A). Cùng khuôn 6 shade
     50/100/200/700/800/900, giá trị SÁNG y hệt bảng gốc Tailwind v3 — KHÔNG được gộp vào họ có sẵn
     dù tên gần giống (green ≠ emerald: green-100 #dcfce7 khác emerald-100 #d1fae5; yellow ≠ amber:
     yellow-100 #fef9c3 khác amber-100 #fef3c7) — gộp là đổi nền sáng, vi phạm tiêu chí số một. */
  --c-green-50: 240 253 244;
  --c-green-100: 220 252 231;
  --c-green-200: 187 247 208;
  --c-green-700: 21 128 61;
  --c-green-800: 22 101 52;
  --c-green-900: 20 83 45;
  --c-yellow-50: 254 252 232;
  --c-yellow-100: 254 249 195;
  --c-yellow-200: 254 240 138;
  --c-yellow-700: 161 98 7;
  --c-yellow-800: 133 77 14;
  --c-yellow-900: 113 63 18;
  --c-slate-50: 248 250 252;
  --c-slate-100: 241 245 249;
  --c-slate-200: 226 232 240;
  /* T-7 (v1.85+, docs/VIEC-DANG-LAM.md §3.27 mục B) — BA bậc MỞ RỘNG riêng của họ slate (300/400/
     600), CHỈ dùng làm CHỮ/VIỀN cho `UI.Placeholder` (kl-ui.js) — KHÔNG áp cho 9 họ ngữ nghĩa kia
     (SEMANTIC_SHADES của test/goi85-nen-toi.js giữ nguyên [50,100,200,700,800,900], ba bậc này có
     bảng đối chứng RIÊNG). Giá trị SÁNG = bảng gốc Tailwind v3 (colors.slate[300/400/600]). */
  --c-slate-300: 203 213 225;
  --c-slate-400: 148 163 184;
  --c-slate-600: 71 85 105;
  --c-slate-700: 51 65 85;
  --c-slate-800: 30 41 59;
  --c-slate-900: 15 23 42;

  /* T-6 — HAI mã KHÔNG thuộc bảng Tailwind (đề bài mục B), xử RIÊNG LẺ, không ép vào họ nào:
     --c-hairline = #eef2f7 (mã tự chế, dùng làm VIỀN mảnh/NỀN nút nhỏ — kl-ui.js InfoTip,
     app-admin.js/app-codong.js vạch chia dưới header). --c-surface-alt = #fafafa (= neutral-50/
     zinc-50, KHÁC gray-50 #f9fafb — app-info.js thẻ mặt hàng). Giá trị SÁNG giữ nguyên từng byte. */
  --c-hairline: 238 242 247;
  --c-surface-alt: 250 250 250;
  /* T-7 (§3.27 mục C) — thanh NỀN TRACK biểu đồ cổ tức trong app-codong.js (PerShopSummary,
     bar(div, ...)), #e0f2fe (= sky-100, tổng kênh 720), mảng sáng trên nền tối. KHÔNG có họ `sky`
     trong kho ⇒ khai BIẾN LẺ như --c-hairline/--c-surface-alt thay vì tạo cả một họ chỉ để dùng
     một chỗ. 🚨 CHỈ sửa app-codong.js:350 (tham số 3 của bar(...) cho hàng cổ tức) — KHÔNG đụng
     `kl-data.js` dòng khai bộ màu MÀN HÌNH `palesky` (cũng chứa "#E0F2FE" nhưng là MỘT TRONG 20 BỘ
     MÀU của public/manhinh/**, cố ý KHÔNG theo theme sáng/tối của app — xem CLAUDE.md §10.4). */
  --c-sky-track: 224 242 254;
}
/* ---- NỀN TỐI theo MÁY (prefers-color-scheme) — chỉ áp khi người dùng KHÔNG ép "Sáng" ---
   Đo bằng script (không nhìn mắt, xem docs/VIEC-DANG-LAM.md §3.18 B7): tương phản chữ/nền
   THẤP NHẤT trong 12 biến này là 4,73:1 (gray-300 trên gray-200), mọi cặp khác cao hơn.
   🚨 gray-50/white/gray-100/gray-200 CHỈ được dùng làm NỀN/VIỀN trong toàn kho (đã grep,
   0 lượt text-gray-50/100/200) ⇒ được phép rất TỐI. gray-300..900 CHỈ được dùng làm CHỮ
   (0 lượt bg-gray-400..900) ⇒ bắt buộc SÁNG, và PHẢI sáng dần 300→900 (900 = chữ chính,
   đậm nhất theo nghĩa SÁNG NHẤT ở nền tối — ĐẢO cực so với nghĩa "đậm = tối nhất" ở nền
   sáng, đúng như CLAUDE.md §3.18 cảnh báo: --c-gray-900 là chữ CHÍNH, ở nền tối phải SÁNG). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --c-white: 23 26 32;     /* thẻ/khung nổi — #171A20 */
    --c-black: 0 0 0;        /* lớp phủ modal (bg-black/40..60) — giữ nguyên, vẫn đúng vai trò */
    --c-gray-50: 15 17 21;   /* nền trang/app shell — #0F1115 */
    --c-gray-100: 34 38 45;  /* mặt phụ / viền nhạt / hover */
    --c-gray-200: 46 51 59;  /* viền chính, đường chia — #2E333B */
    --c-gray-300: 153 158 168;
    --c-gray-400: 168 174 184;
    --c-gray-500: 184 189 199;
    --c-gray-600: 199 203 212;
    --c-gray-700: 213 217 225;
    --c-gray-800: 226 229 235;
    --c-gray-900: 240 239 236; /* chữ chính — #F0EFEC, SÁNG NHẤT trong 12 biến */

    /* T-2 — 5 họ màu ngữ nghĩa, LẬT NGƯỢC đúng 3 vai trò (xem chú thích đầy đủ ở khối :root
       trần). NỀN (50/100) tối SẪM lại (gần mức nền trang/mặt phụ ở trên); VIỀN (200) tối hơn
       NỀN-50 một bậc (đề bài); CHỮ (700/800/900) SÁNG lên, đo tương phản THẬT ≥4,5:1 trên cả hai
       nền (goi85 mục ⑫: thấp nhất 5,17:1 ở emerald-700/emerald-100, còn lại đều >5,7:1).
       🚨 VÒNG 3 (người giám sát tự mở ảnh, bắt bằng mắt) — LẤY THẲNG shade 950/900 của Tailwind
       theo SỐ là SAI: `950` không cùng độ sáng giữa các hue (`red-950` tổng kênh 89, `blue-950`
       144, `violet-950` 163) ⇒ 5 thẻ không đều nhau, xanh dương/tím nổi lên thành mảng sáng giữa
       4 thẻ tối — đúng loại lỗi "khoảng trắng trong nền dark" chủ đã bác ở T-1, chỉ nhẹ hơn.
       ⇒ NỀN dưới đây tính lại bằng HSL: GIỮ NGUYÊN Hue + Saturation gốc của từng họ (không đổi
       "màu gì"), chỉ dò Lightness sao cho tổng 3 kênh RỚT ĐÚNG một mức chung cho mọi họ (-50 ⇒
       ~92, -100 ⇒ ~170, chênh lệch thật giữa họ sáng nhất/tối nhất chỉ 1 đơn vị — xem ca ⑬ goi85,
       ngưỡng chốt cứng ≤40). CHỮ (700/800/900) giữ NGUYÊN giá trị VÒNG 2 — tương phản với nền mới
       vẫn ≥5,1:1 (đo lại, xem chú thích trên), không cần đổi. */
    --c-red-50: 72 10 10;
    --c-red-100: 116 27 27;
    --c-red-200: 52 7 7;
    --c-red-600: 229 93 93; /* T-9 VIỆC A (v1.87+) — = #E55D5D, LẬT vai trò CHỮ/VIỀN. Giữ Hue+Saturation
       của #DC2626, nâng Lightness tới giá trị ĐẦU TIÊN đạt ≥5,0:1 trên 5 nền tối trung tính (64/72
       lượt đo thật, xem docs §3.29): #171A20(5,03) · #15171D(5,17) · #121519(5,28) · #14161C(5,21) ·
       #0F1115(5,45). CỐ Ý bỏ qua 8 lượt trên nền CÓ SẮC (#741B1B/#480A0A/#12182D/#1A0939/#023327) —
       ép đạt cả nền đó thì phải nhạt tới #EC8B8B, mất hẳn tính báo động. --c-red-strong (nền đặc
       mang chữ trắng) KHÔNG khai lại ở đây — xem chú thích ở :root trần. */
    --c-red-700: 252 165 165;
    --c-red-800: 254 202 202;
    --c-red-900: 254 226 226; /* AttentionPanel không dùng text-red-900 (đã grep) — vẫn khai đủ cho nhất quán 5 họ */
    --c-blue-50: 15 23 53;
    --c-blue-100: 23 44 104;
    --c-blue-200: 11 17 38;
    --c-blue-600: 86 134 239; /* T-9 ĐỢT 2 (v1.88+) — = #5686EF, LẬT vai trò CHỮ/VIỀN. Giữ Hue+Saturation
       của #2563EB, nâng Lightness tới giá trị ĐẦU TIÊN đạt ≥5,0:1 trên 5 nền tối trung tính (xem
       docs §3.29 đợt 2). --c-blue-strong (nền đặc mang chữ trắng) KHÔNG khai lại ở đây — xem chú
       thích ở :root trần. */
    --c-blue-700: 147 197 253;
    --c-blue-800: 191 219 254;
    --c-blue-900: 219 234 254;
    --c-violet-50: 26 9 57;
    --c-violet-100: 51 19 100;
    --c-violet-200: 19 6 41;
    --c-violet-600: 159 111 242; /* T-9 ĐỢT 2 (v1.88+) — = #9F6FF2, LẬT vai trò CHỮ/VIỀN. Giữ Hue+Saturation
       của #7C3AED, nâng Lightness tới giá trị ĐẦU TIÊN đạt ≥5,0:1 trên 5 nền tối trung tính (xem
       docs §3.29 đợt 2). --c-violet-strong (nền đặc mang chữ trắng) KHÔNG khai lại ở đây — xem chú
       thích ở :root trần. */
    --c-violet-700: 196 181 253;
    --c-violet-800: 221 214 254;
    --c-violet-900: 237 233 254;
    --c-amber-50: 65 24 3;
    --c-amber-100: 108 48 14;
    --c-amber-200: 47 17 2;
    --c-amber-700: 252 211 77;
    --c-amber-800: 253 230 138;
    --c-amber-900: 254 243 199; /* AttentionPanel: TIÊU ĐỀ thẻ vàng (level="yellow") — đúng thẻ chủ chụp */
    --c-emerald-50: 2 51 39;
    --c-emerald-100: 7 93 70;
    --c-emerald-200: 1 37 28;
    --c-emerald-700: 110 231 183;
    --c-emerald-800: 167 243 208;
    --c-emerald-900: 209 250 229; /* AttentionPanel: TIÊU ĐỀ thẻ lục (level="green") */

    /* T-5 — họ CAM, cùng phép tính ⑬ (HSL giữ Hue+Saturation gốc, dò Lightness cho tổng 3 kênh
       rớt đúng mức chung: -50⇒92, -100⇒170, -200⇒66, y hệt 5 họ trên). CHỮ (700/800/900) = giá
       trị Tailwind gốc orange-300/200/100 (lật thang, giống cách làm của 5 họ). */
    --c-orange-50: 61 22 9;
    --c-orange-100: 113 41 16;
    --c-orange-200: 44 16 6;
    --c-orange-700: 253 186 116;
    --c-orange-800: 254 215 170;
    --c-orange-900: 255 237 213;

    /* T-6 — BA họ mới, cùng phép tính ⑬ của goi85 (giữ Hue gốc từng họ, dò Saturation/Lightness
       cho tổng 3 kênh rớt đúng mức chung: -50⇒91–92, -100⇒170, -200⇒65–66, y hệt 6 họ trên).
       CHỮ (700/800/900) = giá trị Tailwind gốc <họ>-300/200/100 (lật thang, giống 6 họ trên).
       🚨 green cố ý dùng saturation THẤP hơn giá trị "giữ nguyên S gốc theo shade" (S≈0,62 thay vì
       ~0,74+) — ở saturation cao hơn, kênh G (trọng số lớn nhất trong công thức WCAG) kéo độ sáng
       nền lên gần độ sáng chữ (cùng là màu lục) và tương phản rớt DƯỚI 4,5:1 (đã đo: 4,14:1 ở
       green-700 tối trên green-100 tối) — hạ saturation nền xuống ~0,62 giữ đúng mọi mức chung mà
       tương phản thấp nhất vẫn 5,07:1 (ca ⑫ goi85, gần bằng mức thấp nhất của emerald 5,17:1). */
    --c-green-50: 12 53 26;
    --c-green-100: 23 98 49;
    --c-green-200: 9 38 19;
    --c-green-700: 86 239 172;
    --c-green-800: 187 247 208;
    --c-green-900: 220 252 231;
    --c-yellow-50: 47 43 2;
    --c-yellow-100: 88 81 1;
    --c-yellow-200: 35 31 0;
    --c-yellow-700: 253 224 71;
    --c-yellow-800: 254 240 138;
    --c-yellow-900: 254 249 195;
    --c-slate-50: 18 31 43;
    --c-slate-100: 34 57 79;
    --c-slate-200: 15 21 30;
    /* T-7 (§3.27 mục B) — BA bậc MỞ RỘNG slate. -300/-400 GIỮ NGUYÊN giá trị SÁNG ở nền tối (đã tự
       đạt ≥4,5:1 làm CHỮ/VIỀN trên nền thẻ tối #171A20 — đo 11,74:1 và 6,80:1, xem bảng đo mục A
       của đề bài — không cần lật thang). -600 LẬT sang giá trị SÁNG của -400 (mirror 1000−600=400,
       cùng khuôn 700/800/900 phía dưới) vì #475569 nguyên bản chỉ đạt 2,30:1: 71,85,105 → 148,163,184
       nâng lên 6,80:1. */
    --c-slate-300: 203 213 225;
    --c-slate-400: 148 163 184;
    --c-slate-600: 148 163 184;
    --c-slate-700: 203 213 225;
    --c-slate-800: 226 232 240;
    --c-slate-900: 241 245 249;

    /* T-6 — hai biến lẻ (đề bài mục B): --c-hairline bám mức "VIỀN" chung (-200 ⇒ ~65, giữ tông
       xanh-xám gốc của #eef2f7); --c-surface-alt bám mức "NỀN thẻ" chung (-50 ⇒ ~93, xám trung
       tính vì #fafafa vốn không có hue — S=0). */
    --c-hairline: 14 21 30;
    --c-surface-alt: 31 31 31;
    /* T-7 (§3.27 mục C) — --c-sky-track bám mức "NỀN -100" chung (~170, tính bằng HSL giữ Hue+
       Saturation gốc của #e0f2fe, dò Lightness — cùng phép tính ⑬ dùng cho 9 họ ngữ nghĩa). */
    --c-sky-track: 3 64 104;
  }
}
/* ---- NỀN TỐI khi người dùng BẤM nút 3 nấc (kl-theme.js gán data-theme="dark" lên <html>) ---
   LẶP LẠI Y HỆT khối @media ở trên theo chủ ý (CLAUDE.md quy định "để nút đè thắng cả hai
   chiều") — KHÔNG gộp bằng cách import biến, giữ hai khối tường minh để đọc độc lập được. */
:root[data-theme="dark"] {
  --c-white: 23 26 32;
  --c-black: 0 0 0;
  --c-gray-50: 15 17 21;
  --c-gray-100: 34 38 45;
  --c-gray-200: 46 51 59;
  --c-gray-300: 153 158 168;
  --c-gray-400: 168 174 184;
  --c-gray-500: 184 189 199;
  --c-gray-600: 199 203 212;
  --c-gray-700: 213 217 225;
  --c-gray-800: 226 229 235;
  --c-gray-900: 240 239 236;

  /* T-2 — LẶP LẠI Y HỆT khối @media ở trên (nút đè phải thắng cả hai chiều — xem chú thích ở
     khối @media). */
  --c-red-50: 72 10 10;
  --c-red-100: 116 27 27;
  --c-red-200: 52 7 7;
  --c-red-600: 229 93 93; /* T-9 VIỆC A — LẶP LẠI Y HỆT khối @media ở trên */
  --c-red-700: 252 165 165;
  --c-red-800: 254 202 202;
  --c-red-900: 254 226 226;
  --c-blue-50: 15 23 53;
  --c-blue-100: 23 44 104;
  --c-blue-200: 11 17 38;
  --c-blue-600: 86 134 239; /* T-9 ĐỢT 2 — LẶP LẠI Y HỆT khối @media ở trên */
  --c-blue-700: 147 197 253;
  --c-blue-800: 191 219 254;
  --c-blue-900: 219 234 254;
  --c-violet-50: 26 9 57;
  --c-violet-100: 51 19 100;
  --c-violet-200: 19 6 41;
  --c-violet-600: 159 111 242; /* T-9 ĐỢT 2 — LẶP LẠI Y HỆT khối @media ở trên */
  --c-violet-700: 196 181 253;
  --c-violet-800: 221 214 254;
  --c-violet-900: 237 233 254;
  --c-amber-50: 65 24 3;
  --c-amber-100: 108 48 14;
  --c-amber-200: 47 17 2;
  --c-amber-700: 252 211 77;
  --c-amber-800: 253 230 138;
  --c-amber-900: 254 243 199;
  --c-emerald-50: 2 51 39;
  --c-emerald-100: 7 93 70;
  --c-emerald-200: 1 37 28;
  --c-emerald-700: 110 231 183;
  --c-emerald-800: 167 243 208;
  --c-emerald-900: 209 250 229;

  /* T-5 — LẶP LẠI Y HỆT khối @media ở trên (nút đè phải thắng cả hai chiều). */
  --c-orange-50: 61 22 9;
  --c-orange-100: 113 41 16;
  --c-orange-200: 44 16 6;
  --c-orange-700: 253 186 116;
  --c-orange-800: 254 215 170;
  --c-orange-900: 255 237 213;

  /* T-6 — LẶP LẠI Y HỆT khối @media ở trên (nút đè phải thắng cả hai chiều). */
  --c-green-50: 12 53 26;
  --c-green-100: 23 98 49;
  --c-green-200: 9 38 19;
  --c-green-700: 86 239 172;
  --c-green-800: 187 247 208;
  --c-green-900: 220 252 231;
  --c-yellow-50: 47 43 2;
  --c-yellow-100: 88 81 1;
  --c-yellow-200: 35 31 0;
  --c-yellow-700: 253 224 71;
  --c-yellow-800: 254 240 138;
  --c-yellow-900: 254 249 195;
  --c-slate-50: 18 31 43;
  --c-slate-100: 34 57 79;
  --c-slate-200: 15 21 30;
  /* T-7 — LẶP LẠI Y HỆT khối @media ở trên (nút đè phải thắng cả hai chiều). */
  --c-slate-300: 203 213 225;
  --c-slate-400: 148 163 184;
  --c-slate-600: 148 163 184;
  --c-slate-700: 203 213 225;
  --c-slate-800: 226 232 240;
  --c-slate-900: 241 245 249;
  --c-hairline: 14 21 30;
  --c-surface-alt: 31 31 31;
  --c-sky-track: 3 64 104;
}
/* color-scheme: theo máy mặc định; nút 3 nấc (kl-theme.js) ghi đè khi có data-theme rõ ràng —
   giúp control gốc trình duyệt (thanh cuộn, ô nhập, ô chọn ngày…) cũng đổi màu theo, không chỉ
   nội dung của app. */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
html { height: 100%; }
/* Vertical-only scroll lock (mobile): hết rubber-band + pull-to-refresh trên toàn cục. */
html, body { overscroll-behavior: none; }
body {
  height: 100%; margin: 0; padding: 0; overflow: hidden;
  touch-action: pan-y;            /* chỉ pan dọc; chặn double-tap zoom (pinch đã tắt ở viewport) */
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-tap-highlight-color: transparent;
}
#root { height: 100%; }
/* T-1 VÒNG 2 (F1) — token hoá NGAY nền lớp .kl-app-shell (khoá này thuộc kl-base.css, LÀN GIAO
   DIỆN CHUNG). 🚨 SỰ THẬT phải nói rõ trong báo cáo: cả 5 app đều RENDER shell qua
   `className:"kl-app-shell"` KÈM `style={{background:"..."}}` NỘI TUYẾN ngay trong app-*.js
   (app-quanly.js dòng 5814/5837, app-admin.js dòng 4879, app-codong.js dòng 1040/1059 đều ghi đè
   "#f9fafb"; app-grafik.js/app-info.js ghi đè "var(--primary-light)") — style nội tuyến LUÔN
   thắng class ⇒ sửa dòng NÀY để đúng kiến trúc/nhất quán, nhưng KHÔNG khiến vỏ 5 app đổi màu trên
   máy thật (vẫn sáng, vì bị inline đè). Sửa 5 chỗ inline đó thuộc app-*.js — NGOÀI LÀN, để dành
   cho lô dọn "LÀN APP" sau (T-1 báo cáo đã nêu, ước lượng ~243 chỗ hex nội tuyến cần dọn). */
.kl-app-shell { height: 100vh; height: 100dvh; overflow: hidden; display: flex; flex-direction: column; background: rgb(var(--c-gray-50)); }
/* Khung cuộn chuẩn: CHỈ dọc, không kéo ngang, không tràn overscroll ra cha. */
.kl-scroll-y { overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; touch-action: pan-y; -webkit-overflow-scrolling: touch; }
/* Loading placeholder (thay style="" nội tuyến trên #root để hợp CSP). */
.kl-loading { padding: 40px; text-align: center; color: rgb(var(--c-gray-400)); font-family: system-ui, sans-serif; font-size: 13px; }
@keyframes kl-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }
.kl-pulse { animation: kl-pulse 1.5s ease-in-out infinite; }
@keyframes kl-toast-in { from { transform: translateX(110%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.kl-toast { animation: kl-toast-in 220ms ease-out; }
@keyframes kl-fade-in { from { opacity: 0; } to { opacity: 1; } }
.kl-fade { animation: kl-fade-in 180ms ease-out; }
@keyframes kl-pop-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.kl-pop { animation: kl-pop-in 220ms ease-out; }
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; }
.kl-focus:focus { outline: none; box-shadow: 0 0 0 3px var(--ring); }
@keyframes kl-spin { to { transform: rotate(360deg); } }
.kl-spin { animation: kl-spin 0.7s linear infinite; }
/* GÓI20 (rà UI/UX 03/08): TÔN TRỌNG "giảm chuyển động" của hệ điều hành. Người bị chóng mặt /
   rối loạn tiền đình bật công tắc này ở iOS (Trợ năng → Chuyển động) hoặc Android; trước đây app
   vẫn quay/nhấp nháy y nguyên. Vòng quay của nút "đang tải" GIỮ LẠI nhưng chậm hẳn (2,4s) — tắt
   hẳn thì mất luôn tín hiệu "máy đang chạy", còn tệ hơn. */
@media (prefers-reduced-motion: reduce) {
  .kl-pulse, .kl-toast, .kl-fade, .kl-pop { animation: none !important; }
  .kl-spin { animation-duration: 2.4s; }
  * { scroll-behavior: auto !important; }
}
/* GÓI25 (v1.25.0, lệnh chủ 04/08) — NGUYÊN NHÂN GỐC của lỗi "zoom loạn cả 3 app" (khoá viewport ở
   v1.24.0 chỉ vá TRIỆU CHỨNG, không vá gốc): iOS Safari TỰ ĐỘNG phóng to trang khi người dùng chạm
   vào input/select/textarea có cỡ chữ TÍNH RA nhỏ hơn 16px — hành vi cố hữu của iOS, không phải lỗi
   của ta. Cả 4 app đều dùng class Tailwind `text-sm` (=14px) cho ô nhập ⇒ mỗi lần bấm vào ô tiền/ô
   chọn tháng là trang phóng to, và Safari NHỚ mức phóng đó theo từng trang ⇒ tắt app mở lại vẫn
   phóng ⇒ đúng hiện tượng "hỗn loạn" chủ báo. Từ iOS 10, Safari CỐ Ý bỏ qua user-scalable=no /
   maximum-scale=1 (lý do khả năng tiếp cận) nên khoá viewport KHÔNG chữa được — cách chữa DUY NHẤT
   đáng tin, không phụ thuộc phiên bản iOS, là ép sàn chữ mọi ô có thể bấm vào lên ĐÚNG 16px.
   BẪY ĐỘ ƯU TIÊN: class `text-sm` của Tailwind có độ ưu tiên (0,1,0); bộ chọn trần `input{}` chỉ
   (0,0,1) sẽ THUA. Bộ chọn dưới đây dùng `[class]` để nâng lên (0,1,1) mới đè được.
   CẤM hạ xuống dưới 16px vì bất kỳ lý do gì (kể cả "cho đẹp hơn") — hạ là lỗi tự phóng của iOS quay
   lại y nguyên. Không giới hạn bằng @media theo bề ngang màn hình — máy tính bảng / xoay ngang /
   chia đôi màn hình đều phải được che, và 16px trên máy tính cũng không xấu. */
input[class], select[class], textarea[class] {
  font-size: 16px;
}
input[type=hidden][class],
input[type=file][class],
input[type=checkbox][class],
input[type=radio][class] {
  font-size: inherit; /* các loại này không gây iOS tự phóng; ép 16px chỉ phá giao diện vô ích */
}
