/* PromoProof — main.css, vùng [giaodien]. Mobile-first, KHÔNG import ngoài.
   Selector bám CẤU TRÚC HTML gốc do tool sinh (p intro → ul.merchant-facts →
   figure.wp-block-table > table) và HỢP ĐỒNG MARKUP của plugin coupon-enhance
   (docs/tinhnang_hop_dong_markup.md): .cpn-codes/.cpn-row/.cpn-code/.cpn-show.
   Thiếu plugin thì bảng mã vẫn ra card đẹp, chỉ mất nút. */

/* ---------- 0. Font headline (SELF-HOST) ----------
   Bricolage Grotesque, giấy phép SIL OFL → được phép self-host.
   File .woff2 nằm trong repo (assets/fonts/), KHÔNG link Google Fonts CDN:
   CLAUDE.md cấm request ra ngoài lúc render, và một CDN font là đúng một request
   chặn render vào máy chủ của người khác.
   Bản variable, chỉ subset LATIN (75KB) — site chỉ hiển thị tiếng Anh.
   font-display: swap → chữ hệ thống hiện ngay, font hiện sau, không chặn vẽ trang.
   Chỉ dùng cho headline (h1/h2, logo, tên sự kiện, số % trên cuống vé); body và
   mono vẫn là font hệ thống — đó là lý do 75KB không ảnh hưởng Lighthouse. */
@font-face {
    font-family: "Bricolage Grotesque";
    src: url("../fonts/bricolage-grotesque.woff2") format("woff2");
    font-weight: 400 800;
    font-style: normal;
    font-display: swap;
}

/* ---------- 1. Tokens — bản chốt "Voucher Bold" (14/07/2026) ----------
   Nguyên tắc: nền/viền/chữ TRUNG TÍNH (hết "xanh toàn tập"); teal chỉ đứng ở vai
   ACCENT — cuống vé, nút, dấu tick, footer. Thêm một màu ấm (--c-mark) làm đối
   trọng, dùng đúng 2 chỗ: vệt highlight trong H1 và badge TOP 1-2-3. */
:root {
    --c-bg: #fff;
    --c-page: #f5f6f5;          /* nền trang — xám ấm nhẹ, để card TRẮNG nổi lên */
    --c-surface: #f5f6f5;
    --c-ink: #111c1a;
    --c-text: #3a4443;
    /* #6b7773 cua ban chot chi dat 4.30 tren nen trang moi (#f5f6f5) — duoi chuan
       AA 4.5. Ban cu qua duoc vi nen la TRANG; doi nen xam la keo tut ca chu xam
       xuong. Toi mot nac: 4.90 tren nen trang, 5.31 tren card. */
    --c-muted: #626e6a;
    --c-accent: #0c8271;
    --c-accent-dark: #07564a;
    --c-accent-deep: #04332c;   /* footer + đầu tối của gradient cuống vé */
    --c-accent-soft: #d7f3e9;
    --c-mark: #f9d878;          /* highlight vàng ấm */
    --c-warn-bg: #fff4d6;
    --c-warn-ink: #8a5a00;
    --c-border: #e2e6e4;
    --c-code-bg: #f5f6f5;

    /* scale 4/8/12/16/24 (+32/48 cho section) */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 24px;
    --sp-6: 32px;
    --sp-7: 48px;

    --r-sm: 8px;
    --r: 12px;
    --r-lg: 16px;
    --r-xl: 24px;

    --shadow: 0 8px 20px rgba(4, 51, 44, .1);
    --shadow-lift: 0 12px 26px rgba(4, 51, 44, .22);

    --wrap: 1180px;
    --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-display: "Bricolage Grotesque", var(--font);   /* self-host, xem mục 0 */
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    /* Nét đứt — texture chủ đạo: mép xé của vé, gạch dưới section head, mép list. */
    --c-dash: #bdc7c3;

    /* RĂNG CƯA TEM THƯ — thay lỗ đục đơn của bản cũ. Chu kỳ 20px, bán kính 5px.
       Dùng chung cho vé mã và banner sự kiện → cả trang chủ nói cùng một thứ tiếng. */
    --perf-r: 5px;
    --perf-step: 20px;
}

/* HAI VAI CHỮ (hệ thống, không tải font ngoài — CLAUDE.md).
   .fact = MỌI DỮ KIỆN đo được: mã, số mã, %, ngày verify, số nguồn, chữ cái A-Z.
   Mono là chữ của hoá đơn và của chiếc vé — đây là nơi site có giọng riêng,
   và nó cũng nói đúng bản chất: cái gì in mono là cái tra được về data thật.
   Sans dành cho câu chữ. Không trộn hai vai. */
.fact {
    font-family: var(--font-mono);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

/* Màu control của plugin [tinhnang] đổi bằng BIẾN (hợp đồng mục 3) —
   không tranh specificity với CSS plugin. */
.cpn-codes,
.cpn-modal,
.cpn-saved {
    --cpn-accent: var(--c-accent);
    --cpn-ink: var(--c-ink);
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    color: var(--c-text);
    background: var(--c-page);      /* nền xám ấm → card trắng nổi lên */
    line-height: 1.6;
    -webkit-text-size-adjust: 100%;
}

img { max-width: 100%; height: auto; }

/* Link CHU dung accent-dark chu khong phai accent: #0c8271 chi dat 4.36 tren nen
   trang moi (duoi 4.5). accent-dark dat 7.95. --c-accent VAN giu nguyen vai NEN
   (nut, chip, cuong ve) — o do chu trang tren teal dat 4.72, khong sao. */
a { color: var(--c-accent-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

/* BA VAI CHỮ. display = headline (h1/h2, logo, tên sự kiện, số % trên cuống vé):
   giọng voucher, đậm, siết chữ. sans = câu văn. mono = dữ kiện (xem .fact).
   h3 KHÔNG dùng display: nó là tiêu đề nhỏ trong thân bài, để display vào đó thì
   font đậm nhảy khắp trang và mất hẳn thứ bậc. */
h1, h2, h3 {
    margin: 0 0 var(--sp-4);
    color: var(--c-ink);
    line-height: 1.15;
    letter-spacing: -.022em;
}
h1, h2 {
    font-family: var(--font-display);
    font-weight: 800;
    letter-spacing: -.025em;
}
h1 { font-size: clamp(1.7rem, 1.3rem + 1.6vw, 2.25rem); }
h2 { font-size: clamp(1.35rem, 1.15rem + .8vw, 1.7rem); }
h3 { font-size: 1.05rem; }

:focus-visible {
    outline: 2px solid var(--c-accent);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--sp-4); }

.screen-reader-text {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: var(--sp-2);
    z-index: 100;
    padding: var(--sp-2) var(--sp-4);
    background: var(--c-accent);
    color: #fff;
    border-radius: var(--r-sm);
}
.skip-link:focus { left: var(--sp-4); }

/* ---------- 3. Buttons & search ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-4);
    min-height: 42px;
    font: inherit;
    font-weight: 700;
    color: #fff;
    background: var(--c-accent);
    border: 1px solid var(--c-accent);
    border-radius: 999px;              /* pill — ngôn ngữ nút của bản chốt */
    cursor: pointer;
}
.btn:hover { background: var(--c-accent-dark); text-decoration: none; }

.search-form { display: flex; gap: var(--sp-2); width: 100%; }
.search-form .search-field {
    flex: 1 1 auto;
    min-width: 0;
    padding: var(--sp-2) var(--sp-3);
    padding-left: var(--sp-4);
    min-height: 42px;
    font: inherit;
    color: var(--c-text);
    background: var(--c-page);
    border: 1px solid var(--c-border);
    border-radius: 999px;
}
.search-form .search-field::placeholder { color: var(--c-muted); }

/* ---------- 4. Header / Footer ---------- */
/* Bản chốt: header KHÔNG có viền liền dưới — cả khối header là một "cuống vé"
   trắng, ngăn với trang bằng đúng thứ texture của site: NÉT ĐỨT. */
.site-header {
    border-bottom: 0;
    background: var(--c-bg);
}
.site-header__top { border-bottom: 2px dashed var(--c-dash); }
.site-header__top .wrap {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex-wrap: wrap;
    padding-top: var(--sp-3);
    padding-bottom: var(--sp-3);
}
/* Logo = mark SVG (in inline, xem inc/brand.php) + wordmark là CHỮ HTML thật.
   Không dùng <img src="trove-logo.svg">: SVG trong <img> không thấy @font-face của
   trang → wordmark rơi về font hệ điều hành, mỗi máy một dáng. */
.site-logo {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    line-height: 1;
    white-space: nowrap;
}
.site-logo:hover { text-decoration: none; opacity: .85; }
.site-logo__mark { flex: 0 0 auto; display: block; }
.site-logo__text {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--c-ink);
    letter-spacing: -.03em;
}
.site-logo__text i { font-style: normal; color: var(--c-accent); }

/* Footer nền teal đậm (#04332c) — mà gradient của mark KẾT THÚC đúng ở #04332c:
   để nguyên thì góc dưới-phải của mark tan vào nền, hình vuông mất một góc. Kéo
   cả hai chặng gradient sáng lên cho tách khỏi nền. stop-color là thuộc tính CSS
   → sửa được từ đây, không phải đẻ thêm một file SVG bản tối. */
.site-logo--dark .site-logo__text { color: #fff; }
.site-logo--dark .site-logo__text i { color: #7fd6be; }
.site-logo--dark .site-logo__mark stop:first-child { stop-color: #2fbb9f; }
.site-logo--dark .site-logo__mark stop:last-child { stop-color: #0c8271; }

.nav-toggle {
    margin-left: auto;
    padding: var(--sp-2) var(--sp-3);
    font: inherit;
    color: var(--c-ink);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
    cursor: pointer;
}
.header-search { flex: 1 1 100%; }

/* Menu = DẢI RIÊNG dưới logo, không nhét cạnh ô search: 4 hub + A-Z + trang
   "How We Verify" không đủ chỗ trên một dòng cùng logo và ô tìm kiếm.
   Nền surface + viền trên → đọc ra là thanh điều hướng, không phải chữ trôi nổi. */
/* Nav: hết dải nền xám. Trên desktop mỗi mục là một CHIP pill — cùng ngôn ngữ
   với nút và ô tìm kiếm. Trên mobile giữ list dọc (chip xếp dọc thì rối). */
.primary-nav {
    border-top: 0;
    background: var(--c-bg);
}
.primary-nav[hidden] { display: none; }
.primary-nav ul {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin: 0;
    padding: var(--sp-1) 0;
    list-style: none;
}
.primary-nav li + li { border-top: 1px dashed var(--c-dash); }
.primary-nav a {
    display: block;
    padding: var(--sp-3) 0;
    color: var(--c-text);
    font-weight: 600;
    font-size: .95rem;
}
.primary-nav a:hover { color: var(--c-accent); text-decoration: none; }
.primary-nav .current-menu-item > a,
.primary-nav a[aria-current="page"] { color: var(--c-accent); }

@media (min-width: 768px) {
    .nav-toggle { display: none; }
    .primary-nav[hidden] { display: block; }   /* desktop: bỏ qua [hidden], không cần JS */
    .primary-nav ul {
        flex-direction: row;
        align-items: center;
        gap: var(--sp-2);
        /* Chip nav dính vào đường nét đứt của header → thở đều 14px cả trên lẫn dưới. */
        padding: 14px 0;
    }
    .primary-nav li + li { border-top: 0; }
    .primary-nav a {
        padding: 7px 14px;
        font-size: .9rem;
        border-radius: 999px;
        background: var(--c-page);
    }
    .primary-nav a:hover { background: var(--c-accent-soft); color: var(--c-accent-dark); }
    .header-search { flex: 0 1 320px; margin-left: auto; }
}

/* Footer TEAL ĐẬM — neo thương hiệu, đóng trang bằng đúng màu của cuống vé.
   Nền tối nên MỌI màu chữ phải khai lại: --c-muted (#6b7773) trên nền #04332c là
   không đọc được. Đây là chỗ dễ vỡ nhất khi đổi token, không phải chỗ đẹp nhất. */
.site-footer {
    margin-top: var(--sp-7);
    padding: var(--sp-7) 0 var(--sp-5);
    background: var(--c-accent-deep);
    border-top: 0;
    font-size: .9rem;
    color: #a9cec1;
}
.footer-top { display: grid; gap: var(--sp-6); }
@media (min-width: 768px) {
    .footer-top {
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr);
        gap: var(--sp-7);
    }
}
.footer-brand .site-logo { margin-bottom: var(--sp-2); }
.footer-tagline { margin: 0 0 var(--sp-3); max-width: 36ch; }
/* Dấu PROOF thu nhỏ: câu duy nhất site được phép khoe, và nó đúng — mọi mã đều
   có ngày kiểm in kèm (không có ngày → template không in mã đó). */
.footer-verify {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin: 0;
    color: #7fd6be;
}
.footer-verify svg { flex: 0 0 auto; }

.footer-nav {
    display: grid;
    gap: var(--sp-5);
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.footer-col__title { margin: 0 0 var(--sp-3); color: #fff; }
.site-footer ul {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    margin: 0;
    padding: 0;
    list-style: none;
}
.site-footer a { color: #a9cec1; }
.site-footer a:hover { color: #fff; }

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--sp-3) var(--sp-5);
    margin-top: var(--sp-6);
    padding-top: var(--sp-5);
    border-top: 1px dashed rgba(255, 255, 255, .28);
}
.footer-bottom .disclosure { margin: 0; max-width: 64ch; font-size: .82rem; }
.footer-copy { margin: 0; }

/* ---------- 5. Section ---------- */
.site-main { padding: var(--sp-5) 0 var(--sp-7); }
.section { padding-top: var(--sp-6); }

/* Rule nét đứt = cùng đường đục lỗ của chiếc vé, lặp lại làm ngôn ngữ của site.
   Eyebrow mono nói ĐÚNG khoá sắp xếp thật của khối (BY LIVE CODE COUNT / BY
   DISCOUNT / BY LAST CHECK) — cấu trúc mã hoá sự thật, không phải nhãn trang trí. */
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-2) var(--sp-4);
    flex-wrap: wrap;
    margin-bottom: var(--sp-4);
    padding-bottom: var(--sp-3);
    border-bottom: 2px dashed var(--c-dash);
}
.section-head h2 { margin: 0; }
/* Eyebrow thành CHIP teal: nó là dữ kiện (khoá sắp xếp thật), nên được đóng khung
   như một nhãn có thẩm quyền, không còn là chữ xám trôi ở mép phải. */
.section-eyebrow {
    padding: 4px var(--sp-3);
    color: var(--c-accent-dark);
    background: var(--c-accent-soft);
    border-radius: 999px;
}

.page-title { margin-bottom: var(--sp-2); }
.page-subtitle { margin: 0 0 var(--sp-5); color: var(--c-muted); }

/* Markup do [seo] sinh (couponsite_breadcrumb, class .breadcrumb/.breadcrumb-sep)
   — theme chỉ style, không tự chế breadcrumb thứ hai nữa. */
.breadcrumb {
    margin: 0 0 var(--sp-4);
    font-family: var(--font-mono);   /* đường dẫn = dữ kiện điều hướng → mono */
    font-size: .74rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--c-muted);
}
.breadcrumb a { color: var(--c-muted); }
.breadcrumb a:hover { color: var(--c-accent); }
.breadcrumb-sep { color: var(--c-dash); }
.breadcrumb [aria-current="page"] { color: var(--c-ink); }

/* ---------- 5b. Hero trang chủ (H1 duy nhất của trang) ----------
   NÉN LẠI: trước đây H1 to bằng áp phích, nằm ngay trên dải banner cũng to
   không kém → hai "hero" tranh nhau làm nhân vật chính, mắt khách rơi vào
   banner còn H1 thành chú thích. Phân vai lại: H1 + câu dẫn là DÒNG MỞ ĐẦU
   (một băng chữ gọn), dải banner mới là phần hình. */
.home-hero { padding: var(--sp-5) 0 0; }
.home-hero .wrap {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-2) var(--sp-5);
    flex-wrap: wrap;
}
.hero-title {
    max-width: 24ch;
    margin: 0;
    font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3rem);
    line-height: 1.06;
}
/* Vệt highlight vàng dưới cụm từ khoá — dừng ở 62% chiều cao chữ nên nó đọc ra là
   NÉT BÚT DẠ QUANG quẹt qua, không phải một ô nền tô kín.
   PHP: front-page.php bọc "actually work" trong <mark class="hero-mark">. Không có
   <mark> thì hero vẫn nguyên vẹn, chỉ mất vệt vàng — CSS không phụ thuộc cứng. */
/* Vệt vàng phải nằm ở CHÂN CHỮ. Bản cũ dùng linear-gradient(transparent 62%,...):
   62% đó là 62% của INLINE BOX, không phải của chữ — mà đáy inline box nằm THẤP
   HƠN BASELINE 0.276em (đo 14/07: box 52px, baseline ở 40px, font-size 43.4px).
   Kết quả: vệt chỉ liếm 7.8px cuối của chữ nhưng thò 12px xuống dưới baseline —
   quá nửa vệt nằm ở khoảng trống giữa hai dòng, nên nhìn như nó "đè xuống dòng
   dưới". Mọi con số % ở đây đều thừa kế cái vùng chết đó.
   → Neo vào baseline bằng em (0.922em là metric của Bricolage, không đổi theo
   cỡ chữ): vệt cao 0.27em, bắt đầu 0.24em TRÊN baseline (= 1/3 dưới của chữ) và
   dừng ngay 0.03em dưới baseline. clone → cụm bị ngắt dòng thì mỗi dòng một vệt
   riêng ở chân, không kéo thành khối liền. */
.hero-mark {
    background: linear-gradient(var(--c-mark), var(--c-mark)) no-repeat 0 .682em / 100% .27em;
    color: inherit;
    padding: 0;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
}
.hero-sub {
    max-width: 44ch;
    margin: 0;
    color: var(--c-muted);
    font-size: .95rem;
}


/* ---------- 6. TẦNG 1 — Banner sự kiện ---------- */
.events { padding: var(--sp-5) 0 0; }

/* Mobile: 1 cột vuốt ngang, snap từng banner. */
.events__row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 86%;
    gap: var(--sp-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--sp-2);
    -webkit-overflow-scrolling: touch;
}
.events__row > * { scroll-snap-align: start; }

/* Chỉ 1 banner (mùa khác chưa có Page hub → bị lọc bỏ): cho nó chiếm trọn
   chiều ngang, đừng để lưới cứng 3 cột bỏ trống 2/3 trang. */
.events__row:not(:has(.evt:nth-child(2))) { grid-auto-columns: 100%; }

@media (min-width: 900px) {
    .events__row {
        grid-auto-flow: row;
        grid-auto-columns: auto;
        grid-template-columns: 1fr;             /* mặc định: 1 banner = full width */
        gap: var(--sp-4);
        overflow: visible;
    }
    /* Số cột bám theo SỐ BANNER THẬT sự render được (:has đếm hộ, khỏi cần PHP
       truyền class xuống). Banner đầu luôn to nhất. */
    .events__row:has(.evt:nth-child(2)) { grid-template-columns: 1.5fr 1fr; }
    .events__row:has(.evt:nth-child(3)) { grid-template-columns: 1.6fr 1fr 1fr; }
}

.evt {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: 190px;
    padding: var(--sp-5);
    padding-right: 76px;              /* chừa chỗ dải barcode ::after */
    overflow: hidden;
    border-radius: 14px;
    color: var(--evt-ink, #fff);
    background: linear-gradient(135deg, var(--evt-from, #0c8271), var(--evt-to, #04332c));

    /* RĂNG CƯA mép trên/dưới — banner cũng là một chiếc vé, cùng texture với
       .ticket__row. Bóng đổ phải là drop-shadow chứ KHÔNG box-shadow: mask cắt
       hình nên box-shadow bị mask ăn mất, còn drop-shadow bám theo hình đã khuyết. */
    box-shadow: none;
    filter: drop-shadow(0 12px 26px rgba(4, 51, 44, .22));
    transition: transform .18s ease, filter .18s ease;
    -webkit-mask-image:
        radial-gradient(circle var(--perf-r) at 10px 0, transparent 97%, #000 100%),
        radial-gradient(circle var(--perf-r) at 10px 100%, transparent 97%, #000 100%);
    -webkit-mask-size: var(--perf-step) 100%;
    -webkit-mask-repeat: repeat-x;
    -webkit-mask-composite: source-in;
    mask-image:
        radial-gradient(circle var(--perf-r) at 10px 0, transparent 97%, #000 100%),
        radial-gradient(circle var(--perf-r) at 10px 100%, transparent 97%, #000 100%);
    mask-size: var(--perf-step) 100%;
    mask-repeat: repeat-x;
    mask-composite: intersect;
}
.evt:hover,
.evt:focus-visible {
    transform: translateY(-2px);
    filter: drop-shadow(0 16px 30px rgba(4, 51, 44, .3));
    text-decoration: none;
}
.evt--featured { min-height: 240px; }

/* Đốm halftone trắng toả từ góc phải — chất giấy in của voucher. */
.evt::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(255, 255, 255, .28) 1.5px, transparent 1.6px);
    background-size: 11px 11px;
    -webkit-mask-image: linear-gradient(215deg, #000 5%, transparent 45%);
    mask-image: linear-gradient(215deg, #000 5%, transparent 45%);
    pointer-events: none;
}
/* Dải barcode + đường xé nét đứt sát mép phải. */
.evt::after {
    content: "";
    position: absolute;
    top: 20px;
    bottom: 20px;
    right: 14px;
    width: 34px;
    border-left: 2px dashed rgba(255, 255, 255, .55);
    background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, .85) 0 2px, transparent 2px 6px);
    background-position: 12px 0;
    background-size: calc(100% - 12px) 100%;
    background-repeat: no-repeat;
    pointer-events: none;
}

/* Artwork tự vẽ: SVG nét mảnh, chìm sau chữ. Không ảnh stock/AI. */
.evt__art {
    position: absolute;
    top: 0;
    right: 0;
    width: 62%;
    max-width: 260px;
    opacity: .28;
    pointer-events: none;
}
.evt__art .evt-art { width: 100%; height: auto; }

.evt__body { position: relative; display: flex; flex-direction: column; gap: var(--sp-1); }

.evt__when {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    opacity: .92;
}
.evt__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}
.evt__name {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.3rem);
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: 1.05;
}
.evt--featured .evt__name { font-size: clamp(1.8rem, 1.2rem + 2.6vw, 2.9rem); }
.evt__tagline {
    max-width: 34ch;
    font-size: .92rem;
    opacity: .92;
}
.evt__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    margin-top: var(--sp-2);
    font-weight: 700;
    font-size: .9rem;
}

/* ---------- 7. Logo store (favicon + fallback chữ cái) ---------- */
.store-logo {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--logo-size, 56px);
    height: var(--logo-size, 56px);
    border-radius: var(--r);
    overflow: hidden;
    background: hsl(var(--logo-hue, 200) 62% 92%);
    border: 1px solid var(--c-border);
}
.store-logo__char {
    font-size: calc(var(--logo-size, 56px) * .42);
    font-weight: 800;
    line-height: 1;
    color: hsl(var(--logo-hue, 200) 55% 30%);
}
/* Favicon nằm ĐÈ lên chữ cái; tải hỏng → onerror gỡ ảnh → chữ lộ ra.
   Nền trắng + hiện ảnh CHỈ SAU KHI tải xong (class .is-loaded do onload gắn).
   Vì sao: cái <img> vẽ nền trắng của nó NGAY khi có mặt trong DOM, kể cả lúc bitmap
   chưa về → khung trắng che mất chữ cái, khách thấy 36 ô trắng rỗng trong lúc chờ.
   Bắt được lỗi này khi soi Firefox (nó chụp đúng khoảnh khắc ảnh chưa kịp vẽ).
   Chưa tải xong → ảnh trong suốt → chữ cái đứng thay, không có khoảng trắng câm. */
.store-logo__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    padding: 18%;
    background: transparent;
    opacity: 0;
    transition: opacity .15s ease;
}
.store-logo__img.is-loaded {
    background: #fff;
    opacity: 1;
}

/* ---------- 8. TẦNG 2 — Card store ---------- */
.store-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--sp-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* BUG CŨ (đã sửa): card là flex 1 hàng "logo | tên | nút" → trong ô grid 260px,
   phần chữ bị bóp còn vài chục px: tên bẻ giữa từ ("Bluett i Power Inc") và
   "37 active codes" xếp dọc từng chữ.
   Fix: bố cục GRID 2 hàng — hàng 1 [logo | tên+meta], hàng 2 nút full width.
   Tên có nguyên chiều ngang card → không bao giờ phải bẻ chữ. */
.store-card {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
        "logo body"
        "cta  cta";
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-4);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.store-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow);
    border-color: var(--c-accent-soft);
}
.store-card .store-logo { grid-area: logo; }

.store-card__body { grid-area: body; min-width: 0; }
.store-card__name {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
    /* break-word: chỉ bẻ khi MỘT TỪ dài hơn cả dòng (domain dài), không bẻ
       giữa từ bình thường như "anywhere" từng làm. */
    overflow-wrap: break-word;
}
.store-card__name a { color: var(--c-ink); }
.store-card__name a:hover { color: var(--c-accent); text-decoration: none; }
.store-card__meta {
    margin: var(--sp-1) 0 0;
    font-size: .72rem;       /* mono uppercase rộng hơn sans → hạ cỡ cho gọn 1 dòng */
    color: var(--c-muted);
}
.store-card__cta {
    grid-area: cta;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-3);
    font-size: .875rem;
    font-weight: 700;
    color: var(--c-accent-dark);
    background: var(--c-accent-soft);
    white-space: nowrap;
}
.store-card__cta:hover { text-decoration: none; background: var(--c-accent); color: #fff; }

/* ♥ của plugin gắn vào card (.cpn-has-heart đã có position:relative).
   Chừa chỗ theo CHIỀU DỌC (dải trống phía trên), KHÔNG chừa theo chiều ngang:
   chừa ngang thì cột chữ chỉ còn ~86px và tên store lại bị bẻ giữa từ
   ("embarkvet.co / m") — đúng cái bug vừa sửa. */
.cpn-has-heart .cpn-heart {
    position: absolute;
    top: var(--sp-2);
    right: var(--sp-2);
}
.store-card.cpn-has-heart { padding-top: 40px; }

/* ---------- 8b. Top brands = BẢNG XẾP HẠNG (không phải "lưới card thứ hai") ----------
   Bệnh: Top brands và Recently verified render CÙNG một card, cạnh nhau, nên trang
   chủ có hai dải card giống hệt nhau và khối "giỏi nhất" chẳng được nhấn gì.
   Chữa: Top brands thêm CỘT SỐ HẠNG (mono, đúng giọng "dữ kiện đo được"), top 3 tô
   màu nhấn; Recently verified hạ xuống bản compact ở dưới. */
.store-grid--rank { counter-reset: rank; }
.store-card--rank {
    counter-increment: rank;
    grid-template-columns: auto auto minmax(0, 1fr);
    grid-template-areas:
        "rank logo body"
        "cta  cta  cta";
}
/* Top 3: ::before rời khỏi luồng grid (thành badge absolute) → cột "rank" mất chủ,
   để lại một khoảng trống câm ở đầu card. Bỏ hẳn cột đó cho 3 card này. */
.store-grid--rank > .store-card:nth-child(-n+3) {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
        "logo body"
        "cta  cta";
}
/* ::before là GRID ITEM thật (không phải lớp phủ absolute) → số hạng có cột riêng,
   không bao giờ đè lên logo. */
.store-card--rank::before {
    content: counter(rank);
    grid-area: rank;
    min-width: 1.3em;
    font-family: var(--font-mono);
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1;
    text-align: right;
    color: var(--c-muted);
    font-variant-numeric: tabular-nums;
}
/* TOP 1-2-3: số hạng ở cột trái đổi thành BADGE PILL VÀNG cưỡi lên mép card
   (bản chốt). Vàng chỉ xuất hiện đúng 2 chỗ trên toàn site — vệt highlight trong
   H1 và badge này — nên nó vẫn là điểm nhấn chứ không thành màu trang trí. */
.store-grid--rank > .store-card:nth-child(-n+3) {
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--c-accent), var(--shadow);
}
.store-grid--rank > .store-card:nth-child(-n+3)::before {
    content: "TOP " counter(rank);
    position: absolute;
    top: -11px;
    left: 14px;
    min-width: 0;
    padding: 2px 10px;
    font-size: .7rem;
    letter-spacing: .08em;
    color: #1b2a26;
    background: var(--c-mark);
    border-radius: 999px;
}
.store-grid--rank > .store-card:nth-child(-n+3) .store-card__cta {
    color: #fff;
    background: var(--c-accent);
}

/* ---------- 8c. Recently verified = DÒNG THỜI GIAN (vai phụ) ----------
   Nhỏ hơn, dày hơn, không nút: 24 card có nút "View codes" chỉ là 24 lần lặp lại
   cùng một lời mời. Cả card bấm được (::after của chính thẻ <a> tên store — vẫn
   một thẻ <a>, không lồng link, đúng hợp đồng [tinhnang]). */
.store-grid--compact {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--sp-2);
}
.store-card--compact {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "logo body";
    padding: var(--sp-3);
    background: var(--c-bg);
    border-color: transparent;
    border-radius: var(--r);
}
.store-card--compact:hover {
    transform: none;
    box-shadow: none;
    background: var(--c-bg);
    border-color: var(--c-accent-soft);
}
.store-card--compact .store-card__name { font-size: .92rem; }
.store-card--compact .store-card__name a::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
}
/* Nút ♥ phải nằm TRÊN lớp phủ, nếu không plugin mất nút Save ở khối này. */
.store-card--compact .cpn-heart { z-index: 2; }
/* 40px của card thường là để chừa ♥; card compact thấp hơn nên chỉ cần 28px. */
.store-card--compact.cpn-has-heart { padding-top: 28px; }

/* ---------- 9. TẦNG 3 — Ticket mã (hình chiếc vé) ---------- */
.ticket-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp-3);
    margin: 0;
    padding: 0;
    list-style: none;
}
@media (min-width: 640px) { .ticket-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .ticket-grid { grid-template-columns: repeat(3, 1fr); } }

/* Shadow đặt ở .ticket bằng drop-shadow: mask cắt khuyết 2 lỗ ở .cpn-row, nên
   box-shadow thường sẽ bị mask ăn mất — drop-shadow bám theo hình đã khuyết. */
.ticket {
    filter: drop-shadow(0 8px 20px rgba(4, 51, 44, .12));
    transition: transform .18s ease, filter .18s ease;
}
/* Các vé cùng một hàng phải bằng nhau, nếu không cuống vé teal thò thụt lệch lạc. */
.ticket__box, .ticket__row { height: 100%; }

/* ♥ của plugin gắn ở góc phải vé và ĐÈ LÊN TÊN STORE (tên bị cắt cụt).
   Chừa chỗ theo CHIỀU DỌC — chừa ngang thì tên lại bị bẻ, đã dính bài học đó
   ở card store. */
.ticket.cpn-has-heart .ticket__main { padding-top: 28px; }
.ticket:hover {
    transform: translateY(-2px);
    filter: drop-shadow(0 12px 26px rgba(4, 51, 44, .2));
}

/* CỠ VÉ. Bản trước: stub 116px + min-height 152px + chữ số 1.85rem → mỗi vé cao
   ~204px, gần bằng banner sự kiện (~246px) ngay phía trên. Vé là món ăn phụ,
   banner mới là món chính: hạ toàn bộ thang một nấc để trật tự thị giác quay lại. */
/* LỖ ĐỤC (bản 1b) — KHÔNG phải răng cưa. Răng cưa nhỏ chỉ dành cho banner .evt;
   vé giữ đúng cơ chế cũ, chỉ 2 CẶP lỗ tròn:
   MỘT cặp lỗ (r=10) tại ranh cuống/thân — đúng chỗ đường nét đứt đi qua.
   Bản chốt còn một cặp nhỏ (r=7) cách mép phải 40px để đánh dấu ranh DẢI BARCODE.
   Đã BỎ: vé của ta không có dải barcode (thứ đó chỉ có trên banner), nên cặp lỗ ấy
   đứng trơ như hai vết khía không lý do. Luật của site: lỗ đục + nét đứt = "xé được
   ở đây"; không có gì để xé thì không đục lỗ. Và barcode để riêng cho banner —
   lặp nó lên 12 chiếc vé là làm rẻ chính cái dấu ấy.
   Bản trước tôi áp răng cưa lên cả vé (theo voucher-bold.css) → mép vé lởm chởm
   quanh cả tấm và drop-shadow bám theo từng răng, thành viền đậm lổn nhổn.
   LƯU Ý: KHÔNG khai mask-size/mask-repeat ở đây. Bộ răng cưa cần chúng
   (20px 100% / repeat-x); để sót lại là 4 lỗ tròn này bị TILE 20px một, vé nát. */
.ticket__row {
    --stub: 104px;
    position: relative;
    display: grid;
    grid-template-columns: var(--stub) minmax(0, 1fr);
    min-height: 132px;
    background: var(--c-bg);
    border-radius: 18px;
    box-shadow: none;

    -webkit-mask-image:
        radial-gradient(circle 10px at var(--stub) 0,    transparent 98%, #000 100%),
        radial-gradient(circle 10px at var(--stub) 100%, transparent 98%, #000 100%);
    -webkit-mask-composite: source-in;
    mask-image:
        radial-gradient(circle 10px at var(--stub) 0,    transparent 98%, #000 100%),
        radial-gradient(circle 10px at var(--stub) 100%, transparent 98%, #000 100%);
    mask-composite: intersect;
}

/* Nửa trái: mức giảm to đậm. */
.ticket__stub {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: var(--sp-2);
    color: #fff;
    overflow: hidden;
    background: linear-gradient(160deg, var(--c-accent), var(--c-accent-deep));
    border-radius: 18px 0 0 18px;
    text-align: center;
}
/* Đốm halftone trắng trên cuống — chất giấy in của voucher. Nằm dưới chữ nhờ
   .ticket__stub > * { position: relative }. */
.ticket__stub::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(255, 255, 255, .28) 1.3px, transparent 1.4px);
    background-size: 9px 9px;
    -webkit-mask-image: linear-gradient(160deg, #000 10%, transparent 65%);
    mask-image: linear-gradient(160deg, #000 10%, transparent 65%);
    pointer-events: none;
}
.ticket__stub > * { position: relative; }
.ticket__big {
    /* Bản chốt: con số % chuyển sang FONT DISPLAY — nó là thứ to nhất trên vé, phải
       nói giọng voucher chứ không phải giọng hoá đơn. Chữ "OFF" bên dưới vẫn mono:
       vai "dữ kiện" không mất, chỉ chuyển xuống dòng phụ. */
    font-family: var(--font-display);
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: -.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}
.ticket__small {
    font-family: var(--font-mono);
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    opacity: .9;
}

/* Nửa phải. Đường đục lỗ vẽ ở ĐÂY (không phải ở stub) — nửa phải nằm sau trong
   DOM nên nét đứt luôn nổi lên trên, không bị nền trắng đè mất như bản trước. */
.ticket__main {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    padding: var(--sp-3);
    border-left: 2px dashed #c8d1cd;
}
/* Đốm teal nhạt toả từ góc dưới-phải: đối trọng của đốm trắng trên cuống. */
.ticket__main::before {
    content: "";
    position: absolute;
    bottom: -6px;
    right: -6px;
    width: 120px;
    height: 78px;
    background-image: radial-gradient(rgba(12, 130, 113, .2) 1.3px, transparent 1.4px);
    background-size: 9px 9px;
    -webkit-mask-image: linear-gradient(225deg, #000 20%, transparent 75%);
    mask-image: linear-gradient(225deg, #000 20%, transparent 75%);
    pointer-events: none;
}
.ticket__store { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.ticket__name {
    font-size: .95rem;
    font-weight: 700;
    color: var(--c-ink);
    overflow-wrap: anywhere;
    /* Tên brand dài (vd "DAYALANE Furniture Affiliate Program - Premium Home &
       Dining") từng kéo dài vé ra và phá hàng → chặn ở 2 dòng. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.ticket__name:hover { color: var(--c-accent); text-decoration: none; }
.ticket__details {
    margin: 0;
    font-size: .8rem;
    color: var(--c-muted);
    display: -webkit-box;
    -webkit-line-clamp: 1;   /* 1 dòng: dòng thứ 2 chỉ lặp lại thứ cuống vé đã nói */
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.ticket__action {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: var(--sp-1);
}
/* Mã: plugin JS che thành SAVE•••• (đừng in mã bằng CSS content — hợp đồng cấm). */
.ticket .cpn-code {
    padding: var(--sp-1) var(--sp-2);
    font-family: var(--font-mono);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--c-ink);
    background: var(--c-page);
    border: 1.5px dashed var(--c-accent);   /* chip mã: nét đứt teal, đọc ra là "xé được" */
    border-radius: var(--r-sm);
    overflow-wrap: anywhere;
}
.ticket .cpn-show,
.ticket .cpn-deal { margin-left: 0; border-radius: 999px; }

 /* Dấu PROOF — lý do site tên PromoProof. Ngày verify + số nguồn là bằng chứng
    THẬT lấy từ blob v2; in mono cạnh một dấu tick tự vẽ. Không có data → template
    không in dòng này (không có dấu rỗng). */
.ticket__date {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    margin: 0;
    font-size: .68rem;
    color: var(--c-muted);
}
.ticket__date svg { flex: 0 0 auto; color: var(--c-accent); }
.ticket__date.is-urgent {
    align-self: flex-start;
    padding: 2px var(--sp-2);
    color: var(--c-warn-ink);
    background: var(--c-warn-bg);
    border-radius: 999px;
}
.ticket__date.is-urgent svg { color: var(--c-warn-ink); }

/* Mobile hẹp: vé xếp DỌC — cuống lên trên, lỗ khuyết chuyển sang 2 cạnh bên. */
@media (max-width: 439px) {
    .ticket__row {
        /* --stub ở desktop là CHIỀU RỘNG cột; ở đây nó thành CHIỀU CAO thanh ngang.
           Để nguyên 104px thì thành một dải teal trống hoác chỉ chứa "85% OFF". */
        --stub: 54px;
        grid-template-columns: 1fr;
        grid-template-rows: var(--stub) auto;
        /* Vé xếp DỌC → cặp lỗ to chuyển sang 2 CẠNH BÊN, đúng ngang ranh cuống/thân.
           Cặp lỗ nhỏ bỏ hẳn: ở bề ngang 375px nó rơi vào giữa chữ. */
        -webkit-mask-image:
            radial-gradient(circle 10px at 0 var(--stub),    transparent 98%, #000 100%),
            radial-gradient(circle 10px at 100% var(--stub), transparent 98%, #000 100%);
        -webkit-mask-composite: source-in;
        mask-image:
            radial-gradient(circle 10px at 0 var(--stub),    transparent 98%, #000 100%),
            radial-gradient(circle 10px at 100% var(--stub), transparent 98%, #000 100%);
        mask-composite: intersect;
    }
    .ticket__stub {
        flex-direction: row;
        gap: var(--sp-2);
        align-items: baseline;
        border-radius: 18px 18px 0 0;
    }
    .ticket__main {
        border-left: 0;
        border-top: 2px dashed #c8d1cd;   /* đường xé chuyển sang nằm ngang */
    }
}

/* ---------- 10. Browse by letter ---------- */
.letter-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding: 0;
    margin: 0;
    list-style: none;
}
.letter-grid a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    font-family: var(--font-mono);
    font-weight: 600;
    color: var(--c-ink);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: 50%;
    transition: transform .15s ease, background .15s ease, color .15s ease;
}
.letter-grid a:hover {
    transform: translateY(-2px);
    color: var(--c-accent-dark);
    background: var(--c-accent-soft);
    border-color: var(--c-accent-soft);
    text-decoration: none;
}
.letter-grid a[aria-current="page"] {
    color: #fff;
    background: var(--c-accent);
    border-color: var(--c-accent);
}

/* ---------- 11. Trang store (single) ---------- */
.store-layout { display: block; }
@media (min-width: 960px) {
    .store-layout {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 300px;
        gap: var(--sp-6);
        align-items: start;
    }
}

/* HERO trang store = NỬA TRÊN CỦA CHIẾC VÉ.
   Cùng ngôn ngữ với card mã (commit a3167aa): mép dưới có đường đục lỗ nét đứt
   và 2 lỗ tròn khuyết ở hai đầu — trang store và card mã nói cùng một thứ tiếng,
   không chế phong cách thứ hai.
   Màu: --store-hue do PHP đổ xuống, sinh từ md5(domain) → mỗi store một tông,
   ổn định. 0 byte tải từ ngoài: gradient + repeating-gradient thuần CSS, không
   ảnh stock, không ảnh AI, không đọc màu từ logo. */
.store-hero {
    --hue: var(--store-hue, 200);
    --notch: 12px;
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-bottom: var(--sp-5);
    padding: var(--sp-5) var(--sp-5) var(--sp-6);
    border-radius: var(--r-lg);
    background:
        /* sợi vân chéo rất nhạt — chất giấy của vé, không phải hoạ tiết ồn ào */
        repeating-linear-gradient(135deg,
            rgba(255, 255, 255, .45) 0 2px,
            transparent 2px 11px),
        linear-gradient(135deg,
            hsl(var(--hue) 72% 93%),
            hsl(calc(var(--hue) + 28) 62% 82%));
    box-shadow: inset 0 0 0 1px hsl(var(--hue) 45% 78%);

    /* 2 lỗ tròn khuyết ở hai đầu đường xé (đáy hero) */
    -webkit-mask-image:
        radial-gradient(circle var(--notch) at 0 100%, transparent 98%, #000 100%),
        radial-gradient(circle var(--notch) at 100% 100%, transparent 98%, #000 100%);
    -webkit-mask-composite: source-in;
    mask-image:
        radial-gradient(circle var(--notch) at 0 100%, transparent 98%, #000 100%),
        radial-gradient(circle var(--notch) at 100% 100%, transparent 98%, #000 100%);
    mask-composite: intersect;
}
/* Đường xé nét đứt nối 2 lỗ khuyết */
.store-hero::after {
    content: "";
    position: absolute;
    left: var(--notch);
    right: var(--notch);
    bottom: 0;
    border-bottom: 2px dashed hsl(var(--hue) 40% 70%);
}

.store-hero h1 { margin: 0; }
.store-hero__text { min-width: 0; flex: 1 1 260px; }
/* Dòng dữ kiện dưới H1: domain [· category]. Category chưa có → chỉ còn domain,
   dấu chấm ngăn cách cũng biến mất theo (dùng ::before của chip, không phải
   separator rời) → không bao giờ lòi ra dấu "·" cụt. */
.store-hero__facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
    margin: var(--sp-2) 0 0;
    color: hsl(var(--hue) 35% 28%);
}
.store-hero__domain { color: inherit; }
.store-hero__cat {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--sp-2);
    color: hsl(var(--hue) 40% 24%);
    background: rgba(255, 255, 255, .72);
    border: 1px solid rgba(255, 255, 255, .9);
    border-radius: 999px;
}
a.store-hero__cat:hover { background: #fff; text-decoration: none; }

/* Logo to hơn, nổi trên nền màu store: thẻ trắng, viền mảnh, bóng 1 lớp.
   Cơ chế fallback chữ cái (favicon chết → onerror gỡ ảnh) GIỮ NGUYÊN —
   nền chữ cái vẫn là hsl(--logo-hue) của store-logo.php. */
.store-hero .store-logo {
    border-color: #fff;
    box-shadow: 0 8px 20px hsl(var(--hue) 40% 40% / .18);
}

@media (max-width: 599px) {
    .store-hero { padding: var(--sp-4) var(--sp-4) var(--sp-5); }
    .store-hero h1 { font-size: 1.5rem; }
}

.store-content > p:first-child { font-size: 1.05rem; color: var(--c-text); }
.store-content > p:last-child em {
    display: block;
    padding: var(--sp-3) var(--sp-4);
    font-size: .875rem;
    font-style: normal;
    color: var(--c-muted);
    background: var(--c-bg);
    border-radius: var(--r);
}

/* Khối facts → hàng badge */
.store-content .merchant-facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin: var(--sp-5) 0;
    padding: 0;
    list-style: none;
}
.store-content .merchant-facts li {
    padding: var(--sp-2) var(--sp-3);
    font-size: .85rem;
    background: var(--c-page);
    border: 1px solid var(--c-border);
    border-radius: 999px;
}
.store-content .merchant-facts strong { font-weight: 650; color: var(--c-muted); }

/* Bảng mã của tool → danh sách card. Cột: 1 Code · 2 Discount · 3 Details · 4 Expires.
   KHÔNG gỡ .cpn-codes [hidden]{display:none!important} của plugin (luật lọc). */
.store-content .wp-block-table { margin: 0; }
.store-content .wp-block-table table { display: block; width: 100%; border-collapse: collapse; }
.store-content .wp-block-table thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
}
.store-content .wp-block-table tbody { display: grid; gap: var(--sp-3); }
.store-content .wp-block-table tr {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-areas: "discount" "details" "code" "expires" "proof";
    gap: var(--sp-1) var(--sp-4);
    padding: var(--sp-4);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    transition: transform .18s ease, box-shadow .18s ease;
}
.store-content .wp-block-table tr:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.store-content .wp-block-table td { padding: 0; border: 0; min-width: 0; }

/* Dấu PROOF trên từng mã. data-verified do plugin/tool gắn sẵn trên .cpn-row
   (hợp đồng markup mục 2) — CSS chỉ in lại BẰNG CHỨNG CÓ THẬT, không bịa.
   Mã không có tín hiệu này → không có pseudo → không dòng nào.

   CHỮ LÀ "LAST SEEN", KHÔNG PHẢI "VERIFIED" — đây là luật, không phải sở thích:
   ticket trang chủ (giaodien.php:451-476) chỉ được nói "Verified" khi mã do chính
   merchant nộp qua affiliate network (source_type='network'); còn lại nói "Last
   seen" vì thứ tool đo được chỉ là "ngày X mã này VẪN CÒN ĐƯỢC LIỆT KÊ" trên site
   nguồn — không phải "đã thử ở checkout". attr(data-verified) KHÔNG mang theo
   nguồn, nên CSS không có cách nào phân biệt → phải nói câu yếu hơn, câu đúng.
   Nếu nói "Verified" ở đây thì trang store và trang chủ nói KHÁC NHAU về cùng một
   mã — tự vạch nhau đúng thứ site đem bán. Chưa nổ vì bài v1 không sinh
   data-verified; nổ ngay hôm sink v2 đẩy bài.
   Muốn chữ "Verified" sáng lại đúng chỗ → render.php phải gắn thêm nguồn
   (data-verified-src="network"); đó là vùng [tinhnang] → docs/fix_backlog.md. */
.store-content .cpn-row[data-verified]::after {
    grid-area: proof;
    content: "Last seen " attr(data-verified);
    font-family: var(--font-mono);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--c-muted);
}

/* Mã KHÔNG có hạn dùng: tool vẫn in "—" vào ô Expires. Dấu gạch trơ đó không
   nói gì cả → ẩn hẳn ô (spec: không có expires thì không hiện gì, đừng bịa).
   Tool v2 ghi data-expires="" rỗng, plugin thì bỏ hẳn attribute → chặn cả hai. */
.store-content .cpn-row:not([data-expires]) td:nth-child(4),
.store-content .cpn-row[data-expires=""] td:nth-child(4) { display: none; }

.store-content .wp-block-table td:nth-child(1) {
    grid-area: code;
    margin-top: var(--sp-2);
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}
.store-content .wp-block-table td:nth-child(1) code {
    display: inline-block;
    padding: var(--sp-2) var(--sp-4);
    font-family: var(--font-mono);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--c-accent-dark);
    background: var(--c-code-bg);
    border: 1px dashed var(--c-accent);
    border-radius: var(--r-sm);
    overflow-wrap: anywhere;
}
.store-content .wp-block-table td:nth-child(2) {
    grid-area: discount;
    font-family: var(--font-mono);   /* dữ kiện → mono, cùng giọng với vé */
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
    color: var(--c-accent-dark);
}
.store-content .wp-block-table td:nth-child(3) { grid-area: details; }
.store-content .wp-block-table td:nth-child(4) {
    grid-area: expires;
    font-family: var(--font-mono);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--c-muted);
}

@media (min-width: 600px) {
    .store-content .wp-block-table tr {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "discount code"
            "details  code"
            "expires  code"
            "proof    code";
        align-items: center;
    }
    .store-content .wp-block-table td:nth-child(1) { margin-top: 0; justify-self: end; }
}

/* Related stores */
.related-stores {
    margin-top: var(--sp-6);
    padding: var(--sp-4);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
}
.related-stores h2 { font-size: 1.05rem; margin-bottom: var(--sp-3); }
.related-stores ul { margin: 0; padding: 0; list-style: none; }
.related-stores li + li { margin-top: var(--sp-1); padding-top: var(--sp-1); border-top: 1px dashed var(--c-dash); }
.related-stores a { display: block; padding: var(--sp-2) 0; color: var(--c-text); font-size: .95rem; }
.related-stores a:hover { color: var(--c-accent); }
@media (min-width: 960px) {
    .related-stores { position: sticky; top: var(--sp-4); margin-top: 0; }
}

/* ---------- 12. Pagination, empty state, trang tĩnh ---------- */
.pagination { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-6); }
.pagination .page-numbers {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 42px;
    height: 42px;
    padding: 0 var(--sp-3);
    color: var(--c-ink);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
}
.pagination .page-numbers:hover { border-color: var(--c-accent); text-decoration: none; }
.pagination .page-numbers.current { color: #fff; background: var(--c-accent); border-color: var(--c-accent); }
.pagination .dots { border-color: transparent; }

/* Màn hình rỗng là một LỜI MỜI HÀNH ĐỘNG, không phải lời xin lỗi: nói đúng
   chuyện gì xảy ra rồi đưa ngay đường đi tiếp (ô tìm + bảng chữ cái). */
.empty-state {
    padding: var(--sp-6);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);   /* nét đứt: cùng texture với vé */
    border-radius: var(--r-lg);
}
.empty-state__head { margin: 0 0 var(--sp-2); font-size: 1.15rem; color: var(--c-ink); font-weight: 700; }
.empty-state p { margin: 0; max-width: 52ch; color: var(--c-muted); }
.empty-state .search-form { max-width: 28rem; margin: var(--sp-4) 0 0; }

/* ---------- 13. TRANG TĨNH (About / Contact / Privacy / Terms / Disclosure / How-to)
   Template do [seo] sinh (.static-page > h1.page-title + .static-content) —
   theme chỉ style. page.php (trang chưa gán template) dùng lại y hệt class này. */
/* Template [seo] KHÔNG bọc .wrap → tự canh lề ở đây, nếu không chữ dính mép trái.
   Khung hẹp (820px) và canh giữa: trang tĩnh chỉ có MỘT cột chữ — thả nó vào
   khung 1180px của trang chủ thì nửa phải trống hoác, trông như quên làm nốt. */
.static-page {
    width: 100%;
    max-width: 820px;
    margin: 0 auto;
    padding: var(--sp-5) var(--sp-4) var(--sp-7);
}
.static-page .page-title {
    max-width: 20ch;             /* tiêu đề ngắn, gãy dòng có chủ đích */
    margin-bottom: var(--sp-4);
    padding-bottom: var(--sp-4);
    border-bottom: 2px dashed var(--c-dash);   /* mép đục lỗ mở đầu trang */
}

.static-content {
    max-width: 66ch;             /* measure đọc dài: ~66 ký tự/dòng */
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--c-text);
}
.static-content > * + * { margin-top: var(--sp-4); }

/* Nguồn 6 trang tĩnh gõ xuống dòng cứng ~70 ký tự/dòng → WordPress (wpautop)
   biến mỗi newline thành <br>, câu bị bẻ giữa chừng ("...nothing if it / only
   applies..."). Không có <br> nào mang nghĩa (đã soi cả 6 trang) → bỏ, để chữ
   tự chảy theo measure.
   [seo] cần ngắt dòng THẬT (địa chỉ, thơ...): bọc trong .keep-breaks. */
.static-content br { display: none; }
.static-content .keep-breaks br { display: inline; }

/* Mỗi mục lớn mở bằng một đường đục lỗ — chia mục, không trang trí. */
.static-content h2 {
    margin-top: var(--sp-7);
    padding-top: var(--sp-4);
    border-top: 1px dashed var(--c-dash);
    font-size: 1.3rem;
}
.static-content h3 { margin-top: var(--sp-5); font-size: 1.05rem; }
.static-content strong { color: var(--c-ink); font-weight: 700; }
.static-content a { text-decoration: underline; text-underline-offset: 3px; }

/* Danh sách gạch đầu dòng: dấu gạch mảnh màu accent, không bullet tròn mặc định. */
.static-content ul { margin-left: 0; padding-left: 0; list-style: none; }
.static-content ul > li {
    position: relative;
    padding-left: var(--sp-5);
    margin-top: var(--sp-2);
}
.static-content ul > li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .85em;
    width: 12px;
    height: 2px;
    background: var(--c-accent);
}

/* SIGNATURE — QUY TRÌNH THẬT (vd 6 bước dùng mã ở trang How to use promo codes):
   số bước in trên CUỐNG VÉ teal có mép đứt, đúng thế giới của coupon.
   Chỉ <ol> mới được đánh số: ở đây thứ tự MANG THÔNG TIN (làm sai thứ tự là hỏng).
   Danh sách không tuần tự (<ul>) tuyệt đối không đánh số. */
.static-content ol {
    counter-reset: step;
    margin-left: 0;
    padding-left: 0;
    list-style: none;
}
/* LƯU Ý: KHÔNG dùng display:grid trên <li>. Nội dung li là inline (strong, <br>,
   text) — grid biến từng cụm thành một ô lưới riêng, chữ rơi vào cột 44px và
   xếp dọc từng từ (đã dính đúng lỗi này). Cuống vé đặt absolute, chữ chảy inline. */
.static-content ol > li {
    counter-increment: step;
    position: relative;
    padding: var(--sp-3) 0 var(--sp-3) 60px;
    margin-top: 0;
    min-height: 60px;
    border-bottom: 1px dashed var(--c-dash);
}
.static-content ol > li:last-child { border-bottom: 0; }
.static-content ol > li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: var(--sp-3);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 36px;
    font-family: var(--font-mono);
    font-size: 1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #fff;
    background: linear-gradient(160deg, var(--c-accent), var(--c-accent-dark));
    border-radius: var(--r-sm);
}

/* Trang chưa gán template (page.php) — dùng lại đúng ngôn ngữ trên. */
.entry-content { max-width: 66ch; }

/* ---------- 14. TRANG HUB DEAL (page-deals-hub.php — markup của [seo]) ----------
   Bố cục [seo] dựng là CỐ Ý, CSS không đảo: breadcrumb → H1 → intro → DANH SÁCH
   STORE → bài văn → dòng "how this list is built". Danh sách đứng trước bài văn
   vì đó là đường ra tiền.
   Class do [seo] cam kết giữ ổn định — theme chỉ style, không sửa template họ. */
.deals-hub {
    width: 100%;
    max-width: 820px;
    margin: 0 auto;
    padding: var(--sp-5) var(--sp-4) var(--sp-7);
}
.deals-hub .page-title {
    margin-bottom: var(--sp-4);
    padding-bottom: var(--sp-4);
    border-bottom: 2px dashed var(--c-dash);
}

.hub-intro { margin-bottom: var(--sp-5); }
.hub-blurb {
    margin: 0;
    max-width: 62ch;
    font-size: 1.05rem;
    line-height: 1.7;
}
/* Trạng thái sự kiện + số store: DỮ KIỆN → mono (giọng chung của site). */
.hub-status,
.hub-count {
    margin: var(--sp-3) 0 0;
    font-family: var(--font-mono);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    color: var(--c-muted);
}
.hub-status {
    display: inline-block;
    padding: var(--sp-1) var(--sp-3);
    color: var(--c-accent-dark);
    background: var(--c-accent-soft);
    border-radius: 999px;
}

/* Danh sách store: xếp hạng là THÔNG TIN THẬT (sắp theo mức giảm verify được)
   → số thứ tự có nghĩa, in mono. */
.hub-list {
    counter-reset: rank;
    margin: 0;
    padding: 0;
    list-style: none;
}
.hub-store {
    counter-increment: rank;
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-3) var(--sp-3) var(--sp-3) 52px;
    border-bottom: 1px dashed var(--c-dash);
    transition: background .15s ease;
}
.hub-store:hover { background: var(--c-surface); }
.hub-store:last-child { border-bottom: 0; }
.hub-store::before {
    content: counter(rank);
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    text-align: right;
    font-family: var(--font-mono);
    font-size: .8rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--c-muted);
}
.hub-store-link {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-3);
    flex: 1 1 auto;
    min-width: 0;
}
.hub-store-link:hover { text-decoration: none; }
.hub-store-name {
    font-weight: 700;
    color: var(--c-ink);
    /* `anywhere` chứ KHÔNG `break-word`: hai cái nhìn giống nhau nhưng chỉ
       `anywhere` làm giảm chiều rộng min-content của flex item. Với
       `break-word`, tên hãng là một chuỗi liền không dấu cách
       (Guangzhoumaiyuandianzishangwuyouxiangongsi — merchant thật trong kho)
       vẫn đẩy .hub-store-link rộng ra và làm TRÀN NGANG cả trang ở 375px
       (đo 14/07: /fashion-apparel/ scrollWidth 429 > 375). */
    overflow-wrap: anywhere;
    min-width: 0;
}
.hub-store-link:hover .hub-store-name { color: var(--c-accent); }
/* Mức giảm = điểm nhấn, bên phải, mono như mọi con số khác trên site. */
.hub-store-best {
    padding: 2px var(--sp-2);
    font-family: var(--font-mono);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--c-accent-dark);
    background: var(--c-accent-soft);
    border-radius: 999px;
    white-space: nowrap;
}
.hub-store-meta {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: .72rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--c-muted);
    white-space: nowrap;
}

/* Bài văn dưới danh sách + dòng "how this list is built" */
.deals-hub .entry-content,
.deals-hub .static-content { margin-top: var(--sp-6); }
.hub-method {
    margin-top: var(--sp-6);
    padding-top: var(--sp-4);
    border-top: 1px dashed var(--c-dash);
    font-size: .875rem;
    color: var(--c-muted);
}
.hub-empty {
    padding: var(--sp-5);
    color: var(--c-muted);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-radius: var(--r-lg);
}

/* Mobile: tên store dài + số mã cùng một hàng thì số mã bị đẩy rơi lệch giữa
   các dòng. Cho nó hẳn một dòng riêng, canh trái theo tên. */
@media (max-width: 599px) {
    .hub-store { padding-left: 40px; }
    .hub-store::before { width: 28px; }
    .hub-store-meta { flex-basis: 100%; margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
    .evt:hover, .ticket:hover, .store-card:hover, .letter-grid a:hover { transform: none; }
}

/* ---------- 16. FAQ ----------
   MỘT bộ style cho HAI nơi: khối FAQ trang chủ (front-page.php) và khối FAQ cuối
   trang store do [seo] in ra (store-faq.php, filter the_content). Họ đã in
   .store-faq > .faq-item > h3 + p từ lâu nhưng CSS chưa có một dòng nào → trên
   trang store nó đang hiện ra như chữ trần. Bám đúng class của họ, không đòi họ
   đổi markup.

   Chữ "Q" mono trước câu hỏi: cùng giọng "dữ kiện" của vé và của bảng xếp hạng. */
.store-faq {
    margin-top: var(--sp-6);
    padding-top: var(--sp-5);
    border-top: 2px dashed var(--c-dash);
}
.store-faq > h2 { margin: 0 0 var(--sp-2); font-size: 1.25rem; }

.faq-list { display: grid; }
@media (min-width: 900px) {
    /* Trang chủ: 2 cột (5 câu xếp một cột dọc thì khối dài lê thê ở cuối trang). */
    .home-faq .faq-list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: var(--sp-7);
    }
}
.faq-list, .store-faq { border-bottom: 1px dashed var(--c-dash); }

.faq-item {
    padding: var(--sp-4) 0;
    border-top: 1px dashed var(--c-dash);
    max-width: 72ch;
}
.faq-item h3 {
    display: flex;
    gap: var(--sp-2);
    margin: 0 0 var(--sp-2);
    font-size: 1rem;
    font-weight: 700;
    color: var(--c-ink);
}
.faq-item h3::before {
    content: "Q";
    flex: 0 0 auto;
    font-family: var(--font-mono);
    font-weight: 700;
    color: var(--c-accent);
}
.faq-item p {
    margin: 0;
    padding-left: calc(1ch + var(--sp-2));   /* thẳng hàng với chữ câu hỏi, không phải với Q */
    color: var(--c-text);
    line-height: 1.65;
}

/* ---------- 15. BLOG / GUIDES (CPT 'guide' — markup của [seo], plugin coupon-seo)
   Cùng luật với mục 13/14: [seo] giữ markup, theme chỉ style.
   Class [seo] cam kết giữ ổn định:
     archive  .guide-archive > .page-title + .page-subtitle + ul.guide-list > li.guide-card
     bài      .guide-page > article.guide > .page-title + .guide-meta + .guide-content
     trang chủ .guide-list--home (biến thể lưới, nằm TRONG .wrap 1180px)
     trang brand .brand-guides (khối "Guides for this brand")
     shortcode .stats-table + .stats-note
   Template [seo] KHÔNG bọc .wrap -> tự canh lề, y hệt .static-page. */
.guide-archive,
.guide-page {
    width: 100%;
    max-width: 820px;
    margin: 0 auto;
    padding: var(--sp-5) var(--sp-4) var(--sp-7);
}
.guide-archive .page-title,
.guide-page .page-title {
    margin-bottom: var(--sp-4);
    padding-bottom: var(--sp-4);
    border-bottom: 2px dashed var(--c-dash);   /* mép đục lỗ mở đầu trang, như trang tĩnh */
}
.guide-archive .page-subtitle {
    max-width: 60ch;
    margin: 0 0 var(--sp-6);
    color: var(--c-muted);
    line-height: 1.65;
}

/* Dòng tác giả + ngày. Ngày đã là .fact (mono) từ template -> ở đây chỉ lo màu/cỡ. */
.guide-meta {
    margin: calc(var(--sp-4) * -1) 0 var(--sp-6);
    font-size: .9rem;
    color: var(--c-muted);
}
.guide-meta .fact { color: var(--c-muted); }

/* ----- Thân bài ----- */
.guide-content {
    max-width: 66ch;             /* measure đọc dài, giống .static-content */
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--c-text);        /* KHÔNG để thừa hưởng màu accent: chữ là chữ, link mới xanh */
}
.guide-content > * + * { margin-top: var(--sp-4); }
.guide-content h2 {
    margin-top: var(--sp-7);
    color: var(--c-ink);
    line-height: 1.3;
}
.guide-content h3 {
    margin-top: var(--sp-5);
    color: var(--c-ink);
}
.guide-content a { text-decoration: underline; text-underline-offset: 2px; }
.guide-content strong { color: var(--c-ink); font-weight: 700; }
.guide-content ul,
.guide-content ol { padding-left: var(--sp-5); }
.guide-content li + li { margin-top: var(--sp-2); }

/* Trích fine print của hãng — đây là bằng chứng, cho nó ra dáng bằng chứng. */
.guide-content blockquote {
    margin-left: 0;
    margin-right: 0;
    padding: var(--sp-4);
    color: var(--c-ink);
    background: var(--c-bg);
    border-left: 3px solid var(--c-accent);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.guide-content blockquote p { margin: 0; }

/* ----- Bảng trong bài ----- */
.guide-content table {
    width: 100%;
    border-collapse: collapse;
    font-size: .95rem;
}
.guide-content th {
    padding: var(--sp-2) var(--sp-3);
    text-align: left;
    font-family: var(--font-mono);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--c-muted);
    border-bottom: 2px dashed var(--c-dash);
}
.guide-content td {
    padding: var(--sp-3);
    border-bottom: 1px solid var(--c-border);
    vertical-align: top;
}

/* ----- Biểu đồ [cseo_stats]: số THẬT, vẽ bằng CSS, không ảnh ----- */
.stats-block {
    padding: var(--sp-5);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-radius: var(--r-lg);
}
.stats-total {
    display: flex;
    align-items: baseline;
    gap: var(--sp-3);
    margin: 0 0 var(--sp-5);
    padding-bottom: var(--sp-4);
    border-bottom: 2px dashed var(--c-dash);
}
.stats-total b {
    font-size: clamp(1.8rem, 1.4rem + 2vw, 2.6rem);
    font-weight: 700;
    letter-spacing: 0;               /* đè letter-spacing của .fact: số to không cần giãn */
    text-transform: none;
    color: var(--c-ink);
    font-variant-numeric: tabular-nums;
}
.stats-total span { color: var(--c-muted); line-height: 1.4; }

.stats-bars { list-style: none; margin: 0; padding: 0; }
.stats-bar + .stats-bar { margin-top: var(--sp-4); }
.stats-bar__label {
    display: block;
    margin-bottom: var(--sp-2);
    color: var(--c-ink);
    font-size: .95rem;
}
.stats-bar__track {
    display: block;
    height: 10px;
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: 999px;
    overflow: hidden;
}
.stats-bar__fill {
    display: block;
    height: 100%;
    min-width: 2px;                  /* 0.5% van phai THAY duoc — thanh tang hinh la mat thong tin */
    background: linear-gradient(90deg, var(--c-accent), var(--c-accent-dark));
    border-radius: 999px;
}
.stats-bar__val {
    display: block;
    margin-top: var(--sp-1);
    color: var(--c-muted);
    font-variant-numeric: tabular-nums;
}
.stats-note {
    font-size: .875rem;
    color: var(--c-muted);
}

/* ----- "Vé" của bài: logo hãng THẬT (favicon) + con số cốt lõi ----- */
.guide-ticket {
    position: relative;
    margin: var(--sp-6) 0;
    padding: var(--sp-5);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-radius: var(--r-lg);
}
.guide-ticket__head {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
.guide-ticket__brand { color: var(--c-muted); }
.guide-ticket__stat {
    margin: 0;
    font-family: var(--font-mono);
    font-size: clamp(1.9rem, 1.4rem + 2.4vw, 2.8rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.01em;
    color: var(--c-ink);
    font-variant-numeric: tabular-nums;
}
.guide-ticket__sub {
    margin: var(--sp-2) 0 0;
    max-width: 40ch;
    color: var(--c-text);
    line-height: 1.5;
}
/* Chân vé — đường đục lỗ, texture chủ đạo của site. */
.guide-ticket__foot {
    margin: var(--sp-4) 0 0;
    padding-top: var(--sp-3);
    border-top: 2px dashed var(--c-dash);
    color: var(--c-muted);
}

/* ----- THẺ BÀI (dùng chung /blog/ + trang chủ) -----
   Thứ bậc theo Morningstar DS / USWDS / NN/g (nghiên cứu 14/07/2026):
       chuyên mục (nhỏ) -> TIÊU ĐỀ (to nhất) -> excerpt (mờ) -> ngày (mờ nhất)
   Bản cũ lấy CON SỐ làm dòng to nhất và dìm tiêu đề xuống dưới. Sai: tiêu đề là
   LINK LABEL, mà link label phải tự đứng được ngoài ngữ cảnh — "7" thì không.
   Con số to chỉ đúng ở KPI/dashboard, nơi con số CHÍNH LÀ nội dung.
   Không design system nào, không site coupon nào (KCL, MoneySavingExpert,
   Rakuten, CouponFollow) đặt thứ gì to hơn tiêu đề trên thẻ bài. */
.guide-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.guide-card {
    position: relative;                        /* mỏ neo cho lớp phủ link ở dưới */
    padding: var(--sp-5) 0;
    border-bottom: 1px dashed var(--c-dash);
}
.guide-archive .guide-card:first-child { padding-top: 0; }

/* 1. Eyebrow = chuyên mục (+ favicon hãng nếu bài nói về một hãng cụ thể).
   ĐÂY là thứ tạo biến hoá thị giác thay cho ảnh — site cấm ảnh stock/AI.
   Không có chuyên mục lẫn logo -> PHP không in dòng này. Không chừa chỗ,
   không in "Uncategorized". */
.guide-kicker {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin: 0 0 var(--sp-2);
    color: var(--c-muted);
}
.guide-kicker .store-logo { flex: 0 0 auto; }

/* 2. TIÊU ĐỀ — to nhất, đậm nhất, tương phản cao nhất. Và là cái <a>. */
.guide-card-title {
    margin: 0 0 var(--sp-2);
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
}
.guide-card-title a { color: var(--c-ink); }
.guide-card-title a:hover { color: var(--c-accent); text-decoration: none; }
/* Bấm đâu trên thẻ cũng vào bài, NHƯNG link vẫn chỉ là một cái, bọc đúng tiêu đề
   -> screen reader đọc "link: <tên bài>", không đọc cả cục thẻ. (Yêu cầu a11y,
   không phải lựa chọn thẩm mỹ.) */
.guide-card-title a::after {
    content: "";
    position: absolute;
    inset: 0;
}

/* 3. Excerpt — mờ hơn tiêu đề, measure ngắn cho dễ quét. */
.guide-card-excerpt {
    margin: 0 0 var(--sp-3);
    max-width: 62ch;
    font-size: .95rem;
    color: var(--c-muted);
    line-height: 1.6;
}

/* 4. Ngày — mờ nhất. */
.guide-card-date { margin: 0; color: var(--c-muted); }

/* MÀU THEO CHUYÊN MỤC — "engine" biến hoá thị giác của một site không có ảnh.
   Thêm chuyên mục mới -> thêm 1 rule ở đây; thiếu rule thì chữ rơi về --c-muted,
   vẫn đọc được, không vỡ. */
.guide-kicker--brand-guide span { color: var(--c-accent); }
.guide-kicker--data span        { color: #b45309; }   /* hổ phách */
.guide-kicker--how-to span      { color: #4338ca; }   /* chàm */

/* ----- Biến thể trang chủ: lưới, nằm trong .wrap 1180px ----- */
.guide-list--home {
    display: grid;
    gap: var(--sp-4);
    grid-template-columns: 1fr;
}
/* flex-column để NGÀY tụt hẳn xuống đáy (margin-top:auto): các thẻ bị kéo cao
   bằng thẻ dài nhất, không ghim thì thẻ ngắn chừa một mảng trống chết ở đáy. */
.guide-list--home .guide-card {
    display: flex;
    flex-direction: column;
    padding: var(--sp-5);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-bottom: 1px dashed var(--c-dash);
    border-radius: var(--r-lg);
    transition: box-shadow .15s ease, border-color .15s ease;
}
.guide-list--home .guide-card-date {
    margin-top: auto;
    padding-top: var(--sp-4);
}
.guide-list--home .guide-card:hover {
    border-color: var(--c-accent);
    box-shadow: var(--shadow);
}
.guide-list--home .guide-card-title { font-size: 1.1rem; }
.section-more {
    margin: var(--sp-4) 0 0;
    font-weight: 600;
}

/* ----- Khối "Guides for this brand" trên trang store ----- */
.brand-guides {
    margin-top: var(--sp-6);
    padding: var(--sp-5);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-radius: var(--r-lg);
}
.brand-guides h2 {
    margin: 0 0 var(--sp-3);
    font-size: 1.1rem;
    color: var(--c-ink);
}
.brand-guides ul { margin: 0; padding-left: var(--sp-5); }
.brand-guides li + li { margin-top: var(--sp-2); }

@media (min-width: 700px) {
    .guide-list--home { grid-template-columns: repeat(3, 1fr); }
}

/* Mobile: bảng 3-4 cột không nhét vừa 375px. Cho CHÍNH cái bảng cuộn ngang
   (display:block biến nó thành khối cuộn được) thay vì ép chữ vỡ vụn — và quan
   trọng hơn: thay vì đẩy cả trang tràn ngang. */
@media (max-width: 599px) {
    .guide-content table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}


/* ---------- 17. Browse by category ----------
   Ô category = TRỤC BROWSE, không phải chip trang trí: mỗi ô mang một SỐ THẬT
   (số brand, đếm từ bài) nên nó nói được thứ thanh menu không nói được.
   Category chưa có trang đích ([seo] chưa dựng) → .cat-tile__off: cùng hình hài
   nhưng xám, không hover, không con trỏ tay — nhìn là biết chưa bấm được, thay vì
   bấm vào rồi lạc. */
.cat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--sp-3);
    margin: 0;
    padding: 0;
    list-style: none;
}
.cat-tile a,
.cat-tile__off {
    display: flex;
    flex-direction: column;
    gap: 2px;
    height: 100%;
    padding: var(--sp-3) var(--sp-4);
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: var(--r);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.cat-tile a:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow);
    border-color: var(--c-accent);
    text-decoration: none;
}
.cat-tile__off {
    background: var(--c-surface);
    border-style: dashed;
    border-color: var(--c-dash);
}
.cat-tile__name {
    font-weight: 650;
    line-height: 1.3;
    color: var(--c-ink);
    overflow-wrap: break-word;
}
.cat-tile__off .cat-tile__name { color: var(--c-muted); }
.cat-tile__count { color: var(--c-muted); }

/* Ô của chính ngành đang xem: viền đậm + không nhấc lên khi hover (bấm lại chính
   nó thì đi đâu?). Cùng ngôn ngữ với .letter-grid a[aria-current]. */
.cat-tile a[aria-current="page"] {
    border-color: var(--c-accent);
    background: var(--c-accent-soft);
}
.cat-tile a[aria-current="page"]:hover { transform: none; box-shadow: none; }
.cat-tile a[aria-current="page"] .cat-tile__name { color: var(--c-accent-dark); }

/* ---------- 16. KHỐI NỘI DUNG TRANG BRAND (markup của [seo] — coupon-seo/inc/brand-content.php)
   Vì sao có: trang brand trước đây chỉ có 233 từ ngoài bảng mã, và 2.591 trang
   giống hệt nhau về cấu trúc — đúng thứ Google gọi "cookie-cutter template" /
   thin affiliation. Các khối này sinh lúc RENDER từ data thật; thiếu data thì
   [seo] không in ra, nên CSS ở đây không bao giờ phải lo khung rỗng.
   Class [seo] cam kết giữ: .brand-compare .brand-expired .brand-activity
                            .brand-related .brand-byline  */
.brand-compare,
.brand-expired,
.brand-activity,
.brand-related {
    margin-top: var(--sp-6);
    padding-top: var(--sp-5);
    border-top: 1px dashed var(--c-dash);   /* mép đục lỗ giữa các khối */
}
.brand-compare h2,
.brand-expired h2,
.brand-activity h2,
.brand-related h2 {
    margin: 0 0 var(--sp-3);
    font-size: 1.15rem;
    color: var(--c-ink);
}
.brand-compare p,
.brand-expired__lead { margin: 0 0 var(--sp-3); color: var(--c-text); line-height: 1.65; }
.brand-compare strong { color: var(--c-ink); }

/* Dòng "cách tính" — nói ra luật, không giấu. Nhỏ và mờ: nó là chú thích. */
.brand-compare__note,
.brand-activity__note {
    margin: 0;
    font-size: .875rem;
    color: var(--c-muted);
    line-height: 1.55;
}

/* ----- Nhật ký: ngày (mono) | việc ----- */
.brand-activity ul { list-style: none; margin: 0 0 var(--sp-4); padding: 0; }
.brand-activity__row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding: var(--sp-2) 0;
    border-bottom: 1px solid var(--c-border);
    line-height: 1.5;
}
.brand-activity__date { flex: 0 0 auto; color: var(--c-muted); white-space: nowrap; }
.brand-activity__what { flex: 1 1 16rem; color: var(--c-text); }
.brand-activity code,
.brand-expired__code {
    font-family: var(--font-mono);
    background: var(--c-code-bg);
    border-radius: var(--r-sm);
    padding: 1px var(--sp-2);
}

/* ----- Mã đã chết: mờ đi, gạch ngang — KHÔNG được trông như mã còn dùng được ----- */
.brand-expired__list { list-style: none; margin: 0; padding: 0; }
.brand-expired__list li {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    align-items: baseline;
    padding: var(--sp-2) 0;
    border-bottom: 1px solid var(--c-border);
    color: var(--c-muted);
}
.brand-expired__code {
    color: var(--c-muted);
    text-decoration: line-through;          /* đọc ra NGAY là mã chết */
    background: transparent;
    border: 1px dashed var(--c-border);
    letter-spacing: 0;
    text-transform: none;
}
.brand-expired__when { font-size: .875rem; }

/* ----- Brand liên quan: internal link thật, không phải trang trí ----- */
.brand-related__list {
    display: grid;
    gap: var(--sp-2);
    grid-template-columns: 1fr;
    list-style: none;
    margin: 0 0 var(--sp-3);
    padding: 0;
}
.brand-related__list a {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--sp-3);
    padding: var(--sp-3);
    color: var(--c-ink);
    background: var(--c-bg);
    border: 1px dashed var(--c-dash);
    border-radius: var(--r-sm);
}
.brand-related__list a:hover {
    border-color: var(--c-accent);
    text-decoration: none;
}
.brand-related__name { font-weight: 600; }
.brand-related__best { flex: 0 0 auto; color: var(--c-accent); white-space: nowrap; }
.brand-related__more { margin: 0; font-weight: 600; }

/* ♥ Save của coupon-enhance tự gắn vào MỌI <li> chứa link "-coupons" — thẻ brand
   liên quan cũng là card trỏ tới store, nên nó có ♥ là ĐÚNG, không phải lỗi.
   Nhưng ♥ nằm absolute ở góc trên-phải, đúng chỗ ta để mức giảm -> đè nhau.
   Chừa chỗ theo chiều DỌC (dải trống phía trên), KHÔNG chừa theo chiều ngang —
   cùng luật theme đã áp cho .store-card (chừa ngang thì tên brand bị bẻ giữa từ). */
.brand-related__list li.cpn-has-heart > a { padding-top: 34px; }

/* ----- Byline: ai làm trang này + đường tới quy trình (E-E-A-T) ----- */
.brand-byline {
    margin-top: var(--sp-6);
    padding-top: var(--sp-4);
    border-top: 2px dashed var(--c-dash);
    font-size: .9rem;
    color: var(--c-muted);
}
.brand-byline strong { color: var(--c-text); }

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