/*
 * Orange Pacific Mental Health — global design system: "Dawn Horizon".
 *
 * Hand-authored (no build step). Enqueued on the front end AND inside the block
 * editor (add_editor_style), so blocks look identical in both. Per-block
 * style.scss files consume the --op-* custom properties below.
 *
 * PALETTE PROVENANCE: sampled from the client's own logo mark (a sun setting
 * over three stacked ocean waves) plus their live site chrome — not invented.
 *   #002848  wordmark + header nav   -> navy
 *   #0070A8  the wave bands          -> azure
 *   #F89808 / #F8C008  the sun disc  -> sun / gold
 *   #FECE8B  live header background  -> apricot
 *   #FEF7E8  live hero headline      -> cream
 * The live Squarespace site uses only navy, apricot and cream. The azure and
 * the saturated amber are already in the mark and are put back to work here.
 *
 * ACCESSIBILITY, BAKED INTO THE TOKENS RATHER THAN LEFT TO JUDGEMENT:
 *  - --op-apricot is a SURFACE ONLY, never a text colour. Apricot buttons
 *    always carry navy labels (10.3:1).
 *  - --op-ember-700 is the text-safe warm tone on cream (5.0:1). Reach for it
 *    instead of --op-sun-500 whenever the warm colour is carrying words.
 *  - Body line-height 1.7 and a 68ch measure. This site is read by anxious and
 *    distracted people; comfortable reading is a feature, not a nicety.
 *
 * NAMING: the design's own tokens were already --op-* prefixed, which is the
 * prefix this theme uses, so they ported across unchanged. The design's
 * UNPREFIXED tokens (--font-body, --step-0, --sp-m, --wrap, --radius-m, --ease)
 * were prefixed on the way in — unprefixed custom properties share a global
 * scope with WordPress core and every plugin, and the collision shows up as a
 * style that changes when an unrelated plugin is activated.
 */

:root {
	/* --- Ground and surfaces ------------------------------------------- */
	--op-cream: #fef7e8;
	--op-surface: #fffcf4;
	--op-sand: #f4e7cd;
	--op-sand-deep: #e8d5b0;

	/* --- Ocean ramp ---------------------------------------------------- */
	--op-navy-900: #002848;
	--op-navy-800: #013352;
	--op-navy-700: #013a63;
	--op-dusk-800: #123a63;
	--op-azure-600: #0070a8;
	--op-azure-500: #1f86bc;
	--op-azure-300: #8fc4e2;
	--op-azure-100: #dcedf7;

	/* --- Sun ramp ------------------------------------------------------ */
	--op-sun-500: #f89808;
	--op-sun-400: #f8c008;
	--op-apricot: #fece8b;
	--op-apricot-100: #ffe7c4;
	--op-ember-700: #a85210; /* AA-safe warm TEXT on cream. */

	/* --- Text ---------------------------------------------------------- */
	--op-ink: var(--op-navy-900);
	--op-ink-muted: #4a5c6b;
	--op-ink-on-dark: var(--op-cream);
	--op-ink-on-dark-muted: #b9cedd;

	/* --- The signature gradients --------------------------------------- */
	/* Night to dawn, left to right. Drives the sun scroll rule and the top
	   rule of each state panel, so a row of panels reads as one dawn. */
	--op-horizon: linear-gradient(
		90deg,
		#002848 0%,
		#123a63 22%,
		#0070a8 40%,
		#a85210 60%,
		#f89808 78%,
		#f8c008 90%,
		#fece8b 100%
	);
	/* The sun itself, exactly as it appears in the logo. */
	--op-sundisc: linear-gradient(180deg, #f89808 0%, #f8c008 100%);

	/* --- The local accent, one slice of the dawn ------------------------
	   A location page takes the SAME quarter of --op-horizon that its state
	   panel occupies on the homepage, so the four location pages read as
	   siblings rather than as one layout recoloured four times. Set per block
	   by the `state` attribute (see .op-loc--* below); these are the fallback,
	   the ocean end, used by any block that has no state chosen yet. */
	--op-local-grad: linear-gradient(90deg, var(--op-navy-900) 0%, var(--op-azure-600) 100%);
	--op-local-ink: var(--op-azure-600);
	--op-local-wash: var(--op-azure-100);
	--op-local-edge: var(--op-azure-300);
	/* Display-scale accent, for the one place the local colour runs large: the
	   city name in the H1. It follows --op-local-ink unless a slice overrides
	   it, which only Washington needs to — see the note there. */
	--op-local-display: var(--op-local-ink);

	/* --- Type ---------------------------------------------------------- */
	/* Petrona (warm humanist serif) for display, Hanken Grotesk (warm humanist
	   sans) for body and UI. Loaded in inc/enqueue.php AND named in theme.json
	   — theme.json is not optional, see the note there. */
	--op-font-display: "Petrona", Georgia, "Times New Roman", serif;
	--op-font-body: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
	--op-font-spec: var(--op-font-body);

	/* Fluid type scale. */
	--op-step--1: clamp(0.84rem, 0.8rem + 0.18vw, 0.94rem);
	--op-step-0: clamp(1.03rem, 0.98rem + 0.24vw, 1.19rem);
	--op-step-1: clamp(1.24rem, 1.15rem + 0.42vw, 1.55rem);
	--op-step-2: clamp(1.49rem, 1.33rem + 0.75vw, 2.05rem);
	--op-step-3: clamp(1.79rem, 1.53rem + 1.24vw, 2.7rem);
	--op-step-4: clamp(2.15rem, 1.73rem + 2vw, 3.58rem);
	--op-step-5: clamp(2.58rem, 1.9rem + 3.15vw, 4.72rem);

	/* --- Space --------------------------------------------------------- */
	--op-sp-2xs: 0.375rem;
	--op-sp-xs: 0.625rem;
	--op-sp-s: 1rem;
	--op-sp-m: 1.5rem;
	--op-sp-l: 2.25rem;
	--op-sp-xl: 3.5rem;
	--op-sp-2xl: 5.5rem;

	/* --- Layout -------------------------------------------------------- */
	--op-measure: 68ch;
	--op-wrap: 1200px;
	--op-wrap-narrow: 900px;
	--op-gutter: 1.25rem;

	/* Sticky header height. Anchor targets clear it via scroll-padding-top on
	   <html>, so an in-page jump never lands with its heading under the bar. */
	--op-header-h: 6rem;

	/* Scrollbar width, published by theme.js for full-bleed alignment. */
	--op-sbw: 0px;

	/* --- Radii. One of the loudest signals a design gives off. Dawn Horizon
	   is soft and rounded: pill buttons, generous card corners. --- */
	--op-r-sm: 8px;
	--op-r-md: 16px;
	--op-r-lg: 28px;
	--op-r-pill: 999px;

	/* --- Elevation and motion ------------------------------------------ */
	--op-shadow-lift: 0 1px 2px rgba(0, 40, 72, 0.05), 0 8px 24px -12px rgba(0, 40, 72, 0.18);
	--op-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

	/* --- Semantic aliases ----------------------------------------------
	   The theme's chrome, style.css's .opmh-container, inc/partials.php's
	   background allowlist and the editor's background picker all resolve
	   through these names. They are mapped onto the Dawn Horizon palette
	   rather than duplicated, so there is still exactly one source of truth
	   per colour. Keep the names; change what they point at. */
	--op-paper: var(--op-cream);
	--op-tint: var(--op-surface);
	--op-dark: var(--op-navy-800);
	--op-dark-deep: var(--op-navy-900);
	--op-line: var(--op-sand-deep);
	--op-white: #ffffff;
	--op-accent: var(--op-sun-500); /* accent for FILLS, rules and icons */
	--op-accent-ink: var(--op-ember-700); /* accent TEXT on light surfaces */
	--op-bg: var(--op-cream);
	--op-border: var(--op-sand-deep);
	--op-text: var(--op-ink);
	--op-muted: var(--op-ink-muted);
	--op-ink-soft: var(--op-ink-muted); /* used by editor.css */
	--op-dark-line: rgba(254, 247, 232, 0.22); /* borders on dark, editor.css */
	--op-primary: var(--op-azure-600);
	--op-container: var(--op-wrap);
	--op-pad: var(--op-gutter);
	--op-grad-accent: var(--op-sundisc);
}

/* ==========================================================================
   Base reset. WordPress ships NONE of this on the front end, and the absence
   reads as a mobile layout bug rather than a missing reset (SETUP §9).
   ========================================================================== */

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

html {
	scroll-behavior: smooth;
	/* Clears the sticky header when jumping to an anchor. */
	scroll-padding-top: var(--op-header-h);
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--op-cream);
	color: var(--op-ink);
	font-family: var(--op-font-body);
	font-size: var(--op-step-0);
	line-height: 1.7;
	font-weight: 400;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	/* clip, NOT hidden. `hidden` makes <body> a scroll container, which breaks
	   position: sticky on the header. The mockup used `hidden` and got away
	   with it; this theme's header is sticky, so it would not. */
	overflow-x: clip;
}

h1,
h2,
h3,
h4 {
	font-family: var(--op-font-display);
	font-weight: 500;
	line-height: 1.12;
	letter-spacing: -0.015em;
	margin: 0;
	text-wrap: balance;
}

h1 {
	font-size: var(--op-step-5);
}

h2 {
	font-size: var(--op-step-4);
}

h3 {
	font-size: var(--op-step-2);
}

h4 {
	font-size: var(--op-step-1);
}

p {
	margin: 0;
	max-width: var(--op-measure);
	text-wrap: pretty;
}

a {
	color: var(--op-azure-600);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

a:hover {
	color: var(--op-navy-900);
}

img {
	max-width: 100%;
	display: block;
	height: auto;
}

ul {
	margin: 0;
	padding: 0;
}

/* Form controls don't inherit font-family from body — force it, or an unstyled
   button renders in the user-agent font beside correctly-set prose. */
button,
input,
select,
textarea,
optgroup {
	font-family: inherit;
}

:focus-visible {
	outline: 3px solid var(--op-azure-600);
	outline-offset: 3px;
	border-radius: 3px;
}

::selection {
	background: var(--op-apricot);
	color: var(--op-navy-900);
}

/* Locks page scroll while the mobile nav is open (set by theme.js). */
.op-no-scroll {
	overflow: hidden;
}

/* ==========================================================================
   Utilities
   ========================================================================== */

/* Skip link — visible only when focused. Keyboard users land here first. */
.op-skip {
	position: absolute;
	left: var(--op-sp-s);
	top: -100px;
	z-index: 200;
	background: var(--op-navy-900);
	color: var(--op-cream);
	padding: var(--op-sp-xs) var(--op-sp-m);
	border-radius: var(--op-r-sm);
	font-weight: 600;
	text-decoration: none;
	transition: top 0.2s var(--op-ease);
}

.op-skip:focus {
	top: var(--op-sp-s);
	color: var(--op-cream);
}

.op-vh {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.op-container {
	width: min(100% - (var(--op-gutter) * 2), var(--op-wrap));
	margin-inline: auto;
}

.op-container--narrow {
	--op-wrap: var(--op-wrap-narrow);
}

.op-section {
	padding-block: var(--op-sp-2xl);
	position: relative;
}

.op-section--tight {
	padding-block: var(--op-sp-xl);
}

/* Used where a wave divider already supplies the visual break above/below, so
   the section must not add a second one. */
.op-section--after-wave {
	padding-block: var(--op-sp-xl);
}

.op-shead {
	max-width: 62ch;
	margin-bottom: var(--op-sp-xl);
}

.op-shead p {
	margin-top: var(--op-sp-s);
	color: var(--op-ink-muted);
	font-size: var(--op-step-1);
}

/* An eyebrow with no heading after it shouldn't carry the heading's bottom
   margin, and a heading with no lede shouldn't either. */
.op-shead > :last-child {
	margin-bottom: 0;
}

.op-grid {
	display: grid;
	gap: var(--op-sp-m);
}

.op-grid--3 {
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.op-grid--2 {
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* ==========================================================================
   Section backgrounds. A block's `background` attribute resolves to one of
   these, validated against a PHP allowlist before it reaches a class name
   (inc/partials.php → opmh_section_bg).
   ========================================================================== */

.op-section--paper {
	background: var(--op-cream);
}

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

.op-section--sand {
	background: var(--op-sand);
}

.op-section--dark {
	background: var(--op-navy-800);
	color: var(--op-ink-on-dark);
}

.op-section--dark-deep {
	background: var(--op-navy-900);
	color: var(--op-ink-on-dark);
}

.op-section--dark h2,
.op-section--dark h3,
.op-section--dark h4,
.op-section--dark-deep h2,
.op-section--dark-deep h3,
.op-section--dark-deep h4 {
	color: var(--op-cream);
}

.op-section--dark p,
.op-section--dark-deep p {
	color: var(--op-ink-on-dark-muted);
}

/* ==========================================================================
   Shared text helpers
   ========================================================================== */

/* Eyebrow: a small sun disc, then SENTENCE-CASE text. Deliberately not the
   tracked-uppercase eyebrow used on other King Tide properties — the disc is
   the logo's sun, and the whole point is that this brand doesn't read like the
   others. Don't "fix" it to uppercase. */
.op-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.55em;
	font-family: var(--op-font-body);
	font-size: var(--op-step--1);
	font-weight: 600;
	color: var(--op-ember-700);
	margin: 0 0 var(--op-sp-s);
}

.op-eyebrow::before {
	content: "";
	width: 0.72em;
	height: 0.72em;
	border-radius: 50%;
	background: var(--op-sundisc);
	flex: none;
}

.op-eyebrow--on-dark {
	color: var(--op-apricot);
}

.op-lede {
	font-size: var(--op-step-1);
	color: var(--op-ink-muted);
	max-width: var(--op-measure);
	margin: 0;
}

.op-section--dark .op-lede,
.op-section--dark-deep .op-lede {
	color: var(--op-ink-on-dark-muted);
}

.op-rule {
	height: 1px;
	background: var(--op-sand-deep);
	border: 0;
	margin: 0;
}

/* A short label pinned to unfinished content, so a placeholder can never be
   mistaken for shipped copy. Removed as each item is filled in. */
.op-placeholder-tag {
	display: inline-block;
	font-family: var(--op-font-body);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--op-ember-700);
	background: var(--op-apricot-100);
	border-radius: var(--op-r-pill);
	padding: 0.25em 0.8em;
	margin-bottom: var(--op-sp-xs);
}

/* ==========================================================================
   Plan pills. Styled HERE rather than in the insurance block, because the
   services block lists the same plans inside a card on the location pages —
   and a block's stylesheet only loads when that block is on the page.
   ========================================================================== */

.op-plans {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: var(--op-sp-2xs);
	margin: 0;
	padding: 0;
}

.op-plans li {
	background: var(--op-surface);
	border: 1px solid var(--op-sand);
	border-radius: var(--op-r-sm);
	padding: 0.5em 0.9em;
	font-size: 0.92rem;
	font-weight: 500;
}

/* Inside a card the pills are a supporting detail, not the section's subject,
   so they run smaller. Same system, lower volume. */
.op-plans--tight {
	margin-top: var(--op-sp-m);
}

.op-plans--tight li {
	font-size: 0.85rem;
	padding: 0.35em 0.7em;
}

/* ==========================================================================
   Numbered step cards. Moved HERE from the steps block for the same reason as
   .op-plans above it: the NAP block renders the booking sequence in its right
   column on the service-area pages, and a block's stylesheet only loads when
   that block is on the page.

   A real <ol> with a CSS counter, because this IS a sequence. The numbers come
   from counter() rather than being typed, so reordering renumbers them
   automatically and they can never disagree.
   ========================================================================== */

.op-steps {
	list-style: none;
	display: grid;
	gap: var(--op-sp-m);
	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
	counter-reset: step;
	margin: 0;
	padding: 0;
}

.op-step {
	counter-increment: step;
	background: var(--op-surface);
	border: 1px solid var(--op-sand);
	border-radius: var(--op-r-md);
	padding: var(--op-sp-l);
	position: relative;
}

.op-step::before {
	content: counter(step);
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border-radius: 50%;
	background: var(--op-sundisc);
	color: var(--op-navy-900);
	font-family: var(--op-font-body);
	font-size: 0.9rem;
	font-weight: 700;
	margin-bottom: var(--op-sp-m);
}

.op-step h3 {
	font-size: var(--op-step-1);
	margin-bottom: var(--op-sp-2xs);
}

.op-step p {
	color: var(--op-ink-muted);
	font-size: 0.97rem;
}

/* A short marker inside a step for the part that is not usable yet — the
   booking route nobody has explained, say. Same voice as .op-placeholder-tag
   but inline, under the copy it qualifies. */
.op-step__note {
	display: block;
	margin-top: var(--op-sp-2xs);
	font-size: var(--op-step--1);
	font-style: italic;
	color: var(--op-local-ink);
}

/* ==========================================================================
   Callouts. Moved HERE from the prose block: the signature band blocks
   (daybar, route, calendar) set the same local-note asides beside their
   graphics, and a block's stylesheet only loads when that block is on the
   page.

   Two variants carry meaning, not decoration. 'note' is the paragraph that
   has to be true of THIS place and nowhere else; 'limit' is where the service
   stops.
   ========================================================================== */

.op-callout__label {
	display: block;
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	margin-bottom: var(--op-sp-xs);
}

.op-callout p {
	margin: 0;
}

/* The local note ON A DARK BAND: an apricot edge, no fill, cream copy set
   larger — the loudest thing in its section. */
.op-callout--note {
	border-left: 3px solid var(--op-apricot);
	padding-left: var(--op-sp-m);
}

.op-callout--note .op-callout__label {
	color: var(--op-apricot);
}

/* The local note ON A LIGHT SECTION. Apricot fails contrast on cream, so the
   light variant takes the page's own local accent instead, and the copy runs
   navy at the same larger size. Emitted by the server when the section's
   background is light, so the two variants can never be hand-mismatched. */
.op-callout--light {
	border-left-color: var(--op-local-edge);
}

.op-callout--light .op-callout__label {
	color: var(--op-local-ink);
}

.op-callout--light p {
	font-size: var(--op-step-1);
	line-height: 1.55;
	color: var(--op-navy-900);
}

/* Where we stop: a plain sand panel. Deliberately quiet — an alarming
   treatment would read as a warning rather than as candour. */
.op-callout--limit {
	background: var(--op-sand);
	border-radius: var(--op-r-md);
	padding: var(--op-sp-l);
}

.op-callout--limit .op-callout__label {
	color: var(--op-local-ink);
}

.op-callout--limit p {
	color: #4a3a22;
	font-size: 0.97rem;
}

/* On the deep band the note is set larger and in cream. */
.op-section--dark .op-callout--note p,
.op-section--dark-deep .op-callout--note p {
	color: var(--op-cream);
	font-size: var(--op-step-1);
	line-height: 1.55;
}

/* The label treatment of .op-callout__label, standing on its own above a
   graphic rather than heading a note. */
.op-band-label {
	display: block;
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--op-apricot);
	margin-bottom: var(--op-sp-xs);
}

/* ==========================================================================
   Buttons. Styled HERE, not in any block's style.scss — the header, hero,
   how-it-works and closing CTA all need the same skin.

   Specificity note (SETUP §9): variants are written .op-btn.op-btn--x so that
   a later `padding` shorthand can't silently beat an earlier `padding-inline`
   when someone re-sorts this file.
   ========================================================================== */

.op-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.55em;
	padding: 0.85em 1.6em;
	border-radius: var(--op-r-pill);
	font-family: var(--op-font-body);
	font-size: var(--op-step-0);
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	border: 1.5px solid transparent;
	cursor: pointer;
	transition: transform 0.18s var(--op-ease), box-shadow 0.18s var(--op-ease),
		background-color 0.18s var(--op-ease), color 0.18s var(--op-ease);
}

.op-btn:hover {
	transform: translateY(-2px);
}

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

/* Apricot is a surface, never a text colour. Labels stay navy — 10.3:1. */
.op-btn.op-btn--primary {
	background: var(--op-apricot);
	color: var(--op-navy-900);
	box-shadow: var(--op-shadow-lift);
}

.op-btn.op-btn--primary:hover {
	background: var(--op-sun-400);
	color: var(--op-navy-900);
}

.op-btn.op-btn--ghost {
	background: transparent;
	color: var(--op-navy-900);
	border-color: var(--op-sand-deep);
}

.op-btn.op-btn--ghost:hover {
	background: var(--op-surface);
	border-color: var(--op-azure-600);
	color: var(--op-navy-900);
}

.op-btn.op-btn--on-dark {
	background: var(--op-apricot);
	color: var(--op-navy-900);
}

.op-btn.op-btn--on-dark:hover {
	background: var(--op-sun-400);
	color: var(--op-navy-900);
}

.op-btn.op-btn--ghost-dark {
	background: transparent;
	color: var(--op-cream);
	border-color: rgba(254, 247, 232, 0.35);
}

.op-btn.op-btn--ghost-dark:hover {
	background: rgba(254, 247, 232, 0.1);
	color: var(--op-cream);
	border-color: var(--op-apricot);
}

.op-btn.op-btn--block {
	width: 100%;
	justify-content: center;
}

.op-btn-row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--op-sp-s);
	align-items: center;
}

@media ( max-width: 600px ) {
	/* Stack full-width so both are easy tap targets, rather than one wide
	   button beside a narrow one. */
	.op-btn-row .op-btn {
		width: 100%;
		justify-content: center;
	}
}

/* ==========================================================================
   Wave divider (signature element, part 1). The three stacked bands are lifted
   straight from the logo mark. Rendered by opmh_wave() so every use is
   identical — see inc/partials.php.
   ========================================================================== */

.op-wave {
	display: block;
	width: 100%;
	height: clamp(48px, 7vw, 96px);
	color: var(--op-azure-600);
}

.op-wave--flip {
	transform: scaleY(-1);
}

.op-wave__band-1 {
	fill: currentColor;
	opacity: 0.22;
}

.op-wave__band-2 {
	fill: currentColor;
	opacity: 0.45;
}

.op-wave__band-3 {
	fill: currentColor;
	opacity: 1;
}

/* Matched to the deep-water section's own colour so the bands meet it exactly.
   If a wave ever appears to float above a seam, this is the token to check. */
.op-wave--deep {
	color: var(--op-navy-900);
}

/* The warm variant, for the one signature band that is light: matched to the
   dawn band's apricot ground the same way --deep is matched to navy. */
.op-wave--dawn {
	color: var(--op-apricot);
}

/* ==========================================================================
   LOCATION ACCENT (signature element, part 4)

   Each Google Business Profile landing page owns one slice of the shared dawn,
   read north to south, so the four pages reassemble into --op-horizon:

     Bellevue, WA  -> washington  navy into dusk    (the night end)
     Sisters, OR   -> oregon      dusk into azure
     Glendale, CA  -> california  ember into sun
     Tempe, AZ     -> arizona     gold into apricot (the dawn end)

   WHY THE CLASS SITS ON EACH BLOCK RATHER THAN ON <body>: the block editor
   renders the canvas in an iframe whose <body> is the editor's, not the
   theme's, so a body-level class would leave the client editing the page in
   the wrong accent — a drift the client sees and we don't. Every block that
   spends the accent carries its own `state` attribute, and opmh_section_attrs()
   turns it into the class below on both sides.

   Custom properties inherit, so a block only has to declare the state; every
   descendant resolves --op-local-* from it.

   THE ACCENT IS NEVER A FULL-BLEED BACKGROUND. It runs at full width in
   exactly one place, the short rule under the H1. Everywhere else it is an
   edge, a top rule, or small bold text. Spending the boldness once is what
   keeps it a signature.
   ========================================================================== */

.op-loc--california {
	--op-local-grad: linear-gradient(90deg, #a85210 0%, #f89808 55%, #f8c008 100%);
	--op-local-ink: var(--op-ember-700); /* 5.0:1 on cream */
	--op-local-wash: #fdf1de;
	--op-local-edge: var(--op-apricot);
}

/*
 * Washington needs one split the other three slices do not. Its band sits so
 * close to the base ink that navy-700 accent text is legible but does not read
 * AS an accent: at body scale that is right for a small label, and at H1 scale
 * the city name would simply look like the rest of the heading. So the display
 * accent drops one stop down the ocean ramp to azure-600 — 5.0:1 on cream, the
 * same ratio California's ember carries.
 */
.op-loc--washington {
	--op-local-grad: linear-gradient(90deg, #002848 0%, #123a63 100%);
	--op-local-ink: var(--op-navy-700);
	--op-local-display: var(--op-azure-600);
	--op-local-wash: #e7eef4;
	--op-local-edge: var(--op-azure-300);
}

.op-loc--oregon {
	--op-local-grad: linear-gradient(90deg, #123a63 0%, #0070a8 100%);
	--op-local-ink: var(--op-azure-600);
	--op-local-wash: var(--op-azure-100);
	--op-local-edge: var(--op-azure-300);
}

.op-loc--arizona {
	--op-local-grad: linear-gradient(90deg, #f8c008 0%, #fece8b 100%);
	--op-local-ink: var(--op-ember-700);
	--op-local-wash: #fef3e2;
	--op-local-edge: var(--op-apricot);
}

/* ==========================================================================
   Scroll reveal. Scoped to .js so a failed or blocked script can never leave
   content permanently invisible — without this, one JS error hides the page.
   ========================================================================== */

.js .op-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 0.6s var(--op-ease), transform 0.6s var(--op-ease);
}

.js .op-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* ==========================================================================
   Reduced motion. Stops the sun rule tracking scroll, cancels reveals and
   hover lifts.
   ========================================================================== */

@media ( prefers-reduced-motion: reduce ) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}

	.js .op-reveal {
		opacity: 1;
		transform: none;
	}

	.op-btn:hover {
		transform: none;
	}
}
