/* GENERATED by wb-listora/bin/build-layered-css.mjs from listora-variables.css — do NOT edit. */
@layer listora {
/**
 * WB Listora — design variables (compiled output)
 *
 * GENERATED by bin/build-css.mjs — do NOT edit directly.
 * Edit the source files in src/ and run `npm run build:css`.
 *
 * @package WBListora
 */

/* === src/variables/colors.css === */
/**
 * WB Listora — v2 colors token layer
 *
 * Single source of truth for ALL color values used across the plugin.
 * Blocks reference these tokens; blocks NEVER hardcode hex literals
 * and NEVER define their own color tokens.
 *
 * @since 1.0.5 (v2 token system — runs in parallel with v1 tokens
 *               in shared.css during migration; v1 removed in Phase 4)
 */

:root {
	/* === Brand ===
	   Community-OS alignment: read BuddyNext's --brand first (matches the host
	   exactly when on BuddyNext), then WP theme.json, then the accent token of
	   the common themes that have no theme.json primary (Astra, Kadence,
	   Blocksy, BuddyBoss, an Elementor kit), then the fallback. Without that
	   chain a purple Astra site got blue Listora buttons (card 10379292712).
	   A site sets its own colour with :root { --listora-primary: ... }. */
	--listora-primary:        var(--brand, var(--wp--preset--color--primary, var(--ast-global-color-0, var(--global-palette1, var(--theme-palette-color-1, var(--bb-primary-color, var(--e-global-color-primary, #2271b1)))))));
	--listora-primary-hover:  var(--brand-hover, color-mix(in srgb, var(--listora-primary) 85%, #000));
	--listora-primary-fg:     #ffffff;

	/* Text that sits on a fixed surface, so it never flips with dark mode:
	   a dark scrim over a photo (card rating, category name, lightbox
	   controls) and the amber rating/featured fill. */
	--listora-on-media:       #ffffff;
	--listora-on-rating:      #2b1a00;

	/*
	 * Brand colour, darkened enough to be READ.
	 *
	 * `--listora-primary` is whatever brand colour the site (or its theme)
	 * chose, and brand colours are picked to stand out on a surface, not to
	 * be legible as small text on one. BuddyX's default #ee4036 measures
	 * 3.62:1 on white — under the 4.5:1 AA floor — so every secondary
	 * button, type badge and Add-to-Compare label rendered in it failed,
	 * on every site that never changed the theme accent (BC 10208336512).
	 *
	 * Listora cannot dictate a site's brand colour, and should not: the
	 * owner picked it. What it can do is stop using the raw value for
	 * SMALL TEXT and use a darkened derivation instead — which works for
	 * whatever colour the owner picks, and is close to a no-op on brands
	 * that are already dark. #ee4036 becomes 7.6:1 on white and clears
	 * 4.5:1 even on the tinted washes these labels sit on, while still
	 * reading unmistakably as the brand.
	 *
	 * Use for brand-coloured TEXT on a light surface. Backgrounds, borders
	 * and large display type keep `--listora-primary`: a 3:1 floor applies
	 * to those, and recolouring them would change the site's look rather
	 * than its legibility.
	 *
	 * A site that wants the exact brand value back overrides this token.
	 *
	 * DELIBERATELY NOT APPLIED TO BRAND BACKGROUNDS under white text — primary
	 * buttons, badge pills, active pagination. Those measure 3.87:1 with
	 * BuddyX's default accent and would reach AA if the BACKGROUND darkened,
	 * but Listora's buttons would then stop matching the theme's own buttons,
	 * which use the same colour and fail identically. Owner decision, taken
	 * 2026-08-18: stay consistent with the theme, because the colour is the
	 * site's choice and diverging fixes our audit while making every install
	 * look inconsistent.
	 *
	 * An owner who must pass an audit gets there in one line, in their theme
	 * or a customiser snippet:
	 *
	 *   :root { --listora-button-bg: var(--listora-primary-text); }
	 *
	 * which darkens Listora's brand-backed controls without touching the
	 * theme's. See docs/architecture/CSS-ARCHITECTURE.md.
	 */
	/* Dark schemes flip the mix toward white (listora-base.css dark blocks):
	   a darkened brand on a dark surface read 1.7:1 (card 10337175822).
	   Re-declared on .listora-block (components/baseline.css) so it follows
	   a brand a bridge or theme sets below :root. */
	--listora-primary-text-mix:    65%;
	--listora-primary-text-toward: #000000;
	--listora-primary-text:   color-mix(in srgb, var(--listora-primary) var(--listora-primary-text-mix), var(--listora-primary-text-toward));

	/* === Semantic status — base / bg / fg triplet === */
	--listora-success:    #16a34a;
	--listora-success-bg: #ecfdf5;
	--listora-success-fg: #166534; /* green-700 read 4.21:1 on its 12% tint */

	--listora-warning:    #d97706;
	--listora-warning-bg: #fef3c7;
	/*
	 * amber-800, not amber-700. `--listora-warning-fg` is the text colour on
	 * warning surfaces, and the tightest of those is not the solid
	 * `--listora-warning-bg` but the 6% tint `.listora-alert--warn` paints —
	 * which composites over wp-admin's #f0f0f1 rather than white, landing at
	 * rgb(239,233,226). #b45309 measured 4.16:1 there, under the AA floor.
	 * #92400e clears both: 5.87:1 on that tint, 6.37:1 on #fef3c7
	 * (BC 10208336512).
	 */
	--listora-warning-fg: #92400e;

	--listora-danger:     #dc2626;
	--listora-danger-bg:  #fef2f2;
	--listora-danger-fg:  #b91c1c;

	--listora-info:       #2563eb;
	--listora-info-bg:    #eff6ff;
	--listora-info-fg:    #1d4ed8;

	--listora-premium:    #7c3aed;
	--listora-premium-bg: #f3e8ff;
	--listora-premium-fg: #6d28d9;

	--listora-favorite:   var(--wp--preset--color--vivid-red, #cf2e2e);
	--listora-rating:     var(--wp--preset--color--luminous-vivid-amber, #f5a623);

	/* === Surface (backgrounds) ===
	   BuddyNext-first so cards/page match the host; theme.json + fallback behind. */
	--listora-bg-base:     var(--bg, var(--wp--preset--color--base, #ffffff));
	--listora-bg-surface:  color-mix(in srgb, var(--listora-bg-elevated) 95%, #1a1a1a);
	--listora-bg-elevated: var(--surface, var(--wp--preset--color--base, #ffffff));
	--listora-bg-muted:    var(--canvas, var(--wp--preset--color--contrast-4, #f5f5f5));
	--listora-bg-inverse:  #1a1a1a;

	/* === Border === */
	--listora-border-default: var(--line, var(--wp--preset--color--contrast-3, #e0e0e0));
	--listora-border-subtle:  #e2e8f0;
	--listora-border-strong:  #c3c4c7;
	--listora-border-divider: #f0f0f0;

	/* === wp-admin compatibility palette ===
	   Used by admin CSS (`assets/css/admin*.css`) only. These tokens match
	   the WordPress core admin design language so the plugin's admin chrome
	   harmonises with native wp-admin elements (settings tables, list
	   tables, postbox headers). Do NOT use on customer-facing surfaces. */
	--listora-wp-admin-text:           #1d2327; /* wp-admin body/heading text */
	--listora-wp-admin-text-strong:    #1e1e1e;
	--listora-wp-admin-text-muted:     #50575e; /* wp-admin secondary text */
	--listora-wp-admin-text-faint:     #787c82; /* wp-admin description / placeholder */
	--listora-wp-admin-text-disabled:  #757575;
	--listora-wp-admin-border:         #dcdcde; /* wp-admin native border */
	--listora-wp-admin-bg-row-hover:   #f0f0f1;
	--listora-wp-admin-link:           #0073aa; /* wp-admin legacy link blue */

	/* === Listora admin-extended neutrals ===
	   Granular shades for the Listora admin UI (between WP-admin and
	   listora-bg-*). Use when WP-admin tokens are too neutral and the
	   listora frontend palette is too saturated. */
	--listora-admin-bg-subtle:    #f7f7f5; /* Listora admin card bg, light */
	--listora-admin-bg-tint:      #f0f6fc; /* WP info-tint background */
	--listora-admin-bg-soft:      #f1f5f9; /* Slate-50 — secondary surface */
	--listora-admin-bg-paper:     #f5f5f5;
	--listora-admin-bg-tertiary:  #f0f0ed; /* Listora admin tertiary surface */
	--listora-admin-border-faint: #ddd;    /* legacy WP border alias */
}

/* === src/variables/spacing.css === */
/**
 * WB Listora — v2 spacing token layer
 *
 * Numeric scale (1..16) replaces the legacy named scale
 * (--listora-gap-xs..3xl). Predictable arithmetic: each step
 * is approximately the previous step + 4px (rem-based).
 *
 * Migration map for shared.css consumers (search-replace, Phase 2):
 *   --listora-gap-xs   → --listora-space-1   (0.25rem / 4px)
 *   --listora-gap-sm   → --listora-space-2   (0.5rem / 8px)
 *   --listora-gap-md   → --listora-space-4   (1rem / 16px)
 *   --listora-gap-lg   → --listora-space-6   (1.5rem / 24px)
 *   --listora-gap-xl   → --listora-space-8   (2rem / 32px)
 *   --listora-gap-2xl  → --listora-space-12  (3rem / 48px)
 *   --listora-gap-3xl  → --listora-space-16  (4rem / 64px)
 *
 * @since 1.0.5 (v2)
 */

:root {
	/* === Spacing scale — rem-based === */
	--listora-space-1:  0.25rem;   /* 4px  */
	--listora-space-2:  0.5rem;    /* 8px  */
	--listora-space-3:  0.75rem;   /* 12px */
	--listora-space-4:  1rem;      /* 16px */
	--listora-space-5:  1.25rem;   /* 20px */
	--listora-space-6:  1.5rem;    /* 24px */
	--listora-space-8:  2rem;      /* 32px */
	--listora-space-12: 3rem;      /* 48px */

	/* === Semantic aliases for the most-common slots === */
	--listora-grid-gap:              var(--listora-space-6);
	--listora-card-padding:          var(--listora-space-4);
	--listora-card-gap:              var(--listora-space-3);
	--listora-form-control-padding:  var(--listora-space-3);

	/* === Tap target minimum (a11y) === */
	--listora-tap-target: 44px;
}

/* === src/variables/typography.css === */
/**
 * WB Listora — v2 typography token layer
 *
 * Resolves the legacy --listora-text-* namespace overload (used
 * for both size AND foreground color). Splits into:
 *
 *   --listora-text-size-{xs..4xl}   (size)
 *   --listora-fg-{default,strong,muted,faint,inverse,...}   (color)
 *
 * Migration map (search-replace, Phase 2):
 *   --listora-text-xs (size)   → --listora-text-size-xs
 *   --listora-text-sm (size)   → --listora-text-size-sm
 *   --listora-text-base (size) → --listora-text-size-base
 *   --listora-text-lg (size)   → --listora-text-size-lg
 *   --listora-text-xl (size)   → --listora-text-size-xl
 *   --listora-text-2xl (size)  → --listora-text-size-2xl
 *   --listora-text-3xl (size)  → --listora-text-size-3xl
 *   (new)                       → --listora-text-size-4xl
 *
 *   --listora-text (color)     → --listora-fg-default
 *   --listora-text-strong      → --listora-fg-strong
 *   --listora-text-secondary   → --listora-fg-muted
 *   --listora-text-muted       → --listora-fg-faint
 *   --listora-text-faint       → --listora-fg-faint
 *   --listora-text-inverse     → --listora-fg-inverse
 *
 * @since 1.0.5 (v2)
 */

:root {
	/* === Type size scale — rem-based === */
	--listora-text-size-xs:   0.75rem;    /* 12px */
	--listora-text-size-sm:   0.875rem;   /* 14px */
	--listora-text-size-base: 1rem;       /* 16px */
	--listora-text-size-lg:   1.125rem;   /* 18px */
	--listora-text-size-xl:   1.25rem;    /* 20px */
	--listora-text-size-2xl:  1.5rem;     /* 24px */
	--listora-text-size-3xl:  1.875rem;   /* 30px */

	/* === Line heights === */
	--listora-line-tight:   1.25;
	--listora-line-snug:    1.375;
	--listora-line-base:    1.5;

	/* === Font weights === */
	--listora-weight-normal:   400;
	--listora-weight-medium:   500;
	--listora-weight-semibold: 600;
	--listora-weight-bold:     700;

	/* === Letter spacing === */
	--listora-tracking-wide:  0.01em;

	/* === Foreground (text) colors — semantic ===
	   Listora-owned, not read from the theme's contrast presets: a theme's
	   body grey is chosen for its own surfaces, and Reign's default #7b7b7b
	   measured 4.23:1 on white (3.85:1 on Listora's muted surfaces). Dark
	   schemes re-bind these in listora-base.css (cards 10340592969,
	   10337175822). */
	--listora-fg-default:    #1a1a1a;
	--listora-fg-strong:     #1a1a1a;
	--listora-fg-muted:      #555555;
	/*
	 * #6f6f6f, not #999999. The old fallback measured 2.85:1 on white and
	 * 2.73:1 on the page surface — both well under the 4.5:1 AA floor, and it
	 * carries real information (dashboard timestamps, result counts, member
	 * email), so the large-text exemption does not apply (BC 10208336512).
	 * #6f6f6f clears 4.5 on every surface we paint: 5.02 on #ffffff, 4.81 on
	 * #fafafa, 4.70 on #f7f7f9. #767676 — the usual "AA grey" — passes on
	 * white but only reaches 4.35 on #fafafa, so it is not enough here.
	 */
	/* Listora's own value, not the theme's contrast-3 preset: faint text
	   carries counts and metadata, and presets measured 4.34:1 on Listora's
	   muted surfaces (#64748b on #f1f5f9). #5b6472 is 5.3:1 there, 5.9:1 on
	   white (cards 10340592969, 10337175822). */
	--listora-fg-faint:      #5b6472;
	--listora-fg-inverse:    #ffffff;
	--listora-fg-danger:     var(--listora-danger-fg);

	/* === BC aliases — the v1 → v2 migration map documented above, never
	   actually declared. email-templates.css and ~20 other call sites across
	   the plugin still read these v1 names with no fallback (color: var(
	   --listora-text) resolves to nothing without this block). Card
	   10351203844 (Tier 1). Prefer the v2 names in new code; this block only
	   keeps existing call sites correct until they're migrated. */
	--listora-text:           var(--listora-fg-default);
	--listora-text-strong:    var(--listora-fg-strong);
	--listora-text-secondary: var(--listora-fg-muted);
	--listora-text-muted:     var(--listora-fg-faint);
	--listora-text-faint:     var(--listora-fg-faint);
	--listora-text-inverse:   var(--listora-fg-inverse);
	/* v1 name, not part of the documented map above but read the same way
	   (bare, no fallback) — assets/css/admin/email-templates.css:29,64. */
	--listora-fg:             var(--listora-fg-default);
}

/* === src/variables/radius.css === */
/**
 * WB Listora — v2 radius token layer
 *
 * Border-radius scale + semantic aliases.
 *
 * @since 1.0.5 (v2)
 */

:root {
	--listora-radius-sm:   6px;
	--listora-radius-md:   10px;
	--listora-radius-lg:   14px;
	--listora-radius-xl:   20px;
	--listora-radius-full: 9999px;

	/* === Semantic aliases === */
	--listora-card-radius:   var(--listora-radius-md);
	--listora-input-radius:  var(--listora-radius-sm);
	--listora-button-radius: var(--listora-radius-sm);
	--listora-pill-radius:   var(--listora-radius-full);
	--listora-modal-radius:  var(--listora-radius-lg);
}

/* === src/variables/shadow.css === */
/**
 * WB Listora — v2 shadow token layer
 *
 * Elevation scale + focus ring + semantic aliases.
 *
 * @since 1.0.5 (v2)
 */

:root {
	/* Community-OS alignment: read BuddyNext's soft layered --bn-shadow-* first,
	   matching standalone fallback, so elevation is uniform across the suite. */
	--listora-shadow-xs: var(--bn-shadow-xs, 0 1px 2px rgba(0, 0, 0, 0.04));
	--listora-shadow-sm: var(--bn-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04));
	--listora-shadow-md: var(--bn-shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05));
	--listora-shadow-lg: var(--bn-shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04));
	--listora-shadow-xl: var(--bn-shadow-lg, 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04));

	/* === Focus ring — 2px inner halo + 2px brand ring === */
	--listora-focus-ring: 0 0 0 2px var(--listora-bg-elevated), 0 0 0 4px var(--listora-primary);

	/* === Semantic aliases === */
	--listora-card-shadow-hover: var(--listora-shadow-lg);
	--listora-modal-shadow:      var(--listora-shadow-xl);
}

/* === src/variables/motion.css === */
/**
 * WB Listora — v2 motion token layer
 *
 * Transition durations + easing curves. Respects prefers-reduced-motion.
 *
 * @since 1.0.5 (v2)
 */

:root {
	--listora-transition-fast: 0.1s ease;
	--listora-transition-base: 0.2s ease;
	--listora-transition-slow: 0.35s cubic-bezier(0.4, 0, 0.2, 1);

	/* === Easing curves === */
	--listora-ease-out:    cubic-bezier(0, 0, 0.2, 1);
	--listora-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (prefers-reduced-motion: reduce) {
	:root {
		--listora-transition-fast: 0.01ms ease;
		--listora-transition-base: 0.01ms ease;
		--listora-transition-slow: 0.01ms ease;
	}
}
}
