/* ============================================================================
   REDESIGN ĐỢT 2 — CHUẨN HOÁ COMPONENT (lớp phủ, nạp SAU mọi CSS)
   CHỈ đổi GIÁ TRỊ style; KHÔNG đổi tên id/class; KHÔNG đụng DOM/JS.
   Mọi màu lấy từ tokens.css. Bỏ file này = quay lại như cũ (an toàn).
   ============================================================================ */

/* ---------------------------------------------------------------------------
   B5. BADGE TRẠNG THÁI — HỆ 5 MÀU NHẤT QUÁN
   Gom mọi họ badge (payment-hist / aa / acct / dash-chip / reward-status...)
   về đúng 5 bộ token. CHỈ đổi màu nền/chữ/viền (giữ nguyên layout/cỡ).
   Reclassify theo spec: review → cam (trước lẫn đỏ/cam); forever → xanh dương
   (trước 1 chỗ tím). Các trạng thái khác GIỮ nguyên nghĩa màu, chỉ token-hoá.
   --------------------------------------------------------------------------- */

/* 🟢 XANH LÁ — còn hạn · đã xác nhận · thành công · đủ điều kiện */
.payment-hist-badge.is-paid,
.aa-pay-paid,
.acct-pay-paid,
.acct-exp-badge-ok,
.aa-badge-ok,
.dash-chip-ok,
.rs-status-ok,
.reward-status-enough {
    background: var(--surface-success);
    color: var(--green-text);
    border: 1px solid var(--border-success);
}

/* 🟠 CAM — chờ thanh toán · sắp hết hạn · cần kiểm tra lại · cảnh báo */
.payment-hist-badge.is-pending,
.payment-hist-badge.is-review,
.aa-pay-pending,
.aa-pay-review,
.acct-pay-pending,
.acct-pay-review,
.acct-exp-badge-pending,
.aa-badge-pending,
.aa-chip-waiting,
.dash-chip-warn,
.reward-status-missing,
.account-expiry-warn,
.account-expiry-note {
    background: var(--orange-tint);
    color: var(--text-warning);
    border: 1px solid var(--border-warning);
}

/* 🔴 ĐỎ — hết hạn (tài khoản) · ĐÃ HUỶ · lỗi · làm sai · cần hoàn tiền.
   [ĐỢT 3A-A2] "Đã huỷ" (admin chủ động huỷ, phụ huynh đã chuyển tiền) → ĐỎ để gây chú ý,
   phân biệt với "hết hiệu lực" (phiếu tự hết sau 3 ngày) = XÁM ở nhóm dưới. */
.payment-status-banner.is-expired,
.aa-badge-expired,
.acct-exp-badge-expired,
.aa-chip-refund,
.aa-pay-refund-warn,
.acct-pay-cancelled,
.payment-hist-badge.is-cancelled,
.aa-pay-cancelled,
.dash-chip-danger,
.account-expiry-expired,
.account-expiry-note.expired {
    background: var(--red-tint);
    color: var(--accent-danger);
    border: 1px solid var(--border-danger);
}

/* 🔵 XANH DƯƠNG — chờ admin xác nhận · vĩnh viễn · thông tin */
.payment-hist-badge.is-waiting,
.aa-pay-waiting,
.acct-pay-waiting,
.acct-exp-badge-forever,
.aa-pay-forever-warn,
.aa-badge-forever,
.aa-tag {
    background: var(--surface-hover);
    color: var(--text-strong);
    border: 1px solid var(--blue-200);
}

/* ⚪ XÁM — hết hiệu lực (phiếu tự hết sau 3 ngày) · chưa hiệu lực. KHÔNG ai làm gì sai. */
.payment-hist-badge.is-expired,
.aa-pay-expired,
.rs-status-missing {
    background: var(--surface-muted);
    color: var(--text-muted);
    border: 1px solid var(--border-subtle);
}

/* ---------------------------------------------------------------------------
   B6. CHẤM ĐỎ THÔNG BÁO — 🗑️ ĐÃ XOÁ Ở [M4.2 lô 4] VÌ LÀ CODE CHẾT.
   Khối cũ khai `.has-settings-pw-hint::after` (0,1,1) nhưng luật thật của app là
   `.header-icon-btn.has-settings-pw-hint::after` (0,2,1) ở style.css:10949 —
   độ ưu tiên cao hơn nên khối này CHƯA BAO GIỜ CHẠY. Giữ lại chỉ tổ khiến người
   sau tin rằng chấm đỏ lấy màu từ đây. Màu thật nay đã là --accent-danger.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   B1. NÚT — trạng thái CHUNG bổ sung (không đổi màu vai trò ở đây).
   Quầng focus bàn phím thống nhất (spec: :focus-visible → --shadow-focus).
   --------------------------------------------------------------------------- */
button:focus-visible,
.auth-btn:focus-visible,
.dash-btn:focus-visible,
.aa-btn:focus-visible,
.payment-btn:focus-visible,
.paywall-btn:focus-visible,
.confirm-dialog-btn:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* ---------------------------------------------------------------------------
   B2. Ô NHẬP — quầng focus thống nhất cho các ô "trơn" (trước thiếu focus).
   --------------------------------------------------------------------------- */
.password-input:focus,
.student-select:focus,
.total-score-input:focus,
.reward-input:focus,
.exchange-input:focus,
.admin-password-input:focus {
    outline: none;
    border-color: var(--accent-secondary);
    box-shadow: var(--shadow-focus);
}

/* ---------------------------------------------------------------------------
   B1. NÚT — thống nhất MÀU theo VAI TRÒ (giữ nguyên tên class + layout/kích thước).
   --------------------------------------------------------------------------- */

/* CHÍNH → xanh lá (Lưu/Xác nhận trong app). Trước đa số xanh dương;
   nay xanh lá để phân biệt rõ với nút PHỤ (xanh dương) và CTA (cam).
   [ĐỢT 3A-A1] ĐÃ BỎ .auth-btn-primary khỏi nhóm này: nút màn Home (Đăng nhập/Đăng ký/
   Gửi lại) là "cửa vào nhà" → giữ XANH DƯƠNG (màu thương hiệu), xem khối B1 dưới. */
.confirm-dialog-ok,
.dash-btn-primary,
.aa-btn-primary {
    background: var(--accent-primary);
    color: var(--text-on-accent);
}
.confirm-dialog-ok:hover,
.dash-btn-primary:hover,
.aa-btn-primary:hover {
    background: var(--accent-primary-hover);
}

/* [ĐỢT 3A-A1] Nút Đăng nhập/Gửi lại = XANH DƯƠNG (đã tự về mặc định auth.css).
   Nút "Đăng ký" (#authRegSubmit) = nút PHỤ (nền trắng, viền xanh) để không tranh chấp
   với Đăng nhập trên cùng màn Home. */
#authRegSubmit {
    background: var(--surface-white);
    color: var(--accent-secondary);
    border: 1.5px solid var(--accent-secondary);
    box-shadow: none;
}
#authRegSubmit:hover {
    background: var(--surface-subtle);
}

/* ---------------------------------------------------------------------------
   A3. NÚT TRẮC NGHIỆM ≥ 44px — trẻ lớp 1–5 ngón tay kém chính xác, bấm nhầm
   đáp án là ức chế thật. Đề dài thêm thì CUỘN (không hại); bấm nhầm mới hại.
   Cả 2 nút vốn display:(inline-)flex + căn giữa nên chữ tự canh giữa theo chiều cao.
   --------------------------------------------------------------------------- */
.choice-btn,
.q-choice {
    min-height: var(--touch-min);
}

/* ============================================================================
   ĐỢT 3A — PHẦN B/C/D: HOME · ĐĂNG KÝ/QUÊN MK · PAYWALL
   ============================================================================ */

/* B2. MOBILE (<900px): vùng ĐĂNG NHẬP lên TRƯỚC (khách quay lại là đa số);
   học thử ở dưới. PC 2 cột GIỮ trial trái / login phải (không đụng). */
@media (max-width: 899.98px) {
    .home-overlay .home-login-zone { order: -1; }
}

/* B3. Dòng nhấn "Miễn phí · Không cần đăng ký" ở vùng học thử (element tĩnh mới). */
.home-overlay .home-trial-free {
    text-align: center;
    font-weight: 800;
    font-size: 14px;
    margin: 2px 0 10px;
}

/* B1. Dải màu logo (--brand-strip: xanh lá→vàng→cam) làm viền TRÊN thẻ Home. */
.home-overlay .home-card {
    position: relative;
}
.home-overlay .home-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 5px;
    background: var(--brand-strip);
    border-radius: 16px 16px 0 0;
    z-index: 2;
}

/* C. Ô nhập LỖI (đăng ký/quên MK): viền --accent-danger + nền --red-soft.
   `.is-invalid` sẵn cho JS; `:user-invalid` tự bật sau khi rời ô sai (không cần JS). */
.auth-input.is-invalid,
.auth-input:user-invalid {
    border-color: var(--accent-danger);
    background: var(--surface-danger);
}
.auth-input.is-invalid:focus,
.auth-input:user-invalid:focus {
    box-shadow: var(--shadow-focus);
    border-color: var(--accent-danger);
}

/* D. PAYWALL — nút "Liên hệ quản trị viên" (#paywallContact) DỄ THẤY hơn:
   thành hộp xanh dương nhạt thay vì dòng text mờ (giữ nguyên JS render bên trong). */
#paywallContact.paywall-contact {
    margin-top: 14px;
    padding: 12px 14px;
    background: var(--surface-hover);
    border: 1px solid var(--blue-200);
    border-radius: var(--radius-md);
    color: var(--text-strong);
    font-size: 14px;
    font-weight: 600;
}

/* CTA NỔI BẬT → gradient cam. "Gia hạn tài khoản" thuộc nhóm CTA (spec), trước là xanh lá. */
.acct-exp-renew-btn {
    background: linear-gradient(135deg, var(--orange-500), var(--orange-600));
    color: var(--text-on-accent);
    box-shadow: var(--shadow-cta);
}
.acct-exp-renew-btn:hover {
    filter: brightness(1.04);
    background: linear-gradient(135deg, var(--orange-500), var(--orange-600));
}
/* CTA cam dùng chung token bóng (payment vốn hard-code đúng giá trị). */
.payment-btn-primary {
    box-shadow: var(--shadow-cta);
}

/* NGUY HIỂM → --accent-danger (Xoá). Trước red-500; thống nhất với hệ đỏ. */
.reward-shop-delete-btn {
    background: var(--accent-danger);
}
.reward-shop-delete-btn:hover {
    background: var(--red-700);
}

/* VÔ HIỆU → thống nhất opacity .55 + mất bóng + not-allowed (vài nút trước dùng .6/default). */
.auth-btn-primary:disabled,
.auth-btn-google:disabled,
.auth-btn-secondary:disabled,
.paywall-btn-secondary:disabled,
.payment-btn:disabled,
.welcome-grade-btn:disabled {
    opacity: .55;
    box-shadow: none;
    cursor: not-allowed;
}

/* ============================================================================
   ĐỢT 3B — MÀN HỌC SINH LÀM BÀI + KẾT QUẢ
   Hệ THẬT = thẻ .q-card/.q-grid/.q-choice/.q-count-* (bảng cũ .exam-table là code chết).
   Class chấm điểm động (GIỮ TÊN, chỉ style): q-card-graded, is-correct, is-wrong,
   q-result-badge, q-correct-inline, .q-choice.selected.
   ============================================================================ */

/* --- A1. Tiêu đề khu (Tính nhanh / Lời văn) rõ ràng, có khoảng thở --- */
.quiz-section-header h2 {
    color: var(--text-strong);
    font-weight: var(--weight-extrabold);
    font-size: var(--text-lg);
    letter-spacing: .2px;
}
.math-quiz-layout { gap: var(--space-6); }
.quiz-section { padding: var(--space-6) var(--space-7); }
.quiz-section-header { margin-bottom: var(--space-5); }

/* --- A2. Thẻ câu hỏi: thêm bóng mềm; SỐ CÂU thành viên thuốc nổi bật --- */
.q-card {
    box-shadow: var(--shadow-xs);
}
.q-card-no {
    align-self: flex-start;
    background: var(--surface-hover);
    color: var(--text-strong);
    font-weight: var(--weight-extrabold);
    border-radius: var(--radius-pill);
    padding: 2px 10px;
    font-size: var(--text-xs);
}

/* --- A3. Ô nhập đáp án (Tính nhanh): MOBILE nâng cao vùng bấm ≥44px (desktop giữ compact). --- */
@media (max-width: 900px) {
    .q-answer-input .answer-input,
    .q-answer-input input {
        min-height: var(--touch-min);
    }
}
/* Ô nhập sau khi chấm (disabled) — xám nhẹ, rõ là đã khoá. */
.answer-input:disabled {
    background: var(--surface-muted);
    color: var(--text-muted);
    opacity: 1;
}

/* --- A4. Nút trắc nghiệm: 4 nút cách nhau RÕ hơn (chống bấm nhầm) --- */
.q-choices { gap: var(--space-5); }
/* Được chọn (khi đang làm) → nền xanh ĐẶC, chữ trắng, phóng nhẹ scale(1.04). */
.q-choice.selected {
    background: var(--accent-secondary);
    border-color: var(--accent-secondary);
    color: var(--text-on-accent);
    transform: scale(1.04);
    transition: transform var(--dur-fast) var(--ease-bounce), background var(--dur-fast) var(--ease-out);
}

/* --- A5. Emoji đếm: TO + tách bạch hơn (không dính nhau) ---
   ⚠️ File này nạp SAU style.css nên rule ở đây ĐÈ style.css. Trước đây nó khai một cỡ
   RIÊNG (clamp 13–22px) → lệch với cỡ khai trong style.css, gây "câu icon to câu icon nhỏ".
   Nay dùng CHUNG biến --q-count-icon (tokens.css) → muốn đổi cỡ chỉ sửa 1 chỗ duy nhất.
   Khe giữa 2 icon hạ 6px → 4px: icon nay TO hơn nhiều nên vẫn tách bạch rõ, đồng thời
   nhường chỗ để hàng 3 icon không bị bẻ dòng trong ô hẹp (câu 3 nhóm). */
.q-count-row { gap: var(--space-2); }
.q-count-emoji { font-size: var(--q-count-icon); }

/* ============================================================================
   D1. CHẤM ĐIỂM TỪNG CÂU — tô nền/viền thẻ (trước "Lô 3 bỏ dở", chưa có).
   ============================================================================ */
/* Câu ĐÚNG → thẻ xanh lá nhạt + viền xanh, dấu ✓ (badge). */
.q-card.is-correct {
    background: var(--surface-success);
    border-color: var(--border-success);
}
.q-card.is-correct .q-result-badge { color: var(--text-success); }
/* Nút trẻ chọn ĐÚNG → xanh đặc (giữ scale từ A4). */
.q-card.is-correct .q-choice.selected {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: var(--text-on-accent);
}

/* Câu SAI → thẻ đỏ nhạt + viền đỏ, dấu ✗. */
.q-card.is-wrong {
    background: var(--red-tint);
    border-color: var(--border-danger);
}
.q-card.is-wrong .q-result-badge { color: var(--accent-danger); }
/* Nút trẻ chọn SAI → tô ĐỎ (trước vẫn xanh dương). */
.q-card.is-wrong .q-choice.selected {
    background: var(--red-tint);
    border-color: var(--red-500);
    color: var(--accent-danger);
    transform: none;
}
/* Đáp án đúng (chữ inline) → XANH LÁ tích cực (trước đang đỏ, dễ hiểu nhầm là lỗi). */
.q-card.is-wrong .q-correct-inline,
.q-correct-inline {
    color: var(--text-success);
    font-weight: var(--weight-bold);
}

/* ============================================================================
   B2. MENU trái — mục đang chọn rõ + vùng bấm ≥44px.
   ============================================================================ */
.menu-link {
    min-height: var(--touch-min);
}
.menu-link.active-section {
    background: var(--surface-hover);
    color: var(--text-strong);
    font-weight: var(--weight-bold);
}

/* ============================================================================
   3B-2 — HOÀN THIỆN MÀN LÀM BÀI (5 việc cần JS). CSS phần hiển thị.
   ============================================================================ */

/* --- VIỆC 1: Modal TỔNG KẾT sau nộp bài (thay alert) --- */
.exam-summary-modal {
    position: fixed;
    inset: 0;
    z-index: 10001;
    background: rgba(var(--shadow-rgb), 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-8);
    box-sizing: border-box;
}
.exam-summary-modal.hidden-section { display: none !important; }
.exam-summary-box {
    width: min(400px, 100%);
    background: var(--surface-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-9) var(--space-8) var(--space-8);
    text-align: center;
    border-top: 6px solid var(--accent-primary);
    max-height: calc(100vh - 2 * var(--space-8));
    overflow-y: auto;
    box-sizing: border-box;
}
/* Màu theo bậc: cao → xanh lá; trung bình/thấp → CAM (không bao giờ đỏ). */
.exam-summary-box.tier-high { border-top-color: var(--accent-primary); }
.exam-summary-box.tier-mid,
.exam-summary-box.tier-low { border-top-color: var(--accent-highlight); }
.exam-summary-emoji { font-size: 48px; line-height: 1; margin-bottom: var(--space-4); }
.exam-summary-title {
    margin: 0 0 var(--space-4);
    font-size: var(--text-2xl);
    font-weight: var(--weight-black);
    color: var(--text-strong);
}
.exam-summary-score {
    font-size: 56px;
    font-weight: var(--weight-black);
    line-height: 1;
    margin-bottom: var(--space-2);
}
.tier-high .exam-summary-score { color: var(--accent-primary); }
.tier-mid .exam-summary-score,
.tier-low .exam-summary-score { color: var(--accent-highlight); }
.exam-summary-correct {
    font-size: var(--text-lg);
    font-weight: var(--weight-extrabold);
    color: var(--text-body);
    margin-bottom: var(--space-6);
}
.exam-summary-reward {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
}
.exam-summary-reward-points {
    background: var(--surface-success);
    color: var(--text-success);
    border: 1px solid var(--border-success);
    border-radius: var(--radius-pill);
    padding: var(--space-3) var(--space-7);
    font-weight: var(--weight-extrabold);
    font-size: var(--text-md);
}
.exam-summary-reward-none { color: var(--text-warning); font-weight: var(--weight-bold); font-size: var(--text-base); }
.exam-summary-reward-garden { color: var(--green-text); font-size: var(--text-sm); }
.exam-summary-message {
    font-size: var(--text-md);
    color: var(--text-body);
    line-height: var(--leading-normal);
    margin: 0 0 var(--space-8);
}
.exam-summary-actions { display: flex; gap: var(--space-6); justify-content: center; }
.exam-summary-btn {
    min-height: var(--touch-min);
    min-width: 120px;
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    cursor: pointer;
    padding: 0 var(--space-7);
    transition: var(--transition-btn);
}
.exam-summary-btn-primary { background: var(--accent-primary); color: var(--text-on-accent); }
/* [M4.2 lô 1e] bọc chống HOVER DÍNH trên màn cảm ứng */
@media (hover: hover) {
.exam-summary-btn-primary:hover { background: var(--accent-primary-hover); transform: translateY(-1px); }
}
.exam-summary-btn-secondary {
    background: var(--surface-white);
    color: var(--accent-secondary);
    border: 1.5px solid var(--accent-secondary);
}
.exam-summary-btn-secondary:hover { background: var(--surface-subtle); }
@media (max-width: 480px) {
    .exam-summary-btn { flex: 1 1 auto; min-width: 0; padding: 0 var(--space-4); }
    .exam-summary-score { font-size: 48px; }
}

/* --- VIỆC 2 (ĐÃ DỌN 10/08/2026 · M7.4) ---
   Ở ĐÂY TỪNG CÓ một rule biến nút "Nộp bài" thành NÚT NỔI (position:fixed) trên điện
   thoại. Nó CHẾT 100% và đã được gỡ: file này nạp SAU style.css và độ ưu tiên cao hơn,
   NHƯNG nó không có `!important`, mà style.css:9012-9025 lại đặt
   position/left/right/bottom/top/transform/z-index/margin/width đều `!important` →
   thua sạch. Riêng box-shadow thì thua style.css:5673 (cũng !important, đứng sau).
   Ai đọc file này mà tưởng app đang có nút nổi là hiểu nhầm — app KHÔNG có.

   Ở ĐÂY CŨNG TỪNG CÓ `#section-questions .math-quiz-layout { padding-bottom: 72px }` —
   phần chừa chỗ cho CÁI NÚT NỔI nói trên. Nút nổi đã chết từ lâu nên 72px đó thành khe
   trắng thừa giữa thẻ câu cuối và nút "Nộp bài". ĐẠI CA CHỐT GỠ ngày 10/08/2026.
   Đo thật ở 390px: khe 107px → 35px (35px là khoảng cách TỰ NHIÊN của bố cục:
   14px lề dưới thẻ cuối + 21px khe khối đề→nút, gồm margin-top 6px của nút).

   🔴 ĐỪNG GỠ NHẦM SANG `.content-area { padding-bottom }` ở style.css:12155-12157 —
   ĐÓ MỚI là chỗ chừa cho THANH NAV ĐÁY (nav cao 57px). Đo cả 6 phương án padding đều
   thấy khoảng dưới nút GIỮ NGUYÊN 86px, tức nav không bao giờ che nút. Gỡ nhầm chỗ đó
   là nút "Nộp bài" chui xuống dưới thanh nav, trẻ làm xong không bấm nộp được. */

/* --- VIỆC 3: Nút Nộp bài trạng thái "đang chấm" --- */
.btn-finish-exam.is-grading { opacity: .6; cursor: wait; }

/* --- VIỆC 4: Tô ĐÁP ÁN ĐÚNG cho câu trắc nghiệm (xanh lá, viền nét đứt) --- */
.q-choice.q-choice-correct-answer {
    background: var(--surface-success);
    border: 2px dashed var(--accent-primary);
    color: var(--text-success);
}

/* ============================================================================
   ĐỢT 3C — MÀN THANH TOÁN (nơi ra tiền: rõ ràng + đáng tin). CSS restyle;
   nội dung do JS sinh (đã giữ nguyên tên id/class + onclick + logic QR/thanh toán).
   ============================================================================ */

/* --- A1. Thẻ gói: chọn thấy NGAY (viền + nền xanh + ✓); giá TO --- */
.payment-pkg-list { gap: var(--space-6); }
.payment-pkg-item {
    position: relative;
    border: 2px solid var(--border-card);
    min-height: var(--touch-min);
    transition: var(--transition-btn);
}
.payment-pkg-item:hover { border-color: var(--blue-300); }
/* Gói được chọn: NHẬN BIẾT bằng VIỀN XANH ĐẬM + nền xanh nhạt (đã bỏ dấu "✓" đè lên số tiền). */
.payment-pkg-item.selected {
    border-color: var(--accent-secondary);
    background: var(--surface-hover);
}
.payment-pkg-name { font-size: var(--text-md); color: var(--text-strong); }
.payment-pkg-price { font-size: var(--text-xl); color: var(--orange-600); }
/* Nhãn "Tiết kiệm nhất" (JS gắn cho gói dài nhất) — tinh tế, không hét. */
.payment-pkg-badge {
    display: inline-block;
    background: var(--surface-success);
    color: var(--text-success);
    border: 1px solid var(--border-success);
    border-radius: var(--radius-pill);
    padding: 1px 8px;
    font-size: var(--text-xs);
    font-weight: var(--weight-extrabold);
    margin-left: var(--space-3);
    vertical-align: middle;
    white-space: nowrap;
}
/* [BỎ] .payment-reassure ("Gia hạn sớm được cộng dồn…") đã gỡ khỏi giao diện popup gia hạn. */
.payment-legal-note { font-size: var(--text-sm); text-align: center; color: var(--text-muted); margin: var(--space-5) 0; line-height: var(--leading-snug); }
.payment-legal-note a { color: var(--accent-secondary); font-weight: var(--weight-bold); text-decoration: underline; }

/* --- B1. QR TO, RÕ: nền trắng + viền trắng dày (camera dễ bắt) + bóng nhẹ --- */
.payment-qr-box {
    padding: var(--space-9);
    border: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-sm);
}

/* --- B2. Nút SAO CHÉP ≥44px, rõ; phản hồi "đã chép" chuyển XANH --- */
.payment-copy-btn {
    min-height: var(--touch-min);
    font-size: var(--text-base);
}
.payment-copy-mini {
    min-height: var(--touch-min);
    font-size: var(--text-sm);
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-sm);
}
.payment-copy-btn.is-copied,
.payment-copy-mini.is-copied {
    background: var(--surface-success);
    border-color: var(--border-success);
    color: var(--text-success);
}

/* --- B3. Cảnh báo "đúng số tiền/nội dung" → CAM nhắc nhở (KHÔNG đỏ) --- */
.payment-hint {
    background: var(--surface-warning);
    border: 1px solid var(--border-warning);
    color: var(--text-warning);
    border-radius: var(--radius-md);
    padding: var(--space-5) var(--space-6);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    margin: var(--space-5) 0;
}

/* --- B4. Nút "Tôi đã thực hiện thanh toán" NỔI NHẤT; "Huỷ yêu cầu" NHẠT hẳn --- */
.payment-btn-primary {
    min-height: 54px;
    font-size: var(--text-lg);
    box-shadow: var(--shadow-cta);
}
.payment-btn-outline {
    background: var(--surface-white);
    color: var(--text-muted);
    border: 1px solid var(--border-subtle);
    font-weight: var(--weight-medium);
    min-height: 46px;
}
.payment-btn-zalo { box-shadow: 0 4px 12px rgba(0, 104, 255, 0.25); }

/* --- C1. Banner "chờ admin xác nhận" → XANH DƯƠNG (trấn an, đang xử lý — không phải cảnh báo) --- */
.payment-status-banner.is-waiting {
    background: var(--surface-hover);
    color: var(--text-strong);
    border: 1px solid var(--blue-200);
}

/* --- C2. Lịch sử phiếu: thẻ rõ; lý do dễ đọc (badge theo hệ màu đợt 2 đã có) --- */
.payment-hist-item { border-color: var(--border-card); }
.payment-hist-extra { color: var(--ink-600); }

/* --- C3. Dòng trạng thái phiếu trong thẻ Tài khoản — ĐẬP VÀO MẮT --- */
.acct-pay-line { font-weight: var(--weight-bold); }

/* ============================================================================
   ĐỢT 3D — MÀN CÀI ĐẶT (phụ huynh). CSS thuần + vài hiển thị.
   ⚠️ KHÔNG đụng placeAccountCard / #accountExpiryCard / 4 id slot /
   .account-card-slot{display:contents} / phân quyền / logic mật khẩu.
   ============================================================================ */

/* --- A. CỔNG MẬT KHẨU: ô to rõ, nút Mở Cài đặt nổi, link quên MK thấy rõ.
   (Lưới 2 cột PC / 1 cột mobile + thẻ tài khoản lên trước đã có sẵn.) --- */
.gate-card .settings-pw-input { min-height: var(--touch-min); font-size: var(--text-md); }
.settings-gate-open-btn {
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    min-height: var(--touch-min);
    font-weight: var(--weight-bold);
    border-radius: var(--radius-md);
    padding: 0 var(--space-8);
}
.settings-gate-open-btn:hover { background: var(--accent-secondary-hover); }
.gate-card .settings-forgot-link {
    color: var(--accent-secondary);
    font-weight: var(--weight-medium);
    text-decoration: underline;
    font-size: var(--text-sm);
}
/* [REDESIGN] Cổng sai mật khẩu → dòng lỗi inline + ô viền đỏ (thay alert). */
.settings-gate-error {
    color: var(--accent-danger);
    background: var(--surface-danger);
    border: 1px solid var(--border-danger);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-5);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    margin-top: var(--space-3);
}
.settings-pw-input.is-invalid {
    border-color: var(--accent-danger);
    background: var(--surface-danger);
}

/* --- B. THẺ TÀI KHOẢN: Ngày hết hạn + Số ngày còn lại NỔI BẬT; dòng phiếu đập mắt --- */
.acct-exp-row-key .acct-exp-label {
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    color: var(--text-body);
}
.acct-exp-row-key .acct-exp-value {
    font-size: var(--text-lg);
    font-weight: var(--weight-extrabold);
}
.acct-pay-line {
    padding: var(--space-5) var(--space-6);
    font-size: var(--text-base);
    box-shadow: var(--shadow-xs);
}

/* --- C. LƯỚI 4 THẺ + cổng: nền kem ấm + bóng mềm + tiêu đề đậm (lưới 2×2/1 cột đã có) --- */
.account-expiry-box,
.system-config-card,
.login-pw-card,
.settings-pw-card,
.gate-card {
    background: var(--surface-card);
    box-shadow: var(--shadow-md);
}
.settings-group-title {
    color: var(--text-strong);
    font-weight: var(--weight-extrabold);
}
/* Công tắc cấu hình hệ thống: vùng bấm ≥44px, checkbox to hơn. */
.system-config-card .admin-toggle-row { min-height: var(--touch-min); align-items: center; }
.system-config-card-body .admin-toggle-row input[type="checkbox"] {
    width: 20px;
    height: 20px;
    cursor: pointer;
}

/* --- D. TAB HỌC SINH: con đang chọn nổi bật; ghi chú "Tối đa 3"; toast lưu --- */
.student-info-segment-btn { min-height: var(--touch-min); font-size: var(--text-base); }
.student-info-segment-btn.active {
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    border-color: var(--accent-secondary);
    font-weight: var(--weight-extrabold);
}
/* KHÔNG đặt display ở đây — để .hidden-section (không !important) vẫn ẩn được. */
.student-info-max-note {
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    font-style: italic;
    margin-left: var(--space-4);
}

/* --- E. TAB CẤU HÌNH: nav tab đang mở rõ + vùng bấm ≥44px --- */
.admin-parent-tab-btn,
.admin-child-tab-btn { min-height: var(--touch-min); }
/* [FIX Ô ẢNH] BỎ flex-wrap:wrap cũ: thẻ phần thưởng tối thiểu 300px (grid minmax 300px) → Icon|Điểm|Ảnh
   THỪA chỗ trên 1 hàng; wrap khiến ô Ảnh rớt xuống dòng riêng, ở đó align-self:stretch không có gì để
   bám → co ~0 (chỉ còn đường kẻ). Ép NOWRAP: ô Ảnh ở cùng hàng, cao bằng cột (đã test 296–360px không
   tràn). Ô Điểm co vừa đủ (min-width sẵn có). */
.reward-shop-admin-row2 { flex-wrap: nowrap; }

/* --- TOAST dùng chung (báo "đã lưu"...) — nổi trên cùng, tự tắt --- */
.app-toast-wrap {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + var(--space-8));
    left: 50%;
    transform: translateX(-50%);
    z-index: 10002;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    pointer-events: none;
    width: max-content;
    max-width: calc(100vw - 2 * var(--space-8));
}
.app-toast {
    background: var(--ink-900);
    color: var(--text-inverse);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--space-5) var(--space-8);
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    text-align: center;
    opacity: 0;
    transform: translateY(-10px);
    transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.app-toast.is-in { opacity: 1; transform: translateY(0); }
.app-toast-success { background: var(--accent-primary); }
.app-toast-error { background: var(--accent-danger); }
.app-toast-info { background: var(--accent-secondary); }

/* ============================================================================
   ĐỢT 3E — DASHBOARD tổng quan + LỊCH SỬ (phụ huynh QUÉT NHANH, hiểu ngay).
   Chỉ HIỂN THỊ + dùng dữ liệu ĐÃ CÓ (không query/tính thống kê mới).
   ============================================================================ */

/* --- A1. Thẻ con: nền kem ấm + bóng mềm; cao bằng nhau (nút xuống đáy) --- */
.dash-card {
    background: var(--surface-card);
    border-color: var(--border-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}
.dash-card-actions { margin-top: auto; }
.dash-card-name { color: var(--text-strong); }
.dash-card-grade {
    display: inline-block;
    background: var(--surface-hover);
    color: var(--text-strong);
    border: 1px solid var(--blue-200);
    border-radius: var(--radius-pill);
    padding: 1px 8px;
    font-weight: var(--weight-bold);
    font-size: var(--text-xs);
}
.dash-card-score { font-size: var(--text-base); color: var(--text-muted); }
.dash-score-num { font-size: var(--text-2xl); font-weight: var(--weight-black); color: var(--accent-primary); }

/* Thanh tiến độ tới hạng kế (width do JS đặt từ scoreInCycle đã có). */
.dash-progress {
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--surface-muted);
    overflow: hidden;
}
.dash-progress-fill {
    height: 100%;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--progress-fill), var(--green-500));
    transition: width var(--dur-slow) var(--ease-out);
}

/* --- A2. Lần học gần nhất (đã có) — dễ đọc --- */
.dash-activity { font-size: var(--text-sm); color: var(--text-body); line-height: var(--leading-snug); }
.dash-activity-when { color: var(--text-muted); font-weight: var(--weight-bold); }
.dash-activity-empty { color: var(--text-faint); font-style: italic; }

/* --- A3. Tô NHẸ theo độ đều đặn: đều → viền trái xanh; lâu → viền trái cam + nhắc thân thiện. KHÔNG ĐỎ. --- */
.dash-card-active { border-left: 4px solid var(--green-400); }
.dash-card-stale { border-left: 4px solid var(--orange-500); }
.dash-recency-note {
    background: var(--surface-warning);
    border: 1px solid var(--border-warning);
    color: var(--text-warning);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-5);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
}

/* --- B. LỊCH SỬ: header đậm, hover hàng, empty thân thiện (bảng/thẻ/empty đã có sẵn) --- */
.hoctap-history-table th,
.activity-history-table th {
    font-weight: var(--weight-extrabold);
    color: var(--text-strong);
}
.hoctap-history-table .ah-parent-row:hover td,
.activity-history-table .ah-parent-row:hover td { background: var(--surface-hover); }
.hoctap-history-table td,
.activity-history-table td { border-bottom-color: var(--border-subtle); }
.history-empty {
    color: var(--text-muted);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
}

/* ============================================================================
   ĐỢT 3F — KHU VUI CHƠI · CỬA HÀNG · GAME · VƯỜN · NHIỆM VỤ (thưởng cho trẻ).
   CSS thuần — KHÔNG đụng logic game/điểm/lượt quay/trao thưởng. Vui nhưng KHÔNG rối.
   ============================================================================ */

/* --- A. CỬA HÀNG: thẻ thưởng; đủ điểm SÁNG + nút xanh; chưa đủ MỜ + nút mờ; giá TO --- */
.rs-card {
    background: var(--surface-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.rs-card-point {
    font-size: var(--text-xl);
    font-weight: var(--weight-black);
    /* [M4.5] --orange-600 trên nền kem chỉ 2,40:1 — dưới ngưỡng 3:1 của chữ LỚN.
       Đổi sang --text-warning: 5,03:1, vẫn giữ tông ấm.
       ⚠️ Rule này ĐÈ .rs-card-point ở style.css:4415 (cùng đặc hiệu, file nạp sau) —
       chỗ kia đã dùng --text-warning từ trước, sửa nhầm chỗ kia là vô ích. */
    color: var(--text-warning);
    white-space: nowrap;
}
.rs-redeem-btn { min-height: var(--touch-min); font-weight: var(--weight-bold); }
/* Đủ điểm (có .btn-bonus) → nút CHÍNH xanh lá, bấm được. */
.rs-redeem-btn.btn-bonus {
    background: var(--accent-primary);
    color: var(--text-on-accent);
}
/* [M4.2 lô 1e] bọc chống HOVER DÍNH trên màn cảm ứng */
@media (hover: hover) {
.rs-redeem-btn.btn-bonus:hover { background: var(--accent-primary-hover); transform: translateY(-1px); }
}
/* Chưa đủ điểm (disabled) → mờ + không bấm được. */
.rs-redeem-btn:disabled {
    opacity: .55;
    cursor: not-allowed;
    background: var(--surface-muted);
    color: var(--text-faint);
    box-shadow: none;
}
/* Thẻ chưa đủ điểm → mờ nhẹ (để đủ-điểm nổi hơn). :has() — trình duyệt 2026 hỗ trợ. */
.rs-card:has(.rs-redeem-btn:disabled) { opacity: .78; }
/* [A2] Banner điểm hiện có — đầu màn cửa hàng, TO, dễ thấy. */
.rs-points-banner {
    background: var(--surface-success);
    border: 1px solid var(--border-success);
    color: var(--text-success);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-7);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    text-align: center;
    margin-bottom: var(--space-6);
}
.rs-points-banner b { font-size: var(--text-xl); font-weight: var(--weight-black); color: var(--accent-primary); }
/* [A1] "Còn thiếu N điểm" — CAM động viên (không đỏ), tạo động lực cố thêm. */
.rs-card-missing {
    text-align: center;
    color: var(--text-warning);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    margin-bottom: var(--space-3);
}
.rs-card-missing b { color: var(--orange-600); font-weight: var(--weight-black); }

/* --- B. KHU VUI CHƠI (tab) + tab con Rèn Luyện: nút to, dễ bấm, đang mở rõ --- */
.garden-tab-btn,
.renluyen-child-tab-btn,
.garden-child-tab-btn { min-height: var(--touch-min); }
/* Tab con Rèn Luyện (nền nhạt khi active) → chữ đậm cho rõ. */
.renluyen-child-tab-btn.active {
    color: var(--text-strong);
    font-weight: var(--weight-extrabold);
}
/* [FIX tương phản] Tab cha Khu vui chơi khi active: garden.css cho nền XANH ĐẬM (--blue-800),
   nên chữ PHẢI TRẮNG. Trước đây rule này ép color:--text-strong (≈--blue-800) → chữ tối trên
   nền tối = MẤT CHỮ (contrast 1.0). Đồng bộ tab chuẩn .history-parent-tab-btn.active.
   (Mobile có rule id riêng #section-playground …active: nền nhạt + chữ đậm — vẫn tương phản.) */
.garden-tab-btn.active {
    background: var(--blue-800);
    color: var(--text-inverse);
    border-bottom-color: var(--yellow-500);
    font-weight: var(--weight-extrabold);
}
/* Giữ chữ RÕ khi focus: chỉ thêm viền outline, KHÔNG đổi nền/màu chữ (tránh nền trùng chữ). */
.garden-tab-btn:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 2px;
}
.renluyen-child-tab-btn.tab-locked { opacity: .55; }

/* --- C. VÒNG QUAY: số lượt RÕ; hết lượt mờ; kết quả nổi --- */
.lucky-spin-status-count {
    font-size: var(--text-2xl);
    font-weight: var(--weight-black);
    color: var(--accent-primary);
}
.lucky-spin-status-box {
    background: var(--surface-card);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xs);
}
.lucky-wheel.wheel-disabled { opacity: .5; filter: grayscale(0.35); cursor: not-allowed; }
.lucky-result {
    font-weight: var(--weight-extrabold);
    color: var(--accent-primary);
}
/* [REDESIGN] Popup ăn mừng sau quay — trúng: xanh lá; chưa trúng: cam nhẹ (không đỏ). */
.lucky-result-popup {
    position: fixed;
    inset: 0;
    z-index: 10002;
    background: rgba(var(--shadow-rgb), 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-8);
    box-sizing: border-box;
}
.lucky-result-popup.hidden-section { display: none !important; }
.lucky-result-popup-box {
    width: min(360px, 100%);
    background: var(--surface-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-9) var(--space-8) var(--space-8);
    text-align: center;
    border-top: 6px solid var(--accent-primary);
    box-sizing: border-box;
}
.lucky-result-popup-box.is-nothing { border-top-color: var(--orange-500); }
.lucky-result-popup-emoji { font-size: 52px; line-height: 1; margin-bottom: var(--space-4); }
.lucky-result-popup-title { margin: 0 0 var(--space-4); font-size: var(--text-2xl); font-weight: var(--weight-black); color: var(--text-strong); }
.lucky-result-popup-prize { font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--accent-primary); margin-bottom: var(--space-8); }
.lucky-result-popup-box.is-nothing .lucky-result-popup-prize { color: var(--text-warning); }
.lucky-result-popup-btn {
    min-height: var(--touch-min);
    min-width: 140px;
    border: none;
    border-radius: var(--radius-md);
    background: var(--accent-primary);
    color: var(--text-on-accent);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    cursor: pointer;
    padding: 0 var(--space-8);
}
.lucky-result-popup-btn:hover { background: var(--accent-primary-hover); }

/* --- E. NHIỆM VỤ: thẻ rõ theo trạng thái; nút Nhận Thưởng nổi bật --- */
.quest-card {
    background: var(--surface-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}
.quest-card.quest-completed { border-color: var(--border-success); }
.quest-title { color: var(--text-strong); font-weight: var(--weight-extrabold); }
.quest-progress-text { font-weight: var(--weight-bold); color: var(--text-body); }
/* Nút "Nhận Thưởng" (đạt) → xanh lá CHÍNH nổi bật. */
.quest-btn.btn-claim {
    background: var(--accent-primary);
    color: var(--text-on-accent);
    min-height: var(--touch-min);
    font-weight: var(--weight-extrabold);
}
/* [M4.2 lô 1e] bọc chống HOVER DÍNH trên màn cảm ứng */
@media (hover: hover) {
.quest-btn.btn-claim:hover { background: var(--accent-primary-hover); transform: translateY(-1px); }
}
.quest-btn.btn-claimed { min-height: var(--touch-min); }
.quest-btn:disabled { opacity: .55; cursor: not-allowed; }

/* --- D. GAME: khung/nút rõ, ≥44px. CHỈ khung + nút, KHÔNG đụng nội dung/logic. --- */
/* Lật thẻ: panel kết thúc + nút. */
.mg-start-btn { min-height: var(--touch-min); }
.mg-overlay-panel {
    background: var(--surface-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.mg-complete-text__title { color: var(--accent-primary); font-weight: var(--weight-black); }
/* Vườn: nút thao tác ≥44px. */
.plot-btn { min-height: var(--touch-min); }
/* Đua toán: override CSS-inject-runtime bằng đặc hiệu cao (#racing-panel ...). */
#racing-panel .math-racing-start-btn { min-height: var(--touch-min); font-weight: var(--weight-bold); }
#racing-panel .math-racing-choice-btn { min-height: var(--touch-min); }
/* KHÔNG đổi màu tiêu đề đua (nền do CSS-inject, tránh chữ vô hình) — chỉ đậm hơn. */
#racing-panel .math-racing-title { font-weight: var(--weight-black); }

/* ============================================================================
   ĐỢT 3G — KHU QUẢN TRỊ (danh sách TK · duyệt thanh toán · cấu hình) — HOÀN THIỆN.
   CSS thuần (lớp phủ nạp CUỐI). TUYỆT ĐỐI KHÔNG đụng logic ghi tiền (window.fbAdmin
   ở index.html), KHÔNG đổi thứ tự / gộp / bỏ 3 nút duyệt — chỉ đổi STYLE + KHOẢNG CÁCH.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   A. DANH SÁCH TÀI KHOẢN
   --------------------------------------------------------------------------- */
/* A1. Header BẢNG = thanh gradient xanh nhạt, DÍNH (sticky) khi cuộn — mắt luôn
   thấy tên cột. border-spacing ngang = 0 nên các ô th ghép thành thanh liền mạch. */
.aa-table thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    padding: 9px 12px;
    color: var(--blue-900);
    background: linear-gradient(180deg, var(--surface-subtle) 0%, var(--blue-100) 100%);
    box-shadow: 0 2px 4px rgba(var(--shadow-rgb), .10);
}
.aa-table thead th:first-child {
    border-top-left-radius: var(--radius-md);
    border-bottom-left-radius: var(--radius-md);
}
.aa-table thead th:last-child {
    border-top-right-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}
/* Hàng: hover thêm nền XANH NHẠT (cộng với viền/bóng đã có) → lướt mắt dễ. */
.aa-table tbody .aa-row:hover .aa-td { background: var(--surface-subtle); }

/* A2. Ô TÌM: gắn icon kính lúp (SVG nội tuyến, KHÔNG tải ngoài). */
.aa-search {
    padding-left: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6FAF' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.5' y2='16.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 13px center;
    background-size: 17px;
}

/* A3. Nút "Dọn phiếu hết hiệu lực" = VIỀN trung tính (KHÔNG đỏ, KHÔNG giống nút
   nguy hiểm). Trước đây .aa-btn-outline chưa có CSS → rơi về .aa-btn; nay định nghĩa. */
.aa-btn-outline {
    background: var(--surface-white);
    color: var(--accent-secondary-hover);
    border: 1.5px solid var(--blue-200);
}
.aa-btn-outline:hover { background: var(--surface-subtle); }

/* A4. Banner "⚠️ Cần hoàn tiền: N" — ĐẬP VÀO MẮT + bấm để lọc (vốn đã là <button>). */
.aa-refund-banner-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    border-left: 5px solid var(--red-500);
    font-size: 15px;
    box-shadow: 0 1px 6px rgba(210, 60, 50, .14);
}

/* ---------------------------------------------------------------------------
   B. CHI TIẾT NHÀ + KHU DUYỆT THANH TOÁN  (⭐ NHẠY CẢM — TIỀN THẬT)
   --------------------------------------------------------------------------- */
/* B1. Thẻ phiếu ĐANG CHỜ: nổi bật "cần xử lý"; SỐ TIỀN to; mã phiếu giãn chữ dễ đọc. */
.aa-pay-wc-card {
    border-left: 4px solid var(--orange-500);
    box-shadow: 0 2px 10px rgba(214, 158, 46, .12);
}
.aa-pay-wc-info b { font-size: 18px; color: var(--blue-900); }
.aa-pay-code { letter-spacing: .5px; }

/* B2. ⭐⭐ BA NÚT DUYỆT — GIỮ NGUYÊN thứ tự DOM & class; chỉ đổi STYLE + KHOẢNG CÁCH.
   [1] ✅ Xác nhận  (.aa-btn-primary → XANH LÁ, to/đậm hơn) — bên TRÁI.
   [2] 🔍 Kiểm tra lại (.aa-btn) — ở giữa, trung tính.
   [3] ❌ Huỷ bỏ   (.aa-btn-danger → ĐỎ) — ĐẨY XA sang PHẢI, cách hẳn nút Xác nhận
       (chống bấm nhầm "mất tiền"). Không đảo/gộp/bỏ nút nào. */
.aa-pay-wc-actions { gap: 10px; align-items: center; }
/* [M4.2 lô 1h] 42px → 44px cho đủ chuẩn chạm. Ba nút này ĐỤNG TIỀN nên cố ý dùng
   `.btn` TRẦN chứ KHÔNG dùng `.btn-compact`: compact bóp đệm ngang từ 18px xuống
   12px, mà 18px chính là khoảng cách chống bấm nhầm ghi ở ghi chú ngay trên. */
.aa-pay-wc-actions .aa-btn { min-height: var(--touch-min); }
.aa-pay-wc-actions .aa-btn-primary {
    font-weight: 800;
    padding-left: 18px;
    padding-right: 18px;
    box-shadow: 0 2px 8px rgba(76, 175, 80, .28);
}
.aa-pay-wc-actions .aa-btn-danger { margin-left: auto; }
/* Cùng nguyên tắc cho nút trong LỊCH SỬ phiếu: nút Huỷ tách sang phải. */
.aa-pay-hist-actions .aa-btn-danger { margin-left: auto; }

/* B3. POPUP duyệt. Dòng "Hạn sau gia hạn" = nền xanh + chữ to → chốt hạ đập vào mắt. */
.aa-modal-kv-hl {
    background: var(--surface-success);
    border-radius: var(--radius-sm);
    padding: 8px 10px;
    border-bottom: none;
    margin-top: 4px;
}
.aa-modal-kv-hl > span { color: var(--text-success); font-weight: 800; }
.aa-modal-kv-hl > b { color: var(--text-success); font-size: 18px; }
/* Cảnh báo (phiếu đã huỷ/hết hạn…) mạnh hơn: viền đỏ bên trái. */
.aa-modal-warn { border-left: 4px solid var(--red-500); font-weight: 600; }
/* Popup HUỶ: 2 lựa chọn "Chưa nhận / Đã nhận (cần hoàn tiền)" thành Ô CHỌN rõ ràng;
   ô đang chọn viền xanh + nền nhạt → admin THẤY RÕ đang chọn gì trước khi bấm Huỷ.
   (Giữ mặc định "Chưa nhận" đã tick sẵn — an toàn cho luồng needsRefund.) */
.aa-modal-radio {
    border: 1.5px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    margin-bottom: 8px;
    transition: border-color .12s ease, background .12s ease;
}
.aa-modal-radio:has(input:checked) {
    border-color: var(--accent-secondary);
    background: var(--surface-subtle);
}

/* B4. LỊCH SỬ phiếu: nhãn "⚠️ CẦN HOÀN TIỀN" có viền; hover item nhẹ. */
.aa-pay-refund-warn { border: 1px solid var(--border-danger); }
.aa-pay-hist-item:hover { border-color: var(--blue-200); }

/* ---------------------------------------------------------------------------
   C. TAB CẤU HÌNH (thanh toán / đề toán / hệ thống) — quét nhanh.
   --------------------------------------------------------------------------- */
/* Bảng gói giá: kẻ ZEBRA để dò từng gói dễ; header đậm màu hơn chút. */
.billing-pkg-table tbody tr:nth-child(even) td { background: var(--surface-tint-blue); }
.billing-pkg-table th { color: var(--text-strong); }

/* ============================================================================
   🔔 CHUÔNG THÔNG BÁO — badge số (trên nút) + popup dropdown danh sách.
   Chấm CAM = việc cần làm (không mờ dù đã đọc); chấm XANH = tin chỉ-để-biết chưa đọc.
   ============================================================================ */
.header-icon-btn.has-bell-badge { position: relative; }
.header-icon-btn.has-bell-badge::after {
    content: attr(data-bell-count);
    position: absolute; top: -5px; right: -5px;
    min-width: 17px; height: 17px; padding: 0 4px;
    background: var(--red-500); color: var(--text-inverse);
    border: 2px solid var(--surface-white); border-radius: var(--radius-pill);
    font-size: 10px; font-weight: 800; line-height: 13px; text-align: center;
    box-sizing: border-box; z-index: 3;
}

.bell-popup {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: min(360px, calc(100vw - 24px));
    max-height: min(70vh, 520px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--surface-white);
    border: 1px solid var(--border-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: 10001;
}
.bell-popup.hidden-section { display: none !important; }
.bell-popup-head {
    position: sticky; top: 0;
    display: flex; align-items: center; justify-content: space-between;
    background: linear-gradient(180deg, var(--surface-subtle), var(--blue-100));
    color: var(--blue-900); font-weight: 800; font-size: 15px;
    padding: 11px 14px; border-bottom: 1px solid var(--border-card);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.bell-popup-close {
    border: none; background: transparent; cursor: pointer;
    font-size: 22px; line-height: 1; color: var(--text-strong);
    width: 32px; height: 32px; border-radius: var(--radius-circle);
}
.bell-popup-close:hover { background: rgba(var(--shadow-rgb), .1); }
.bell-popup-list { padding: 6px; }
.bell-empty { padding: 30px 16px; text-align: center; color: var(--text-muted); font-style: italic; }

.bell-item {
    display: flex; flex-direction: column; gap: 8px;
    padding: 11px 12px; border-radius: var(--radius-md);
    border-bottom: 1px solid var(--border-faint);
}
.bell-item:last-child { border-bottom: none; }
.bell-item-action { background: var(--surface-warning); }
.bell-item-main { display: flex; gap: 9px; align-items: flex-start; }
.bell-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: var(--radius-circle); margin-top: 5px; background: transparent; }
.bell-dot-info { background: var(--accent-secondary); }
.bell-dot-action { background: var(--orange-500); }
.bell-item-body { min-width: 0; flex: 1 1 auto; }
.bell-item-text { font-size: 14px; line-height: 1.5; color: var(--text-strong); word-break: break-word; }
.bell-item-text b { font-weight: 800; }
.bell-item-time { font-size: 12px; color: var(--text-muted); margin-top: 3px; }
/* Dòng phụ nhỏ trong 1 thông báo (vd EMAIL của tài khoản vừa đăng ký, dưới TÊN phụ huynh). */
.bell-sub { display: block; font-size: 12.5px; color: var(--text-muted); word-break: break-all; margin-top: 2px; }
/* 📄 Chỉ-để-biết ĐÃ ĐỌC → MỜ đi. ✋ Cần-làm KHÔNG mờ (dù đã đọc) — không gắn class read. */
.bell-item-read .bell-item-text { color: var(--text-muted); font-weight: 500; }
.bell-item-read .bell-item-text b { font-weight: 600; color: var(--text-muted); }

.bell-item-actions { display: flex; flex-wrap: wrap; gap: 8px; padding-left: 18px; }
.bell-act-btn {
    min-height: 40px; display: inline-flex; align-items: center; justify-content: center;
    padding: 0 14px; border-radius: var(--radius-md);
    font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer;
    background: var(--surface-white); color: var(--accent-secondary-hover);
    border: 1.5px solid var(--blue-200); text-decoration: none;
}
.bell-act-btn:hover { background: var(--surface-subtle); }
.bell-act-primary { background: var(--accent-primary); color: var(--text-on-accent); border-color: var(--accent-primary); }
.bell-act-primary:hover { background: var(--accent-primary-hover); }
.bell-act-zalo { background: var(--accent-secondary); color: var(--text-inverse); border-color: var(--accent-secondary); }
.bell-act-zalo:hover { background: var(--accent-secondary-hover); }

/* Điện thoại: popup bám mép, nút chạm ≥44px, né tai thỏ. */
@media (max-width: 900px) {
    .bell-popup {
        position: fixed;
        top: calc(env(safe-area-inset-top, 0px) + 56px);
        left: 8px; right: 8px;
        width: auto;
        max-height: 74vh;
    }
    .bell-act-btn { min-height: 44px; }
}

/* ============================================================================
   [ĐỢT 5 · M4.2 lô 1b] HỆ NÚT DÙNG CHUNG `.btn*`
   Đặc tả: docs/mockup/M2-3-dac-ta-chot.md mục 5.1

   📌 Đại ca đã chốt phương án "TẠO CLASS MỚI" (thay vì sơn lại class cũ tại chỗ).

   🔒 HỆ NÀY ĐANG NGỦ ĐÔNG: MỌI selector dưới đây đều đòi có `.btn`, kể cả các
      biến thể (`.btn.btn-outline` chứ không phải `.btn-outline`). Nhờ vậy chừng
      nào chưa gắn class `.btn` vào nút nào thì KHÔNG nút nào đổi một pixel.
      ⚠️ Đặc biệt quan trọng với `.btn-outline` và `.btn-bonus` — hai tên này ĐÃ
         TỒN TẠI trong style.css và đang được dùng thật. Viết `.btn-outline {…}`
         trần ở đây là đè lên 31 nút đang chạy mà không ai bấm nút nào.

   Khung nút (padding, bo góc, cỡ chữ, gap, transition) đã do luật `button` trần
   ở đầu style.css lo — khối này CHỈ lo MÀU + 4 TRẠNG THÁI + tiêu điểm bàn phím.
   ============================================================================ */

.btn {
    min-height: var(--touch-min);          /* 44px — chuẩn chạm, không ngoại lệ */
    border-radius: var(--radius-md);
    font-size: var(--text-md);
    font-weight: var(--weight-extrabold);
    box-shadow: var(--shadow-sm);
    /* ⚠️ CỐ Ý KHÔNG khai `border: none` ở đây. Luật `button` trần đầu style.css đã
       khai rồi, nên nút thường vẫn không viền; còn nút nào TỰ ĐẶT viền (nút Google
       ở màn đăng nhập, .bell-act-btn, .shopee-mini-btn…) thì GIỮ được viền của nó.
       Khai ở đây là xoá viền của cả nhóm đó mà chẳng để làm gì. */
}

/* ⚠️ HÀNG RÀO BẮT BUỘC (đặc tả mục 5.10): mọi hiệu ứng RÊ CHUỘT phải nằm trong
   @media (hover: hover). Trên màn cảm ứng, hover "dính" lại sau khi chạm → nút bị
   nhấc lên rồi KẸT nguyên trạng thái đó. Grep cả 7 file CSS của app trước đợt này
   = 0 kết quả, tức app chưa từng có hàng rào này. */
/* ⚠️ VÌ SAO BỌC `:where()`: `.btn:hover:not(:disabled):not(.is-grading)` có độ ưu tiên
   (0,4,0) — CAO hơn mọi rule riêng của từng họ nút. Mà app có 8 họ nút tự đặt
   `transform` lúc rê/nhấn, trong đó nhiều nút cố ý LÚN XUỐNG (kiểu nút 3D):
   `.btn-start-exam:hover` và `.btn-finish-exam:hover` translateY(+2px),
   `.quest-btn.btn-claim:hover` +2px, `.symbol-key:active` scale(.96)…
   Để nguyên (0,4,0) là mọi nút đó bị đảo thành NHẤC LÊN — mất hẳn cảm giác bấm.
   `:where()` cho toàn bộ phần điều kiện về 0 → cả rule chỉ còn (0,1,0), tức `.btn`
   chỉ đưa ra MẶC ĐỊNH, họ nào có cá tính riêng thì cá tính đó thắng. */
@media (hover: hover) {
    .btn:where(:hover):where(:not(:disabled)):where(:not(.is-grading)) {
        transform: translateY(-2px);
    }
}

.btn:where(:active):where(:not(:disabled)):where(:not(.is-grading)) {
    transform: translateY(1px);
    box-shadow: var(--shadow-press);
}

/* Tiêu điểm BÀN PHÍM: bắt buộc mọi nút. Dùng :focus-visible nên chuột bấm không
   hiện quầng, chỉ khi đi bằng phím Tab mới hiện. */
.btn:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* Trạng thái 4 (vô hiệu) và trạng thái 5 (ĐANG XỬ LÝ — app có thật:
   setFinishExamBusy đặt disabled + class .is-grading + đổi chữ "⏳ Đang chấm…").
   Hai trạng thái dùng chung một kiểu, và GIỮ NGUYÊN cơ chế đổi chữ của JS. */
.btn:disabled,
.btn.is-grading {
    opacity: .5;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* ---- BIẾN THỂ MÀU (tương phản đã đo, xem đặc tả mục 6) ---- */
.btn.btn-primary   { background: var(--accent-primary);   color: var(--text-inverse); }  /* 4,93:1 */
.btn.btn-secondary { background: var(--accent-secondary); color: var(--text-inverse); }  /* 5,23:1 */
.btn.btn-danger    { background: var(--accent-danger);    color: var(--text-inverse); }  /* 5,07:1 */
/* 🔴 Nút CAM BẮT BUỘC chữ xanh đậm. Chữ trắng trên cam chỉ 2,1:1 — mất chữ. */
.btn.btn-cta       { background: var(--accent-highlight); color: var(--blue-900); box-shadow: var(--shadow-cta); }  /* 5,54:1 */
.btn.btn-outline   { background: var(--surface-white);    color: var(--text-strong); border: var(--border-width) solid var(--accent-secondary); }  /* 9,24:1 */

@media (hover: hover) {
    .btn.btn-primary:hover:not(:disabled)   { background: var(--accent-primary-hover); }
    .btn.btn-secondary:hover:not(:disabled) { background: var(--accent-secondary-hover); }
    .btn.btn-outline:hover:not(:disabled)   { background: var(--surface-hover); }
    .btn.btn-cta:hover:not(:disabled)       { background: var(--orange-600); }
    .btn.btn-danger:hover:not(:disabled)    { background: var(--red-700); }
}

/* ---- BIẾN THỂ CỠ ---- */
.btn.btn-hero {
    min-height: 64px;
    border-radius: var(--radius-xl);
    font-size: var(--text-xl);
}
/* ⚠️ "compact" là HẸP hơn, KHÔNG phải THẤP hơn — vẫn giữ đủ 44px chuẩn chạm.
   Đặc tả M2-3 §4.3 ghi: "Vùng chạm ≥ --touch-min (44px) — KHÔNG NGOẠI LỆ",
   nên biến thể này KHÔNG có nấc dưới 44px. Chỗ "nhỏ" nằm ở PADDING NGANG và CỠ CHỮ.

   ⚠️ `min-height` KHAI LẠI có chủ đích dù `.btn` đã có: ở đây selector là
      `.btn.btn-compact` (0,2,0), đủ sức thắng các rule NGỮ CẢNH (0,2,0) của
      admin-accounts.css nhờ file này nạp sau. Viết `.btn` không thôi (0,1,0) là thua.
   ⚠️ KHÔNG khai padding DỌC: giữ 10px của luật `button` trần. `<button>` là
      border-box nên 10px nằm TRONG 44px, không đội chiều cao lên.
   ⚠️ Cỡ chữ 15px chứ không phải 14px — thang chữ của dự án nhảy thẳng 13 → 15
      (xem ghi chú ở đầu style.css), chèn 14px là đẻ ra nấc thang thứ hai. */
.btn.btn-compact {
    min-height: var(--touch-min);
    padding-inline: var(--btn-pad-x-sm);
    font-size: var(--text-base);
}

/* ----------------------------------------------------------------------------
   [M4.2 lô 1c] CƯỠNG CHẾ CHUẨN CHẠM ≥44px cho 3 nhóm nút còn sót.
   Ba nhóm này KHÔNG gắn `.btn` được vì chiều cao của chúng bị khai ở rule có độ
   ưu tiên cao hơn `.btn` (0,1,0), nên gắn class vào cũng vô ích:
     · `.rs-card .rs-redeem-btn { min-height: 40px }` — (0,2,0), style.css
     · `.header-icon-btn { height: 42px }` + nhánh 38px trong media query ≤900px
     · `.menu-link { min-height: 34px }` — bản vá 44px cũ nằm TRONG media ≤900px
       nên trên PC không ăn.
   Khối này nằm ở file nạp SAU CÙNG và ngoài mọi media query nên thắng chắc.
   ⚠️ Dùng `height` cho .header-icon-btn (không phải min-height) vì nút đó vuông,
      bề ngang đã cố định — đổi sang min-height là méo hình tròn của nút.
   ---------------------------------------------------------------------------- */
.header-icon-btn {
    height: var(--touch-min);
    width: var(--touch-min);
}

.menu-link,
.student-menu-link {
    min-height: var(--touch-min);
}

.rs-card .rs-redeem-btn {
    min-height: var(--touch-min);
}

/* ----------------------------------------------------------------------------
   [M4.2 lô 3] Ô NHẬP — chuẩn chạm ≥44px cho MỌI ô.
   Đặc tả M2-3 §5.2: chiều cao `min-height: var(--touch-min)`.
   Khảo sát màn thật đếm được 33/43 ô đang dưới 44px.

   ⚠️ Liệt kê theo TÊN LỚP chứ không viết `.app input` chung chung: app có ô nhập
      nằm trong hàng bảng và trong thẻ nhỏ, quét chung dễ thổi cao chỗ không mong muốn.
   ⚠️ `.answer-input` KHÔNG có ở đây — nó bị một rule `!important` khoá cứng chiều cao
      nên phải sửa tại chỗ trong style.css (xem ghi chú ở đó).
   ---------------------------------------------------------------------------- */
.pdef-input,
.aa-input,
.shopee-input,
.billing-input,
.auth-input,
.admin-password-input,
.training-date-input,
.inventory-select,
.lucky-rate-input,
.promo-input,
.acct-exp-select,
.trial-months-select,
.password-input,
.settings-input,
.quests-config-input {
    min-height: var(--touch-min);
    /* ⚠️ BẮT BUỘC đi kèm: app KHÔNG có reset border-box toàn cục cho ô nhập. Thiếu dòng
       này thì `min-height` được CỘNG THÊM vào đệm + viền — đo thật cho ra
       .training-date-input 56px và .promo-input 68px thay vì 44px. */
    box-sizing: border-box;
}

/* Ô nhập trong màn CÀI ĐẶT không mang class riêng (vd #correctStreakStartDate,
   các ô ngày/tháng kỳ thi) — phủ theo phạm vi màn để không sót, và để những ô
   thêm sau này tự động đạt chuẩn mà không phải nhớ gắn class. */
#section-settings input[type="text"],
#section-settings input[type="number"],
#section-settings input[type="date"],
#section-settings input[type="password"],
#section-settings select {
    min-height: var(--touch-min);
    box-sizing: border-box;
}

/* ----------------------------------------------------------------------------
   [M4.2 lô 5] THẺ — đệm co lại trên ĐIỆN THOẠI.
   Đặc tả M2-3 §5.3: đệm trong `--space-8` (18px), điện thoại co còn `--space-7` (14px).
   Màn hẹp mà giữ 18px mỗi bên là mất 36px bề ngang cho chỗ trống.

   ⚠️ KHÔNG liệt kê `.admin-child-panel` và `.garden-child-panel` dù đặc tả §5.3 có
      ghi tên: kiểm ra chúng KHÔNG PHẢI THẺ mà là khung chứa tab (chỉ khai
      display:none/block). Cho chúng đệm là đẩy lệch mọi nội dung bên trong.
   ⚠️ Cũng không có `.quests-config-box`: nó luôn đi KÈM `.settings-group-box`
      (index.html:1574…), tức là biến thể chứ không phải thẻ riêng — khai thêm là
      cộng dồn đệm hai lần.
   ---------------------------------------------------------------------------- */
@media (max-width: 640px) {
    .main-panel,
    .settings-group-box,
    .dash-card,
    .lucky-inventory-box {
        padding: var(--space-7);
    }
}

/* ----------------------------------------------------------------------------
   [M4.2 lô 6] MODAL — thống nhất HỘP theo đặc tả §5.6 (đại ca chốt 08/08).
   Khảo sát trước khi sửa: 8 họ modal đang có 6 SẮC lớp phủ và 4 BO GÓC khác nhau
   (14 / 16 / 20 / 0px), hộp thì trắng trong khi mọi thẻ khác của app đã là kem.

   Lớp phủ đã đưa về một sắc `rgba(var(--shadow-rgb), …)` ngay tại chỗ khai của
   từng modal — nhờ đó hệ theme M5 với tới được.
   ⚠️ GIỮ RIÊNG độ đậm ở 2 chỗ: màn CẮT ẢNH học sinh (.65 — là trình sửa ảnh, nền
      phải tối hẳn mới thấy rõ vùng cắt) và popup admin (.55 — phía sau là bảng
      dày chữ). Đặc tả nói thống nhất MỘT SẮC, không nói phải cùng độ đậm.
   ---------------------------------------------------------------------------- */
.confirm-dialog-box,
.exam-summary-box,
.promo-admin-modal-box,
.reward-detail-box,
.aa-modal,
.mg-overlay-panel {
    background: var(--surface-card);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

/* ============================================================================
   [M4.2b] THANH TAB CUỘN NGANG + CHỈ BÁO "CÒN TAB BỊ ẨN"
   Mẫu đã dựng và đo đạt trong docs/mockup/huong-A.html (M2.2, đại ca duyệt).

   Cấu trúc: .tabnav (khung bọc, KHÔNG cuộn) > .tabnav-bar (hàng tab, CUỘN NGANG)
             + 2 mũi tên .tabnav-hint là ANH EM, nằm NGOÀI vùng cuộn.

   5 BẪY đã đào sẵn trong kế hoạch — mỗi dòng dưới đây gỡ một bẫy:
   ① Bọc thêm 1 lớp là GIẾT position:sticky của 3 hàng tab → quyền sticky được
      CHUYỂN lên khung bọc bằng lớp .tabnav--sticky-* (xem cuối khối).
   ② Khung bọc BẮT BUỘC position:relative — .app có backdrop-filter ở PC nhưng bị
      gỡ ở ≤900px, thiếu dòng này thì mũi tên văng đi 2 nơi khác nhau ở 2 khổ màn.
   ③ Mũi tên là ANH EM NGOÀI vùng cuộn — làm con của phần tử overflow-x:auto thì
      nó TRÔI THEO nội dung.
   ④ overflow-y: hidden BẮT BUỘC — để auto sẽ sinh thanh cuộn DỌC thừa.
   ⑤ `button { margin: 3px }` toàn cục cộng dồn với gap → phải reset margin: 0.
   ============================================================================ */
.tabnav {
    position: relative;              /* ② */
    padding-inline: 14px;            /* lề riêng cho mũi tên — KHÔNG đè lên tab */
}

.tabnav > .tabnav-bar {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;              /* ④ */
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    scroll-padding-inline: 52px;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.tabnav > .tabnav-bar::-webkit-scrollbar { display: none; }

.tabnav > .tabnav-bar > button,
.tabnav > .tabnav-bar > a {
    margin: 0;                       /* ⑤ */
    flex: 0 0 auto;
    /* PEEK: luôn ló mẩu tab kế để trẻ biết còn tab phía sau và chạm thẳng vào được */
    max-width: calc(100% - 56px);
}

/* Mũi tên nhỏ — CHỈ ĐỂ NHÌN, không nuốt cú chạm */
.tabnav-hint {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 10px;
    height: 18px;
    display: none;                   /* ③ mặc định ẩn, chỉ hiện khi thật sự tràn */
    pointer-events: none;
    z-index: 2;
    color: var(--tabnav-hint-color);
    font-size: 15px;
    line-height: 18px;
    font-weight: 900;
    text-align: center;
}
.tabnav-hint--prev { left: 2px; }
.tabnav-hint--next { right: 2px; }
.tabnav.can-prev > .tabnav-hint--prev,
.tabnav.can-next > .tabnav-hint--next { display: block; }

/* ① CHUYỂN QUYỀN STICKY lên khung bọc — giữ nguyên điều kiện media query gốc */
.tabnav--sticky-panel { position: sticky; top: 0; z-index: 6; }
.tabnav--sticky-panel > .tabnav-bar { position: static; }

@media (max-width: 900px) {
    .tabnav--sticky-top {
        position: sticky;
        top: var(--app-mobile-sticky-top, 0px);
        z-index: 30;
        background: var(--surface-card);
        box-shadow: 0 4px 10px rgba(var(--shadow-rgb), 0.06);
    }
    .tabnav--sticky-top > .tabnav-bar { position: static; background: none; box-shadow: none; }
}

/* ============================================================================
   [ĐỢT 5 · M9.3 — 10/08/2026] KHU VƯỜN trên PC: 3 ô đất hàng cuối bị XÉN MẤT,
   không cuộn tới được.
   ĐO THẬT trên bản live (đi ngược từ lưới lên từng tầng cha):
     #section-playground  cao 361 / nội dung 472  → tràn 111px, overflow:hidden ⇒ XÉN
     .garden-wrapper      cao 361 / nội dung 471  → tràn 110px
     #garden-panel-garden cao 261 / nội dung 391  → tràn 130px
     #gardenRealContent   cao 391  ← MẮT XÍCH GÃY
   NGUYÊN NHÂN GỐC: chuỗi flex dựng ở style.css (@media min-width:901px) có đủ
   #garden-panel-garden → #garden-child-plots → .garden-plots-grid, nhưng BỎ SÓT
   đúng tầng #gardenRealContent nằm giữa. Tầng này là display:block, flex:0 1 auto,
   min-height:auto ⇒ KHÔNG co theo cha và CẮT ĐỨT chuỗi flex, nên lưới đội cao ra
   ngoài khung rồi bị overflow:hidden của khu chơi xén mất hàng cuối.
   CÁCH SỬA: nối lại mắt xích đó vào chuỗi flex, và cho CHÍNH LƯỚI cuộn nội bộ
   (thanh Nước/Phân/Tiến độ + tab vẫn đứng yên — đúng ý đồ thiết kế gốc, và đúng
   yêu cầu "chỉ cuộn trong tab Vườn cây, không cuộn cả trang").
   grid-auto-rows: minmax(130px, 1fr) giữ được cả hai đời sống — màn CAO thì hàng
   vẫn giãn lấp đầy khung y như trước, màn THẤP thì hàng giữ 130px và lưới cuộn.
   ⚠️ PHẢI đặt ở file này: garden.css nạp Ở TRONG BODY (index.html:2246) nên rule
   viết trong style.css KHÔNG thắng được grid-auto-rows:1fr của nó.
   CHỈ PC — dưới 901px giữ nguyên như cũ (đại ca dặn không đụng điện thoại).
   ĐO LẠI SAU VÁ: mọi tầng tràn 0; lưới cuộn được; ô cuối trước cuộn khuất 340px,
   sau cuộn hiện đủ; lưới không vượt ra ngoài màn.
   ============================================================================ */
@media (min-width: 901px) {
    #garden-panel-garden > #gardenRealContent {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .garden-plots-grid {
        overflow-y: auto;
        grid-template-rows: none;
        grid-auto-rows: minmax(130px, 1fr);
    }
}
