/**
 * Identity Software — bespoke section styles.
 *
 * theme.json owns the palette, spacing scale, layout widths and base element
 * styles. This file owns the things theme.json can't express: section grids,
 * the full-bleed photo bands, the dark AI section, card hovers, image slots.
 *
 * Class names deliberately match identity-homepage.html / proof-of-concept.html
 * so the designs stay traceable to the markup.
 *
 * Breakpoints: 900px and 560px. The PoC design used 860px; it is normalised
 * onto 900/560 here so both pages reflow at the same points.
 *
 * Contents
 *   1.  Brand tokens
 *   2.  Shared primitives (kicker, headings, image slots, quiet link)
 *   3.  Site header / footer
 *   4.  Home — hero
 *   5.  Home — trust strip
 *   6.  Home — pain points
 *   7.  Shared — full-bleed photo band
 *   8.  Home — operational backbone
 *   9.  Home — AI capability (dark)
 *   10. Home — case study
 *   11. Home — why us
 *   12. Home — team
 *   13. Home — pricing paths
 *   14. Shared — FAQ
 *   15. Shared — final CTA
 *   16. Projects — home grid, archive, single
 *   17. Proof of Concept page
 *   18. Home — Google reviews
 *   19. Contact page
 *   20. Responsive
 */

/* ===============================================================
   1. Brand tokens — aliases onto the theme.json presets so the
   ported design CSS can keep using --bronze, --cream, etc.
   =============================================================== */
:root {
	--bronze: var(--wp--preset--color--bronze);
	--bronze-deep: var(--wp--preset--color--bronze-deep);
	--bronze-tint: var(--wp--preset--color--bronze-tint);
	--cream: var(--wp--preset--color--cream);
	--butter: var(--wp--preset--color--butter);
	--butter-soft: var(--wp--preset--color--butter-soft);
	--ink: var(--wp--preset--color--ink);
	--white: var(--wp--preset--color--white);
	--muted: var(--wp--preset--color--muted);
	--line: var(--wp--preset--color--line);

	/* Supporting tones used inside dark sections — not brand palette
	   entries, so deliberately kept out of theme.json. */
	--ink-raised: #221b16;
	--ink-line: #3a2f28;
	--ink-text: #c2b4a5;
	--ink-text-bright: #d8cabb;
}

/* ===============================================================
   2. Shared primitives
   =============================================================== */

/* The ported section CSS carries its own vertical rhythm, so the editor's
   flow gap is neutralised inside designed sections.
   Specificity is deliberately held at one class (the :where() contributes
   nothing) and this rule is declared first, so every design rule below wins
   the tie on source order while core's zero-specificity rule still loses. */
.idsw-section :where(.is-layout-flow, .is-layout-constrained) > *,
.idsw-section:where(.is-layout-flow, .is-layout-constrained) > * {
	margin-block-start: 0;
}

/* Designed pages butt their sections straight against each other, so the flow
   gap between top-level sections goes too — otherwise the page background
   shows through as a cream sliver between each coloured band. */
.idsw-page > * {
	margin-block-start: 0;
}

/* Same reason, one level up: header, main and footer butt together. */
.wp-site-blocks > * {
	margin-block-start: 0;
}

/* Eyebrow / kicker — the small uppercase bronze label above headings. */
/* Sections that colour all their paragraphs (.why p, .poc-why p) would
   otherwise win over .kicker on specificity, since the kicker is a paragraph
   here where the source design used a div. */
.why .kicker,
.poc-why .kicker {
	color: var(--bronze);
}

.kicker {
	margin-bottom: 16px;
	color: var(--bronze);
	font-size: 0.74rem;
	font-weight: 800;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* Kicker with the leading dot (hero + final CTA). */
.kicker.has-dot {
	display: inline-flex;
	align-items: center;
	gap: 9px;
}

.kicker.has-dot::before {
	content: "";
	width: 7px;
	height: 7px;
	flex-shrink: 0;
	border-radius: 50%;
	background: currentColor;
}

/* These carry their own max-width, which constrained layout would auto-centre
   (core declares margin-left/right: auto !important, so CSS can't win). Every
   pattern therefore nests them inside a plain flow group, where normal block
   margins apply and they sit hard left as the designs intend. */
.sec-head {
	max-width: 19ch;
}

.sec-sub {
	max-width: 56ch;
	margin: 20px 0 0;
	color: var(--muted);
	font-size: 1.1rem;
}

/* Italic bronze accent inside headings. */
.em {
	color: var(--bronze);
	font-style: italic;
	font-weight: 800;
}

/* Quiet secondary link with the butter underline. */
.link-quiet a,
a.link-quiet {
	padding-bottom: 2px;
	border-bottom: 2px solid var(--butter);
	color: var(--bronze);
	font-size: 0.94rem;
	font-weight: 700;
}

/* Buttons: the theme.json default is the bronze primary. These are the
   variants the designs use. */
.btn-alt .wp-block-button__link:hover,
.wp-block-button.btn-alt .wp-block-button__link:hover {
	background-color: #f8e3a4;
}

.wp-block-button__link {
	transition: transform 0.12s, background-color 0.15s;
}

.wp-block-button__link:hover {
	transform: translateY(-1px);
}

/* ---- Image slots ---------------------------------------------
   Sized wrappers holding each photo. The sizing classes (.hero-img,
   .case-img, …) live alongside .is-image-slot on the wrapper, so a
   photo can be swapped without the layout moving. The bronze-tint
   background shows only while a slot is empty.
   --------------------------------------------------------------- */
.is-image-slot {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: var(--bronze-tint);
	border-radius: 14px;
}

/* Crops are baked into the exported files, so object-fit here is a safety net
   — nudge object-position per slot if a subject needs to sit off-centre. */
.is-image-slot img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* core/image renders a <figure>, which carries a default margin. */
figure.is-image-slot,
.is-image-slot figure,
.is-image-slot .wp-block-image {
	width: 100%;
	height: 100%;
	margin: 0;
}

/* Once a photo is in, the empty-slot background is redundant. */
.is-image-slot:has(img) {
	background: none;
}

/* Slot sitting on a dark background. */
.is-image-slot.is-on-dark {
	background: #3a2f24;
}

/* ---- Contact: Calendly booking ---------------------------------
   The widget is an iframe Calendly sizes itself; min-height holds the
   space so the page doesn't jump when it loads, and the fallback link
   underneath covers the case where the script never arrives.
   --------------------------------------------------------------- */
.booking__widget {
	position: relative;
	margin-top: 34px;
}

.booking__widget .calendly-inline-widget {
	min-width: 320px;
	height: 1000px;
}

.booking__fallback {
	margin: 14px 0 0;
	color: var(--muted);
	font-size: 0.9rem;
	text-align: center;
}

/* Until the script lands, the fallback link is the only thing on offer;
   once the widget is up it would just be noise, so it steps aside. */
.booking__widget:has(iframe) .booking__fallback {
	display: none;
}

.booking__widget .calendly-inline-widget.is-unavailable {
	height: auto;
	min-height: 0;
}

.contact__lede {
	max-width: 52ch;
	margin: 0 0 26px;
	color: var(--muted);
	font-size: 1.02rem;
}

/* ---- Blog index + 404 -----------------------------------------
   Both are plain single-column pages; they borrow .sec-head and
   .kicker from the section styles and need very little of their own.
   --------------------------------------------------------------- */
.blog-index .sec-sub {
	max-width: 56ch;
}

.blog-list {
	margin-top: 46px;
}

.blog-list .wp-block-post-template {
	display: grid;
	gap: 18px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.blog-list .wp-block-post-template > li {
	padding: 30px 28px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
	transition: transform 0.15s, box-shadow 0.15s;
}

.blog-list .wp-block-post-template > li:hover {
	transform: translateY(-3px);
	box-shadow: 0 18px 40px -22px rgba(154, 106, 56, 0.4);
}

.blog-list__date {
	margin: 0 0 8px;
	color: var(--muted);
	font-size: 0.82rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.blog-list h2 {
	margin: 0 0 10px;
	font-size: 1.4rem;
	letter-spacing: -0.02em;
}

.blog-list h2 a {
	color: var(--ink);
	text-decoration: none;
}

.blog-list h2 a:hover {
	color: var(--bronze);
}

.blog-list .wp-block-post-excerpt {
	margin: 0;
}

.blog-list .wp-block-post-excerpt__excerpt {
	margin: 0;
	color: var(--muted);
	font-size: 1rem;
}

.blog-pager {
	margin-top: 38px;
	font-weight: 700;
}

.err__inner {
	max-width: 640px;
}

.err__links {
	margin: 30px 0 0;
	padding: 0;
	list-style: none;
	color: var(--muted);
	line-height: 2.1;
}

.err__links a {
	font-weight: 700;
}

.err__search {
	margin-top: 34px;
	max-width: 420px;
}

/* ===============================================================
   3. Site header / footer
   =============================================================== */
/* The sticky element has to be the template-part wrapper, not .site-bar.
   WordPress renders the header part inside <div class="wp-block-template-part">,
   which is exactly as tall as the header, and sticky only moves an element
   within its parent: set on .site-bar it had no room and never stuck. */
.wp-site-blocks > .wp-block-template-part:has(> .site-bar) {
	position: sticky;
	top: 0;
	z-index: 60;
}

/* With the header pinned, an in-page jump (/#what, /#pricing, …) would land the
   section's heading underneath it. Offset anchor scrolling by the bar's height
   plus a little air. */
html {
	scroll-padding-top: 84px;
}

/* Logged in, the admin bar is fixed across the top; sit below it instead of
   under it. Below 600px core stops fixing the admin bar, so neither do we. */
.admin-bar .wp-site-blocks > .wp-block-template-part:has(> .site-bar) {
	top: 32px;
}

@media (max-width: 782px) {
	.admin-bar .wp-site-blocks > .wp-block-template-part:has(> .site-bar) {
		top: 46px;
	}
}

@media (max-width: 600px) {
	.admin-bar .wp-site-blocks > .wp-block-template-part:has(> .site-bar) {
		top: 0;
	}
}

.site-bar__inner {
	min-height: 66px;
	gap: 28px;
}

/* Brand lockup — the reversed logo, linked home. */
.brand {
	flex-shrink: 0;
	margin: 0;
}

.brand a {
	display: block;
}

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

.site-nav {
	color: #f0dcc4;
	font-size: 0.9rem;
	font-weight: 600;
}

.site-nav a {
	transition: color 0.15s;
}

.site-nav a:hover {
	color: #fff;
}

.site-bar__cta .wp-block-button__link {
	padding: 9px 18px;
	border-radius: 6px;
	font-size: 0.86rem;
}

.site-footer {
	padding-top: 56px;
	padding-bottom: 34px;
	color: #9d938a;
	font-size: 0.9rem;
}

.site-footer a {
	color: #d8cec3;
	transition: color 0.15s;
}

.site-footer a:hover {
	color: #fff;
}

.site-footer__cols {
	display: grid;
	grid-template-columns: 1.4fr 1fr 0.8fr 0.9fr;
	gap: 40px;
	align-items: start;
}

.site-footer__col > * {
	margin-top: 0;
	margin-bottom: 0;
}

.site-footer__col > * + * {
	margin-top: 14px;
}

.site-footer .is-brand .brand img {
	height: 34px;
}

.site-footer__blurb {
	max-width: 34ch;
	line-height: 1.65;
}

.site-footer__cta a {
	color: var(--butter);
	font-weight: 700;
	text-decoration: none;
}

.site-footer__cta a:hover {
	color: #fff;
}

.site-footer__head {
	margin: 0;
	color: var(--ink-text-bright);
	font-size: 0.78rem;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.site-footer__addr a,
.site-footer__contact a,
.site-footer__links a {
	text-decoration: none;
}

.site-footer__addr a:hover,
.site-footer__contact a:hover,
.site-footer__links a:hover {
	text-decoration: underline;
}

.site-footer__addr,
.site-footer__contact {
	line-height: 1.8;
}

.site-footer__links {
	padding: 0;
	list-style: none;
	line-height: 1.9;
}

.site-footer__bar {
	gap: 16px;
	align-items: center;
	margin-top: 42px;
	padding-top: 22px;
	border-top: 1px solid var(--ink-line);
	font-size: 0.85rem;
}

.site-footer__bar p {
	margin: 0;
}

/* ===============================================================
   4. Home — hero
   =============================================================== */
.hero__inner {
	display: grid;
	grid-template-columns: 1.02fr 0.98fr;
	gap: 56px;
	align-items: center;
	padding-top: 76px;
	padding-bottom: 84px;
}

.hero h1 {
	margin: 0;
}

.hero .lede {
	max-width: 38ch;
	margin-top: 24px;
	color: var(--muted);
	font-size: 1.16rem;
}

.hero .lede strong {
	color: var(--ink);
	font-weight: 700;
}

.hero__actions {
	gap: 18px;
	align-items: center;
	margin-top: 34px;
}

.hero-img {
	height: 440px;
}

/* ===============================================================
   5. Home — trust strip
   =============================================================== */
.trust {
	padding-top: 22px;
	padding-bottom: 22px;
	color: #f0dcc4;
}

.trust__inner {
	gap: 12px 32px;
	align-items: center;
	justify-content: center;
	text-align: center;
}

.trust .label {
	margin: 0;
	font-size: 0.74rem;
	font-weight: 800;
	letter-spacing: 0.14em;
	opacity: 0.75;
	text-transform: uppercase;
}

.trust .names {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 28px;
	justify-content: center;
	margin: 0;
	color: #fff;
	font-size: 0.98rem;
	font-weight: 700;
}

.trust .names p {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0;
}

.trust .names p::before {
	content: "";
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--butter);
}

/* ===============================================================
   6. Home — pain points
   =============================================================== */
/* Every section with a photo behind it gets the same hairline top and bottom,
   so the run of them reads as a set rather than each one floating. The case
   study and the pain points already had it; the rule now covers all of them,
   and the darker line holds up over a photograph where --line disappears. */
.has-photo-bg,
.pain,
.case {
	border-top: 1px solid rgba(20, 19, 19, 0.1);
	border-bottom: 1px solid rgba(20, 19, 19, 0.1);
}

/* Narrow the heading, not its wrapper: the section is a constrained layout,
   so a narrowed direct child gets centred by core's auto margins. */
.pain__top .sec-head {
	max-width: 20ch;
}

.painlist {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 18px;
	margin-top: 48px;
}

.pcard {
	padding: 26px 22px;
	border: 1px solid var(--line);
	border-radius: 12px;
	background: var(--white);
}

.pcard h3 {
	margin: 0 0 8px;
	font-size: 1.02rem;
	letter-spacing: -0.01em;
}

.pcard p {
	margin: 0;
	color: var(--muted);
	font-size: 0.93rem;
	line-height: 1.5;
}

.pain .turn {
	margin: 44px 0 0;
	font-size: 1.5rem;
	font-weight: 800;
	letter-spacing: -0.025em;
	text-align: center;
}

/* A padded chip rather than coloured text: over the blurred office photo it
   needs its own ground to stand out. nowrap keeps it one chip; left to wrap on
   a phone it split into two, "one" and "system", on separate lines. */
.turn__mark {
	padding: 0.06em 0.36em 0.1em;
	border-radius: 8px;
	background: var(--white);
	color: var(--bronze);
	white-space: nowrap;
}

/* ---- Shared: section with a photo behind it ---------------------
   Added by a pattern once its background image exists. The photo sits
   at the back, a wash in the section's own colour sits over it, and
   the content is lifted above both. --photo-rgb is the section's
   background colour, so the wash and the mobile fade both land on it.

   On a phone the stacked cards make the section several screens
   tall, and a cover-cropped photo behind all of that is a blurry
   sliver. So below 900px the photo becomes a banner behind the
   heading and fades into flat colour before the cards start.
   --------------------------------------------------------------- */
.has-photo-bg {
	position: relative;
	overflow: hidden;
}

.has-photo-bg > * {
	position: relative;
	z-index: 2;
}

/* The section is a constrained layout, which hands every child a centred
   max-width, absolutely positioned ones included. */
.has-photo-bg > .sec-bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	max-width: none;
	margin: 0;
}

.sec-bg img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.has-photo-bg::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg,
		rgba(var(--photo-rgb), 0.95) 0%,
		rgba(var(--photo-rgb), 0.76) 55%,
		rgba(var(--photo-rgb), 0.86) 100%);
}

.pain {
	--photo-rgb: 253, 244, 220;
}

/* The pain photo is blurred to make the job sheets unreadable (it is a real
   client office), and a blurred photo stays out of the text's way on its own.
   So this section can take a much lighter wash than the sharp backbone photo,
   which is what lets the clutter actually read as clutter. Desktop only; the
   mobile banner rules below replace it. */
@media (min-width: 901px) {
	.pain.has-photo-bg::after {
		background: linear-gradient(180deg,
			rgba(var(--photo-rgb), 0.92) 0%,
			rgba(var(--photo-rgb), 0.68) 50%,
			rgba(var(--photo-rgb), 0.88) 100%);
	}
}

.backbone {
	--photo-rgb: 254, 248, 242;
}

.how {
	--photo-rgb: 255, 255, 255;
}

/* Heading and its lead sit side by side, as in the AI and team sections. It
   saves a few hundred pixels of height and keeps the copy out of the walkers'
   faces, which is where the photo is busiest. */
.how__head {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 52px;
	align-items: end;
}

.how__head .sec-sub {
	margin: 0;
}

/* This photo is bright and high-contrast exactly where the heading falls, so
   the wash is heaviest across the top band and eases off over the middle,
   where only the cards sit. */
@media (min-width: 901px) {
	.how.has-photo-bg::after {
		background: linear-gradient(180deg,
			rgba(var(--photo-rgb), 0.97) 0%,
			rgba(var(--photo-rgb), 0.93) 26%,
			rgba(var(--photo-rgb), 0.8) 52%,
			rgba(var(--photo-rgb), 0.9) 100%);
	}
}

/* Cards over a photograph need a resting shadow; flat-edged they read as holes
   cut in the image. */
.has-photo-bg .pcard,
.has-photo-bg .bcard {
	box-shadow: 0 20px 44px -28px rgba(20, 19, 19, 0.45);
}

/* ===============================================================
   7. Shared — full-bleed photo band
   =============================================================== */
.band {
	position: relative;
	display: flex;
	min-height: 380px;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: var(--ink);
	color: #fff;
	text-align: center;
}

.band__txt {
	padding: 70px 24px;
}

.band .kicker {
	color: var(--butter);
	letter-spacing: 0.18em;
}

.band h2 {
	max-width: 17ch;
	margin: 0 auto;
}

/* ---- Video facade ---------------------------------------------
   A poster and a play button until someone presses it, at which
   point video.js appends the iframe and .is-playing hides the two.
   Used in the home hero, where .hero-video swaps the 16:9 box for
   the hero slot's fixed height.
   --------------------------------------------------------------- */
.video-embed {
	position: relative;
	overflow: hidden;
	aspect-ratio: 16 / 9;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--ink);
	box-shadow: 0 24px 50px -30px rgba(20, 19, 19, 0.5);
}

/* In the hero the box takes the old photo slot's height instead of a 16:9
   ratio; declared after .video-embed so it actually wins the aspect-ratio. */
.hero-video {
	height: 440px;
	aspect-ratio: auto;
}

.video-embed__poster,
.video-embed iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

.video-embed__play {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	background: linear-gradient(180deg, rgba(20, 19, 19, 0.1), rgba(20, 19, 19, 0.55));
	color: #fff;
	font-weight: 700;
	text-decoration: none;
	transition: background 0.15s;
}

.video-embed__play:hover,
.video-embed__play:focus-visible {
	background: linear-gradient(180deg, rgba(20, 19, 19, 0.2), rgba(20, 19, 19, 0.65));
	color: #fff;
}

.video-embed__icon {
	display: block;
	width: 76px;
	height: 76px;
	border-radius: 50%;
	background: var(--bronze);
	box-shadow: 0 10px 30px -10px rgba(20, 19, 19, 0.7);
	transition: transform 0.15s, background 0.15s;
}

/* The triangle is drawn with a clip-path rather than a glyph or an SVG file so
   it stays crisp at any size and needs no extra request. */
.video-embed__icon::after {
	content: "";
	display: block;
	width: 100%;
	height: 100%;
	background: #fff;
	clip-path: polygon(38% 30%, 38% 70%, 70% 50%);
}

.video-embed__play:hover .video-embed__icon,
.video-embed__play:focus-visible .video-embed__icon {
	transform: scale(1.06);
	background: var(--bronze-deep);
}

.video-embed__label {
	font-size: 0.98rem;
	letter-spacing: 0.01em;
	text-shadow: 0 1px 10px rgba(20, 19, 19, 0.5);
}

.video-embed__len {
	opacity: 0.8;
	font-weight: 600;
}

.video-embed.is-playing .video-embed__poster,
.video-embed.is-playing .video-embed__play {
	display: none;
}

/* ===============================================================
   8. Home — operational backbone
   =============================================================== */
.bb-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 22px;
	margin-top: 46px;
}

.bcard {
	padding: 32px 28px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
	transition: transform 0.15s, box-shadow 0.15s;
}

.bcard:hover {
	transform: translateY(-3px);
	box-shadow: 0 18px 40px -22px rgba(154, 106, 56, 0.4);
}

.bcard h3 {
	margin: 0 0 12px;
	font-size: 1.28rem;
}

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

/* ---- How we work ---------------------------------------------
   Shares .bb-grid/.bcard with the backbone section above; only the
   column count and the closing line differ. Four cards at 1160px
   would leave each one a narrow column of text, so they sit 2x2.
   --------------------------------------------------------------- */
.bb-grid.is-four {
	grid-template-columns: repeat(2, 1fr);
}

/* .how__foot is the only child of its group, so WordPress's layout styles
   zero its margin-block-start via :first-child. Matching that specificity
   with the section class is enough to win it back. */
.how .how__foot {
	max-width: 60ch;
	margin: 38px 0 0;
	color: var(--ink);
	font-size: 1.06rem;
	font-weight: 600;
}

/* ===============================================================
   9. Home — AI capability (dark)
   =============================================================== */
.ai .kicker {
	color: var(--butter);
}

.ai__intro {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 52px;
	align-items: end;
	margin-bottom: 46px;
}

.ai__intro p {
	margin: 0;
	color: var(--ink-text-bright);
	font-size: 1.08rem;
}

.ai__intro p strong {
	color: #fff;
}

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

.aicard {
	padding: 30px 26px;
	border: 1px solid var(--ink-line);
	border-radius: 14px;
	background: var(--ink-raised);
}

.aicard h3 {
	margin: 0 0 10px;
	color: #fff;
	font-size: 1.18rem;
}

.aicard p {
	margin: 0;
	color: var(--ink-text);
	font-size: 0.96rem;
}

.ai .proof {
	margin: 38px 0 0;
	padding: 22px 26px;
	border: 1px solid var(--ink-line);
	border-left: 3px solid var(--butter);
	border-radius: 12px;
	background: var(--ink-raised);
	color: #e8dccd;
	font-size: 1rem;
}

.ai .proof strong {
	color: #fff;
}

/* ===============================================================
   10. Home — case study
   =============================================================== */
.case {
	position: relative;
	overflow: hidden;
}

/* Crownpack's own factory floor, sitting under the section as texture. The
   wash has to stay heavy: the section before this one is the dark AI band, so
   this one has to keep reading as light, and the body copy on top of it is
   ink on near-white. Same layering as .band — real <img> for the crop and
   lazy-loading, tint in ::after, content lifted above both. */
.case__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	border-radius: 0;
	/* The section is a constrained layout, which hands every child a centred
	   max-width — including an absolutely positioned one, which would leave the
	   photo floating in a column instead of spanning the section. */
	max-width: none;
	margin: 0;
}

/* The wash is light now that the copy sits on its own card rather than
   directly on the photo: enough to keep the section reading as warm and to
   stop the factory fighting the cards, not enough to hide it. */
.case::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(254, 248, 242, 0.42), rgba(243, 230, 214, 0.52));
}

.case__grid {
	position: relative;
	z-index: 2;
	display: grid;
	grid-template-columns: 1.05fr 0.95fr;
	gap: 56px;
	align-items: center;
}

/* Both columns carry the same card treatment as .bcard, so they read as
   solid objects sitting on the photo rather than washes over it. */
.case__body {
	padding: 36px 34px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
}

.case-img {
	height: 480px;
	border: 1px solid var(--line);
}

/* Same arrangement as the project cards' silent previews: the still sits in
   the markup underneath and the clip plays over it, so a decode failure or no
   JavaScript leaves a picture rather than a hole.

   The box takes the recording's own shape rather than .case-img's fixed
   height: the full capture zooms in and out, and any cover-crop tight enough
   to fill a squarer box let the desktop behind the app show at the edges. */
.case-media {
	position: relative;
	height: auto;
	aspect-ratio: 960 / 608;
}

.case-media__vid {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}


/* A resting shadow, which .bcard doesn't need on its flat background: over a
   photograph a flat-edged card reads as a hole punched in the image rather
   than an object sitting on it. */
.case__body,
.case-img {
	box-shadow: 0 24px 50px -30px rgba(20, 19, 19, 0.5);
}

/* Green, because the system is live: this reads as a status light rather than
   the butter-yellow "in progress" it replaced. */
.case .badge {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 18px;
	padding: 6px 12px;
	border-radius: 20px;
	background: #e3f1e2;
	color: #1f5122;
	font-size: 0.72rem;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.case .badge::before {
	content: "";
	width: 7px;
	height: 7px;
	flex-shrink: 0;
	border-radius: 50%;
	background: #2e7d32;
	animation: idsw-pulse 2s ease-out infinite;
}

/* The ring is drawn by the shadow rather than a second element, so the dot
   stays a single ::before and the badge markup is untouched. */
@keyframes idsw-pulse {
	0% {
		box-shadow: 0 0 0 0 rgba(46, 125, 50, 0.55);
	}

	70% {
		box-shadow: 0 0 0 7px rgba(46, 125, 50, 0);
	}

	100% {
		box-shadow: 0 0 0 0 rgba(46, 125, 50, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.case .badge::before {
		animation: none;
	}
}

.case h2 {
	margin: 0 0 20px;
	font-size: clamp(1.8rem, 3.2vw, 2.5rem);
}

.case p {
	margin: 0 0 16px;
	color: var(--muted);
	font-size: 1.06rem;
}

.case p strong {
	color: var(--ink);
}

/* Kept for a client quote that is drafted but not yet signed off: the markup
   is out of case-study-crownpack.php until it is. Not dead code. */
.case .quote {
	margin: 26px 0;
	padding: 4px 0 4px 20px;
	border-left: 3px solid var(--bronze);
	color: var(--ink);
	font-size: 1.12rem;
	font-style: italic;
	font-weight: 600;
}

/* core/quote wraps its text in a paragraph; keep the quote's own type. */
.case .quote p {
	margin: 0;
	color: inherit;
	font-size: inherit;
}

.case .quote cite {
	display: block;
	margin-top: 10px;
	color: var(--muted);
	font-size: 0.88rem;
	font-style: normal;
	font-weight: 700;
}

.case .soon {
	margin: 8px 0 0;
	padding-top: 16px;
	border-top: 1px solid var(--line);
	font-size: 0.88rem;
}

/* ===============================================================
   11. Home — why us
   =============================================================== */
.why {
	border-bottom: 1px solid var(--line);
}

.why__grid {
	display: grid;
	grid-template-columns: 0.92fr 1.08fr;
	gap: 56px;
	align-items: center;
}

.why-img {
	height: 460px;
}

.why .lead {
	margin: 0 0 22px;
	color: var(--ink);
	font-size: 1.45rem;
	font-weight: 700;
	letter-spacing: -0.025em;
	line-height: 1.3;
}

.why p {
	margin: 0 0 18px;
	color: var(--muted);
	font-size: 1.06rem;
}

.why p strong {
	color: var(--ink);
}

.why ul {
	margin: 26px 0 0;
	padding: 0;
	list-style: none;
}

.why li {
	display: flex;
	gap: 14px;
	padding: 13px 0;
	border-top: 1px solid var(--line);
	font-size: 1rem;
}

.why li:first-child {
	border-top: 0;
}

.why li::before {
	content: "→";
	flex-shrink: 0;
	color: var(--bronze);
	font-weight: 900;
}

/* ===============================================================
   12. Home — team
   =============================================================== */
.team__head {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 52px;
	align-items: end;
	margin-bottom: 48px;
}

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

.tgrid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 26px;
	max-width: 760px;
	margin: 0 auto;
}

.tcard {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--line);
	border-radius: 16px;
	background: var(--white);
	transition: transform 0.15s, box-shadow 0.15s;
}

.tcard:hover {
	transform: translateY(-4px);
	box-shadow: 0 22px 46px -24px rgba(154, 106, 56, 0.45);
}

.tcard .is-image-slot {
	height: 300px;
	border-radius: 0;
}

.tbody {
	padding: 26px 24px 28px;
}

.tbody .nm {
	margin: 0;
	font-size: 1.28rem;
	font-weight: 800;
	letter-spacing: -0.02em;
}

.tbody .role {
	margin: 3px 0 0;
	color: var(--bronze);
	font-size: 0.9rem;
	font-weight: 700;
}

.tbody .bio {
	margin: 14px 0 0;
	color: var(--muted);
	font-size: 0.96rem;
}

.tbody .prov {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: 18px 0 0;
}

.tbody .prov p {
	padding: 4px 10px;
	border: 1px solid var(--line);
	border-radius: 20px;
	background: var(--butter-soft);
	color: #7a6a52;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.03em;
}

.team .foot {
	margin: 40px 0 0;
	color: var(--ink);
	font-size: 1.15rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	text-align: center;
}

/* ===============================================================
   13. Home — pricing paths
   =============================================================== */
.paths {
	border-top: 1px solid var(--line);
}

.pgrid {
	display: grid;
	grid-template-columns: 1.25fr 0.75fr;
	gap: 24px;
	margin-top: 46px;
}

.path {
	display: flex;
	flex-direction: column;
	padding: 38px 34px;
	border: 1px solid var(--line);
	border-radius: 16px;
	background: var(--white);
}

.path.is-primary {
	border-color: var(--bronze);
	background: var(--bronze);
	color: #fff;
}

.path .tag {
	margin: 0;
	color: var(--bronze);
	font-size: 0.72rem;
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.path.is-primary .tag {
	color: var(--butter);
}

.path h3 {
	margin: 12px 0 14px;
	font-size: 1.65rem;
	letter-spacing: -0.025em;
}

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

.path.is-primary p {
	color: #f2e2cd;
}

.path .price {
	margin: 24px 0 6px;
	color: var(--ink);
	font-size: 2.3rem;
	font-weight: 900;
	letter-spacing: -0.03em;
	line-height: 1.1;
}

.path .price-note {
	margin: 6px 0 0;
	color: var(--muted);
	font-size: 0.84rem;
	font-weight: 600;
	letter-spacing: 0;
}

.path.is-primary .price {
	color: #fff;
}

.path.is-primary .price-note {
	color: #e8d3b8;
}

.path ul {
	flex: 1;
	margin: 20px 0 0;
	padding: 0;
	list-style: none;
}

.path li {
	display: flex;
	gap: 11px;
	padding: 9px 0;
	font-size: 0.96rem;
}

.path li::before {
	content: "✓";
	flex-shrink: 0;
	color: var(--bronze);
	font-weight: 900;
}

.path.is-primary li::before {
	color: var(--butter);
}

.path .wp-block-buttons {
	margin-top: 26px;
}

.path .wp-block-button {
	width: 100%;
}

.path .wp-block-button__link {
	display: block;
	text-align: center;
}

/* ===============================================================
   14. Shared — FAQ
   =============================================================== */
.faq {
	border-top: 1px solid var(--line);
}

.faq .faq__list {
	margin-top: 34px;
	border-top: 1px solid var(--line);
}

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

.faq summary {
	position: relative;
	padding: 22px 44px 22px 4px;
	cursor: pointer;
	font-size: 1.08rem;
	font-weight: 700;
	list-style: none;
}

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

.faq summary::after {
	content: "+";
	position: absolute;
	top: 50%;
	right: 8px;
	color: var(--bronze);
	font-size: 1.5rem;
	font-weight: 400;
	transform: translateY(-50%);
	transition: transform 0.2s;
}

.faq details[open] summary::after {
	transform: translateY(-50%) rotate(45deg);
}

.faq details p {
	max-width: 70ch;
	margin: 0;
	padding: 0 44px 22px 4px;
	color: var(--muted);
	font-size: 1.01rem;
}

/* ===============================================================
   15. Shared — final CTA
   =============================================================== */
.final {
	text-align: center;
}

.final__inner {
	padding-top: 100px;
	padding-bottom: 100px;
}

.final .kicker {
	color: var(--butter);
}

.final h2 {
	max-width: 17ch;
	margin: 0 auto;
	font-size: clamp(2.1rem, 3.8vw, 3rem);
}

.final p {
	max-width: 48ch;
	margin: 22px auto 0;
	color: #f2e2cd;
	font-size: 1.14rem;
}

.final .wp-block-buttons {
	justify-content: center;
	margin-top: 34px;
}

.final .wp-block-button__link {
	padding: 17px 36px;
	font-size: 1.05rem;
}

.final .sub {
	/* auto side margins matter: .final p sets max-width, so margin-left:0
	   would park this narrow box against the left edge instead of centring. */
	margin: 18px auto 0;
	color: #e8d3b8;
	font-size: 0.9rem;
}

/* ===============================================================
   16. Projects — home page grid, archive, and single project
   ---------------------------------------------------------------
   Cards are driven by a query loop, so the grid is the post-template
   list itself and each card is an <li>.
   =============================================================== */
.work-grid .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 22px;
	margin: 46px 0 0;
	padding: 0;
	list-style: none;
}

.work-grid .wp-block-post-template > li {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
	transition: transform 0.15s, box-shadow 0.15s;
}

.work-grid .wp-block-post-template > li:hover {
	transform: translateY(-3px);
	box-shadow: 0 18px 40px -22px rgba(154, 106, 56, 0.4);
}

.work-grid .wp-block-post-featured-image {
	position: relative;
	margin: 0;
	border-bottom: 1px solid var(--line);
}

.work-grid .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	height: 210px;
	object-fit: cover;
}

/* Silent looping preview, sitting over the featured image which doubles as its
   poster. Anything that stops the video showing reveals the still underneath. */
.card-video {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ---- Click-to-play controls for the local silent clips ---------
   The clip sits over its still and stays invisible until played, so
   the still is what shows at rest and there is no flash of an empty
   video element while it buffers.
   --------------------------------------------------------------- */
.vid-play {
	position: relative;
}

.card-video,
.case-media__vid {
	opacity: 0;
	transition: opacity 0.2s;
}

.vid-play.is-playing .card-video,
.vid-play.is-playing .case-media__vid {
	opacity: 1;
}

/* When the whole surface is the control, say so with the cursor. */
.vid-play.is-surface {
	cursor: pointer;
}

.vid-play__btn {
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 2;
	display: grid;
	width: 68px;
	height: 68px;
	place-items: center;
	padding: 0;
	transform: translate(-50%, -50%);
	border: 0;
	border-radius: 50%;
	background: var(--bronze);
	box-shadow: 0 10px 30px -10px rgba(20, 19, 19, 0.7);
	cursor: pointer;
	transition: transform 0.15s, background 0.15s, opacity 0.2s;
}

.vid-play__btn:hover,
.vid-play__btn:focus-visible {
	background: var(--bronze-deep);
	transform: translate(-50%, -50%) scale(1.06);
}

/* On a project card the whole image is a link to the project, so the control
   tucks into a corner and leaves the rest of it clickable. */
.vid-play__btn.is-corner {
	top: auto;
	left: auto;
	right: 14px;
	bottom: 14px;
	width: 44px;
	height: 44px;
	transform: none;
}

.vid-play__btn.is-corner:hover,
.vid-play__btn.is-corner:focus-visible {
	transform: scale(1.06);
}

.vid-play__icon {
	display: block;
	width: 100%;
	height: 100%;
	background: #fff;
	clip-path: polygon(38% 30%, 38% 70%, 70% 50%);
}

/* Pressed state swaps the triangle for a pause bar pair. */
.vid-play.is-playing .vid-play__icon {
	clip-path: polygon(30% 28%, 44% 28%, 44% 72%, 30% 72%, 56% 72%, 56% 28%, 70% 28%, 70% 72%, 56% 72%, 56% 28%, 44% 28%, 44% 72%);
}

/* Once it is running the control should not sit on top of the thing it
   started; it comes back on hover or keyboard focus. */
.vid-play.is-playing .vid-play__btn {
	opacity: 0;
}

.vid-play.is-playing:hover .vid-play__btn,
.vid-play.is-playing .vid-play__btn:focus-visible {
	opacity: 1;
}

/* Hiding the element also stops playback, so this genuinely honours the
   preference rather than just dimming the motion. */
@media (prefers-reduced-motion: reduce) {
	.card-video {
		display: none;
	}
}

.work-grid .wp-block-post-title {
	margin: 22px 24px 0;
	font-size: 1.15rem;
	letter-spacing: -0.02em;
}

.work-grid .wp-block-post-excerpt {
	margin: 10px 24px 26px;
}

.work-grid .wp-block-post-excerpt__excerpt {
	color: var(--muted);
	font-size: 0.94rem;
}

.work-grid__more {
	margin: 34px 0 0;
	font-size: 0.94rem;
	font-weight: 700;
}

.work-grid__more a {
	padding-bottom: 2px;
	border-bottom: 2px solid var(--butter);
	color: var(--bronze);
}

/* Archive header sits above the grid, so the grid's top margin is redundant. */
.archive-head .wp-block-query-pagination {
	margin-top: 48px;
	font-weight: 700;
}

/* ---- spec panel on a single project ---- */
.project-spec {
	margin: 0 0 32px;
	padding: 24px 26px;
	border: 1px solid var(--line);
	border-left: 3px solid var(--bronze);
	border-radius: 12px;
	background: var(--butter-soft);
}

.project-spec .spec__row {
	margin: 0;
	padding: 7px 0;
	font-size: 0.96rem;
}

.project-spec .spec__row + .spec__row {
	border-top: 1px solid var(--line);
}

.project-spec .spec__row strong {
	display: inline-block;
	min-width: 8.5em;
	color: var(--bronze);
	font-size: 0.76rem;
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	vertical-align: baseline;
}

.project-spec a {
	border-bottom: 1px solid var(--line);
}

/* ===============================================================
   17. Proof of Concept page
   ---------------------------------------------------------------
   Ported from proof-of-concept.html. That design still carried blue
   accents from an earlier template (radial glows, kicker colours, the
   button shadow, a blue-black footer); every one is harmonised to
   bronze/butter here so the PoC reads as the same site as the home
   page. Structure and layout are unchanged.
   =============================================================== */

/* ---- hero ---- */
.poc-hero {
	position: relative;
	overflow: hidden;
}

.poc-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(900px 520px at 80% -12%, rgba(154, 106, 56, 0.3), transparent 60%);
}

.poc-hero__inner {
	position: relative;
	display: grid;
	grid-template-columns: 1.02fr 0.98fr;
	gap: 52px;
	align-items: center;
	padding-top: 92px;
	padding-bottom: 96px;
}

.poc-hero .kicker {
	color: var(--ink-text);
}

.poc-hero .kicker.has-dot::before {
	background: var(--butter);
	box-shadow: 0 0 0 4px rgba(252, 236, 187, 0.16);
}

.poc-hero h1 {
	margin: 0;
	font-size: clamp(2.5rem, 5vw, 3.9rem);
}

.poc-hero .lede {
	max-width: 32ch;
	margin-top: 24px;
	color: var(--ink-text-bright);
	font-size: 1.15rem;
}

.poc-hero__actions {
	gap: 20px;
	align-items: center;
	margin-top: 36px;
}

.poc-hero__actions .wp-block-button__link {
	border-radius: 10px;
	box-shadow: 0 12px 30px -12px rgba(154, 106, 56, 0.75);
}

.price-tag {
	margin: 0;
	color: var(--ink-text);
	font-size: 0.92rem;
}

.price-tag strong {
	color: #fff;
	font-size: 1.12rem;
	font-weight: 800;
}

.poc-hero-img {
	height: 360px;
	border-radius: 16px;
	box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.7);
}

/* ---- stat strip ---- */
.poc-stats {
	border-top: 1px solid var(--ink-line);
	border-bottom: 1px solid var(--ink-line);
}

.poc-stats__inner {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
	padding-top: 38px;
	padding-bottom: 38px;
	text-align: center;
}

.poc-stat .n {
	margin: 0;
	color: #fff;
	font-size: 2.6rem;
	font-weight: 900;
	letter-spacing: -0.03em;
	line-height: 1;
}

.poc-stat .l {
	margin: 10px 0 0;
	color: var(--ink-text);
	font-size: 0.82rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.poc-stat + .poc-stat {
	border-left: 1px solid var(--ink-line);
}

/* ---- trust (dark variant of the home strip) ---- */
.poc-trust {
	padding-top: 26px;
	padding-bottom: 26px;
}

.poc-trust .label {
	margin: 0;
	color: var(--ink-text);
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.poc-trust .names p {
	color: #e8dccd;
}

.poc-trust .names p::before {
	background: var(--bronze);
}

/* ---- problem ---- */
.poc-problem__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 52px;
	align-items: center;
}

.poc-problem .lead {
	margin: 0;
	color: var(--ink);
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.25;
}

.poc-problem .sub {
	margin: 22px 0 0;
	color: var(--muted);
	font-size: 1.08rem;
}

.poc-problem .sub.is-turn {
	margin-top: 16px;
	color: var(--ink);
	font-weight: 700;
}

.poc-problem .pull {
	padding: 28px;
	border: 1px solid var(--line);
	border-left: 4px solid var(--bronze);
	border-radius: 12px;
	background: var(--white);
}

.poc-problem .pull .q {
	margin: 0;
	font-size: 1.3rem;
	font-weight: 800;
	line-height: 1.3;
}

.poc-problem .pull .c {
	margin: 14px 0 0;
	color: var(--muted);
	font-size: 0.96rem;
}

/* ---- deliverables ---- */
.poc-deliver .kicker {
	color: var(--butter);
}

.poc-deliver__cards {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 22px;
	margin-top: 44px;
}

.dcard {
	padding: 30px 26px;
	border: 1px solid var(--ink-line);
	border-radius: 14px;
	background: var(--ink-raised);
	transition: transform 0.15s, border-color 0.15s;
}

.dcard:hover {
	transform: translateY(-3px);
	border-color: #4a3d33;
}

.dcard h3 {
	margin: 0 0 12px;
	color: #fff;
	font-size: 1.28rem;
}

.dcard p {
	margin: 0;
	color: var(--ink-text);
	font-size: 0.98rem;
}

/* ---- why us ---- */
.poc-why__grid {
	display: grid;
	grid-template-columns: 0.9fr 1.1fr;
	gap: 52px;
	align-items: center;
}

.poc-why .who-img {
	height: 420px;
	border-radius: 16px;
}

.poc-why .lead {
	margin: 0 0 22px;
	color: var(--ink);
	font-size: 1.4rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.3;
}

.poc-why p {
	margin: 0 0 18px;
	color: var(--muted);
	font-size: 1.08rem;
}

.poc-why p strong {
	color: var(--ink);
}

/* ---- how it works ---- */
.sprints {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 24px;
	margin-top: 44px;
}

.sprint {
	padding: 32px 30px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
}

.sprint .tag {
	margin: 0;
	color: var(--bronze);
	font-size: 0.74rem;
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.sprint h3 {
	margin: 12px 0 10px;
	font-size: 1.4rem;
}

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

.sprint__price {
	gap: 8px;
	align-items: baseline;
	margin-top: 20px;
}

.sprint__price .amount {
	margin: 0;
	font-size: 1.4rem;
	font-weight: 800;
}

.sprint__price .gst {
	margin: 0;
	color: var(--muted);
	font-size: 0.82rem;
	font-weight: 600;
}

.sprint-full {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	align-items: center;
	justify-content: space-between;
	margin-top: 24px;
	padding: 32px 36px;
	border-radius: 14px;
	background: var(--ink);
	color: #fff;
}

.sprint-full .rec {
	margin: 0;
	color: var(--butter);
	font-size: 0.72rem;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.sprint-full h3 {
	margin: 8px 0;
	color: #fff;
	font-size: 1.5rem;
}

.sprint-full p {
	max-width: 44ch;
	margin: 0;
	color: var(--ink-text);
	font-size: 0.96rem;
}

.sprint-full__amt .amt {
	margin: 0;
	font-size: 2rem;
	font-weight: 900;
	white-space: nowrap;
}

.sprint-full__amt .gst {
	margin: 2px 0 0;
	color: var(--ink-text);
	font-size: 0.88rem;
	font-weight: 600;
}

/* ---- build-cost bands ---- */
.poc-cost .kicker {
	color: var(--butter);
}

.crows {
	overflow: hidden;
	margin-top: 40px;
	border: 1px solid var(--ink-line);
	border-radius: 14px;
}

.crow {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 20px;
	align-items: center;
	padding: 24px 28px;
	border-top: 1px solid var(--ink-line);
}

.crow:first-child {
	border-top: 0;
	background: var(--ink-raised);
}

.crow .t {
	margin: 0;
	font-size: 1.1rem;
	font-weight: 800;
}

.crow .d {
	margin: 4px 0 0;
	color: var(--ink-text);
	font-size: 0.94rem;
}

.crow .amt {
	margin: 0;
	font-size: 1.2rem;
	font-weight: 800;
	white-space: nowrap;
}

.crow.is-head .t,
.crow.is-head .amt {
	color: var(--ink-text);
	font-size: 0.78rem;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.poc-cost .foot {
	max-width: 62ch;
	margin: 22px 0 0;
	color: var(--ink-text);
	font-size: 1rem;
}

.poc-cost .foot strong {
	color: #fff;
}

/* ---- fit ---- */
.poc-fit__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 24px;
	margin-top: 40px;
}

.fitcard {
	padding: 30px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
}

.fitcard.is-yes {
	border-top: 4px solid var(--bronze);
}

.fitcard.is-no {
	border-top: 4px solid var(--line);
}

.fitcard h3 {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 14px;
	font-size: 1.18rem;
}

.fitcard h3::before {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	flex-shrink: 0;
	border-radius: 50%;
	color: #fff;
	font-size: 0.9rem;
	font-weight: 900;
}

.fitcard.is-yes h3::before {
	content: "✓";
	background: var(--bronze);
}

.fitcard.is-no h3::before {
	content: "–";
	background: #b3a798;
}

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

/* ---- final CTA, dark variant ---- */
.final.is-dark {
	position: relative;
	overflow: hidden;
}

.final.is-dark::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(700px 380px at 50% -10%, rgba(154, 106, 56, 0.32), transparent 60%);
}

.final.is-dark .final__inner {
	position: relative;
}

.final.is-dark p {
	color: var(--ink-text-bright);
}

.final.is-dark .sub {
	color: var(--ink-text);
}

/* ===============================================================
   18. Home — Google reviews
   ---------------------------------------------------------------
   The Places API returns at most five reviews and often fewer, so
   the cards sit in a horizontal scroll rail rather than a grid: a
   rail reads correctly at any count, where a three-up grid leaves
   a ragged last row at four or five. Pure CSS — scroll-snap and a
   focusable container, no carousel script.
   =============================================================== */
.grev__wrap {
	margin-top: 42px;
}

/* Holds the star <symbol> for every <use> on the page, so five cards carry one
   copy of the path rather than twenty-five. Must take up no space. */
.grev__defs {
	position: absolute;
	width: 0;
	height: 0;
	overflow: hidden;
}

/* Only rendered while IDSW_GOOGLE_REVIEWS_FIXTURE is on. Deliberately loud:
   fake testimonials reaching the live site would be far worse than ugly. */
.grev__sample {
	margin: 0 0 26px;
	padding: 12px 16px;
	border: 1px dashed var(--bronze);
	border-radius: 10px;
	background: var(--butter-soft);
	color: var(--bronze-deep);
	font-size: 0.88rem;
	font-weight: 700;
}

/* ---- rating summary + Google attribution ----
   Google's terms want the source named next to the reviews, which is what the
   G and its link do. */
.grev__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px 24px;
	padding-bottom: 22px;
	border-bottom: 1px solid var(--line);
}

.grev__score {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
}

.grev__num {
	color: var(--ink);
	font-size: 2.6rem;
	font-weight: 800;
	line-height: 1;
	letter-spacing: -0.03em;
}

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

.grev__source {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	margin: 0;
	font-size: 0.94rem;
	font-weight: 700;
}

.grev__g {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}

.grev__source a,
.grev__more a {
	padding-bottom: 2px;
	border-bottom: 2px solid var(--butter);
	color: var(--bronze);
}

/* ---- stars ----
   Bronze rather than Google's amber: the G beside the rating already says where
   these came from, so the stars can stay on brand. */
.grev-stars {
	display: inline-flex;
	gap: 2px;
}

.grev-star {
	width: 17px;
	height: 17px;
	flex-shrink: 0;
	fill: var(--bronze);
}

.grev-star.is-empty {
	fill: var(--line);
}

/* ---- the rail ---- */
/* Arrow controls, added by reviews.js. Desktop only: below 900px the rail is
   swiped, and a pointer-only affordance would just take up room. */
.grev__nav {
	display: none;
}

@media (min-width: 901px) {
	.grev__nav {
		display: flex;
		gap: 8px;
		align-self: end;
	}
}

.grev__arrow {
	display: grid;
	width: 40px;
	height: 40px;
	place-items: center;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: 50%;
	background: var(--white);
	color: var(--bronze);
	cursor: pointer;
	transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}

.grev__arrow svg {
	width: 18px;
	height: 18px;
}

.grev__arrow:hover:not(:disabled) {
	border-color: var(--bronze);
	background: var(--bronze-tint);
}

.grev__arrow:disabled {
	opacity: 0.35;
	cursor: default;
}

.grev__rail {
	display: flex;
	gap: 22px;
	margin-top: 34px;
	padding-bottom: 16px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: thin;
	scrollbar-color: var(--bronze-tint) var(--cream);
}

/* The rail is the scroll container, so it takes keyboard focus to be arrow-key
   scrollable — which means the ring has to be visible when it does. */
.grev__rail:focus-visible {
	border-radius: 4px;
	outline: 2px solid var(--bronze);
	outline-offset: 8px;
}

.grev__rail::-webkit-scrollbar {
	height: 8px;
}

.grev__rail::-webkit-scrollbar-track {
	border-radius: 4px;
	background: var(--cream);
}

.grev__rail::-webkit-scrollbar-thumb {
	border-radius: 4px;
	background: var(--bronze-tint);
}

/* Three or fewer reviews divide the row and finish flush with the section's
   edges. The theme has no global border-box reset, so the padding has to be
   counted inside the width. */
.grev-card {
	display: flex;
	box-sizing: border-box;
	min-width: 262px;
	max-width: 372px;
	flex: 1 1 0;
	flex-direction: column;
	padding: 28px 26px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--cream);
	scroll-snap-align: start;
}

/* Four or five, and the cards give up 96px so the next one shows at the edge.
   That peek is the only dependable signal that the rail scrolls: macOS hides
   its scrollbars until something touches them. */
.grev__rail.is-scrollable .grev-card {
	max-width: none;
	flex: 0 0 clamp(262px, calc((100% - 44px - 96px) / 3), 340px);
}

.grev-card__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.grev-card__when {
	flex-shrink: 0;
	color: var(--muted);
	font-size: 0.84rem;
}

/* Clamped so one long review can't set the height of every card in the rail;
   the link in the footer is how you get the rest. Browsers without line-clamp
   simply show the whole review, which is a taller card, not a broken one. */
.grev-card__text {
	display: -webkit-box;
	flex: 1 1 auto;
	margin: 18px 0 0;
	padding: 0;
	overflow: hidden;
	border: 0;
	font-size: 0.98rem;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 8;
}

.grev-card__text p {
	margin: 0 0 12px;
	color: var(--ink);
	line-height: 1.62;
}

.grev-card__text p:last-child {
	margin-bottom: 0;
}

.grev-card__by {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-top: 22px;
	padding-top: 18px;
	border-top: 1px solid var(--line);
}

.grev-card__avatar {
	width: 40px;
	height: 40px;
	flex-shrink: 0;
	border-radius: 50%;
	object-fit: cover;
}

/* Reviewers without a profile photo get their initial rather than a hole. */
.grev-card__avatar.is-initial {
	display: grid;
	place-items: center;
	background: var(--bronze-tint);
	color: var(--bronze-deep);
	font-size: 1rem;
	font-weight: 800;
}

.grev-card__who {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: 3px;
}

/* Google hands back whatever case the reviewer typed, so some names arrive
   lowercase and sit oddly beside the properly-cased ones. Capitalising in CSS
   rather than PHP leaves the stored name untouched, so the link's aria-label
   and Google's required attribution still carry it exactly as written. */
.grev-card__name {
	font-size: 0.96rem;
	font-weight: 700;
	letter-spacing: -0.01em;
	text-transform: capitalize;
}

.grev-card__link {
	color: var(--bronze);
	font-size: 0.84rem;
	font-weight: 700;
}

.grev-card__link:hover {
	border-bottom: 2px solid var(--butter);
}

.grev__more {
	margin: 32px 0 0;
	font-size: 0.94rem;
	font-weight: 700;
}

/* ===============================================================
   19. Contact page — hero, form, and the details column
   ---------------------------------------------------------------
   The form is rendered by the [idsw_contact_form] shortcode, so its
   markup is hand-written rather than block output: the class names
   here are the ones inc/contact-form.php emits.
   =============================================================== */
.contact-hero__inner {
	max-width: 780px;
	padding-top: 88px;
	padding-bottom: 88px;
}

.contact-hero h1 {
	margin: 0;
	font-size: clamp(2.4rem, 4.6vw, 3.6rem);
}

.contact-hero .lede {
	margin: 22px 0 0;
	max-width: 60ch;
	color: var(--muted);
	font-size: 1.14rem;
}

.contact-hero .lede strong {
	color: var(--ink);
}

.contact__grid {
	display: grid;
	grid-template-columns: 1.45fr 1fr;
	gap: 56px;
	align-items: start;
}

.contact__form .sec-head {
	margin: 0 0 8px;
}

/* ---- The form ------------------------------------------------- */
.cform {
	/* Not a palette entry: the brand has no red, and errors need to read
	   as errors without fighting the bronze. */
	--error: #a33a2a;
	--error-tint: #fbeeeb;

	margin-top: 28px;
}

.cform__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* Row gap much larger than the 8px inside a row: a label has to read as
	   belonging to the field below it, not the one above. */
	gap: 26px 20px;
}

.cform__row {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin: 0;
	min-width: 0;
}

.cform__row.is-full {
	grid-column: 1 / -1;
}

.cform__label {
	font-size: 0.86rem;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: var(--ink);
}

.cform__optional {
	font-weight: 500;
	color: var(--muted);
	letter-spacing: 0;
}

.cform__hint {
	font-size: 0.86rem;
	line-height: 1.45;
	color: var(--muted);
}

.cform__input {
	width: 100%;
	/* The theme has no global border-box reset, so without this the padding
	   and border are added to the 100% and every field overflows its grid
	   column — running under the next column's label and into the aside. */
	box-sizing: border-box;
	padding: 13px 15px;
	border: 1px solid var(--line);
	border-radius: 8px;
	background: var(--white);
	color: var(--ink);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.45;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.cform__input::placeholder {
	color: #a89880;
}

.cform__input:focus {
	outline: none;
	border-color: var(--bronze);
	box-shadow: 0 0 0 3px rgba(154, 106, 56, 0.18);
}

/* Keyboard users still get a visible ring in forced-colours / no-shadow
   contexts, where the box-shadow above is dropped. */
.cform__input:focus-visible {
	outline: 2px solid transparent;
	outline-offset: 2px;
}

textarea.cform__input {
	min-height: 150px;
	resize: vertical;
}

.cform__row.has-error .cform__input {
	border-color: var(--error);
}

.cform__row.has-error .cform__input:focus {
	box-shadow: 0 0 0 3px rgba(163, 58, 42, 0.16);
}

.cform__error {
	font-size: 0.86rem;
	font-weight: 600;
	color: var(--error);
}

/* Error summary — the landing point after a failed submit. */
.cform__summary {
	margin: 0 0 24px;
	padding: 18px 22px;
	border: 1px solid var(--error);
	border-left-width: 4px;
	border-radius: 10px;
	background: var(--error-tint);
}

.cform__summary:focus {
	outline: 2px solid var(--error);
	outline-offset: 2px;
}

.cform__summary p {
	margin: 0;
	color: var(--error);
}

.cform__summary ul {
	margin: 8px 0 0;
	padding-left: 20px;
	font-size: 0.94rem;
}

.cform__summary li + li {
	margin-top: 4px;
}

.cform__summary a {
	color: var(--error);
	text-decoration: underline;
}

/* Honeypot. Off-screen rather than display:none, which the more careful
   bots test for — and aria-hidden in the markup, so nobody real meets it. */
.cform__pot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.cform__captcha {
	margin-top: 24px;
}

.cform__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px;
	margin-top: 28px;
}

/* Matches the theme.json button element styles — this is a bare <button>,
   so it inherits none of them. */
.cform__submit {
	padding: 15px 32px;
	border: 0;
	border-radius: 8px;
	background: var(--bronze);
	color: var(--white);
	font-family: inherit;
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.2;
	cursor: pointer;
	transition: transform 0.12s, background-color 0.15s;
}

.cform__submit:hover,
.cform__submit:focus {
	background: var(--bronze-deep);
	transform: translateY(-1px);
}

.cform__submit[disabled] {
	opacity: 0.6;
	cursor: progress;
	transform: none;
}

.cform__note {
	margin: 0;
	flex: 1 1 220px;
	font-size: 0.86rem;
	color: var(--muted);
}

.cform__sent {
	padding: 34px 32px;
	border: 1px solid var(--line);
	border-left: 4px solid var(--bronze);
	border-radius: 14px;
	background: var(--white);
}

.cform__sent h3 {
	margin: 0;
}

.cform__sent p {
	margin: 12px 0 0;
	color: var(--muted);
}

/* ---- Details column ------------------------------------------- */
.contact__aside {
	display: flex;
	flex-direction: column;
	gap: 18px;
	margin-top: 28px;
}

.contact-card {
	padding: 28px 26px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
}

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

.contact-card__label {
	margin: 0 0 12px !important;
	font-size: 0.74rem;
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--bronze) !important;
}

.contact-card__line {
	font-size: 1.08rem !important;
	font-weight: 700;
	color: var(--ink) !important;
}

.contact-card__line + .contact-card__line {
	margin-top: 8px !important;
}

.contact-card__line a {
	border-bottom: 2px solid var(--butter);
}

.contact-card__line a:hover {
	border-bottom-color: var(--bronze);
}

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

.contact-steps li {
	position: relative;
	padding-left: 26px;
	color: var(--muted);
	font-size: 0.96rem;
	line-height: 1.5;
}

.contact-steps li + li {
	margin-top: 12px;
}

.contact-steps li::before {
	content: "→";
	position: absolute;
	left: 0;
	top: 0;
	color: var(--bronze);
	font-weight: 700;
}

/* ---- Thank you page ------------------------------------------- */
.thanks__inner {
	max-width: 720px;
	padding-top: 100px;
	padding-bottom: 100px;
}

.thanks h1 {
	margin: 0;
	font-size: clamp(2.3rem, 4.4vw, 3.4rem);
}

.thanks .lede {
	margin: 22px 0 0;
	color: var(--muted);
	font-size: 1.14rem;
}

.thanks .lede a {
	font-weight: 700;
	color: var(--ink);
	border-bottom: 2px solid var(--butter);
}

.thanks .lede a:hover {
	border-bottom-color: var(--bronze);
}

.thanks__next {
	margin-top: 40px;
	padding: 28px 26px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: var(--white);
}

.thanks .wp-block-buttons {
	margin-top: 36px;
}

/* ===============================================================
   20. Responsive — 900px and 560px, matching the source designs.
   =============================================================== */
@media (max-width: 900px) {
	.site-footer__cols {
		grid-template-columns: 1fr 1fr;
		gap: 34px;
	}

	.site-footer .is-brand {
		grid-column: 1 / -1;
	}

	.site-bar__inner {
		gap: 16px;
	}

	.hero__inner {
		grid-template-columns: 1fr;
		gap: 28px;
		padding-top: 56px;
		padding-bottom: 64px;
	}

	.hero-img {
		height: 280px;
	}

	/* Full width on a phone, the fixed height would crop the poster to a
	   portrait sliver; the video's own ratio suits the column better. */
	.hero-video {
		height: auto;
		aspect-ratio: 16 / 9;
	}

	.case__body {
		padding: 28px 24px;
	}

	/* Project cards (home grid and the projects archive) never had a breakpoint
	   and stayed three-up on a phone, squeezing the titles to a word per line. */
	.work-grid .wp-block-post-template {
		grid-template-columns: repeat(2, 1fr);
	}

	.how__head,
	.pain__top,
	.case__grid,
	.why__grid,
	.ai__intro,
	.team__head {
		grid-template-columns: 1fr;
		gap: 32px;
	}

	.painlist {
		grid-template-columns: 1fr 1fr;
	}

	.has-photo-bg > .sec-bg {
		bottom: auto;
		height: 440px;
	}

	.has-photo-bg::after {
		background: linear-gradient(180deg,
			rgba(var(--photo-rgb), 0.72) 0,
			rgba(var(--photo-rgb), 0.82) 240px,
			rgb(var(--photo-rgb)) 440px);
	}

	/* The blurred pain photo doesn't turn into a distracting sliver the way a
	   sharp one does, so on a phone it runs the full height of the section. */
	.pain.has-photo-bg > .sec-bg {
		bottom: 0;
		height: auto;
	}

	.pain.has-photo-bg::after {
		background: linear-gradient(180deg,
			rgba(var(--photo-rgb), 0.88) 0%,
			rgba(var(--photo-rgb), 0.7) 45%,
			rgba(var(--photo-rgb), 0.9) 100%);
	}

	.aigrid,
	.tgrid {
		grid-template-columns: 1fr;
		gap: 26px;
	}

	.bb-grid,
	.bb-grid.is-four,
	.pgrid {
		grid-template-columns: 1fr;
	}

	.case-img,
	.why-img {
		height: 300px;
	}

	/* Proof of Concept — the source design broke at 860px; normalised here. */
	.poc-hero__inner {
		grid-template-columns: 1fr;
		gap: 24px;
		padding-top: 64px;
		padding-bottom: 72px;
	}

	.poc-hero-img {
		height: 260px;
	}

	.poc-stats__inner {
		grid-template-columns: 1fr;
	}

	.poc-stat + .poc-stat {
		border-left: 0;
		border-top: 1px solid var(--ink-line);
		margin-top: 8px;
		padding-top: 20px;
	}

	.poc-problem__grid,
	.poc-why__grid,
	.poc-deliver__cards,
	.sprints,
	.poc-fit__grid {
		grid-template-columns: 1fr;
	}

	.contact__grid {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.contact-hero__inner,
	.thanks__inner {
		padding-top: 60px;
		padding-bottom: 60px;
	}

	.poc-why .who-img {
		height: 300px;
	}

	.sprint-full {
		flex-direction: column;
		align-items: flex-start;
	}

	.crow {
		grid-template-columns: 1fr;
	}

	.grev-card {
		max-width: 340px;
	}

	/* Two-and-a-bit cards visible, so the rail still reads as scrollable. */
	.grev__rail.is-scrollable .grev-card {
		flex-basis: min(340px, 76%);
	}

	.grev__num {
		font-size: 2.2rem;
	}
}

@media (max-width: 560px) {
	.site-footer__cols {
		grid-template-columns: 1fr;
		gap: 30px;
	}

	.work-grid .wp-block-post-template {
		grid-template-columns: 1fr;
		gap: 16px;
		margin-top: 32px;
	}

	/* Full width, a fixed 210px image is a thin letterbox strip; let the card's
	   width set its height instead. The preview video fills the same box. */
	.work-grid .wp-block-post-featured-image img {
		height: auto;
		aspect-ratio: 16 / 10;
	}

	.painlist {
		grid-template-columns: 1fr;
		gap: 10px;
		margin-top: 32px;
	}

	.pcard,
	.backbone .bcard {
		padding: 18px 20px;
	}

	.backbone .bb-grid {
		gap: 10px;
		margin-top: 32px;
	}

	.backbone .bcard h3 {
		margin-bottom: 6px;
		font-size: 1.08rem;
	}

	.backbone .bcard p,
	.pcard p {
		font-size: 0.92rem;
	}

	.cform__grid {
		grid-template-columns: 1fr;
	}

	.cform__actions {
		align-items: stretch;
	}

	.cform__submit {
		width: 100%;
	}

	.grev__head {
		flex-direction: column;
		align-items: flex-start;
	}

	/* One card at a time, with whatever follows showing at the edge. min-width
	   wins over either flex-basis above, so this covers both cases. */
	.grev-card {
		min-width: 85%;
		max-width: none;
		padding: 24px 21px;
	}
}
