/*
Theme Name: Edmundo Mendez Industrial
Theme URI: https://edmundomendez.com
Author: Dez Visuals Media, LLC
Author URI: https://dezvisuals.com
Description: Industrial-brand child theme of Twenty Twenty-Five for edmundomendez.com — the portfolio of Edmundo Mendez, Jr., Digital Media Producer. Flat high-contrast color blocking, stencil display type, sheared edges, and a signature film-strip perforation divider. Covers video, photography, and web design work.
Template: twentytwentyfive
Version: 1.18.0
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 7.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: edmundo-mendez-industrial
Tags: block-patterns, full-site-editing, portfolio, one-column, custom-colors, custom-logo, editor-style, wide-blocks
*/

/* ==========================================================================
   1. DESIGN TOKENS
   Single source of truth. Hex values are taken verbatim from the brand guide.
   ========================================================================== */

:root {
	/* ---- Brand palette (exact) ---- */
	--em-steel-black: #000000;
	--em-industrial-orange: #F79733;
	--em-deep-navy: #223F4D;
	--em-charcoal: #303131;
	--em-oxblood-maroon: #632525;
	--em-steel-gray: #C9CACA;
	--em-white: #FFFFFF;

	/* ---- Semantic roles ---- */
	--em-bg: var(--em-steel-black);
	--em-bg-alt: var(--em-deep-navy);
	--em-surface: var(--em-charcoal);
	--em-plate: var(--em-steel-gray);      /* light "steel plate" ground        */
	--em-accent: var(--em-industrial-orange);
	--em-accent-tertiary: var(--em-oxblood-maroon); /* sparing use only         */
	--em-text: var(--em-white);
	--em-text-muted: var(--em-steel-gray);
	--em-text-on-plate: var(--em-steel-black);
	--em-hairline: color-mix(in srgb, var(--em-steel-gray) 32%, transparent);

	/* ---- Type stacks ---- */
	--em-font-display: "Big Shoulders Stencil", "Big Shoulders Stencil Display", "Rajdhani", "Oswald", Impact, sans-serif;
	--em-font-heading: "Oswald", "Arial Narrow", Arial, sans-serif;
	--em-font-body: "Work Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
	--em-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

	/* ---- Tracking ---- */
	--em-track-heading: 0.06em;
	--em-track-label: 0.1em;
	--em-track-meta: 0.14em;
	--em-track-display: 0.02em;

	/* ---- Geometry ---- */
	--em-radius: 0;                        /* never anything else               */
	--em-shear: clamp(1.5rem, 4vw, 3.5rem);/* sheared-edge depth                */
	--em-shear-corner: 1.25rem;            /* notched card corner               */
	--em-rule: 2px;                        /* structural rule weight            */

	/* ---- Film-strip divider ---- */
	--em-strip-height: clamp(44px, 6vw, 68px);
	--em-strip-perf-size: 14px;            /* perforation diameter              */
	--em-strip-perf-pitch: 34px;           /* centre-to-centre spacing          */
	--em-strip-perf-inset: 11px;           /* row inset from bar edge           */
	--em-strip-bar: var(--em-industrial-orange);
	--em-strip-perf: var(--em-steel-black);

	/* ---- Riveted corner marks ---- */
	--em-rivet-size: 6px;
	--em-rivet-inset: 10px;
	--em-rivet-color: var(--em-steel-gray);

	/* ---- Photo mat ----
	 * Media sits inset on its plate rather than bleeding to the frame edge, so
	 * the palette stays visible once real photographs fill the grids. Without
	 * this the colour system disappears the moment placeholders are replaced.
	 */
	--em-mat: clamp(10px, 1.1vw, 16px);
	--em-mat-bg: var(--em-charcoal);

	/* ---- Browser-plate chrome (web design cards) ---- */
	--em-chrome-mark: color-mix(in srgb, var(--em-steel-gray) 55%, transparent);
	--em-chrome-plate: color-mix(in srgb, var(--em-steel-gray) 22%, transparent);

	/* ---- Logo geometry ----
	 * The supplied lockup carries its own padding inside the PNG: the steel-gray
	 * ink starts 70px into a 1005px-wide image, and sits 51px down from the top.
	 * These ratios let the tagline align to the visible "E" instead of to the
	 * edge of the image box, at whatever width the logo is rendered.
	 * Measured from assets/logo/em-logo-horizontal.png — re-measure if it changes.
	 */
	--em-logo-w: 240px;
	--em-logo-ink-inset: 0.0697;   /*  70 / 1005  */
	--em-logo-ink-drop: 0.1405;    /*  51 / 363   */
}

/* ==========================================================================
   2. FLAT-ONLY RESET
   Depth comes from layered flat panels and colour contrast — never effects.
   ========================================================================== */

.wp-site-blocks *,
.wp-site-blocks *::before,
.wp-site-blocks *::after,
.block-editor-block-list__layout *,
.block-editor-block-list__layout *::before,
.block-editor-block-list__layout *::after {
	border-radius: 0 !important;
}

.wp-site-blocks *,
.block-editor-block-list__layout * {
	box-shadow: none;
	text-shadow: none;
	backdrop-filter: none;
}

/*
 * Gradients are killed by class, not by a blanket `background-image: none`.
 * A blanket rule would also strip the film-strip perforations and the tile
 * rivet marks, both of which are painted with hard-stop background layers.
 * Inline gradients set deliberately on a block still win, as they should.
 */
.wp-site-blocks [class*="-gradient-background"],
.wp-site-blocks .has-background-gradient,
.block-editor-block-list__layout [class*="-gradient-background"],
.block-editor-block-list__layout .has-background-gradient {
	background-image: none;
}

/* ==========================================================================
   3. BASE TYPOGRAPHY
   ========================================================================== */

body {
	font-family: var(--em-font-body);
	font-weight: 400;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6,
.wp-block-post-title,
.wp-block-site-title {
	font-family: var(--em-font-heading);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--em-track-heading);
	line-height: 1.05;
	text-wrap: balance;
}

/* Display face is reserved for statement headlines only — never body copy. */
h1,
.em-display,
.wp-block-cover h1 {
	font-family: var(--em-font-display);
	letter-spacing: var(--em-track-display);
	line-height: 0.92;
}

/* Meta, captions, dates, credits — the "stencilled plate" small print. */
.em-meta,
.wp-element-caption,
.wp-block-post-date,
.wp-block-post-terms,
.wp-block-post-author-name,
.wp-block-comment-date,
figcaption {
	font-family: var(--em-font-mono);
	font-size: 0.8125rem;
	font-weight: 400;
	letter-spacing: var(--em-track-meta);
	text-transform: uppercase;
	color: var(--em-text-muted);
	line-height: 1.5;
}

/* Eyebrow label above a headline. */
.em-eyebrow {
	display: inline-block;
	font-family: var(--em-font-mono);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--em-accent);
	margin-bottom: 1rem;
}

.em-eyebrow::before {
	content: "";
	display: inline-block;
	width: 2.25rem;
	height: var(--em-rule);
	background-color: currentColor;
	vertical-align: middle;
	margin-right: 0.75em;
}

/* ==========================================================================
   4. FILM-STRIP DIVIDER  (signature element)
   A solid bar with two rows of circular perforations. The perforation colour
   always matches the page background sitting behind the bar, so the holes
   read as genuine cutouts.
   ========================================================================== */

.em-filmstrip {
	display: block;
	width: 100%;
	height: var(--em-strip-height);
	background-color: var(--em-strip-bar);
	background-image:
		radial-gradient(circle, var(--em-strip-perf) 0 calc(var(--em-strip-perf-size) / 2), transparent calc(var(--em-strip-perf-size) / 2)),
		radial-gradient(circle, var(--em-strip-perf) 0 calc(var(--em-strip-perf-size) / 2), transparent calc(var(--em-strip-perf-size) / 2));
	background-size: var(--em-strip-perf-pitch) calc(var(--em-strip-perf-inset) * 2);
	background-position:
		left 0 top var(--em-strip-perf-inset),
		left 0 bottom var(--em-strip-perf-inset);
	background-repeat: repeat-x, repeat-x;
	border: 0;
	margin: 0;
}

/* -- Variant 1: bar sits on the black page ground -- */
.em-filmstrip--on-black {
	--em-strip-bar: var(--em-industrial-orange);
	--em-strip-perf: var(--em-steel-black);
}

/* -- Variant 2: bar sits on an orange section (navy bar per approved pairing) -- */
.em-filmstrip--on-orange {
	--em-strip-bar: var(--em-deep-navy);
	--em-strip-perf: var(--em-industrial-orange);
}

/* -- Variant 3: bar sits on the light steel-plate ground -- */
.em-filmstrip--on-plate {
	--em-strip-bar: var(--em-charcoal);
	--em-strip-perf: var(--em-steel-gray);
}

/* -- Variant 4: bar sits on a navy section -- */
.em-filmstrip--on-navy {
	--em-strip-bar: var(--em-industrial-orange);
	--em-strip-perf: var(--em-deep-navy);
}

/* -- Variant 5: bar sits on a charcoal section -- */
.em-filmstrip--on-charcoal {
	--em-strip-bar: var(--em-industrial-orange);
	--em-strip-perf: var(--em-charcoal);
}

/* Slimmer run for tighter spots. */
.em-filmstrip--slim {
	--em-strip-height: 30px;
	--em-strip-perf-size: 9px;
	--em-strip-perf-pitch: 22px;
	--em-strip-perf-inset: 7px;
}

/* ==========================================================================
   5. SHEARED / ANGLED CUTS
   Replaces every rounded corner. Applied to sections, covers, and media.
   ========================================================================== */

.em-shear-bottom {
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--em-shear)), 0 100%);
}

.em-shear-bottom-rev {
	clip-path: polygon(0 0, 100% 0, 100% 100%, 0 calc(100% - var(--em-shear)));
}

.em-shear-top {
	clip-path: polygon(0 var(--em-shear), 100% 0, 100% 100%, 0 100%);
}

.em-shear-both {
	clip-path: polygon(0 var(--em-shear), 100% 0, 100% calc(100% - var(--em-shear)), 0 100%);
}

/* Notched corner — a chamfer, never a radius. */
.em-notch-tr {
	clip-path: polygon(0 0, calc(100% - var(--em-shear-corner)) 0, 100% var(--em-shear-corner), 100% 100%, 0 100%);
}

.em-notch-bl {
	clip-path: polygon(0 0, 100% 0, 100% 100%, var(--em-shear-corner) 100%, 0 calc(100% - var(--em-shear-corner)));
}

/* A sheared cover needs bottom padding so its content clears the cut. */
.em-shear-bottom.wp-block-cover,
.em-shear-both.wp-block-cover {
	padding-bottom: calc(var(--em-shear) + var(--wp--preset--spacing--60, 3rem));
}

/* ==========================================================================
   6. SECTION PANELS
   Flat colour blocking. Depth = adjacent panels, not shadow.
   ========================================================================== */

.em-panel {
	background-color: var(--em-bg);
	color: var(--em-text);
}

.em-panel--navy {
	background-color: var(--em-deep-navy);
	color: var(--em-white);
}

.em-panel--charcoal {
	background-color: var(--em-charcoal);
	color: var(--em-steel-gray);
}

.em-panel--orange {
	background-color: var(--em-industrial-orange);
	color: var(--em-deep-navy);
}

.em-panel--orange :is(h1, h2, h3, h4, h5, h6),
.em-panel--orange .em-eyebrow {
	color: var(--em-deep-navy);
}

/* Tertiary accent — one section at most. */
.em-panel--maroon {
	background-color: var(--em-oxblood-maroon);
	color: var(--em-industrial-orange);
}

.em-panel--maroon :is(h1, h2, h3, h4, h5, h6) {
	color: var(--em-industrial-orange);
}

.em-panel--plate {
	background-color: var(--em-steel-gray);
	color: var(--em-text-on-plate);
}

.em-panel--plate :is(h1, h2, h3, h4, h5, h6) {
	color: var(--em-steel-black);
}

.em-panel--plate .em-meta,
.em-panel--plate figcaption {
	color: var(--em-charcoal);
}

/* ==========================================================================
   7. PORTFOLIO TILES  — riveted steel plates
   ========================================================================== */

.em-tile {
	position: relative;
	display: block;
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-hairline);
	overflow: hidden;
	transition: background-color 120ms linear, border-color 120ms linear;
}

/* Riveted corner marks: four flat squares, one per corner. */
.em-tile::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	pointer-events: none;
	z-index: 2;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.85;
}

.em-tile:hover,
.em-tile:focus-within {
	background-color: var(--em-oxblood-maroon);
	border-color: var(--em-industrial-orange);
}

.em-tile:hover::after,
.em-tile:focus-within::after {
	--em-rivet-color: var(--em-industrial-orange);
	opacity: 1;
}

.em-tile figure,
.em-tile .wp-block-image {
	margin: 0;
}

.em-tile img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--em-shear-corner)), calc(100% - var(--em-shear-corner)) 100%, 0 100%);
}

.em-tile__body {
	padding: 1.25rem 1.5rem 1.5rem;
}

.em-tile__body h3,
.em-tile__body h4 {
	margin: 0 0 0.35rem;
	color: var(--em-white);
	letter-spacing: var(--em-track-label);
}

.em-tile:hover .em-tile__body h3,
.em-tile:hover .em-tile__body h4 {
	color: var(--em-industrial-orange);
}

.em-tile__body .em-meta {
	margin: 0;
}

/* Whole-tile click target. */
.em-tile a::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
}

.em-tile a {
	text-decoration: none;
	color: inherit;
}

/* ==========================================================================
   8. BUTTONS
   ========================================================================== */

.wp-block-button__link,
.wp-element-button {
	font-family: var(--em-font-heading);
	font-weight: 600;
	font-size: 0.8125rem;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
	border-radius: 0;
	border: var(--em-rule) solid var(--em-industrial-orange);
	padding: 0.9rem 2rem;
	transition: background-color 120ms linear, color 120ms linear;
	clip-path: polygon(0 0, calc(100% - 0.75rem) 0, 100% 0.75rem, 100% 100%, 0.75rem 100%, 0 calc(100% - 0.75rem));
}

/*
 * Solid (primary). Rest is the dark state and hover lights up to orange —
 * the reverse of the original. Both button styles now resolve to the same
 * orange-fill/navy-text on hover, so the whole system has one hover
 * behaviour rather than two.
 */
.wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background) {
	background-color: var(--em-deep-navy);
	color: var(--em-industrial-orange);
}

.wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background):hover,
.wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background):focus-visible {
	background-color: var(--em-industrial-orange);
	color: var(--em-deep-navy);
}

/*
 * On the maroon call-to-action panel a navy fill sits at 1.04:1 against the
 * panel — the shape would vanish and leave only the border. Those buttons
 * take a black fill instead, which reads at 1.8:1 and keeps the same
 * dark-at-rest, orange-on-hover behaviour.
 */
.em-panel--maroon .wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background) {
	background-color: var(--em-steel-black);
	color: var(--em-industrial-orange);
}

.em-panel--maroon .wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background):hover,
.em-panel--maroon .wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-background):focus-visible {
	background-color: var(--em-industrial-orange);
	color: var(--em-deep-navy);
}

/* Outline (secondary) */
.wp-block-button.is-style-outline > .wp-block-button__link {
	background-color: transparent;
	color: var(--em-industrial-orange);
	border-color: var(--em-industrial-orange);
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-outline > .wp-block-button__link:focus-visible {
	background-color: var(--em-industrial-orange);
	color: var(--em-deep-navy);
}

/* On an orange panel the pairing inverts to navy-on-orange. */
.em-panel--orange .wp-block-button__link {
	background-color: var(--em-deep-navy);
	color: var(--em-industrial-orange);
	border-color: var(--em-deep-navy);
}

.em-panel--orange .wp-block-button__link:hover {
	background-color: var(--em-steel-black);
	border-color: var(--em-steel-black);
	color: var(--em-industrial-orange);
}

/* ==========================================================================
   9. HEADER / NAVIGATION / FOOTER
   ========================================================================== */

/*
 * The header ground is Charcoal, not Steel Black, and that is deliberate.
 * Both supplied EM lockups have an opaque #303131 plate baked into the PNG.
 * On a black header that plate would read as a floating grey rectangle, and
 * knocking it out to transparent is not an option either — steel gray on
 * black is not one of the five approved pairings. Charcoal ground + steel
 * gray mark IS pairing 2, so matching the header to the plate is the only
 * resolution that keeps the logo on-brand and seamless at the same time.
 */
.em-header,
.wp-block-template-part header .wp-block-group,
header.wp-block-template-part {
	background-color: var(--em-charcoal);
}

/* Black page body against the charcoal header — flat panels, no shadow. */
.em-header {
	border-bottom: var(--em-rule) solid var(--em-industrial-orange);
}

/* ---- Site logo ---- */
.wp-block-site-logo {
	margin: 0;
	line-height: 0;
}

.wp-block-site-logo a,
.wp-block-site-logo .custom-logo-link {
	display: block;
	text-decoration: none;
}

.wp-block-site-logo img,
.custom-logo {
	display: block;
	width: var(--em-logo-w);
	max-width: 100%;
	height: auto;
	/* The lockup is already a rectangular plate — never chamfer it. */
	clip-path: none;
}

.wp-block-navigation {
	font-family: var(--em-font-heading);
	font-weight: 600;
	font-size: 0.8125rem;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
}

.wp-block-navigation a {
	text-decoration: none;
	padding-bottom: 0.25rem;
	border-bottom: var(--em-rule) solid transparent;
	color: var(--em-white);
}

.wp-block-navigation a:hover,
.wp-block-navigation .current-menu-item a,
.wp-block-navigation .current_page_item a {
	color: var(--em-industrial-orange);
	border-bottom-color: var(--em-industrial-orange);
}

.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--em-steel-black);
	padding-top: 4rem;
}

.wp-block-site-title a {
	font-family: var(--em-font-heading);
	font-weight: 700;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
	text-decoration: none;
}

.wp-block-site-logo img {
	clip-path: none;
}

footer.wp-block-template-part,
.wp-block-template-part footer {
	background-color: var(--em-charcoal);
	color: var(--em-steel-gray);
	border-top: var(--em-rule) solid var(--em-industrial-orange);
}

/* ==========================================================================
   10. STRICT GRID
   ========================================================================== */

.em-grid {
	display: grid;
	gap: var(--wp--preset--spacing--40, 30px);
	align-items: stretch;
}

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

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

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

@media (max-width: 600px) {
	.em-grid--4,
	.em-grid--3 {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Columns blocks used as tile grids must stretch, not float. */
.em-grid-columns.wp-block-columns {
	align-items: stretch;
	gap: var(--wp--preset--spacing--40, 30px);
}

.em-grid-columns.wp-block-columns > .wp-block-column {
	display: flex;
	flex-direction: column;
}

.em-grid-columns.wp-block-columns > .wp-block-column > .em-tile {
	flex: 1 1 auto;
}

/* ==========================================================================
   11. HERO
   ========================================================================== */

.em-hero.wp-block-cover {
	min-height: clamp(70vh, 75vh, 900px);
	align-items: flex-end;
	padding-top: var(--wp--preset--spacing--80, 100px);
	border-bottom: 0;
}

.em-hero .wp-block-cover__inner-container {
	max-width: var(--wp--style--global--wide-size, 1400px);
	margin-inline: auto;
	width: 100%;
}

.em-hero h1 {
	margin: 0 0 1rem;
	max-width: 18ch;
}

.em-hero__lede {
	max-width: 46ch;
	color: var(--em-steel-gray);
	font-size: clamp(1rem, 1.5vw, 1.25rem);
}

/* A hard orange rule anchoring the hero to the grid. */
.em-hero__rule {
	width: 6rem;
	height: var(--em-rule);
	background-color: var(--em-industrial-orange);
	margin: 0 0 1.5rem;
}

/* ==========================================================================
   12. IMAGES & MEDIA
   ========================================================================== */

.wp-block-image img,
.wp-block-post-featured-image img {
	border-radius: 0;
}

.em-crop-shear img {
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--em-shear)), 0 100%);
}

.em-crop-notch img {
	clip-path: polygon(0 0, calc(100% - var(--em-shear-corner)) 0, 100% var(--em-shear-corner), 100% 100%, 0 100%);
}

/* ==========================================================================
   13. ACCESSIBILITY
   ========================================================================== */

:focus-visible {
	outline: 3px solid var(--em-industrial-orange);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}

/* Windows High Contrast — keep the perforations legible. */
@media (forced-colors: active) {
	.em-filmstrip {
		forced-color-adjust: none;
	}
}

/* ==========================================================================
   14. RESPONSIVE TILE GRID
   Core's Columns block jumps straight from N-up to stacked at 782px, which
   leaves a four-tile grid painfully narrow on tablets. Step it through 2-up.
   ========================================================================== */

@media (min-width: 782px) and (max-width: 1024px) {
	.em-grid-columns.wp-block-columns {
		flex-wrap: wrap;
	}

	.em-grid-columns.wp-block-columns > .wp-block-column {
		flex-basis: calc(50% - (var(--wp--preset--spacing--40, 30px) / 2)) !important;
		flex-grow: 0;
	}
}

/* ==========================================================================
   15. HEADER NAV OVERFLOW GUARDS
   A seven-item uppercase nav at wide tracking, sitting beside a 240px logo,
   outgrows the wide container well before the mobile breakpoint. Core's
   Navigation block does not collapse to a hamburger until 600px, so between
   those two points it simply overflowed the viewport. These rules let the row
   wrap and tighten the type as space runs out, so it degrades instead.
   ========================================================================== */

.em-header .wp-block-group.is-layout-flex {
	row-gap: var(--wp--preset--spacing--30, 20px);
}

/* Never let a flex child force the row wider than its container. */
.em-header .wp-block-navigation,
.em-header .wp-block-group {
	min-width: 0;
}

.em-header .wp-block-navigation {
	max-width: 100%;
}

/* Wrap nav items rather than pushing them off the edge. */
.em-header .wp-block-navigation__container {
	flex-wrap: wrap;
	row-gap: 0.5rem;
}

/* Tighten tracking before wrapping becomes necessary. */
@media (max-width: 1280px) {
	.em-header .wp-block-navigation {
		font-size: 0.75rem;
		letter-spacing: 0.06em;
	}
}

@media (max-width: 1100px) {
	.em-header .em-brand {
		--em-logo-w: 190px;
	}
}

/*
 * Between 600 and 860px the full six-item nav is still showing and genuinely
 * needs its own row — but right-aligned, not left, so it stays on the same
 * edge it occupies on desktop.
 */
@media (min-width: 601px) and (max-width: 860px) {
	.em-header .wp-block-group.is-content-justification-space-between > .wp-block-group {
		flex-basis: 100%;
		justify-content: flex-end;
	}

	.em-header .wp-block-navigation__container {
		justify-content: flex-end;
	}
}

/*
 * Below 600px core collapses the nav to a hamburger. A ~40px button has no
 * business taking a row of its own under the logo — it belongs opposite the
 * lockup, which is where people reach for it. Holding the row to nowrap is
 * safe here precisely because the button is that small.
 */
@media (max-width: 600px) {
	.em-header .wp-block-group.is-content-justification-space-between {
		flex-wrap: nowrap;
		align-items: center;
		gap: var(--wp--preset--spacing--30, 20px);
	}

	.em-header .wp-block-group.is-content-justification-space-between > .em-brand {
		flex: 0 1 auto;
		min-width: 0;
	}

	.em-header .wp-block-group.is-content-justification-space-between > .wp-block-group:not(.em-brand) {
		flex: 0 0 auto;
		justify-content: flex-end;
		margin-left: auto;
	}

	.em-header .wp-block-navigation__container,
	.em-header .wp-block-navigation {
		justify-content: flex-end;
	}
}

/* ==========================================================================
   16. BRAND STACK — LOGO + TAGLINE
   The tagline is a stencilled plate line sitting tight under the lockup, in
   the same steel gray as the mark so the pair reads as one unit on charcoal.
   ========================================================================== */

.em-brand {
	display: flex;
	flex-direction: column;
	/* The lockup already carries ~14% of its height as padding below the mark,
	   which is the whole optical gap the tagline needs. Adding more on top of
	   that is what made the pair read as two loose objects. */
	gap: 0;
	align-items: flex-start;
}

.em-brand .wp-block-site-tagline,
.em-footer .wp-block-site-tagline {
	margin: 0;
	font-family: var(--em-font-mono);
	font-size: 0.6875rem;
	font-weight: 400;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--em-steel-gray);
	line-height: 1.2;
}

/* Indent the tagline by exactly the logo's own internal padding, so its first
   letter sits flush under the "E" of the lockup at any rendered width. */
.em-brand .wp-block-site-tagline {
	padding-left: calc(var(--em-logo-w) * var(--em-logo-ink-inset));
}

@media (max-width: 600px) {
	.em-brand .wp-block-site-tagline,
	.em-footer .wp-block-site-tagline {
		font-size: 0.625rem;
		letter-spacing: 0.18em;
	}
}

/* ==========================================================================
   17. FOOTER
   ========================================================================== */

.em-footer {
	background-color: var(--em-charcoal);
	color: var(--em-steel-gray);
}

.em-footer__nav {
	font-family: var(--em-font-heading);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
}

.em-footer__nav .wp-block-navigation-item__content {
	color: var(--em-steel-gray);
	border-bottom: var(--em-rule) solid transparent;
	padding-bottom: 0.15rem;
}

.em-footer__nav .wp-block-navigation-item__content:hover {
	color: var(--em-industrial-orange);
	border-bottom-color: var(--em-industrial-orange);
}

/* A hairline plate edge above the copyright row. */
.em-footer__base {
	border-top: 1px solid var(--em-hairline);
	padding-top: var(--wp--preset--spacing--40, 30px);
}

.em-footer__base p {
	margin: 0;
}

.em-footer__base a {
	color: var(--em-steel-gray);
	text-decoration: none;
	border-bottom: 1px solid var(--em-hairline);
}

.em-footer__base a:hover {
	color: var(--em-industrial-orange);
	border-bottom-color: var(--em-industrial-orange);
}

/* Footer lockup runs slightly smaller than the header's. */
.em-footer .em-brand {
	--em-logo-w: 220px;
}

@media (max-width: 600px) {
	.em-brand {
		--em-logo-w: 170px;
	}
}

/* Vertical footer menu was reading as a loose column — tighten the run. */
.em-footer__nav .wp-block-navigation__container {
	row-gap: 0.6rem;
}

/* ==========================================================================
   18. SOCIAL ICONS
   Logos-only style: bare glyphs, no chips. The global radius reset already
   squares off core's rounded shapes, which is what the brand wants anyway.
   ========================================================================== */

.em-social {
	/* Match the tagline's alignment to the lockup's ink, less the 0.25em
	   padding core puts inside each icon's anchor. */
	margin-left: calc((var(--em-logo-w) * var(--em-logo-ink-inset)) - 0.25em);
	margin-top: var(--wp--preset--spacing--30, 20px);
	gap: 0.35rem;
}

.em-social .wp-block-social-link {
	background: none;
	transition: transform 120ms linear;
}

.em-social .wp-block-social-link-anchor,
.em-social .wp-block-social-link a {
	color: var(--em-steel-gray);
	fill: currentColor;
}

.em-social .wp-block-social-link:hover,
.em-social .wp-block-social-link:focus-within {
	transform: none;
}

.em-social .wp-block-social-link:hover .wp-block-social-link-anchor,
.em-social .wp-block-social-link:focus-within .wp-block-social-link-anchor {
	color: var(--em-industrial-orange);
}

.em-social svg {
	width: 1.35em;
	height: 1.35em;
}

/* ==========================================================================
   19. FLUSH SECTION SEAMS
   Core gives every top-level child of .wp-site-blocks, and every child of a
   constrained layout, a `margin-block-start` equal to the block gap (1.2rem).
   In a design built from edge-to-edge flat panels that reads as a band of
   page background between sections — visible wherever two adjacent panels
   are not both black, and fatal above a film-strip bar, whose cutouts only
   read as cutouts when the panel above it is flush.

   Specificity note: core's rules are `:root :where(...) > *`, and :where()
   contributes nothing, so a two-class selector clears them without !important.
   Spacing inside panels is untouched — only the panel seams close up.
   ========================================================================== */

.wp-site-blocks > *,
.wp-site-blocks > footer,
.wp-site-blocks > main,
.wp-site-blocks .em-hero,
.wp-site-blocks .em-panel,
.wp-site-blocks .em-filmstrip {
	margin-block-start: 0;
	margin-block-end: 0;
}

/* The root wrapper also carries top/bottom padding from the global styles,
   which would leave the same band above the header and below the footer. */
.wp-site-blocks {
	padding-top: 0;
	padding-bottom: 0;
}

/* ==========================================================================
   20. PORTFOLIO GALLERY
   Built on core/gallery so adding work is a normal upload, not a markup edit.
   Each frame gets the same riveted steel-plate treatment as the home tiles.
   ========================================================================== */

.em-gallery.wp-block-gallery {
	gap: var(--wp--preset--spacing--40, 30px);
}

.em-gallery .wp-block-image {
	position: relative;
	margin: 0;
	border: var(--em-rule) solid var(--em-hairline);
	transition: border-color 120ms linear;
}

.em-gallery .wp-block-image img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	/* Chamfer the lower-right corner — the house cut, never a radius. */
	clip-path: polygon(
		0 0,
		100% 0,
		100% calc(100% - var(--em-shear-corner)),
		calc(100% - var(--em-shear-corner)) 100%,
		0 100%
	);
}

/* Riveted corner marks, matching .em-tile. */
.em-gallery .wp-block-image::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	pointer-events: none;
	z-index: 2;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.75;
}

.em-gallery .wp-block-image:hover {
	border-color: var(--em-industrial-orange);
}

.em-gallery .wp-block-image:hover::after {
	--em-rivet-color: var(--em-industrial-orange);
	opacity: 1;
}

/* Captions sit on the plate, not floating over the image. */
.em-gallery .wp-block-image figcaption {
	position: static;
	margin: 0;
	padding: 0.6rem 0.75rem 0.7rem;
	background: none;
	text-align: left;
}

/* ---- Portfolio page header ---- */

.em-pagehead__lede {
	max-width: 52ch;
	color: var(--em-steel-gray);
}

/* ==========================================================================
   21. VIDEO GRID
   One frame treatment, three possible contents. A cell can hold a YouTube or
   Vimeo embed, a video uploaded to the media library, or a still poster image,
   and all three sit in an identical 16:9 riveted plate. That matters here
   because the work is split between a client's YouTube channel and files
   hosted on this site — swapping a cell from one to the other should not
   change how the grid looks.
   ========================================================================== */

.em-reel.wp-block-columns {
	align-items: stretch;
	gap: var(--wp--preset--spacing--50, 40px);
}

.em-reel .wp-block-column {
	display: flex;
	flex-direction: column;
}

.em-reel__frame {
	position: relative;
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-hairline);
	transition: border-color 120ms linear;
}

.em-reel__frame:hover,
.em-reel__frame:focus-within {
	border-color: var(--em-industrial-orange);
}

/* Riveted corner marks, matching the tiles and the gallery. */
.em-reel__frame::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	pointer-events: none;
	z-index: 3;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.7;
}

.em-reel__frame:hover::after,
.em-reel__frame:focus-within::after {
	--em-rivet-color: var(--em-industrial-orange);
	opacity: 1;
}

/*
 * The media well. Every media type is forced to the same 16:9 box so the
 * grid stays on the rails whatever a given cell happens to contain.
 */
.em-reel__frame .wp-block-embed,
.em-reel__frame .wp-block-video,
.em-reel__frame .wp-block-image {
	margin: 0;
}

.em-reel__frame .wp-block-embed__wrapper,
.em-reel__frame .wp-block-video,
.em-reel__frame .wp-block-image {
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
}

.em-reel__frame .wp-block-embed__wrapper iframe,
.em-reel__frame iframe,
.em-reel__frame video,
.em-reel__frame .wp-block-image img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

/* Core's fluid-embed padding hack fights the aspect-ratio box — disable it. */
.em-reel__frame .wp-block-embed.wp-embed-aspect-16-9 .wp-block-embed__wrapper::before {
	content: none;
	padding-top: 0;
}

.em-reel__body {
	padding: 1rem 1.25rem 1.25rem;
}

.em-reel__body h3 {
	margin: 0 0 0.3rem;
	color: var(--em-white);
	letter-spacing: var(--em-track-label);
}

.em-reel__frame:hover ~ .em-reel__body h3 {
	color: var(--em-industrial-orange);
}

.em-reel__body .em-meta {
	margin: 0;
}

@media (max-width: 781px) {
	.em-reel.wp-block-columns {
		gap: var(--wp--preset--spacing--40, 30px);
	}
}

/* ==========================================================================
   22. WEB DESIGN CARDS
   A site is shown as a screenshot on a steel plate with a flat browser bar.
   The window controls are squares, not dots — a circle would be the only
   rounded thing in the entire theme.
   ========================================================================== */

.em-sites.wp-block-columns {
	align-items: stretch;
	gap: var(--wp--preset--spacing--50, 40px);
}

.em-sites .wp-block-column {
	display: flex;
	flex-direction: column;
}

.em-site__frame {
	position: relative;
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-hairline);
	transition: border-color 120ms linear;
}

.em-site__frame:hover,
.em-site__frame:focus-within {
	border-color: var(--em-industrial-orange);
}

/* Flat browser chrome: three square controls and an address plate. */
.em-site__frame::before {
	content: "";
	display: block;
	height: 30px;
	background-color: var(--em-charcoal);
	border-bottom: 1px solid var(--em-hairline);
	background-image:
		linear-gradient(var(--em-chrome-mark), var(--em-chrome-mark)),
		linear-gradient(var(--em-chrome-mark), var(--em-chrome-mark)),
		linear-gradient(var(--em-chrome-mark), var(--em-chrome-mark)),
		linear-gradient(var(--em-chrome-plate), var(--em-chrome-plate));
	background-size: 7px 7px, 7px 7px, 7px 7px, 45% 9px;
	background-repeat: no-repeat;
	background-position: 12px center, 27px center, 42px center, 68px center;
}

.em-site__frame:hover::before {
	--em-chrome-mark: var(--em-industrial-orange);
}

/* Riveted corners, matching every other plate in the theme. */
.em-site__frame::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	top: calc(30px + var(--em-rivet-inset));
	pointer-events: none;
	z-index: 3;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.7;
}

.em-site__frame:hover::after,
.em-site__frame:focus-within::after {
	--em-rivet-color: var(--em-industrial-orange);
	opacity: 1;
}

/* Screenshot well — 16:10, the shape a site actually photographs as. */
.em-site__frame .wp-block-image {
	margin: 0;
	position: relative;
	aspect-ratio: 16 / 10;
	overflow: hidden;
}

.em-site__frame .wp-block-image img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
}

.em-site__body {
	padding: 1.1rem 1.25rem 1.35rem;
}

.em-site__body h3 {
	margin: 0 0 0.3rem;
	color: var(--em-white);
	letter-spacing: var(--em-track-label);
}

.em-site__body .em-meta {
	margin: 0 0 0.75rem;
}

/* Outbound link to the live site. */
.em-site__link {
	display: inline-block;
	margin: 0;
	font-family: var(--em-font-heading);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
}

.em-site__link a {
	color: var(--em-industrial-orange);
	text-decoration: none;
	border-bottom: var(--em-rule) solid transparent;
	padding-bottom: 0.15rem;
}

.em-site__link a:hover,
.em-site__link a:focus-visible {
	border-bottom-color: var(--em-industrial-orange);
	text-decoration: none;
}

/* ==========================================================================
   23. CONTACT — THIRD-PARTY FORM WELL
   The contact form is hosted by HoneyBook, which means an iframe this theme
   cannot style from the outside. Rather than fight it, the embed sits on a
   riveted plate that frames it, and the well forces the iframe to full width
   with a sane minimum height so the layout does not collapse before the
   third-party script has finished sizing itself.
   ========================================================================== */

.em-formslot {
	position: relative;
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-hairline);
	padding: clamp(1rem, 2.5vw, 1.75rem);
}

.em-formslot::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	pointer-events: none;
	z-index: 2;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.7;
}

/* Anything the embed drops in — iframe, form, or injected div — goes full
   width. Third-party widgets often ship a fixed pixel width otherwise.
   HoneyBook's placement controller fills a div named hb-p-<placement id>,
   so the container is matched on the prefix rather than an exact class. */
.em-formslot iframe,
.em-formslot [class*="hb-p-"],
.em-formslot form {
	display: block;
	width: 100%;
	max-width: 100%;
	border: 0;
}

.em-formslot iframe {
	min-height: 640px;
}

/* Placeholder state, shown until the real embed replaces it. */
.em-formslot--empty {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 380px;
	padding: clamp(1.5rem, 4vw, 3rem);
	border-style: dashed;
}

.em-formslot--empty p {
	margin: 0 0 0.6rem;
	font-family: var(--em-font-mono);
	font-size: 0.8125rem;
	letter-spacing: 0.1em;
	line-height: 1.7;
	color: var(--em-steel-gray);
}

.em-formslot--empty p:first-child {
	color: var(--em-industrial-orange);
	text-transform: uppercase;
	letter-spacing: 0.18em;
}

.em-formslot--empty p:last-child {
	margin-bottom: 0;
}

/* ---- Contact intro column ---- */

.em-contact__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.em-contact__list li {
	position: relative;
	padding-left: 1.75rem;
	margin-bottom: 0.8rem;
	color: var(--em-steel-gray);
}

/* Square bullet — the house mark, not a disc. */
.em-contact__list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 8px;
	height: 8px;
	background-color: var(--em-industrial-orange);
}

/* ==========================================================================
   24. BLOG INDEX
   Post cards reuse the riveted plate from the portfolio grids. They have to
   read correctly with or without a featured image, because a post written in
   a hurry will not always have one — so the plate, not the image, carries the
   card, and the image is an optional band across the top.
   ========================================================================== */

.em-postgrid {
	gap: var(--wp--preset--spacing--50, 40px);
}

.em-post {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-hairline);
	transition: border-color 120ms linear;
}

.em-post:hover,
.em-post:focus-within {
	border-color: var(--em-industrial-orange);
}

.em-post::after {
	content: "";
	position: absolute;
	inset: var(--em-rivet-inset);
	pointer-events: none;
	z-index: 3;
	background-image:
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color)),
		linear-gradient(var(--em-rivet-color), var(--em-rivet-color));
	background-size: var(--em-rivet-size) var(--em-rivet-size);
	background-repeat: no-repeat;
	background-position: left top, right top, left bottom, right bottom;
	opacity: 0.7;
}

.em-post:hover::after,
.em-post:focus-within::after {
	--em-rivet-color: var(--em-industrial-orange);
	opacity: 1;
}

/* Featured image, when there is one. */
.em-post .wp-block-post-featured-image {
	margin: 0;
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
}

.em-post .wp-block-post-featured-image img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.em-post__body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	padding: 1.25rem 1.4rem 1.5rem;
}

.em-post__body .wp-block-post-date {
	margin: 0 0 0.5rem;
}

.em-post__body .wp-block-post-title {
	margin: 0 0 0.6rem;
	letter-spacing: var(--em-track-label);
}

.em-post__body .wp-block-post-title a {
	color: var(--em-white);
	text-decoration: none;
}

.em-post:hover .wp-block-post-title a {
	color: var(--em-industrial-orange);
}

.em-post__body .wp-block-post-excerpt {
	margin: 0;
	color: var(--em-steel-gray);
}

.em-post__body .wp-block-post-excerpt__excerpt {
	font-size: 0.9375rem;
	line-height: 1.6;
}

/* Push the read-more to the bottom so cards of differing length line up. */
.em-post__body .wp-block-post-excerpt__more-text {
	margin: auto 0 0;
	padding-top: 0.9rem;
}

.em-post__body .wp-block-post-excerpt__more-link {
	font-family: var(--em-font-heading);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
	color: var(--em-industrial-orange);
	text-decoration: none;
	border-bottom: var(--em-rule) solid transparent;
	padding-bottom: 0.15rem;
}

.em-post__body .wp-block-post-excerpt__more-link:hover,
.em-post__body .wp-block-post-excerpt__more-link:focus-visible {
	border-bottom-color: var(--em-industrial-orange);
}

/* ---- Pagination ---- */

.em-pagination {
	font-family: var(--em-font-heading);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
}

.em-pagination a,
.em-pagination .wp-block-query-pagination-numbers .page-numbers {
	color: var(--em-steel-gray);
	text-decoration: none;
	border-bottom: var(--em-rule) solid transparent;
	padding-bottom: 0.15rem;
}

.em-pagination a:hover,
.em-pagination .page-numbers.current {
	color: var(--em-industrial-orange);
	border-bottom-color: var(--em-industrial-orange);
}

/* Shown when the blog has no posts yet. */
.em-noposts {
	border: var(--em-rule) dashed var(--em-hairline);
	padding: clamp(1.5rem, 4vw, 3rem);
	color: var(--em-steel-gray);
	font-family: var(--em-font-mono);
	letter-spacing: 0.08em;
}

/* Inline "all posts" style link, sitting beside a section heading. */
.em-morelink {
	margin: 0;
	font-family: var(--em-font-heading);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--em-track-label);
	text-transform: uppercase;
}

.em-morelink a {
	color: var(--em-industrial-orange);
	text-decoration: none;
	border-bottom: var(--em-rule) solid transparent;
	padding-bottom: 0.15rem;
}

.em-morelink a:hover,
.em-morelink a:focus-visible {
	border-bottom-color: var(--em-industrial-orange);
}

/* ==========================================================================
   25. PHOTO MATS — KEEPING THE PALETTE VISIBLE
   Every framed image across the site sits inset on a coloured plate instead
   of bleeding to the frame edge. The mat colour cycles through the palette,
   and each mat pairs its rivets using one of the five approved combinations,
   so the colour system reads across a page of real photographs rather than
   being covered by them.

   Cycling is done with :nth-child rather than per-item classes so it applies
   automatically to galleries built in the editor, with no markup to maintain.
   ========================================================================== */

/* ---- Photography gallery ---- */

.em-gallery .wp-block-image {
	padding: var(--em-mat);
	background-color: var(--em-mat-bg);
}

.em-gallery .wp-block-image:nth-child(5n + 1) {
	--em-mat-bg: var(--em-charcoal);
	--em-rivet-color: var(--em-steel-gray);
}

.em-gallery .wp-block-image:nth-child(5n + 2) {
	--em-mat-bg: var(--em-deep-navy);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-gallery .wp-block-image:nth-child(5n + 3) {
	--em-mat-bg: var(--em-industrial-orange);
	--em-rivet-color: var(--em-deep-navy);
}

.em-gallery .wp-block-image:nth-child(5n + 4) {
	--em-mat-bg: var(--em-oxblood-maroon);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-gallery .wp-block-image:nth-child(5n + 5) {
	--em-mat-bg: var(--em-steel-gray);
	--em-rivet-color: var(--em-charcoal);
}

/* ---- Video reel frames ---- */

.em-reel__frame {
	padding: var(--em-mat);
	background-color: var(--em-mat-bg);
}

.em-reel .wp-block-column:nth-child(odd) .em-reel__frame {
	--em-mat-bg: var(--em-deep-navy);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-reel .wp-block-column:nth-child(even) .em-reel__frame {
	--em-mat-bg: var(--em-industrial-orange);
	--em-rivet-color: var(--em-deep-navy);
}

/* Add em-reel--alt to a row to swap it onto the second pair of mats. */
.em-reel--alt .wp-block-column:nth-child(odd) .em-reel__frame {
	--em-mat-bg: var(--em-oxblood-maroon);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-reel--alt .wp-block-column:nth-child(even) .em-reel__frame {
	--em-mat-bg: var(--em-charcoal);
	--em-rivet-color: var(--em-steel-gray);
}

/* ---- Web design screenshots ----
   Padding goes on the image well, not the frame, so the browser chrome bar
   still spans the full width of the plate. */

.em-site__frame .wp-block-image {
	margin: var(--em-mat);
	background-color: var(--em-mat-bg);
}

.em-site__frame {
	background-color: var(--em-mat-bg);
}

.em-sites .wp-block-column:nth-child(odd) .em-site__frame {
	--em-mat-bg: var(--em-charcoal);
	--em-rivet-color: var(--em-steel-gray);
}

.em-sites .wp-block-column:nth-child(even) .em-site__frame {
	--em-mat-bg: var(--em-deep-navy);
	--em-rivet-color: var(--em-industrial-orange);
}

/* ---- Homepage discipline tiles ---- */

.em-tile {
	background-color: var(--em-mat-bg);
}

.em-tile .wp-block-image {
	margin: var(--em-mat) var(--em-mat) 0;
}

.em-grid-columns .wp-block-column:nth-child(3n + 1) .em-tile {
	--em-mat-bg: var(--em-deep-navy);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-grid-columns .wp-block-column:nth-child(3n + 2) .em-tile {
	--em-mat-bg: var(--em-charcoal);
	--em-rivet-color: var(--em-steel-gray);
}

.em-grid-columns .wp-block-column:nth-child(3n + 3) .em-tile {
	--em-mat-bg: var(--em-oxblood-maroon);
	--em-rivet-color: var(--em-industrial-orange);
}

/* The tile used to flip its whole background on hover. Now that the mat is
   visible that reads as the card changing colour, so hold the mat steady and
   let only the border and rivets respond. */
.em-tile:hover,
.em-tile:focus-within {
	background-color: var(--em-mat-bg);
}

/* ---- Blog cards ---- */

.em-post {
	background-color: var(--em-mat-bg);
}

.em-post .wp-block-post-featured-image {
	margin: var(--em-mat) var(--em-mat) 0;
}

.em-postgrid > li:nth-child(4n + 1) .em-post {
	--em-mat-bg: var(--em-charcoal);
	--em-rivet-color: var(--em-steel-gray);
}

.em-postgrid > li:nth-child(4n + 2) .em-post {
	--em-mat-bg: var(--em-deep-navy);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-postgrid > li:nth-child(4n + 3) .em-post {
	--em-mat-bg: var(--em-oxblood-maroon);
	--em-rivet-color: var(--em-industrial-orange);
}

.em-postgrid > li:nth-child(4n + 4) .em-post {
	--em-mat-bg: var(--em-industrial-orange);
	--em-rivet-color: var(--em-deep-navy);
}

/* Text on an orange or steel-gray mat needs the dark ink of its pairing. */
.em-postgrid > li:nth-child(4n + 4) .em-post .wp-block-post-title a,
.em-postgrid > li:nth-child(4n + 4) .em-post .wp-block-post-excerpt {
	color: var(--em-deep-navy);
}

/* ==========================================================================
   26. FILM-STRIP COLOUR VARIANTS — ONE PER PAGE
   Two families, because a bar only reads on a ground it contrasts with.

   Direct: the bar sits straight on the black page, cutouts black. Only
   colours bright against black work here — orange, steel gray, white.

   Plate: the bar sits inside a steel-gray band, built from top and bottom
   borders, with cutouts in the band colour so they still read as punched
   through. This is what makes navy, maroon and charcoal usable — on black
   they measure under 2:1 and the perforations disappear entirely.
   ========================================================================== */

/* ---- Direct on black ---- */

.em-filmstrip--orange {
	--em-strip-bar: var(--em-industrial-orange);
	--em-strip-perf: var(--em-steel-black);
}

.em-filmstrip--gray {
	--em-strip-bar: var(--em-steel-gray);
	--em-strip-perf: var(--em-steel-black);
}

.em-filmstrip--white {
	--em-strip-bar: var(--em-white);
	--em-strip-perf: var(--em-steel-black);
}

/* ---- On a steel-gray plate band ---- */

.em-filmstrip--navy-plate,
.em-filmstrip--maroon-plate,
.em-filmstrip--charcoal-plate {
	--em-strip-perf: var(--em-steel-gray);
	border-top: 10px solid var(--em-steel-gray);
	border-bottom: 10px solid var(--em-steel-gray);
}

.em-filmstrip--navy-plate {
	--em-strip-bar: var(--em-deep-navy);
}

.em-filmstrip--maroon-plate {
	--em-strip-bar: var(--em-oxblood-maroon);
}

.em-filmstrip--charcoal-plate {
	--em-strip-bar: var(--em-charcoal);
}

/* ==========================================================================
   27. FILM-STRIP — ONE CONSISTENT BAR
   Supersedes the two-family experiment in section 26. That produced visibly
   different bars page to page: some sat directly on black, others carried a
   steel-gray plate band, and the perforations were filled steel gray rather
   than reading as open holes.

   There is now a single structure everywhere — a solid bar with genuinely
   open-looking perforations. The holes are painted in the page ground rather
   than a contrasting colour, so they read as punched through rather than as
   filled dots, and no bar carries a band, border or stroke.

   Every legacy modifier is folded into the same appearance on purpose: pages
   already published carry a mix of the old classes, and this way they all
   render identically without needing each page edited.
   ========================================================================== */

.em-filmstrip,
.em-filmstrip--orange,
.em-filmstrip--gray,
.em-filmstrip--white,
.em-filmstrip--navy,
.em-filmstrip--navy-plate,
.em-filmstrip--charcoal-plate,
.em-filmstrip--on-black,
.em-filmstrip--on-charcoal,
.em-filmstrip--on-orange,
.em-filmstrip--on-navy,
.em-filmstrip--on-plate {
	--em-strip-bar: var(--em-deep-navy);
	--em-strip-perf: var(--em-steel-black);
	border: 0;
}

/* The one alternate: swap any divider to oxblood with a single class. */
.em-filmstrip--maroon,
.em-filmstrip--maroon-plate {
	--em-strip-bar: var(--em-oxblood-maroon);
	--em-strip-perf: var(--em-steel-black);
	border: 0;
}

/* ==========================================================================
   28. NO SIDEWAYS SCROLL
   Full-width sections were stopping short of the right edge. Root padding is
   clamp(30px, 5vw, 50px) and alignfull breaks out by that on each side, so
   anything overflowing makes the document wider than the viewport — every
   100%-wide band then ends before the scroll width and reads as cut off.

   overflow-x: clip rather than hidden: clip does not create a scroll
   container, so position: sticky and anchor links keep working.
   ========================================================================== */

html,
body,
.wp-site-blocks {
	overflow-x: clip;
	max-width: 100%;
}

/*
 * Full-bleed the divider deterministically instead of relying on alignfull.
 *
 * alignfull breaks out with negative margins, which depends on the parent
 * carrying has-global-padding. Where that does not hold the bar ends up
 * inset, and capping it with max-width made it worse — the negative left
 * margin still escaped while the right edge got clamped back, which is
 * exactly the cut-off right edge.
 *
 * 100vw is always the viewport, whatever the container. It includes the
 * scrollbar, so the few pixels of overflow that creates are absorbed by the
 * overflow-x: clip above rather than producing a sideways scroll.
 */
.em-filmstrip {
	position: relative;
	left: 50%;
	transform: translateX(-50%);
	width: 100vw;
	max-width: 100vw;
	/*
	 * Core sets negative margins on .alignfull inside .has-global-padding at
	 * specificity (0,2,0). Plain .em-filmstrip is (0,1,0) and loses, so those
	 * margins survived and dragged this 100vw band left by the root padding,
	 * leaving the right edge short — the cut-off. This is why the Blog page
	 * was never affected: its divider sits in the template, whose parent has
	 * no global padding, so core never applied the margins there.
	 *
	 * !important rather than an escalating specificity war with core, which
	 * would break again the next time that rule is reworked upstream.
	 */
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* ==========================================================================
   29. PAGE HERO — TAKES AN IMAGE OR A VIDEO
   Every page header is a Cover block, so media is added the ordinary way:
   select the hero, choose Add media, pick an image or a video from the
   library. Nothing else has to change.

   Empty, it has to look exactly like the flat panel it replaced — hence the
   solid ground below and a content-driven height. Only once media is present
   does it take a minimum height worth showing a frame in.
   ========================================================================== */

.em-pagehead {
	background-color: var(--em-steel-black);
	min-height: 0;
}

/* With media in place, give the frame room. :has() lets the empty state stay
   exactly as it was rather than forcing a tall empty box on every page. */
.em-pagehead:has(.wp-block-cover__image-background),
.em-pagehead:has(.wp-block-cover__video-background),
.em-pagehead:has(video) {
	min-height: 60vh;
}

/* Cover crops its media to fill; keep video behaving like the image does. */
.em-pagehead video,
.em-hero video,
.em-pagehead .wp-block-cover__image-background,
.em-hero .wp-block-cover__image-background {
	object-fit: cover;
	object-position: center;
}

/* The inner column keeps the same measure as the panels it replaced. */
.em-pagehead .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1400px);
	margin-inline: auto;
}

@media (prefers-reduced-motion: reduce) {
	.em-pagehead video,
	.em-hero video {
		display: none;
	}
}

/* ==========================================================================
   30. IMAGE LIGHTBOX
   Uses WordPress core's built-in lightbox rather than a script of our own.
   Core handles the parts that are easy to get wrong: focus is trapped while
   it is open, Escape closes it, focus returns to the thumbnail that opened
   it, and the trigger is a real button announced to screen readers.

   Enabled in theme.json for core/image. Disabled on the homepage tiles,
   where the whole card is already a link and a second trigger would add a
   stray tab stop.

   Everything below is presentation only — the overlay is core's markup, so
   the behaviour keeps working if these rules are ever removed.
   ========================================================================== */

.wp-lightbox-overlay {
	background-color: var(--em-steel-black);
}

.wp-lightbox-overlay .scrim {
	background-color: var(--em-steel-black);
	opacity: 0.94;
}

/* The enlarged frame gets the same steel-plate edge as the grid it came from,
   but no chamfer — a cropped corner on the full-size image would clip work. */
.wp-lightbox-overlay .wp-block-image img {
	border: var(--em-rule) solid var(--em-hairline);
	clip-path: none;
	object-fit: contain;
}

/* Square, on-brand close button. Core ships a round one. */
.wp-lightbox-overlay .close-button {
	background-color: var(--em-charcoal);
	border: var(--em-rule) solid var(--em-industrial-orange);
	color: var(--em-industrial-orange);
	width: 3rem;
	height: 3rem;
	top: var(--wp--preset--spacing--40, 30px);
	right: var(--wp--preset--spacing--40, 30px);
	transition: background-color 120ms linear, color 120ms linear;
}

.wp-lightbox-overlay .close-button:hover,
.wp-lightbox-overlay .close-button:focus-visible {
	background-color: var(--em-industrial-orange);
	color: var(--em-deep-navy);
}

.wp-lightbox-overlay .close-button svg {
	fill: currentColor;
}

/* The "enlarge" affordance on each thumbnail. */
.em-gallery .wp-block-image .lightbox-trigger,
.wp-block-image .lightbox-trigger {
	background-color: var(--em-charcoal);
	border: 1px solid var(--em-industrial-orange);
	fill: var(--em-industrial-orange);
	opacity: 0;
	transition: opacity 120ms linear;
}

.wp-block-image:hover .lightbox-trigger,
.wp-block-image .lightbox-trigger:focus-visible {
	opacity: 1;
}

/* Caption shown beneath the enlarged image. */
.wp-lightbox-overlay .wp-element-caption {
	font-family: var(--em-font-mono);
	font-size: 0.8125rem;
	letter-spacing: var(--em-track-meta);
	color: var(--em-steel-gray);
}

@media (prefers-reduced-motion: reduce) {
	.wp-lightbox-overlay,
	.wp-lightbox-overlay img {
		transition: none !important;
		animation: none !important;
	}
}
