/* ==========================================================================
   DESIGN SYSTEM — css/ds.css
   --------------------------------------------------------------------------
   Nạp DUY NHẤT ở index.html, và nạp SAU style.css / sidebar.css /
   mobile-ux.css / soft-ui.css (xem thứ tự <link> trong index.html).

   Quy ước:
     - Mọi rule đều scope dưới `body.tv-app` → không thể rò rỉ sang 29 trang
       còn lại dù sau này có trang khác lỡ nạp file này.
     - Trang chủ KHÔNG còn `class="soft-ui"` trên <body>. css/soft-ui.css được
       scope 100% dưới `body.soft-ui` (đã kiểm chứng), nên bỏ class đó là vô
       hiệu hóa toàn bộ neumorphism trên trang chủ mà không phải sửa file dùng
       chung. Vì vậy KHÔNG dùng `body.soft-ui` trong file này.
     - Token dùng namespace `--tv-*`, KHÔNG đụng `--white` / `--gray-*` /
       `--spacing-*`: js/main.js:154 gắn `body.force-light` và
       css/style.css:3160-3174 khai báo lại thang xám đó lúc runtime.
     - Được phép dùng `!important` ở đúng những chỗ phải thắng
       css/mobile-ux.css (file đó có 258 `!important`), không rải tràn lan.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
    /* --- Bề mặt: trắng ngà ấm --- */
    --tv-bg:            #FAF7F0;
    --tv-surface:       #FFFFFF;
    --tv-surface-2:     #F3EEE3;
    --tv-surface-sunk:  #EFE8DA;

    /* --- Chữ --- */
    --tv-ink:           #1E1B4B;
    /* chàm đậm — 15:1 trên --tv-bg */
    --tv-ink-soft:      #4B4869;
    --tv-muted:         #5A6272;
    /* 5,7:1 trên --tv-bg (AA). KHÔNG dùng #6B7280: chỉ 4,37:1, trượt AA */

    /* --- Accent vàng đồng --- */
    --tv-accent:        #B8860B;
    /* 3,0:1 → chỉ chữ LỚN, icon, viền, gạch chân */
    --tv-accent-text:   #8A6508;
    /* 5,0:1 → dùng cho link/chữ nhỏ màu vàng */
    --tv-accent-strong: #96690A;
    --tv-accent-soft:   #F5EBD6;
    --tv-accent-line:   #E3D2A8;

    /* --- Viền & trạng thái --- */
    --tv-border:        #E6DFD2;
    --tv-border-strong: #D5CBB8;
    --tv-success:       #15803D;
    --tv-success-soft:  #E7F4EB;
    --tv-warn:          #B45309;
    --tv-warn-soft:     #FBF0E0;
    --tv-error:         #B91C1C;
    --tv-error-soft:    #FBEAEA;

    /* --- Typography --- */
    --tv-font-heading: 'Lora', Georgia, 'Times New Roman', serif;
    --tv-font-body:    'Be Vietnam Pro', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

    /* --- Khoảng cách --- */
    --tv-space-1: 0.25rem;
    --tv-space-2: 0.5rem;
    --tv-space-3: 0.75rem;
    --tv-space-4: 1rem;
    --tv-space-5: 1.5rem;
    --tv-space-6: 2rem;
    --tv-space-7: 3rem;

    /* --- Bo góc & đổ bóng: mềm, ấm, không "SaaS" --- */
    --tv-radius-sm: 8px;
    --tv-radius-md: 12px;
    --tv-radius-lg: 18px;
    --tv-radius-pill: 999px;

    --tv-shadow-sm: 0 1px 2px rgba(30, 27, 75, .06);
    --tv-shadow-md: 0 2px 10px rgba(30, 27, 75, .07);
    --tv-shadow-lg: 0 10px 30px -8px rgba(30, 27, 75, .16);

    /* --- Layout --- */
    --tv-sidebar-w: 264px;
    --tv-sidebar-w-collapsed: 68px;
}

/* ==========================================================================
   2. NỀN TRANG
   style.css:229 vẽ nền bằng `body::before` (fixed, z-index:-1) nằm TRÊN nền của
   `body` trong thứ tự vẽ → phải đổi CẢ HAI, nếu không nền vẫn là var(--gray-50).
   ========================================================================== */

body.tv-app {
    background: var(--tv-bg);
    color: var(--tv-ink);
    font-family: var(--tv-font-body);
    font-size: 16px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;

    /* Ánh xạ thương hiệu cũ → palette mới.
       Nhiều rule trong style.css / sidebar.css / mobile-ux.css vẫn dùng
       var(--primary-color) và một số còn kèm !important (ví dụ nút ☰ ở
       mobile-ux.css:183). Vì custom property kế thừa, khai báo lại ở đây khiến
       TẤT CẢ các rule đó tự lấy màu mới mà không phải viết lại từng rule. */
    --primary-color: #1E1B4B;
    --primary-dark: #14112F;
    --primary-light: #4B4869;
    --secondary-color: #F3EEE3;
    --accent-color: #F5EBD6;
}

body.tv-app::before {
    background: var(--tv-bg);
}

body.tv-app h1,
body.tv-app h2,
body.tv-app h3,
body.tv-app h4 {
    font-family: var(--tv-font-heading);
    color: var(--tv-ink);
    line-height: 1.3;
    letter-spacing: -0.01em;
}

body.tv-app p {
    color: var(--tv-ink-soft);
}

/* Link mặc định trong nội dung */
body.tv-app .main-content a:not(.tv-btn):not(.tv-card-link):not(.tv-tool) {
    color: var(--tv-accent-text);
    text-decoration-color: var(--tv-accent-line);
    text-underline-offset: 3px;
}

body.tv-app .main-content a:not(.tv-btn):not(.tv-card-link):not(.tv-tool):hover {
    color: var(--tv-accent-strong);
    text-decoration-color: currentColor;
}

/* Focus ring dùng chung — chỉ hiện khi điều hướng bằng bàn phím */
body.tv-app :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--tv-accent);
    outline-offset: 2px;
    border-radius: var(--tv-radius-sm);
}

body.tv-app .tv-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   3. LAYOUT SHELL
   sidebar.css:274 đặt `.main-layout{margin-left:200px}` không điều kiện, và
   :362 đặt 180px trong @media(max-width:1024px). Rule của ta có specificity
   (0,2,0) nên thắng ở mọi bề rộng — nhưng vì thế PHẢI tự khai báo lại MQ,
   nếu không sẽ phá khoảng 768–1024px.
   ========================================================================== */

body.tv-app .sidebar {
    width: var(--tv-sidebar-w);
    background: var(--tv-surface);
    border-right: 1px solid var(--tv-border);
    box-shadow: none;
}

body.tv-app .main-layout {
    margin-left: var(--tv-sidebar-w);
    background: transparent;
}

/* ⚠ BẮT BUỘC: .main-layout là FLEX ITEM của .container{display:flex}
   (sidebar.css:3). Flex item mặc định có `min-width: auto` = không co nhỏ hơn
   min-content của nội dung. Nên chỉ cần MỘT khối con có min-content lớn — ví dụ
   grid `repeat(auto-fit, minmax(180px, 1fr))` (min-content ~800px) hay bảng rộng
   — là `.main-layout` phình ra theo, cả trang rộng hơn màn hình, rồi bị
   `body{overflow-x:hidden}` (mobile-ux.css:9, giá trị truyền ra viewport) CẮT
   mất phần bên phải mà người dùng không cuộn tới được.
   Đã tái hiện và xác minh bằng Chrome headless: thiếu dòng này trang chủ rộng
   840px trên màn 390px.
   `min-width: 0` cho phép co lại; phần nội dung quá rộng tự cuộn trong khung
   `overflow-x: auto` của chính nó. */
body.tv-app .main-layout,
body.tv-app .main-content {
    min-width: 0;
}

@media (max-width: 1024px) {
    body.tv-app .sidebar {
        width: 216px;
    }

    body.tv-app .main-layout {
        margin-left: 216px;
    }
}

@media (max-width: 768px) {
    body.tv-app .sidebar {
        width: min(320px, 86vw);
    }

    /* !important là lớp chặn thứ hai: bảo đảm trên mobile .main-layout KHÔNG BAO
       GIỜ bị đẩy sang phải, kể cả khi có class trạng thái nào đó lỡ còn sót.
       Trang rộng hơn màn hình sẽ bị `body{overflow-x:hidden}` (mobile-ux.css:9,
       giá trị truyền ra viewport) CẮT đi và người dùng không cuộn tới được. */
    body.tv-app .main-layout {
        margin-left: 0 !important;
    }
}

/* .header giữ lại vì js/stats.js:39-47 chèn .page-stats ngay sau .header ĐẦU TIÊN
   — và nó dùng querySelectorAll('.header') nên mỗi trang chỉ được có ĐÚNG MỘT .header.

   ⚠ CHỈ scope cho trang chủ: 28 trang khác có .header là khối tiêu đề xếp dọc
   (h1 + mô tả + nút). Ép display:flex lên chúng sẽ đổi layout ngoài ý muốn. Các
   trang đó vẫn được đổi màu chữ/viền qua token, không đổi bố cục.

   KHÔNG đặt `padding` ở rule gốc: ở ≤768px mobile-ux.css:111 đặt
   `padding: 12px 16px 12px 56px` (56px bên trái là chỗ cho nút ☰). Rule gốc có
   specificity cao hơn sẽ đè mất và nút ☰ chồng lên thương hiệu. Padding được
   khai báo riêng cho desktop trong @media bên dưới. */
body.tv-app.tv-home .main-layout .header {
    background: var(--tv-surface);
    border-bottom: 1px solid var(--tv-border);
    text-align: left;
    display: flex;
    align-items: center;
    gap: var(--tv-space-3);
    flex-wrap: wrap;
}

/* Căn hàng của header trùng cột nội dung (.main-content max-width 1100px).
   Dùng padding-inline = max(gutter, nửa phần dư) để mép trái khớp nhau mà nền
   header vẫn tràn hết bề ngang. Chỉ áp từ 769px để không phá padding mobile. */
@media (min-width: 769px) {
    body.tv-app.tv-home .main-layout .header {
        padding-block: var(--tv-space-3);
        padding-inline: max(var(--tv-space-5), calc((100% - 1100px) / 2));
    }
}

/* Khối thương hiệu ở header trang chủ đã bỏ. Cụm nút phải tự đẩy sang phải —
   trước đây việc đó nhờ `.tv-brand { margin-right: auto }`. */
body.tv-app .tv-header-actions {
    margin-left: auto;
}

/* sidebar.css:28-43 khai báo `display:none` rồi `display:flex` trong CÙNG một
   rule → cuối cùng là flex ở MỌI bề rộng. Trước đây soft-ui.css:244 lo ẩn nó
   trên desktop; trang chủ bỏ soft-ui nên phải tự ẩn. */
body.tv-app .main-layout .header .mobile-menu-toggle {
    display: none;
}

@media (max-width: 768px) {
    body.tv-app .main-layout .header .mobile-menu-toggle {
        display: flex;
    }
}

body.tv-app .main-content {
    /* style.css:241-251 bọc .main-content thành một thẻ trắng có viền + đổ bóng.
       Giao diện mới đã có thẻ ở từng khối (hero, form, lưới công cụ) nên thẻ bao
       ngoài sẽ gây lồng thẻ. Bỏ phần trang trí, giữ `contain` của style.css. */
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: var(--tv-space-5);
    max-width: 1100px;
    width: 100%;
    margin: 0 auto;
}

@media (max-width: 768px) {
    body.tv-app .main-content {
        padding: var(--tv-space-4) var(--tv-space-3);
    }
}

/* ==========================================================================
   4. NAV PHÂN NHÓM (sidebar)
   Dùng class riêng `.tv-nav-*` (KHÔNG dùng .sidebar-link) để tránh mọi rule
   cũ bám vào .sidebar-link trong sidebar.css / soft-ui.css / mobile-ux.css.
   ========================================================================== */

body.tv-app .sidebar-header {
    padding: var(--tv-space-4) var(--tv-space-5);
    border-bottom: 1px solid var(--tv-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tv-space-2);
}

body.tv-app .sidebar-header h2 {
    font-family: var(--tv-font-heading);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--tv-ink);
    margin: 0;
    white-space: nowrap;
}

body.tv-app .sidebar-toggle {
    background: var(--tv-surface-2);
    border: 1px solid var(--tv-border);
    color: var(--tv-ink-soft);
    width: 30px;
    height: 30px;
    border-radius: var(--tv-radius-pill);
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    flex-shrink: 0;
}

body.tv-app .sidebar-toggle:hover {
    background: var(--tv-accent-soft);
    border-color: var(--tv-accent-line);
}

body.tv-app .sidebar-content {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--tv-space-3) var(--tv-space-3) var(--tv-space-5);
}

body.tv-app .sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: var(--tv-space-1);
}

/* sidebar.css:558-560 chỉ đặt flex-shrink:0 cho `> a.sidebar-link`, nên các
   <div> nhóm sẽ bị bóp méo nếu không tự khai báo. */
body.tv-app .tv-nav-group {
    flex-shrink: 0;
    margin-bottom: var(--tv-space-3);
}

body.tv-app .tv-nav-group:last-child {
    margin-bottom: 0;
}

body.tv-app .tv-nav-label {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--tv-muted);
    padding: 0 var(--tv-space-3);
    margin-bottom: var(--tv-space-2);
}

body.tv-app .tv-nav-link {
    display: flex;
    align-items: center;
    gap: var(--tv-space-2);
    padding: 9px var(--tv-space-3);
    border-radius: var(--tv-radius-sm);
    color: var(--tv-ink-soft);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 500;
    border-left: 2px solid transparent;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

body.tv-app .tv-nav-link .tv-nav-icon {
    width: 24px;
    text-align: center;
    font-size: 1rem;
    flex-shrink: 0;
}

body.tv-app .tv-nav-link:hover {
    background: var(--tv-surface-2);
    color: var(--tv-ink);
}

body.tv-app .tv-nav-link.active {
    background: var(--tv-accent-soft);
    border-left-color: var(--tv-accent);
    color: var(--tv-ink);
    font-weight: 600;
}

/* Mục AI Agent — sản phẩm chiến lược, đặt nổi bật */
body.tv-app .tv-nav-link--featured {
    background: var(--tv-ink);
    color: #F7F3E8;
    border-left-color: var(--tv-accent);
    font-weight: 600;
}

body.tv-app .tv-nav-link--featured:hover {
    background: #2A2660;
    color: #FFFFFF;
}

body.tv-app .tv-nav-link--featured .tv-nav-badge {
    margin-left: auto;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    background: var(--tv-accent);
    color: #FFFFFF;
    padding: 2px 7px;
    border-radius: var(--tv-radius-pill);
}

body.tv-app .sidebar-footer {
    border-top: 1px solid var(--tv-border);
    padding: var(--tv-space-3);
}

body.tv-app .sidebar-footer a {
    color: var(--tv-ink-soft);
}

/* ==========================================================================
   5. NÚT
   `.btn` được JS dùng ở nhiều nơi (.btn-retry, nút trong modal, overlay) nên
   phải restyle .btn chứ không chỉ class mới.
   ========================================================================== */

body.tv-app .btn,
body.tv-app .tv-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--tv-space-2);
    font-family: var(--tv-font-body);
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.2;
    padding: 11px 20px;
    border-radius: var(--tv-radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    background: var(--tv-ink);
    color: #FBF8F1;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .1s ease;
}

body.tv-app .btn:hover,
body.tv-app .tv-btn:hover {
    background: #2A2660;
}

body.tv-app .btn:active,
body.tv-app .tv-btn:active {
    transform: translateY(1px);
}

body.tv-app .tv-btn--accent {
    background: var(--tv-accent-strong);
    color: #FFFFFF;
}

body.tv-app .tv-btn--accent:hover {
    background: #7A5A07;
}

body.tv-app .tv-btn--outline,
body.tv-app .btn-secondary {
    background: var(--tv-surface);
    color: var(--tv-ink);
    border-color: var(--tv-border-strong);
}

body.tv-app .tv-btn--outline:hover,
body.tv-app .btn-secondary:hover {
    background: var(--tv-accent-soft);
    border-color: var(--tv-accent-line);
    color: var(--tv-ink);
}

body.tv-app .tv-btn--ghost {
    background: transparent;
    color: var(--tv-accent-text);
    border-color: transparent;
    padding: 8px 10px;
    font-weight: 500;
}

body.tv-app .tv-btn--ghost:hover {
    background: var(--tv-accent-soft);
    color: var(--tv-ink);
}

body.tv-app .tv-btn--lg {
    font-size: 1.05rem;
    padding: 14px 28px;
}

body.tv-app .tv-btn--sm {
    font-size: 0.85rem;
    padding: 7px 14px;
}

body.tv-app .tv-btn--block {
    width: 100%;
}

body.tv-app .btn:disabled,
body.tv-app .tv-btn:disabled {
    opacity: .6;
    cursor: not-allowed;
}

/* ==========================================================================
   6. BIỂU MẪU
   `.input-field` là hợp đồng dùng chung: fortune-context.js tự sinh markup này
   lúc runtime, và mobile-ux.css:201-231 lo tap target 48px + font 16px chống
   zoom iOS trên mobile. Giữ nguyên cấu trúc, chỉ đổi màu theo palette mới.
   ========================================================================== */

body.tv-app .input-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

body.tv-app .input-field label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--tv-ink-soft);
}

body.tv-app .input-field input,
body.tv-app .input-field select,
body.tv-app .input-field textarea,
body.tv-app .tv-field input,
body.tv-app .tv-field select,
body.tv-app .tv-field textarea {
    width: 100%;
    font-family: var(--tv-font-body);
    font-size: 1rem;
    color: var(--tv-ink);
    /* ⚠ Dùng background-color, KHÔNG dùng shorthand `background`.
       Shorthand sẽ reset background-image về none, background-position về 0% 0%
       và background-repeat về repeat cho MỌI input/select/textarea bên dưới.
       Với <select> trên mobile, mobile-ux.css:229 vẽ mũi tên bằng background-image
       → shorthand ở đây (specificity 0,2,1 > 0,1,1 của rule đó) làm mũi tên mất
       hoặc lặp kín ô đè lên chữ. */
    background-color: var(--tv-surface);
    border: 1px solid var(--tv-border-strong);
    border-radius: var(--tv-radius-sm);
    padding: 11px 12px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

body.tv-app .input-field input:focus,
body.tv-app .input-field select:focus,
body.tv-app .input-field textarea:focus,
body.tv-app .tv-field input:focus,
body.tv-app .tv-field select:focus,
body.tv-app .tv-field textarea:focus {
    outline: none;
    border-color: var(--tv-accent);
    box-shadow: 0 0 0 3px rgba(184, 134, 11, .16);
}

body.tv-app .input-field input::placeholder,
body.tv-app .input-field textarea::placeholder {
    color: #9A9382;
}

body.tv-app .input-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
    gap: var(--tv-space-3);
}

/* Khối "Tùy chọn nâng cao" */
body.tv-app .tv-advanced {
    margin-top: var(--tv-space-3);
    border-top: 1px dashed var(--tv-border-strong);
    padding-top: var(--tv-space-2);
}

body.tv-app .tv-advanced>summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--tv-accent-text);
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
}

body.tv-app .tv-advanced>summary::-webkit-details-marker {
    display: none;
}

body.tv-app .tv-advanced>summary::before {
    content: '＋';
    font-weight: 700;
}

body.tv-app .tv-advanced[open]>summary::before {
    content: '－';
}

body.tv-app .tv-advanced[open]>summary {
    margin-bottom: var(--tv-space-2);
}

/* ==========================================================================
   7. THẺ / KHỐI
   ========================================================================== */

body.tv-app .tv-card {
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-lg);
    padding: var(--tv-space-5);
    box-shadow: var(--tv-shadow-sm);
}

body.tv-app .tv-section {
    margin: var(--tv-space-6) 0;
}

body.tv-app .tv-section__head {
    margin-bottom: var(--tv-space-4);
}

body.tv-app .tv-section__title {
    font-size: 1.4rem;
    margin: 0 0 var(--tv-space-1);
}

body.tv-app .tv-section__sub {
    color: var(--tv-muted);
    font-size: 0.95rem;
    margin: 0;
}

body.tv-app .tv-eyebrow {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--tv-accent-text);
    margin-bottom: var(--tv-space-2);
}

body.tv-app .tv-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--tv-ink-soft);
    background: var(--tv-accent-soft);
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius-pill);
    padding: 4px 12px;
}

body.tv-app .tv-note {
    font-size: 0.82rem;
    color: var(--tv-muted);
    border-left: 3px solid var(--tv-accent-line);
    padding-left: var(--tv-space-3);
    margin: var(--tv-space-4) 0;
}

/* ==========================================================================
   8. KẾT QUẢ LUẬN GIẢI
   .result-card / .result-content / .btn-retry do js/ui.js sinh ra, và
   pdf-export.js đọc lại chính các class này → KHÔNG đổi tên.
   ========================================================================== */

body.tv-app .result-card {
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-md);
    box-shadow: var(--tv-shadow-sm);
    margin-bottom: var(--tv-space-4);
    padding: var(--tv-space-5);
}

body.tv-app .result-card .result-title,
body.tv-app .result-title {
    font-family: var(--tv-font-heading);
    color: var(--tv-ink);
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0 0 var(--tv-space-3);
    padding-bottom: var(--tv-space-2);
    border-bottom: 2px solid var(--tv-accent-line);
}

body.tv-app .result-content {
    color: var(--tv-ink-soft);
    line-height: 1.75;
}

body.tv-app .result-content h3,
body.tv-app .result-content h4 {
    color: var(--tv-ink);
    margin: var(--tv-space-4) 0 var(--tv-space-2);
}

body.tv-app .result-content ul,
body.tv-app .result-content ol {
    padding-left: 1.35rem;
}

body.tv-app .result-content li {
    margin-bottom: 6px;
}

body.tv-app .result-content strong {
    color: var(--tv-ink);
}

body.tv-app .result-card.error {
    border-color: var(--tv-error);
    background: var(--tv-error-soft);
}

/* --- Tiến độ từng cung --- */

body.tv-app .palace-progress-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tv-space-2);
    margin-top: var(--tv-space-3);
}

body.tv-app .palace-progress-card {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--tv-muted);
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-pill);
    padding: 4px 12px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

body.tv-app .palace-progress-card.processing {
    background: var(--tv-warn-soft);
    border-color: var(--tv-warn);
    color: var(--tv-warn);
    font-weight: 600;
}

body.tv-app .palace-progress-card.completed {
    background: var(--tv-success-soft);
    border-color: #B7DCC4;
    color: var(--tv-success);
    font-weight: 600;
}

body.tv-app .palace-progress-card.completed::before {
    content: '✓';
    font-weight: 700;
}

body.tv-app .palace-progress-card.processing::before {
    content: '◌';
}

/* --- Thanh tiến độ tổng (js/progress-ui.js) --- */

body.tv-app .tv-progress {
    margin: var(--tv-space-4) 0 var(--tv-space-2);
}

/* js/progress-ui.js đặt `hidden` khi lưới bước rỗng (ví dụ luồng Bát Tự) */
body.tv-app .tv-progress[hidden] {
    display: none;
}

body.tv-app .tv-progress__track {
    height: 8px;
    background: var(--tv-surface-sunk);
    border-radius: var(--tv-radius-pill);
    overflow: hidden;
    border: 1px solid var(--tv-border);
}

body.tv-app .tv-progress__fill {
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, var(--tv-accent), var(--tv-accent-strong));
    border-radius: var(--tv-radius-pill);
    transition: width .45s ease;
}

body.tv-app .tv-progress__meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--tv-space-3);
    margin-top: var(--tv-space-2);
    font-size: 0.85rem;
    color: var(--tv-muted);
}

body.tv-app .tv-progress__count {
    font-weight: 700;
    color: var(--tv-accent-text);
    font-variant-numeric: tabular-nums;
}

/* --- Skeleton cho phần chưa luận xong --- */

body.tv-app .tv-skeleton {
    border-radius: var(--tv-radius-md);
    border: 1px solid var(--tv-border);
    background: var(--tv-surface);
    padding: var(--tv-space-5);
    margin-bottom: var(--tv-space-4);
}

body.tv-app .tv-skeleton__line {
    height: 11px;
    border-radius: var(--tv-radius-pill);
    background: linear-gradient(90deg, var(--tv-surface-2) 25%, var(--tv-surface-sunk) 37%, var(--tv-surface-2) 63%);
    background-size: 400% 100%;
    animation: tv-shimmer 1.4s ease-in-out infinite;
    margin-bottom: 10px;
}

body.tv-app .tv-skeleton__line:last-child {
    margin-bottom: 0;
    width: 62%;
}

body.tv-app .tv-skeleton__line--title {
    height: 15px;
    width: 42%;
    margin-bottom: var(--tv-space-3);
}

@keyframes tv-shimmer {
    0% {
        background-position: 100% 50%;
    }

    100% {
        background-position: 0 50%;
    }
}

@media (prefers-reduced-motion: reduce) {
    body.tv-app .tv-skeleton__line {
        animation: none;
    }

    body.tv-app .tv-progress__fill {
        transition: none;
    }
}

/* ==========================================================================
   9. MODAL
   style.css:2126-2215 và :2741-2812 đã lo phần khung + transition
   (`.modal-overlay` / `.active` / `.modal-content` / `.modal-close`), ở đây chỉ
   đổi màu. Modal nằm ngoài .main-content vì .main-content có
   `contain: layout style paint` (style.css:250) → sẽ thành containing block
   của position:fixed và làm modal lệch.
   ========================================================================== */

body.tv-app .modal-overlay {
    background: rgba(24, 21, 56, .55);
    backdrop-filter: blur(3px);
}

body.tv-app .modal-content {
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-lg);
    box-shadow: var(--tv-shadow-lg);
    color: var(--tv-ink);
}

body.tv-app .modal-content h3 {
    font-family: var(--tv-font-heading);
    color: var(--tv-ink);
}

body.tv-app .modal-content p {
    color: var(--tv-ink-soft);
}

body.tv-app .modal-close {
    color: var(--tv-muted);
    border-radius: var(--tv-radius-pill);
}

body.tv-app .modal-close:hover {
    background: var(--tv-surface-2);
    color: var(--tv-ink);
}

/* ==========================================================================
   10. THỐNG KÊ (js/stats.js sinh ra .page-stats với inline style)
   ========================================================================== */

body.tv-app .page-stats {
    background: var(--tv-surface-2);
    border-bottom: 1px solid var(--tv-border);
    padding: var(--tv-space-3) var(--tv-space-5);
}

body.tv-app .page-stats .stats-number {
    color: var(--tv-ink);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

body.tv-app .page-stats .stats-label {
    color: var(--tv-muted);
    font-size: 0.78rem;
}

/* ==========================================================================
   11. TOAST
   ========================================================================== */

body.tv-app .toast {
    font-family: var(--tv-font-body);
    border-radius: var(--tv-radius-sm);
    box-shadow: var(--tv-shadow-lg);
}

body.tv-app .toast-success {
    background: var(--tv-success);
}

body.tv-app .toast-error {
    background: var(--tv-error);
}

body.tv-app .toast-info {
    background: var(--tv-ink);
}

body.tv-app .toast-warning {
    background: var(--tv-warn);
}

/* ==========================================================================
   12. TRANG TRÍ & FLOATING — chừa chỗ cho bottom tab bar
   ========================================================================== */

body.tv-app .zalo-link {
    background: #0068FF;
    box-shadow: var(--tv-shadow-lg);
}

@media (max-width: 768px) {

    /* Thanh bottom tab bar đã BỎ (điều hướng mobile giờ dùng nút "☰ Công cụ"
       trên header). Vì vậy phải trả lại khoảng trống mà mobile-ux.css chừa cho
       thanh đó, nếu không mỗi trang mobile thừa ~68–80px trắng ở đáy:
         - mobile-ux.css:660  `.footer{padding-bottom:80px!important}`
         - mobile-ux.css:780  `.main-layout{padding-bottom:68px!important}`
         - mobile-ux.css:906  bản @supports có env(safe-area-inset-bottom)
         - mobile-ux.css:785  `#toast-container{bottom:72px!important}`
       Rule ở đây có specificity (0,2,0) + !important nên thắng các rule (0,1,0)
       + !important ở trên, và ds.css lại nạp sau. */
    body.tv-app .main-layout {
        padding-bottom: 0 !important;
    }

    body.tv-app .footer {
        padding-bottom: var(--tv-space-5) !important;
    }

    body.tv-app #toast-container {
        top: auto !important;
        bottom: 16px !important;
    }
}

/* ==========================================================================
   13. SIDEBAR THU GỌN — CHỈ DESKTOP
   Trạng thái do js/app-shell.js gắn class `tv-nav-collapsed` lên <body> — KHÔNG
   dùng `.sidebar.collapsed` của sidebar.css và không ghi style nội tuyến, để
   bề rộng sidebar và margin của .main-layout luôn khớp nhau ở mọi media query.

   ⚠ BẮT BUỘC bọc trong @media (min-width: 769px).
   `body.tv-app.tv-nav-collapsed .main-layout` có specificity (0,3,0) — CAO HƠN
   rule `body.tv-app .main-layout { margin-left: 0 }` trong
   @media (max-width: 768px) vốn chỉ (0,2,0). Không bọc media query thì chỉ cần
   người dùng từng bấm thu gọn menu trên desktop (trạng thái nằm lại trong
   localStorage) là trên điện thoại `.main-layout` bị đẩy margin-left 68px →
   trang rộng hơn màn hình 68px. Vì css/mobile-ux.css:9 đặt
   `body { overflow-x: hidden }` và giá trị này được TRUYỀN RA VIEWPORT, phần
   tràn bị cắt chứ không cuộn tới được → nhìn như bị zoom vào mép trái.
   ========================================================================== */

@media (min-width: 769px) {

    body.tv-app.tv-nav-collapsed .sidebar {
        width: var(--tv-sidebar-w-collapsed);
    }

    body.tv-app.tv-nav-collapsed .main-layout {
        margin-left: var(--tv-sidebar-w-collapsed);
    }

    body.tv-app.tv-nav-collapsed .sidebar-header {
        justify-content: center;
        padding-left: var(--tv-space-2);
        padding-right: var(--tv-space-2);
    }

    body.tv-app.tv-nav-collapsed .tv-nav-label,
    body.tv-app.tv-nav-collapsed .tv-nav-link .tv-nav-text,
    body.tv-app.tv-nav-collapsed .tv-nav-link--featured .tv-nav-badge,
    body.tv-app.tv-nav-collapsed .sidebar-header h2 {
        display: none;
    }

    body.tv-app.tv-nav-collapsed .tv-nav-link {
        justify-content: center;
        padding-left: 6px;
        padding-right: 6px;
    }

    body.tv-app.tv-nav-collapsed .tv-nav-group {
        margin-bottom: var(--tv-space-2);
    }

    body.tv-app.tv-nav-collapsed .sidebar-content {
        padding-left: var(--tv-space-1);
        padding-right: var(--tv-space-1);
    }

    body.tv-app.tv-nav-collapsed #support-links {
        display: none;
    }
}

/* Khoá cuộn nền khi mở ngăn kéo mobile. mobile-ux.css:8-14 ép
   `overflow-x/y !important` trên body nên phải dùng !important + specificity
   cao hơn mới thắng được. */
body.tv-app.tv-nav-open {
    overflow: hidden !important;
}

/* ==========================================================================
   14. KHU TÀI KHOẢN TRÊN HEADER
   --------------------------------------------------------------------------
   Thứ tự trên header (đăng nhập rồi):
       [Nạp xu]  [6876 xu ▾]
   - "Nạp xu" (#topupBtn) là nút riêng, luôn hiện.
   - Pill số xu là nút gọn, bấm mới xổ ra panel: Điểm danh + Đăng xuất.
   - Chưa đăng nhập: [Đăng nhập]
   js/app-shell.js dựng khu này từ chính các phần tử mà js/main.js đang quản lý
   (#loginBtn, #topupBtn, #checkinBtn, #user-balance-container) nên không phải
   sửa main.js; main.js vẫn tự ẩn/hiện từng nút theo trạng thái đăng nhập.
   ========================================================================== */

body.tv-app .tv-account {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-2);
    margin-left: auto;
}

body.tv-app .tv-account__trigger {
    display: none;
    /* chỉ hiện khi đã đăng nhập */
    align-items: center;
    gap: 6px;
    font-family: var(--tv-font-body);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--tv-ink);
    background: var(--tv-accent-soft);
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius-pill);
    padding: 7px 14px;
    cursor: pointer;
    white-space: nowrap;
}

body.tv-app .tv-account.is-authed .tv-account__trigger {
    display: inline-flex;
}

body.tv-app .tv-account__trigger:hover {
    background: #EFE1C4;
}

body.tv-app .tv-account__trigger #user-balance {
    font-variant-numeric: tabular-nums;
}

body.tv-app .tv-account__caret {
    font-size: 0.7rem;
    color: var(--tv-accent-text);
    transition: transform .18s ease;
}

body.tv-app .tv-account.is-open .tv-account__caret {
    transform: rotate(180deg);
}

body.tv-app .tv-account__panel {
    /* position:fixed + gắn vào <body> (js/app-shell.js) — KHÔNG lồng trong header.
       Header các trang bị cắt theo nhiều cách: `contain: layout style`
       (style.css:2099), `position: sticky` trên mobile, và khung `overflow-x:auto`
       (mobile-ux.css:131). Panel absolute lồng trong đó sẽ bị cắt trên mobile.
       top/right dưới đây chỉ là giá trị dự phòng; JS ghi đè khi mở. */
    position: fixed;
    top: 56px;
    right: 12px;
    z-index: 1400;
    min-width: 220px;
    max-width: calc(100vw - 24px);
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: var(--tv-space-2);
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-md);
    box-shadow: var(--tv-shadow-lg);
    text-align: left;
}

body.tv-app .tv-account__panel[hidden] {
    display: none;
}

body.tv-app .tv-account__panel .btn {
    width: 100%;
    justify-content: flex-start;
    font-size: 0.88rem;
    padding: 9px 12px;
    background: transparent;
    color: var(--tv-ink);
    border-color: transparent;
}

body.tv-app .tv-account__panel .btn:hover {
    background: var(--tv-accent-soft);
    color: var(--tv-ink);
}

body.tv-app .tv-account__item {
    display: block;
    padding: 9px 12px;
    border-radius: var(--tv-radius-sm);
    font-size: 0.88rem;
    color: var(--tv-muted);
    text-decoration: none;
}

body.tv-app .tv-account__item:hover {
    background: var(--tv-surface-2);
    color: var(--tv-ink);
}

body.tv-app .tv-account__item--logout {
    border-top: 1px solid var(--tv-border);
    margin-top: 4px;
    color: var(--tv-error);
}

body.tv-app .tv-account__item--logout:hover {
    background: var(--tv-error-soft);
    color: var(--tv-error);
}

/* Trang chủ: header xếp hàng ngang nên khu tài khoản nằm cuối hàng */
body.tv-app.tv-home .tv-account {
    margin-left: var(--tv-space-2);
}

/* Trên mobile có tới 3 phần tử cạnh nhau (Nạp xu · số xu · nút ☰) nên phải thu
   nhỏ tối đa, nếu không chúng chiếm gần hết chiều ngang và đẩy nhau xuống dòng
   thứ hai, làm header cao thêm. Mọi trang đều có các nút này nên áp dụng chung. */
@media (max-width: 768px) {

    body.tv-app .tv-account {
        gap: 4px;
        margin-left: var(--tv-space-1);
    }

    /* Nút "Nạp xu" — vẫn giữ >= 32px chiều cao để đủ lớn cho ngón tay */
    body.tv-app .tv-account .btn {
        font-size: 0.78rem;
        padding: 7px 10px;
    }

    /* Pill số xu */
    body.tv-app .tv-account__trigger {
        font-size: 0.78rem;
        padding: 6px 10px;
        gap: 4px;
    }

    body.tv-app .tv-tools__toggle {
        font-size: 0.8rem;
        padding: 7px 10px;
    }

}

/* ==========================================================================
   15. NÚT "☰ CÔNG CỤ" — có mặt trên MỌI trang
   --------------------------------------------------------------------------
   Thay cho thanh bottom tab bar cũ ở mobile: một nút mở ra panel 4 nhóm.
   Panel do js/app-shell.js gắn vào <body> với position:fixed (xem chú thích
   trong file đó: lồng panel trong .header sẽ bị cắt ở các trang có overflow).
   ========================================================================== */

body.tv-app .tv-tools {
    position: relative;
    flex-shrink: 0;
}

body.tv-app .tv-tools__toggle {
    font-family: var(--tv-font-body);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--tv-ink);
    background: var(--tv-surface-2);
    border: 1px solid var(--tv-border-strong);
    border-radius: var(--tv-radius-sm);
    padding: 8px 14px;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color .15s ease, border-color .15s ease;
}

body.tv-app .tv-tools__toggle:hover {
    background: var(--tv-accent-soft);
    border-color: var(--tv-accent-line);
}

body.tv-app .tv-tools__toggle[aria-expanded="true"] {
    background: var(--tv-accent-soft);
    border-color: var(--tv-accent);
}

body.tv-app .tv-tools__panel {
    position: fixed;
    z-index: 1300;
    width: min(92vw, 680px);
    max-height: min(72vh, 560px);
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(168px, 100%), 1fr));
    gap: var(--tv-space-4);
    padding: var(--tv-space-4);
    background: var(--tv-surface);
    border: 1px solid var(--tv-border);
    border-radius: var(--tv-radius-md);
    box-shadow: var(--tv-shadow-lg);
    text-align: left;
}

body.tv-app .tv-tools__panel[hidden] {
    display: none;
}

body.tv-app .tv-tools__group {
    min-width: 0;
}

body.tv-app .tv-tools__link {
    display: block;
    padding: 7px 9px;
    border-radius: var(--tv-radius-sm);
    font-size: 0.88rem;
    color: var(--tv-ink-soft);
    text-decoration: none;
}

body.tv-app .tv-tools__link:hover {
    background: var(--tv-accent-soft);
    color: var(--tv-ink);
}

body.tv-app .tv-tools__link.active {
    background: var(--tv-accent-soft);
    color: var(--tv-ink);
    font-weight: 600;
}

/* Thanh gọn ở đầu trang, chỉ dùng cho trang KHÔNG có .header
   (tinhbattu, ban-do-sao-phuong-tay, soi-ban-do-sao-luc-sinh).
   Cố ý KHÔNG dùng class `.header`: js/stats.js chèn .page-stats sau MỌI `.header`
   nên thêm một `.header` nữa sẽ làm khối thống kê xuất hiện hai lần. */
body.tv-app .tv-appbar {
    position: sticky;
    top: 0;
    z-index: 1100;
    background: var(--tv-surface);
    border-bottom: 1px solid var(--tv-border);
    box-shadow: var(--tv-shadow-sm);
    font-family: var(--tv-font-body);
}

body.tv-app .tv-appbar__inner {
    display: flex;
    align-items: center;
    gap: var(--tv-space-3);
    flex-wrap: wrap;
    max-width: 1100px;
    margin: 0 auto;
    padding: 10px var(--tv-space-4);
}

body.tv-app .tv-appbar__brand {
    font-family: var(--tv-font-heading);
    font-weight: 700;
    color: var(--tv-ink);
    text-decoration: none;
    margin-right: auto;
}

body.tv-app .tv-appbar__ai {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--tv-ink);
    background: var(--tv-accent-soft);
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius-pill);
    padding: 6px 13px;
    text-decoration: none;
    white-space: nowrap;
}

/* ==========================================================================
   16. TƯƠNG THÍCH: token --neu-* của css/soft-ui.css
   Các trang bỏ class `soft-ui` sẽ không còn css/soft-ui.css áp dụng, nhưng
   css/ai-agent.css vẫn dùng var(--neu-*) bên trong. Khai báo lại theo palette
   mới để các trang đó không bị giá trị rỗng.
   ========================================================================== */

:root {
    --neu-bg: #FAF7F0;
    --neu-surface-raised: #FFFFFF;
    --neu-surface-sunken: #F3EEE3;
    --neu-accent-tint: #F5EBD6;
    --neu-shadow-light: #FFFFFF;
    --neu-shadow-dark: #E6DFD2;
    --neu-shadow-dark-strong: #D5CBB8;
    --neu-raised-xs: 0 1px 2px rgba(30, 27, 75, .06);
    --neu-raised-sm: 0 2px 8px rgba(30, 27, 75, .07);
    --neu-raised-md: 0 4px 14px rgba(30, 27, 75, .09);
    --neu-raised-lg: 0 10px 30px -8px rgba(30, 27, 75, .16);
    --neu-inset-xs: inset 0 1px 2px rgba(30, 27, 75, .05);
    --neu-inset-sm: inset 0 1px 3px rgba(30, 27, 75, .06);
    --neu-inset-md: inset 0 2px 5px rgba(30, 27, 75, .07);
    --neu-radius-xs: var(--tv-radius-sm);
    --neu-radius-sm: var(--tv-radius-sm);
    --neu-radius-md: var(--tv-radius-md);
    --neu-radius-lg: var(--tv-radius-lg);
    --neu-radius-xl: var(--tv-radius-lg);
    --neu-radius-pill: var(--tv-radius-pill);
    --neu-accent: #1E1B4B;
    --neu-accent-dark: #14112F;
    --neu-accent-light: #4B4869;
    --neu-text: #4B4869;
    --neu-text-strong: #1E1B4B;
    --neu-text-muted: #5A6272;
}

/* ==========================================================================
   17. KHỐI HỖ TRỢ TRONG SIDEBAR (chỉ Zalo — Messenger đã bỏ theo yêu cầu)
   ========================================================================== */

body.tv-app #support-links {
    font-size: 0.85rem;
}

body.tv-app #support-links a {
    color: var(--tv-accent-text);
    text-decoration: none;
}

body.tv-app #support-links a:hover {
    text-decoration: underline;
}

/* ==========================================================================
   18. NỘI DUNG TRANG CŨ: chuẩn hoá bảng và tiêu đề trong vùng nội dung
   Nhiều trang tự đặt màu chữ/viền cho bảng bằng mã cứng; các rule dưới đây chỉ
   nhắm vào bảng nằm trong vùng nội dung để không phá bảng nghiệp vụ đặc thù
   (lá số, tứ trụ, đại vận…).
   ========================================================================== */

body.tv-app .main-content table:not(.tv-compare):not(.bazi-table):not([class*="laso"]) {
    border-color: var(--tv-border);
}

body.tv-app .main-content h1,
body.tv-app .main-content h2 {
    font-family: var(--tv-font-heading);
    color: var(--tv-ink);
}

/* ==========================================================================
   18. BỘ CHỌN PHƯƠNG PHÁP GIEO QUẺ (kinhdich.html)
   --------------------------------------------------------------------------
   Vì sao phải viết lại: `mobile-ux.css:217-225` áp cho MỌI `.input-field input`
   các lệnh `appearance: none` + `min-height: 48px !important` +
   `border-radius: 12px !important`. Hai radio của Kinh Dịch nằm trong
   `.input-field`, nên bị biến thành ô vuông cao 48px không có dấu chấm → gần như
   không nhìn ra đang chọn cái nào.

   Trước đây `css/soft-ui.css:569-582` có rule khôi phục dấu chấm cho radio, nhưng
   file đó chỉ áp dụng khi <body> có class `soft-ui` — mà trang chủ đề đã bỏ class
   này trên toàn site, nên phần khôi phục đó không còn chạy. Rule dưới đây thay thế.

   Giữ nguyên `<input type="radio" name="divination-method">` vì
   `js/kinhdich.js:258` đọc `input[name="divination-method"]:checked`. Chỉ đổi
   phần NHÌN: ô vuông có dấu ✓ khi chọn (dễ thấy hơn hẳn), kèm viền + nền nhấn cho
   cả thẻ lựa chọn.
   ========================================================================== */

body.tv-app .method-picker {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tv-space-3);
    margin-top: 6px;
}

body.tv-app .method-option {
    display: flex !important;
    align-items: center;
    gap: var(--tv-space-3);
    flex: 1 1 230px;
    /* Ghi đè `.input-field label` của mobile-ux.css:210 (!important) */
    padding: 14px 16px !important;
    margin-bottom: 0 !important;
    font-size: 0.95rem !important;
    background: var(--tv-surface);
    border: 1.5px solid var(--tv-border-strong);
    border-radius: var(--tv-radius-md);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}

body.tv-app .method-option:hover {
    border-color: var(--tv-accent-line);
    background: var(--tv-accent-soft);
}

body.tv-app .method-option:has(input:checked) {
    border-color: var(--tv-accent);
    background: var(--tv-accent-soft);
    box-shadow: 0 0 0 1px var(--tv-accent);
}

/* Ô tick vuông. Ghi đè toàn bộ rule `.input-field input` của mobile-ux.css. */
body.tv-app .method-option input[type="radio"] {
    appearance: none !important;
    -webkit-appearance: none !important;
    position: relative;
    flex: 0 0 auto;
    width: 24px !important;
    height: 24px !important;
    min-height: 0 !important;
    max-height: 24px !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 2px solid var(--tv-border-strong) !important;
    border-radius: 7px !important;
    background: var(--tv-surface) !important;
    box-shadow: none !important;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

body.tv-app .method-option input[type="radio"]:checked {
    background: var(--tv-accent-strong) !important;
    border-color: var(--tv-accent-strong) !important;
}

body.tv-app .method-option input[type="radio"]:checked::after {
    content: '✓';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
}

body.tv-app .method-option input[type="radio"]:focus-visible {
    outline: 3px solid var(--tv-accent);
    outline-offset: 2px;
}

body.tv-app .method-option .method-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

body.tv-app .method-option .method-text strong {
    color: var(--tv-ink);
    font-weight: 600;
}

body.tv-app .method-option .method-text em {
    font-style: normal;
    font-size: 0.82rem;
    color: var(--tv-muted);
}

body.tv-app .method-option:has(input:checked) .method-text em {
    color: var(--tv-accent-text);
}

/* Mũi tên select trên mobile: mobile-ux.css:228-232 vẽ bằng SVG màu xanh cũ
   #4a6fa5, đổi sang màu chàm của design system.
   Rule này phải TỰ KHAI BÁO ĐẦY ĐỦ cả vị trí / lặp / kích thước, không chỉ
   background-image: trước đây chỉ set mỗi ảnh nên nó thừa hưởng
   `background-position: 0% 0%` và `background-repeat: repeat` → mũi tên lặp kín
   ô và đè lên chữ. Ghi đè bằng !important để không phụ thuộc thứ tự nạp file. */
@media (max-width: 768px) {
    body.tv-app .input-field select {
        background-color: var(--tv-surface) !important;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M6 8L1 3h10z' fill='%231E1B4B'/%3E%3C/svg%3E") !important;
        background-repeat: no-repeat !important;
        background-position: right 14px center !important;
        background-size: 12px 12px !important;
        /* Chừa chỗ cho mũi tên để chữ không bao giờ chạy xuống dưới nó */
        padding-right: 40px !important;
    }
}

/* ==========================================================================
   19. KHUNG CHAT (ai-agent.html) — ô nhập luôn trong tầm mắt
   --------------------------------------------------------------------------
   `.chat-messages` (ai-agent.css:203) đã có `height: min(56vh,560px)` + overflow
   riêng, nhưng `.chat-input-area` nằm SAU nó trong luồng thường. Trên màn thấp
   (mobile), 56vh cộng header + thanh agent đẩy ô nhập xuống dưới đáy khung nhìn →
   phải cuộn mới gõ được. Cách sửa:
     - Desktop: ghim ô nhập vào đáy khung nhìn bằng `position: sticky`.
     - Mobile: chặn chiều cao thẻ chat theo khung nhìn và cho phần tin nhắn co
       giãn (`flex:1; min-height:0`) để cả thanh agent + tin nhắn + ô nhập vừa
       trong một màn hình.
   ========================================================================== */

body.tv-app .chat-input-area {
    position: sticky;
    bottom: 0;
    z-index: 5;
    /* Nền đặc để tin nhắn không hiện xuyên qua khi cuộn xuống dưới ô nhập */
    background: var(--tv-surface);
    border-top: 1px solid var(--tv-border);
    padding-top: 10px;
}

@media (max-width: 768px) {

    body.tv-app .chat-card {
        /* 100dvh trừ phần header + khoảng thở; có fallback 100vh cho trình duyệt cũ */
        height: calc(100vh - 150px);
        height: calc(100dvh - 150px);
        padding: 0.75rem;
    }

    body.tv-app .chat-messages {
        /* Bỏ chiều cao cố định của ai-agent.css để nhường chỗ cho ô nhập */
        height: auto;
        flex: 1 1 auto;
        min-height: 120px;
    }

    body.tv-app .chat-input-area {
        flex: 0 0 auto;
    }
}

/* ==========================================================================
   20. DÒNG MIỄN TRỪ Ở FOOTER (js/app-shell.js bơm vào mọi trang chưa có)
   ========================================================================== */

body.tv-app .tv-disclaimer {
    max-width: 900px;
    margin: var(--tv-space-3) auto 0;
    padding-top: var(--tv-space-3);
    border-top: 1px solid var(--tv-border);
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--tv-muted);
    text-align: center;
}

/* ==========================================================================
   21. PHIÊN CHAT CŨ trong sidebar (js/app-shell.js dựng)
   Nằm trong nhóm "Trợ lý AI", ngay dưới link "AI Agent Bát Tự".
   Hiện 3 phiên gần nhất; "Xem tất cả" mở rộng; ô tìm kiếm gọi server.
   ========================================================================== */

body.tv-app .tv-ai-history {
    margin: var(--tv-space-2) 0 0 var(--tv-space-3);
    padding-left: var(--tv-space-2);
    border-left: 2px solid var(--tv-border);
}

body.tv-app .tv-ai-history__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tv-space-1);
    margin-bottom: 4px;
}

body.tv-app .tv-ai-history__title {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--tv-muted);
}

body.tv-app .tv-ai-history__more {
    font-family: var(--tv-font-body);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--tv-accent-text);
    background: transparent;
    border: 0;
    padding: 2px 4px;
    border-radius: var(--tv-radius-sm);
    cursor: pointer;
    white-space: nowrap;
}

body.tv-app .tv-ai-history__more:hover {
    background: var(--tv-accent-soft);
}

body.tv-app .tv-ai-history__more[hidden] {
    display: none;
}

body.tv-app .tv-ai-history__search {
    width: 100%;
    font-family: var(--tv-font-body);
    font-size: 0.78rem;
    color: var(--tv-ink);
    background-color: var(--tv-surface);
    border: 1px solid var(--tv-border-strong);
    border-radius: var(--tv-radius-sm);
    padding: 6px 8px;
    margin-bottom: 4px;
}

body.tv-app .tv-ai-history__search[hidden] {
    display: none;
}

body.tv-app .tv-ai-history__list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Danh sách dài tự cuộn, không kéo dài sidebar vô hạn */
    max-height: 240px;
    overflow-y: auto;
}

body.tv-app .tv-ai-history__item {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 5px 7px;
    border-radius: var(--tv-radius-sm);
    border-left: 2px solid transparent;
    text-decoration: none;
}

body.tv-app .tv-ai-history__item:hover {
    background: var(--tv-surface-2);
}

body.tv-app .tv-ai-history__item.is-active {
    background: var(--tv-accent-soft);
    border-left-color: var(--tv-accent);
}

body.tv-app .tv-ai-history__item-title {
    font-size: 0.8rem;
    color: var(--tv-ink-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.tv-app .tv-ai-history__item.is-active .tv-ai-history__item-title {
    color: var(--tv-ink);
    font-weight: 600;
}

body.tv-app .tv-ai-history__item-meta {
    font-size: 0.68rem;
    color: var(--tv-muted);
}

body.tv-app .tv-ai-history__empty,
body.tv-app .tv-ai-history__loading {
    margin: 2px 0 0;
    font-size: 0.75rem;
    color: var(--tv-muted);
}

body.tv-app .tv-ai-history__empty[hidden] {
    display: none;
}

/* Khi sidebar thu gọn thì ẩn luôn khối này (chỉ còn icon) */
@media (min-width: 769px) {
    body.tv-app.tv-nav-collapsed .tv-ai-history {
        display: none;
    }
}

/* ==========================================================================
   22. GỢI Ý SẢN PHẨM TRÊN MOBILE — dải cuộn ngang, mỗi lần một sản phẩm
   --------------------------------------------------------------------------
   Mặc định (ai-agent.css:355) là grid `repeat(auto-fill, minmax(240px,1fr))`:
   trên màn 390px chỉ 1 cột nhưng danh sách vẫn cao dần theo số sản phẩm. Đổi
   sang dải ngang + scroll-snap để tiết kiệm diện tích: mỗi thẻ chiếm 90% bề
   ngang nên vừa hiện trọn 1 sản phẩm, vừa hé sản phẩm kế tiếp làm dấu hiệu
   "kéo sang phải để xem tiếp".
   ========================================================================== */

@media (max-width: 768px) {

    body.tv-app .product-list {
        display: flex;
        gap: 8px;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        /* Ẩn thanh cuộn cho gọn (vẫn vuốt được bình thường) */
        scrollbar-width: none;
        padding-bottom: 2px;
    }

    body.tv-app .product-list::-webkit-scrollbar {
        display: none;
    }

    body.tv-app .product-card {
        /* 90% → 1 sản phẩm trọn vẹn + hé sản phẩm kế tiếp */
        flex: 0 0 90%;
        max-width: 90%;
        scroll-snap-align: start;
        scroll-snap-stop: always;
        min-width: 0;
    }

    /* Nút đóng khối gợi ý nằm ở đầu khối, không cuộn theo dải */
    body.tv-app .product-slot-head {
        position: relative;
        z-index: 1;
    }
}

/* ==========================================================================
   23. IN ẤN
   ========================================================================== */

@media print {

    body.tv-app .sidebar,
    body.tv-app .header,
    body.tv-app .footer,
    body.tv-app .zalo-float,
    body.tv-app .page-stats {
        display: none !important;
    }

    body.tv-app .main-layout {
        margin-left: 0 !important;
    }
}
