/* =====================================================================
   VINAMEDICAL — Design Tokens
   Toàn bộ biến nền tảng: màu, chữ, khoảng cách, bo góc, đổ bóng, chuyển động.
   Mọi file CSS khác CHỈ được dùng biến khai báo ở đây, không hard-code màu.
   ===================================================================== */

:root {
  /* ---------- 1. Thang màu thương hiệu ---------- */

  /* Primary — "Vina Blue": phát triển từ mã nhận diện gốc #099DCA */
  --vm-primary-50:  #eaf7fc;
  --vm-primary-100: #cdedf8;
  --vm-primary-200: #9fdcf1;
  --vm-primary-300: #66c6e7;
  --vm-primary-400: #2faeda;
  --vm-primary-500: #0c9dcb;
  /* R4 — Nấc chèn giữa 500 và 600, sinh ra cho --vm-grad-brand-indicator.
     Lý do phải có nó: vạch chỉ báo trạng thái nằm trên thẻ đã nhuộm nhẹ màu
     thương hiệu (#f3f9fb, L = 0.93771), nên muốn đạt 3:1 thì độ chói của nó
     phải ≤ 0.27924. primary-500 (L = 0.28504) hụt đúng 2% — sát đến mức bực
     mình nhưng vẫn là hụt (2.95:1). #0b96c4 có L = 0.25869 ⇒ 3.20:1, mà chênh
     độ sáng cảm nhận với primary-500 chỉ ΔL* ≈ 0.9 — mắt gần như không phân
     biệt được, tức là mua được sự tuân thủ gần như miễn phí về thẩm mỹ. */
  --vm-primary-550: #0b96c4;
  --vm-primary-600: #0a7ea6;
  --vm-primary-700: #0c6482;
  --vm-primary-800: #10516a;
  --vm-primary-900: #123f52;
  --vm-primary-950: #0a2733;

  /* R1 — Nấc "ĐỒNG ĐỘ CHÓI" (iso-luminant) của primary-600, KHÔNG phải một nấc
     sáng-tối của thang. Đọc kỹ chỗ này trước khi sửa: mọi nấc khác trong thang
     khác nhau ở ĐỘ SÁNG, riêng nấc này cố ý có ĐÚNG độ chói của primary-600
     (L = 0.17484 so với 0.17739) và chỉ khác SẮC ĐỘ — xanh biển 209° thay vì
     xanh ngọc 194°. Sinh ra để --vm-grad-brand ở chế độ tối vẫn "chuyển màu"
     nhìn thấy được mà không xê dịch độ chói ra khỏi khe hợp lệ cực hẹp
     [0.15561 – 0.18333]. Vì sao khe hẹp đến thế, xem --vm-grad-brand ở khối tối. */
  --vm-primary-600-azure: #0b76ce;

  /* Accent — "Vina Red": phát triển từ mã nhận diện gốc #BF1F3C */
  --vm-accent-50:  #fdf2f5;
  --vm-accent-100: #fce3e9;
  --vm-accent-200: #f9c7d3;
  --vm-accent-300: #f296ab;
  --vm-accent-400: #e85f7e;
  --vm-accent-500: #d93659;
  /* R2 — Nấc chèn giữa 500 và 600, sinh ra RIÊNG cho --vm-cta-hover ở chế độ tối.
     Khác accent-600 ở chỗ nó đậm hơn accent-500 bằng ĐỘ BÃO HOÀ chứ không bằng
     độ chói: L = 0.16660, chỉ thấp hơn accent-500 (0.18111) đúng 8%, trong khi
     accent-600 tụt xuống 0.12383 — mức tụt đó chính là thứ làm thân nút chìm vào
     nền tối. Xem --vm-cta-hover ở khối chế độ tối để biết vì sao không thể đi
     theo hướng "hover thì sáng lên" quen thuộc. */
  --vm-accent-550: #e01046;
  --vm-accent-600: #bf1f3c;
  --vm-accent-700: #a0182f;
  --vm-accent-800: #85182b;
  --vm-accent-900: #711829;
  --vm-accent-950: #3f0912;

  /* Neutral — xám lạnh ngả xanh, hợp tông y tế */
  --vm-neutral-0:   #ffffff;
  --vm-neutral-50:  #f7f9fb;
  --vm-neutral-100: #eff3f7;
  --vm-neutral-200: #e1e8ef;
  --vm-neutral-300: #cbd6e0;
  --vm-neutral-400: #9aaabc;
  --vm-neutral-500: #6d8095;
  --vm-neutral-550: #5e7188;
  --vm-neutral-600: #4f627a;
  /* B5 — Nấc chèn thêm giữa 600 và 700. Sinh ra để tách hai lớp chữ phụ:
     trước đây --vm-text-soft và --vm-text-muted CÙNG trỏ về neutral-600 nên ở
     chế độ sáng hai lớp trùng khít (1.00:1), 10 thành phần BEM dùng cả hai
     mất hẳn phân cấp. Xem giải thích đầy đủ ở --vm-text-soft bên dưới. */
  --vm-neutral-650: #3f4e63;
  --vm-neutral-700: #3c4c61;
  --vm-neutral-800: #2a3746;
  --vm-neutral-900: #1b2530;
  --vm-neutral-950: #0e151d;

  /* Màu ngữ nghĩa */
  --vm-success-50:  #ecfdf5;
  --vm-success-500: #10b981;
  --vm-success-600: #059669;
  --vm-success-700: #047857;
  --vm-warning-50:  #fffbeb;
  --vm-warning-500: #f59e0b;
  --vm-warning-600: #d97706;
  --vm-warning-700: #b45309;
  --vm-danger-50:   #fef2f2;
  --vm-danger-500:  #ef4444;
  --vm-danger-600:  #dc2626;
  --vm-danger-700:  #b91c1c;
  --vm-info-50:     #eff6ff;
  --vm-info-500:    #3b82f6;
  --vm-info-600:    #2563eb;

  /* ---------- 2. Vai trò màu (light mode mặc định) ---------- */
  --vm-bg:            var(--vm-neutral-0);
  --vm-bg-subtle:     var(--vm-neutral-50);
  --vm-bg-muted:      var(--vm-neutral-100);
  --vm-bg-inverse:    var(--vm-neutral-950);
  --vm-surface:       var(--vm-neutral-0);
  --vm-surface-2:     var(--vm-neutral-50);
  --vm-surface-hover: var(--vm-neutral-100);

  --vm-text:          var(--vm-neutral-900);
  /* B5 — Trước đây soft VÀ muted cùng trỏ neutral-600 ⇒ trùng khít 1.00:1 ở chế độ
     sáng. Không thể sửa bằng cách kéo muted SÁNG LÊN: muốn muted đạt AA 4.5:1 trên
     --vm-bg-muted (#eff3f7, L=0.8917) thì độ chói của nó phải ≤ 0.1593, còn muốn
     nó nhạt hơn soft (#4f627a, L=0.1180) tối thiểu 1.3:1 thì phải ≥ 0.1684 —
     hai điều kiện loại trừ nhau, VÔ NGHIỆM. Nên phải đi hướng ngược lại: giữ
     nguyên muted (đã đạt AA) và ĐẨY SOFT ĐẬM THÊM một nấc. Soft là lớp chữ nổi
     hơn (thân bài, .vm-lead) nên đậm thêm vừa đúng vai trò vừa chỉ tăng tương phản.
     #3f4e63: 8.46:1 trên trắng, 7.59:1 trên #eff3f7, 8.02:1 trên #f7f9fb. */
  --vm-text-soft:     var(--vm-neutral-650);
  /* Giữ nguyên neutral-600 (#4f627a) — đợt trước nâng từ #5e7188 lên là ĐÚNG:
     #5e7188 chỉ đạt 4.49:1 trên #eff3f7, hụt AA. #4f627a đạt 6.25:1 trên trắng,
     5.92:1 trên #f7f9fb, 5.60:1 trên #eff3f7, 5.06:1 trên #e1e8ef.
     Chênh với --vm-text-soft nay là 1.35:1 — đủ để mắt thấy hai lớp khác nhau. */
  --vm-text-muted:    var(--vm-neutral-600);
  --vm-text-inverse:  var(--vm-neutral-0);
  --vm-text-on-brand: #ffffff;  /* trắng / --vm-brand (#0a7ea6) = 4.62:1 — đạt AA */
  --vm-text-on-deep:  #eaf3f8;  /* chữ trên nền xanh đậm (.vm-section--dark, hero trang con) */
  /* 0.82 chứ không phải 0.78: nền khó nhất của --vm-grad-deep là điểm dừng sáng
     nhất #0c6482, và ở mức mờ 0.78 chữ hoà ra chỉ đạt 4.27:1 — hụt ngưỡng AA
     4.5. Nâng lên 0.82 cho 4.54:1. Đây là mức nhỏ nhất đủ đạt, giữ được nhiều
     nhất sự khác biệt so với --vm-text-on-deep đặc ở trên. */
  --vm-text-on-deep-soft: rgba(234, 243, 248, 0.82);

  --vm-border:        var(--vm-neutral-200);
  --vm-border-strong: var(--vm-neutral-300);
  --vm-border-subtle: var(--vm-neutral-100);

  --vm-brand:         var(--vm-primary-600);
  --vm-brand-hover:   var(--vm-primary-700);
  --vm-brand-soft:    var(--vm-primary-50);
  --vm-brand-ring:    color-mix(in srgb, var(--vm-primary-500) 40%, transparent);
  /* Tách vai trò: --vm-brand dùng cho NỀN/viền, --vm-brand-text dùng khi màu
     thương hiệu làm MÀU CHỮ. Lý do: #0a7ea6 chỉ đạt 4.62:1 trên nền trắng nhưng
     rớt xuống 4.38:1 trên #f7f9fb, 4.22:1 trên #eaf7fc, 4.14:1 trên #eff3f7 —
     tức là hỏng ngay khi khối được tô nền nhạt. #0c6482 đạt 6.64 / 6.30 / 6.08 / 5.96. */
  --vm-brand-text:    var(--vm-primary-700);

  --vm-cta:           var(--vm-accent-600);
  --vm-cta-hover:     var(--vm-accent-700);
  --vm-cta-soft:      var(--vm-accent-50);
  /* Tách vai trò giống trên: --vm-cta cho NỀN nút, --vm-cta-text cho MÀU CHỮ.
     Ở chế độ sáng hai giá trị trùng nhau (#bf1f3c đạt 6.04:1 trên trắng,
     5.42:1 trên #eff3f7) nên hình thức không đổi; việc tách chỉ có tác dụng
     ở chế độ tối, nơi --vm-cta phải sáng lên để làm nền mà chữ thì không theo kịp. */
  --vm-cta-text:      var(--vm-accent-600);
  /* B4 — Màu chữ NẰM TRÊN nền --vm-cta. Trước đây components.css ghi cứng #fff
     nên không ai kiểm soát được. Lưu ý: biến này KHÔNG lật theo chế độ, khác hẳn
     --vm-text-on-brand. Lý do là hai thang màu hành xử khác nhau: ở chế độ tối
     --vm-brand nhảy lên #2faeda rất sáng khiến chữ trắng chỉ còn 2.56:1 (buộc
     phải lật sang chữ tối), còn --vm-cta chỉ lên tới #d93659 — chữ trắng vẫn đạt
     4.54:1. Thử lật sang chữ tối ở chế độ tối còn tệ hơn: #3f0912 trên #d93659
     chỉ được 3.67:1. Nên trắng là đáp án đúng cho CẢ HAI chế độ. */
  --vm-text-on-cta:   #ffffff;
  /* R3 — Màu chữ/biểu tượng NẰM TRÊN nền --vm-grad-brand. Trước đây components.css
     ghi cứng #fff ở hai lớp nút nên nằm ngoài hệ token, không ai kiểm được.
     ĐỪNG thay bằng --vm-text-on-brand: hai biến này trông giống nhau nhưng lật
     theo hai luật khác hẳn. --vm-text-on-brand phải lật sang chữ TỐI ở chế độ
     tối vì --vm-brand nhảy lên #2faeda rất sáng; còn --vm-grad-brand thì ở CẢ HAI
     chế độ đều được thiết kế quanh độ chói của primary-600 nên trắng luôn là đáp
     án đúng — thử chữ tối #0a2733 trên điểm dừng sáng nhất chỉ được 3.37:1.
     Vì vậy biến này cố ý KHÔNG có bản khai lại ở hai khối tối. */
  --vm-text-on-grad-brand: #ffffff;

  /* Nền mềm của khung hội thoại trợ lý — trước đây tro-ly.css gọi
     --vm-surface-soft nhưng biến này chưa từng được khai báo ở đâu. */
  --vm-surface-soft:  var(--vm-neutral-50);

  --vm-link:          var(--vm-primary-700);
  --vm-link-hover:    var(--vm-accent-600);

  /* Nền phủ / kính mờ */
  --vm-overlay:       color-mix(in srgb, var(--vm-neutral-950) 55%, transparent);
  --vm-glass:         color-mix(in srgb, var(--vm-neutral-0) 72%, transparent);
  --vm-glass-border:  color-mix(in srgb, var(--vm-neutral-0) 55%, transparent);

  /* Gradient dùng lại nhiều nơi */
  /* B2 — Dải thương hiệu dùng làm NỀN cho khối có chữ hoặc biểu tượng trắng.
     Bản cũ (600 → 500 → 400) kết thúc ở #2faeda: chữ trắng chỉ còn 2.56:1.
     Nội suy 101 điểm dọc trục thì 98 điểm rớt AA 4.5:1 (rớt ngay từ điểm thứ 3)
     và 44 điểm rớt cả ngưỡng 3:1 — tức gần như MỌI điểm trên nút đều hỏng, bất
     kể góc 135deg đặt trục ở đâu. Hạ cả ba điểm dừng xuống 800 → 700 → 600:
     điểm sáng nhất nay là #0a7ea6, đúng bằng --vm-brand, nên chữ trắng đạt tối
     thiểu 4.62:1 và 0/101 điểm rớt AA. Đây là mặc định AN TOÀN — đặt bất cứ nội
     dung trắng nào lên cũng đạt chuẩn, không cần nhớ chọn biến nào. */
  --vm-grad-brand:  linear-gradient(135deg, var(--vm-primary-800) 0%, var(--vm-primary-700) 45%, var(--vm-primary-600) 100%);
  /* Bản rực rỡ giữ nguyên dải cũ. CHỈ dùng cho trang trí thuần không có gì đè
     lên: vạch nhấn 3–4px, rèm che ảnh. Không có nội dung thì không có nghĩa vụ
     tương phản, nên giữ được nét xanh sáng của nhận diện. */
  --vm-grad-brand-vivid: linear-gradient(135deg, var(--vm-primary-600) 0%, var(--vm-primary-500) 45%, var(--vm-primary-400) 100%);
  /* R4 — Biến thể của -vivid dành cho vạch/nét MANG Ý NGHĨA (chỉ báo trạng thái
     "đang chọn"), khác với -vivid là trang trí thuần. Ranh giới giữa hai biến
     chính là chỗ WCAG 1.4.11 bắt đầu có hiệu lực: trang trí thì không có nghĩa
     vụ tương phản, còn thứ dùng để NHẬN BIẾT TRẠNG THÁI thì phải đạt 3:1.
     Đánh đổi: điểm dừng sáng nhất hạ từ primary-400 (#2faeda, chỉ đạt 2.41:1
     trên thẻ đã nhuộm #f3f9fb) xuống primary-550 (#0b96c4 ⇒ 3.20:1). Chấp nhận
     mất ΔL* ≈ 6.7 ở đầu sáng để giữ được đúng chất xanh rực của nhận diện —
     đây là mức hạ NHỎ NHẤT còn đạt chuẩn, vì primary-500 hụt sát nút (2.95:1).
     Vì sao chỉ có HAI điểm dừng mà không giữ ba như -vivid: vạch này phải đạt
     3:1 ở CẢ HAI chế độ, mà hai chế độ kẹp nó từ hai phía ngược nhau — nền sáng
     đặt TRẦN độ chói 0.27924, nền tối đặt SÀN 0.15139. Thêm một điểm dừng tối
     hơn (primary-700, L = 0.10804) thì chế độ sáng vẫn đạt nhưng chế độ tối rớt
     31/101 điểm (thấp nhất 2.35:1). Dải 600 → 550 nằm gọn trong khe đó:
     0/101 điểm rớt ở cả hai chế độ (thấp nhất 3.20 sáng / 3.39 tối). */
  --vm-grad-brand-indicator: linear-gradient(135deg, var(--vm-primary-600) 0%, var(--vm-primary-550) 100%);
  /* B3 — Dải dùng để TÔ CHỮ (background-clip: text). Ở đây dải chính là màu chữ
     nên phải tương phản với NỀN TRANG — ngược hẳn hai biến trên. Chế độ sáng
     trùng --vm-grad-brand: tối thiểu 4.62:1 trên nền trắng, 0/101 điểm rớt.
     Chế độ tối phải lật sang nấc sáng, xem hai khối dark ở cuối tệp. */
  --vm-grad-brand-text: linear-gradient(135deg, var(--vm-primary-800) 0%, var(--vm-primary-700) 45%, var(--vm-primary-600) 100%);
  --vm-grad-cta:    linear-gradient(135deg, var(--vm-accent-600) 0%, var(--vm-accent-500) 100%);
  --vm-grad-deep:   linear-gradient(135deg, var(--vm-primary-950) 0%, var(--vm-primary-800) 55%, var(--vm-primary-700) 100%);
  --vm-grad-sheen:  linear-gradient(120deg, transparent 15%, color-mix(in srgb, #fff 55%, transparent) 50%, transparent 85%);

  /* ---------- 3. Kiểu chữ ---------- */
  --vm-font-display: 'Be Vietnam Pro', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --vm-font-body:    'Inter', 'Be Vietnam Pro', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --vm-font-mono:    ui-monospace, 'JetBrains Mono', 'Cascadia Code', Consolas, monospace;

  /* Thang cỡ chữ co giãn theo màn hình */
  --vm-text-2xs:  0.6875rem;                            /* 11px */
  --vm-text-xs:   0.75rem;                              /* 12px */
  --vm-text-sm:   0.875rem;                             /* 14px */
  --vm-text-base: 1rem;                                 /* 16px */
  --vm-text-md:   clamp(1.0625rem, 0.2vw + 1rem, 1.125rem);
  --vm-text-lg:   clamp(1.125rem, 0.4vw + 1rem, 1.3125rem);
  --vm-text-xl:   clamp(1.3125rem, 0.7vw + 1.1rem, 1.625rem);
  --vm-text-2xl:  clamp(1.5rem, 1.1vw + 1.2rem, 2rem);
  --vm-text-3xl:  clamp(1.75rem, 1.8vw + 1.3rem, 2.5rem);
  --vm-text-4xl:  clamp(2.125rem, 2.8vw + 1.4rem, 3.25rem);
  --vm-text-5xl:  clamp(2.5rem, 4vw + 1.5rem, 4.25rem);

  --vm-leading-tight:   1.12;
  --vm-leading-snug:    1.28;
  --vm-leading-normal:  1.7;   /* tối thiểu cho tiếng Việt có dấu */
  --vm-leading-relaxed: 1.85;

  --vm-tracking-tight: -0.02em;
  --vm-tracking-snug:  -0.011em;
  --vm-tracking-wide:  0.02em;
  --vm-tracking-caps:  0.09em;

  --vm-weight-normal: 400;
  --vm-weight-medium: 500;
  --vm-weight-semi:   600;
  --vm-weight-bold:   700;
  --vm-weight-black:  800;

  /* ---------- 4. Khoảng cách (thang 4px) ---------- */
  --vm-space-1:  0.25rem;
  --vm-space-2:  0.5rem;
  --vm-space-3:  0.75rem;
  --vm-space-4:  1rem;
  --vm-space-5:  1.25rem;
  --vm-space-6:  1.5rem;
  --vm-space-7:  1.75rem;
  --vm-space-8:  2rem;
  --vm-space-10: 2.5rem;
  --vm-space-12: 3rem;
  --vm-space-14: 3.5rem;
  --vm-space-16: 4rem;
  --vm-space-20: 5rem;
  --vm-space-24: 6rem;
  --vm-space-32: 8rem;

  /* Khoảng cách dọc giữa các section, co theo màn hình */
  --vm-section-y: clamp(3.5rem, 6vw, 6.5rem);
  --vm-section-y-sm: clamp(2.5rem, 4vw, 4rem);

  /* ---------- 5. Bố cục ---------- */
  --vm-container: 1280px;
  --vm-container-narrow: 920px;
  --vm-container-wide: 1480px;
  --vm-gutter: clamp(1rem, 3vw, 2rem);
  --vm-header-h: 76px;
  --vm-header-h-scrolled: 64px;
  --vm-topbar-h: 40px;

  /* Vùng chạm tối thiểu. WCAG 2.2 AA (2.5.8) bắt buộc 24×24; 44×44 là mức
     khuyến nghị thực hành, dùng làm chuẩn chung cho mọi nút nhỏ. */
  --vm-tap-min: 44px;

  /* Bề ngang nút mở trợ lý. Nút "lên đầu trang" phải né đúng con số này,
     nếu hai chỗ lệch nhau thì hai nút nổi chồng lên nhau. */
  --vm-tl-nut-size: 58px;
  --vm-tl-nut-size-sm: 52px;

  /* ---------- 6. Bo góc ---------- */
  --vm-radius-xs: 4px;
  --vm-radius-sm: 8px;
  --vm-radius-md: 12px;
  --vm-radius-lg: 16px;
  --vm-radius-xl: 22px;
  --vm-radius-2xl: 30px;
  --vm-radius-pill: 999px;
  /* Bo góc riêng cho nhóm điều khiển - ngành y tế chuộng góc chặt */
  --vm-radius-control: 10px;
  --vm-radius-card: 14px;

  /* ---------- 7. Đổ bóng ---------- */
  --vm-shadow-line: 0 0 0 1px rgba(14, 21, 29, 0.07);
  --vm-shadow-xs: 0 1px 2px rgba(14, 21, 29, 0.05);
  --vm-shadow-sm: 0 1px 3px rgba(14, 21, 29, 0.07), 0 1px 2px rgba(14, 21, 29, 0.04);
  --vm-shadow-md: 0 4px 14px rgba(14, 21, 29, 0.08), 0 1px 3px rgba(14, 21, 29, 0.05);
  --vm-shadow-lg: 0 12px 32px rgba(14, 21, 29, 0.10), 0 4px 10px rgba(14, 21, 29, 0.05);
  --vm-shadow-xl: 0 24px 56px rgba(14, 21, 29, 0.14), 0 8px 18px rgba(14, 21, 29, 0.06);
  --vm-shadow-brand: 0 12px 30px color-mix(in srgb, var(--vm-primary-600) 26%, transparent);
  --vm-shadow-cta: 0 12px 30px color-mix(in srgb, var(--vm-accent-600) 28%, transparent);
  --vm-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.6);
  --vm-shadow-focus: 0 0 0 3px color-mix(in srgb, var(--vm-primary-500) 42%, transparent);

  /* ---------- 8. Chuyển động ---------- */
  --vm-dur-fast: 140ms;
  --vm-dur-base: 240ms;
  --vm-dur-slow: 420ms;
  --vm-dur-slower: 720ms;
  --vm-ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --vm-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --vm-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ---------- 9. Lớp chồng ---------- */
  --vm-z-base: 1;
  --vm-z-sticky: 100;
  --vm-z-header: 200;
  --vm-z-dropdown: 300;
  --vm-z-drawer: 400;
  --vm-z-modal: 500;
  --vm-z-toast: 600;
}

/* =====================================================================
   Chế độ tối — chỉ định nghĩa lại các biến vai trò, không đụng thang màu
   ===================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --vm-bg:            var(--vm-neutral-950);
    --vm-bg-subtle:     #121b25;
    --vm-bg-muted:      #17222e;
    --vm-bg-inverse:    var(--vm-neutral-50);
    --vm-surface:       #141e29;
    --vm-surface-2:     #1a2634;
    --vm-surface-hover: #21303f;

    --vm-text:          #e8eef4;
    --vm-text-soft:     #a9bacb;
    --vm-text-muted:    #7e93a8;
    --vm-text-inverse:  var(--vm-neutral-950);
    /* Chế độ tối kéo --vm-brand sáng lên nên chữ TRẮNG trên nền thương hiệu chỉ
       còn 2.56:1. Phải lật ngược: chữ tối trên nền sáng — #0a2733 / #2faeda = 6.06:1. */
    --vm-text-on-brand: var(--vm-primary-950);

    --vm-border:        #253444;
    --vm-border-strong: #33475b;
    --vm-border-subtle: #1c2836;

    --vm-surface-soft:  #121b25;

    --vm-brand:         var(--vm-primary-400);
    --vm-brand-hover:   var(--vm-primary-300);
    --vm-brand-soft:    color-mix(in srgb, var(--vm-primary-500) 16%, transparent);
    /* #66c6e7 đạt 9.44:1 trên --vm-bg, 8.65 trên --vm-surface, 7.88 trên --vm-surface-2. */
    --vm-brand-text:    var(--vm-primary-300);

    --vm-cta:           var(--vm-accent-500);
    /* B4 — Trước đây là --vm-accent-400 (#e85f7e). Hover SÁNG LÊN là quy ước quen
       thuộc ở chế độ tối, nhưng riêng nút CTA thì nó phá tương phản: chữ trắng trên
       #e85f7e chỉ còn 3.30:1, rớt AA, và THẤP HƠN chính lúc nghỉ (4.54:1 trên
       #d93659) — hover càng rõ ý định bấm thì chữ càng khó đọc.
       Đã thử hướng mà --vm-text-on-brand dùng (lật sang chữ tối ở chế độ tối):
       không cứu được, vì #3f0912 trên nền NGHỈ #d93659 chỉ đạt 3.67:1 — vá được
       hover thì vỡ lúc nghỉ. Thang accent khác thang primary ở chỗ đó: chế độ tối
       --vm-brand vọt lên #2faeda rất sáng buộc phải lật chữ, còn --vm-cta dừng ở
       #d93659 nên chữ trắng vẫn là đáp án đúng.
       Cách duy nhất còn lại là cho hover ĐẬM XUỐNG, đúng như chế độ sáng vẫn làm
       (600 → 700). Chế độ tối nay đi 500 → 600: chữ trắng lên 6.04:1, và hover
       tương phản TỐT HƠN lúc nghỉ, thuận chiều kỳ vọng.

       R2 — Đoạn trên đúng về TRỤC CHỮ nhưng sai về TRỤC NỀN, và đây là chỗ sửa lại.
       accent-600 có L = 0.12383, quá tối để thân nút còn tách khỏi nền tối: trên
       .vm-section (#121b25) chỉ còn 2.88:1, trên --vm-surface-2 còn 2.54:1 — tức
       nghịch lý "hover tệ hơn nghỉ" không bị diệt mà chỉ chuyển từ trục chữ sang
       trục nền (nghỉ 3.82 → hover 2.88).
       Ràng buộc thật của nút này ở chế độ tối, khi chữ là trắng:
         chữ trắng đạt 4.5:1  ⇒ L ≤ 0.18333
         thân đạt 3:1 vs --vm-surface-2 (L = 0.018538) ⇒ L ≥ 0.15561
       Cả nghỉ lẫn hover đều phải nằm trong khe [0.15561 – 0.18333]. Khe đó rộng
       ΔL* ≈ 2.9 — DƯỚI ngưỡng mắt người phân biệt được. Kết luận quan trọng cho
       người sửa sau: ở chế độ tối, nút CTA KHÔNG THỂ báo hiệu hover bằng độ sáng
       nền, dù sáng lên hay tối đi. Đừng mất công tìm màu khác, không có.
       Nên hover đi bằng hai thứ còn lại:
       (1) ĐỘ BÃO HOÀ — accent-550 (#e01046, L = 0.16660) đậm đà hơn accent-500 mà
           gần như không đổi độ chói: chữ trắng 4.85:1 (nhỉnh hơn lúc nghỉ 4.54),
           thân 3.16:1 trên --vm-surface-2 và 3.58:1 trên .vm-section — cả hai trục
           nay đều thuận chiều, không còn trục nào tệ đi khi rê chuột;
       (2) VIỀN + nhấc nhẹ — xem .vm-btn--cta:hover trong components.css. Cần (2)
           vì riêng (1) thay đổi quá tinh tế để làm tín hiệu trạng thái. */
    --vm-cta-hover:     var(--vm-accent-550);
    --vm-cta-soft:      color-mix(in srgb, var(--vm-accent-500) 16%, transparent);
    /* #d93659 làm màu chữ trên nền tối chỉ đạt 3.37–4.04:1. #e85f7e đạt 4.65–5.57:1. */
    --vm-cta-text:      var(--vm-accent-400);

    --vm-link:          var(--vm-primary-300);
    --vm-link-hover:    var(--vm-accent-300);

    /* B3 — Chữ tô gradient ở chế độ tối phải lật sang nấc SÁNG, nếu để nguyên
       dải 800/700/600 của chế độ sáng thì chữ gần như tan vào nền (#10516a trên
       --vm-surface #141e29 chỉ 1.93:1). Dải 300 → 400 đạt tối thiểu 6.56:1 trên
       #141e29, 7.16:1 trên --vm-bg, 5.97:1 trên --vm-surface-2. */
    --vm-grad-brand-text: linear-gradient(135deg, var(--vm-primary-300) 0%, var(--vm-primary-400) 100%);

    /* R1 — Bản khai lại BẮT BUỘC cho chế độ tối. Trước đây --vm-grad-brand chỉ
       khai ở :root nên dải 800 → 700 → 600 của chế độ sáng chảy thẳng vào chế độ
       tối; ở đó điểm dừng tối nhất (#10516a, L = 0.070356) chỉ còn 2.10:1 trên
       --vm-bg và 1.93:1 trên --vm-surface, rớt hẳn ngưỡng 3:1 của WCAG 1.4.11
       trên 8 khối thật, trong đó có nút nổi trợ lý và dải CTA cuối MỌI trang.
       (Biến anh em --vm-grad-brand-text đã có bản khai lại ngay bên trên — khuôn
       mẫu đúng nằm sẵn trong tệp, chỉ là chưa ai áp cho biến này.)

       Vì sao dải mới trông "phẳng" hơn hẳn dải chế độ sáng: nó buộc phải thế.
       Nội dung đè lên dải này luôn là TRẮNG (cả 8 khối), nên:
         chữ trắng đạt 4.5:1        ⇒ điểm dừng SÁNG NHẤT có L ≤ 0.18333
         thân đạt 3:1 vs surface-2  ⇒ điểm dừng TỐI NHẤT  có L ≥ 0.15561
       Hai đầu dải bị ép vào cùng một khe rộng vỏn vẹn 0.0277 độ chói. Đã thử các
       nấc có sẵn: primary-700 (L = 0.10804) thân chỉ 2.31:1 — rớt; primary-500
       (0.28504) chữ trắng 3.13:1 — rớt; primary-400 (0.35938) chữ 2.56:1 — rớt.
       Chỉ primary-600 lọt khe. Hướng "dải sáng + chữ tối" (cách đã cứu được
       --vm-text-on-brand) cũng vô nghiệm ở đây: #0a2733 trên primary-600 chỉ 3.37:1.

       Nên dải phải chuyển màu bằng SẮC ĐỘ thay vì sáng-tối: primary-600-azure
       (#0b76ce, xanh biển 209°, L = 0.17484) → primary-600 (#0a7ea6, xanh ngọc
       194°, L = 0.17739). Hai đầu chênh nhau chưa tới 1% độ chói nhưng lệch 15°
       sắc độ nên mắt vẫn thấy rõ là một dải chuyển màu.
       Lưu ý một cái bẫy khi đổi hai mã này: nội suy dải trong sRGB là hàm LỒI,
       nên các điểm GIỮA dải luôn tụt độ chói xuống DƯỚI đường thẳng nối hai đầu.
       Vì vậy không được kiểm mỗi hai điểm dừng — phải nội suy đủ 101 điểm. Dải
       hiện tại: 0/101 điểm rớt AA 4.5:1 (thấp nhất 4.60) và 0/101 điểm rớt 3:1
       trên mọi nền tối (thấp nhất 3.27 trên --vm-surface-2, 3.92 trên --vm-bg).
       CHỈ khai ở hai khối tối — khối :root phải giữ nguyên dải 800/700/600 vì ở
       chế độ sáng dải đó đang tốt (chữ trắng 4.62, thân 4.14–4.62 trên nền sáng). */
    --vm-grad-brand: linear-gradient(135deg, var(--vm-primary-600-azure) 0%, var(--vm-primary-600) 100%);

    --vm-overlay:       rgba(4, 8, 12, 0.72);
    --vm-glass:         color-mix(in srgb, #101a24 74%, transparent);
    --vm-glass-border:  color-mix(in srgb, #ffffff 10%, transparent);

    --vm-shadow-line: 0 0 0 1px rgba(255, 255, 255, 0.07);
    --vm-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
    --vm-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.45);
    --vm-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);
    --vm-shadow-lg: 0 14px 36px rgba(0, 0, 0, 0.55);
    --vm-shadow-xl: 0 26px 60px rgba(0, 0, 0, 0.6);
    --vm-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  }
}

/* Người dùng bấm nút chuyển sang tối — thắng cả cài đặt hệ thống */
:root[data-theme="dark"] {
  --vm-bg:            var(--vm-neutral-950);
  --vm-bg-subtle:     #121b25;
  --vm-bg-muted:      #17222e;
  --vm-bg-inverse:    var(--vm-neutral-50);
  --vm-surface:       #141e29;
  --vm-surface-2:     #1a2634;
  --vm-surface-hover: #21303f;

  --vm-text:          #e8eef4;
  --vm-text-soft:     #a9bacb;
  --vm-text-muted:    #7e93a8;
  --vm-text-inverse:  var(--vm-neutral-950);
  /* Xem giải thích ở khối @media (prefers-color-scheme: dark) phía trên:
     trắng trên #2faeda = 2.56:1, còn #0a2733 trên #2faeda = 6.06:1. */
  --vm-text-on-brand: var(--vm-primary-950);

  --vm-border:        #253444;
  --vm-border-strong: #33475b;
  --vm-border-subtle: #1c2836;

  --vm-surface-soft:  #121b25;

  --vm-brand:         var(--vm-primary-400);
  --vm-brand-hover:   var(--vm-primary-300);
  --vm-brand-soft:    color-mix(in srgb, var(--vm-primary-500) 16%, transparent);
  --vm-brand-text:    var(--vm-primary-300);

  --vm-cta:           var(--vm-accent-500);
  /* B4 + R2 — Xem giải thích ở khối @media (prefers-color-scheme: dark) phía trên. */
  --vm-cta-hover:     var(--vm-accent-550);
  --vm-cta-soft:      color-mix(in srgb, var(--vm-accent-500) 16%, transparent);
  --vm-cta-text:      var(--vm-accent-400);

  --vm-link:          var(--vm-primary-300);
  --vm-link-hover:    var(--vm-accent-300);

  /* B3 — Xem giải thích ở khối @media (prefers-color-scheme: dark) phía trên. */
  --vm-grad-brand-text: linear-gradient(135deg, var(--vm-primary-300) 0%, var(--vm-primary-400) 100%);

  /* R1 — Xem giải thích ở khối @media (prefers-color-scheme: dark) phía trên.
     Hai khối tối PHẢI khai giống hệt nhau; thiếu một bên là lỗi tái phát. */
  --vm-grad-brand: linear-gradient(135deg, var(--vm-primary-600-azure) 0%, var(--vm-primary-600) 100%);

  --vm-overlay:       rgba(4, 8, 12, 0.72);
  --vm-glass:         color-mix(in srgb, #101a24 74%, transparent);
  --vm-glass-border:  color-mix(in srgb, #ffffff 10%, transparent);

  --vm-shadow-line: 0 0 0 1px rgba(255, 255, 255, 0.07);
  --vm-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
  --vm-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.45);
  --vm-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);
  --vm-shadow-lg: 0 14px 36px rgba(0, 0, 0, 0.55);
  --vm-shadow-xl: 0 26px 60px rgba(0, 0, 0, 0.6);
  --vm-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
