/*
 * Public CSS Bundle: sale-widget.bundle.css
 * Auto-generated by scripts/bundle_public_css.py
 * DO NOT EDIT - Edit source files instead
 *
 * Sources: sale-widget/sale-widget-base.css, sale-widget/components/leaderboard.css, sale-widget/components/plan-rows.css, sale-widget/sale-widget-tablet.css, sale-widget/sale-widget-mobile.css, sale-widget/sale-widget-mobile-small.css, sale-widget/themes/arena.css, sale-widget/themes/memorial.css, sale-widget/themes/july4th.css, sale-widget/themes/class.css
 */

/* === sale-widget/sale-widget-base.css === */

/**
 * Sale Widget — base styles (popup overlay + persistent widget).
 *
 * NO media queries here. NO theme overrides here. NO component-specific
 * rules (leaderboard, plan-rows) here. Those live in their own files.
 *
 * Viewport overrides: sale-widget-tablet.css / -mobile.css / -mobile-small.css
 * Theme overrides:    themes/<name>.css scoped via [data-theme="..."]
 * Components:         components/<name>.css (leaderboard, plan-rows)
 */

/* ============================================
   CSS Variables
   ============================================ */
:root {
    /* Foundation palette: gold #fdcc05, blue #0264c0, navy #0e172a.
       This file is exclusive to welcome-default.html (no other page
       loads sale-widget.bundle.css), so these are edited directly -
       no scoping needed. Primary/hover/light and text swapped to the
       exact foundation blue/navy; gold is used explicitly on the two
       actual "claim it" CTA buttons further down, not here, since most
       --sale-primary uses pair it with white text (badges, the toggle
       icon bg) where gold wouldn't have enough contrast. */
    --sale-primary: #0264c0;
    --sale-primary-hover: #024a8f;
    --sale-primary-light: #4d9fe0;
    --sale-bg: #eff6ff;
    --sale-bg-dark: #dbeafe;
    --sale-text: #0e172a;
    --sale-text-light: #4d9fe0;
    --sale-white: #ffffff;
    --sale-shadow: 0 20px 40px rgba(2, 100, 192, 0.2);
    --sale-shadow-sm: 0 4px 12px rgba(2, 100, 192, 0.15);
    --sale-radius: 16px;
    --sale-radius-sm: 12px;
    --sale-transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ============================================
   Popup Overlay
   ============================================ */
.sale-popup-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.6);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10000;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--sale-transition), visibility var(--sale-transition);
    padding: 20px;
}

.sale-popup-overlay.active {
    opacity: 1;
    visibility: visible;
}

.sale-popup {
    background: linear-gradient(135deg, var(--sale-white) 0%, var(--sale-bg) 100%);
    border-radius: var(--sale-radius);
    box-shadow: var(--sale-shadow);
    padding: 40px;
    max-width: 420px;
    width: 100%;
    text-align: center;
    position: relative;
    transform: scale(0.9) translateY(20px);
    transition: transform var(--sale-transition);
}

.sale-popup-overlay.active .sale-popup {
    transform: scale(1) translateY(0);
}

.sale-popup-close {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 36px;
    height: 36px;
    border: none;
    background: var(--sale-bg-dark);
    border-radius: 50%;
    font-size: 24px;
    line-height: 1;
    color: var(--sale-text);
    cursor: pointer;
    transition: background var(--sale-transition), transform var(--sale-transition);
}

.sale-popup-close:hover {
    background: var(--sale-primary);
    color: var(--sale-white);
    transform: scale(1.1);
}

.sale-popup-badge {
    display: inline-block;
    background: var(--sale-primary);
    color: var(--sale-white);
    font-size: 0.85rem;
    font-weight: 600;
    padding: 6px 16px;
    border-radius: 20px;
    margin-bottom: 16px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Badge with a logo tucked behind the pill (opt-in via sale.badge_logo).
   The wrap is the positioning context; the logo sits centered BEHIND the pill,
   the pill (translucent in-theme) rides on top of it. */
.sale-popup-badge-wrap {
    position: relative;
    display: inline-block;
    margin-bottom: 16px;
    /* overflow intentionally visible: a larger logo pokes above/below the pill
       (the pill's translucent fill covers the middle; the ends show fully). */
}

.sale-popup-badge-wrap .sale-popup-badge {
    position: relative;
    z-index: 1;
    margin-bottom: 0;
}

.sale-popup-badge-logo {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 0;
    width: 88px;
    height: auto;
    pointer-events: none;
}

/* Entrance animation — badge + logo animate in once the popup becomes
   active. Held at opacity:0 by default so they don't flash visible before
   the overlay itself fades in; .active kicks off the animation with a
   slight stagger (logo first, pill a beat after) for a layered feel. */
.sale-popup-badge-logo,
.sale-popup-badge-wrap .sale-popup-badge {
    opacity: 0;
}

.sale-popup-overlay.active .sale-popup-badge-logo {
    animation: salePopupLogoIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.15s forwards;
}

.sale-popup-overlay.active .sale-popup-badge-wrap .sale-popup-badge {
    animation: salePopupBadgeIn 0.4s ease-out 0.35s forwards;
}

@keyframes salePopupLogoIn {
    from {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.4) rotate(-12deg);
    }
    to {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1) rotate(0deg);
    }
}

@keyframes salePopupBadgeIn {
    from {
        opacity: 0;
        transform: translateY(8px) scale(0.9);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.sale-popup-headline {
    font-size: 2rem;
    font-weight: 700;
    color: var(--sale-text);
    margin: 0 0 20px 0;
    line-height: 1.2;
}

/* Popup countdown — flip-clock style (Days/Hours/Min/Sec cards on a dark
   navy panel), replacing the old flat "HH:MM:SS" text. Foundation
   palette: navy panel + cards, white numerals, gold labels. The widget's
   compact countdown (.sale-widget-countdown-timer) is untouched. */
.sale-popup-countdown {
    background: var(--sale-text);
    border-radius: var(--sale-radius-sm);
    padding: 18px 16px 14px;
    margin-bottom: 20px;
}

.sale-countdown-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--sale-primary-light);
    margin-bottom: 12px;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.8px;
}

.sale-countdown-flip {
    display: flex;
    justify-content: center;
    gap: 8px;
}

.sale-countdown-flip-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1;
    max-width: 68px;
}

.sale-countdown-flip-num {
    position: relative;
    display: block;
    width: 100%;
    /* Explicit height + line-height (matching .flap's 40px popup size,
       box-sizing so the border doesn't add to it) instead of the old
       padding-based sizing, so the Seconds card is exactly the same
       length as the Days/Hours/Min flap cards next to it. */
    height: 40px;
    line-height: 38px;
    padding: 0;
    box-sizing: border-box;
    background: linear-gradient(180deg, #1e293b 0%, #0e172a 100%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    color: #ffffff;
    font-family: var(--font-heading, inherit);
    font-size: 1.4rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.5px;
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* Flip-clock split line down the middle of each card */
.sale-countdown-flip-num::after {
    content: '';
    position: absolute;
    left: 4px;
    right: 4px;
    top: 50%;
    height: 1px;
    background: rgba(0, 0, 0, 0.4);
}

.sale-countdown-flip-label {
    font-size: 0.62rem;
    font-weight: 700;
    /* Gold, not --sale-primary (blue) - matches the reference image's
       amber labels-on-dark and the gold CTA treatment used elsewhere. */
    color: #fdcc05;
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

/* .urgent (< 1hr remaining) still pulses the whole panel via the shared
   @keyframes pulse rule below - the gold labels + white numerals read
   clearly through the opacity dip without needing their own color swap. */

/* Live-ticking seconds — smaller + red for a subtle urgency cue.
   Used inside both the popup and widget countdown timers. */
.sale-countdown-secs {
    color: #dc2626;
    font-size: 0.62em;
    font-weight: 700;
    margin-left: 3px;
    letter-spacing: 0.5px;
    font-variant-numeric: tabular-nums;
}

.sale-popup-code {
    margin-bottom: 24px;
}

.sale-code-label {
    font-size: 0.9rem;
    color: #64748b;
}

.sale-code-value {
    display: inline-block;
    background: var(--sale-text);
    color: var(--sale-white);
    font-size: 1.1rem;
    font-weight: 700;
    padding: 8px 20px;
    border-radius: 8px;
    margin-left: 8px;
    letter-spacing: 2px;
    font-family: monospace;
}

.sale-popup-cta {
    display: inline-block;
    /* Gold, not --sale-primary: this is the actual "claim it" conversion
       button, same treatment as the primary CTAs on the public pages. */
    background: #fdcc05;
    color: #0e172a;
    font-size: 1.1rem;
    font-weight: 600;
    padding: 16px 40px;
    border-radius: var(--sale-radius-sm);
    text-decoration: none;
    transition: background var(--sale-transition), transform var(--sale-transition), box-shadow var(--sale-transition);
    box-shadow: 0 4px 14px rgba(253, 204, 5, 0.35);
}

.sale-popup-cta:hover {
    background: #e6b800;
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(253, 204, 5, 0.45);
}

/* ============================================
   Persistent Widget
   ============================================ */
.sale-widget {
    position: fixed;
    bottom: 20px;
    left: 20px;
    z-index: 9999;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.sale-widget[data-state="hidden"] {
    display: none;
}

/* Toggle Button (Minimized State) */
.sale-widget-toggle {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--sale-primary);
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--sale-shadow-sm);
    transition: transform var(--sale-transition), box-shadow var(--sale-transition);
    position: relative;
}

.sale-widget-toggle:hover {
    transform: scale(1.08);
    box-shadow: var(--sale-shadow);
}

.sale-widget[data-state="expanded"] .sale-widget-toggle {
    display: none;
}

.sale-widget-icon {
    width: 24px;
    height: 24px;
    color: var(--sale-white);
}

.sale-widget-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: #dc2626;
    color: var(--sale-white);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 10px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

/* Expanded Panel */
.sale-widget-panel {
    background: var(--sale-white);
    border-radius: var(--sale-radius);
    box-shadow: var(--sale-shadow);
    padding: 20px;
    width: 280px;
    display: none;
    animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(10px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.sale-widget[data-state="expanded"] .sale-widget-panel {
    display: block;
}

.sale-widget-header {
    /* The minimize button is taken out of normal flow (absolute, pinned
       top-right) so .sale-widget-titles can be centered across the
       FULL width of the box via justify-content, rather than only
       having the leftover space next to the button to center within. */
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
}

.sale-widget-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--sale-text);
}

.sale-widget-minimize {
    position: absolute;
    top: 50%;
    right: 0;
    transform: translateY(-50%);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--sale-bg);
    border: none;
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    color: var(--sale-text);
    transition: background var(--sale-transition);
}

.sale-widget-minimize:hover {
    background: var(--sale-bg-dark);
}

/* Widget countdown — same flip-clock concept as the popup
   (.sale-countdown-flip*), scaled down to fit the 280px-wide corner
   panel: smaller cards, tighter gaps, 3-letter labels ("Hrs" not
   "Hours") so 4 cells fit comfortably without wrapping. */
.sale-widget-countdown {
    background: var(--sale-text);
    border-radius: var(--sale-radius-sm);
    padding: 12px 8px 10px;
    text-align: center;
    margin-bottom: 12px;
}

.sale-widget-countdown-label {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--sale-primary-light);
    display: block;
    margin-bottom: 8px;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

.sale-widget-countdown-flip {
    display: flex;
    justify-content: center;
    gap: 5px;
}

.sale-widget-countdown-flip-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex: 1;
    max-width: 52px;
}

.sale-widget-countdown-flip-num {
    position: relative;
    display: block;
    width: 100%;
    /* Explicit height + line-height (matching .flap's 30px widget size,
       box-sizing so the border doesn't add to it) instead of the old
       padding-based sizing, so the Seconds card is exactly the same
       length as the Days/Hours/Min flap cards next to it. */
    height: 30px;
    line-height: 28px;
    padding: 0;
    box-sizing: border-box;
    background: linear-gradient(180deg, #1e293b 0%, #0e172a 100%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    color: #ffffff;
    font-family: var(--font-heading, inherit);
    font-size: 1rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.sale-widget-countdown-flip-num::after {
    content: '';
    position: absolute;
    left: 3px;
    right: 3px;
    top: 50%;
    height: 1px;
    background: rgba(0, 0, 0, 0.4);
}

.sale-widget-countdown-flip-label {
    font-size: 0.5rem;
    font-weight: 700;
    color: #fdcc05;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

/* ============================================
   Split-flap (Solari board) mechanical flip
   Used by BOTH the full-screen popup (.sale-popup-countdown) and the
   corner widget (.sale-widget-countdown) — Days/Hours/Min cells only in
   each; Seconds keeps the plain ticking number (.sale-*-countdown-flip-
   num); a full mechanical flip every single second would be too rapid
   to read and defeats the point of the effect. Each cell is built from
   2 static panels (always showing the current value, split top/bottom
   at the card's midline) plus 2 animated "leaf" panels that swing on a
   3D hinge to simulate a physical flap card falling away (top leaf) and
   a new one swinging up into place (bottom leaf). JS (sale-widget.js)
   only ever touches text content and one class (.flipping) - all the
   actual motion lives here.

   --flap-height/--flap-font-size default to the (smaller) corner-widget
   size; the popup override block below sizes them up to match its
   larger card. Set on .flap itself so the values inherit down to every
   descendant that reads them. ============================================ */
/* iOS TEXT AUTO-SIZING OPT-OUT — do not remove.
   Every countdown cell is a FIXED-height box (--flap-height, or 40px/30px on
   the plain SEC cell) whose digit is positioned by line-height. iOS inflates
   the computed font-size of text inside blocks it judges narrow, but leaves
   those fixed heights alone, so the glyph outgrows its line box and the
   half-height overflow:hidden panels clip it — the digits read oversized,
   high, and sliced at the seam. It is iOS-only: Chrome on iOS is WebKit, so it
   is affected while Chrome and Safari on desktop are not, and no headless
   engine reproduces it. Reported on an iPhone 17 Pro Max, 2026-09-02.
   text-size-adjust inherits, so setting it on the two countdown roots covers
   every cell beneath them. */
.sale-popup-countdown,
.sale-widget-countdown {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

.flap {
    position: relative;
    width: 100%;
    height: var(--flap-height, 30px);
    perspective: 160px;
    /* Panel border width. The spans below cancel exactly this much back out
       (see the note there), so the two values must never drift apart — which
       is why it is one variable rather than 1px written in two places. */
    --flap-border: 1px;
}

.flap-static-top,
.flap-static-bottom,
.flap-leaf-top,
.flap-leaf-bottom {
    position: absolute;
    left: 0;
    right: 0;
    height: calc(var(--flap-height, 30px) / 2);
    overflow: hidden;
    background: linear-gradient(180deg, #1e293b 0%, #0e172a 100%);
    border: var(--flap-border, 1px) solid rgba(255, 255, 255, 0.08);
}

/* The inner span is drawn at the FULL card height and absolutely
   positioned inside its half-height panel, so the panel's
   overflow:hidden crops it to exactly the top or bottom half of the
   glyph — top panels pin the span's top edge to the panel's top
   (showing the span's own top half), bottom panels pin the span's
   bottom edge to the panel's bottom (showing the span's own bottom
   half). This is deliberately not flexbox-based (align-items on an item
   taller than its container is easy to get backwards, and was backwards
   in an earlier pass here) — absolute positioning makes which half
   shows unambiguous. */
.flap-static-top span,
.flap-static-bottom span,
.flap-leaf-top span,
.flap-leaf-bottom span {
    position: absolute;
    left: 0;
    right: 0;
    height: var(--flap-height, 30px);
    line-height: var(--flap-height, 30px);
    text-align: center;
    color: #ffffff;
    font-family: var(--font-heading, inherit);
    font-size: var(--flap-font-size, 1rem);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* `top`/`bottom` on an absolutely positioned child resolve against the parent's
   PADDING box, not its border box — so each panel's outer border pushes its own
   span inward: the top panel's top border shoves the top half DOWN 1px, and the
   bottom panel's bottom border shoves the bottom half UP 1px. That is a 2px
   shear between the two halves of what is supposed to be one glyph, and it is
   why the digits read torn (Anderson, 2026-09-02). Pulling each span back out
   by the border width puts both spans on the SAME absolute Y range, which is
   the whole invariant that makes the halves join into one number.
   Proof: bash scripts/sale_env.sh test-flap --expect fixed */
.flap-static-top span,
.flap-leaf-top span {
    top: calc(-1 * var(--flap-border, 1px));
}

.flap-static-bottom span,
.flap-leaf-bottom span {
    bottom: calc(-1 * var(--flap-border, 1px));
}

.flap-static-top,
.flap-leaf-top {
    top: 0;
    border-radius: 6px 6px 0 0;
    border-bottom: none;
}

.flap-static-bottom,
.flap-leaf-bottom {
    bottom: 0;
    border-radius: 0 0 6px 6px;
    border-top: none;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}

.flap-leaf-top,
.flap-leaf-bottom {
    z-index: 2;
    backface-visibility: hidden;
}

.flap-leaf-top {
    transform-origin: bottom;
}

.flap-leaf-bottom {
    transform-origin: top;
    transform: rotateX(90deg);
}

/* .flipping (added by JS only when a unit's value actually changes)
   plays the two-stage flip: top leaf falls away first, bottom leaf
   swings up a beat later - same sequential timing a real mechanical
   board has. */
.flap.flipping .flap-leaf-top {
    animation: flapLeafDown 0.3s ease-in forwards;
}

.flap.flipping .flap-leaf-bottom {
    animation: flapLeafUp 0.3s ease-out 0.3s forwards;
}

@keyframes flapLeafDown {
    from { transform: rotateX(0deg); }
    to { transform: rotateX(-90deg); }
}

@keyframes flapLeafUp {
    from { transform: rotateX(90deg); }
    to { transform: rotateX(0deg); }
}

/* Split-line down the middle, matching the plain flip-num card's look */
.flap::after {
    content: '';
    position: absolute;
    left: 3px;
    right: 3px;
    top: 50%;
    height: 1px;
    background: rgba(0, 0, 0, 0.5);
    z-index: 3;
    pointer-events: none;
}

/* Popup's flap cards are larger than the corner widget's (matches the
   popup's originally larger 1.4rem digit size) — same .flap component,
   just sized up via the custom properties it reads. */
.sale-popup-countdown .flap {
    --flap-height: 40px;
    --flap-font-size: 1.4rem;
}

.sale-widget-code {
    text-align: center;
    font-size: 0.9rem;
    color: #64748b;
    margin-bottom: 12px;
}

.sale-widget-code strong {
    background: var(--sale-text);
    color: var(--sale-white);
    padding: 4px 10px;
    border-radius: 4px;
    font-family: monospace;
    letter-spacing: 1px;
    margin-left: 4px;
}

.sale-widget-cta {
    display: block;
    /* Same gold "claim it" treatment as .sale-popup-cta. */
    background: #fdcc05;
    color: #0e172a;
    text-align: center;
    font-size: 0.95rem;
    font-weight: 600;
    padding: 12px 20px;
    border-radius: var(--sale-radius-sm);
    text-decoration: none;
    transition: background var(--sale-transition);
}

.sale-widget-cta:hover {
    background: #e6b800;
}

/* Hide CTA on pricing page (handled by JS adding this class) */
.sale-widget-cta.hidden,
.sale-popup-cta.hidden {
    display: none;
}

/* ============================================
   Urgency Animation (< 1 hour remaining)
   ============================================ */
.sale-countdown-timer.urgent,
.sale-widget-countdown-timer.urgent {
    animation: pulse 1.5s ease-in-out infinite;
    color: #dc2626;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* ============================================
   Subtitle (optional — under headline)
   ============================================ */
.sale-popup-subtitle {
    font-size: 0.95rem;
    color: var(--sale-text-light);
    margin: -8px 0 18px;
    line-height: 1.45;
    font-weight: 500;
}

/* ============================================
   Hashtag / rally line (optional — bold, its own line under the subtitle)
   ============================================ */
.sale-popup-hashtag {
    font-size: 1rem;
    font-weight: 800;
    color: var(--sale-text);
    margin: -10px 0 18px;
    line-height: 1.3;
    letter-spacing: 0.3px;
}


/* === sale-widget/components/leaderboard.css === */

/**
 * Leaderboard component — used by prize-tied sales (Arena Season 1 pattern).
 *
 * Renders inside .sale-popup when sale.leaderboard is provided.
 * Base styling assumes a dark background (Arena theme); a default
 * light-theme fallback is provided via :not([data-theme="arena"]) so
 * future light-theme leaderboard sales render correctly without changes.
 *
 * Per-theme overrides live in themes/<name>.css.
 */

/* ============================================
   Leaderboard (optional — live Top 8 for Arena-style sales)
   Mirrors the rank-row style from the Top 8 email template.
   ============================================ */
.sale-popup-leaderboard {
    margin: 0 0 18px;
    text-align: left;
}

.sale-leaderboard-label {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 1.6px;
    text-transform: uppercase;
    color: #fdcc05;
    margin-bottom: 10px;
    text-align: center;
}

.sale-leaderboard-label::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #fdcc05;
    margin-right: 6px;
    vertical-align: middle;
    animation: sale-live-dot 1.4s ease-in-out infinite;
}

@keyframes sale-live-dot {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

.sale-leaderboard-rows {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 5px;
}

.sale-leaderboard-row {
    display: grid;
    grid-template-columns: 32px 32px 1fr auto;
    align-items: center;
    gap: 10px;
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.20);
    border-left: 4px solid var(--rank-accent, #cbd5e1);
    border-radius: 8px;
    padding: 7px 10px 7px 8px;
    color: rgba(255, 255, 255, 0.96);
    font-size: 0.85rem;
    line-height: 1.2;
}

.sale-rank-num {
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--rank-accent, #cbd5e1);
    text-align: center;
}

.sale-rank-insignia {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: white;
    border: 1.5px solid var(--rank-accent, #cbd5e1);
    padding: 1px;
    object-fit: contain;
    display: block;
}

.sale-rank-insignia-empty {
    background: rgba(255, 255, 255, 0.06);
    border-style: dashed;
}

.sale-rank-name {
    font-weight: 700;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sale-rank-branch {
    display: block;
    font-size: 0.6rem;
    font-weight: 800;
    color: rgba(255, 255, 255, 0.82);
    letter-spacing: 1.1px;
    text-transform: uppercase;
    margin-top: 2px;
}

.sale-rank-points {
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--rank-accent, #fff);
    text-align: right;
    line-height: 1.05;
}

.sale-rank-points-label {
    display: block;
    font-size: 0.55rem;
    font-weight: 800;
    color: rgba(255, 255, 255, 0.78);
    letter-spacing: 1.1px;
    text-transform: uppercase;
    margin-top: 2px;
}

/* Light-theme fallback (when no Arena theme — gives a default look) */
.sale-popup-overlay:not([data-theme="arena"]) .sale-leaderboard-row {
    background: var(--sale-bg);
    border-color: var(--sale-bg-dark);
    color: var(--sale-text);
}

.sale-popup-overlay:not([data-theme="arena"]) .sale-rank-name {
    color: var(--sale-text);
}

.sale-popup-overlay:not([data-theme="arena"]) .sale-rank-branch,
.sale-popup-overlay:not([data-theme="arena"]) .sale-rank-points-label {
    color: var(--sale-text-light);
}

.sale-popup-overlay:not([data-theme="arena"]) .sale-leaderboard-label {
    color: var(--sale-primary);
}

.sale-popup-overlay:not([data-theme="arena"]) .sale-leaderboard-label::before {
    background: var(--sale-primary);
}


/* === sale-widget/components/plan-rows.css === */

/**
 * Plan-rows component — per-plan apply table (Memorial 2026 pattern).
 *
 * Renders inside both .sale-popup and .sale-widget-panel when sale.plan_rows
 * is set. Each row shows plan name + code + discount + Apply button.
 *
 * Base styles only (no media queries). Responsive overrides for this
 * component live in sale-widget-mobile.css and sale-widget-mobile-small.css.
 *
 * Theme-specific row coloring (active state, best-row accent) lives in
 * themes/<name>.css.
 */

/* ============================================
   Plan rows (per-plan apply table — Memorial 2026 pattern)
   Used by both popup and widget when sale.plan_rows is set.
   ============================================ */
.sale-popup-wide {
    max-width: 480px;
    /* 5 rows + headline + countdown + CTA can exceed viewport height on
       smaller desktop windows. Cap to viewport with internal scroll as
       safety, then tighten internal spacing below so most viewports
       don't need to scroll at all. */
    max-height: 92vh;
    overflow-y: auto;
    padding: 28px 32px;
}

/* Tighten popup spacing for the plan-rows variant so 5 rows fit on desktop
   without the top badge or bottom CTA getting clipped. Scoped to
   .sale-popup-wide so the single-code popup variant is unaffected. */
.sale-popup-wide .sale-popup-headline {
    font-size: 1.6rem;
    margin-bottom: 10px;
}

.sale-popup-wide .sale-popup-subtitle {
    margin: -2px 0 8px;
}

.sale-popup-wide .sale-popup-memorial-note {
    margin: 0 0 12px;
}

.sale-popup-wide .sale-popup-countdown {
    padding: 12px 18px;
    margin-bottom: 14px;
}

.sale-popup-wide .sale-countdown-timer {
    font-size: 1.35rem;
}

.sale-popup-wide .sale-plan-rows {
    margin-bottom: 14px;
    gap: 5px;
}

.sale-popup-wide .sale-plan-row {
    padding: 8px 10px;
}

.sale-popup-wide .sale-popup-cta {
    padding: 12px 32px;
    font-size: 1rem;
}

.sale-widget-panel-wide {
    width: 320px;
}

.sale-widget-titles {
    display: flex;
    flex-direction: column;
    /* No align-items override — flex items in a column default to
       "stretch", so both the title and subtitle spans (blockified as
       flex items) already share the same cross-axis width (the wider
       of the two, "Up to 40% off"). text-align: center on this parent
       inherits to both, centering each line's text within that shared
       width so the shorter line reads centered relative to the longer
       one - not just individually centered within its own shrink-fit
       box (which would have no visible effect). */
    gap: 0;
    text-align: center;
}

.sale-plan-rows {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    display: grid;
    gap: 6px;
}

.sale-plan-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-left: 4px solid #cbd5e1;
    border-radius: 10px;
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.sale-plan-row:hover {
    background: #f1f5f9;
    transform: translateX(2px);
}

.sale-plan-row.active {
    background: #fef2f2;
    border-color: #b91c1c;
    border-left-width: 4px;
    box-shadow: 0 0 0 2px rgba(185, 28, 28, 0.15);
}

.sale-plan-row-best {
    border-left-color: #d4a017;
}

.sale-plan-row-best.active {
    border-left-color: #b91c1c;
}

.sale-plan-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.sale-plan-name {
    font-size: 0.92rem;
    font-weight: 700;
    color: #0c1e3e;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sale-plan-code {
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 800;
    color: #b91c1c;
    letter-spacing: 1.2px;
    margin-top: 2px;
}

.sale-plan-discount {
    font-size: 0.82rem;
    font-weight: 800;
    color: #0c1e3e;
    text-align: right;
    white-space: nowrap;
}

.sale-plan-row-best .sale-plan-discount {
    color: #b45309;
}

.sale-plan-apply {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 7px 12px;
    background: #0c1e3e;
    color: #ffffff;
    text-decoration: none;
    border-radius: 6px;
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.4px;
    transition: background 0.18s ease, transform 0.18s ease;
    white-space: nowrap;
}

.sale-plan-apply:hover {
    background: #1e3a8a;
    transform: translateX(2px);
}

.sale-plan-row.active .sale-plan-apply {
    background: #b91c1c;
}

.sale-plan-row.active .sale-plan-apply:hover {
    background: #991b1b;
}

/* Compact widget variant — tighter padding so 5 rows fit */
.sale-plan-rows-widget .sale-plan-row {
    padding: 8px 10px;
    gap: 6px;
}

.sale-plan-rows-widget .sale-plan-name {
    font-size: 0.82rem;
}

.sale-plan-rows-widget .sale-plan-code {
    font-size: 0.66rem;
    letter-spacing: 1px;
}

.sale-plan-rows-widget .sale-plan-discount {
    font-size: 0.74rem;
}

.sale-plan-rows-widget .sale-plan-apply {
    padding: 5px 9px;
    font-size: 0.7rem;
}


/* === sale-widget/sale-widget-tablet.css === */

/**
 * Sale Widget — tablet viewport overrides (max-width: 1024px).
 *
 * Layout-only adjustments. No base styling, no theme overrides, no
 * new components. If a rule isn't here, the base file's value applies.
 */

/* ============================================
   Responsive: Tablet (max-width: 1024px)
   ============================================ */
@media (max-width: 1024px) {
    .sale-popup {
        max-width: 400px;
        padding: 32px;
    }

    .sale-popup-headline {
        font-size: 1.75rem;
    }

    .sale-widget-panel {
        width: 260px;
    }
}


/* === sale-widget/sale-widget-mobile.css === */

/**
 * Sale Widget — mobile viewport overrides (max-width: 768px).
 *
 * Layout-only adjustments. Covers both the base popup/widget overrides
 * AND the plan-rows component overrides at this breakpoint.
 */

/* ============================================
   Responsive: Mobile (max-width: 768px)
   ============================================ */
@media (max-width: 768px) {
    .sale-popup-overlay {
        padding: 16px;
    }

    .sale-popup {
        max-width: 100%;
        padding: 28px 24px;
    }

    .sale-popup-headline {
        font-size: 1.5rem;
    }

    .sale-countdown-timer {
        font-size: 1.5rem;
    }

    .sale-popup-cta {
        padding: 14px 32px;
        font-size: 1rem;
        width: 100%;
    }

    .sale-widget {
        bottom: 16px;
        left: 16px;
    }

    .sale-widget-panel {
        width: 240px;
        padding: 16px;
    }

    .sale-widget-toggle {
        width: 52px;
        height: 52px;
    }

    /* Plan rows — POPUP keeps inline 3-col layout (popup goes full-width on
       mobile so there's room) but tightens spacing aggressively so 5 rows
       fit above the fold. WIDGET stacks the Apply button below each row
       because the panel is too narrow for inline. */
    .sale-popup-wide {
        max-width: 100%;
        padding: 20px 18px;
    }
    .sale-popup-wide .sale-popup-headline {
        font-size: 1.3rem;
    }
    .sale-popup-wide .sale-countdown-timer {
        font-size: 1.2rem;
    }
    .sale-popup-wide .sale-plan-row {
        padding: 7px 9px;
        gap: 8px;
    }
    .sale-popup-wide .sale-plan-name {
        font-size: 0.82rem;
    }
    .sale-popup-wide .sale-plan-code {
        font-size: 0.65rem;
    }
    .sale-popup-wide .sale-plan-discount {
        font-size: 0.75rem;
    }
    .sale-popup-wide .sale-plan-apply {
        padding: 6px 10px;
        font-size: 0.72rem;
    }
    .sale-popup-wide .sale-popup-cta {
        padding: 11px 24px;
        font-size: 0.95rem;
    }

    /* Widget plan-rows — compact 2-col / 2-row layout per row so the panel
       doesn't dominate the screen. Layout per row:
           [Plan name              ] [ Discount  ]
           [Code                   ] [ Apply →   ]
       Panel fixed at 270px (was calc(100vw - 32px) max 320px = ~84% of viewport). */
    .sale-widget-panel-wide {
        width: 270px;
        max-width: 270px;
        padding: 14px;
    }
    .sale-widget-panel-wide .sale-widget-header {
        margin-bottom: 8px;
    }
    .sale-widget-panel-wide .sale-widget-title {
        font-size: 0.92rem;
    }
    .sale-widget-panel-wide .sale-widget-subtitle {
        font-size: 0.6rem;
        letter-spacing: 0.5px;
    }
    .sale-widget-panel-wide .sale-widget-countdown {
        padding: 7px 10px;
        margin-bottom: 8px;
    }
    .sale-widget-panel-wide .sale-widget-countdown-label {
        font-size: 0.68rem;
    }
    .sale-widget-panel-wide .sale-widget-countdown-timer {
        font-size: 1rem;
    }
    .sale-widget-panel-wide .sale-plan-rows {
        gap: 4px;
        margin-bottom: 8px;
    }
    .sale-widget-panel-wide .sale-plan-row {
        grid-template-columns: 1fr auto;
        grid-template-rows: auto auto;
        gap: 2px 8px;
        padding: 6px 8px;
    }
    .sale-widget-panel-wide .sale-plan-info {
        grid-column: 1;
        grid-row: 1 / span 2;
    }
    .sale-widget-panel-wide .sale-plan-name {
        font-size: 0.78rem;
    }
    .sale-widget-panel-wide .sale-plan-code {
        font-size: 0.6rem;
        letter-spacing: 0.8px;
        margin-top: 1px;
    }
    .sale-widget-panel-wide .sale-plan-discount {
        grid-column: 2;
        grid-row: 1;
        font-size: 0.68rem;
        text-align: right;
        align-self: center;
        order: unset;
    }
    .sale-widget-panel-wide .sale-plan-apply {
        grid-column: 2;
        grid-row: 2;
        padding: 4px 10px;
        font-size: 0.64rem;
        width: auto;
        justify-content: center;
        align-self: center;
        order: unset;
    }
    .sale-widget-panel-wide .sale-widget-cta {
        padding: 10px 12px;
        font-size: 0.85rem;
    }
}


/* === sale-widget/sale-widget-mobile-small.css === */

/**
 * Sale Widget — small mobile viewport overrides (max-width: 480px).
 *
 * Layout-only adjustments for the tightest screens. Cascades over both
 * tablet and mobile breakpoint files. Covers base popup/widget AND
 * plan-rows component at this breakpoint.
 */

/* ============================================
   Responsive: Mobile Portrait (max-width: 480px)
   ============================================ */
@media (max-width: 480px) {
    .sale-popup {
        padding: 24px 20px;
        border-radius: var(--sale-radius-sm);
    }

    .sale-popup-badge {
        font-size: 0.75rem;
        padding: 5px 12px;
    }

    .sale-popup-headline {
        font-size: 1.35rem;
    }

    .sale-popup-countdown {
        padding: 12px 16px;
    }

    .sale-countdown-timer {
        font-size: 1.35rem;
    }

    .sale-code-value {
        font-size: 1rem;
        padding: 6px 14px;
    }

    .sale-widget {
        bottom: 12px;
        left: 12px;
    }

    .sale-widget-panel {
        width: 220px;
        padding: 14px;
    }

    .sale-widget-toggle {
        width: 48px;
        height: 48px;
    }

    .sale-widget-icon {
        width: 20px;
        height: 20px;
    }

    /* Plan rows — popup-wide goes even tighter on tiny screens so 5 rows
       fit + leave room for headline, countdown, and CTA without scrolling. */
    .sale-popup-wide {
        padding: 16px 14px;
    }
    .sale-popup-wide .sale-popup-headline {
        font-size: 1.2rem;
    }
    .sale-popup-wide .sale-popup-subtitle {
        font-size: 0.85rem;
    }
    .sale-popup-wide .sale-popup-memorial-note {
        font-size: 0.78rem;
    }
    .sale-popup-wide .sale-popup-countdown {
        padding: 9px 12px;
        margin-bottom: 10px;
    }
    .sale-popup-wide .sale-countdown-timer {
        font-size: 1.1rem;
    }
    .sale-popup-wide .sale-plan-rows {
        margin-bottom: 10px;
        gap: 4px;
    }
    .sale-popup-wide .sale-plan-row {
        padding: 6px 8px;
    }
    .sale-popup-wide .sale-plan-name {
        font-size: 0.78rem;
    }
    .sale-popup-wide .sale-plan-code {
        font-size: 0.62rem;
    }
    .sale-popup-wide .sale-plan-apply {
        padding: 5px 8px;
        font-size: 0.68rem;
    }
    .sale-popup-wide .sale-popup-cta {
        padding: 10px 18px;
        font-size: 0.9rem;
    }

    /* Widget plan-rows: compact mobile layout from sale-widget-mobile.css
       already handles this viewport; nothing extra needed for ≤480px. */
}


/* === sale-widget/themes/arena.css === */

/**
 * Theme: arena — black + gold palette (Top 8 email match).
 *
 * Activates when [data-theme="arena"] is on .sale-popup-overlay or .sale-widget.
 * No media queries here — theme overrides cascade through all viewports.
 */

/* ============================================
   THEME: arena — black + gold (Top 8 email palette)
   Activates when [data-theme="arena"] is on .sale-popup-overlay or .sale-widget
   ============================================ */
.sale-popup-overlay[data-theme="arena"],
.sale-widget[data-theme="arena"] {
    --sale-primary: #fdcc05;          /* Arena gold */
    --sale-primary-hover: #f59e0b;    /* Amber */
    --sale-primary-light: #facc15;
    --sale-bg: #fffbeb;               /* Light yellow */
    --sale-bg-dark: #fef3c7;
    --sale-text: #0f172a;             /* Dark navy */
    --sale-text-light: #475569;
    --sale-shadow: 0 20px 40px rgba(15, 23, 42, 0.35);
    --sale-shadow-sm: 0 4px 14px rgba(15, 23, 42, 0.25);
}

/* Arena popup — solid navy background with gold accents (matches email) */
.sale-popup-overlay[data-theme="arena"] .sale-popup {
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #fff;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-close {
    background: rgba(255, 255, 255, 0.1);
    color: #fdcc05;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-close:hover {
    background: #fdcc05;
    color: #0f172a;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-badge {
    background: #fdcc05;
    color: #0f172a;
    font-weight: 800;
    letter-spacing: 1.4px;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-headline {
    color: #fff;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-subtitle {
    color: rgba(255, 255, 255, 0.94);
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-countdown {
    background: rgba(253, 204, 5, 0.12);
    border: 1px solid rgba(253, 204, 5, 0.4);
}

.sale-popup-overlay[data-theme="arena"] .sale-countdown-label {
    color: #fdcc05;
    font-weight: 700;
    letter-spacing: 0.8px;
}

.sale-popup-overlay[data-theme="arena"] .sale-countdown-timer {
    color: #fff;
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-code {
    margin-bottom: 18px;
}

.sale-popup-overlay[data-theme="arena"] .sale-code-label {
    color: rgba(255, 255, 255, 0.88);
}

.sale-popup-overlay[data-theme="arena"] .sale-code-value {
    background: #0f172a;
    color: #fdcc05;
    border: 1px solid rgba(253, 204, 5, 0.4);
    font-family: 'SF Mono', 'Menlo', Consolas, monospace;
    letter-spacing: 2.5px;
    font-weight: 800;
}

/* Leaderboard label gold for Arena (default uses primary blue) */
.sale-popup-overlay[data-theme="arena"] .sale-leaderboard-label {
    color: #fdcc05;
}

.sale-popup-overlay[data-theme="arena"] .sale-leaderboard-label::before {
    background: #fdcc05;
    box-shadow: 0 0 8px rgba(253, 204, 5, 0.6);
}

/* Arena leaderboard rows — white cards so branch accents + points pop */
.sale-popup-overlay[data-theme="arena"] .sale-leaderboard-row {
    background: #ffffff;
    border: 1px solid transparent;
    border-left: 4px solid var(--rank-accent, #cbd5e1);
    color: #0f172a;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.sale-popup-overlay[data-theme="arena"] .sale-rank-name {
    color: #0f172a;
}

.sale-popup-overlay[data-theme="arena"] .sale-rank-branch {
    color: #64748b;
    font-weight: 800;
}

.sale-popup-overlay[data-theme="arena"] .sale-rank-points-label {
    color: #94a3b8;
    font-weight: 800;
}

/* Insignia on white card — add subtle inner ring for definition */
.sale-popup-overlay[data-theme="arena"] .sale-rank-insignia {
    background: #ffffff;
    box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.08);
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-cta {
    background: #fdcc05;
    color: #0f172a;
    font-weight: 800;
    box-shadow: 0 6px 18px rgba(253, 204, 5, 0.35);
}

.sale-popup-overlay[data-theme="arena"] .sale-popup-cta:hover {
    background: #f59e0b;
    box-shadow: 0 8px 24px rgba(253, 204, 5, 0.5);
}

/* Arena widget (bottom-left) — gold toggle, navy panel */
.sale-widget[data-theme="arena"] .sale-widget-toggle {
    background: #fdcc05;
}

.sale-widget[data-theme="arena"] .sale-widget-icon {
    color: #0f172a;
}

.sale-widget[data-theme="arena"] .sale-widget-badge {
    background: #0f172a;
    color: #fdcc05;
}

.sale-widget[data-theme="arena"] .sale-widget-panel {
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #fff;
}

.sale-widget[data-theme="arena"] .sale-widget-title {
    color: #fdcc05;
    font-weight: 800;
    letter-spacing: 0.4px;
}

.sale-widget[data-theme="arena"] .sale-widget-minimize {
    background: rgba(255, 255, 255, 0.1);
    color: #fdcc05;
}

.sale-widget[data-theme="arena"] .sale-widget-minimize:hover {
    background: #fdcc05;
    color: #0f172a;
}

.sale-widget[data-theme="arena"] .sale-widget-countdown {
    background: rgba(253, 204, 5, 0.12);
    border: 1px solid rgba(253, 204, 5, 0.3);
}

.sale-widget[data-theme="arena"] .sale-widget-countdown-label {
    color: #fdcc05;
}

.sale-widget[data-theme="arena"] .sale-widget-countdown-timer {
    color: #fff;
}

.sale-widget[data-theme="arena"] .sale-widget-code {
    color: rgba(255, 255, 255, 0.7);
}

.sale-widget[data-theme="arena"] .sale-widget-code strong {
    background: #0f172a;
    color: #fdcc05;
    border: 1px solid rgba(253, 204, 5, 0.4);
    font-family: 'SF Mono', 'Menlo', Consolas, monospace;
    letter-spacing: 1.5px;
    font-weight: 800;
}

.sale-widget[data-theme="arena"] .sale-widget-prize-hint {
    color: rgba(255, 255, 255, 0.7);
}

.sale-widget[data-theme="arena"] .sale-widget-prize-hint strong {
    color: #fdcc05;
}

.sale-widget[data-theme="arena"] .sale-widget-cta {
    background: #fdcc05;
    color: #0f172a;
    font-weight: 800;
}

.sale-widget[data-theme="arena"] .sale-widget-cta:hover {
    background: #f59e0b;
}

/* Wider popup for Arena to fit giveaway prize list comfortably */
.sale-popup-overlay[data-theme="arena"] .sale-popup {
    max-width: 460px;
}


/* === sale-widget/themes/memorial.css === */

/**
 * Theme: memorial — red / white / navy with gold accent (Memorial Day 2026).
 *
 * Activates when [data-theme="memorial"] is on .sale-popup-overlay or .sale-widget.
 * No media queries here — theme overrides cascade through all viewports.
 */

/* ============================================
   THEME: memorial — red / white / navy with gold accent
   Activates when [data-theme="memorial"] is on .sale-popup-overlay or .sale-widget
   ============================================ */
.sale-popup-overlay[data-theme="memorial"],
.sale-widget[data-theme="memorial"] {
    --sale-primary: #b91c1c;          /* Red-700 */
    --sale-primary-hover: #991b1b;    /* Red-800 */
    --sale-primary-light: #ef4444;    /* Red-500 */
    --sale-bg: #fef2f2;               /* Red-50 */
    --sale-bg-dark: #fee2e2;          /* Red-100 */
    --sale-text: #0c1e3e;             /* Deep navy */
    --sale-text-light: #475569;       /* Slate-600 */
    --sale-shadow: 0 22px 44px rgba(12, 30, 62, 0.28);
    --sale-shadow-sm: 0 4px 14px rgba(12, 30, 62, 0.18);
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup {
    background: #ffffff;
    border-top: 6px solid #b91c1c;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-badge {
    background: #b91c1c;
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 1.2px;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-headline {
    color: #0c1e3e;
    font-weight: 800;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-subtitle {
    color: #334155;
    font-weight: 600;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-memorial-note {
    color: #64748b;
    font-style: italic;
    font-size: 0.9rem;
    margin: -2px 0 14px;
    line-height: 1.4;
    text-align: center;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-countdown {
    background: #fef2f2;
    border: 1px solid #fee2e2;
}

.sale-popup-overlay[data-theme="memorial"] .sale-countdown-label {
    color: #b91c1c;
    font-weight: 700;
    letter-spacing: 0.6px;
}

.sale-popup-overlay[data-theme="memorial"] .sale-countdown-timer {
    color: #0c1e3e;
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-cta,
.sale-widget[data-theme="memorial"] .sale-widget-cta {
    background: #0c1e3e;
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 0.3px;
    box-shadow: 0 6px 18px rgba(12, 30, 62, 0.35);
}

.sale-popup-overlay[data-theme="memorial"] .sale-popup-cta:hover,
.sale-widget[data-theme="memorial"] .sale-widget-cta:hover {
    background: #1e3a8a;
    box-shadow: 0 8px 22px rgba(12, 30, 62, 0.45);
}

/* Memorial widget — navy panel with red toggle */
.sale-widget[data-theme="memorial"] .sale-widget-toggle {
    background: #b91c1c;
}

.sale-widget[data-theme="memorial"] .sale-widget-icon {
    color: #ffffff;
}

.sale-widget[data-theme="memorial"] .sale-widget-badge {
    background: #0c1e3e;
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 0.4px;
}

.sale-widget[data-theme="memorial"] .sale-widget-panel {
    background: #ffffff;
    border-top: 4px solid #b91c1c;
}

.sale-widget[data-theme="memorial"] .sale-widget-title {
    color: #0c1e3e;
    font-weight: 800;
}

.sale-widget[data-theme="memorial"] .sale-widget-subtitle {
    color: #b91c1c;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    display: block;
    margin-top: 2px;
}

.sale-widget[data-theme="memorial"] .sale-widget-minimize {
    background: #fef2f2;
    color: #b91c1c;
}

.sale-widget[data-theme="memorial"] .sale-widget-minimize:hover {
    background: #b91c1c;
    color: #ffffff;
}

.sale-widget[data-theme="memorial"] .sale-widget-countdown {
    background: #fef2f2;
    border: 1px solid #fee2e2;
}

.sale-widget[data-theme="memorial"] .sale-widget-countdown-label {
    color: #b91c1c;
    font-weight: 700;
}


/* === sale-widget/themes/july4th.css === */

/**
 * Theme: july4th — Independence Day red / white / blue with subtle firework bursts.
 *
 * Activates when [data-theme="july4th"] is on .sale-popup-overlay or .sale-widget.
 * No media queries here — theme overrides cascade through all viewports.
 *
 * Fireworks: two static CSS bursts (repeating-conic spokes masked into a disc)
 * on .sale-popup::before/::after at ~7% opacity, tucked into the top corners.
 * Pure CSS, NON-animated, pointer-events:none, sitting behind the content.
 */

/* ============================================
   THEME: july4th — palette
   ============================================ */
.sale-popup-overlay[data-theme="july4th"],
.sale-widget[data-theme="july4th"] {
    --sale-primary: #1d4ed8;          /* Blue-700 */
    --sale-primary-hover: #1e40af;    /* Blue-800 */
    --sale-primary-light: #3b82f6;    /* Blue-500 */
    --sale-bg: #eff6ff;               /* Blue-50 */
    --sale-bg-dark: #dbeafe;          /* Blue-100 */
    --sale-text: #0a2463;             /* Deep navy */
    --sale-text-light: #3b5bdb;       /* Indigo */
    --sale-shadow: 0 22px 44px rgba(10, 36, 99, 0.28);
    --sale-shadow-sm: 0 4px 14px rgba(10, 36, 99, 0.18);
}

/* ============================================
   Popup — white card, tricolor top ribbon, firework bursts
   ============================================ */
.sale-popup-overlay[data-theme="july4th"] .sale-popup {
    /* 6px red/white/blue ribbon pinned to the very top, then plain white below */
    background:
        linear-gradient(90deg,
            #b91c1c 0 33.33%,
            #f8fafc 33.33% 66.66%,
            #1d4ed8 66.66% 100%) top / 100% 6px no-repeat,
        #ffffff;
    overflow: hidden;                 /* clip the corner bursts to the rounded card */
}

/* keep all content above the firework layer — but NOT the close button, whose
   own absolute top/right positioning (from base) must be preserved. */
.sale-popup-overlay[data-theme="july4th"] .sale-popup > *:not(.sale-popup-close) {
    position: relative;
    z-index: 1;
}

/* close button stays pinned top-right (base) and rides above the bursts */
.sale-popup-overlay[data-theme="july4th"] .sale-popup-close {
    z-index: 2;
}

/* two static firework bursts — 24 thin spokes masked into a center-gapped disc */
.sale-popup-overlay[data-theme="july4th"] .sale-popup::before,
.sale-popup-overlay[data-theme="july4th"] .sale-popup::after {
    content: "";
    position: absolute;
    z-index: 0;
    width: 190px;
    height: 190px;
    background: repeating-conic-gradient(
        from 7.5deg,
        currentColor 0deg 0.7deg,
        transparent 0.7deg 15deg);
    -webkit-mask: radial-gradient(circle,
        transparent 0 11%, #000 15% 46%, transparent 52%);
            mask: radial-gradient(circle,
        transparent 0 11%, #000 15% 46%, transparent 52%);
    opacity: 0.16;   /* 0.07 washed red/blue out to gray; 0.16 lets the color read while staying behind content */
    pointer-events: none;
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup::before {
    top: -48px;
    left: -48px;
    color: #b91c1c;                   /* red burst, top-left */
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup::after {
    top: -58px;
    right: -58px;
    color: #1d4ed8;                   /* blue burst, top-right */
}

/* Badge — slightly translucent red pill; the (larger) logo behind it shows
   through the overlap and extends past the pill edges. */
.sale-popup-overlay[data-theme="july4th"] .sale-popup-badge {
    background: rgba(185, 28, 28, 0.68);   /* red @ 68% so the logo behind clearly reads through */
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 1.2px;
    text-shadow: 0 1px 2px rgba(120, 12, 12, 0.55);   /* keep white text legible over the lighter red + logo */
}

/* logo is a bold watermark clipped to the pill, seen through the translucent red;
   doubled to 88px, kept centered on the pill (the wrap clips the overflow) */
.sale-popup-overlay[data-theme="july4th"] .sale-popup-badge-logo {
    width: auto;
    height: 88px;
    opacity: 1;
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-headline {
    color: #0a2463;
    font-weight: 800;
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-hashtag {
    color: #b91c1c;
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-subtitle {
    color: #334155;
    font-weight: 600;
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-countdown {
    background: #eff6ff;
    border: 1px solid #dbeafe;
}

.sale-popup-overlay[data-theme="july4th"] .sale-countdown-label {
    color: #b91c1c;
    font-weight: 700;
    letter-spacing: 0.6px;
}

.sale-popup-overlay[data-theme="july4th"] .sale-countdown-timer {
    color: #0a2463;
}

.sale-popup-overlay[data-theme="july4th"] .sale-code-value {
    background: #0a2463;              /* navy code chip */
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-cta {
    background: linear-gradient(135deg, #1d4ed8 0%, #1e40af 100%);
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 0.3px;
    box-shadow: 0 6px 18px rgba(10, 36, 99, 0.35);
}

.sale-popup-overlay[data-theme="july4th"] .sale-popup-cta:hover {
    background: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
    box-shadow: 0 8px 22px rgba(10, 36, 99, 0.45);
}

/* ============================================
   Persistent widget — tricolor ribbon + patriotic accents (no bursts; too small)
   ============================================ */
.sale-widget[data-theme="july4th"] .sale-widget-toggle {
    background: #b91c1c;
}

.sale-widget[data-theme="july4th"] .sale-widget-icon {
    color: #ffffff;
}

.sale-widget[data-theme="july4th"] .sale-widget-badge {
    background: #0a2463;
    color: #ffffff;
    font-weight: 800;
    letter-spacing: 0.4px;
}

.sale-widget[data-theme="july4th"] .sale-widget-panel {
    background: #ffffff;
    border-top: 4px solid transparent;
    border-image: linear-gradient(90deg,
        #b91c1c 0 33.33%,
        #cbd5e1 33.33% 66.66%,
        #1d4ed8 66.66% 100%) 1;
}

.sale-widget[data-theme="july4th"] .sale-widget-title {
    color: #0a2463;
    font-weight: 800;
}

.sale-widget[data-theme="july4th"] .sale-widget-subtitle {
    color: #b91c1c;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    display: block;
    margin-top: 2px;
}

.sale-widget[data-theme="july4th"] .sale-widget-minimize {
    background: #eff6ff;
    color: #1d4ed8;
}

.sale-widget[data-theme="july4th"] .sale-widget-minimize:hover {
    background: #1d4ed8;
    color: #ffffff;
}

.sale-widget[data-theme="july4th"] .sale-widget-countdown {
    background: #eff6ff;
    border: 1px solid #dbeafe;
}

.sale-widget[data-theme="july4th"] .sale-widget-countdown-label {
    color: #b91c1c;
    font-weight: 700;
}

.sale-widget[data-theme="july4th"] .sale-widget-code strong {
    background: #0a2463;
}

.sale-widget[data-theme="july4th"] .sale-widget-cta {
    background: linear-gradient(135deg, #1d4ed8 0%, #1e40af 100%);
    color: #ffffff;
    font-weight: 800;
}

.sale-widget[data-theme="july4th"] .sale-widget-cta:hover {
    background: linear-gradient(135deg, #1e40af 0%, #1e3a8a 100%);
}


/* === sale-widget/themes/class.css === */

/**
 * Theme: class — tonight's free class, in the Classroom's ink and gold.
 *
 * Activates when [data-theme="class"] is on .sale-widget (the class kind
 * never opens the popup, but the popup rules are here so a future kind that
 * does is not left on the blue default). No media queries here.
 */

.sale-popup-overlay[data-theme="class"],
.sale-widget[data-theme="class"] {
    --sale-primary: #fdcc05;
    --sale-primary-hover: #f59e0b;
    --sale-primary-light: #fdcc05;
    --sale-bg: #fef3c7;
    --sale-bg-dark: #fde68a;
    --sale-text: #0f172a;
    --sale-text-light: #475569;
    --sale-shadow: 0 20px 40px rgba(15, 23, 42, 0.35);
    --sale-shadow-sm: 0 4px 14px rgba(15, 23, 42, 0.25);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* ---------- Widget: the ink panel ---------- */
.sale-widget[data-theme="class"] .sale-widget-toggle {
    background: #0f172a;
    border: 2px solid #fdcc05;
}
.sale-widget[data-theme="class"] .sale-widget-icon { color: #fdcc05; }
.sale-widget[data-theme="class"] .sale-widget-badge {
    background: #fdcc05;
    color: #0f172a;
    letter-spacing: 1px;
}

.sale-widget[data-theme="class"] .sale-widget-panel {
    background: #0f172a;
    color: #fff;
    border: 1px solid rgba(253, 204, 5, 0.35);
}
.sale-widget[data-theme="class"] .sale-widget-titles {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding-right: 32px;
    padding-left: 32px;
}
.sale-widget[data-theme="class"] .sale-widget-title {
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 800;
    font-size: 11px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: #fdcc05;
}
.sale-widget[data-theme="class"] .sale-widget-subtitle {
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 800;
    font-size: 16px;
    line-height: 1.15;
    color: #fff;
    text-align: center;
}
.sale-widget[data-theme="class"] .sale-widget-minimize {
    background: rgba(255, 255, 255, 0.1);
    color: #fdcc05;
}
.sale-widget[data-theme="class"] .sale-widget-minimize:hover {
    background: #fdcc05;
    color: #0f172a;
}

.sale-widget[data-theme="class"] .sale-widget-countdown {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
}
.sale-widget[data-theme="class"] .sale-widget-countdown-label {
    color: rgba(255, 255, 255, 0.6);
    font-weight: 800;
    letter-spacing: 1.4px;
}
.sale-widget[data-theme="class"] .flap-static-top span,
.sale-widget[data-theme="class"] .flap-static-bottom span,
.sale-widget[data-theme="class"] .flap-leaf-top span,
.sale-widget[data-theme="class"] .flap-leaf-bottom span,
.sale-widget[data-theme="class"] .sale-widget-countdown-flip-num {
    color: #fdcc05;
}
.sale-widget[data-theme="class"] .sale-widget-countdown-flip-label {
    color: rgba(255, 255, 255, 0.6);
}

/* The class is in session: the clock steps aside for the live line. */
.sale-widget[data-theme="class"].is-live .sale-widget-countdown { display: none; }
.sale-widget-live {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 12px;
    padding: 10px 12px;
    border-radius: 12px;
    background: rgba(4, 120, 87, 0.18);
    border: 1px solid rgba(16, 185, 129, 0.5);
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 800;
    font-size: 13px;
    color: #6ee7b7;
}
.sale-widget-live[hidden] { display: none; }
.sale-widget-live-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #10b981;
    animation: saleLivePulse 1.6s ease-in-out infinite;
}
@keyframes saleLivePulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

.sale-widget[data-theme="class"] .sale-widget-cta {
    background: #fdcc05;
    color: #0f172a;
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 800;
    box-shadow: 0 6px 18px rgba(253, 204, 5, 0.35);
}
.sale-widget[data-theme="class"] .sale-widget-cta:hover { background: #f59e0b; }

/* ---------- Popup, should a kind with a popup ever wear this theme ---------- */
.sale-popup-overlay[data-theme="class"] .sale-popup {
    background: #0f172a;
    color: #fff;
    border: 3px solid #fdcc05;
}
.sale-popup-overlay[data-theme="class"] .sale-popup-headline,
.sale-popup-overlay[data-theme="class"] .sale-popup-subtitle { color: #fff; }
.sale-popup-overlay[data-theme="class"] .sale-popup-badge { background: #fdcc05; color: #0f172a; font-weight: 800; }
.sale-popup-overlay[data-theme="class"] .sale-popup-close { background: rgba(255, 255, 255, 0.1); color: #fdcc05; }

@media (prefers-reduced-motion: reduce) {
    .sale-widget-live-dot { animation: none; }
}
