/*
Theme Name: Developer Hack
Theme URI: https://developerhack.com
Author: InputIdea
Author URI: https://inputidea.com
Description: Deep Signal — the Developer Hack block theme. Built programmatically: templates and tokens live in the developerhack-com repo and deploy as one hashable artifact. Design tokens come from the "Deep Signal" brand system; every colour, size and step in theme.json traces to it.
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.1
Version: 0.4.0
License: Proprietary
License URI: https://developerhack.com/license
Text Domain: developerhack
Tags: block-theme, full-site-editing, dark
*/

/*
 * WHAT LIVES HERE AND WHAT DOES NOT.
 *
 * theme.json owns every token — colour, type, spacing, radius, shadow. Nothing in
 * this file re-declares one, and nothing here introduces a value that is not
 * derivable from a preset. If a hex appears below it is inside an rgba() for a
 * decorative wash, where a preset var cannot carry an alpha channel.
 *
 * This file holds the two things theme.json cannot express: keyframes, and the
 * pseudo-element background layers the Deep Signal look is built from.
 */

/* ---------------------------------------------------------------------------
   MOTION — the four named animations from the brand system's motion section.
   Quiet and ambient; never scrolljacking.
   --------------------------------------------------------------------------- */

@keyframes dh-blink { 50% { opacity: 0; } }
@keyframes dh-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@keyframes dh-fadeup {
	from { opacity: 0; transform: translateY(20px); }
	to   { opacity: 1; transform: translateY(0); }
}
@keyframes dh-spin { to { transform: rotate(360deg); } }

/*
 * REDUCED MOTION IS HONOURED, AND THE DECISION IS NOT UNIFORM.
 *
 * The plugin repo learned this the hard way: a blanket `animation: none` stops a
 * loading spinner, which then reads as "not loading" when it is. The same rule
 * applies in reverse here — every animation on this page is DECORATIVE (a fade-up
 * on load, a blinking cursor, a pulsing status dot, a slowly rotating sigil).
 * None of them is the only signal for anything, so under `reduce` they all stop
 * dead, and the fade-up must also settle VISIBLE rather than at its start state.
 */
@media (prefers-reduced-motion: reduce) {
	.dh-fadeup,
	.dh-blink,
	.dh-pulse,
	.dh-spin {
		animation: none !important;
	}

	.dh-fadeup {
		opacity: 1;
		transform: none;
	}
}

/* ---------------------------------------------------------------------------
   THE DEEP SIGNAL BACKDROP — two stacked layers on one element.
   --------------------------------------------------------------------------- */

/*
 * A 56px teal grid, then two radial washes. Both are pseudo-elements rather than
 * extra blocks: they are decoration with no content, so putting them in the
 * markup would give an editor two empty groups to trip over and a screen reader
 * two more nodes to announce.
 */
.dh-backdrop {
	position: relative;
	isolation: isolate;
}

.dh-backdrop::before,
.dh-backdrop::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: -1;
}

.dh-backdrop::before {
	background-image:
		linear-gradient(rgba(0, 212, 170, 0.035) 1px, transparent 1px),
		linear-gradient(90deg, rgba(0, 212, 170, 0.035) 1px, transparent 1px);
	background-size: 56px 56px;
}

/*
 * The two washes sit high in the page, per Homepage v2: violet right of centre,
 * teal left. Both templates share this — on the single-viewport Coming Soon page
 * "high in the page" and "behind the hero" are the same place, so there is no
 * reason for a second variant.
 */
.dh-backdrop::after {
	background:
		radial-gradient(ellipse at 78% 12%, rgba(108, 92, 231, 0.12) 0%, transparent 45%),
		radial-gradient(ellipse at 20% 8%, rgba(0, 212, 170, 0.10) 0%, transparent 42%);
}

/* ---------------------------------------------------------------------------
   ANIMATION HOOKS — applied by class from the templates.
   --------------------------------------------------------------------------- */

.dh-fadeup { animation: dh-fadeup 0.7s ease both; }
.dh-fadeup-1 { animation-delay: 0.1s; }
.dh-fadeup-2 { animation-delay: 0.2s; }
.dh-fadeup-3 { animation-delay: 0.3s; }
.dh-fadeup-4 { animation-delay: 0.45s; }
.dh-fadeup-5 { animation-delay: 0.55s; }

.dh-blink { animation: dh-blink 1.2s step-end infinite; }
.dh-pulse { animation: dh-pulse 2s ease infinite; }
.dh-spin {
	transform-box: fill-box;
	transform-origin: center;
	animation: dh-spin 16s linear infinite;
}

/* ---------------------------------------------------------------------------
   COMPONENT TEXTURE — the small pieces the brand system names.
   --------------------------------------------------------------------------- */

/* The mono eyebrow with a rule either side. */
.dh-eyebrow {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--xs);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}

.dh-eyebrow::before,
.dh-eyebrow::after {
	content: "";
	width: 30px;
	height: 1px;
	background: var(--wp--preset--color--accent);
	flex-shrink: 0;
}

/*
 * Homepage v2's hero eyebrow is left-aligned with ONE rule, to its left. Coming
 * Soon's is centred with a rule either side. Same component, one modifier, rather
 * than two near-identical blocks that drift apart.
 */
.dh-eyebrow--start {
	justify-content: flex-start;
	letter-spacing: 0.21em;
}

.dh-eyebrow--start::after { content: none; }

/* Amber eyebrow, rules included — the maintenance page's only signal colour. */
.dh-eyebrow--warm { color: var(--wp--preset--color--accent-warm); }

.dh-eyebrow--warm::before,
.dh-eyebrow--warm::after { background: var(--wp--preset--color--accent-warm); }

/* The gradient signature bar. Brand rule: key cards and code panels only. */
.dh-signature {
	position: relative;
	overflow: hidden;
}

.dh-signature::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	background: linear-gradient(
		90deg,
		var(--wp--preset--color--accent),
		var(--wp--preset--color--accent-alt),
		var(--wp--preset--color--accent-warm)
	);
}

/* The wordmark: mono braces, then the name with an accent second half. */
.dh-wordmark {
	display: inline-flex;
	align-items: center;
	gap: 11px;
	text-decoration: none;
	color: var(--wp--preset--color--ink);
}

.dh-wordmark:hover { text-decoration: none; }

.dh-wordmark__braces {
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 700;
	font-size: 1.625rem;
	line-height: 1;
	color: var(--wp--preset--color--accent);
	text-shadow: 0 0 20px rgba(0, 212, 170, 0.4);
}

.dh-wordmark__name {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.1875rem;
	letter-spacing: -0.02em;
}

.dh-wordmark__name em {
	font-style: normal;
	color: var(--wp--preset--color--accent);
}

/* Accent glow on a heading fragment. */
.dh-glow {
	color: var(--wp--preset--color--accent);
	text-shadow: 0 0 40px rgba(0, 212, 170, 0.3);
}

/*
 * The amber variant, for the maintenance page. `accent-warm` is already the brand
 * system's pending/queued colour in the Content Salvo workflow panel, and a
 * temporary outage is the same semantic — which also makes the maintenance page
 * unmistakably not the Coming Soon page at a glance.
 */
.dh-glow--warm {
	color: var(--wp--preset--color--accent-warm);
	text-shadow: 0 0 40px rgba(240, 165, 0, 0.3);
}

/* A pill status badge with a pulsing dot. */
.dh-badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.5625rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-alt);
	border: 1px solid rgba(108, 92, 231, 0.4);
	border-radius: 20px;
	padding: 3px 10px;
	white-space: nowrap;
}

.dh-badge__dot {
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--wp--preset--color--accent-alt);
	flex-shrink: 0;
}

/*
 * A status dot outside a badge. `.dh-badge__dot` is scoped to the pill; this is the
 * same shape used inline, and it takes `currentColor` so it inherits whatever signal
 * colour its context has already established rather than naming one again.
 */
.dh-dot {
	display: inline-block;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
	vertical-align: middle;
}

.dh-dot--warm { background: var(--wp--preset--color--accent-warm); }

/* ---------------------------------------------------------------------------
   THE MAINTENANCE STATUS STRIP
   --------------------------------------------------------------------------- */

/*
 * Three key/value rows under a gradient signature bar. Deliberately looks like a
 * readout rather than prose: the page is machine-adjacent (it accompanies a 503),
 * and a mono table reads as a state report instead of an apology.
 */
.dh-status {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--xs);
	width: 100%;
	max-width: 420px;
	margin-inline: auto;
	text-align: left;
	background: rgba(17, 17, 34, 0.85);
	border: 1px solid rgba(240, 165, 0, 0.2);
	border-radius: 8px;
	padding: var(--wp--preset--spacing--md) var(--wp--preset--spacing--lg);
}

.dh-status__row {
	display: flex;
	align-items: baseline;
	gap: var(--wp--preset--spacing--sm);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	line-height: 1.5;
}

.dh-status__key {
	flex: 0 0 4.5rem;
	color: var(--wp--preset--color--ink-dim);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-size: 0.625rem;
}

.dh-status__val { color: var(--wp--preset--color--ink-muted); }
.dh-status__val--warm { color: var(--wp--preset--color--accent-warm); }

@media (max-width: 600px) {
	.dh-status { padding: var(--wp--preset--spacing--md); }
	.dh-status__row { flex-direction: column; gap: 2px; }
}

/* ---------------------------------------------------------------------------
   THE CAPTURE FORM — styling markup this repo does not own
   --------------------------------------------------------------------------- */

/*
 * THE FORM IS `inervecenter/capture-form`. Everything below styles hooks the
 * plugin emits; none of this markup lives in this repo, and that is the point —
 * the block generates the honeypot and the timing token from the ability's own
 * constants and refuses to register if the two disagree, which a copy of the
 * markup here could never do.
 *
 * The hooks are a shipped interface per contract §9: `-form`, `-heading`,
 * `-field`, `-submit`, `-status`, `-decoy`, on a wrapper carrying `.ii-nc-capture`.
 * Measured off the rendered output rather than read out of the block's PHP.
 *
 * ⚠️ `.ii-nc-capture-decoy` IS NOT STYLED HERE AND MUST NOT BE. Its inline
 * off-screen positioning is what makes the honeypot work; `display:none` would
 * make some fillers skip it and quietly retire the control (contract §3). It is
 * absolutely positioned, so it costs nothing in the flex row below.
 */
.ii-nc-capture {
	width: 100%;
	max-width: 480px;
	margin-inline: auto;
}

/*
 * Input and button on one line, status underneath. The DOM order the block emits
 * is heading, field, decoy, hidden inputs, button, status — so a wrapping flex row
 * with a full-width status is the layout that needs no ordering tricks.
 */
.ii-nc-capture-form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 10px;
}

.ii-nc-capture-heading {
	flex-basis: 100%;
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.125rem;
	text-align: left;
}

.ii-nc-capture-field {
	flex: 1 1 12rem;
	min-width: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
	text-align: left;
}

/*
 * THE LABEL IS VISIBLE, AND THAT IS A DELIBERATE DEPARTURE FROM THE MOCK. The
 * design shows a placeholder and no label. The block emits a real `<label>` and no
 * placeholder, and hiding it would leave an unlabelled empty box — worse for
 * everyone, not just for a screen reader. So it is styled as a mono field label,
 * which the brand system already has a shape for.
 */
.ii-nc-capture-field label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-dim);
}

/*
 * ⚠️ `box-sizing: border-box` IS LOAD-BEARING, NOT TIDINESS. WordPress does not
 * reset it for form controls in a block theme, so `width: 100%` plus `padding:
 * 15px 18px` plus a 1px border made this input 378px wide inside a 340px field —
 * it slid 28px underneath the submit button. Measured, not noticed: at a glance the
 * row looked correct because the button paints over the overflow.
 */
.ii-nc-capture-field input {
	box-sizing: border-box;
	width: 100%;
	padding: 15px 18px;
	background: rgba(17, 17, 34, 0.9);
	border: 1px solid rgba(136, 136, 170, 0.25);
	border-radius: 4px;
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.8125rem;
	outline: none;
}

.ii-nc-capture-field input:focus-visible {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 0 0 2px rgba(0, 212, 170, 0.25);
}

.ii-nc-capture-submit {
	box-sizing: border-box;
	/* A transparent 1px border so the button's box matches the input's, which has a
	   real one. Without it they differ by 2px and bottom-align visibly out of step. */
	border: 1px solid transparent;
	padding: 15px 26px;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	border-radius: 4px;
	cursor: pointer;
	white-space: nowrap;
	box-shadow: 0 0 30px rgba(0, 212, 170, 0.22);
	transition: box-shadow 0.3s ease;
}

.ii-nc-capture-submit:hover { box-shadow: 0 0 48px rgba(0, 212, 170, 0.4); }

.ii-nc-capture-submit[disabled] {
	opacity: 0.6;
	cursor: default;
	box-shadow: none;
}

/*
 * THE LIVE REGION. The block's script writes `textContent` here and nothing else —
 * there is no success/error modifier class — so one legible neutral style has to
 * carry both outcomes, and it does.
 *
 * When empty it collapses to `height: 0` rather than `display: none`: an
 * `aria-live` region that is removed from the box tree and then returned is not
 * reliably announced, and the whole purpose of this element is to be announced.
 */
.ii-nc-capture-status {
	flex-basis: 100%;
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	letter-spacing: 0.04em;
	line-height: 1.5;
	color: var(--wp--preset--color--ink-muted);
	text-align: left;
}

.ii-nc-capture-status:empty { height: 0; }

/*
 * Success, tinted — a PROGRESSIVE refinement, not a requirement. On success the
 * script removes the field and the button and sets `data-nc-done` on the form; that
 * attribute is not named in the contract as a styling interface, so if it ever goes
 * away this rule simply stops applying and the message stays perfectly readable in
 * the neutral style above.
 */
.ii-nc-capture-form[data-nc-done="1"] .ii-nc-capture-status {
	color: var(--wp--preset--color--accent);
}

/* MOBILE: the row stacks. Measured at 480px the button beside the input leaves the
   input about 90px wide, which is unusable. */
@media (max-width: 600px) {
	.ii-nc-capture-field { flex-basis: 100%; }
	.ii-nc-capture-submit { width: 100%; }
}

/* The reassurance line under the Coming Soon form. Ours, not the block's. */
.dh-capture-note {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	color: var(--wp--preset--color--ink-dim);
	letter-spacing: 0.04em;
}

/*
 * IN THE CLOSING CTA PANEL THE BUTTON IS VIOLET. Content Salvo's own colour, the
 * same as the two buttons that scroll down to it, so arriving at the form does not
 * look like arriving somewhere else.
 */
.dh-cta .ii-nc-capture-submit {
	background: var(--wp--preset--color--accent-alt);
	color: #fff;
	box-shadow: 0 0 32px rgba(108, 92, 231, 0.3);
}

.dh-cta .ii-nc-capture-submit:hover { box-shadow: 0 0 52px rgba(108, 92, 231, 0.45); }

/* ---------------------------------------------------------------------------
   THE CONTENT SALVO CARD
   --------------------------------------------------------------------------- */

.dh-salvo {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--md);
	text-align: left;
	max-width: 560px;
	margin-inline: auto;
	background: rgba(17, 17, 34, 0.85);
	border: 1px solid rgba(108, 92, 231, 0.25);
	border-radius: 12px;
	padding: var(--wp--preset--spacing--md) var(--wp--preset--spacing--lg);
}

.dh-salvo__sigil { flex-shrink: 0; }

.dh-salvo__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: -0.015em;
}

.dh-salvo__head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 6px;
}

.dh-salvo__body {
	font-size: 0.875rem;
	font-weight: 300;
	color: var(--wp--preset--color--ink-muted);
	line-height: 1.6;
	margin: 0;
}

/* The sigil is 64px of decoration; below 600px it costs more than it gives. */
@media (max-width: 600px) {
	.dh-salvo { gap: var(--wp--preset--spacing--sm); padding: var(--wp--preset--spacing--md); }
	.dh-salvo__sigil { display: none; }
}

/* ---------------------------------------------------------------------------
   LAYOUT HELPERS
   --------------------------------------------------------------------------- */

/* The front page is a full-viewport column: nav, centred body, footer. */
.dh-viewport {
	min-height: 100vh;
	min-height: 100svh;
	display: flex;
	flex-direction: column;
}

.dh-viewport__center {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
}

/* A hairline rule, used above the footer. */
.dh-rule-top { border-top: 1px solid rgba(255, 255, 255, 0.04); }

/* Mono micro-copy, used in the footer and captions. */
.dh-mono-dim {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	color: var(--wp--preset--color--ink-dim);
	letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------------
   FOCUS — one visible ring everywhere, on our own colours.
   --------------------------------------------------------------------------- */

:where(a, button, input, textarea, select, summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   ARCHIVE / LIST TEXTURE — the non-front templates are minimal but real.
   --------------------------------------------------------------------------- */

.dh-meta {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}

.dh-card {
	background: var(--wp--preset--color--card);
	border: 1px solid rgba(255, 255, 255, 0.04);
	border-radius: 8px;
	padding: var(--wp--preset--spacing--lg);
	transition: border-color 0.4s ease, transform 0.4s ease;
}

.dh-card:hover {
	border-color: rgba(0, 212, 170, 0.18);
	transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
	.dh-card:hover { transform: none; }
}

/* ===========================================================================
   HOMEPAGE V2
   ===========================================================================

   Everything below arrived with Homepage v2. It is organised the way the page
   reads top to bottom — chrome, hero, sections, footer — rather than by CSS
   concern, because that is the order someone comparing this file to the design
   will be working in.

   THE GUTTER RULE, STATED ONCE. The page wrapper zeroes its own horizontal
   padding so the backdrop and every section rule can run edge to edge. Each
   full-width band therefore owns its gutter, via `.dh-section` or its own
   `__inner`. The design's gutter is 44px; `xl` (48px) is the nearest token and
   nothing here invents a value to hit 44 exactly.
   --------------------------------------------------------------------------- */

.dh-section {
	padding-inline: var(--wp--preset--spacing--md);
}

@media (min-width: 782px) {
	.dh-section {
		padding-inline: var(--wp--preset--spacing--xl);
	}
}

/* ---------------------------------------------------------------------------
   THE NAV BAR
   --------------------------------------------------------------------------- */

/*
 * A translucent bar with a blurred backdrop, sitting on the decorative grid.
 * NOT sticky — the design's nav is `position: relative`, and a page this long
 * with a 62px hero does not want 70px of chrome following it down.
 *
 * ⚠️ THE BLUR IS ON A PSEUDO-ELEMENT, AND MOVING IT BACK ONTO `.dh-nav` BREAKS THE
 * PHONE MENU. `backdrop-filter` makes an element a CONTAINING BLOCK for
 * `position: fixed` descendants. Core's mobile overlay is `position: fixed;
 * inset: 0` and expects that to mean the viewport; with the filter on `.dh-nav` it
 * meant the 70px nav bar instead. Measured: the open overlay was 29px tall inside a
 * 844px viewport, so the first link sat on it and the other two painted over the
 * page below — a menu that looked half-broken and half-missing.
 *
 * A pseudo-element carries the filter without becoming an ancestor of anything, so
 * the same frosted bar renders and `fixed` resolves against the viewport again. The
 * inner wrapper is positioned so it paints ABOVE the pseudo-element: an absolutely
 * positioned `::before` outranks in-flow content in paint order, and without this it
 * would sit on top of the wordmark.
 */
.dh-nav {
	position: relative;
	border-bottom: 1px solid rgba(0, 212, 170, 0.1);
}

.dh-nav::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: rgba(10, 10, 20, 0.6);
	backdrop-filter: blur(12px);
}

.dh-nav__inner {
	position: relative;
	max-width: 1180px;
	margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--md);
}

@media (min-width: 782px) {
	.dh-nav__inner { padding-inline: var(--wp--preset--spacing--xl); }
}

/*
 * The three nav links.
 *
 * ⚠️ THE COLOUR IS SET ON THE CONTAINER, NOT ON THE LINK, AND THAT IS NOT A
 * STYLISTIC PREFERENCE. Core ships
 *
 *     .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content
 *         { color: inherit; }
 *
 * — the class is DOUBLED, deliberately, giving specificity 0,3,0. The obvious
 * rule here (`.dh-nav__menu .wp-block-navigation-item__content { color: ... }`)
 * is 0,2,0 and loses; it was written that way first, and the rendered check
 * measured the links at `rgb(232,232,240)` — inherited ink — while every other
 * property on the same rule applied. A class the theme sets and core does not
 * touch wins; a class core has already doubled does not.
 *
 * So the container carries the colour and core's own `inherit` delivers it.
 * Hover matches core's specificity by doubling the class the same way.
 */
.dh-nav__menu {
	color: var(--wp--preset--color--ink-muted);
}

.dh-nav__menu .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	font-weight: 400;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	text-decoration: none;
}

.dh-nav__menu .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.dh-nav__menu .wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

/*
 * THE MOBILE OVERLAY'S COLOURS ARE NOT SET HERE, DELIBERATELY.
 *
 * They live on the navigation block in `parts/header.html`, as
 * `overlayBackgroundColor` / `overlayTextColor`, because core paints an unstyled
 * open overlay WHITE from a 0,5,0 selector — see the comment there. A rule in this
 * file cannot reach it without either `!important` or a specificity contest, and
 * core's own selector carries the escape hatch (`:not(.has-background)`), so the
 * block attribute is the supported route rather than a workaround.
 *
 * Only the things core has no attribute for stay in CSS.
 */
.dh-nav__menu .wp-block-navigation__responsive-container-open,
.dh-nav__menu .wp-block-navigation__responsive-container-close {
	color: var(--wp--preset--color--ink);
}

.dh-nav__menu .wp-block-navigation__responsive-container.is-menu-open {
	padding: var(--wp--preset--spacing--xl) var(--wp--preset--spacing--md);
}

.dh-nav__menu .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	font-size: 0.875rem;
}

/* ---------------------------------------------------------------------------
   BUTTON VARIANTS — four, and each one is a job the design gives it.
   --------------------------------------------------------------------------- */

/* theme.json's button element owns family, size, weight, tracking, case and
   radius. These only change colour, padding and glow. */

/* Accent fill with a teal halo — the hero's primary. */
.dh-btn-glow .wp-element-button {
	box-shadow: 0 0 34px rgba(0, 212, 170, 0.25);
	transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.dh-btn-glow .wp-element-button:hover {
	box-shadow: 0 0 54px rgba(0, 212, 170, 0.4);
	transform: translateY(-2px);
}

/* Violet fill — Content Salvo's own colour, used for its two calls to action. */
.dh-btn-alt .wp-element-button {
	background-color: var(--wp--preset--color--accent-alt);
	color: #fff;
	box-shadow: 0 0 32px rgba(108, 92, 231, 0.3);
	transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.dh-btn-alt .wp-element-button:hover {
	background-color: var(--wp--preset--color--accent-alt);
	box-shadow: 0 0 52px rgba(108, 92, 231, 0.45);
	transform: translateY(-2px);
}

/* Outlined accent — the nav's call to action, and it fills on hover. */
.dh-btn-outline .wp-element-button {
	background-color: transparent;
	color: var(--wp--preset--color--accent);
	border: 1px solid var(--wp--preset--color--accent);
	transition: background-color 0.25s ease, color 0.25s ease;
}

.dh-btn-outline .wp-element-button:hover {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

/* The nav button is smaller than a body button. */
.dh-btn-sm .wp-element-button {
	padding: 9px 18px;
}

/* A quiet secondary: muted rule, muted text, no fill. */
.dh-btn-quiet .wp-element-button {
	background-color: transparent;
	color: var(--wp--preset--color--ink-muted);
	border: 1px solid rgba(136, 136, 170, 0.25);
	transition: border-color 0.25s ease, color 0.25s ease;
}

.dh-btn-quiet .wp-element-button:hover {
	border-color: var(--wp--preset--color--ink-muted);
	color: var(--wp--preset--color--ink);
	background-color: transparent;
}

@media (prefers-reduced-motion: reduce) {
	.dh-btn-glow .wp-element-button:hover,
	.dh-btn-alt .wp-element-button:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   SECTION KICKERS AND SMALL TEXT
   --------------------------------------------------------------------------- */

/*
 * `// how we think` — mono, wide-tracked, uppercase. Applied to an `h2` in the
 * How We Think section, where it IS the section heading; theme.json's `h2`
 * element style is a one-element selector, so this single class outranks all of
 * family, size, weight and tracking without any `!important`.
 */
.dh-kicker {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--label);
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: 0.36em;
	text-transform: uppercase;
}

/* Inside a card the 4px tracking is too loose for the width available. */
.dh-kicker--tight { letter-spacing: 0.18em; }

/* The one emphasised phrase in the hero paragraph. */
.dh-strong {
	color: var(--wp--preset--color--ink);
	font-weight: 500;
}

/* A mono numeral above a card title — amber, per the leverage test. */
.dh-num {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.05em;
}

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

/*
 * A capped sentence under an uncapped heading. Both centred blocks on this page
 * want the heading to span and only the line beneath it to be measured; a
 * `constrained` parent caps every child alike, which is not the same shape.
 */
.dh-lede {
	max-width: 560px;
	margin-inline: auto;
}

.dh-lede--narrow { max-width: 460px; }

/* ---------------------------------------------------------------------------
   THE HERO CODE PANEL
   --------------------------------------------------------------------------- */

/*
 * Ten lines of mono with a gradient signature bar across the top (`.dh-signature`
 * supplies the bar). Lines are block-level `div`s so they wrap inside the panel
 * instead of pushing it wider than a phone — which is what a `pre` would do, and
 * the mobile-overflow assertion in bin/check-theme-render.mjs would catch it.
 */
.dh-code {
	background: rgba(17, 17, 34, 0.85);
	border: 1px solid rgba(0, 212, 170, 0.12);
	border-radius: 8px;
	padding: var(--wp--preset--spacing--md) var(--wp--preset--spacing--md) var(--wp--preset--spacing--md) var(--wp--preset--spacing--sm);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.78rem;
	line-height: 1.85;
	color: var(--wp--preset--color--ink-dim);
}

.dh-code__line { white-space: normal; }

.dh-code__ln {
	display: inline-block;
	min-width: 26px;
	opacity: 0.35;
	user-select: none;
}

.dh-code__c {
	color: var(--wp--preset--color--ink-dim);
	font-style: italic;
	opacity: 0.7;
}

.dh-code__c--signal {
	color: var(--wp--preset--color--accent);
	font-style: normal;
	opacity: 0.85;
}

.dh-code__kw { color: var(--wp--preset--color--accent-alt); }
.dh-code__fn { color: var(--wp--preset--color--accent); }
.dh-code__str { color: var(--wp--preset--color--accent-warm); }

/* ---------------------------------------------------------------------------
   THE HOW-WE-THINK PANELS
   --------------------------------------------------------------------------- */

.dh-panel {
	height: 100%;
	background: rgba(17, 17, 34, 0.7);
	border: 1px solid rgba(255, 255, 255, 0.06);
	border-radius: 10px;
	padding: var(--wp--preset--spacing--lg);
}

.dh-panel--accent { border-color: rgba(0, 212, 170, 0.25); }
.dh-panel--alt { border-color: rgba(108, 92, 231, 0.3); }

/* ---------------------------------------------------------------------------
   THE CONTENT SALVO IDENTITY BLOCK
   --------------------------------------------------------------------------- */

.dh-ident {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	margin-bottom: var(--wp--preset--spacing--md);
}

.dh-ident__sigil { flex-shrink: 0; }

.dh-ident__over {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-dim);
	margin: 0;
}

.dh-ident__name {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.625rem;
	letter-spacing: -0.015em;
	margin: 0;
}

.dh-badge-row { margin: 0 0 var(--wp--preset--spacing--md); }

/* The three feature bullets: a violet marker, no list bullet. */
.dh-bullets {
	list-style: none;
	padding-left: 0;
}

.dh-bullets li {
	position: relative;
	padding-left: 22px;
	font-size: 0.875rem;
	line-height: 1.5;
	margin-bottom: 11px;
}

.dh-bullets li::before {
	content: "▸";
	position: absolute;
	left: 0;
	font-family: var(--wp--preset--font-family--mono);
	color: var(--wp--preset--color--accent-alt);
}

/* ---------------------------------------------------------------------------
   THE WORKFLOW PANEL — a picture of Content Salvo running.
   --------------------------------------------------------------------------- */

.dh-flow {
	background: #0d0d1c;
	border: 1px solid rgba(108, 92, 231, 0.18);
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 24px 70px rgba(0, 0, 0, 0.5);
}

.dh-flow__chrome {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	padding: 13px var(--wp--preset--spacing--sm);
	border-bottom: 1px solid rgba(255, 255, 255, 0.05);
	background: rgba(108, 92, 231, 0.05);
}

.dh-flow__dots { display: flex; gap: 6px; }

.dh-flow__dots i {
	width: 9px;
	height: 9px;
	border-radius: 50%;
}

.dh-flow__dots i:nth-child(1) { background: #ff6b9d; }
.dh-flow__dots i:nth-child(2) { background: var(--wp--preset--color--accent-warm); }
.dh-flow__dots i:nth-child(3) { background: var(--wp--preset--color--accent); }

.dh-flow__file {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	color: var(--wp--preset--color--ink-muted);
}

.dh-flow__body { padding: var(--wp--preset--spacing--md) var(--wp--preset--spacing--sm); }

.dh-flow__head {
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xxs);
	margin-bottom: var(--wp--preset--spacing--sm);
}

.dh-flow__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 0.9375rem;
}

.dh-flow__tag {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	color: var(--wp--preset--color--accent-alt);
	border: 1px solid rgba(108, 92, 231, 0.3);
	border-radius: 4px;
	padding: 3px 8px;
}

/* Five steps and four connecting rails, as one flex row. */
.dh-flow__steps {
	display: flex;
	align-items: flex-start;
	margin-bottom: var(--wp--preset--spacing--sm);
}

.dh-flow__step {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.5rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-align: center;
	color: var(--wp--preset--color--ink-dim);
}

.dh-flow__step i {
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: var(--wp--preset--color--ink-dim);
	flex-shrink: 0;
}

.dh-flow__step.is-done { color: var(--wp--preset--color--accent); }
.dh-flow__step.is-done i { background: var(--wp--preset--color--accent); }
.dh-flow__step.is-now { color: var(--wp--preset--color--accent-alt); }
.dh-flow__step.is-now i { background: var(--wp--preset--color--accent-alt); }
.dh-flow__step.is-next i { background: var(--wp--preset--color--accent-warm); opacity: 0.5; }

.dh-flow__rail {
	flex: 0 1 0.6em;
	height: 1px;
	margin-top: 5px;
	background: rgba(255, 255, 255, 0.12);
}

.dh-flow__rail.is-done { background: rgba(0, 212, 170, 0.4); }

.dh-flow__rows {
	display: flex;
	flex-direction: column;
	gap: 9px;
}

.dh-flow__row {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	padding: 12px 14px;
	background: rgba(255, 255, 255, 0.025);
	border: 1px solid rgba(255, 255, 255, 0.05);
	border-radius: 6px;
	border-left-width: 2px;
	border-left-style: solid;
}

.dh-flow__what {
	flex: 1;
	min-width: 0;
	font-size: 0.8125rem;
	line-height: 1.35;
	color: var(--wp--preset--color--ink);
}

.dh-flow__what em {
	display: block;
	margin-top: 3px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	font-style: normal;
	color: var(--wp--preset--color--ink-dim);
}

.dh-flow__state {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.5rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	white-space: nowrap;
}

.dh-flow__row.is-ready { border-left-color: var(--wp--preset--color--accent); }
.dh-flow__row.is-ready .dh-flow__state { color: var(--wp--preset--color--accent); }
.dh-flow__row.is-review { border-left-color: var(--wp--preset--color--accent-alt); }
.dh-flow__row.is-review .dh-flow__state { color: var(--wp--preset--color--accent-alt); }
.dh-flow__row.is-queued { border-left-color: var(--wp--preset--color--accent-warm); }
.dh-flow__row.is-queued .dh-flow__state { color: var(--wp--preset--color--accent-warm); }

/* ---------------------------------------------------------------------------
   THE CARD GRIDS
   --------------------------------------------------------------------------- */

/* `.dh-card` already carries the card surface, rule and lift. A grid child must
   also fill its cell, or a short card leaves a hole under it. */
.dh-grid > .dh-card { height: 100%; }

/* The leverage test's cards warm to amber rather than teal on hover. */
.dh-card--warm:hover { border-color: rgba(240, 165, 0, 0.25); }

/* ---------------------------------------------------------------------------
   THE "MORE SYSTEMS COMING" BAND
   --------------------------------------------------------------------------- */

.dh-band {
	background: linear-gradient(180deg, rgba(0, 212, 170, 0.04), transparent);
}

.dh-band__line { line-height: 1.7; }

.dh-band__tag {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
	white-space: nowrap;
}

.dh-band__text {
	font-size: var(--wp--preset--font-size--body-l);
	font-weight: 300;
	color: var(--wp--preset--color--ink-muted);
}

/* ---------------------------------------------------------------------------
   THE CLOSING CALL TO ACTION
   --------------------------------------------------------------------------- */

/*
 * A card-surface panel with a violet wash bled in from behind. The wash is a
 * pseudo-element so the panel stays one block in the markup.
 */
.dh-cta {
	position: relative;
	overflow: hidden;
	background: var(--wp--preset--color--card);
	border: 1px solid rgba(108, 92, 231, 0.18);
	border-radius: 16px;
	padding: var(--wp--preset--spacing--xxl) var(--wp--preset--spacing--lg);
	text-align: center;
}

.dh-cta::before {
	content: "";
	position: absolute;
	inset: -50%;
	pointer-events: none;
	background: radial-gradient(circle at center, rgba(108, 92, 231, 0.07) 0%, transparent 50%);
}

.dh-cta > * { position: relative; }

.dh-cta__head {
	font-size: var(--wp--preset--font-size--heading-l);
	line-height: 1.2;
	margin-bottom: var(--wp--preset--spacing--xs);
}

/* ---------------------------------------------------------------------------
   THE FOOTER
   --------------------------------------------------------------------------- */

.dh-foot__inner {
	max-width: 1180px;
	margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--md);
}

@media (min-width: 782px) {
	.dh-foot__inner { padding-inline: var(--wp--preset--spacing--xl); }
}

.dh-foot__links a {
	color: var(--wp--preset--color--ink-dim);
	text-decoration: none;
}

.dh-foot__links a:hover,
.dh-foot__links a:focus-visible {
	color: var(--wp--preset--color--accent);
	text-decoration: none;
}
