/*
Theme Name: The Story Doctor
Theme URI: https://thestorydoctor.net
Author: The Story Department
Author URI: https://thestorydepartment.com
Copyright: © Karel Segers
Description: Classic PHP theme for thestorydoctor.net — Karel Segers's script consultancy. Built line for line from the approved "Homepage Hi-Fi (v4.10)" mockup. No build step, no page builder, no jQuery, no webfonts. WooCommerce is the purchase path and is styled here rather than replaced. Companion to the Story Doctor Engine plugin, which owns the free logline generator and the script intake.
Version: 1.73.0
Requires at least: 6.4
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: storydoctor
Tags: one-column, custom-menu, custom-logo, accessibility-ready, e-commerce, translation-ready
*/

/* ==========================================================================
   Design tokens
   Lifted verbatim from the v4.10 mockup, which is the source of truth. The
   shared foundations (design-system/foundations.html) set the family type
   scale and the steel blue; what differs here is deliberate and brand-level:
   the logo red #db0039 is this site's lead accent, and Logline It's magenta
   appears nowhere.

   One thing worth knowing before you "fix" it: --blue-ink, not the red, is
   the fill on primary buttons. The red is the site's punctuation — section
   rules, the flagship price, the "Free tool" pill, the top border on raised
   panels. The mockup settles this, and the mockup wins.
   ========================================================================== */
:root {
	/* The page works in both, so native controls track the system until the
	   reader says otherwise; the [data-theme] rules further down pin it. */
	color-scheme: light dark;
	--bg: #ffffff;
	--surface: #f1f2f0;
	--panel: #ffffff;
	--text: #14181d;
	--muted: #5b6570;
	--border: #d8dcdf;
	--blue: #4880a0;
	--blue-ink: #3e7391;
	--blue-hover: #325d76;
	/*
	 * Two the step outline screens need and the palette did not carry.
	 *
	 * --skeleton is for anything FILLED: placeholder blocks, progress tracks.
	 * The hairline tokens are pitched to sit against --panel, and used as a
	 * fill on --surface they compute to 1.1:1 and simply vanish. Anything
	 * drawn as a line still takes --ghost-border or --rule.
	 *
	 * --blue-lift is the blue on a navy ground, where --blue falls to about
	 * 3.1:1 at small sizes. Type and anything 5px or under on the navy band
	 * takes this instead.
	 */
	--skeleton: #dfe2e5;
	--blue-lift: #6aa8c8;
	--on-blue: #ffffff;
	/* Text that sits ON the brand red. White in this scheme; see the dark block,
	   where the red lightens and white on it stops being readable. */
	--on-red: #ffffff;
	--navy: #16202b;
	--navy-2: #1e2b38;
	--red: #db0039;
	--radius: 10px;
	--font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

	/* Service pages (archive + single product).
	 *
	 * The design brief asked for these as `--mono`, `--ink` and `--rule`. Two of
	 * those names were already taken or absent here, and taking them literally
	 * would have broken the site:
	 *
	 *   `--mono` is this theme's monospace FONT STACK, used in 15 `font-family`
	 *   declarations. Redefining it as a grey would have set the typeface to a
	 *   colour everywhere it is used. The metadata grey is `--meta` instead.
	 *
	 *   `--ink` did not exist; this theme's ink has always been `--text`. It is
	 *   aliased rather than duplicated, so a rule written against the design
	 *   vocabulary drops in unchanged and there is still one value to edit.
	 */
	--ink: var(--text);
	/* Mock 5b sets body copy, spec values and step text a shade off the heading
	   ink (#242c34 against #14181d). Not in the brief's token list, but it is in
	   the design on every one of those, so it is a token rather than a literal
	   repeated fifteen times. */
	--ink-soft: #242c34;
	--meta: #8b949c;
	--rule: #e4e7e4;
	--row-tint: #fbfbfa;
	/* Reading measure for long-form pages (the sample report, articles). */
	--measure: 68ch;
	/* Set by the theme, so the hero photograph can live in assets/ rather than
	   be inlined as base64 the way the mockup had to. */
	--ghost-bg: rgba(255, 255, 255, 0.82);
	--ghost-bg-hover: #ffffff;
	--ghost-border: #c3ccd2;
	--hero-scrim: linear-gradient(96deg, rgba(241, 242, 240, 0.95) 0%, rgba(241, 242, 240, 0.9) 52%, rgba(241, 242, 240, 0.68) 76%, rgba(241, 242, 240, 0.3) 100%);
	--hero-scrim-narrow: linear-gradient(180deg, rgba(241, 242, 240, 0.95) 0%, rgba(241, 242, 240, 0.97) 100%);
	--hero-img: none;
}

/* ==========================================================================
   The dark palette
   --------------------------------------------------------------------------
   It has to apply in two situations, and CSS cannot express them in one rule:

     1. the system asks for dark, and the reader has not overridden it;
     2. the reader has chosen dark outright, whatever the system says.

   A media query and a plain attribute selector cannot be combined into a single
   block, so THE TWO LISTS BELOW ARE DUPLICATED ON PURPOSE AND MUST STAY
   IDENTICAL. `tools/check-theme-tokens.sh` at the repo root compares them and
   fails if they drift — run it after touching either.

   The alternative was `light-dark()`, which needs one declaration per token
   instead of two lists. It is well supported now, but an unsupported browser
   drops the whole declaration and lands on an unset token, which is a blank or
   inherited colour rather than a slightly wrong one. Duplication that a script
   checks is the cheaper failure.
   ========================================================================== */

/* 1. The system's preference, unless the reader has asked for light. */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		color-scheme: dark;
		--bg: #0f1720;
		--surface: #141d27;
		--panel: #16202b;
		--text: #e8edf2;
		--muted: #9aa7b4;
		--border: #2a3746;
		--blue: #6aa8c8;
		--blue-ink: #8cc0dc;
		--blue-hover: #8cc0dc;
		--skeleton: #2a3746;
		--blue-lift: #8cc0dc;
		--on-blue: #08131c;
		/* The dark scheme lifts --red from #db0039 to #f2557b so it holds up on a
		   dark ground — and white on that is 3.3:1, under the 4.5:1 that counts
		   as readable. The same ink as --on-blue takes it to 5.68:1. */
		--on-red: #08131c;
		--navy: #0b1219;
		--navy-2: #121b25;
		--red: #f2557b;
		/* The service-page tokens again, for dark. The brief gave light values
		   only; a #e4e7e4 hairline and a near-white row tint would both glow on
		   a dark ground, so they are re-pitched here rather than inherited. */
		--ink-soft: #d7dee5;
		--meta: #7d8894;
		--rule: #2a3746;
		--row-tint: #141d27;
		--ghost-bg: rgba(232, 237, 242, 0.08);
		--ghost-bg-hover: rgba(232, 237, 242, 0.14);
		--ghost-border: #3d4c5c;
		--hero-scrim: linear-gradient(96deg, rgba(15, 23, 32, 0.94) 0%, rgba(15, 23, 32, 0.88) 44%, rgba(15, 23, 32, 0.68) 72%, rgba(15, 23, 32, 0.38) 100%);
		--hero-scrim-narrow: linear-gradient(180deg, rgba(15, 23, 32, 0.95) 0%, rgba(15, 23, 32, 0.97) 100%);
	}
}

/* 2. The reader's own choice. Identical to the block above — see the note. */
:root[data-theme="dark"] {
	color-scheme: dark;
	--bg: #0f1720;
	--surface: #141d27;
	--panel: #16202b;
	--text: #e8edf2;
	--muted: #9aa7b4;
	--border: #2a3746;
	--blue: #6aa8c8;
	--blue-ink: #8cc0dc;
	--blue-hover: #8cc0dc;
	--skeleton: #2a3746;
	--blue-lift: #8cc0dc;
	--on-blue: #08131c;
	--on-red: #08131c;
	--navy: #0b1219;
	--navy-2: #121b25;
	--red: #f2557b;
	--ink-soft: #d7dee5;
	--meta: #7d8894;
	--rule: #2a3746;
	--row-tint: #141d27;
	--ghost-bg: rgba(232, 237, 242, 0.08);
	--ghost-bg-hover: rgba(232, 237, 242, 0.14);
	--ghost-border: #3d4c5c;
	--hero-scrim: linear-gradient(96deg, rgba(15, 23, 32, 0.94) 0%, rgba(15, 23, 32, 0.88) 44%, rgba(15, 23, 32, 0.68) 72%, rgba(15, 23, 32, 0.38) 100%);
	--hero-scrim-narrow: linear-gradient(180deg, rgba(15, 23, 32, 0.95) 0%, rgba(15, 23, 32, 0.97) 100%);
}

/*
 * Native controls follow `color-scheme`, not the tokens: scrollbars, select
 * menus, date pickers, the checkout's autofill. Without this, a reader who picks
 * light while their system is dark gets a light page with dark scrollbars and a
 * black dropdown, which reads as a broken page rather than a chosen one.
 */
:root[data-theme="light"] {
	color-scheme: light;
}

/* ==========================================================================
   Base
   ========================================================================== */
* {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
}

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

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

body {
	margin: 0;
	font-family: var(--font);
	background: var(--bg);
	color: var(--text);
	font-size: 17px;
	line-height: 1.65;
	-webkit-text-size-adjust: 100%;
}

a {
	color: var(--blue-ink);
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

/* `height: auto` is not decoration — it is what makes the width/height
   attributes on every <img> safe. Those attributes are there so the browser can
   reserve the right box before the image loads, but they also act as the used
   height unless something says otherwise. Without this line, any image whose
   width CSS sets (the Karel cutout, at calc(120% + 42px)) renders at its
   attribute height instead of its own proportions, and comes out stretched.
   Rules further down that set an explicit height — posters, the divider band,
   the avatar — are more specific and still win. */
img {
	max-width: 100%;
	height: auto;
}

/* Every interactive state is defined, per the brief. The mockup is silent on
   focus, so this is an addition rather than a departure: a visible ring in
   both colour modes, only for keyboard users. */
:focus-visible {
	outline: 3px solid var(--blue);
	outline-offset: 2px;
	border-radius: 3px;
}

/*
 * Placeholder text, in one place for every field on the site — the theme's own
 * forms and the ones WooCommerce renders.
 *
 * Left alone, the browser supplies its own: Chrome uses #757575, which is 4.6:1
 * on white and 3.6:1 on these dark panels, so every placeholder on the checkout,
 * the search box and the intake form failed in the dark scheme. `--muted` is
 * 5.9:1 in light and 6.7:1 in dark, and it is the colour the rest of the site
 * already uses for secondary type.
 *
 * `opacity: 1` because Firefox dims placeholders by default, which would undo
 * the colour underneath it.
 */
input::placeholder,
textarea::placeholder {
	color: var(--muted);
	opacity: 1;
}

/* --- The light / dark / auto switch --------------------------------------- */

/*
 * Three states on one control, the way Logline It's works. The glyphs are all
 * present in the markup and CSS shows one, so switching modes never waits on a
 * network request or a re-render, and the button keeps its width — a control
 * that resizes as you press it is hard to press twice.
 */
.theme-toggle {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 1px solid var(--border);
	border-radius: 9px;
	background: var(--panel);
	color: var(--muted);
	cursor: pointer;
	flex: none;
}

/*
 * The tooltip, ported from Logline It's. A pseudo-element rather than `title`
 * because the native one waits about a second before it appears, which is long
 * enough that somebody deciding whether to press an unlabelled icon has already
 * pressed it and found out.
 *
 * It says what the *next* press does, which is the question a three-state cycle
 * raises. The button's accessible name carries the same thing in a sentence, so
 * a screen reader hears it without this — the tooltip is for the pointer.
 *
 * Inverted, like the buy button: ink on the page's ground reversed, so it reads
 * as an overlay in both schemes and needs no palette of its own.
 */
.theme-toggle::after {
	content: attr(data-tip);
	position: absolute;
	top: 100%;
	right: 0;
	margin-top: 8px;
	padding: 5px 9px;
	border-radius: 6px;
	background: var(--text);
	color: var(--bg);
	font-family: var(--mono);
	font-size: 0.68rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	line-height: 1.2;
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.06s ease;
	z-index: 40;
}

/* No tip before the script has written one, and none on a touch press, where
   :hover sticks after the tap and leaves the bubble stranded on screen. */
.theme-toggle:not([data-tip])::after {
	content: none;
}

@media (hover: hover) {
	.theme-toggle:hover::after {
		opacity: 1;
	}
}

.theme-toggle:focus-visible::after {
	opacity: 1;
}

/* In the phone's menu the button sits at the right edge of the panel, so the
   bubble opens leftwards from it rather than off the screen. */
.theme-toggle--panel::after {
	right: 0;
	left: auto;
}

.theme-toggle:hover {
	color: var(--text);
	border-color: var(--muted);
}

.theme-toggle svg {
	width: 18px;
	height: 18px;
	display: none;
}

/* Auto is the state with no stored choice, so it is also the fallback here:
   an unset data-mode still shows an icon rather than an empty box. */
.theme-toggle .i-auto {
	display: block;
}

.theme-toggle[data-mode="light"] .i-auto,
.theme-toggle[data-mode="dark"] .i-auto {
	display: none;
}

.theme-toggle[data-mode="light"] .i-light,
.theme-toggle[data-mode="dark"] .i-dark {
	display: block;
}

/*
 * `display` from a class beats the browser's own `[hidden] { display: none }`,
 * so a button that ships hidden would show anyway until the script ran. The
 * theme already learned this on `.cart[hidden]`; the carousel's controls still
 * had the bug, and are fixed with it below.
 */
.theme-toggle[hidden] {
	display: none;
}

/*
 * Which copy shows. The header row carries it down to 560px; below that the row
 * is full — brand, CTA and the menu button — and a fourth control pushed the
 * menu button off a 430px screen. The panel copy takes over there.
 */
.theme-toggle--panel {
	display: none;
}

.navpanel-scheme {
	display: none;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	margin: 4px 0 0;
	padding-top: 14px;
	border-top: 1px solid var(--border);
	font-size: 0.94rem;
	color: var(--muted);
}

@media (max-width: 860px) {
	.theme-toggle {
		width: 34px;
		height: 34px;
	}
}

@media (max-width: 560px) {
	.theme-toggle--bar {
		display: none;
	}

	.theme-toggle--panel {
		display: inline-flex;
	}

	.navpanel-scheme {
		display: flex;
	}
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--panel);
	color: var(--text);
	border: 1px solid var(--border);
	border-radius: 0 0 8px 0;
	padding: 12px 18px;
	font-weight: 600;
}

.skip-link:focus {
	left: 0;
}

.wrap {
	max-width: 1120px;
	margin: 0 auto;
	padding: 0 24px;
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
	display: inline-block;
	font: inherit;
	font-weight: 600;
	border-radius: 8px;
	padding: 12px 22px;
	cursor: pointer;
	border: 1px solid transparent;
	text-decoration: none;
	text-align: center;
}

.btn:hover {
	text-decoration: none;
}

.btn.primary {
	background: var(--blue-ink);
	color: var(--on-blue);
}

.btn.primary:hover {
	background: var(--blue-hover);
}

/* The brand red as a button fill. The tokens carry it through both schemes —
   the dark block lightens --red and flips --on-red to near-black — and the
   hover matches the one the WooCommerce checkout buttons already use. */
.btn.accent {
	background: var(--red);
	color: var(--on-red);
}

.btn.accent:hover {
	filter: brightness(0.92);
	color: var(--on-red);
}

.btn.ghost {
	background: var(--ghost-bg);
	border-color: var(--ghost-border);
	color: var(--text);
}

.btn.ghost:hover {
	background: var(--ghost-bg-hover);
	border-color: var(--blue-ink);
}

.btn.onnavy {
	background: rgba(255, 255, 255, 0.1);
	border-color: rgba(255, 255, 255, 0.38);
	color: #fff;
}

.btn.onnavy:hover {
	background: rgba(255, 255, 255, 0.18);
}

.btn.sm {
	padding: 9px 16px;
	font-size: 0.9rem;
}

/* Pressed and unavailable states, which the mockup only defines for #usend. */
.btn:active {
	transform: translateY(1px);
}

.btn:disabled,
.btn[aria-disabled="true"] {
	opacity: 0.45;
	cursor: not-allowed;
	transform: none;
}

/* ==========================================================================
   Section primitives
   ========================================================================== */
.kicker {
	font-size: 0.7rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--blue-ink);
	font-weight: 700;
	margin: 0 0 12px;
}

h2.sect {
	font-size: 1.9rem;
	font-weight: 800;
	margin: 0 0 8px;
	letter-spacing: -0.025em;
	line-height: 1.15;
}

.sect-sub {
	color: var(--muted);
	margin: 0 0 30px;
	max-width: 40em;
}

.centred {
	text-align: center;
}

.centred .sect-sub {
	margin-left: auto;
	margin-right: auto;
}

.rule {
	width: 44px;
	height: 3px;
	background: var(--red);
	border-radius: 2px;
	margin: 0 0 16px;
}

.centred .rule {
	margin-left: auto;
	margin-right: auto;
}

/* ==========================================================================
   Family bar + site header
   ========================================================================== */
.family {
	background: var(--surface);
	border-bottom: 1px solid var(--border);
	font-size: 0.78rem;
}

.family .wrap {
	display: flex;
	gap: 18px;
	padding-top: 7px;
	padding-bottom: 7px;
	align-items: center;
	flex-wrap: wrap;
}

.family span.here {
	font-weight: 700;
	color: var(--text);
}

.family a {
	color: var(--muted);
}

.family .lead {
	color: var(--muted);
	margin-right: auto;
}

header.site {
	border-bottom: 1px solid var(--border);
	position: sticky;
	top: 0;
	background: var(--bg);
	z-index: 20;
}

header.site .wrap {
	display: flex;
	align-items: center;
	gap: 26px;
	padding-top: 11px;
	padding-bottom: 11px;
}

.brand {
	display: flex;
	align-items: center;
	gap: 11px;
}

.brand img {
	width: 38px;
	height: 38px;
	display: block;
}

.logo {
	font-size: 1.12rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	color: var(--text);
}

a.brand:hover {
	text-decoration: none;
}

nav.main {
	display: flex;
	gap: 22px;
	margin-left: auto;
	font-size: 0.94rem;
	align-items: center;
}

nav.main a {
	color: var(--text);
}

.cart {
	color: var(--muted);
	font-size: 0.9rem;
}

.cart[hidden] {
	display: none;
}

@media (max-width: 900px) {
	nav.main a.hideable {
		display: none;
	}
}

/* Mobile nav disclosure.
   The mockup drops the nav links below 900px and leaves only the cart and
   "Send your script". That's fine as a picture but it strands /services/,
   /about/ and /contact/ on a phone, so the brief's "every template readable
   at 360px" and "keyboard-navigable nav" would both fail. This panel is the
   one deliberate addition to the design: invisible above 900px, so the
   approved desktop composition is untouched. */
.navtoggle {
	display: none;
	background: none;
	border: 1px solid var(--border);
	border-radius: 8px;
	color: var(--text);
	font: inherit;
	font-size: 0.85rem;
	font-weight: 600;
	padding: 7px 12px;
	cursor: pointer;
	align-items: center;
	gap: 7px;
}

.navtoggle:hover {
	border-color: var(--blue-ink);
}

.navtoggle .bars {
	display: block;
	width: 15px;
	height: 9px;
	border-top: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
}

.navpanel {
	display: none;
}

@media (max-width: 900px) {
	.navtoggle {
		display: inline-flex;
	}

	.navpanel {
		display: block;
		border-top: 1px solid var(--border);
		background: var(--bg);
	}

	.navpanel[hidden] {
		display: none;
	}

	.navpanel ul {
		list-style: none;
		margin: 0;
		padding: 6px 0 12px;
	}

	.navpanel li + li {
		border-top: 1px solid var(--border);
	}

	.navpanel a {
		display: block;
		padding: 12px 0;
		color: var(--text);
		font-size: 1rem;
		font-weight: 600;
	}
}

/* ==========================================================================
   1 — Hero and symptoms
   ========================================================================== */
/* The scrim is a contrast budget, not a taste setting. It has to keep `.cred` —
   muted grey at 1.05rem, the smallest text on the band — clear of WCAG AA, while
   letting the stethoscope read. Measured at 1440px against the rendered page, the
   stops below put the copy's background at 5.10:1 and its darkest local patch at
   4.61:1, both over the 4.5:1 floor. Lighten them further and measure again
   rather than judging it by eye: the photograph is lightest exactly where the
   headline sits, so it flatters itself. */
/*
 * The scrim is a token, not a rule in a media query, and that is the whole
 * point: it has to follow the *tokens*, which the colour switch controls, and
 * not the system preference on its own. As a media-query rule it broke the
 * moment the switch shipped — a reader choosing dark on a light laptop got
 * near-white type over the light scrim and could not read the hero at all.
 */
.hero {
	position: relative;
	border-bottom: 1px solid var(--border);
	background:
		var(--hero-scrim),
		var(--hero-img) center / cover no-repeat,
		var(--surface);
}

/* Narrow screens take the vertical wash, in whichever scheme is in force. */
@media (max-width: 900px) {
	.hero {
		background:
			var(--hero-scrim-narrow),
			var(--hero-img) center / cover no-repeat,
			var(--surface);
	}
}

.hero .wrap {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr);
	gap: 48px;
	align-items: end;
	padding-top: 76px;
	padding-bottom: 76px;
}

.hero h1 {
	font-size: clamp(2.9rem, 6.2vw, 4.6rem);
	font-weight: 800;
	line-height: 1.06;
	letter-spacing: -0.035em;
	margin: 0 0 14px;
}

.hero h1 em {
	font-style: normal;
	color: var(--red);
}

@media (max-width: 620px) {
	.hero h1 {
		font-size: 2.15rem;
	}
}

.hero .cred {
	color: var(--muted);
	font-size: 1.05rem;
	margin: 0 0 30px;
	max-width: 30em;
}

/* The CTA pair: one block, half the container each. */
/*
 * Flex rather than two equal columns. The row held a pair, so 1fr 1fr was
 * right; with one button left that same rule rendered it at half width with
 * an empty column beside it. Flex lets it take the width it needs, and would
 * still sit a second one alongside if the row ever grows again.
 */
.hero .actions {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	max-width: 640px;
}

/* `.btn` is inline-block by default, which would ignore the centring below and
   leave the taller mobile buttons' label off-centre vertically. Flex here rather
   than changing `.btn` itself, which every other button on the site shares. */
.hero .actions .btn {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 22px 24px;
	font-size: 1.18rem;
	border-radius: 4px;
}

.hero .kicker {
	color: var(--muted);
}

/* The marked page, framed, overlapping the foot of the band. Three numbers have
   to stay in step: the overhang must first cancel `.hero .wrap`'s 76px bottom
   padding before any of it crosses the seam, so -110px is 34px of actual overlap,
   and `.symstrip`'s 74px top padding is what clears that. An overhang of 76px or
   less buys nothing — the exhibit just sits lower inside the band. */
.hero-exhibit {
	margin: 0 0 -110px;
	background: var(--panel);
	border: 1px solid var(--border);
	border-top: 3px solid var(--red);
	padding: 10px 10px 4px;
	box-shadow: 0 18px 48px rgba(20, 24, 29, 0.2);
}

/* A fixed height against a portrait file, so `object-fit` is doing the cropping
   rather than the box distorting the page. The focal point is low: the tick and
   the handwriting sit below centre. */
.hero-exhibit img {
	display: block;
	width: 100%;
	height: 300px;
	object-fit: cover;
	object-position: 50% 58%;
}

.hero-exhibit figcaption {
	padding: 10px 4px 8px;
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--muted);
}

@media (max-width: 900px) {
	.hero .wrap {
		grid-template-columns: 1fr;
		gap: 26px;
		padding-top: 42px;
		padding-bottom: 42px;
	}

	.hero .actions {
		max-width: none;
	}

	.hero .actions .btn {
		min-height: 52px;
		/* Full width here, which the grid used to do. */
		flex: 1 1 100%;
	}

	/* The exhibit sits below the copy here, so it no longer breaks the band. */
	.hero-exhibit {
		margin-bottom: 0;
	}

	/* Full-container width against a 200px window crops far harder than the narrow
	   desktop column does, and the two marks are too far apart to both survive it.
	   The tick and the thumb are the legible pair at this size, so the focal point
	   drops to meet them and the handwriting is let go. */
	.hero-exhibit img {
		height: 200px;
		object-position: 50% 70%;
	}
}

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

.symlist li {
	padding: 9px 0 9px 20px;
	position: relative;
	font-size: 0.97rem;
	border-bottom: 1px solid var(--border);
}

.symlist li:last-child {
	border-bottom: 0;
	padding-bottom: 2px;
}

.symlist li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 18px;
	width: 9px;
	height: 2px;
	background: var(--blue);
}

/* Symptoms, now a strip under the hero rather than a hero column. The top padding
   clears the exhibit's -56px overhang. */
.symstrip {
	background: var(--panel);
	border-bottom: 1px solid var(--border);
	padding: 74px 0 34px;
}

.symstrip h2 {
	font-size: 1.35rem;
	font-weight: 800;
	letter-spacing: -0.015em;
	margin: 0 0 18px;
}

.symstrip .symlist {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--border);
}

/* The list reads as four columns divided by rules, so the row borders the panel
   version used come off and a right-hand divider goes on instead. */
.symstrip .symlist li {
	padding: 16px 22px 16px 20px;
	border-bottom: 0;
	border-right: 1px solid var(--border);
	font-size: 0.97rem;
	text-wrap: pretty;
}

.symstrip .symlist li:last-child {
	border-right: 0;
	padding-bottom: 16px;
}

.symstrip .symlist li::before {
	top: 25px;
	left: 0;
}

.symstrip .foot {
	margin: 18px 0 0;
	font-size: 0.9rem;
	color: var(--muted);
}

@media (max-width: 900px) {
	.symstrip {
		padding-top: 38px;
	}

	.symstrip .symlist {
		grid-template-columns: 1fr;
	}

	.symstrip .symlist li {
		border-right: 0;
		border-bottom: 1px solid var(--border);
	}

	/* Stacked, the last item's rule would double the section's own bottom border. */
	.symstrip .symlist li:last-child {
		border-bottom: 0;
	}
}

/* ==========================================================================
   2 — Services reprise (navy)
   ========================================================================== */
.services2 {
	background: var(--navy);
	color: #e8edf2;
	padding: 56px 0;
}

.services2 .kicker {
	color: #8ec2dd;
}

.services2 h2.sect {
	color: #fff;
}

.services2 .sect-sub {
	color: #b9c4ce;
}

.s2row {
	/* Wrap-and-centre rather than a fixed three columns, so the block reads as
	   intentional whether it holds one card, two, or three — a service still in
	   draft simply leaves fewer, centred, not a gap in a rigid grid. */
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 16px;
	margin: 0 0 24px;
}

.s2row .s2card {
	flex: 1 1 240px;
	max-width: 340px;
}

@media (max-width: 820px) {
	.s2row .s2card { max-width: none; flex-basis: 100%; }
}

.s2card {
	display: flex;
	flex-direction: column;
	gap: 3px;
	text-align: left;
	background: var(--navy-2);
	border: 1px solid rgba(255, 255, 255, 0.16);
	border-radius: 12px;
	padding: 20px 22px;
	color: #e8edf2;
	text-decoration: none;
	transition: border-color 0.15s;
}

.s2card:hover {
	border-color: #8ec2dd;
	text-decoration: none;
}

.s2card.flag {
	border-color: #db0039;
	background: rgba(219, 0, 57, 0.08);
}

.s2tag {
	align-self: flex-start;
	margin: 0 0 6px;
	padding: 3px 8px;
	font-family: var(--mono);
	font-size: 9px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: #fff;
	background: #db0039;
	border-radius: 4px;
}

/* The stage selector standing in for the homepage upload form: it carries its
   own plate, so it only needs room to breathe inside the intake section. */
.sd-stage-home {
	margin: 8px auto 0;
	max-width: 760px;
}

.s2card .t {
	font-size: 0.7rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: #8ec2dd;
	font-weight: 700;
}

.s2card.flag .t {
	color: #f2557b;
}

.s2card .p {
	font-size: 1.9rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	color: #fff;
	line-height: 1.1;
}

.s2card .d {
	font-size: 0.88rem;
	color: #b9c4ce;
	margin-top: 4px;
}

/* ==========================================================================
   3 — Credits and testimonials
   ========================================================================== */
.proof {
	padding: 64px 0 30px;
}

.proofhead {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 26px;
	flex-wrap: wrap;
}

.creditrow {
	display: grid;
	grid-template-columns: 0.62fr 2fr;
	gap: 30px;
	align-items: stretch;
	margin-bottom: 58px;
}

@media (max-width: 860px) {
	.creditrow {
		grid-template-columns: 1fr;
		gap: 22px;
	}
}

.filmgrid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	/* Deliberately left to stretch. The cutout column runs ~19px taller than
	   three 156px cards, so the mockup's rows settle at 162.33px and the grid
	   ends level with Karel's feet. Pinning the rows with align-content:start
	   would be tidier in the abstract and would not match the approved page. */
}

@media (max-width: 540px) {
	.filmgrid {
		grid-template-columns: 1fr;
	}
}

.film {
	display: flex;
	gap: 16px;
	align-items: stretch;
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	overflow: hidden;
	height: 156px;
}

.poster {
	flex: 0 0 104px;
	width: 104px;
	height: 156px;
	object-fit: contain;
	object-position: left center;
	display: block;
	background: var(--surface);
}

@media (max-width: 620px) {
	.film {
		height: auto;
		min-height: 150px;
	}

	.poster {
		height: auto;
	}
}

.film .meta {
	padding: 14px 16px 14px 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-width: 0;
}

.film .meta b {
	display: block;
	font-size: 1.08rem;
	font-weight: 800;
	line-height: 1.2;
	margin-bottom: 3px;
	letter-spacing: -0.02em;
}

.film .yg {
	font-size: 0.83rem;
	color: var(--muted);
	margin-bottom: 8px;
}

.film .by {
	font-size: 0.85rem;
	line-height: 1.4;
}

.film .by span {
	display: block;
	color: var(--muted);
	font-size: 0.64rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-weight: 700;
	margin-bottom: 1px;
}

.who-card {
	display: flex;
	flex-direction: column;
}

.who-card .cut {
	position: relative;
	z-index: 3;
	width: calc(120% + 42px);
	max-width: none;
	margin: auto -42px -34px -11%;
	display: block;
	filter: drop-shadow(0 18px 34px rgba(20, 24, 29, 0.26));
	/* The width is fluid, so the height must follow it and only it. Stating the
	   ratio explicitly rather than leaving it to `height: auto` alone means the
	   shape is declared, not inherited from whatever the file happens to be, and
	   it holds at every width and before the image has loaded. `flex-shrink: 0`
	   covers the other direction: this is an item in a column flex container, so
	   without it the card could compress the photograph vertically if its
	   contents ever outgrew it. Karel does not get squashed at any width. */
	aspect-ratio: 470 / 530;
	height: auto;
	flex-shrink: 0;
}

@media (max-width: 860px) {
	.who-card .cut {
		width: 64%;
		margin: 20px auto -4px;
		z-index: 1;
	}
}

.who-card .in {
	padding: 0 2px;
}

.who-card b {
	display: block;
	font-size: 1.06rem;
	letter-spacing: -0.015em;
}

.who-card .role {
	font-size: 0.82rem;
	color: var(--muted);
	margin: 2px 0 9px;
}

.who-card p {
	margin: 0 0 12px;
	font-size: 0.9rem;
	color: var(--muted);
}

.who-card a {
	font-size: 0.89rem;
	font-weight: 600;
}

.qrow {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
}

@media (max-width: 860px) {
	.qrow {
		grid-template-columns: 1fr;
	}
}

.quote {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 24px 26px;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.quote p {
	margin: 0 0 12px;
	font-size: 1.02rem;
	line-height: 1.58;
}

.quote .who {
	font-size: 0.85rem;
	color: var(--muted);
}

.quote .who b {
	color: var(--text);
}

.qfoot {
	margin: 16px 0 0;
	font-size: 0.92rem;
	font-weight: 600;
}

/* ==========================================================================
   4 — Start free: the two documents and the generator
   ========================================================================== */
.startfree {
	background: var(--navy);
	color: #e8edf2;
	padding: 64px 0;
}

.startfree .kicker {
	color: #8ec2dd;
}

.startfree h2.sect {
	color: #fff;
}

.startfree .sect-sub {
	color: #b9c4ce;
}

.startfree a {
	color: #8ec2dd;
}

.sfgrid {
	display: grid;
	grid-template-columns: 0.86fr 1.34fr;
	gap: 28px;
	align-items: start;
}

@media (max-width: 900px) {
	.sfgrid {
		grid-template-columns: 1fr;
	}
}

.docs {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.doccard {
	background: var(--navy-2);
	border: 1px solid rgba(255, 255, 255, 0.14);
	border-radius: 12px;
	padding: 20px 22px;
}

.doccard .lbl {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #8ec2dd;
	margin: 0 0 6px;
}

.doccard b {
	display: block;
	font-size: 1.06rem;
	color: #fff;
	margin-bottom: 5px;
}

.doccard p {
	margin: 0;
	color: #b9c4ce;
	font-size: 0.94rem;
}

/* The generator panel — a reusable component (parts/generator.php), because it
   is wanted elsewhere as well as on the front page. */
.gen-panel {
	background: var(--panel);
	color: var(--text);
	border: 1px solid var(--border);
	border-top: 4px solid var(--red);
	border-radius: 6px 6px 14px 14px;
	padding: 26px 28px;
	box-shadow: 0 22px 54px rgba(0, 0, 0, 0.42);
}

.gen-panel .top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 14px;
}

.gen-panel .top b {
	font-size: 1.28rem;
	color: var(--text);
	letter-spacing: -0.02em;
}

.gen-panel .top span {
	font-size: 0.66rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--on-red);
	background: var(--red);
	border-radius: 999px;
	padding: 4px 11px;
	font-weight: 700;
	white-space: nowrap;
}

.gen-panel textarea {
	width: 100%;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 13px;
	font: inherit;
	font-size: 0.96rem;
	background: var(--bg);
	color: var(--text);
	resize: vertical;
	min-height: 112px;
}

/*
 * The generator's placeholder used to be a hardcoded #7d8b97, chosen against the
 * dark panel it sits on in the dark scheme, where it measures 5.17:1. In the
 * light scheme the same value is 3.49:1 on white — under the bar, and invisible
 * to a dark-mode audit because it only fails in the other one. It now takes the
 * shared rule above like every other field.
 */

.gen-row {
	display: flex;
	gap: 11px;
	align-items: center;
	margin-top: 12px;
	flex-wrap: wrap;
}

.gen-row select {
	font: inherit;
	font-size: 0.92rem;
	padding: 11px 13px;
	border: 1px solid var(--border);
	border-radius: 9px;
	background: var(--bg);
	color: var(--text);
}

.gen-note {
	font-size: 0.79rem;
	color: var(--muted);
	margin: 12px 0 0;
}

.gen-out {
	display: none;
	margin-top: 18px;
	border-left: 3px solid var(--red);
	background: var(--surface);
	border-radius: 0 9px 9px 0;
	padding: 15px 18px;
}

.gen-out.show {
	display: block;
}

.gen-out .ll {
	font-size: 1.05rem;
	font-weight: 700;
	line-height: 1.45;
	margin: 0 0 8px;
	color: var(--text);
}

.gen-out .next {
	font-size: 0.86rem;
	color: var(--muted);
	margin: 0;
}

/* The failure state the mockup never needed: a real API call can be refused,
   rate-limited or unconfigured, and the writer has to be told which. */
.gen-out.error {
	border-left-color: var(--muted);
}

.gen-out.error .ll {
	font-weight: 600;
	font-size: 0.98rem;
}

/* ==========================================================================
   5 — The step outline tool

   Sits between the free documents and the notes you pay for, and is styled to
   read that way: on the page's own surface rather than the navy of the free
   band above it, so it is plainly a different offer and not a fourth free
   thing. Only rendered where the plugin is installed.
   ========================================================================== */
.steptool {
	background: var(--surface);
	border-top: 1px solid var(--border);
	border-bottom: 1px solid var(--border);
	padding: 56px 0;
}

.steptool-grid {
	display: grid;
	grid-template-columns: 1.15fr 1fr;
	gap: 32px;
	align-items: center;
}

@media (max-width: 900px) {
	.steptool-grid {
		grid-template-columns: 1fr;
		gap: 24px;
	}
}

.steptool .kicker {
	color: var(--blue-ink);
}

.steptool .sect-sub {
	max-width: 34rem;
	margin-bottom: 20px;
}

.steptool-points {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.steptool-points li {
	background: var(--panel);
	border: 1px solid var(--border);
	border-left: 3px solid var(--blue);
	border-radius: 6px;
	padding: 12px 14px;
	color: var(--muted);
	font-size: 0.95rem;
	line-height: 1.55;
}

.steptool-points b {
	display: block;
	margin-bottom: 2px;
	color: var(--text);
	font-size: 0.9rem;
	letter-spacing: 0.02em;
}

/* ==========================================================================
   6 — What you receive
   ========================================================================== */
.whatget {
	padding: 64px 0;
}

.steps {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 30px;
	margin-bottom: 38px;
}

@media (max-width: 820px) {
	.steps {
		grid-template-columns: 1fr;
		gap: 20px;
	}
}

.step {
	border-top: 2px solid var(--border);
	padding-top: 16px;
}

.step .n {
	font-family: var(--mono);
	font-size: 0.76rem;
	letter-spacing: 0.12em;
	color: var(--blue-ink);
	font-weight: 700;
}

.step b {
	display: block;
	font-size: 1.08rem;
	margin: 6px 0;
}

.step p {
	margin: 0;
	color: var(--muted);
	font-size: 0.94rem;
}

.dgrid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 16px;
}

@media (max-width: 900px) {
	.dgrid {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 540px) {
	.dgrid {
		grid-template-columns: 1fr;
	}
}

.dcard {
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 20px;
	background: var(--panel);
	display: flex;
	flex-direction: column;
}

.dcard .num {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--muted);
	margin: 0 0 6px;
}

.dcard b {
	display: block;
	font-size: 1.04rem;
	margin-bottom: 6px;
}

.dcard p {
	margin: 0 0 14px;
	color: var(--muted);
	font-size: 0.92rem;
}

.tag {
	margin-top: auto;
	align-self: flex-start;
	font-size: 0.71rem;
	font-weight: 700;
	border-radius: 999px;
	padding: 3px 11px;
	letter-spacing: 0.02em;
}

.tag.free {
	background: var(--red);
	color: var(--on-red);
}

.tag.tier {
	background: var(--surface);
	color: var(--muted);
	border: 1px solid var(--border);
}

.inset {
	margin-top: 22px;
	max-width: 640px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-left: 3px solid var(--red);
	border-radius: 0 10px 10px 0;
	padding: 16px 20px;
	font-size: 0.94rem;
}

.inset b {
	color: var(--text);
}

/* ==========================================================================
   7 — Send your script (the divider band and the intake)
   ========================================================================== */
.band {
	margin: 0;
	line-height: 0;
}

.band img {
	width: 100%;
	height: 230px;
	object-fit: cover;
	display: block;
}

.intake {
	background: var(--surface);
	border-bottom: 1px solid var(--border);
	padding: 64px 0;
}

.intake-panel {
	max-width: 640px;
	margin: 0 auto;
}

.dropzone {
	border: 2px dashed var(--border);
	border-radius: 12px;
	padding: 38px 22px;
	text-align: center;
	color: var(--muted);
	cursor: pointer;
	background: var(--panel);
	transition: border-color 0.15s;
}

.dropzone.hover,
.dropzone:hover {
	border-color: var(--blue);
}

.dropzone .big {
	font-size: 1.9rem;
	display: block;
	margin-bottom: 8px;
}

.dropzone b {
	color: var(--text);
}

.dropzone .types {
	font-size: 0.79rem;
	margin-top: 9px;
}

.reader {
	display: flex;
	gap: 12px;
	align-items: center;
	justify-content: center;
	text-align: left;
	margin: 14px 0 0;
	font-size: 0.87rem;
	color: var(--muted);
}

.reader img {
	width: 42px;
	height: 42px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 42px;
}

.reader span {
	max-width: 34em;
}

.reader b {
	color: var(--text);
}

.filelist {
	list-style: none;
	margin: 14px 0 0;
	padding: 0;
	font-size: 0.86rem;
}

.filelist li {
	display: flex;
	gap: 10px;
	align-items: center;
	border: 1px solid var(--border);
	border-radius: 8px;
	padding: 8px 13px;
	margin-bottom: 6px;
	background: var(--panel);
}

.filelist li .nm {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.filelist li .sz {
	color: var(--muted);
	font-size: 0.8rem;
}

/* Removing a file: the mockup's list is display-only, but a real upload needs
   a way back out of a mistake. */
.filelist li .rm {
	background: none;
	border: 0;
	color: var(--muted);
	font: inherit;
	font-size: 1.1rem;
	line-height: 1;
	padding: 0 2px;
	cursor: pointer;
}

.filelist li .rm:hover {
	color: var(--red);
}

.filelist li.bad {
	border-color: var(--red);
}

.filelist li .why {
	color: var(--red);
	font-size: 0.78rem;
}

.intake-panel label {
	display: block;
	font-weight: 600;
	font-size: 0.87rem;
	margin: 22px 0 5px;
}

.intake-panel input {
	width: 100%;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 13px;
	font: inherit;
	font-size: 0.95rem;
	background: var(--panel);
	color: var(--text);
}

/* Why the script is coming (Theme 1.70.0). Each reason is a full-width row so
   the whole line is the target, and the chosen one is marked by more than the
   dot. The general .intake-panel label and input rules are undone here: they
   are for the email field, and a radio stretched to 100% is not a radio. */
.intake-panel .why {
	border: 0;
	padding: 0;
	margin: 0 0 22px;
}

.intake-panel .why legend {
	font-weight: 700;
	font-size: 1.05rem;
	margin: 0 0 10px;
	padding: 0;
}

.intake-panel label.whyopt {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0 0 8px;
	padding: 12px 14px;
	border: 1px solid var(--border);
	border-radius: 9px;
	background: var(--panel);
	font-weight: 500;
	font-size: 0.95rem;
	cursor: pointer;
}

.intake-panel label.whyopt:has( input:checked ) {
	border-color: var(--red);
	box-shadow: inset 3px 0 0 var(--red);
}

.intake-panel .whyopt input {
	width: auto;
	margin: 0;
	padding: 0;
	accent-color: var(--red);
	flex: none;
}

.intake-panel .orderref {
	margin: 4px 0 0 14px;
}

.intake-panel .orderref label {
	margin-top: 12px;
}

.intake-panel .orderref .hint {
	margin: 6px 0 0;
	font-size: 0.85rem;
	color: var(--muted);
}

.sd-send-form {
	margin: 32px 0 16px;
}

/* Proof of submission: the register, the receipt, and the offline-copy tick.
   Set apart from the hurt box by colour rather than by a second red rule, so
   the page has one place that says "start here" and this is not it. */
.proofbox {
	margin: 0 0 22px;
	padding: 20px 22px;
	border: 1px solid var(--border);
	border-left: 3px solid var(--blue);
	border-radius: 4px 12px 12px 4px;
	background: var(--panel);
}

.proofbox h3 {
	margin: 0 0 6px;
	font-size: 1rem;
}

.proofbox p {
	margin: 0 0 12px;
	font-size: 0.9rem;
	color: var(--muted);
}

.intake-panel label.proofopt {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin: 0;
	font-weight: 500;
	font-size: 0.9rem;
	cursor: pointer;
}

.intake-panel .proofopt input {
	width: auto;
	margin: 3px 0 0;
	padding: 0;
	flex: none;
	accent-color: var(--red);
}

/* The homepage's way in: each reason is a link to the page with it chosen. */
.send-why {
	list-style: none;
	margin: 26px auto 28px;
	padding: 0;
	max-width: 560px;
	display: grid;
	gap: 8px;
	text-align: left;
}

.send-why a {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	padding: 13px 16px;
	border: 1px solid var(--border);
	border-radius: 9px;
	background: var(--panel);
	color: var(--text);
	font-weight: 600;
	text-decoration: none;
}

.send-why a:hover,
.send-why a:focus-visible {
	border-color: var(--red);
}

.send-why a span {
	color: var(--red);
}

.hurtbox {
	margin: 26px 0 22px;
	text-align: center;
	background: var(--panel);
	border: 1px solid var(--border);
	border-top: 3px solid var(--red);
	border-radius: 4px 4px 12px 12px;
	padding: 24px;
}

.hurtbox h3 {
	font-size: 1.16rem;
	font-weight: 800;
	margin: 0 0 6px;
	letter-spacing: -0.02em;
}

.hurtbox p {
	color: var(--muted);
	font-size: 0.92rem;
	margin: 0 0 14px;
}

.hurtbox textarea {
	width: 100%;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 12px;
	font: inherit;
	font-size: 0.94rem;
	background: var(--bg);
	color: var(--text);
	resize: vertical;
	min-height: 92px;
}

#usend {
	width: 100%;
	padding: 15px 22px;
	font-size: 1.02rem;
}

#usend:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

.missing {
	font-size: 0.81rem;
	color: var(--muted);
	margin: 9px 0 0;
	text-align: center;
}

.up-done {
	display: none;
	margin-top: 14px;
	border: 1px solid var(--blue);
	border-radius: 10px;
	padding: 12px 16px;
	font-size: 0.92rem;
	background: var(--panel);
	text-align: center;
}

.up-done.show {
	display: block;
}

.up-done.bad {
	border-color: var(--red);
}

/* Real uploads take time, so there is a progress bar the mockup didn't need. */
.up-bar {
	display: none;
	margin-top: 14px;
	height: 6px;
	border-radius: 999px;
	background: var(--border);
	overflow: hidden;
}

.up-bar.show {
	display: block;
}

.up-bar i {
	display: block;
	height: 100%;
	width: 0;
	background: var(--red);
	transition: width 0.2s;
}

.secure {
	max-width: 560px;
	margin: 26px auto 0;
	font-size: 0.85rem;
	color: var(--muted);
	text-align: center;
	line-height: 1.6;
}

.secure b {
	color: var(--text);
}

/* ==========================================================================
   8 — Services in full
   ========================================================================== */
.services {
	background: var(--surface);
	border-top: 1px solid var(--border);
	border-bottom: 1px solid var(--border);
	padding: 64px 0;
}

.top3 {
	display: grid;
	grid-template-columns: 1fr 1.14fr 1fr;
	gap: 20px;
	align-items: center;
}

@media (max-width: 900px) {
	.top3 {
		grid-template-columns: 1fr;
	}
}

.tcard {
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 14px;
	padding: 28px;
	display: flex;
	flex-direction: column;
}

.tcard.flag {
	border-color: var(--blue);
	background: var(--panel);
	box-shadow: 0 16px 44px rgba(20, 24, 29, 0.13);
	padding: 36px 30px;
	position: relative;
	border-top: 4px solid var(--red);
}

.tcard .tier {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--blue-ink);
	margin: 0 0 8px;
	font-weight: 700;
}

.tcard h3 {
	font-size: 1.5rem;
	font-weight: 800;
	margin: 0 0 4px;
	letter-spacing: -0.025em;
}

.tcard.flag h3 {
	font-size: 1.85rem;
}

.tcard .price {
	font-size: 2.1rem;
	font-weight: 800;
	margin: 0 0 4px;
	letter-spacing: -0.03em;
}

.tcard.flag .price {
	font-size: 2.7rem;
	color: var(--red);
}

.tcard .incl {
	font-size: 0.82rem;
	color: var(--muted);
	margin: 0 0 14px;
}

.tcard p.body {
	margin: 0 0 20px;
	font-size: 0.95rem;
	color: var(--muted);
}

.tcard .btn {
	margin-top: auto;
}

.badge {
	position: absolute;
	top: -12px;
	left: 30px;
	font-size: 0.68rem;
	font-weight: 700;
	background: var(--red);
	color: var(--on-red);
	border-radius: 999px;
	padding: 4px 13px;
	letter-spacing: 0.04em;
}

.svcmore {
	display: flex;
	gap: 26px;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	margin-top: 30px;
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 24px 28px;
}

.svcmore > div {
	max-width: none;
	flex: 1 1 560px;
}

.svcmore .cols {
	columns: 2;
	column-gap: 34px;
	column-rule: 1px solid var(--border);
}

@media (max-width: 760px) {
	.svcmore .cols {
		columns: 1;
	}
}

.svcmore .cols p {
	margin: 0;
}

.svcmore b {
	display: block;
	font-size: 1.06rem;
	color: var(--text);
	margin-bottom: 5px;
	letter-spacing: -0.015em;
}

.svcmore p {
	margin: 0;
	font-size: 0.95rem;
	color: var(--muted);
}

.ceiling {
	max-width: 560px;
	margin: 22px auto 0;
	background: var(--panel);
	border: 1px solid var(--border);
	border-left: 3px solid var(--red);
	border-radius: 0 10px 10px 0;
	padding: 15px 20px;
}

.ceiling .lbl {
	font-family: var(--mono);
	font-size: 0.64rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--blue-ink);
	font-weight: 700;
	margin: 0 0 5px;
}

.ceiling p {
	margin: 0;
	font-size: 0.93rem;
	color: var(--muted);
}

/* ==========================================================================
   9 — Where AI stands
   ========================================================================== */
.humansec {
	padding: 34px 0 60px;
}

.human {
	background: var(--navy);
	color: #e8edf2;
	border-radius: 4px 14px 14px 4px;
	border-left: 5px solid var(--red);
	padding: 30px 34px;
}

.human .head {
	display: flex;
	gap: 18px;
	align-items: flex-start;
	margin-bottom: 6px;
}

.human .glyph {
	flex: 0 0 46px;
	margin-top: 2px;
}

.human .lead {
	font-size: 1.02rem;
	color: #b9c4ce;
	margin: 0 0 24px;
	max-width: 40em;
}

.human .lbl {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: #8ec2dd;
	margin: 0 0 9px;
}

.human b {
	display: block;
	font-size: 1.45rem;
	color: #fff;
	margin-bottom: 9px;
	letter-spacing: -0.02em;
}

.aigrid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0;
	border: 1px solid rgba(255, 255, 255, 0.2);
	border-radius: 12px;
	overflow: hidden;
}

@media (max-width: 760px) {
	.aigrid {
		grid-template-columns: 1fr;
	}
}

.aicard {
	padding: 22px 24px;
	background: rgba(255, 255, 255, 0.045);
}

.aicard + .aicard {
	border-left: 1px solid rgba(255, 255, 255, 0.2);
}

@media (max-width: 760px) {
	.aicard + .aicard {
		border-left: 0;
		border-top: 1px solid rgba(255, 255, 255, 0.2);
	}
}

.aicard .h {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #8ec2dd;
	font-weight: 700;
	margin: 0 0 9px;
}

.aicard p {
	margin: 0;
	font-size: 0.94rem;
	color: #dbe3ea;
}

/* ==========================================================================
   10 — The Story Department family
   ========================================================================== */
.handoff {
	padding: 60px 0;
}

.hgrid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
}

@media (max-width: 860px) {
	.hgrid {
		grid-template-columns: 1fr;
	}
}

.hcard {
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 22px;
	display: flex;
	flex-direction: column;
}

.hcard .thumb {
	margin: -22px -22px 16px;
	border-radius: 12px 12px 0 0;
	overflow: hidden;
	border-bottom: 1px solid var(--border);
}

.hcard .thumb img {
	width: 100%;
	height: 104px;
	object-fit: cover;
	display: block;
}

.hcard .strip {
	margin: -22px -22px 16px;
	height: 7px;
	background: var(--blue);
	border-radius: 12px 12px 0 0;
}

.hcard b {
	display: block;
	font-size: 1.02rem;
	margin-bottom: 6px;
}

.hcard b span {
	color: var(--blue-ink);
}

.hcard p {
	margin: 0 0 14px;
	color: var(--muted);
	font-size: 0.92rem;
}

.hcard a.more {
	margin-top: auto;
	font-size: 0.9rem;
	font-weight: 600;
}

/* ==========================================================================
   Footer
   ========================================================================== */
footer.site {
	border-top: 1px solid var(--border);
	padding: 38px 0 28px;
	font-size: 0.89rem;
	background: var(--surface);
}

.fgrid {
	display: grid;
	grid-template-columns: 2fr 1fr 1fr;
	gap: 24px;
	margin-bottom: 24px;
}

@media (max-width: 820px) {
	.fgrid {
		grid-template-columns: 1fr;
	}
}

footer .fam {
	color: var(--muted);
}

footer .fam b {
	color: var(--text);
}

footer .fam img {
	width: 30px;
	height: 30px;
	display: block;
	margin-bottom: 10px;
}

footer ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

footer ul li {
	margin-bottom: 6px;
}

footer .legal {
	color: var(--muted);
	font-size: 0.79rem;
	border-top: 1px solid var(--border);
	padding-top: 16px;
}

/* Newsletter signup — one list, The Story Department's. */
.newsletter {
	background: var(--panel);
	border: 1px solid var(--border);
	border-top: 3px solid var(--red);
	border-radius: 4px 4px 12px 12px;
	padding: 20px 22px;
	margin-bottom: 24px;
}

.newsletter b {
	display: block;
	font-size: 1.02rem;
	color: var(--text);
	margin-bottom: 4px;
}

.newsletter p {
	margin: 0 0 12px;
	color: var(--muted);
	font-size: 0.88rem;
}

.newsletter form {
	display: flex;
	gap: 9px;
	flex-wrap: wrap;
}

.newsletter input[type="email"] {
	flex: 1 1 220px;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 13px;
	font: inherit;
	font-size: 0.94rem;
	background: var(--bg);
	color: var(--text);
}

/* ==========================================================================
   Small-screen adjustments (from the mockup)
   ========================================================================== */
@media (max-width: 560px) {
	/* Three things now share the header row that the mockup only had two of,
	   because the nav disclosure had to go somewhere. Without this the CTA wraps
	   to three lines on a 390px phone. The button keeps its accessible name via
	   aria-label once the word is hidden. */
	header.site .wrap {
		gap: 10px;
	}

	nav.main {
		gap: 10px;
	}

	nav.main .btn.primary.sm {
		padding: 9px 12px;
		font-size: 0.82rem;
		white-space: nowrap;
	}

	.navtoggle-label {
		display: none;
	}

	.navtoggle {
		padding: 8px 11px;
	}

	.family .lead {
		display: none;
	}

	.family .wrap {
		gap: 12px;
		font-size: 0.73rem;
	}

	.logo {
		font-size: 1rem;
	}

	.brand img {
		width: 32px;
		height: 32px;
	}

	h2.sect {
		font-size: 1.6rem;
	}
}

/* ==========================================================================
   Content pages — the reading layout
   The mockup covers the front page only. Everything below shares its type,
   cards and buttons rather than inventing a second visual language.
   ========================================================================== */
.page-head {
	border-bottom: 1px solid var(--border);
	background: var(--surface);
	padding: 46px 0 38px;
}

.page-head h1 {
	font-size: 2.2rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1.12;
	margin: 0 0 8px;
}

@media (max-width: 620px) {
	.page-head h1 {
		font-size: 1.75rem;
	}
}

.page-head .standfirst {
	color: var(--muted);
	font-size: 1.05rem;
	margin: 0;
	max-width: 40em;
}

.page-body {
	padding: 46px 0 64px;
}

.prose {
	max-width: var(--measure);
}

.prose > * + * {
	margin-top: 1.1em;
}

.prose h2 {
	font-size: 1.4rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin-top: 2em;
	margin-bottom: 0.4em;
}

.prose h3 {
	font-size: 1.12rem;
	font-weight: 700;
	margin-top: 1.6em;
	margin-bottom: 0.3em;
}

.prose ul,
.prose ol {
	padding-left: 1.3em;
}

.prose li + li {
	margin-top: 0.35em;
}

.prose img {
	height: auto;
	border-radius: var(--radius);
}

.prose hr {
	border: 0;
	border-top: 1px solid var(--border);
	margin: 2.2em 0;
}

.prose code {
	font-family: var(--mono);
	font-size: 0.9em;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 5px;
	padding: 1px 5px;
}

.prose pre {
	overflow-x: auto;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 16px;
}

.prose pre code {
	border: 0;
	background: none;
	padding: 0;
}

.prose table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.95rem;
}

.prose :is(th, td) {
	border-bottom: 1px solid var(--border);
	padding: 9px 12px;
	text-align: left;
}

.table-scroll {
	overflow-x: auto;
}

/* --- Contact form ---------------------------------------------------------- */

/*
 * The Contact template's form, beneath the page's own copy. Held to the same
 * 68ch measure as the prose above it so the page stays one column and the
 * fields do not stretch to a width nobody types into.
 *
 * Field styling deliberately matches the intake form's — same border, radius,
 * padding and panel ground — because they are the site's two public forms and a
 * visitor who has met one should recognise the other. Colours are all tokens,
 * so the dark scheme comes for free.
 */
.sd-contact {
	max-width: var(--measure);
	margin-top: 38px;
}

.sd-contact-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 18px;
}

@media (max-width: 620px) {
	.sd-contact-row {
		grid-template-columns: 1fr;
	}
}

.sd-contact-field {
	margin: 20px 0 0;
}

/* The paired row supplies its own gap; a top margin here would double it. */
.sd-contact-row .sd-contact-field {
	margin-top: 0;
}

.sd-contact-field label {
	display: block;
	margin: 0 0 5px;
	font-weight: 600;
	font-size: 0.87rem;
}

.sd-contact-optional {
	margin-left: 7px;
	font-family: var(--mono);
	font-size: 0.72rem;
	font-weight: 400;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--muted);
}

.sd-contact-field :is(input, textarea) {
	width: 100%;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 13px;
	font: inherit;
	font-size: 0.95rem;
	background: var(--panel);
	color: var(--text);
}

.sd-contact-field textarea {
	resize: vertical;
	min-height: 150px;
}

/*
 * The honeypot. Off screen rather than `display: none`, because some bots skip
 * hidden inputs and fill everything else — which is the whole point of it.
 * aria-hidden and tabindex="-1" in the markup keep it away from people.
 */
.sd-contact-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.sd-turnstile {
	margin-top: 22px;
}

.sd-contact-actions {
	margin: 26px 0 0;
}

/* The three post-redirect states. Ruled on the left like the pull-quotes, so a
   result reads as the page speaking rather than as another field. */
.sd-contact-notice {
	margin: 0 0 26px;
	border: 1px solid var(--border);
	border-left: 3px solid var(--blue);
	border-radius: 0 10px 10px 0;
	background: var(--surface);
	padding: 16px 20px;
}

.sd-contact-notice.is-error {
	border-left-color: var(--red);
}

.sd-contact-notice strong {
	display: block;
	font-size: 1.05rem;
	letter-spacing: -0.01em;
}

.sd-contact-notice p {
	margin: 6px 0 0;
	font-size: 0.92rem;
	color: var(--muted);
}

/* Shown in place of the form when the plugin is not active, so the page offers
   an address rather than a button that cannot work. */
.sd-contact-off {
	border: 1px solid var(--border);
	border-top: 3px solid var(--red);
	border-radius: 4px 4px 12px 12px;
	background: var(--panel);
	padding: 24px;
}

.sd-contact-off h2 {
	margin: 0 0 6px;
	font-size: 1.16rem;
	font-weight: 800;
	letter-spacing: -0.02em;
}

.sd-contact-off p {
	margin: 0;
	font-size: 0.92rem;
	color: var(--muted);
}

/* Verdict pull-quotes, for the sample report. */
.prose blockquote,
.verdict {
	margin: 1.6em 0;
	border-left: 3px solid var(--red);
	background: var(--surface);
	border-radius: 0 10px 10px 0;
	padding: 18px 22px;
	font-size: 1.12rem;
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: -0.01em;
}

.prose blockquote p,
.verdict p {
	margin: 0;
}

.prose blockquote cite,
.verdict cite {
	display: block;
	margin-top: 8px;
	font-size: 0.85rem;
	font-weight: 400;
	font-style: normal;
	color: var(--muted);
}

/* Report extract panel — a component, used on the sample report and wherever
   a fragment of Karel's writing is quoted as evidence. */
.extract {
	border: 1px solid var(--border);
	border-top: 4px solid var(--red);
	border-radius: 6px 6px 14px 14px;
	background: var(--panel);
	padding: 24px 26px;
	box-shadow: 0 10px 30px rgba(20, 24, 29, 0.07);
}

.extract .lbl {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--blue-ink);
	font-weight: 700;
	margin: 0 0 10px;
}

.extract h3 {
	font-size: 1.16rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin: 0 0 8px;
}

.extract > :last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   FAQ accordion — native <details>, no framework and no JS
   ========================================================================== */
.faq {
	max-width: var(--measure);
	border-top: 1px solid var(--border);
}

.faq details {
	border-bottom: 1px solid var(--border);
}

.faq summary {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 16px 0;
	font-size: 1.04rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	cursor: pointer;
	list-style: none;
}

.faq summary::-webkit-details-marker {
	display: none;
}

.faq summary::after {
	content: "+";
	margin-left: auto;
	font-family: var(--mono);
	font-size: 1.2rem;
	font-weight: 400;
	color: var(--blue-ink);
	flex: 0 0 auto;
}

.faq details[open] summary::after {
	content: "–";
}

.faq summary:hover {
	color: var(--blue-ink);
}

.faq .answer {
	padding: 0 0 18px;
	color: var(--muted);
}

.faq .answer > :first-child {
	margin-top: 0;
}

/* ==========================================================================
   Archive and search listings
   ========================================================================== */
.cardlist {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 18px;
}

.listcard {
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 20px 22px;
	display: flex;
	flex-direction: column;
}

.listcard h2 {
	font-size: 1.1rem;
	font-weight: 700;
	letter-spacing: -0.015em;
	margin: 0 0 6px;
}

.listcard h2 a {
	color: var(--text);
}

.listcard .meta {
	font-size: 0.8rem;
	color: var(--muted);
	margin: 0 0 10px;
}

.listcard p {
	margin: 0 0 14px;
	color: var(--muted);
	font-size: 0.93rem;
}

.listcard .more {
	margin-top: auto;
	font-size: 0.9rem;
	font-weight: 600;
}

.pager {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin-top: 34px;
}

.pager .page-numbers {
	border: 1px solid var(--border);
	border-radius: 8px;
	padding: 8px 14px;
	color: var(--text);
	font-size: 0.92rem;
	font-weight: 600;
	background: var(--panel);
}

.pager .page-numbers:hover {
	border-color: var(--blue-ink);
	text-decoration: none;
}

.pager .page-numbers.current {
	background: var(--blue-ink);
	border-color: var(--blue-ink);
	color: var(--on-blue);
}

.searchform {
	display: flex;
	gap: 9px;
	flex-wrap: wrap;
	max-width: 480px;
}

.searchform input[type="search"] {
	flex: 1 1 200px;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 13px;
	font: inherit;
	font-size: 0.95rem;
	background: var(--panel);
	color: var(--text);
}

/* ==========================================================================
   404
   ========================================================================== */
.notfound {
	padding: 70px 0 80px;
	text-align: center;
}

.notfound .code {
	font-family: var(--mono);
	font-size: 0.8rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--blue-ink);
	font-weight: 700;
	margin: 0 0 12px;
}

.notfound h1 {
	font-size: 2.1rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	margin: 0 0 10px;
}

.notfound p {
	color: var(--muted);
	max-width: 34em;
	margin: 0 auto 22px;
}

.notfound .searchform {
	margin: 0 auto 26px;
	justify-content: center;
}

/* ==========================================================================
   Small corrections where semantics differ from the mockup's markup
   The mockup set testimonials as bare <p>s; the theme uses figure/blockquote,
   which is better for a screen reader and carries a user-agent margin the
   mockup never had to cancel.
   ========================================================================== */
.quote blockquote {
	margin: 0;
}

.quote figcaption {
	font-size: 0.85rem;
	color: var(--muted);
}

/* ==========================================================================
   Services page — the per-tier detail rows under the cards
   ========================================================================== */
.tierdetail {
	display: flex;
	flex-direction: column;
	gap: 28px;
}

.tierrow {
	display: grid;
	grid-template-columns: 1.6fr 1fr;
	gap: 28px;
	border-top: 2px solid var(--border);
	padding-top: 22px;
	scroll-margin-top: 90px;
}

@media (max-width: 760px) {
	.tierrow {
		grid-template-columns: 1fr;
		gap: 16px;
	}
}

.tierrow h2 {
	font-size: 1.5rem;
	font-weight: 800;
	letter-spacing: -0.025em;
	margin: 0 0 6px;
}

.tierrow .tier {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--blue-ink);
	font-weight: 700;
	margin: 0 0 6px;
}

.tierrow .who {
	font-weight: 600;
	margin: 0 0 10px;
}

.tierrow p {
	color: var(--muted);
	font-size: 0.96rem;
	margin: 0;
}

.tierrow dl {
	margin: 0;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 18px 20px;
	align-self: start;
}

.tierrow dt {
	font-family: var(--mono);
	font-size: 0.64rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--muted);
	font-weight: 700;
}

.tierrow dd {
	margin: 2px 0 12px;
	font-size: 0.95rem;
}

.tierrow dd:last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   WooCommerce
   Woo's three stylesheets are dequeued (inc/woocommerce.php), so everything a
   shop needs is here. It is deliberately the same handful of primitives as the
   rest of the site — cards, buttons, the type scale — rather than a second
   design that happens to sit on the same domain.
   ========================================================================== */

/* --- Buttons Woo renders itself ---------------------------------------- */
.woocommerce .button,
.sd-woo button[type="submit"],
.sd-woo .button,
.sd-woo a.button,
.sd-woo input[type="submit"] {
	display: inline-block;
	font: inherit;
	font-weight: 600;
	border-radius: 8px;
	padding: 12px 22px;
	cursor: pointer;
	border: 1px solid transparent;
	background: var(--blue-ink);
	color: var(--on-blue);
	text-decoration: none;
	text-align: center;
}

.sd-woo .button:hover,
.sd-woo a.button:hover,
.sd-woo button[type="submit"]:hover,
.sd-woo input[type="submit"]:hover {
	background: var(--blue-hover);
	text-decoration: none;
}

.sd-woo .button:disabled,
.sd-woo button[disabled] {
	opacity: 0.45;
	cursor: not-allowed;
}

.sd-woo .button.alt,
.sd-woo #place_order {
	background: var(--red);
	color: var(--on-red);
}

.sd-woo .button.alt:hover,
.sd-woo #place_order:hover {
	filter: brightness(0.92);
}

/* --- Product archive --------------------------------------------------- */
.sd-woo ul.products {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 20px;
}

.sd-woo ul.products li.product {
	--sd-card-pad: 24px;
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 14px;
	padding: var(--sd-card-pad);
	display: flex;
	flex-direction: column;
	text-align: left;
	/* The containing block for the sale badge, which is taken out of flow so it
	   cannot push this card's image down past its neighbours'. */
	position: relative;
}

.sd-woo ul.products li.product a {
	text-decoration: none;
}

.sd-woo ul.products li.product img {
	border-radius: 10px;
	margin-bottom: 14px;
	height: auto;
}

.sd-woo ul.products li.product .woocommerce-loop-product__title {
	font-size: 1.32rem;
	font-weight: 800;
	letter-spacing: -0.025em;
	color: var(--text);
	margin: 0 0 6px;
	line-height: 1.2;
}

.sd-woo ul.products li.product .price {
	display: block;
	font-size: 1.9rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	color: var(--text);
	margin-bottom: 14px;
}

.sd-woo ul.products li.product .price del {
	color: var(--muted);
	font-size: 0.6em;
	font-weight: 600;
	margin-right: 6px;
}

.sd-woo ul.products li.product .price ins {
	text-decoration: none;
}

.sd-woo ul.products li.product .button {
	margin-top: auto;
	align-self: flex-start;
}

/*
 * The sale badge sits ON the image, never above it.
 *
 * WooCommerce prints this span as the first child of the card's link and of
 * div.product, ahead of the image in both. Left in normal flow it takes a line
 * of its own, so a discounted product's image started 38px lower than every
 * full-price one beside it — the shop grid read as misaligned, and on a product
 * page the featured image was pushed toward the fold. Taking it out of flow is
 * the fix: the badge occupies no height, so every card's image starts at the
 * same place whether or not the product is on sale.
 *
 * Inset from the card's own padding rather than a magic number, so it stays in
 * the image's corner if that padding is ever changed.
 */
.sd-woo .onsale {
	position: absolute;
	z-index: 2;
	margin: 0;
	background: var(--red);
	color: var(--on-red);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	border-radius: 999px;
	padding: 3px 12px;
	/* It is decoration over a link; let the click through to the image beneath. */
	pointer-events: none;
}

.sd-woo ul.products li.product .onsale {
	top: calc( var(--sd-card-pad) + 10px );
	left: calc( var(--sd-card-pad) + 10px );
}

/* --- Single product ---------------------------------------------------- */
.sd-woo div.product {
	display: grid;
	grid-template-columns: 1fr 1.1fr;
	gap: 40px;
	align-items: start;
	/* Containing block for the sale badge — see .sd-woo .onsale above. */
	position: relative;
}

/* Over the gallery's top-left corner, which is this grid's first column at
   every width (the layout collapses to one column below 860px, gallery first). */
.sd-woo div.product .onsale {
	top: 12px;
	left: 12px;
}

@media (max-width: 860px) {
	.sd-woo div.product {
		grid-template-columns: 1fr;
		gap: 24px;
	}
}

.sd-woo div.product .woocommerce-product-gallery img {
	border-radius: var(--radius);
	height: auto;
}

.sd-woo div.product .summary {
	max-width: 34em;
}

.sd-woo div.product .price {
	font-size: 2.7rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	color: var(--red);
	margin: 0 0 6px;
}

.sd-woo div.product .woocommerce-product-details__short-description {
	color: var(--muted);
	margin-bottom: 22px;
}

.sd-woo div.product form.cart {
	display: flex;
	gap: 12px;
	align-items: center;
	flex-wrap: wrap;
	margin-bottom: 24px;
}

.sd-woo .quantity input {
	width: 5em;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 10px;
	font: inherit;
	background: var(--panel);
	color: var(--text);
	text-align: center;
}

.sd-woo .product_meta {
	font-size: 0.85rem;
	color: var(--muted);
	border-top: 1px solid var(--border);
	padding-top: 14px;
}

/* Woo's tab strip, reduced to headings — one service has little to tab between. */
.sd-woo .woocommerce-tabs {
	grid-column: 1 / -1;
	border-top: 1px solid var(--border);
	padding-top: 30px;
}

.sd-woo .woocommerce-tabs ul.tabs {
	list-style: none;
	margin: 0 0 20px;
	padding: 0;
	display: flex;
	gap: 20px;
	flex-wrap: wrap;
}

.sd-woo .woocommerce-tabs ul.tabs a {
	font-weight: 700;
	font-size: 0.95rem;
	color: var(--muted);
}

.sd-woo .woocommerce-tabs ul.tabs li.active a {
	color: var(--text);
}

.sd-woo .woocommerce-tabs .panel {
	max-width: var(--measure);
}

.sd-woo .related,
.sd-woo .up-sells {
	grid-column: 1 / -1;
	border-top: 1px solid var(--border);
	padding-top: 30px;
}

.sd-woo .related > h2,
.sd-woo .up-sells > h2 {
	font-size: 1.4rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin: 0 0 18px;
}

/* --- Tables: cart and order review ------------------------------------ */
.sd-woo table.shop_table {
	width: 100%;
	border-collapse: collapse;
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	overflow: hidden;
	margin-bottom: 24px;
}

.sd-woo table.shop_table :is(th, td) {
	padding: 14px 16px;
	text-align: left;
	border-bottom: 1px solid var(--border);
	font-size: 0.95rem;
	vertical-align: middle;
}

.sd-woo table.shop_table th {
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--muted);
	background: var(--surface);
}

.sd-woo table.shop_table tr:last-child :is(th, td) {
	border-bottom: 0;
}

.sd-woo table.shop_table img {
	width: 54px;
	height: auto;
	border-radius: 6px;
}

.sd-woo .cart_item .product-name a {
	font-weight: 700;
	color: var(--text);
}

.sd-woo .product-remove a {
	color: var(--muted);
	font-size: 1.2rem;
	text-decoration: none;
}

.sd-woo .product-remove a:hover {
	color: var(--red);
}

.sd-woo .cart-collaterals {
	max-width: 420px;
	margin-left: auto;
}

.sd-woo .cart_totals h2,
.sd-woo #order_review_heading {
	font-size: 1.2rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin: 0 0 14px;
}

.sd-woo .order-total :is(th, td) {
	font-weight: 800;
	font-size: 1.05rem;
}

.sd-woo .coupon {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin-bottom: 18px;
}

/* --- Forms: checkout, account, addresses ------------------------------ */
.sd-woo form .form-row {
	margin-bottom: 16px;
}

.sd-woo form label {
	display: block;
	font-weight: 600;
	font-size: 0.87rem;
	margin-bottom: 5px;
}

.sd-woo :is(input[type="text"], input[type="email"], input[type="tel"], input[type="password"], input[type="number"], select, textarea) {
	width: 100%;
	border: 1px solid var(--border);
	border-radius: 9px;
	padding: 11px 13px;
	font: inherit;
	font-size: 0.95rem;
	background: var(--panel);
	color: var(--text);
}

.sd-woo textarea {
	min-height: 96px;
	resize: vertical;
}

.sd-woo .woocommerce-checkout .col2-set {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 28px;
}

@media (max-width: 760px) {
	.sd-woo .woocommerce-checkout .col2-set {
		grid-template-columns: 1fr;
		gap: 8px;
	}
}

.sd-woo #customer_details h3,
.sd-woo .woocommerce-billing-fields h3 {
	font-size: 1.2rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	margin: 0 0 14px;
}

.sd-woo #payment {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 20px 22px;
}

.sd-woo #payment ul.payment_methods {
	list-style: none;
	margin: 0 0 16px;
	padding: 0;
}

.sd-woo #payment ul.payment_methods li + li {
	margin-top: 10px;
}

.sd-woo #payment label {
	display: inline;
	font-weight: 600;
}

.sd-woo #place_order {
	width: 100%;
	padding: 15px 22px;
	font-size: 1.02rem;
}

/* The trust row, immediately above the place-order button where it is read. */
.trustrow {
	list-style: none;
	margin: 0 0 18px;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 14px;
	font-size: 0.84rem;
	color: var(--muted);
}

@media (max-width: 700px) {
	.trustrow {
		grid-template-columns: 1fr;
		gap: 10px;
	}
}

.trustrow li {
	background: var(--panel);
	border: 1px solid var(--border);
	border-top: 3px solid var(--red);
	border-radius: 4px 4px 10px 10px;
	padding: 12px 14px;
	line-height: 1.45;
}

.trustrow strong {
	display: block;
	color: var(--text);
	font-size: 0.9rem;
	margin-bottom: 2px;
}

/* --- Account ---------------------------------------------------------- */
.sd-woo .woocommerce-MyAccount-navigation ul {
	list-style: none;
	margin: 0 0 24px;
	padding: 0;
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
}

.sd-woo .woocommerce-MyAccount-navigation a {
	display: inline-block;
	border: 1px solid var(--border);
	border-radius: 8px;
	padding: 8px 14px;
	font-size: 0.92rem;
	font-weight: 600;
	color: var(--text);
	background: var(--panel);
}

.sd-woo .woocommerce-MyAccount-navigation a:hover {
	border-color: var(--blue-ink);
	text-decoration: none;
}

.sd-woo .woocommerce-MyAccount-navigation li.is-active a {
	background: var(--blue-ink);
	border-color: var(--blue-ink);
	color: var(--on-blue);
}

.sd-woo .woocommerce-MyAccount-content {
	max-width: var(--measure);
}

/* --- Notices ---------------------------------------------------------- */
.sd-woo :is(.woocommerce-message, .woocommerce-info, .woocommerce-error) {
	list-style: none;
	margin: 0 0 24px;
	padding: 14px 18px;
	border: 1px solid var(--border);
	border-left: 3px solid var(--blue);
	border-radius: 0 10px 10px 0;
	background: var(--surface);
	font-size: 0.95rem;
}

.sd-woo .woocommerce-error {
	border-left-color: var(--red);
}

.sd-woo :is(.woocommerce-message, .woocommerce-info, .woocommerce-error) .button {
	float: right;
	margin-left: 16px;
	padding: 7px 14px;
	font-size: 0.88rem;
}

/* --- Thank-you page --------------------------------------------------- */
.sd-woo ul.woocommerce-order-overview {
	list-style: none;
	margin: 0 0 28px;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 14px;
}

.sd-woo ul.woocommerce-order-overview li {
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 14px 16px;
	font-family: var(--mono);
	font-size: 0.66rem;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--muted);
}

.sd-woo ul.woocommerce-order-overview li strong {
	display: block;
	margin-top: 5px;
	font-family: var(--font);
	font-size: 1.02rem;
	letter-spacing: -0.01em;
	text-transform: none;
	color: var(--text);
}

/* Anything Woo renders that this stylesheet hasn't reached: keep it readable
   and keep it from breaking the page's horizontal scroll. */
.sd-woo .woocommerce {
	max-width: 100%;
}

.sd-woo .woocommerce-Price-amount {
	white-space: nowrap;
}

/* ==========================================================================
   Script Services — the index
   --------------------------------------------------------------------------
   A hairline table. Every row rides ONE grid — header, service, extras and the
   closing row alike — because the columns reading straight down the page is
   what makes this an index rather than a list of cards. Change .sd-services-row
   and every row moves together; that is the point, so do not give a row type
   its own columns.

   Nothing here is rounded. The design is square throughout, deliberately, in
   contrast to the rest of the site's 10px radius.
   ========================================================================== */
.sd-services {
	color: var(--ink);
	/*
	 * Contained, or the 1fr title column grows without limit on a wide monitor
	 * and opens a lake of white between the excerpt (which stops at 32em) and
	 * the production column.
	 *
	 * 1184px is not arbitrary: the site's `.wrap` is 1120px wide including 24px
	 * of padding, so its content sits 1072px across. This block keeps the
	 * design's 56px gutter, so 1072 + 56 + 56 = 1184 puts its content on exactly
	 * the same edges — the table lines up with the logo above it and the footer
	 * below, which it would not do at the mock's own 1280 canvas.
	 */
	max-width: 1184px;
	margin-inline: auto;
}

.sd-services-masthead {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 40px;
	padding: 78px 56px 44px;
	border-bottom: 1px solid var(--ink);
}

.sd-services-kicker {
	margin: 0 0 14px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--red);
}

.sd-services-h1 {
	margin: 0;
	font-size: 66px;
	line-height: 0.98;
	letter-spacing: -0.04em;
	color: var(--ink);
}

.sd-services-standfirst {
	margin: 0;
	text-align: right;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.16em;
	line-height: 1.9;
	text-transform: uppercase;
	color: var(--meta);
	white-space: nowrap;
}

.sd-services-table {
	padding: 0 56px;
}

/* The one grid. */
/*
 * The one grid. `minmax(0, 300px)` rather than a flat 300px so the production
 * column gives way before the copy column does — at middling widths the fixed
 * version squeezed the excerpt into a narrow ribbon beside 300px of nothing.
 */
.sd-services-row {
	display: grid;
	grid-template-columns: 96px minmax( 0, 1fr ) minmax( 0, 300px ) 150px;
	gap: 32px;
	align-items: center;
}

/* Nothing to print in it: don't reserve it. */
.sd-services-table--no-production .sd-services-row {
	grid-template-columns: 96px minmax( 0, 1fr ) 150px;
}

.sd-services-table--no-production .sd-services-cell--production,
.sd-services-table--no-production .sd-services-row--head .sd-services-cell:nth-child( 3 ) {
	display: none;
}

.sd-services-row--head {
	padding: 15px 0;
	border-bottom: 1px solid var(--rule);
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-services-row--item {
	padding: 26px 0;
	border-bottom: 1px solid var(--rule);
}

/* Banding, so a long index is easier to read across. Deliberately slight: the
   tint is the same one the closing row uses, and at #fbfbfa it reads as a change
   of ground rather than as a highlighted row. The mocks have no banding — this
   is a later call by Karel, recorded here so it is not "corrected" back later. */
.sd-services-row--alt {
	background: var(--row-tint);
	/* The tint has to reach the container's edge, not stop at the text. */
	box-shadow: -56px 0 0 var(--row-tint), 56px 0 0 var(--row-tint);
}

/* The last extras row closes the table against the ink rule. */
.sd-services-extras .sd-services-row--item:last-child {
	border-bottom: 1px solid var(--ink);
}

/*
 * Every plate the same height, and that height is the tallest row's.
 *
 * Letting each plate stretch to its own row made them ragged — 84px against a
 * neighbour's 105px, because the height of a row is set by how much copy it
 * carries, which has nothing to do with the picture. One number for all of them
 * reads as a column; seven different ones read as an accident.
 *
 * 105px is what the tallest row (Story Notes) measured. It is a single custom
 * property on purpose: if the copy grows and a row outgrows it, change this and
 * every plate follows. `align-self: start` keeps the top level with the service
 * name, and the artwork stays centred while the ground fills whatever is left.
 */
.sd-services {
	--sd-plate-h: 105px;
}

.sd-services-cell--plate {
	align-self: start;
}

.sd-services-cell--plate > a {
	display: block;
}

.sd-plate {
	display: block;
	width: 96px;
	height: var(--sd-plate-h);
	object-fit: cover;
	border: 0;
	border-radius: 0;
}

.sd-plate--painted {
	background-repeat: no-repeat;
	background-position: center;
	/* Scaled to the width, so the artwork keeps its size while the field grows. */
	background-size: 100% auto;
}

.sd-plate--empty {
	display: block;
	background: var(--row-tint);
	border: 1px solid var(--rule);
}

.sd-services-title {
	margin: 0 0 6px;
	font-size: 25px;
	font-weight: 700;
	letter-spacing: -0.025em;
	line-height: 1.15;
}

.sd-services-title a {
	color: var(--ink);
	text-decoration: none;
}

.sd-services-title a:hover,
.sd-services-title a:focus-visible {
	color: var(--red);
}

.sd-services-excerpt {
	margin: 0;
	font-size: 15px;
	color: var(--muted);
	max-width: 32em;
	text-wrap: pretty;
}

/* The production column stays quiet on purpose — it is reference, not copy. */
.sd-services-cell--production {
	display: flex;
	flex-direction: column;
}

.sd-services-production-line {
	font-family: var(--mono);
	font-size: 10.5px;
	letter-spacing: 0.13em;
	line-height: 2;
	text-transform: uppercase;
	color: var(--muted);
	/* Room for the bullet, so a wrapped second line sits under the text and
	   not under the dot. */
	padding-left: 12px;
	text-indent: -12px;
}

/*
 * The bullet is the theme's, not the author's — every row gets one whether or
 * not somebody typed a dot into the field, and `sd_service_spec()` strips the
 * typed ones so the two can never stack up.
 */
.sd-services-production-line::before {
	content: "·";
	margin-right: 6px;
	color: var(--muted);
}

/* The same three values, folded under the excerpt at narrow widths. */
.sd-services-production--inline {
	display: none;
	margin: 8px 0 0;
	font-family: var(--mono);
	font-size: 10.5px;
	letter-spacing: 0.13em;
	line-height: 1.9;
	text-transform: uppercase;
	color: var(--muted);
}

.sd-services-cell--price {
	text-align: right;
}

/* MOST BOOKED tag — the stage selector's recommended-chip accent: a filled
 * accent plate with reversed text, mono, on one card only (brief §6). */
.sd-services-scope {
	margin: 6px 0 0;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.04em;
	color: var(--meta);
}

.sd-services-tag {
	display: inline-block;
	margin: 8px 0 0;
	padding: 3px 8px;
	font-family: var(--mono);
	font-size: 9px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: #fff;
	background: var(--red);
	border-radius: 4px;
}

.sd-services-price {
	display: block;
	font-size: 26px;
	font-weight: 700;
	letter-spacing: -0.02em;
	color: var(--ink);
}

.sd-services-rrp {
	display: block;
	margin-top: 2px;
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--meta);
	text-decoration: line-through;
}

.sd-services-cta {
	display: inline-block;
	margin-top: 10px;
	font-family: var(--mono);
	font-size: 12px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--red);
	text-decoration: none;
	background: none;
	border: 0;
	padding: 0;
	border-radius: 0;
}

.sd-services-cta:hover,
.sd-services-cta:focus-visible {
	text-decoration: underline;
}

.sd-services-extras-label,
.sd-services-specialist-label {
	margin: 0;
	padding: 34px 0 15px;
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--red);
}

.sd-services-closing {
	margin-top: 0;
	padding: 22px 56px;
	background: var(--row-tint);
	border-top: 1px solid var(--rule);
	border-bottom: 1px solid var(--rule);
}

.sd-services-closing-label {
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-services-closing-copy {
	font-size: 15px;
	color: var(--ink);
}

.sd-services-closing .sd-services-cta {
	margin-top: 0;
}

.sd-services-empty {
	padding: 40px 0;
	color: var(--muted);
}

/* --- Buy-time options (product page: pages, delivery, follow-up call) ------ */
.sd-buy-options {
	display: flex;
	flex-direction: column;
	gap: 18px;
	margin: 0 0 20px;
}

.sd-buy-option {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.sd-buy-pages label,
.sd-buy-option legend {
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--meta);
	padding: 0;
}

.sd-buy-pages input[type="number"] {
	max-width: 120px;
	padding: 9px 12px;
	font-size: 16px;
	border: 1px solid var(--border);
	border-radius: 8px;
	background: var(--bg);
	color: var(--ink);
}

.sd-buy-note {
	font-size: 13px;
	line-height: 1.5;
	color: var(--muted);
}

.sd-buy-option fieldset,
fieldset.sd-buy-option {
	border: 0;
	padding: 0;
	margin: 0;
}

.sd-buy-radio {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 9px 0;
	border-top: 1px solid var(--rule);
	cursor: pointer;
}

.sd-buy-radio:first-of-type {
	border-top: 0;
}

.sd-buy-radio input {
	margin: 0;
}

.sd-buy-radio-main {
	flex: 1 1 auto;
	color: var(--ink);
}

.sd-buy-radio-x {
	flex: none;
	font-family: var(--mono);
	font-size: 12px;
	letter-spacing: 0.04em;
	color: var(--muted);
}

.sd-buy-eta {
	font-size: 14px;
	color: var(--ink);
}

/* --- Sample report: the email gate, the PDF, the cross-links (§9) ---------- */
.sd-report-gate {
	max-width: 620px;
	margin: 8px 0 12px;
	padding: 28px 30px;
	border: 1px solid var(--border);
	border-radius: 14px;
	background: var(--surface);
}

.sd-report-gate-lead {
	margin: 0 0 16px;
	font-size: 17px;
	line-height: 1.5;
	color: var(--ink);
}

.sd-report-gate-form {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
}

.sd-report-gate-form input[type="email"] {
	flex: 1 1 260px;
	padding: 12px 14px;
	font-size: 16px;
	border: 1px solid var(--border);
	border-radius: 9px;
	background: var(--bg);
	color: var(--ink);
}

.sd-report-gate-form button {
	flex: none;
	padding: 12px 22px;
	font-family: var(--mono);
	font-size: 13px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: #fff;
	background: var(--blue);
	border: 0;
	border-radius: 9px;
	cursor: pointer;
}

.sd-report-gate-form button:hover {
	background: var(--blue-hover);
}

.sd-report-gate-note {
	margin: 14px 0 0;
	font-size: 13px;
	color: var(--muted);
}

.sd-report-gate-error {
	margin: 0 0 12px;
	color: var(--red);
	font-size: 14px;
}

.sd-report-pdf {
	margin: 0 0 20px;
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}

.sd-report-pdf-note {
	font-size: 13px;
	color: var(--muted);
}

.sd-services-sample a,
.sd-service-sample a {
	font-family: var(--mono);
	font-size: 12px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--blue-ink);
	text-decoration: none;
}

.sd-services-sample a:hover,
.sd-service-sample a:hover {
	text-decoration: underline;
}

.sd-services-sample {
	margin: 12px 0 0;
}

.sd-service-sample {
	margin: 0 0 18px;
}

/* Risk-reversal guarantee on report-returning product pages (§12). */
.sd-service-guarantee {
	margin: 18px 0 0;
	padding: 16px 18px;
	border: 1px solid var(--border);
	border-left: 3px solid var(--blue);
	border-radius: 0 10px 10px 0;
	background: var(--surface);
}

.sd-service-guarantee-body {
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--ink);
}

.sd-buy-wait {
	margin: 0;
	font-size: 13px;
	color: var(--muted);
}

.sd-enquiry-start,
.sd-service-start {
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.06em;
	color: var(--muted);
}

.sd-service-start {
	margin: 4px 0 0;
}

/* --- Enquiry band (services index, above the selector) ------------------- */
/*
 * The bespoke, high-value services, read before the fixed-price catalogue
 * (brief §6). A premium navy panel — the dark treatment the homepage uses for
 * its own service band — so it reads as a tier of its own rather than a pale
 * box, and holds one service or two without looking empty. Each service is a
 * card within the panel; the outlined light CTA marks the enquiry action apart
 * from the red "add to cart" of the catalogue below.
 */
.sd-enquiry {
	margin: 0 0 42px;
	padding: clamp(22px, 4vw, 38px);
	background: var(--navy);
	color: #e8edf2;
	border-radius: 16px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 16px 44px rgba(16, 32, 43, .16);
}

.sd-enquiry-eyebrow {
	margin: 0;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: #8ec2dd;
}

.sd-enquiry-list {
	display: grid;
	gap: 16px;
	margin-top: 18px;
}

/* Two across when there is room, so a pair sits side by side; a lone service
   fills one comfortable column instead of stretching the whole width. */
@media (min-width: 720px) {
	.sd-enquiry-list { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

.sd-enquiry-item {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 22px 24px;
	background: var(--navy-2);
	border: 1px solid rgba(255, 255, 255, .10);
	border-radius: 12px;
}

.sd-enquiry-name {
	margin: 0;
	font-size: 21px;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.15;
}

.sd-enquiry-name a { color: #fff; text-decoration: none; }
.sd-enquiry-name a:hover,
.sd-enquiry-name a:focus-visible { color: #8ec2dd; text-decoration: underline; }

.sd-enquiry-lede {
	margin: 0;
	font-size: 14.5px;
	line-height: 1.55;
	color: #b9c4ce;
	max-width: 48ch;
}

.sd-enquiry-buy {
	margin-top: auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px 20px;
	flex-wrap: wrap;
	padding-top: 6px;
}

.sd-enquiry-figures { display: flex; flex-direction: column; gap: 2px; }

.sd-enquiry-price {
	font-size: 22px;
	font-weight: 700;
	letter-spacing: -.02em;
	color: #fff;
}

.sd-enquiry-start {
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: #8ea3b4;
}

.sd-enquiry-cta {
	flex: none;
	font-family: var(--mono);
	font-size: 12px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--navy);
	background: #cfe1ec;
	text-decoration: none;
	border-radius: 8px;
	padding: 11px 18px;
	transition: background .15s, color .15s;
}

.sd-enquiry-cta:hover,
.sd-enquiry-cta:focus-visible { background: #fff; color: var(--navy); }

/* --- Narrow ------------------------------------------------------------- */
/*
 * Collapse at 1100px, not 860. Between those two the fixed middle and price
 * columns leave the copy column too narrow to read — the state in the report:
 * a tall ribbon of text beside a wide empty field.
 */
@media (max-width: 1100px) {
	.sd-services-masthead {
		display: block;
		padding: 44px 24px 26px;
	}

	.sd-services-h1 {
		font-size: 40px;
	}

	.sd-services-standfirst {
		margin-top: 18px;
		text-align: left;
		white-space: normal;
	}

	.sd-services-table {
		padding: 0 24px;
	}

	/* Thumbnail beside the text, price and CTA sharing the row beneath it. */
	.sd-services-row {
		grid-template-columns: 96px 1fr;
		gap: 18px;
	}

	.sd-services-row--head {
		display: none;
	}

	.sd-services-cell--production {
		display: none;
	}

	.sd-services-production--inline {
		display: block;
	}

	.sd-services-cell--price {
		grid-column: 1 / -1;
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 16px;
		text-align: left;
		margin-top: 14px;
	}

	.sd-services-rrp {
		margin-top: 0;
	}

	.sd-services-cta {
		margin-top: 0;
	}

	.sd-services-closing {
		padding: 20px 24px;
	}

	.sd-services-closing .sd-services-row {
		grid-template-columns: 1fr;
		gap: 8px;
	}

	.sd-services-closing .sd-services-cell--price {
		grid-column: auto;
		margin-top: 4px;
	}
}


/* ==========================================================================
   Script Services — a service's page (option 3c, the two-tone split)
   --------------------------------------------------------------------------
   Breadcrumb strip, then two full-height columns meeting on a hairline: white
   on the left (plate, spec, description, steps), a paper wash on the right
   (name, price, caveat). The wash runs the whole column — that is why these are
   stretched grid children and not a pair of stacked sections.

   Square throughout, with ONE exception the brief is explicit about: the plate
   keeps a 12px radius. Everything else — price box, stepper, button — is square.
   ========================================================================== */
.sd-service {
	color: var(--ink);
	/*
	 * How far the two bleeding elements reach past the container to touch the
	 * page edge. Zero once the viewport is narrower than the container, so the
	 * same rules do nothing on a phone instead of needing a second set.
	 */
	--sd-container: 1184px;
	--sd-bleed: max( 0px, ( 100vw - var(--sd-container) ) / 2 );
	/*
	 * The bleed is sized off 100vw, which counts the scrollbar on the platforms
	 * that overlay one. Clipping here keeps a stray pixel or two from becoming a
	 * horizontal scrollbar; it cannot clip anything wanted, because nothing in
	 * this block is meant to sit outside the page.
	 */
	overflow-x: clip;
}

/* Contained, like the index — the copy lines up with the header above it. What
   escapes the container is the wash and the plate band, and only those. */
.sd-service-crumbs,
.sd-service-split {
	max-width: var(--sd-container);
	margin-inline: auto;
}

.sd-service-crumbs {
	padding: 22px 48px;
	border-bottom: 1px solid var(--border);
	font-size: 14px;
	color: var(--muted);
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.sd-service-crumbs a {
	color: var(--muted);
	text-decoration: none;
}

.sd-service-crumbs a:hover {
	color: var(--red);
}

.sd-service-crumbs-current {
	font-weight: 600;
	color: var(--ink);
}

/*
 * Two columns, two rows. The band and the body are separate grid children of
 * the split rather than a wrapped left column, because that is what lets the
 * phone layout lift the band above the H1 — `order` reaches siblings, never out
 * of a parent. The wash spans both rows on the right.
 */
/*
 * 51/49 rather than the 55/45 this shipped with. The wash carries a 52px H1, a
 * 20px lede, four labelled values and a price box, and at 45% of 1184px its
 * content well was 421px — enough that "Written report + scorecard" fitted, and
 * not enough that anything longer did. Four points off the left column buys the
 * right one 63px, about 12% more room, which is the difference between a value
 * wrapping and not. The left column keeps 460px of measure for 19px body copy,
 * inside the range that reads.
 *
 * The band bleeds to the seam, so it narrows with the column and simply shows
 * less of the plate's own ground. Nothing is re-cropped.
 */
.sd-service-split {
	display: grid;
	grid-template-columns: 51% 49%;
	grid-template-rows: auto 1fr;
	align-items: stretch;
	background: var(--panel);
}

.sd-service-band {
	grid-column: 1;
	grid-row: 1;
}

.sd-service-left-body {
	grid-column: 1;
	grid-row: 2;
	min-width: 0;
	/* So the repeat CTA can be pushed to the foot of the column. */
	display: flex;
	flex-direction: column;
}

.sd-service-right {
	grid-column: 2;
	grid-row: 1 / span 2;
	min-width: 0;
}

/*
 * The band. 268px of it, plus the 54px of padding below, is what puts the spec
 * list's top rule level with the top of the price box opposite — 322px from the
 * top of the split, which is the pairing the design is built on. Change the band
 * height, the right column's copy or the type sizes and that padding has to be
 * re-tuned to keep the two frames level.
 *
 * The artwork carries its own clearance inside the file, so it is never padded,
 * inset or rounded here.
 */
.sd-service-band {
	display: block;
	/* Runs from the page's left edge to the seam. The wide plate has ground to
	   spare on both sides, so widening the frame shows more of the artwork's
	   own margin rather than stretching or re-cropping it. */
	width: calc( 100% + var(--sd-bleed) );
	/* The base stylesheet caps every image at `max-width: 100%`, which silently
	   clamped this back to the column and left the band stopping short of the
	   seam. It is the one image on the site that is meant to be wider than its
	   container. */
	max-width: none;
	margin-left: calc( -1 * var(--sd-bleed) );
	height: 268px;
	object-fit: cover;
	border-radius: 0;
}

/*
 * The painted band: ground as a colour, artwork as an image on top.
 *
 * Why not simply a wider <img>: the band is wider than the column by the bleed,
 * so an image centred in it sits half the bleed left of the column's content —
 * which is exactly what it looked like. And no re-exported asset can fix that,
 * because the bleed is a function of the window width: an image cut to look
 * centred at 1600px is off at 1440px and off again at 1920px.
 *
 * So the artwork is positioned instead. `50%` centres it in the band; adding
 * half the bleed slides it back over the column's centre, at any width. The
 * strip it leaves bare either side is the ground colour, flat, so the join is
 * invisible.
 */
.sd-service-band--painted {
	background-repeat: no-repeat;
	/* Scale by height so the artwork keeps its proportions and its own clearance. */
	background-size: auto 100%;
	background-position: calc( 50% + var(--sd-bleed) / 2 ) center;
}

.sd-service-left-body {
	padding: 54px 72px 72px;
}

/*
 * Flush under "Best for", whose bottom rule serves as this block's top one —
 * one line between them, not two. No rule of its own for the same reason it had
 * none when it sat under the price box: the neighbour above already closes with
 * a border, and a second hairline a whisker away reads as a doubled edge.
 */
.sd-service-spec {
	margin-top: 0;
}

/*
 * 118px of label, not the 190px this used when it had a 55% column to itself —
 * the wash is the narrower half, and a value like "A pilot going out to
 * producers" needs the room more than a four-word label does. minmax(0,1fr)
 * because a grid track's default min-width is auto, which lets a long unbroken
 * value push the row wider than the column instead of wrapping inside it.
 */
.sd-service-spec-row {
	display: grid;
	grid-template-columns: 118px minmax(0, 1fr);
	gap: 20px;
	padding: 13px 0;
	border-bottom: 1px solid var(--rule);
	align-items: baseline;
}

.sd-service-spec-label {
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-service-spec-value {
	font-size: 15px;
	color: var(--ink);
}

/* First thing under the band now the spec has moved across, so no top gap. */
.sd-service-desc {
	margin-top: 44px;
}

.sd-service-left-body > .sd-service-desc:first-child {
	margin-top: 0;
}

.sd-service-eyebrow {
	margin: 0 0 14px;
	font-family: var(--mono);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--red);
}

.sd-service-copy p {
	margin: 0 0 15px;
	font-size: 19px;
	line-height: 1.65;
	max-width: 62ch;
	color: var(--ink-soft);
	text-wrap: pretty;
}

.sd-service-copy p:last-child {
	margin-bottom: 0;
}

/*
 * The second buy button, at the foot of the left column. `margin-top: auto`
 * inside the flex column pins it to the bottom, which is also the answer to the
 * two columns finishing at different heights: the leftover white ends up
 * between the description and the button, where it reads as space, instead of
 * stranded under everything.
 */
.sd-service-repeat {
	margin: 44px 0 0;
	padding-top: 26px;
	border-top: 1px solid var(--rule);
	margin-top: auto;
}

.sd-service-repeat-cta {
	display: inline-flex;
	align-items: baseline;
	gap: 10px;
	font-family: var(--mono);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--red);
	text-decoration: none;
}

.sd-service-repeat-cta:hover {
	text-decoration: underline;
}

/*
 * "Best for" — the qualifying line, directly under the lede.
 *
 * Ruled top and bottom, and the spec runs flush underneath, so the four facts
 * read as one bounded block. Unruled it floated between the lede and the table
 * with a gap on either side, belonging to neither.
 *
 * Label beside the value on the same track as the spec rows below — the same
 * 118px column and 20px gap, so every value in the block starts on one edge.
 * It was set label-above-value, on the argument that it is a sentence about the
 * reader rather than a spec, and the cost of that was a value indented to
 * nothing while the three under it lined up: the ragged edge read as a fault
 * before it read as emphasis. It keeps its larger type, which is what marks it
 * out now.
 */
.sd-service-bestfor {
	display: grid;
	grid-template-columns: 118px minmax(0, 1fr);
	gap: 20px;
	align-items: baseline;
	margin: 26px 0 0;
	padding: 13px 0;
	border-top: 1px solid var(--rule);
	border-bottom: 1px solid var(--rule);
}

.sd-service-bestfor-label {
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-service-bestfor-value {
	font-size: 17px;
	line-height: 1.45;
	color: var(--ink);
}

/* "After you pay" — under the buy box, so it answers the question the button
   raises. Numbered like the block it replaced, at the wash's smaller scale. */
.sd-service-after {
	margin-top: 26px;
	padding-top: 22px;
	border-top: 1px solid var(--border);
}

.sd-service-after-label {
	margin: 0 0 10px;
	font-family: var(--mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-service-after-steps {
	margin: 0;
	padding: 0;
	list-style: none;
}

.sd-service-after-step {
	display: flex;
	gap: 14px;
	padding: 7px 0;
	align-items: baseline;
}

.sd-service-after-n {
	flex: 0 0 20px;
	width: 20px;
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.16em;
	color: var(--red);
}

.sd-service-after-t {
	font-size: 15px;
	line-height: 1.5;
	color: var(--ink-soft);
}

/* The one pointer to the extras on the whole page, so it sits where the money
   decision is being made rather than below it. */
.sd-service-extras-hint {
	margin: 16px 0 14px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--rule);
	font-size: 14px;
}

.sd-service-extras-hint a {
	color: var(--red);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.sd-service-extras-hint a:hover {
	color: var(--ink);
}

/* --- Right: the wash ------------------------------------------------------ */
/* Asymmetric on purpose: 56px on the left holds the copy off the seam, which is
   a visible edge, while the right side runs into the wash's own bleed and needs
   less. The 16px difference goes to the values. */
.sd-service-right {
	padding: 64px 40px 72px 56px;
	background: var(--surface);
	border-left: 1px solid var(--border);
	/*
	 * The wash carries on to the page's right edge. A shifted box-shadow rather
	 * than a pseudo-element or a wider box: it paints the same colour past the
	 * edge without entering layout, so the column's width — and therefore the
	 * seam — stays exactly where the 55/45 split puts it. Box shadows also never
	 * add to the scrollable width, which a negative margin would.
	 */
	box-shadow: var(--sd-bleed) 0 0 var(--surface);
}

.sd-service-badge {
	display: inline-block;
	margin: 0;
	padding: 5px 11px;
	border-radius: 4px;
	background: var(--red);
	color: var(--on-red);
	font-family: var(--mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.sd-service-h1 {
	margin: 16px 0 0;
	font-size: 52px;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.04em;
	color: var(--ink);
}

.sd-service-lede {
	margin: 18px 0 0;
	font-size: 20px;
	line-height: 1.45;
	color: var(--ink-soft);
	text-wrap: pretty;
}

/* The price box reads as a card ON the wash, so it is white and square. */
.sd-service-buy {
	margin-top: 30px;
	border: 1px solid var(--ink);
	border-radius: 0;
	padding: 26px;
	background: var(--panel);
}

.sd-service-buy-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 10px;
	font-family: var(--mono);
	text-transform: uppercase;
}

.sd-service-onsale {
	font-size: 10px;
	letter-spacing: 0.2em;
	color: var(--red);
}

.sd-service-rrp {
	font-size: 10px;
	letter-spacing: 0.16em;
	color: var(--meta);
	text-decoration: line-through;
}

.sd-service-price {
	margin: 0 0 18px;
	font-size: 52px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.04em;
	color: var(--ink);
}

.sd-service-buy form.cart {
	display: flex;
	/*
	 * Wrapping matters here. The engine hooks its options into
	 * woocommerce_before_add_to_cart_button, so .sd-buy-options is a sibling
	 * of the quantity and the button rather than a block above them. In a
	 * single flex line, align-items: stretch then grew both of those to the
	 * height of the options, which is what turned Add to cart into a black
	 * bar the height of the box and left the stepper floating in the middle
	 * of it.
	 *
	 * align-items applies per line, not per container, so wrapping the
	 * options onto their own row restores it: they sit above, and the
	 * quantity and the button stretch to each other and nothing else.
	 */
	flex-wrap: wrap;
	gap: 12px;
	align-items: stretch;
	margin: 0 0 16px;
}

.sd-service-buy form.cart > .sd-buy-options {
	flex: 1 1 100%;
	margin-bottom: 4px;
}

.sd-service-buy .quantity {
	display: flex;
	align-items: stretch;
	border: 1px solid var(--border);
	border-radius: 0;
	background: var(--panel);
}

.sd-service-buy .quantity input[type="number"] {
	width: 56px;
	border: 0;
	background: none;
	text-align: center;
	font-size: 16px;
	font-weight: 700;
	color: var(--ink);
	border-radius: 0;
	padding: 13px 4px;
	appearance: textfield;
}

.sd-service-buy .quantity input[type="number"]::-webkit-outer-spin-button,
.sd-service-buy .quantity input[type="number"]::-webkit-inner-spin-button {
	appearance: none;
	margin: 0;
}

.sd-service-step-btn {
	appearance: none;
	background: none;
	border: 0;
	padding: 0 13px;
	font-size: 18px;
	line-height: 1;
	color: var(--meta);
	cursor: pointer;
	border-radius: 0;
}

.sd-service-step-btn:hover {
	color: var(--ink);
}

/* Beats `.sd-woo .button.alt`, three classes, which would paint this red. */
/*
 * `--bg` and not `#fff` for the label. The button paints itself in `--ink`, which
 * is `--text` — so in the dark scheme it is a near-white slab, and a hardcoded
 * white label on it was white on light grey: the button reduced to a rectangle
 * with something written on it nobody could read. Pairing the two tokens makes it
 * an inverted button in both schemes, which is what it already was in light: dark
 * slab, light label; light slab, dark label.
 */
.sd-woo .sd-service-buy .button,
.sd-woo .sd-service-buy .button.alt,
.sd-woo .sd-service-buy button[type="submit"] {
	flex: 1 1 auto;
	background: var(--ink);
	color: var(--bg);
	border: 0;
	border-radius: 0;
	padding: 16px;
	font-family: var(--mono);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	text-align: center;
	cursor: pointer;
}

.sd-woo .sd-service-buy .button:hover,
.sd-woo .sd-service-buy .button.alt:hover,
.sd-woo .sd-service-buy button[type="submit"]:hover {
	background: var(--red);
}

.sd-service-buy-meta {
	margin: 0;
	font-family: var(--mono);
	font-size: 10px;
	letter-spacing: 0.14em;
	line-height: 1.9;
	text-transform: uppercase;
	color: var(--meta);
}

.sd-service-buy-meta span {
	display: block;
}

/* Under the price box, inside the wash — not across in the left column. */
.sd-service-note {
	margin-top: 26px;
	padding-top: 22px;
	border-top: 1px solid var(--border);
}

.sd-service-note-label {
	margin: 0 0 8px;
	font-family: var(--mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--red);
}

.sd-service-note-body {
	margin: 0;
	font-size: 16px;
	line-height: 1.6;
	color: var(--ink-soft);
}

/* --- Narrow --------------------------------------------------------------- */
@media (max-width: 860px) {
	.sd-service-crumbs {
		padding: 16px 24px;
	}

	/*
	 * Stacked, in the order a phone should meet them: the picture, then the
	 * name and the price, then the description.
	 *
	 * The band goes first because it was arriving last — below the wash, below
	 * the buy box, well past the fold — so a phone got no image at all on the
	 * first screen. It is short at this width, so it costs little to scroll past
	 * and does the job of telling you which service you are looking at. The buy
	 * box still lands well within the first screen behind it.
	 *
	 * Single-column grid, so every child is its own row; the explicit
	 * grid-column/row from the desktop rules has to be cleared or the band and
	 * the wash fight over row 1.
	 */
	.sd-service-split {
		grid-template-columns: 1fr;
		grid-template-rows: none;
	}

	.sd-service-band,
	.sd-service-left-body,
	.sd-service-right {
		grid-column: auto;
		grid-row: auto;
	}

	.sd-service-band {
		order: 1;
		height: 180px;
	}

	.sd-service-right {
		order: 2;
		padding: 32px 24px 40px;
		border-left: 0;
		border-bottom: 1px solid var(--border);
		/* Full width already; nothing to bleed into. */
		box-shadow: none;
	}

	/* The band stays full-bleed on a phone; only the copy below it insets. */
	.sd-service-left-body {
		order: 3;
		padding: 32px 24px 48px;
	}

	/* Nothing below it to push away from on a single column. */
	.sd-service-repeat {
		margin-top: 32px;
	}

	.sd-service-h1 {
		font-size: 38px;
	}

	.sd-service-lede {
		font-size: 18px;
	}

	/* Narrower label track, both blocks together — they share an edge and have to
	   keep sharing it at every width. */
	.sd-service-spec-row,
	.sd-service-bestfor {
		grid-template-columns: 110px minmax(0, 1fr);
		gap: 16px;
	}

	.sd-service-copy p {
		font-size: 17px;
	}
}

/* Pagination, on the rare archive that needs it. Square and quiet, like the
   rest of the index — it is a utility, not a feature. */
.sd-services .woocommerce-pagination {
	padding: 26px 56px 0;
}

.sd-services .woocommerce-pagination ul {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
}

.sd-services .woocommerce-pagination li {
	margin: 0;
	border: 0;
}

.sd-services .woocommerce-pagination a,
.sd-services .woocommerce-pagination span {
	display: block;
	min-width: 34px;
	padding: 7px 10px;
	border: 1px solid var(--rule);
	border-radius: 0;
	background: none;
	font-family: var(--mono);
	font-size: 12px;
	letter-spacing: 0.08em;
	text-align: center;
	color: var(--ink);
	text-decoration: none;
}

.sd-services .woocommerce-pagination a:hover {
	border-color: var(--ink);
	color: var(--red);
}

/* Same pairing as the buy button, and it had the same defect: the current page
   number was white on a near-white chip in the dark scheme. */
.sd-services .woocommerce-pagination .current {
	background: var(--ink);
	border-color: var(--ink);
	color: var(--bg);
}

@media (max-width: 860px) {
	.sd-services .woocommerce-pagination {
		padding: 22px 24px 0;
	}
}

/* ==========================================================================
   "Other services" — a scrolling row at the foot of a service page
   --------------------------------------------------------------------------
   Scroll-snap, not a JavaScript slider. The row is a real scroll container, so
   it works with a trackpad, a touch screen, a scrollbar and the keyboard before
   any script loads; the arrows are an enhancement bolted on afterwards and are
   hidden until the script unhides them. No library, and nothing to re-measure
   on resize.
   ========================================================================== */
/*
 * Page-wide, unlike everything above it.
 *
 * The heading and the arrows stay on the container's edges so the section still
 * belongs to the page, but the track runs from that left edge out to the right
 * edge of the window. Cards then leave the screen rather than stopping short of
 * it, which is what tells you there is more — and, with the row wider than the
 * viewport, gives it something to actually scroll.
 */
.sd-others {
	padding: 34px 0 44px;
	border-top: 1px solid var(--rule);
}

.sd-others-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 20px;
	margin: 0 auto 20px;
	max-width: var(--sd-container);
	padding: 0 56px;
}

.sd-others-title {
	margin: 0;
	font-size: 22px;
	font-weight: 700;
	letter-spacing: -0.02em;
	color: var(--ink);
}

.sd-others-nav {
	display: flex;
	gap: 8px;
}

/* Same rule as the colour switch: the markup ships these hidden and the script
   reveals them, which only works if the attribute is allowed to win. */
.sd-others-nav[hidden] {
	display: none;
}

.sd-others-btn {
	appearance: none;
	width: 38px;
	height: 38px;
	border: 1px solid var(--border);
	border-radius: 0;
	background: var(--panel);
	color: var(--ink);
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
}

.sd-others-btn:hover:not(:disabled) {
	border-color: var(--ink);
	color: var(--red);
}

.sd-others-btn:disabled {
	opacity: 0.35;
	cursor: default;
}

.sd-others-track {
	display: flex;
	gap: 20px;
	margin: 0;
	/* Starts level with the heading — the container's own left edge — and runs
	   to the window's right edge. `scroll-padding` keeps snapping honest, or the
	   first card snaps under the inset. */
	padding: 0 24px 6px calc( var(--sd-bleed, 0px) + 56px );
	scroll-padding-left: calc( var(--sd-bleed, 0px) + 56px );
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	/* A visible focus ring matters here: the track is tabbable so a keyboard can
	   scroll it, and a focusable thing with no focus style is a trap. */
	outline-offset: 3px;
	scrollbar-width: thin;
	overscroll-behavior-x: contain;
}

/*
 * Plates only — no name, no price. The strip is a row of pictures you can flick
 * through, and its height is the wide plate's: 2.63:1 rather than the 4:3 of
 * the square set, which is what keeps it shallow.
 */
.sd-others-item {
	flex: 0 0 340px;
	scroll-snap-align: start;
}

.sd-others-link {
	display: block;
	text-decoration: none;
	color: var(--ink);
}

.sd-others-plate {
	display: block;
	width: 100%;
	aspect-ratio: 1408 / 536;
	background-color: var(--row-tint);
	background-repeat: no-repeat;
	background-position: center;
	/* Scaled by height, so a square plate falling back into this frame shows
	   whole on its ground instead of being cropped to a letterbox. */
	background-size: auto 100%;
	border-radius: 0;
}

/* No known ground to sit on: fill the frame instead of floating the artwork. */
.sd-others-plate--cover {
	background-size: cover;
	border: 1px solid var(--rule);
}

.sd-others-link:hover .sd-others-plate {
	outline: 2px solid var(--red);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.sd-others-track {
		scroll-behavior: auto;
	}
}

@media (max-width: 860px) {
	.sd-others {
		padding: 34px 0 44px;
	}

	.sd-others-head {
		padding: 0 24px;
	}

	.sd-others-track {
		padding-left: 24px;
		padding-right: 16px;
		scroll-padding-left: 24px;
	}

	.sd-others-item {
		flex-basis: 240px;
	}

	/* Touch scrolling is the native gesture here; the arrows only take up room. */
	.sd-others-nav {
		display: none;
	}
}

/* ==========================================================================
   Report inserts
   --------------------------------------------------------------------------
   Fragments of one real coverage report, dropped into the page as framed
   prints. Rendered by sd_report_insert() in inc/inserts.php.

   The figure is a two-column grid: the print takes a little under half the
   container and its caption takes the rest. That is the whole point of the
   layout. Pinned on its own, a 520px print inside a 1120px container left
   roughly 600px of empty page beside it on every placement, and four of them
   stacked down the sample report page turned it into a ladder of white gaps.
   Filling that column with the caption fixes the hole and puts the words at a
   readable size at the same time, which is why the caption came off the mount.
   There is no centred variant: centring is what produced the gaps.

   The mount is white in both schemes. A photographic print does not repaint
   itself when the reader picks dark mode; making the frame follow --panel turned
   it into another card, which is the one thing it must not look like. The
   caption is outside the mount now, so it takes ordinary tokens and inherits its
   ink from whatever section it lands in — which is what lets the same component
   sit on the white credits section and on the navy AI panel.

   The turn is 1.5 degrees or less. It is enough to read as a thing laid on the
   page rather than a thing laid out by CSS, and small enough that the monospaced
   type inside stays comfortable. Past about 2.5 degrees it looks like a mistake.

   Direction is not a free choice, and the class names say which axis they are
   on: `pin-*` is where the print sits, `turn-*` is which way it leans. A print
   on the left turns anticlockwise and one on the right turns clockwise, so both
   lean in towards the middle of the page. sd_report_insert() derives the turn
   from the placement so the two cannot be set against each other.

   `turn-none` is the third case and the interesting one. Four of the seven crops
   contain one of the report's rubber stamps — CLIENT COPY, BEFORE ANYTHING ELSE,
   PROTECT, ACTION — and every one of those is set on a slant in the document
   itself. Turning the mount underneath gives the reader two angles a degree or
   two apart with nothing to relate them, which reads as a printing fault rather
   than as a print laid down askew. Those four sit square and let the stamp carry
   the angle. It is a property of the picture, so the catalogue records it and no
   placement can override it.
   ========================================================================== */
.report-insert {
	/* These were 480 / 560 / 720 when each crop held only the report's text
	   block. The crops now run the full width of the sheet — letterhead, margins,
	   and whatever the edges cut through — which shows about 17% more page across,
	   and the frames came down another 8% on top of that. Between them the type
	   renders at roughly 79% of its first size: more document, smaller words, and
	   deliberately so. It has stopped being something to read at a glance and
	   become something to recognise, with the sample report page carrying the
	   readable copy. Do not shrink these further without moving that job. */
	--print-w: 520px;
	display: grid;
	/* Generous, because a rotated box's corners reach past its own bounding box
	   and a tight margin lets them collide with whatever sits above and below. */
	margin: 48px 0;
	gap: 26px 44px;
	align-items: center;
}

.report-insert.is-wide {
	--print-w: 660px;
}

.report-insert.is-narrow {
	--print-w: 440px;
}

/* Two columns only where there is room for two. The breakpoint is 900px rather
   than the 620px the rest of this block uses, because a 520px print and a column
   of text do not both fit in a 620px container — they just squeeze. */
@media (min-width: 900px) {
	.report-insert.pin-left {
		grid-template-columns: minmax(0, var(--print-w)) minmax(0, 1fr);
	}

	.report-insert.pin-right {
		grid-template-columns: minmax(0, 1fr) minmax(0, var(--print-w));
	}

	/* DOM order stays print-then-caption in both cases, so a screen reader and a
	   phone meet the picture before the words about it either way. */
	.report-insert.pin-right .print {
		order: 2;
	}

	.report-insert.pin-right figcaption {
		order: 1;
	}
}

/* `min-width: 0` on both grid items, and it is load-bearing rather than tidiness.
   A grid item defaults to `min-width: auto`, which refuses to shrink below its
   content's min-content width — and the sheet's image is 610px on phones. Without
   it the figure grew to 610px inside a 360px screen and took the caption's column
   off the edge with it, which is exactly what the scroll container was added to
   prevent. */
.report-insert .print,
.report-insert figcaption {
	min-width: 0;
}

.report-insert .print {
	background: #ffffff;
	padding: 14px;
	border: 1px solid rgba(20, 24, 29, 0.1);
	border-radius: 3px;
	box-shadow: 0 16px 40px rgba(20, 24, 29, 0.22);
}

.report-insert .print.turn-ccw {
	transform: rotate(-1.5deg);
}

.report-insert .print.turn-cw {
	transform: rotate(1.3deg);
}

/* Square, because the stamp inside is already on the slant. Declared rather than
   left to the absence of a rule, so the rendered markup says which of the three
   cases applies. */
.report-insert .print.turn-none {
	transform: none;
}

/* The image carries its own hairline: the report's paper is cream, and without
   one it bleeds into the white mount and the print loses its edge. */
.report-insert img {
	display: block;
	width: 100%;
	height: auto;
	border: 1px solid rgba(20, 24, 29, 0.08);
}

/* Nothing to do on a desktop; it earns its keep in the phone rules at the foot
   of this block, where it becomes a scroll container. */
.report-insert .sheet {
	line-height: 0;
}

.report-insert figcaption p {
	margin: 0;
}

/* `.lbl` has no base rule in this stylesheet — every section styles its own — so
   this is the base for ours, and the AI panel overrides it below the way it
   overrides its own. */
.report-insert figcaption .lbl {
	font-family: var(--mono);
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--red);
	margin-bottom: 10px;
}

/* No colour of its own: it inherits, which is what lets this component sit on a
   white section and on the navy panel without a variant for each. */
.report-insert figcaption .cap {
	font-size: 1.22rem;
	font-weight: 700;
	line-height: 1.28;
	letter-spacing: -0.01em;
	margin-bottom: 12px;
}

.report-insert figcaption .note {
	font-size: 0.98rem;
	line-height: 1.62;
	color: var(--muted);
	max-width: 42em;
}

/* The AI panel is navy in BOTH schemes, so --muted (a grey pitched for the page
   ground) and --red (3.19:1 on that navy) are both wrong on it. It already
   solved this for its own labels; these follow the same two values. */
.humansec .report-insert figcaption .lbl {
	color: #8ec2dd;
}

.humansec .report-insert figcaption .note {
	color: #b7c6d4;
}

/* Straightening on hover is the whole reward for turning it in the first place,
   which is why the square ones are left out of both halves: there is nothing to
   straighten, and a transition on an element that never moves is just a promise
   the page does not keep. */
@media (prefers-reduced-motion: no-preference) {
	.report-insert .print.turn-ccw,
	.report-insert .print.turn-cw {
		transition: transform 0.25s ease;
	}

	.report-insert:hover .print.turn-ccw,
	.report-insert:hover .print.turn-cw {
		transform: rotate(0deg);
	}
}

@media (max-width: 620px) {
	.report-insert {
		margin: 34px 0;
		gap: 18px;
	}

	.report-insert .print {
		padding: 10px;
	}

	/* The monospaced report type is already small; at phone widths the turn costs
	   more legibility than it buys character. */
	.report-insert .print.turn-ccw,
	.report-insert .print.turn-cw {
		transform: none;
	}

	/* A 330px-wide frame would put the report's type at about five pixels a glyph,
	   which is a photograph of a document rather than a document. The sheet scrolls
	   sideways instead. 610, not the 520 this was when the crops were tighter: the
	   sheet now spends about 15% of its width on the page margins, so holding the
	   type at the size it had means holding a wider image. Plain `overflow-x`, the
	   same thing `.prose pre` and `.table-scroll` already do. */
	.report-insert .sheet {
		overflow-x: auto;
		overscroll-behavior-x: contain;
	}

	.report-insert .sheet img {
		width: 610px;
		max-width: none;
	}

	.report-insert figcaption .cap {
		font-size: 1.1rem;
	}
}

/* ═══════════════════════════════════════════════════════════════════════════
   STEP OUTLINE — submit + library (2A) and waiting (1E)

   Two logged-in screens for the outline generator. Everything is drawn with
   the palette above; the mockup's own --sd-* set is not ported, because the
   theme already carries every value and --sd-* is taken.

   Anything FILLED takes --skeleton. The hairline tokens are pitched against
   --panel and vanish when used as a fill on --surface. Anything on the navy
   band takes --blue-lift, because --blue falls to about 3.1:1 there.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Shared ──────────────────────────────────────────────────────────────── */

.so-kicker {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--text);
}

.so-kicker--small {
	font-size: 12px;
	color: var(--muted);
}

.so-blink {
	display: inline-block;
	width: 8px;
	height: 8px;
	background: var(--blue);
	animation: so-blink 1.4s steps(1) infinite;
}

.so-blink--lift {
	width: 11px;
	height: 11px;
	background: var(--blue-lift);
}

@keyframes so-blink {
	0%, 49% { opacity: 1; }
	50%, 100% { opacity: 0.15; }
}

/* Filled, so --skeleton rather than a hairline token. */
.so-track {
	display: block;
	height: 9px;
	border-radius: var(--radius);
	background: var(--skeleton);
	overflow: hidden;
}

.so-track--thin { height: 5px; border-radius: 3px; }

.so-track__fill {
	display: block;
	height: 100%;
	background: var(--text);
	transition: width 0.5s ease;
}

/* ── 2A: page head ───────────────────────────────────────────────────────── */

.so-head__inner {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 40px;
	flex-wrap: wrap;
}

.so-head .rule {
	width: 56px;
	height: 4px;
	background: var(--red);
}

.so-head__credits {
	text-align: right;
	flex: 0 0 auto;
}

.so-head__label {
	display: block;
	margin-bottom: 4px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--meta);
}

.so-head__figure {
	display: block;
	font-size: 52px;
	line-height: 1;
	font-weight: 600;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

/* ── 2A: the two columns ─────────────────────────────────────────────────── */

.so-grid {
	display: grid;
	grid-template-columns: 1fr 400px;
	/* No gap. The divider is a border on the right column, and the fill has
	   to run the full row height to the footer, so the row stretches. */
	gap: 0;
	align-items: stretch;
	/* The theme's own container: 1120px, not --sd-container, which is 1184
	   and belongs to a different component. The 24px gutter lives on the
	   columns rather than here, so the right column's fill still reaches the
	   container edge instead of stopping short of it. */
	max-width: 1120px;
	margin: 0 auto;
}

.so-grid__main { padding: 48px 44px 64px 24px; }

.so-grid__side {
	padding: 48px 24px 64px 44px;
	border-left: 1px solid var(--ghost-border);
	background: var(--surface);
}

@media (max-width: 900px) {
	.so-grid { grid-template-columns: 1fr; }
	.so-grid__main { padding: 32px 24px 40px; }
	.so-grid__side { padding: 32px 24px 48px; border-left: 0; border-top: 1px solid var(--ghost-border); }
}

/* ── 2A: the form ────────────────────────────────────────────────────────── */

.so-form__fields { margin: 24px 0 0; }

.so-field-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 20px;
	margin: 0 0 20px;
}

@media (max-width: 620px) {
	.so-field-row { grid-template-columns: 1fr; }
	.so-field--empty { display: none; }
}

.so-field { display: block; margin: 0 0 20px; }

.so-field__label {
	display: block;
	margin: 0 0 7px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--text);
}

.so-field__label em {
	font-style: normal;
	color: var(--meta);
	margin-left: 6px;
}

/* Square, with the weight on the bottom edge. */
.so-input {
	width: 100%;
	padding: 11px 13px;
	border: 1px solid var(--ghost-border);
	border-bottom: 2px solid var(--text);
	border-radius: 0;
	background: var(--panel);
	color: var(--text);
	font: inherit;
}

.so-input:focus-visible {
	outline: 2px solid var(--blue);
	outline-offset: 1px;
}

/* The zone is the input's label, so a click anywhere opens the picker with
   no script at all. The drop handler is an enhancement on top. */
.so-drop {
	display: flex;
	align-items: center;
	gap: 20px;
	padding: 26px 24px;
	border: 1px dashed var(--meta);
	background: var(--surface);
	cursor: pointer;
}

.so-drop.is-over { border-color: var(--blue); background: var(--panel); }

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

.so-drop__input:focus-visible + .so-drop__body { outline: 2px solid var(--blue); outline-offset: 4px; }

.so-drop__body { flex: 1 1 auto; }

.so-drop__title {
	display: block;
	font-size: 26px;
	font-weight: 600;
	line-height: 1.2;
	color: var(--text);
}

.so-drop__spec {
	display: block;
	margin-top: 8px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--meta);
}

.so-drop__button {
	flex: 0 0 auto;
	padding: 10px 18px;
	border: 1px solid var(--ghost-border);
	background: var(--panel);
	font-size: 14px;
	color: var(--text);
}

.so-submit {
	display: flex;
	align-items: center;
	gap: 18px;
	flex-wrap: wrap;
	margin: 28px 0 0;
}

.so-submit__note {
	margin: 0;
	max-width: 34ch;
	font-size: 14px;
	line-height: 1.5;
	color: var(--muted);
}

/* ── 2A: what happens to your script ─────────────────────────────────────── */

.so-privacy {
	margin: 48px 0 0;
	padding: 26px 0 0;
	border-top: 1px solid var(--rule);
}

.so-privacy__list {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14px 34px;
	margin: 18px 0 0;
	padding: 0;
	list-style: none;
}

.so-privacy__list li {
	position: relative;
	padding-left: 17px;
	font-size: 15px;
	line-height: 1.55;
	color: var(--ink-soft);
}

.so-privacy__list li::before {
	content: "";
	position: absolute;
	top: 0.55em;
	left: 0;
	width: 7px;
	height: 7px;
	background: var(--red);
}

.so-privacy__wide { grid-column: 1 / -1; }

@media (max-width: 620px) {
	.so-privacy__list { grid-template-columns: 1fr; }
}

/* ── 2A: the library ─────────────────────────────────────────────────────── */

/* The way back to the form, from a screen a writer can otherwise get stuck on.
   First thing in the column, and full width so it reads as the way out rather
   than as one more item in the list. */
.so-library__new {
	display: block;
	margin: 0 0 24px;
	text-align: center;
}

/*
 * The same destination on the quote screen, where it must not compete with
 * the button that starts the build. A link, sized like the row links it sits
 * above, not a filled button.
 */
.so-library__another {
	display: inline-block;
	margin: 0 0 24px;
	font-size: 15px;
	font-weight: 600;
	color: var(--text);
	text-decoration: underline;
	text-decoration-color: var(--red);
	text-underline-offset: 3px;
}

.so-library__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding-bottom: 12px;
}

.so-library__count {
	font-family: var(--mono);
	font-size: 12px;
	color: var(--meta);
	font-variant-numeric: tabular-nums;
}

.so-library__list {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 2px solid var(--text);
}

.so-library__empty {
	padding: 22px 0;
	border-bottom: 1px solid var(--ghost-border);
	font-size: 15px;
	color: var(--muted);
}

.so-row {
	padding: 18px 0;
	border-bottom: 1px solid var(--ghost-border);
}

.so-row__link {
	display: block;
	text-decoration: none;
	color: inherit;
}

.so-row__title {
	display: block;
	font-size: 17px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--text);
}

.so-row__status {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 8px 0 10px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--blue-ink);
}

.so-row__meta {
	display: block;
	margin-top: 9px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--meta);
}

.so-row--done { display: flex; align-items: flex-end; gap: 12px 16px; flex-wrap: wrap; }
/* The column is 400px. The title takes the line to itself or it collides with
   the state on any title longer than a word. */
.so-row--done .so-row__title { flex: 1 1 100%; }
.so-row--done .so-row__meta { flex: 1 1 auto; margin-top: 0; }

.so-row__end { flex: 0 0 auto; margin-left: auto; text-align: right; }

.so-row__state {
	display: block;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--meta);
}

.so-row__open {
	display: inline-block;
	margin-top: 4px;
	font-size: 15px;
	font-weight: 600;
	color: var(--text);
	text-decoration: underline;
	text-decoration-color: var(--red);
	text-underline-offset: 3px;
}

/*
 * Where the link would be on the row you are already reading. It has to read
 * as a label and not as something to click: no underline, no pointer, and the
 * quiet weight that tells the eye the action is in the other column.
 */
.so-row__here {
	display: inline-block;
	margin-top: 4px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--muted);
}

.so-row__link--here { cursor: default; }

.so-keep {
	margin: 26px 0 0;
	padding: 16px 20px;
	border-left: 4px solid var(--text);
	background: var(--panel);
	font-size: 14px;
	line-height: 1.55;
	color: var(--ink-soft);
}

.so-keep__title {
	display: block;
	margin-bottom: 5px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--text);
}

/* ── 1E: the band ────────────────────────────────────────────────────────── */

.so-band {
	position: relative;
	background: var(--navy);
	color: #e8edf2;
	padding: 30px 0 34px;
}

.so-band__top {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 22px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.so-band__eyebrow { color: var(--blue-lift); }
.so-band__elapsed { color: rgba(232, 237, 242, 0.6); font-variant-numeric: tabular-nums; }

.so-band__row {
	display: flex;
	align-items: center;
	gap: 44px;
}

@media (max-width: 900px) {
	.so-band__row { flex-wrap: wrap; gap: 26px; }
}

/* Decorative, and stilled entirely under reduced motion. */
.so-bars {
	display: flex;
	align-items: flex-end;
	gap: 9px;
	height: 74px;
	flex: 0 0 auto;
}

.so-bars__bar {
	width: 20px;
	height: 74px;
	border-radius: 11px;
	background: #e8edf2;
	transform-origin: bottom center;
	transform: scaleY(0.26);
	animation: so-bar 2.4s ease-in-out infinite;
}

.so-bars__bar.is-blue { background: var(--blue-lift); }
.so-bars__bar.is-red { background: var(--red); }

@keyframes so-bar {
	0%, 100% { transform: scaleY(0.26); }
	50% { transform: scaleY(1); }
}

.so-ticker { flex: 1 1 auto; min-width: 0; }

.so-ticker__now {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 10px;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--blue-lift);
}

/* A clipped viewport one line tall; the reel translates up inside it. */
.so-ticker__viewport {
	height: 48px;
	overflow: hidden;
}

.so-ticker__reel {
	display: flex;
	flex-direction: column;
	animation: so-reel 12s steps(1) infinite;
}

.so-ticker__line {
	display: block;
	height: 48px;
	line-height: 48px;
	font-size: 38px;
	font-weight: 600;
	white-space: nowrap;
	color: #e8edf2;
}

@keyframes so-reel {
	0%   { transform: translateY(0); }
	25%  { transform: translateY(-48px); }
	50%  { transform: translateY(-96px); }
	75%  { transform: translateY(-144px); }
	100% { transform: translateY(-192px); }
}

.so-notify { flex: 0 0 auto; text-align: right; }

.so-notify__link {
	display: block;
	font-family: var(--mono);
	font-size: 11px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: #e8edf2;
	text-decoration: underline;
	text-decoration-color: var(--blue-lift);
	text-underline-offset: 4px;
}

.so-notify__note {
	display: block;
	margin-top: 6px;
	font-size: 14px;
	color: rgba(232, 237, 242, 0.6);
}

/* The real percentage, not an animation. */
.so-band__track {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 5px;
	background: rgba(232, 237, 242, 0.16);
}

.so-band__fill {
	display: block;
	height: 100%;
	background: var(--blue-lift);
	transition: width 0.5s ease;
}

/* ── 1E: the panel ───────────────────────────────────────────────────────── */

/* The panel sits in the reading column now, so it carries no ground of its
   own: the tint belongs to the library column, as on every other screen. */
.so-panel__inner { padding: 40px 0 56px; }

.so-panel__title {
	margin: 0 0 20px;
	font-size: 26px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--text);
}

.so-panel__phase {
	margin: 26px 0 0;
	font-size: 21px;
	font-weight: 600;
	color: var(--text);
}

.so-panel__explanation {
	margin: 10px 0 0;
	max-width: 64ch;
	font-size: 16px;
	line-height: 1.6;
	color: var(--muted);
}

.so-phases {
	display: flex;
	flex-direction: column;
	gap: 15px;
	margin: 30px 0 0;
	padding: 0;
	list-style: none;
}

.so-phase { display: flex; align-items: center; gap: 12px; font-size: 16px; }

.so-phase__dot {
	flex: 0 0 auto;
	width: 13px;
	height: 13px;
	border-radius: 50%;
	background: transparent;
	box-shadow: inset 0 0 0 2px var(--meta);
}

.so-phase.is-done { color: var(--text); font-weight: 500; }
.so-phase.is-done .so-phase__dot { background: var(--text); box-shadow: none; }

.so-phase.is-current { color: var(--red); font-weight: 600; }
.so-phase.is-current .so-phase__dot { background: var(--red); box-shadow: none; }

.so-phase.is-pending { color: var(--meta); font-weight: 400; }

.so-notes {
	display: flex;
	flex-direction: column;
	gap: 16px;
	margin: 34px 0 0;
}

.so-note {
	padding: 20px 24px;
	background: var(--panel);
	border-left: 4px solid var(--text);
}

.so-note--time { border-left-color: var(--blue-ink); }

.so-note__title {
	display: block;
	margin-bottom: 9px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--muted);
}

.so-note p {
	margin: 0;
	max-width: 66ch;
	font-size: 16px;
	line-height: 1.6;
	color: var(--ink-soft);
}

.so-note b { color: var(--text); }

.so-coming {
	margin: 38px 0 0;
	padding: 26px 0 0;
	border-top: 1px solid var(--rule);
}

.so-coming__list {
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 11px;
}

.so-coming__list li {
	position: relative;
	padding-left: 17px;
	font-size: 15px;
	line-height: 1.55;
	color: var(--ink-soft);
}

.so-coming__list li::before {
	content: "";
	position: absolute;
	top: 0.55em;
	left: 0;
	width: 7px;
	height: 7px;
	background: var(--red);
}

/* ── The gate: read and counted, waiting for the writer ──────────────────── */

.so-quote__figure {
	margin: 22px 0 6px;
	font-size: 46px;
	line-height: 1;
	font-weight: 700;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

.so-quote__explanation {
	margin: 0 0 26px;
	max-width: 54ch;
	font-size: 16px;
	line-height: 1.6;
	color: var(--muted);
}

.so-quote__actions {
	display: flex;
	align-items: center;
	gap: 18px;
	flex-wrap: wrap;
	margin: 0;
}

.so-quote__balance { font-size: 14px; color: var(--muted); }

.so-quote__error {
	margin: 14px 0 0;
	padding: 12px 16px;
	border-left: 4px solid var(--red);
	background: var(--panel);
	font-size: 15px;
	color: var(--text);
}

.so-quote__error[hidden] { display: none; }

.so-row__state.is-ready { color: var(--red); }

/* ── The outline itself, inside the reading column ───────────────────────── */

/*
 * The plugin's stylesheet draws the outline; this only decides how wide it is
 * allowed to get. Read across the full page a step line is too long to track,
 * because the eye loses the row between the location tag and the page number
 * at the far end.
 */
.so-result .soe-outline,
.so-result .soe-shape,
.so-result .soe-climaxes { max-width: 100%; }

.so-result table { width: 100%; }

/* The row being read, in the list beside it. */
.so-row.is-here {
	margin-left: -14px;
	padding-left: 10px;
	border-left: 4px solid var(--red);
}

.so-row.is-here .so-row__title { color: var(--red); }

/* ── 1E: once there is nothing left to wait for ──────────────────────────── */

/*
 * No padding of its own. It sits on .so-grid__main, which already sets the
 * column's, and declaring it again here won that cascade and knocked the
 * left column eight pixels above the right one, along with its gutters.
 */

.so-result__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	/* The same 24 the sidebar's button carries. Both columns then run
	   button, 24, head, 12, rule, and the two rules meet. */
	margin: 0 0 24px;
}

/*
 * Three equal actions. The theme's bare .btn is transparent on both border
 * and ground, so next to a filled one it reads as an unselected tab.
 */
.so-download {
	border-color: var(--ghost-border);
	background: var(--panel);
	color: var(--blue-ink);
}

.so-download:hover,
.so-download:focus-visible {
	border-color: var(--blue-ink);
	background: var(--panel);
}

/* The mirror of .so-library__head, so the two rules meet. */
.so-result__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding-bottom: 12px;
}

.so-result__count {
	font-family: var(--mono);
	font-size: 12px;
	color: var(--meta);
	font-variant-numeric: tabular-nums;
}

.so-result__note {
	margin: 0 0 22px;
	max-width: 62ch;
	font-size: 16px;
	line-height: 1.6;
	color: var(--ink-soft);
}

.so-result__outline {
	padding-top: 22px;
	/* The same 2px the library's list carries, so they read as one line
	   crossing the divider rather than two rules of different weights. */
	border-top: 2px solid var(--text);
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	/* The bars stand still at full height, the squares stop blinking, and the
	   ticker shows its first line rather than rotating. The two tracks were
	   never animated: they are the real percentage. */
	.so-bars__bar { animation: none; transform: scaleY(1); }
	.so-blink { animation: none; opacity: 1; }
	.so-ticker__reel { animation: none; transform: none; }
	.so-track__fill,
	.so-band__fill { transition: none; }
}
