/* ── Design tokens (light = :root, dark = html.dark overrides only) ──
   The light palette is CANONICAL here; the html.dark block at the bottom
   of this file redefines tokens (plus legacy component rescues). Values
   were extracted 2026-07-19 from the pre-token hardcoded palette — see
   docs/STYLE-GUIDE.md §1 for roles and §3.2/§3.3 for radii & shadows.
   Static artwork drop-shadow tokens live in p1-artwork.css (artwork scope);
   the interactive artwork glow is global because archives use it too. */
:root {
	/* Surfaces & text */
	--p1-bg: #fff;
	--p1-text: #1a1a1a;
	--p1-text-strong-muted: #383838; /* ink↔muted midpoint (11.7:1) — attributions and small text that must read ink-adjacent while staying quieter than body ink (first consumer: .p1-invited-cite) */
	--p1-text-muted: #565656;   /* a11y anchor — pairs with #c4c4c4 in dark (≈7:1 / ≈10:1) */
	--p1-text-subtle: #757575;  /* AA floor (4.6:1) — placeholders, faint labels */
	--p1-border: #eaeaea;       /* neutral hairline */
	--p1-border-warm: #ede9e3;  /* warm hairline — header/dropdown family */
	--p1-border-input: #ccc;    /* form input borders */
	--p1-surface: #f2f2f2;      /* neutral raised surface (grey button, hover wells) */
	--p1-surface-warm: #faf9f7; /* warm well (submission list, inquire inputs) */
	--p1-glass-bg: rgba(255,255,255,0.92);
	--p1-glass-border: rgba(0,0,0,0.05);
	--p1-accent: #33435C;       /* essay slate-blue — the site's only brand accent */
	--p1-accent-rgb: 51, 67, 92;      /* rgb triple of --p1-accent (for rgba() consumers, e.g. GF focus rings) */
	--p1-accent-soft: #5B6E8C;  /* essay accent-soft — hover/soft states of the accent */
	--p1-bg-rgb: 255, 255, 255; /* rgb triple of --p1-bg */

	/* Status colors (badges, votes, form states) */
	--p1-error: #c62828;        /* canonical error red */
	--p1-success: #2e7d32;      /* canonical success green */

	/* Radius scale: sm/md/lg/pill (+ 50% literal for circles) */
	--p1-radius-sm: 4px;        /* controls: buttons, inputs, thumbs, cards */
	--p1-radius-md: 8px;        /* large media surfaces: slider, popup cards */
	--p1-radius-lg: 10px;       /* modal panels */
	--p1-radius-pill: 999px;    /* pills: chips, counters, floating islands */

	/* Interactive artwork glow (§3.3): hover/current feedback shared by
	   single-artwork thumbnails and every interactive archive view. */
	--p1-glow-artwork-interactive: 0 0 0 1px rgba(var(--p1-accent-rgb), .18), 0 0 16px rgba(var(--p1-accent-rgb), .28), 0 0 36px rgba(var(--p1-accent-rgb), .14);

	/* Shadows (§3.3) — pinned-element elevation: an INSET top shadow for
	   the band under a pinned header, faded in once its companion
	   container has scrolled (.is-scrolled). Inset on purpose: a drop
	   shadow with negative spread collapses to nothing on a hairline-thin
	   caster (CSS spec: empty shadow shape). */
	--p1-shadow-pinned: inset 0 10px 12px -10px rgba(0,0,0,.28);
}

/* ── Global reset & base ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
	color: var(--p1-text);
	background: var(--p1-bg);
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}
a { color: inherit; }
img { max-width: 100%; display: block; }

/* Native Cross-Document View Transitions */
@view-transition { navigation: auto; }


/* ── Site header ─────────────────────────────────────────────────── */
.p1-site-header {
	position: sticky;
	top: 0;
	z-index: 200;
	background: var(--p1-bg);
	border-bottom: 1px solid var(--p1-border-warm);
	box-shadow: 0 4px 20px rgba(0,0,0,0.05); /* Subtle menu bar elevation */
	view-transition-name: p1-main-header;
}
.p1-site-header__inner {
	max-width: 100%;
	margin: 0;
	padding: 0 4vw;
	height: 96px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 48px;
}

/* ── Logo ────────────────────────────────────────────────────────── */
.p1-logo {
	text-decoration: none;
	display: flex;
	flex-direction: column;
	line-height: 1;
	gap: 3px;
	flex-shrink: 0;
}
.p1-logo__first, .p1-logo__last { transition: opacity 0.2s ease; }
.p1-logo:hover .p1-logo__first, .p1-logo:hover .p1-logo__last { opacity: 0.6; }
.p1-logo__first {
	font-family: 'Cormorant Garamond', Georgia, serif;
	font-weight: 600;
	font-size: 1.25rem;
	color: #888;
	text-transform: uppercase;
	letter-spacing: 0.2em;
}
.p1-logo__last {
	font-family: 'Cormorant Garamond', Georgia, serif;
	font-weight: 600;
	font-size: 2.2rem;
	color: var(--p1-text);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	line-height: 1;
}
.p1-logo--agency { gap: 6px; }
.p1-logo--agency .p1-logo__first {
	font-size: 2rem;
	color: var(--p1-text);
	letter-spacing: 0.08em;
	text-transform: none;
}
.p1-logo--agency .p1-logo__last {
	font-family: inherit;
	font-size: 0.78rem;
	color: var(--p1-text-muted);
	letter-spacing: 0.22em;
	text-transform: uppercase;
}

/* ── Navigation ──────────────────────────────────────────────────── */
.p1-nav { display: flex; align-items: center; }

.p1-nav__list {
	display: flex;
	list-style: none;
	gap: 48px;
	align-items: center;
}
.p1-nav__item { position: relative; }

.p1-nav__link {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	text-decoration: none;
	font-size: 0.85rem;
	font-weight: 400;
	color: var(--p1-text-muted); /* was #595959 — ladder-merged (ΔRGB 3) */
	letter-spacing: 0.18em;
	text-transform: uppercase;
	position: relative;
	padding-bottom: 3px;
	transition: color 0.2s;
	white-space: nowrap;
	background: none;
	border: none;
	cursor: pointer;
	font-family: inherit;
}
.p1-nav__link::after {
	content: '';
	position: absolute;
	bottom: 0;
	left: 0;
	width: 0;
	height: 1px;
	background: currentColor; /* was #1a1a1a — invisible in dark; now follows the link's hover ink in both modes */
	transition: width 0.25s ease;
}
.p1-nav__link:hover,
.p1-nav__link--active { color: #1a1a1a; }
.p1-nav__link:hover::after,
.p1-nav__link--active::after { width: 100%; }

/* (Nav dropdown CSS removed 2026-07-19, Wave B1 — no emitting markup existed:
   header.php builds the nav manually with no .p1-nav__dropdown / chevron
   elements, and the companion JS targeted missing ids. See STYLE-GUIDE §6 #10.) */

/* ── Hamburger (mobile) ──────────────────────────────────────────── */
.p1-nav__burger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	background: none;
	border: none;
	cursor: pointer;
	padding: 8px;
	z-index: 401;
	position: relative;
}
.p1-nav__burger span {
	display: block;
	width: 24px;
	height: 1.5px;
	background: #1a1a1a;
	transition: transform 0.25s, opacity 0.2s;
	transform-origin: center;
}
.p1-nav__burger.is-open span:nth-child(1) { transform: rotate(45deg) translate(4.7px, 4.7px); }
.p1-nav__burger.is-open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.p1-nav__burger.is-open span:nth-child(3) { transform: rotate(-45deg) translate(4.7px, -4.7px); }

/* ── Mobile menu ─────────────────────────────────────────────────── */
@media (max-width: 820px) {
	.p1-site-header__inner { padding: 0 20px; height: 72px; }
	.p1-nav__burger { display: flex; }

	.p1-nav__list {
		position: fixed;
		inset: 0;
		background: var(--p1-bg);
		flex-direction: column;
		justify-content: center;
		align-items: center;
		gap: 8px;
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transition: opacity 0.3s, visibility 0.3s;
		z-index: 400;
	}
	.p1-nav__list.is-open {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
	}
	.p1-nav__item { width: 100%; text-align: center; }
	.p1-nav__link { font-size: 0.9rem; padding: 12px 0; justify-content: center; width: 100%; -webkit-appearance: none; appearance: none; }
	.p1-nav__link::after { display: none; }
}

/* ── Header Custom Buttons ───────────────────────────────────────── */
.p1-nav__item--updates { position: relative; }
.p1-header-login-btn {
	position: absolute;
	top: -20px;
	right: 0;
	background: transparent;
	border: none;
	font-size: 0.65rem;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: #888;
	cursor: pointer;
	transition: color 0.2s;
	padding: 0;
}
.p1-header-login-btn:hover { color: #111; }

@media (max-width: 900px) {
	.p1-header-login-btn {
		position: relative;
		top: auto;
		right: auto;
		margin-bottom: 20px;
		display: block;
		width: 100%;
		text-align: center;
	}
	.p1-nav__item--updates {
		display: flex;
		flex-direction: column;
		align-items: center;
	}
	.p1-nav__item--toggle {
		display: none !important;
	}
	.p1-theme-toggle--mobile {
		display: block !important;
		position: relative;
		z-index: 1000;
	}
}

.p1-header-updates-btn {
	padding: 6px 16px;
	font-family: inherit;
	font-size: 0.85rem;
	font-weight: 400;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--p1-text-muted); /* was #595959 — ladder-merged (ΔRGB 3) */
	background: transparent;
	border: 1px solid #ddd;
	border-radius: var(--p1-radius-sm);
	cursor: pointer;
	transition: all 0.2s;
}
.p1-header-updates-btn:hover {
	color: #1a1a1a;
	border-color: #1a1a1a;
}

/* ── Modal system (.p1-modal) — THE one modal recipe, sitewide ────────
   Merged 2026-07-25 (Wave C, STYLE-GUIDE §6 #2): the former
   .p1-header-modal family (Get Updates / Login) is now .p1-modal with
   the --header variant, and the base moved here from p1-artwork.css
   because header modals render on every page.
   Anatomy: .p1-modal-overlay > .p1-modal > __close / __title /
   __desc? / __body*. The base title is the CONTROL tier (1.6rem/600 —
   functional dialogs are the default); --page and --header opt into
   the 2.4rem Cormorant 600 DISPLAY tier. Artwork-only modal internals
   (sign-form fields, register note) stay in p1-artwork.css.
   Open contract: `.open` on the overlay + aria-hidden swap + body
   scroll lock; ESC and overlay-click close; close button is focused
   on open. See STYLE-GUIDE §5.1. */
.p1-modal-overlay {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 9000;
	background: rgba(0,0,0,.55);
	backdrop-filter: blur(3px);
	align-items: flex-start;
	justify-content: center;
	padding: 5vh 20px;
	overflow-y: auto;
}
.p1-modal-overlay.open { display: flex; }
/* Header modals sit above the floating nav island (z 9990); app-page
   modals keep the shipped 9000 (the island stays visible over their
   backdrop — preserved behavior, not a new choice). */
.p1-modal-overlay--header { z-index: 9999; }

.p1-modal {
	background: var(--p1-bg);
	border-radius: var(--p1-radius-lg);
	padding: 40px 44px 44px;
	max-width: 560px;
	width: 100%;
	position: relative;
	box-shadow: 0 20px 60px rgba(0,0,0,.2);
	margin: auto;
	animation: p1ModalIn .25s cubic-bezier(0.19, 1, 0.22, 1); /* the house entrance curve (§3.4) */
}
@media (max-width: 600px) { .p1-modal { padding: 28px 20px 32px; } }
@keyframes p1ModalIn { from { opacity: 0; transform: translateY(15px) scale(0.95); } to { opacity: 1; transform: none; } }

.p1-modal__close {
	position: absolute;
	top: 16px;
	right: 16px;
	width: 36px;
	height: 36px;
	border: none;
	background: transparent;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	transition: background .15s;
	padding: 0;
	color: var(--p1-text-muted);
}
.p1-modal__close:hover { background: var(--p1-surface); color: #111; }
.p1-modal__close svg   { width: 20px; height: 20px; }

.p1-modal__title { font-size: 1.6rem; font-weight: 600; margin: 0 0 20px; padding-right: 36px; } /* control-tier title (the default) — 1.6rem/600, essay value (§2.2) */
.p1-modal__desc  { font-size: 0.95rem; color: var(--p1-text-muted); margin-bottom: 24px; line-height: 1.5; } /* lede line under a display title */
.p1-modal__body  { font-size: 1rem; color: var(--p1-text-muted); margin-bottom: 24px; }
.p1-modal__body--left { text-align: left; margin-bottom: 0; }
.p1-modal__body--content img { max-width: 100%; height: auto; border-radius: var(--p1-radius-sm); margin: 15px 0; }
.p1-modal__body--content p { line-height: 1.6; margin-bottom: 1em; }
/* Lists in popup Gutenberg content (§5.7): the global reset strips the
   UA list indent, and with list-style-position: outside the markers land
   LEFT of the scrolling __body — clipped by its overflow (every
   --content body is a clip box). Restore the indent inside the clip;
   24px = the reading scope's own rhythm step (columns gap, lead-detail
   gutter — §3.1). Indent only, no margins: text nodes keep their exact
   flow positions, so the change is provably content-neutral. Markers
   inherit the body's tokened color — dark mode rides the tokens.
   (ul.p1-icon-list opts back out below — its icon column replaces the
   markers, so there is nothing to clip.) */
.p1-modal__body--content ul,
.p1-modal__body--content ol { padding-inline-start: 24px; }

/* Gravity Forms inside modals — the canonical modal-form skin (§5.4).
   Scoped OUT of the --header context (:not(.p1-modal--header)): the
   header updates form has always rendered GF-pure (Orbital framework +
   the house var remap — its old lower-specificity skin lost every
   declaration), and half-winning class rules against Orbital produce
   broken hybrids (verified Wave C). App-page modal forms (inquiry)
   keep this skin exactly as shipped. */
.p1-modal .gform_wrapper { margin: 0; }
.p1-modal:not(.p1-modal--header) .gform_wrapper input[type="text"],
.p1-modal:not(.p1-modal--header) .gform_wrapper input[type="email"],
.p1-modal:not(.p1-modal--header) .gform_wrapper input[type="tel"],
.p1-modal:not(.p1-modal--header) .gform_wrapper textarea {
	width: 100%;
	border: 1px solid var(--p1-border-input);
	border-radius: var(--p1-radius-sm);
	padding: 10px 12px;
	font-size: .95rem;
	font-family: inherit;
	transition: border-color .15s;
}
.p1-modal:not(.p1-modal--header) .gform_wrapper input:focus,
.p1-modal:not(.p1-modal--header) .gform_wrapper textarea:focus { outline: none; border-color: #222; }
.p1-modal:not(.p1-modal--header) .gform_wrapper textarea { min-height: 120px; resize: vertical; }
.p1-modal:not(.p1-modal--header) .gform_wrapper .gfield_label { font-weight: 600; font-size: .9rem; margin-bottom: 5px; display: block; }
.p1-modal:not(.p1-modal--header) .gform_wrapper .gfield { margin-bottom: 16px; }
.p1-modal:not(.p1-modal--header) .gform_wrapper .gform_footer { margin-top: 6px; padding: 0; }
.p1-modal:not(.p1-modal--header) .gform_wrapper input[type="submit"] {
	background: #222;
	color: #fff;
	border: none;
	padding: 12px 28px;
	border-radius: var(--p1-radius-sm);
	font-size: .95rem;
	font-family: inherit;
	cursor: pointer;
	transition: background .2s;
}
.p1-modal:not(.p1-modal--header) .gform_wrapper input[type="submit"]:hover { background: #444; }
/* AJAX confirmations can render outside .gform_wrapper — same scoping. */
.p1-modal:not(.p1-modal--header) .gform_confirmation_message { font-size: 1rem; line-height: 1.6; }

/* ── Modal variants ── */
.p1-modal--centered { text-align: center; padding: 40px; }
.p1-modal--narrow   { max-width: 480px; width: 90%; }
.p1-modal--medium   { max-width: 720px; width: 95%; padding: 40px; }
.p1-modal--centered .p1-modal__title { margin-bottom: 16px; }
.p1-modal--centered .p1-btn + .p1-btn { margin-left: 12px; }

/* Header-context variant (--header): Get Updates / Login. 480px
   centered panel with the display-tier title and a __desc lede;
   forms inside stay left-aligned. Pair with .p1-modal-overlay--header. */
.p1-modal--header { max-width: 480px; padding: 40px; text-align: center; }
.p1-modal--header .p1-modal__title {
	font-size: 2.4rem;      /* modal display title — same tier as --page (2.4rem/600 since #14 R2) */
	font-weight: 600;
	line-height: 1.2;
	color: var(--p1-text);
	margin: 0 0 12px;
	padding-right: 0;       /* centered title, no close-button clearance */
}
.p1-modal--header .gform_wrapper { text-align: left; }
.p1-modal--header .gform_heading { display: none; }

/* ── Detail rail (.p1-detail-rail) — STYLE-GUIDE §5.7 ─────────────────────
   THE sidebar for reading-content image details (#14 R4, owner ask:
   "one column of sidebar (about 1/3 the width) and the text the other
   2/3"). One <aside class="p1-detail-rail"> per reading column, built at
   render time by inc/performance.php from the content's image-only
   columns; each figure spans the rail's width, captions beneath (§5.5
   detail-caption recipe). The rail REPLACES the R2 float-right
   figure.p1-lead-detail + hanging 220px columns. Presentation is
   universal here (both §5.7 scopes load this file); the 2/3–1/3 GRID
   that seats it is declared per scope (the --page block below, and
   .p1-page__content in page.php). Rail gap 24px = the reading scope's
   rhythm step (§3.1). No colors beyond the tokened caption — dark mode
   rides the tokens. */
.p1-detail-rail {
	display: flex;
	flex-direction: column;
	gap: 24px;
}
.p1-detail-rail figure.wp-block-image { margin: 0; }
.p1-detail-rail figure.wp-block-image img {
	max-width: 100%;
	height: auto;
	display: block;
	border-radius: var(--p1-radius-sm);
	margin: 0; /* beats the --content img 15px stack (higher specificity) */
}
.p1-detail-rail figcaption,
.p1-page__content figure.wp-block-image > figcaption.wp-element-caption {
	font-size: 0.82rem;
	line-height: 1.5;
	color: var(--p1-text-muted);
	text-align: left;
	margin: 8px 0 0;
}

/* ── Page-in-modal variant (.p1-modal--page) ──────────────────────────────
   For popups whose content is a real, deep-linked WP page (worked example:
   the Medium & Technique popup, #p1-medium-modal). Combine with --medium.
   Title = the modal DISPLAY title (2.4rem Cormorant 600 — same tier as
   --header). Body = 2/3 reading column + 1/3 .p1-detail-rail sidebar
   (assembled at render time by inc/performance.php) when the content has
   image details, single reading column otherwise; embed columns group
   with their text on a warm mat. Editor preset sizes are pinned to the
   reading size. */
.p1-modal--page { padding-bottom: 24px; }
.p1-modal--page .p1-modal__title {
	font-size: 2.4rem;      /* modal display title (2.4rem/600 since #14 R2) */
	font-weight: 600;
	line-height: 1.2;
	color: var(--p1-text);
	margin: 0 0 18px;
	padding: 0 36px 14px 0; /* right clearance for the close button */
	border-bottom: 1px solid var(--p1-border);
	position: relative;     /* anchors the ::after elevation strip below */
}
/* Pinned-title elevation (#14 R3, guide §5.7): the title stays put while
   the __body scrolls beneath it — once the body has scrolled, a soft
   shadow fades in under the hairline so the pinning reads as deliberate
   depth. .is-scrolled is toggled on the panel by p1-artwork.js (and by
   the style-guide demo script) at body scrollTop > 0; the shadow is an
   INSET top shadow on a 12px ::after band under the hairline, so opacity
   can transition and nothing bleeds above the divider. At rest there is
   NO shadow — the hairline alone divides. */
.p1-modal--page .p1-modal__title::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;              /* the band hangs just under the hairline */
	height: 12px;           /* matches the shadow's 12px blur reach */
	box-shadow: var(--p1-shadow-pinned);
	opacity: 0;
	transition: opacity .2s; /* standard duration (§3.4) */
	pointer-events: none;
}
.p1-modal--page.is-scrolled .p1-modal__title::after { opacity: 1; }
.p1-modal--page .p1-modal__body {
	max-height: 70vh;
	overflow-y: auto;
	margin-bottom: 0;
	padding-right: 16px;    /* scrollbar breathing room */
	text-align: left;
	font-size: 1.05rem;
	line-height: 1.7;
	color: var(--p1-text);
	--wp--preset--font-size--medium: 1.05rem; /* normalize preset drift to reading size */
}
/* The §5.7 reading grid (#14 R4): when the render-time transformer has
   built a detail rail, the body splits 2/3 text | 1/3 rail. Auto-placed
   grid, NOT a wrapper pair: every normal block is pinned to column 1
   (successive rows) and the rail spans the rows of column 2 — so below
   the breakpoint the grid simply reverts to block flow and the rail
   sits inline in DOCUMENT ORDER (after the bullets, before the gargoyle
   line on page 113). Never add row-gap here: block margins carry the
   vertical rhythm, and the rail's 32-row span would multiply any gap.
   No :has() support ⇒ no grid: the rail reads inline full-width there
   (same degradation family as the :has column rules it replaced). */
.p1-modal--page .p1-modal__body:has(> .p1-detail-rail) {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); /* "about 1/3" — the owner's split */
	column-gap: 24px;       /* reading-scope rhythm step (§3.1) */
}
.p1-modal--page .p1-modal__body:has(> .p1-detail-rail) > :not(.p1-detail-rail) { grid-column: 1; }
.p1-modal--page .p1-modal__body > .p1-detail-rail {
	grid-column: 2;
	grid-row: 1 / span 32;  /* "all the rows" — implicit grids can't 1/-1; empty rows are zero-height */
}
.p1-modal--page .p1-modal__body p { line-height: 1.7; }
.p1-modal--page .p1-modal__body p:empty,
.p1-modal--page .p1-modal__body .wp-block-group:empty { display: none; }
.p1-modal--page .p1-modal__body .wp-block-group { display: block; }
.p1-modal--page .p1-modal__body .wp-block-columns { gap: 24px; margin: 0 0 1.4em; }
.p1-modal--page .p1-modal__body .wp-block-column > figure { margin: 0; }
.p1-modal--page .p1-modal__body .wp-block-column > figure img { margin: 0; display: block; }
/* Embed group mat (#14 R2, item 3): an embed column block reads as ONE
   unit — its text + video share a warm mat (essay figure-caption idiom;
   same surface family as the submission well). Tokens carry dark mode. */
.p1-modal--page .p1-modal__body .wp-block-columns:has(figure.wp-block-embed) {
	display: block;
	background: var(--p1-surface-warm);
	border: 1px solid var(--p1-border-warm);
	border-radius: var(--p1-radius-md);
	padding: 20px;
}
.p1-modal--page .p1-modal__body .wp-block-columns:has(figure.wp-block-embed) .wp-block-column + .wp-block-column { margin-top: 16px; }
.p1-modal--page .p1-modal__body .wp-block-columns:has(figure.wp-block-embed) .wp-block-column > p:last-child { margin-bottom: 0; }
.p1-modal--page .p1-modal__body .wp-block-columns:has(figure.wp-block-embed) figure.wp-block-embed { margin: 0; }
.p1-modal--page .p1-modal__body figure.wp-block-embed iframe {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	border-radius: var(--p1-radius-sm);
}
@media (max-width: 600px) {
	/* Narrow columns can't afford a sidebar — back to block flow: the
	   rail sits inline in document order, its figures as centered
	   plates (mobile echo of the essay's full-bleed figure collapse).
	   Captions center with the plates (§5.5). */
	.p1-modal--page .p1-modal__body:has(> .p1-detail-rail) { display: block; }
	.p1-modal--page .p1-modal__body > .p1-detail-rail { margin: 0 0 1.35em; }
	.p1-modal--page .p1-modal__body > .p1-detail-rail figure.wp-block-image { max-width: 300px; margin: 0 auto; }
	.p1-modal--page .p1-modal__body > .p1-detail-rail figcaption { text-align: center; }
}

/* ── YouTube poster facade (.p1-yt-facade) ────────────────────────────
   Injected at render time by inc/performance.php (#14 item 4) in place
   of the medium page's oEmbed iframe, on both surfaces (the --page
   modal and /medium-and-technique/). Poster = hq1.jpg (a real in-video
   frame, #14 R3; filterable via p1_yt_facade_poster) with an onerror
   hqdefault fallback; object-fit:cover crops the hq-family's baked
   4:3 letterbox bars exactly. Sizing mirrors the embed
   iframe rule above (100%, 16:9, --p1-radius-sm). The poster img
   carries its own class so this recipe outranks the generic
   .p1-modal__body--content img rule by order at equal specificity —
   no !important. Relocated here from wp_add_inline_style (the Wave B2
   TEMPORARY block in inc/performance.php) per #14 item 4. */
.p1-yt-facade {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	cursor: pointer;
	overflow: hidden;
	background: #000;
	border-radius: var(--p1-radius-sm);
}
.p1-yt-facade img.p1-yt-facade__poster,
.p1-yt-facade iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	margin: 0;
	object-fit: cover;
}
.p1-yt-facade__play {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 64px;
	height: 64px;
	transform: translate(-50%, -50%);
	border-radius: 50%;
	background: rgba(0,0,0,.72);
	transition: background-color .2s ease;
	pointer-events: none;
}
.p1-yt-facade__play::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 55%;
	transform: translate(-50%, -50%);
	border-style: solid;
	border-width: 11px 0 11px 19px;
	border-color: transparent transparent transparent #fff;
}
.p1-yt-facade:hover .p1-yt-facade__play,
.p1-yt-facade:focus-visible .p1-yt-facade__play { background: var(--p1-accent); }
.p1-yt-facade:focus-visible { outline: 2px solid var(--p1-accent); outline-offset: 2px; }
.p1-yt-facade[data-p1-playing] .p1-yt-facade__play { display: none; }

/* ── Icon list (ul.p1-icon-list) — sketched bullet icons (guide §5.9) ──
   The site's first icon set: four hand-sketched line icons replacing the
   disc markers of the Medium & Technique bullets (48-unit viewBox,
   stroke 1.7, currentColor — dark mode inherits the body ink). The class
   + per-<li> inline SVGs are attached at RENDER TIME by
   inc/performance.php (p1_mt_icon_svgs + the 97-priority transformer);
   page 113's stored content is untouched. Renders in both §5.7 scopes
   (the --page modal body and .p1-page__content), hence this global home.
   Layout: icon left (absolutely positioned, centered on the row), text
   flowing beside with hanging alignment via the li's padding. NOT a
   grid/flex li: the bullets carry inline <em> children, and a grid or
   flex li promotes each of them to their own item, shattering the
   inline flow (caught on first render). */
ul.p1-icon-list {
	--p1-icon-size: 48px; /* prominent per owner ask ("2x"): 1 viewBox-unit per px — the size the set was drawn for (judged on both surfaces at 34/40/48/56, guide §5.9) */
	list-style: none;
	padding-inline-start: 0;
}
/* Supersedes the 24px popup list indent (§5.7) for THIS list only — the
   icon column carries the left rhythm; other popup lists keep their
   discs + indent. */
.p1-modal__body--content ul.p1-icon-list { padding-inline-start: 0; }
ul.p1-icon-list > li {
	position: relative;
	padding-left: calc(var(--p1-icon-size) + 16px);
	min-height: var(--p1-icon-size); /* single-line rows still clear the icon */
	align-content: center;           /* modern block centering; older engines top-align harmlessly */
}
ul.p1-icon-list > li + li { margin-top: 14px; }
.p1-icon-list__icon {
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	width: var(--p1-icon-size);
	height: var(--p1-icon-size);
	opacity: .85; /* the sketch reads a touch lighter than the text ink (preview idiom) */
}
@media (max-width: 600px) {
	ul.p1-icon-list { --p1-icon-size: 40px; } /* narrow columns keep a readable measure beside the icon */
}

/* Login stub form (header Login modal — needs-decision, §6 #10).
   Not a Gravity Form; styled standalone so it can't collide with the
   modal GF skin. Values preserved from the pre-merge header skin. */
.p1-dummy-login-form label { font-size: 0.85rem; font-weight: 600; color: #333; margin-bottom: 8px; display: block; text-align: left; }
.p1-dummy-login-form input[type="email"], .p1-dummy-login-form input[type="password"] {
	width: 100%; padding: 12px; border: 1px solid var(--p1-border-input); border-radius: var(--p1-radius-sm); font-family: inherit; font-size: 0.9rem;
	-webkit-appearance: none; appearance: none;
}
.p1-dummy-login-form button[type="submit"] {
	width: 100%; padding: 14px; margin-top: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.85rem; cursor: pointer;
	-webkit-appearance: none; appearance: none;
}

/* ── Shared heading font ─────────────────────────────────────────── */
h1, h2, h3 {
	font-family: 'Cormorant Garamond', Georgia, serif;
	font-weight: 400;
}

/* ── Site Footer ─────────────────────────────────────────────────── */
.p1-site-footer {
	background: #111;
	padding: 56px 40px 40px;
	margin-top: 80px;
	position: relative;
	z-index: 200;
	view-transition-name: p1-main-footer;
}
.p1-site-footer__inner {
	max-width: 1280px;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 20px;
	text-align: center;
}
.p1-site-footer__logo {
	text-decoration: none;
	display: flex;
	flex-direction: column;
	align-items: center;
	line-height: 1;
	gap: 2px;
	margin-bottom: 4px;
}
.p1-site-footer__logo-first {
	font-family: 'Cormorant Garamond', Georgia, serif;
	font-weight: 300;
	font-size: 0.65rem;
	color: #aaa;
	text-transform: uppercase;
	letter-spacing: 0.45em;
}
.p1-site-footer__logo-last {
	font-family: 'Cormorant Garamond', Georgia, serif;
	font-weight: 600;
	font-size: 1.3rem;
	color: #eee;
	letter-spacing: 0.2em;
	text-transform: uppercase;
}
.p1-site-footer__nav {
	display: flex;
	align-items: center;
	gap: 16px;
	font-size: 0.75rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
}
.p1-site-footer__nav a {
	color: #aaa;
	text-decoration: none;
	transition: color 0.2s;
	text-underline-offset: 3px;
}
.p1-site-footer__nav a:hover { color: #fff; text-decoration: underline; }
.p1-site-footer__nav span { color: #888; }
.p1-site-footer__copy {
	font-size: 0.7rem;
	color: #888;
	letter-spacing: 0.08em;
}

/* ── Button family (.p1-btn) ─────────────────────────────────────────
   Moved here from p1-artwork.css 2026-07-19 (Wave B1): buttons render on
   archive/series/end/magic-link pages where p1-artwork.css never loads —
   those templates carried drifted redefinitions (STYLE-GUIDE §6 #4).
   The --grey (suggestion submit) variant stays in p1-artwork.css, coupled
   to the ghost form. Dark inversions live in the html.dark block below. */
.p1-btn { display: inline-block; padding: 11px 22px; border-radius: var(--p1-radius-sm); text-decoration: none; font-size: .9rem; font-family: inherit; cursor: pointer; transition: background .1s, color .1s, border-color .1s; border: 2px solid transparent; }
.p1-btn--outline  { border-color: #222; color: #222; background: transparent; }
.p1-btn--outline:hover { background: #222; color: #fff; }

.p1-btn--subtle-outline { background: transparent; color: #999; border: 1px solid var(--p1-border); }
.p1-btn--subtle-outline:hover, .p1-btn--subtle-outline:focus { background: transparent; color: #666; border-color: var(--p1-border-input); }
.p1-btn--primary  { background: #222; color: #fff; border-color: #222; }
.p1-btn--primary:hover { background: #444; border-color: #444; }

/* ── Floating nav island ─────────────────────────────────────────────
   Moved here from p1-artwork.css 2026-07-19 (Wave B1): the island also
   renders on /end/, which previously re-hardcoded it inline. */
.p1-floating-nav {
	position: fixed;
	bottom: 30px;
	right: 30px;
	display: flex;
	gap: 10px;
	z-index: 9990;
	background: var(--p1-glass-bg);
	padding: 10px;
	border-radius: var(--p1-radius-pill);
	box-shadow: 0 10px 30px rgba(0,0,0,0.1);
	backdrop-filter: blur(10px);
	border: 1px solid var(--p1-glass-border);
}
.p1-floating-nav .p1-btn {
	border-radius: var(--p1-radius-pill);
	padding: 10px 20px;
}
/* Center "All" gallery link (issue #17): icon+label anchor between the pills.
   Rides .p1-btn--subtle-outline (the island's quiet tier), so hover/dark come
   from the button family; the glyph inherits currentColor. Slightly tighter
   padding than the pills — icon+short label — keeps the island one line at 375px. */
.p1-floating-nav .p1-floating-nav__all {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 10px 16px;
}
.p1-floating-nav__all svg { display: block; flex: none; }

/* ── Masonry grid (artwork archive + series singles) ─────────────────
   Single source since 2026-07-19 (Wave B1) — was duplicated with drift in
   archive-artwork.php and single-series.php (STYLE-GUIDE §6 #4). The
   archive definition won every drift: transparent item bg, inline-block
   items, 16px gaps. Templates keep only page-unique pieces (archive:
   contact tile + filter bar; series: grid bottom margin). */
.p1-masonry {
	column-count: 4;
	column-gap: 16px;
}
@media (max-width: 1100px) { .p1-masonry { column-count: 3; } }
@media (max-width: 700px)  { .p1-masonry { column-count: 2; } }
@media (max-width: 420px)  { .p1-masonry { column-count: 1; } }

.p1-masonry-item {
	display: inline-block;
	width: 100%;
	vertical-align: top;
	break-inside: avoid;
	margin-bottom: 16px;
	text-decoration: none;
	color: inherit;
	border-radius: var(--p1-radius-md); /* was 6px in both copies — nudged to the scale (§3.2) */
	overflow: hidden;
	background: transparent; /* series copy had #f5f5f5 — archive value wins */
	transition: transform .2s, box-shadow .2s;
}
.p1-masonry-item:hover { transform: translateY(-3px); }
.p1-masonry-item[hidden] { display: none; }

/* Artwork-only archive feedback. The contact tile is prose/CTA, not artwork
   imagery, and series grids keep their existing treatment. Glow is a paint-only
   box-shadow, so hover/current/focus never change card geometry. */
.p1-archive-artwork .p1-masonry-item:not(.p1-masonry-item--contact):is(:hover, :focus-visible) {
	position: relative;
	z-index: 5;
	box-shadow: var(--p1-glow-artwork-interactive);
}
.p1-archive-artwork .p1-masonry-item:not(.p1-masonry-item--contact):focus-visible {
	outline: 2px solid var(--p1-accent);
	outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
	.p1-archive-artwork .p1-masonry-item { transition: none; }
}

/* Padding-bottom trick keeps natural ratio before img loads */
.p1-masonry-item__img-wrap {
	position: relative;
	width: 100%;
	overflow: hidden;
}
.p1-masonry-item__img-wrap img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.p1-masonry-item__no-img {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #bbb;
	font-size: .85rem;
}
.p1-masonry-item__meta  { padding: 10px 12px 12px; }
.p1-masonry-item__title { font-size: .95rem; font-weight: 600; line-height: 1.3; }
.p1-masonry-item__series{ font-size: .78rem; color: #888; margin-top: 3px; }

/* ── Gravity Forms — house base skin ─────────────────────────────────
   ONE tokened base under every gform context (STYLE-GUIDE §5.4 / §6 #7):
   remaps the GF "Orbital" palette (#204ce5 electric blue) onto the house
   accent tokens via GF's own custom-property system, so focus rings,
   spinners, choice controls and unskinned submits brand themselves in
   both modes. The six per-context skins stay as refinements on top.
   !important is REQUIRED here and sets VARIABLES ONLY: GF prints a
   per-form inline <style> re-declaring the Orbital palette at ID
   specificity (#gform_wrapper_NNN[data-form-index].gform-theme), which no
   class selector can outrank. This is the one sanctioned !important
   exception outside the legacy dark rescues — see STYLE-GUIDE §5.4. */
.gform_wrapper.gform-theme,
[data-parent-form] {
	--gf-color-primary: var(--p1-accent) !important;
	--gf-color-primary-rgb: var(--p1-accent-rgb) !important;
	--gf-color-primary-contrast: var(--p1-bg) !important;
	--gf-color-primary-contrast-rgb: var(--p1-bg-rgb) !important;
	--gf-color-primary-darker: var(--p1-accent-soft) !important;
	--gf-color-primary-lighter: var(--p1-accent-soft) !important;
}
/* GF confirmation convention (Cormorant italic, success green) rides the
   status token so dark mode is automatic — contexts opt in (§5.4). */

/* ── Dark Mode ───────────────────────────────────────────────────────
   Token OVERRIDES only — the light palette in :root (top of file) is
   canonical. Component rules below are legacy !important rescues that
   fight inline styles; do not add new ones (see STYLE-GUIDE §5.6). */
html.dark {
	--p1-bg: #1a1a1a;
	--p1-text: #eaeaea;
	--p1-text-strong-muted: #d7d7d7; /* ink↔muted midpoint, dark half (12.1:1 on #1a1a1a) */
	--p1-text-muted: #c4c4c4;   /* was #999 — re-anchored to the a11y pair (#565656/#c4c4c4) */
	--p1-text-subtle: #999;
	--p1-border: #2a2a2a;
	--p1-border-warm: #2a2a2a;  /* warm hairlines flatten to neutral in dark */
	--p1-border-input: #444;
	--p1-surface: #222;
	--p1-surface-warm: #0a0a0a;
	--p1-glass-bg: rgba(26,26,26,0.92);
	--p1-glass-border: #333;
	--p1-accent: #9DB2CE;       /* essay slate-blue, dark half */
	--p1-accent-rgb: 157, 178, 206;
	--p1-accent-soft: #7E93B0;
	--p1-glow-artwork-interactive: 0 0 0 1px rgba(var(--p1-accent-rgb), .34), 0 0 16px rgba(var(--p1-accent-rgb), .24), 0 0 36px rgba(var(--p1-accent-rgb), .12);
	--p1-bg-rgb: 26, 26, 26;
	--p1-error: #e57373;        /* dark error — mirrors the success 800→300 lightening */
	--p1-success: #81c784;      /* dark success (was hardcoded per-context) */
	--p1-shadow-pinned: inset 0 10px 12px -10px rgba(0,0,0,.8); /* dark shadows need much higher alpha to read on #1a1a1a (header idiom: .05→.4); .8 yields a just-visible band */

	/* Header & Nav */
	.p1-site-header { background: var(--p1-bg); border-bottom-color: var(--p1-border); box-shadow: 0 4px 20px rgba(0,0,0,0.4); }
	.p1-logo__last { color: var(--p1-text); }
	.p1-nav__link { color: #ccc !important; }
	.p1-nav__link:hover, .p1-nav__link--active { color: #fff !important; }

	.p1-header-login-btn { color: #888; }
	.p1-header-login-btn:hover { color: #fff; }
	.p1-header-updates-btn { color: #ccc; border-color: #444; }
	.p1-header-updates-btn:hover { color: #fff; border-color: #666; background: #222; }

	/* Burger & Mobile Nav */
	.p1-nav__burger span { background: #eaeaea !important; }

	/* Single Artwork */
	.p1-artwork-specs dt { color: #888; }
	.p1-artwork-specs dd { color: #ccc; }
	.p1-artwork-specs, .p1-artwork-specs__item { border-color: var(--p1-border); }
	.p1-btn--outline, .p1-btn--subtle-outline { background: #222 !important; color: #eaeaea !important; border-color: #444 !important; }
	.p1-btn--outline:hover, .p1-btn--subtle-outline:hover { background: #333 !important; color: #fff !important; border-color: #666 !important; }
	.p1-btn--primary { background: #eee; color: #111; border-color: #eee; }
	.p1-btn--primary:hover { background: #fff; border-color: #fff; }
	/* Modals (one system since Wave C — the former .p1-header-modal
	   rescues are gone: __desc and close-hover now ride the tokens, and
	   the old `.p1-header-modal button` background rescue also hit the
	   close button — the stray light disc in dark header modals). */
	.p1-modal { background: #1a1a1a !important; border: 1px solid var(--p1-border) !important; color: #eaeaea !important; }
	.p1-modal__title { color: #fff !important; }
	.p1-modal__close { color: #fff !important; }
	.p1-modal .gform_wrapper *, .p1-modal .gfield_label, .p1-dummy-login-form label { color: #eaeaea !important; }
	.p1-dummy-login-form input[type="email"], .p1-dummy-login-form input[type="password"] { background: #222 !important; color: #fff !important; border-color: #444 !important; }
	.p1-dummy-login-form button[type="submit"] { background: #eaeaea !important; color: #111 !important; border: none !important; }
	.p1-dummy-login-form button[type="submit"]:hover { background: #fff !important; }

	/* (Post-vote thank-you rescues removed 2026-07-19, Wave B1 — the
	   thank-you UI is now class-based and tokened in p1-artwork.css,
	   no !important needed. STYLE-GUIDE §6 #3.) */
	.p1-modal .gform_wrapper input[type="text"],
	.p1-modal .gform_wrapper input[type="email"],
	.p1-modal .gform_wrapper input[type="tel"],
	.p1-modal .gform_wrapper textarea {
		background: #222 !important;
		color: #fff !important;
		border-color: #444 !important;
	}
	.p1-modal .gform_wrapper input[type="submit"],
	.p1-modal .gform_wrapper button[type="submit"] {
		background: #eee !important;
		color: #111 !important;
	}
	.p1-btn--grey { background: #222 !important; color: #ddd !important; border-color: #333 !important; }

	/* End Page & Forms */
	.p1-end-form-wrapper { background: #1a1a1a !important; border-color: var(--p1-border) !important; color: #fff !important; }
	.p1-end-form-wrapper .gform_wrapper *, .p1-end-form-wrapper .gfield_label, .p1-end-form-wrapper .gfield_description { color: #eaeaea !important; }
	.p1-end-form-wrapper .gform_wrapper input[type="submit"], .p1-end-form-wrapper .gform_wrapper button[type="submit"] { background: #eaeaea !important; color: #111 !important; font-weight: 600 !important; text-transform: uppercase !important; letter-spacing: 0.1em !important; border-radius: var(--p1-radius-sm) !important; border: none !important; }
	.p1-end-form-wrapper .gform_wrapper input[type="submit"]:hover, .p1-end-form-wrapper .gform_wrapper button[type="submit"]:hover { background: #fff !important; }
	.p1-inquire-page .gform_wrapper input[type="submit"], .p1-inquire-page .gform_wrapper button[type="submit"] { background: #eaeaea !important; color: #111 !important; }
	.p1-inquire-page .gform_wrapper input[type="submit"]:hover, .p1-inquire-page .gform_wrapper button[type="submit"]:hover { background: #fff !important; }
	.p1-inquire-page .gform_confirmation_message { background: #1a1a1a !important; color: #eaeaea !important; border-color: #333 !important; }
	input[type="text"], input[type="email"], input[type="tel"], textarea, select {
		background-color: #1a1a1a !important;
		color: #eee !important;
		border-color: #333 !important;
	}

	/* Protect Titles & Descriptions form from global dark overrides */
	.p1-artwork-title-form-wrapper input[type="text"] {
		background-color: transparent !important;
		color: #eaeaea !important;
		border-color: transparent !important;
		border-bottom-color: #444 !important;
	}
	.p1-artwork-title-form-wrapper input[type="text"]:focus {
		border-bottom-color: #fff !important;
	}
	.p1-artwork-title-form-wrapper textarea {
		background-color: transparent !important;
		color: #eee !important;
		border: none !important;
		border-bottom: 2px dashed #555 !important;
		box-shadow: none !important;
		outline: none !important;
	}
	.p1-artwork-title-form-wrapper textarea:focus {
		border-bottom-color: #fff !important;
	}
	.p1-artwork-title-form-wrapper input[type="text"]::placeholder,
	.p1-artwork-title-form-wrapper textarea::placeholder { color: var(--p1-text-subtle) !important; font-style: italic !important; opacity: 1 !important; }

	/* (Voting accordion rescues removed 2026-07-19, Wave B1 — entries are
	   class-based and tokened in p1-artwork.css; the .p1-submissions-* and
	   .p1-entry-meta selectors had no emitting markup at all.) */

	/* SPA Overlay Mask */
	#p1-spa-overlay { background: var(--p1-bg) !important; }

	/* Floating Nav Island & Submits */
	.p1-floating-nav { background: rgba(30,30,30,0.92) !important; border-color: rgba(255,255,255,0.05) !important; box-shadow: 0 10px 30px rgba(0,0,0,0.5) !important; }
	.p1-artwork-title-form-wrapper input[type="submit"], .p1-artwork-title-form-wrapper button[type="submit"] { background: #222 !important; color: #fff !important; border: 1px solid #444 !important; }

	/* Footer */
	.p1-site-footer { border-top-color: var(--p1-border); }
	.p1-site-footer__logo-last { color: var(--p1-text); }

	/* Icons */
	.p1-sun-icon { display: block !important; }
	.p1-moon-icon { display: none !important; }
}

@media (max-width: 820px) {
	html.dark .p1-nav__list { background: #1a1a1a !important; }
}
