/*
 * Storefront design tokens
 * --------------------------
 * Canonical reference: docs/STOREFRONT-DESIGN.md §3.1
 * Audit:               docs/STOREFRONT-DESIGN-AUDIT.md (Step 1) + Step 8 (this file).
 *
 * Brand tokens are emitted server-side per request from $app->domainConfig->ui
 * by module/{computer,mobile}/layout/head.tokens.phtml. They KEEP full
 * saturation in both light and dark modes — audit decision D5.
 *   --lb-brand        ← firstColor
 *   --lb-brand-alt    ← secondColor
 *   --lb-brand-hover  ← adjustBrightness(firstColor, -25)
 *   --lb-accent       ← buttonColor
 *
 * Dark-mode palette: Tailwind slate (D5). Activated by [data-theme="dark"] on
 * <html>. The anti-flash script in head.phtml sets that attribute BEFORE first
 * paint by reading localStorage.theme. Toggle UI lives in:
 *   - Desktop: module/computer/layout/header.phtml (between cart and account)
 *   - Mobile:  module/mobile/layout/sidenav.phtml (#headerSidenavInfo footer)
 */

:root {
    /* Functional — surface / text / border */
    --lb-bg:           #ffffff;
    --lb-surface:      #f7f7f7;
    --lb-surface-alt:  #fafafa;
    --lb-section:      #f6f6f6;  /* full-bleed alternating section strips (homepage bands) */
    --lb-card:         #ffffff;  /* raised cards on top of section strips */
    --lb-text:         #212529;
    --lb-text-muted:   #6c757d;
    --lb-border:       #dee2e6;
    --lb-link:         var(--lb-brand);

    /* State */
    --lb-success:      #1da751;
    --lb-warning:      #ff8000;
    --lb-danger:       #e2504a;
    --lb-info:         #54aeff;
    --lb-price-promo:  #bf0000;

    /*
     * Text-on-light variants of state colours (Phase B5b).
     * --lb-success / --lb-danger fail WCAG AA body text on white
     * (3.14:1 + 3.83:1 respectively). These darker siblings hit ≥7:1
     * (AAA) so error / success TEXT can be read by everyone. The
     * original tokens stay for backgrounds, borders + icons where
     * the 3:1 non-text threshold is enough.
     */
    --lb-text-success: #0a6b2c;
    --lb-text-danger:  #a01a1f;

    /*
     * Coupon UI palette (cart + checkout discount surfaces — Phase 5.0-d).
     * Extracted from inline hex literals during cart/checkout redesign Phase A.
     * Reference: docs/CART-CHECKOUT-REDESIGN-PLAN.md §6 Phase A3.
     * Dark-mode overrides defined under [data-theme="dark"] below.
     */
    --lb-coupon-bg:           #d4edda;
    --lb-coupon-text:         #155724;
    --lb-coupon-border:       #b8e0c2;
    --lb-coupon-stale-bg:     #fff3cd;
    --lb-coupon-stale-text:   #856404;

    /* Shadows */
    --lb-shadow-sm:    0 1px 2px rgba(0, 0, 0, .05);
    --lb-shadow:       0 2px 8px rgba(0, 0, 0, .08);
    --lb-shadow-lg:    0 8px 24px rgba(0, 0, 0, .12);

    /* Radius */
    --lb-radius-sm:    .25rem;
    --lb-radius:       .5rem;
    --lb-radius-lg:    1rem;
    --lb-radius-pill:  999px;
}

/*
 * Dark mode — Tailwind slate.
 *
 * Slate scale (for reference):
 *   slate-50:  #f8fafc   slate-500: #64748b
 *   slate-100: #f1f5f9   slate-600: #475569
 *   slate-200: #e2e8f0   slate-700: #334155
 *   slate-300: #cbd5e1   slate-800: #1e293b
 *   slate-400: #94a3b8   slate-900: #0f172a
 *
 * Brand tokens are NOT overridden — they keep full saturation in dark mode
 * (audit decision D5). The price-promo token gets a lighter red because
 * #bf0000 on a slate-900 background reads almost-black.
 */
[data-theme="dark"] {
    /* Functional — surface / text / border */
    --lb-bg:           #0f172a;  /* slate-900 */
    --lb-surface:      #1e293b;  /* slate-800 */
    --lb-surface-alt:  #334155;  /* slate-700 */
    --lb-section:      #1e293b;  /* slate-800 — slightly lighter than page bg */
    --lb-card:         #334155;  /* slate-700 — raised cards pop on top of section */
    --lb-text:         #f8fafc;  /* slate-50 */
    --lb-text-muted:   #94a3b8;  /* slate-400 */
    --lb-border:       #334155;  /* slate-700 */
    /* --lb-link inherits brand — stays saturated for contrast on dark bg */

    /* State — keep saturation, only price-promo needs lightening */
    --lb-price-promo:  #ff6b6b;  /* D2 dark-mode value */

    /* Text-on-dark variants — on slate-900 the lighter tint reads
       cleaner than the darkened light-mode hex (Phase B5b). */
    --lb-text-success: #6ee7a4;
    --lb-text-danger:  #f4a5a1;

    /* Coupon UI palette — slate-friendly dark equivalents (Phase A3) */
    --lb-coupon-bg:           #1f4727;
    --lb-coupon-text:         #86efac;
    --lb-coupon-border:       #2d5a3f;
    --lb-coupon-stale-bg:     #4a3a0d;
    --lb-coupon-stale-text:   #fde68a;

    /* Shadows — opacity bumped to read against dark surfaces */
    --lb-shadow-sm:    0 1px 2px rgba(0, 0, 0, .25);
    --lb-shadow:       0 2px 8px rgba(0, 0, 0, .35);
    --lb-shadow-lg:    0 8px 24px rgba(0, 0, 0, .50);
}

/*
 * Typography scale — values per STOREFRONT-DESIGN.md §4.2 (target assumes
 * html=16px, which is the browser default).
 *
 * Two-axis model:
 *   1. BODY BASELINE — what bare text (un-classed <p>, <div>, <span>, <a>)
 *      inherits. Declared below: 14px on computer, BS4-default 16px on mobile.
 *   2. TOKEN VALUES — what elements that EXPLICITLY use these tokens render
 *      at. These are absolute rem values (relative to <html>, not <body>).
 *
 * Declared here but not yet used. Phase 2 (heading unification) and Phase 3
 * (gradual adoption in component CSS) wire them in. See
 * docs/STOREFRONT-TYPOGRAPHY-MIGRATION-PLAN.md.
 */
:root {
    --lb-font-xs:    0.75rem;    /* 12px */
    --lb-font-sm:    0.875rem;   /* 14px */
    --lb-font-base:  1rem;       /* 16px */
    --lb-font-md:    1.125rem;   /* 18px */
    --lb-font-lg:    1.25rem;    /* 20px */
    --lb-font-xl:    1.5rem;     /* 24px */
    --lb-font-2xl:   1.875rem;   /* 30px */
    --lb-font-3xl:   2.25rem;    /* 36px */
}

/*
 * Body baseline binding — minimal so the toggle produces visible feedback
 * even before per-component dark-mode polish lands. Templates that hardcode
 * colours will keep their light look; those will be migrated to tokens in a
 * follow-up pass.
 *
 * Font-size baseline is device-specific:
 *   - computer: 14px (preserves the legacy BS3 body inheritance the
 *     storefront is calibrated against; replaces BS3's implicit gift)
 *   - mobile:   16px (BS4 default; in production for years)
 * The font-size rule below is scoped via the data-device attribute set on
 * <body> by the per-device head.phtml. DO NOT add data-device to
 * standalone error/auth/gone pages "for consistency" — those pages run
 * BS4 full at body=16px today and shrinking them is a regression. See
 * docs/STOREFRONT-TYPOGRAPHY-MIGRATION-PLAN.md §11.
 */
body {
    background-color: var(--lb-bg);
    color: var(--lb-text);
}
body[data-device="computer"] {
    font-size: 14px;
    line-height: 1.42857143;
}
/* body[data-device="mobile"] inherits BS4's 1rem (16px) — explicit no-op */

/*
 * Computer-storefront rem base — the lost "10px-base trick".
 * --------------------------------------------------------------------
 * The codebase was built when BS3.4.1 CDN was loaded, and BS3 sets
 * `html { font-size: 10px }` in its reboot. Hundreds of CSS rules and
 * template inline styles inherited that base and used `Nrem` to mean
 * "N×10 pixels" (e.g. `font-size: 2.6rem` for a 26px hamburger,
 * `padding: 3rem 6rem` for 30/60px banner padding, BS4 spacing utility
 * `mt-5 = 3rem` for 30px top margin, etc.).
 *
 * When the storefront migrated from BS3+BS4-grid to BS4-full, the
 * `html { font-size: 10px }` rule disappeared (BS4 doesn't set html
 * font-size). Every rem-based declaration silently started rendering
 * at 1.6× its intended pixel size. Result: bloated chrome, oversized
 * type, loose spacing across hundreds of templates.
 *
 * Restore the base here, scoped via `html[data-device="computer"]` so:
 *   - Mobile storefront (html[data-device="mobile"]) keeps BS4 16px base
 *   - Backoffice (no data-device) keeps BS4 16px base
 *   - Standalone error/auth pages keep BS4 16px base
 * Only the computer storefront — which was historically calibrated
 * for 10px — gets the matched base.
 *
 * Compensation: BS4-full's own internals (.btn, .form-control, .alert,
 * .card-body, .modal-*) use `1rem` font-size and rem-based paddings.
 * At html=10px those shrink to ~62% of their default rendering. The
 * computer-scoped overrides further down in this file (after the body
 * shim) bring those back to their BS3-era pixel sizes (14px buttons,
 * 14px form controls, etc.) so dev visual matches production exactly.
 */
html[data-device="computer"] {
    font-size: 10px;
}

/*
 * BS4 component overrides — compensate for html=10px (see block above).
 * These restore the pre-migration pixel sizes that the storefront chrome
 * and templates were calibrated against.
 */
html[data-device="computer"] .btn {
    font-size: 14px;
    line-height: 1.42857143;
    padding: 6px 12px;
}
html[data-device="computer"] .btn-lg {
    font-size: 18px;
    padding: 10px 16px;
}
html[data-device="computer"] .btn-sm {
    font-size: 12px;
    padding: 5px 10px;
}
html[data-device="computer"] .form-control,
html[data-device="computer"] .form-select,
html[data-device="computer"] .input-group-text {
    font-size: 14px;
    line-height: 1.42857143;
    padding: 6px 12px;
}
/*
 * BS4 .form-control-lg / .input-group-lg — large form variant used
 * across the checkout. Production was sized at ~46px tall with ~16px
 * font; the unscoped BS4 defaults render at ~30px tall with 12.5px
 * font at html=10x base. Pin the production dimensions here so the
 * inputs match what was shipped, and so the .callingCodeContainer
 * .select2-container (also fixed at 46px height — see
 * computer/checkout/informationContactDetails.css) stays aligned with
 * its sibling .form-control-lg phone-number input.
 */
html[data-device="computer"] .form-control-lg,
html[data-device="computer"] .form-select-lg,
html[data-device="computer"] .input-group-lg > .form-control,
html[data-device="computer"] .input-group-lg > .form-select,
html[data-device="computer"] .input-group-lg > .input-group-text {
    height: 46px;
    font-size: 16px;
    line-height: 1.5;
    padding: 10px 16px;
}
/*
 * BS4 .custom-select — uses calc(1.5em + .75rem + 2px) for height which collapses
 * at html=10x base (ends up ~24px tall) and clips any text once a consumer rule
 * bumps padding. Pin to auto height so consumers (e.g. .cartProductQuantity) can
 * control sizing via their own padding/font-size without text getting cropped.
 * Padding is left to the consumer — overriding it here would defeat per-component
 * layout (e.g. cart needs text-align:center with symmetric padding).
 */
html[data-device="computer"] .custom-select {
    font-size: 14px;
    line-height: 1.42857143;
    height: auto;
    background-size: 8px 10px;
    background-position: right 12px center;
}
html[data-device="computer"] .alert {
    padding: 12px 20px;
    margin-bottom: 16px;
    font-size: 14px;
}
html[data-device="computer"] .card-body {
    padding: 20px;
}
html[data-device="computer"] .card-header {
    padding: 12px 20px;
}
html[data-device="computer"] .card-footer {
    padding: 12px 20px;
}
html[data-device="computer"] .modal-title {
    font-size: 20px;
}
html[data-device="computer"] .modal-body {
    padding: 16px;
}
html[data-device="computer"] .modal-header,
html[data-device="computer"] .modal-footer {
    padding: 16px;
}
html[data-device="computer"] .dropdown-menu {
    font-size: 14px;
    padding: 8px 0;
    min-width: 160px;
}
html[data-device="computer"] .dropdown-item {
    padding: 4px 24px;
}
html[data-device="computer"] .badge {
    font-size: 75%;
    padding: 5px 10px;
}

/*
 * Cart + checkout pages get the WCAG-recommended 16px body baseline ahead of
 * the storefront-wide BS3→BS4 typography migration (audit Step 4d-retry that
 * keeps being rolled back). Scoped via data-module so it only affects the
 * highest-conversion flow without disturbing the rest of the storefront.
 * Reference: docs/CART-CHECKOUT-REDESIGN-PLAN.md §11 Q26 default.
 */
body[data-device="computer"][data-module="/cart/"],
body[data-device="computer"][data-module="/checkout/"] {
    font-size: 16px;
    line-height: 1.5;
}

/*
 * Sticky panel rescue — cart + checkout only.
 * --------------------------------------------------------------------
 * The storefront-wide `#body { overflow: hidden }` (layout/head.css)
 * establishes an overflow context that NEUTRALISES `position: sticky`
 * on any descendant. The previous sticksy.min.js worked because it used
 * `position: fixed` instead, which sits outside the normal flow and
 * ignores ancestor overflow contexts.
 *
 * `overflow: clip` (Chrome 90+, Safari 16+, Firefox 81+) clips overflow
 * the same way `hidden` does but does NOT establish a scroll-port —
 * which lets descendant sticky elements re-attach to the viewport as
 * their scrolling ancestor. overflow-y: visible keeps vertical free.
 *
 * Scoped to cart + checkout so the rest of the storefront keeps its
 * existing overflow behaviour. Side effect: the `.cart-summary` sticky
 * rule that's been in cart.css:280 since the cart redesign now ALSO
 * starts working — Phase B12 was going to revisit anyway.
 * Reference: docs/CART-CHECKOUT-REDESIGN-PLAN.md §6 Phase A8.
 */
body[data-module="/cart/"] #body,
body[data-module="/checkout/"] #body,
body[data-module="/blog/"] #body {
    overflow-x: clip;
    overflow-y: visible;
    /*
     * `display: flow-root` re-establishes a Block Formatting Context
     * that the original `overflow: hidden` provided "for free". With
     * just `overflow-x: clip; overflow-y: visible` we lose the BFC,
     * which lets descendant margin-top values (e.g. `.row.mt-5`) escape
     * up through #body and collapse with its parent — gluing content
     * to the top of the page. flow-root creates a BFC without
     * re-introducing the overflow context that broke sticky in the
     * first place. Caught 2026-05-21 on the blog index.
     */
    display: flow-root;
}

/*
 * Baseline focus ring — replaces the browser-default :focus-visible outline
 * (which Chrome renders as a fuzzy blue-grey halo that looks terrible on
 * the brand-blue header, especially around the logo). Uses currentColor so
 * the ring picks up the contextual text colour:
 *   - On the header (white text on blue bg) → white ring
 *   - On the body  (dark text on light bg) → dark ring
 *   - On brand-coloured links → brand ring
 *
 * Scope is limited to <a> and <button> so it doesn't fight Bootstrap's
 * input / form-control focus shadows. Mouse-only focus (without :focus-
 * visible) is suppressed so clicks don't leave a lingering ring.
 */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
summary:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
    border-radius: 2px;
}

a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible),
summary:focus:not(:focus-visible) {
    outline: none;
}

/*
 * Honour the OS preference ONLY when the user has not yet made an explicit
 * choice. The toggle script sets data-theme="light"|"dark" on <html>; the
 * presence of that attribute disables this media query via the selector
 * specificity above.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        --lb-bg:           #0f172a;
        --lb-surface:      #1e293b;
        --lb-surface-alt:  #334155;
        --lb-section:      #1e293b;
        --lb-card:         #334155;
        --lb-text:         #f8fafc;
        --lb-text-muted:   #94a3b8;
        --lb-border:       #334155;
        --lb-price-promo:  #ff6b6b;
        --lb-text-success:        #6ee7a4;
        --lb-text-danger:         #f4a5a1;
        --lb-coupon-bg:           #1f4727;
        --lb-coupon-text:         #86efac;
        --lb-coupon-border:       #2d5a3f;
        --lb-coupon-stale-bg:     #4a3a0d;
        --lb-coupon-stale-text:   #fde68a;
        --lb-shadow-sm:    0 1px 2px rgba(0, 0, 0, .25);
        --lb-shadow:       0 2px 8px rgba(0, 0, 0, .35);
        --lb-shadow-lg:    0 8px 24px rgba(0, 0, 0, .50);
    }
}
