/* ==========================================================================
   Jexii Builder — supplemental theme styles

   Design tokens (color, typography, spacing, shadows) live in theme.json.
   This file holds only the few rules that theme.json cannot express.

   PRINCIPLE: this theme should be able to house any brand. Every color
   reference resolves to a theme.json token via CSS variables — no
   hardcoded hex/rgba palette values — so a child theme that swaps the
   palette gets a coherent re-brand without fighting parent CSS.

   OPINIONATED EFFECTS (atmospheric texture, gradient buttons, card
   hover-lift) are opt-IN via block styles or body classes — the theme
   defaults are quiet and neutral; LR's distinctive look is one named
   variation, not the only one.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Layout: remove the default block gap between the header, main, and footer
   template parts so site sections sit flush.
   -------------------------------------------------------------------------- */

body > .wp-site-blocks > * {
	margin-block: 0;
}


/* --------------------------------------------------------------------------
   Stacked full-width sections sit flush.

   In a constrained layout the global block gap is added as a top margin on
   every section after the first, leaving a sliver of page background between
   adjacent full-bleed bands. Zero it so consecutive full-width sections butt
   together (the common marketing-page look). Scoped to .alignfull + .alignfull
   so wide and normal sections keep their normal rhythm.

   This is only a DEFAULT: a per-section top margin overrides it.
   -------------------------------------------------------------------------- */

.is-layout-constrained > .alignfull + .alignfull {
	margin-block-start: 0;
}


/* --------------------------------------------------------------------------
   Responsive safety net: prevent horizontal scroll from full-bleed sections
   or image breakouts. overflow-x only — never overflow-y (would break sticky).
   -------------------------------------------------------------------------- */

html,
body {
	overflow-x: clip;
	max-width: 100%;
}


/* --------------------------------------------------------------------------
   Atmospheric texture — OPT-IN.

   Faint blueprint grid + film grain overlay. Originally shipped as the
   default for Lantern Row's blueprint-themed feel. Now opt-in via a body
   class so sites with different brand expressions (warm, playful,
   high-contrast) aren't forced into the cool-blueprint aesthetic.

   To enable on a site: add the .has-jxb-atmosphere class to <body> via
   a body_class filter (typical for Lantern Row, Jexii.com).

   Both layers ignore pointer events and inherit the primary palette token,
   so the grid color follows the active palette rather than being literally
   blue on every site.
   -------------------------------------------------------------------------- */

body.has-jxb-atmosphere::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background-image:
		linear-gradient(color-mix(in srgb, var(--wp--preset--color--primary) 5%, transparent) 1px, transparent 1px),
		linear-gradient(90deg, color-mix(in srgb, var(--wp--preset--color--primary) 5%, transparent) 1px, transparent 1px);
	background-size: 48px 48px;
	-webkit-mask-image: radial-gradient(120% 80% at 50% -10%, #000 35%, transparent 78%);
	mask-image: radial-gradient(120% 80% at 50% -10%, #000 35%, transparent 78%);
}

body.has-jxb-atmosphere::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	opacity: 0.025;
	mix-blend-mode: soft-light;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}


/* --------------------------------------------------------------------------
   Buttons.

   Default: flat. Background = primary token; text = base token (palette
   resolves per child theme). Smooth transitions on hover. The hover shadow
   color is derived from the primary token via color-mix so a brand swap
   produces a correctly-colored glow.

   Gradient lift (the LR look) is opt-in: add the block-style class
   .is-style-jxb-gradient to a button. Outline style remains untouched.
   -------------------------------------------------------------------------- */

.wp-block-button .wp-block-button__link {
	transition: box-shadow 0.25s ease, transform 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}

/* Gradient-button block style — opt-in. */
.wp-block-button.is-style-jxb-gradient .wp-block-button__link:not(.has-background) {
	background: linear-gradient(
		180deg,
		var(--wp--preset--color--primary-light, var(--wp--preset--color--primary)),
		var(--wp--preset--color--primary)
	);
}

/* Secondary-button block style — solid accent-dark fill, ink text. Same
   geometry as the default button; color subset is the only differentiator.
   A faint inner ring keeps it defined when it sits on a same-hue surface
   (e.g. a deep-yellow button on a pale-yellow hero band). */
.wp-block-button.is-style-jxb-secondary .wp-block-button__link {
	background: var(--wp--preset--color--accent-dark, var(--wp--preset--color--accent)) !important;
	color: var(--wp--preset--color--ink) !important;
	box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--wp--preset--color--ink) 14%, transparent);
}

.wp-block-button.is-style-jxb-secondary .wp-block-button__link:hover {
	background: color-mix(in srgb, var(--wp--preset--color--accent-dark, var(--wp--preset--color--accent)) 85%, var(--wp--preset--color--ink)) !important;
	color: var(--wp--preset--color--ink) !important;
}

.wp-block-button.is-style-jxb-gradient .wp-block-button__link:hover,
.wp-block-button:not(.is-style-outline) .wp-block-button__link:hover {
	box-shadow: 0 10px 38px -10px color-mix(in srgb, var(--wp--preset--color--primary) 45%, transparent);
	transform: translateY(-1px);
}


/* --------------------------------------------------------------------------
   Vertical rhythm in hero / CTA stacks.
   -------------------------------------------------------------------------- */

.jxb-measure-hero .wp-block-buttons,
.jxb-measure-cta .wp-block-buttons {
	margin-top: 1.5rem;
}

.wp-block-buttons + p.has-small-font-size {
	margin-top: 0.875rem !important;
}


/* --------------------------------------------------------------------------
   Heading font-size slugs (h1–h4): kebab-casing mismatch shim.
   theme.json registers h1/h2/h3/h4 slugs which WP kebab-cases to h-1..h-4.
   Re-point the un-hyphenated utility classes at WordPress's actual vars.
   -------------------------------------------------------------------------- */

.has-h1-font-size { font-size: var(--wp--preset--font-size--h-1) !important; }
.has-h2-font-size { font-size: var(--wp--preset--font-size--h-2) !important; }
.has-h3-font-size { font-size: var(--wp--preset--font-size--h-3) !important; }
.has-h4-font-size { font-size: var(--wp--preset--font-size--h-4) !important; }


/* --------------------------------------------------------------------------
   Palette-slug collision fix. The palette color slug "border" makes
   WordPress emit `.has-border-color { color: var(...border) }` — a text
   color utility. Block border support adds an identically named class to
   any bordered block. Scope the reset to bordered blocks that don't set
   their own text color.
   -------------------------------------------------------------------------- */

.has-border-color:not(.has-text-color) {
	color: inherit !important;
}


/* --------------------------------------------------------------------------
   Color-scheme block styles for the Group block.
   Light / Soft / Dark / Brand mappings of the palette. All values come
   from tokens — palette swap reflows automatically.
   -------------------------------------------------------------------------- */

.wp-block-group.is-style-jxb-light {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
}

.wp-block-group.is-style-jxb-soft {
	background:
		radial-gradient(130% 90% at 50% 0%,
			color-mix(in srgb, var(--wp--preset--color--accent) 8%, var(--wp--preset--color--surface)),
			var(--wp--preset--color--surface) 62%);
	color: var(--wp--preset--color--ink);
}

.wp-block-group.is-style-jxb-dark {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--base);
}

.wp-block-group.is-style-jxb-brand {
	background: linear-gradient(
		135deg,
		var(--wp--preset--color--ink) 0%,
		var(--wp--preset--color--primary) 100%
	);
	color: var(--wp--preset--color--base);
}

.wp-block-group.is-style-jxb-dark :where(h1, h2, h3, h4, h5, h6),
.wp-block-group.is-style-jxb-brand :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--base);
}

.wp-block-group.is-style-jxb-dark a:not(.wp-element-button),
.wp-block-group.is-style-jxb-brand a:not(.wp-element-button) {
	color: var(--wp--preset--color--accent);
}

/* Scheme-override safety net so palette-coded text classes flip per scheme. */
.wp-block-group.is-style-jxb-light .has-base-color,
.wp-block-group.is-style-jxb-light .has-on-dark-color,
.wp-block-group.is-style-jxb-light .has-on-dark-soft-color,
.wp-block-group.is-style-jxb-soft  .has-base-color,
.wp-block-group.is-style-jxb-soft  .has-on-dark-color,
.wp-block-group.is-style-jxb-soft  .has-on-dark-soft-color {
	color: var(--wp--preset--color--ink) !important;
}

.wp-block-group.is-style-jxb-dark  .has-ink-color,
.wp-block-group.is-style-jxb-dark  .has-primary-dark-color,
.wp-block-group.is-style-jxb-brand .has-ink-color,
.wp-block-group.is-style-jxb-brand .has-primary-dark-color {
	color: var(--wp--preset--color--base) !important;
}

.wp-block-group.is-style-jxb-dark  .has-ink-soft-color,
.wp-block-group.is-style-jxb-dark  .has-muted-color,
.wp-block-group.is-style-jxb-brand .has-ink-soft-color,
.wp-block-group.is-style-jxb-brand .has-muted-color {
	color: var(--wp--preset--color--on-dark) !important;
}


/* --------------------------------------------------------------------------
   Eyebrow + label treatments. Mono-tracked uppercase is the default; child
   themes can override the font and tracking via the eyebrow size class.
   The eyebrow color is unset by default (inherits) so a child theme using
   the eyebrow on yellow vs blue vs dark can choose appropriately.
   -------------------------------------------------------------------------- */

:where(p.has-eyebrow-font-size),
.jxb-label,
.jxb-label-strong {
	text-transform: uppercase;
}

p.has-eyebrow-font-size {
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 500;
	letter-spacing: var(--wp--custom--tracking--eyebrow);
}

.wp-block-group.is-style-jxb-light p.has-eyebrow-font-size,
.wp-block-group.is-style-jxb-soft  p.has-eyebrow-font-size,
.wp-block-group.is-style-jxb-light .jxb-label,
.wp-block-group.is-style-jxb-soft  .jxb-label {
	color: var(--wp--preset--color--primary) !important;
}

.jxb-label {
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 500;
	letter-spacing: var(--wp--custom--tracking--label);
}

.jxb-label-strong {
	font-family: var(--wp--preset--font-family--mono);
	font-weight: var(--wp--custom--weight--bold);
	letter-spacing: var(--wp--custom--tracking--tight);
}

.jxb-bold {
	font-weight: var(--wp--custom--weight--bold);
}


/* --------------------------------------------------------------------------
   Cards / tiles / panels.

   Default card = flat fill, simple ring border, no hover transform. Quiet.

   Lift-on-hover (the LR/Stripe-feature-tile look) is OPT-IN via the block
   style .is-style-jxb-lift. Hover glow color resolves to the primary token
   so child themes get correctly-colored lift.

   Accent-bordered "highlighted" cards (pricing's most-popular) keep their
   accent ring; the soft glow on hover resolves to the accent token.
   -------------------------------------------------------------------------- */

.wp-block-group.has-border-color.has-base-background-color {
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--base) !important;
	box-shadow:
		0 1px 3px 0 rgba(0, 0, 0, 0.04),
		0 0 0 1px var(--wp--preset--color--border);
	border-width: 0 !important;
	transition: box-shadow 0.3s ease, transform 0.3s ease;
}

/* Lift-on-hover — opt-in. */
.wp-block-group.is-style-jxb-lift.has-border-color.has-base-background-color:hover {
	transform: translateY(-2px);
	box-shadow:
		0 18px 54px -30px color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent),
		0 0 0 1px var(--wp--preset--color--primary);
}

.wp-block-group.has-accent-border-color.has-base-background-color {
	border-radius: var(--wp--custom--radius--sm);
	box-shadow:
		0 4px 16px -4px color-mix(in srgb, var(--wp--preset--color--accent) 20%, transparent),
		0 0 0 2px var(--wp--preset--color--accent);
	border-width: 0 !important;
	transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.wp-block-group.is-style-jxb-lift.has-accent-border-color.has-base-background-color:hover {
	transform: translateY(-2px);
	box-shadow:
		0 18px 54px -28px color-mix(in srgb, var(--wp--preset--color--accent) 40%, transparent),
		0 0 0 2px var(--wp--preset--color--accent);
}

.wp-block-group.has-border-color.has-surface-background-color {
	border-radius: var(--wp--custom--radius--sm);
}


/* --------------------------------------------------------------------------
   Plan-tier system — crisp microlabels, a "what's free" checklist, and
   left-aligned upgrade cards. Tier identity reads through COLOUR, not pastel
   fills: a coloured dot + uppercase mono label (free = teal, starter = blue,
   pro = purple). These three tones are a fixed product-tier palette, kept
   independent of the site brand so tier meaning reads the same on any skin.
   -------------------------------------------------------------------------- */

/* Tier microlabel: a leading colour dot + tracked uppercase mono. No fill. */
.jxb-tier-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.6em;
	margin: 0;
	padding: 0;
	background: none;
	border-radius: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.12em;
	line-height: 1.2;
	text-transform: uppercase;
}
.jxb-tier-pill::before {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-radius: 999px;
	background: currentColor;
}
.jxb-tier-pill.jxb-tier-free    { color: #0f6e56; }
.jxb-tier-pill.jxb-tier-starter { color: #185fa5; }
.jxb-tier-pill.jxb-tier-pro     { color: #534ab7; }

/* Free checklist — title-only; crisp white check in a solid teal disc. */
.jxb-checklist {
	list-style: none;
	padding-left: 0;
	margin: 0;
}
.jxb-checklist li {
	position: relative;
	padding-left: 1.85em;
	margin: 0 0 0.8rem;
	font-weight: 500;
	line-height: 1.4;
}
.jxb-checklist li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.1em;
	width: 1.15em;
	height: 1.15em;
	border-radius: 999px;
	background:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-6.5'/%3E%3C/svg%3E") center / 0.72em no-repeat,
		#1d9e75;
}

/* Tier upgrade cards. Left-align the content — WordPress's constrained layout
   auto-centres a card's children (margin-inline:auto), which reads as dated;
   pin them left. The coloured microlabel carries the tier; no top bar. */
.jxb-tier-card.is-layout-constrained > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
	max-width: none !important;
}
.jxb-tier-card .jxb-tier-pill {
	margin-bottom: 0.5rem;
}


/* --------------------------------------------------------------------------
   HUD product panel — shows the product instead of only describing it.
   Light glass with HUD corners, a mono status line, a SERP preview, score
   chips, and analysis rows. Modelled on the Luxii metadata panel; this is
   the device that makes a page read as a real product rather than a flyer.
   -------------------------------------------------------------------------- */

.jxb-hud {
	position: relative;
	background: linear-gradient(180deg, #ffffff, #eef8f7);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 12px;
	box-shadow:
		0 44px 90px -42px rgba(16, 42, 64, 0.30),
		inset 0 1px 0 rgba(255, 255, 255, 0.9);
	padding: 1.5rem 1.5rem 1.6rem;
	overflow: hidden;
	font-family: var(--wp--preset--font-family--geist);
}
.jxb-hud::before,
.jxb-hud::after {
	content: "";
	position: absolute;
	width: 14px;
	height: 14px;
	border: 1.5px solid var(--wp--preset--color--accent);
	opacity: 0.7;
	pointer-events: none;
}
.jxb-hud::before { top: 10px; left: 10px; border-right: 0; border-bottom: 0; }
.jxb-hud::after  { bottom: 10px; right: 10px; border-left: 0; border-top: 0; }

.jxb-hud__head {
	display: flex;
	align-items: center;
	gap: 0.55em;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	margin-bottom: 1rem;
}
.jxb-hud__dot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
	box-shadow: 0 0 12px var(--wp--preset--color--accent);
	animation: jxb-hud-blink 2.4s steps(1) infinite;
}
@keyframes jxb-hud-blink { 0%, 70% { opacity: 1; } 71%, 100% { opacity: 0.35; } }

.jxb-hud__serp {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 8px;
	background: #fff;
	padding: 0.85rem 1rem;
}
.jxb-hud__url { font-size: 12px; color: var(--wp--preset--color--muted); }
.jxb-hud__title {
	color: #1a0dab;
	font-size: 18px;
	font-weight: 600;
	line-height: 1.25;
	margin: 0.15rem 0;
}
.jxb-hud__desc { font-size: 13px; line-height: 1.45; color: var(--wp--preset--color--ink-soft); }

.jxb-hud__scores { display: flex; gap: 0.6rem; margin: 1rem 0; }
.jxb-hud__score {
	flex: 1;
	text-align: center;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 8px;
	background: #fff;
	padding: 0.6rem 0.3rem;
}
.jxb-hud__score b {
	display: block;
	font-family: var(--wp--preset--font-family--outfit);
	font-size: 26px;
	font-weight: 700;
	line-height: 1;
	color: var(--wp--preset--color--primary);
}
.jxb-hud__score span {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.jxb-hud__rows { display: grid; gap: 0.55rem; }
.jxb-hud__row {
	display: flex;
	align-items: center;
	gap: 0.6em;
	font-size: 13px;
	color: var(--wp--preset--color--ink);
}
.jxb-hud__row::before {
	content: "";
	flex: none;
	width: 1.15em;
	height: 1.15em;
	border-radius: 50%;
}
.jxb-hud__row.ok::before {
	background:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-6.5'/%3E%3C/svg%3E") center / 0.72em no-repeat,
		#1d9e75;
}
.jxb-hud__row.warn::before {
	background:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23ffffff' d='M7 3.2h2v5.6H7zM7 10.6h2v2.2H7z'/%3E%3C/svg%3E") center / 0.85em no-repeat,
		#e0a93f;
}

/* Hero that carries a HUD panel: two columns, content left-aligned. */
.jxb-hero-split { align-items: center; }
@media (max-width: 781px) {
	.jxb-hud { margin-top: var(--wp--preset--spacing--40); }
}

/* HUD panel body variants — shared design language, different content per
   plugin so every hero reads as the same product family. */

/* Neutral (pending) row state, beside the existing .ok / .warn. */
.jxb-hud__row.neut::before {
	background: #fff;
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--border);
}

/* Usage / progress bar (Dashboard, pSEO counts). */
.jxb-hud__bar {
	margin-top: 0.9rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
.jxb-hud__bar > span { display: flex; justify-content: space-between; margin-bottom: 0.35rem; }
.jxb-hud__bar i {
	display: block;
	height: 7px;
	border-radius: 999px;
	background: var(--wp--preset--color--border);
	overflow: hidden;
}
.jxb-hud__bar i::before {
	content: "";
	display: block;
	height: 100%;
	width: var(--fill, 60%);
	border-radius: 999px;
	background: linear-gradient(90deg, var(--wp--preset--color--primary), var(--wp--preset--color--accent));
}

/* Thumbnail grid (Stock) — gradient tiles standing in for photos, each with a
   provider badge. */
.jxb-hud__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.jxb-hud__grid > div {
	position: relative;
	aspect-ratio: 4 / 3;
	border-radius: 6px;
	overflow: hidden;
	background: linear-gradient(135deg, #cfe6e7, #9cc6d8 60%, #5b8fb0);
}
.jxb-hud__grid > div:nth-child(2) { background: linear-gradient(135deg, #d9e4c7, #97b386 60%, #5f7e63); }
.jxb-hud__grid > div:nth-child(3) { background: linear-gradient(135deg, #e6d6c9, #c39f88 55%, #8a6f5c); }
.jxb-hud__grid > div:nth-child(4) { background: linear-gradient(135deg, #cdd4e6 0%, #8f9ec4 60%, #5f6f9c); }
.jxb-hud__grid > div:nth-child(5) { background: linear-gradient(135deg, #e8cfd6, #c389a0 55%, #8a5c74); }
.jxb-hud__grid > div:nth-child(6) { background: linear-gradient(135deg, #cfe0e6, #8fb6c4 60%, #5f8a9c); }
.jxb-hud__grid b {
	position: absolute;
	left: 6px;
	bottom: 6px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 9px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: #fff;
	background: rgba(16, 32, 46, 0.55);
	padding: 2px 6px;
	border-radius: 4px;
}

/* Image + metadata fields (Optimize). */
.jxb-hud__meta { display: grid; grid-template-columns: 84px 1fr; gap: 0.9rem; align-items: start; }
.jxb-hud__meta > .jxb-hud__thumb {
	aspect-ratio: 1;
	border-radius: 8px;
	background: linear-gradient(135deg, #cfe6e7, #8fb6c4 55%, #4e7a8c);
}
.jxb-hud__field { font-size: 12.5px; line-height: 1.4; margin-bottom: 0.5rem; }
.jxb-hud__field b {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 9.5px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	margin-bottom: 0.1rem;
}
.jxb-hud__field span { color: var(--wp--preset--color--ink); }

/* Mini ranking chart (Insights). */
.jxb-hud__chart { display: flex; align-items: flex-end; gap: 5px; height: 60px; margin-bottom: 0.9rem; }
.jxb-hud__chart i {
	flex: 1;
	border-radius: 3px 3px 0 0;
	background: linear-gradient(180deg, var(--wp--preset--color--accent), var(--wp--preset--color--primary));
	opacity: 0.85;
}


/* --------------------------------------------------------------------------
   Richness layer — gradient ink, an animated glow, and a scrolling marquee.
   The visual language that reads as a modern product (after luxii.app).
   -------------------------------------------------------------------------- */

/* Gradient ink for large headings on light sections. Deep blue → teal so the
   start stays dark/legible and the tail carries the brand accent. Large text
   only (it would fail contrast at body size). */
.jxb-gradient-text {
	background: linear-gradient(112deg,
		var(--wp--preset--color--primary-dark) 0%,
		var(--wp--preset--color--primary) 46%,
		var(--wp--preset--color--accent) 100%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* Animated radial glow behind a hero/section. Sits below content; the host's
   direct children are lifted above it. */
.jxb-glow { position: relative; }
.jxb-glow::before {
	content: "";
	position: absolute;
	z-index: 0;
	top: -180px;
	right: -90px;
	width: 620px;
	height: 620px;
	max-width: 80vw;
	pointer-events: none;
	background: radial-gradient(circle,
		color-mix(in srgb, var(--wp--preset--color--accent) 20%, transparent),
		color-mix(in srgb, var(--wp--preset--color--primary) 6%, transparent) 44%,
		transparent 68%);
	filter: blur(8px);
	animation: jxb-glow 9s ease-in-out infinite alternate;
}
.jxb-glow > * { position: relative; z-index: 1; }
@keyframes jxb-glow {
	from { opacity: 0.5; transform: scale(0.95); }
	to   { opacity: 1;   transform: scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
	.jxb-glow::before, .jxb-hud__dot, .jxb-marquee__track { animation: none; }
}

/* Scrolling capability marquee — masked at the edges, mono caps with teal
   markers. The track holds the list twice; -50% translate loops seamlessly. */
.jxb-marquee {
	overflow: hidden;
	border-block: 1px solid var(--wp--preset--color--border);
	padding: 0.9rem 0;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.jxb-marquee__track {
	display: flex;
	width: max-content;
	gap: 2.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	animation: jxb-marquee 42s linear infinite;
}
.jxb-marquee__track li {
	display: flex;
	align-items: center;
	gap: 0.6em;
	white-space: nowrap;
	margin: 0;
}
.jxb-marquee__track li::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 999px;
	background: var(--wp--preset--color--accent);
	flex: none;
}
@keyframes jxb-marquee { to { transform: translateX(-50%); } }


/* --------------------------------------------------------------------------
   "Most popular" corner ribbon. A diagonal banner pinned to the card corner,
   OUT of the content flow — so the highlighted card's title and price stay
   baseline-aligned with the sibling cards instead of being pushed down by an
   inline label. The host card opts in by containing a direct-child .jxb-ribbon.
   -------------------------------------------------------------------------- */

.wp-block-group:has(> .jxb-ribbon) {
	position: relative;
	overflow: hidden;
}
.jxb-ribbon {
	position: absolute;
	top: 24px;
	right: -54px;
	width: 185px;
	margin: 0;
	padding: 6px 0;
	transform: rotate(45deg);
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	text-align: center;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	box-shadow: 0 4px 10px -3px rgba(16, 42, 64, 0.35);
}

.wp-block-group.jxb-panel {
	border-radius: var(--wp--custom--radius--xl);
}

/* Equal-height cards in a row. */
.wp-block-column:has(> .wp-block-group.has-border-color.has-base-background-color) {
	display: flex;
	flex-direction: column;
}

.wp-block-column > .wp-block-group.has-border-color.has-base-background-color {
	flex: 1 0 auto;
}


/* --------------------------------------------------------------------------
   DESIGN RULE: uniform card media.

   Any image inside a card that carries .jxb-card-media is forced to a
   uniform aspect ratio with object-fit: cover, so a row of cards always
   shows identically-sized media regardless of the source image dimensions.
   No distortion — the image crops to fill.

   The ratio is themeable: child themes override --jxb-card-media-ratio
   (default 4/3). Per-instance override: set the custom property inline.
   -------------------------------------------------------------------------- */

:root {
	--jxb-card-media-ratio: 4 / 3;
}

.jxb-card-media img {
	aspect-ratio: var(--jxb-card-media-ratio);
	object-fit: cover;
	width: 100%;
	height: auto;
}

/* --------------------------------------------------------------------------
   Image fit — editor block styles (core/image), set in the Styles panel.
   "Crop to fill" makes any image a uniform cover tile (crops edges); "Fit"
   shows the whole image at its natural ratio (no crop) — for diagrams, game
   boards, tables, anything where cropping loses information. "Fit" wins over
   the .jxb-card-media cover default via !important so it can be applied to a
   card image to un-crop it.
   -------------------------------------------------------------------------- */
.wp-block-image.is-style-jxb-cover img {
	aspect-ratio: var(--jxb-card-media-ratio, 4 / 3);
	object-fit: cover;
	width: 100%;
	height: auto;
}
.wp-block-image.is-style-jxb-contain img {
	aspect-ratio: auto !important;
	object-fit: contain !important;
	height: auto !important;
}


/* --------------------------------------------------------------------------
   DESIGN RULE: bottom-justified card actions.

   Inside equal-height cards, a Buttons block that is the card's last child
   pins to the bottom of the card, so a row of cards always shows its CTAs
   on one line regardless of how much copy each card carries.

   The card group must be a flex column for margin-top:auto to work. The
   equal-height rule above already makes the COLUMN a flex container; this
   makes the CARD itself one too. Constrained-layout sibling margins keep
   applying, so the card's internal rhythm is unchanged.
   -------------------------------------------------------------------------- */

.wp-block-column > .wp-block-group.has-border-color.has-base-background-color {
	display: flex;
	flex-direction: column;
}

.wp-block-column > .wp-block-group.has-border-color.has-base-background-color > .wp-block-buttons:last-child {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--30);
}


/* --------------------------------------------------------------------------
   DESIGN RULE: section headers align with their content grid.

   A Group carrying .jxb-section-head (typically alignwide, placed above an
   alignwide card grid) caps its text children at the narrow measure for
   readability — but pins them to the LEFT edge of the container instead of
   centering. This keeps the eyebrow/heading/intro visually attached to the
   grid below it: same left edge, no floating-indent mismatch.

   For a centered section header (hero-style), use .jxb-measure-narrow
   as before — that one centers.
   -------------------------------------------------------------------------- */

.jxb-section-head.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--narrow);
	margin-left: 0;
	margin-right: auto;
}


/* --------------------------------------------------------------------------
   Comparison table (section-comparison-table).
   -------------------------------------------------------------------------- */

.wp-block-table.jxb-compare {
	overflow-x: auto;
}

.wp-block-table.jxb-compare table {
	width: 100%;
	border-collapse: collapse;
}

.wp-block-table.jxb-compare th,
.wp-block-table.jxb-compare td {
	padding: 0.75rem 1rem;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--border);
	text-align: center;
	vertical-align: middle;
}

.wp-block-table.jxb-compare thead th {
	font-family: var(--wp--preset--font-family--outfit);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	border-bottom-width: 2px;
}

.wp-block-table.jxb-compare thead th:first-child,
.wp-block-table.jxb-compare tbody td:first-child {
	text-align: left;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.wp-block-table.jxb-compare tbody tr:last-child td {
	border-bottom: 0;
}


/* --------------------------------------------------------------------------
   FAQ accordion (section-faq).
   -------------------------------------------------------------------------- */

.wp-block-details.jxb-faq {
	border-top: 1px solid var(--wp--preset--color--border);
	padding: var(--wp--preset--spacing--30) 0;
}

.wp-block-details.jxb-faq:last-of-type {
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.wp-block-details.jxb-faq summary {
	cursor: pointer;
	font-family: var(--wp--preset--font-family--outfit);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
}

.wp-block-details.jxb-faq summary::-webkit-details-marker {
	display: none;
}

.wp-block-details.jxb-faq summary::after {
	content: "+";
	font-weight: 400;
	font-size: 1.25em;
	line-height: 1;
	color: var(--wp--preset--color--accent);
}

.wp-block-details.jxb-faq[open] summary::after {
	content: "−";
}

.wp-block-details.jxb-faq > :not(summary) {
	margin-top: var(--wp--preset--spacing--20);
	margin-bottom: 0;
	color: var(--wp--preset--color--ink-soft);
}


/* --------------------------------------------------------------------------
   Navigation. Menu links inherit the heading font family from the site
   title's choice; mobile dropdown is compact, anchored to the header.
   -------------------------------------------------------------------------- */

.wp-block-navigation {
	font-family: var(--wp--preset--font-family--outfit);
	font-weight: 500;
}

/* Header: sticky bar with a hairline bottom border. Background uses a
   palette-derived translucent fill via color-mix; child themes get the
   right tint automatically. The frosted blur is preserved. */
.jxb-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: color-mix(in srgb, var(--wp--preset--color--base) 80%, transparent);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--wp--preset--color--border);
}

body.admin-bar .jxb-header {
	top: 32px;
}

@media (max-width: 782px) {
	body.admin-bar .jxb-header {
		top: 46px;
	}
}

.jxb-header .wp-block-navigation.is-responsive {
	position: static !important;
}

.wp-block-navigation__responsive-container-open {
	color: var(--wp--preset--color--ink);
}

.wp-block-navigation__responsive-container-open svg {
	width: 24px;
	height: 24px;
}

.wp-block-navigation__responsive-container.is-menu-open {
	position: absolute !important;
	top: 100% !important;
	right: 0 !important;
	bottom: auto !important;
	left: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	background: var(--wp--preset--color--base) !important;
	border-top: 1px solid var(--wp--preset--color--border) !important;
	box-shadow: 0 8px 24px -4px rgba(0, 0, 0, 0.08) !important;
	animation: jxb-nav-drop 0.15s ease;
}

@keyframes jxb-nav-drop {
	from { opacity: 0; transform: translateY(-4px); }
	to   { opacity: 1; transform: translateY(0); }
}

body.has-modal-open {
	overflow: initial !important;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-close {
	position: static !important;
	top: auto !important;
	left: auto !important;
	right: auto !important;
	bottom: auto !important;
	width: 100% !important;
	padding: 0 !important;
	min-height: 0 !important;
	height: auto !important;
	flex: 0 0 auto !important;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-dialog {
	margin-top: 0 !important;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content {
	width: 100% !important;
	max-width: var(--wp--custom--measure--header) !important;
	margin-inline: auto !important;
	padding: 0 var(--wp--preset--spacing--50) 1rem !important;
	flex: 0 0 auto !important;
	min-height: 0 !important;
	gap: 0 !important;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-close {
	display: none !important;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container {
	padding-top: 0 !important;
	gap: 0 !important;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list {
	display: block !important;
	width: 100%;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list > .wp-block-navigation-item,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	display: block;
	border-top: 1px solid var(--wp--preset--color--border);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list > .wp-block-navigation-item:first-child,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:first-child {
	border-top: 0;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	display: block;
	padding: 0.75rem 0 !important;
	font-family: var(--wp--preset--font-family--outfit) !important;
	font-size: var(--wp--preset--font-size--body) !important;
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: 0;
	color: var(--wp--preset--color--ink) !important;
	text-decoration: none !important;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--primary) !important;
}


/* --------------------------------------------------------------------------
   Featured images on the post templates.
   -------------------------------------------------------------------------- */

.wp-block-post-featured-image img {
	border-radius: var(--wp--custom--radius--md);
}


/* --------------------------------------------------------------------------
   Width philosophy. contentSize (1140px) is the LAYOUT CONTAINER — the
   default canvas for grids, nav, and sections. It is deliberately NOT a
   reading measure. Prose protects itself: loose text blocks dropped straight
   into post content cap at the narrow measure and center, so an article page
   reads like an article while everything structural gets the full container.
   Patterns that want tighter text use the jxb-measure-* utilities below.
   -------------------------------------------------------------------------- */

.wp-block-post-content.is-layout-constrained > :where(p, ul, ol, blockquote, h1, h2, h3, h4, h5, h6) {
	max-width: var(--wp--custom--measure--narrow);
}


/* --------------------------------------------------------------------------
   Narrow content measures.
   -------------------------------------------------------------------------- */

.jxb-measure-hero.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
.jxb-measure-narrow.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
.jxb-measure-cta.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	margin-left: auto;
	margin-right: auto;
}

.jxb-measure-hero.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--hero);
}

.jxb-measure-narrow.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--narrow);
}

.jxb-measure-cta.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--cta);
}

.jxb-header.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--header);
}

.jxb-footer.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: var(--wp--custom--measure--footer);
}


/* --------------------------------------------------------------------------
   Footer link columns.
   -------------------------------------------------------------------------- */

.jxb-footer .jxb-footer__links {
	list-style: none;
	padding-left: 0;
	margin: 0;
}

.jxb-footer .jxb-footer__links li {
	margin: 0;
}

.jxb-footer .jxb-footer__links a {
	display: inline-block;
	padding-block: 0.3rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
}

.jxb-footer .jxb-footer__links a:hover {
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
}


/* --------------------------------------------------------------------------
   MOBILE RESPONSIVE RULES

   Real responsive behavior, not just "overflow-x: clip and pray." These
   rules tune padding, hero/CTA vertical rhythm, button sizing, and
   column-stack spacing for narrow viewports.
   -------------------------------------------------------------------------- */

/* < 781px — WP's natural column-stack breakpoint. Below this the .alignfull
   sections need tighter horizontal padding so content doesn't pinch to a
   sliver. Hero/CTA vertical padding scales down by ~30%. */
@media (max-width: 781px) {

	/* Tighter side padding on full-width sections */
	.wp-block-group.alignfull[style*="padding-left"] {
		padding-left: var(--wp--preset--spacing--40) !important;
		padding-right: var(--wp--preset--spacing--40) !important;
	}

	/* Hero/CTA vertical rhythm — keep generous but not desktop-huge */
	.jxb-measure-hero,
	.jxb-measure-cta {
		padding-top: var(--wp--preset--spacing--60) !important;
		padding-bottom: var(--wp--preset--spacing--60) !important;
	}

	/* Section padding (non-hero) — slightly tighter */
	.wp-block-group.alignfull[style*="padding-top: var(--wp--preset--spacing--70)"] {
		padding-top: var(--wp--preset--spacing--60) !important;
	}
	.wp-block-group.alignfull[style*="padding-bottom: var(--wp--preset--spacing--70)"] {
		padding-bottom: var(--wp--preset--spacing--60) !important;
	}

	/* Buttons in a Buttons block — keep readable, full-width default on
	   center-aligned hero/CTA stacks for stronger tap targets */
	.jxb-measure-hero .wp-block-buttons,
	.jxb-measure-cta .wp-block-buttons {
		gap: 0.75rem !important;
		flex-direction: column !important;
		align-items: stretch !important;
	}

	.jxb-measure-hero .wp-block-buttons .wp-block-button,
	.jxb-measure-cta .wp-block-buttons .wp-block-button {
		width: 100%;
	}

	.jxb-measure-hero .wp-block-buttons .wp-block-button__link,
	.jxb-measure-cta .wp-block-buttons .wp-block-button__link {
		display: block;
		text-align: center;
	}

	/* Footer link columns — roomier tap targets */
	.jxb-footer .jxb-footer__links a {
		padding-block: 0.45rem;
	}

	/* Card / tile padding — tighter on mobile so cards don't waste space */
	.wp-block-group.has-border-color {
		padding: var(--wp--preset--spacing--40) !important;
	}
}

/* < 481px — phone-size. Even tighter spacing, drop nav-link padding, ensure
   the eyebrow doesn't disappear at fluid-min values. */
@media (max-width: 480px) {

	.wp-block-group.alignfull[style*="padding-left"] {
		padding-left: var(--wp--preset--spacing--30) !important;
		padding-right: var(--wp--preset--spacing--30) !important;
	}

	.jxb-measure-hero,
	.jxb-measure-cta {
		padding-top: var(--wp--preset--spacing--50) !important;
		padding-bottom: var(--wp--preset--spacing--50) !important;
	}

	/* Eyebrow visibility at small sizes */
	p.has-eyebrow-font-size {
		font-size: 0.75rem !important;
		letter-spacing: 0.15em;
	}
}
