/*
 * ============================================================================
 * tokens.css — Design Token System
 * Retail Store Theme — OCL Consulting
 * ============================================================================
 *
 * This file is the single source of truth for every design decision in the
 * theme. All colors, typography, spacing, shadows, borders, and motion live
 * here as CSS custom properties. No component file should ever contain a raw
 * color value or magic-number spacing value — they reference these tokens.
 *
 * ARCHITECTURE: Three-Tier Token Model
 * ─────────────────────────────────────
 * Tier 1 — Primitive tokens (--_ prefix):
 *   Raw computed values, named by their position in the scale.
 *   Example: --_navy-500: oklch(28% 0.07 240)
 *   NEVER referenced directly in component CSS. Only Tier 2 reads them.
 *
 * Tier 2 — Semantic tokens (--color-*, --space-*, etc.):
 *   Purpose-named aliases that map primitives to roles.
 *   Example: --color-primary: var(--_navy-500)
 *   These are what all component CSS references.
 *
 * Tier 3 — Component tokens (scoped):
 *   Local overrides when a component genuinely needs a one-off value.
 *   Example: .product-badge { --badge-bg: var(--color-sale) }
 *   Rare — most components work with Tier 2 directly.
 *
 * DARK MODE:
 *   Only Tier 2 semantic tokens are overridden in [data-theme="dark"].
 *   Tier 1 primitives never change. Component CSS never changes.
 *   The entire theme repaints by remapping ~25 semantic tokens.
 *
 * HOW TO REBRAND:
 *   Change --h-primary (hue angle) and --h-accent at the top of :root.
 *   Every color in the system — buttons, prices, links, badges — updates.
 *   That is the power of the hue-based system. No hex values to hunt.
 *
 * COLORS: All values use oklch() — the perceptually uniform color space.
 *   oklch(L% C H)  where L = lightness 0–100%, C = chroma 0–0.4, H = hue 0–360
 *   Why not hex/hsl? Because oklch(40% 0.15 240) and oklch(40% 0.15 30) are
 *   actually the same perceived brightness. HSL/hex are not — a yellow at
 *   hsl(60, 50%, 50%) looks far brighter than a blue at the same values.
 *   oklch makes contrast and accessibility calculations predictable.
 *
 * SOURCE: Built from 10 DeepSeek analytical tasks (Session S226, Stage 2).
 *   Color extraction, contrast verification, typography scale math, spacing
 *   system, shadow conversion, transition timing, WooCommerce-specific tokens.
 *
 * @package RetailStoreTheme
 * @version 2.0.0
 * ============================================================================
 */


/* ============================================================================
   @property DECLARATIONS — Makes tokens animatable via CSS transitions
   ============================================================================
   Without @property, CSS transitions on custom properties don't interpolate —
   they just snap from old to new value. With @property, the browser understands
   the type and smoothly animates between values.

   Use cases: theme-switch transitions, hover gradient angle animations,
   animated price/count displays.
   ============================================================================ */

@property --color-primary {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(28% 0.07 240);
}

@property --color-accent {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(62% 0.15 65);
}

@property --color-surface {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(97% 0.005 240);
}

@property --gradient-angle {
  /* Used for animated hero gradient backgrounds */
  syntax: '<angle>';
  inherits: false;
  initial-value: 135deg;
}


/* ============================================================================
   TIER 1 — PRIMITIVE TOKENS
   Raw scale values. Never used directly in component CSS.
   Documented here so the palette is visible in one place.
   ============================================================================ */

:root {

  /* ------------------------------------------------------------------
     Brand Hue Configuration
     Change ONLY these three values to rebrand the entire site.
     Every single color token below recalculates automatically.
     ------------------------------------------------------------------
     Primary hue 240 = navy blue (professional, trustworthy — Irish retail)
     Accent hue 65 = warm amber (action, energy — add-to-cart buttons)
     Secondary hue 145 = success green (in-stock, positive states)
     ------------------------------------------------------------------ */
  --h-primary:   240;   /* Navy blue */
  --h-accent:     65;   /* Warm amber */
  --h-secondary: 145;   /* Success green */

  /* Chroma (saturation) levels
     Retail uses modest chroma — professional look, not garish.
     P3 block below boosts these on wide-gamut displays. */
  --c-vibrant: 0.15;    /* Brand actions, strong UI */
  --c-muted:   0.06;    /* Subtle tints, hover states */
  --c-subtle:  0.01;    /* Near-neutral, surfaces, borders */
  --c-neutral: 0;       /* True grays (no hue) */

  /* Primitive lightness scale — position 50 = mid, 900 = darkest */
  --_l-50:   98%;
  --_l-100:  95%;
  --_l-200:  92%;
  --_l-300:  87%;
  --_l-400:  72%;
  --_l-500:  55%;
  --_l-600:  42%;
  --_l-700:  28%;    /* ← Primary navy lives here */
  --_l-800:  18%;
  --_l-900:  14%;
  --_l-950:  10%;

  /* Navy primitive scale */
  --_navy-50:  oklch(var(--_l-50)  var(--c-subtle)  var(--h-primary));
  --_navy-100: oklch(var(--_l-100) var(--c-muted)   var(--h-primary));
  --_navy-200: oklch(var(--_l-200) var(--c-subtle)  var(--h-primary));
  --_navy-300: oklch(var(--_l-300) var(--c-subtle)  var(--h-primary));
  --_navy-400: oklch(var(--_l-400) var(--c-muted)   var(--h-primary));
  --_navy-500: oklch(var(--_l-600) var(--c-vibrant) var(--h-primary)); /* #2563a8 equivalent */
  --_navy-600: oklch(var(--_l-700) var(--c-vibrant) var(--h-primary)); /* #1a3a5c — primary */
  --_navy-700: oklch(var(--_l-800) var(--c-muted)   var(--h-primary)); /* #0f2237 — dark */
  --_navy-800: oklch(var(--_l-900) var(--c-subtle)  var(--h-primary));
  --_navy-900: oklch(var(--_l-950) var(--c-subtle)  var(--h-primary));

  /* Amber primitive scale */
  --_amber-300: oklch(82% 0.10 var(--h-accent));
  --_amber-400: oklch(70% 0.13 var(--h-accent));   /* #f0a04b hover */
  --_amber-500: oklch(62% 0.15 var(--h-accent));   /* #e8821a — primary accent */
  --_amber-600: oklch(54% 0.15 var(--h-accent));
  --_amber-700: oklch(44% 0.13 var(--h-accent));

  /* Neutral gray scale (zero chroma — no hue cast) */
  --_gray-50:  oklch(var(--_l-50)  var(--c-neutral) 0);
  --_gray-100: oklch(var(--_l-100) var(--c-neutral) 0);
  --_gray-200: oklch(var(--_l-200) var(--c-neutral) 0);
  --_gray-300: oklch(var(--_l-300) var(--c-neutral) 0);
  --_gray-400: oklch(var(--_l-400) var(--c-neutral) 0);
  --_gray-500: oklch(var(--_l-500) var(--c-neutral) 0);
  --_gray-600: oklch(var(--_l-600) var(--c-neutral) 0);
  --_gray-700: oklch(var(--_l-700) var(--c-neutral) 0);
  --_gray-800: oklch(var(--_l-800) var(--c-neutral) 0);
  --_gray-900: oklch(var(--_l-900) var(--c-neutral) 0);

  /* Status primitives — fixed lightness ensures visual harmony
     All status colors are calibrated to similar perceived brightness (~48%)
     so a green badge and a red badge feel equally prominent. */
  --_green-500: oklch(48% 0.14 var(--h-secondary));  /* #2d7a3a success */
  --_red-500:   oklch(45% 0.18 25);                  /* #c0392b error */
  --_orange-500:oklch(50% 0.12 60);                  /* #b35c00 warning */
  --_blue-500:  oklch(52% 0.15 220);                 /* info */

}


/* ============================================================================
   TIER 2 — SEMANTIC TOKENS (Light Mode)
   Purpose-named tokens. These are what all component CSS references.
   All are mapped from Tier 1 primitives above.
   ============================================================================ */

:root {

  /* ------------------------------------------------------------------
     SURFACES
     Background colors for page regions, cards, inputs.
     The slight navy tint on surfaces (vs. pure white) ties everything
     to the brand palette without being visible — subtle coherence.
     ------------------------------------------------------------------ */
  --color-surface:         var(--_navy-50);           /* Main page bg — very slight navy tint */
  --color-surface-alt:     oklch(95% 0.008 240);      /* Alternating sections, sidebar */
  --color-surface-card:    oklch(100% 0 0);           /* Product cards, modals, dropdowns */
  --color-surface-input:   oklch(100% 0 0);           /* Form inputs, search fields */
  --color-surface-overlay: oklch(5% 0.01 240 / 0.7);  /* Modal backdrop overlay */

  /* ------------------------------------------------------------------
     TEXT
     Body text hierarchy. The primary text uses a near-black with
     a barely-perceptible navy tint — warmer than pure #000,
     more refined than neutral #1a1a1a.

     Contrast verification (from DS task):
     --color-text-primary (L≈15%) on white: ~12:1 ✓ WCAG AAA
     --color-text-secondary (L≈55%) on white: ~4.0:1 ✗ WCAG AA body (use only for >18px)
     --color-text-price (L≈28%) on white: ~10.5:1 ✓ WCAG AAA
     ------------------------------------------------------------------ */
  --color-text:           oklch(15% 0.01 240);        /* Primary body text — near-black navy */
  --color-text-muted:     oklch(45% 0.02 240);        /* Secondary: breadcrumbs, metadata, counts */
  --color-text-heading:   oklch(10% 0.01 240);        /* Section headings, product page H1 */
  --color-text-price:     oklch(28% 0.07 240);        /* Current price — primary navy (strong, premium) */
  --color-text-link:      oklch(28% 0.07 240);        /* Inline text links */
  --color-text-on-dark:   oklch(97% 0.005 240);       /* Text on navy header, dark buttons */
  /*
   * WCAG 1.4.3 (Contrast Minimum) — placeholder text must meet 4.5:1 on white.
   * oklch(60% …) = ~2.8:1 — FAILS. Darkened to oklch(52% …) = ~4.6:1 — PASSES.
   * Rationale: CSS Accessibility Guidelines treat placeholder as informational
   * text, not decoration — the 4.5:1 threshold applies.
   */
  --color-text-placeholder: oklch(52% 0.02 240);      /* Form input placeholder text — AA contrast ≥4.5:1 */

  /* ------------------------------------------------------------------
     BRAND — PRIMARY (Navy)
     Used for: header background, price display, main links,
     active nav items, focus rings, secondary CTA buttons.
     ------------------------------------------------------------------ */
  --color-primary:         oklch(28% 0.07 240);       /* #1a3a5c — brand anchor */
  --color-primary-hover:   oklch(42% 0.12 245);       /* #2563a8 — lighter on hover */
  --color-primary-active:  oklch(18% 0.055 238);      /* #0f2237 — darker on press */
  --color-primary-subtle:  oklch(95% 0.008 240);      /* Very light tint for hover backgrounds */

  /* ------------------------------------------------------------------
     BRAND — ACCENT (Amber)
     Used for: Add-to-Cart buttons, primary CTAs, sale badges,
     cart count badge, key highlight elements.

     CONTRAST ALERT: Amber (L≈62%) on white = ~3.0:1.
     This PASSES WCAG AA for large text (≥18px or ≥14px bold) but FAILS
     for small body text. Never use --color-accent for text under 18px.
     Use --color-accent-accessible (darker amber) for small amber text.

     WCAG 1.4.3 audit result (S226 Stage 5): white text on oklch(62% 0.15 65) = 3.26:1.
     This FAILS 3:1 for large text and 4.5:1 for normal text.
     FIX: Buttons now use dark navy text (--color-text-on-accent) instead of white,
     achieving 6.5:1 on amber — PASSES AA for all text sizes.
     See css/components.css .rst-btn-primary for the text-color application.
     ------------------------------------------------------------------ */
  --color-accent:          oklch(62% 0.15 65);        /* #e8821a — CTA amber */
  --color-accent-hover:    oklch(54% 0.15 65);        /* Darker amber on hover */
  --color-accent-active:   oklch(44% 0.13 65);        /* Pressed state */
  --color-accent-subtle:   oklch(95% 0.05 65);        /* Light amber tint for sale backgrounds */
  --color-accent-accessible: oklch(44% 0.13 65);      /* AA-compliant amber for small text labels */
  /*
   * WCAG 1.4.3: dark navy text on amber = ~6.5:1 — PASSES AAA.
   * Use this on all amber (.rst-btn-primary) button text instead of white,
   * because white-on-amber = 3.26:1 which fails WCAG AA entirely.
   */
  --color-text-on-accent:  oklch(15% 0.01 240);       /* Dark navy text ON amber backgrounds — AAA contrast */

  /* ------------------------------------------------------------------
     WOOCOMMERCE — PRODUCT PRICING
     Separate from text tokens because pricing is a distinct semantic zone
     in retail. Price display is the most important UX element on a
     product page — it gets its own tokens.
     ------------------------------------------------------------------ */
  --color-price:           oklch(28% 0.07 240);       /* Current price — same as primary, strong */
  --color-price-sale:      oklch(45% 0.18 25);        /* Sale/reduced price — red (urgency) */
  /*
   * WCAG 1.4.3: oklch(55% …) on white = ~3.4:1 — FAILS 4.5:1 for normal text.
   * The crossed-out price is informational (screen readers announce it), so it
   * must meet the 4.5:1 threshold. Darkened to oklch(42% …) = ~5.8:1 — PASSES.
   */
  --color-price-regular:   oklch(42% 0.02 240);       /* Crossed-out original price — WCAG AA ≥4.5:1 */
  --color-price-label:     oklch(50% 0.02 240);       /* "Was:" / "Now:" labels */

  /* ------------------------------------------------------------------
     WOOCOMMERCE — STOCK STATUS
     Consistent lightness (~50%) across all three states ensures a
     green badge and a red badge are perceived as equally prominent.
     Only the hue changes — not the visual weight.
     ------------------------------------------------------------------ */
  --color-stock-in:        oklch(48% 0.14 145);       /* In stock — green */
  --color-stock-low:       oklch(50% 0.12 60);        /* Low stock / last few — amber */
  --color-stock-out:       oklch(45% 0.18 25);        /* Out of stock — red */
  --color-stock-backorder: oklch(48% 0.12 220);       /* On backorder — blue */

  /* Background tints for stock badges */
  --color-stock-in-bg:     oklch(96% 0.04 145);       /* dcfce7 equivalent */
  --color-stock-low-bg:    oklch(96% 0.04 65);        /* Light amber tint */
  --color-stock-out-bg:    oklch(96% 0.04 25);        /* fee2e2 equivalent */

  /* ------------------------------------------------------------------
     WOOCOMMERCE — RATINGS & REVIEWS
     Amber star ratings use a slightly warmer hue than the CTA amber
     to visually separate the two uses of orange/yellow.
     ------------------------------------------------------------------ */
  --color-rating:          oklch(75% 0.18 80);        /* Filled star — golden amber */
  --color-rating-empty:    oklch(85% 0.02 240);       /* Empty star outline */
  --color-verified:        oklch(48% 0.14 145);       /* Verified purchase badge */

  /* ------------------------------------------------------------------
     STATUS SYSTEM
     Used for: WooCommerce notices, form validation, order tracking.
     Each status has both a foreground color and a background tint.
     The consistent ~50% lightness for foreground colors ensures
     all four status types feel equally prominent.
     ------------------------------------------------------------------ */
  --color-success:         oklch(48% 0.14 145);       /* #2d7a3a */
  --color-success-bg:      oklch(96% 0.04 145);       /* d4edda equivalent */
  --color-warning:         oklch(50% 0.12 60);        /* #b35c00 */
  --color-warning-bg:      oklch(96% 0.05 65);        /* Warm tint */
  --color-error:           oklch(45% 0.18 25);        /* #c0392b */
  --color-error-bg:        oklch(96% 0.04 25);        /* f8d7da equivalent */
  --color-info:            oklch(52% 0.15 220);
  --color-info-bg:         oklch(96% 0.04 220);

  /* Order status badges (customer portal) */
  --color-status-processing: oklch(52% 0.15 220);     /* Blue */
  --color-status-completed:  oklch(48% 0.14 145);     /* Green */
  --color-status-pending:    oklch(50% 0.12 60);      /* Amber */
  --color-status-on-hold:    oklch(48% 0.14 280);     /* Purple */
  --color-status-cancelled:  oklch(45% 0.12 25);      /* Red-muted */
  --color-status-refunded:   oklch(55% 0.02 240);     /* Neutral */
  --color-status-failed:     oklch(45% 0.18 25);      /* Red */

  /* ------------------------------------------------------------------
     BORDERS
     Borders use the primary hue at low chroma and high lightness —
     they feel like they belong to the brand without competing with content.
     ------------------------------------------------------------------ */
  --color-border:           oklch(88% 0.005 240);     /* Default dividers, card edges */
  --color-border-strong:    oklch(75% 0.008 240);     /* Input fields, table borders */
  --color-border-focus:     var(--color-primary);     /* Focus ring — full navy weight */
  --color-border-error:     var(--color-error);       /* Invalid input fields */
  --color-border-brand:     var(--color-primary);     /* Branded accents (footer widget headings) */

  /* ------------------------------------------------------------------
     INTERACTIVE STATES
     These tokens define how surfaces respond to interaction.
     Used for: nav link hovers, card hover overlays, selected items.
     ------------------------------------------------------------------ */
  --color-hover-bg:         oklch(95% 0.008 240);     /* Subtle hover on nav, table rows */
  --color-active-bg:        oklch(90% 0.02 240);      /* Active/selected items */
  --color-selected-bg:      oklch(92% 0.04 240);      /* Highlighted/checked items */

  /* ------------------------------------------------------------------
     SHADOWS
     All shadows use oklch(0% 0 0 / alpha) — equivalent to rgba(0,0,0,alpha)
     but expressed in the oklch space. On dark mode, shadows are overridden
     to be more pronounced (dark-on-dark needs stronger depth cues).

     The 'xs' shadow is for form inputs — too subtle for cards but gives
     depth to input fields. The 'xl' is for modals and drawers.
     ------------------------------------------------------------------ */
  --shadow-xs: 0 1px 2px oklch(0% 0 0 / 0.06);
  --shadow-sm: 0 1px 3px oklch(0% 0 0 / 0.08),
               0 1px 2px oklch(0% 0 0 / 0.06);
  --shadow-md: 0 4px 6px oklch(0% 0 0 / 0.07),
               0 2px 4px oklch(0% 0 0 / 0.06);
  --shadow-lg: 0 10px 15px oklch(0% 0 0 / 0.10),
               0 4px 6px oklch(0% 0 0 / 0.05);
  --shadow-xl: 0 20px 25px oklch(0% 0 0 / 0.12),
               0 10px 10px oklch(0% 0 0 / 0.04);
  --shadow-focus: 0 0 0 3px oklch(28% 0.07 240 / 0.20); /* Focus ring glow — navy at 20% */

}


/* ============================================================================
   FLUID TYPE SCALE
   Major Third ratio (1.25x), viewport range 375px → 1440px.
   Formula: clamp(min, preferred, max)
   Where: preferred = fluid midpoint using vw units.

   WHY FLUID TYPE? Static px sizes jump at breakpoints, causing jarring
   layout shifts. Fluid sizes scale smoothly with the viewport —
   the heading on a 400px phone is readable, the same heading on a
   1400px desktop is impactful, no manual overrides needed.

   The retail context uses these steps differently from an editorial site:
   - Large steps (5,6): Hero headlines, sale promotions
   - Medium steps (3,4): Section headings, product page title
   - Small steps (1,2): Product card titles, subheadings
   - Base (0,-1): Prices, descriptions, UI
   - Tiny (-2): Badges, labels, meta
   ============================================================================ */

:root {

  /* Fluid type scale — do not use these step names in component CSS;
     use the retail-semantic aliases below instead */
  --step--2: clamp(0.694rem, 0.668rem + 0.13vw, 0.800rem);  /* ≈ 11–13px */
  --step--1: clamp(0.833rem, 0.784rem + 0.25vw, 1.000rem);  /* ≈ 13–16px */
  --step-0:  clamp(1.000rem, 0.913rem + 0.43vw, 1.250rem);  /* ≈ 16–20px  BASE */
  --step-1:  clamp(1.200rem, 1.048rem + 0.76vw, 1.563rem);  /* ≈ 19–25px */
  --step-2:  clamp(1.440rem, 1.185rem + 1.27vw, 1.953rem);  /* ≈ 23–31px */
  --step-3:  clamp(1.728rem, 1.317rem + 2.06vw, 2.441rem);  /* ≈ 28–39px */
  --step-4:  clamp(2.074rem, 1.436rem + 3.19vw, 3.052rem);  /* ≈ 33–49px */
  --step-5:  clamp(2.488rem, 1.534rem + 4.77vw, 3.815rem);  /* ≈ 40–61px */
  --step-6:  clamp(2.986rem, 1.588rem + 6.99vw, 4.768rem);  /* ≈ 48–76px */

  /* ------------------------------------------------------------------
     RETAIL SEMANTIC TYPE ALIASES
     Components reference these names, not the raw step numbers.
     This makes intent clear and allows remapping without touching components.
     ------------------------------------------------------------------ */

  /* Product pricing — the most important text on the page */
  --font-price-hero:    var(--step-4);  /* Big price on single product page */
  --font-price-card:    var(--step-1);  /* Price on product grid card */

  /* Product titles */
  --font-product-title-page: var(--step-4);  /* H1 on single product page */
  --font-product-title-card: var(--step-0);  /* Product name on grid card */

  /* Page structure */
  --font-section-heading: var(--step-3);  /* Homepage section headings */
  --font-page-heading:    var(--step-5);  /* Main page H1 (Shop, My Account) */
  --font-hero-heading:    var(--step-6);  /* Hero/promotional headlines */

  /* UI chrome */
  --font-nav:    var(--step--1);          /* Navigation links */
  --font-meta:   var(--step--1);          /* Breadcrumbs, counts, helper text */
  --font-button: var(--step-0);           /* CTA button labels */
  --font-badge:  var(--step--2);          /* SALE, NEW, IN STOCK badges */
  --font-label:  var(--step--2);          /* Form field labels */
  --font-caption:var(--step--1);          /* Figure captions, legal text */

  /* ------------------------------------------------------------------
     FONT FAMILIES
     Fraunces: Variable serif for display headings. Adds character and
       editorial quality to section headers and product hero titles.
       Its optical size axis makes it highly legible at all scales.
       Best used at H1-H3 level. Below 20px it loses its distinctiveness.

     Inter: Variable sans-serif for all UI. Product names on cards,
       prices, buttons, nav, meta text. Optimised for on-screen legibility
       at small sizes — exactly what retail product cards demand.

     Source Serif 4: Optional serif for long product descriptions.
       The standard recommends serif for extended reading. Only activated
       on single product pages with >200 word descriptions.

     System fallbacks use metric-matched @font-face declarations (see
     functions.php for the preload links and enqueue order).
     ------------------------------------------------------------------ */
  --font-display: 'Fraunces', 'Fraunces Fallback', Georgia, 'Times New Roman', serif;
  --font-sans:    'Inter', 'Inter Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-serif:   'Source Serif 4', 'Source Serif 4 Fallback', Georgia, serif;
  --font-mono:    'JetBrains Mono', 'Cascadia Code', 'Fira Code', 'Courier New', monospace;

  /* ------------------------------------------------------------------
     FONT WEIGHTS
     Variable fonts support 100–900. Named tokens make intent legible.
     ------------------------------------------------------------------ */
  --font-weight-thin:       100;
  --font-weight-light:      300;
  --font-weight-regular:    400;
  --font-weight-medium:     500;
  --font-weight-semibold:   600;
  --font-weight-bold:       700;
  --font-weight-extrabold:  800;

  /* ------------------------------------------------------------------
     LINE HEIGHTS
     Retail type has different reading contexts than editorial:
     - Tight: headings, badges (multi-line headings look bad with loose lh)
     - Snug: product card titles (often truncated at 2 lines)
     - Normal: UI text, navigation
     - Relaxed: product descriptions, long-form content
     ------------------------------------------------------------------ */
  --line-height-tight:    1.1;   /* H1, H2 — prevent double-line heading gaps */
  --line-height-snug:     1.25;  /* Product card titles — 2-line max */
  --line-height-normal:   1.5;   /* UI text, navigation, prices */
  --line-height-relaxed:  1.65;  /* Product descriptions */
  --line-height-loose:    1.75;  /* Long-form, fine print, legal */

  /* ------------------------------------------------------------------
     LETTER SPACING
     Tight for prices (premium feeling), slightly tracked for all-caps
     labels (required for readability — all-caps at 0 tracking is a sin),
     slight negative for large display headings (Fraunces looks better
     slightly tighter at large sizes).
     ------------------------------------------------------------------ */
  --letter-spacing-display:  -0.01em;  /* Fraunces headings — tighter at large sizes */
  --letter-spacing-heading:   0;        /* Mid-size headings — neutral */
  --letter-spacing-body:      0;        /* Body text */
  --letter-spacing-ui:       +0.01em;  /* Nav links, button text */
  --letter-spacing-price:    -0.02em;  /* Prices — tighter tracking = more premium */
  --letter-spacing-badge:    +0.06em;  /* ALL-CAPS badges — must track for legibility */
  --letter-spacing-meta:     +0.02em;  /* Breadcrumbs, labels */

  /* Fraunces optical-size settings for heading levels */
  --font-variation-h1: 'opsz' 72, 'wght' 700;   /* Large display — high opsz = decorative */
  --font-variation-h2: 'opsz' 48, 'wght' 650;   /* Section level */
  --font-variation-h3: 'opsz' 28, 'wght' 600;   /* Sub-section level */

}


/* ============================================================================
   SPACING SCALE
   8px base unit. Named tokens, not numeric.

   WHY NAMED? "--space-md" communicates intent. "--space-4" just communicates
   position in a scale. When two designers debate whether a gap is "sm" or
   "md", they're talking about the design intent. When they debate whether
   it's "space-3" vs "space-4", they're doing arithmetic.

   FIXED vs FLUID:
   Fixed spacing (--space-xs through --space-3xl) is used inside components
   where consistent geometry matters: padding inside a button, gap between
   icon and label, margin-bottom on a card heading.

   Fluid spacing (--space-section-*, --space-gap) scales with the viewport
   and is used for outer layout: section vertical padding, container
   horizontal padding, card grid gap. These use clamp() so they breathe
   naturally from mobile to desktop without breakpoint overrides.
   ============================================================================ */

:root {

  /* Fixed spacing — component-level */
  --space-2xs:  0.25rem;   /*  4px — icon gap, tight padding */
  --space-xs:   0.5rem;    /*  8px — inline padding, small gaps */
  --space-sm:   0.75rem;   /* 12px — button padding, form field gaps */
  --space-md:   1rem;      /* 16px — base unit, card padding */
  --space-lg:   1.5rem;    /* 24px — section element spacing */
  --space-xl:   2rem;      /* 32px — generous padding, large gaps */
  --space-2xl:  3rem;      /* 48px — section-level spacing (mobile) */
  --space-3xl:  4rem;      /* 64px — section-level spacing (desktop) */
  --space-4xl:  5rem;      /* 80px — hero-level top/bottom padding */

  /* Fluid spacing — layout-level (scales with viewport) */
  --space-section-y:   clamp(3rem, 6vw, 6rem);         /* Section vertical padding: 48–96px */
  --space-section-x:   clamp(1rem, 4vw, 2.5rem);       /* Container horizontal padding: 16–40px */
  --space-gap:         clamp(1rem, 2.5vw, 1.5rem);     /* Card grid gap: 16–24px */
  --space-gap-wide:    clamp(1.5rem, 4vw, 3rem);       /* Generous grid gap for hero sections */

  /* Semantic spacing aliases — communicates use, not just size */
  --space-inset:       var(--space-md);    /* Standard padding inside components */
  --space-stack:       var(--space-md);    /* Vertical spacing between elements */
  --space-inline:      var(--space-sm);   /* Horizontal spacing between inline elements */

}


/* ============================================================================
   BORDER RADII
   Conservative radii for retail — slightly rounded corners communicate
   approachability without the softness of consumer apps. Square corners
   (radius 0) feel too utilitarian; pill buttons (radius 9999px) feel
   too casual for a multi-department retail chain.

   The scale uses rem (not px) so it scales proportionally with font size.
   ============================================================================ */

:root {

  --radius-xs:   0.125rem;   /*  2px — barely visible, tight badges */
  --radius-sm:   0.25rem;    /*  4px — table cells, compact badges */
  --radius-md:   0.5rem;     /*  8px — cards, buttons, inputs (default) */
  --radius-lg:   0.75rem;    /* 12px — larger cards, modals */
  --radius-xl:   1rem;       /* 16px — feature cards, hero elements */
  --radius-2xl:  1.5rem;     /* 24px — promotional banners */
  --radius-full: 9999px;     /* Pills — cart count, service tags, nav CTA */

}


/* ============================================================================
   Z-INDEX SCALE
   WooCommerce has its own stacking contexts (minicart drawer, product
   quick-view, cookie notice). This scale ensures predictable layering.

   Important: always use these tokens in component CSS.
   Never hardcode z-index values — they become unmaintainable.
   ============================================================================ */

:root {

  --z-below:    -1;    /* Behind-the-page decorative elements */
  --z-base:      0;    /* Default stacking context */
  --z-raised:   10;    /* Cards on hover, inline badges */
  --z-sticky:   20;    /* Sticky header, sticky sidebar */
  --z-drawer:   30;    /* Minicart drawer, mobile nav */
  --z-overlay:  40;    /* Modal backdrop */
  --z-modal:    50;    /* Product quick-view, dialogs */
  --z-toast:    60;    /* Add-to-cart notification, alerts */
  --z-tooltip:  70;    /* Tooltip, dropdown menus */
  --z-cookie:   80;    /* Cookie consent — must be above everything */

}


/* ============================================================================
   MOTION & TRANSITIONS
   The Fancy Sites Standard bans the 'ease' keyword — it uses a generic
   cubic-bezier that feels generic and robot-like at retail interaction speeds.
   Named easing curves communicate the physics of each interaction.

   EASING RATIONALE:
   Standard: most transitions — feels natural, slightly decelerated
   Spring: buttons, interactive elements — slight overshoot signals responsiveness
   Enter: things appearing (modals, drawers, dropdowns) — fast start, ease in
   Exit: things disappearing — ease out, exits faster than entries
   Snappy: menus, dropdowns — brief, decisive
   ============================================================================ */

:root {

  /* Duration scale — from instant feedback to atmospheric transitions */
  --duration-instant:      50ms;    /* Toggle states, active press feedback */
  --duration-fast:        150ms;    /* Hover states, tooltip appear */
  --duration-normal:      300ms;    /* Modal open/close, drawer, page entry */
  --duration-slow:        500ms;    /* Hero reveals, page transitions */
  --duration-atmospheric: 800ms;    /* Ambient animations (gradient, parallax) */

  /* Easing curves — no 'ease', 'linear', or 'ease-in-out' keywords */
  --easing-standard: cubic-bezier(0.4, 0, 0.2, 1);        /* Natural deceleration — default */
  --easing-spring:   cubic-bezier(0.34, 1.56, 0.64, 1);   /* Overshoot — button click, badge pop */
  --easing-enter:    cubic-bezier(0.0, 0.0, 0.2, 1);      /* Element arriving — modal, drawer */
  --easing-exit:     cubic-bezier(0.4, 0.0, 1, 1);        /* Element leaving — faster than entry */
  --easing-snappy:   cubic-bezier(0.2, 0, 0, 1);          /* Menus, selects — decisive */

  /* Semantic transition shortcuts — for common multi-property patterns */
  --transition-default:  var(--duration-normal) var(--easing-standard);
  --transition-hover:    var(--duration-fast)   var(--easing-standard);
  --transition-enter:    var(--duration-normal) var(--easing-enter);
  --transition-exit:     var(--duration-fast)   var(--easing-exit);
  --transition-spring:   var(--duration-normal) var(--easing-spring);

}


/* ============================================================================
   LAYOUT TOKENS
   Container widths, grid configuration, breakpoint references.

   Note: CSS custom properties cannot be used inside @media queries
   (e.g., @media (min-width: var(--bp-md)) does NOT work).
   These breakpoint tokens are documentation + for use in CSS calc(),
   not for use inside @media rules directly.

   The container padding uses clamp() — it scales from 1rem on mobile
   to 2.5rem on desktop, eliminating the need for padding media queries.
   ============================================================================ */

:root {

  /* Breakpoint reference values (use in clamp() calc, not in @media) */
  --bp-sm:   480px;
  --bp-md:   768px;
  --bp-lg:  1024px;
  --bp-xl:  1280px;
  --bp-2xl: 1536px;

  /* Container widths */
  --container-default:  75rem;   /* 1200px — main content area */
  --container-wide:     90rem;   /* 1440px — full-bleed sections */
  --container-narrow:   50rem;   /* 800px — product description text */
  --container-padding:  clamp(1rem, 4vw, 2.5rem);  /* Fluid horizontal padding */

  /* Product grid — WooCommerce product list configuration */
  --product-grid-min-card: 240px;   /* Minimum product card width (auto-fit) */
  --product-card-img-height: 220px; /* Fixed image height for visual consistency */

}


/* ============================================================================
   P3 WIDE GAMUT ENHANCEMENT
   Modern displays (Apple, Samsung OLED, many 2023+ monitors) support
   Display P3 — a color gamut ~35% wider than sRGB. The amber accent and
   success green particularly benefit from P3's extended red-green range.

   Why only boost accent and status — not the primary navy?
   The navy is intentionally desaturated (professional, trustworthy).
   Boosting its chroma on P3 would make it vivid at the expense of that
   brand signal. Amber and green benefit from vibrance; navy does not.
   ============================================================================ */

@supports (color: oklch(50% 0.3 260)) and (color-gamut: p3) {
  :root {
    /* Boost accent amber on P3 — add-to-cart buttons are more vibrant */
    --color-accent:          oklch(62% 0.22 65);
    --color-accent-hover:    oklch(54% 0.22 65);

    /* Boost success/error status on P3 — stock badges pop harder */
    --color-stock-in:        oklch(48% 0.20 145);
    --color-stock-out:       oklch(45% 0.25 25);
    --color-rating:          oklch(75% 0.25 80);

    /* Slight chroma increase for primary on P3 — barely visible but cohesive */
    --c-vibrant: 0.18;
    --c-muted:   0.08;
  }
}


/* ============================================================================
   DARK MODE OVERRIDES
   Only semantic tokens change. Tier 1 primitives stay constant.
   Component CSS never changes — the entire theme repaints by remapping
   these ~30 semantic tokens.

   THE RULES (from the Fancy Sites Standard):
   - Never pure black background — minimum oklch(12% 0.01 240)
   - Never pure white text — maximum oklch(92% 0.002 240)
   - Extended reading target: 8.0–9.5:1 contrast ratio
   - Warm accents are mandatory on dark (cool blue accents recede visually)
   - Border subtlety: very fine borders, nothing harsh

   HALATION COMPENSATION (dark mode typography):
   Light text on dark backgrounds appears to 'bloom' outward — characters
   look heavier and slightly blurry. Compensation: reduce font-weight by
   ~50 units, add letter-spacing: 0.02em, use antialiased font-smoothing.
   These are applied to body/heading elements (not in this token file —
   they go in the base typography layer).

   Flash prevention: the inline script in <head> (see functions.php)
   reads localStorage and sets data-theme="dark" before CSS loads,
   preventing a white flash on dark mode page loads.
   ============================================================================ */

[data-theme="dark"] {

  color-scheme: dark;  /* Tells the browser: native UI (scrollbars, inputs) should be dark */

  /* Surfaces — never pure black */
  --color-surface:         oklch(14% 0.008 240);    /* Page background — near #1a1a28 */
  --color-surface-alt:     oklch(18% 0.012 240);    /* Alternating section */
  --color-surface-card:    oklch(20% 0.015 240);    /* Product cards */
  --color-surface-input:   oklch(22% 0.015 240);    /* Form inputs */
  --color-surface-overlay: oklch(5% 0.01 240 / 0.8); /* Modal backdrop — deeper */

  /* Text — never pure white */
  --color-text:           oklch(88% 0.008 240);    /* Body text — ≈ #D8D8E4 — ~11:1 contrast */
  --color-text-muted:     oklch(65% 0.01 240);     /* Secondary text */
  --color-text-heading:   oklch(94% 0.004 240);    /* Headings — ≈ #EEEEF6 — ~15:1 contrast */
  --color-text-price:     oklch(82% 0.08 240);     /* Prices in dark — lighter navy derivative */
  --color-text-link:      oklch(72% 0.12 240);     /* Links — lightened primary for dark bg */
  --color-text-placeholder: oklch(50% 0.02 240);   /* Inputs placeholder */

  /* Primary on dark — lighten so navy is visible on dark background */
  --color-primary:         oklch(65% 0.12 240);    /* Navy → lighter on dark for visibility */
  --color-primary-hover:   oklch(72% 0.12 240);
  --color-primary-subtle:  oklch(25% 0.04 240);    /* Subtle hover bg on dark */

  /* Accent amber on dark — MANDATORY bright/warm accent (dark mode standard)
     Cool blues recede on dark backgrounds; warm ambers advance.
     Increase lightness and chroma for dark mode legibility. */
  --color-accent:          oklch(70% 0.18 65);     /* Brighter amber for dark */
  --color-accent-hover:    oklch(76% 0.18 65);
  --color-accent-subtle:   oklch(25% 0.06 65);     /* Dark amber tint background */

  /* Borders — very subtle on dark */
  --color-border:           oklch(28% 0.008 240);
  --color-border-strong:    oklch(38% 0.01 240);
  --color-border-focus:     oklch(65% 0.12 240);   /* Lightened primary on dark */

  /* Shadows — more pronounced on dark (light-on-dark needs stronger depth cues) */
  --shadow-sm: 0 1px 3px oklch(0% 0 0 / 0.35),
               0 1px 2px oklch(0% 0 0 / 0.25);
  --shadow-md: 0 4px 6px oklch(0% 0 0 / 0.40),
               0 2px 4px oklch(0% 0 0 / 0.30);
  --shadow-xl: 0 20px 25px oklch(0% 0 0 / 0.45),
               0 10px 10px oklch(0% 0 0 / 0.30);

  /* Rating stars — slightly warmer on dark */
  --color-rating:          oklch(78% 0.20 80);

  /* Status adjustments — boost luminance slightly for dark backgrounds */
  --color-success:         oklch(56% 0.16 145);
  --color-error:           oklch(55% 0.20 25);
  --color-warning:         oklch(60% 0.14 60);
  --color-stock-in:        oklch(56% 0.16 145);
  --color-stock-out:       oklch(55% 0.20 25);
}

/* Auto dark mode from system preference (before user has manually toggled) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --color-surface:         oklch(14% 0.008 240);
    --color-surface-alt:     oklch(18% 0.012 240);
    --color-surface-card:    oklch(20% 0.015 240);
    --color-surface-input:   oklch(22% 0.015 240);
    --color-text:            oklch(88% 0.008 240);
    --color-text-muted:      oklch(65% 0.01 240);
    --color-text-heading:    oklch(94% 0.004 240);
    --color-text-price:      oklch(82% 0.08 240);
    --color-text-link:       oklch(72% 0.12 240);
    --color-primary:         oklch(65% 0.12 240);
    --color-primary-hover:   oklch(72% 0.12 240);
    --color-accent:          oklch(70% 0.18 65);
    --color-accent-hover:    oklch(76% 0.18 65);
    --color-border:          oklch(28% 0.008 240);
    --color-border-strong:   oklch(38% 0.01 240);
  }
}


/* ============================================================================
   REDUCED MOTION — Accessibility
   Vestibular disorders affect ~15% of people. Sudden motion — scrolljack,
   parallax, bounce animations — can cause nausea and disorientation.
   This block disables ALL non-essential motion for users who have
   enabled the OS accessibility setting.

   Note: This is NOT about removing delight — it's about medical necessity.
   The @media block ensures the site remains fully functional;
   state transitions just happen instantly instead of animating.
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:       0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration:      0.001ms !important;
    scroll-behavior:          auto !important;
  }
}


/* ============================================================================
   SMOOTH THEME TRANSITIONS
   When the user toggles dark mode, backgrounds and borders cross-fade
   instead of snapping. Text transitions are shorter than backgrounds —
   text should feel responsive; surface repaints can breathe.

   The .no-transition class is applied by the flash-prevention script
   on initial page load (see functions.php), then removed after first
   paint. This prevents a transition from light-to-dark firing on load.
   ============================================================================ */

*,
*::before,
*::after {
  transition:
    background-color 300ms var(--easing-standard),
    border-color     250ms var(--easing-standard),
    color            150ms var(--easing-standard),
    box-shadow       300ms var(--easing-standard);
}

/* Disable during initial page load — prevents flash */
.no-transition *,
.no-transition *::before,
.no-transition *::after {
  transition: none !important;
}
