/* ============================================================================
   HƯỚNG DẪN TẠI CHỖ — giao diện nút ❓ và lớp phủ làm mờ
   [LÔ 1 — 03/10/2026]  JS: src/guide/guide-fab.js (nạp ngay) ·
                            src/guide/guide-overlay.js + guide-data.js (nạp lười)

   🔴 LUẬT CỦA FILE NÀY — MỌI class đều phải bắt đầu bằng ".guide-".
      Vì sao: file này nạp trong <head>, còn redesign-components.css nạp trong <body>
      nên LUÔN đứng sau và thắng mọi tranh chấp. Đặt tên riêng tuyệt đối thì không có
      tranh chấp nào để mà thua — khỏi phải phụ thuộc thứ tự nạp.

   🔴 KHÔNG được gộp file này vào 11 lát css/style-*.css: `node scripts/cut-css.js
      --verify` kiểm nối 11 lát phải khớp sha256 style.css gốc TỪNG BYTE.

   📐 TẦNG z-index đã chọn (đối chiếu các tầng đang có trong app):
        thanh điều hướng đáy            900
        >>> nút ❓                       950   (trên thanh đáy, DƯỚI mọi màn chặn)
        cụm nút làm bài dính đáy (ĐT)   999   (không chồng nút ❓: nó ở đáy, nút ở 35%)
        .auth-overlay / #noStudentScreen 1000
        màn khởi động #bootLoading     1100
        nút Zalo nổi                   1200
        màn thanh toán                 1500
        >>> lớp phủ hướng dẫn          2500   (DƯỚI các modal 9999+)
      🔴 Nút ❓ trước đây là 1150 → NỔI TRÊN màn khởi động, màn "chưa có học sinh" và các
         modal học thử (đợt rà soát 03/10/2026). Hạ xuống 950 thì mọi màn chặn (≥1000)
         tự che nút — không cần JS canh từng màn. Lớp phủ cố ý ĐỨNG DƯỚI modal: đang mở
         modal thì không mở được hướng dẫn.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. NÚT ❓ — ba trạng thái: CO (mặc định) · NỞ · ẩn
   --------------------------------------------------------------------------- */

.guide-fab {
    position: fixed;
    right: 0;
    /* 35% từ đáy: TRÁNH HẲN nút Zalo nổi (bottom 18px) và thanh điều hướng đáy.
       Cũng vừa tầm ngón cái khi cầm điện thoại một tay. */
    bottom: 35%;
    z-index: 950;

    display: flex;
    align-items: center;
    gap: 0;

    border: none;
    border-radius: var(--radius-pill, 999px) 0 0 var(--radius-pill, 999px);
    padding: 9px 7px 9px 9px;

    background: var(--guide-fab-bg);
    color: var(--guide-fab-fg);
    box-shadow: -2px 3px 12px rgba(var(--shadow-rgb), .28);

    cursor: pointer;
    font-family: inherit;
    /* Nút mặc định là nowrap; ở đây CỐ Ý giữ nowrap vì chữ "Hướng dẫn" phải nằm
       một dòng khi nở ra. Khai tường minh để sau này không ai phải đoán. */
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;

    transition: padding var(--dur-base, .2s) var(--ease-out),
        box-shadow var(--dur-base, .2s) var(--ease-out);
}

/* 🔴 VÙNG CHẠM THẬT 44×44 — phần NHÌN THẤY lúc co chỉ ~26px, nhỏ hơn ngưỡng chạm
   an toàn. Lớp giả này nới vùng bắt ngón tay ra mọi phía mà KHÔNG làm nút to lên.
   Trẻ lớp 2 ngón chưa chuẩn; chạm hụt vài lần là bỏ không dùng nữa. */
.guide-fab::before {
    content: "";
    position: absolute;
    top: 50%;
    /* NEO VỀ MÉP PHẢI, chỉ nới sang TRÁI. Bản đầu căn giữa (left:50% + translate -50%) trên một
       nút dán sát mép phải (right:0) → nửa phần nới thêm nằm NGOÀI màn, vùng chạm thật chỉ
       ~38–41px, dưới 44px mà bài kiểm vẫn xanh vì chỉ đọc min-width khai báo (đợt rà soát). */
    right: 0;
    left: auto;
    transform: translateY(-50%);
    min-width: 44px;
    min-height: 44px;
    width: 100%;
    height: 100%;
}

.guide-fab-icon {
    font-size: 17px;
    line-height: 1;
    display: block;
}

/* Chữ "Hướng dẫn" — cuộn ra bằng max-width (animate được), không phải display */
.guide-fab-text {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    font-size: 15px;
    font-weight: 700;
    transition: max-width var(--dur-base, .2s) var(--ease-out),
        opacity var(--dur-fast, .15s) var(--ease-out),
        margin-left var(--dur-base, .2s) var(--ease-out);
    margin-left: 0;
}

.guide-fab.is-open {
    padding-right: 15px;
    box-shadow: -3px 5px 18px rgba(var(--shadow-rgb), .36);
}

.guide-fab.is-open .guide-fab-text {
    max-width: 120px;
    opacity: 1;
    margin-left: 7px;
}

/* Chấm đỏ "chưa xem" — phải nằm ở PHẦN LÓ RA, nếu không thì lúc co không ai thấy.
   Định vị theo .guide-fab (position:fixed nên là khối chứa) → góc trên-trái của nút,
   đúng phần còn lộ ra khi nút đang CO sát mép phải.
   Dùng --accent-danger: đây là CHẤM BÁO, không phải màu nền mang ý nghĩa đúng/sai. */
.guide-fab.has-unseen .guide-fab-icon::after {
    content: "";
    position: absolute;
    top: 5px;
    left: 5px;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-circle, 50%);
    background: var(--accent-danger);
    /* 🔴 VIỀN TRẮNG, không phải viền màu nền nút. Đỏ (--accent-danger) và xanh nền nút
       (--accent-secondary) có CÙNG độ sáng → đo được chỉ 1,03:1 ở cả 9 theme: trẻ mù màu
       đỏ–xanh KHÔNG THẤY chấm. Viền trắng tách chấm ra: đỏ/trắng 5,07:1 · trắng/nền 5,23:1. */
    box-shadow: 0 0 0 2px var(--guide-fab-fg);
    animation: guideChamNhay 1.6s ease-in-out infinite;
}

/* [LÔ 6] Đại ca chốt: chấm đỏ NHẤP NHÁY, không tự bung hướng dẫn ra.
   Nháy bằng opacity + scale nhẹ chứ không tắt hẳn — tắt hẳn thì ở nhịp tối trẻ
   nhìn sang tưởng không có gì. */
@keyframes guideChamNhay {
    0%, 100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: .35;
        transform: scale(.75);
    }
}

.guide-fab-hidden {
    display: none !important;
}

/* 🔴 ẨN NÚT BẰNG CSS, KHÔNG BẰNG JS — hai hoàn cảnh dưới đây đều có sẵn class trên body,
   nên để CSS đọc thẳng là KHÔNG BAO GIỜ LỆCH NHỊP. Bản đầu tiểu đệ làm bằng JS
   (guideFabSync) và dính lỗi thật: guideStart() gắn body.guide-running nhưng không ai
   gọi lại hàm đồng bộ → nút ❓ nổi chình ình trên nền mờ. Bài kiểm tests/guide-lo1.spec.js
   bắt được. JS giờ chỉ còn lo trường hợp guideSuppress() (không có class nào trên body).
     · auth-locked   : đang ở màn đăng nhập — y hệt cách nút Zalo nổi đang làm
     · guide-running : lớp phủ đang chạy — nút không được nổi trên nền mờ */
body.auth-locked .guide-fab,
body.guide-running .guide-fab,
body.auth-locked #menu-guide,
body.guide-running #menu-guide {
    display: none !important;
}

/* PC (>900px — cùng ngưỡng isMobileNavWidth): KHÔNG dùng nút nổi, dùng nút header.
   Chia bằng @media chứ KHÔNG bằng JS → xoay máy / kéo cửa sổ qua ngưỡng không vỡ. */
@media (min-width: 901px) {
    .guide-fab {
        display: none;
    }
}

@media (max-width: 900px) {
    #menu-guide {
        display: none;
    }
}

/* Chấm đỏ cho nút ❓ trên header PC — theo đúng nếp .has-settings-pw-hint có sẵn */
#menu-guide {
    position: relative;
}

#menu-guide.has-unseen::after {
    content: "";
    position: absolute;
    top: 3px;
    right: 3px;
    width: 9px;
    height: 9px;
    border-radius: var(--radius-circle, 50%);
    background: var(--accent-danger);
    animation: guideChamNhay 1.6s ease-in-out infinite;
}

/* Người đã bật "giảm chuyển động" trong máy: chấm vẫn hiện, chỉ thôi nháy. */
@media (prefers-reduced-motion: reduce) {
    .guide-fab.has-unseen .guide-fab-icon::after,
    #menu-guide.has-unseen::after {
        animation: none;
    }
}

/* ---------------------------------------------------------------------------
   2. LỚP PHỦ — làm mờ + khoét vùng sáng
   --------------------------------------------------------------------------- */

.guide-overlay {
    position: fixed;
    inset: 0;
    z-index: 2500;
    display: none;
    /* Vuốt trên nền mờ KHÔNG được cuộn trang phía sau: trang trôi là phần tử trôi khỏi ô
       sáng, ô sáng khoanh vào chỗ khác (đợt rà soát 03/10/2026). Phiếu tự cho cuộn lại. */
    touch-action: none;
    overscroll-behavior: contain;
}

.guide-overlay.is-on {
    display: block;
}

/* 🔴 CÁCH KHOÉT: một ô trong suốt đặt đúng chỗ phần tử đích, rồi đổ bóng KHỔNG LỒ
   ra ngoài nó — phần bóng chính là nền mờ. Chỉ ĐỌC toạ độ phần tử, KHÔNG sửa style
   của nó. Cách hay gặp là nâng z-index phần tử đích lên, nhưng cách ấy vỡ ngay khi
   tổ tiên nó có overflow:hidden hay transform (thanh tab dính, panel cuộn). */
.guide-hole {
    position: absolute;
    border-radius: var(--radius-lg, 14px);
    box-shadow: 0 0 0 9999px var(--guide-scrim);
    outline: 3px solid var(--guide-ring);
    outline-offset: 2px;
    pointer-events: none;
    transition: top var(--dur-base, .2s) var(--ease-out),
        left var(--dur-base, .2s) var(--ease-out),
        width var(--dur-base, .2s) var(--ease-out),
        height var(--dur-base, .2s) var(--ease-out);
}

/* Không tìm được phần tử nào để chỉ (hiếm — vd mọi bước đều bị bỏ qua êm):
   thu ô về giữa màn, cỡ 0 → thành nền mờ trơn, phiếu vẫn đọc được. */
.guide-hole.is-blank {
    width: 0;
    height: 0;
    outline: none;
    top: 50%;
    left: 50%;
}

.guide-pulse {
    position: absolute;
    border-radius: var(--radius-lg, 14px);
    pointer-events: none;
    box-shadow: 0 0 0 0 rgba(var(--guide-ring-rgb), .55);
    animation: guidePulse 1.9s var(--ease-out) infinite;
}

@keyframes guidePulse {
    0% {
        box-shadow: 0 0 0 0 rgba(var(--guide-ring-rgb), .55);
    }

    70% {
        box-shadow: 0 0 0 14px rgba(var(--guide-ring-rgb), 0);
    }

    100% {
        box-shadow: 0 0 0 0 rgba(var(--guide-ring-rgb), 0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .guide-pulse {
        animation: none;
    }
}

/* ---------------------------------------------------------------------------
   3. PHIẾU CHỮ — điện thoại: dán đáy màn · PC: bong bóng cạnh phần tử
   --------------------------------------------------------------------------- */

.guide-sheet {
    position: absolute;
    background: var(--guide-sheet-bg);
    color: var(--guide-sheet-fg);
    border: 1px solid var(--guide-sheet-line);
    border-radius: var(--radius-lg, 14px);
    box-shadow: var(--shadow-lg);
    padding: 16px 16px 12px;
    box-sizing: border-box;
}

.guide-sheet-title {
    font-size: 18px;
    font-weight: 800;
    margin: 0 0 6px;
    /* Chừa chỗ cho nút ✕ 44px ở góc phải — tiêu đề dài không chui xuống dưới nút. */
    padding-right: 44px;
    color: var(--text-strong);
}

/* 🔴 16px là SÀN cho chữ đọc trên điện thoại (luật nhà). Đừng hạ xuống cho "gọn". */
.guide-sheet-text {
    font-size: 16px;
    line-height: 1.5;
    margin: 0;
}

.guide-sheet-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
}

.guide-sheet-count {
    font-size: 14px;
    color: var(--guide-sheet-dim);
    margin-right: auto;
}

/* Mọi nút điều khiển ≥44px — luật vùng chạm */
.guide-btn {
    min-height: 44px;
    min-width: 44px;
    padding: 0 16px;
    border-radius: var(--radius-pill, 999px);
    border: 1.5px solid var(--guide-sheet-line);
    background: var(--surface-white);
    color: var(--text-strong);
    font-family: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    /* button mặc định nowrap → chữ dài bị cắt cụt ở vài bề rộng màn. */
    white-space: normal;
}

.guide-btn:disabled {
    opacity: .45;
    cursor: default;
}

.guide-btn-main {
    background: var(--guide-fab-bg);
    color: var(--guide-fab-fg);
    border-color: var(--guide-fab-bg);
}

/* Nút ✕ phải ĐỦ 44px như mọi nút khác (bản đầu để 40px — trái chính dòng luật ở trên). */
.guide-btn-close {
    position: absolute;
    top: 4px;
    right: 4px;
    min-height: var(--touch-min);
    min-width: var(--touch-min);
    padding: 0;
    border: none;
    background: transparent;
    color: var(--guide-sheet-dim);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}

/* 🔴 CHẶN LUẬT button TOÀN CỤC (css/style-1.css:210–234). Ba thứ đè lên nút của phiếu:
   · button:hover{background:var(--blue-800)} — độ ưu tiên (0,1,1) THẮNG .guide-btn (0,1,0),
     và KHÔNG bọc @media(hover:hover) nên DÍNH sau khi chạm trên điện thoại. Chữ nút "◀ Lùi"
     là --text-strong = chính --blue-800 → nền trùng màu chữ → MẤT CHỮ (đợt rà soát 03/10).
   · button{margin:3px} — đẩy nút ❓ lệch 3px khỏi mép phải.
   · button{line-height:1} — chữ nút xuống dòng thì dính chùm.
   Khai lại bằng .guide-…:hover (0,2,0) để thắng chắc chắn, không phụ thuộc thứ tự nạp. */
.guide-fab,
.guide-btn,
.guide-btn-close {
    margin: 0;
}

.guide-btn {
    line-height: 1.25;
}

.guide-fab:hover {
    background: var(--guide-fab-bg);
}

.guide-btn:hover {
    background: var(--surface-hover);
}

.guide-btn-main:hover {
    background: var(--guide-fab-bg);
}

.guide-btn-close:hover {
    background: transparent;
    color: var(--guide-sheet-fg);
}

/* Tiêu điểm bàn phím (bộ máy nay đưa tiêu điểm vào phiếu khi mở) phải NHÌN THẤY được. */
.guide-btn:focus-visible,
.guide-btn-close:focus-visible {
    /* KHÔNG dùng --guide-ring: nó nay là TRẮNG (để nổi trên nền mờ) — trên phiếu nền sáng
       viền trắng thì vô hình. */
    outline: 3px solid var(--accent-secondary);
    outline-offset: 2px;
}

/* --- ĐIỆN THOẠI: phiếu DÁN ĐÁY MÀN ---
   Bong bóng nổi cạnh phần tử trên màn 360px là cụt chữ hoặc tràn ngang. Dán đáy thì
   chữ to, rộng rãi, và chỗ đứng của phiếu luôn đoán được — trẻ không phải đi tìm. */
@media (max-width: 900px) {
    .guide-sheet {
        left: 10px;
        right: 10px;
        bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
        top: auto;
        width: auto;
        max-height: 48vh;
        overflow-y: auto;
        /* Lớp phủ chặn vuốt (touch-action:none) — riêng phiếu thì cho vuốt dọc khi chữ dài. */
        touch-action: pan-y;
        overscroll-behavior: contain;
    }

    /* Phần tử đang chỉ nằm ở ĐÁY màn (thanh điều hướng, nút Nộp bài dính đáy…) →
       guidePlaceSheet() gắn .is-top để phiếu dán lên ĐỈNH, khỏi che mất chính thứ
       đang được chỉ. Chừa vùng an toàn tai thỏ. */
    .guide-sheet.is-top {
        top: calc(env(safe-area-inset-top, 0px) + 10px);
        bottom: auto;
    }
}

/* ĐIỆN THOẠI XOAY NGANG (màn thấp): phiếu ăn tới 40–45% chiều cao → phần tử không còn
   chỗ. Thu gọn khoảng đệm, KHÔNG hạ cỡ chữ đọc dưới 16px (luật nhà). */
@media (max-width: 900px) and (max-height: 500px) {
    .guide-sheet {
        max-height: 40vh;
        padding: 10px 14px 8px;
    }

    .guide-sheet-title {
        font-size: 16px;
        margin-bottom: 2px;
    }

    .guide-sheet-foot {
        margin-top: 8px;
    }
}

/* --- PC: bong bóng, JS đặt toạ độ --- */
@media (min-width: 901px) {
    .guide-sheet {
        width: 340px;
        max-width: calc(100vw - 32px);
    }
}
