/* ============================================================================
 * style-5.css   —   Lõi phần 5
 * ----------------------------------------------------------------------------
 * 🔴 LÁT CẮT CỦA style.css. 11 lát PHẢI nạp ĐÚNG THỨ TỰ trong index.html.
 *    Đổi thứ tự = đổi kết quả đè = lệch giao diện, KHÔNG có lỗi nào báo.
 *    Nối cả 11 lát (bỏ banner này) = style.css gốc TỪNG BYTE.
 *    Kiểm:  node scripts/cut-css.js --verify
 *
 * MỤC LỤC — 1320 dòng · 151 rule · 47.4 KB
 *   dòng    28–130    Lịch sử                 (16 rule)
 *   dòng   133–169    Tổng quan & biểu đồ     (5 rule)
 *   dòng   197–304    Học sinh & huy hiệu     (12 rule)
 *   dòng   326–355    Thành phần dùng chung   (3 rule)
 *   dòng   377–467    Nền & còn lại           (8 rule)
 *   dòng   476–594    Nền & còn lại           (12 rule)
 *   dòng   610–658    Nền & còn lại           (7 rule)
 *   dòng   743–802    Cài đặt & khu admin     (6 rule)
 *   dòng   830–918    Điều hướng & khung      (9 rule)
 *   dòng  1060–1143   Học sinh & huy hiệu     (10 rule)
 *   dòng  1148–1179   Tổng quan & biểu đồ     (3 rule)
 *   dòng  1208–1241   Cửa hàng & phần thưởng  (4 rule)
 *
 * Bảng tra đầy đủ mọi miền:      docs/BANDO-CSS.md
 * Vì sao cắt kiểu này:           docs/kien-truc/K6-1-so-do-tach-css.md
 * ========================================================================== */

/* --- 4 mảng lịch sử: 2 cột × 2 hàng (rộng, cân đối) --- */
.dash-hist-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
}

.dash-hist-block {
    background: var(--surface-white);
    border: 1px solid var(--border-card);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(var(--shadow-rgb), 0.05);
}

.dash-hist-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: var(--surface-tint-blue);
    border-bottom: 2px solid var(--dash-cat-color, var(--accent-secondary));
    font-weight: 800;
    color: var(--text-strong);
}

.dash-hist-head-label {
    flex: 1 1 auto;
}

.dash-hist-count {
    background: #eef7ff;
    border-radius: var(--radius-pill);
    padding: 1px 9px;
    font-size: 12px;
    color: var(--text-muted);
}

.dash-hist-list {
    padding: 6px 10px;
}

.dash-hist-empty {
    padding: 14px;
    text-align: center;
    color: var(--ink-300);
    font-style: italic;
}

.dash-hist-row {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 8px 4px;
    border-bottom: 1px solid var(--border-faint);
}

.dash-hist-row:last-child {
    border-bottom: none;
}

.dash-hist-icon {
    font-size: 18px;
    flex: 0 0 auto;
    line-height: 1.4;
}

.dash-hist-body {
    flex: 1 1 auto;
    min-width: 0;
}

.dash-hist-title {
    font-size: 14px;
    color: var(--text-strong);
    font-weight: 700;
}

.dash-hist-note {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-top: 1px;
}

.dash-hist-right {
    flex: 0 0 auto;
    text-align: right;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
}

.dash-hist-point {
    font-weight: 800;
    color: var(--text-success);
    font-size: 14px;
}

.dash-hist-when {
    font-size: 11.5px;
    color: var(--ink-300);
    white-space: nowrap;
}

/* --- Phân trang --- */
.dash-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 8px;
    border-top: 1px solid var(--border-faint);
}

.dash-pager-btn {
    cursor: pointer;
    border: 1px solid var(--border-card);
    background: var(--surface-white);
    color: var(--accent-secondary);
    border-radius: var(--radius-sm);
    width: 32px;
    height: 32px;
    font-size: 16px;
    font-weight: 800;
}

.dash-pager-btn:disabled {
    opacity: .4;
    cursor: default;
}

.dash-pager-info {
    font-size: 13px;
    color: var(--text-muted);
    font-weight: 700;
}

/* --- Điện thoại: rớt 1 cột, nút/vùng chạm đủ lớn --- */
@media (max-width: 600px) {
    .dash-grid {
        grid-template-columns: 1fr;
    }

    .dash-hist-grid {
        grid-template-columns: 1fr;
    }

    .dash-header {
        padding: 14px;
    }

    .dash-greet {
        font-size: 17px;
    }

    .dash-card-actions {
        flex-direction: column;
    }

    .dash-btn {
        width: 100%;
    }
}

/* ==================================================================== */
/* [SIDEBAR GỌN] Dải CHIP đổi con (thay danh sách con dài).             */
/*  Chip giữ class menu-link/student-menu-link để logic cũ chạy nguyên; */
/*  ở đây override bằng độ ưu tiên cao hơn để hiển thị dạng "viên".     */
/* ==================================================================== */
.student-chip-bar {
    display: flex;
    flex-wrap: nowrap;
    /* 3 chip LUÔN 1 hàng trên desktop */
    gap: 6px;
    /* margin-top + padding-top: đẩy chip rời mép trên vùng cuộn (.side-menu-nav overflow)
       để cạnh trên chip KHÔNG bị mép cắt che, nhất là khi hover viền đậm. */
    margin: 0 0 12px;
    padding-top: 3px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border-card);
    /* tách chip với 3 mục chức năng */
}

.student-chip-bar .student-chip {
    position: relative;
    /* mốc z-index để viền không bị bóng chip bên cạnh đè */
    display: inline-flex;
    flex-direction: row;
    flex: 1 1 0;
    /* CHIA ĐỀU bề rộng → không vỡ 1 hàng */
    min-width: 0;
    /* cho phép co + ellipsis */
    align-items: center;
    justify-content: center;
    gap: 4px;
    /* [M4.3] 38px → chuẩn chạm 44px. ĐO TRƯỚC KHI SỬA để chắc không phá bản vá
       "menu bên bị cắt trên laptop màn thấp": ở màn cao 900px menu chỉ chiếm 737px
       nên còn dư ~160px — thêm 6px × 3 nút = 18px vẫn thừa chỗ. Còn trên laptop màn
       thấp thì tầng media (min-width:901px)+(max-height:820px) ĐÃ TỰ hạ chip xuống
       34px, nên dòng này không với tới được ở đó. Hai ràng buộc hoá ra KHÔNG chọi
       nhau như tiểu đệ tưởng lúc ở lô 1c. */
    min-height: var(--touch-min);
    padding: 7px 10px;
    margin: 0;
    border: 1.5px solid var(--border-card);
    border-radius: var(--radius-pill);
    background: var(--surface-white);
    color: var(--text-strong);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.1;
    text-align: center;
}

/* Tên dài hơn giới hạn (tên cũ) → cắt gọn "…", KHÔNG làm vỡ bố cục 1 hàng. */
.student-chip-bar .student-chip .student-chip-name {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Ẩn badge "Đang làm/Đã nộp" trên CHIP để dành chỗ hiện đủ tên bé (logic badge giữ nguyên). */
.student-chip-bar .student-chip .student-badge {
    display: none !important;
}

.student-chip-bar .student-chip:hover {
    background: #eef7ff;
    /* Viền rõ + đủ cả 4 cạnh; z-index để nổi LÊN TRÊN bóng của chip đang chọn kế bên
       (trước đây bóng chip active đè làm "mất đường kẻ trên"). */
    border: 1.5px solid #7eb1de;
    color: var(--text-strong);
    z-index: 2;
}

.student-chip-bar .student-chip.active-student {
    background: linear-gradient(135deg, var(--accent-secondary), var(--blue-800));
    border-color: var(--blue-800);
    color: var(--text-inverse);
    font-weight: 800;
    /* Bóng gọn (blur nhỏ, không spread) để KHÔNG lan sang đè viền chip kế bên. */
    box-shadow: 0 2px 5px rgba(var(--shadow-rgb), 0.3);
    z-index: 1;
}

.student-chip-bar .student-chip.active-student .student-chip-name {
    color: var(--text-inverse);
}

.student-chip-bar .student-chip .student-chip-name {
    white-space: nowrap;
}

.student-chip-bar .student-chip.active-student .student-badge {
    background: rgba(255, 255, 255, 0.28);
    color: var(--text-inverse);
}

/* Mobile (≤900px): dải chip ẩn khi menu thu, hiện khi ☰ mở; chip vẫn xếp viên cuộn dòng. */
@media (max-width: 900px) {
    .side-menu .student-chip-bar {
        display: none;
    }

    .side-menu.mobile-menu-open .student-chip-bar {
        display: flex;
        flex-wrap: wrap;
    }

    .side-menu.mobile-menu-open .student-chip-bar .student-chip {
        display: inline-flex;
        width: auto;
        flex-direction: row;
    }
}

/* ==================================================================== */
/* [LÔ 1] MÀN LÀM BÀI DẠNG THẺ — trắc nghiệm ngang A–D có nhãn.          */
/*  (Lô 2: số cột theo số câu; Lô 3: màu trạng thái sau nộp.)            */
/* ==================================================================== */
.q-grid {
    display: grid;
    /* [LÔ 2 — SỬA VỠ TABLET/ĐIỆN THOẠI NGANG] PHẢI là minmax(0,1fr), KHÔNG được để 1fr trần.
       `1fr` = minmax(AUTO,1fr): cỡ TỐI THIỂU của cột là min-content. Câu "lời văn" dài làm
       min-content của cột lớn hơn phần chia đều → cột KHÔNG CHỊU CO → lưới phình rộng hơn khung
       và thẻ cột phải bị đẩy ra ngoài mép (đo được: cột luôn cứng 561,8px + 493,6px ở mọi khổ
       768→1440px, thẻ câu 9/11/13/15 vượt mép tới +418px ở iPad Pro dọc).
       minmax(0,...) cho phép cột co nhỏ hơn nội dung → chữ tự xuống dòng thay vì tràn. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    align-items: stretch;
    /* đồng bộ chiều cao theo hàng — CSS Grid, KHÔNG JS */
    margin-top: 4px;
}

.q-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: var(--surface-cream);
    /* trắng/kem */
    border: 1px solid var(--blue-100);
    /* [M4.1] Đọc --radius-lg (20px) thay vì --radius-xl. Thang bo góc mới đổi VAI TRÒ
       của --radius-xl thành “khối hành động cực lớn” (24px); thẻ câu hỏi thuộc nhóm
       THẺ → --radius-lg. Giá trị mới của --radius-lg = 20px ĐÚNG BẰNG --radius-xl cũ
       nên thẻ câu hỏi giữ nguyên hình dáng, không phình lên 24px. */
    border-radius: var(--radius-lg);
    padding: 13px 14px;
    box-sizing: border-box;
}

.q-card-no {
    font-size: 13px;
    color: var(--text-muted);
    font-weight: 700;
}

.q-card-text {
    font-size: 16px;
    color: var(--text-body);
    font-weight: 600;
    line-height: 1.4;
    white-space: pre-wrap;
    word-break: break-word;
}

.q-card-answer {
    margin-top: auto;
}

/* dồn vùng trả lời xuống đáy → các thẻ cùng hàng thẳng đáy */

/* Tự luận: ô nhập rộng full thẻ, THẤP gọn như giao diện cũ; cỡ chữ ≥16px (chống auto-zoom). */
.q-answer-input .answer-input,
.q-answer-input input {
    width: 100%;
    box-sizing: border-box;
    min-height: 30px;
    height: 30px;
    padding: 3px 8px;
    font-size: 16px;
}

/* ===== Khối Ô VUÔNG EMOJI (đếm / so sánh) — GỌN trong thẻ, KHÔNG vỡ lưới ===== */
/* N ô LUÔN nằm trên 1 HÀNG, chia đều bề ngang (grid-template-columns đặt INLINE = repeat(N,minmax(0,1fr))).
   minmax(0,1fr) -> cột không phình theo nội dung -> KHÔNG bao giờ xuống dòng so le. */
.q-count-boxes {
    display: grid;
    grid-auto-flow: column;
    gap: 6px;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    margin: 2px 0;
    align-items: stretch;
}

/* Mỗi marker = 1 ô: viền mảnh, bo góc. Các HÀNG emoji xếp DỌC (>5 emoji -> 2 hàng), căn giữa.
   min-width:0 + overflow:hidden -> ô co vừa cột, không đẩy lưới rộng ra. */
.q-count-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-width: 0;
    max-width: 100%;
    /* [SỬA HIỂN THỊ] Thu padding NGANG 6px → 4px: mỗi ô được thêm 4px bề ngang cho icon,
       nhờ đó icon phóng to hơn mà hàng 3 icon vẫn đủ chỗ (ca câu 3 nhóm). */
    padding: 4px;
    border: 1px solid var(--border-card);
    border-radius: var(--radius-md);
    background: var(--surface-answer);
    box-sizing: border-box;
    overflow: hidden;
}

/* Ô MIX (đếm chọn lọc, nhiều loại trộn): icon WRAP nhiều hàng tự nhiên, căn giữa (đè hướng cột của ô đếm). */
.q-count-box-mix {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px;
    padding: 6px 8px;
}

/* 1 HÀNG emoji trong ô: JS đã chia hàng chủ động (emojiBoxInnerHtml theo maxPerRow), nhưng VẪN để
   wrap làm LƯỚI AN TOÀN — nếu vì lý do nào đó hàng vẫn rộng hơn ô thì icon XUỐNG DÒNG chứ TUYỆT ĐỐI
   không bị cắt cụt (ô có overflow:hidden). Trước đây nowrap chính là thủ phạm làm nhóm 5 icon mất
   icon đầu/cuối khi câu có 3 nhóm. */
.q-count-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-width: 0;
    max-width: 100%;
}

/* [SỬA HIỂN THỊ] Icon ĐỒNG NHẤT ở MỌI câu hỏi và TO, dễ nhìn cho trẻ lớp 1.
   TRƯỚC: cỡ co theo bề ngang từng ô (container query 15cqi) -> câu 1 nhóm icon to 20px, câu 3 nhóm
   icon tụt sàn 12px -> nhìn "câu to câu nhỏ". NAY: chỉ co nhẹ theo bề ngang MÀN HÌNH (giống nhau cho
   mọi câu trên cùng máy) -> các câu bằng nhau. Việc "vừa ô" do JS lo bằng chia hàng, không bóp icon. */
.q-count-emoji {
    font-size: var(--q-count-icon);
    line-height: 1.1;
}

/* CHUẨN: icon co theo BỀ NGANG KHỐI ICON (= bề ngang thẻ câu hỏi), KHÔNG theo từng ô và cũng
   KHÔNG theo màn hình.
   - Theo TỪNG Ô (cách cũ) -> câu 3 nhóm ô hẹp -> icon 12px, câu 1 nhóm -> 20px => TO NHỎ LỆCH NHAU.
   - Theo MÀN HÌNH -> từ 601px lưới đổi sang 2 CỘT nên thẻ hẹp đi một nửa trong khi icon vẫn phóng
     theo màn hình rộng => hàng bị bẻ vụn (mỗi icon một dòng).
   - Theo BỀ NGANG THẺ (cách này) -> mọi thẻ trong lưới rộng BẰNG NHAU nên mọi câu có icon BẰNG NHAU,
     đồng thời tự thu lại vừa vặn khi lưới chuyển 2 cột.
   Hệ số dưới đây KHÔNG phải ước lượng — đo thật trên trình duyệt: 1 icon emoji chiếm
   1,373 × cỡ-chữ (không phải ~1,2 như cảm tính), khe giữa 2 icon 4px, ô trừ 10px (padding+viền).
   Ca chật nhất = câu 3 nhóm, mỗi hàng 3 icon:  C = W/3 − 14  và cần 3·1,373·F + 8 ≤ C
   =>  F ≤ 8,09%·W − 5,34px  → lấy 8cqi − 5,5px cho dư an toàn. */
@supports (container-type: inline-size) {

    .q-count-boxes,
    .q-calc-row {
        container-type: inline-size;
    }

    .q-count-boxes .q-count-emoji,
    .q-calc-row .q-count-emoji {
        font-size: clamp(13px, calc(8cqi - 5.5px), 22px);
    }
}

/* Emoji đi kèm số trong nút trắc nghiệm "đếm ra số" (vd "3 🐟") — nâng cho cân với icon trong ô. */
.q-choice-emoji {
    font-size: 18px;
}

/* ===== Hàng PHÉP TÍNH emoji (kiểu B) — ô vuông + dấu/chữ XEN KẼ trên một hàng, GỌN trong thẻ ===== */
/* Cả hàng wrap khi thẻ hẹp (ô thứ hai + "= ?" rớt xuống dòng) — KHÔNG tràn, KHÔNG phá lưới 2 cột. */
.q-card-calc {
    /* phần đề khi là phép tính: bỏ giới hạn chữ thường, để hàng flex tự lo */
    white-space: normal;
}

.q-calc-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

/* Ô vuông phép tính: NHỎ GỌN hơn ô đếm (vì nhiều thứ trên một hàng). */
.q-calc-box {
    padding: 2px 5px;
    gap: 1px;
    border-radius: var(--radius-sm);
}

/* [SỬA HIỂN THỊ] BỎ cỡ riêng 15px của ô phép tính/điền dấu — trước đây nó làm icon câu "Điền dấu"
   nhỏ hơn hẳn icon câu "đếm/so sánh". Nay KHÔNG khai lại font-size: ô này thừa hưởng đúng cỡ chung
   .q-count-emoji -> icon mọi dạng câu bằng nhau. (.q-calc-row đã tự wrap nên hàng dài vẫn không tràn.) */

/* Đoạn chữ/dấu ("Tính:", "+", "−", "= ?") — rõ, đậm, không co mất. */
.q-calc-text {
    font-size: 16px;
    font-weight: 700;
    color: var(--text-body);
    white-space: nowrap;
    flex: 0 0 auto;
}

/* Ô "?" GIỮA hai ô icon (điền dấu emoji): ô vuông, viền NÉT ĐỨT -> gợi ý chỗ cần điền.
   [SỬA HIỂN THỊ] To lên cho cân với icon đã phóng (22px → 28px ngang, 26px → 34px cao). */
.q-calc-qbox {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 34px;
    padding: 0 8px;
    border: 1.5px dashed var(--blue-300);
    border-radius: var(--radius-sm);
    background: var(--surface-white);
    color: var(--accent-secondary);
    font-size: 20px;
    font-weight: 800;
    flex: 0 0 auto;
}

/* Trắc nghiệm NGANG A–D có nhãn. */
/* [LÔ 2] minmax(0,...) CÙNG LÝ DO với .q-grid: đáp án dài (vd "99020 đồng") làm min-content của
   cột lớn hơn phần chia đều → 4 nút không chịu co → hàng đáp án phình rộng hơn thẻ và bị cắt mép
   (đo được: cần 529px nhưng thẻ chỉ có 510px — lỗi này có ở CẢ PC 1920, không riêng tablet). */
.q-choices {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 8px;
}

/* Câu SO SÁNH CHỌN VẾ (side_max/side_min): chỉ 2–3 nhãn chữ -> ô rộng vừa, không bóp nhỏ. */
.q-choices.q-choices-side {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
}

.q-choice {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    /* THẤP gọn như giao diện cũ */
    padding: 4px 8px;
    border: 1.5px solid var(--border-card);
    border-radius: var(--radius-sm);
    background: var(--surface-white);
    color: var(--text-strong);
    font-family: inherit;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
    /* [LÔ 2] Cho nút co được trong cột hẹp: KHÔNG lấy nội dung làm bề rộng tối thiểu. */
    min-width: 0;
    /* [LÔ 2] BẮT BUỘC khai tường minh: trình duyệt tự đặt white-space:nowrap cho <button>
       (mặc định của UA, không rule nào của app khai) → đáp án dài không chịu xuống dòng và bị
       cắt mép. Đặt normal thì overflow-wrap ở .q-choice-value mới có tác dụng. */
    white-space: normal;
}

.q-choice:hover {
    background: #eef7ff;
}

.q-choice-value {
    font-size: 15px;
    font-weight: 700;
    line-height: 1.15;
    text-align: center;
    /* [LÔ 2] Đáp án dài ("99020 đồng") thì XUỐNG DÒNG trong nút, KHÔNG tràn ra ngoài rồi bị cắt.
       break-word chỉ ngắt khi thật sự không còn cách nào → chữ ngắn vẫn nằm nguyên một dòng. */
    min-width: 0;
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Đang chọn (trắc nghiệm, chưa nộp) — xanh dương nhạt. */
.q-choice.selected {
    background: var(--surface-hover);
    border-color: var(--accent-secondary);
    color: var(--text-strong);
}

.q-choice[disabled] {
    cursor: default;
}

/* Kết quả sau nộp (Lô 3 sẽ tô nền/viền thẻ + nút theo trạng thái). */
.q-result {
    margin-top: 2px;
    font-size: 13.5px;
    line-height: 1.35;
}

.q-result-badge {
    font-weight: 800;
    font-size: 13.5px;
}

.q-card.is-correct .q-result-badge {
    color: var(--text-success);
}

.q-card.is-wrong .q-result-badge {
    color: var(--accent-danger);
}

/* Bài sai: badge + đáp án đúng nằm CÙNG 1 dòng (xuống dòng mềm nếu đáp án quá dài). */
.q-correct-inline {
    color: var(--accent-danger);
    font-weight: 700;
}

/* [LÔ 2] TABLET DỌC + ĐIỆN THOẠI XOAY NGANG (601–1100px): vùng làm bài về 1 CỘT.
   Lý do: ở dải này khung còn lại cho lưới câu quá hẹp để chứa 2 thẻ (từ 901px trở lên menu bên
   còn chiếm ~375px, nên iPhone Max ngang 932px chỉ còn ~494px cho CẢ 2 cột → mỗi thẻ ~241px,
   chữ chen chúc). Về 1 cột thì thẻ rộng gấp đôi, đọc thoải mái.
   GIỮ NGUYÊN 2 cột cho iPad NGANG (1180/1366) và PC (>1100px) — không đụng bố cục đang đẹp.
   Dùng minmax(0,1fr) cùng lý do đã ghi ở .q-grid (chống cột phình theo min-content). */
@media (max-width: 1100px) {
    .q-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Điện thoại: 1 cột; trắc nghiệm xếp 2×2 (A B / C D). */
@media (max-width: 600px) {
    .q-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .q-choices {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ===== Phân số dọc (\frac{}{}) — tử trên / gạch ngang / mẫu dưới (thuần CSS) ===== */
.frac {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    vertical-align: middle;
    margin: 0 .18em;
    line-height: 1.04;
    text-align: center;
}

.frac-num {
    display: block;
    padding: 0 .4em;
}

.frac-den {
    display: block;
    padding: 2px .4em 0;
    border-top: 2px solid currentColor;
}

/* ===== Ô nhập phân số: dáng tử / gạch ngang / mẫu, căn giữa (giống phân số ở đề) ===== */
.frac-input {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    vertical-align: middle;
    gap: 4px;
}

/* Đặc hiệu cao + !important để THẮNG '.q-answer-input input{width:100%}' và '.answer-input{...!important}' */
.q-answer-input .frac-input input,
.frac-input input {
    width: 63px !important;
    height: auto !important;
    min-height: 0 !important;
    text-align: center;
    font-size: 18px !important;
    padding: 5px 4px !important;
    border: 1.5px solid #c7d9f8;
    border-radius: var(--radius-xs);
    box-sizing: border-box;
}

.q-answer-input .frac-input input:focus,
.frac-input input:focus {
    border-color: var(--blue-800);
    outline: none;
}

/* Đường gạch phân số đậm (khớp màu/độ dày gạch ở đề) */
.frac-input .frac-input-line {
    width: 100%;
    height: 2px;
    background: var(--blue-800);
}

/* ===== Thẻ câu PHÂN SỐ: chỉ HÀNG (đề + ô nhập) là 2 cột; feedback nằm NGOÀI, dưới cùng ===== */
/* .q-content-row chỉ xuất hiện trong thẻ phân số -> feedback (.q-result) vẫn là block full-width dưới. */
.q-content-row {
    display: flex;
    align-items: center;
    gap: 14px;
}

.q-card.is-fraction .q-content-row .q-card-text {
    flex: 1 1 auto;
}

.q-card.is-fraction .q-content-row .q-card-answer {
    flex: 0 0 130px;
    display: flex;
    justify-content: center;
    /* QUAN TRỌNG: huỷ '.q-card-answer{margin-top:auto}' (vốn dồn vùng trả lời xuống đáy ở thẻ thường)
       — trong hàng phân số margin-top:auto đẩy phương án/ô nhập xuống đáy, làm align-items vô hiệu.
       Bỏ margin-top:auto -> align-items của hàng quyết định: INPUT căn giữa, MCQ top (flex-start). */
    margin-top: 0 !important;
}

/* Câu TRẮC NGHIỆM phân số: đẩy cụm phương án lên NGANG DÒNG ĐẦU của đề (top-align). */
.q-card.is-fraction[data-q-type="MCQ"] .q-content-row {
    align-items: flex-start;
}

/* Điện thoại: chật thì đề trên / ô nhập phân số xuống dòng & CĂN GIỮA; feedback vẫn dưới cùng */
@media (max-width: 600px) {
    .q-card.is-fraction .q-content-row {
        flex-wrap: wrap;
    }

    .q-card.is-fraction .q-content-row .q-card-answer {
        flex-basis: 100%;
        justify-content: center;
    }
}

/* ====================================================================
   [DỜI NÚT "THOÁT CÀI ĐẶT"] #finishAdminButton dời từ header vào panel Cài đặt,
   nằm cùng hàng với <h2>Cài đặt</h2> (tiêu đề trái, nút góc phải). Trung hoà mọi
   rule header/mobile-fixed cũ của #finishAdminButton để nó là nút thường trong hàng.
   GIỮ NGUYÊN id/onclick/logic ẩn-hiện (hidden-keep-space + setAdminModeVisible).
   ==================================================================== */
/* Hàng tiêu đề: "Cài đặt" CĂN GIỮA vùng; nút "Thoát Cài đặt" neo GÓC PHẢI (absolute,
   không đẩy tiêu đề → tiêu đề luôn ở giữa). */
.settings-title-row {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    margin-bottom: 14px;
}

.settings-title-row h2 {
    margin: 0 !important;
    text-align: center;
}

/* Vô hiệu mọi vị trí/kích thước "header" + "nổi đáy mobile" cũ của nút; neo góc phải. */
.settings-title-row #finishAdminButton {
    position: absolute !important;
    top: 50% !important;
    right: 0 !important;
    bottom: auto !important;
    left: auto !important;
    transform: translateY(-50%) !important;
    order: 0 !important;
    z-index: 2 !important;
    width: auto !important;
    min-width: 0 !important;
    max-width: 60% !important;
    height: 42px !important;
    min-height: 42px !important;
    padding: 0 18px !important;
    margin: 0 !important;
    flex: 0 0 auto !important;
    font-size: 15px !important;
    border-radius: var(--radius-lg) !important;
    white-space: nowrap;
}

/* [KÉO LÊN] Đang ở Cài đặt → ẩn hàng header bài thi (trống) + thu lề để panel Cài đặt
   LÊN SÁT ĐỈNH, lấp vùng trống phía trên. Class do JS (showSection) bật → chạy mọi trình duyệt. */
body.settings-active .control-area {
    margin: 0 !important;
}

body.settings-active .main-control-row {
    display: none !important;
}

/* [CANH ĐÁY] KHÔNG đặt min-height cho panel Cài đặt: trên desktop (≥901px) lớp layout sẵn có
   (.app-layout{align-items:stretch} + .content-area{display:flex;column} + .content-section{flex:1 1 auto})
   ĐÃ tự canh đáy 2 cột bằng nhau; và #section-settings .settings-panel cần GIỮ min-height:0 để cuộn
   nội bộ (ép min-height sẽ CẮT nội dung tab admin trên laptop màn thấp). */

/* [ẨN TRÊN MOBILE] Nút "Thoát Cài đặt" TRÙNG chức năng với nút 🏠 ở header: khi đã mở khóa
   Cài đặt, cả hai đều gọi finishAdminMode() (lưu + khóa admin + về trang chính). Ở ≤900px nút
   header đã đổi thành 🏠 nên ẩn nút này cho gọn — KHÔNG mất lối thoát. PC (>900px) GIỮ NGUYÊN:
   header vẫn là ⚙️ (vào Cài đặt) nên đây là lối thoát chính. Chỉ ẩn HIỂN THỊ, KHÔNG đụng id/onclick/JS. */
@media (max-width: 900px) {
    .settings-title-row #finishAdminButton {
        display: none !important;
    }
}

/* =======================================================================
   [MOBILE BOTTOM NAV — CHỈ ≤900px] Thanh điều hướng dưới 5 mục.
   -----------------------------------------------------------------------
   • PC (≥901px): KHÔNG hiển thị (mặc định display:none) → PC giữ nguyên 100%
     sidebar + 4 menu link như cũ.
   • Mobile: thanh cố định đáy màn (fixed bottom), tô sáng mục đang mở, tự ẩn
     khi ở màn ngoài 5 mục (dashboard/settings/…) qua class .mbn-hidden do JS bật.
   • Auth-overlay (z-index:1000) che thanh khi chưa đăng nhập (thanh z-index:900).
   • Tôn trọng vùng "home indicator" iPhone qua env(safe-area-inset-bottom).
   • Trên mobile: ẩn 4 menu link cũ trong sidebar (tránh trùng) — GIỮ id/handler,
     chỉ ẩn bằng CSS; PC vẫn hiện đủ.
   ======================================================================= */

/* Mặc định (gồm PC ≥901px): ẩn hoàn toàn. */
.mobile-bottom-nav {
    display: none;
}

@media (max-width: 900px) {
    /* Chừa khoảng đáy cho nội dung cuối trang không bị thanh dưới che. */
    .content-area {
        padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    }

    /* Thanh điều hướng dưới. */
    .mobile-bottom-nav {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 900;
        /* < 1000 (auth-overlay) để không đè màn đăng nhập */
        align-items: stretch;
        justify-content: space-around;
        background: rgba(248, 251, 255, 0.98);
        border-top: 1px solid var(--border-card);
        box-shadow: 0 -4px 14px rgba(var(--shadow-rgb), 0.14);
        padding: 0 0 env(safe-area-inset-bottom, 0px) 0;
        margin: 0;
        -webkit-backdrop-filter: blur(2px);
        backdrop-filter: blur(2px);
    }

    /* JS bật class này để ẩn thanh ở màn ngoài 5 mục (dashboard/settings/…). */
    .mobile-bottom-nav.mbn-hidden {
        display: none;
    }

    /* Mỗi mục: override style button toàn cục (nền xanh/màu trắng/margin/min-height). */
    .mobile-bottom-nav .mbn-item {
        position: relative;
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        min-height: 56px;
        margin: 0;
        padding: 7px 2px;
        border: none;
        border-radius: 0;
        background: transparent;
        color: var(--text-muted);
        font-weight: 700;
        white-space: nowrap;
        cursor: pointer;
        box-shadow: none;
        -webkit-appearance: none;
        appearance: none;
        -webkit-tap-highlight-color: transparent;
        touch-action: manipulation;
        transition: color 0.15s ease;
    }

    /* Triệt tiêu hover/active toàn cục của button (translateY/đổi nền). */
    .mobile-bottom-nav .mbn-item:hover,
    .mobile-bottom-nav .mbn-item:hover:not(:disabled),
    .mobile-bottom-nav .mbn-item:active {
        background: transparent;
        transform: none;
        color: var(--text-strong);
    }

    .mobile-bottom-nav .mbn-icon {
        font-size: 22px;
        line-height: 1;
    }

    .mobile-bottom-nav .mbn-label {
        font-size: 11px;
        line-height: 1.1;
    }

    /* Mục đang mở: sáng + có vạch vàng phía trên (đồng bộ tông gold #f0b400 của app). */
    .mobile-bottom-nav .mbn-item.mbn-active {
        color: var(--text-strong);
    }

    .mobile-bottom-nav .mbn-item.mbn-active .mbn-label {
        font-weight: 800;
    }

    .mobile-bottom-nav .mbn-item.mbn-active::before {
        content: "";
        position: absolute;
        top: 0;
        left: 24%;
        right: 24%;
        height: 3px;
        border-radius: 0 0 3px 3px;
        background: var(--yellow-500);
    }

    /* Ẩn 4 menu link cũ trong sidebar trên mobile (đã có bottom nav) — GIỮ id/handler,
       chỉ ẩn hiển thị. Cần !important để thắng rule .mobile-menu-open .menu-link{display:block}.
       KHÔNG ẩn #menu-dashboard ("← Tổng quan các con") — vẫn truy cập được. */
    #menu-shop,
    #menu-playground,
    #menu-quests,
    #menu-history {
        display: none !important;
    }
}

/* =======================================================================
   [MOBILE LÔ 2 — CHỈ ≤900px] LAYOUT 1 CỘT.
   -----------------------------------------------------------------------
   • Ẩn HẲN sidebar trái; gom thanh hạng + dải chip đổi con + mục Ôn thi + dòng
     "hôm nay" lên ĐẦU vùng nội dung (#mobileTopPanel). Hồ sơ con (avatar+tên+hạng)
     gom lên HEADER (#mobileHeaderProfile — xem block "HEADER MOBILE"). JS MobileLayout
     di chuyển phần tử THẬT, trả về sidebar/top-bar trên PC.
   • Header CỐ ĐỊNH trên cùng; thanh dưới (LÔ 1) cố định đáy; khối tầng-2 CUỘN.
   • PC (≥901px): KHÔNG áp gì (panel mặc định display:none; mọi rule trong @media).
   ======================================================================= */

/* Panel mặc định (gồm PC): ẩn. Trên PC nó luôn TRỐNG (JS không di chuyển gì vào). */
.mobile-top-panel { display: none; }

@media (max-width: 900px) {
    /* 1) Ẩn HẲN sidebar trái (đã gom nội dung cần thiết lên panel). !important để
       thắng cả trạng thái .mobile-menu-open cũ. */
    .side-menu { display: none !important; }

    /* Ẩn khối panel đầu nội dung ở màn Cài đặt + Tổng quan (đồng bộ với LÔ 1: thanh
       dưới cũng ẩn ở 2 màn này) — tránh chồng nội dung Cài đặt + nút "← Tổng quan"
       thừa khi đang Ở Tổng quan. Tái dùng class JS body.settings-active /
       body.dashboard-active (showSection bật), KHÔNG dùng :has() để chạy mọi trình duyệt. */
    body.settings-active .mobile-top-panel,
    body.dashboard-active .mobile-top-panel {
        display: none !important;
    }

    /* 2) Header CỐ ĐỊNH theo VIEWPORT (yêu cầu: chỉ header + thanh dưới cố định, tầng 2
       cuộn). DÙNG position:fixed (chắc chắn đứng yên dù nội dung cuộn trong body).
       LƯU Ý: .app có backdrop-filter (dòng 1612) — backdrop-filter trên tổ tiên PHÁ
       position:sticky VÀ làm position:fixed neo theo .app thay vì viewport → phải GỠ
       backdrop-filter của .app trên mobile thì fixed mới neo đúng viewport. Nội dung
       chừa padding-top = chiều cao header (đo runtime → --mobile-header-h; fallback 56px).
       z-index < thanh dưới (900) và < auth-overlay (1000). */
    .app {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        padding-top: var(--mobile-header-h, 56px) !important;
    }
    .app-header {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 70;
        background: var(--surface-white);
        box-shadow: 0 2px 10px rgba(var(--shadow-rgb), 0.10);
        padding: 6px 8px;
    }

    /* 3) Khối đầu nội dung: hiện + xếp dọc, đặt TRƯỚC mọi mục khác trong content-area. */
    .mobile-top-panel {
        display: flex;
        flex-direction: column;
        gap: 10px;
        order: -1;
        margin: 4px 0 8px;
    }

    /* (Nút "← Tổng quan" + thẻ hồ sơ con KHÔNG còn vào panel — đã chuyển lên HEADER;
       xem block "HEADER MOBILE". Đã bỏ các rule cũ dành cho chúng trong panel.) */

    /* Thanh hạng trong panel: bỏ lề thừa (panel đã có gap). */
    .mobile-top-panel .top-bar { margin: 0; }

    /* Dải chip đổi con trong panel: xuống dòng + chip như trạng thái "menu mở" cũ
       (đã được kiểm chứng); bỏ viền/đệm "ngăn cách menu" của sidebar. */
    .mobile-top-panel .student-chip-bar {
        display: flex;
        flex-wrap: wrap;
        border-bottom: none;
        padding-bottom: 0;
        margin: 0;
    }
    .mobile-top-panel .student-chip-bar .student-chip {
        display: inline-flex;
        width: auto;
        flex-direction: row;
    }

    /* Tránh chừa khoảng trắng khi dòng "hôm nay" / mục Ôn thi đang TRỐNG. */
    .mobile-top-panel #todayScoreMessage:empty { display: none; }
    .mobile-top-panel #examReviewMenuContainer:empty { display: none; }
}

/* =======================================================================
   [HEADER MOBILE — CHỈ ≤900px] Header GỌN + CỐ ĐỊNH (avatar + tên + hạng).
   -----------------------------------------------------------------------
   • Ẩn tiêu đề app to + ô tài khoản → header 1 hàng: TRÁI = avatar nhỏ + tên +
     huy hiệu hạng (JS chuyển .student-profile-card vào #mobileHeaderProfile);
     PHẢI = nút Tổng quan (icon) + ⚙️ + 🚪.
   • Header đã sticky top (block trước) → avatar/tên/hạng LUÔN thấy khi cuộn;
     thanh hạng/chip/"hôm nay" cuộn cùng nội dung trong #mobileTopPanel.
   • PC (≥901px): KHÔNG áp gì (#mobileHeaderProfile mặc định display:none; mọi rule
     trong @media; nút Tổng quan + tiêu đề + sidebar giữ y như cũ).
   ======================================================================= */

/* PC + mặc định: slot header mobile ẩn (PC không thấy avatar trên header). */
.mobile-header-profile { display: none; }

@media (max-width: 900px) {
    /* Header 1 hàng: trái = hồ sơ gọn, phải = cụm icon. (Sticky/nền giữ từ block trước.) */
    .app-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
    }

    /* Ẩn tiêu đề app to + ô tài khoản trên mobile cho gọn (giữ id, chỉ ẩn; thông tin
       tài khoản vẫn xem trong Cài đặt). PC giữ nguyên cả hai. */
    .app-header h1 { display: none; }
    #authAccountBox { display: none !important; }

    .app-header-actions { flex: 0 0 auto; }

    /* Slot trái: cụm hồ sơ gọn. */
    .mobile-header-profile {
        display: flex;
        align-items: center;
        flex: 1 1 auto;
        min-width: 0;
        overflow: hidden;
    }

    /* Thẻ hồ sơ thu gọn thành cụm NGANG: [avatar] [tên / hạng]. Bỏ nền/viền/bóng của
       thẻ to. Ghi đè .student-profile-card{display:none} + .student-photo-box{display:none}
       (rule mobile cũ của bố cục sidebar). */
    .mobile-header-profile .student-profile-card {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-rows: auto auto;
        align-items: center;
        column-gap: 8px;
        row-gap: 1px;
        width: auto;
        margin: 0;
        padding: 0;
        background: none;
        border: none;
        box-shadow: none;
        text-align: left;
        min-width: 0;
    }
    .mobile-header-profile .student-photo-box {
        display: flex !important;
        grid-column: 1;
        grid-row: 1 / span 2;
        width: auto !important;
        margin: 0 !important;
        padding: 0 !important;
        justify-content: flex-start;
    }
    .mobile-header-profile .student-photo-frame-box {
        width: 42px !important;
        height: 42px !important;
        margin: 0 !important;
    }
    .mobile-header-profile #studentProfileName {
        grid-column: 2;
        grid-row: 1;
        margin: 0;
        font-size: 14px;
        font-weight: 800;
        line-height: 1.15;
        min-width: 0;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .mobile-header-profile #studentLevel {
        grid-column: 2;
        grid-row: 2;
        justify-self: start;
        margin: 0;
        padding: 1px 8px;
        font-size: 10.5px;
        box-shadow: none;
    }

    /* [DANH HIỆU] Trên mobile: viên badge xuống 2 dòng nhỏ để không tràn header.
       Dòng 1: danh hiệu + dãy sao. Dòng 2: viên huy hiệu nhỏ. (avatar mobile 42px) */
    .mobile-header-profile #studentLevel.has-rank {
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-start;
        column-gap: 4px;
        row-gap: 1px;
        padding: 1px 8px;
        max-width: 100%;
        line-height: 1.15;
    }

    .mobile-header-profile #studentLevel.has-rank .rank-sep {
        display: none;
    }

    .mobile-header-profile #studentLevel.has-rank .rank-name {
        order: 1;
    }

    .mobile-header-profile #studentLevel.has-rank .rank-stars {
        order: 2;
    }

    .mobile-header-profile #studentLevel.has-rank .rank-badge-name {
        order: 3;
        flex-basis: 100%;
        font-size: 9.5px;
        opacity: 0.95;
    }

    /* Nút "Tổng quan các con" (#menu-dashboard) trên header mobile = ICON vuông
       (đồng bộ ⚙️/🚪). Ẩn chữ "← Tổng quan các con" (giữ cho PC) bằng font-size:0 +
       icon qua ::before. Giữ NGUYÊN id + handler showSection('dashboard'). */
    .app-header-actions #menu-dashboard {
        width: 38px;
        height: 38px;
        min-width: 38px;
        /* !important cho padding/margin/border-radius để thắng block .menu-link
           (style.css ~4255-4259: padding/margin-bottom/border-radius đều !important),
           nếu không nút icon bị to/lệch thay vì vuông 38px gọn như ⚙️/🚪. */
        padding: 0 !important;
        margin: 0 !important;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        border: 1px solid var(--border-card);
        border-radius: var(--radius-md) !important;
        background: var(--surface-subtle);
        color: var(--text-strong);
        /* !important: thắng .menu-link{font-size:15px !important} (style.css ~4257) — nếu
           không, chữ "← Tổng quan các con" vẫn hiện 15px (nguyên nhân LỖI 3). */
        font-size: 0 !important;
        line-height: 1;
        overflow: hidden;
    }
    .app-header-actions #menu-dashboard::before {
        /* 📊 biểu đồ/Tổng quan — đổi từ 🏠 để KHÔNG trùng icon "về nhà" của nút ⚙️→🏠. */
        content: "📊";
        font-size: 18px;
        line-height: 1;
    }
    .app-header-actions #menu-dashboard:hover {
        background: var(--blue-100);
    }

    /* [MOBILE] Khi ĐANG ở Cài đặt: nút ⚙️ (#menu-settings) đổi icon thành 🏠 (về trang
       chính). Đổi icon bằng CSS (ẩn ⚙️ + ::before 🏠) — hành vi do onSettingsHeaderButtonClick,
       nhãn do updateSettingsHeaderButtonLabel. body.settings-active set cả ở PC nhưng rule
       trong @media nên CHỈ mobile; PC giữ ⚙️. !important để chắc thắng .header-icon-btn. */
    body.settings-active #menu-settings {
        font-size: 0 !important;
        overflow: hidden;
    }
    body.settings-active #menu-settings::before {
        content: "🏠";
        font-size: 18px;
        line-height: 1;
    }
    /* [ICON KHÓA] Nút đang là 🏠 (mobile ở Cài đặt) → KHÔNG hiện khóa (hiển nhiên đang mở). */
    body.settings-active #menu-settings .settings-lock-badge { display: none; }
}

/* =======================================================================
   [REWARD 2 DÒNG — CHỈ ≤900px] Tách thanh "🎯 Sắp lên hạng" trong panel thành
   2 DÒNG cho đủ thông tin (thay bố cục "1 dòng" cũ làm cắt cụt tên hạng):
     • DÒNG 1: nhãn + TÊN HẠNG đầy đủ (không cắt, không "…"; xuống dòng nếu quá dài).
     • DÒNG 2: thanh tiến độ + số điểm đầy đủ "X / Y điểm" (không rút gọn).
   CHỈ đổi LAYOUT (flex-wrap + bỏ ellipsis/nowrap) — KHÔNG đổi nội dung/cách tính
   hạng-điểm-%. Hiệu ứng "hot" (≥85%) ở .reward-progress-fill giữ nguyên.
   CHỈ áp thanh reward TRONG #mobileTopPanel (mobile). PC giữ nguyên 100%.
   ======================================================================= */
@media (max-width: 900px) {
    .mobile-top-panel .reward-progress-box {
        flex-wrap: wrap;
        align-items: center;
        gap: 4px 8px;
        /* row-gap 4 (giữa 2 dòng) / column-gap 8 (giữa thanh và số ở dòng 2) */
    }

    /* DÒNG 1: nhãn + tên hạng — chiếm TRỌN hàng, hiện ĐẦY ĐỦ (không cắt "…"). */
    .mobile-top-panel .reward-progress-title {
        flex: 1 1 100%;
        min-width: 0;
        max-width: 100%;
        overflow: visible;
        text-overflow: clip;
        white-space: normal;
        font-size: 14px;
        line-height: 1.25;
    }

    /* DÒNG 2: thanh tiến độ chiếm phần còn lại (bỏ min-width 180px của bản gốc để
       nhường chỗ cho số điểm; vẫn đủ rộng để thấy tiến độ). */
    .mobile-top-panel .reward-progress-track {
        flex: 1 1 auto;
        min-width: 80px;
    }

    /* DÒNG 2: số "X / Y điểm" hiện ĐẦY ĐỦ. white-space:normal để (a) số dài vẫn
       xuống dòng ở khoảng trắng thay vì tràn, (b) thông điệp "đã đạt hạng cao nhất"
       (text dài) không bị tràn ngang. */
    .mobile-top-panel .reward-progress-text {
        flex: 0 1 auto;
        white-space: normal;
        font-size: 13px;
    }
}

/* ============================================================
   [GIA HẠN TÀI KHOẢN] Vùng phụ huynh xem hạn của chính mình + lối gia hạn
   (Cài đặt → Thông tin chung → Cài đặt chung). Mobile-first.
   ============================================================ */
.account-expiry-box {
    margin-bottom: 14px;
}

.account-expiry-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.account-expiry-info {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.acct-exp-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
}

.acct-exp-label {
    font-size: 14px;
    color: var(--text-muted);
    font-weight: 600;
}

.acct-exp-value {
    font-size: 16px;
    color: var(--text-strong);
    font-weight: 700;
    text-align: right;
}

.acct-exp-badge {
    display: inline-block;
    padding: 3px 12px;
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
}

.acct-exp-badge-ok {
    background: var(--surface-success);
    color: var(--text-success);
}

.acct-exp-badge-forever {
    background: var(--surface-hover);
    color: var(--text-strong);
}

.acct-exp-badge-expired {
    background: var(--surface-danger);
    color: var(--accent-danger);
}

.acct-exp-badge-pending {
    background: var(--orange-tint);
    color: var(--text-warning);
}

/* ============================================================
   [PAYWALL — ĐỢT 0] Màn gia hạn cho tài khoản hết hạn / chưa hiệu lực.
   Tái dùng .auth-overlay (full-screen fixed) + .auth-card. Mobile-first;
   nút & chữ ≥16px; không tràn ngang (giá trị dài tự xuống dòng).
   ============================================================ */
/* [DỰ PHÒNG] auth.css đã có `.auth-overlay.hidden-section { display:none !important }` mà paywall
   cũng mang class .auth-overlay → đã ẩn đúng lúc tải trang. Rule này là bản dự phòng theo tên riêng
   .paywall-overlay (phòng khi ai đó gỡ class auth-overlay). Vô hại, giữ cho chắc. */