/* Hội Doanh nghiệp Hạnh Thông — one stylesheet, no build step.
 *
 * There is no framework here on purpose: the whole site is server-rendered
 * HTML, and a 9 KB stylesheet that a volunteer editor can read beats a
 * toolchain somebody has to maintain to change a colour.
 *
 * Type starts at 16px, controls are at least 44px tall, and every interactive
 * element has a visible focus ring — the association's members will read this
 * on a phone, and some of them with the text size turned up. */

:root {
    /* Logo do Hội cung cấp: xanh #1d7fa9, đỏ #df221f, vàng #debe27.
       Các sắc đậm dành cho chữ và nút giữ tương phản tối thiểu 4.5:1. */
    --brand-blue: #1d7fa9;
    --brand-red: #df221f;
    --brand-gold: #debe27;
    --brand-indigo: #264185;

    --navy-900: #10465e;
    --navy-800: #126583;
    --navy-700: #147b9c;
    --navy-600: #1d7fa9;
    --navy-100: #dceff5;
    --navy-050: #f0f8fb;

    --accent-600: #c91e19;
    --accent-500: #df221f;
    --accent-100: #fce9e8;
    --accent-text: #9b1511;

    /* Vàng của logo chỉ làm điểm nhấn; chữ trên nền vàng dùng sắc nâu đậm. */
    --gold-500: #debe27;
    --gold-100: #fbf1d0;
    --gold-text: #765e00;

    --green-700: #16653c;
    --green-100: #e3f5ea;
    --red-700: #a52121;     /* đỏ **cảnh báo**, trầm hơn đỏ logo */
    --red-100: #fbe9e9;
    --ink-900: #16202b;
    --ink-700: #37485b;
    --ink-500: #607385;
    --line: #d5e3ec;
    --paper: #ffffff;
    --shell: #f6fafc;
    --radius: 10px;
    --radius-sm: 6px;
    --shadow-sm: 0 1px 2px rgba(8, 47, 69, .07), 0 1px 8px rgba(8, 47, 69, .05);
    --shadow-md: 0 2px 6px rgba(8, 47, 69, .08), 0 12px 28px rgba(8, 47, 69, .07);
    /* Phông hệ thống, **không** tải phông từ máy chủ ngoài: một tệp phông từ
       Google Fonts là một lần trình duyệt người đọc gọi sang máy chủ bên thứ
       ba — cùng lý do đã không nhúng video YouTube trực tiếp.

       "Inter" đứng đầu danh sách nhưng dự án **không tự lưu trữ** nó, nên nó
       chỉ có tác dụng với người đã cài sẵn. Giữ lại vì vô hại và có lợi cho số
       ít đó; phần còn lại rơi xuống phông hệ thống, vốn có đủ dấu tiếng Việt
       trên mọi nền tảng còn được hỗ trợ.

       Phông chữ trên logo là một bộ chữ **in đậm, hơi hẹp**; không nhận dạng
       được chính xác từ ảnh raster nên không bịa ra một cái tên ở đây. Muốn
       khớp đúng thì cần chính tệp phông — xem ghi chú ở #19803. */
    --font: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.6;
    color: var(--ink-900);
    background: var(--shell);
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 { line-height: 1.25; margin: 0 0 .5em; color: var(--navy-900); font-weight: 650; }
h1 { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.3rem); }
h2 { font-size: clamp(1.3rem, 1.1rem + .8vw, 1.65rem); }
h3 { font-size: 1.12rem; }
p { margin: 0 0 1em; }
a { color: var(--navy-700); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--navy-800); }
img { max-width: 100%; height: auto; }

:is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 3px solid var(--accent-500);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Nhãn chỉ dành cho trình đọc màn hình: không ai nhìn thấy, nhưng ô nhập vẫn
   có tên khi được đọc lên. */
.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;
}

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--navy-900); color: #fff; padding: .75rem 1rem;
}
.skip-link:focus { left: 0; }

.wrap { width: min(1180px, 100% - 2rem); margin-inline: auto; }
.stack > * + * { margin-top: 1rem; }

/* ---------------------------------------------------------------- banner */
.env-banner {
    background: var(--gold-100);
    border-bottom: 1px solid #f0d6ae;
    color: #6b3b00;
    font-size: .875rem;
    padding: .5rem 0;
}
.env-banner strong { color: #6b3b00; }

/* ---------------------------------------------------------------- header */
.site-header { background: var(--paper); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 30; }
.header-inner { display: flex; align-items: center; gap: 1rem; min-height: 72px; }
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--navy-900); }
.brand img { height: 44px; width: auto; }
.brand-mark {
    width: 44px; height: 44px; border-radius: 10px; flex: none;
    background: linear-gradient(145deg, var(--navy-700), var(--navy-900));
    color: #fff; display: grid; place-items: center; font-weight: 700; letter-spacing: .02em;
}
.brand-name { font-weight: 700; font-size: 1.02rem; line-height: 1.2; white-space: nowrap; }
.brand-sub { font-size: .76rem; color: var(--ink-500); letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }

.nav-toggle { display: none; }
.nav-toggle-label {
    display: none; margin-left: auto; align-items: center; gap: .5rem;
    min-height: 44px; padding: 0 .9rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); cursor: pointer; font-weight: 600;
}
.site-nav { margin-left: auto; display: flex; align-items: center; gap: .75rem; }
.nav-list { display: flex; align-items: center; gap: .15rem; list-style: none; margin: 0; padding: 0; }
.nav-item { position: relative; }
.nav-item > a {
    padding: .55rem .7rem; border-radius: var(--radius-sm); text-decoration: none;
    color: var(--ink-700); font-weight: 550; font-size: .95rem; display: inline-flex;
    align-items: center; gap: .3rem; min-height: 44px; white-space: nowrap;
}
.nav-item > a:hover { background: var(--navy-050); color: var(--navy-800); }
/* "page" = trang đang xem; "true" = nhánh đang mở (mục cha của trang đang
   xem). Cả hai đều cần sáng lên, vì mục con nằm trong menu thả xuống đang đóng
   — nếu chỉ tô "page" thì ở /tin-tuc/ không có gì sáng trên thanh menu. */
.nav-item > a[aria-current] { color: var(--navy-900); background: var(--navy-100); }
.nav-sub a[aria-current="page"] { font-weight: 600; background: var(--navy-100); }

/* Mũi tên chỉ ra mục có menu con. Vẽ bằng CSS nên không thêm ảnh hay phông. */
.has-sub > a::after {
    content: ""; width: .4em; height: .4em; margin-top: -.25em;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(45deg); opacity: .6; flex: none;
}

.nav-sub {
    position: absolute; top: 100%; left: 0; z-index: 40;
    display: none; min-width: 15rem; margin: 0; padding: .35rem;
    list-style: none; background: var(--paper);
    border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
/* Mở bằng chuột và bằng bàn phím. `:focus-within` là lý do menu này dùng được
   mà không cần một dòng JavaScript nào. */
.nav-item:hover > .nav-sub,
.nav-item:focus-within > .nav-sub { display: block; }

.nav-sub a {
    display: block; padding: .5rem .7rem; border-radius: var(--radius-sm);
    text-decoration: none; color: var(--ink-700); font-size: .92rem;
    white-space: nowrap;
}
.nav-sub a:hover { background: var(--navy-050); color: var(--navy-800); }
.nav-cta, .nav-login { white-space: nowrap; }

/* --------------------------------------------------------------- buttons */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
    min-height: 44px; padding: .6rem 1.1rem; border-radius: var(--radius-sm);
    border: 1px solid transparent; font: inherit; font-weight: 600; cursor: pointer;
    text-decoration: none; text-align: center;
}
.btn-primary { background: var(--navy-800); color: #fff; }
.btn-primary:hover { background: var(--navy-900); color: #fff; }
.btn-accent { background: var(--accent-600); color: #fff; }
.btn-accent:hover { background: var(--accent-text); color: #fff; }
.btn-ghost { background: var(--paper); border-color: var(--line); color: var(--navy-800); }
.btn-ghost:hover { background: var(--navy-050); }
.btn-danger { background: var(--red-700); color: #fff; }
.btn-sm { min-height: 36px; padding: .35rem .7rem; font-size: .875rem; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .55; pointer-events: none; }

/* ----------------------------------------------------------------- cards */
.card {
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.15rem; box-shadow: var(--shadow-sm);
}
.card-tight { padding: .9rem 1rem; }
.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.split { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr); }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }

/* ----------------------------------------------------------------- badges */
.badge {
    display: inline-flex; align-items: center; gap: .3rem; padding: .18rem .5rem;
    border-radius: 999px; font-size: .76rem; font-weight: 650; line-height: 1.5;
    background: var(--navy-100); color: var(--navy-800); white-space: nowrap;
}
.badge-sample { background: var(--gold-100); color: var(--gold-text); }
.badge-ok { background: var(--green-100); color: var(--green-700); }
.badge-warn { background: var(--gold-100); color: var(--gold-text); }
.badge-danger { background: var(--red-100); color: var(--red-700); }
.badge-muted { background: #eceff3; color: var(--ink-500); }

/* ------------------------------------------------------------------ hero */
.hero { background: linear-gradient(160deg, var(--navy-900), var(--navy-800) 60%, var(--navy-700)); color: #fff; }
.hero-inner { padding: 3rem 0 3.25rem; display: grid; gap: 2rem; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: center; }
@media (max-width: 900px) { .hero-inner { grid-template-columns: 1fr; padding: 2.25rem 0; } }
.hero h1 { color: #fff; margin-bottom: .6rem; }
.hero p { color: #d8e8f5; font-size: 1.06rem; max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.25rem; }
.hero-search { background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25); border-radius: var(--radius); padding: 1.1rem; }
.hero-search label { color: #fff; font-weight: 600; display: block; margin-bottom: .4rem; }
.hero-search .field-row { display: flex; gap: .5rem; flex-wrap: wrap; }
.hero-search input[type="search"] { flex: 1 1 12rem; }
.hero-note { color: #bcd6ea; font-size: .85rem; margin: .6rem 0 0; }

/* ----------------------------------------------------------------- forms */
.field { margin-bottom: 1.1rem; }
.field > label, .field-label { display: block; font-weight: 600; margin-bottom: .35rem; color: var(--navy-900); }
.field .helptext { display: block; font-size: .85rem; color: var(--ink-500); margin-top: .3rem; }
input[type="text"], input[type="email"], input[type="tel"], input[type="url"], input[type="search"],
input[type="password"], input[type="number"], input[type="date"], input[type="datetime-local"],
select, textarea {
    width: 100%; min-height: 44px; padding: .55rem .7rem; font: inherit; color: var(--ink-900);
    background: var(--paper); border: 1px solid #b9c7d4; border-radius: var(--radius-sm);
}
textarea { min-height: 7rem; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--navy-700); }
.field-error input, .field-error select, .field-error textarea { border-color: var(--red-700); background: #fff8f8; }
.errorlist { list-style: none; margin: .35rem 0 0; padding: 0; color: var(--red-700); font-size: .875rem; font-weight: 550; }
.checkbox-row { display: flex; gap: .6rem; align-items: flex-start; }
.checkbox-row input[type="checkbox"] { width: 22px; height: 22px; min-height: 22px; margin-top: .15rem; flex: none; }
.checkbox-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.checkbox-list li { display: flex; align-items: center; gap: .5rem; }
.checkbox-list input { width: 20px; height: 20px; min-height: 20px; }
.required-mark { color: var(--red-700); }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.1rem; margin: 0 0 1.25rem; }
legend { font-weight: 650; color: var(--navy-900); padding: 0 .4rem; }

/* --------------------------------------------------------------- notices */
.notice { border-radius: var(--radius); padding: .85rem 1rem; border: 1px solid; margin-bottom: 1rem; }
.notice-info { background: var(--navy-050); border-color: var(--navy-100); }
.notice-ok { background: var(--green-100); border-color: #bfe3cd; color: #0f4f2e; }
.notice-warn { background: var(--gold-100); border-color: #f0d6ae; color: #6b3b00; }
.notice-danger { background: var(--red-100); border-color: #f1c7c7; color: #7e1a1a; }
.notice p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- tables */
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); }
table { width: 100%; border-collapse: collapse; font-size: .94rem; }
th, td { text-align: left; padding: .65rem .8rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th { background: var(--navy-050); font-weight: 650; color: var(--navy-900); white-space: nowrap; }
tr:last-child td { border-bottom: 0; }

/* ----------------------------------------------------------------- misc */
.meta { color: var(--ink-500); font-size: .875rem; }
.muted { color: var(--ink-500); }
.section { padding: 2.5rem 0; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.section-head h2 { margin: 0; }
.chip-row { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
    display: inline-flex; align-items: center; min-height: 36px; padding: .3rem .75rem;
    border: 1px solid var(--line); border-radius: 999px; background: var(--paper);
    text-decoration: none; color: var(--ink-700); font-size: .9rem;
}
.chip:hover { border-color: var(--navy-700); color: var(--navy-800); }
.chip[aria-current="true"] { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }
.logo-tile {
    display: grid; place-items: center; height: 72px; border-radius: var(--radius-sm);
    background: var(--navy-050); color: var(--navy-800); font-weight: 700; font-size: 1.3rem;
    border: 1px solid var(--line); overflow: hidden;
}
.logo-tile img { max-height: 100%; object-fit: contain; }
.stat { text-align: center; }
.stat .n { font-size: 2rem; font-weight: 700; color: var(--navy-800); display: block; line-height: 1.1; }
.stat .l { color: var(--ink-500); font-size: .9rem; }
/* --- Nội dung do Ban thư ký soạn ----------------------------------------
   `.prose` bọc phần HTML đến từ trình soạn thảo. Danh sách thẻ ở đây phải phủ
   đúng allowlist trong hanhthong/core/richtext.py — thẻ nào qua được bộ lọc mà
   không có định dạng ở đây thì hiện ra theo mặc định của trình duyệt, lạc hẳn
   khỏi phần còn lại của trang.

   `white-space: pre-line` đã bị gỡ: nó có từ thời `body` là văn bản thuần
   render bằng `|linebreaks`, dùng để giữ dấu xuống dòng. Nay nội dung là HTML
   có <p> và <br> thật, nên giữ lại quy tắc đó sẽ biến mỗi dấu xuống dòng
   trong mã nguồn HTML thành một lần ngắt dòng thừa trên màn hình. */
.prose { max-width: 70ch; }
.prose > *:first-child { margin-top: 0; }
.prose > *:last-child { margin-bottom: 0; }
.prose p { margin: 0 0 1rem; }
.prose h1, .prose h2, .prose h3 { margin: 1.75rem 0 .6rem; line-height: 1.3; }
.prose h1 { font-size: 1.5rem; }
.prose h2 { font-size: 1.25rem; }
.prose h3 { font-size: 1.08rem; }
.prose ul, .prose ol { margin: 0 0 1rem; padding-left: 1.5rem; }
.prose li { margin-bottom: .35rem; }
.prose li > ul, .prose li > ol { margin-top: .35rem; margin-bottom: 0; }
.prose blockquote {
    margin: 1rem 0; padding: .5rem 0 .5rem 1rem;
    border-left: 3px solid var(--navy-700); color: var(--ink-700);
}
.prose pre {
    margin: 0 0 1rem; padding: .85rem 1rem; overflow-x: auto;
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.prose code { font-size: .92em; }
.prose a { text-decoration: underline; }
.prose h4 { font-size: 1rem; margin: 1.25rem 0 .4rem; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 1.75rem 0; }
.prose u { text-underline-offset: .15em; }
.prose sub, .prose sup { font-size: .75em; }

/* Bảng do người soạn tạo. Bề rộng cột để CSS quyết định, không lấy từ nội
   dung: thuộc tính `width` trong `style` bị bộ lọc bỏ, vì cho bảng dùng cũng
   là cho mọi đoạn văn dùng (xem richtext.py). */
.prose table {
    width: 100%; border-collapse: collapse; margin: 0 0 1rem;
    font-size: .95rem;
}
.prose th, .prose td {
    border: 1px solid var(--line); padding: .5rem .65rem;
    text-align: left; vertical-align: top;
}
.prose th { background: var(--paper); font-weight: 600; }
.prose caption { caption-side: bottom; padding-top: .5rem; font-size: .875rem; color: var(--ink-500); }
/* Bảng rộng hơn màn hình phải cuộn bên trong nó, không đẩy cả trang.
   Chỉ bật trên màn hình hẹp: `display: block` biến bảng thành khối thường và
   `width: 100%` mất tác dụng — bảng co lại bằng nội dung, hẹp hơn cột chữ.
   Trên máy tính giữ `display: table` để bảng trải hết bề ngang. */
@media (max-width: 640px) {
    .prose table { display: block; overflow-x: auto; }
}
.prose img { height: auto; border-radius: var(--radius-sm); }
.prose figure { margin: 1rem 0; }
.prose figcaption { font-size: .875rem; color: var(--ink-500); margin-top: .4rem; }
.empty { text-align: center; padding: 2.5rem 1rem; color: var(--ink-500); background: var(--paper); border: 1px dashed var(--line); border-radius: var(--radius); }
.pagination { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; justify-content: center; margin-top: 1.5rem; }
.dl-grid { display: grid; gap: .6rem 1rem; grid-template-columns: max-content 1fr; margin: 0; }
.dl-grid dt { font-weight: 600; color: var(--ink-700); }
.dl-grid dd { margin: 0; }
@media (max-width: 520px) { .dl-grid { grid-template-columns: 1fr; gap: .15rem; } .dl-grid dd { margin-bottom: .5rem; } }

/* ---------------------------------------------------------------- footer */
/* ------------------------------------------------------------ backoffice */
.bo-shell { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 1.5rem; align-items: start; padding: 1.5rem 0; }
@media (max-width: 900px) { .bo-shell { grid-template-columns: 1fr; } }
.bo-nav { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: .6rem; position: sticky; top: 90px; }
.bo-nav a { display: flex; justify-content: space-between; gap: .5rem; align-items: center; padding: .6rem .7rem; border-radius: var(--radius-sm); text-decoration: none; color: var(--ink-700); font-weight: 550; min-height: 44px; }
.bo-nav a:hover { background: var(--navy-050); }
.bo-nav a[aria-current="page"] { background: var(--navy-800); color: #fff; }
.queue-count { background: var(--accent-600); color: #fff; border-radius: 999px; padding: 0 .5rem; font-size: .8rem; font-weight: 700; }
.bo-nav a[aria-current="page"] .queue-count { background: #fff; color: var(--navy-900); }
.diff-table td.old { color: var(--red-700); } .diff-table td.new { color: var(--green-700); font-weight: 600; }
.action-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* ------------------------------------------------------------- mobile nav */
/* Between the desktop nav and the mobile menu there is a band where nine links
   plus a call-to-action no longer fit on one line. Tightening them there is
   better than letting the button wrap onto a second row. */
@media (max-width: 1240px) {
    .nav-item > a { padding: .5rem .5rem; font-size: .92rem; }
    .brand-name { font-size: .95rem; }
    .header-inner { gap: .6rem; }
}

/* Below this the nine links plus the call-to-action stop fitting on one line,
   and a button that wraps onto a second row looks like a mistake. The
   hamburger is the honest answer there, not a cramped row. */
@media (max-width: 1100px) {
    .nav-toggle-label { display: inline-flex; }
    .site-nav {
        display: none; width: 100%; flex-direction: column; align-items: stretch;
        gap: 0; padding: .5rem 0 1rem; border-top: 1px solid var(--line); margin-left: 0;
    }
    .site-nav a { width: 100%; }
    .nav-toggle:checked ~ .site-nav { display: flex; }
    .header-inner { flex-wrap: wrap; }

    /* Trong menu thu gọn, mục con hiện luôn dưới mục cha và thụt vào: không ai
       muốn bấm hai lần trên điện thoại để thấy một danh sách bốn mục. */
    .nav-list { flex-direction: column; align-items: stretch; width: 100%; gap: 0; }
    .nav-item { width: 100%; }
    .nav-item > a { width: 100%; }
    .nav-sub {
        display: block; position: static; min-width: 0;
        border: 0; box-shadow: none; background: transparent;
        padding: 0 0 .4rem .9rem; margin: 0;
        border-left: 2px solid var(--navy-100);
    }
    .nav-sub a { padding: .45rem .6rem; min-height: 40px; display: flex; align-items: center; }
    .has-sub > a::after { display: none; }
    .nav-cta, .nav-login { width: 100%; justify-content: center; margin-top: .5rem; }
}

@media print {
    .site-header, .site-footer, .env-banner, .btn { display: none; }
    body { background: #fff; }
}

/* --- Ảnh bìa trang chủ ---------------------------------------------------
   Lớp phủ tối phía trên ảnh, không phải tuỳ chọn thẩm mỹ: chữ trắng trên một
   ảnh bất kỳ do Ban thư ký tải lên có thể không đọc được, và họ không nên phải
   nghĩ về độ tương phản khi chọn ảnh. */
.hero-has-image { background-size: cover; background-position: center; }
.hero-has-image > .hero-inner { position: relative; }
.hero-has-image::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(12,35,64,.88), rgba(12,35,64,.72) 65%, rgba(29,100,150,.7));
}
.hero-has-image { position: relative; }

/* --- Banner --------------------------------------------------------------
   Trượt bằng CSS, không tự chuyển. Xem ghi chú trong
   templates/includes/banners.html để biết vì sao không tự chuyển. */
.banners { background: var(--navy-900); }
.banner-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Thanh trượt mỏng thay vì ẩn hẳn: ẩn đi thì trên máy tính không có gì cho
     biết còn banner nữa ở bên phải. */
  scrollbar-width: thin;
}
.banner-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  scroll-margin-top: 8rem;
  position: relative;
  min-height: 15rem;
  display: grid;
  align-items: end;
}
.banner-slide:focus { outline: none; }
.banner-image {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  max-height: 26rem;
  object-fit: cover;
  object-position: center 30%;
  display: block;
}
.banner-body {
  grid-area: 1 / 1;
  position: relative;
  padding: 1.75rem clamp(1rem, 5vw, 4rem) 2rem;
  max-width: 48rem;
  color: #fff;
}
/* Khi có ảnh, chữ nằm trên ảnh nên cần lớp phủ; khi không có ảnh thì nền navy
   của .banners đã đủ tương phản. */
.banner-slide:has(.banner-image) .banner-body {
  background: linear-gradient(to top, rgba(12,35,64,.92), rgba(12,35,64,.45) 70%, transparent);
  width: 100%;
  max-width: none;
}
.banner-title { color: #fff; margin: 0 0 .4rem; font-size: clamp(1.25rem, 2.6vw, 1.9rem); }
.banner-summary { color: #dce9f4; margin: 0 0 .9rem; max-width: 52ch; }

.banner-dots { display: none; }
.banners-multi .banner-dots {
  display: flex;
  gap: .5rem;
  justify-content: center;
  padding: .75rem 0 1rem;
  background: var(--navy-900);
}
.banner-dot {
  width: 1.5rem; height: 1.5rem;
  display: grid; place-items: center;
  border-radius: 50%;
}
.banner-dot::before {
  content: "";
  width: .6rem; height: .6rem;
  border-radius: 50%;
  background: rgba(255,255,255,.45);
}
.banner-dot:hover::before, .banner-dot:focus-visible::before { background: #fff; }
.banner-dot:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

@media (max-width: 700px) {
  .banner-slide { min-height: 12rem; }
  .banner-image { max-height: 18rem; }
}
/* Người đã bật "giảm hiệu ứng chuyển động" không nên bị trang tự cuộn mượt. */
@media (prefers-reduced-motion: reduce) {
  .banner-track { scroll-behavior: auto; }
}

/* ---------------------------------------------------------- thư viện ảnh
   Lưới ảnh thuần CSS. Không có JavaScript nào trên trang công khai, nên hai
   điều phải lo bằng CSS:

   * **Ô ảnh cao bằng nhau.** Ảnh dọc và ảnh ngang lẫn nhau trong một lưới sẽ
     làm các hàng so le. `aspect-ratio` + `object-fit: cover` cho mọi ô cùng
     hình dạng mà không cắt méo ảnh.
   * **Trang không nhảy khi ảnh tải xong.** Thẻ `<img>` được khai sẵn
     `width`/`height` từ cơ sở dữ liệu, nên trình duyệt chừa đúng chỗ. Không có
     script nào để sửa việc nhảy đó sau. */
/* Hai lưới ảnh, chung một khai báo: `.gallery-grid` cho thẻ có chữ kèm theo,
   `.photo-wall` cho bức tường ảnh thuần — ô nhỏ hơn và khít hơn. */
.gallery-grid, .photo-wall { display: grid; }
.gallery-grid { gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.photo-wall { gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.gallery-card { display: flex; flex-direction: column; gap: .5rem; }
.gallery-thumb {
    position: relative; display: block;
    aspect-ratio: 4 / 3; overflow: hidden;
    border-radius: var(--radius-sm); background: var(--grey-100, #eee);
}
/* Ảnh phóng nhẹ khi trỏ vào: dấu hiệu "bấm được" mà không cần thêm chữ. */
.gallery-thumb img {
    width: 100%; height: 100%; display: block;
    object-fit: cover; transition: transform .18s ease;
}
.gallery-thumb:hover img, .gallery-thumb:focus-visible img { transform: scale(1.04); }
.gallery-thumb:focus-visible { outline: 3px solid var(--navy-700, #1b3a5c); outline-offset: 2px; }
.gallery-empty { display: block; width: 100%; height: 100%; background: var(--grey-100, #eee); }
.gallery-play {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 2rem; color: #fff;
    text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
    background: rgba(0, 0, 0, .18);
}

/* Trang một ảnh. `max-height` theo chiều cao khung nhìn để ảnh dọc không đẩy
   phần chú thích và đường quay về sự kiện xuống dưới màn hình. */
.photo-stage { margin: 1rem 0 0; }
.photo-stage img {
    max-width: 100%; max-height: 78vh; width: auto; height: auto;
    display: block; margin: 0 auto;
    border-radius: var(--radius); background: var(--grey-100, #eee);
}
.photo-stage figcaption { margin-top: .6rem; text-align: center; color: var(--ink-600, #555); }

@media (prefers-reduced-motion: reduce) {
    .gallery-thumb img { transition: none; }
    .gallery-thumb:hover img, .gallery-thumb:focus-visible img { transform: none; }
}

/* Danh sách tài liệu tải về (hồ sơ doanh nghiệp, tài liệu Hội). */
.doc-list { list-style: none; padding: 0; margin: .5rem 0 0; display: flex; flex-direction: column; gap: .5rem; }
.doc-list > li { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
