    /* Landing Page Specific Styles */

    /* ==========================================================================
       Official breakpoint set (task 059, 2026-08-12):
         Desktop     (default, no query)  >= 1024px  — multi-column grid as-is
         Tablet      @media (min-width: 768px) and (max-width: 1023px)   [NEW — this file had no tablet tier before task 059]
         Mobile      @media (max-width: 767px)
         Small-phone @media (max-width: 479px)
       Applies to rules NEW/edited by task 059 only (the .hscroll-track/.hscroll-item
       carousel atom, .waste-vs-divider, .benefit-item.hscroll-item — see below).
       Pre-existing rules elsewhere in this file intentionally still use the
       older 768px/480px boundaries (deliberate, see task 059 spec §3.5/§6 —
       avoids an unrelated diff across ~280 lines this task doesn't otherwise
       touch). Result: this file has 2 parallel boundary conventions in play
       until a future dedicated cleanup task unifies them.
       ========================================================================== */
    body {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
        line-height: 1.6;
        color: var(--ink);
        /* Direction B: near-black fallback so any section/gap without its own opaque background
           shows dark, not the old bright brand gradient (was showing through .mini-cta and other
           sections that don't set their own background — see task risk notes). */
        background: var(--bg);
        margin: 0;
        padding: 0;
    }

    .landing-wrapper {
        min-height: 100vh;
    }

    /* Hero Section — Direction B (Bảo Mật, Kỹ Thuật): near-black bg + brighter brand-gradient accents */
    .hero {
        background: var(--bg);
        background-image:
            radial-gradient(circle at 15% 20%, var(--accent-soft) 0%, transparent 45%),
            radial-gradient(circle at 85% 0%, rgba(56, 189, 248, 0.12) 0%, transparent 40%);
        color: var(--ink);
        padding: 80px 20px 120px;
        text-align: center;
        position: relative;
        overflow: hidden;
        border-bottom: 1px solid var(--border);
    }

    .hero::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: url('data:image/svg+xml,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse"><path d="M 100 0 L 0 0 0 100" fill="none" stroke="rgba(95, 144, 247,0.12)" stroke-width="1"/></pattern></defs><rect width="100%" height="100%" fill="url(%23grid)"/></svg>');
        opacity: 0.5;
    }

    .hero-content {
        max-width: 1200px;
        margin: 0 auto;
        position: relative;
        z-index: 1;
    }

    /* Task v1.1.2-001: was a flat var(--ink) white with only a text-shadow —
       reported as "chỉ 1 màu trắng khó đọc". Gradient runs white → accent so the
       line still reads as one heading rather than two coloured halves. The
       shield icon is a sibling <svg> using currentColor, so it is deliberately
       left OUTSIDE the gradient (background-clip:text on an svg would erase it):
       .hero h1 keeps a real `color` for the icon, and only the text span is
       clipped. */
    .hero h1 {
        font-size: 3.5rem;
        font-weight: 800;
        margin-bottom: 20px;
        line-height: 1.2;
        color: var(--ink);
        text-shadow: 0 2px 20px rgba(95, 144, 247, 0.35);
    }

    .hero h1 .hero-title-text {
        background: linear-gradient(120deg,
                var(--ink) 0%,
                var(--ink) 35%,
                var(--a1) 65%,
                var(--a2) 100%);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
        /* text-shadow does not apply to background-clip:text; the readable
           lift comes from the drop-shadow filter on the h1's own layer. */
        filter: drop-shadow(0 2px 18px rgba(95, 144, 247, 0.45));
    }

    /* Hero free-trial badge — task v1.1.2-001 moved this off the inline style
       block in index.php (UI_COMPONENT_LIBRARY.md: no ad-hoc inline component
       styling) so it can have a mobile step at all. */
    .hero-badge {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        background: rgba(16, 185, 129, 0.2);
        border: 2px solid #10b981;
        color: var(--ink);
        padding: 8px 20px;
        border-radius: var(--radius-pill, 50px);
        margin-bottom: 20px;
        font-weight: 600;
        line-height: 1.35;
    }

    .hero-badge svg {
        flex: 0 0 auto;
    }

    .hero .tagline {
        font-size: 1.5rem;
        margin-bottom: 40px;
        color: var(--ink-soft);
        font-weight: 300;
    }

    .hero .cta-buttons {
        display: flex;
        gap: 20px;
        justify-content: center;
        flex-wrap: wrap;
    }

    .hero .btn {
        padding: 15px 40px;
        font-size: 1.1rem;
        border-radius: var(--radius-pill);
        text-decoration: none;
        font-weight: 600;
        transition: all 0.3s ease;
        display: inline-block;
        border: none;
        cursor: pointer;
    }

    .hero .btn-primary {
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        color: var(--ink);
        box-shadow: var(--shadow-card);
    }

    .hero .btn-primary:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-hover);
    }

    .hero .btn-secondary {
        background: transparent;
        color: var(--ink);
        border: 2px solid var(--border);
    }

    .hero .btn-secondary:hover {
        background: var(--accent-soft);
        border-color: var(--a1);
    }

    /* Features Section — Direction B tokens */
    .features-section {
        padding: 80px 20px;
        background: var(--bg-alt);
    }

    .section-container {
        max-width: 1200px;
        margin: 0 auto;
    }

    .section-title {
        text-align: center;
        font-size: 2.5rem;
        font-weight: 800;
        color: #1f2937;
        margin-bottom: 20px;
    }

    .section-subtitle {
        text-align: center;
        font-size: 1.2rem;
        color: #6b7280;
        margin-bottom: 60px;
    }

    /* Sections restyled to Direction B (dark) need their own title/subtitle colors —
       .section-title/.section-subtitle stay shared across the whole site, so scope overrides
       instead of changing the base rule (still used by not-yet-migrated sections e.g. how-it-works). */
    .features-section .section-title,
    .benefits-section .section-title,
    .pricing-section .section-title,
    .charts-section .section-title,
    .how-it-works-section .section-title,
    .pricing-page-hero .section-title,
    .compare-section .section-title,
    /* Task v1.1.2-001: .problem-section used to carry an inline
       `style="color: var(--danger-ink)"` on its <h2>. Turning that section from
       "here are 4 problems" into "here is what we block for you" dropped the
       inline red, which exposed the fact that this section had never been added
       to this override list — the base .section-title colour is #1f2937, i.e.
       near-invisible on the dark Direction B surface. */
    .problem-section .section-title,
    /* Task v1.1.2-001: .blog-section had the same gap — its <h2> rendered at the
       base #1f2937 on the dark surface, i.e. all but unreadable. Unlike
       .problem-section it never had an inline colour hiding the problem, so it
       had been shipping dark-on-dark since task 061. */
    .blog-section .section-title {
        color: var(--ink);
    }

    .features-section .section-subtitle,
    .benefits-section .section-subtitle,
    .pricing-section .section-subtitle,
    .charts-section .section-subtitle,
    .how-it-works-section .section-subtitle,
    .pricing-page-hero .section-subtitle,
    .compare-section .section-subtitle,
    .blog-section .section-subtitle {
        color: var(--ink-soft);
    }

    .features-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 40px;
    }

    .feature-card {
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 40px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        transition: all 0.3s ease;
    }

    .feature-card:hover {
        transform: translateY(-5px);
        box-shadow: var(--shadow-hover);
    }

    .feature-icon {
        font-size: 3rem;
        margin-bottom: 20px;
    }

    .feature-title {
        font-size: 1.5rem;
        font-weight: 700;
        color: var(--ink);
        margin-bottom: 15px;
    }

    .feature-description {
        color: var(--ink-soft);
        line-height: 1.6;
    }

    /* Benefits Section */
    .benefits-section {
        padding: 80px 20px;
        background: var(--bg);
    }

    .benefits-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
        gap: 30px;
        margin-top: 40px;
    }

    .benefit-item {
        display: flex;
        align-items: start;
        gap: 15px;
    }

    .benefit-icon {
        font-size: 1.5rem;
        color: var(--a1);
        flex-shrink: 0;
    }

    .benefit-text h3 {
        font-size: 1.2rem;
        color: var(--ink);
        margin-bottom: 8px;
    }

    .benefit-text p {
        color: var(--ink-soft);
        margin: 0;
    }

    /* Pricing Section */
    .pricing-section {
        padding: 80px 20px;
        background: var(--bg-alt);
    }

    .pricing-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 40px;
        max-width: 1200px;
        margin: 0 auto;
    }

    .pricing-card {
        background: var(--surface);
        border-radius: var(--radius-card);
        padding: 40px;
        box-shadow: var(--shadow-card);
        text-align: center;
        transition: all 0.3s ease;
        border: 3px solid var(--border);
    }

    .pricing-card.featured {
        border-color: var(--a1);
        transform: scale(1.05);
        box-shadow: var(--shadow-hover);
    }

    .pricing-card:hover {
        transform: translateY(-5px);
        box-shadow: var(--shadow-hover);
    }

    .pricing-badge {
        display: inline-block;
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        color: var(--ink);
        padding: 6px 16px;
        border-radius: 20px;
        font-size: 0.85rem;
        font-weight: 600;
        margin-bottom: 20px;
    }

    .pricing-name {
        font-size: 1.8rem;
        font-weight: 700;
        color: var(--ink);
        margin-bottom: 15px;
    }

    /* Price figure — sized from a measurement, not a guess (Playwright probe,
       2026-08-16). --num-font is monospace ('Courier New'), so the string's
       width is exactly chars x 0.6em: page/pricing.php renders the full
       "2.000.000 VNĐ" (13 chars = 7.8em), which at the previous 2.5rem needed
       312px inside a 254px content box (340px card - 3px border x2 - 40px
       padding x2). It therefore ALWAYS wrapped after the thousands group and,
       with .pricing-period ("/ tháng") sitting underneath, the price read as
       three stacked lines. 1.875rem needs 234px -> one line at >=768px with
       ~20px (8%) of slack left for font fallbacks / a longer future price.
       line-height is pinned here too: the inherited 1.6 gave the figure a 64px
       box for a 40px glyph, so tightening it keeps the (now smaller) number
       reading as the card's hero figure instead of a loose paragraph. */
    .pricing-price {
        font-size: 1.875rem;
        line-height: 1.25;
        font-weight: 800;
        color: var(--a1);
        margin-bottom: 10px;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    .pricing-period {
        color: var(--ink-soft);
        font-size: 1rem;
        margin-bottom: 30px;
    }

    .pricing-features {
        list-style: none;
        padding: 0;
        margin-bottom: 30px;
    }

    .pricing-features li {
        padding: 12px 0;
        border-bottom: 1px solid var(--border);
        color: var(--ink-soft);
    }

    .pricing-features li:last-child {
        border-bottom: none;
    }

    .pricing-features li::before {
        content: '✓';
        color: var(--success-ink);
        font-weight: bold;
        margin-right: 10px;
    }

    /* CTA Section */
    .cta-section {
        padding: 80px 20px;
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        color: var(--ink);
        text-align: center;
    }

    .cta-content {
        max-width: 800px;
        margin: 0 auto;
    }

    .cta-section h2 {
        font-size: 2.5rem;
        margin-bottom: 20px;
    }

    .cta-section p {
        font-size: 1.2rem;
        margin-bottom: 30px;
        opacity: 0.9;
    }

    /* Responsive */
    @media (max-width: 768px) {

        /* Show mobile menu toggle */
        .mobile-nav-toggle,
        .mobile-nav-overlay {
            display: block;
        }

        /* Hero adjustments */
        .hero {
            padding: 60px 15px 100px;
        }

        .hero h1 {
            font-size: 2rem;
            line-height: 1.3;
        }

        /* Task v1.1.2-001: at 390px the 38-char badge wrapped onto a second line
           ("dòng miễn phí 7 ngày đầu tiên bị rớt dòng"). Shrink type/padding/icon
           so it stays a single line down to 360px. */
        .hero-badge {
            font-size: 0.8rem;
            padding: 7px 14px;
            gap: 6px;
            margin-bottom: 16px;
        }

        .hero-badge svg {
            width: 17px;
            height: 17px;
        }

        .hero .tagline {
            font-size: 1rem;
            margin-bottom: 30px;
        }

        .hero .cta-buttons {
            flex-direction: column;
            gap: 15px;
        }

        .btn {
            width: 100%;
            padding: 12px 30px;
            font-size: 1rem;
        }

        /* Section spacing */
        .features-section,
        .benefits-section,
        .pricing-section,
        .cta-section,
        .problem-section,
        .how-it-works-section,
        .charts-section {
            padding: 50px 15px;
        }

        .section-container {
            padding: 0;
        }

        .section-title {
            font-size: 1.8rem;
            line-height: 1.3;
            margin-bottom: 15px;
        }

        .section-subtitle {
            font-size: 1rem;
            margin-bottom: 40px;
        }

        /* Features grid — mobile carousel: grid-template-columns/gap removed here,
           .features-grid.hscroll-track handles mobile layout (task 059, see atom
           block below); grid restored >=768px in the same atom block. */
        .feature-card {
            padding: 25px 20px;
        }

        .feature-icon {
            font-size: 2.5rem;
        }

        .feature-title {
            font-size: 1.3rem;
        }

        /* Benefits grid — mobile carousel, same as features-grid above (task 059) */

        /* Pricing cards — mobile carousel, same as features-grid above (task 059) */
        .pricing-card {
            padding: 30px 20px;
        }

        .pricing-card.featured {
            transform: scale(1);
        }

        .pricing-name {
            font-size: 1.5rem;
        }

        /* Carousel card is 78vw capped at 340px, so the narrowest real content
           box is at 360px viewport: 281px card - 3px border x2 - 20px padding
           x2 = 235px. The old 2rem needed 250px there -> "1.000.000 VNĐ" and
           "2.000.000 VNĐ" wrapped. 1.75rem needs 218px -> one line down to
           360px, still the largest type on the card. */
        .pricing-price {
            font-size: 1.75rem;
        }

        .pricing-features {
            font-size: 0.9rem;
        }

        .pricing-features li {
            padding: 10px 0;
            word-wrap: break-word;
        }

        /* Problem cards */
        .problem-card {
            padding: 25px 15px;
        }

        .problem-icon {
            font-size: 2.5rem;
        }

        .problem-card h3 {
            font-size: 1.1rem;
        }

        .problem-card p {
            font-size: 0.9rem;
        }

        /* Waste visual */
        .waste-visual {
            padding: 25px 15px !important;
        }

        .waste-visual h3 {
            font-size: 1.3rem !important;
        }

        .waste-visual>div {
            grid-template-columns: 1fr !important;
            gap: 20px !important;
        }

        .waste-visual h4 {
            font-size: 1.1rem !important;
        }

        /* Workflow */
        .workflow-container {
            flex-direction: column;
        }

        .workflow-step {
            min-width: 100%;
            max-width: 100%;
        }

        .workflow-arrow {
            transform: rotate(90deg);
            margin: 10px 0;
        }

        .step-icon {
            font-size: 2.5rem;
        }

        .step-content h3 {
            font-size: 1.2rem;
        }

        .step-content p {
            font-size: 0.9rem;
        }

        /* Quality grid */
        .quality-grid {
            grid-template-columns: 1fr;
            gap: 20px;
        }

        .quality-card {
            padding: 20px 15px;
        }

        .quality-number {
            font-size: 2rem;
        }

        /* Charts use centralized CSS from style.css */

        /* Mini CTA sections */
        .mini-cta {
            padding: 40px 15px !important;
        }

        .mini-cta .section-container {
            padding: 30px 20px !important;
            margin: 0 auto;
        }

        .mini-cta h3 {
            font-size: 1.5rem !important;
        }

        .mini-cta p {
            font-size: 1rem !important;
        }

        .mini-cta .btn {
            width: 100%;
            padding: 14px 25px !important;
            font-size: 1rem !important;
        }

        .mini-cta-actions {
            display: flex;
            flex-direction: column;
            gap: 12px !important;
            width: 100%;
        }

        /* CTA section */
        .cta-section h2 {
            font-size: 1.8rem;
            line-height: 1.3;
        }

        .cta-section p {
            font-size: 1rem;
        }

        /* Fix overflow issues */
        body,
        html {
            overflow-x: hidden;
        }

        * {
            max-width: 100%;
        }

        .landing-wrapper {
            overflow-x: hidden;
            width: 100%;
        }
    }

    /* Extra small devices */
    @media (max-width: 480px) {
        .hero h1 {
            font-size: 1.6rem;
        }

        .section-title {
            font-size: 1.5rem;
        }
    }

    /* Horizontal scroll carousel (atom, task 059) — mobile-first: this IS the
       default behavior; >=768px, sections wanting "grid on desktop / carousel
       on mobile" (features-grid/benefits-grid/pricing-grid) override back to
       grid in the block below. A page wanting carousel at every viewport can
       use .hscroll-track/.hscroll-item directly with no override needed. */
    .hscroll-track {
        display: flex;
        gap: 16px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding: 4px 4px 16px 20px;
        scroll-padding-left: 20px;
    }

    @media (prefers-reduced-motion: no-preference) {
        .hscroll-track {
            scroll-behavior: smooth;
        }
    }

    .hscroll-track::-webkit-scrollbar {
        height: 6px;
    }

    .hscroll-track::-webkit-scrollbar-thumb {
        background: var(--border);
        border-radius: var(--radius-pill);
    }

    .hscroll-item {
        flex: 0 0 78vw;
        /* peek: card doesn't fit the viewport exactly -> right edge is visibly
           cut off, signalling "there's more" without relying on the hint text alone */
        max-width: 320px;
        scroll-snap-align: start;
    }

    .hscroll-hint {
        display: block;
        text-align: center;
        font-size: .85rem;
        color: var(--ink-faint);
        margin-top: 8px;
    }

    @media (min-width: 768px) {
        .hscroll-hint {
            display: none;
            /* only needed while the carousel is actually active (mobile/tablet) */
        }
    }

    /* >=768px: features/benefits/pricing grids go back to their original CSS
       grid (0 change to desktop display, values unchanged from pre-059) */
    @media (min-width: 768px) {
        .features-grid.hscroll-track {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            overflow: visible;
            padding: 0;
            gap: 40px;
        }

        .benefits-grid.hscroll-track {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            overflow: visible;
            padding: 0;
            gap: 30px;
            margin-top: 40px;
        }

        .pricing-grid.hscroll-track {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            overflow: visible;
            padding: 0;
            gap: 40px;
            max-width: 1200px;
            margin: 0 auto;
        }
    }

    /* Pricing carousel item: bigger max-width cap (more content per card) +
       snap-align center so the "featured" (Business) card can land centered
       when scrolled to, unlike benefits/features which snap-align start.
       flex-basis intentionally matches the shared 78vw (not a wider value
       like 84vw) — measured at 375px viewport, 84vw left 0px of the next
       card visibly cut off (fully clipped, not "peeking"), which fails the
       task's own explicit peek requirement (verified with Playwright
       boundingBox() math, not just reading the CSS). 78vw + a taller
       max-width (340px vs the default 320px) still gives pricing cards more
       room once the viewport is wide enough to hit the cap, without losing
       the peek on real small phones. */
    .pricing-grid .hscroll-item {
        flex-basis: 78vw;
        max-width: 340px;
        scroll-snap-align: center;
    }

    /* Blog section (task 061) — .blog-grid.hscroll-track composes the same
       carousel atom as features/benefits/pricing above: mobile carousel is
       the base .hscroll-track rule (no override needed), >=768px restores a
       CSS grid. */
    /* Task v1.1.2-001: .blog-section was the ONLY section with no padding at all
       — every sibling carries `padding: 80px 20px` (inline in index.php), this
       one carried nothing, so the blog block sat flush against its neighbours
       and had no side gutter on narrow screens. Measured: blog 0px vs charts
       80px 20px. Set here rather than inline to avoid adding more inline style. */
    .blog-section {
        padding: 80px 20px;
    }

    @media (min-width: 768px) {
        .blog-grid.hscroll-track {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
            overflow: visible;
            padding: 0;
            gap: 32px;
            /* Task v1.1.2-001: had `max-width: 1000px` while .section-container
               (and every other section's grid) is 1200px — the blog cards were
               visibly narrower and floated in the middle of a wider section.
               Inherit the container width like the rest of the page. */
            margin: 0 auto;
        }
    }

    /* New pattern: blog needs image+title+excerpt+date, distinct from
       .feature-card (icon+title+text)/.pricing-card — stays within existing
       §1.1 tokens (--surface/--border/--radius-card/--shadow-card/--a1/--a2),
       no new hex/gradient invented. */
    .blog-card {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        overflow: hidden;
        text-decoration: none;
        color: inherit;
        display: flex;
        flex-direction: column;
        transition: transform .25s, box-shadow .25s, border-color .25s;
    }

    .blog-card:hover {
        transform: translateY(-4px);
        box-shadow: var(--shadow-hover);
        border-color: var(--a1);
    }

    .blog-card-image {
        width: 100%;
        aspect-ratio: 16/9;
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .blog-card-image img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .blog-card-body {
        padding: 20px 20px 22px;
        display: flex;
        flex-direction: column;
        gap: 10px;
        flex: 1;
    }

    .blog-card-date {
        font-size: .78rem;
        color: var(--ink-faint);
        font-family: var(--num-font);
    }

    .blog-card-title {
        font-size: 1.1rem;
        font-weight: 700;
        color: var(--ink);
        line-height: 1.4;
        margin: 0;
    }

    .blog-card-excerpt {
        font-size: .9rem;
        color: var(--ink-soft);
        line-height: 1.6;
        margin: 0;
        flex: 1;
    }

    .blog-card-cta {
        font-size: .85rem;
        font-weight: 600;
        color: var(--a1);
    }

    .blog-card:hover .blog-card-cta {
        color: var(--a2);
    }

    .blog-viewall {
        text-align: center;
        margin-top: 40px;
    }

    /* .benefit-item stays a flex row (icon-left/text-right) at desktop — only
       overridden on mobile so it reads as a standalone "chip card" inside the
       carousel instead of a bare icon+text row with nothing framing it. */
    @media (max-width: 767px) {
        .benefit-item.hscroll-item {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: var(--radius-card);
            padding: 20px;
            flex-direction: column;
            align-items: center;
            text-align: center;
            gap: 10px;
        }
    }

    /* Waste-visual comparison divider — mobile direction flip (task 059).
       >=768px the divider is a vertical line (see .waste-vs-divider rule
       above, matches .waste-visual-grid's 3-column layout); on mobile the 2
       columns stack vertically (.waste-visual>div, existing 768px block
       above), so the divider's line flips horizontal to still read as
       "between" the 2 stacked blocks. */
    @media (max-width: 767px) {
        .waste-vs-divider {
            flex-direction: row;
        }

        .waste-vs-divider .line {
            height: 1px;
            width: 100%;
        }
    }

    /* Problem Section Styles — Direction B: dark surface cards, danger tokens, monospace stat figures */
    .problem-section .section-subtitle {
        color: var(--ink-soft);
    }

    .problem-card {
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 30px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        text-align: center;
        transition: all 0.3s;
    }

    .problem-card:hover {
        transform: translateY(-5px);
        box-shadow: var(--shadow-hover);
    }

    .problem-icon {
        font-size: 3.5rem;
        margin-bottom: 15px;
    }

    .problem-card h3 {
        color: var(--danger-ink);
        font-size: 1.3rem;
        margin-bottom: 12px;
    }

    .problem-card p {
        color: var(--ink-soft);
        font-size: 0.95rem;
        line-height: 1.6;
        margin-bottom: 15px;
    }

    .problem-stat {
        background: var(--danger-bg);
        color: var(--danger-ink);
        padding: 8px 15px;
        border-radius: 20px;
        font-weight: 700;
        font-size: 1.2rem;
        display: inline-block;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    /* ======================================================================
       Capability cards (task v1.1.2-001) — replaced the old 4 .problem-card
       "here are 4 scary things" tiles. Deliberately NOT danger-token styled
       like .problem-card above: this section now answers "what does the tool
       do for you", so it reads as accent/positive, not alarm. .problem-card
       rules are kept above because .problem-section is still the wrapper
       class and other pages/tests may reference them.
       ====================================================================== */
    .capability-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
        gap: 24px;
        margin-top: 40px;
    }

    .capability-card {
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 28px 24px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
        display: flex;
        flex-direction: column;
        /* Left-aligned on purpose: these are 3-4 line explanations, not
           one-word labels — centred body copy at this length is hard to scan
           (UX_PAGE_STANDARD.md). */
        text-align: left;
    }

    .capability-card:hover {
        transform: translateY(-5px);
        box-shadow: var(--shadow-hover);
        border-color: var(--a1);
    }

    .capability-icon {
        margin-bottom: 14px;
        line-height: 1;
    }

    .capability-card h3 {
        color: var(--ink);
        font-size: 1.15rem;
        margin-bottom: 10px;
        line-height: 1.35;
        /* Titles are 1-2 lines depending on card width, which used to leave the
           body copy of each card starting at a different height. Reserving two
           lines here keeps every description (and therefore every card) aligned
           at any column count. Not subgrid: with `auto-fit` columns the cards
           wrap onto several parent rows at tablet widths, which subgrid row
           spanning does not survive cleanly. */
        min-height: 2.7em;
        display: flex;
        align-items: center;
    }

    .capability-card p {
        color: var(--ink-soft);
        font-size: 0.92rem;
        line-height: 1.65;
        margin-bottom: 16px;
        flex: 1 1 auto;
    }

    .capability-card p strong {
        color: var(--ink);
        font-weight: 600;
    }

    .capability-tag {
        align-self: flex-start;
        background: var(--accent-soft);
        color: var(--a1);
        border: 1px solid var(--border);
        padding: 5px 12px;
        border-radius: var(--radius-pill, 20px);
        font-weight: 600;
        font-size: 0.78rem;
        letter-spacing: 0.02em;
    }

    .capability-plan-note {
        margin-top: 28px;
        text-align: center;
        color: var(--ink-soft);
        font-size: 0.92rem;
        line-height: 1.6;
    }

    .capability-plan-note strong {
        color: var(--ink);
    }

    /* Attack-scenario caveat under the waste example. Amber, not red: it is a
       qualifier on the numbers above, not a fifth threat card. Kept visually
       separate from the 30-60% figure on purpose — see the comment on
       waste_attack_note in config/languages/vi/landing.php. */
    .waste-attack-note {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        margin: 24px auto 0;
        max-width: 760px;
        padding: 14px 18px;
        border-radius: var(--radius-card);
        background: rgba(245, 158, 11, 0.08);
        border: 1px solid rgba(245, 158, 11, 0.25);
        color: var(--ink-soft);
        font-size: 0.88rem;
        line-height: 1.6;
        text-align: left;
    }

    .waste-attack-note svg {
        flex: 0 0 auto;
        margin-top: 2px;
    }

    /* Waste Visualization — refactored from inline styles to classes (Direction B tokens) */
    .waste-visual {
        margin-top: 60px;
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 40px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
    }

    .waste-visual-title {
        text-align: center;
        color: var(--danger-ink);
        margin-bottom: 30px;
        font-size: 1.8rem;
    }

    .waste-visual-grid {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        gap: 24px;
        align-items: center;
    }

    /* "VS" divider (task 059) — makes the 2-column comparison read as 1 continuous
       block instead of 2 unrelated widgets side by side. */
    .waste-vs-divider {
        display: flex;
        align-items: center;
        justify-content: center;
        align-self: stretch;
    }

    .waste-vs-divider .line {
        width: 1px;
        flex: 1;
        background: var(--border);
    }

    .waste-vs-divider span {
        flex-shrink: 0;
        width: 44px;
        height: 44px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 800;
        font-size: .8rem;
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        color: var(--ink);
        box-shadow: var(--shadow-card);
        margin: 10px 0;
    }

    .waste-col-heading {
        margin-bottom: 15px;
    }

    .waste-col-heading.is-danger {
        color: var(--danger-ink);
    }

    .waste-col-heading.is-success {
        color: var(--success-ink);
    }

    .money-bar {
        height: 60px;
        border-radius: var(--radius-pill);
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 1.3rem;
        font-weight: 700;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    /* Solid-fill tokens (task 059) — --danger-bg/--success-bg are alpha-only,
       these are the saturated bootstrap-style colors used as data-viz bar fills. */
    .money-bar.is-danger {
        background: var(--danger-solid);
    }

    .money-bar.is-success {
        background: var(--success-solid);
    }

    .waste-breakdown {
        margin-top: 15px;
        padding: 15px;
        border-radius: var(--radius-pill);
    }

    .waste-breakdown.is-danger {
        background: var(--danger-bg);
    }

    .waste-breakdown.is-success {
        background: var(--success-bg);
    }

    .waste-row {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
        color: var(--ink-soft);
    }

    .waste-row strong {
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    .waste-row strong.is-danger {
        color: var(--danger-ink);
    }

    .waste-row strong.is-success {
        color: var(--success-ink);
    }

    .waste-divider {
        margin: 10px 0;
        border: none;
        border-top: 1px solid var(--border);
    }

    .waste-total-row {
        display: flex;
        justify-content: space-between;
        font-size: 1.1rem;
        color: var(--ink);
    }

    .waste-total-row strong.is-success {
        color: var(--success-ink);
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    /* Task v1.1.2-001: this .is-danger pair never existed — the "no protection"
       total was marked .is-success and therefore rendered green, i.e. the losing
       column's bottom line looked like a win. Switching the markup to .is-danger
       alone would have left it uncoloured (inheriting --ink), so the rule has to
       land here too. */
    .waste-total-row strong.is-danger {
        color: var(--danger-ink);
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    .waste-savings-box {
        margin-top: 20px;
        padding: 20px;
        border-radius: var(--radius-pill);
        text-align: center;
        color: white;
        background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    }

    .waste-savings-label {
        font-size: 0.9rem;
        opacity: 0.9;
        margin-bottom: 5px;
    }

    .waste-savings-amount {
        font-size: 1.5rem;
        font-weight: 800;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    .waste-savings-year {
        font-size: 0.9rem;
        opacity: 0.9;
        margin-top: 5px;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    /* Mini CTA Sections — refactored from per-instance inline styles to 1 shared class (Direction B tokens).
       NOTE: the outer <section> needs its own opaque background — without it the section is transparent
       and body's background shows through around the centered .section-container card. */
    .mini-cta {
        padding: 60px 20px;
        background: var(--bg-alt);
    }

    .mini-cta .section-container {
        text-align: center;
        max-width: 800px;
        margin: 0 auto;
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 50px 40px;
        border-radius: 20px;
        box-shadow: var(--shadow-card);
    }

    .mini-cta-badge {
        display: inline-block;
        color: var(--ink);
        padding: 10px 24px;
        border-radius: var(--radius-pill);
        margin-bottom: 20px;
        font-weight: 600;
        font-size: 1rem;
    }

    .mini-cta-badge.is-success {
        background: linear-gradient(135deg, #10b981 0%, #059669 100%);
        box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
    }

    .mini-cta-badge.is-accent {
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        box-shadow: var(--shadow-card);
    }

    .mini-cta h3 {
        font-size: 1.8rem;
        color: var(--ink);
        margin-bottom: 15px;
        font-weight: 700;
    }

    .mini-cta p {
        font-size: 1.1rem;
        color: var(--ink-soft);
        margin-bottom: 30px;
        line-height: 1.6;
    }

    .mini-cta-actions {
        display: flex;
        gap: 15px;
        justify-content: center;
        flex-wrap: wrap;
    }

    .mini-cta-actions .btn {
        padding: 14px 35px;
        font-size: 1.05rem;
    }

    .mini-cta-actions .btn-primary {
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        box-shadow: var(--shadow-card);
        color: var(--ink);
    }

    .mini-cta-actions .btn-primary.is-success {
        background: linear-gradient(135deg, #10b981 0%, #059669 100%);
        box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
    }

    .mini-cta-actions .btn-secondary {
        background: transparent;
        color: var(--a1);
        border: 2px solid var(--a1);
    }

    .mini-cta-actions .btn-secondary.is-success {
        color: var(--success-ink);
        border-color: var(--success-ink);
    }

    .mini-cta-footnote {
        margin-top: 15px;
        font-size: 0.9rem;
        color: var(--ink-faint);
    }

    /* Workflow Styles — brought into Direction B scope: same dark-card treatment as .problem-card */
    .workflow-container {
        display: flex;
        align-items: center;
        justify-content: center;
        flex-wrap: wrap;
        gap: 20px;
    }

    .workflow-step {
        flex: 1;
        min-width: 280px;
        max-width: 350px;
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 30px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        position: relative;
        transition: all 0.3s;
    }

    .workflow-step:hover {
        transform: translateY(-8px);
        box-shadow: var(--shadow-hover);
    }

    .step-number {
        position: absolute;
        top: -15px;
        left: 50%;
        transform: translateX(-50%);
        width: 50px;
        height: 50px;
        background: linear-gradient(135deg, var(--a1) 0%, var(--a2) 100%);
        color: var(--ink);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 1.5rem;
        font-weight: 800;
        box-shadow: var(--shadow-card);
    }

    .step-icon {
        font-size: 3rem;
        margin: 20px 0 15px;
        text-align: center;
    }

    .step-content h3 {
        color: var(--ink);
        font-size: 1.3rem;
        margin-bottom: 12px;
        text-align: center;
    }

    .step-content p {
        color: var(--ink-soft);
        font-size: 0.95rem;
        line-height: 1.6;
        text-align: center;
        margin-bottom: 15px;
    }

    .step-metrics {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: center;
        margin-top: 15px;
    }

    .metric-badge {
        background: var(--accent-soft);
        color: var(--a1);
        padding: 6px 12px;
        border-radius: 16px;
        font-size: 0.75rem;
        font-weight: 600;
    }

    .workflow-arrow {
        font-size: 2rem;
        color: var(--a1);
        font-weight: 700;
    }

    /* Quality Dashboard Styles — JS-driven (renderQualityDashboard()); only container chrome tokenized,
       dynamic status colors set inline by JS are left untouched (out of scope, see task risk notes). */
    .quality-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
        gap: 25px;
        margin-top: 30px;
    }

    .quality-card {
        background: var(--surface);
        border: 1px solid var(--border);
        padding: 25px;
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
        transition: all 0.3s;
    }

    .quality-card:hover {
        transform: translateY(-3px);
        box-shadow: var(--shadow-hover);
    }

    .quality-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 15px;
    }

    .quality-title {
        font-size: 0.9rem;
        color: var(--ink-soft);
        text-transform: uppercase;
        letter-spacing: 0.5px;
        font-weight: 600;
    }

    .quality-icon {
        font-size: 1.8rem;
    }

    .quality-number {
        font-size: 2.5rem;
        font-weight: 800;
        margin-bottom: 5px;
        font-family: var(--num-font);
        font-variant-numeric: tabular-nums;
    }

    .quality-label {
        font-size: 0.85rem;
        color: var(--ink-faint);
    }

    .quality-bar {
        height: 8px;
        background: var(--border);
        border-radius: 4px;
        overflow: hidden;
        margin-top: 12px;
    }

    .quality-bar-fill {
        height: 100%;
        transition: width 1s ease;
    }

    /* Analytics chart cards (ChartLoader, Chart.js) — restyle container only, scoped to this page
       (.charts-section) so the global css/style.css .chart-card definition stays untouched for
       other pages. Canvas/chart color configs are NOT touched here (see task risk notes). */
    .charts-section .chart-card {
        background: var(--surface);
        border: 1px solid var(--border);
        box-shadow: var(--shadow-card);
    }

    .charts-section .chart-card:hover {
        box-shadow: var(--shadow-hover);
    }

    .charts-section .chart-card-title {
        color: var(--ink);
    }

    .charts-section .chart-card-subtitle {
        color: var(--ink-soft);
    }

    @media (max-width: 768px) {
        .workflow-container {
            flex-direction: column;
        }

        .workflow-arrow {
            transform: rotate(90deg);
            margin: 10px 0;
        }

        .waste-visual>div {
            grid-template-columns: 1fr !important;
        }
    }

/* Floating auth bar — dark/glass rebuild, landing-scoped only (task 060).
   Base .glass-btn (css/style.css) stays light-on-light for .mobile-menu-toggle
   (every page, floats over the header's purple gradient — unrelated to Direction B)
   and for .floating-auth-buttons on every OTHER page (register/login/terms/blog —
   still the light #f5f7fa body). This file loads on index.php AND page/pricing.php
   (task 071 added the 2nd consumer — both are Direction B/dark pages), so this
   rule only ever applies where the body background is actually dark. See task
   060 spec §2.5 and task 071 spec §2.5. */
.floating-auth-buttons .glass-btn {
    background: var(--glass-bg);
    border-color: var(--glass-border);
    border-radius: var(--glass-radius);
    color: var(--glass-ink);
    box-shadow: var(--glass-shadow-resting);
}

.floating-auth-buttons .glass-btn:hover {
    background: var(--glass-bg);
    border-color: var(--a1);
    box-shadow: var(--glass-shadow-hover);
}

/* ==========================================================================
   page/pricing.php (task 071) — this file's 2nd consumer besides index.php.
   Reuses .pricing-grid/.pricing-card/.hscroll-track verbatim (no new CSS
   needed for Block A, the 3 plan-summary cards). The rules below are new:
   the page hero and the full feature-comparison table (Block B).
   ========================================================================== */

.pricing-page-hero {
    padding: 60px 20px 30px;
    background: var(--bg);
    text-align: center;
}

.compare-section {
    padding: 60px 20px 80px;
    background: var(--bg);
}

/* Comparison table — sticky first column + overflow-x:auto (plain scroll,
   NOT .hscroll-track). scroll-snap-type (the atom's mechanism) actively
   jumps the viewport to the next item boundary on every scroll gesture,
   which fights the point of a pinned column: the user needs to scroll
   smoothly, pixel-by-pixel, while the sticky column stays put so they can
   read "which row am I on" against "which plan column is this". Sticky
   positioning doesn't care what scroll mechanism the ancestor uses, but it
   is a bad *experience* combined with snap — so this table intentionally
   does not compose with .hscroll-track. See task 071 spec §3.4. */
.compare-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    /* Deviation from task 071 spec §3.4's CSS (which didn't include this) —
       required after measuring real overflow at 375px, not assumed: a
       `<table>` with a `position: sticky` cell inside `overflow-x: auto`
       leaks its full unclipped width into `document.documentElement.scrollWidth`
       in Chromium (page-level horizontal scrollbar) even though `.compare-wrap`
       itself correctly clips visually and scrolls internally (confirmed via
       Playwright: without `contain: paint`, docScrollWidth was 734px at a
       375px viewport; with it, 375px — sticky-column pin behavior unaffected
       either way). `contain: paint` forces the browser to actually clip
       overflow at this box instead of only visually. */
    contain: paint;
}

.compare-table {
    width: 100%;
    min-width: 640px;
    border-collapse: collapse;
    background: var(--surface);
}

.compare-table th,
.compare-table td {
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
    color: var(--ink-soft);
    text-align: center;
}

.compare-table thead th {
    color: var(--ink);
    font-weight: 700;
}

.compare-table thead th:first-child,
.compare-table tbody th {
    position: sticky;
    left: 0;
    background: var(--surface);
    z-index: 1;
    text-align: left;
    color: var(--ink);
    font-weight: 600;
    /* Edge shadow is the only affordance telling the user this column is
       pinned while the rest of the row scrolls underneath it — no other
       indicator exists for this pattern (unlike .hscroll-track's caption
       hint, deliberately not reused here, see comment above). */
    box-shadow: 2px 0 6px rgba(0, 0, 0, .35);
}

.compare-table thead th.plan-business,
.compare-table tbody td.plan-business {
    /* Keep "featured" plan visually consistent with .pricing-card.featured
       in Block A above, using the same accent-soft token. */
    background: var(--accent-soft);
}

.compare-table tfoot td {
    border-bottom: none;
    padding: 20px 18px;
}

.compare-table tfoot .btn {
    display: inline-flex;
}

/* Task v1.1.2-001 — mobile comparison table ("bảng so sánh tính năng trên mobile
   quá xấu"). Measured at 390px BEFORE: auto table-layout allocated the column
   widths exactly backwards — the text-heavy feature column got 93px (labels
   wrapped to 4 lines, rows up to 157px tall) while each plan column got 239px
   to display a single ✓. Table came to 809px inside a 350px wrap: 2.3 screens
   of horizontal scrolling to read a table that carries almost no text.

   Fixed layout with explicit percentages instead: the browser stops sizing
   columns by content, the feature label gets the room it actually needs, and
   the whole table fits the viewport with no horizontal scroll at all. The
   sticky first column and .compare-wrap's overflow handling are left in place
   untouched — they still do their job at tablet widths where the table does
   overflow, and are simply inert here. */
@media (max-width: 767px) {
    .compare-table {
        min-width: 0;
        table-layout: fixed;
        font-size: 0.82rem;
    }

    .compare-table th,
    .compare-table td {
        padding: 10px 8px;
        word-break: break-word;
    }

    .compare-table thead th:first-child,
    .compare-table tbody th {
        width: 36%;
    }

    .compare-table thead th:not(:first-child),
    .compare-table tbody td {
        width: 21.33%;
    }

    .compare-table tfoot td {
        padding: 14px 5px;
    }

    /* The tfoot CTA was the one thing still forcing horizontal scroll after the
       columns were fixed: .btn's intrinsic width is 120px, which does not fit a
       75px fixed column, so it punched 64px past the wrap. Full-width inside its
       own cell + compact type keeps it tappable (still ~44px tall) without
       reopening the scroll. */
    .compare-table tfoot .btn {
        display: flex;
        width: 100%;
        /* The shared .btn atom carries `min-width: 120px` and `white-space:
           nowrap`; both have to be released here or the button keeps its
           intrinsic 120px regardless of `width: 100%` (measured: width computed
           to 120px with min-width:120px still winning). */
        min-width: 0;
        white-space: normal;
        padding: 9px 4px;
        font-size: 0.68rem;
        line-height: 1.3;
        text-align: center;
        justify-content: center;
    }
}

/* Screen-reader-only text — pairs with the checkmark icon in the comparison
   table so "included"/"not included" is announced, not just shown visually
   (IconHelper::render() has no aria-hidden/label option to attach this to
   directly, see task 071 report's deviation note). Kept here rather than a
   shared utility file since this is the only current consumer. */
.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;
}
