/*
 * congcuseoai.com — CSS nền + component dùng chung.
 *
 * Nạp SAU design-tokens.css. Mọi biến bên dưới alias sang token mới (phase 01, 260904) — tên
 * biến CŨ (--bg, --fg, --muted, --line, --primary, --radius, --maxw...) giữ nguyên để ~180 rule
 * hiện có tự đổi giao diện mà không phải sửa từng dòng. KHÔNG viết cứng hex/px mới ở đây —
 * mọi giá trị mới phải tham chiếu var(--...) trong design-tokens.css.
 */

/* --muted/--line/--maxw KHÔNG khai báo lại ở đây — design-tokens.css đã dùng thẳng đúng tên
   này với giá trị đúng, khai báo lại bằng var(--muted) sẽ tạo vòng lặp tự tham chiếu (invalid). */
:root {
    --bg: var(--canvas);
    --fg: var(--ink);
    --primary: var(--brand);
    --primary-fg: var(--surface);
    --danger: var(--danger-fg);
    --radius: var(--r);
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font);
    font-size: var(--fs-base);
    line-height: 1.6;
}

h1, h2, h3, h4, h5, h6 { font-weight: 700; }

a { color: var(--brand-link); text-decoration: none; }
a:hover { color: var(--brand-darker); }

/* a11y (phase 10): lưới an toàn cho MỌI <a>/<button>/<summary> chưa có :focus-visible riêng
   (pager, tab-nav, legal-tab, breadcrumb, dash-shortcut, tile-add, post-nav-link...). Đặc hiệu
   thấp hơn .btn/.seg-item/.side-link:focus-visible (đã có riêng ở components.css/app-shell.css)
   nên không đè lên các rule đó — chỉ lấp chỗ trống cho phần tử KHÔNG mang class component nào. */
a:focus-visible, button:focus-visible, summary:focus-visible {
    outline: 2px solid var(--brand-dark); outline-offset: 2px;
}

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

.site-header { border-bottom: 1px solid var(--line); }
.header-inner { display: flex; align-items: center; gap: 24px; padding: 14px 0; flex-wrap: wrap; }
.brand { font-weight: 700; font-size: 1.05rem; text-decoration: none; color: var(--fg); }
/* flex-wrap (phase 10, a11y/responsive): 6 link trong .site-nav tràn ngang ở 390px nếu không
   bọc dòng — .header-inner đã flex-wrap nhưng đó chỉ bọc GIỮA .brand/.site-nav, không bọc CÁC
   LINK bên trong .site-nav. */
.site-nav { display: flex; gap: 18px; align-items: center; margin-left: auto; flex-wrap: wrap; }

.inline-form { display: inline; margin: 0; }
.hidden-form { display: none; }

a { color: var(--primary); }
nav a { text-decoration: none; color: var(--muted); }
nav a:hover { color: var(--fg); }

.credits {
    padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
    font-variant-numeric: tabular-nums; text-decoration: none; color: var(--fg);
}

/* .btn/.btn-primary/.btn-ghost/.btn-lg/.btn-soft/.btn-danger/.btn-small giờ ở components.css (phase 03) */

.hero { padding: 64px 0 40px; max-width: 720px; }
.hero h1 { font-size: 2.3rem; line-height: 1.25; margin: 0 0 16px; }
.lead { font-size: 1.1rem; color: var(--muted); }

/* Trang pháp lý (/dieu-khoan-su-dung, /chinh-sach-bao-mat) — 2 tab là <a> thật, không JS. */
.legal-tabs { display: flex; gap: 10px; margin: 40px auto 0; max-width: 760px; }
.legal-tab {
    padding: 9px 18px; border-radius: var(--r-md); font-weight: 700; font-size: var(--fs-sm);
    border: 1px solid var(--line); color: var(--ink-3); background: var(--surface);
}
.legal-tab.is-active { background: var(--brand); border-color: var(--brand); color: var(--surface); }
.legal-title { font-size: var(--fs-h1); font-weight: 800; letter-spacing: -0.02em; margin: 32px 0 8px; }
.legal-updated { font-size: var(--fs-sm); color: var(--muted-2); margin: 0 0 32px; max-width: 760px; }

.error-page { padding: 80px 0; text-align: center; }
.error-code { font-size: 4rem; font-weight: 700; color: var(--muted); margin: 0; line-height: 1; }
.error-page h1 { margin: 8px 0 12px; }

.debug-box {
    margin-top: 32px; text-align: left; background: var(--surface-dark); color: var(--on-dark);
    padding: 16px; border-radius: var(--radius); overflow: auto;
}
.debug-box pre { font-size: 0.78rem; white-space: pre-wrap; word-break: break-word; }

/* .app-main giờ định nghĩa ở app-shell.css (phase 02, shell sidebar riêng cho /app/*, /admin/*) */

/* Footer công khai (4 cột, dùng chung mọi trang qua layouts/main.php) */
.site-footer { background: var(--surface-dark); color: var(--on-dark); }
.footer-grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: var(--sp-8); padding: var(--sp-12) 20px var(--sp-6); }
.footer-col h3 { font-weight: 700; color: var(--surface); font-size: var(--fs-md); margin: 0 0 var(--sp-4); }
.footer-col a { display: block; color: var(--on-dark); font-size: var(--fs-md); margin-bottom: 10px; }
.footer-col a:hover { color: var(--surface); }
.footer-brand .brand-dark { color: var(--surface); font-weight: 800; font-size: var(--fs-title); margin-bottom: 14px; display: inline-block; }
.footer-brand p { font-size: var(--fs-md); line-height: 1.6; margin: 0; max-width: 260px; color: var(--on-dark); }
.footer-bottom {
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px;
    padding: var(--sp-5) 20px; border-top: 1px solid #3A3D2F; font-size: var(--fs-sm);
}

@media (max-width: 720px) {
    .footer-grid { grid-template-columns: 1fr 1fr; }
}

/* ── Đăng nhập (màn hình chia đôi, `layouts/auth.php` + `auth/login.php`) ────────────────── */
.auth-split { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; background: var(--canvas); }
.auth-col { display: flex; flex-direction: column; justify-content: center; padding: 0 64px; }
.auth-col-inner { max-width: 380px; }
.auth-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 44px; }
.auth-brand-mark {
    width: 34px; height: 34px; border-radius: var(--r-sm); background: var(--brand-grad);
    display: flex; align-items: center; justify-content: center; color: var(--surface);
    font-weight: 800; font-size: var(--fs-title);
}
.auth-brand-name { font-weight: 800; font-size: var(--fs-title); color: var(--ink); }
.auth-col h1 { font-size: var(--fs-h1); font-weight: 800; letter-spacing: -0.02em; margin: 0 0 10px; }
.auth-col .lead { font-size: var(--fs-lg); color: var(--muted); margin: 0 0 30px; }

.btn-google {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
    padding: 13px; font-weight: 600; font-size: var(--fs-md); color: var(--ink);
}
.btn-google:hover { border-color: var(--brand); color: var(--ink); }

.fine-print { font-size: var(--fs-sm); color: var(--muted); text-align: center; margin-top: 22px; }

.auth-quote-panel {
    background: linear-gradient(135deg, var(--brand-darker), var(--brand-dark));
    display: flex; align-items: center; justify-content: center; padding: 60px;
}
.auth-quote { max-width: 380px; color: var(--surface); }
.auth-quote-text { font-size: var(--fs-lg); line-height: 1.7; margin-bottom: 24px; }
.auth-quote-author { display: flex; align-items: center; gap: 12px; }
.auth-quote-avatar { width: 38px; height: 38px; border-radius: 50%; background: rgba(255, 255, 255, .2); }
.auth-quote-name { font-weight: 700; font-size: var(--fs-md); }
.auth-quote-role { font-size: var(--fs-sm); color: var(--on-dark); }

@media (max-width: 860px) {
    .auth-split { grid-template-columns: 1fr; }
    .auth-quote-panel { display: none; }
    .auth-col { padding: 48px 24px; }
}

/* .alert/.alert-warning/.alert-danger/.alert-ok giờ ở components.css (phase 03) */
/* .notice — xoá (phase 10, 260908): 0 kết quả grep app/Views + public/assets/js, class không
   còn view nào dùng (rơi rớt từ trước phase 01, không phải class API của JS). */

/* ── Quản trị ──────────────────────────────────────────────────────────────── */
.muted { color: var(--muted); }
/* .btn-danger/.stat-grid/.stat/.stat-num giờ ở components.css (phase 03) */

/* Kết quả gom cụm (/app/cum-chu-de, phase 14) — mỗi cụm một khối, bảng con bên trong dùng lại
   .table-scroll/.data-table đã có sẵn ở dưới. */
.cluster-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin-bottom: 14px; }
.cluster-card-head { display: flex; gap: 10px; align-items: center; cursor: pointer; margin-bottom: 6px; }
.cluster-card-head input[type="checkbox"] { width: 16px; height: 16px; flex-shrink: 0; }

.search-form { display: flex; gap: 8px; margin: 16px 0 24px; }
.search-form input { flex: 1; max-width: 340px; padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }

/* .table-scroll/.data-table/.tag/.tag-ok/.tag-bad/.tag-admin giờ ở components.css (phase 03) */

.pager { display: flex; gap: 16px; align-items: center; margin-top: 18px; }

.detail-list { display: grid; grid-template-columns: max-content 1fr; gap: 6px 20px; margin: 18px 0 26px; }
.detail-list dt { color: var(--muted); }
.detail-list dd { margin: 0; }

.action-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }

/* ── Credit & bảng giá ─────────────────────────────────────────────────────── */
.amount-in  { color: var(--ok-fg); }
.amount-out { color: var(--danger); }
.margin-bad { color: var(--danger); font-weight: 700; }

.preset-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin: 16px 0 24px; }
.preset { display: block; border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; cursor: pointer; }
.preset:has(input:checked) { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary) inset; }
.preset-amount { display: block; font-weight: 700; font-size: 1.1rem; }
.preset-credits { display: block; color: var(--muted); font-size: 0.88rem; }

fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; }
fieldset[disabled] { opacity: 0.55; }
legend { padding: 0 6px; color: var(--muted); font-size: 0.9rem; }

/* input.cell-input/textarea.cell-input (không phải .cell-input suông): components.css có rule
   chung `input[type="text"], input[type="number"]...textarea` đặc hiệu (0,1,1) > class suông
   (0,1,0) — nếu để suông thì dù style.css nạp sau vẫn thua vì đặc hiệu tính trước thứ tự nguồn.
   Thêm hậu tố phần tử (cả input lẫn textarea — .cell-input dùng cho cả hai, xem search-providers.php/
   ai-providers.php) để hoà đặc hiệu, lúc đó thứ tự nạp (style.css sau cùng) mới thắng đúng ý đồ ban đầu. */
input.cell-input, textarea.cell-input { width: 96px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); color: var(--fg); font: inherit; }
td input.cell-input[type="text"] { width: 180px; }

.new-pair { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.new-pair input { padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }
.new-pair legend { width: 100%; }

.adjust-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 12px 0 4px; }
.adjust-form input { padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }
.adjust-form input[type="text"] { min-width: 260px; }

.pager a.active { font-weight: 700; color: var(--fg); }

.redirect-box { padding: 80px 0; text-align: center; }

/* Hang doi job — .progress-bar giờ ở components.css (phase 03) */
.status-chips { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0; }

.status-pending { opacity: 0.75; }
.status-running { border-color: var(--primary); }
.status-failed  { color: var(--danger); border-color: var(--danger); }

.job-detail-row > td { padding-top: 0; border-top: 0; }
.job-detail-row summary { cursor: pointer; font-size: 0.88rem; }
.job-error { color: var(--danger); }
.job-detail-row pre {
    white-space: pre-wrap; word-break: break-word; margin: 6px 0 0;
    padding: 10px; border-radius: var(--radius); background: var(--line);
    font-size: 0.82rem; max-height: 260px; overflow: auto;
}

.note-list { margin: 0 0 20px; padding-left: 20px; }
.note-list li { margin-bottom: 5px; }

/* Nghien cuu SERP */
.research-block {
    white-space: pre-wrap; word-break: break-word; margin: 8px 0 20px;
    padding: 14px; border-radius: var(--radius); border: 1px solid var(--line);
    background: var(--line); font-size: 0.85rem; max-height: 420px; overflow: auto;
}
.job-track { margin: 16px 0; max-width: 480px; }
.job-track .progress-bar { margin-bottom: 6px; }

/* Du an & ho so viet bai */
.tab-nav { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--line); margin: 20px 0 24px; }
.tab-nav a { padding: 9px 16px; border: 1px solid transparent; border-bottom: 0; border-radius: var(--radius) var(--radius) 0 0; color: var(--muted); text-decoration: none; margin-bottom: -1px; }
.tab-nav a:hover { color: var(--fg); }
.tab-nav a.active { border-color: var(--line); background: var(--bg); color: var(--fg); font-weight: 600; }

/* .field/.required giờ ở components.css (phase 03) — chỉ giữ hành vi riêng chưa có ở đó */
.stack-form { max-width: 680px; }
.field textarea { resize: vertical; }

/* .field-grid — modifier cho form "cài đặt nhiều trường độc lập" (hồ sơ dự án, hồ sơ viết bài,
   form sinh ảnh AI): 680px cố định của .stack-form khiến trang trống hẳn nửa bên phải trên
   desktop rộng (phát hiện qua phản hồi thực tế 260908, không phải từ mockup). CHỈ gắn class này
   cho form thật sự gồm nhiều field ĐỘC LẬP hoặc từng CẶP field độc lập với nhau (không liên quan
   tuần tự) — các form công cụ nhanh 1-2 trường (lọc từ khoá, tra cứu SERP...) vẫn dùng .stack-form
   suông, giữ nguyên cột hẹp. `margin:auto` để tự căn giữa trong `.app-main` (không có max-width)
   thay vì dính sát lề trái — cùng áp dụng khi form dài hơn 1040px hay ngắn hơn.
   Field chứa textarea/nhóm toggle/toggle đơn/tiêu đề phụ/đoạn giới thiệu/khối <div> không phải
   .field (thanh tiến trình job...) đều trải hết 2 cột để không bị cắt vụn hay xén nửa — dùng
   :has()/:not() để tự nhận diện, không cần thêm class thủ công cho từng phần tử con. */
@media (min-width: 900px) {
    .field-grid {
        max-width: 1040px;
        margin: 0 auto;
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 0 28px;
        align-items: start;
    }
    .field-grid > .field:has(textarea),
    .field-grid > .toggle-group,
    .field-grid > .toggle,
    .field-grid > div:not(.field),
    .field-grid > h3,
    .field-grid > p {
        grid-column: 1 / -1;
    }
}

.toggle-group { display: grid; gap: 12px; margin-bottom: 20px; }
.toggle { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.toggle input { margin-top: 3px; }

.swatches { display: inline-flex; gap: 6px; margin-top: 8px; }
.swatch { width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--line); display: inline-block; }

/* .row-active — xoá (phase 10, 260908): 0 kết quả grep app/Views + public/assets/js; màu
   rgba(37,99,235,...) còn sót từ bảng màu xanh cũ trước phase 01, không khớp token mới. */

.adjust-form select, .new-pair select {
    padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--bg); color: var(--fg); font: inherit;
}

/* .write-layout/.write-sidebar (phase 08) — xoá (260908): sidebar "Bài gần đây" dời sang trang
   riêng /app/bai-viet, /app/viet-bai giờ chỉ còn 1 cột .write-main (xem style bên dưới). */

.ctx-lights { display: flex; gap: 14px; margin: 10px 0 6px; flex-wrap: wrap; }
.ctx-light {
    display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--muted);
}
.ctx-light::before {
    content: ""; width: 9px; height: 9px; border-radius: 999px; background: var(--line); display: inline-block;
}
.ctx-light.is-on { color: var(--fg); }
.ctx-light.is-on::before { background: var(--ok-fg); }

.outline-item {
    border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 12px;
    display: flex; flex-direction: column; gap: 8px; background: var(--bg);
}
.outline-item--h3 { margin-left: 24px; border-style: dashed; }
.outline-children { margin-top: 6px; }
.outline-drag-handle { cursor: grab; color: var(--muted); user-select: none; }
.outline-field input { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }
.outline-item textarea { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; resize: vertical; }
/* input.outline-word-estimate: cùng lý do đặc hiệu như .cell-input ở trên — phần tử do
   outline-editor.js tạo bằng document.createElement('input') nên luôn là <input>. */
input.outline-word-estimate { width: 100px; padding: 6px 8px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }
.outline-item-actions { display: flex; gap: 8px; justify-content: flex-end; }
.outline-intro { border: 1px dashed var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 16px; }
.outline-intro textarea { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }

.editor-body {
    min-height: 420px; border: 1px solid var(--line); border-radius: var(--radius); padding: 18px;
    background: var(--bg); line-height: 1.7;
}
.editor-body:focus { outline: 2px solid var(--primary); outline-offset: 2px; }
.editor-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }

.lint-findings { margin: 10px 0 0; padding-left: 20px; }
.lint-findings li { margin-bottom: 4px; font-size: 0.9rem; }
.lint-clean { color: var(--ok-fg); font-size: 0.9rem; }

.link-candidate-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.link-candidate-row span { flex: 0 0 220px; font-size: 0.9rem; }
/* input.link-candidate-url: cùng lý do đặc hiệu — phần tử do editor.js tạo luôn là <input type=url>. */
input.link-candidate-url { flex: 1; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: inherit; }

.model-remain { color: var(--muted); font-size: 0.82rem; }

/* Tao anh AI (phase 09) */
.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin: 16px 0 28px; }
.image-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px; background: var(--bg); }
.image-card img { width: 100%; height: 150px; object-fit: cover; border-radius: 6px; background: var(--line); display: block; }
.image-card-prompt { font-size: 0.82rem; color: var(--muted); margin: 8px 0; max-height: 3.2em; overflow: hidden; }
.image-card-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.image-empty { color: var(--muted); }

.storage-bar { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; max-width: 320px; margin: 6px 0; }
.storage-bar > span { display: block; height: 100%; background: var(--primary); transition: width 0.4s ease; }
.storage-bar.is-near-full > span { background: var(--danger); }

/* Blog & trang marketing (phase 12) */
.breadcrumb { font-size: 0.88rem; color: var(--muted); margin: 20px 0 0; }
.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--fg); }

.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 24px; margin: 24px 0 8px; }
.blog-card { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--bg); display: flex; flex-direction: column; }
.blog-card-thumb { display: block; aspect-ratio: 16 / 9; background: var(--line); }
.blog-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-thumb--empty { background: linear-gradient(135deg, var(--line), var(--bg)); }
.blog-card-body { padding: 16px; }
.blog-card-date { display: block; font-size: 0.8rem; color: var(--muted); margin-bottom: 6px; }
.blog-card-title { font-size: 1.05rem; margin: 0 0 8px; line-height: 1.35; }
.blog-card-title a { color: var(--fg); text-decoration: none; }
.blog-card-title a:hover { color: var(--primary); }
.blog-card-excerpt {
    margin: 0; color: var(--muted); font-size: 0.9rem;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

.post { max-width: 760px; margin: 24px auto 0; }
.post-header h1 { font-size: 2rem; line-height: 1.3; margin: 12px 0 10px; }
.post-meta { color: var(--muted); font-size: 0.9rem; margin: 0 0 12px; }
.tag-chip-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 8px; }
.tag-chip-list .tag { text-decoration: none; color: var(--fg); }
.tag-chip-list .tag:hover { border-color: var(--primary); color: var(--primary); }

/* Typography cho nội dung đã qua HtmlSanitizer — phải hỗ trợ đúng tập thẻ trong
   HtmlSanitizer::ALLOWED (p/br/strong/b/em/i/u/s/h2-h4/ul/ol/li/blockquote/a/img/code/pre/
   figure/figcaption/table+thead+tbody+tr+th+td/hr). */
.post-body { max-width: 760px; margin: 20px auto 0; line-height: 1.75; font-size: 1.02rem; }
.post-body h2 { font-size: 1.5rem; margin: 36px 0 14px; }
.post-body h3 { font-size: 1.25rem; margin: 28px 0 12px; }
.post-body h4 { font-size: 1.08rem; margin: 22px 0 10px; }
.post-body p { margin: 0 0 16px; }
.post-body ul, .post-body ol { margin: 0 0 16px; padding-left: 24px; }
.post-body li { margin-bottom: 6px; }
.post-body blockquote {
    margin: 0 0 16px; padding: 4px 18px; border-left: 3px solid var(--primary);
    color: var(--muted); font-style: italic;
}
.post-body a { color: var(--primary); }
.post-body img { max-width: 100%; height: auto; border-radius: var(--radius); display: block; margin: 8px auto; }
.post-body figure { margin: 0 0 16px; }
.post-body figcaption { text-align: center; font-size: 0.85rem; color: var(--muted); margin-top: 6px; }
.post-body code {
    background: var(--line); border-radius: 4px; padding: 2px 6px; font-size: 0.88em;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.post-body pre {
    background: var(--line); border-radius: var(--radius); padding: 14px; overflow-x: auto; margin: 0 0 16px;
}
.post-body pre code { background: none; padding: 0; }
.post-body hr { border: 0; border-top: 1px solid var(--line); margin: 28px 0; }
/* table không có class .data-table (nội dung tự do do admin nhập) — display:block cho phép
   cuộn ngang trên chính thẻ table, không cần bọc thêm div wrapper. */
.post-body table { display: block; overflow-x: auto; border-collapse: collapse; width: 100%; margin: 0 0 16px; font-size: 0.92rem; }
.post-body th, .post-body td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; }
.post-body th { background: var(--line); font-weight: 600; }

.post-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 760px; margin: 32px auto 0; }
.post-nav-link { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; text-decoration: none; color: var(--fg); font-size: 0.92rem; }
.post-nav-link:hover { border-color: var(--primary); }
.post-nav-next { text-align: right; grid-column: 2; }

.related-posts { max-width: 760px; margin: 48px auto 0; }
.related-posts h2 { font-size: 1.3rem; }

/* Admin blog */
.stack-form.blog-form { max-width: 860px; }
/* ≥960px: 2 thẻ .card con (Nội dung + Thiết lập & SEO) đang xếp dọc trong khung 860px khiến
   desktop rộng chỉ dùng hết ~1/2 bề ngang trang (phản hồi thực tế 260908). Xếp 2 cột — nội dung
   chiếm phần rộng hơn (bài viết dài), thiết lập/SEO cột hẹp bên phải — không cần sửa view vì 2
   .card này đã là anh em trực tiếp trong <form>. Nút Lưu (<p>) trải hết bề ngang ở hàng cuối. */
@media (min-width: 960px) {
    .stack-form.blog-form {
        max-width: 1220px;
        display: grid;
        grid-template-columns: 1.6fr 1fr;
        gap: 0 24px;
        align-items: start;
    }
    .stack-form.blog-form > p { grid-column: 1 / -1; }
}
.og-preview { display: block; margin-top: 10px; max-width: 240px; max-height: 140px; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--line); }
/* input.media-url-input (không phải .media-url-input suông): components.css có rule chung
   `input[type="text"]...` đặc hiệu (0,0,1,1) > class suông (0,0,1,0) — nếu để suông thì
   `input.cell-input` (cũng 0,0,1,1, cùng thẻ này, xem blog-media.php) đè width xuống 96px bất kể
   `.media-url-input` nạp sau. Thêm hậu tố `input` để hoà đặc hiệu với `.cell-input` đi kèm trên
   cùng input, lúc đó thứ tự nguồn (đứng sau trong cùng file) mới thắng đúng ý đồ 100%. Lỗi có từ
   trước phase 09, phát hiện bởi code-reviewer khi review phase 06/07/09 (260905), sửa tại đây vì
   thấp rủi ro (chỉ 1 nơi dùng, trong `.image-card` của blog-media.php). */
input.media-url-input { width: 100%; font-size: 0.78rem; margin: 8px 0; }

/* === Dashboard, dự án, hồ sơ (phase 06, 260905) ===
   Lưới thẻ + nút hành động đầu trang cho /app, /app/du-an, /app/ho-so-viet. Chỉ dùng lại token
   + component đã có (.card/.tag/.btn/.tile-add) — các class dưới đây thuần layout/spacing. */

/* Nút hành động đầu nội dung — thay cho $topbarSlot không gán được từ view (xem dashboard.php,
   projects/index.php: view() render nội dung TRƯỚC layout). */
.page-actions { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); margin-bottom: var(--sp-3); flex-wrap: wrap; }
.page-actions h1 { margin: 0; }

/* Bảng điều khiển (/app) */
.dash-shortcuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-4); margin: var(--sp-5) 0 var(--sp-6); }
.dash-shortcut { display: flex; flex-direction: column; gap: 6px; color: inherit; }
.dash-shortcut:hover { border-color: var(--brand); }
.dash-shortcut svg { color: var(--brand-link); }
.dash-shortcut-title { font-weight: 700; font-size: var(--fs-lg); color: var(--ink); }
.dash-panels { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--sp-5); }
.dash-steps { margin: 0; padding-left: 20px; }
.dash-steps li { margin-bottom: 10px; }
.dash-balance { font-size: var(--fs-h2); font-weight: 800; margin: 4px 0 16px; }
@media (max-width: 860px) { .dash-panels { grid-template-columns: 1fr; } }

/* Dự án (/app/du-an) */
.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; margin-top: var(--sp-4); }
.project-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.project-avatar {
    width: 40px; height: 40px; border-radius: var(--r); background: var(--tint); color: var(--brand-link);
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: var(--fs-lg); flex-shrink: 0;
}
.project-card-info { min-width: 0; flex: 1; }
.project-card-name { display: block; font-weight: 700; font-size: var(--fs-lg); color: var(--ink); }
.project-card-domain { display: block; font-size: var(--fs-sm); }
.project-card-niche { font-size: var(--fs-sm); margin: 0 0 14px; }
.project-card-actions { display: flex; gap: 10px; padding-top: 14px; border-top: 1px solid var(--line-softer); }
.project-card-actions .btn, .project-card-actions form { flex: 1; }
.project-card-actions form .btn { width: 100%; }

/* Ô "+ Tạo dự án mới" bằng <details> thuần HTML — summary dùng lại .tile-add, không cần JS
   để đóng/mở; trình duyệt tự cuộn + mở khi có link fragment #tao-du-an trỏ tới (dashboard 06). */
.inline-create summary { list-style: none; }
.inline-create summary::-webkit-details-marker { display: none; }
.inline-create[open] summary { margin-bottom: 16px; }
.inline-create form { max-width: 420px; }

/* Hồ sơ viết bài (/app/ho-so-viet) */
.profile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; margin-top: var(--sp-4); }
.profile-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
.profile-card-name { display: block; font-weight: 700; font-size: var(--fs-lg); color: var(--ink); }
.profile-card-project { display: block; font-size: var(--fs-sm); margin-top: 2px; }
.profile-card-meta { font-size: var(--fs-sm); margin: 0 0 16px; }
.profile-card-actions { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 14px; border-top: 1px solid var(--line-softer); }
.profile-card-actions .btn, .profile-card-actions form { flex: 1; min-width: 90px; }
.profile-card-actions form .btn { width: 100%; }

/* === Công cụ nghiên cứu (phase 07, 260905) ===
   3 bố cục đặc thù + 1 lưới thẻ cho 5 trang JS/fetch-driven (tu-khoa, nghien-cuu, cum-chu-de,
   y-dinh-tim-kiem, kiem-tra-geo). Chỉ layout/spacing — màu sắc/badge/nút dùng lại token +
   component đã có (.card/.tag/.btn/.empty-state/.progress-bar). KHÔNG đụng CSS của
   .cluster-card/.job-track/.status-chips/.model-remain (đã có sẵn ở trên/components.css). */

/* SERP chi tiết (/app/nghien-cuu/{id}): cột chính + card "Gợi ý từ đối thủ" bên phải. */
.research-layout { display: grid; grid-template-columns: 1fr 300px; gap: var(--sp-6); align-items: start; }
.research-side { position: sticky; top: var(--sp-5); }

/* GEO Audit (/app/kiem-tra-geo): cột hạng mục kiểm tra (tĩnh) + form/kết quả. */
.geo-layout { display: grid; grid-template-columns: 220px 1fr; gap: var(--sp-6); align-items: start; }
.geo-side { position: sticky; top: var(--sp-5); }
.geo-checklist { margin: 0; padding-left: 20px; color: var(--muted); font-size: var(--fs-sm); }
.geo-checklist li { margin-bottom: 10px; }

@media (max-width: 900px) {
    .research-layout, .geo-layout { grid-template-columns: 1fr; }
    .research-side, .geo-side { position: static; }
}

/* Cụm chủ đề (/app/cum-chu-de): lưới 3 cột thẻ .cluster-card (class đã có, style.css ~156) —
   topic-cluster.js/search-intent.js tự tạo .cluster-card bằng document.createElement, chỉ đổi
   layout của vùng chứa cha, không đụng chính thẻ. */
.cluster-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--sp-4); }
.cluster-grid .cluster-card { margin-bottom: 0; }

/* Search intent (/app/y-dinh-tim-kiem): bảng cột tỉ lệ theo <colgroup> (đặt trực tiếp trong view
   vì mỗi bảng có số cột khác nhau) — chỉ cần table-layout:fixed để % width có tác dụng. */
.intent-table { table-layout: fixed; }
.intent-table tbody td { white-space: normal; word-break: break-word; }

/* === Công cụ sản xuất (phase 08, 260905) ===
   Viết bài AI (/app/viet-bai), Thư viện ảnh (/app/thu-vien-anh), Đăng WordPress (/app/dang-bai) —
   3 trang JS/fetch-driven nặng nhất hệ thống. CHỈ ghi đè màu/bo góc/khoảng cách bằng token mới
   (--surface/--r-lg/--r-md/--sp-*) cho các selector ĐÃ CÓ ở mục "Viet bai AI (phase 08)"/"Tao anh
   AI (phase 09)" phía trên (không xoá/sửa ở đó — cùng độ đặc hiệu, đứng sau trong file nên thắng).
   `.lint-findings`/`.lint-clean`/`.image-empty` là class DO editor.js/image-gallery.js TỰ TẠO
   bằng chuỗi HTML cứng — không đổi tên được (sửa .js ngoài phạm vi phase này), nên chỉ đổi màu
   cho trông giống `.alert--warn`/`.alert--ok`/`.empty-state` qua CSS, không đụng tên class. */

/* Khung /app/viet-bai: 1 cột .write-main (dải bước, tóm tắt chi phí, panel bước). */
/* > * + * (không phải mọi phần tử lồng sâu): mỗi partial bước (keyword-form/outline-panel/
   editor-panel) render_partial() ra NHIỀU phần tử anh em cấp cao nhất (h1, p, .card, script) —
   bọc riêng trong .write-step ở index.php để margin dưới đây chỉ tính giữa 3 khối lớn
   (.seg, .cost-summary, .write-step), không chèn thêm khoảng trắng giữa h1 và đoạn giới thiệu
   của chính bước đó (đã có margin mặc định của trình duyệt lo phần đó). */
.write-main > * + * { margin-top: var(--sp-5); }

/* .write-recent* (sidebar "Bài gần đây") — xoá (260908): dời sang bảng .data-table riêng ở
   /app/bai-viet (app/Views/app/write/list.php), dùng lại .tag--ok/.tag--neutral/.tag--danger
   có sẵn thay vì tự định nghĩa class trạng thái mới. */

/* Panel "Tóm tắt chi phí" (cost-summary.php, MỚI) — số liệu thật từ $writeOptions/$imageGenerateOptions. */
.cost-summary-list { display: grid; gap: var(--sp-2); margin: var(--sp-3) 0; }
.cost-summary-row { display: flex; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-md); }
.cost-summary-row dt { margin: 0; color: var(--ink-3); font-weight: 600; }
.cost-summary-row dd { margin: 0; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.cost-summary-note { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); }

/* Đề cương + ô soạn thảo: bo góc/nền theo token mới thay cho --radius/--bg cũ (alias cùng giá
   trị nhưng --r-lg/--surface khớp đúng ngôn ngữ thị giác của .card trong mockup). */
.outline-item, .outline-intro { background: var(--surface); border-radius: var(--r-md); }
.editor-body { background: var(--surface); border-radius: var(--r-lg); font-size: var(--fs-lg); }
.editor-body h2 { font-size: 1.4rem; margin: 28px 0 12px; }
.editor-body h3 { font-size: 1.15rem; margin: 22px 0 10px; }
.editor-body p { margin: 0 0 14px; }
.editor-body ul, .editor-body ol { margin: 0 0 14px; padding-left: 22px; }
.editor-body blockquote { margin: 0 0 14px; padding: 4px 16px; border-left: 3px solid var(--brand); color: var(--muted); font-style: italic; }
.editor-body img { max-width: 100%; height: auto; border-radius: var(--r-md); display: block; margin: 8px auto; }

/* .lint-findings/.lint-clean: chuỗi HTML cứng từ editor.js::renderLint(), xem đầu mục này. */
.lint-findings { background: var(--warn-bg); color: var(--warn-fg); border-radius: var(--r); padding: 12px 16px; list-style: none; }
.lint-findings li { margin-bottom: 4px; }
.lint-clean { display: inline-block; background: var(--ok-bg); color: var(--ok-fg); border-radius: var(--r); padding: 8px 14px; }

/* /app/thu-vien-anh: lưới 4 cột + thẻ ảnh bo tròn hơn + cắt prompt còn 2 dòng. */
.image-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.image-card { background: var(--surface); border-radius: var(--r-md); }
.image-card-prompt { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; max-height: none; }
/* .image-empty: chuỗi HTML cứng từ image-gallery.js::renderGrid(), xem đầu mục này. */
.image-empty { padding: 48px 24px; text-align: center; color: var(--muted); }

/* /app/dang-bai: 2 cột (chọn bài / cấu hình đăng). */
.wp-columns { display: grid; grid-template-columns: 1fr 1.3fr; gap: var(--sp-5); align-items: start; }

@media (max-width: 900px) {
    .wp-columns { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
    .image-grid { grid-template-columns: repeat(2, 1fr); }
}
