/**
 * Darkhorse — design system.
 *
 * Rules of the house:
 *
 * 1. LOW SPECIFICITY. Every component selector is a single class (0,1,0) or a
 *    class + element. Final Blocks' per-element styling engine emits doubled
 *    uid selectors (0,2,0), so anything a user changes in the editor wins over
 *    this file without !important. Never break that contract.
 *
 * 2. SAME BREAKPOINTS AS THE ENGINE. Tablet ≤ 1024px, mobile ≤ 767px — the
 *    exact media queries Final Blocks generates, so theme responsiveness and
 *    user overrides always agree on where "tablet" and "mobile" begin.
 *
 * 3. SEMANTIC TOKENS. Components read --dh-* vars, which map to theme.json
 *    presets on :root. Style variations recolor the entire system by swapping
 *    the palette; `.dh-invert` flips a subtree to on-dark colors locally.
 *
 * 4. MOTION IS OPT-IN AND RESPECTFUL. Scroll reveals only engage when the
 *    runtime adds `.dh-js` to <html>; everything animates from a visible
 *    default and honors prefers-reduced-motion.
 *
 * Index:
 *   1. Tokens            6. Header & navigation   11. Blog & query
 *   2. Base              7. Footer                12. Comments
 *   3. Layout            8. Heroes & decor        13. Forms & search
 *   4. Typography        9. Effects & motion      14. Utilities
 *   5. Buttons          10. Components (cards,
 *                            badges, accordion,
 *                            pricing, marquee…)
 */

/* ====================================================================== *
 * 1. Tokens
 * ====================================================================== */

:root {
	/* Fallbacks mirror theme.json — if preset emission ever changes scope
	   or a variation omits a slug, components stay visible instead of
	   resolving to `initial` (the invisible-primary-button bug class). */
	--dh-bg: var(--wp--preset--color--base, #ffffff);
	--dh-text: var(--wp--preset--color--contrast, #0e0f13);
	--dh-muted: var(--wp--preset--color--muted, #5a5f6a);
	--dh-primary: var(--wp--preset--color--primary, #4353ff);
	--dh-accent: var(--wp--preset--color--accent, #9c4dff);
	--dh-surface: var(--wp--preset--color--surface, #f5f6f8);
	--dh-line: var(--wp--preset--color--outline, #e5e7ec);
	--dh-gradient: var(--wp--preset--gradient--brand, linear-gradient(135deg, #4353ff 0%, #9c4dff 100%));
	--dh-radius-s: var(--wp--custom--radius--s);
	--dh-radius-m: var(--wp--custom--radius--m);
	--dh-radius-l: var(--wp--custom--radius--l);
	--dh-radius-xl: var(--wp--custom--radius--xl);
	--dh-ease: var(--wp--custom--ease);
	--dh-speed: var(--wp--custom--speed);
	--dh-shadow-sm: var(--wp--preset--shadow--sm);
	--dh-shadow-md: var(--wp--preset--shadow--md);
	--dh-shadow-lg: var(--wp--preset--shadow--lg);
	--dh-shadow-glow: var(--wp--preset--shadow--glow);
	--dh-header-h: var(--wp--custom--header-height);
	--dh-gutter: var(--wp--custom--gutter);
	/* On-primary text — the book's contract: BASE on filled/gradient
	   controls (dark-on-neon for dark styles, light-on-color for light
	   ones). Hardcoded #fff was unreadable on Arcade's gradient. */
	--dh-on-primary: var(--wp--preset--color--base, #fff);
	/* Placeholder / empty-select: 35% of the field's own text color.
	   currentcolor resolves on the element that uses the token. */
	--dh-placeholder: color-mix(in srgb, currentcolor 35%, transparent);
	/* Alias of core's admin-bar offset — 0 when the bar is absent. */
	--dh-admin-bar: var(--wp-admin--admin-bar--height, 0px);
}

/* Flip a subtree to on-dark colors (ink heroes, dark footers, media overlays).
   Components below only ever read the vars, so this one class restyles all
   of them at once. */
.dh-invert {
	--dh-bg: transparent;
	--dh-text: #fff;
	--dh-muted: rgba(255, 255, 255, 0.72);
	--dh-surface: rgba(255, 255, 255, 0.06);
	--dh-line: rgba(255, 255, 255, 0.16);
	color: var(--dh-text);
}

/* ====================================================================== *
 * 2. Base
 * ====================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-padding-top: calc(var(--dh-header-h) + 16px);
}

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	margin: 0;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

img,
video {
	max-width: 100%;
	height: auto;
}

:where(a) {
	text-underline-offset: 0.2em;
}

:focus-visible {
	outline: 2px solid var(--dh-primary);
	outline-offset: 2px;
	border-radius: 2px;
}

::selection {
	background: color-mix(in srgb, var(--dh-primary) 22%, transparent);
}

/* Theme-owned fields only — Final Blocks paints its own placeholder
   from --fb-color-placeholder. Opacity 1 stops Firefox compounding
   its UA 0.54 fade on top of an already-faded mix. */
:where(input, textarea):not(.wp-block-final-block)::placeholder {
	color: var(--dh-placeholder);
	opacity: 1;
}

:where(input, textarea):not(.wp-block-final-block)::-moz-placeholder {
	color: var(--dh-placeholder);
	opacity: 1;
}

/* Accessible skip link (printed by the theme before the page). */
.dh-skip-link {
	position: absolute;
	top: -100%;
	left: 16px;
	z-index: 100000;
	padding: 10px 18px;
	background: var(--dh-text);
	color: var(--dh-bg);
	border-radius: var(--dh-radius-s);
	font-weight: 600;
	text-decoration: none;
}

.dh-skip-link:focus {
	top: 16px;
}

/* ====================================================================== *
 * 3. Layout
 * ====================================================================== */

/* Full-height canvas: every page is at least the viewport tall — the
   site frame is a flex column and <main> absorbs the slack, so short
   pages pin the footer to the bottom (and, with no footer, content
   grows to the bottom edge; with no header, from the top). Blank-canvas
   templates (landing) opt out via their template body class — they own
   the whole viewport themselves. */
body:not(.page-template-page-landing) .wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px));
	min-height: calc(100svh - var(--wp-admin--admin-bar--height, 0px));
}

body:not(.page-template-page-landing) .wp-site-blocks > main {
	flex: 1 0 auto;
}

/* Sections own their whitespace — the frame never forces it. WP bakes
   theme.json's blockGap into LITERAL margins between every layout
   child (it never reads --wp--style--block-gap back), so the site
   frame (header / mounts / main / footer), the bands inside <main>,
   and top-level sections in post-content all got 1.5rem wedges nobody
   asked for — two empty mount divs alone cost 3rem under the header.
   Frame pieces and main's bands stack flush (their padding IS their
   spacing). Post-content is a BLOCKLIST, not an allowlist: every
   direct child stacks flush (Final Blocks sections, core groups,
   covers, any third-party section — FB even interleaves sibling
   <style> tags, which broke sibling-pair matching), and only genuine
   prose elements get their rhythm restored, so a plain typed page
   still reads normally. A block-level margin attribute on anything
   still wins (inline style) — that's the per-section escape hatch. */
/* Fragment navs move focus to the fresh <main> (a11y) — the region
   target itself must never paint the site focus ring (the global
   :focus-visible rule outlined the whole page after every swap). */
main[tabindex="-1"]:focus-visible,
main[tabindex="-1"]:focus {
	outline: none;
}

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

.wp-site-blocks main > * + * {
	margin-block-start: 0;
}

.wp-block-post-content > * {
	margin-block-start: 0;
}

.wp-block-post-content > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, blockquote, figure, table, pre, hr, .wp-block-buttons):not(:first-child) {
	margin-block-start: var(--wp--style--block-gap, 1.5rem);
}

.dh-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size);
	margin-inline: auto;
	padding-inline: var(--dh-gutter);
}

.dh-container--content {
	max-width: var(--wp--style--global--content-size);
}

.dh-section {
	padding-block: var(--wp--preset--spacing--80);
}

.dh-section--tight {
	padding-block: var(--wp--preset--spacing--60);
}

.dh-section--roomy {
	padding-block: var(--wp--preset--spacing--90);
}

.dh-section--surface {
	background: var(--dh-surface);
}

.dh-section--ink {
	background: var(--wp--preset--gradient--ink);
}

.dh-section--mesh {
	background-image: var(--wp--preset--gradient--mesh);
}

.dh-section--line-top {
	border-top: 1px solid var(--dh-line);
}

/* Grids — collapse 4→2→1 and 3→1, 2→1 at the engine's breakpoints. */
.dh-grid {
	display: grid;
	gap: var(--wp--preset--spacing--40);
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.dh-grid--2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dh-grid--4 {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

.dh-grid--gap-l {
	gap: var(--wp--preset--spacing--50);
}

/* 50/50 feature split with vertical centering. */
.dh-split {
	display: grid;
	gap: var(--wp--preset--spacing--60);
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: center;
}

.dh-split--wide-media {
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

/* Vertical rhythm / horizontal cluster primitives. */
.dh-stack {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--40);
}

.dh-stack--s {
	gap: var(--wp--preset--spacing--30);
}

.dh-stack--l {
	gap: var(--wp--preset--spacing--50);
}

.dh-cluster {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	align-items: center;
}

.dh-cluster--center {
	justify-content: center;
}

.dh-cluster--between {
	justify-content: space-between;
}

.dh-center {
	text-align: center;
}

.dh-center > * {
	margin-inline: auto;
}

.dh-measure {
	max-width: 42rem;
}

.dh-measure-s {
	max-width: 34rem;
}

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

	.dh-split,
	.dh-split--wide-media {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--wp--preset--spacing--50);
	}
}

@media (max-width: 767px) {
	.dh-grid,
	.dh-grid--2,
	.dh-grid--4 {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ====================================================================== *
 * 4. Typography
 * ====================================================================== */

.dh-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	margin: 0;
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--dh-primary);
}

.dh-eyebrow--pill {
	padding: 0.35em 0.9em;
	border: 1px solid color-mix(in srgb, var(--dh-primary) 35%, transparent);
	border-radius: var(--wp--custom--radius--round);
	background: color-mix(in srgb, var(--dh-primary) 8%, transparent);
}

.dh-display {
	margin: 0;
	font-size: var(--wp--preset--font-size--colossal);
	line-height: 1.05;
	letter-spacing: -0.03em;
	font-weight: 800;
	text-wrap: balance;
}

.dh-title {
	margin: 0;
	text-wrap: balance;
}

.dh-lede {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.55;
	color: var(--dh-muted);
	text-wrap: pretty;
}

.dh-muted {
	color: var(--dh-muted);
}

.dh-small {
	font-size: var(--wp--preset--font-size--small);
}

.dh-text-gradient {
	background: var(--dh-gradient);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* ====================================================================== *
 * 5. Buttons
 * ====================================================================== */

/* Ensure smooth transitions on all interactive elements that change on hover/focus. */
a,
button:not([disabled]),
.wp-block-button__link,
.dh-iconlink,
.dh-iconbtn,
.dh-sidetoggle,
.dh-navtabs__tab,
.dh-mega__trigger,
.dh-btn,
.dh-sidenav .wp-block-navigation-item__content {
	transition:
		color var(--dh-speed) var(--dh-ease),
		background-color var(--dh-speed) var(--dh-ease),
		border-color var(--dh-speed) var(--dh-ease),
		transform var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		opacity var(--dh-speed) var(--dh-ease);
}

.dh-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5em;
	padding: 0.72em 1.5em;
	border: 1px solid transparent;
	border-radius: var(--dh-radius-m);
	background: var(--dh-text);
	color: var(--dh-bg);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	position: relative;
	overflow: hidden;
	transition:
		transform var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		background-color var(--dh-speed) var(--dh-ease),
		border-color var(--dh-speed) var(--dh-ease),
		color var(--dh-speed) var(--dh-ease);
}

.dh-btn:hover {
	transform: translateY(-2px);
	box-shadow: var(--dh-shadow-md);
}

.dh-btn:active {
	transform: translateY(0);
}

.dh-btn--primary {
	background: var(--dh-primary);
	color: var(--dh-on-primary);
}

.dh-btn--primary:hover {
	background: color-mix(in srgb, var(--dh-primary) 86%, var(--dh-text));
}

.dh-btn--gradient {
	background: var(--dh-gradient);
	color: var(--dh-on-primary);
}

.dh-btn--glow {
	background: var(--dh-gradient);
	color: var(--dh-on-primary);
	box-shadow: var(--dh-shadow-glow);
}

.dh-btn--glow:hover {
	box-shadow: var(--dh-shadow-glow), var(--dh-shadow-md);
}

/* Sheen sweep across gradient/glow buttons. */
.dh-btn--gradient::before,
.dh-btn--glow::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.35) 50%, transparent 65%);
	transform: translateX(-120%);
	transition: transform 600ms var(--dh-ease);
	pointer-events: none;
}

.dh-btn--gradient:hover::before,
.dh-btn--glow:hover::before {
	transform: translateX(120%);
}

.dh-btn--outline {
	background: transparent;
	border-color: var(--dh-line);
	color: var(--dh-text);
}

.dh-btn--outline:hover {
	border-color: var(--dh-primary);
	color: var(--dh-primary);
	box-shadow: none;
}

.dh-btn--ghost {
	background: transparent;
	color: var(--dh-text);
}

.dh-btn--ghost:hover {
	background: color-mix(in srgb, var(--dh-text) 6%, transparent);
	box-shadow: none;
	transform: none;
}

.dh-btn--soft {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

.dh-btn--soft:hover {
	background: color-mix(in srgb, var(--dh-primary) 16%, transparent);
	box-shadow: none;
}

.dh-btn--white {
	background: #fff;
	color: #101014;
}

/* Text link with a traveling arrow. */
.dh-btn--link {
	background: transparent;
	color: var(--dh-primary);
	padding: 0.25em 0;
	border-radius: 0;
	overflow: visible;
	font-weight: 600;
}

.dh-btn--link::after {
	content: "→";
	transition: transform var(--dh-speed) var(--dh-ease);
}

.dh-btn--link:hover {
	transform: none;
	box-shadow: none;
}

.dh-btn--link:hover::after {
	transform: translateX(4px);
}

.dh-btn--s {
	padding: 0.5em 1.1em;
	font-size: var(--wp--preset--font-size--small);
}

.dh-btn--l {
	padding: 0.9em 2em;
	font-size: var(--wp--preset--font-size--large);
}

/* Same size grade on a core button (the className lands on the block
   wrapper, so reach the link). */
.wp-block-button.dh-btn--l .wp-block-button__link {
	padding: 0.9em 2em;
	font-size: var(--wp--preset--font-size--large);
}

.dh-btn--pill {
	border-radius: var(--wp--custom--radius--round);
}

.dh-btn--block {
	width: 100%;
}

/* ====================================================================== *
 * 6. Header & navigation
 * ====================================================================== */

/* Positioning classes live on the template-part wrapper (the outermost
   element in the page flow) so position:sticky has room to work. */
.dh-sticky {
	position: sticky;
	top: 0;
	z-index: 200;
}

/* Logged-in offset: sit below the admin bar instead of under it. Core
   defines --wp-admin--admin-bar--height on :root when the bar renders. */
.admin-bar .dh-sticky,
.admin-bar .dh-header-overlay {
	top: var(--wp-admin--admin-bar--height, 32px);
}

/* Overlay header for hero-first landing pages: rides on top of the first
   section, turns solid once scrolled (runtime adds .is-scrolled). */
.dh-header-overlay {
	position: fixed;
	top: 0;
	right: 0;
	left: 0;
	z-index: 200;
}

/* The glass surface lives on a ::before, NOT the header itself:
   backdrop-filter on the header would make it the containing block for
   position:fixed descendants — which is exactly where core's mobile
   navigation overlay lives. Filter on the header = menu clipped inside
   the bar. Never move the blur back onto .dh-header. */
.dh-header {
	position: relative;
	border-bottom: 1px solid transparent;
	transition:
		border-color var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		transform 300ms var(--dh-ease);
}

/* Glass is a BLOCK STYLE ("Glass" / "Glass on scroll" on core/group,
   inc/setup.php), not header chrome (owner ruling 2026-08-11: surface
   is the block's own choice — background color for solid, no style for
   transparent, these for glass). The patterns seed dh-glass on their
   root group; removing the style in the editor removes the effect. */
/* Positioning context for the surface at ZERO specificity (:where) —
   any real positioning rule (variations, .dh-pos-sticky, legacy
   classes, inline) beats it by existing. The old :not() guard chain
   silently weighed (0,4,0) — each :not(.x) counts a full class — and
   out-gunned every variation's position (owner QA: "single class
   specificity for something this omnipresent isn't a good idea"). */
:where(.is-style-dh-glass, .is-style-dh-glass-scroll) {
	position: relative;
}

/* The surface derives from VARS, not hardcodes: tint defaults to the
   theme bg but follows the block's own background color (the render
   filter relocates a set background into --dh-glass-tint + the
   .dh-glass-tinted class); strength and blur are override-able the
   same way. */
:is(.is-style-dh-glass, .is-style-dh-glass-scroll)::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: color-mix(in srgb, var(--dh-glass-tint, var(--dh-bg)) var(--dh-glass-strength, 86%), transparent);
	-webkit-backdrop-filter: blur(var(--dh-glass-blur, 14px));
	backdrop-filter: blur(var(--dh-glass-blur, 14px));
	transition: opacity var(--dh-speed) var(--dh-ease);
}

/* A glass block whose background was relocated into the tint var must
   not ALSO paint that background opaquely on the element. */
.dh-glass-tinted.dh-glass-tinted {
	background: transparent;
}

/* "Glass on scroll": transparent while riding the top of the page,
   surfaces once scrolled (bindBars stamps .is-scrolled on the bar
   itself and on positioning wrappers). */
.is-style-dh-glass-scroll::before {
	opacity: 0;
}

:is(.is-scrolled .is-style-dh-glass-scroll, .is-style-dh-glass-scroll.is-scrolled)::before {
	opacity: 1;
}

/* NO hardcoded scrolled chrome (owner ruling 2026-08-28): scrolled
   appearance is AUTHORED per block via stuck-state editing — the theme
   painting its own line/shadow here both second-guessed that system and
   dressed non-sticky rows (bindBars stamps .is-scrolled on every
   watched bar, signpost stay columns included). The rest-state seat on
   .dh-header (transparent 1px hairline + border/shadow transitions)
   stays: it's the animation rail stuck-state edits ride on. */

/* Overlay variant starts transparent, gains its surface when scrolled. */
.dh-header-overlay :is(.is-style-dh-glass, .is-style-dh-glass-scroll)::before {
	opacity: 0;
}

.dh-header-overlay.is-scrolled :is(.is-style-dh-glass, .is-style-dh-glass-scroll)::before {
	opacity: 1;
}

/* Editor-driven sticky (core's Position panel) gets the header chrome
   the .dh-sticky class used to provide. The natural seat is the header
   TEMPLATE PART itself (header.is-position-sticky — the outermost
   element in the flow; sticky on an inner group is caged by the
   wrapper's own height). Scoped to header context so a sticky
   in-content group keeps its own stacking. */
header.is-position-sticky,
header .is-position-sticky,
.is-position-sticky.dh-header {
	z-index: 200;
}

/* Core bakes `top:0px` INLINE on position-sticky blocks — the admin-bar
   offset can only out-rank an inline style with !important (documented
   exception; logged-in admins only). */
/* The admin-bar offset belongs to the HEADER CONTAINER only (owner
   ruling 2026-08-29): the old `header .is-position-sticky` descendant
   arm was wrapper-era — post-unwrap, rows carry tagName header, so it
   was shoving the offset onto core-sticky nav menus INSIDE the rows. */
.admin-bar header.is-position-sticky,
.admin-bar .is-position-sticky.dh-header {
	top: var(--wp-admin--admin-bar--height, 32px) !important;
}

/* ------------------------------------------------------------------ *
 * Header v2 — behavior variations on the template part + Header panel
 * (inc/header-panel.php). Surface stays on the inner group (Glass /
 * background color); these classes only place and move the bar.
 * ------------------------------------------------------------------ */

/* Panel-driven sticky (Default variation's toggle). The THEME renders
   this — no core inline top to fight, so offset and admin bar compose
   in one calc, no !important. The offset is a STUCK offset: sticky
   top:N shoves the bar down AT REST too (owner QA round 2 #4), so the
   rest state pins to the edge and the offset engages with .is-scrolled. */
.dh-pos-sticky,
.is-style-dh-dynamic {
	position: sticky;
	top: 0;
	z-index: 200;
	/* top/bottom ride along so the STUCK offset slides in instead of
	   jumping when .is-scrolled lands (owner QA 2026-08-13). */
	transition: transform 300ms var(--dh-ease, ease), top 300ms var(--dh-ease, ease), bottom 300ms var(--dh-ease, ease);
}

.admin-bar :is(.dh-pos-sticky, .is-style-dh-dynamic) {
	top: var(--wp-admin--admin-bar--height, 32px);
}

:is(.dh-pos-sticky, .is-style-dh-dynamic).is-scrolled {
	top: var(--dh-header-offset, 0px);
}

.admin-bar :is(.dh-pos-sticky, .is-style-dh-dynamic).is-scrolled {
	top: calc(var(--wp-admin--admin-bar--height, 32px) + var(--dh-header-offset, 0px));
}

/* Header rows are TOP-LEVEL elements — the core-injected part wrapper is
   stripped at render (owner ruling 2026-08-27, supersedes the caging
   law), so each row carries its own position classes and every
   positioning / admin-bar / frame rule in this sheet applies to rows
   directly. (.dh-rows display:contents was the interim simulation of
   this and is retired.)

   SIGNPOST rows (dh-sp-left/center/right, grid columns on the site
   wrapper — the grid template itself is emitted per-page from
   inc/header-panel.php): sticky signposts are measure-then-promote.
   Static at rest — the row honestly sizes its track, and without JS it
   degrades to a normal header — then darkhorse.js stamps .dh-sp-stuck
   on scroll, engaging sticky + the row span that gives it travel. */
[data-dh-sp-sticky]:not(.dh-sp-stuck) {
	position: static;
}

.dh-sp-stuck {
	position: sticky;
	top: 0;
	z-index: 200;
	align-self: start;
}

.admin-bar .dh-sp-stuck {
	top: var(--wp-admin--admin-bar--height, 32px);
}

/* Column alignment: vertical seat of a shorter column against a taller
   neighbor. Unset = stretch (the grid's true default — full-height
   backgrounds). Unstuck only — a promoted row spans the page-tall area,
   so align-self:start must win the moment it sticks (.dh-sp-stuck sets
   it). */
.dh-sp-align-start:not(.dh-sp-stuck) {
	align-self: start;
}

.dh-sp-align-center:not(.dh-sp-stuck) {
	align-self: center;
}

.dh-sp-align-end:not(.dh-sp-stuck) {
	align-self: end;
}

/* Interface: a TRUE overlay — fixed full-frame, ripped out of the flow;
   the frame ignores the pointer and every direct child reinstates it,
   so content anywhere in the frame is interactive while the empty
   frame lets clicks through to the page. */
.is-style-dh-interface {
	position: fixed;
	inset: var(--dh-header-offset, 0px) 0 0 0;
	z-index: 200;
	pointer-events: none;
	/* The frame NEVER paints — it spans the whole viewport, so any
	   background here (legacy ref-era wrapper colors, hand classes)
	   curtains the entire site. Surfaces belong to the bar/groups
	   inside. !important outranks inline ref-era styles. */
	background: transparent !important;
}

.is-style-dh-interface > * {
	pointer-events: auto;
}

.admin-bar .is-style-dh-interface {
	top: calc(var(--wp-admin--admin-bar--height, 32px) + var(--dh-header-offset, 0px));
}

/* Dynamic contrast (Header panel toggle): darkhorse.js classifies the
   section behind the bar and flips this attribute; the ink follows.
   :where keeps link recoloring at zero specificity so any explicit
   author color on nav items wins. */
[data-dh-contrast] {
	transition: color 250ms var(--dh-ease, ease);
}

[data-dh-contrast="dark"] {
	color: var(--wp--preset--color--base, #fff);
}

[data-dh-contrast="light"] {
	color: var(--dh-text, currentColor);
}

[data-dh-contrast] :where(a:not(.wp-element-button), .wp-block-site-title a, .wp-block-navigation-item__content) {
	color: inherit;
	transition: color 250ms var(--dh-ease, ease);
}

/* Disorder: the header rides the END of the wp-site-blocks flex column
   without touching the markup order; its sticky toggle pins to the
   BOTTOM edge instead of the top. */
.is-style-dh-disorder {
	order: 99;
}

.is-style-dh-disorder.dh-pos-sticky {
	top: auto;
	bottom: 0;
}

.is-style-dh-disorder.dh-pos-sticky.is-scrolled {
	bottom: var(--dh-header-offset, 0px);
}

/* Hidden state (Dynamic's loiter/trailing/hybrid behaviors + legacy
   classes). */
:is(.dh-sticky--hide, .is-style-dh-hide-on-scroll, .is-style-dh-dynamic).is-hidden {
	transform: translateY(-110%);
}

:is(.dh-sticky--hide, .is-style-dh-hide-on-scroll) {
	transition: transform 300ms var(--dh-ease);
}

/* Bar LAYOUT (flex direction/justification/gap) now lives in each
   header pattern's block attributes so it's editable in the inspector —
   the class only keeps the structural minimum every bar must have. */
.dh-header__bar {
	min-height: var(--dh-header-h);
}

/* Flow layout ( :where(.is-layout-flow) > * + * ) injects a 1.5rem
   blockGap margin-block-start on every non-first child. Inside a header
   that lands on the bar (right after the announcement zone) and on any
   grouped item — reading as lopsided top padding, heavier up top than
   below. Headers own their spacing entirely via flex/grid gap, so strip
   every inherited block margin. */
.dh-header > *,
.dh-header :where(.wp-block-group, .wp-block-buttons, .wp-block-button, .wp-block-post-title, .wp-block-search, .wp-block-social-links, [class*="wp-block-darkhorse-"], p) {
	margin-block: 0;
}

/* ---- Header layouts 2.0 ---------------------------------------------- *
 * Composable structures. .dh-header__bar is the two-cluster flex row
 * (space-between). .dh-header__bar--split is a 3-zone grid whose CENTER
 * stays optically centered regardless of side widths — that's what core's
 * flex header can't do. Each zone is a .dh-header__group cluster. Because
 * direction is only source order, every header has a free mirror variant. */
.dh-header__bar--split {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--wp--preset--spacing--40);
	min-height: var(--dh-header-h);
}

.dh-header__bar--split > :nth-child(1) {
	justify-self: start;
}

.dh-header__bar--split > :nth-child(2) {
	justify-self: center;
}

.dh-header__bar--split > :nth-child(3) {
	justify-self: end;
}

/* Phone / utility text link in the bar. Authored as a core paragraph
   ( <p class="dh-header__tel"><a href="tel:…"> ) so it's a real, editable
   block — style both the wrapper and its link. */
.dh-header__tel,
.dh-header__tel a {
	font-weight: 600;
	white-space: nowrap;
	color: var(--dh-text);
	text-decoration: none;
}

.dh-header__tel:hover,
.dh-header__tel a:hover {
	color: var(--dh-primary);
}

/* Mobile: collapse to brand + hamburger. Auxiliary clusters (.dh-aux) and
   anything marked .dh-hide-mobile step aside; the nav's own overlay trigger
   carries navigation, so every desktop header degrades to a clean app bar.
   Per-header mobile presentation gets refined against the live render. */
@media (max-width: 767px) {
	.dh-header__bar--split {
		display: flex;
		justify-content: space-between;
	}

	.dh-header__bar--split > * {
		justify-self: auto;
	}

	.dh-header .dh-aux {
		display: none;
	}
}

.dh-brand {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	font-size: 1.375rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	text-decoration: none;
	color: var(--dh-text);
}

.dh-brand:hover {
	color: var(--dh-primary);
}

/* Announcement bar. */
.dh-topbar {
	/* The announcement Element renders as a <p class="dh-topbar">, so the
	   topbar IS the paragraph — its default block margin opened a gap above
	   the bar. (The .dh-topbar p rule only covers a nested paragraph.) */
	margin: 0;
	background: var(--dh-text);
	color: var(--dh-bg);
	font-size: var(--wp--preset--font-size--small);
	text-align: center;
	padding: 0.55em var(--dh-gutter);
}

.dh-topbar a {
	color: inherit;
	font-weight: 600;
}

.dh-topbar--gradient {
	background: var(--dh-gradient);
	color: var(--dh-on-primary);
}

/* --- core/navigation dressed as a Darkhorse menu ------------------------ */

.dh-nav {
	font-weight: 550;
	font-size: 0.9375rem;
}

/* Animated underline on top-level items. */
.dh-nav .wp-block-navigation-item__content {
	position: relative;
	padding-block: 0.35em;
}

.dh-nav .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px;
	background: var(--dh-gradient);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--dh-speed) var(--dh-ease);
}

.dh-nav .wp-block-navigation-item__content:hover::after,
.dh-nav .current-menu-item > .wp-block-navigation-item__content::after {
	transform: scaleX(1);
}

/* Dropdown panels: soft card, slide-fade in. */
.dh-nav .wp-block-navigation__submenu-container {
	border: 1px solid var(--dh-line) !important;
	border-radius: var(--dh-radius-m);
	box-shadow: var(--dh-shadow-lg);
	padding: 6px !important;
	background: var(--dh-bg) !important;
	color: var(--dh-text) !important;
}

.dh-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	border-radius: var(--dh-radius-s);
	padding: 0.5em 0.75em !important;
	transition: background-color var(--dh-speed) var(--dh-ease);
}

.dh-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
	content: none;
}

.dh-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background: color-mix(in srgb, var(--dh-primary) 8%, transparent);
	color: var(--dh-primary);
}

@media (prefers-reduced-motion: no-preference) {
	.dh-nav .wp-block-navigation__submenu-container {
		animation: dh-pop 180ms var(--dh-ease);
	}
}

@keyframes dh-pop {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
}

/* ====================================================================== *
 * 7. Footer
 * ====================================================================== */

.dh-footer {
	background: var(--dh-surface);
	border-top: 1px solid var(--dh-line);
	/* Baseline vertical rhythm for every footer variant — several designs
	   (centered, cta, dark, app, minimal, sitemap) had content abutting the
	   top edge because only the columns/mega grid carried its own padding. */
	padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--50);
}

.dh-footer--ink {
	background: var(--wp--preset--gradient--ink);
	border-top: none;
}

.dh-footer__grid {
	display: grid;
	grid-template-columns: minmax(0, 4fr) repeat(3, minmax(0, 2fr));
	gap: var(--wp--preset--spacing--50);
	/* Top spacing now comes from .dh-footer; keep only the gap to the bottom bar. */
	padding-block: 0 var(--wp--preset--spacing--60);
}

.dh-footer__title {
	margin: 0 0 0.9em;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--dh-muted);
}

.dh-footer__links {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.65em;
}

.dh-footer__links a {
	color: var(--dh-text);
	text-decoration: none;
	transition: color var(--dh-speed) var(--dh-ease);
}

.dh-footer__links a:hover {
	color: var(--dh-primary);
}

.dh-footer__bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--40);
	border-top: 1px solid var(--dh-line);
	font-size: var(--wp--preset--font-size--small);
	color: var(--dh-muted);
}

.dh-social {
	display: flex;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.dh-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	border: 1px solid var(--dh-line);
	color: var(--dh-text);
	text-decoration: none;
	font-size: 0.9375rem;
	font-weight: 600;
	transition:
		border-color var(--dh-speed) var(--dh-ease),
		color var(--dh-speed) var(--dh-ease),
		transform var(--dh-speed) var(--dh-ease);
}

.dh-social a:hover {
	border-color: var(--dh-primary);
	color: var(--dh-primary);
	transform: translateY(-2px);
}

/* Core social-links wearing the dh-social identity (authored as
   wp:social-links + is-style-logos-only; the circle chrome comes from
   the rules above). */
.dh-social .wp-block-social-link {
	margin: 0;
}

/* Core's block CSS zeroes border-bottom on every social link (its
   anti-underline rule, 0,2,1) — that erased the circle's bottom edge.
   Restore it at 0,3,1. */
.dh-social.wp-block-social-links .wp-social-link a {
	border-bottom: 1px solid var(--dh-line);
}

.dh-social.wp-block-social-links .wp-social-link a:hover {
	border-bottom-color: var(--dh-primary);
}

/* logos-only paints icons in each SERVICE's brand color — X and GitHub
   are black, invisible on ink footers. Outspecify core (0,4,1 beats its
   0,3,1 service-color rules) and keep icons on the token. */
.dh-social.wp-block-social-links.is-style-logos-only .wp-block-social-link a {
	color: var(--dh-text);
}

.dh-social.wp-block-social-links.is-style-logos-only .wp-block-social-link a {
	padding: 0;
}

.dh-social .wp-block-social-link svg {
	width: 1.1em;
	height: 1.1em;
	/* Don't depend on core's block CSS for this — unfilled icons render
	   black and vanish on ink footers. */
	fill: currentColor;
}

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

@media (max-width: 767px) {
	.dh-footer__grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ====================================================================== *
 * 8. Heroes & decor
 * ====================================================================== */

.dh-hero {
	position: relative;
	overflow: clip;
	padding-block: var(--wp--preset--spacing--90);
}

/* Under an overlay header, clear the fixed bar. */
.dh-hero--under-header {
	padding-top: calc(var(--wp--preset--spacing--90) + var(--dh-header-h));
}

.dh-hero--full {
	min-height: 92svh;
	display: flex;
	align-items: center;
}

.dh-hero--mesh {
	background-image: var(--wp--preset--gradient--mesh);
}

/* Full-bleed media background (image or video element with .dh-media-bg). */
.dh-media-bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: -2;
}

.dh-overlay {
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(180deg, rgba(8, 9, 12, 0.55), rgba(8, 9, 12, 0.78));
}

/* Blurred gradient orbs — pure decoration, aria-hidden in markup. */
.dh-orb {
	position: absolute;
	width: 44vw;
	max-width: 640px;
	aspect-ratio: 1;
	border-radius: 50%;
	background: var(--dh-gradient);
	filter: blur(90px);
	opacity: 0.35;
	z-index: -1;
	pointer-events: none;
}

.dh-orb--tl {
	top: -18%;
	left: -12%;
}

.dh-orb--br {
	bottom: -22%;
	right: -10%;
}

.dh-orb--faint {
	opacity: 0.18;
}

@media (prefers-reduced-motion: no-preference) {
	.dh-orb {
		animation: dh-drift 16s ease-in-out infinite alternate;
	}

	.dh-orb--br {
		animation-delay: -8s;
	}
}

@keyframes dh-drift {
	to {
		transform: translate3d(4%, 6%, 0) scale(1.08);
	}
}

/* Subtle grain so flat gradients don't band. */
.dh-noise::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	opacity: 0.05;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

/* Keep hero content above decor layers. */
.dh-hero > .dh-container {
	position: relative;
	z-index: 1;
}

/* ====================================================================== *
 * 9. Effects & motion
 * ====================================================================== */

/* Scroll reveal: hidden state ONLY when the runtime is present (html.dh-js),
   so content is always visible in the editor, in RSS, and without JS. */
.dh-js [data-dh-reveal] {
	opacity: 0;
	transform: translateY(22px);
	transition:
		opacity 640ms var(--dh-ease),
		transform 640ms var(--dh-ease);
	transition-delay: var(--dh-reveal-delay, 0ms);
}

.dh-js [data-dh-reveal="left"] {
	transform: translateX(-26px);
}

.dh-js [data-dh-reveal="right"] {
	transform: translateX(26px);
}

.dh-js [data-dh-reveal="zoom"] {
	transform: scale(0.94);
}

.dh-js [data-dh-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.dh-js [data-dh-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* Hover lift for cards and media. */
.dh-lift {
	transition:
		transform var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		border-color var(--dh-speed) var(--dh-ease);
}

.dh-lift:hover {
	transform: translateY(-4px);
	box-shadow: var(--dh-shadow-lg);
}

/* Marquee — duplicate the track content once in markup for a seamless loop. */
.dh-marquee {
	display: flex;
	overflow: hidden;
	gap: var(--wp--preset--spacing--60);
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.dh-marquee__track {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--60);
	flex-shrink: 0;
	min-width: 100%;
	justify-content: space-around;
	animation: dh-marquee 32s linear infinite;
}

/* Authored as one core-block track (darkhorse.js clones the second):
   a lone track stays static — covers no-JS and the editor canvas. */
.dh-marquee__track:only-child {
	animation: none;
}

.dh-marquee__track > * {
	margin: 0;
}

.dh-marquee:hover .dh-marquee__track {
	animation-play-state: paused;
}

@keyframes dh-marquee {
	to {
		transform: translateX(calc(-100% - var(--wp--preset--spacing--60)));
	}
}

@media (prefers-reduced-motion: reduce) {
	.dh-marquee__track {
		animation: none;
	}

	.dh-marquee {
		flex-wrap: wrap;
		-webkit-mask-image: none;
		mask-image: none;
	}
}

/* Back to top. */
.dh-backtotop {
	position: fixed;
	right: 22px;
	bottom: 22px;
	z-index: 190;
	width: 46px;
	height: 46px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--dh-line);
	border-radius: 50%;
	background: var(--dh-bg);
	color: var(--dh-text);
	box-shadow: var(--dh-shadow-md);
	cursor: pointer;
	font-size: 1.1rem;
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px);
	transition:
		opacity var(--dh-speed) var(--dh-ease),
		visibility var(--dh-speed) var(--dh-ease),
		transform var(--dh-speed) var(--dh-ease);
}

.dh-backtotop.is-visible {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.dh-backtotop:hover {
	color: var(--dh-primary);
	border-color: var(--dh-primary);
}

/* ====================================================================== *
 * 10. Components
 * ====================================================================== */

/* --- Cards -------------------------------------------------------------- */

.dh-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--50);
	background: var(--dh-bg);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-l);
	/* Any hover chrome (dh-lift, character shadows) animates instead of
	   snapping — mirrors the book's .sb-card transition. Must include
	   transform: same specificity as .dh-lift but later in the file, so
	   this list REPLACES lift's on .dh-card.dh-lift — omitting
	   transform made the lift snap. */
	transition:
		transform var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		border-color var(--dh-speed) var(--dh-ease);
}

.dh-card--surface {
	background: var(--dh-surface);
	border-color: transparent;
}

.dh-card--glass {
	background: rgba(255, 255, 255, 0.06);
	border-color: rgba(255, 255, 255, 0.14);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

.dh-card--accent-top {
	border-top: 3px solid;
	border-image: var(--dh-gradient) 1;
	border-top-left-radius: 0;
	border-top-right-radius: 0;
}

.dh-icon-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border-radius: var(--dh-radius-m);
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
	font-size: 1.5rem;
	line-height: 1;
}

.dh-icon-badge--gradient {
	background: var(--dh-gradient);
	color: var(--dh-on-primary);
}

/* --- Badges & chips ------------------------------------------------------ */

.dh-badge {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	padding: 0.3em 0.85em;
	border-radius: var(--wp--custom--radius--round);
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.4;
}

.dh-badge--outline {
	background: transparent;
	border: 1px solid var(--dh-line);
	color: var(--dh-muted);
}

.dh-badge--solid {
	background: var(--dh-text);
	color: var(--dh-bg);
}

/* Badges inside cards (e.g. the "Most popular" ribbon on the featured price
   card) center over the card. The pill is inline-flex, so auto margins only
   work once it's a block/flex box sized to its content. */
.dh-card .dh-badge {
	display: flex;
	width: -moz-fit-content;
	width: fit-content;
	margin-inline: auto;
}

/* --- Stats & counters ----------------------------------------------------- */

.dh-stat {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}

.dh-stat__number {
	margin: 0;
	font-size: var(--wp--preset--font-size--xx-large);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1;
	background: var(--dh-gradient);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	font-variant-numeric: tabular-nums;
}

.dh-stat__label {
	margin: 0;
	color: var(--dh-muted);
	font-size: var(--wp--preset--font-size--small);
}

/* Centered variant (stats bands; hero-split stats stay start-aligned). */
.dh-stat.dh-center {
	align-items: center;
	text-align: center;
}

/* --- Accordion (native <details>, zero JS required) ---------------------- */

.dh-accordion {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	/* Scroll anchoring fights the open/close height animation and reads
	   as jitter — content below may shift, the viewport must not. */
	overflow-anchor: none;
}

.dh-accordion__item {
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	background: var(--dh-bg);
	overflow: hidden;
	transition: border-color var(--dh-speed) var(--dh-ease);
}

.dh-accordion__item[open] {
	border-color: color-mix(in srgb, var(--dh-primary) 45%, var(--dh-line));
}

.dh-accordion__q,
.dh-accordion__item > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.1rem 1.35rem;
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

.dh-accordion__q::-webkit-details-marker,
.dh-accordion__item > summary::-webkit-details-marker {
	display: none;
}

.dh-accordion__q::after,
.dh-accordion__item > summary::after {
	content: "+";
	flex-shrink: 0;
	width: 1.5em;
	height: 1.5em;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
	font-weight: 500;
	transition: transform var(--dh-speed) var(--dh-ease);
}

.dh-accordion__item[open] .dh-accordion__q::after,
.dh-accordion__item[open] > summary::after {
	transform: rotate(45deg);
}

.dh-accordion__a {
	padding: 0 1.35rem 1.2rem;
	color: var(--dh-muted);
}

.dh-accordion__a > :first-child {
	margin-top: 0;
}

.dh-accordion__a > :last-child {
	margin-bottom: 0;
}

/* Open/close motion lives in darkhorse.js (WAAPI on .dh-accordion__a):
   the ::details-content block-size transition never arms in practice —
   verified empirically in a current Chromium with both interpolate-size
   and ::details-content supported — and Safari can't style the pseudo
   at all. Without JS (or with reduced motion) the accordion still
   opens/closes natively; it just snaps. */

/* --- Pricing -------------------------------------------------------------- */

.dh-price-card {
	position: relative;
	gap: var(--wp--preset--spacing--40);
}

/* The CTA hugs the card's bottom edge so all tiers line up uniformly
   regardless of feature-list length. */
.dh-price-card .wp-block-buttons {
	margin-top: auto;
}

.dh-price-card--featured {
	border: 2px solid transparent;
	background:
		linear-gradient(var(--dh-bg), var(--dh-bg)) padding-box,
		var(--dh-gradient) border-box;
	box-shadow: var(--dh-shadow-lg);
}

.dh-price {
	display: flex;
	align-items: baseline;
	gap: 0.35rem;
	margin: 0;
}

.dh-price__amount {
	font-size: 3rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1;
}

.dh-price__period {
	color: var(--dh-muted);
	font-size: var(--wp--preset--font-size--small);
}

.dh-check-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.6em;
}

.dh-check-list li {
	position: relative;
	padding-left: 1.75em;
}

.dh-check-list li::before {
	content: "✓";
	position: absolute;
	left: 0;
	top: 0.18em;
	width: 1.2em;
	height: 1.2em;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	font-size: 0.85em;
	font-weight: 700;
	color: var(--dh-primary);
	background: color-mix(in srgb, var(--dh-primary) 12%, transparent);
}

/* --- Testimonials --------------------------------------------------------- */

.dh-quote {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--40);
}

.dh-quote__text {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.5;
	text-wrap: pretty;
}

.dh-quote__text::before {
	content: "“";
	display: block;
	font-size: 3rem;
	line-height: 0.6;
	margin-bottom: 0.35em;
	background: var(--dh-gradient);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	font-weight: 800;
}

.dh-quote__cite {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	font-style: normal;
}

.dh-avatar {
	width: 44px;
	height: 44px;
	border-radius: 50%;
	object-fit: cover;
	background: var(--dh-gradient);
	flex-shrink: 0;
}

.dh-avatar--letter {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--dh-on-primary);
	font-weight: 700;
}

.dh-quote__name {
	margin: 0;
	font-weight: 600;
	line-height: 1.3;
}

.dh-quote__role {
	margin: 0;
	color: var(--dh-muted);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.3;
}

/* --- Logo cloud ------------------------------------------------------------ */

.dh-logo {
	font-weight: 700;
	font-size: 1.125rem;
	letter-spacing: -0.01em;
	color: var(--dh-muted);
	opacity: 0.75;
	white-space: nowrap;
	transition: opacity var(--dh-speed) var(--dh-ease), color var(--dh-speed) var(--dh-ease);
}

.dh-logo:hover {
	opacity: 1;
	color: var(--dh-text);
}

/* ====================================================================== *
 * 11. Blog & query
 * ====================================================================== */

.dh-page-head {
	padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--50);
}

.dh-page-head .wp-block-query-title,
.dh-page-head .dh-page-title {
	margin: 0;
}

.dh-post-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--wp--preset--spacing--50);
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.dh-post-grid--2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dh-post-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--50);
}

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

@media (max-width: 767px) {
	.dh-post-grid,
	.dh-post-grid--2 {
		grid-template-columns: minmax(0, 1fr);
	}
}

.dh-post-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
	height: 100%;
}

.dh-post-card .wp-block-post-featured-image {
	margin: 0;
	border-radius: var(--dh-radius-l);
	overflow: hidden;
	border: 1px solid var(--dh-line);
}

.dh-post-card .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	transition: transform 500ms var(--dh-ease);
}

.dh-post-card:hover .wp-block-post-featured-image img {
	transform: scale(1.04);
}

.dh-post-card .wp-block-post-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.25;
}

.dh-post-card .wp-block-post-title a {
	color: var(--dh-text);
	text-decoration: none;
	transition: color var(--dh-speed) var(--dh-ease);
}

.dh-post-card .wp-block-post-title a:hover {
	color: var(--dh-primary);
}

.dh-post-card .wp-block-post-excerpt {
	margin: 0;
	color: var(--dh-muted);
	font-size: 0.9375rem;
}

.dh-post-card .wp-block-post-excerpt__more-link {
	display: none;
}

/* Meta row (date · categories). */
.dh-post-meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.35em 0.9em;
	font-size: var(--wp--preset--font-size--small);
	color: var(--dh-muted);
}

.dh-post-meta .wp-block-post-date {
	margin: 0;
}

.dh-post-meta a {
	color: var(--dh-primary);
	text-decoration: none;
	font-weight: 600;
}

.dh-post-meta a:hover {
	text-decoration: underline;
}

/* Category pills (post-terms with .dh-term-pills). */
.dh-term-pills {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.dh-term-pills .wp-block-post-terms__separator {
	display: none;
}

.dh-term-pills a {
	display: inline-block;
	padding: 0.25em 0.8em;
	border-radius: var(--wp--custom--radius--round);
	background: color-mix(in srgb, var(--dh-primary) 9%, transparent);
	color: var(--dh-primary);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
	transition: background-color var(--dh-speed) var(--dh-ease);
}

.dh-term-pills a:hover {
	background: color-mix(in srgb, var(--dh-primary) 16%, transparent);
}

/* Pagination. */
.dh-pagination {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
	padding-block: var(--wp--preset--spacing--60);
	font-weight: 600;
}

.dh-pagination a,
.dh-pagination .page-numbers.current,
.dh-pagination .wp-block-query-pagination-previous,
.dh-pagination .wp-block-query-pagination-next {
	text-decoration: none;
}

.dh-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding-inline: 0.5em;
	border-radius: var(--dh-radius-s);
	color: var(--dh-text);
	transition: background-color var(--dh-speed) var(--dh-ease), color var(--dh-speed) var(--dh-ease);
}

.dh-pagination .page-numbers:hover {
	background: color-mix(in srgb, var(--dh-text) 6%, transparent);
}

.dh-pagination .page-numbers.current {
	background: var(--dh-text);
	color: var(--dh-bg);
}

/* Single post. */
.dh-entry-head {
	padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--40);
}

.dh-entry-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--xx-large);
}

.dh-entry-media {
	margin-block: var(--wp--preset--spacing--40) var(--wp--preset--spacing--60);
}

.dh-entry-media img {
	border-radius: var(--dh-radius-xl);
	width: 100%;
}

/* Long-form content niceties inside post content. */
.dh-entry .wp-block-post-content blockquote,
.dh-entry blockquote {
	margin: 2rem 0;
	padding: 0.25rem 0 0.25rem 1.5rem;
	border-left: 3px solid;
	border-image: var(--dh-gradient) 1;
	font-size: var(--wp--preset--font-size--large);
	font-style: italic;
}

.dh-entry pre {
	background: var(--dh-surface);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	padding: 1.25rem;
	overflow: auto;
	font-size: 0.9em;
}

.dh-entry code {
	font-family: var(--wp--preset--font-family--mono);
}

.dh-entry :not(pre) > code {
	background: var(--dh-surface);
	border: 1px solid var(--dh-line);
	border-radius: 5px;
	padding: 0.1em 0.4em;
	font-size: 0.88em;
}

/* Prev / next post links. */
.dh-post-nav {
	display: flex;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--40);
	padding-block: var(--wp--preset--spacing--60);
	border-top: 1px solid var(--dh-line);
}

.dh-post-nav a {
	color: var(--dh-text);
	font-weight: 600;
	text-decoration: none;
	max-width: 44%;
}

.dh-post-nav a:hover {
	color: var(--dh-primary);
}

.dh-post-nav .post-navigation-link-next {
	text-align: right;
	margin-left: auto;
}

/* ====================================================================== *
 * 12. Comments
 * ====================================================================== */

.dh-comments {
	padding-block: var(--wp--preset--spacing--60);
	border-top: 1px solid var(--dh-line);
}

.dh-comments .wp-block-comments-title {
	font-size: var(--wp--preset--font-size--x-large);
	margin: 0 0 1.5em;
}

.dh-comments .wp-block-comment-template {
	list-style: none;
	margin: 0;
	padding: 0;
}

.dh-comments .wp-block-comment-template li {
	margin-bottom: var(--wp--preset--spacing--40);
}

.dh-comments .wp-block-comment-template li ul,
.dh-comments .wp-block-comment-template li ol {
	list-style: none;
	margin: var(--wp--preset--spacing--40) 0 0 var(--wp--preset--spacing--50);
	padding: 0;
}

.dh-comment {
	padding: var(--wp--preset--spacing--40);
	background: var(--dh-surface);
	border-radius: var(--dh-radius-m);
}

.dh-comment .wp-block-avatar img {
	border-radius: 50%;
}

.dh-comment .wp-block-comment-author-name {
	font-weight: 700;
}

.dh-comment .wp-block-comment-date {
	font-size: var(--wp--preset--font-size--small);
	color: var(--dh-muted);
}

.dh-comment .wp-block-comment-content {
	margin-top: 0.5rem;
}

.dh-comment .wp-block-comment-reply-link a,
.dh-comment .wp-block-comment-edit-link a {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
}

.dh-comments .comment-reply-title {
	margin-bottom: 0.75em;
}

.dh-comments input[type="text"],
.dh-comments input[type="email"],
.dh-comments input[type="url"],
.dh-comments textarea {
	width: 100%;
}

.dh-comments .form-submit .submit {
	background: var(--dh-primary);
	color: var(--dh-on-primary);
	border: none;
	border-radius: var(--dh-radius-m);
	padding: 0.72em 1.5em;
	font-weight: 600;
	cursor: pointer;
	transition: background-color var(--dh-speed) var(--dh-ease);
}

.dh-comments .form-submit .submit:hover {
	background: var(--dh-accent);
}

/* ====================================================================== *
 * 13. Forms & search
 * ====================================================================== */

/* Theme native <select> — same chrome as Final Blocks, but never the
   FB block (uid-scoped doll styles own those). :where() keeps this
   under editor component selects if the sheet leaks into the canvas. */
:where(select):not(.wp-block-final-block):not(.components-select-control__input) {
	-webkit-appearance: none;
	appearance: none;
	background-color: transparent;
	background-image:
		linear-gradient(52.5deg, transparent 55%, var(--dh-placeholder) 0%),
		linear-gradient(127.5deg, var(--dh-placeholder) 45%, transparent 0%);
	background-position:
		calc(100% - 1.15em) calc(50% - 0em),
		calc(100% - 0.65em) calc(50% - 0em);
	background-size: 0.5em 0.5em;
	background-repeat: no-repeat;
	padding-inline-end: 2em;
}

:where(select):not(.wp-block-final-block):not(.components-select-control__input):has(option:disabled:checked) {
	color: var(--dh-placeholder);
}

.dh-input,
.dh-comments input[type="text"],
.dh-comments input[type="email"],
.dh-comments input[type="url"],
.dh-comments textarea {
	appearance: none;
	padding: 0.7em 1em;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	background: var(--dh-bg);
	color: var(--dh-text);
	font: inherit;
	transition: border-color var(--dh-speed) var(--dh-ease), box-shadow var(--dh-speed) var(--dh-ease);
}

.dh-input:focus,
.dh-comments input:focus,
.dh-comments textarea:focus {
	outline: none;
	border-color: var(--dh-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--dh-primary) 18%, transparent);
}

.dh-search {
	display: flex;
	gap: 0.5rem;
	max-width: 480px;
}

.dh-search .dh-input {
	flex: 1;
	min-width: 0;
}

.dh-search--center {
	margin-inline: auto;
}

/* ====================================================================== *
 * 14. Utilities
 * ====================================================================== */

.dh-hide {
	display: none !important;
}

@media (max-width: 1024px) {
	.dh-hide-tablet {
		display: none !important;
	}
}

@media (min-width: 1025px) {
	.dh-only-tablet {
		display: none !important;
	}
}

@media (max-width: 767px) {
	.dh-hide-mobile {
		display: none !important;
	}
}

@media (min-width: 768px) {
	.dh-only-mobile {
		display: none !important;
	}
}

.dh-visually-hidden {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	border: 0;
	white-space: nowrap;
}

.dh-radius {
	border-radius: var(--dh-radius-l);
	overflow: hidden;
}

.dh-shadow {
	box-shadow: var(--dh-shadow-lg);
}

.dh-border {
	border: 1px solid var(--dh-line);
}

/* ====================================================================== *
 * 15. Pattern extras & core-block compatibility
 * ====================================================================== */

/* Gradient call-to-action band. */
.dh-cta-band {
	position: relative;
	overflow: clip;
	padding: var(--wp--preset--spacing--70) var(--dh-gutter);
	border-radius: var(--dh-radius-xl);
	background: var(--dh-gradient);
	box-shadow: var(--dh-shadow-glow);
}

.dh-avatar--l {
	width: 72px;
	height: 72px;
	font-size: 1.5rem;
}

.dh-media {
	display: block;
	width: 100%;
}

.dh-page-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--xx-large);
}

/* Site title / tagline as brand pieces. */
.dh-brand.wp-block-site-title,
.wp-block-site-title.dh-brand {
	margin: 0;
	font-size: 1.375rem;
	line-height: 1.2;
}

.dh-brand a {
	color: inherit;
	text-decoration: none;
	transition: color var(--dh-speed) var(--dh-ease);
}

.dh-brand a:hover {
	color: var(--dh-primary);
}

.wp-block-site-tagline {
	margin: 0;
}

/* Query title / term description in page heads. */
.wp-block-query-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--xx-large);
}

.dh-page-head .wp-block-term-description {
	margin: 0.75rem 0 0;
	max-width: 42rem;
}

.dh-page-head .wp-block-term-description p {
	margin: 0;
}

/* Core search block, Darkhorse-flavored. */
.dh-searchform .wp-block-search__input {
	padding: 0.7em 1em;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	background: var(--dh-bg);
	color: var(--dh-text);
	font: inherit;
}

.dh-searchform .wp-block-search__input:focus {
	outline: none;
	border-color: var(--dh-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--dh-primary) 18%, transparent);
}

.dh-searchform .wp-block-search__button {
	margin-left: 0.5rem;
	padding: 0.7em 1.4em;
	border: none;
	border-radius: var(--dh-radius-m);
	background: var(--dh-primary);
	color: var(--dh-on-primary);
	font-weight: 600;
	cursor: pointer;
	transition: background-color var(--dh-speed) var(--dh-ease);
}

.dh-searchform .wp-block-search__button:hover {
	background: var(--dh-accent);
}

.dh-searchform .wp-block-search__inside-wrapper {
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	padding: 4px;
	background: var(--dh-bg);
}

.dh-searchform .wp-block-search__inside-wrapper .wp-block-search__input {
	border: none;
	box-shadow: none;
}

/* Avatars from core blocks. */
.dh-entry-avatar,
.dh-entry-avatar img,
.dh-post-meta .wp-block-avatar img,
.dh-comment .wp-block-avatar img {
	border-radius: 50%;
}

.dh-post-meta .wp-block-avatar {
	line-height: 0;
}

.dh-comment__byline {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

/* ====================================================================== *
 * 16. App shell: full-bleed sections, router, palette, zones, dark mode
 * ====================================================================== */

/* --- Full-bleed sections inside constrained content -------------------- *
 * Pattern sections manage their own inner width via .dh-container, so when
 * they land inside a constrained post-content area they break out to the
 * full viewport instead of being squeezed to prose width. */

body {
	overflow-x: clip;
}

.is-layout-constrained > .dh-section,
.is-layout-constrained > .dh-hero {
	/* Full bleed the way core does .alignfull inside a root-padding-aware
	   constrained container: drop the width cap and negate the global padding
	   so the band spans the content container edge-to-edge. No `vw` (so no
	   scrollbar skew) and never wider than the layout — the old 100vw approach
	   overshot the constrained/padded width and shoved the page sideways. */
	max-width: none;
	margin-left: calc(-1 * var(--wp--style--root--padding-left, var(--dh-gutter)));
	margin-right: calc(-1 * var(--wp--style--root--padding-right, var(--dh-gutter)));
}

/* The header is sticky (in flow), so the block-gap margin between it and the
   main entry left a seam above the first section. Sections/heroes carry their
   own generous padding, so seat the entry flush under the header. */
main.dh-entry {
	margin-top: 0;
}

/* --- App-shell navigation motion (GSAP push/flip; see app.js) ---------- *
 * During a push transition the outgoing <main> is pinned as a fixed
 * overlay while the incoming one takes the flow; the html wrapper clips
 * the horizontal travel. Nav scrolls are INSTANT (app feel) — the
 * momentary class beats the global smooth scroll-behavior. */
html.dh-motion {
	overflow-x: clip;
	scroll-behavior: auto;
}

/* Both planes need an opaque, viewport-tall surface while sliding —
   mains are transparent by default AND often shorter than the page
   they replace, so the outgoing archive showed through / below the
   incoming article (owner QA). Token fill is the CSS floor; app.js
   also stamps the computed body color + min-height inline. */
html.dh-motion main,
[data-dh-motion-old] {
	background-color: var(--wp--preset--color--base, var(--dh-bg, #fff));
	min-height: 100vh;
	min-height: 100dvh;
	isolation: isolate;
}

/* --- Loading skeleton ---------------------------------------------------
 * Slides in as the incoming view when a fragment takes longer than the
 * flash budget; bars shimmer until content arrives. */
.dh-skel {
	padding-top: var(--wp--preset--spacing--70);
}

.dh-skel__bar {
	height: 1em;
	border-radius: var(--dh-radius-s);
	background: color-mix(in srgb, var(--dh-text) 8%, var(--dh-surface));
	margin-block: 0.55em;
}

.dh-skel__bar--title {
	height: 2.4em;
	width: 60%;
	margin-bottom: 1.2em;
}

.dh-skel__bar--short {
	width: 40%;
}

.dh-skel__block {
	aspect-ratio: 16 / 9;
	border-radius: var(--dh-radius-l);
	background: color-mix(in srgb, var(--dh-text) 8%, var(--dh-surface));
	margin-block: 1.4em;
}

@media (prefers-reduced-motion: no-preference) {
	.dh-skel__bar,
	.dh-skel__block {
		background-image: linear-gradient(
			100deg,
			transparent 30%,
			color-mix(in srgb, var(--dh-bg) 55%, transparent) 50%,
			transparent 70%
		);
		background-size: 220% 100%;
		animation: dh-skel-shimmer 1.2s ease-in-out infinite;
	}
}

@keyframes dh-skel-shimmer {
	from {
		background-position: 120% 0;
	}

	to {
		background-position: -120% 0;
	}
}

/* --- Progress bar --------------------------------------------------------
   Facebook-style loader: a slim brand-gradient bar that grows while the
   fragment loads AND continuously shimmers (the gradient sweeps through
   the bar), with a soft glow bleeding into the page. */

.dh-progress {
	position: fixed;
	top: 0;
	left: 0;
	height: 4px;
	width: 0;
	z-index: 400;
	background: linear-gradient(
		90deg,
		var(--wp--preset--color--primary),
		var(--wp--preset--color--accent),
		var(--wp--preset--color--primary)
	);
	background-size: 200% 100%;
	border-radius: 0 3px 3px 0;
	box-shadow: 0 0 12px color-mix(in srgb, var(--wp--preset--color--primary) 55%, transparent),
		0 1px 6px color-mix(in srgb, var(--wp--preset--color--accent) 35%, transparent);
	opacity: 0;
	pointer-events: none;
}

.dh-progress.is-active {
	opacity: 1;
	animation:
		dh-progress 1.2s var(--dh-ease) forwards,
		dh-progress-shimmer 1s linear infinite;
}

.dh-progress.is-done {
	animation: dh-progress-shimmer 1s linear infinite;
	width: 100%;
	transition: width 150ms var(--dh-ease), opacity 300ms 150ms;
	opacity: 0;
}

@keyframes dh-progress {
	0% { width: 0; }
	60% { width: 62%; }
	100% { width: 84%; }
}

@keyframes dh-progress-shimmer {
	from { background-position: 200% 0; }
	to { background-position: 0% 0; }
}

@media (prefers-reduced-motion: reduce) {
	.dh-progress.is-active,
	.dh-progress.is-done {
		animation: dh-progress 1.2s var(--dh-ease) forwards;
	}

	.dh-progress.is-done {
		animation: none;
	}
}

/* --- Zones & Elements ----------------------------------------------------- */

.dh-mount:empty {
	display: none;
}

.dh-mount--overlay {
	position: fixed;
	inset: auto 0 0 0;
	z-index: 290;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	padding: 0 var(--dh-gutter) 18px;
	pointer-events: none;
}

.dh-mount--overlay .dh-rider {
	pointer-events: auto;
	max-width: min(560px, 100%);
	width: 100%;
}

/* --- Icon buttons (header controls) -------------------------------------- */

.dh-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border: 1px solid transparent;
	border-radius: 50%;
	background: transparent;
	color: var(--dh-text);
	font-size: 1.05rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color var(--dh-speed) var(--dh-ease), border-color var(--dh-speed) var(--dh-ease);
}

.dh-iconbtn:hover {
	background: color-mix(in srgb, var(--dh-text) 7%, transparent);
}

.dh-iconbtn--search::before {
	content: "";
	width: 17px;
	height: 17px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' d='M10.5 17a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Zm9.5 3-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' d='M10.5 17a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Zm9.5 3-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Scheme toggle glyphs: show the one for the scheme you'd switch TO. */
.dh-when-dark {
	display: none;
}

html[data-dh-scheme="dark"] .dh-when-dark {
	display: inline;
}

html[data-dh-scheme="dark"] .dh-when-light {
	display: none;
}

/* --- Command palette ------------------------------------------------------ */

.dh-palette {
	position: fixed;
	inset: 0;
	z-index: 500;
	display: none;
}

.dh-palette.is-open {
	display: block;
}

.dh-palette-open {
	overflow: hidden;
}

.dh-palette__backdrop {
	position: absolute;
	inset: 0;
	background: color-mix(in srgb, var(--dh-text) 32%, transparent);
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
}

.dh-palette__panel {
	position: relative;
	margin: min(16vh, 160px) auto 0;
	width: min(620px, calc(100% - 2 * var(--dh-gutter)));
	background: var(--dh-bg);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-l);
	box-shadow: var(--dh-shadow-lg);
	overflow: hidden;
}

@media (prefers-reduced-motion: no-preference) {
	.dh-palette.is-open .dh-palette__panel {
		animation: dh-pop 200ms var(--dh-ease);
	}
}

.dh-palette__input {
	width: 100%;
	border: none;
	background: transparent;
	color: var(--dh-text);
	font: inherit;
	font-size: var(--wp--preset--font-size--large);
	padding: 1rem 1.25rem;
	outline: none;
}

.dh-palette__hint {
	position: absolute;
	top: 1.35rem;
	right: 1.25rem;
	font-size: 11px;
	color: var(--dh-muted);
	letter-spacing: 0.06em;
	pointer-events: none;
}

.dh-palette__list {
	list-style: none;
	margin: 0;
	padding: 6px;
	max-height: 340px;
	overflow: auto;
	border-top: 1px solid var(--dh-line);
}

.dh-palette__list:empty {
	display: none;
}

.dh-palette__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.65rem 0.85rem;
	border-radius: var(--dh-radius-s);
	color: var(--dh-text);
	text-decoration: none;
	font-weight: 550;
}

.dh-palette__item em {
	font-style: normal;
	font-size: var(--wp--preset--font-size--small);
	color: var(--dh-muted);
}

.dh-palette__item.is-active,
.dh-palette__item:hover {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

.dh-palette__empty {
	padding: 0.85rem;
	color: var(--dh-muted);
	text-align: center;
}

/* --- Dark scheme ----------------------------------------------------------- *
 * Neutrals flip; each palette's primary/accent hues carry through, so every
 * style variation keeps its identity in the dark. Booted pre-paint by an
 * inline script (inc/assets.php). */

/* The preset overrides MUST live on the root element, not on body. The
   --dh-* tokens (--dh-bg/--dh-surface/--dh-line…) are declared on :root and
   resolve their var(--wp--preset--color--*) against the ROOT's values —
   custom properties set on a descendant (body) don't propagate upward, so
   overriding them on body left every token (and thus every card/footer
   surface) on the light palette while only body's own background went dark. */
/* Light-based styles flipping dark. Dark-based styles (Arcade,
   Cinematic — data-dh-base-scheme="dark", inc/character.php) are
   ALREADY dark natively: overriding their neutrals here just "muted"
   their curated palette, so they're excluded… */
html[data-dh-scheme="dark"]:not([data-dh-base-scheme="dark"]) {
	--wp--preset--color--base: #0b0d12;
	--wp--preset--color--contrast: #f2f4f8;
	--wp--preset--color--surface: #131722;
	--wp--preset--color--outline: #232837;
	--wp--preset--color--muted: #98a0af;
	--wp--preset--shadow--sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.35);
	--wp--preset--shadow--md: 0 6px 18px -4px rgba(0, 0, 0, 0.55);
	--wp--preset--shadow--lg: 0 18px 44px -12px rgba(0, 0, 0, 0.65);
	color-scheme: dark;
}

/* …and flip to a LIGHT neutral set instead when toggled: the toggle
   always inverts the CURRENT state, whatever the style starts as. */
html[data-dh-base-scheme="dark"][data-dh-scheme="light"] {
	--wp--preset--color--base: #f4f5f8;
	--wp--preset--color--contrast: #10131b;
	--wp--preset--color--surface: #ffffff;
	--wp--preset--color--outline: #dfe2ea;
	--wp--preset--color--muted: #5a6272;
	--wp--preset--shadow--sm: 0 1px 2px rgba(16, 19, 27, 0.06), 0 2px 6px rgba(16, 19, 27, 0.07);
	--wp--preset--shadow--md: 0 6px 18px -4px rgba(16, 19, 27, 0.14);
	--wp--preset--shadow--lg: 0 18px 44px -12px rgba(16, 19, 27, 0.24);
	color-scheme: light;
}

html[data-dh-base-scheme="dark"][data-dh-scheme="light"] body {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

html[data-dh-scheme="dark"] body {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}

/* Motion kill-switch: nothing in Darkhorse fights a reduced-motion request. */
@media (prefers-reduced-motion: reduce) {
	.dh-btn,
	.dh-lift,
	.dh-social a,
	.dh-post-card .wp-block-post-featured-image img {
		transition: none;
	}

	.dh-btn:hover,
	.dh-lift:hover,
	.dh-social a:hover,
	.dh-post-card:hover .wp-block-post-featured-image img {
		transform: none;
	}
}

/* --- Responsive utilities -------------------------------------------------
   Core blocks lack per-breakpoint layout (a Row stays a row on phones).
   Pattern markup carries these classes so the FREE, core-blocks-only
   library is fully responsive without any plugin. Breakpoints mirror the
   Final Blocks defaults (tablet ≤1024, mobile ≤767). */

@media (max-width: 1024px) {
	.dh-stack\@md.dh-stack\@md {
		flex-direction: column;
		align-items: stretch;
	}

	.dh-stack\@md.dh-stack\@md > * {
		flex-basis: auto !important;
	}

	.dh-reverse\@md.dh-reverse\@md {
		flex-direction: column-reverse;
	}

	.dh-hide\@md.dh-hide\@md {
		display: none;
	}

	.dh-center\@md.dh-center\@md {
		text-align: center;
		justify-content: center;
	}
}

@media (max-width: 767px) {
	.dh-stack\@sm.dh-stack\@sm {
		flex-direction: column;
		align-items: stretch;
	}

	.dh-stack\@sm.dh-stack\@sm > * {
		flex-basis: auto !important;
	}

	.dh-reverse\@sm.dh-reverse\@sm {
		flex-direction: column-reverse;
	}

	.dh-hide\@sm.dh-hide\@sm {
		display: none;
	}

	.dh-center\@sm.dh-center\@sm {
		text-align: center;
		justify-content: center;
	}
}

@media (min-width: 768px) {
	.dh-only\@sm.dh-only\@sm {
		display: none;
	}
}

/* --- Layout templates & app shells ---------------------------------------
   Sidebar / Holy Grail page layouts and the two app shells (bottom tab
   bar, fixed side nav). Grids collapse at the engine breakpoints. */

.dh-container--narrow {
	max-width: 900px;
}

.dh-layout-sidebar {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: var(--wp--preset--spacing--60);
	align-items: start;
	padding-block: var(--wp--preset--spacing--60);
}

.dh-layout-sidebar--left {
	grid-template-columns: 320px minmax(0, 1fr);
}

.dh-layout-sidebar--left .dh-layout-sidebar__main {
	order: 2;
}

.dh-layout-sidebar__aside {
	position: sticky;
	top: calc(var(--dh-header-h) + 24px);
}

.dh-layout-holy {
	display: grid;
	grid-template-columns: 240px minmax(0, 1fr) 300px;
	gap: var(--wp--preset--spacing--50);
	align-items: start;
	padding-block: var(--wp--preset--spacing--60);
}

.dh-layout-holy__rail,
.dh-layout-holy__aside {
	position: sticky;
	top: calc(var(--dh-header-h) + 24px);
}

@media (max-width: 1024px) {
	.dh-layout-sidebar,
	.dh-layout-sidebar--left,
	.dh-layout-holy {
		grid-template-columns: minmax(0, 1fr);
	}

	.dh-layout-sidebar--left .dh-layout-sidebar__main {
		order: 0;
	}

	.dh-layout-sidebar__aside,
	.dh-layout-holy__rail,
	.dh-layout-holy__aside {
		position: static;
	}
}

/* Mobile app shell: content clears the fixed bottom tab bar. */
.dh-appshell {
	padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
}

.dh-navbottom {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 300;
	background: color-mix(in srgb, var(--dh-bg) 88%, transparent);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
	border-top: 1px solid var(--dh-line);
	padding-bottom: env(safe-area-inset-bottom, 0px);
}

.dh-navbottom__bar {
	display: flex;
	justify-content: space-around;
	align-items: stretch;
}

.dh-navbottom__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	flex: 1;
	padding: 10px 4px 8px;
	border: 0;
	background: none;
	color: var(--dh-muted);
	font: inherit;
	font-size: 0.6875rem;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
}

.dh-navbottom__item:hover,
.dh-navbottom__item[aria-current] {
	color: var(--dh-primary);
}

.dh-navbottom__icon {
	font-size: 1.25rem;
	line-height: 1;
}

/* Web app shell: fixed side nav, content offset right. */
.dh-navside {
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	z-index: 300;
	width: 260px;
	background: var(--dh-surface);
	border-right: 1px solid var(--dh-line);
	overflow-y: auto;
}

.admin-bar .dh-navside {
	top: var(--wp-admin--admin-bar--height, 32px);
}

.dh-navside__inner {
	padding: 20px 18px;
	min-height: 100%;
}

.dh-navside__menu .wp-block-navigation__container {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.dh-navside__menu a {
	display: block;
	padding: 8px 10px;
	border-radius: var(--dh-radius-s);
	text-decoration: none;
	color: var(--dh-text);
}

.dh-navside__menu a:hover,
.dh-navside__menu .current-menu-item > a {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

.dh-navside__foot {
	margin-top: auto;
	display: flex;
	gap: 8px;
	align-items: center;
}

.dh-webshell {
	margin-left: 260px;
	min-height: 100vh;
}

@media (max-width: 1024px) {
	.dh-navside {
		position: fixed;
		top: auto;
		right: 0;
		bottom: 0;
		width: 100%;
		border-right: 0;
		border-top: 1px solid var(--dh-line);
		overflow: visible;
	}

	.dh-navside__inner {
		padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
	}

	.dh-navside__menu .wp-block-navigation__container {
		flex-direction: row;
		justify-content: space-around;
	}

	.dh-navside .dh-brand,
	.dh-navside__foot {
		display: none;
	}

	.dh-webshell {
		margin-left: 0;
		padding-bottom: 72px;
	}
}

/* --- New header variants -------------------------------------------------- */

.dh-header--transparent {
	background: transparent;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
}

.dh-header--compact .dh-header__bar {
	min-height: 56px;
}


.dh-header-search .wp-block-search__input {
	border-radius: var(--dh-radius-round, 999px);
}

/* Mega-ready nav: submenus become wide panels. */
.dh-nav--mega .wp-block-navigation__submenu-container {
	min-width: 420px;
	padding: 12px;
	border-radius: var(--dh-radius-m);
	box-shadow: var(--dh-shadow-lg);
}

.dh-loginout a {
	color: var(--dh-text);
	text-decoration: none;
	font-weight: 600;
	font-size: 0.875rem;
	/* "Log out" must never wrap into a squeezed two-liner. */
	white-space: nowrap;
}

.dh-iconbtn--cart {
	text-decoration: none;
}

.dh-iconbtn--cart::before {
	content: "";
	width: 18px;
	height: 18px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='20' r='1'/%3E%3Ccircle cx='18' cy='20' r='1'/%3E%3Cpath d='M2 3h3l2.3 12.3a1 1 0 0 0 1 .7h9a1 1 0 0 0 1-.8L21 7H6'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='20' r='1'/%3E%3Ccircle cx='18' cy='20' r='1'/%3E%3Cpath d='M2 3h3l2.3 12.3a1 1 0 0 0 1 .7h9a1 1 0 0 0 1-.8L21 7H6'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

/* Account icon (cart's fallback under darkhorse/cart). */
.dh-iconbtn--account::before {
	content: "";
	width: 18px;
	height: 18px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

/* Cart item-count bubble. */
.dh-iconbtn--cart {
	position: relative;
	overflow: visible;
}

.dh-cart__count {
	position: absolute;
	top: 2px;
	right: 2px;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	border-radius: 999px;
	background: var(--dh-primary);
	color: var(--dh-on-primary);
	font-size: 0.6875rem;
	font-weight: 700;
	line-height: 16px;
	text-align: center;
}

/* ------------------------------------------------------------------ *
 * Header building blocks: darkhorse/search, darkhorse/cart,
 * darkhorse/page-title. Real, editable blocks the theme ships so
 * headers never rely on raw HTML.
 * ------------------------------------------------------------------ */

/* Cart/account block wrapper rides the header centerline, no layout margin. */
.dh-cart-block {
	display: inline-flex;
	align-items: center;
	margin: 0;
}

/* Live search bar: a real input with a suggestions dropdown, right in the
   header. The <form> is the block wrapper, so typography/color/border/spacing
   controls land on it; inner input inherits font + color. Base declarations
   are wrapped in :where() (0 specificity) so ANY editor control — including
   border-radius, background, font-size — overrides these defaults. */
:where(.dh-livesearch) {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	width: 100%;
	min-width: 180px;
	max-width: 320px;
	margin: 0;
	padding: 0.45em 0.75em;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-round, 999px);
	background: color-mix(in srgb, var(--dh-text) 4%, transparent);
	color: var(--dh-text);
	font-size: 0.9375rem;
	line-height: 1.2;
	transition: border-color var(--dh-speed) var(--dh-ease), background-color var(--dh-speed) var(--dh-ease), box-shadow var(--dh-speed) var(--dh-ease);
}

.dh-livesearch:focus-within {
	border-color: var(--dh-primary);
	background: var(--dh-bg);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--dh-primary) 16%, transparent);
}

.dh-livesearch__icon {
	flex: none;
	width: 15px;
	height: 15px;
	background: currentColor;
	opacity: 0.7;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' d='M10.5 17a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Zm9.5 3-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' d='M10.5 17a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Zm9.5 3-4.4-4.4'/%3E%3C/svg%3E") center / contain no-repeat;
}

.dh-livesearch__input {
	flex: 1;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	color: inherit;
	font: inherit;
	line-height: inherit;
}

.dh-livesearch__input::placeholder {
	color: var(--dh-placeholder);
	opacity: 1;
}

.dh-livesearch__input:focus {
	outline: none;
}

/* Hide the browser's native search "×" clear control (we own the UI). */
.dh-livesearch__input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.dh-livesearch__kbd {
	flex: none;
	min-width: 1.3em;
	padding: 0.1em 0.4em;
	border: 1px solid var(--dh-line);
	border-radius: 0.35em;
	background: var(--dh-bg);
	color: var(--dh-muted);
	font-family: inherit;
	font-size: 0.75rem;
	line-height: 1.3;
	text-align: center;
}

.dh-livesearch:focus-within .dh-livesearch__kbd {
	display: none;
}

/* Suggestions dropdown anchored beneath the bar. */
.dh-livesearch__results {
	position: absolute;
	top: calc(100% + 8px);
	left: 0;
	right: 0;
	z-index: 60;
	max-height: min(60vh, 420px);
	overflow-y: auto;
	margin: 0;
	padding: 6px;
	list-style: none;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	background: var(--dh-bg);
	box-shadow: var(--dh-shadow-lg);
}

.dh-livesearch__results[hidden] {
	display: none;
}

.dh-livesearch__item {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75em;
	padding: 0.55em 0.7em;
	border-radius: calc(var(--dh-radius-m) - 4px);
	color: var(--dh-text);
	text-decoration: none;
	font-size: 0.9375rem;
	line-height: 1.3;
	cursor: pointer;
}

.dh-livesearch__item em {
	flex: none;
	color: var(--dh-muted);
	font-style: normal;
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.dh-livesearch__item.is-active,
.dh-livesearch__item:hover {
	background: color-mix(in srgb, var(--dh-primary) 12%, transparent);
	color: var(--dh-primary);
}

.dh-livesearch__empty {
	padding: 0.7em;
	color: var(--dh-muted);
	font-size: 0.9375rem;
	text-align: center;
}

/* Current-page title from darkhorse/page-title. Own class (the theme's
   .dh-page-title is the xx-large page-head utility) so it reads as a modest
   masthead line by default; the block's typography controls override this. */
:where(.dh-current-title) {
	font-size: 1.125rem;
	font-weight: 650;
	letter-spacing: -0.01em;
	line-height: 1.2;
	color: var(--dh-text);
	text-decoration: none;
}

.dh-current-title a {
	color: inherit;
	text-decoration: none;
}

/* --- darkhorse/login: view / popover / modal --------------------------- */

/* Full view that replaces <main>, with a ← Back button. */
.dh-login-view {
	max-width: 420px;
	margin-inline: auto;
	padding-block: var(--wp--preset--spacing--60);
}

.dh-login-view__back {
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
	margin-bottom: 1.25rem;
	padding: 0.3em 0.2em;
	border: 0;
	background: none;
	color: var(--dh-muted);
	font: inherit;
	font-weight: 600;
	cursor: pointer;
}

.dh-login-view__back::before {
	content: "";
	width: 1em;
	height: 1em;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round' d='M15 5l-7 7 7 7'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round' d='M15 5l-7 7 7 7'/%3E%3C/svg%3E") center / contain no-repeat;
}

.dh-login-view__back:hover {
	color: var(--dh-primary);
}

.dh-login-view__title {
	margin: 0 0 1.25rem;
	font-size: var(--wp--preset--font-size--x-large);
}

/* Centered modal (dimmed backdrop). */
.dh-login-modal {
	position: fixed;
	inset: 0;
	z-index: 300;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: clamp(16px, 12vh, 140px) 16px 16px;
	background: color-mix(in srgb, #000 45%, transparent);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}

.dh-login-modal__panel {
	width: 100%;
	max-width: 380px;
}

.dh-login-popover {
	position: fixed;
	inset: 0;
	z-index: 500;
	pointer-events: none;
}

.dh-login-popover__panel {
	pointer-events: auto;
}

/* Small popover anchored to the button (no backdrop) — JS sets top/left. */
.dh-login-popover__panel {
	width: 300px;
	max-width: calc(100vw - 16px);
	z-index: 500;
}

/* Shared panel card (modal + popover). */
.dh-login-panel {
	padding: 1.4rem;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-l, 18px);
	background: var(--dh-bg);
	box-shadow: var(--dh-shadow-lg);
}

.dh-login-panel__title {
	margin: 0 0 1.1rem;
	font-size: 1.2rem;
}

html.dh-login-open {
	overflow: hidden;
}

/* Shared field styling for core's wp_login_form markup. */
.dh-login-view__card p,
.dh-login-panel p {
	margin: 0 0 1rem;
}

.dh-login-view__card label,
.dh-login-panel label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--dh-text);
}

.dh-login-view__card .login-remember label,
.dh-login-panel .login-remember label {
	display: flex;
	align-items: center;
	gap: 0.5em;
	font-weight: 500;
}

.dh-login-view__card input[type="text"],
.dh-login-view__card input[type="email"],
.dh-login-view__card input[type="password"],
.dh-login-panel input[type="text"],
.dh-login-panel input[type="email"],
.dh-login-panel input[type="password"] {
	width: 100%;
	padding: 0.7em 0.9em;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-m);
	background: var(--dh-bg);
	color: var(--dh-text);
	font: inherit;
}

.dh-login-view__card input:focus,
.dh-login-panel input:focus {
	outline: none;
	border-color: var(--dh-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--dh-primary) 18%, transparent);
}

.dh-login-view__card #wp-submit,
.dh-login-panel #wp-submit {
	width: 100%;
	padding: 0.7em 1.2em;
	border: none;
	border-radius: var(--dh-radius-m);
	background: var(--dh-primary);
	color: var(--dh-on-primary);
	font-weight: 650;
	cursor: pointer;
	transition: background-color var(--dh-speed) var(--dh-ease);
}

.dh-login-view__card #wp-submit:hover,
.dh-login-panel #wp-submit:hover {
	background: var(--dh-accent);
}

/* On mobile the live-search bar tightens so it never dominates the bar. */
@media (max-width: 767px) {
	.dh-livesearch {
		min-width: 0;
	}

	.dh-livesearch__kbd {
		display: none;
	}
}

/* ==================================================================
   Archive layouts & post cards (wizard-selectable dispatchers)
   ================================================================== */

/* Shared card typography inside any query loop. */
.dh-posts .wp-block-post-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.25;
}

.dh-posts .wp-block-post-title a {
	color: var(--dh-text);
	text-decoration: none;
	transition: color var(--dh-speed) var(--dh-ease);
}

.dh-posts .wp-block-post-title a:hover {
	color: var(--dh-primary);
}

.dh-posts .wp-block-post-excerpt {
	margin: 0;
	color: var(--dh-muted);
	font-size: 0.9375rem;
}

.dh-posts .wp-block-post-excerpt__more-link {
	display: none;
}

/* --- Layout: classic list --- */
.dh-post-list--divided > .wp-block-post + .wp-block-post {
	border-top: 1px solid var(--dh-line);
	padding-top: var(--wp--preset--spacing--50);
}

/* --- Layout: featured first --- */
.dh-posts-feature-first > .wp-block-post:first-child {
	grid-column: 1 / -1;
}

.dh-posts-feature-first > .wp-block-post:first-child article:not(:has(> .wp-block-cover)) {
	display: grid;
	grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
	align-items: center;
	gap: var(--wp--preset--spacing--50);
}

.dh-posts-feature-first > .wp-block-post:first-child .wp-block-post-title {
	font-size: var(--wp--preset--font-size--x-large);
}

.dh-posts-feature-first > .wp-block-post:first-child .wp-block-cover {
	min-height: 440px;
}

/* --- Layout: compact rows --- */
.dh-post-list--compact {
	gap: var(--wp--preset--spacing--40);
}

.dh-post-list--compact article:has(> .wp-block-post-featured-image) {
	display: grid;
	grid-template-columns: 168px minmax(0, 1fr);
	align-items: center;
	gap: var(--wp--preset--spacing--40);
}

.dh-post-list--compact .wp-block-post-excerpt {
	display: none;
}

.dh-post-list--compact .wp-block-post-title {
	font-size: var(--wp--preset--font-size--medium);
}

.dh-post-list--compact .wp-block-cover {
	min-height: 160px;
}

/* --- Layout: cover mosaic --- */
.dh-post-mosaic {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--wp--preset--spacing--40);
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dh-post-mosaic article {
	height: 100%;
}

.dh-post-mosaic .wp-block-cover {
	min-height: 380px;
	height: 100%;
}

/* --- Card: horizontal row --- */
.dh-post-rowcard {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
	gap: var(--wp--preset--spacing--40);
	align-items: center;
}

.dh-post-rowcard .wp-block-post-featured-image {
	margin: 0;
	border-radius: var(--dh-radius-l);
	overflow: hidden;
	border: 1px solid var(--dh-line);
}

.dh-post-rowcard .wp-block-post-featured-image img {
	display: block;
	width: 100%;
}

.dh-post-rowcard__body {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
	min-width: 0;
}

/* --- Card: cover overlay --- */
.dh-post-covercard {
	height: 100%;
}

.dh-post-cover {
	margin: 0;
	height: 100%;
	border-radius: var(--dh-radius-l);
	overflow: hidden;
}

.dh-post-cover .wp-block-post-title a {
	color: #fff;
}

.dh-post-cover .wp-block-post-title a:hover {
	color: rgba(255, 255, 255, 0.8);
}

.dh-post-cover .dh-post-meta {
	color: rgba(255, 255, 255, 0.75);
}

.dh-post-cover .dh-post-meta a {
	color: #fff;
}

/* --- Card: minimal --- */
.dh-post-minimal {
	border-top: 2px solid var(--dh-text);
	padding-top: var(--wp--preset--spacing--30);
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

/* --- Card: tag-forward --- */
.dh-post-tagcard {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
	background: var(--dh-surface);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-l);
	padding: var(--wp--preset--spacing--40);
	height: 100%;
}

.dh-post-tagcard .dh-post-meta {
	margin-top: auto;
}

@media (max-width: 767px) {
	.dh-post-mosaic {
		grid-template-columns: minmax(0, 1fr);
	}

	.dh-post-rowcard,
	.dh-posts-feature-first > .wp-block-post:first-child article:not(:has(> .wp-block-cover)) {
		grid-template-columns: minmax(0, 1fr);
	}

	.dh-post-list--compact article:has(> .wp-block-post-featured-image) {
		grid-template-columns: 112px minmax(0, 1fr);
	}
}

/* ==================================================================
   WooCommerce (light harmonization — legacy templates in the shell)
   ================================================================== */

.dh-woo {
	padding-block: var(--wp--preset--spacing--60);
}

.dh-woo .woocommerce-products-header__title {
	margin-top: 0;
}

.dh-woo .button,
.dh-woo button[type="submit"] {
	background: var(--dh-primary);
	color: #fff;
	border: 0;
	border-radius: var(--dh-radius-m);
	font-weight: 600;
	padding: 0.7em 1.4em;
	transition: background var(--dh-speed) var(--dh-ease);
}

.dh-woo .button:hover,
.dh-woo button[type="submit"]:hover {
	background: var(--dh-accent);
	color: #fff;
}

.dh-woo ul.products li.product {
	background: var(--dh-surface);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-l);
	overflow: hidden;
	padding-bottom: 1rem;
}

.dh-woo ul.products li.product .woocommerce-loop-product__title,
.dh-woo ul.products li.product .price,
.dh-woo ul.products li.product .button,
.dh-woo ul.products li.product .star-rating {
	margin-left: 1rem;
	margin-right: 1rem;
}

.dh-woo .onsale {
	background: var(--dh-accent);
	border-radius: var(--dh-radius-round, 999px);
}

/* Mini-cart button inherits the icon-button look in headers. */
.dh-header .wc-block-mini-cart__button {
	color: var(--dh-text);
}

/* ==================================================================
   Alignment & mobile-navigation fixes (owner review 2026-07-04)
   ================================================================== */

/* Sit the OPEN overlay below the admin bar (0 when logged out).
   Scoped to .is-menu-open (owner QA 2026-09-01): the unscoped form
   offset EVERY responsive container — inline desktop menus inside the
   header included, since the overlay system positions closed containers
   too. The offset belongs to the open overlay alone. */
.wp-block-navigation__responsive-container.is-menu-open {
	top: var(--dh-admin-bar);
}

/* Mobile navigation overlay: give the open menu a real themed surface
   (core inherits background, which is transparent in our headers) and
   comfortable type. The clipping itself is fixed at .dh-header::before. */
.wp-block-navigation__responsive-container.is-menu-open {
	background: var(--dh-bg);
	color: var(--dh-text);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: calc(var(--dh-header-h, 76px) + 8px);
}

/* DEFAULTS, not mandates (:where = zero specificity): WP 7.0's overlay
   is fully author-editable, so any editor-set typography (preset
   font-size classes land at 0,1,0) must beat this comfortable-type
   seed. The background rule above stays specific on purpose — core
   sets the overlay to inherit, which is transparent in our headers. */
:where(.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content) {
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 600;
	color: var(--dh-text);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	color: var(--dh-text);
}

/* ==================================================================
   Themed CLOSE BUTTON (Overlay panel › Close button; every overlay
   mode). Core's <button> stays the accessible control — the theme
   only restyles it: data-dh-close="x|x-circle", data-dh-close-side,
   --dh-close-size (2.5rem), --dh-close-inset (1rem). Core's own SVG
   / "Close" text is hidden and an X is drawn from currentColor, so
   the nav's text colour (and dynamic contrast) drive it.
   ================================================================== */
.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close {
	position: absolute;
	top: var(--dh-close-inset, 1rem);
	right: var(--dh-close-inset, 1rem);
	left: auto;
	z-index: 3;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: var(--dh-close-size, 2.5rem);
	height: var(--dh-close-size, 2.5rem);
	margin: 0;
	padding: 0;
	font-size: 0;
	line-height: 0;
	color: inherit;
	background: transparent;
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	transition: background-color 180ms var(--dh-ease, ease), transform 180ms var(--dh-ease, ease);
}

.wp-block-navigation__responsive-container[data-dh-close][data-dh-close-side="left"].is-menu-open .wp-block-navigation__responsive-container-close {
	right: auto;
	left: var(--dh-close-inset, 1rem);
}

.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close > * {
	display: none;
}

.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close::before,
.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close::after {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	width: calc(var(--dh-close-size, 2.5rem) * 0.46);
	height: max(2px, calc(var(--dh-close-size, 2.5rem) * 0.06));
	background: currentColor;
	border-radius: 1px;
	transform: translate(-50%, -50%) rotate(45deg);
}

.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.wp-block-navigation__responsive-container[data-dh-close="x-circle"].is-menu-open .wp-block-navigation__responsive-container-close {
	border: max(1px, calc(var(--dh-close-size, 2.5rem) * 0.05)) solid currentColor;
}

.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close:hover,
.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close:focus-visible {
	background: color-mix(in srgb, currentColor 12%, transparent);
	transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close {
		transition: none;
	}
	.wp-block-navigation__responsive-container[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close:hover {
		transform: none;
	}
}

/* ==================================================================
   Nav overlay geometry + motion (Overlay panel on core/navigation —
   inc/header-panel.php renders dhOv* attrs onto the responsive
   container). GEOMETRY: the container ITSELF becomes the panel —
   core's overlay colors keep landing exactly where they always did —
   and a theme scrim (darkhorse.js) dims and guards the exposed page.
   MOTION: enter AND exit ride transition-behavior:allow-discrete +
   @starting-style, so core's abrupt is-menu-open/display:none toggle
   animates both ways with no JS interception of core's close path.
   ================================================================== */

/* Panelized overlay: width caps to the viewport; anchor = margins
   (inset stays 0 0 0 0 from core, margins place the panel, no
   transforms — those belong to the animations). */
.wp-block-navigation__responsive-container.dh-ov.is-menu-open {
	width: min(var(--dh-ov-width, 100vw), 100vw);
	border-radius: var(--dh-ov-radius, 0);
}

.dh-ov--left.is-menu-open {
	margin-right: auto;
}

.dh-ov--right.is-menu-open {
	margin-left: auto;
}

.dh-ov--center.is-menu-open {
	margin-inline: auto;
}

/* CONTAINMENT LAW (owner repro, Safari 17.6): backdrop-filter (or any
   transform/filter) on a block WRAPPING the header items makes that
   block the containing block for the fixed nav overlay + scrim — the
   modal clips into the bar. Blur a header surface with the theme's
   Glass block style (its blur lives on ::before, which cannot contain)
   — never a raw backdrop-filter on a header ancestor. */

/* Scroll unlock: core locks the page via html.has-modal-open — the
   panel's toggle opts back OUT for narrow overlays that should let
   the page breathe. */
html.has-modal-open:has(.dh-ov--unlock.is-menu-open) {
	overflow: auto;
}

/* Scrim: inserted once per dh-ov container (darkhorse.js), directly
   BEFORE it in the DOM. :has drives visibility — no JS on toggle.
   Clicks land on it instead of the page; dismissal is JS's call. */
.dh-ov-scrim {
	position: fixed;
	inset: 0;
	z-index: 99999;
	background: rgb(0 0 0 / 0.35);
	opacity: 0;
	visibility: hidden;
	transition: opacity 250ms var(--dh-ease, ease), visibility 250ms allow-discrete;
}

.dh-ov-scrim:has(+ .wp-block-navigation__responsive-container.is-menu-open) {
	opacity: 1;
	visibility: visible;
}

/* Curated motion. Each recipe only sets ENTRY/EXIT vars; the two gated
   blocks below apply them. Core's abrupt is-menu-open toggle animates
   both ways via allow-discrete + @starting-style — no JS interception
   of core's close path. GATE: in overlayMenu:mobile mode the DESKTOP
   INLINE nav renders through this same container, so the closed-state
   styles may only apply while the container is actually an overlay —
   hidden-by-default (always-overlay), or below core's 600px breakpoint. */
[class*="dh-ov--anim"].wp-block-navigation__responsive-container {
	animation: none;
	transition:
		opacity 280ms var(--dh-ease, ease),
		translate 280ms var(--dh-ease, ease),
		scale 280ms var(--dh-ease, ease),
		filter 280ms var(--dh-ease, ease),
		display 280ms allow-discrete,
		visibility 280ms allow-discrete;
	opacity: 1;
	/* No identity translate/scale/filter here — old WebKit treats a
	   fixed element carrying them as ancestor-composited (clipped);
	   `none` interpolates from the entry values just as well. */
}

/* Recipe defaults (fade = vars untouched) — in :where() so they weigh
   nothing: the recipes below are single-class rules and MUST beat these.
   (2026-09-04: sitting inside the two-class rule above, the defaults
   out-ranked .dh-ov--anim-zoom / .dh-ov--anim-blur, so zoom, blur and
   fade were all the same plain fade; only slide's two-class left/right
   variants got through.) */
:where([class*="dh-ov--anim"].wp-block-navigation__responsive-container) {
	--dh-ov-x: 0 0;
	--dh-ov-s: 1;
	--dh-ov-f: none;
}

/* Slide: direction follows the anchor (left panel from the left, right
   from the right, full/center drops from the top). */
.dh-ov--anim-slide {
	--dh-ov-x: 0 -6%;
}

.dh-ov--anim-slide.dh-ov--left {
	--dh-ov-x: -100% 0;
}

.dh-ov--anim-slide.dh-ov--right {
	--dh-ov-x: 100% 0;
}

/* Zoom */
.dh-ov--anim-zoom {
	--dh-ov-s: 0.94;
}

/* Blur */
.dh-ov--anim-blur {
	--dh-ov-f: blur(12px);
}

/* Overlay-mode gate #1: always-overlay navs. */
.hidden-by-default[class*="dh-ov--anim"]:not(.is-menu-open) {
	opacity: 0;
	translate: var(--dh-ov-x);
	scale: var(--dh-ov-s);
	filter: var(--dh-ov-f);
}

@starting-style {
	.hidden-by-default[class*="dh-ov--anim"].is-menu-open {
		opacity: 0;
		translate: var(--dh-ov-x);
		scale: var(--dh-ov-s);
		filter: var(--dh-ov-f);
	}
}

/* Overlay-mode gate #2: mobile-only overlays below core's breakpoint. */
@media (max-width: 599.98px) {
	[class*="dh-ov--anim"].wp-block-navigation__responsive-container:not(.is-menu-open) {
		opacity: 0;
		translate: var(--dh-ov-x);
		scale: var(--dh-ov-s);
		filter: var(--dh-ov-f);
	}

	@starting-style {
		[class*="dh-ov--anim"].wp-block-navigation__responsive-container.is-menu-open {
			opacity: 0;
			translate: var(--dh-ov-x);
			scale: var(--dh-ov-s);
			filter: var(--dh-ov-f);
		}
	}
}

@media (prefers-reduced-motion: reduce) {
	[class*="dh-ov--anim"].wp-block-navigation__responsive-container,
	.dh-ov-scrim {
		transition: none;
	}
}

/* ==================================================================
   Frame overlay — owner's card math.
   ONLY while html.dh-frame-open / html.dh-frame-closing. Nothing here
   may restyle the site at rest (leftover classes are swept in JS).
   ================================================================== */

html.dh-frame,
html.dh-frame-open,
html.dh-frame-closing {
	--dhw: min(var(--dh-ov-width, 450px), 100vw);
	--dh-frame-avail: calc(100dvh - var(--dh-admin-bar, 0px));
	--dh-frame-margin: var(--dh-ov-margin, calc(var(--dhw) / 4));
	--dh-frame-ease: cubic-bezier(0.4, 0, 0.2, 1);
	--dh-frame-time: 520ms;
}

html.dh-frame-open,
html.dh-frame-open body,
html.dh-frame-open .wp-site-blocks,
html.dh-frame-open .dh-ov--anim-frame.is-menu-open,
html.dh-frame-open .dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-container-content {
	scrollbar-width: none;
	-ms-overflow-style: none;
}

html.dh-frame-open::-webkit-scrollbar,
html.dh-frame-open *::-webkit-scrollbar {
	width: 0;
	height: 0;
	display: none;
}

/* ONE transition, ONE curve, both directions (owner: "not consistent
   in-out, jutters"). Only transform animates — never layout. */
html.dh-frame .wp-site-blocks,
html.dh-frame-open .wp-site-blocks,
html.dh-frame-closing .wp-site-blocks {
	transition: transform var(--dh-frame-time, 520ms) var(--dh-frame-ease, cubic-bezier(0.4, 0, 0.2, 1));
	will-change: transform;
	/* The card claims its stacking seat the instant .dh-frame lands —
	   NOT at .dh-frame-open. The menu goes is-menu-open (fixed, opaque,
	   full-viewport) on click, but dh-frame-open arrives two rAFs later
	   (the transition needs a committed rest frame): without a seat here
	   the menu paints OVER the page for those frames — a full-screen
	   flash right before the animation. relative/isolate/z are
	   paint-only (no layout shift) and identical to the open state. */
	position: relative;
	isolation: isolate;
	z-index: 50;
}

/* GSAP Flip drives the pose (darkhorse.js stamps dh-frame-gsap): the
   stylesheet only holds the END poses, the tween owns the in-between. */
html.dh-frame-gsap .wp-site-blocks {
	transition: none;
}

/* Stage: html/body pinned to the viewport; nothing scrolls but the
   main panel (when allowed). */
html.dh-frame-open,
html.dh-frame-closing {
	box-sizing: border-box;
	height: var(--dh-frame-avail);
	min-height: var(--dh-frame-avail);
	overflow: hidden;
}

html.dh-frame-open body,
html.dh-frame-closing body {
	width: 100%;
	min-height: 0;
	height: 100%;
	overflow: hidden;
}

/* THE MAIN PANEL. Layout stays exactly the viewport (no max-height /
   margin layout jump); every bit of geometry — menu offset, margins,
   max-height, Fit vs Push — is a transform: translate + scale about an
   origin, all three written as vars by darkhorse.js
   (`--dh-frame-tx / --dh-frame-s / --dh-frame-ox`). Open = zoom out (and
   slide, in Push) to reveal the menu behind; close = the exact reverse. */
html.dh-frame-open .wp-site-blocks,
html.dh-frame-closing .wp-site-blocks {
	position: relative;
	isolation: isolate;
	z-index: 50;
	inset: auto;
	box-sizing: border-box;
	width: 100%;
	max-width: 100vw;
	height: var(--dh-frame-avail);
	min-height: var(--dh-frame-avail);
	max-height: var(--dh-frame-avail);
	margin: 0;
	/* SCROLL LOCK by default; "Prevent background scroll" OFF
	   (dh-ov--unlock → html.dh-frame--scroll) lets the panel scroll. */
	overflow: hidden;
	overflow-anchor: none;
	cursor: pointer;
	transform-origin: var(--dh-frame-ox, 50%) 50%;
	border-radius: var(--dh-ov-radius, 0);
	border: var(--dh-ov-border, none);
	border-top: var(--dh-ov-border-top, var(--dh-ov-border, none));
	border-right: var(--dh-ov-border-right, var(--dh-ov-border, none));
	border-bottom: var(--dh-ov-border-bottom, var(--dh-ov-border, none));
	border-left: var(--dh-ov-border-left, var(--dh-ov-border, none));
	outline: var(--dh-ov-outline, none);
	outline-offset: var(--dh-ov-outline-offset, 0);
	box-shadow: var(--dh-ov-shadow, none);
}

html.dh-frame-open .wp-site-blocks {
	transform: translate3d(var(--dh-frame-tx, 0px), 0, 0) scale(var(--dh-frame-s, 1));
}

html.dh-frame-closing .wp-site-blocks {
	transform: translate3d(0, 0, 0) scale(1);
	cursor: default;
}

html.dh-frame--scroll.dh-frame-open .wp-site-blocks,
html.dh-frame--scroll.dh-frame-closing .wp-site-blocks {
	overflow: auto;
}

/* Veil is inert unless Frame is actually open. */
.dh-frame-veil {
	display: none !important;
	pointer-events: none;
}

/* Sticky zero-height first child whose ::before hangs one viewport
   down: rides the panel's scrollport. Tint only — a backdrop blur under
   a scaling transform is what made the animation stutter. */
html.dh-frame-open .dh-frame-veil,
html.dh-frame-closing .dh-frame-veil {
	display: block !important;
	position: sticky;
	top: 0;
	height: 0;
	z-index: 50;
	pointer-events: none;
}

html.dh-frame-open .dh-frame-veil::before,
html.dh-frame-closing .dh-frame-veil::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 100dvh;
	pointer-events: none;
	background: color-mix(in srgb, var(--dh-text, #1a1a1a) 16%, transparent);
	opacity: 1;
	transition: opacity var(--dh-frame-time, 520ms) var(--dh-frame-ease, ease);
}

html.dh-frame-closing .dh-frame-veil::before {
	opacity: 0;
}

html.dh-frame-open .wp-site-blocks a,
html.dh-frame-open .wp-site-blocks button:not(.wp-block-navigation__responsive-container-open),
html.dh-frame-open .wp-site-blocks input,
html.dh-frame-open .wp-site-blocks textarea,
html.dh-frame-open .wp-site-blocks select,
html.dh-frame-open .wp-site-blocks label {
	pointer-events: none;
}

/* THE HEADER STAYS EXACTLY AS IT WAS when the menu was opened (owner
   2026-09-04). The card is the scroll container, so a sticky / promoted
   header keeps sticking — to the card's own scrollport — with its stuck
   look intact. (The old rule forced position:relative here, which
   dropped a scrolled-down header out of the card.) Only the admin-bar
   offset is removed: inside the card there is no bar. */
html:is(.dh-frame-open, .dh-frame-closing) .wp-site-blocks :is(.dh-sp-stuck, .dh-pos-sticky, .is-position-sticky, .is-style-dh-dynamic) {
	/* (0,3,1): out-ranks `.admin-bar :is(…).is-scrolled` (0,3,0), which
	   kept a 32px admin-bar offset inside the card. */
	top: 0;
}

.dh-ov-scrim:has(+ .dh-ov--anim-frame) {
	display: none;
}

.dh-ov--anim-frame.wp-block-navigation__responsive-container {
	--dh-ov-x: 0 0;
	--dh-ov-s: 1;
	--dh-ov-f: none;
	/* Frame animates the MAIN PANEL, not the container. */
	transition: none;
}

/* THE MENU LAYER: position fixed, FULL WINDOW, BEHIND the main panel
   (owner's original structure) — the container paints its own colours
   edge to edge; the menu content is a column of --dhw anchored left /
   right / center. The main panel zooms out above it to reveal it. */
.dh-ov--anim-frame.wp-block-navigation__responsive-container.is-menu-open,
.wp-block-navigation__responsive-container.dh-ov.dh-ov--anim-frame.is-menu-open {
	position: fixed;
	top: var(--dh-admin-bar, 0px);
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 1;
	width: 100vw;
	max-width: 100vw;
	height: var(--dh-frame-avail, calc(100dvh - var(--dh-admin-bar, 0px)));
	margin: 0;
	border-radius: 0;
	box-shadow: none;
	transform: none;
}

/* The menu COLUMN = core's .responsive-close wrapper (the close button
   is absolutely positioned inside it, so it stays in the column). */
.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-close {
	position: relative;
	box-sizing: border-box;
	width: min(var(--dhw, 450px), 100vw);
	max-width: 100vw;
	height: 100%;
	margin-inline: 0 auto;
}

.dh-ov--anim-frame.dh-ov--right.is-menu-open .wp-block-navigation__responsive-close,
html.dh-frame--right .dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-close {
	margin-inline: auto 0;
}

.dh-ov--anim-frame.dh-ov--center.is-menu-open .wp-block-navigation__responsive-close,
html.dh-frame--center .dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-close {
	margin-inline: auto;
}

.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-dialog {
	height: 100%;
}

.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-container-content {
	/* The overlay template part owns its layout/padding; the theme only
	   fills the column and scrolls it. */
	box-sizing: border-box;
	width: 100%;
	max-width: none;
	height: 100%;
	overflow: auto;
	scrollbar-width: none;
}

.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-container-content::-webkit-scrollbar {
	display: none;
}

/* Belt for the modality gate in JS: never paint a ring on the menu
   buttons for plain (non-keyboard) focus — engines disagree about
   :focus-visible after scripted focus/transitions. */
.wp-block-navigation__responsive-container-open:focus:not(:focus-visible),
.wp-block-navigation__responsive-container-close:focus:not(:focus-visible) {
	outline: none;
}

/* Second belt: WebKit MATCHES :focus-visible on click/scripted focus
   where Chrome doesn't, so :not(:focus-visible) can't catch it there.
   darkhorse.js stamps html.dh-mod-pointer on pointerdown (removed on
   Tab/Enter/Space/Escape) — while the visitor is mousing, the menu
   buttons never ring; keyboard users always get the ring. */
html.dh-mod-pointer .wp-block-navigation__responsive-container-open:focus-visible,
html.dh-mod-pointer .wp-block-navigation__responsive-container-close:focus-visible {
	outline: none;
}

/* Menu label is emptied in JS; this draws the X in its place. */
:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close {
	/* The burger becomes the × WITHOUT changing its box (owner 2026-09-04:
	   the header in the card stays exactly as it was — a 2.5rem minimum
	   here grew a 21px text button to 40px, the header with it, and the
	   whole card snapped 19px when the menu closed). The label stays in
	   flow, invisible; the × draws over it. */
	position: relative;
	color: inherit;
	/* A bare "Menu" text node is not a child element: paint the glyphs
	   transparent (currentColor — the × below — is untouched). */
	-webkit-text-fill-color: transparent;
	text-shadow: none;
}

:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close > * {
	visibility: hidden;
}

:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close::before,
:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close::after {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 1.15rem;
	height: 2px;
	background: currentColor;
	border-radius: 1px;
}

:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close::before {
	transform: translate(-50%, -50%) rotate(45deg);
}

:is(html.dh-frame-open, html.dh-frame-closing) .wp-block-navigation__responsive-container-open.is-dh-frame-close::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-container-close,
.dh-ov--anim-frame[data-dh-close].is-menu-open:not([data-dh-ov-close="rail"]):not([data-dh-ov-close="both"]) .wp-block-navigation__responsive-container-close {
	display: none;
}

.dh-ov--anim-frame[data-dh-ov-close="rail"] .wp-block-navigation__responsive-container-close,
.dh-ov--anim-frame[data-dh-ov-close="both"] .wp-block-navigation__responsive-container-close {
	display: block;
	position: absolute;
	top: var(--dh-close-inset, 1rem);
	right: var(--dh-close-inset, 1rem);
}

.dh-ov--anim-frame[data-dh-close][data-dh-ov-close="rail"] .wp-block-navigation__responsive-container-close,
.dh-ov--anim-frame[data-dh-close][data-dh-ov-close="both"] .wp-block-navigation__responsive-container-close {
	display: inline-flex;
}

/* Mobile (below core's 600px overlay breakpoint): the rail takes the
   viewport and the card slides fully out — so the rail's own close
   button is forced visible (JS mirrors this: close mode reads as
   'both' when the rail is at least as wide as the viewport). Owner
   has not yet chosen a "peek" recipe; this is the safe baseline. */
@media (max-width: 599.98px) {
	html.dh-frame,
	html.dh-frame-open,
	html.dh-frame-closing {
		--dhw: 100vw;
	}

	.wp-block-navigation__responsive-container.dh-ov.dh-ov--anim-frame.is-menu-open,
	.wp-block-navigation__responsive-container.dh-ov.dh-ov--anim-frame.dh-ov--right.is-menu-open,
	.wp-block-navigation__responsive-container.dh-ov.dh-ov--anim-frame.dh-ov--center.is-menu-open,
	html.dh-frame--right .wp-block-navigation__responsive-container.dh-ov--anim-frame.is-menu-open,
	html.dh-frame--center .wp-block-navigation__responsive-container.dh-ov--anim-frame.is-menu-open {
		width: 100vw;
		left: 0;
		right: 0;
		transform: none;
	}

	.dh-ov--anim-frame.is-menu-open .wp-block-navigation__responsive-container-close {
		display: block;
		position: absolute;
		top: var(--dh-close-inset, 1rem);
		right: var(--dh-close-inset, 1rem);
	}

	.dh-ov--anim-frame[data-dh-close].is-menu-open .wp-block-navigation__responsive-container-close,
	.dh-ov--anim-frame[data-dh-close].is-menu-open:not([data-dh-ov-close="rail"]):not([data-dh-ov-close="both"]) .wp-block-navigation__responsive-container-close {
		display: inline-flex;
	}
}

@media (prefers-reduced-motion: reduce) {
	html.dh-frame-open .wp-site-blocks,
	html.dh-frame-closing .wp-site-blocks {
		transition: none;
	}
}

/* Header bars: kill default block margins (site-title renders as p/h1
   with UA margins — they fight the flex centering on the vertical axis). */
.dh-header__bar :is(h1, h2, h3, h4, p),
.dh-header__bar .wp-block-site-title,
.dh-topbar p,
.dh-navside :is(h1, h2, h3, p) {
	margin-block: 0;
}

/* Centered sections: flex stacks stretch children, so width-capped text
   (.dh-measure*) and inline-flex pills (.dh-eyebrow/.dh-badge) park at the
   LEFT edge of the column. Center the boxes, not just the text. The combined
   `.dh-center.dh-stack` case (same element carries both classes — the common
   pattern) was missed by the descendant-only selector before. */
.dh-center.dh-stack,
.dh-center .dh-stack {
	align-items: center;
}

.dh-center .dh-measure,
.dh-center .dh-measure-s,
.dh-center .dh-container--content {
	margin-inline: auto;
}

/* Inline-flex pills don't respond to text-align and stretch as flex items —
   center them explicitly wherever they sit in a centered context. */
.dh-center .dh-eyebrow,
.dh-center .dh-badge {
	align-self: center;
	margin-inline: auto;
}

/* ==================================================================
   Header alignment pass (owner screenshots 2026-07-04)
   ================================================================== */

/* Center-stacked header: in a column flex, justify-content is the
   VERTICAL axis — horizontal centering needs align-items. Without it
   the brand and nav hug the left edge. */
.dh-header--center .dh-header__bar {
	align-items: center;
	text-align: center;
}

/* Core wrapper blocks used inside header bars carry their own layout
   margins/alignment — normalize them so every item rides the same
   centerline. */
.dh-header__bar .wp-block-buttons,
.dh-header__bar .wp-block-loginout,
.dh-header__bar .wp-block-search,
.dh-header__bar .wp-block-social-links {
	margin: 0;
}

/* The nav ELEMENT only — core also stamps .wp-block-navigation on the
   overlay's inner <ul>, where the list is a COLUMN and align-items
   becomes horizontal alignment: the bare-class version force-centered
   overlay menu items and silently beat the editor's justification
   control (left = core's default = no CSS emitted to win the fight). */
.dh-header__bar nav.wp-block-navigation {
	align-items: center;
}

.dh-header__bar .wp-block-button {
	margin: 0;
}

/* Header CTAs read as compact utility buttons, not page-sized ones. */
.dh-header__bar .wp-block-button__link {
	padding: 0.55em 1.15em;
	font-size: 0.9375rem;
	font-weight: 650;
	border-radius: var(--dh-radius-m);
}

/* The brand should never wrap into two lines and shove the bar taller. */
.dh-brand {
	white-space: nowrap;
}

/* Nav items shouldn't wrap mid-label when space gets tight. */
.dh-nav .wp-block-navigation-item__content {
	white-space: nowrap;
}

/* ==================================================================
   Core-block conversion pass (sections re-authored in core blocks)
   ================================================================== */

/* Global blockGap flow margins (`:where(.is-layout-flow) > * + *`)
   double up against our gap-based utilities — and in flex ROWS a
   margin-block-start shoves items off the centerline (the header
   vertical-drift bug). Kill them wherever a dh layout utility owns
   the spacing. */
:is(.dh-stack, .dh-cluster, .dh-split, .dh-grid, .dh-header__bar, .dh-header__group, .dh-post-meta, .dh-stat, .dh-cta-band, .dh-card, .dh-quote__cite, .dh-accordion, .dh-sidenav__inner, .dh-sidenav__menu, .dh-sidenav__bar, .dh-sidenav__foot, .dh-sidenav__footrow, .dh-sidenav__brand, .dh-navtabs__panel) > * {
	margin-block-start: 0;
}

/* Core buttons: variant styles matching the dh-btn system. */
.wp-block-button__link {
	/* Padding scales with character warmth (vars from character.php). */
	padding: var(--dh-char-btn-py, 0.62em) var(--dh-char-btn-px, 1.3em);
	transition:
		transform var(--dh-speed) var(--dh-ease),
		box-shadow var(--dh-speed) var(--dh-ease),
		background-color var(--dh-speed) var(--dh-ease),
		border-color var(--dh-speed) var(--dh-ease),
		color var(--dh-speed) var(--dh-ease);
}

/* Every button type owns ONE hover move. Primary (default/glow) is the
   only one that lifts — plus a fade to the accent color. Gradients
   can't transition to solids (browsers snap — the "flash"), so the
   swap is an overlay layer fading in above the gradient. */
.wp-block-button:not([class*="is-style-"]) .wp-block-button__link,
.wp-block-button.is-style-dh-glow .wp-block-button__link {
	position: relative;
	z-index: 0;
	overflow: hidden;
	/* Own compositor layer: the hover lift + overlay fade re-rasterized
	   the label mid-transition (text "glitch" on glow-heavy styles). */
	backface-visibility: hidden;
	transform: translateZ(0);
}

.wp-block-button:not([class*="is-style-"]) .wp-block-button__link::before,
.wp-block-button.is-style-dh-glow .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	background: var(--dh-accent);
	opacity: 0;
	transition: opacity var(--dh-speed) var(--dh-ease);
}

.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover,
.wp-block-button.is-style-dh-glow .wp-block-button__link:hover {
	/* Keep the translateZ layer through the lift or the label
	   re-rasterizes mid-hover (text glitch). */
	transform: translateY(-2px) translateZ(0);
	box-shadow: var(--dh-shadow-md);
}

.wp-block-button:not([class*="is-style-"]) .wp-block-button__link:hover::before,
.wp-block-button.is-style-dh-glow .wp-block-button__link:hover::before {
	opacity: 1;
}

/* Primary (default) = the brand gradient with BASE text — the studio
   book's contract (.sb-btn--primary: --sb-gradient + --sb-base); dark
   styles get dark-on-neon, light styles get light-on-color. */
.wp-block-button:not([class*="is-style-"]) .wp-block-button__link {
	background: var(--dh-gradient);
	color: var(--wp--preset--color--base);
}

.wp-block-button.is-style-dh-glow .wp-block-button__link {
	background: var(--dh-gradient);
	color: var(--wp--preset--color--base);
	box-shadow: var(--dh-shadow-glow);
}

.wp-block-button.is-style-dh-glow .wp-block-button__link:hover {
	box-shadow: var(--dh-shadow-glow), var(--dh-shadow-md);
}

.wp-block-button.is-style-dh-white .wp-block-button__link {
	background: #fff;
	color: #101014;
}

/* Ghost: flickers awake and swaps to the accent entirely. */
.wp-block-button.is-style-dh-ghost .wp-block-button__link {
	/* Book contract (.sb-btn--ghost): a primary tint, not transparent —
	   plus a faint primary ring for definition on busy/dark sections
	   (mirrored into .sb-btn--ghost). Border absorbed into the padding
	   for height parity with the borderless variants. */
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
	border: 1px solid color-mix(in srgb, var(--dh-primary) 35%, transparent);
	padding: calc(var(--dh-char-btn-py, 0.62em) - 1px) calc(var(--dh-char-btn-px, 1.3em) - 1px);
}

.wp-block-button.is-style-dh-ghost .wp-block-button__link:hover {
	background: color-mix(in srgb, var(--dh-accent) 18%, transparent);
	color: var(--dh-accent);
	/* The ring follows the accent swap — a primary ring on an accent
	   fill read as a leftover (owner QA). Mirrored in .sb-btn--ghost. */
	border-color: color-mix(in srgb, var(--dh-accent) 35%, transparent);
}

@keyframes dh-ghost-flicker {
	0%, 100% { opacity: 1; }
	18% { opacity: 0.35; }
	32% { opacity: 1; }
	52% { opacity: 0.55; }
	68% { opacity: 1; }
}

@media (prefers-reduced-motion: no-preference) {
	.wp-block-button.is-style-dh-ghost .wp-block-button__link:hover {
		animation: dh-ghost-flicker 420ms ease;
	}
}

/* Outline hover lives next to the outline base rules (below, near
   .dh-pill) so it wins the specificity tie against the .has-* guards. */

.wp-block-button.is-style-dh-soft .wp-block-button__link {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

.wp-block-button.is-style-dh-soft .wp-block-button__link:hover {
	background: color-mix(in srgb, var(--dh-primary) 16%, transparent);
	box-shadow: none;
}

/* Text buttons: SECONDARY-colored emphasis riding a skewed marker
   highlight that swells on hover. Two mutually-exclusive styles: "Text"
   (dh-link) and "Text →" (dh-link-arrow) — the style picker is the
   arrow toggle, and the glyph itself is themeable via --dh-btn-arrow. */
.wp-block-button.is-style-dh-link .wp-block-button__link,
.wp-block-button.is-style-dh-link-arrow .wp-block-button__link {
	position: relative;
	z-index: 0;
	background: transparent;
	color: var(--dh-secondary, var(--dh-primary));
	padding: 0.25em 0.15em;
	border-radius: 0;
	font-weight: 700;
}

.wp-block-button.is-style-dh-link .wp-block-button__link::before,
.wp-block-button.is-style-dh-link-arrow .wp-block-button__link::before {
	content: "";
	position: absolute;
	z-index: -1;
	left: -0.1em;
	right: -0.1em;
	bottom: 0.1em;
	height: 0.34em;
	background: color-mix(in srgb, var(--dh-primary) 24%, transparent);
	transform: skewX(-12deg);
}

.wp-block-button.is-style-dh-link .wp-block-button__link:hover::before,
.wp-block-button.is-style-dh-link-arrow .wp-block-button__link:hover::before {
	height: 0.85em;
	background: color-mix(in srgb, var(--dh-primary) 32%, transparent);
}

.wp-block-button.is-style-dh-link-arrow .wp-block-button__link::after {
	content: var(--dh-btn-arrow, "→") / "";
	display: inline-block;
	margin-left: 0.45em;
}

@media (prefers-reduced-motion: no-preference) {
	.wp-block-button.is-style-dh-link .wp-block-button__link::before,
	.wp-block-button.is-style-dh-link-arrow .wp-block-button__link::before {
		transition: height var(--dh-speed) var(--dh-ease), background var(--dh-speed) var(--dh-ease);
	}

	.wp-block-button.is-style-dh-link-arrow .wp-block-button__link::after {
		transition: transform var(--dh-speed) var(--dh-ease);
	}

	.wp-block-button.is-style-dh-link-arrow .wp-block-button__link:hover::after {
		transform: translateX(4px);
	}

	/* Naked buttons lean into the swipe on hover. */
	.wp-block-button.is-style-dh-link .wp-block-button__link:hover,
	.wp-block-button.is-style-dh-link-arrow .wp-block-button__link:hover {
		transform: skewX(-8deg);
	}
}

.wp-block-button.dh-pill .wp-block-button__link {
	border-radius: var(--wp--custom--radius--round, 999px);
}

.wp-block-button.is-style-outline .wp-block-button__link {
	border-width: max(var(--dh-char-border, 1px), 1px);
	/* Self-sufficient outline: core's border/background resets sit in
	   :root :where() and lose the source-order tie to theme.json's
	   elements.button (solid primary bg, border-width 0) — so declare
	   border-style here and clear the background below. */
	border-style: solid;
	/* Book contract (.sb-btn--outline): primary border, primary text. */
	border-color: var(--dh-primary);
	/* Height parity with borderless buttons: absorb the border. */
	padding: calc(var(--dh-char-btn-py, 0.62em) - max(var(--dh-char-border, 1px), 1px)) calc(var(--dh-char-btn-px, 1.3em) - max(var(--dh-char-border, 1px), 1px));
}

/* Editor color choices win: only default the palette when the user
   hasn't picked one (core's .has-* guard convention). */
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color) {
	color: var(--dh-primary);
}

.wp-block-button.is-style-outline .wp-block-button__link:not(.has-background) {
	background: transparent;
}

/* Outline: fills solid and inverts. After the guards above: same
   specificity, so source order gives hover the win. */
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--dh-primary);
	border-color: var(--dh-primary);
	color: var(--dh-bg);
	box-shadow: none;
	transform: none;
}

.dh-invert .wp-block-button.is-style-outline .wp-block-button__link {
	color: #fff;
	border-color: rgba(255, 255, 255, 0.4);
}

/* Core images used as framed art (heroes/openers). */
.wp-block-image.dh-radius {
	overflow: hidden;
}

.wp-block-image.dh-radius img {
	display: block;
	width: 100%;
}

.wp-block-image.dh-radius,
.wp-block-image.dh-shadow {
	margin: 0;
}

/* ==================================================================
   Icons — masked SVGs painted with currentColor. Used by
   darkhorse/icon-link (.dh-icon--{slug}) and the side-nav chrome.
   Keep slugs in sync with darkhorse_icon_slugs() + icon-link/index.js.
   ================================================================== */

.dh-icon {
	display: inline-block;
	flex: none;
	width: 20px;
	height: 20px;
	background: currentColor;
	-webkit-mask: var(--dh-icon) center / contain no-repeat;
	mask: var(--dh-icon) center / contain no-repeat;
}

.dh-icon--home { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 10l9-7 9 7v10a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--link { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7'/%3E%3Cpath d='M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--search { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M16.5 16.5L21 21'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--user { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--users { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='4'/%3E%3Cpath d='M2 21a7 7 0 0 1 14 0'/%3E%3Cpath d='M16 4a4 4 0 0 1 0 8'/%3E%3Cpath d='M15 14a7 7 0 0 1 7 7'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--settings { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16'/%3E%3Ccircle cx='9' cy='7' r='2.5'/%3E%3Cpath d='M4 17h16'/%3E%3Ccircle cx='15' cy='17' r='2.5'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--heart { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21C6 16 3 12.5 3 9a5 5 0 0 1 9-3 5 5 0 0 1 9 3c0 3.5-3 7-9 12z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--star { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2l3 7 7 .3-5.5 4.7 2 7.5L12 17l-6.5 4.5 2-7.5L2 9.3 9 9z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--folder { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6a1 1 0 0 1 1-1h5l2 3h9a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--file { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 2h8l4 4v16H6z'/%3E%3Cpath d='M14 2v4h4'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--mail { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 7l9 6 9-6'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--bell { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6'/%3E%3Cpath d='M10 20a2 2 0 0 0 4 0'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--chart { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h16'/%3E%3Cpath d='M8 20v-9'/%3E%3Cpath d='M13 20V4'/%3E%3Cpath d='M18 20v-6'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--grid { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--compass { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M15.5 8.5l-2 5-5 2 2-5z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--phone { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 2 .7 2.9a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.9.3 1.9.6 2.9.7a2 2 0 0 1 1.7 2z'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--help { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M9.5 9a2.5 2.5 0 1 1 3.4 2.3c-.8.3-.9 1-.9 1.7'/%3E%3Cpath d='M12 16.5v.01'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--logout { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpath d='M16 17l5-5-5-5'/%3E%3Cpath d='M21 12H9'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--plus { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14'/%3E%3Cpath d='M5 12h14'/%3E%3C/g%3E%3C/svg%3E"); }
.dh-icon--bolt { --dh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13 2L3 14h8v8l10-12h-8z'/%3E%3C/g%3E%3C/svg%3E"); }

/* ==================================================================
   Nav shell + side rails.
   darkhorse/nav-shell declares layout/behavior; side layouts emit
   .dh-nav-shell--side and .dh-sidenav. Content shifts right via
   body:has(). Reduced state: data-dh-sidenav="min" on <html> (boot in
   inc/assets.php, toggled by darkhorse/side-toggle). Mobile always
   presents reduced; html.dh-sidenav-open expands as an overlay+scrim.
   ================================================================== */

.dh-nav-shell__editor-label {
	display: block;
	margin: 0 0 8px;
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--dh-muted);
}

.dh-header--glass::before {
	background: color-mix(in srgb, var(--dh-bg) 72%, transparent);
	backdrop-filter: blur(14px);
}

:root {
	--dh-sidenav-w: 264px;
	--dh-sidenav-min-w: 72px;
}

.dh-sidenav {
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	z-index: 400;
	width: var(--dh-sidenav-w);
	background: var(--dh-surface);
	border-right: 1px solid var(--dh-line);
	overflow: visible; /* the edge toggle handle hangs outside */
	/* Match site tokens better for side headers */
	box-shadow: var(--dh-shadow-sm);
}

.admin-bar .dh-sidenav {
	top: var(--wp-admin--admin-bar--height, 32px);
}

body:has(.dh-sidenav) .wp-site-blocks {
	padding-left: var(--dh-sidenav-w);
}

html[data-dh-sidenav="min"] .dh-sidenav {
	width: var(--dh-sidenav-min-w);
}

html[data-dh-sidenav="min"] body:has(.dh-sidenav) .wp-site-blocks {
	padding-left: var(--dh-sidenav-min-w);
}

@media (prefers-reduced-motion: no-preference) {
	.dh-sidenav {
		transition: width var(--dh-speed) var(--dh-ease), transform var(--dh-speed) var(--dh-ease), box-shadow var(--dh-speed) var(--dh-ease);
	}

	body:has(.dh-sidenav) .wp-site-blocks {
		transition: padding-left var(--dh-speed) var(--dh-ease);
	}
}

.dh-sidenav__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 14px;
	height: 100%;
	padding: 18px 14px;
	overflow-y: auto;
	overflow-x: hidden;
	scrollbar-gutter: stable;
}

.dh-sidenav__brand {
	display: flex;
	align-items: center;
	gap: 10px;
	min-width: 0;
}

.dh-sidenav__brandname {
	font-size: 1.0625rem;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.dh-sidenav .dh-sidenav__sep {
	width: 100%;
	margin: 0;
	border-color: var(--dh-line);
	opacity: 1;
}

/* The nav cluster centers itself in the leftover space (Rail preset);
   Deck/Panels/Steps override. */
.dh-sidenav__menu {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin-block: auto;
	width: 100%;
}

.dh-sidenav--deck .dh-sidenav__menu,
.dh-sidenav--carpet .dh-sidenav__menu,
.dh-sidenav--cranes .dh-sidenav__menu {
	margin-block: 0;
}

.dh-sidenav--deck .dh-navtabs,
.dh-sidenav--deck .dh-sidenav__search {
	flex: none;
}

.dh-sidenav__bar {
	display: flex;
	align-items: center;
	gap: 8px;
}

.dh-sidenav__foot {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin-top: auto;
	width: 100%;
}

.dh-sidenav__footrow {
	display: flex;
	align-items: center;
	gap: 8px;
	min-height: 32px;
}

/* Icon links. */
.dh-iconlink {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 9px 10px;
	border-radius: var(--dh-radius-s);
	color: var(--dh-text);
	text-decoration: none;
	font-weight: 600;
	font-size: 0.9375rem;
	white-space: nowrap;
	min-width: 0;
}

.dh-iconlink .dh-icon {
	opacity: 0.85;
}

.dh-iconlink:hover,
.dh-iconlink.current-menu-item {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

.dh-iconlink__label {
	overflow: hidden;
	text-overflow: ellipsis;
}

/* The CTA icon-link reads as a soft button. */
.dh-iconlink.dh-sidenav__cta {
	background: color-mix(in srgb, var(--dh-primary) 12%, transparent);
	color: var(--dh-primary);
	font-weight: 700;
	justify-content: center;
}

.dh-iconlink.dh-sidenav__cta:hover {
	background: color-mix(in srgb, var(--dh-primary) 20%, transparent);
}

/* Reduced presentation — shared rules, keyed on the html attribute.
   (Mobile repeats these inside its media query below.) */
html[data-dh-sidenav="min"] .dh-sidenav .dh-iconlink__label,
html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__brandname {
	display: none;
}

html[data-dh-sidenav="min"] .dh-sidenav .dh-iconlink,
html[data-dh-sidenav="min"] .dh-sidenav .dh-login-block {
	justify-content: center;
	padding-inline: 0;
}

html[data-dh-sidenav="min"] .dh-sidenav__brand,
html[data-dh-sidenav="min"] .dh-sidenav__bar,
html[data-dh-sidenav="min"] .dh-sidenav__footrow {
	flex-direction: column;
	justify-content: center;
	align-items: center;
}

/* Rail (min) state per preset: drill-down navs and tab stacks need the
   full column, so they hide; plain navs stay as monogram chips. */
html[data-dh-sidenav="min"] .dh-sidenav--carpet .dh-navtabs,
html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__ctarow,
html[data-dh-sidenav="min"] .dh-sidenav--cranes .dh-sidenav__search,
html[data-dh-sidenav="min"] .dh-sidenav--cranes .dh-sidenav__nav,
html[data-dh-sidenav="min"] .dh-sidenav--deck .dh-sidenav__search {
	display: none;
}

/* Side-nav toggle button. */
.dh-sidetoggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-s);
	background: var(--dh-surface);
	color: var(--dh-text);
	cursor: pointer;
}

.dh-sidetoggle:hover {
	color: var(--dh-primary);
	border-color: color-mix(in srgb, var(--dh-primary) 40%, var(--dh-line));
}

.dh-sidetoggle__chevron {
	width: 14px;
	height: 14px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 5l-7 7 7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 5l-7 7 7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

@media (prefers-reduced-motion: no-preference) {
	.dh-sidetoggle__chevron {
		transition: transform var(--dh-speed) var(--dh-ease);
	}
}

html[data-dh-sidenav="min"] .dh-sidetoggle__chevron {
	transform: rotate(180deg);
}

/* Edge handle: a pill riding the rail's right border, vertically centered
   (Jacob's Ladder). Sits OUTSIDE the scrolling inner column.
   Use high z and explicit right to avoid clipping by content wrappers. */
.dh-sidetoggle--edge {
	position: absolute;
	top: 50%;
	right: -18px;
	transform: translateY(-50%);
	width: 28px;
	height: 28px;
	border-radius: 999px;
	box-shadow: 0 2px 8px rgb(0 0 0 / 0.18);
	z-index: 10;
}

/* Edge toggle handle protrudes outside the rail; keep horizontal overflow visible. */
.dh-sidenav {
	overflow-x: visible;
}

/* Nav Tabs (darkhorse/nav-tabs). */
.dh-navtabs {
	display: flex;
	flex-direction: column;
	gap: 12px;
	flex: 1;
	min-height: 0;
}

.dh-navtabs__list {
	display: flex;
	gap: 4px;
	padding: 4px;
	border-radius: var(--dh-radius-s);
	background: color-mix(in srgb, var(--dh-text) 6%, transparent);
}

.dh-navtabs__tab {
	flex: 1;
	padding: 7px 8px;
	border: 0;
	border-radius: calc(var(--dh-radius-s) - 2px);
	background: transparent;
	color: var(--dh-muted);
	font: inherit;
	font-size: 0.8125rem;
	font-weight: 600;
	white-space: nowrap;
	cursor: pointer;
}

.dh-navtabs__tab.is-active {
	background: var(--dh-surface);
	color: var(--dh-text);
	box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
}

.dh-navtabs__panels {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
}

.dh-navtabs__panel[hidden] {
	display: none;
}

/* Editor-only affordances (panels stack, labelled). */
.dh-navtabs__editor-label {
	display: block;
	margin: 10px 0 4px;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--dh-muted);
}

.dh-navtabs__panel--editor {
	padding: 8px;
	border: 1px dashed var(--dh-line);
	border-radius: var(--dh-radius-s);
}

/* Side-nav flavored core blocks. */
.dh-sidenav .dh-sidenav__nav .wp-block-navigation__container {
	display: flex;
	flex-direction: column;
	gap: 2px;
	width: 100%;
}

.dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 9px 10px;
	border-radius: var(--dh-radius-s);
	color: var(--dh-text);
	text-decoration: none;
	font-weight: 600;
	font-size: 0.9375rem;
}

/* Monogram chips (generated in darkhorse.js): real menu links keep a
   first-letter identity when the rail collapses, so wp_navigation works
   everywhere icon links used to. Hidden at full width. */
.dh-sidenav .dh-navmono {
	display: none;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: var(--dh-radius-s);
	background: color-mix(in srgb, var(--dh-text) 7%, transparent);
	font-size: 0.75rem;
	font-weight: 700;
	line-height: 1;
	text-transform: uppercase;
}

.dh-sidenav .dh-sidenav__nav .current-menu-item .dh-navmono {
	background: color-mix(in srgb, var(--dh-primary) 14%, transparent);
	color: var(--dh-primary);
}

html[data-dh-sidenav="min"] .dh-sidenav .dh-navmono {
	display: inline-flex;
}

html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__label,
html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__nav .wp-block-navigation-submenu__toggle,
html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__nav .wp-block-navigation__submenu-container,
html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__label {
	display: none;
}

html[data-dh-sidenav="min"] .dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__content {
	justify-content: center;
	padding-inline: 0;
}

/* Section caption inside side rails. */
.dh-sidenav .dh-sidenav__label {
	margin: 4px 0 0;
	padding: 0 10px;
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--dh-muted);
}

.dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__content:hover,
.dh-sidenav .dh-sidenav__nav .current-menu-item > .wp-block-navigation-item__content {
	background: color-mix(in srgb, var(--dh-primary) 10%, transparent);
	color: var(--dh-primary);
}

/* Align stretch for nav menus (Red Carpet / Paper Cranes request). */
.dh-sidenav .dh-sidenav__nav .wp-block-navigation__container,
.dh-sidenav__menu {
	align-items: stretch;
}

/* Better overflow handling for long menu links. */
.dh-sidenav .wp-block-navigation-item__content,
.dh-sidenav .dh-iconlink {
	white-space: nowrap;
	overflow: hidden;
}

.dh-sidenav .wp-block-navigation-item__content span,
.dh-sidenav .dh-iconlink__label {
	display: block;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Side nav submenus (esp. Red Carpet): prevent clipping and style the box. */
.dh-sidenav .wp-block-navigation__submenu-container {
	position: static;
	background: var(--dh-surface);
	border: 1px solid var(--dh-line);
	border-radius: var(--dh-radius-s);
	margin-top: 2px;
	padding: 4px;
	box-shadow: var(--dh-shadow-sm);
	width: 100%;
	z-index: 1;
}

.dh-sidenav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding-left: 20px;
	font-size: 0.875rem;
}

.dh-sidenav .dh-sidenav__updates.wp-block-latest-posts {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.dh-sidenav .dh-sidenav__updates a {
	display: block;
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--dh-text);
	text-decoration: none;
}

.dh-sidenav .dh-sidenav__updates a:hover {
	color: var(--dh-primary);
}

.dh-sidenav .dh-sidenav__updates .wp-block-latest-posts__post-date {
	font-size: 0.75rem;
	color: var(--dh-muted);
}

.dh-sidenav .dh-livesearch {
	width: 100%;
}

/* Paper Cranes drill-down: once JS is ready, native submenus hide and
   generated panels slide over the whole rail (a back button pops). */
.dh-cranes-ready .wp-block-navigation__submenu-container,
.dh-cranes-ready .wp-block-navigation-submenu__toggle svg,
.dh-cranes-ready .wp-block-navigation-item__content::after,
.dh-cranes-ready .has-child::after {
	display: none !important;
}

.dh-cranes-ready .wp-block-navigation-submenu__toggle::after {
	content: "";
	display: inline-block;
	width: 12px;
	height: 12px;
	margin-left: auto;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

.dh-cranes-ready .wp-block-navigation-submenu__toggle {
	display: flex;
	align-items: center;
	width: 100%;
	text-align: left;
	cursor: pointer;
}

/* Style generated sub-sub buttons in cranes panels consistently (not unstyled). */
.dh-cranes-panel .dh-iconlink.wp-block-navigation-submenu__toggle {
	justify-content: space-between;
	padding-right: 10px;
}

.dh-cranes-panel .dh-cranes-chevron {
	width: 12px;
	height: 12px;
	margin-left: auto;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

.dh-cranes-panel {
	position: absolute;
	inset: 0;
	z-index: 3;
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 18px 14px;
	background: var(--dh-surface);
	overflow-y: auto;
	transform: translateX(100%);
}

@media (prefers-reduced-motion: no-preference) {
	.dh-cranes-panel {
		transition: transform var(--dh-speed) var(--dh-ease);
	}
}

.dh-cranes-panel.is-open {
	transform: none;
}

.dh-cranes-panel__back {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 6px;
	padding: 9px 10px;
	border: 0;
	border-radius: var(--dh-radius-s);
	background: transparent;
	color: var(--dh-muted);
	font: inherit;
	font-size: 0.875rem;
	font-weight: 600;
	text-align: left;
	cursor: pointer;
}

.dh-cranes-panel__back:hover {
	color: var(--dh-primary);
	background: color-mix(in srgb, var(--dh-primary) 8%, transparent);
}

.dh-cranes-panel__back::before {
	content: "";
	width: 14px;
	height: 14px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5'/%3E%3Cpath d='M11 6l-6 6 6 6'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5'/%3E%3Cpath d='M11 6l-6 6 6 6'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

.dh-cranes-panel__title {
	margin: 0 0 4px;
	padding: 0 10px;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--dh-muted);
}

/* Mobile bottom-dock shells: hide the desktop rail, show top + bottom bars. */
@media (max-width: 767px) {
	.dh-nav-shell--mobile-dock.dh-sidenav {
		position: static;
		width: auto;
		height: auto;
		border: 0;
		box-shadow: none;
		overflow: visible;
		background: transparent;
	}

	.dh-nav-shell--mobile-dock .dh-sidenav__inner,
	.dh-nav-shell--mobile-dock > .dh-sidetoggle {
		display: none !important;
	}

	body:has(.dh-nav-shell--mobile-dock) .wp-site-blocks {
		padding-left: 0;
		padding-top: calc(var(--dh-header-h, 76px) + env(safe-area-inset-top, 0px));
		padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px));
	}

	.dh-sidenav-mobtop {
		position: fixed;
		top: 0;
		right: 0;
		left: 0;
		z-index: 410;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		min-height: var(--dh-header-h, 76px);
		padding: 8px var(--wp--custom--gutter, 16px);
		padding-top: calc(8px + env(safe-area-inset-top, 0px));
		background: color-mix(in srgb, var(--dh-bg) 92%, transparent);
		-webkit-backdrop-filter: blur(12px);
		backdrop-filter: blur(12px);
		border-bottom: 1px solid var(--dh-line);
	}

	.admin-bar .dh-sidenav-mobtop {
		top: var(--wp-admin--admin-bar--height, 32px);
	}

	.dh-sidenav-mobtop__brand {
		font-weight: 700;
		font-size: 1rem;
		text-decoration: none;
		color: var(--dh-text);
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.dh-sidenav-mobtop__actions {
		display: flex;
		align-items: center;
		gap: 6px;
		flex: none;
	}

	.dh-sidenav-mobtop__menu {
		width: 40px;
		height: 40px;
		border: 1px solid var(--dh-line);
		border-radius: var(--dh-radius-s);
		background: var(--dh-surface);
		cursor: pointer;
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/g%3E%3C/svg%3E") center / 18px no-repeat;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/g%3E%3C/svg%3E") center / 18px no-repeat;
		background-color: var(--dh-text);
	}

	/* Deck keeps its search-first identity: live search rides the top bar. */
	.dh-sidenav-mobtop__search {
		flex: 1;
		min-width: 0;
	}

	.dh-sidenav-mobtop__search .dh-livesearch {
		width: 100%;
	}

	.dh-sidenav-mobtop--search .dh-sidenav-mobtop__brand {
		flex: none;
		max-width: 34vw;
	}

	/* Bottom tab dock: parent links as monogram chips + a Menu tile.
	   Submenus never live here — the slide-over panel owns the full tree. */
	.dh-sidenav-mobdock {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 400;
		display: flex;
		justify-content: space-around;
		background: color-mix(in srgb, var(--dh-bg) 88%, transparent);
		-webkit-backdrop-filter: blur(14px);
		backdrop-filter: blur(14px);
		border-top: 1px solid var(--dh-line);
		padding-bottom: env(safe-area-inset-bottom, 0px);
	}

	.dh-mobdock__item {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 3px;
		flex: 1;
		min-width: 0;
		padding: 8px 4px 7px;
		border: 0;
		background: transparent;
		font-size: 0.6563rem;
		font-weight: 600;
		color: var(--dh-muted);
		text-decoration: none;
		cursor: pointer;
	}

	.dh-mobdock__label {
		max-width: 100%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.dh-mobdock__chip {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 26px;
		height: 26px;
		border-radius: var(--dh-radius-s);
		background: color-mix(in srgb, var(--dh-text) 7%, transparent);
		font-size: 0.75rem;
		font-weight: 700;
		line-height: 1;
		text-transform: uppercase;
	}

	.dh-mobdock__chip--menu {
		background-color: color-mix(in srgb, var(--dh-text) 7%, transparent);
	}

	.dh-mobdock__chip--menu::before {
		content: "";
		width: 14px;
		height: 14px;
		background: currentColor;
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	}

	.dh-mobdock__item:hover,
	.dh-mobdock__item.is-active {
		color: var(--dh-primary);
	}

	.dh-mobdock__item.is-active .dh-mobdock__chip {
		background: color-mix(in srgb, var(--dh-primary) 14%, transparent);
		color: var(--dh-primary);
	}

	.dh-sidenav-mobmenu:not([hidden]) {
		position: fixed;
		inset: 0;
		z-index: 420;
		display: flex;
	}

	.dh-sidenav-mobmenu__scrim {
		position: absolute;
		inset: 0;
		background: rgb(0 0 0 / 0.45);
	}

	.dh-sidenav-mobmenu__panel {
		position: relative;
		z-index: 1;
		display: flex;
		flex-direction: column;
		width: min(360px, 88vw);
		height: 100%;
		margin-left: auto;
		background: var(--dh-surface);
		box-shadow: -8px 0 32px rgb(0 0 0 / 0.2);
		padding: calc(16px + env(safe-area-inset-top, 0px)) 16px 16px;
		overflow-y: auto;
	}

	.dh-sidenav-mobmenu__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		margin-bottom: 12px;
	}

	.dh-sidenav-mobmenu__title {
		margin: 0;
		font-weight: 700;
		font-size: 1rem;
	}

	.dh-sidenav-mobmenu__close {
		width: 36px;
		height: 36px;
		border: 1px solid var(--dh-line);
		border-radius: var(--dh-radius-s);
		background: var(--dh-surface);
		cursor: pointer;
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/g%3E%3C/svg%3E") center / 16px no-repeat;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/g%3E%3C/svg%3E") center / 16px no-repeat;
		background-color: var(--dh-text);
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation__container {
		display: flex;
		flex-direction: column;
		gap: 2px;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-item__content {
		display: block;
		padding: 10px 12px;
		border-radius: var(--dh-radius-s);
		font-weight: 600;
		text-decoration: none;
		color: var(--dh-text);
	}

	/* Submenus expand in place as an accordion (bound in darkhorse.js, so
	   they work even when core's navigation view script isn't around).
	   Parent row: link fills, chevron toggle sits right, children span
	   the full width below. */
	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu > .wp-block-navigation-item__content {
		flex: 1;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu__toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 34px;
		border: 0;
		border-radius: var(--dh-radius-s);
		background: transparent;
		color: var(--dh-muted);
		cursor: pointer;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu__toggle svg {
		transition: transform 160ms ease;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu.is-open > .wp-block-navigation-submenu__toggle svg,
	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu > .wp-block-navigation-submenu__toggle[aria-expanded="true"] svg {
		transform: rotate(90deg);
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation__submenu-container {
		display: none;
		position: static;
		visibility: visible;
		opacity: 1;
		width: auto;
		height: auto;
		min-width: 0;
		overflow: visible;
		border: 0;
		box-shadow: none;
		background: transparent;
		padding-left: 12px;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu.is-open > .wp-block-navigation__submenu-container {
		display: block;
	}

	.dh-sidenav-mobmenu__nav .wp-block-navigation-submenu > .wp-block-navigation__submenu-container {
		flex-basis: 100%;
	}

	.dh-sidenav-mobmenu__section {
		margin: 18px 0 6px;
		padding: 0 12px;
		font-size: 0.6875rem;
		font-weight: 700;
		letter-spacing: 0.05em;
		text-transform: uppercase;
		color: var(--dh-muted);
	}

	.dh-sidenav-mobmenu__panel .dh-sidenav__updates {
		padding: 0 12px;
	}

	.dh-sidenav-mobmenu__foot {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 10px;
		margin-top: auto;
		padding-top: 16px;
		border-top: 1px solid var(--dh-line);
	}

	html.dh-sidenav-mobmenu-open {
		overflow: hidden;
	}
}

/* Legacy overlay rail (non bottom-dock shells). */
@media (max-width: 767px) {
	.dh-nav-shell--mobile-dock .dh-sidenav-scrim {
		display: none !important;
	}

	.dh-nav-shell:not(.dh-nav-shell--mobile-dock).dh-sidenav {
		width: var(--dh-sidenav-min-w);
	}

	body:has(.dh-nav-shell:not(.dh-nav-shell--mobile-dock).dh-sidenav) .wp-site-blocks {
		padding-left: var(--dh-sidenav-min-w);
	}

	.dh-sidenav .dh-iconlink__label,
	.dh-sidenav .dh-sidenav__brandname {
		display: none;
	}

	.dh-sidenav .dh-iconlink,
	.dh-sidenav .dh-login-block {
		justify-content: center;
		padding-inline: 0;
	}

	.dh-sidenav__brand,
	.dh-sidenav__bar,
	.dh-sidenav__footrow {
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}

	.dh-sidenav--carpet .dh-navtabs,
	.dh-sidenav .dh-sidenav__ctarow,
	.dh-sidenav--cranes .dh-sidenav__search,
	.dh-sidenav--cranes .dh-sidenav__nav,
	.dh-sidenav--deck .dh-sidenav__search,
	.dh-sidenav .dh-sidenav__label,
	.dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__label,
	.dh-sidenav .dh-sidenav__nav .wp-block-navigation-submenu__toggle,
	.dh-sidenav .dh-sidenav__nav .wp-block-navigation__submenu-container {
		display: none;
	}

	.dh-sidenav .dh-navmono {
		display: inline-flex;
	}

	.dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__content {
		justify-content: center;
		padding-inline: 0;
	}

	/* Expanded-as-overlay. */
	html.dh-sidenav-open .dh-sidenav {
		width: min(320px, 86vw);
		box-shadow: 0 10px 40px rgb(0 0 0 / 0.35);
	}

	html.dh-sidenav-open .dh-sidenav .dh-iconlink__label,
	html.dh-sidenav-open .dh-sidenav .dh-sidenav__brandname {
		display: block;
	}

	html.dh-sidenav-open .dh-sidenav .dh-iconlink,
	html.dh-sidenav-open .dh-sidenav .dh-login-block {
		justify-content: flex-start;
		padding-inline: 10px;
	}

	html.dh-sidenav-open .dh-sidenav__brand,
	html.dh-sidenav-open .dh-sidenav__bar,
	html.dh-sidenav-open .dh-sidenav__footrow {
		flex-direction: row;
	}

	html.dh-sidenav-open .dh-sidenav__footrow {
		justify-content: space-between;
	}

	html.dh-sidenav-open .dh-sidenav--carpet .dh-navtabs,
	html.dh-sidenav-open .dh-sidenav .dh-sidenav__ctarow,
	html.dh-sidenav-open .dh-sidenav--cranes .dh-sidenav__search,
	html.dh-sidenav-open .dh-sidenav--cranes .dh-sidenav__nav,
	html.dh-sidenav-open .dh-sidenav--deck .dh-sidenav__search {
		display: flex;
	}

	html.dh-sidenav-open .dh-sidenav--cranes .dh-sidenav__nav {
		display: block;
	}

	html.dh-sidenav-open .dh-sidenav .dh-sidenav__label,
	html.dh-sidenav-open .dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__label {
		display: block;
	}

	html.dh-sidenav-open .dh-sidenav .dh-sidenav__nav .wp-block-navigation-submenu__toggle {
		display: inline-flex;
	}

	html.dh-sidenav-open .dh-sidenav .dh-sidenav__nav .wp-block-navigation__submenu-container {
		display: block;
	}

	html.dh-sidenav-open .dh-sidenav .dh-navmono {
		display: none;
	}

	html.dh-sidenav-open .dh-sidenav .dh-sidenav__nav .wp-block-navigation-item__content {
		justify-content: flex-start;
		padding-inline: 10px;
	}

	.dh-sidenav-scrim {
		position: fixed;
		inset: 0;
		z-index: 390;
		background: rgb(0 0 0 / 0.45);
		opacity: 0;
		pointer-events: none;
	}

	@media (prefers-reduced-motion: no-preference) {
		.dh-sidenav-scrim {
			transition: opacity var(--dh-speed) var(--dh-ease);
		}
	}

	html.dh-sidenav-open .dh-sidenav-scrim {
		opacity: 1;
		pointer-events: auto;
	}
}

/* State markup channel (Code/BLOCK-STATE-MODEL.md §5): a block rendered
   once per state ships both copies; the runtime toggles `hidden`. A
   block's own display rule would beat the UA's [hidden], so pin it. */
.dh-header [data-state][hidden] {
	display: none !important;
}
