/* ============================================================
   BASE — shared structural/state layer for all 5 storefront themes.
   Loaded BEFORE the active theme css (templates/themes/_head.html).
   Only cross-theme structure/state rules live here; visual skinning
   stays in the theme files. This file speaks exclusively in semantic
   variables (--accent/--accent-ink/--ink/--mut/--line/--surface/
   --surface-2/--radius/--ring), which each theme maps onto its own
   tokens in :root. Every var() carries a fallback so the layer also
   degrades gracefully if a theme misses an alias.
   ============================================================ */

/* ---- z-index scale (single source of truth; replaces 12 magic numbers) --
   header   100  sticky site header / top strip
   dropdown 110  nav dropdown menus (inside the header stacking context)
   overlay  200  page-level overlays: sticky bars, drawers
   modal   1000  dialogs: inquiry / payment
   toast   9999  always on top: cookie banner, skip-link, site messages */
:root{
--z-header:100;--z-dropdown:110;--z-overlay:200;--z-modal:1000;--z-toast:9999}

/* ---- Skip link (all themes; previously styled only in aurora, so the
   link sat permanently visible in the other 4) ---- */
.skip-link{position:fixed;top:12px;left:12px;z-index:var(--z-toast);padding:10px 16px;background:var(--accent,#4f46e5);color:var(--accent-ink,#fff);font-weight:700;font-size:.92rem;border-radius:var(--radius-sm,var(--radius,var(--r,10px)));box-shadow:0 10px 28px rgba(0,0,0,.28);text-decoration:none;transform:translateY(-260%);transition:transform .2s ease}
.skip-link:focus,.skip-link:focus-visible{transform:none;outline:3px solid var(--ring,var(--accent,#4f46e5));outline-offset:2px}

/* ---- Focus visibility: one theme-aware ring everywhere.
   The old global rule referenced a non-existent --primary token and was
   silently dropped, leaving keyboard users with no focus indicator. ---- */
:focus-visible{outline:3px solid var(--ring,var(--accent,#4f46e5));outline-offset:2px}
/* Higher-specificity rings for focusable non-link controls (tabindex=0) */
.thumbs img:focus-visible,.payment-method-tab:focus-visible{outline:3px solid var(--ring,var(--accent,#4f46e5));outline-offset:2px}

/* ---- Disabled state (site.js locks submit buttons while sending) ---- */
.btn:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}
:where(button,input,textarea,select):disabled{cursor:not-allowed}
:where(input,textarea,select):disabled{opacity:.65}

/* ---- Touch targets >= 44px (WCAG 2.5.5) ---- */
.inquiry-close{min-width:44px;min-height:44px}
.payment-method-tab{min-height:44px}
.footer-links a,.social-row a{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px}

/* ---- Django messages: top toast cards ---- */
.site-messages{position:fixed;top:12px;left:50%;transform:translateX(-50%);z-index:var(--z-toast);display:flex;flex-direction:column;gap:8px;width:min(92vw,560px);margin:0;padding:0;list-style:none}
.site-messages .msg{display:flex;align-items:center;gap:10px;margin:0;padding:12px 16px;font-size:.92rem;font-weight:600;line-height:1.45;color:var(--ink,var(--text,#1f2937));background:var(--surface,var(--panel,#fff));border:1px solid var(--line,#e5e7eb);border-left:4px solid var(--msg,var(--accent,#4f46e5));border-radius:var(--radius,var(--r,10px));box-shadow:0 14px 34px -14px rgba(0,0,0,.35)}
.site-messages .msg.success{--msg:#16a34a;background:color-mix(in srgb,#16a34a 9%,var(--surface,var(--panel,#fff)))}
.site-messages .msg.error{--msg:#dc2626;background:color-mix(in srgb,#dc2626 9%,var(--surface,var(--panel,#fff)))}
.site-messages .msg.warning{--msg:#d97706;background:color-mix(in srgb,#d97706 10%,var(--surface,var(--panel,#fff)))}

/* ---- Empty state block (centered, icon slot, CTA) ---- */
.empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;padding:clamp(40px,6vw,72px) 24px;background:var(--surface,var(--panel,#fff));border:1px dashed var(--line,#d1d5db);border-radius:var(--radius-lg,var(--r-lg,var(--radius,var(--r,12px))));color:var(--mut,var(--muted,#6b7280))}
.empty-state svg,.empty-state .empty-icon{width:40px;height:40px;color:var(--accent,#4f46e5)}
.empty-state h2,.empty-state h3,.empty-state p{margin:0}
.empty-state h2,.empty-state h3{color:var(--ink,var(--text,#1f2937))}
.empty-state p{max-width:52ch}
.empty-state .btn{margin-top:8px}

/* ---- Rating badge (gold star + count) ---- */
.rating-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 11px;border:1px solid color-mix(in srgb,#f59e0b 32%,transparent);border-radius:999px;background:color-mix(in srgb,#f59e0b 12%,var(--surface,var(--panel,#fff)));color:var(--ink,var(--text,#1f2937));font-size:.85rem;font-weight:700;line-height:1.5;font-variant-numeric:tabular-nums}
.rating-badge::before{content:"\2605";color:#f59e0b}
.rating-count{margin-left:6px;color:var(--mut,var(--muted,#6b7280));font-size:.85rem}

/* ---- Product cards: clamp long marketplace titles/summaries so cards
   keep a uniform height ---- */
.product-card .card-body h3{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.card-sum{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ---- Rich content: uniform overflow defense + code styles ---- */
.rich-content{overflow-x:auto}
body .rich-content > h2:first-child{margin-top:0}
.table-wrap{overflow-x:auto}
.rich-content pre{overflow-x:auto;margin:1.2em 0;padding:14px 16px;background:var(--surface-2,var(--panel-2,#f7f9fb));border:1px solid var(--line,#e5e7eb);border-radius:var(--radius-sm,var(--radius,var(--r,10px)));font-size:.88rem;line-height:1.6}
.rich-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;font-size:.9em}
.rich-content :not(pre)>code{padding:.12em .38em;background:var(--surface-2,var(--panel-2,#f7f9fb));border:1px solid var(--line,#e5e7eb);border-radius:6px}

/* ---- Modals: ONE mechanism for both dialogs (was 3 mechanisms with
   z-index split 210 vs 1000 across themes). Theme files keep only the
   backdrop skin + dialog box styling. ---- */
.payment-modal,.inquiry-modal{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(10,16,30,.55);opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--tr,.2s ease),visibility var(--tr,.2s ease)}
.payment-modal.open,.inquiry-modal.open{opacity:1;visibility:visible;pointer-events:auto}

/* ---- Payment form: invalid-field ring; stack the expiry/CVC row on
   narrow screens ---- */
.payment-form input.is-invalid{border-color:#dc2626;box-shadow:0 0 0 4px rgba(220,38,38,.12)}
@media(max-width:640px){.card-row{grid-template-columns:1fr}}

/* ---- List toolbar (product index): result count + sort links ---- */
.list-toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem 1rem;margin:0 0 1rem}
.list-count{margin:0;color:var(--mut);font-size:.9rem}
.sort-row{display:flex;flex-wrap:wrap;gap:.4rem}
.sort-opt{display:inline-flex;align-items:center;min-height:36px;padding:0 .8rem;border:1px solid var(--line);border-radius:99px;color:var(--mut);text-decoration:none;font-size:.85rem;transition:border-color var(--tr,.2s ease),color var(--tr,.2s ease)}
.sort-opt:hover{border-color:var(--accent);color:var(--accent)}
.sort-opt.is-active{border-color:var(--accent);color:var(--accent-ink,#fff);background:var(--accent)}

/* ---- Flash deals (deal detail + homepage card + FOMO toast) ----
   Cross-theme structure only; colors speak in semantic vars with fallbacks,
   urgency red (#dc2626) is the one fixed accent by convention. ---- */
.deal-announce{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.4rem .9rem;padding:.55rem 1rem;background:#dc2626;color:#fff;font-weight:800;font-size:.95rem;letter-spacing:.02em;text-align:center}
.deal-announce-sub{font-weight:500;font-size:.85rem;opacity:.92}
.deal-hero{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:clamp(1.5rem,4vw,3rem);align-items:start}
@media(max-width:860px){.deal-hero{grid-template-columns:1fr}}
.deal-pills{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 .6rem}
.deal-status-pill{display:inline-flex;align-items:center;gap:.35rem;padding:.2rem .8rem;border-radius:999px;font-size:.8rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase}
.deal-status-pill.is-live{background:color-mix(in srgb,#dc2626 12%,var(--surface,var(--panel,#fff)));color:#dc2626;border:1px solid color-mix(in srgb,#dc2626 40%,transparent)}
.deal-status-pill.is-live::before{content:"";width:.5em;height:.5em;border-radius:50%;background:#dc2626}
.deal-status-pill.is-ended{background:var(--surface-2,var(--panel-2,#f3f4f6));color:var(--mut,var(--muted,#6b7280));border:1px solid var(--line,#e5e7eb)}
.deal-tagline{margin:.2rem 0 .8rem;color:var(--mut,var(--muted,#6b7280));font-size:1.02rem;line-height:1.5}
.deal-price-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem .9rem;margin:.9rem 0 .2rem}
.price-original{color:var(--mut,var(--muted,#6b7280));font-size:1.1rem}
.price-deal{color:#dc2626;font-size:clamp(1.9rem,4vw,2.6rem);font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.price-normal{font-size:clamp(1.5rem,3vw,2rem);font-weight:800;color:var(--ink,var(--text,#1f2937))}
.price-save-pill{display:inline-flex;align-items:center;padding:.25rem .7rem;border-radius:999px;background:#dc2626;color:#fff;font-size:.85rem;font-weight:800}
.deal-save-line{margin:0 0 .4rem;color:#15803d;font-weight:700;font-size:.95rem}
.deal-ended-note{width:100%;color:var(--mut,var(--muted,#6b7280));font-size:.9rem;font-weight:400}
.deal-countdown{display:inline-flex;align-items:center;gap:.45rem;margin:.6rem 0 .2rem}
.deal-countdown .cd-cell{display:inline-flex;flex-direction:column;align-items:center;min-width:3.4rem;padding:.45rem .3rem .35rem;background:var(--surface,var(--panel,#fff));border:1px solid var(--line,#e5e7eb);border-radius:var(--radius-sm,var(--radius,var(--r,10px)));box-shadow:0 6px 18px -12px rgba(0,0,0,.35)}
.deal-countdown .cd-cell b{font-size:1.35rem;font-weight:800;line-height:1.1;color:var(--ink,var(--text,#1f2937));font-variant-numeric:tabular-nums}
.deal-countdown .cd-cell i{font-style:normal;font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--mut,var(--muted,#6b7280))}
.deal-countdown .cd-sep{font-size:1.3rem;font-weight:800;color:var(--mut,var(--muted,#6b7280))}
.deal-window{margin:.9rem 0 0;color:var(--mut,var(--muted,#6b7280));font-size:.85rem}
.deal-visual .deal-media{position:relative}
.deal-off-badge{position:absolute;top:14px;right:14px;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;width:74px;height:74px;border-radius:50%;background:#dc2626;color:#fff;font-weight:800;font-size:1.15rem;line-height:1;box-shadow:0 10px 24px -8px rgba(220,38,38,.55)}
.deal-off-badge small{font-size:.62rem;font-weight:800;letter-spacing:.1em;margin-top:2px}
.deal-chips{display:flex;flex-wrap:wrap;gap:.5rem;margin:.7rem 0 0}
.chip-stock{color:#15803d;border-color:color-mix(in srgb,#16a34a 35%,transparent)}
.deal-steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin:0;padding:0;list-style:none;counter-reset:deal-step}
@media(max-width:760px){.deal-steps{grid-template-columns:1fr}}
.deal-steps li{position:relative;padding:1.1rem 1.1rem 1rem 3.1rem;background:var(--surface,var(--panel,#fff));border:1px solid var(--line,#e5e7eb);border-radius:var(--radius,var(--r,10px));counter-increment:deal-step}
.deal-steps li::before{content:counter(deal-step);position:absolute;left:1rem;top:1.05rem;display:flex;align-items:center;justify-content:center;width:1.6rem;height:1.6rem;border-radius:50%;background:var(--accent,#4f46e5);color:var(--accent-ink,#fff);font-size:.85rem;font-weight:800}
.deal-steps strong{display:block;margin-bottom:.25rem;color:var(--ink,var(--text,#1f2937))}
.deal-steps p{margin:0;color:var(--mut,var(--muted,#6b7280));font-size:.92rem;line-height:1.5}
.deal-links{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.5rem}
@media(max-width:760px){.deal-links{grid-template-columns:1fr}}
.deal-links-col{background:var(--surface,var(--panel,#fff));border:1px solid var(--line,#e5e7eb);border-radius:var(--radius,var(--r,10px));padding:1.2rem 1.3rem}
.deal-links-col h2{margin-top:0;font-size:1.1rem}
.deal-index-meta{color:var(--mut,var(--muted,#6b7280));font-size:.85rem;margin-left:.5rem}
.deal-index-batch{margin-bottom:1.2rem}
.empty-state-inline{color:var(--mut,var(--muted,#6b7280))}

/* Live→ended switch: deal.js adds .is-expired to <body> when the timer hits
   zero, mirroring what the server renders for an already-expired deal. */
body.is-expired .deal-active-only{display:none!important}
body.is-expired .deal-status-pill.is-live{background:var(--surface-2,var(--panel-2,#f3f4f6));color:var(--mut,var(--muted,#6b7280));border-color:var(--line,#e5e7eb)}
body.is-expired .deal-status-pill.is-live::before{display:none}

/* FOMO toast: bottom-left "X from Y ordered this deal N minutes ago". */
.deal-toast{position:fixed;left:16px;bottom:16px;z-index:var(--z-toast);display:flex;align-items:center;gap:.6rem;max-width:min(92vw,340px);padding:.7rem 1rem;background:var(--surface,var(--panel,#fff));color:var(--ink,var(--text,#1f2937));border:1px solid var(--line,#e5e7eb);border-left:4px solid #dc2626;border-radius:var(--radius,var(--r,10px));box-shadow:0 14px 34px -14px rgba(0,0,0,.35);font-size:.88rem;line-height:1.4;opacity:0;transform:translateY(12px);transition:opacity .25s ease,transform .25s ease}
.deal-toast.is-visible{opacity:1;transform:none}
.deal-toast .deal-toast-dot{flex:none;width:.55rem;height:.55rem;border-radius:50%;background:#dc2626}

/* Homepage flash-deal strip: exactly ONE deal — spider bait + lucky users. */
.flash-deal-strip{padding-top:1.2rem}
.flash-deal-card{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1rem;padding:.8rem 1.1rem;background:var(--surface,var(--panel,#fff));border:1px solid color-mix(in srgb,#dc2626 35%,var(--line,#e5e7eb));border-radius:var(--radius-lg,var(--r-lg,var(--radius,var(--r,12px))));box-shadow:0 12px 30px -18px rgba(220,38,38,.45);text-decoration:none;color:var(--ink,var(--text,#1f2937))}
.flash-deal-card.is-expired{display:none}
.fdc-bolt{font-size:1.5rem;line-height:1}
.fdc-img{width:56px;height:56px;object-fit:cover;border-radius:var(--radius-sm,var(--radius,var(--r,10px)));border:1px solid var(--line,#e5e7eb)}
.fdc-body{display:flex;flex-direction:column;min-width:0;flex:1 1 200px}
.fdc-eyebrow{color:#dc2626;font-size:.75rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase}
.fdc-title{font-size:1rem;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fdc-prices{display:flex;align-items:baseline;gap:.55rem}
.fdc-prices del{color:var(--mut,var(--muted,#6b7280));font-size:.88rem}
.fdc-prices strong{color:#dc2626;font-size:1.2rem;font-weight:800;font-variant-numeric:tabular-nums}
.fdc-cd{font-variant-numeric:tabular-nums;font-weight:800;color:var(--ink,var(--text,#1f2937));background:var(--surface-2,var(--panel-2,#f3f4f6));border:1px solid var(--line,#e5e7eb);border-radius:var(--radius-sm,var(--radius,var(--r,10px)));padding:.35rem .6rem;font-size:.92rem}
.fdc-cta{display:inline-flex;align-items:center;padding:.5rem 1rem;border-radius:999px;background:#dc2626;color:#fff;font-weight:800;font-size:.9rem;white-space:nowrap}
@media(max-width:640px){.flash-deal-card{gap:.6rem}.fdc-cd{order:5}}

/* ---- Print: content only, external URLs expanded, black on white ---- */
@media print{
.site-header,.site-footer,.top-strip,.mobile-inquiry-bar,.payment-modal,.inquiry-modal,.aa-cookies,.skip-link,.site-messages,.nav-toggle{display:none!important}
*,*::before,*::after{background:transparent!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}
body{background:#fff!important}
a[href^="http"]::after{content:" (" attr(href) ")";font-size:.82em;font-weight:400;word-break:break-all}
.rich-content pre{white-space:pre-wrap}
}

/* ---- Reduced motion: single global kill-switch (transition AND
   animation; the old cookies.css copy missed animation) ---- */
@media (prefers-reduced-motion:reduce){
html{scroll-behavior:auto}
*,*::before,*::after{transition:none!important;animation:none!important}
}

/* ---- Homepage product wall: name-only cards ----
   Scoped to .cards-compact, because _card_product.html is shared with the
   product index, category, detail and article pages, which keep full cards.
   The name is clamped to two lines AND reserves both, so every card in the wall
   is the same height and the grid reads as a wall instead of a ragged column. */
.cards-compact .card-body{gap:0;padding:14px 16px 16px}
.cards-compact .product-card .card-body h3{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:.95rem;line-height:1.4;min-height:2.8em}
@media(max-width:640px){
.cards-compact .card-body{padding:12px 13px 14px}
.cards-compact .product-card .card-body h3{font-size:.9rem}
}

/* ---- Rows 3-4 of the wall: deferred layout and paint ----
   content-visibility lets the browser skip layout/paint for cards that are not
   near the viewport. Unlike a JS reveal, the markup ships in the HTML, so
   crawlers and no-JS clients still see all 16 cards and there is nothing to
   flash in. contain-intrinsic-size reserves a plausible box for the first
   paint and `auto` remembers the real one afterwards, so the scrollbar does not
   jump. Browsers without support just render all 16 the old way. */
.card-defer{content-visibility:auto;contain-intrinsic-size:auto 300px}
@media(max-width:960px){.card-defer{contain-intrinsic-size:auto 360px}}
@media(max-width:640px){.card-defer{contain-intrinsic-size:auto 340px}}
