/*
 * site.css — layout & components
 * All colors reference tokens.css variables (Section 8) — no hard-coded
 * hex values here. Section rhythm (Section 7) comes from alternating
 * --bg-page / --bg-surface / --bg-band-dark backgrounds, not decoration.
 */

* { box-sizing: border-box; }

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--bpk-signal-orange);
    color: var(--bpk-deep-navy);
    padding: 12px 20px;
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 8px 0;
}
.skip-link:focus {
    left: 0;
}

/* Standard visually-hidden utility — content stays in the accessibility
   tree (screen readers, heading outline) but is removed from visual
   layout. Used for section headings that exist for correct heading
   order (Lighthouse a11y: heading-order) but have no visual design. */
.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;
}

/* --------------------------------------------------------- offer topbar --- */
/* Site-wide dismissible banner (all pages except the checkout flow) for
   whatever offer Settings::specialOfferActive() currently has on —
   visibility, copy, and the dismiss/localStorage logic all live in
   templates/header-nav.php; this is presentation only. It ships
   `hidden` in the markup and is only ever unhidden by that inline
   script once it confirms the visitor hasn't already dismissed this
   exact offer, so there's no flash-then-hide. Not sticky (only
   .site-header is) — it scrolls away like ordinary page content and the
   header takes over the top of the viewport, same as most promo bars. */
.site-offer-topbar {
    background: var(--bg-surface-alt);
    background: color-mix(in srgb, var(--bpk-signal-orange) 12%, var(--bg-surface-alt));
    border-bottom: 1px solid var(--border-subtle);
}
.site-offer-topbar-inner {
    display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
    gap: 6px 14px;
    padding: 10px 24px;
    text-align: center;
}
/* Icon now lives inline inside .site-offer-topbar-text (wrapped together
   with "Limited-time offer" in one .site-offer-topbar-nowrap unit) rather
   than as its own flex sibling — as a separate flex item it could end up
   wrapping onto its own centered line above the message on narrow
   screens, reading as a stray floating flame instead of part of the
   sentence. vertical-align keeps it sitting on the text baseline now
   that it's inline content, not a flex-centered box. */
.site-offer-topbar-icon { font-size: 1rem; line-height: 1; vertical-align: -2px; }
.site-offer-topbar-text { font-size: 0.86rem; color: var(--text-primary); }
.site-offer-topbar-text strong { font-weight: 700; }
/* Keeps "Limited-time offer" + icon, and "(NN% off)", each as one
   unbreakable unit — the two phrases most likely to leave an orphaned
   fragment (a lone "off)" or a solo flame emoji) on a wrapped line at
   narrow widths. The rest of the sentence still wraps normally. */
.site-offer-topbar-nowrap { white-space: nowrap; }
.site-offer-topbar-cta {
    flex-shrink: 0;
    font-size: 0.82rem; font-weight: 700;
    color: var(--bpk-deep-navy);
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 5px 14px;
    text-decoration: none;
    white-space: nowrap;
}
.site-offer-topbar-cta:hover { border-color: var(--bpk-signal-orange); }
.site-offer-topbar-close {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px;
    border: none; background: transparent; color: var(--text-secondary);
    cursor: pointer; border-radius: 50%;
}
.site-offer-topbar-close:hover { background: rgba(0, 0, 0, 0.06); color: var(--text-primary); }
@media (max-width: 640px) {
    .site-offer-topbar-inner { padding: 8px 16px; gap: 4px 10px; }
    .site-offer-topbar-text { font-size: 0.78rem; }
    /* Expiry date is the least essential clause on a narrow screen —
       dropping it keeps the banner to one wrapped line instead of two,
       so it costs less of the viewport before real page content. */
    .site-offer-topbar-expiry { display: none; }
    .site-offer-topbar-cta { padding: 4px 12px; font-size: 0.78rem; }
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body { margin: 0; line-height: 1.55; }

/* Anchor-linked sections (nav links, hero's "Explore the toolkit",
   in-page jumps) must never land with their heading hidden behind the
   sticky .site-header — scroll-margin-top keeps the landing point clear
   of it on every browser that supports smooth-scroll anchors. The
   header is a single ~79px row above 1280px and ~71px once it collapses
   to the hamburger layout below that (the nav's own breakpoint — see
   .site-nav in the header section), so this offset is tuned to match. */
[id] { scroll-margin-top: 100px; }
@media (max-width: 1279px) { [id] { scroll-margin-top: 90px; } }

.wrap {
    max-width: 1120px;
    margin: 0 auto;
    padding: 0 24px;
}

img, svg { max-width: 100%; display: block; }

a { color: inherit; }

/* ---------------------------------------------------------------- header --- */
/* Single row: brand, primary nav and the customer actions share one
   line — logo and links on the left, utility actions and the CTA on
   the right. A thin brand-orange rule along the very top edge (::before)
   is this header's one signature touch, in place of the two-tier
   layout the site used before. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--bg-page);
    border-bottom: 1px solid var(--border-subtle);
}
.site-header::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--bpk-signal-orange);
}

/* A wider container than the site's standard 1120px .wrap: five nav
   labels, the logo and the header-actions cluster genuinely don't fit
   inside the article-text content width, and a nav bar spanning wider
   than the copy it sits above is normal (most of what "big brand" nav
   bars do differently from this site's old one is exactly this — more
   breathing room than a text column needs). Overrides .wrap's own
   max-width/padding for this one element only. */
.site-header-row {
    max-width: 1360px;
    padding: 0 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    height: 76px;
}

.site-header-logo { flex-shrink: 0; }
/* Slightly smaller than the logo's other uses (footer, etc.) — the
   lockup's native proportions make its rendered width scale with this
   height, and at the row's own 40px height there wasn't quite enough
   width left for the nav and actions cluster at common laptop sizes. */
.site-header-logo .brand-logo { height: 34px; }

.site-nav {
    display: flex;
    align-items: center;
    min-width: 0;
}

/* One soft rounded group (segmented-control language) rather than
   plain inline links — the container's own background is the subtler
   of the two theme-aware surface tokens, so the active item's pill
   (below) always reads as the brighter, "raised" one against it, in
   both themes. */
.site-nav-links {
    display: flex;
    align-items: center;
    gap: 2px;
    background: var(--bg-surface);
    border-radius: 999px;
    padding: 4px;
}

/* .is-active (set server-side in header-nav.php by matching the
   current filename) marks the current page as a raised pill inside
   the group, rather than a background the same as the mobile dropdown
   below uses — reads as "you are here" without competing with the CTA
   button's own filled shape. --bg-page is the brighter choice in light
   mode (pure white against the group's off-white) but the DARKEST of
   the three surface tokens in dark mode, so it's swapped for
   --bg-surface-alt there instead — the token that is actually the
   lighter of the two in that theme. */
.site-nav a {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    white-space: nowrap;
    text-decoration: none;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-secondary);
    padding: 6px 10px;
    border-radius: 999px;
    transition: color var(--bpk-transition-fast), background-color var(--bpk-transition-fast), box-shadow var(--bpk-transition-fast);
}
.site-nav a:hover, .site-nav a:focus-visible { color: var(--text-primary); }
.site-nav a.is-active {
    color: var(--text-primary);
    font-weight: 600;
    background: var(--bg-page);
    box-shadow: 0 1px 2px rgba(23, 43, 58, 0.08);
}
[data-theme="dark"] .site-nav a.is-active {
    background: var(--bg-surface-alt);
    box-shadow: none;
}

/* Only ever visible inside the mobile dropdown (see the nav-open rules
   below) — on desktop "Access Download" lives in .header-actions
   instead. Two copies of one link, each shown in exactly one context,
   the same pattern the hamburger button itself already uses; never
   both visible at once. */
.site-nav a.site-nav-access-mobile { display: none; }

.header-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* Access Download: a quiet text link (icon + label, no border or
   fill) rather than a bordered button — orange stays reserved for the
   in-page hero/offer CTAs and the active-nav underline above, and a
   second bordered button here would compete with .btn-nav-cta for
   which action is primary. flex-shrink:0 + nowrap match the other
   action items so none of them shrinks or wraps before the row hands
   off to the mobile menu. */
/* .header-actions ancestor on the selector (not just .btn-nav-secondary)
   is required, not decorative — .btn's own font-size: 0.95rem sits later
   in this file, and two single-class selectors of equal specificity
   resolve by source order, so a bare .btn-nav-secondary rule here would
   lose that tie and silently keep the base .btn size. */
.header-actions .btn-nav-secondary {
    background: transparent;
    color: var(--text-secondary);
    border-color: transparent;
    flex-shrink: 0;
    white-space: nowrap;
    padding: 12px 6px;
    font-size: 0.875rem;
}
.header-actions .btn-nav-secondary:hover { color: var(--text-primary); }
[data-theme="dark"] .header-actions .btn-nav-secondary { color: var(--text-secondary); }
[data-theme="dark"] .header-actions .btn-nav-secondary:hover { color: var(--bpk-white); }

.nav-toggle {
    display: none;
    background: none;
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
    width: 40px;
    height: 40px;
    color: var(--text-primary);
    cursor: pointer;
}

/* 1280px, not the site's usual 900px tablet breakpoint: five nav
   labels plus the logo and the actions cluster need real width to sit
   on one line without crowding (see .site-header-row's own comment
   above on why the header gets a wider container than .wrap in the
   first place) — below it the hamburger dropdown already handles this
   content cleanly, so that's the safer choice down through tablet and
   smaller-laptop widths rather than letting the row visually crowd. */
@media (max-width: 1279px) {
    /* Collapsed to a single ~68px bar; .site-nav (the links) drops out
       of flow entirely rather than shrinking, and reappears as the
       .nav-open dropdown below once the hamburger is pressed. */
    .site-header-row { height: 68px; }
    .site-nav { display: none; }
    /* Scoped to .header-actions (not just .btn-nav-secondary) so this
       beats the later, unconditional ".btn { display: inline-flex }"
       base rule on specificity (0,2,0 vs 0,1,0) rather than relying on
       source order. A same-specificity, source-order-only override
       here was silently losing to .btn every time, leaving "Access
       Download" visible and overflowing the header. */
    .header-actions .btn-nav-secondary { display: none; }
    .nav-toggle { display: inline-flex; align-items: center; justify-content: center; }
    .site-nav.nav-open {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        height: auto;
        gap: 4px;
        position: absolute;
        top: 69px;
        left: 0;
        right: 0;
        background: var(--bg-page);
        border-top: 1px solid var(--border-subtle);
        border-bottom: 1px solid var(--border-subtle);
        padding: 12px 24px 20px;
        z-index: 39;
    }
    /* .site-nav-links reverts to a full-width, top-to-bottom stack here
       — its own base rule (row, for desktop) doesn't apply once the
       dropdown is open. */
    .site-nav.nav-open .site-nav-links { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; }
    .site-nav.nav-open a { padding: 10px 12px; width: 100%; font-size: 0.95rem; font-weight: 600; }
    .site-nav.nav-open a.is-active { background: var(--bg-surface-alt); border-radius: 7px; }
    /* The mobile-only "Access Download" entry gets its own divider so
       it still reads as a separate action from the informational links
       above it, even though it's now in the same dropdown. */
    .site-nav.nav-open .site-nav-access-mobile {
        display: flex;
        border-top: 1px solid var(--border-subtle);
        margin-top: 8px;
        padding-top: 18px;
    }
}
/* Narrow phones: logo + theme toggle + "Buy Now — $49" + hamburger
   were wide enough together to push the button off-screen. Tighten
   gaps and shrink the header's own controls (not the in-page hero/
   pricing buttons) so everything fits without wrapping or overflow. */
@media (max-width: 640px) {
    .site-header .wrap { gap: 8px; padding: 0 16px; }
    .site-nav.nav-open { padding: 12px 16px 20px; }
    .header-actions { gap: 6px; }
    .site-header .btn-nav-cta {
        padding: 9px 12px;
        font-size: 0.82rem;
        min-height: 38px;
        white-space: nowrap;
    }
    .site-header .theme-toggle-btn, .site-header .nav-toggle { width: 36px; height: 36px; flex: none; }
    .brand-logo { max-width: 132px; }
}
/* Narrowest phones (iPhone SE/mini and similar, ~375px and down): even
   with the tightened values above, brand-logo + theme toggle + the CTA
   + hamburger were still ~20-25px wider than the viewport, causing a
   real horizontal scrollbar on the whole page. The cart SVG inside the
   CTA is purely decorative (the label's own trailing arrow already
   signals "go"), so dropping it here recovers width without losing any
   information — cheaper than shrinking text further, which was already
   near the practical minimum for legibility. */
@media (max-width: 400px) {
    .header-actions { gap: 4px; }
    .site-header .btn-nav-cta svg { display: none; }
    .site-header .btn-nav-cta { padding: 9px 10px; }
}

/* ------------------------------------------------------------- buttons --- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 22px;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    min-height: 44px; /* touch target, Section 9/80 */
    transition: background-color var(--bpk-transition-fast), border-color var(--bpk-transition-fast), transform var(--bpk-transition-fast);
}
.btn:active { transform: translateY(1px); }

.btn-primary {
    background: var(--button-accent-bg);
    color: var(--button-accent-text);
}
.site-header .btn-primary { white-space: nowrap; }
.btn-primary:hover { filter: brightness(1.06); }

.btn-secondary {
    background: transparent;
    color: var(--text-primary);
    border-color: var(--border-subtle);
}
.btn-secondary:hover { border-color: var(--text-primary); }

/* Nav CTA: deliberately NOT orange. The in-page hero/offer CTAs are the
   only things that should read as "the" action on a given page — a
   persistent header button in the same accent color competed with them
   and diluted which orange element actually mattered. Solid navy reads
   as a clear, confident secondary action without stealing that signal.
   Fixed brand colors (not --button-primary-bg) on purpose: that token
   flips to orange in dark mode, which would undo the whole point. */
.btn-nav-cta {
    background: var(--bpk-deep-navy);
    color: var(--bpk-white);
    border-color: var(--bpk-deep-navy);
    /* Full pill rather than the site's standard 8px button radius —
       this is the one rounder shape in the header, which is what makes
       it read as the header's own primary action rather than just
       another .btn. */
    border-radius: 999px;
    /* Locks the label to one line and stops the button from shrinking
       below its content width inside the header-actions flex row — the
       existing `.site-header .btn-primary` nowrap rule below never
       actually matched this button (it's .btn-nav-cta, not
       .btn-primary), so this was the gap. */
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 0.875rem;
}
.btn-nav-cta:hover { filter: brightness(1.3); }
[data-theme="dark"] .btn-nav-cta {
    background: transparent;
    color: var(--bpk-white);
    border-color: rgba(255,255,255,0.35);
}
[data-theme="dark"] .btn-nav-cta:hover { border-color: var(--bpk-white); }

.btn-on-dark {
    background: var(--bpk-signal-orange);
    color: var(--bpk-deep-navy);
}

.btn-ghost-on-dark {
    background: transparent;
    color: var(--bpk-white);
    border-color: rgba(255,255,255,0.35);
}
.btn-ghost-on-dark:hover { border-color: var(--bpk-white); }

/* ---------------------------------------------------------------- theme toggle --- */
.theme-toggle-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    border: 1px solid var(--border-subtle);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: color var(--bpk-transition-fast), border-color var(--bpk-transition-fast), background-color var(--bpk-transition-fast);
}
.theme-toggle-btn:hover, .theme-toggle-btn:focus-visible { color: var(--text-primary); background: var(--bg-surface); }
.theme-toggle-btn svg { width: 18px; height: 18px; }
.theme-toggle-btn .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle-btn .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle-btn .icon-moon { display: block; }

/* ---------------------------------------------------------------- sections --- */
.section { padding: 48px 0; }
.section-tight { padding: 30px 0; }
/* Targeted trims either side of a few specific boundaries that felt
   heavier than the rest — usually because the section before or after
   is unusually tall (10 category cards, 8 purchase-detail cards) or
   narrow/centered (the pricing card), which makes the standard gap
   read as more empty space than it measures. */
.section-tight-top { padding-top: 32px; }
.section-tight-bottom { padding-bottom: 32px; }
/* Page-scoped: the section directly below view-sample.php's page header
   needs a shorter top gap than section-tight-top gives, without changing
   that shared value for the other page that uses it. */
.section-viewer-top { padding-top: 20px; }
.section-alt { background: var(--bg-surface); }
.section-band-dark {
    background: var(--bg-band-dark);
    color: var(--bpk-white);
}
.section-band-dark .section-heading p,
.section-band-dark .section-heading h2 { color: var(--bpk-white); }
.section-band-dark .step-desc { color: rgba(255,255,255,0.72); }

.section-heading {
    /* Widened from 640px: at 640px this block looked like a narrow,
       disconnected strip sitting above the full-width icon/feature grids
       that follow it in the same section (grid measured ~1072px on a
       1440px viewport vs this column's 640px) — reported as a
       word-wrap/alignment issue. 780px keeps line length readable
       (~85-95 characters) while reading as part of the same content
       width as what's below it. */
    max-width: 780px;
    margin: 0 0 26px;
}
/* Scoped variant for a single section (product.php "Structured resources")
   where the heading + paragraph should span the same full width as the
   page-header above it, instead of the default 780px reading column. */
.section-heading--wide { max-width: none; }
.section-heading h2 {
    font-size: clamp(1.6rem, 2.4vw, 2.1rem);
    margin: 0 0 12px;
    letter-spacing: -0.01em;
}
.section-heading p {
    color: var(--text-secondary);
    font-size: 1.05rem;
    margin: 0;
}
/* For a section-heading with nothing else beside it in the section (no
   icon grid/list) — left-flush text just reads as a narrow strip lost in
   a lot of empty space either side. Centering balances that space instead
   of dumping it all on the right. Same treatment the pricing section's
   intro already used inline; this makes it reusable. */
.section-heading--standalone {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}
/* A standalone heading with no other content after it in the same
   section (e.g. "More than a prompt list") would otherwise leave its
   own 26px bottom margin as trailing whitespace before the section's
   padding-bottom even starts, making the gap to the next section read
   larger than every other transition on the page. */
.wrap > .section-heading:last-child {
    margin-bottom: 0;
}

/* ---------------------------------------------------- quote-insight --- */
/* "Most people use AI inconsistently" — deliberately NOT a
   .section-heading. It needs to read as a pulled-out insight/quote, not
   as another oversized page heading, so it gets its own smaller scale,
   a serif accent-orange quotation mark, and a plain (no card/border/
   gradient) editorial layout instead of reusing the h2 heading style
   used everywhere else on the page. */
.quote-insight {
    max-width: 760px;
    /* Trimmed from 40px — the gap down to the comparison panels read as
       too much dead air once both pieces were on the page together;
       the quote's own type/color/mark treatment is untouched. */
    margin: 0 auto 22px;
    padding: 12px 0;
    text-align: center;
}
.quote-insight-mark {
    /* Margin 0 (browsers default blockquote to an indented margin) —
       this isn't an inset/indented quote, it's the page's own centered
       column. */
    margin: 0;
}
/* inline-block so the pseudo-element quote marks below hug the actual
   rendered width of the (usually single-line) sentence, not the full
   760px column — otherwise they'd float far off to the sides of a much
   narrower line of text. */
.quote-insight-text {
    display: inline-block;
    position: relative;
    margin: 0;
    padding: 0 6px;
    /* Deliberately smaller than both the hero h1 (clamp 2.2-3.4rem) and
       every .section-heading h2 (clamp 1.6-2.1rem) on this page, per
       explicit direction that this must read as a pulled quote, not
       compete as another heading in the size hierarchy. Capped at 2rem
       (32px) rather than the full 36px asked for, since 36px would tie
       or exceed the section headings' own 33.6px ceiling at wide
       desktop widths. */
    font-size: clamp(1.75rem, 3vw, 2rem);
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.005em;
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .quote-insight-text { color: var(--bpk-white); }
/* Large decorative quotation marks in the brand accent — a serif glyph
   specifically (the site's own sans-serif doesn't have a distinct
   enough quote-mark shape at this size to read as a deliberate quote
   mark rather than a stray punctuation smudge). Positioned to the
   sentence's own corners via the inline-block wrapper above, not the
   full column width. */
.quote-insight-text::before,
.quote-insight-text::after {
    position: absolute;
    font-family: Georgia, 'Times New Roman', serif;
    font-size: clamp(2.25rem, 4.2vw, 2.75rem);
    line-height: 1;
    color: var(--accent);
    opacity: 0.85;
}
.quote-insight-text::before {
    content: "\201C";
    top: -0.22em;
    left: -0.5em;
}
.quote-insight-text::after {
    content: "\201D";
    bottom: -0.62em;
    right: -0.5em;
}
.quote-insight-desc {
    max-width: 700px;
    margin: 24px auto 0;
    font-size: clamp(1rem, 1.1vw, 1.125rem);
    line-height: 1.65;
    color: var(--text-secondary);
}
/* Subtle on purpose — this is a source line, not a second CTA or a
   testimonial byline, so it stays small and muted rather than styled
   like an attributed quote card. The opacity: 0.75 dimming this used to
   have dropped its effective contrast to ~3.4:1 against the page
   background, below WCAG AA's 4.5:1 (Lighthouse a11y: color-contrast).
   --text-secondary alone already reads as muted (5.85:1) without it, so
   the opacity is dropped rather than tuned down further. */
.quote-insight-attribution {
    margin: 16px 0 0;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

/* --------------------------------------------------------------------- hero --- */
.hero {
    position: relative;
    /* Trimmed further (was 96px/48px, then 56px/24px) — feedback was that
       the hero felt tall, and the gap before the next section still felt
       abrupt afterward. */
    padding: 36px 0 4px;
    overflow: hidden;
}
/* A faint brand-color glow behind the hero so the page doesn't open on
   flat white/black — subtle enough to add depth without introducing a
   new color or competing with the actual CTAs for attention. */
.hero::before {
    content: '';
    position: absolute;
    inset: -60px 0 auto 0;
    height: 520px;
    background: transparent;
    background: radial-gradient(55% 60% at 28% 10%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 70%);
    pointer-events: none;
    z-index: 0;
}
.hero > .wrap { position: relative; z-index: 1; }
/* Two-column layout: text on the left, a real brand-icon graphic filling
   the right column — replaces the old single narrow text column (max-width
   720px) that left a large empty strip of blank space to its right, with
   only a near-invisible 5%-opacity watermark floating in it. */
.hero-grid {
    display: grid;
    /* First column was 720px, but the actual content (h1 wraps around
       ~515px; .lede is capped at max-width: 560px) never fills it — that
       left a large dead gap between the visible text and the icon graphic
       in the second column, on top of the 48px grid gap. Sized to the
       widest real content (.lede's 560px) plus a little breathing room
       so the icon sits close to the text instead of far right of it. */
    grid-template-columns: minmax(0, 580px) 1fr;
    align-items: center;
    gap: 40px;
}
.hero-inner { position: relative; }
.hero-credibility {
    margin: 14px 0 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

/* The right column: the brand icon as a soft backdrop, with a floating
   "product preview" card in front of it. A plain infinity mark on its own
   didn't communicate what the product actually is — the card makes the
   $49 purchase feel tangible by showing real category names and the
   actual prompt count, the same way a screenshot would for a SaaS product. */
/* Vertically centered against the hero text column via .hero-grid's
   align-items: center (the icon backdrop was removed — it stayed partly
   hidden behind the card no matter how it was positioned, so the card
   now stands on its own as the visual). */
.hero-visual-wrap {
    justify-self: center;
    width: 100%;
    max-width: 360px;
}
.hero-preview-card {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    box-shadow: 0 16px 40px -16px rgba(23, 43, 58, 0.28);
    padding: 18px 20px;
}
[data-theme="dark"] .hero-preview-card { box-shadow: 0 16px 40px -16px rgba(0, 0, 0, 0.55); }
.hero-preview-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border-subtle);
    font-weight: 600;
    font-size: 0.92rem;
}
.hero-preview-card-head .brand-icon { height: 22px; }
.hero-preview-card-list {
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 9px 14px;
}
.hero-preview-card-list li {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.84rem;
    color: var(--text-secondary);
    white-space: nowrap;
}
.hero-preview-card-list li svg { width: 14px; height: 14px; flex: none; color: var(--positive); }
/* Informational, not a button — kept as a quiet bordered block rather
   than a solid accent fill. The card sits right next to the hero's own
   orange CTA, and a second solid-orange block here made the eye bounce
   between "click this" and "just read this" with no way to tell which
   was which. Orange in the hero now means exactly one thing: the "View
   Sample" button. */
.hero-preview-card-stat {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text-primary);
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: center;
    padding: 10px 12px;
    border-radius: 10px;
}
@media (max-width: 780px) {
    .hero-grid { grid-template-columns: 1fr; }
    .hero-visual-wrap { display: none; }
}

/* Subtle one-time entrance animation on page load — staggered fade + slight
   rise for the heading and copy. Kept short (0.6s) and understated (16px
   of movement) so it reads as polish, not a gimmick. Disabled entirely
   for users who've asked for reduced motion. */
.hero-inner h1,
.hero-inner .lede,
.hero-inner .hero-ctas {
    opacity: 0;
    animation: hero-rise 0.6s ease-out forwards;
}
.hero-inner h1 { animation-delay: 0.05s; }
.hero-inner .lede { animation-delay: 0.16s; }
.hero-inner .hero-ctas { animation-delay: 0.27s; }
.hero-visual-wrap {
    animation: hero-fade 0.6s ease-out 0.2s forwards;
}

@keyframes hero-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes hero-rise {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .hero-inner h1,
    .hero-inner .lede,
    .hero-inner .hero-ctas,
    .hero-visual-wrap {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* ------------------------------------------------------------ value strip --- */
/* Stage 11 redesign: a quiet, unified proof strip rather than four
   boxed/bordered cards — one cohesive section (icon, number, label, a
   short supporting line) separated by thin vertical dividers instead of
   card borders/backgrounds. Reads as "premium SaaS proof section", not
   an ecommerce stat-badge row, and needs no help from the offer banner
   above it: the subtle band background + generous whitespace carry the
   "this is its own section" read on their own, so it looks equally
   intentional whether the banner is showing or hidden. */
.value-strip-section {
    padding-top: 29px;
    padding-bottom: 29px;
    background: var(--bg-surface);
}
/* Deliberate gap under the offer banner when it's actually showing —
   the dark banner reads as a strong visual "wall" between the hero and
   the light stats band, so this needs more room than a quiet section
   boundary normally gets, to feel like an intentional transition
   rather than the two nearly touching. Scoped to the "-active" class
   (set server-side only when the offer is on) rather than the bare
   .offer-showcase wrapper, since that wrapper is still in the DOM
   (just empty) when the offer is off and must not gain a gap it
   doesn't need. */
.offer-showcase-active + .value-strip-section {
    margin-top: 44px;
}
.value-strip {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
}
.value-strip-item {
    position: relative;
    text-align: center;
    padding: 2px 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* Thin divider between columns — not a border around each item. Kept
   light on purpose so it reads as a quiet separator, not a focal line. */
.value-strip-item:not(:first-child)::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    bottom: 6px;
    width: 1px;
    background: var(--bg-surface);
    background: color-mix(in srgb, var(--border-subtle) 55%, var(--bg-surface) 45%);
}
/* Icon sits in a small tinted chip — gives it more visual weight than a
   bare line icon and is where the orange accent shows up, used
   sparingly (a soft tint, not a solid fill) rather than as the icon's
   own stroke color. */
.value-strip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: transparent;
    background: color-mix(in srgb, var(--accent) 14%, transparent);
    color: var(--bpk-deep-navy);
    /* Kept close to the number on purpose — icon and figure read as one
       unit, with more air reserved for separating that unit from the
       secondary label/description below. */
    margin-bottom: 14px;
}
[data-theme="dark"] .value-strip-icon {
    color: var(--bpk-white);
    background: transparent;
    background: color-mix(in srgb, var(--accent) 20%, transparent);
}
.value-strip-icon svg { width: 19px; height: 19px; stroke-width: 2; }
/* The number is the strongest element on purpose — deep navy (orange
   stays reserved for accents elsewhere, never the primary color here,
   per brand direction), ~32-36px, bold. */
.value-strip-num {
    font-size: clamp(2rem, 3.2vw, 2.25rem);
    font-weight: 800;
    letter-spacing: -0.01em;
    line-height: 1.1;
    color: var(--bpk-deep-navy);
    margin-bottom: 4px;
}
[data-theme="dark"] .value-strip-num { color: var(--bpk-white); }
.value-strip-label {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 2px;
}
.value-strip-desc {
    /* Secondary info on purpose — a step down in both size and weight
       from the label so it doesn't compete with it. */
    font-size: 0.76rem;
    color: var(--text-secondary);
    color: color-mix(in srgb, var(--text-secondary) 85%, var(--text-primary) 15%);
}
@media (max-width: 900px) {
    .value-strip { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
    .value-strip-item:not(:first-child)::before { display: none; }
    .value-strip-item:nth-child(even)::before { display: block; }
}
@media (max-width: 480px) {
    .value-strip-item { padding: 4px 12px; }
}

.hero-eyebrow-logo { margin-bottom: 28px; }
.hero h1 {
    font-size: clamp(2.2rem, 4.4vw, 3.4rem);
    line-height: 1.12;
    letter-spacing: -0.015em;
    margin: 0 0 16px;
}
.hero .lede {
    font-size: 1.15rem;
    color: var(--text-secondary);
    max-width: 560px;
    margin: 0 0 22px;
}
.hero-ctas { display: flex; gap: 14px; flex-wrap: wrap; }

/* -------------------------------------------------------- without/with compare --- */
.compare-grid {
    /* Trimmed alongside .quote-insight's own reduced bottom margin
       above — together they close up the old, overly generous gap
       between the quote and this comparison. */
    margin-top: 16px;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 28px;
    align-items: center;
}
.compare-col {
    position: relative;
    padding: 22px 24px;
    border-radius: 12px;
    border: 1px solid var(--border-subtle);
    /* A colored top edge marks each panel's state (problem/solution) —
       kept to a thin top accent plus a barely-there background tint
       rather than a colored border all around or a filled card, so the
       two panels still read as "clean and professional" first and
       "problem vs. solution" second. */
    border-top-width: 3px;
}
.compare-col h3 { margin: 0 0 14px; font-size: 1rem; }
.compare-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.compare-col li { display: flex; align-items: flex-start; gap: 10px; font-size: 0.92rem; color: var(--text-secondary); text-align: left; }
.compare-col li svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
/* Problem panel — muted red as the accent, on the existing neutral
   surface color, not a red card. */
.compare-col--without {
    background: var(--bg-surface);
    background: color-mix(in srgb, var(--negative) 3%, var(--bg-surface) 97%);
    border-top-color: var(--border-subtle);
    border-top-color: color-mix(in srgb, var(--negative) 55%, var(--border-subtle) 45%);
}
.compare-col--without li svg { color: var(--negative); }
/* Solution panel — brand orange leads (top edge, matching the site's
   existing accent-border convention for this column) with a whisper of
   the same green already used on its check icons, instead of orange
   alone, per "green/orange brand accents". Still the same neutral
   surface color underneath, not a filled/bright card. */
.compare-col--with {
    background: var(--bg-surface);
    background: color-mix(in srgb, var(--positive) 3%, var(--bg-surface) 97%);
    border-top-color: var(--accent);
}
.compare-col--with h3 { color: var(--text-primary); }
.compare-col--with li svg { color: var(--positive); }
.compare-arrow { color: var(--text-secondary); }
.compare-arrow svg { width: 22px; height: 22px; }
@media (max-width: 780px) {
    .compare-grid { grid-template-columns: 1fr; }
    .compare-arrow { transform: rotate(90deg); justify-self: center; }
}

/* ------------------------------------------------------------------ icon rows --- */
.icon-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* More breathing room (was 28px) — at a glance/zoomed-out view these
       three columns read as too small/dense for how important the
       message is. Not turned into full cards — just more air + type. */
    gap: 44px;
}
.icon-list.cols-2 { grid-template-columns: repeat(2, 1fr); }
.icon-list.cols-3 { grid-template-columns: repeat(3, 1fr); }
.icon-list--elevated .icon-item {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 26px 22px;
}
.icon-list--elevated .icon-item .icon-badge {
    background: var(--bg-surface-alt);
}
@media (max-width: 780px) {
    .icon-list.cols-2, .icon-list.cols-3 { grid-template-columns: 1fr; }
}

.icon-item { display: flex; gap: 18px; align-items: flex-start; }
.icon-item .icon-badge {
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-surface-alt);
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .icon-item .icon-badge { color: var(--bpk-signal-orange); }
.section-band-dark .icon-item .icon-badge {
    background: rgba(255,255,255,0.08);
    color: var(--bpk-signal-orange);
}
.icon-item .icon-badge svg { width: 23px; height: 23px; }
.icon-item h3 { margin: 4px 0 8px; font-size: 1.15rem; }
.icon-item p { margin: 0; color: var(--text-secondary); font-size: 1rem; line-height: 1.5; }
.section-band-dark .icon-item p { color: rgba(255,255,255,0.72); }
.section-band-dark .hero-preview-card-list li { color: rgba(255,255,255,0.82); }

/* ------------------------------------------------------------- process steps --- */
/* "What actually changes with structure" — deliberately its own
   component rather than a third use of .icon-list/.icon-item. Three
   boxed, shadowed cards read as "features", which is what this used to
   be; a numbered 01/02/03 progression with a connecting line reads as
   a methodology instead — no card background, no border, no shadow,
   just typography, small icons and whitespace. */
.process-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* 3 content columns + 2 narrow connector columns between them,
       rather than a plain 3-col grid with the connector overlaid —
       keeps the connecting line's width (and therefore its vertical
       centering) independent of the step columns' own width. */
    grid-template-columns: 1fr 64px 1fr 64px 1fr;
    /* Top-aligned, not centered: the three steps' body copy wraps to
       different numbers of lines, and centering each column
       independently within the row shifts their numbers up or down
       relative to each other. Starting every column at the same top
       edge keeps the three numbers level with each other and with
       .process-connector's own margin-top below. */
    align-items: start;
    gap: 0 8px;
    /* Set here (rather than on .process-step-num itself) so
       .process-connector — a sibling grid item, not a descendant of
       the number — can read the same value via CSS custom-property
       inheritance down the tree. */
    --process-num-size: clamp(2rem, 3vw, 2.5rem);
}
.process-step-meta {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 18px;
}
/* The number leads — it's the strongest single element in this
   section, standing in for the oversized icon/heading a feature card
   would normally use to grab attention. Uses --link-accent rather than
   --accent: this section sits on the light section-alt background, and
   --accent (raw --bpk-signal-orange) is the color tokens.css itself
   documents as failing 4.5:1 there (Lighthouse a11y: color-contrast).
   --link-accent is that same brand orange's WCAG-AA-safe variant —
   darker on light mode, already full-brightness (and already passing)
   on dark mode — so this now behaves correctly in both themes without
   a separate dark-mode override. */
.process-step-num {
    font-size: var(--process-num-size);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--link-accent);
}
.process-step-icon {
    display: inline-flex;
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .process-step-icon { color: var(--bpk-signal-orange); }
.process-step-icon svg { width: 22px; height: 22px; }
.process-step h3 { margin: 0 0 8px; font-size: 1.1rem; }
.process-step p { margin: 0; color: var(--text-secondary); font-size: 0.96rem; line-height: 1.55; max-width: 34ch; }
/* A quiet horizontal rule standing in for an arrow — the arrow motif is
   already used twice elsewhere on this page (the comparison panels
   above, the workflow steps below), so a plain connecting line here
   keeps this section visually distinct rather than repeating it a
   third time. Faded at both ends instead of a hard-edged bar so it
   reads as a subtle connector, not a divider/rule. */
.process-connector {
    height: 1px;
    /* Centered against the full height of the row — number, heading and
       description together — rather than pinned to the number alone.
       .process-step itself still starts at the row's top edge (see
       align-items: start above), so the three numbers stay level with
       each other regardless of how many lines each step's own
       description wraps to; this connector is the one exception that
       centers within that shared row height instead. */
    align-self: center;
    background: linear-gradient(to right, transparent, var(--border-subtle) 30%, var(--border-subtle) 70%, transparent);
}
@media (max-width: 780px) {
    .process-steps { grid-template-columns: 1fr; gap: 32px 0; }
    /* Rotated vertical instead of hidden outright — still reads as "a
       sequence connects these" once the columns stack. */
    .process-connector { width: 1px; height: 28px; margin: 0 0 0 26px; background: linear-gradient(to bottom, transparent, var(--border-subtle) 30%, var(--border-subtle) 70%, transparent); }
}

/* --------------------------------------------------------------- applications --- */
/* Real cards (was a 1px-seam table-like grid — dense, felt like a
   spreadsheet at a glance). Each category now gets its own bordered,
   shadowed card with more padding and larger type, scannable in 1-2s. */
.applications-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 20px;
}
.applications-grid > div {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 26px 24px;
    display: flex;
    gap: 16px;
    align-items: flex-start;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.applications-grid > div:hover {
    box-shadow: 0 14px 32px -18px rgba(23, 43, 58, 0.25);
    transform: translateY(-2px);
}
[data-theme="dark"] .applications-grid > div:hover { box-shadow: 0 14px 32px -18px rgba(0, 0, 0, 0.5); }
.applications-grid .icon-badge {
    flex: none;
    width: 42px;
    height: 42px;
    border-radius: 10px;
    background: var(--bg-surface-alt);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .applications-grid .icon-badge { color: var(--bpk-signal-orange); }
.applications-grid .icon-badge svg { width: 22px; height: 22px; }
.applications-grid h3 { margin: 0 0 6px; font-size: 1.05rem; }
.applications-grid p { margin: 0; font-size: 0.92rem; line-height: 1.5; color: var(--text-secondary); }

/* ----------------------------------------------------- category directory --- */
/* "Built for every part of the business" — a second, deliberately
   different treatment from .applications-grid above (which stays as-is
   for product.php's own copy of this same list): a two-column
   directory with quiet row/column rules instead of ten individual
   bordered cards, so ten repeats of the same shape don't read as a
   wall of identical tiles right after the numbered process section
   above. Subtle on purpose — a thin rule, not a card boundary. */
.category-directory {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    column-gap: 48px;
}
.category-directory-item {
    padding: 20px 0;
    /* Faded divider rather than a hard edge, echoing .process-connector
       above so the two redesigned sections still feel related. */
    border-bottom: 1px solid var(--bg-page);
    border-bottom: 1px solid color-mix(in srgb, var(--border-subtle) 55%, var(--bg-page) 45%);
}
/* Right-hand column of the pair gets a vertical rule instead of the
   column-gap alone standing in for a boundary — same faded treatment,
   applied as a left border since column-gap can't carry a background. */
.category-directory-item:nth-child(2n) {
    border-left: 1px solid var(--bg-page);
    border-left: 1px solid color-mix(in srgb, var(--border-subtle) 55%, var(--bg-page) 45%);
    padding-left: 48px;
    margin-left: -48px;
}
/* Last row (the final two items) shouldn't carry a trailing rule with
   nothing below it. */
.category-directory-item:nth-last-child(-n+2) { border-bottom: none; }
.category-directory-item h3 {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 6px;
    font-size: 1.05rem;
}
.category-directory-icon {
    display: inline-flex;
    flex: none;
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .category-directory-icon { color: var(--bpk-signal-orange); }
.category-directory-icon svg { width: 19px; height: 19px; }
.category-directory-item p {
    margin: 0;
    padding-left: 31px; /* aligns under the label, past the icon+gap above */
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-secondary);
}
@media (max-width: 640px) {
    .category-directory { grid-template-columns: 1fr; }
    .category-directory-item:nth-child(2n) { border-left: none; padding-left: 0; margin-left: 0; }
    .category-directory-item:nth-last-child(-n+2) { border-bottom: 1px solid var(--bg-page); border-bottom: 1px solid color-mix(in srgb, var(--border-subtle) 55%, var(--bg-page) 45%); }
    .category-directory-item:last-child { border-bottom: none; }
}

/* --------------------------------------------------------- see what's inside --- */
.inside-block { margin-top: 28px; }
.inside-block:first-of-type { margin-top: 0; }
.inside-block-head { margin-bottom: 22px; }
.inside-block-head h3 { margin: 0 0 6px; font-size: 1.2rem; }
.inside-block-head p { margin: 0; color: var(--text-secondary); font-size: 0.95rem; }

.prompt-sample-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 20px;
}
/* Presented as a small "product preview" card — a document-style top bar
   (category + the real source filename) so each card reads as a genuine
   file excerpt, a boxed preview panel for the quoted text so it looks
   like a screenshot rather than a stray paragraph, and a hover lift to
   match the applications cards elsewhere on the page. */
.prompt-sample-card {
    position: relative;
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    padding: 20px 20px 22px;
    box-shadow: 0 2px 6px rgba(23, 43, 58, 0.06);
    overflow: hidden;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}
/* Slim brand-colored top edge — the one "this is a product" cue that
   doesn't require touching the rest of the card's restrained styling. */
.prompt-sample-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--bpk-signal-orange);
}
.prompt-sample-card:hover {
    box-shadow: 0 18px 36px -18px rgba(23, 43, 58, 0.32);
    transform: translateY(-3px);
}
[data-theme="dark"] .prompt-sample-card { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
[data-theme="dark"] .prompt-sample-card:hover { box-shadow: 0 18px 36px -18px rgba(0, 0, 0, 0.6); }
.prompt-sample-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 16px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border-subtle);
}
.prompt-sample-card-head-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.prompt-sample-card-head .icon-badge {
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: 8px;
    background: var(--bg-surface-alt);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .prompt-sample-card-head .icon-badge { color: var(--bpk-signal-orange); }
.prompt-sample-card-head .icon-badge svg { width: 17px; height: 17px; }
.prompt-sample-card-badge {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-primary);
    background: var(--bg-surface-alt);
    padding: 4px 10px;
    border-radius: 999px;
    white-space: nowrap;
}
/* The real PDF filename each excerpt was copied from — genuine detail
   that reinforces "this is the actual file", not decoration. */
.prompt-sample-card-source {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 0.74rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: var(--text-secondary);
    opacity: 0.85;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.prompt-sample-card-source svg { width: 12px; height: 12px; flex: none; }
.prompt-sample-card h4 { margin: 0 0 6px; font-size: 1.02rem; }
.prompt-sample-card-desc {
    margin: 0 0 14px;
    font-size: 0.85rem;
    color: var(--text-secondary);
}
/* Boxed like a document preview pane, not just italic body text. */
/* A soft inset shadow gives the excerpt panel a slight "screen" depth
   instead of sitting perfectly flush with the card. */
.prompt-sample-card-preview {
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    padding: 14px 16px;
    box-shadow: inset 0 1px 3px rgba(23, 43, 58, 0.05);
}
[data-theme="dark"] .prompt-sample-card-preview { box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25); }
.prompt-sample-card-text {
    margin: 0;
    font-size: 0.9rem;
    font-style: italic;
    color: var(--text-primary);
    line-height: 1.55;
}
@media (max-width: 480px) {
    .prompt-sample-card-head { flex-wrap: wrap; }
    .prompt-sample-card-source { white-space: normal; }
}

.workflow-example-label { margin: 0 0 16px; font-size: 0.88rem; font-weight: 600; color: var(--text-secondary); }
.workflow-steps {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.workflow-step {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    padding: 12px 18px;
    font-size: 0.9rem;
    font-weight: 600;
}
.workflow-arrow { color: var(--text-secondary); flex: none; }
.workflow-arrow svg { width: 16px; height: 16px; }
@media (max-width: 780px) {
    .workflow-steps { flex-direction: column; align-items: stretch; }
    .workflow-step { text-align: center; }
    .workflow-arrow { transform: rotate(90deg); align-self: center; }
}

/* -------------------------------------------------------------- steps (how it works) --- */
.steps { counter-reset: step; display: grid; gap: 28px; }
.step { display: flex; gap: 18px; align-items: flex-start; }
.step-num {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    border: 1.5px solid var(--bpk-signal-orange);
    color: var(--bpk-signal-orange);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.95rem;
}
.step h3 { margin: 4px 0 6px; font-size: 1.05rem; }
.step p { margin: 0; color: var(--text-secondary); font-size: 0.95rem; }

/* --------------------------------------------------------------- what you get --- */
/* Cards, not plain text blocks — visually separates the four groups so
   the section reads as four scannable chunks instead of a dense list. */
.receive-groups { display: grid; gap: 20px; grid-template-columns: repeat(2, 1fr); }
@media (max-width: 780px) { .receive-groups { grid-template-columns: 1fr; } }
.card-surface {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 26px 24px;
}
.receive-group h3 {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.02rem;
    margin: 0 0 14px;
}
.receive-group h3 .icon-badge {
    width: 36px; height: 36px; flex: none; border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg-surface-alt); color: var(--bpk-deep-navy);
}
[data-theme="dark"] .receive-group h3 .icon-badge { color: var(--bpk-signal-orange); }
.receive-group ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.receive-group li {
    padding-left: 22px;
    position: relative;
    color: var(--text-secondary);
    font-size: 0.94rem;
}
/* Bolds the leading figure in a bullet (500+, 200+, ~300...) so the
   numbers themselves scan at a glance instead of hiding inside a
   sentence. */
.receive-stat-num { color: var(--text-primary); font-weight: 800; }
.receive-group li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 8px;
    height: 8px;
    background-image: var(--icon-mark);
    background-size: contain;
    background-repeat: no-repeat;
    opacity: 0.75;
}

/* ------------------------------------------------------------------- pricing --- */
.pricing-card {
    max-width: 460px;
    margin: 0 auto;
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    padding: 40px 36px;
    text-align: center;
}
.pricing-price { font-size: 3rem; font-weight: 800; letter-spacing: -0.02em; margin: 8px 0 2px; }
.pricing-price sup { font-size: 1.2rem; top: -1.4em; }
.pricing-note { color: var(--text-secondary); font-size: 0.9rem; margin: 0 0 20px; }
/* The big four numbers up front in "What you receive," before the
   category cards — so the section reads "there's a lot included" at a
   glance instead of asking the visitor to read every card to find out. */
.receive-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin: 0 0 10px;
    padding: 20px 8px;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    text-align: center;
}
.receive-stats div { display: flex; flex-direction: column; gap: 2px; }
.receive-stats strong { font-size: clamp(1.4rem, 3vw, 1.8rem); font-weight: 800; color: var(--text-primary); letter-spacing: -0.01em; }
.receive-stats span { font-size: 0.78rem; color: var(--text-secondary); font-weight: 600; }
.receive-stats-caption {
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.88rem;
    margin: 0 0 28px;
}
@media (max-width: 640px) {
    .receive-stats { grid-template-columns: repeat(2, 1fr); gap: 14px 8px; }
}

/* A compact recap of the same five numbers from the value strip up top —
   right where someone is deciding whether $49 is worth it. */
.pricing-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
    margin: 0 0 24px;
    padding: 16px 4px;
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
}
.pricing-stats div { display: flex; flex-direction: column; gap: 2px; }
.pricing-stats strong { font-size: 1.05rem; font-weight: 800; color: var(--text-primary); }
.pricing-stats span { font-size: 0.72rem; color: var(--text-secondary); }
.pricing-list { list-style: none; margin: 0 0 28px; padding: 0; text-align: left; display: grid; gap: 12px; }
.pricing-list li { padding-left: 22px; position: relative; font-size: 0.94rem; }
.pricing-list li::before {
    content: '';
    position: absolute; left: 0; top: 0.45em;
    width: 8px; height: 8px;
    background-image: var(--icon-mark);
    background-size: contain; background-repeat: no-repeat;
    opacity: 0.85;
}
.pricing-card .btn { width: 100%; }

/* -------------------------------------------------------------------- testimonials --- */
.testimonial-grid {
    display: grid;
    gap: 20px;
    grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 980px) { .testimonial-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .testimonial-grid { grid-template-columns: 1fr; } }
/* Lighter than the default .card-surface padding — three curated quotes
   should read as quick proof, not another heavy card section. */
.testimonial-card { margin: 0; padding: 22px 20px; }
.testimonial-card blockquote { margin: 0; }
.testimonial-card p {
    margin: 0;
    color: var(--text-primary);
    font-size: 0.96rem;
    line-height: 1.55;
}

/* ------------------------------------------------------------- before-you-purchase --- */
/* Was one large bordered panel holding eight dense dt/dd blocks — split
   into its own small icon card per item so it scans instead of reading
   as a wall of legal-adjacent text. */
.byp-panel {
    padding: 0;
    background: transparent;
}
.byp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 18px;
    margin: 0;
}
.byp-item {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 22px 20px;
}
.byp-item .icon-badge {
    width: 34px; height: 34px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg-surface-alt); color: var(--bpk-deep-navy);
    margin-bottom: 12px;
}
[data-theme="dark"] .byp-item .icon-badge { color: var(--bpk-signal-orange); }
.byp-item .icon-badge svg { width: 18px; height: 18px; }
.byp-item dt { font-weight: 600; margin-bottom: 6px; font-size: 0.98rem; }
.byp-item dd { margin: 0; color: var(--text-secondary); font-size: 0.9rem; line-height: 1.5; }
.byp-links { margin-top: 28px; display: flex; flex-wrap: wrap; gap: 10px 20px; font-size: 0.88rem; }
.byp-links a { text-decoration: underline; color: var(--text-secondary); }

/* ---------------------------------------------------- checkout page container --- */
/* Narrower than the default 1120px .wrap: a payment form reads better as
   a compact, centered task than as a long full-width page. */
/* padding-top/bottom only (not the horizontal shorthand) — a plain
   "padding: 40px 0 16px" was zeroing out .wrap's own 24px side padding,
   leaving "Checkout" / the eyebrow / subtitle flush against the true
   container edge instead of aligned with .checkout-card below (which
   correctly inherits .wrap's padding) — visible as a left-alignment
   mismatch at every width, worst on mobile where nothing else cushions
   it from the screen edge. */
.checkout-page-header { max-width: 1080px; padding-top: 40px; padding-bottom: 16px; }
.checkout-page-header h1 { font-size: clamp(1.75rem, 2.4vw, 2rem); margin: 0; }
.checkout-wrap { max-width: 1080px; padding-bottom: 64px; }

.checkout-alert {
    padding: 12px 16px; border-radius: 8px; font-size: 0.9rem; margin-bottom: 20px;
}
.checkout-alert-error { background: #FBE4E2; color: #B3261E; }
.checkout-alert-warning { background: #FFF3D6; color: #9A6700; }

/* ------------------------------------------------------------------ checkout-card --- */
/* A properly bounded, padded card for a single self-contained box of
   content — the checkout form, the license-key login form, and their
   inline notices. Distinct from .byp-panel on purpose: .byp-panel is
   deliberately bare (padding: 0, background: transparent) because it's
   only ever a bare grid wrapper around its own .byp-item cards on the
   "before you purchase" section — reusing it here left the checkout and
   login forms with no visible card boundary and no internal breathing
   room at all. */
.checkout-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    padding: 28px 26px;
}
.checkout-card + .checkout-card { margin-top: 16px; }
@media (max-width: 480px) {
    .checkout-card { padding: 22px 18px; }
}

/* ------------------------------------------------------------------ checkout layout --- */
/* Two columns, roughly 60/40: the payment form/actions carry the most
   visual weight on the left, a compact sticky order summary sits on the
   right rather than trailing below the form. */
.checkout-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 28px;
    align-items: start;
}
.checkout-main { order: 2; min-width: 0; display: grid; gap: 24px; }
.checkout-main > form.checkout-card { margin-top: 0; }
.checkout-summary { order: 3; }
/* Clean, quiet card: white/page background, a plain 1px border and a
   very subtle resting shadow — matches the general homepage card
   language (e.g. .prompt-sample-card) instead of the heavier tinted
   surface + accent top-border treatment used elsewhere on the site. */
.checkout-summary-card {
    position: sticky; top: 24px;
    background: var(--bg-page);
    box-shadow: 0 2px 6px rgba(23, 43, 58, 0.06);
    padding: 31px 29px;
}
[data-theme="dark"] .checkout-summary-card { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
.checkout-summary-card h2 {
    margin: 0 0 14px; font-size: 0.78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-secondary);
}
.checkout-summary-product { font-size: 0.95rem; font-weight: 600; color: var(--text-primary); margin: 0 0 9px; }
/* Price-tag treatment: a rounded pill (one corner pinched to read as a
   tag) in the brand accent color, with a small tag/label icon in front —
   makes the price the visual focal point of the summary card instead of
   blending into the same near-black text as everything around it. */
.checkout-summary-price-tag {
    display: inline-flex; align-items: center; gap: 8px;
    margin: 5px 0 3px; padding: 8px 16px 8px 12px;
    border-radius: 10px 10px 10px 3px;
    background: transparent;
    background: color-mix(in srgb, var(--accent) 14%, transparent);
    border: 1px solid transparent;
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
    color: var(--text-primary);
}
.checkout-summary-price-tag svg { flex-shrink: 0; color: var(--accent); }
.checkout-summary-price { font-size: 2.1rem; font-weight: 700; letter-spacing: -0.01em; line-height: 1.1; color: var(--text-primary); }
.checkout-summary-price-currency { font-size: 0.95rem; font-weight: 600; color: var(--text-secondary); opacity: 1; margin-left: 5px; }
.checkout-summary-sub { font-size: 0.85rem; color: var(--text-secondary); margin: 7px 0 0; }
.checkout-trust-list { list-style: none; margin: 22px 0 0; padding: 18px 0 0; border-top: 1px solid var(--border-subtle); display: grid; gap: 10px; }
.checkout-trust-list li { display: flex; align-items: center; gap: 10px; font-size: 0.85rem; color: var(--text-secondary); }
.checkout-trust-list svg { flex-shrink: 0; color: var(--bpk-signal-orange); }

.checkout-captcha-wrap { margin: 20px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border-subtle); width: 100%; }
.checkout-captcha-wrap .cf-turnstile { width: 100%; }

/* ---------------------------------------------------------- page header (v2) --- */
.checkout-page-subtitle { margin: 6px 0 0; font-size: 1rem; color: var(--text-secondary); }
.checkout-page-reassurance { margin: 10px 0 0; font-size: 0.84rem; font-weight: 600; color: var(--text-primary); letter-spacing: 0.01em; }

/* ------------------------------------------------------- secure checkout note --- */
/* Compact reassurance line, not a bordered/tinted "seal" box — deliberately
   quieter than a card so it reads as a passing reassurance next to the
   payment-method choice rather than another boxed element on the page. */
.checkout-secure-block {
    display: flex; align-items: flex-start; gap: 10px;
    margin: 20px 0 0;
}
.checkout-secure-block svg { flex-shrink: 0; margin-top: 1px; }
.checkout-secure-block-text {
    margin: 0; font-size: 0.92rem; line-height: 1.5; color: var(--text-secondary);
}
.checkout-secure-block-text strong { color: var(--text-primary); font-weight: 700; }

/* ------------------------------------------------------- what happens after payment --- */
.checkout-after-payment { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--border-subtle); }
.checkout-section-subheading {
    margin: 0 0 12px; font-size: 0.78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-secondary);
}
.checkout-after-payment-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.checkout-after-payment-list li {
    position: relative; padding-left: 24px;
    font-size: 0.86rem; line-height: 1.5; color: var(--text-secondary);
}
.checkout-after-payment-list li::before {
    content: '\2713'; position: absolute; left: 0; top: 1px;
    width: 16px; height: 16px; line-height: 16px; text-align: center;
    font-size: 0.65rem; font-weight: 700; color: var(--bpk-deep-navy);
    background: transparent;
    background: color-mix(in srgb, var(--bpk-signal-orange) 20%, transparent);
    border-radius: 50%;
}
[data-theme="dark"] .checkout-after-payment-list li::before { color: var(--bpk-white); }
.checkout-after-payment-list li strong { color: var(--text-primary); }
.checkout-after-payment-list li a { color: var(--link-accent); }

/* ------------------------------------------------------- order summary (v2) --- */
.checkout-summary-includes {
    list-style: none; margin: 14px 0 0; padding: 14px 0;
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    display: grid; gap: 8px;
}
.checkout-summary-includes li {
    position: relative; padding-left: 16px;
    font-size: 0.88rem; color: var(--text-secondary);
}
.checkout-summary-includes li::before {
    content: ''; position: absolute; left: 0; top: 0.55em;
    width: 5px; height: 5px; border-radius: 50%;
    background: var(--bpk-signal-orange);
}
.checkout-summary-price-block { margin-top: 18px; }
.checkout-summary-price-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; margin-bottom: 8px;
}
.checkout-summary-price-was { font-size: 0.85rem; color: var(--text-secondary); }
.checkout-summary-price-was del { text-decoration: line-through; }
.checkout-summary-offer-badge {
    flex-shrink: 0;
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.01em;
    color: var(--bpk-deep-navy);
    background: transparent;
    background: color-mix(in srgb, var(--bpk-signal-orange) 22%, transparent);
    padding: 3px 9px; border-radius: 999px;
    white-space: nowrap;
}
[data-theme="dark"] .checkout-summary-offer-badge { color: var(--bpk-white); }
.checkout-summary-total-row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; padding-top: 8px;
}
.checkout-summary-total-label { font-size: 0.9rem; font-weight: 600; color: var(--text-primary); }

/* ------------------------------------------------------ "before you buy" points --- */
/* Deliberately quieter than the payment card: smaller eyebrow-style
   title, tighter list, and less padding so it reads as a compact aside
   rather than competing with the payment section for attention. */
.checkout-before-you-buy { padding: 14px 18px; }
.checkout-before-you-buy-title {
    margin: 0 0 8px; font-size: 0.68rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-secondary);
}
.checkout-before-you-buy-list {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: 7px;
}
.checkout-before-you-buy-list li {
    position: relative; padding-left: 18px;
    font-size: 0.82rem; line-height: 1.4; color: var(--text-secondary);
}
.checkout-before-you-buy-list li::before {
    content: ''; position: absolute; left: 0; top: 0.5em;
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--bpk-signal-orange);
}
.checkout-before-you-buy-list li strong { color: var(--text-primary); }
.checkout-before-you-buy-list li a { color: var(--link-accent); }

@media (max-width: 900px) {
    .checkout-layout { grid-template-columns: 1fr; gap: 24px; }
    .checkout-main { order: 2; }
    .checkout-summary { order: 1; }
    .checkout-summary-card { position: static; }
}

/* --------------------------------------------------------- payment method cards --- */
.checkout-payment-method-block { margin-bottom: 24px; }
.checkout-payment-heading {
    margin: 0 0 4px; font-size: 1.4rem; font-weight: 700;
    color: var(--text-primary); letter-spacing: -0.01em;
}
.checkout-payment-subheading {
    margin: 0 0 16px; font-size: 0.92rem; color: var(--text-secondary);
}
/* Retained for any other page still using the plain eyebrow-style label
   (checkout.php itself now uses .checkout-payment-heading instead). */
.checkout-section-heading {
    display: block; font-weight: 600; margin-bottom: 10px;
    font-size: 1.2rem; color: var(--text-primary);
}
/* Single-column, method-first payment list (Section: checkout real-logo
   redesign). One row per provider — LicenseService::computePrice() routes
   pricing/currency by provider, so the selectable unit stays the provider,
   never an individual method — but each row leads with the actual payment
   METHODS (real brand logos) rather than the gateway's own brand name,
   since visitors recognize "Visa" or "Google Pay" far more readily than
   "Razorpay" or "Lemon Squeezy". The provider name still appears (as the
   row title, and as a small avatar) so it's never hidden, just not the
   first thing scanned. */
.payment-method-list {
    display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px;
}

.payment-method-option {
    position: relative;
    display: flex; align-items: flex-start; text-align: left;
    gap: 12px; padding: 12px 14px;
    border: 1.5px solid var(--border-subtle); border-radius: 12px;
    cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.payment-method-option:hover { border-color: var(--bpk-signal-orange); }
/* :has() reached full support across evergreen browsers only in late
   2023 (Firefox was last) — .is-selected is a JS-driven fallback for
   the same visual state (checkout.php toggles it on change), so the
   highlight still works even where :has() silently drops the rule
   below. Identical declarations kept in sync deliberately, not
   duplicated by accident. */
.payment-method-option.is-selected,
.payment-method-option:has(input:checked) {
    border-color: var(--bpk-signal-orange);
    background: transparent;
    background: color-mix(in srgb, var(--bpk-signal-orange) 6%, transparent);
    box-shadow: 0 0 0 1px var(--bpk-signal-orange);
}
.payment-method-option input[type="radio"] {
    flex-shrink: 0; margin: 3px 0 0;
    width: 18px; height: 18px; accent-color: var(--bpk-signal-orange);
}
/* Provider avatar: the provider's own real logo file, shown at its
   original aspect ratio (never squashed into a forced square) on a fixed
   light tile so it stays legible and reads consistently in both themes —
   these are the providers' own official marks, most already opaque with
   their own colors, so the tile itself stays light regardless of site
   theme. Fixed footprint regardless of each provider's own logo aspect
   ratio — Razorpay's and Lemon Squeezy's wordmarks are far wider than
   PayPal's, and without a cap here the widest one balloons the row.
   object-fit: contain (below) scales the real logo down to fit this box
   without distorting or cropping it — never stretched, never redrawn,
   just displayed smaller. */
.payment-method-avatar {
    flex-shrink: 0; width: 46px; height: 34px; padding: 0 6px;
    border-radius: 8px; display: flex; align-items: center; justify-content: center;
    background: #fff; border: 1.5px solid var(--border-subtle); overflow: hidden;
}
.payment-method-avatar img { max-width: 78%; max-height: 78%; height: auto; width: auto; object-fit: contain; display: block; }
.payment-method-body { display: flex; flex-direction: column; gap: 1px; width: 100%; min-width: 0; }
.payment-method-title { font-weight: 700; font-size: 0.92rem; color: var(--text-primary); }
/* Block-level rather than inline: at narrower card widths "(a Stripe
   company)" otherwise mid-word-wraps onto its own line unpredictably —
   forcing it onto its own line always looks deliberate instead of broken. */
.payment-method-title .trust-inline { display: block; font-weight: 500; color: var(--text-secondary); font-size: 0.76rem; margin-top: 1px; }
.payment-method-desc { font-size: 0.76rem; color: var(--text-secondary); line-height: 1.3; margin-bottom: 5px; }
/* Method chips: small pills naming what this gateway accepts, grouped
   from the provider's existing 'accepts' text (see checkout.php) rather
   than claiming anything new. Generic line icons only for categories with
   no brand mark of their own (Card, Netbanking, UPI-as-a-network). */
.payment-method-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 5px; min-width: 0; }
.payment-method-chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 7px; border-radius: 6px;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    font-size: 0.72rem; font-weight: 600; color: var(--text-primary);
    /* Lets a long label ("PayPal balance") wrap or shrink inside its own
       pill instead of forcing the whole row (and card) to overflow at
       narrow widths — a flex item's default min-width is its content's
       full width, which is exactly what caused that overflow. */
    max-width: 100%; min-width: 0;
}
.payment-method-chip svg { flex-shrink: 0; color: var(--text-secondary); }
.payment-method-chip span { min-width: 0; overflow-wrap: break-word; }
/* Real brand-logo row: each mark on its own light card, unmodified
   (original colors/proportions), auto-width so nothing gets stretched or
   cropped to fit a fixed box. */
.payment-method-logo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.brand-chip {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 3px 6px; border-radius: 5px;
    background: #fff; border: 1px solid var(--border-subtle);
}
.brand-chip img { display: block; width: auto; }
/* ------------------------------------------------------------------ legal agreement box --- */
/* Smaller type + a quiet bordered/tinted panel so the three consent
   checkboxes read as routine fine print rather than dominating the page
   the way full-size body-copy paragraphs did. */
.checkout-agreements {
    display: grid; gap: 10px;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    padding: 14px 16px;
    margin-top: 20px;
}
.checkout-agreement-item {
    display: flex; gap: 10px; align-items: flex-start;
    font-weight: normal; font-size: 0.8rem; line-height: 1.45;
    color: var(--text-secondary);
}
.checkout-agreement-item + .checkout-agreement-item { padding-top: 10px; border-top: 1px solid var(--border-subtle); }
.checkout-agreement-item input { margin-top: 4px; flex-shrink: 0; }
.checkout-agreement-item strong { color: var(--text-primary); }
.checkout-agreement-item a { color: var(--link-accent); }

/* ------------------------------------------------------------------ checkout CTA --- */
/* Strong navy button (--button-primary-bg — the same token/treatment the
   homepage's own primary buttons use) rather than the orange accent
   button used for secondary actions elsewhere on this page, so the buy
   action reads as the dominant, unmistakable next step. */
.btn-checkout-cta {
    background: var(--button-primary-bg);
    color: var(--button-primary-text);
    width: 100%;
    margin-top: 22px;
    padding: 15px 22px;
    font-size: 1.05rem;
    min-height: 52px;
}
.btn-checkout-cta:hover { filter: brightness(1.08); box-shadow: 0 4px 12px rgba(23, 43, 58, 0.18); }
/* "Get BusinessPromptKit — $X.XX →" wraps to two lines below ~400px at
   the default size — shrink just enough to keep it on one line rather
   than shortening the copy itself. */
@media (max-width: 420px) {
    .btn-checkout-cta { font-size: 0.92rem; padding: 14px 14px; }
}

.checkout-secure-note {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.8rem; color: var(--text-secondary);
    margin-top: 14px;
}
.checkout-secure-note svg { flex-shrink: 0; color: var(--bpk-signal-orange); }

/* A more prominent "seal" than a plain trust line: bordered badge with a
   shield-check icon, an accurate compliance headline (PayPal and Stripe —
   which powers Lemon Squeezy — are both documented PCI DSS Level 1
   service providers; Razorpay holds a PCI DSS v4.0.1 certification), and
   the existing never-sees-your-card-details reassurance underneath. */
.checkout-trust-seal {
    display: flex; align-items: flex-start; gap: 10px;
    margin-top: 16px; padding: 12px 14px;
    background: var(--bg-page);
    background: color-mix(in srgb, var(--bg-surface-alt) 55%, var(--bg-page));
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
}
.checkout-trust-seal svg { flex-shrink: 0; color: var(--bpk-signal-orange); margin-top: 1px; }
.checkout-trust-seal-text { display: flex; flex-direction: column; gap: 2px; }
.checkout-trust-seal-text strong { font-size: 0.8rem; color: var(--text-primary); }
.checkout-trust-seal-text span { font-size: 0.73rem; color: var(--text-secondary); line-height: 1.4; }

/* ------------------------------------------------------------------ branded text inputs --- */
/* Used on login.php's license-key field (and anywhere else a plain text
   input needs the same polish as the rest of checkout/login) — a
   consistent, slightly rounder border radius and an orange focus ring
   instead of the browser's default blue outline, which clashed with the
   rest of the page's accent color. */
.field-input {
    width: 100%; box-sizing: border-box;
    padding: 12px 14px;
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.95rem;
    background: var(--bg-page);
    color: var(--text-primary);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.field-input:focus {
    outline: none;
    border-color: var(--bpk-signal-orange);
    box-shadow: 0 0 0 3px transparent;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--bpk-signal-orange) 18%, transparent);
}
.field-input.field-input-mono { font-family: 'SFMono-Regular', Consolas, monospace; letter-spacing: 0.03em; }

/* ------------------------------------------------------------------ license key reveal (thank-you page) --- */
.license-key-card {
    background: var(--bg-surface-alt);
    border-top: 3px solid var(--bpk-signal-orange);
    text-align: left;
}
.license-key-card .license-key-label {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.78rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--text-secondary);
    margin: 0 0 12px;
}
.license-key-card .license-key-label svg { flex-shrink: 0; color: var(--bpk-signal-orange); }
.license-key-value {
    display: block; width: 100%; box-sizing: border-box;
    background: var(--bg-page); border: 1px dashed var(--border-subtle); border-radius: 8px;
    padding: 14px 16px;
    font-family: 'SFMono-Regular', Consolas, monospace;
    font-size: 1.1rem; font-weight: 600; letter-spacing: 0.03em;
    word-break: break-all; text-align: center;
    margin-bottom: 14px;
}

/* ------------------------------------------------------------------------ FAQ --- */
/* Stage 4: lighter treatment than About — no surface cards, no icons, no
   numbered badges. Just a stronger question weight/size, roomier
   answer copy, and the existing bottom-border divider between items
   doing the separation work (already present pre-refinement; kept
   as-is rather than adding a wrapping card). */
.faq-list { max-width: 780px; }
.faq-item {
    border-bottom: 1px solid var(--border-subtle);
    padding: 6px 0;
}
.faq-item summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 4px;
    font-weight: 700;
    font-size: 1.08rem;
    color: var(--text-primary);
    border-radius: 8px;
    transition: background-color var(--bpk-transition-fast);
}
.faq-item summary:hover { background: var(--bg-surface); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary .faq-plus {
    flex: none;
    width: 22px; height: 22px;
    border-radius: 999px;
    border: 1.5px solid var(--border-subtle);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.9rem;
    color: var(--text-secondary);
}
.faq-item[open] summary .faq-plus { color: var(--bpk-signal-orange); border-color: var(--bpk-signal-orange); }
.faq-item[open] summary .faq-plus::before { content: '\2212'; } /* minus */
.faq-item summary .faq-plus::before { content: '\002B'; } /* plus */
.faq-item p {
    margin: 0;
    padding: 0 4px 22px;
    color: var(--text-secondary);
    font-size: 0.97rem;
    line-height: 1.65;
    max-width: 68ch;
}

/* Small closing support nudge after the last FAQ item — same divider
   token as the items above it, not a new visual element. */
.faq-closing {
    margin: 8px 0 0;
    padding-top: 28px;
    border-top: 1px solid var(--border-subtle);
    max-width: 780px;
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.95rem;
}
.faq-closing a { color: var(--link-accent); font-weight: 600; text-decoration: none; }
.faq-closing a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------- final CTA --- */
.final-cta { text-align: center; }
.final-cta h2 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin: 0 0 14px; }
.final-cta p { color: rgba(255,255,255,0.75); max-width: 480px; margin: 0 auto 28px; }
.final-cta-actions { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
.final-cta-note { color: rgba(255,255,255,0.6); font-size: 0.85rem; max-width: none; margin: 18px auto 0; }

/* Compact homepage FAQ: link out to the full FAQ page instead of listing
   every question here (Section: homepage shortening pass). */
.faq-more-link { text-align: center; margin: 24px 0 0; font-size: 0.92rem; }
.faq-more-link a { color: var(--link-accent); font-weight: 600; text-decoration: none; }
.faq-more-link a:hover { text-decoration: underline; }

/* ----------------------------------------------------------------------- footer --- */
.site-footer { border-top: 1px solid var(--border-subtle); padding: 56px 0 40px; }
.footer-top {
    display: flex;
    justify-content: space-between;
    gap: 40px;
    flex-wrap: wrap;
    margin-bottom: 36px;
}
/* Was h4 — bumped to h3 (Lighthouse a11y: heading-order; the footer
   followed the page's last h2 directly, skipping a level). Selector
   renamed to match; styling unchanged. */
.footer-col h3 { font-size: 0.85rem; margin: 0 0 12px; color: var(--text-secondary); }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.footer-col a { text-decoration: none; font-size: 0.875rem; color: var(--text-primary); }
.footer-col a:hover { color: var(--bpk-signal-orange); }
.footer-bottom {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding-top: 24px;
    border-top: 1px solid var(--border-subtle);
    font-size: 0.85rem;
    color: var(--text-secondary);
}

/* ------------------------------------------------------------------ page-header for sub-pages --- */
.page-header { padding-top: 36px; padding-bottom: 40px; }
.page-header h1 { font-size: clamp(1.8rem, 3.4vw, 2.6rem); margin: 0 0 14px; letter-spacing: -0.01em; }
.page-header p { color: var(--text-secondary); font-size: 1.05rem; margin: 0; }

/* Login/"Access your download" header: was its own narrow, centered
   500px column (same width as the license-key card below it), which
   visually read as centered content even though the text itself was
   left-aligned. Now shares the plain .wrap width (1120px) like
   checkout's page-header, so it starts flush left the same way — only
   the form card underneath stays narrow. max-width on the paragraph
   alone (not the container) keeps the longer sentence from stretching
   into an unreadably long line now that it's not confined to 500px. */
.login-page-header p { max-width: 560px; }
/* No max-width override here: .prose relies on the plain .wrap max-width (1120px),
   so it spans the same width as the .page-header h1 above it. */
.prose h2 { font-size: 1.3rem; margin: 40px 0 12px; }
.prose h2:first-child { margin-top: 0; }
.prose p { color: var(--text-secondary); margin: 0 0 16px; }
.prose ul { color: var(--text-secondary); }
.page-header p + p { margin-top: 10px; }

/* ------------------------------------------------------- sample viewer --- */
/* In-page PDF preview (assets/js/sample-viewer.js + PDF.js, self-hosted
   under assets/js/pdfjs/). A branded document-viewer chrome: a dark
   toolbar bar above a soft neutral backdrop the page floats on, in the
   style of a document-preview pane (Drive/Docs-style), rather than a
   plain bordered box. */
.sample-viewer {
    max-width: 860px;
    margin: 15px auto 0;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-subtle);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 24px 60px -32px rgba(23, 43, 58, 0.35);
}
.sample-viewer-chrome {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px 18px;
    padding: 14px 18px;
    background: var(--bg-band-dark);
    color: var(--text-on-dark);
}
.sample-viewer-chrome[hidden] { display: none; }
.sample-viewer-doc-name {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-on-dark);
    opacity: 0.85;
    margin-right: auto;
    white-space: nowrap;
}
.sample-viewer-doc-name svg { width: 16px; height: 16px; flex: none; }
.sample-viewer-toolbar-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.sample-viewer-toolbar-group {
    display: flex;
    align-items: center;
    gap: 6px;
}
.sample-viewer-toolbar-divider {
    width: 1px;
    height: 22px;
    background: rgba(255, 255, 255, 0.18);
    margin: 0 4px;
    flex: none;
}
.sample-viewer-prev,
.sample-viewer-next,
.sample-viewer-zoom-out,
.sample-viewer-zoom-in {
    flex: none;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-on-dark);
    cursor: pointer;
    transition: background 0.15s ease, opacity 0.15s ease, border-color 0.15s ease;
}
.sample-viewer-prev svg,
.sample-viewer-next svg,
.sample-viewer-zoom-out svg,
.sample-viewer-zoom-in svg {
    width: 16px;
    height: 16px;
}
.sample-viewer-prev:hover:not(:disabled),
.sample-viewer-next:hover:not(:disabled),
.sample-viewer-zoom-out:hover:not(:disabled),
.sample-viewer-zoom-in:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.28);
}
.sample-viewer-prev:disabled,
.sample-viewer-next:disabled,
.sample-viewer-zoom-out:disabled,
.sample-viewer-zoom-in:disabled {
    opacity: 0.35;
    cursor: default;
}
.sample-viewer-page-indicator {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-on-dark);
    min-width: 96px;
    text-align: center;
}
.sample-viewer-zoom-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-on-dark);
    opacity: 0.9;
    min-width: 40px;
    text-align: center;
}
.sample-viewer-fit-width {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 12px;
    height: 34px;
    border-radius: 9px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-on-dark);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.sample-viewer-fit-width svg { width: 15px; height: 15px; }
.sample-viewer-fit-width:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.28);
}
.sample-viewer-canvas-wrap {
    display: flex;
    justify-content: center;
    padding: 32px 20px;
    overflow-x: auto;
    background:
        radial-gradient(ellipse at top, rgba(23, 43, 58, 0.05), transparent 60%),
        var(--bg-surface-alt);
}
.sample-viewer-page-shadow {
    background: var(--bpk-white);
    border-radius: 4px;
    box-shadow: 0 18px 40px -18px rgba(23, 43, 58, 0.4), 0 2px 8px rgba(23, 43, 58, 0.08);
    line-height: 0;
    flex: none;
}
/* No max-width cap here: the canvas is drawn at its true scaled pixel
   size (100% by default — see sample-viewer.js), and
   .sample-viewer-canvas-wrap scrolls horizontally on viewports too
   narrow to show that width in full, rather than this rule shrinking
   the page down to fit. */
.sample-viewer-canvas {
    display: block;
    height: auto;
    border-radius: 4px;
}
.sample-viewer-status {
    text-align: center;
    padding: 48px 16px;
    color: var(--text-secondary);
    font-size: 0.95rem;
}
.sample-viewer-status--error { color: var(--negative, #C0392B); }
@media (max-width: 560px) {
    .sample-viewer-doc-name { display: none; }
    .sample-viewer-chrome { padding: 12px; }
    .sample-viewer-canvas-wrap { padding: 20px 10px; }
}


/* Hero "try before you buy" prompt line + migrated checkout summary content */
.hero-samples-prompt {
    margin-top: 18px;
    margin-bottom: 4px;
    font-weight: 600;
    color: var(--text-primary);
}
.checkout-summary-value-note {
    margin: 5px 0 2px;
    font-size: 0.88rem;
    color: var(--text-secondary);
}
.checkout-summary-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin: 26px 0 18px;
    text-align: center;
}
.checkout-summary-stats > div {
    display: flex;
    flex-direction: column;
}
.checkout-summary-stats strong {
    font-size: 1.18rem;
    font-weight: 800;
    color: var(--text-primary);
}
.checkout-summary-stats span {
    font-size: 0.72rem;
    color: var(--text-secondary);
}
.checkout-summary-bullets {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    display: grid;
    gap: 7px;
}
.checkout-summary-bullets li {
    font-size: 0.85rem;
    color: var(--text-secondary);
    padding-left: 18px;
    position: relative;
}
.checkout-summary-bullets li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--bpk-signal-orange);
}


/* Stage 2: About page section cards (reuses .card-surface) */
.about-section + .about-section { margin-top: 20px; }
.about-section h2 { margin-top: 0; }

/* Stage 3: About page — surface contrast + numbered eyebrow + icon badge.
   Restrained treatment only: no new tokens, no side-bar accents, no grid.
   .about-section overrides .card-surface's default var(--bg-page) with
   the slightly tinted var(--bg-surface) already used by .checkout-card,
   so each card reads as a distinct surface instead of relying on the
   1px border alone.

   .eyebrow (below) is intentionally page-agnostic — first used here on
   About, then reused as-is on FAQ (Stage 4) as the shared small-caps
   accent label for this "text-heavy page" visual language, rather than
   being redefined per page. */
.about-section {
    background: var(--bg-surface);
}
.eyebrow {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    /* var(--link-accent) rather than the raw brand orange: it's the same
       token already used for accent text elsewhere, and it's the
       theme-aware, WCAG AA-passing orange (see tokens.css) — the raw
       --bpk-signal-orange is reserved for icons/borders, not body text
       on a light background. */
    color: var(--link-accent);
    margin: 0 0 10px;
}
.about-section h2 {
    display: flex;
    align-items: center;
    gap: 12px;
}
.about-section h2 .icon-badge {
    /* One tier up from the smallest badge size used elsewhere (e.g.
       .byp-item's 34px/18px) toward the mid tier (.applications-grid's
       42px/22px) — a touch more presence next to the larger About
       heading, without reaching the largest badge tier on the site. */
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-surface-alt);
    color: var(--bpk-deep-navy);
}
[data-theme="dark"] .about-section h2 .icon-badge { color: var(--bpk-signal-orange); }
.about-section h2 .icon-badge svg { width: 21px; height: 21px; }

/* Stage 2: Contact page — checkout-card nested inside .prose needs its
   first heading's top margin zeroed (the plain ".prose h2:first-child"
   rule no longer matches once the h2 isn't .prose's own first child). */
.prose .checkout-card h2 { margin-top: 32px; }
.prose .checkout-card > h2:first-child { margin-top: 0; }

/* Stage 6: Contact page refinements — email as a clear button action,
   and "Already purchased?" pulled into its own small, subtle callout
   card (reuses .checkout-card, just laid out as a row with its own CTA)
   so it reads as a distinct next-step rather than another paragraph in
   the support-scope card above it. No new tokens: same surface/border/
   radius as every other card, same .btn-secondary as used elsewhere. */
.contact-email-btn { margin-top: 18px; }
.contact-email-btn svg { width: 16px; height: 16px; margin-right: 2px; }
.contact-access-callout {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}
.contact-access-callout h2 { margin: 0 0 6px; font-size: 1.3rem; }
.prose .contact-access-callout h2 { margin-top: 0; }
.contact-access-callout p { margin: 0; max-width: 46ch; }
.contact-access-btn { flex: none; }
@media (max-width: 560px) {
    .contact-access-callout { flex-direction: column; align-items: flex-start; }
    .contact-access-btn { width: 100%; }
}

/* Generalized version of the check-icon list already used on the
   homepage hero card and the comparison table (same var(--positive)
   token, same 'check' icon) — sized for body-copy contexts rather than
   the homepage's compact 0.84rem card text. Replaces default browser
   bullets, which is the one thing on Contact that still read as
   "document-like". */
.check-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.check-list li { display: flex; align-items: center; gap: 10px; color: var(--text-secondary); }
.check-list li svg { width: 16px; height: 16px; flex: none; margin-right: 2px; color: var(--positive); }

/* Stage 5: plain long-form legal/prose pages (Terms, Privacy, Refund,
   License, Cookie Notice) — same "wall of text" problem About had, but
   these are legal boilerplate, not narrative copy, so cards/icons would
   be overkill. A light top divider before each non-first <h2> is enough
   to break the scroll into scannable sections, reusing the same
   var(--border-subtle) token as every other divider on the site (FAQ
   items, .about-section borders). Also benefits .checkout-card's
   internal <h2> sections (e.g. Contact) for the same reason. */
.prose h2:not(:first-child) {
    padding-top: 22px;
    border-top: 1px solid var(--border-subtle);
}

/* Stage 8: sales chat widget (templates/chat-widget.php + chat-widget.js
   + chat-message.php). Scripted keyword matcher, no external AI API, no
   new colors: orange accent only on the launcher and the visitor's own
   message bubbles — the bot's own replies stay neutral, same one-accent
   discipline used throughout this site. Shadow values reused from
   .btn-checkout-cta:hover (navy-tinted rgba already established) rather
   than inventing a new elevation color. */
.chat-widget {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 60;
}
/* White pill (was solid --accent orange) with the chat icon carrying its
   own small colored circular badge instead — reads as a quieter "Ask a
   question" nudge rather than a second orange CTA competing with the
   real ones on the page. Smaller all around than before: less padding,
   a smaller icon badge, and a slightly smaller label. */
.chat-launcher {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-page);
    color: var(--text-primary);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 6px 14px 6px 6px;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(23, 43, 58, 0.14);
    position: relative;
    transition: box-shadow var(--bpk-transition-fast), transform var(--bpk-transition-fast);
}
.chat-launcher:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(23, 43, 58, 0.22); }
.chat-launcher-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-contrast-text);
}
.chat-launcher svg { width: 15px; height: 15px; flex: none; }
.chat-launcher[aria-expanded="true"] .chat-launcher-label { display: none; }
/* Pulse ring — draws attention when panel is closed, stops once opened */
.chat-launcher::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 999px;
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.55);
    animation: chat-pulse 2.4s ease-out infinite;
}
.chat-launcher[aria-expanded="true"]::before { animation: none; }
@keyframes chat-pulse {
    0%   { box-shadow: 0 0 0 0   rgba(245, 158, 11, 0.55); }
    60%  { box-shadow: 0 0 0 10px rgba(245, 158, 11, 0); }
    100% { box-shadow: 0 0 0 0   rgba(245, 158, 11, 0); }
}
/* Online status dot */
.chat-online-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 11px;
    height: 11px;
    background: #22c55e;
    border-radius: 50%;
    border: 2px solid var(--bg-page);
    pointer-events: none;
}

.chat-panel {
    position: absolute;
    right: 0;
    bottom: 68px;
    width: 372px;
    max-width: calc(100vw - 40px);
    max-height: 540px;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    box-shadow: 0 8px 32px rgba(23, 43, 58, 0.22);
    overflow: hidden;
    /* slide-up + fade animation */
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 180ms ease, transform 180ms ease;
    pointer-events: none;
}
[data-theme="dark"] .chat-panel { box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); }
/* The [hidden] attribute is how chat-widget.js opens/closes the panel.
   Without this rule, .chat-panel's own `display: flex` above silently
   wins over the browser's built-in `[hidden] { display: none }` (author
   styles always beat that default, regardless of specificity), so the
   panel would render open on every page load. */
.chat-panel[hidden] { display: none; }
/* Triggered by JS after removing [hidden] — drives the slide-up transition */
.chat-panel--open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.chat-panel-header {
    padding: 12px 40px 12px 14px;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--bg-page);
    position: relative;
    display: flex;
    align-items: center;
    gap: 9px;
}
.chat-panel-header-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    position: relative;
}
.chat-panel-header-avatar svg { width: 14px; height: 14px; color: var(--accent-contrast-text); }
.chat-panel-header-avatar::after {
    content: '';
    position: absolute;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 8px;
    background: #22c55e;
    border-radius: 50%;
    border: 2px solid var(--bg-page);
}
.chat-panel-header-text { flex: 1; min-width: 0; }
.chat-panel-title { display: block; font-weight: 700; color: var(--text-primary); font-size: 0.85rem; line-height: 1.3; }
.chat-panel-subtitle { display: block; font-size: 0.7rem; color: var(--text-secondary); margin-top: 1px; }
.chat-panel-close {
    position: absolute;
    top: 10px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 0;
    border-radius: 6px;
    transition: background var(--bpk-transition-fast), color var(--bpk-transition-fast);
}
.chat-panel-close svg { width: 14px; height: 14px; }
.chat-panel-close:hover { background: var(--bg-surface-alt); color: var(--text-primary); }

.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    scroll-behavior: smooth;
}
.chat-message {
    max-width: 88%;
    padding: 8px 12px;
    border-radius: 14px;
    font-size: 0.81rem;
    line-height: 1.45;
}
.chat-message-bot-wrap {
    display: flex;
    align-items: flex-end;
    gap: 7px;
    align-self: flex-start;
    max-width: 92%;
}
.chat-message-bot-avatar {
    width: 23px;
    height: 23px;
    border-radius: 50%;
    background: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    margin-bottom: 2px;
}
.chat-message-bot-avatar svg { width: 11px; height: 11px; color: var(--accent-contrast-text); }
.chat-message-bot {
    align-self: flex-start;
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    border-bottom-left-radius: 4px;
}
.chat-message-user {
    align-self: flex-end;
    background: var(--accent);
    color: var(--accent-contrast-text);
    border-bottom-right-radius: 4px;
}
.chat-message-typing {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 10px 14px;
    min-width: 52px;
}
.chat-typing-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--text-secondary);
    animation: chat-dot-bounce 1.2s ease-in-out infinite;
    flex: none;
}
.chat-typing-dot:nth-child(2) { animation-delay: 0.18s; }
.chat-typing-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes chat-dot-bounce {
    0%, 80%, 100% { transform: translateY(0);   opacity: 0.4; }
    40%           { transform: translateY(-5px); opacity: 1;   }
}

.chat-quick-replies {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0 14px 10px;
}
.chat-quick-reply {
    background: var(--bg-page);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 5px 11px;
    font-size: 0.73rem;
    color: var(--text-primary);
    cursor: pointer;
    transition: border-color var(--bpk-transition-fast), background var(--bpk-transition-fast);
    white-space: nowrap;
}
.chat-quick-reply:hover { border-color: var(--accent); background: var(--bg-surface-alt); }

.chat-followups {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 6px;
    padding-left: 30px;
}
.chat-followup-chip {
    background: transparent;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 3px 10px;
    font-size: 0.7rem;
    color: var(--link-accent);
    cursor: pointer;
    transition: border-color var(--bpk-transition-fast), background var(--bpk-transition-fast);
}
.chat-followup-chip:hover { border-color: var(--accent); background: var(--bg-surface-alt); }

.chat-form {
    display: flex;
    gap: 7px;
    padding: 11px 14px;
    border-top: 1px solid var(--border-subtle);
}
.chat-input {
    flex: 1;
    min-width: 0;
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    padding: 7px 11px;
    font-size: 0.82rem;
    background: var(--bg-page);
    color: var(--text-primary);
    transition: border-color var(--bpk-transition-fast);
}
.chat-input:focus { outline: none; border-color: var(--accent); }
.chat-send-btn { padding: 7px 14px; font-size: 0.82rem; flex: none; border-radius: 10px; }

@media (max-width: 640px) {
    /* Shrink the launcher to an icon-only circular button on small
       screens. The full pill ("Ask a question" label + padding) is
       wide enough to sit directly on top of page content at common
       scroll positions (stat cards, body copy, checkout trust bullets)
       since the widget is fixed-position and always floats above
       whatever happens to be in the bottom-right corner. A small round
       FAB has a much smaller footprint, so it stops obscuring text
       instead of trying to reserve page space for it. */
    .chat-widget { right: 14px; bottom: 14px; }
    /* Below this width the label is gone anyway, so the white-pill +
       colored-icon-badge treatment (two nested circles) doesn't apply —
       simplest is the button itself becomes the solid colored circle,
       same as it always has on mobile. */
    .chat-launcher {
        width: 52px;
        height: 52px;
        padding: 0;
        justify-content: center;
        border-radius: 50%;
        background: var(--accent);
        color: var(--accent-contrast-text);
        border: none;
    }
    .chat-launcher-icon { width: auto; height: auto; background: transparent; color: inherit; }
    .chat-launcher-label { display: none; }
    .chat-panel { width: calc(100vw - 24px); bottom: 64px; }
}


/* Stage 7: Special offer pricing. Two treatments sharing the same data
   (Settings::specialOfferActive() / effectivePriceUsd()):
   - .price-line / .offer-banner: shared partial
     (templates/special-offer-banner.php) used on Home and Product.
   - .checkout-summary-price-was / -offer-note: integrated directly into
     checkout's existing price tag rather than duplicating the banner
     right next to a price that's already displayed there.

   Stage 8 (revised): the plain-price and offer states are now visually
   distinct on purpose:
   - No offer: .price-line — quiet, plain text. The price is always
     visible, but there's nothing to "sell" here, so it doesn't compete
     for attention with the CTAs above it.
   - Offer active: .offer-banner — a real highlighted banner (tinted
     background, border, shadow, large price, colored savings pill).
     This is the one moment on the page that's actually time-limited and
     worth pushing hard on, so it's deliberately the loudest element
     near the hero CTAs rather than a quiet inline note. */
.price-line {
    margin: 16px 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

/* Deliberately breaks from the site's light/dark-adaptive theme tokens —
   a time-limited discount reads as an event, not just another themed
   component, the same way flash-sale banners on major e-commerce sites
   use one fixed, high-contrast treatment that nothing else on the page
   reuses. Colors are hard-coded on purpose: this banner is intentionally
   identical in light and dark site mode rather than adapting to either.
   A dark navy card with a warm orange glow/border was chosen over a
   solid-orange card so the large orange price and "X% OFF" pill still
   have something to contrast against — solid orange-on-orange would
   have buried its own numbers. */
/* Widened and flattened on purpose (Stage 9 revision) so it clears the
   viewport in one screen on page load, right under the hero, instead of
   pushing the fold down — a wider banner lets the badge/headline/price/
   CTA sit on one shorter row instead of stacking tall. */
.offer-banner {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px 28px;
    background: linear-gradient(160deg, #16283A 0%, #0B131C 100%);
    border: 1px solid rgba(245, 158, 11, 0.5);
    border-radius: 18px;
    padding: clamp(14px, 1.8vw, 20px) clamp(20px, 3vw, 32px);
    margin: 14px 0;
    box-shadow: 0 20px 48px -24px rgba(0, 0, 0, 0.6), 0 0 40px -16px rgba(245, 158, 11, 0.4);
    color: #FFFFFF;
    overflow: hidden;
}
.hero-ctas + .offer-banner { margin-top: 12px; }
/* Decorative sparkle/glow in the top-right corner, echoing the faint
   accent-dust look of typical flash-sale banners — pure CSS (no new
   image asset: the brand's own logo/icon SVGs referenced in tokens.css
   aren't present in this codebase, so a background-image approach isn't
   available here). z-index: -1 keeps it under the badge/headline/price/
   button (all normal-flow children, painted above a stacking context's
   negative-z-index layer) so it never competes with the text. */
.offer-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(circle at 93% 18%, rgba(255, 255, 255, 0.9) 0, rgba(255, 255, 255, 0.9) 1.5px, transparent 1.5px),
        radial-gradient(circle at 85% 32%, var(--bpk-signal-orange) 0, var(--bpk-signal-orange) 2px, transparent 2px),
        radial-gradient(circle at 97% 46%, rgba(255, 255, 255, 0.7) 0, rgba(255, 255, 255, 0.7) 1px, transparent 1px),
        radial-gradient(circle at 89% 62%, var(--bpk-signal-orange) 0, var(--bpk-signal-orange) 1.5px, transparent 1.5px),
        radial-gradient(circle at 78% 12%, rgba(255, 255, 255, 0.6) 0, rgba(255, 255, 255, 0.6) 1px, transparent 1px),
        radial-gradient(ellipse 260px 200px at 100% 0%, rgba(245, 158, 11, 0.22), transparent 70%);
    opacity: 0.9;
}
@media (max-width: 640px) {
    .offer-banner::after { display: none; }
}
/* No longer flex-grow: 1 — with the price/CTA side carrying two
   dividers, a price block and a checklist, it needs the reclaimed
   width more than the intro column does. Own flex column (rather than
   plain block flow) with align-items: flex-start so the badge,
   headline and sub line all anchor to the left edge explicitly,
   regardless of what the wider .offer-banner rule does at any given
   width. The headline itself ("The complete BusinessPromptKit") is
   short; the sub line ("500+ prompts · ... · And more") is the wider
   of the two now, so it's the one sizing this column — kept on one
   line without wrapping. */
.offer-banner-intro {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    flex: 0 1 440px;
    min-width: 220px;
    max-width: 460px;
}
.offer-banner-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--bpk-signal-orange);
    color: var(--bpk-deep-navy);
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 5px 12px 5px 9px;
    border-radius: 999px;
    margin-bottom: 8px;
}
/* Smaller than the badge's own uppercase label around it — the flame
   is a decorative accent, not the thing that should draw the eye
   first, so it steps back and lets "Limited-Time Offer" carry the
   emphasis. */
.offer-banner-flame { font-size: 0.78rem; line-height: 1; }
.offer-banner-headline {
    margin: 0 0 4px;
    font-size: clamp(1rem, 1.6vw, 1.15rem);
    font-weight: 700;
    color: #FFFFFF;
    line-height: 1.2;
}
.offer-banner-sub { margin: 0; font-size: 0.88rem; color: rgba(255, 255, 255, 0.68); white-space: nowrap; }
/* Everything right of the intro text now lives in one flexible group so
   its own leftover width (freed up by the intro no longer growing)
   spreads out as breathing room between the price and the CTA, instead
   of bunching both against the divider. */
.offer-banner-right {
    display: flex;
    align-items: center;
    flex: 1 1 320px;
    justify-content: space-between;
    gap: 28px;
    min-width: 280px;
}
/* Two of these now sit inside .offer-banner-right — one before the
   price block, one before the CTA group — splitting the banner into
   three visually distinct sections (pitch / price / action) rather
   than the earlier two. Same class, same rule, both instances. */
.offer-banner-divider { width: 1px; align-self: stretch; margin: 8px 0; background: rgba(255, 255, 255, 0.1); flex: none; }
.offer-banner-price-block { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; flex: none; }
/* Regular price now stands alone on its own line above the sale price
   (not beside the savings pill — that pill moved next to the big price
   instead), so it no longer needs the trailing dot separator the old
   side-by-side layout used. */
.offer-banner-regular { color: rgba(255, 255, 255, 0.32); font-size: 0.8rem; font-weight: 500; }
.offer-banner-price-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* White rather than the brand orange here — the headline's own inline
   "...for just $39" callout (above) already carries the orange accent,
   so the price block reads as the precise, receipt-like figure next to
   it: high-contrast white, with orange reserved for the savings pill
   beside it. ~12% larger than the previous 1.9–2.3rem range — this is
   still the number the whole banner exists to sell. */
.offer-banner-price { font-size: clamp(2.3rem, 4.8vw, 2.8rem); font-weight: 800; color: #FFFFFF; line-height: 1; }
.offer-banner-savings {
    background: var(--bpk-signal-orange);
    color: var(--bpk-deep-navy);
    font-size: 0.76rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 4px 11px;
    border-radius: 999px;
}
.offer-banner-expiry {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 0.82rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
}
.offer-banner-expiry svg { width: 13px; height: 13px; flex: none; color: var(--bpk-signal-orange); }
/* CTA + reassurance checklist stacked as one unit, directly under the
   button rather than pinned to the far right of the whole row. */
.offer-banner-cta-group {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    flex: none;
}
/* ~10% taller and noticeably wider than the shared .btn baseline
   (12px/22px padding, 44px min-height) — the button earns a bit more
   presence here since it's the banner's one purchase action. */
/* Same size as the header's "Get the Toolkit" button (.btn-nav-cta) —
   padding, min-height and font-size all match it exactly now, rather
   than the larger, bespoke sizing this used before. */
.offer-banner-cta {
    flex: none;
    white-space: nowrap;
    padding: 12px 22px;
    min-height: 44px;
    font-size: 0.875rem;
}
/* Reuses the same "Secure checkout · Instant access · No subscription"
   reassurance copy already used on the homepage hero, view-sample's
   final CTA and checkout — same set of three facts, just presented as
   a short checklist here since the banner has the vertical room for it
   and it sits right beside the one button that commits to a purchase. */
/* Smaller and tighter than a first pass at this size (0.82rem/6px gap)
   — the checklist sits under the CTA button as a secondary reassurance,
   not body copy, so it reads better compact: less vertical height next
   to the button above it, without losing legibility at 3 short lines.
   margin-top: -4px (rather than shifting the whole .offer-banner-cta-
   group, which would carry the button out of line with the price
   block next to it) nudges just this block up so it sits closer to
   the price/offer content's own vertical rhythm. */
.offer-banner-checklist { display: flex; flex-direction: column; gap: 3px; list-style: none; margin: -4px 0 0; padding: 0; }
.offer-banner-checklist li {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1.15;
    color: rgba(255, 255, 255, 0.82);
}
.offer-banner-checklist svg { width: 12px; height: 12px; flex: none; color: var(--bpk-signal-orange); }
@media (max-width: 900px) {
    .offer-banner { justify-content: center; text-align: center; }
    .offer-banner-divider { display: none; }
    .offer-banner-sub { white-space: normal; }
    .offer-banner-right { justify-content: center; flex-wrap: wrap; }
    .offer-banner-price-block { align-items: center; }
    .offer-banner-price-row { justify-content: center; }
    .offer-banner-cta-group { align-items: center; }
}
@media (max-width: 480px) {
    .offer-banner { flex-direction: column; align-items: stretch; }
    /* Same class of bug as .offer-banner-right below, on the sibling
       above it: .offer-banner-intro's base rule (line ~2620) sets
       flex: 1 1 260px so it shares leftover WIDTH 50/50 with
       .offer-banner-right on the desktop row layout. Once
       flex-direction flips to column here, that flex-grow:1 keeps
       applying — now to leftover HEIGHT — stretching .offer-banner-intro
       far past its own content (badge/headline/sub) and pushing
       everything below it down. flex:none makes it content-sized like
       every other child in the stacked layout; gap on the container
       above (row-gap: 14px, inherited from the base .offer-banner rule)
       already provides spacing, so nothing else is needed here. */
    .offer-banner-intro { flex: none; min-width: auto; }
    /* .offer-banner-right's base rule sets flex:1 1 320px and
       justify-content:space-between for the desktop horizontal layout —
       neither gets reset here, so once flex-direction flips to column,
       that same 320px flex-basis applies to its HEIGHT instead of its
       width (forcing a ~320px-tall box), and space-between then spreads
       its two children (price, then the CTA) to the very top and
       bottom of that box — a large, unintended blank gap between the
       price and the button. flex-basis:auto plus a plain gap fixes
       both: real height (content-sized) and even, top-to-bottom
       spacing instead of edge-to-edge. */
    .offer-banner-right { flex-direction: column; align-items: stretch; flex: 1 1 auto; justify-content: flex-start; gap: 16px; }
    .offer-banner-price-block { align-items: flex-start; }
    .offer-banner-cta-group { align-items: stretch; }
    .offer-banner-cta { width: 100%; }
}
/* product.php's final CTA centers a narrow column of content (h2, p all
   constrained + margin:auto); the no-offer .price-line fallback matches
   that same narrow column width, but the offer-active .offer-banner is
   a deliberately wide, self-contained promo strip (badge, price and its
   own CTA in one row) so it gets its own, much wider cap instead of
   matching the column — without this, the banner's own flex row (no
   intrinsic width) would stretch to the full width of that section's
   much wider .wrap instead of being centered as its own element. */
.final-cta .price-line {
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
}
.final-cta .offer-banner {
    max-width: 1040px;
    margin-left: auto;
    margin-right: auto;
}
/* Home: the offer banner now lives in its own full-width section right
   after the hero (moved out of the hero column so the hero stays
   unchanged), so it needs the same centering treatment as the
   product-page final CTA above. */
/* padding-bottom: 0 (overriding .section-tight's own 30px) so the
   value-strip stats row right after this section sits close under the
   banner instead of leaving a second gap on top of the banner's own
   margin-bottom below. */
.offer-showcase { text-align: center; padding-top: 6px; padding-bottom: 0; }
/* More breathing room above the banner, but only when it's actually
   showing — the hero-to-banner transition felt abrupt at the old 6px,
   while an empty, inactive offer-showcase should stay as tight as
   before rather than gaining a blank 30+px band of its own. */
.offer-showcase-active { padding-top: 34px; }
.offer-showcase .price-line {
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
}
/* No separate max-width here (unlike the product-page version below) —
   left at the same width as .wrap itself, so the banner's own left/right
   edges land exactly on the same line as the hero content and the
   stats row above and below it, instead of reading as a narrower,
   separately-framed element floating inside that column. */
.offer-showcase .offer-banner {
    margin-bottom: 0;
}

.checkout-summary-price-wrap { display: flex; flex-direction: column; gap: 4px; }
.checkout-summary-price-was { color: var(--text-secondary); font-size: 1rem; font-weight: 500; }
.checkout-summary-offer-note { margin: 4px 0 0; font-size: 0.85rem; color: var(--link-accent); font-weight: 600; }