/* ==========================================================================
   MEP TOOL — NỀN SAO (Starfield)
   Lớp lót để chữ vẫn đọc được khi có cảnh WebGL chạy phía sau.
   Bản gốc: 04_WEBSITE\demo\starfield-meptool\index.html — áp lên site 18/08/2026.

   File này CHỈ có tác dụng khi nen-sao.js gắn class .nen-sao lên <html> và
   <body>. Script chỉ gắn class sau khi đã qua đủ cửa kiểm (xem đầu nen-sao.js),
   nên máy yếu, điện thoại, hoặc người tắt chuyển động nhận đúng giao diện cũ —
   file này nằm im, không đổi một điểm ảnh nào.

   VÌ SAO CẦN LỚP LÓT: website vẽ trên nền #000 ĐẶC và phân lớp bằng ĐƯỜNG VIỀN
   chứ không bằng nền khối. Đo trên trang chủ: 8/10 khối nội dung có nền alpha=0.
   Bật nền động lên là chữ nằm thẳng trên hình đang chạy — và MỌI con số tương
   phản trong style.css hết hiệu lực, vì chúng giả định nền đen tĩnh.
   ========================================================================== */


/* ==========================================================================
   1. NHƯỜNG CHỖ CHO CANVAS

   style.css đặt `body { background: var(--bg) }`. Nền của <body> vẽ ở bước 3
   của thứ tự vẽ, còn canvas là phần tử fixed z-index:-3 nên vẽ ở bước 2 —
   tức là nền body PHỦ KÍN canvas. Phải trả nền về cho <html>.

   Không dùng :has() để với ngược lên <html>: trình duyệt nào không hiểu :has()
   sẽ cho ra <html> không nền + <body> trong suốt = trang trắng trơn. Script gắn
   class lên CẢ HAI phần tử, nên luật dưới đây không phụ thuộc tính năng nào.
   ========================================================================== */

html.nen-sao { background: var(--bg); }
body.nen-sao { background: transparent; }

#nen-sao {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  display: block;
  z-index: -3;                /* dưới #nen-diu (-2), #nen-hoa (-1), và mọi nội dung */
  pointer-events: none;
  opacity: 0;
  transition: opacity .9s ease;
}
#nen-sao.hien { opacity: 1; }

/* --- Lớp hoà nền cho CHẾ ĐỘ SÁNG -----------------------------------------
   Cảnh sao luôn vẽ tối, kể cả khi khách bấm sang giao diện sáng. Trang trắng
   mà sau lưng là hố đen thì vừa chói vừa vô lý.

   Lớp này phủ đúng màu nền của site lên trên canvas nhưng DƯỚI nội dung. Chế
   độ tối: trong suốt hoàn toàn (nền vốn đã đen, phủ thêm đen là thừa). Chế độ
   sáng: lên 0,90, kéo cảnh tối về gần trắng, chỉ còn lọt một lớp lấp lánh mờ.

   KHÔNG hạ opacity của chính canvas: cảnh vẽ bằng cộng màu (additive), hạ
   opacity làm sao mờ đều nhau và mất hết tương phản giữa sao sáng với nền.
   Phủ một lớp màu lên trên thì giữ được thứ bậc sáng tối của cảnh.

   0,90 CHỨ KHÔNG PHẢI 0,82 — đo ở 0,82 thì chữ nhấn nằm trên --surface-3 chỉ
   được 4,36:1, trượt. Hai đường chữa: nâng độ đục --surface-3 lên 0,91 (khối
   đó bịt kín, mất đúng thứ vừa cất công làm trong suốt) hoặc nâng lớp hoà nền
   lên 0,90 (MỌI khối giữ nguyên độ đục). Chọn đường thứ hai: đổi một thứ chữa
   được nhiều chỗ. Giá phải trả là lớp sao mờ hơn hẳn ở chế độ sáng — nhượng bộ
   ở phần trang trí, không nhượng ở khả năng đọc.
   -------------------------------------------------------------------------- */
#nen-hoa {
  position: fixed; inset: 0;
  z-index: -1;                /* trên #nen-diu (-2), trên canvas (-3), dưới nội dung */
  background: var(--bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity .35s ease;
}
:root[data-theme="light"] #nen-hoa { opacity: .90; }


/* --- Dải hạ sáng sau cột nội dung ----------------------------------------
   CHỮ KHÔNG NẰM TRONG KHỐI KÍNH THÌ NẰM THẲNG TRÊN SAO. Đo trên trang chủ
   18/08: 129 khối chữ, 93 khối có kính che, 36 khối không — trong đó 12 nằm
   trong hero (đã có màn chắn .hero::after dựng riêng). Còn 24 khối trần thật,
   rút gọn lại là 4 h2 + 4 p.lead (chip .tag, nút .btn, .box đều tự có nền).

   Đo tương phản 24 khối đó ở trường hợp xấu nhất (ngôi sao trắng bão hoà đi
   qua ngay sau nét chữ): 21 khối TRƯỢT, tệ nhất là h2 ở 1,37:1. Bản demo không
   lộ ra vì 24 phép đo hồi đó đều rơi vào khối CÓ kính.

   Lớp này chặn TRẦN độ sáng của nền ngay sau cột chữ. Ngưỡng tính ngược từ
   chữ tối nhất đứng trên nền trần:
     · chế độ TỐI  — chữ --muted #AFAFAF cần nền không sáng quá #434343,
                     tức phải phủ ít nhất 0,737 màu đen lên ngôi sao trắng
     · chế độ SÁNG — chữ --muted #6E6E6E cần nền không tối quá #F1F1F1.
                     LỚP HOÀ NỀN 0,90 MỘT MÌNH CHỈ ĐƯA ĐƯỢC TỚI #E6E6E6 =
                     4,09:1, TRƯỢT. Đây là lỗ hổng thứ hai demo chưa đo. Lớp
                     này dùng chính var(--bg) nên ở chế độ sáng nó phủ TRẮNG,
                     cộng với lớp hoà nền ra #F9F9F9 = 4,83:1, đạt.
   Chọn 0,75 (trên mức tối thiểu 0,737 một chút để còn biên) — cùng một con số
   phục vụ được cả hai chế độ.

   BỀ NGANG là số đo, không phải ước lượng: chữ trần trải từ 118px tới 1245px
   trên khung 1440, tức cần nửa rộng 602px tính từ tâm. Lấy 610px cho tròn biên,
   vạt mềm thêm 120px mỗi bên để không thấy mép dải.

   HỆ QUẢ ĐÃ BIẾT, chấp nhận theo lựa chọn ngày 18/08: khung càng hẹp thì phần
   sao còn rực càng ít. Ở 1440px chỉ còn khoảng 20px mỗi mép; phải từ 1920px
   trở lên mới có dải sao rõ ràng hai bên. Muốn sao rực khắp trang thì phải đổi
   sang cách khác (bó nền sao trong hero, hoặc lót kính cho từng tiêu đề mục) —
   đừng chỉ hạ con số 0,75 xuống, đó là đường thẳng tới 21 chỗ trượt cũ.
   -------------------------------------------------------------------------- */
body.nen-sao { --diu-nua: 610px; --diu-vat: 120px; }

#nen-diu {
  position: fixed; inset: 0;
  z-index: -2;
  background: var(--bg);
  opacity: .75;
  pointer-events: none;
  /* Che bằng mask chứ không bằng gradient nhiều chặng màu: mask chỉ nội suy
     kênh alpha nên không sinh viền xám ở chỗ chuyển sang trong suốt — lỗi kinh
     điển khi nội suy từ màu đặc sang `transparent` ở chế độ sáng.
     Khung hẹp hơn 2×(nửa+vạt) thì các chặng calc âm, trình duyệt tự kẹp lại
     thành đặc hết bề ngang — đúng chiều an toàn. */
  --m: linear-gradient(90deg,
        transparent 0,
        transparent calc(50% - var(--diu-nua) - var(--diu-vat)),
        #000 calc(50% - var(--diu-nua)),
        #000 calc(50% + var(--diu-nua)),
        transparent calc(50% + var(--diu-nua) + var(--diu-vat)),
        transparent 100%);
  -webkit-mask-image: var(--m);
          mask-image: var(--m);
}


/* ==========================================================================
   2. ĐÈ TOKEN NỀN — KHÔNG LIỆT KÊ SELECTOR

   Bản đầu trong demo liệt kê .card .note .table-scroll… và SÓT: figure.minhhoa
   (khối hình to nhất trang), th (tiêu đề cột bảng), .note.ok, .foot vẫn đặc
   nguyên. Liệt kê selector thì chỉ bắt được thứ mình nhớ ra.

   Đã quét lại style.css khi áp lên site: MỌI nền đặc đều lấy từ đúng nhóm
   token dưới đây (§5.5b giữ "0 mã hex ngoài :root" nên không có ngoại lệ nào
   lọt lưới). Hạ chúng xuống là TOÀN BỘ khối cùng trong suốt một lượt — kể cả
   khối viết thêm sau này, và kể cả 5 trang demo chưa từng thử.

   CỐ Ý KHÔNG ĐỘNG VÀO:
   · --bg          <html> phải đặc, không thì trang thành trong suốt thật sự;
                   .nav đã tự pha color-mix(--bg 85%) nên vốn đã nhìn xuyên.
   · --tag-*-bg    chip nhãn cỡ vài chục px², để đặc thì nhãn còn đọc ra là nhãn.
   · #FFFFFF của .minhhoa.khung-giay img — cố ý cố định, đó là "mặt giấy".

   ĐỘ ĐỤC LÀ SỐ ĐO RA, KHÔNG PHẢI CHỌN CHO ĐẸP. Đo lần đầu ở 0,72 (giá trị gốc
   của --glass): ba màu chữ đạt nhưng chữ phụ chỉ 2,91:1 — trượt 4,5:1 — đúng
   lúc một ngôi sao trắng bão hoà đi qua sau nó. Ba đường chữa:
     · nâng đục lên 0,86            → đạt, nhưng gần như bịt kín, quay về đen thui
     · giữ 0,72, nâng --muted       → chữ phụ sáng gần bằng thân bài, mất thứ bậc
     · NÂNG VỪA PHẢI CẢ HAI (0,78 + --muted #ACACAC trở lên) → đạt, vẫn nhìn
       xuyên thấy sao chạy, vẫn còn chênh lệch chữ chính / chữ phụ
   Đường thứ ba là đường đang dùng. Hạ xuống dưới 0,78 là chữ phụ trượt ngay.

   Ba bậc nền KHÔNG cùng một độ đục: bậc càng sáng thì khi phủ lên một ngôi sao
   trắng càng nhạt, nên phải đục hơn để bù. Cào bằng một con số cho cả ba là
   bậc sáng nhất trượt.

   (Đây là khối ĐỊNH NGHĨA token, tương đương :root — nên có giá trị màu thô
   trong này là đúng chỗ, không phạm §5.5b.)
   ========================================================================== */

body.nen-sao {
  --surface:     rgba(11, 11, 11, .78);   /* chữ phụ 4,79:1 ở nền xấu nhất */
  --surface-2:   rgba(19, 19, 19, .82);   /* .78 chỉ được 4,39 — trượt → .82 */
  --surface-3:   rgba(27, 27, 27, .85);   /* sáng hơn nữa → nâng tiếp */
  --glass:       rgba(11, 11, 11, .78);
  --ok-soft:     rgba(12, 38, 6, .78);
  --accent-soft: rgba(12, 38, 6, .78);
  --warn-soft:   rgba(42, 33, 10, .78);
  --danger-soft: rgba(42, 15, 15, .78);
  --info-soft:   rgba(12, 30, 42, .78);
}

:root[data-theme="light"] body.nen-sao {
  --surface:     rgba(255, 255, 255, .78);
  --surface-2:   rgba(244, 244, 244, .78);
  --surface-3:   rgba(236, 236, 236, .78);
  --glass:       rgba(255, 255, 255, .78);
  --ok-soft:     rgba(233, 249, 228, .82);
  --accent-soft: rgba(233, 249, 228, .82);
  --warn-soft:   rgba(255, 246, 224, .82);
  --danger-soft: rgba(253, 236, 234, .82);
  --info-soft:   rgba(230, 243, 250, .82);
}


/* ==========================================================================
   3. ĐỘ SÁNG CHỮ

   Chữ trắng tinh trên nền đen có sao chạy thì chói, đọc lâu mỏi mắt. Làm dịu
   là ĐÚNG — nhưng làm dịu chính là ăn vào phần dư tương phản vừa cân xong,
   nên có một cái sàn không được vượt qua.

   Nền sau lớp kính ở trường hợp xấu nhất (chế độ tối, sao trắng bão hoà ngay
   sau chữ) đo được là #414141. Giữ 4,5:1 với nền đó thì chữ KHÔNG được tối hơn
   #ACACAC — sàn tuyệt đối cho MỌI vai chữ. Bộ dưới đây dừng ngay trên sàn, và
   vẫn giữ ba bậc chênh nhau để còn phân biệt tiêu đề / thân bài / chữ phụ.

   Chế độ sáng đi ngược chiều: làm dịu là làm chữ NHẠT đi, nên sàn nằm ở phía
   bên kia. Ở đó dư nhiều hơn hẳn nên dịu được mạnh tay hơn.
   ========================================================================== */

body.nen-sao {
  --text:       #DCDCDC;
  --text-2:     #C4C4C4;
  --muted:      #AFAFAF;   /* sàn là #ACACAC — dừng ngay trên sàn */
  --accent-ink: #2FD91A;   /* neon hạ nhiệt, vẫn là xanh neon */
  --accent-h:   #6BEA55;
}

:root[data-theme="light"] body.nen-sao {
  --text:       #2A2A2A;
  --text-2:     #4A4A4A;
  --muted:      #6E6E6E;
  /* #1B7A3C đo ra ĐÚNG 4,50 trên nền --surface-3 — đạt nhưng không còn biên
     nào, một thay đổi nhỏ bất kỳ là trượt. Hạ một nấc lấy dư: 5,15. */
  --accent-ink: #187034;
  --accent-h:   #125829;
}


/* ==========================================================================
   4. LÀM NHOÈ NỀN SAU KHỐI CHỮ NHIỀU

   Đây là chỗ backdrop-filter ĐƯỢC dùng, không phạm §5.5g: luật đó cấm dùng cho
   khối có nền ĐẶC (làm mờ cái không ai nhìn xuyên qua). Ở đây nền trong suốt
   78% và có hình chạy thật phía sau — đúng ca nó sinh ra để phục vụ.

   KHÔNG áp cho mọi thứ: mỗi lớp backdrop-filter là một lượt lọc riêng của GPU,
   rải khắp trang là tự bắn vào chân về hiệu năng. Chỉ những khối chữ nhiều.
   Sót một khối ở đây là mất phần làm nhoè trang trí, KHÔNG mất tương phản —
   tương phản đã do phần đè token ở mục 2 lo trọn.
   ========================================================================== */

body.nen-sao .card,
body.nen-sao .card-3d,
body.nen-sao .note,
body.nen-sao .dl,
body.nen-sao .titleblock,
body.nen-sao .palette,
body.nen-sao .table-scroll,
body.nen-sao .schedule,
body.nen-sao .doc section,
body.nen-sao .minhhoa,
body.nen-sao .ma-may,
body.nen-sao .dk-hop,
body.nen-sao .foot,
body.nen-sao table {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}


/* ==========================================================================
   5. VAN AN TOÀN

   Ba media query dưới đây là lưới hứng cuối. Script đã tự kiểm cùng các điều
   kiện này trước khi chạy (nên máy hợp lệ không tải một byte three.js nào),
   nhưng người dùng đổi cài đặt GIỮA phiên thì script đã chạy rồi — CSS phải
   tự dọn được mà không cần nạp lại trang.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  #nen-sao, #nen-diu, #nen-hoa { display: none !important; }
  html.nen-sao, body.nen-sao { background: var(--bg); }
}

/* style.css đã có khối này cho .card-3d và .nav; nối dài cho nền sao. */
@media (prefers-reduced-transparency: reduce) {
  #nen-sao, #nen-diu, #nen-hoa { display: none !important; }
  html.nen-sao, body.nen-sao { background: var(--bg); }
  body.nen-sao {
    --surface: #0B0B0B; --surface-2: #131313; --surface-3: #1B1B1B;
    --glass: #0B0B0B;
    --ok-soft: #0C2606; --accent-soft: #0C2606; --warn-soft: #2A210A;
    --danger-soft: #2A0F0F; --info-soft: #0C1E2A;
  }
  :root[data-theme="light"] body.nen-sao {
    --surface: #FFFFFF; --surface-2: #F4F4F4; --surface-3: #ECECEC;
    --glass: #FFFFFF;
    --ok-soft: #E9F9E4; --accent-soft: #E9F9E4; --warn-soft: #FFF6E0;
    --danger-soft: #FDECEA; --info-soft: #E6F3FA;
  }
  body.nen-sao .card, body.nen-sao .card-3d, body.nen-sao .note,
  body.nen-sao .dl, body.nen-sao .titleblock, body.nen-sao .palette,
  body.nen-sao .table-scroll, body.nen-sao .schedule, body.nen-sao .doc section,
  body.nen-sao .minhhoa, body.nen-sao .ma-may, body.nen-sao .dk-hop,
  body.nen-sao .foot, body.nen-sao table {
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  }
}

/* In ra giấy: nền động là mực thừa, và style.css đã đặt body về --surface. */
@media print {
  #nen-sao, #nen-diu, #nen-hoa { display: none !important; }
  body.nen-sao .card, body.nen-sao .card-3d, body.nen-sao .note,
  body.nen-sao .dl, body.nen-sao .titleblock, body.nen-sao .palette,
  body.nen-sao .table-scroll, body.nen-sao .minhhoa, body.nen-sao .foot,
  body.nen-sao table {
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  }
}
