/* ============================================================
 * Manifest Tier 1 — Design System: base.css
 * ------------------------------------------------------------
 * The THEME CONTRACT. Every CSS custom property listed here is
 * a documented override-point for per-template theme.css files.
 *
 * Load order (critical): reset.css -> fonts.css -> base.css ->
 *                        components.css -> utilities.css
 *
 * DO NOT inline hex colors or px literals downstream — always
 * consume the tokens declared in :root below. If a downstream
 * file needs a value that doesn't exist here, ADD the token
 * (with a comment) before using it. That's the contract.
 * ============================================================ */


/* ============================================================
 * Alpine.js cloak — hide [x-cloak] elements until Alpine inits.
 * Convention: add x-cloak attribute to elements that use x-show
 * or x-if to avoid Flash Of Unstyled Content (FOUC). Alpine
 * strips the attribute on init, after which this rule no longer
 * matches and x-show/x-if takes over visibility control.
 * ============================================================ */
[x-cloak] { display: none !important; }


/* ============================================================
 * :root — THE THEME CONTRACT
 * Default values reflect the "kopi" palette used by template-01
 * (warm cream + emerald teal + gold) and the Playfair Display +
 * Crimson Pro typographic pair. Override these in theme.css.
 * ============================================================ */
:root {
	/* ---------- Palette (WCAG AA verified on default bg) ---------- */
	--color-primary:          #0F766E;  /* Teal — buttons, links, focus ring, .badge-primary, .price-current */
	--color-primary-hover:    #0E6B64;  /* Deeper teal — hover state, maintains >=4.5:1 with white text */
	--color-on-primary:       #FFFFFF;  /* Text/icon color on top of --color-primary surfaces (.btn-primary, .badge-primary, .skip-link). White default is safe for all dark primaries (luminance < 0.5). Theme.css overrides to #1A1A1A when a template ships a LIGHT primary (rare). Consumed by components.css instead of hard-coded #fff so contrast follows the brand palette. */
	--color-accent:           #D4A75A;  /* Warm gold — .badge-accent, decorative dividers */
	--color-accent-hover:     #C19A4D;  /* Deeper gold — hover state */
	--color-bg:               #FAF8F5;  /* Warm cream — page background */
	--color-bg-elevated:      #FFFFFF;  /* White — card/modal/elevated surface */
	--color-bg-subtle:        #F5F2ED;  /* Warm sand — secondary surface, hero gradient stop */
	--color-bg-warm-end:      #F0EBE3;  /* Lighter shade — used by hero-warm second gradient stop */
	--color-text:             #1A1A1A;  /* Near-black — body text (16.1:1 on bg, AAA) */
	--color-text-secondary:   #525252;  /* Neutral-600 — body subtext, .field-hint, captions (7.6:1 on bg) */
	--color-text-tertiary:    #6B6B6B;  /* Neutral-500 — meta text, breadcrumb inactive, placeholder (5.4:1 on bg) */
	--color-text-disabled:    #A3A3A3;  /* Disabled / placeholder tone */
	--color-border:           #E5E5E5;  /* Light hairline — .field input borders, .card divider */
	--color-border-strong:    #D4D4D4;  /* Slightly darker — used when border needs emphasis */
	--color-success:          #047857;  /* Emerald-700 — .toast-success, .badge-success */
	--color-success-soft:     #D1FAE5;  /* Soft success tint for alert backgrounds */
	--color-warning:          #B45309;  /* Amber-700 — .toast-warning, low-stock indicator */
	--color-warning-soft:     #FEF3C7;  /* Soft warning tint */
	--color-error:            #B91C1C;  /* Red-700 — .btn-danger, .field-error, .toast-error */
	--color-error-soft:       #FEE2E2;  /* Soft error tint */
	--color-wa:               #25D366;  /* WhatsApp brand — .wa-float (externally locked; do NOT theme) */

	/* ---------- Alpha / overlay derivations ----------
	 * Used by .drawer-overlay, .modal-overlay, .site-header backdrop.
	 * Alpha forms allow translucent backgrounds while keeping the
	 * base color theme-driven. */
	--color-overlay:          rgba(26, 26, 26, 0.40);    /* Modal/drawer scrim */
	--color-overlay-strong:   rgba(26, 26, 26, 0.65);    /* Lightbox bg */
	--color-header-bg:        rgba(250, 248, 245, 0.85); /* Sticky header backdrop pre-blur */
	--color-selection:        rgba(15, 118, 110, 0.25);  /* ::selection bg derived from --color-primary */
	--color-focus-ring:       rgba(15, 118, 110, 0.35);  /* Glow halo for :focus-visible */
	--color-accent-tint:      rgba(212, 167, 90, 0.12);  /* Hero radial-gradient accent overlay */
	--color-primary-tint:     rgba(15, 118, 110, 0.08);  /* Hero radial-gradient + .alert-info bg */
	--color-primary-tint-strong: rgba(15, 118, 110, 0.20); /* .alert-info border */

	/* ---------- Typography ----------
	 * --font-display: headings + hero title + price-current
	 * --font-body:    body, forms, UI text */
	--font-display:           'Playfair Display', 'Times New Roman', Georgia, serif;
	--font-body:              'Crimson Pro', Georgia, 'Times New Roman', serif;
	--font-mono:              ui-monospace, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;

	--font-size-base:         1.0625rem;   /* 17px — body baseline. html font-size stays at 100% for user rem scaling */
	--font-size-scale:        1.250;       /* Modular ratio: major third. h6=base, h1=base*scale^4 */
	--font-size-h6:           1.0625rem;   /* base */
	--font-size-h5:           1.328rem;    /* base * scale */
	--font-size-h4:           1.66rem;     /* base * scale^2 */
	--font-size-h3:           2.075rem;    /* base * scale^3 */
	--font-size-h2:           2.323rem;    /* base * scale^3.5 */
	--font-size-h1:           2.594rem;    /* base * scale^4 */
	--font-size-sm:           0.875rem;    /* 14px — .field-hint, captions, .badge */
	--font-size-xs:           0.75rem;     /* 12px — .text-caption, .announcement-bar */
	--font-size-caption:      0.75rem;     /* alias for .text-caption usage */

	--line-height-body:       1.6;         /* Body paragraph */
	--line-height-tight:      1.15;        /* Headings */
	--line-height-snug:       1.35;        /* Compact UI (button labels, badges) */
	--line-height-loose:      1.75;        /* Long-form legal pages */

	--letter-spacing-display: -0.02em;     /* Heading tracking */
	--letter-spacing-body:    0;
	--letter-spacing-caption: 0.12em;      /* Uppercase eyebrows + .announcement-bar */
	--letter-spacing-button:  0.01em;      /* Slight tracking on button labels */

	--font-weight-regular:    400;
	--font-weight-medium:     500;
	--font-weight-semibold:   600;
	--font-weight-bold:       700;

	/* ---------- Spacing scale (semantic, density-scaled) ----------
	 * --density multiplier (default 1) reflows the whole scale.
	 * Used by .stack/.cluster gaps, .p-* utilities, component padding. */
	--density:                1;
	--space-0:                0;
	--space-xs:               calc(0.25rem  * var(--density)); /* 4px */
	--space-sm:               calc(0.5rem   * var(--density)); /* 8px */
	--space-md:               calc(1rem     * var(--density)); /* 16px */
	--space-lg:               calc(1.5rem   * var(--density)); /* 24px */
	--space-xl:               calc(2rem     * var(--density)); /* 32px */
	--space-2xl:              calc(3rem     * var(--density)); /* 48px */
	--space-3xl:              calc(4rem     * var(--density)); /* 64px */

	/* Numeric aliases (1..12) — kept for legacy reference; prefer semantic above. */
	--space-1:                var(--space-xs);
	--space-2:                var(--space-sm);
	--space-3:                calc(0.75rem * var(--density));
	--space-4:                var(--space-md);
	--space-6:                var(--space-lg);
	--space-8:                var(--space-xl);
	--space-12:               var(--space-2xl);

	/* ---------- Layout ---------- */
	--section-gap:            clamp(3rem, 2rem + 5vw, 6rem);   /* Vertical rhythm between page sections */
	--container-padding:      clamp(1rem, 0.5rem + 2vw, 2rem); /* Container side padding (responsive) */
	--container-max:          80rem;       /* 1280px content max width */
	--container-narrow:       48rem;       /* 768px article/legal-page max */
	--prose-max:              65ch;        /* Long-form reading width */
	--header-height:          4rem;        /* Mobile sticky header height; bumped to 5rem on md+ below */

	/* ---------- Border radius ---------- */
	--radius-sm:              0.25rem;     /* .badge, .input, .field, focus-ring */
	--radius-md:              0.375rem;    /* .btn, .card, .toast (default) */
	--radius-lg:              0.5rem;      /* .modal, .drawer */
	--radius-xl:              0.75rem;     /* Featured cards, hero media */
	--radius-full:            9999px;      /* Pills, .wa-float, .btn-icon, .switch */

	/* ---------- Shadows ---------- */
	--shadow-sm:              0 1px 2px rgba(0, 0, 0, 0.05);
	--shadow-md:              0 4px 12px rgba(0, 0, 0, 0.08);
	--shadow-lg:              0 12px 24px -8px rgba(0, 0, 0, 0.12);
	--shadow-xl:              0 25px 50px -12px rgba(0, 0, 0, 0.18);
	--shadow-brand:           0 12px 24px -8px rgba(15, 118, 110, 0.25); /* .btn-primary:hover lift */
	--shadow-focus:           0 0 0 3px var(--color-focus-ring);         /* :focus-visible glow */

	/* ---------- Motion ---------- */
	--transition-fast:        150ms;       /* Hover, focus, color transitions */
	--transition-medium:      250ms;       /* Transform, shadow, layout transitions */
	--transition-slow:        400ms;       /* Modal/drawer enter/exit */
	--ease-out:               ease; /* Live-WP parity 2026-06-05: was easeOutExpo cubic-bezier; live uses CSS default ease. */
	--ease-in-out:            cubic-bezier(0.4, 0, 0.2, 1);  /* Standard material-style */

	/* ---------- Z-index scale (named layers) ----------
	 * Contract: ONLY use these tokens for stacking, never raw numbers.
	 * Stacking order (low → high):
	 *   base → sticky-cta → demo-banner(40, set in app.js) → wa-float
	 *   → dropdown → header → drawer-overlay → drawer
	 *   → modal-overlay → modal → toast → skip-link
	 * B21.1 2026-06-10: drawer/overlay raised to 200/199 so mobile drawer
	 * tap-targets (close-X, first nav links) sit above the sticky header(100)
	 * and the app.js demo banner(40); modal/toast/skip-link bumped in lockstep
	 * to preserve their relative ordering above the drawer.
	 * NOTE: toast intentionally sits above modal — critical UX
	 * notifications (e.g. payment failure) must remain visible even
	 * when a modal is open. Skip-link beats everything (a11y). */
	--z-base:                 0;
	--z-sticky-cta:           20;          /* Mobile bottom CTA bar (product page) */
	--z-dropdown:             50;          /* Dropdown menus (nav, account, filter) — bumped 2026-06-05 to match live z-50 */
	--z-header:               100;         /* Sticky site header — bumped 2026-06-05 for safety vs floating elements */
	--z-wa-float:             45;          /* WA floating button (above header, below drawer) */
	--z-sticky-buy-bar:       45;          /* Sticky buy bar (product page, above header) */
	--z-drawer-overlay:       199;         /* B21.1 2026-06-10: bumped above header(100)+demo-banner(40) so drawer tap-targets aren't blocked */
	--z-drawer:               200;         /* Mobile nav drawer / cart drawer — must sit above sticky header + demo banner */
	--z-modal-overlay:        209;         /* B21.1: kept above drawer so modal opened from drawer overlays it */
	--z-modal:                210;         /* Quick-view + Snap payment + lightbox */
	--z-toast:                220;         /* Toast notifications (above everything) */
	--z-skip-link:            230;         /* Skip-to-content link (must beat all) */

	/* ---------- Legacy aliases (migration shim for WP theme port) ----------
	 * Existing .mt-* selectors in the live WP theme reference
	 * --brand-primary etc. Keep these aliases so that Stage 2
	 * (WP theme rebuild) only has to swap CSS file imports — no
	 * HTML class renames. Remove these once the WP theme is
	 * fully ported to --color-* names. */
	--bg-base:                var(--color-bg);
	--bg-elevated:            var(--color-bg-elevated);
	--bg-subtle:              var(--color-bg-subtle);
	--fg-primary:             var(--color-text);
	--fg-secondary:           var(--color-text-secondary);
	--fg-tertiary:            var(--color-text-tertiary);
	--brand-primary:          var(--color-primary);
	--brand-primary-hover:    var(--color-primary-hover);
	--brand-accent:           var(--color-accent);
	--brand-accent-hover:     var(--color-accent-hover);
	--border-subtle:          var(--color-border);

	/* ---------- color-mix fallback tokens (iOS Safari <16.2 compat) ----------
	 * iOS Safari <16.2 (released Dec 2022) doesn't support color-mix().
	 * components.css uses these as PROGRESSIVE-ENHANCEMENT fallbacks:
	 *   background: var(--color-primary-tint-8);   // fallback (this token)
	 *   background: color-mix(...);                // modern browsers override
	 * Values precomputed from hex tokens above:
	 *   --color-primary #0F766E -> rgb(15, 118, 110)
	 *   --color-accent  #D4A75A -> rgb(212, 167, 90)
	 *   --color-success #047857 -> rgb(4, 120, 87)
	 *   --color-warning #B45309 -> rgb(180, 83, 9)
	 *   --color-error   #B91C1C -> rgb(185, 28, 28)
	 *   --color-text    #1A1A1A -> rgb(26, 26, 26)
	 * Note: when source color-mix() mixes with --color-bg-elevated (white)
	 * instead of transparent, the rgba() fallback against the page is
	 * visually within ~3% of the mixed result — acceptable as fallback.
	 * Naming: --color-{name}-tint-{percent} where percent is the alpha. */
	--color-primary-tint-5:    rgba(15, 118, 110, 0.05);
	--color-primary-tint-6:    rgba(15, 118, 110, 0.06);
	--color-primary-tint-8:    rgba(15, 118, 110, 0.08);
	--color-primary-tint-12:   rgba(15, 118, 110, 0.12);
	--color-primary-tint-14:   rgba(15, 118, 110, 0.14);
	--color-primary-tint-18:   rgba(15, 118, 110, 0.18);
	--color-primary-tint-20:   rgba(15, 118, 110, 0.20);
	--color-primary-tint-30:   rgba(15, 118, 110, 0.30);
	--color-primary-tint-35:   rgba(15, 118, 110, 0.35);
	--color-primary-tint-40:   rgba(15, 118, 110, 0.40);
	--color-accent-tint-5:     rgba(212, 167, 90, 0.05);
	--color-accent-tint-6:     rgba(212, 167, 90, 0.06);
	--color-accent-tint-8:     rgba(212, 167, 90, 0.08);
	--color-accent-tint-12:    rgba(212, 167, 90, 0.12);
	--color-accent-tint-18:    rgba(212, 167, 90, 0.18);
	--color-accent-tint-40:    rgba(212, 167, 90, 0.40);
	--color-success-tint-8:    rgba(4, 120, 87, 0.08);
	--color-success-tint-12:   rgba(4, 120, 87, 0.12);
	--color-success-tint-25:   rgba(4, 120, 87, 0.25);
	--color-warning-tint-8:    rgba(180, 83, 9, 0.08);
	--color-warning-tint-14:   rgba(180, 83, 9, 0.14);
	--color-warning-tint-25:   rgba(180, 83, 9, 0.25);
	--color-error-tint-4:      rgba(185, 28, 28, 0.04);
	--color-error-tint-6:      rgba(185, 28, 28, 0.06);
	--color-error-tint-10:     rgba(185, 28, 28, 0.10);
	--color-error-tint-18:     rgba(185, 28, 28, 0.18);
	--color-error-tint-25:     rgba(185, 28, 28, 0.25);
	--color-error-tint-30:     rgba(185, 28, 28, 0.30);
	--color-text-tint-5:       rgba(26, 26, 26, 0.05);
	--color-text-tint-10:      rgba(26, 26, 26, 0.10);
	--color-text-tint-25:      rgba(26, 26, 26, 0.25);
	--color-text-tint-30:      rgba(26, 26, 26, 0.30);
	--color-text-tint-35:      rgba(26, 26, 26, 0.35);
	--color-text-tint-40:      rgba(26, 26, 26, 0.40);
	/* Mixed-with-black variants (color-mix(... XX%, #000)) — darker shades */
	--color-error-dark-85:     #9D1818;  /* rgb(157, 24, 24) — error mixed 85% with #000 */
	--color-text-dark-95:      #181818;  /* rgb(24, 24, 24) — text mixed 95% with #000 */
	/* Background tints (mixing two backgrounds, approximated against cream) */
	--color-bg-mix-80:         #F8F5F0;  /* 80% --color-bg + 20% --color-bg-subtle */
	--color-bg-mix-85:         rgba(250, 248, 245, 0.85);
	--color-bg-elevated-tint-95: rgba(255, 255, 255, 0.95);
	--color-bg-subtle-mix-70:  #F7F4EF;  /* 70% --color-bg-subtle + 30% --color-bg-elevated */
	/* Currentcolor fallback — assume text color context (~25% alpha) */
	--color-currentcolor-tint-25: rgba(26, 26, 26, 0.25);
	/* Pure black 50% alpha — generic overlay */
	--color-black-tint-50:     rgba(0, 0, 0, 0.50);
}


/* ============================================================
 * Responsive root tweaks
 * Header reflows taller on md+; utilities pick this up via var(). */
/* ============================================================ */
@media (min-width: 768px) {
	:root {
		--header-height: 5rem;
	}
}


/* ============================================================
 * Dark-mode hook (Tier 2 deferred — do not implement yet)
 * Documented placeholder so theme.css authors know where the
 * override lives. Keep empty body so it has zero effect today.
 * ============================================================ */
:root[data-theme="dark"] {
	/* Reserved for Tier 2 dark palette. */
}


/* ===== 8-AXIS VARIANT SCHEMA — P1-8 =====
 * Single greppable section housing all 8 orthogonal axes that the typed
 * `variantAxes` schema (see audit-artifacts/P1-8-SCHEMA-LOCKED.md) drives.
 * MfstApp.variant.applyToHtml() writes data-* attrs on <html> from
 * MfstAppConfig.variantAxes (or DEFAULT_AXES) before first paint.
 *
 * CASCADE ORDER (later wins on conflict, per L5):
 *   1. stylePack    (radius + shadow preset bundle)
 *   2. tone         (neutral grays + bg surfaces — never brand colors per L7)
 *   3. density      (--density spacing multiplier)
 *   4. radius       (fine-tune --radius-sm/md/lg/xl on top of stylePack)
 *   5. motion       (--transition-* durations + easing)
 *   6. ctaStyle     (component-target exception — .btn-primary surface only)
 *   7. heroLayout   (component-target exception — .hero structural lever; JS x-if)
 *   8. socialProof  (component-target exception — .trust-strip surface; JS x-show)
 *
 * RULES (audit-locked):
 *   L4  ALL axis selectors live in this single block (greppability).
 *   L6  components.css NEVER reads [data-*] axis attrs. Only 3 axes
 *       (ctaStyle/heroLayout/socialProof) component-target. Other 5 only
 *       override :root tokens.
 *   L7  `tone` axis NEVER overrides --color-primary or --color-accent.
 *   L17 @media (prefers-reduced-motion) stays AFTER the [data-motion] block
 *       below so the accessibility override always wins cascade.
 * ============================================================ */

/* ---------- 1. stylePack ---------- */
/* Preset visual bundle. Tuned radius + shadow tokens; theme.css palette
 * remains the brand source of truth. 'soft' is default and ships as the
 * :root baseline; the explicit selector is kept for clarity/auditability. */
:root[data-style-pack="soft"] {
	/* Default — same as :root. Explicit block for clarity + future hooks. */
	--radius-md:    0.5rem;
	--radius-lg:    0.75rem;
	--radius-xl:    1rem;
	--shadow-md:    0 4px 12px rgba(0, 0, 0, 0.08);
	--shadow-lg:    0 12px 24px -8px rgba(0, 0, 0, 0.12);
}
:root[data-style-pack="bold"] {
	--radius-md:    0.25rem;
	--radius-lg:    0.375rem;
	--radius-xl:    0.5rem;
	--shadow-md:    0 6px 18px rgba(0, 0, 0, 0.14);
	--shadow-lg:    0 18px 36px -10px rgba(0, 0, 0, 0.22);
}
:root[data-style-pack="minimal"] {
	--radius-md:    0.125rem;
	--radius-lg:    0.125rem;
	--radius-xl:    0.25rem;
	--shadow-md:    none;
	--shadow-lg:    0 1px 2px rgba(0, 0, 0, 0.05);
}
:root[data-style-pack="editorial"] {
	--radius-md:    0.25rem;
	--radius-lg:    0.375rem;
	--radius-xl:    0.5rem;
	--shadow-md:    0 2px 8px rgba(0, 0, 0, 0.06);
	--shadow-lg:    0 8px 20px -6px rgba(0, 0, 0, 0.10);
}

/* ---------- 2. tone (BRAND FIREWALL — L7) ---------- */
/* Neutral grays + bg surface temperature only. NEVER touches
 * --color-primary or --color-accent. */
:root[data-tone="neutral"] {
	/* Default — explicit block for clarity. */
}
:root[data-tone="warm"] {
	--color-bg:                #FBF8F3; /* warm cream */
	--color-bg-subtle:         #F5EFE6;
	--color-bg-elevated:       #FFFDF9;
	--color-text-secondary:    #5C4F44;
	--color-text-tertiary:     #6F5F50;
	--color-border:            #E8DFD2;
}
:root[data-tone="cool"] {
	--color-bg:                #F7F9FB; /* cool ash */
	--color-bg-subtle:         #EEF2F6;
	--color-bg-elevated:       #FFFFFF;
	--color-text-secondary:    #4A5563;
	--color-text-tertiary:     #5C6675;
	--color-border:            #DBE3EB;
}

/* ---------- 3. density ---------- */
/* Canonical vocab: compact / standard / spacious (P1-8). Legacy
 * tight / medium / airy kept as aliased rows below — REMOVE in P2 once
 * Stage 3 templates migrate. */
:root[data-density="compact"]  { --density: 0.85; }
:root[data-density="standard"] { --density: 1;    }
:root[data-density="spacious"] { --density: 1.15; }
/* Legacy aliases — REMOVE in P2 (post-Stage-3 migration). */
:root[data-density="tight"]    { --density: 0.85; }
:root[data-density="medium"]   { --density: 1;    }
:root[data-density="airy"]     { --density: 1.15; }

/* ---------- 4. radius ---------- */
/* Fine-tunes --radius-sm/md/lg/xl on top of stylePack. Does NOT touch
 * --radius-full (pill chips/wa-float/badges keep their pill shape). */
:root[data-radius="rounded"] {
	/* Default — explicit block for clarity. */
}
:root[data-radius="sharp"] {
	--radius-sm:    0.125rem;
	--radius-md:    0.125rem;
	--radius-lg:    0.25rem;
	--radius-xl:    0.375rem;
}
:root[data-radius="pill"] {
	--radius-sm:    0.5rem;
	--radius-md:    1rem;
	--radius-lg:    1.25rem;
	--radius-xl:    1.5rem;
}

/* ---------- 5. motion ---------- */
/* Animation intensity. Reduced-motion @media query below ALWAYS wins (L17). */
:root[data-motion="standard"] {
	/* Default — explicit block for clarity. */
}
:root[data-motion="subtle"] {
	--transition-fast:   100ms;
	--transition-medium: 180ms;
	--transition-slow:   280ms;
	--ease-out:          cubic-bezier(0.4, 0, 0.2, 1); /* gentle ease-in-out */
}
:root[data-motion="expressive"] {
	--transition-fast:   200ms;
	--transition-medium: 350ms;
	--transition-slow:   550ms;
	--ease-out:          cubic-bezier(0.16, 1, 0.3, 1); /* easeOutExpo (premium) */
}

/* ---------- 6. ctaStyle (component-target exception — L6/L18) ----------
 * Targets .btn-primary directly. WCAG AA contrast guarantee per L18:
 *   solid     — 4.5:1 text/bg (default — palette responsibility in theme.css).
 *   outline   — 3:1 border/bg + 4.5:1 text/bg (text remains brand primary).
 *   underline — 4.5:1 text/bg + 2px underline thickness.
 */
:root[data-cta-style="solid"] .btn-primary {
	/* Default — explicit block for clarity. */
}
:root[data-cta-style="outline"] .btn-primary {
	background: transparent;
	color: var(--color-primary);
	border: 2px solid var(--color-primary);
}
:root[data-cta-style="outline"] .btn-primary:hover {
	background: var(--color-primary);
	color: var(--color-bg-elevated);
}
:root[data-cta-style="underline"] .btn-primary {
	background: transparent;
	border: 0;
	color: var(--color-primary);
	padding-left: 0;
	padding-right: 0;
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
	box-shadow: none;
}
:root[data-cta-style="underline"] .btn-primary:hover {
	color: var(--color-primary-hover);
	text-decoration-thickness: 3px;
}

/* ---------- 7. heroLayout (component-target exception — L6/L8) ----------
 * The 4 variants are STRUCTURALLY different (different DOM children present
 * per variant), so Alpine `x-if` mounts/unmounts the per-variant sub-template
 * at the .hero root. The CSS rules below tune the wrapper + per-variant
 * layout containers (.hero__media-bg / .hero__collage-grid / .hero__accent-rule)
 * when present. Component baseline rules for .hero-inner / .hero-split-50 /
 * .hero-collage / .hero-full-bleed-overlay live in components.css; this block
 * applies axis-conditional overrides on top.
 *
 * JS SCAFFOLD (Alpine, per L8) — author once at template root:
 *   <section class="hero" x-data>
 *     <template x-if="$store.mfst.heroLayout === 'split'">     ... split markup ...     </template>
 *     <template x-if="$store.mfst.heroLayout === 'fullbleed'"> ... fullbleed markup ... </template>
 *     <template x-if="$store.mfst.heroLayout === 'collage'">   ... collage markup ...   </template>
 *     <template x-if="$store.mfst.heroLayout === 'minimal'">   ... minimal markup ...   </template>
 *   </section>
 * Bind via Alpine.store('mfst', { heroLayout: MfstApp.variant.get('heroLayout') }).
 */

/* 7.1 split — default 2-col (image + text). Component baseline owns layout. */
:root[data-hero-layout="split"] .hero {
	/* Default — explicit block for clarity. Layout in components.css .hero-split-50. */
}

/* 7.2 fullbleed — full-viewport image with text overlay.
 *  - Wrapper goes edge-to-edge; min-height fills hero space.
 *  - .hero__media-bg paints the image as background-image cover.
 *  - Its ::after applies a dark scrim for text contrast (WCAG AA).
 *  - .hero-inner is centered and sits above the scrim (z-index: 1). */
:root[data-hero-layout="fullbleed"] .hero {
	padding: 0;
	min-height: clamp(24rem, 70vh, 40rem);
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	color: var(--color-bg-elevated);
}
:root[data-hero-layout="fullbleed"] .hero > .hero__media-bg {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	z-index: 0;
}
:root[data-hero-layout="fullbleed"] .hero > .hero__media-bg::after {
	content: '';
	position: absolute;
	inset: 0;
	/* Dark scrim for white text contrast (WCAG AA). Theme.css MAY override
	 * with a lighter scrim + dark text if its palette warrants it. */
	background: linear-gradient(
		180deg,
		rgba(0, 0, 0, 0.30) 0%,
		rgba(0, 0, 0, 0.55) 100%
	);
}
:root[data-hero-layout="fullbleed"] .hero .hero-inner {
	position: relative;
	z-index: 1;
	padding-block: var(--space-2xl);
}
:root[data-hero-layout="fullbleed"] .hero .hero-title,
:root[data-hero-layout="fullbleed"] .hero .hero-subtitle {
	color: inherit; /* inherits the bg-elevated white set on .hero */
}
:root[data-hero-layout="fullbleed"] .hero .hero-subtitle {
	opacity: 0.92;
}

/* 7.3 collage — 2-3 image grid with text content adjacent/overlaid.
 *  - .hero__collage-grid is a responsive grid; 1 col mobile -> 3 col desktop.
 *  - First cell = featured image (spans 2 rows on desktop), other cells =
 *    secondary photos. Optional .hero__collage-text overlays the featured cell.
 *  - Components.css .hero-collage already ships a related baseline; this
 *    block tunes the variant container around the collage. */
:root[data-hero-layout="collage"] .hero {
	padding-block: var(--space-xl);
}
:root[data-hero-layout="collage"] .hero .hero__collage-grid {
	display: grid;
	gap: var(--space-md);
	grid-template-columns: 1fr;
	grid-auto-rows: minmax(8rem, auto);
}
@media (min-width: 768px) {
	:root[data-hero-layout="collage"] .hero .hero__collage-grid {
		grid-template-columns: 2fr 1fr 1fr;
		grid-template-rows: 1fr 1fr;
		gap: var(--space-lg);
	}
	:root[data-hero-layout="collage"] .hero .hero__collage-grid > :first-child {
		grid-column: 1;
		grid-row: 1 / span 2;
	}
}
:root[data-hero-layout="collage"] .hero .hero__collage-grid > * {
	border-radius: var(--radius-md);
	overflow: hidden;
	background: var(--color-bg-subtle);
	min-height: 8rem;
}
:root[data-hero-layout="collage"] .hero .hero__collage-grid img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* 7.4 minimal — text-first hero with no media slot.
 *  - Center-aligned typography-heavy layout, generous vertical breathing room.
 *  - Optional .hero__accent-rule (a 2px tinted underline beneath the title)
 *    drives the editorial feel.
 *  - Theme.css owns palette + font-pair; CSS here is structural only. */
:root[data-hero-layout="minimal"] .hero {
	text-align: center;
	padding-block: clamp(var(--space-2xl), 10vw, 8rem);
}
:root[data-hero-layout="minimal"] .hero .hero-inner {
	max-width: 48rem; /* keeps line-length readable on wide screens */
	margin-inline: auto;
}
:root[data-hero-layout="minimal"] .hero .hero-actions {
	justify-content: center;
}
:root[data-hero-layout="minimal"] .hero .hero-subtitle {
	margin-inline: auto; /* center the max-width: 32rem subtitle */
}
:root[data-hero-layout="minimal"] .hero .hero__accent-rule {
	display: block;
	width: 3rem;
	height: 2px;
	margin: var(--space-md) auto var(--space-lg);
	background: var(--color-accent);
	border: 0;
}

/* ---------- 8. socialProof (component-target exception — L6) ----------
 * Visual surface only; mount/unmount of badges/ugc/metrics/none happens in
 * Alpine (x-show for the first three, x-if=false for "none" per L8).
 * The 'none' CSS row is defense-in-depth: even if Alpine fails to remove
 * the node, display:none ensures the section never paints.
 *
 * Alpine JS render notes (per L8 in P1-8-SCHEMA-LOCKED):
 *   - badges/ugc/metrics → use x-show (similar DOM, cheap toggle)
 *   - none               → use x-if="false" (full DOM removal, no paint)
 * Components.css owns baseline .trust-strip (.trust-item / .trust-value /
 * .trust-caption / .trust-icon). The blocks below ONLY override per-variant. */

:root[data-social-proof="badges"] .trust-strip {
	/* Default — logo/icon grid. Inherits components.css baseline:
	 * 2-col mobile → 4-col desktop, centered .trust-item with .trust-icon
	 * + .trust-caption + .trust-value. No override needed. */
}

:root[data-social-proof="ugc"] .trust-strip {
	/* Customer photo gallery — 3-col mobile, 4-col desktop square grid.
	 * Each .trust-item becomes a photo tile with caption below the image. */
	grid-template-columns: repeat(3, 1fr);
	gap: var(--space-sm);
	padding: var(--space-md) 0;
}
:root[data-social-proof="ugc"] .trust-strip .trust-item {
	padding: 0;
	gap: var(--space-xs);
	position: relative;
	overflow: hidden;
	border-radius: var(--radius-md);
}
:root[data-social-proof="ugc"] .trust-strip .trust-item > img,
:root[data-social-proof="ugc"] .trust-strip .trust-item picture {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: var(--radius-md);
}
:root[data-social-proof="ugc"] .trust-strip .trust-caption {
	margin-top: var(--space-xs);
	text-transform: none;
	letter-spacing: normal;
	font-size: 0.75rem;
}
:root[data-social-proof="ugc"] .trust-strip .trust-icon,
:root[data-social-proof="ugc"] .trust-strip .trust-value {
	display: none;
}
@media (min-width: 768px) {
	:root[data-social-proof="ugc"] .trust-strip {
		grid-template-columns: repeat(4, 1fr);
		gap: var(--space-md);
	}
}

:root[data-social-proof="metrics"] .trust-strip {
	/* Counter cards — number-forward tiles. Inherits 2-col → 4-col grid
	 * from baseline; per-tile we boost the .trust-value font-size and
	 * stack number above caption. */
	gap: var(--space-md);
	padding: var(--space-lg) 0;
}
:root[data-social-proof="metrics"] .trust-strip .trust-item {
	background: var(--color-bg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	padding: var(--space-md) var(--space-sm);
	gap: var(--space-2xs, 0.25rem);
}
:root[data-social-proof="metrics"] .trust-strip .trust-value {
	font-size: 2rem;
	line-height: 1.1;
	letter-spacing: -0.01em;
}
:root[data-social-proof="metrics"] .trust-strip .trust-icon {
	display: none;
}
@media (min-width: 768px) {
	:root[data-social-proof="metrics"] .trust-strip .trust-value {
		font-size: 2.5rem;
	}
}

:root[data-social-proof="none"] .trust-strip {
	display: none;
}


/* ============================================================
 * prefers-reduced-motion — accessibility override
 * MUST stay AFTER the [data-motion] block above (L17) so the
 * reduced-motion override always wins on cascade.
 * Force-zero transitions/animations site-wide for users who've
 * requested reduced motion in their OS. The blanket * rule
 * is in reset.css; here we additionally neutralize tokens so
 * any component that reads --transition-* gets instant timing.
 * ============================================================ */
@media (prefers-reduced-motion: reduce) {
	:root {
		--transition-fast:   0ms;
		--transition-medium: 0ms;
		--transition-slow:   0ms;
	}
}
/* ===== END 8-AXIS VARIANT SCHEMA ===== */


/* ============================================================
 * Document defaults
 * html font-size stays at 100% (16px) so user rem scaling
 * works. Body owns the visual baseline.
 * ============================================================ */
html {
	font-size: 100%;
	color-scheme: light; /* Tier 1 light-only; Tier 2 adds 'dark' */
	font-family: var(--font-body); /* Avoid UA fallback to Times — match live parity 2026-06-05 */
	line-height: 1.5;
}

body {
	font-family: var(--font-body);
	font-size: var(--font-size-base);
	line-height: var(--line-height-body);
	color: var(--color-text);
	background-color: var(--color-bg);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

main {
	display: block; /* IE/older Safari safeguard */
	min-height: 50vh;
}


/* ============================================================
 * Typography hierarchy
 * Modular scale derived from --font-size-scale.
 * h1 + h2 use clamp() for fluid mobile-first sizing.
 * All headings consume --font-display so theme.css can swap
 * (e.g. template-04 = Inter for both display + body).
 * ============================================================ */
h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-display);
	font-weight: var(--font-weight-bold);
	letter-spacing: var(--letter-spacing-display);
	line-height: var(--line-height-tight);
	color: var(--color-text);
	margin: 0 0 var(--space-sm);
	text-wrap: balance; /* Progressive enhancement — Chrome 114+, Safari 17.4+ */
}

h1 {
	font-size: clamp(2rem, 1.4rem + 3vw, var(--font-size-h1));
	font-weight: var(--font-weight-bold);
}

h2 {
	font-size: clamp(1.65rem, 1.2rem + 2vw, var(--font-size-h2));
	font-weight: var(--font-weight-bold);
}

h3 {
	font-size: var(--font-size-h3);
	font-weight: var(--font-weight-semibold);
}

h4 {
	font-size: var(--font-size-h4);
	font-weight: var(--font-weight-semibold);
}

h5 {
	font-size: var(--font-size-h5);
	font-weight: var(--font-weight-medium);
}

h6 {
	font-size: var(--font-size-h6);
	font-weight: var(--font-weight-medium);
}


/* ============================================================
 * Inline + block text elements
 * ============================================================ */
p {
	margin: 0 0 var(--space-md);
	max-width: var(--prose-max); /* Optional — long-form pages override per-section */
}

p:last-child {
	margin-bottom: 0;
}

a {
	color: var(--color-primary);
	text-decoration: none;
	transition: color var(--transition-fast) var(--ease-out);
}

a:hover {
	color: var(--color-primary-hover);
	text-decoration: underline;
	text-underline-offset: 0.18em;
	text-decoration-thickness: 1px;
}

a:visited {
	color: var(--color-primary);
}

strong, b {
	font-weight: var(--font-weight-semibold);
	color: var(--color-text);
}

em, i {
	font-style: italic;
}

small {
	font-size: var(--font-size-sm);
	color: var(--color-text-secondary);
}

code {
	font-family: var(--font-mono);
	font-size: 0.9em;
	background: var(--color-bg-subtle);
	padding: 0.15em 0.35em;
	border-radius: var(--radius-sm);
	color: var(--color-text);
}

pre {
	font-family: var(--font-mono);
	font-size: var(--font-size-sm);
	background: var(--color-bg-subtle);
	padding: var(--space-md);
	border-radius: var(--radius-md);
	overflow-x: auto;
	margin: 0 0 var(--space-md);
}

pre code {
	background: transparent;
	padding: 0;
	border-radius: 0;
}

blockquote {
	margin: 0 0 var(--space-md);
	padding: var(--space-md) var(--space-lg);
	border-left: 3px solid var(--color-accent);
	color: var(--color-text-secondary);
	font-style: italic;
	background: var(--color-bg-subtle);
	border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

hr {
	border: 0;
	height: 1px;
	background: var(--color-border);
	margin: var(--space-xl) 0;
}

figure {
	margin: 0 0 var(--space-md);
}

figcaption {
	font-size: var(--font-size-sm);
	color: var(--color-text-tertiary);
	margin-top: var(--space-sm);
	text-align: center;
}


/* ============================================================
 * Nav/drawer/footer list reset.
 * reset.css only strips list-style for ul[role="list"]; the
 * mobile drawer + footer use plain <ul>, so without this they
 * render disc markers + a 40px indent. Strip them explicitly.
 * ============================================================ */
.drawer-body ul,
.site-footer ul {
  list-style: none;
  padding-left: 0;
}

/* ============================================================
 * Long-form list defaults (article/main scope)
 * reset.css restores markers here for editorial content where
 * they ARE expected (legal pages, blog).
 * ============================================================ */
article ul, article ol,
main .prose ul, main .prose ol {
	list-style: revert;
	padding-left: 1.5em;
	margin: 0 0 var(--space-md);
}

article li, main .prose li {
	margin-bottom: var(--space-xs);
}


/* ============================================================
 * Tables (raw element baseline — components.css may add .table)
 * ============================================================ */
table {
	width: 100%;
	border-collapse: collapse;
	margin: 0 0 var(--space-md);
	font-size: var(--font-size-base);
}

th, td {
	padding: var(--space-sm) var(--space-md);
	text-align: left;
	border-bottom: 1px solid var(--color-border);
	vertical-align: top;
}

th {
	font-weight: var(--font-weight-semibold);
	color: var(--color-text);
	background: var(--color-bg-subtle);
	font-family: var(--font-body);
	letter-spacing: var(--letter-spacing-caption);
	text-transform: uppercase;
	font-size: var(--font-size-xs);
}


/* ============================================================
 * Form element raw baseline (Proposal 3 hybrid)
 * A class-less <input> still renders sanely so a forgotten
 * .field-control class doesn't break the page. Components add
 * specificity on top.
 * ============================================================ */
label {
	display: inline-block;
	font-weight: var(--font-weight-medium);
	color: var(--color-text);
	line-height: var(--line-height-snug);
}

input, select, textarea {
	font-family: var(--font-body);
	font-size: var(--font-size-base);
	line-height: var(--line-height-snug);
	color: var(--color-text);
	background: var(--color-bg-elevated);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-sm);
	padding: 0.625rem 0.875rem;
	width: 100%;
	transition: border-color var(--transition-fast) var(--ease-out),
	            box-shadow var(--transition-fast) var(--ease-out);
}

input:focus, select:focus, textarea:focus {
	outline: 0;
	border-color: var(--color-primary);
	box-shadow: var(--shadow-focus);
}

input::placeholder, textarea::placeholder {
	color: var(--color-text-tertiary);
	opacity: 1; /* Firefox normalize */
}

input:disabled, select:disabled, textarea:disabled,
button:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

textarea {
	min-height: 6rem;
	resize: vertical;
}

/* Native checkbox/radio — accent color hook so :checked state
 * picks up the theme color without custom-component shenanigans. */
input[type="checkbox"], input[type="radio"] {
	accent-color: var(--color-primary);
	width: auto;
	min-width: 1.125rem;
	min-height: 1.125rem;
	padding: 0;
	margin-right: var(--space-sm);
	cursor: pointer;
}


/* ============================================================
 * Native <dialog> + <details> baseline
 * Components.css uses .modal class on dialogs; here we ensure
 * the raw element behaves sensibly when class is forgotten.
 * ============================================================ */
dialog {
	border: 0;
	background: var(--color-bg-elevated);
	color: var(--color-text);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-xl);
	padding: var(--space-lg);
	max-width: min(92vw, 32rem);
}

dialog::backdrop {
	background: var(--color-overlay);
	backdrop-filter: blur(4px);
	-webkit-backdrop-filter: blur(4px);
}

details {
	margin: 0 0 var(--space-sm);
}

summary {
	cursor: pointer;
	font-weight: var(--font-weight-medium);
	padding: var(--space-sm) 0;
	list-style: none;
}

summary::-webkit-details-marker {
	display: none;
}


/* ============================================================
 * :focus-visible — universal accessibility ring
 * Tab navigation surfaces ring; mouse click doesn't (per
 * :focus-visible semantics in modern browsers). reset.css
 * removed default outline so we apply this everywhere.
 * ============================================================ */
:focus-visible {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
	border-radius: var(--radius-sm);
}

/* Specialized: form inputs already use border + box-shadow on
 * :focus (above); suppress the redundant outline for them. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
	outline: 0;
}


/* ============================================================
 * ::selection — text highlight color
 * Derived from --color-primary so per-template theming flows.
 * ============================================================ */
::selection {
	background: var(--color-primary);
	color: #fff;
}

::-moz-selection {
	background: var(--color-primary);
	color: #fff;
}


/* ============================================================
 * Custom scrollbar (webkit + standards)
 * Subtle thumb so it doesn't fight editorial layouts.
 * ============================================================ */
* {
	scrollbar-width: thin;
	scrollbar-color: var(--color-text-tertiary) var(--color-bg-subtle);
}

::-webkit-scrollbar {
	width: 8px;
	height: 8px;
}

::-webkit-scrollbar-track {
	background: var(--color-bg-subtle);
}

::-webkit-scrollbar-thumb {
	background: var(--color-text-tertiary);
	border-radius: var(--radius-sm);
}

::-webkit-scrollbar-thumb:hover {
	background: var(--color-text-secondary);
}


/* ============================================================
 * Skip-to-content link (a11y critical)
 * First focusable element on every page. Hidden off-screen
 * until keyboard focus surfaces it. Tabs to it -> Enter ->
 * jumps focus + scroll to <main id="main-content">.
 *
 * Used inline as: <a href="#main-content" class="skip-link">…</a>
 * Must be placed immediately after <body>.
 * ============================================================ */
.skip-link {
	position: absolute;
	top: -100px;
	left: var(--space-sm);
	z-index: var(--z-skip-link);
	background: var(--color-primary);
	color: #fff;
	padding: var(--space-sm) var(--space-md);
	border-radius: var(--radius-md);
	font-weight: var(--font-weight-medium);
	font-size: var(--font-size-sm);
	box-shadow: var(--shadow-lg);
	transition: top var(--transition-fast) var(--ease-out);
	text-decoration: none;
}

.skip-link:focus,
.skip-link:focus-visible {
	top: var(--space-sm);
	outline: 2px solid var(--color-bg-elevated);
	outline-offset: 2px;
}


/* ============================================================
 * Lazy-loaded image fade-in
 * Moved from _app.js injectStyles — pure CSS, applied by
 * browser-native loading="lazy" attribute. MfstApp.initLazyImageFade
 * adds .loaded class on img.load event for browsers that don't
 * trigger the transition automatically.
 * ============================================================ */
img[loading="lazy"] {
	opacity: 0;
	transition: opacity var(--transition-slow) var(--ease-out);
}

img[loading="lazy"].loaded,
img[loading="lazy"][data-loaded="true"],
img[loading="lazy"].is-loaded {
	opacity: 1;
}

/* Failsafe — if JS doesn't run, still show images after a beat. */
@media (scripting: none) {
	img[loading="lazy"] {
		opacity: 1;
	}
}


/* ============================================================
 * [hidden] safety net + utility-ish baselines
 * reset.css applies display:none !important on [hidden] but
 * we re-state here for legibility of the contract.
 * ============================================================ */
[hidden] {
	display: none !important;
}

[aria-hidden="true"] {
	/* Visually present per ARIA semantics — do NOT auto-hide,
	 * just remove from a11y tree. Authors hide visually with
	 * the [hidden] attribute or .hidden class. */
}


/* ============================================================
 * Body scroll-lock utility
 * Applied to <body> when modal/drawer opens. Pairs with
 * MfstApp.modal.lock(el). scrollbar-gutter prevents layout
 * shift when scrollbar disappears.
 * ============================================================ */
body.is-locked,
body.no-scroll {
	overflow: hidden;
	touch-action: none;
	scrollbar-gutter: stable;
}


/* ============================================================
 * Page-level container baseline
 * .container is the canonical wrapper. Utilities.css declares
 * the layout primitives; this is just the typographic safe
 * zone for raw <main> content when no wrapper class is used.
 * ============================================================ */
main > * {
	box-sizing: border-box;
}


/* ============================================================
 * Font-loading optimization
 * font-display: swap is set in fonts/fonts.css. Here we hide
 * the FOIT briefly via size-adjust hints if the browser supports
 * it. Progressive enhancement only.
 * ============================================================ */
@supports (font-size-adjust: 1) {
	body {
		font-size-adjust: 0.52; /* Crimson Pro x-height ratio */
	}
}


/* ============================================================
 * Brand-dot accent — used in every logo render
 *   <a class="logo">Senja<span class="brand-dot">.</span></a>
 * Single-purpose utility kept in base.css because every page's
 * logo references it. Components.css does not need to repeat.
 * ============================================================ */
.brand-dot {
	color: var(--color-primary);
}


/* ============================================================
 * Legacy WP-port alias bridge (Stage 2 shim, P2 fix 2026-06-02)
 * The WP child theme + Phase 5 plugin reference older --brand-* /
 * --bg-* / --fg-* var names. Aliasing here keeps the WP port a
 * 1:1 swap, not a rewrite. Was previously duplicated in every
 * per-template theme.css Stanza B (~14 lines × 10 templates = 140
 * lines of duplication). Moved to base.css = single source.
 *
 * Each per-template theme.css overrides --color-* only;
 * --brand-*/--bg-*/--fg-*/--border-subtle auto-inherit via these
 * aliases.
 * ============================================================ */
:root {
	--brand-primary:        var(--color-primary);
	--brand-primary-hover:  var(--color-primary-hover);
	--brand-accent:         var(--color-accent);
	--brand-accent-hover:   var(--color-accent-hover);
	--bg-base:              var(--color-bg);
	--bg-elevated:          var(--color-bg-elevated);
	--bg-subtle:            var(--color-bg-subtle);
	--fg-primary:           var(--color-text);
	--fg-secondary:         var(--color-text-secondary);
	--fg-tertiary:          var(--color-text-tertiary);
	--border-subtle:        var(--color-border);
}


/* ============================================================
 * END base.css
 * Next file in load order: components.css
 * ============================================================ */
