/*
Theme Name: Huntley Scanner
Theme URI: https://github.com/zacharyfleck
Author: Zachary Fleck
Author URI: https://github.com/zacharyfleck
Description: A custom block (Full Site Editing) theme for Huntley Scanner — live fire and EMS radio for McHenry County, Illinois. Dark, high-contrast, and built around Broadcastify and OpenMHz feeds.
Version: 1.0.2
Requires at least: 6.5
Tested up to: 6.7
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: huntley-scanner
Tags: blog, news, block-patterns, full-site-editing, custom-colors, custom-logo, dark-mode, one-column, two-columns, three-columns, featured-images
*/

/*
 * Most styling for this theme lives in theme.json (colors, fonts, layout,
 * spacing, buttons, links). This stylesheet only holds what theme.json cannot
 * express:
 *   0. Sticky footer
 *   1. Hero treatment
 *   2. Section furniture (eyebrows, section headers)
 *   3. Feed cards, badges and status indicators
 *   4. Post cards (query loops)
 *   5. Header / navigation responsive behavior
 *   6. Footer layout
 *   7. Form controls on a dark background
 *   8. Contact Form 7
 */

/* ------------------------------------------------------------------ *
 * 0. Sticky footer
 *    Keep the footer pinned to the bottom of the viewport on short pages
 *    (e.g. 404, thin pages). WordPress wraps all template blocks in
 *    .wp-site-blocks; make it a full-height flex column and let <main> grow.
 * ------------------------------------------------------------------ */

.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.wp-site-blocks > main {
	flex: 1 0 auto;
	margin-block-start: 0;
}

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

/* ------------------------------------------------------------------ *
 * 1. Hero
 *    A dark gradient panel with a soft red glow off the top-right and a
 *    faint scan-line grid — a nod to radio equipment without the kitsch.
 *    Both overlays are decorative and sit behind the content.
 * ------------------------------------------------------------------ */

.hs-hero {
	position: relative;
	overflow: hidden;
	isolation: isolate;
	border-bottom: 1px solid var(--wp--preset--color--graphite);
}

.hs-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -2;
	background:
		radial-gradient(60rem 32rem at 82% -12%, rgba(204, 51, 51, 0.35), transparent 62%),
		radial-gradient(40rem 26rem at 8% 108%, rgba(204, 51, 51, 0.12), transparent 60%);
	pointer-events: none;
}

.hs-hero h1 {
	max-width: 18ch;
}

/* The hero's supporting paragraph should not run the full 46rem column. */
.hs-hero .hs-hero__lede {
	max-width: 46ch;
}

/* ------------------------------------------------------------------ *
 * 2. Section furniture
 * ------------------------------------------------------------------ */

/* Small mono label that sits above a section heading. */
.hs-eyebrow {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 500;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ash);
	margin-bottom: 0.5rem;
}

/* A short red rule, used as an accent under section headings. */
.hs-eyebrow::before {
	content: "";
	display: inline-block;
	width: 1.75rem;
	height: 2px;
	margin-right: 0.75rem;
	vertical-align: middle;
	background: var(--wp--preset--color--red);
}

/* Centered sections put the rule above the label instead of beside it. */
.has-text-align-center.hs-eyebrow::before {
	display: block;
	margin: 0 auto 0.75rem;
}

/* Alternating band backgrounds get a hairline separator so the seam reads
   as intentional rather than as a rendering artifact. */
.hs-band {
	border-top: 1px solid var(--wp--preset--color--graphite);
	border-bottom: 1px solid var(--wp--preset--color--graphite);
}

/* ------------------------------------------------------------------ *
 * 3. Players, link rows and badges
 * ------------------------------------------------------------------ */

.hs-card {
	padding: 1.5rem;
	background: var(--wp--preset--color--charcoal);
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 8px;
}

.hs-card__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.4rem;
	line-height: 1.15;
	color: var(--wp--preset--color--white);
}

.hs-card__text {
	margin: 0.35rem 0 0;
	color: var(--wp--preset--color--ash);
	font-size: var(--wp--preset--font-size--small);
}

/* Live stream cards. Broadcastify retired its embeddable player, so the whole
   card is a link out to the feed page. */
.hs-players {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
	gap: 1.5rem;
}

.hs-player {
	display: flex;
	flex-direction: column;
	text-decoration: none;
	transition: border-color 0.2s ease;
}

.hs-player:hover,
.hs-player:focus-visible {
	border-color: var(--wp--preset--color--red);
	text-decoration: none;
}

/* Pushed to the bottom so the cue lines up across cards of unequal height. */
.hs-player__cue {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	margin-top: auto;
	padding-top: 1.25rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ash);
	transition: color 0.2s ease;
}

.hs-player:hover .hs-player__cue,
.hs-player:focus-visible .hs-player__cue {
	color: var(--wp--preset--color--ember);
}

/* Feeds that have no embed (Broadcastify Calls, OpenMHz) are link rows. */
.hs-links {
	display: grid;
	gap: 0.75rem;
}

.hs-link {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 1rem 1.25rem;
	background: var(--wp--preset--color--charcoal);
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 8px;
	text-decoration: none;
	transition: border-color 0.2s ease, background 0.2s ease;
}

.hs-link:hover,
.hs-link:focus-visible {
	border-color: var(--wp--preset--color--red);
	text-decoration: none;
}

.hs-link__title {
	margin-right: auto;
	font-weight: 600;
	color: var(--wp--preset--color--white);
}

.hs-link__arrow {
	color: var(--wp--preset--color--ash);
	transition: color 0.2s ease, transform 0.2s ease;
}

.hs-link:hover .hs-link__arrow,
.hs-link:focus-visible .hs-link__arrow,
.hs-player:hover .hs-link__arrow,
.hs-player:focus-visible .hs-link__arrow {
	color: var(--wp--preset--color--ember);
	transform: translate(2px, -2px);
}

@media (prefers-reduced-motion: reduce) {
	.hs-link__arrow {
		transition: none;
	}

	.hs-link:hover .hs-link__arrow,
	.hs-link:focus-visible .hs-link__arrow,
	.hs-player:hover .hs-link__arrow,
	.hs-player:focus-visible .hs-link__arrow {
		transform: none;
	}
}

/* ------------------------------------------------------------------ *
 * 3a. Departments
 * ------------------------------------------------------------------ */

/* The details card on a single department. A description list rather than a
   table: the rows are label/value pairs, not tabular data, and rows with no
   value are dropped server-side (see inc/department.php).

   Vertical margin is deliberately not set here. Block layout already emits
   `> * { margin-block: 0 }` plus a blockGap rule on its children, at the same
   specificity as a class — and this stylesheet loads after those, so a
   `margin: 0` here would silently win and collapse the gap the template asked
   for. Same applies to every other direct child of a layout container below. */
.hs-dept-details {
	display: grid;
}

.hs-dept-details__row {
	display: grid;
	grid-template-columns: minmax(8rem, 12rem) 1fr;
	gap: 0.5rem 1.5rem;
	padding: 0.85rem 0;
	border-top: 1px solid var(--wp--preset--color--graphite);
}

.hs-dept-details__row:first-child {
	padding-top: 0;
	border-top: 0;
}

.hs-dept-details__row:last-child {
	padding-bottom: 0;
}

.hs-dept-details__label {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ash);
}

.hs-dept-details__value {
	margin: 0;
	color: var(--wp--preset--color--fog);
}

/* Multi-line fields (address, hours) come back as a plain list. */
.hs-dept-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.hs-dept-list li + li {
	margin-top: 0.25rem;
}

/* Editor-only note, shown where the Site Editor has no department to read. */
.hs-dept-details__notice {
	margin: 0;
	padding: 1rem 1.25rem;
	color: var(--wp--preset--color--ash);
	font-size: var(--wp--preset--font-size--small);
	border: 1px dashed var(--wp--preset--color--steel);
	border-radius: 8px;
}

/* The unit-numbering roster in the post body.

   Scoped to the body class rather than a class on the template's post-content,
   so this still applies if the department template has been customised in the
   Site Editor — the database copy would not carry a class added to the file.

   Core's table block leaves two marks that make an untouched table look like a
   spreadsheet: a 1px `currentColor` border on every cell, and `table-layout:
   fixed` from the editor's default `has-fixed-layout`. Fixed layout splits two
   columns 50/50, which hands the same width to "902" as to "Station 2
   Ambulance". Both are undone below: borders come off in favour of banded rows,
   and the identifier column shrinks to its content.

   No vertical margin here — the figure is a direct child of the post-content
   layout container, which already owns the gap either side of it. See the note
   at the top of 3a. */
.single-hs_department .wp-block-table {
	/* Long descriptions on a narrow screen scroll the table, not the page.
	   `overflow` also clips the banded rows to the radius. */
	overflow-x: auto;
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 8px;
}

/* Beats core's `.wp-block-table .has-fixed-layout` (0,2,0) on the strength of
   the element selector. */
.single-hs_department .wp-block-table table {
	table-layout: auto;
	border-collapse: collapse;
	width: 100%;
}

.single-hs_department .wp-block-table td {
	border: 0;
	padding: 0.6rem 1.25rem;
	vertical-align: top;
}

/* Mildly alternating bands. Charcoal is one step off the ink page background —
   enough to track a row across on Huntley's 27-row roster, not so much that the
   table reads as striped. */
.single-hs_department .wp-block-table tr:nth-child(odd) {
	background-color: var(--wp--preset--color--charcoal);
}

.single-hs_department .wp-block-table tr:hover {
	background-color: var(--wp--preset--color--graphite);
}

/* The identifier column: mono, because these are call signs rather than prose,
   matching how the theme sets every other technical string. `width: 1%` with no
   wrapping collapses the column to its widest value — "MABAS AIR 5" on Huntley
   — and leaves the rest to the description. */
.single-hs_department .wp-block-table td:first-child {
	width: 1%;
	white-space: nowrap;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.8rem;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--white);
}

.single-hs_department .wp-block-table td:last-child {
	color: var(--wp--preset--color--fog);
}

/* Featured images are department crests and patches — square, and usually a
   logo rather than a photograph. Two consequences run through the rules below:

   - They are sized, not stretched. A square run to the full content width is a
     wall; these are badges, so they get a fixed ceiling and sit left.
   - The block asks for `scale: contain`, so a stray non-square upload is
     letterboxed instead of cropped. Cropping a patch cuts the lettering off it.

   Core's post-featured-image block outputs nothing at all for a post with no
   thumbnail, so none of this needs an empty case — the layout just closes up. */

/* On a single department, between the title and the details table. No vertical
   margin: it is a direct child of the main layout container, which already owns
   the 2.5rem gap either side of it. */
.hs-dept-media {
	max-width: 11rem;
}

/* Centering needs auto inline margins, and the core block sets
   `margin-left: 0; margin-right: 0` on itself at single-class specificity — so
   the core class is chained on here to win outright rather than tie and depend
   on which stylesheet happens to load last. Same trick on the card below. */
.hs-dept-media.wp-block-post-featured-image {
	margin-inline: auto;
}

.hs-dept-media img {
	display: block;
	width: 100%;
	border-radius: 8px;
}

/* Index cards on /departments/ and the type archives. */
.hs-dept-index .hs-dept-card {
	height: 100%;
}

.hs-dept-card__media {
	max-width: 5.5rem;
}

/* Sits centered beneath the type eyebrow. The extra top margin beats the card
   layout's own 0.5rem blockGap (0,3,0 against 0,1,0): a crest wants a little
   more separation from the label above it than the text rows want. */
.hs-dept-card .hs-dept-card__media.wp-block-post-featured-image {
	margin-inline: auto;
	margin-block-start: 0.75rem;
}

.hs-dept-card__media img {
	display: block;
	width: 100%;
	border-radius: 6px;
}

/* The crest wants more air beneath it than the text rows want between them.
   Scoped through .hs-dept-card so this reads 0,2,0 and beats the layout
   container's own blockGap rule outright — see the note at the top of 3a about
   what happens when a margin here merely ties with that one. */
.hs-dept-card .hs-dept-card__media + * {
	margin-block-start: 1rem;
}

.hs-dept-card .wp-block-post-title {
	font-size: 1.4rem;
	line-height: 1.15;
}

.hs-dept-card .wp-block-post-title a {
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.hs-dept-card:hover {
	border-color: var(--wp--preset--color--red);
}

.hs-dept-card .wp-block-post-title a:hover,
.hs-dept-card .wp-block-post-title a:focus {
	color: var(--wp--preset--color--ember);
}

.hs-dept-card .wp-block-post-excerpt {
	color: var(--wp--preset--color--ash);
	font-size: var(--wp--preset--font-size--small);
}

/* Type filter above the index — core's categories block, unbulleted. */
.hs-term-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 0.75rem;
	padding: 0;
	list-style: none;
}

.hs-term-filter li {
	margin: 0;
}

.hs-term-filter a {
	display: inline-block;
	padding: 0.3rem 0.8rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ash);
	text-decoration: none;
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 999px;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.hs-term-filter a:hover,
.hs-term-filter a:focus-visible {
	color: var(--wp--preset--color--ember);
	border-color: var(--wp--preset--color--red);
	text-decoration: none;
}

@media (max-width: 600px) {
	.hs-dept-details__row {
		grid-template-columns: 1fr;
		gap: 0.2rem;
	}

	.single-hs_department .wp-block-table td {
		padding: 0.55rem 0.9rem;
	}
}

/* ------------------------------------------------------------------ *
 * 3b. Archive browser
 * ------------------------------------------------------------------ */

/* Rendered by the huntley-scanner-archives plugin. One recording per day, so
   navigation is year then month and the page shows a single month: a year at
   once would be ~365 rows, and ~365 audio elements, which is neither scannable
   nor cheap.

   Note the deliberate absence of vertical margin on `.hs-archive` itself — it
   is a direct child of a layout container, which already owns the gap above and
   below it. See the note in section 3a. */
.hs-archive__nav ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.hs-archive__nav + .hs-archive__nav {
	margin-top: 0.75rem;
}

.hs-archive__pill {
	display: inline-block;
	padding: 0.3rem 0.8rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ash);
	text-decoration: none;
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 999px;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.hs-archive__pill:hover,
.hs-archive__pill:focus-visible {
	color: var(--wp--preset--color--ember);
	border-color: var(--wp--preset--color--red);
	text-decoration: none;
}

.hs-archive__pill.is-current {
	color: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--red);
	background: var(--wp--preset--color--charcoal);
}

/* Month names are three letters of wildly different widths; a floor keeps the
   row from looking ragged. */
.hs-archive__months .hs-archive__pill {
	min-width: 3.4rem;
	text-align: center;
}

/* The abbr carries the full "April 2019" as a tooltip and to assistive tech —
   it should not pick up the browser's dotted underline for that. */
.hs-archive__pill abbr {
	text-decoration: none;
	border: 0;
	cursor: inherit;
}

.hs-archive__month {
	margin-top: 2rem;
}

.hs-archive__month-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.4rem;
	color: var(--wp--preset--color--white);
}

.hs-archive__summary {
	margin: 0.25rem 0 1.25rem;
	padding-bottom: 0.75rem;
	color: var(--wp--preset--color--steel);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	border-bottom: 1px solid var(--wp--preset--color--graphite);
}

.hs-archive__days {
	display: grid;
	gap: 0.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.hs-archive__day {
	display: grid;
	grid-template-columns: 4.5rem minmax(0, 1fr) auto;
	align-items: center;
	gap: 0.5rem 1rem;
	padding: 0.5rem 0.75rem;
	border-radius: 8px;
	transition: background 0.2s ease;
}

.hs-archive__day:hover,
.hs-archive__day:focus-within {
	background: var(--wp--preset--color--charcoal);
}

.hs-archive__date {
	display: flex;
	align-items: baseline;
	gap: 0.5rem;
}

/* Day-of-month is the thing being scanned for, so it gets a fixed column and
   the mono face — the numbers line up down the list. */
.hs-archive__dom {
	min-width: 1.5rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.95rem;
	color: var(--wp--preset--color--white);
	text-align: right;
}

.hs-archive__dow {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ash);
}

/* Native controls, deliberately: they are keyboard accessible, they honor the
   OS media keys and they cost no JavaScript. `color-scheme` is the standard way
   to ask for the dark rendering of them, which is the only part of the widget
   worth having an opinion about here. */
.hs-archive__player {
	width: 100%;
	min-width: 0;
	height: 2.25rem;
	color-scheme: dark;
}

.hs-archive__actions {
	display: flex;
	align-items: baseline;
	gap: 0.9rem;
	justify-content: flex-end;
}

.hs-archive__meta {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	color: var(--wp--preset--color--steel);
	white-space: nowrap;
}

.hs-archive__download {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ash);
	text-decoration: none;
	white-space: nowrap;
	border-bottom: 1px solid transparent;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.hs-archive__download:hover,
.hs-archive__download:focus-visible {
	color: var(--wp--preset--color--ember);
	border-bottom-color: var(--wp--preset--color--red);
	text-decoration: none;
}

/* Narrow: the player takes its own line under the date and the actions, rather
   than being squeezed into a third of the width. */
@media (max-width: 40rem) {
	.hs-archive__day {
		grid-template-columns: auto 1fr;
		padding: 0.6rem 0.5rem;
	}

	.hs-archive__player {
		grid-column: 1 / -1;
	}
}

.hs-archive__empty {
	color: var(--wp--preset--color--ash);
}

/* Source badge — marks which service a link goes to. */
.hs-badge {
	display: inline-block;
	margin: 0;
	padding: 0.25rem 0.6rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
	border: 1px solid currentColor;
	border-radius: 999px;
}

.hs-badge.is-calls {
	color: var(--wp--preset--color--amber);
}

.hs-badge.is-openmhz {
	color: var(--wp--preset--color--green);
}

/* Outline buttons: theme.json styles the filled variant, core's outline
   style needs its own colors on a dark surface. */
.wp-block-button.is-style-outline > .wp-block-button__link {
	color: var(--wp--preset--color--fog);
	border-color: var(--wp--preset--color--steel);
	background: transparent;
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-outline > .wp-block-button__link:focus {
	color: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--red);
	background: rgba(204, 51, 51, 0.12);
}

/* ------------------------------------------------------------------ *
 * 4. Post cards (query loops on the home page, blog and archives)
 * ------------------------------------------------------------------ */

.hs-posts .wp-block-post-template {
	list-style: none;
	margin: 0;
	padding: 0;
}

.hs-posts li.wp-block-post {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1.5rem;
	background: var(--wp--preset--color--charcoal);
	border: 1px solid var(--wp--preset--color--graphite);
	border-radius: 8px;
	transition: border-color 0.2s ease;
}

.hs-posts li.wp-block-post:hover,
.hs-posts li.wp-block-post:focus-within {
	border-color: var(--wp--preset--color--steel);
}

.hs-posts .wp-block-post-title {
	margin: 0;
	font-size: 1.35rem;
	line-height: 1.25;
}

.hs-posts .wp-block-post-title a {
	color: var(--wp--preset--color--white);
}

.hs-posts .wp-block-post-title a:hover,
.hs-posts .wp-block-post-title a:focus {
	color: var(--wp--preset--color--ember);
	text-decoration: none;
}

.hs-posts .wp-block-post-excerpt {
	margin: 0;
	color: var(--wp--preset--color--ash);
	font-size: var(--wp--preset--font-size--small);
}

.hs-posts .wp-block-post-featured-image {
	margin: 0 0 0.5rem;
}

.hs-posts .wp-block-post-featured-image img {
	border-radius: 6px;
}

/* ------------------------------------------------------------------ *
 * 5. Header & navigation
 * ------------------------------------------------------------------ */

.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	border-bottom: 1px solid var(--wp--preset--color--graphite);
	/* Slightly translucent so content scrolling underneath is hinted at. */
	background-color: rgba(26, 27, 30, 0.92);
}

/*
 * The blur is deliberately scoped above core's 600px navigation breakpoint.
 * backdrop-filter makes an element a containing block for its fixed-position
 * descendants, which would trap the mobile menu overlay inside the bar
 * instead of letting it cover the viewport.
 */
@media (min-width: 600px) {
	.site-header {
		-webkit-backdrop-filter: saturate(140%) blur(8px);
		backdrop-filter: saturate(140%) blur(8px);
	}
}

/* The brand lockup: logo chip + wordmark, as one link. */
.site-header .hs-brand a {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	text-decoration: none;
	color: var(--wp--preset--color--white);
}

/*
 * The logo is a tall white silhouette of a handheld radio (roughly 1:2.4).
 * On its own at header scale it reads as a thin sliver, so it sits in a
 * squared "hardware" chip: a slightly raised dark panel with a red LED at
 * the top-right corner, on the same side as the antenna in the artwork.
 */
.site-header .hs-brand__mark {
	position: relative;
	display: grid;
	place-items: center;
	flex: none;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 10px;
	border: 1px solid var(--wp--preset--color--graphite);
	background: linear-gradient(160deg, #34363c 0%, #24252a 100%);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.site-header .hs-brand__mark img {
	display: block;
	width: auto;
	height: 1.7rem;
}

/* Standby LED. Static by default — the pulsing dot belongs to the "live"
   status on feed cards, and two competing pulses reads as noise. */
.site-header .hs-brand__mark::after {
	content: "";
	position: absolute;
	top: 0.3rem;
	right: 0.3rem;
	width: 0.3rem;
	height: 0.3rem;
	border-radius: 50%;
	background: var(--wp--preset--color--red);
	box-shadow: 0 0 6px rgba(204, 51, 51, 0.9);
}

.site-header .hs-brand a:hover .hs-brand__mark,
.site-header .hs-brand a:focus-visible .hs-brand__mark {
	border-color: var(--wp--preset--color--red);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.07),
		0 0 18px rgba(204, 51, 51, 0.3);
}

.site-header .hs-brand__text {
	display: block;
}

.site-header .hs-brand .hs-brand__name {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	line-height: 1;
}

.site-header .hs-brand .hs-brand__name em {
	font-style: normal;
	color: var(--wp--preset--color--red);
}

.site-header .hs-brand .hs-brand__tagline {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.625rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ash);
	margin-top: 0.2rem;
}

/* Phones: the lockup, the CTA and the hamburger all share one row, so drop
   the tagline and tighten the chip rather than let the bar wrap. */
@media (max-width: 599px) {
	.site-header .hs-brand a {
		gap: 0.6rem;
	}

	.site-header .hs-brand__mark {
		width: 2.4rem;
		height: 2.4rem;
	}

	.site-header .hs-brand__mark img {
		height: 1.45rem;
	}

	.site-header .hs-brand .hs-brand__name {
		font-size: 1.2rem;
	}

	.site-header .hs-brand .hs-brand__tagline {
		display: none;
	}

	/* Override the block's 1.75rem gap between the CTA and the hamburger. */
	.site-header .hs-header-actions {
		gap: 0.6rem;
	}
}

/* Navigation links: quiet until hovered, then a red underline. */
.site-header .wp-block-navigation a {
	position: relative;
	padding-bottom: 2px;
	text-decoration: none;
}

.site-header .wp-block-navigation a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -2px;
	height: 2px;
	background: var(--wp--preset--color--red);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.2s ease;
}

.site-header .wp-block-navigation a:hover::after,
.site-header .wp-block-navigation a:focus::after,
.site-header .wp-block-navigation .current-menu-item a::after {
	transform: scaleX(1);
}

/* The "Listen live" button in the header bar is a size smaller than the
   in-page buttons. */
.site-header .hs-header-cta .wp-block-button__link {
	padding: 0.55rem 1.1rem;
	font-size: var(--wp--preset--font-size--x-small);
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

/*
 * Mobile bar. The menu collapses to a hamburger below 600px, but the CTA
 * stays put — it is the main thing people come here to do. To make it fit
 * alongside the brand and the hamburger it drops to "Listen", tightens its
 * padding, and moves ahead of the hamburger so the toggle stays at the far
 * right edge where a thumb expects it.
 */
@media (max-width: 599px) {
	.site-header .hs-header-cta {
		order: -1;
	}

	.site-header .hs-header-cta .wp-block-button__link {
		padding: 0.5rem 0.8rem;
		letter-spacing: 0.06em;
	}

	.site-header .hs-cta-word {
		display: none;
	}
}

/* Underlines inside the mobile overlay would be misaligned; drop them. */
.site-header .wp-block-navigation__responsive-container.is-menu-open a::after {
	display: none;
}

.site-header .wp-block-navigation__responsive-container.is-menu-open {
	padding: 2rem 1.5rem;
}

/* ------------------------------------------------------------------ *
 * 6. Footer
 * ------------------------------------------------------------------ */

.site-footer {
	border-top: 1px solid var(--wp--preset--color--graphite);
}

.site-footer .wp-block-navigation {
	gap: 0.4rem;
}

/* The site menu runs in two balanced columns so the footer stays short.
   Multi-column (rather than a grid) fills top-to-bottom and re-balances on
   its own as links are added or removed. */
.site-footer .footer-navigation .wp-block-navigation__container {
	display: block;
	columns: 2;
	column-gap: 2.5rem;
}

.site-footer .footer-navigation .wp-block-navigation-item {
	display: block;
	break-inside: avoid;
	margin-bottom: 0.4rem;
}

.site-footer .wp-block-navigation a,
.site-footer .wp-block-social-link a {
	color: var(--wp--preset--color--ash);
}

.site-footer .wp-block-navigation a:hover,
.site-footer .wp-block-navigation a:focus {
	color: var(--wp--preset--color--fog);
}

.site-footer .hs-footer-heading {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--white);
	margin-bottom: 0.25rem;
}

/* Footer lockup: the same radio mark as the header, but bare — no chip, so
   it reads as a sign-off rather than a second logo competing with the one
   in the bar. The image is decorative; the text beside it carries the name. */
.site-footer .hs-footer-brand {
	display: flex;
	align-items: center;
	gap: 0.6rem;
}

.site-footer .hs-footer-brand img {
	display: block;
	width: auto;
	height: 1.6rem;
	opacity: 0.9;
}

.site-footer .hs-footer-brand .hs-footer-heading {
	margin-bottom: 0;
}

/* The legal / emergency strip along the very bottom. */
.site-footer .hs-footer-legal {
	border-top: 1px solid var(--wp--preset--color--graphite);
	padding-top: 1rem;
	color: var(--wp--preset--color--ash);
	font-size: var(--wp--preset--font-size--x-small);
}

.site-footer .hs-footer-legal p {
	margin: 0;
	line-height: 1.5;
}

/* Copyright left, policy links right — they collapse onto separate lines
   only when the row runs out of room. */
.site-footer .hs-footer-bottom {
	width: 100%;
}

.site-footer .hs-footer-policies {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
}

.site-footer .hs-footer-policies a {
	color: var(--wp--preset--color--ash);
	text-decoration: none;
}

.site-footer .hs-footer-policies a:hover,
.site-footer .hs-footer-policies a:focus {
	color: var(--wp--preset--color--fog);
	text-decoration: underline;
}

.site-footer .hs-footer-policies span {
	color: var(--wp--preset--color--steel);
}

/* Emergency notice: never let this get lost in the small print. */
.hs-notice {
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--wp--preset--color--red);
	border-left-width: 3px;
	border-radius: 6px;
	background: rgba(204, 51, 51, 0.1);
	color: var(--wp--preset--color--fog);
	font-size: var(--wp--preset--font-size--small);
}

.hs-notice strong {
	color: var(--wp--preset--color--white);
}

@media (max-width: 781px) {
	.site-footer .hs-footer-row {
		flex-direction: column;
		gap: 1.5rem;
	}
}

/* ------------------------------------------------------------------ *
 * 7. Form controls on a dark background
 *    Core's search / comment inputs default to a light chrome; give them
 *    the same surface treatment as the cards.
 * ------------------------------------------------------------------ */

.wp-block-search__input,
input[type="text"],
input[type="email"],
input[type="url"],
input[type="search"],
textarea,
select {
	background: var(--wp--preset--color--charcoal);
	color: var(--wp--preset--color--fog);
	border: 1px solid var(--wp--preset--color--steel);
	border-radius: 4px;
	padding: 0.7rem 0.85rem;
	font-family: inherit;
	font-size: 1rem;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.wp-block-search__input::placeholder,
input::placeholder,
textarea::placeholder {
	color: var(--wp--preset--color--ash);
}

.wp-block-search__input:focus,
input:focus,
textarea:focus,
select:focus {
	outline: none;
	border-color: var(--wp--preset--color--red);
	box-shadow: 0 0 0 0.15rem rgba(204, 51, 51, 0.25);
}

.wp-block-search__button {
	background: var(--wp--preset--color--red);
	color: var(--wp--preset--color--white);
	border: none;
	border-radius: 4px;
	padding: 0.7rem 1.25rem;
	font-weight: 600;
	cursor: pointer;
	transition: background 0.2s ease;
}

.wp-block-search__button:hover,
.wp-block-search__button:focus {
	background: var(--wp--preset--color--ember);
}

/* Visible focus ring everywhere — important on a dark palette where the
   browser default is easy to miss. */
:where(a, button, input, textarea, select, summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--ember);
	outline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 * 8. Contact Form 7 (only applies when the plugin is active)
 *    Section 7 above already covers CF7's text inputs and textarea,
 *    which are plain input[type=…] elements. The submit button is the
 *    one control it misses, because core's button styling comes from
 *    theme.json and lands on .wp-element-button — a class CF7 does not
 *    put on its own submit.
 * ------------------------------------------------------------------ */

/* Form layout, the same shape the Catherine Daley Design theme uses: the form
   is a grid whose rows are centered, and each row is a fixed-width column. That
   centers the fields and the button together, rather than centering the button
   against left-aligned inputs. */
.wpcf7-form {
	display: grid;
	gap: 1.25rem;
	justify-items: center;
}

.wpcf7-form p {
	width: 100%;
	max-width: 36rem;
	margin: 0;
}

/* CF7 nests the control inside a label, with a <br> between the caption and the
   field. Making both wrappers block-level lets the field fill the column and
   keeps the caption on its own line. */
.wpcf7-form label,
.wpcf7-form .wpcf7-form-control-wrap {
	display: block;
}

.wpcf7-form label {
	color: var(--wp--preset--color--fog);
	font-size: var(--wp--preset--font-size--small);
}

/* border-box matters here: section 7 gives these controls padding, and without
   it a 100%-width field overflows the column by exactly that padding. */
.wpcf7-form input[type="text"],
.wpcf7-form input[type="email"],
.wpcf7-form input[type="tel"],
.wpcf7-form input[type="url"],
.wpcf7-form input[type="date"],
.wpcf7-form input[type="number"],
.wpcf7-form textarea,
.wpcf7-form select {
	box-sizing: border-box;
	width: 100%;
	margin-top: 0.4rem;
}

/* Matches styles.elements.button in theme.json. Kept in sync by hand: there is
   no selector this stylesheet can borrow, since theme.json emits its button
   rules onto .wp-element-button and .wp-block-button__link only. If the button
   design changes there, change it here too. */
.wpcf7-form .wpcf7-submit {
	appearance: none;
	background: var(--wp--preset--color--red);
	color: var(--wp--preset--color--white);
	border: none;
	border-radius: 4px;
	padding: 0.85rem 1.5rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.02em;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.2s ease;
}

.wpcf7-form .wpcf7-submit:hover,
.wpcf7-form .wpcf7-submit:focus {
	background: var(--wp--preset--color--ember);
}

/* Section 7 gives every focused input a red border and glow, which is right for
   a text field and wrong for a solid button. This is 0,2,0 against that rule's
   0,1,1, so it wins on specificity rather than on load order. */
.wpcf7-form .wpcf7-submit:focus {
	border: none;
	box-shadow: none;
}

/* CF7 emits the submit alone in a trailing paragraph and injects its spinner
   as a sibling. Centering the paragraph therefore centers the pair, and keeps
   working if a form template adds a second control beside the button —
   which setting `margin-inline: auto` on the button itself would not. */
.wpcf7-form p:has(.wpcf7-submit) {
	text-align: center;
}

/* The spinner is inline-block and merely `visibility: hidden` until a submit is
   in flight, so it always occupies space. Left at CF7's default 24px it drags
   the centered button visibly off-center. */
.wpcf7-form .wpcf7-spinner {
	margin: 0 0 0 0.75rem;
}

/* Response and validation messages, on a dark surface rather than the plugin's
   default light one. */
.wpcf7-form .wpcf7-response-output {
	width: 100%;
	max-width: 36rem;
	margin: 0;
	padding: 0.8rem 1rem;
	border: 1px solid var(--wp--preset--color--steel);
	border-radius: 4px;
	color: var(--wp--preset--color--fog);
	font-size: var(--wp--preset--font-size--small);
	text-align: center;
}

.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7-form.unaccepted .wpcf7-response-output,
.wpcf7-form.payment-required .wpcf7-response-output {
	border-color: var(--wp--preset--color--red);
}

.wpcf7-form.sent .wpcf7-response-output {
	border-color: var(--wp--preset--color--green);
}

/* Per-field validation text. CF7's default is a light-background red that is
   hard to read here. */
.wpcf7-form .wpcf7-not-valid-tip {
	color: var(--wp--preset--color--ember);
	font-size: var(--wp--preset--font-size--x-small);
}
