/* ==========================================================================
   ADVENNO DESIGN SYSTEM — Phase 3a (tokens only)
   ==========================================================================
   This file defines design tokens. It does NOT contain any component or
   layout rules — those land in Phase 3b/c/d as each cluster cleanup ships.

   Loaded AFTER bundle.min.css. Because the new token names here do not
   collide with the old ones in bundle.min.css (e.g. --color-accent vs
   --accent-cyan), nothing visible changes during Phase 3a. The tokens are
   defined and ready for Phase 3b/4 components to consume.

   Rules of this file:
     - No `!important` is allowed (except the prefers-reduced-motion guard
       which already lives in head.php critical CSS).
     - No element selectors — only :root, [data-theme="..."], @media.
     - No component classes — those come later.

   Decisions reference: project_advenno_design_system_decisions.md (memory).
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. ROOT — DARK THEME DEFAULT + ALL THEME-INDEPENDENT TOKENS
   -------------------------------------------------------------------------- */
:root {

  /* ---- Surfaces ---- */
  --color-bg:             #0A0E1A;
  --color-surface-1:      #11162A;
  --color-surface-2:      #181F37;
  --color-surface-3:      #1F2744;

  /* ---- Borders ---- */
  --color-border-subtle:  rgba(255, 255, 255, 0.06);
  --color-border-default: rgba(255, 255, 255, 0.12);
  --color-border-strong:  rgba(255, 255, 255, 0.22);

  /* ---- Text ---- */
  --color-text-primary:   #E5E7EB;
  --color-text-secondary: #9CA3AF;
  --color-text-muted:     #6B7280;
  --color-text-inverse:   #0F172A;

  /* ---- Accent (teal + emerald) ---- */
  --color-accent:           #14B8A6;
  --color-accent-hover:     #0D9488;
  --color-accent-subtle:    rgba(20, 184, 166, 0.10);
  --color-accent-secondary: #34D399;

  /* ---- Status ---- */
  --color-success: #22C55E;
  --color-warning: #F59E0B;
  --color-error:   #EF4444;

  /* ---- Structural shadows (dark — higher alpha for legibility on dark bg) ---- */
  --shadow-xs: 0 1px 2px  rgba(0, 0, 0, 0.40);
  --shadow-sm: 0 2px 4px  rgba(0, 0, 0, 0.35), 0 1px 2px  rgba(0, 0, 0, 0.30);
  --shadow-md: 0 4px 8px  rgba(0, 0, 0, 0.40), 0 2px 4px  rgba(0, 0, 0, 0.30);
  --shadow-lg: 0 16px 32px rgba(0, 0, 0, 0.45), 0 4px 8px  rgba(0, 0, 0, 0.35);
  --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.50), 0 8px 16px rgba(0, 0, 0, 0.40);

  /* ---- Accent glow — ONE element per page maximum (e.g. hero primary CTA) ---- */
  --shadow-accent-glow: 0 0 32px rgba(20, 184, 166, 0.30);


  /* ====================================================================
     THEME-INDEPENDENT TOKENS BELOW — declared once, never overridden
     ==================================================================== */

  /* ---- Typography: font families ---- */
  --font-display: 'Space Grotesk', system-ui, -apple-system, sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;

  /* ---- Typography: type scale (fluid, clamp-based) ---- */
  --text-display-xl: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);     /* 40 - 72  px */
  --text-display-lg: clamp(2rem,   1.4rem + 2.8vw, 3.5rem);   /* 32 - 56  px */
  --text-h1:         clamp(1.75rem, 1.3rem + 2vw,   2.5rem);  /* 28 - 40  px */
  --text-h2:         clamp(1.5rem,  1.2rem + 1.4vw, 2rem);    /* 24 - 32  px */
  --text-h3:         clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);  /* 20 - 24  px */
  --text-h4:         1.125rem;                                /* 18       px */
  --text-body-lg:    1.125rem;                                /* 18       px */
  --text-body:       1rem;                                    /* 16       px */
  --text-body-sm:    0.9375rem;                               /* 15       px */
  --text-caption:    0.8125rem;                               /* 13       px */
  --text-mono:       0.875rem;                                /* 14       px */

  /* ---- Spacing scale (4-px geometric grid) ---- */
  --space-0:  0;
  --space-1:  0.25rem;   /*   4 px */
  --space-2:  0.5rem;    /*   8 px */
  --space-3:  0.75rem;   /*  12 px */
  --space-4:  1rem;      /*  16 px */
  --space-5:  1.5rem;    /*  24 px */
  --space-6:  2rem;      /*  32 px */
  --space-7:  3rem;      /*  48 px */
  --space-8:  4rem;      /*  64 px */
  --space-9:  6rem;      /*  96 px */
  --space-10: 8rem;      /* 128 px */

  /* ---- Container widths ---- */
  --container-sm:  640px;
  --container-md:  768px;
  --container-lg:  1024px;
  --container-xl:  1280px;
  --container-2xl: 1400px;

  /* ---- Radius scale ---- */
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   16px;
  --radius-xl:   24px;
  --radius-pill: 9999px;

  /* ---- Motion: durations ---- */
  --duration-instant: 100ms;
  --duration-fast:    150ms;
  --duration-normal:  200ms;
  --duration-slow:    400ms;
  --duration-theme:   300ms;

  /* ---- Motion: easings ---- */
  --ease-out:    cubic-bezier(0.2, 0.8, 0.2, 1);   /* default for entry, hover, reveal */
  --ease-in:     cubic-bezier(0.4, 0, 1, 1);       /* exits only                       */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);     /* theme switch, layout recovery    */
  --ease-linear: linear;                            /* opacity / color shifts           */
}


/* --------------------------------------------------------------------------
   2. LIGHT THEME — system preference (no JS, or JS hasn't set data-theme yet)
   --------------------------------------------------------------------------
   This block fires for visitors whose OS is set to light AND who have no
   explicit `data-theme` attribute on <html>. The pre-paint script in
   includes/head.php normally sets data-theme to either "light" or "dark"
   from localStorage or matchMedia — but if JS is disabled or the script
   hasn't run yet, this @media block still honours system preference.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: light) {
  :root {
    --color-bg:             #FFFFFF;
    --color-surface-1:      #F8FAFC;
    --color-surface-2:      #F1F5F9;
    --color-surface-3:      #E2E8F0;

    --color-border-subtle:  #E2E8F0;
    --color-border-default: #CBD5E1;
    --color-border-strong:  #94A3B8;

    --color-text-primary:   #0F172A;
    --color-text-secondary: #475569;
    --color-text-muted:     #64748B;
    --color-text-inverse:   #FFFFFF;

    --color-accent:           #0D9488;
    --color-accent-hover:     #0F766E;
    --color-accent-subtle:    rgba(13, 148, 136, 0.08);
    --color-accent-secondary: #10B981;

    --shadow-xs: 0 1px 2px  rgba(0, 0, 0, 0.10);
    --shadow-sm: 0 2px 4px  rgba(0, 0, 0, 0.08), 0 1px 2px  rgba(0, 0, 0, 0.06);
    --shadow-md: 0 4px 8px  rgba(0, 0, 0, 0.10), 0 2px 4px  rgba(0, 0, 0, 0.06);
    --shadow-lg: 0 16px 32px rgba(0, 0, 0, 0.12), 0 4px 8px  rgba(0, 0, 0, 0.08);
    --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.14), 0 8px 16px rgba(0, 0, 0, 0.10);

    --shadow-accent-glow: 0 0 24px rgba(13, 148, 136, 0.20);
  }
}


/* --------------------------------------------------------------------------
   3. LIGHT THEME — explicit choice (JS set data-theme="light")
   --------------------------------------------------------------------------
   Higher specificity than :root and @media — wins regardless of OS pref.
   Values mirror the @media block above.
   -------------------------------------------------------------------------- */
[data-theme="light"] {
  --color-bg:             #FFFFFF;
  --color-surface-1:      #F8FAFC;
  --color-surface-2:      #F1F5F9;
  --color-surface-3:      #E2E8F0;

  --color-border-subtle:  #E2E8F0;
  --color-border-default: #CBD5E1;
  --color-border-strong:  #94A3B8;

  --color-text-primary:   #0F172A;
  --color-text-secondary: #475569;
  --color-text-muted:     #64748B;
  --color-text-inverse:   #FFFFFF;

  --color-accent:           #0D9488;
  --color-accent-hover:     #0F766E;
  --color-accent-subtle:    rgba(13, 148, 136, 0.08);
  --color-accent-secondary: #10B981;

  --shadow-xs: 0 1px 2px  rgba(0, 0, 0, 0.10);
  --shadow-sm: 0 2px 4px  rgba(0, 0, 0, 0.08), 0 1px 2px  rgba(0, 0, 0, 0.06);
  --shadow-md: 0 4px 8px  rgba(0, 0, 0, 0.10), 0 2px 4px  rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 16px 32px rgba(0, 0, 0, 0.12), 0 4px 8px  rgba(0, 0, 0, 0.08);
  --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.14), 0 8px 16px rgba(0, 0, 0, 0.10);

  --shadow-accent-glow: 0 0 24px rgba(13, 148, 136, 0.20);
}


/* --------------------------------------------------------------------------
   4. DARK THEME — explicit choice (JS set data-theme="dark")
   --------------------------------------------------------------------------
   Re-declares dark values at higher specificity than the @media light block,
   so a user who explicitly picked dark while their OS is on light still
   gets dark. Values mirror :root.
   -------------------------------------------------------------------------- */
[data-theme="dark"] {
  --color-bg:             #0A0E1A;
  --color-surface-1:      #11162A;
  --color-surface-2:      #181F37;
  --color-surface-3:      #1F2744;

  --color-border-subtle:  rgba(255, 255, 255, 0.06);
  --color-border-default: rgba(255, 255, 255, 0.12);
  --color-border-strong:  rgba(255, 255, 255, 0.22);

  --color-text-primary:   #E5E7EB;
  --color-text-secondary: #9CA3AF;
  --color-text-muted:     #6B7280;
  --color-text-inverse:   #0F172A;

  --color-accent:           #14B8A6;
  --color-accent-hover:     #0D9488;
  --color-accent-subtle:    rgba(20, 184, 166, 0.10);
  --color-accent-secondary: #34D399;

  --shadow-xs: 0 1px 2px  rgba(0, 0, 0, 0.40);
  --shadow-sm: 0 2px 4px  rgba(0, 0, 0, 0.35), 0 1px 2px  rgba(0, 0, 0, 0.30);
  --shadow-md: 0 4px 8px  rgba(0, 0, 0, 0.40), 0 2px 4px  rgba(0, 0, 0, 0.30);
  --shadow-lg: 0 16px 32px rgba(0, 0, 0, 0.45), 0 4px 8px  rgba(0, 0, 0, 0.35);
  --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.50), 0 8px 16px rgba(0, 0, 0, 0.40);

  --shadow-accent-glow: 0 0 32px rgba(20, 184, 166, 0.30);
}


/* ==========================================================================
   PHASE 3b — BUTTON CLUSTER
   ==========================================================================
   Replaces the legacy .btn cluster in bundle.min.css for the COLOR, BORDER,
   BACKGROUND, BOX-SHADOW, BORDER-RADIUS, PADDING, FONT, MIN-HEIGHT, and
   TRANSITION properties. Because none of those properties carry !important
   in bundle.min.css's .btn rules, and design-system.css loads AFTER
   bundle.min.css, these rules win cascade naturally.

   What is INTENTIONALLY NOT touched in bundle.min.css and still applies:
     - .btn { cursor:pointer !important } (universal pointer cursor)
     - .hero-cta-enhanced .btn { width:100% !important; justify-content:center !important }
       (intentional full-width buttons inside hero CTA containers)
     - @media (max-width:480px) .btn / .btn-lg / .btn-sm { ... !important }
       (mobile responsive sizing — still wins because !important + media query)
     - .btn-primary::before pseudo-element shimmer (legacy decoration)
     - .btn-icon, .btn-pulse (legacy specialty variants — Phase 4 will revisit)
     - Compound selectors like .nav-item:hover .btn (higher specificity wins)

   Spec reference: Phase 2 §C.1 — 4 variants × 4 sizes × 4 states.
   Legacy aliases mapped here so existing markup keeps working unchanged:
     .btn-accent  -> visually same as .btn-primary  (used in header.php Contact CTA)
     .btn-outline -> visually same as .btn-secondary (used in legacy hero CTAs)
   ========================================================================== */

/* ---- Base ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 10px 20px;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-primary);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    background   var(--duration-normal) var(--ease-out),
    color        var(--duration-normal) var(--ease-out),
    border-color var(--duration-normal) var(--ease-out),
    box-shadow   var(--duration-normal) var(--ease-out),
    transform    var(--duration-normal) var(--ease-out);
}

/* ---- States (apply to every variant) ---- */
.btn:active {
  transform: translateY(0) scale(0.98);
  transition-duration: var(--duration-instant);
}

.btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.btn[disabled],
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---- Sizes ---- */
.btn-sm {
  padding: 7px 14px;
  min-height: 36px;
  font-size: var(--text-caption);
}

.btn-lg {
  padding: 14px 28px;
  min-height: 52px;
  font-size: var(--text-body);
}

.btn-xl {
  padding: 18px 36px;
  min-height: 60px;
  font-size: var(--text-body-lg);
}

/* ---- Variant: Primary (teal -> emerald gradient + accent glow on hover) ---- */
.btn-primary,
.btn-accent {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-secondary));
  color: var(--color-text-inverse);
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}

.btn-primary:hover,
.btn-accent:hover {
  transform: translateY(-1px);
  color: var(--color-text-inverse);
  box-shadow: var(--shadow-md), var(--shadow-accent-glow);
}

/* ---- Variant: Secondary (outlined) ---- */
.btn-secondary,
.btn-outline {
  background: transparent;
  color: var(--color-text-primary);
  border-color: var(--color-border-default);
}

.btn-secondary:hover,
.btn-outline:hover {
  transform: translateY(-1px);
  background: var(--color-accent-subtle);
  color: var(--color-text-primary);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

/* ---- Variant: Ghost (minimal, no border) ---- */
.btn-ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: transparent;
}

.btn-ghost:hover {
  background: var(--color-surface-2);
  color: var(--color-text-primary);
  border-color: transparent;
}

/* ---- Variant: Danger (destructive only) ---- */
.btn-danger {
  background: var(--color-error);
  color: #FFFFFF;
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}

.btn-danger:hover {
  transform: translateY(-1px);
  background: #DC2626;
  color: #FFFFFF;
  box-shadow: var(--shadow-md);
}

/* ---- Reduced motion: collapse hover/active transforms ---- */
@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .btn:active {
    transform: none;
  }
}


/* ==========================================================================
   PHASE 3c — CARD CLUSTER (base only, conservative)
   ==========================================================================
   Defines the BASE .card visual treatment (background, border, radius,
   shadow, transition, hover, focus). Does NOT touch variant rules — the
   per-variant !important styles in bundle.min.css for .problem-card,
   .feature-card, .selector-card, .hero-stat-item, section#pricing .card,
   [data-theme="light"] .problem-card, etc. keep working unchanged.

   What WINS via cascade order (no !important needed, design-system.css
   loads after bundle.min.css):
     - background, color, border, border-radius, padding, box-shadow,
       transition on .card BASE
     - hover transform/shadow on INTERACTIVE cards (a.card / button.card /
       .card[onclick] / .selector-card)
     - focus-visible ring (new — bundle had inconsistent focus)
     - .card-glass background+blur (uses color-mix; falls back to bundle's
       background if browser doesn't support color-mix)
     - .card-elevated as a new opt-in variant (not used yet — Phase 4 pages
       can apply it to feature/stat cards)

   What is INTENTIONALLY NOT touched and still applies:
     - .problem-card display:flex !important + gap !important (intentional)
     - .hero-stat-item display:flex !important + padding !important (intentional)
     - section#pricing .card hover transform !important (pricing-specific lift)
     - [data-theme="light"] .problem-card background (light-theme variant)
     - .features-grid:has(.problem-card) gap (grid-context layout)
     - All .card::before / .card-glass canvas / responsive narrow-viewport rules

   Spec reference: Phase 2 §C.2 (3 variants: card / card-elevated / card-glass).
   ========================================================================== */

/* ---- Base card ---- */
.card {
  background: var(--color-surface-1);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  transition:
    background   var(--duration-normal) var(--ease-out),
    color        var(--duration-normal) var(--ease-out),
    border-color var(--duration-normal) var(--ease-out),
    box-shadow   var(--duration-normal) var(--ease-out),
    transform    var(--duration-normal) var(--ease-out);
}

/* ---- Glass variant — translucent + blur, used sparingly (expensive) ---- */
.card-glass {
  /* color-mix lets us pick up whichever theme is active for surface-1.
     Browsers without color-mix support (very old) fall back to the
     bundle.min.css .card-glass rule (no break). */
  background: color-mix(in srgb, var(--color-surface-1) 70%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
}

/* ---- Elevated variant — opt-in, for feature/stat cards (Phase 4 will adopt) ---- */
.card-elevated {
  background: var(--color-surface-1);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-6);
}

/* ---- Interactive cards: hover + focus
   Restricted to elements that semantically signal interactivity.
   .selector-card is included by class because the existing markup
   uses <a class="card selector-card"> — both selectors match. ---- */
a.card:hover,
button.card:hover,
.card[onclick]:hover,
.selector-card:hover {
  transform: translateY(-2px);
  border-color: var(--color-border-default);
  box-shadow: var(--shadow-md);
}

a.card:focus-visible,
button.card:focus-visible,
.card[onclick]:focus-visible,
.selector-card:focus-visible,
.card-elevated:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ---- Reduced motion: collapse hover transforms ---- */
@media (prefers-reduced-motion: reduce) {
  a.card:hover,
  button.card:hover,
  .card[onclick]:hover,
  .selector-card:hover {
    transform: none;
  }
}


/* ==========================================================================
   PHASE 3d — FORM CLUSTER
   ==========================================================================
   Defines the .form-* class system. The codebase uses TWO naming
   conventions historically — .form-input (used in admin password flows,
   currency settings, employees, file-manager, etc.) AND .form-control
   (Bootstrap-style, used in admin/create-invoice and other CRUD forms).
   This file styles BOTH names identically so neither needs markup change.

   What WINS via cascade order (no !important needed):
     - background, color, border, border-radius, padding (where bundle
       lacks !important on the base .form-input/.form-textarea rule)
     - hover, focus, focus-visible
     - placeholder color, error/disabled state
     - .form-helper, .form-error (new — spec C.3)
     - .form-check (custom checkbox/radio — new spec)

   What is INTENTIONALLY NOT touched and still applies:
     - Universal `input,select,textarea { font-size:16px !important }`
       (iOS zoom prevention — keep)
     - `input[type="text|email|tel|...] { min-height:48px !important; width:100% !important }`
       (mobile tap target + full-width inputs — intentional)
     - `.contact-form-area input { width:100% !important; font-size:16px !important }`
       (scoped contact form — kept; full form will be rebuilt in Phase 4)
     - `.contact-form-area .btn { width:100% !important }`
       (full-width submit on contact)
     - `textarea { min-height:120px !important }` (matches my value — no-op)
     - `cursor:text !important` on input/textarea (same value — no-op)

   Public contact form ([includes/contact-form.php]) uses INLINE styles
   instead of these classes — it gets no visual change here. Phase 4 will
   migrate that markup to use the design-system form classes.
   ========================================================================== */

/* ---- Base: text input, textarea, select (aliased: .form-input & .form-control) ---- */
.form-input,
.form-control,
.form-textarea,
.form-select {
  display: block;
  width: 100%;
  padding: 12px 14px;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: var(--text-body);    /* 16px — also prevents iOS zoom-on-focus */
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text-primary);
  background: var(--color-surface-3);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-sm);
  appearance: none;
  -webkit-appearance: none;
  transition:
    background   var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    box-shadow   var(--duration-fast) var(--ease-out);
}

/* ---- Placeholder color (separate rule so unsupported pseudo-elements skip cleanly) ---- */
.form-input::placeholder,
.form-control::placeholder,
.form-textarea::placeholder {
  color: var(--color-text-muted);
  opacity: 1;
}

/* ---- Textarea: vertical resize + taller default ---- */
.form-textarea {
  min-height: 120px;
  resize: vertical;
  line-height: 1.5;
}

/* ---- Select: custom chevron via inline SVG ---- */
.form-select {
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%239CA3AF' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 8px;
}

/* ---- Hover ---- */
.form-input:hover,
.form-control:hover,
.form-textarea:hover,
.form-select:hover {
  border-color: var(--color-border-strong);
}

/* ---- Focus (universal — :focus is more reliable than :focus-visible on text inputs
        because clicking into a text input IS the meaningful "focus" event for typing) ---- */
.form-input:focus,
.form-control:focus,
.form-textarea:focus,
.form-select:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-accent-subtle);
}

/* ---- Error state — set via .is-error class OR aria-invalid="true" ---- */
.form-input.is-error,
.form-control.is-error,
.form-textarea.is-error,
.form-select.is-error,
.form-input[aria-invalid="true"],
.form-control[aria-invalid="true"],
.form-textarea[aria-invalid="true"],
.form-select[aria-invalid="true"] {
  border-color: var(--color-error);
}

.form-input.is-error:focus,
.form-control.is-error:focus,
.form-textarea.is-error:focus,
.form-select.is-error:focus,
.form-input[aria-invalid="true"]:focus,
.form-control[aria-invalid="true"]:focus,
.form-textarea[aria-invalid="true"]:focus,
.form-select[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}

/* ---- Disabled ---- */
.form-input:disabled,
.form-control:disabled,
.form-textarea:disabled,
.form-select:disabled {
  opacity: 0.5;
  background: var(--color-surface-2);
  cursor: not-allowed;
}

/* ---- Label ---- */
.form-label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-text-secondary);
}

/* ---- Group: vertical spacing between fields ---- */
.form-group {
  margin-bottom: var(--space-5);
}

.form-group:last-child {
  margin-bottom: 0;
}

/* ---- Helper text / Error text (spec C.3 — new utility classes) ---- */
.form-helper,
.form-error {
  display: block;
  margin-top: 6px;
  font-size: var(--text-caption);
  line-height: 1.4;
}

.form-helper {
  color: var(--color-text-muted);
}

.form-error {
  color: var(--color-error);
}

/* ---- Custom checkbox + radio ---- */
.form-check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-body-sm);
  color: var(--color-text-primary);
  user-select: none;
}

.form-check input[type="checkbox"],
.form-check input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  flex-shrink: 0;
  background: var(--color-surface-3);
  border: 1.5px solid var(--color-border-default);
  cursor: pointer;
  transition:
    background   var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.form-check input[type="checkbox"] {
  border-radius: 4px;
}

.form-check input[type="radio"] {
  border-radius: var(--radius-pill);
}

.form-check input[type="checkbox"]:hover,
.form-check input[type="radio"]:hover {
  border-color: var(--color-border-strong);
}

.form-check input[type="checkbox"]:checked,
.form-check input[type="radio"]:checked {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}

.form-check input[type="checkbox"]:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.5 6.5L5 9L9.5 3.5' stroke='white' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px 12px;
}

.form-check input[type="radio"]:checked {
  background-image: radial-gradient(circle, #FFFFFF 33%, transparent 38%);
}

.form-check input[type="checkbox"]:focus-visible,
.form-check input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.form-check input[type="checkbox"]:disabled,
.form-check input[type="radio"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---- Form row: two-column layout for paired fields (e.g. first/last name).
   Used by admin CRUD pages AND now the public contact form. Collapses to
   a single column under 640 px so labels and inputs stay readable on phones. ---- */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (max-width: 640px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}


/* ==========================================================================
   PHASE 3e — LAYOUT PRIMITIVES
   ==========================================================================
   Additive new utility classes for Phase 4 page rebuilds. Provides the
   vocabulary to replace the 7,164 inline `style=""` declarations across
   the codebase (per Phase 1 audit) with reusable named patterns.

   NAMES THAT COLLIDE with bundle.min.css and are INTENTIONALLY NOT defined
   here (existing behaviour kept so currently-shipped pages don't shift):
     - .container (13 refs) — keep existing 1400px max-width pattern
     - .section   (10 refs) — keep existing fixed 4.5rem block padding
     - .section-alt (2 refs)
     - .grid, .grid-2, .grid-3, .grid-4 (54 refs total) — keep existing
       grid-template-columns rules
   Phase 4 rebuilds can KEEP using these existing names; new names below
   are opt-in additions for cases where the existing rule doesn't fit
   (e.g. narrower hero copy column → .container-md, fluid hero padding
   → .section-hero, vertical-flow groups → .stack).

   All rules below are NEW class names (verified with .layout_check.py:
   0 references in bundle.min.css before this commit). Zero cascade risk.

   Spec reference: Phase 2 §C.7.
   ========================================================================== */

/* ---- Container variants (narrower max-widths than the default 1400px .container) ---- */
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-2xl {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--space-5);
  box-sizing: border-box;
}

.container-sm  { max-width: var(--container-sm); }   /*  640 px — narrow blog body */
.container-md  { max-width: var(--container-md); }   /*  768 px — hero copy / dense text */
.container-lg  { max-width: var(--container-lg); }   /* 1024 px — article body */
.container-xl  { max-width: var(--container-xl); }   /* 1280 px — wide content */
.container-2xl { max-width: var(--container-2xl); }  /* 1400 px — explicit alias for the default .container width */


/* ---- Section variants (additive — does NOT redefine .section) ---- */

/* Hero section — fluid responsive vertical padding (taller than .section) */
.section-hero {
  padding-block: clamp(var(--space-8), 8vw, var(--space-10));   /* 64 → 128 px */
  position: relative;
}

/* Compact section — half the vertical padding of a default .section */
.section-sm {
  padding-block: clamp(var(--space-6), 4vw, var(--space-7));    /* 32 → 48 px */
  position: relative;
}


/* ---- Stack: vertical flex with explicit gap (replaces hand-rolled margin chains) ---- */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);          /* default 16 px */
}

/* Stack-N modifiers — pick gap explicitly */
.stack-1 { gap: var(--space-1); }   /*  4 px */
.stack-2 { gap: var(--space-2); }   /*  8 px */
.stack-3 { gap: var(--space-3); }   /* 12 px */
.stack-4 { gap: var(--space-4); }   /* 16 px (default) */
.stack-5 { gap: var(--space-5); }   /* 24 px */
.stack-6 { gap: var(--space-6); }   /* 32 px */
.stack-7 { gap: var(--space-7); }   /* 48 px */


/* ---- Row: horizontal flex with wrap (replaces inline flex/gap declarations) ---- */
.row {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
}


/* ---- Cluster: inline-flex wrap for chips, tags, button rows ---- */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}


/* ---- Auto-fit responsive grid (no fixed column count — adapts to container width) ---- */
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: var(--space-5);
}

/* Optional fixed-5-column grid (the spec doesn't define .grid-5; bundle doesn't have one) */
.grid-5 {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-5);
}

@media (max-width: 768px) {
  .grid-5 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 480px) {
  .grid-5 {
    grid-template-columns: 1fr;
  }
}


/* ---- Center: combined flex-center utility (common Phase 4 pattern: center a CTA row) ---- */
.center {
  display: flex;
  align-items: center;
  justify-content: center;
}


/* ---- Visually-hidden but screen-reader-accessible (a11y utility) ---- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* ---- .text-gradient utility — teal -> emerald gradient on H1/H2 keywords ----
   Replaces the legacy bundle.min.css .text-gradient rule (which used the old
   cyan -> blue -> violet stops). Used site-wide on H1 keyword spans like:
     <h1>Privacy <span class="text-gradient">Policy</span></h1>
   Cascade order: this file loads after bundle.min.css, so this rule wins
   for background, -webkit-background-clip, color. Bundle's rule has no
   !important on these properties (verified). */
.text-gradient {
  background: linear-gradient(135deg, var(--color-accent-secondary), var(--color-accent));
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
}


/* ==========================================================================
   PHASE 3f — NAV CLUSTER (FOCUS RINGS ONLY — minimal, intentionally)
   ==========================================================================
   The nav cluster (header pill, mega-menu, mobile drawer, dropdown, theme
   toggle, hamburger) is the densest cluster in bundle.min.css: 323 rules,
   343 `!important` declarations. 84 of those !important flags are on the
   exact properties a colour/background restyle would set (background:27,
   color:20, transform:11, box-shadow:10, opacity:7, transition:6, border-
   color:3).

   The nav also has the most intricate interactive behaviour on the site:
   mega-menu reveal timing, dropdown positioning, mobile drawer slide+
   focus-trap, hamburger animation, theme-toggle cross-fade. All of it
   currently WORKS — the user's brief was explicit that we must not break
   working functionality, especially on a surface that touches every page.

   THEREFORE Phase 3f only adds what the nav genuinely lacks today:
   consistent keyboard `:focus-visible` rings. These are purely additive
   `outline` declarations — they cannot interact with the existing rules
   (which set background/color/transform/box-shadow), and they fix a real
   a11y deficiency where keyboard users currently get inconsistent or
   missing focus indication across nav links, dropdown items, mega-menu
   links, mobile-toggle, theme-toggle, and the skip link.

   A FULL nav restyle (teal accent colours, simpler hover states, cleaner
   mega-menu typography) is deferred to a dedicated future phase paired
   with Phase 4 page rebuilds — at that point the nav can be verified
   per-page-template as each page is migrated.
   ========================================================================== */

/* ---- Universal focus-visible ring for nav interactive elements ---- */
.skip-link:focus-visible,
.main-nav a:focus-visible,
.main-nav button:focus-visible,
.nav-link:focus-visible,
.dropdown a:focus-visible,
.mega-links a:focus-visible,
.mega-featured-link:focus-visible,
.mega-view-all a:focus-visible,
.mega-cta a:focus-visible,
.mobile-toggle:focus-visible,
.mobile-nav-close:focus-visible,
.theme-toggle:focus-visible,
.logo:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---- Skip-link: make it visible on focus, not just to screen readers ---- */
/* The bundle.min.css .skip-link rule positions it off-screen with top:-100%
   until focused. We don't touch that. We only ensure that when it's focused
   our universal :focus-visible ring above renders on it. */
