@import url("https://fonts.googleapis.com/css2?family=Lora:wght@400;500;600&display=swap");

/* Inter — body / UI. Variable file, only 400-600 is declared. latin-ext */
@font-face {
	font-family: "Inter";
	font-style: normal;
	font-weight: 400 600;
	font-display: swap;
	src: url(/static/inter-latin-ext.woff2) format("woff2");
	unicode-range:
		U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
		U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
		U+A720-A7FF;
}

/* Inter — latin */
@font-face {
	font-family: "Inter";
	font-style: normal;
	font-weight: 400 600;
	font-display: swap;
	src: url(/static/inter.woff2) format("woff2");
	unicode-range:
		U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
		U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   INFINIX RENO — global brand theme tokens.
   Single source of truth for brand colour and type. The UnoCSS theme in
   static/config.js maps its utility colours onto these same hex values, so
   `bg-amber` and `var(--color-primary)` always resolve to the same colour.
   ========================================================================== */
:root {
	/* Identity colours */
	--brand-espresso: #2a211b;
	--brand-amber-gold: #f5c142;
	--brand-amber-text: #956b00;
	--brand-daylight-yellow: #fdf280;
	--brand-light-mortar: #dcd8d1;

	/* Derived shades, only for hover/active states */
	--brand-espresso-dark: #1b140f;
	--brand-amber-gold-dark: #e0a92b;

	/* Semantic roles */
	--color-primary: var(--brand-amber-gold);
	--color-secondary: var(--brand-daylight-yellow);
	--color-dark: var(--brand-espresso);

	--background-main: #ffffff;
	--background-soft: #f7f7f5;
	/* Warm off-white ground and the soft cream form surface, both derived from
	   Amber Gold rather than being new hues. */
	--background-warm: #fcfbf7;
	--surface-cream: #fff6e0;

	--text-primary: var(--brand-espresso);
	--text-secondary: #7a736b;
	--text-on-dark: #f2f2f2;

	--border-color: var(--brand-light-mortar);

	/* One brand gradient, used sparingly as a thin decorative rule */
	--brand-gradient: linear-gradient(
		90deg,
		#2a211b 0%,
		#f5c142 35%,
		#fdf280 65%,
		#dcd8d1 100%
	);

	--font-display: "Lora", Georgia, serif;
	--font-body: "Inter", Arial, sans-serif;
}

html {
	font-size: 14px;
}

body {
	font-family: var(--font-body);
	font-optical-sizing: auto;
	font-style: normal;
	/* 11px. The root is left at 14px so rem spacing does not move. */
	font-size: 0.7857rem;
	line-height: 1.55;
	letter-spacing: 0.005em;
	color: var(--text-primary);
	background-color: var(--background-main);
}

/* Headings are Lora everywhere, so a missing utility class can never
   silently fall back to the body sans. */
h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--font-display);
	font-weight: 500;
	line-height: 1.12;
	letter-spacing: -0.02em;
	color: var(--text-primary);
}

/* Display sizes live here rather than in per-page utilities: the root is 14px,
   so the utility scale tops out below the brand's H1 range. clamp() covers
   mobile -> tablet -> desktop in one declaration. A page that deliberately
   wants a small heading still overrides these with a text-* utility. */
h1 {
	font-size: clamp(30px, 4.15vw, 60px);
	line-height: 1.06;
	letter-spacing: -0.035em;
}

h2 {
	font-size: clamp(22px, 2.6vw, 41px);
	line-height: 1.14;
	letter-spacing: -0.03em;
}

.same-as-h2 {
	font-family: var(--font-display);
	font-size: clamp(22px, 2.6vw, 41px);
	font-weight: 500;
	line-height: 1.14;
	letter-spacing: -0.03em;
	color: inherit;
}

/* Home page section headers, set larger so they carry some of the weight the
   hero H1 does. Size only: they stay in title case, and the tracking stays on
   the base -0.03em above, which is tuned for lower-case. Scoped to .home-page
   on purpose: every other page keeps the base h2. The closing CTA heading is a
   <p class="same-as-h2"> rather than an h2, so it is named here too or it
   would be the one section header left behind at the old size. The footer's
   headings sit outside <main class="home-page">, so they are untouched. */
.home-page :is(h2, .same-as-h2) {
	font-size: clamp(26px, 3.2vw, 46px);
}

.stat-value {
	font-size: clamp(34px, 7.2vw, 62px);
	font-weight: 700;
	color: #6b2513;
}

.fx-foil {
	font-weight: 700;
	color: transparent;
	background: linear-gradient(
		108deg,
		#7a4a08 0%,
		#f2c15d 18%,
		#fff4b8 24%,
		#b87014 36%,
		#f6d66d 51%,
		#8e560b 68%,
		#fff0a2 76%,
		#c98218 100%
	) 0 0 / 230% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	text-shadow:
		0 1px 0 rgba(255, 244, 184, 0.45),
		0 9px 20px rgba(0, 0, 0, 0.36);
	animation: fx-foil 3.1s ease-in-out infinite;
}

.fx-foil--hero {
	animation-duration: 5.5s;
}

@keyframes fx-foil {
	0%,
	100% {
		background-position: 115% 0;
		filter: saturate(1.05);
	}
	45% {
		background-position: -35% 0;
		filter: saturate(1.35) brightness(1.12);
	}
}

@media (prefers-reduced-motion: reduce) {
	.fx-foil {
		animation: none;
		background-position: 50% 0;
	}
}

h3 {
	font-size: clamp(18px, 1.65vw, 26px);
	line-height: 1.25;
	letter-spacing: -0.02em;
}

.text-accent {
	color: var(--brand-amber-text);
}

.text-highlight {
	display: inline-block;
	background: linear-gradient(to right, #c6a15b 0%, #7a4a08 38%, #d2b46c 50%, #956b00 50%, #b8964e 100%);
	background-clip: text;
	-webkit-background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.premium-shell {
	position: relative;
	isolation: isolate;
	border: 1px solid rgba(220, 216, 209, 0.9);
	border-radius: 20px;
	background: linear-gradient(145deg, rgba(255, 255, 255, 0.98), rgba(252, 251, 247, 0.92));
	box-shadow:
		0 24px 60px -38px rgba(42, 33, 27, 0.42),
		0 8px 20px -16px rgba(42, 33, 27, 0.2);
}

.premium-shell::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: linear-gradient(120deg, rgba(245, 193, 66, 0.14), transparent 30%);
	pointer-events: none;
	z-index: -1;
}

.premium-card {
	border: 1px solid rgba(220, 216, 209, 0.78);
	border-radius: 16px;
	background: rgba(255, 255, 255, 0.88);
	box-shadow: 0 16px 34px -26px rgba(42, 33, 27, 0.48);
	transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}

.premium-card:hover {
	transform: translateY(-3px);
	border-color: rgba(245, 193, 66, 0.7);
	box-shadow: 0 22px 40px -26px rgba(42, 33, 27, 0.48);
}

/* Card rows that used to be a non-wrapping flex strip: the About Us philosophy
   and strengths lists, "What You Get From the First Conversation" on Contact
   Us, and "Why It Is Worth Doing Properly" on each service page.
   One column on phones, two once a card can still hold a comfortable measure,
   three only past 1280px where each card keeps ~360px. A trailing odd card
   spans the two-column row but is capped at one column's width and centred, so
   the rule keeps working whatever the card count becomes. */
.card-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 1.75rem;
	justify-items: center;
	align-items: stretch;
}

/* min-width: 0 so a long unbroken word wraps instead of widening the column. */
.card-grid > * {
	width: 100%;
	min-width: 0;
	max-width: 32rem;
}

@media (min-width: 768px) {
	.card-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.card-grid > * {
		max-width: none;
	}

	.card-grid > :last-child:nth-child(odd) {
		grid-column: 1 / -1;
		max-width: calc(50% - 0.875rem);
	}
}

@media (min-width: 1280px) {
	.card-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.card-grid > :last-child:nth-child(odd) {
		grid-column: auto;
		max-width: none;
	}
}

.testimonials-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

.testimonial-second,
.testimonial-third {
	display: none;
}

@media (min-width: 768px) {
	.testimonials-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.testimonial-second {
		display: block;
	}
}

@media (min-width: 1024px) {
	.testimonials-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.testimonial-third {
		display: block;
	}
}

@media (prefers-reduced-motion: reduce) {
	.premium-card:hover {
		transform: none;
	}
}

/* Button interaction: a small lift and a soft shadow on hover, pressed back
   down on click. Kept off the transform of anything that also animates in. */
.btn-lift {
	will-change: transform;
}

.btn-lift:hover:not(:disabled) {
	transform: translateY(-2px);
	box-shadow: 0 10px 22px -10px rgba(42, 33, 27, 0.45);
}

.btn-lift:active:not(:disabled) {
	transform: translateY(0);
	box-shadow: 0 4px 10px -6px rgba(42, 33, 27, 0.4);
}

.button-primary {
	background: linear-gradient(135deg, var(--brand-espresso) 0%, #4b2b1c 52%, var(--brand-espresso-dark) 100%);
	box-shadow: 0 10px 24px -14px rgba(42, 33, 27, 0.8);
}

.button-primary:disabled {
	background: var(--brand-light-mortar);
}

.button-primary:hover:not(:disabled) {
	box-shadow:
		0 12px 26px -12px rgba(42, 33, 27, 0.9),
		0 0 0 2px rgba(245, 193, 66, 0.28);
}

.button-primary:active:not(:disabled) {
	box-shadow: 0 5px 12px -8px rgba(42, 33, 27, 0.8);
}

.cta-section__action {
	min-height: 3.5rem;
	padding-inline: 2rem;
	border-color: var(--brand-amber-gold);
	box-shadow:
		0 12px 26px -12px rgba(42, 33, 27, 0.9),
		0 0 0 1px rgba(245, 193, 66, 0.22);
}

.cta-section__action:hover:not(:disabled) {
	transform: translateY(-2px);
	box-shadow:
		0 16px 30px -12px rgba(42, 33, 27, 0.95),
		0 0 0 3px rgba(245, 193, 66, 0.28);
}

.cta-section__action:focus-visible {
	outline: 2px solid var(--brand-amber-gold);
	outline-offset: 3px;
}

@media (max-width: 767.98px) {
	.cta-section__action {
		width: min(100%, 22rem);
	}
}

/* Submitting state. htmx puts .htmx-request on the form while its request is
   in flight, so the button can say what is happening; hx-disabled-elt disables
   it at the same time, which is what stops a second submission. */
.form-busy-label {
	display: none;
}

.htmx-request .form-busy-label {
	display: inline;
}

.htmx-request .form-idle-label {
	display: none;
}

/* Projects hub pager. Every card for a category is in the DOM; the pager shows
   one window of them — three on phones, six from md up — so the window can
   follow the viewport without a round trip. Until Alpine takes over, the same
   window is enforced here, so the grid never flashes the whole category. */
.project-list:not([data-ready]) .project-grid > :nth-child(n + 4) {
	display: none;
}

@media (min-width: 768px) {
	.project-list:not([data-ready]) .project-grid > :nth-child(n + 7) {
		display: none;
	}
}

/* Each card fades up in turn. `backwards` rather than `both`: the card must let
   go of the transform when it finishes, or the hover lift below stops working.
   Turning display back on replays the animation, so every page change staggers
   without any JavaScript driving it. */
.project-grid .project-card {
	animation: project-card-in 380ms ease-out backwards;
	animation-delay: calc(var(--card-slot, 0) * 70ms);
}

@keyframes project-card-in {
	from {
		opacity: 0;
		transform: translateY(10px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

.project-pager__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	color: var(--brand-espresso);
	border-radius: 9999px;
	transition:
		color 200ms ease,
		transform 200ms ease,
		opacity 200ms ease;
}

.project-pager__button svg {
	width: 100%;
	height: 100%;
}

.project-pager__button:hover:not(:disabled) {
	color: var(--brand-amber-gold);
	transform: translateY(-1px);
}

.project-pager__button:disabled {
	opacity: 0.35;
	cursor: not-allowed;
}

.mobile-menu {
	display: flex;
	min-height: 100dvh;
	box-sizing: border-box;
	flex-direction: column;
	overflow-y: auto;
	padding: 0.5rem 1.5rem max(1.5rem, calc(1rem + env(safe-area-inset-bottom)));
}

.mobile-menu__links {
	margin-top: 4rem;
	padding-bottom: 1.5rem;
}

.mobile-menu__cta {
	width: 100%;
	min-height: 3.5rem;
	margin-top: auto;
	justify-content: center;
}

@media (prefers-reduced-motion: reduce) {
	.project-grid .project-card {
		animation: none;
	}

	.project-pager__button:hover:not(:disabled) {
		transform: none;
	}
}

/* Renovation process steps. The numbered circles darken down the list — a light
   warm brown at step 01 easing to the darkest espresso at step 06 — so the six
   read as one sequence. --step-progress runs 0 to 1 and is set per item. */
.process-step__number {
	background: color-mix(in oklab, var(--brand-espresso-dark) calc(var(--step-progress, 1) * 100%), #463c34);
}

/* Service-area row on About Us. One line that scrolls itself: two identical
   tracks sit side by side and both slide left by their own width plus the gap,
   so the second one is exactly where the first started when the loop restarts.
   Clipped here rather than by the page, and paused while hovered or focused so
   a reader can stop on a place name. */
.area-marquee {
	display: flex;
	gap: 12px;
	overflow: hidden;
	/* Fades both ends instead of cutting a pill in half at the edge. */
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.area-marquee__track {
	display: flex;
	flex: none;
	align-items: center;
	gap: 12px;
	min-width: max-content;
	animation: area-marquee-scroll 70s linear infinite;
}

.area-marquee:hover .area-marquee__track,
.area-marquee:focus-within .area-marquee__track {
	animation-play-state: paused;
}

@keyframes area-marquee-scroll {
	to {
		transform: translateX(calc(-100% - 12px));
	}
}

/* Reduced motion: no travel at all, the pills simply wrap as they used to. */
@media (prefers-reduced-motion: reduce) {
	.area-marquee {
		flex-wrap: wrap;
		-webkit-mask-image: none;
		mask-image: none;
	}

	.area-marquee__track {
		flex: 1 1 auto;
		flex-wrap: wrap;
		min-width: 0;
		animation: none;
	}

	.area-marquee__track[aria-hidden="true"] {
		display: none;
	}
}

.blog-card,
.project-card {
	box-shadow: 0 10px 24px -18px rgba(42, 33, 27, 0.3);
	border: 1px solid rgba(42, 33, 27, 0.12);
	transition:
		transform 200ms ease,
		box-shadow 200ms ease,
		border-color 200ms ease,
		background-color 200ms ease;
}

.blog-card:hover,
.project-card:hover {
	transform: translateY(-2px);
	border-color: rgba(42, 33, 27, 0.2);
	box-shadow: 0 16px 30px -16px rgba(42, 33, 27, 0.42);
}

/* Projects keeps its category links in normal flow. This is a mobile-only
   companion that provides the same anchors while visitors browse lower down. */
.project-filter-chip.is-active {
	background: var(--brand-amber);
	border-color: var(--brand-amber);
}

.project-section-title {
	font-family: var(--font-display);
	font-size: 1.82rem;
	font-weight: 500;
	line-height: 1.12;
	letter-spacing: -0.02em;
}

@media (min-width: 768px) {
	.project-section-title {
		font-size: 1.25rem;
	}
}

.project-speed-dial {
	display: none;
}

.about-choose {
	display: grid;
	gap: 2.5rem;
}

.about-choose__intro {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

.about-choose__reasons {
	display: grid;
	gap: 0;
}

.about-choose__reason {
	display: grid;
	grid-template-columns: 2.25rem minmax(0, 1fr);
	gap: 1rem;
	padding: 1.25rem 0;
	border-top: 1px solid var(--border-color);
}

.about-choose__reason:first-child {
	border-top: 0;
	padding-top: 0;
}

.about-choose__icon {
	display: flex;
	align-items: flex-start;
	justify-content: center;
}

.about-choose__icon svg {
	width: 2rem;
	height: 2rem;
}

.about-choose__reason-title {
	margin-bottom: 0.375rem;
	font-family: var(--font-display);
	font-size: 1.25rem;
	font-weight: 500;
	line-height: 1.2;
	letter-spacing: -0.02em;
	color: var(--text-primary);
}

/* Phones only: the icon alternates sides down the list so the column has a
   rhythm instead of one hard left rail. The DOM order never changes — the icon
   span is still written before its text — only which grid column each lands in,
   so the reading order stays 1, 2, 3, ... and the text keeps its natural
   left alignment on both variants. */
@media (max-width: 767.98px) {
	.about-choose__reason:nth-child(even) {
		grid-template-columns: minmax(0, 1fr) 2.25rem;
	}

	.about-choose__reason:nth-child(even) > .about-choose__icon {
		grid-column: 2;
		grid-row: 1;
		justify-content: flex-end;
	}

	/* Text follows the icon: the right-hand items read right-aligned so each
	   pair of rows mirrors the other. Phones only — the desktop grid keeps
	   everything left-aligned. */
	.about-choose__reason:nth-child(even) > :last-child {
		grid-column: 1;
		grid-row: 1;
		text-align: right;
	}
}

@media (min-width: 768px) {
	.about-choose {
		grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
		gap: 3.5rem;
	}

	/* Two columns that touch. There is deliberately no column gap: the cells
	   have to share an edge for a row rule to run into the centre divider
	   instead of stopping short of it. The breathing room is padding inside
	   each cell, so every border sits on a cell edge and the row rules meet the
	   single centre line at a clean intersection. */
	.about-choose__reasons {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.about-choose__reason:nth-child(odd) {
		padding-right: 2.5rem;
	}

	/* The centre divider lives on the right-hand cell only — one 1px line, not
	   two overlapping ones. */
	.about-choose__reason:nth-child(even) {
		border-left: 1px solid var(--border-color);
		padding-left: 2.5rem;
	}

	/* Row one carries no rule above it, and nothing is added below row three. */
	.about-choose__reason:nth-child(2) {
		border-top: 0;
		padding-top: 0;
	}

	.about-choose__reason-title {
		font-size: 1.45rem;
	}
}

@media (min-width: 0) {
	.project-speed-dial {
		position: fixed;
		right: max(1rem, calc(1rem + env(safe-area-inset-right)));
		bottom: max(1.75rem, calc(1.75rem + env(safe-area-inset-bottom)));
		z-index: 50;
		display: flex;
		flex-direction: column;
		align-items: flex-end;
		gap: 0.75rem;
	}

	.project-speed-dial__menu {
		display: flex;
		max-height: min(60vh, 22.5rem);
		max-width: min(calc(100vw - 2rem), 16rem);
		flex-direction: column;
		align-items: flex-end;
		gap: 0.5rem;
		overflow-y: auto;
		padding: 0.25rem;
		scrollbar-width: thin;
	}

	.project-speed-dial__option {
		display: inline-flex;
		min-height: 2.75rem;
		align-items: center;
		justify-content: space-between;
		gap: 0.75rem;
		border: 1.5px solid var(--border-color);
		border-radius: 999px;
		background: var(--background-warm);
		padding: 0.625rem 1rem;
		color: var(--text-primary);
		font-family: var(--font-body);
		font-size: 0.875rem;
		font-weight: 600;
		line-height: 1.25rem;
		text-align: right;
		box-shadow: 0 8px 20px -15px rgba(42, 33, 27, 0.42);
		transition: border-color 180ms ease, background-color 180ms ease, box-shadow 180ms ease, color 180ms ease;
	}

	.project-speed-dial__option:hover,
	.project-speed-dial__option:focus-visible {
		border-color: var(--brand-amber-gold);
		background: var(--surface-cream);
		outline: none;
		box-shadow: 0 0 0 3px rgba(245, 193, 66, 0.28), 0 8px 20px -15px rgba(42, 33, 27, 0.42);
	}

	.project-speed-dial__option:active {
		background: var(--brand-daylight-yellow);
	}

	.project-speed-dial__option.is-active {
		border-color: var(--brand-amber-gold-dark);
		background: var(--brand-amber-gold);
		color: var(--brand-espresso);
		box-shadow: 0 8px 20px -15px rgba(42, 33, 27, 0.48);
	}

	.project-speed-dial__option.is-active:hover,
	.project-speed-dial__option.is-active:focus-visible {
		border-color: var(--brand-amber-gold-dark);
		background: var(--brand-amber-gold-dark);
		color: var(--brand-espresso-dark);
		box-shadow: 0 0 0 3px rgba(245, 193, 66, 0.28), 0 8px 20px -15px rgba(42, 33, 27, 0.48);
	}

	.project-speed-dial__option.is-active:active {
		background: var(--brand-amber-gold-dark);
	}

	.project-speed-dial__check {
		font-size: 1rem;
		line-height: 1;
	}

	.project-speed-dial__trigger {
		display: inline-flex;
		width: 3.5rem;
		height: 3.5rem;
		align-items: center;
		justify-content: center;
		border: 1px solid var(--brand-espresso);
		border-radius: 50%;
		background: linear-gradient(135deg, var(--brand-espresso) 0%, #4b2b1c 52%, var(--brand-espresso-dark) 100%);
		color: var(--brand-amber-gold);
		box-shadow: 0 10px 24px -14px rgba(42, 33, 27, 0.8);
		transition: background-color 180ms ease, border-color 180ms ease, transform 180ms ease;
	}

	.project-speed-dial__trigger:hover,
	.project-speed-dial__trigger:focus-visible {
		border-color: var(--brand-amber-gold);
		background: var(--brand-espresso-dark);
		outline: 2px solid var(--brand-amber-gold);
		outline-offset: 3px;
		box-shadow:
			0 12px 26px -12px rgba(42, 33, 27, 0.9),
			0 0 0 2px rgba(245, 193, 66, 0.28);
	}

	.project-speed-dial__trigger:active {
		background: var(--brand-espresso-dark);
		box-shadow: 0 5px 12px -8px rgba(42, 33, 27, 0.8);
		transform: translateY(1px);
	}

	.project-speed-dial__trigger svg {
		width: 1.375rem;
		height: 1.375rem;
	}

	.project-speed-dial__filter {
		display: block;
		color: var(--brand-amber-gold);
	}

	.project-speed-dial__menu-enter,
	.project-speed-dial__menu-leave {
		transition: opacity 180ms ease, transform 180ms ease;
	}

	.project-speed-dial__menu-enter-start,
	.project-speed-dial__menu-leave-end {
		opacity: 0;
		transform: translateY(0.5rem);
	}

	.project-speed-dial__menu-enter-end,
	.project-speed-dial__menu-leave-start {
		opacity: 1;
		transform: translateY(0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.btn-lift:hover:not(:disabled),
	.btn-lift:active:not(:disabled),
	.blog-card:hover,
	.project-card:hover {
		transform: none;
	}

	.project-speed-dial__menu-enter,
	.project-speed-dial__menu-leave,
	.project-speed-dial__option,
	.project-speed-dial__trigger {
		transition-duration: 1ms;
	}
}

/* ==========================================================================
   SECTION PHOTO BACKDROP

   A photograph behind a section, softened so it reads as atmosphere rather
   than as the subject. The image is blurred and scaled slightly (blur leaves
   soft transparent edges; the scale hides them), then covered by a scrim in
   the section's own colour so the existing text colours stay legible without
   the section changing theme. An inset shadow adds the vignette.

   Two variants: --light keeps Espresso text on a pale ground, --dark keeps
   white text on Espresso.
   ========================================================================== */
.section-photo {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
	border-radius: inherit;
}

.section-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: blur(3px);
	transform: scale(1.06);
}

.section-photo::after {
	content: "";
	position: absolute;
	inset: 0;
	box-shadow: inset 0 0 90px rgba(42, 33, 27, 0.22);
}

.section-photo--light::after {
	background: linear-gradient(
		100deg,
		rgba(255, 255, 255, 0.94) 0%,
		rgba(255, 255, 255, 0.86) 45%,
		rgba(247, 247, 245, 0.72) 100%
	);
}

.section-photo--dark::after {
	background: linear-gradient(
		100deg,
		rgba(42, 33, 27, 0.93) 0%,
		rgba(42, 33, 27, 0.86) 55%,
		rgba(27, 20, 15, 0.9) 100%
	);
}

/* Anything that should sit above the backdrop. */
.section-photo-content {
	position: relative;
	z-index: 1;
}

/* The hero backdrop is a slideshow. One flex track holds the five
   photographs plus a repeat of the first, and slides one hero-width at a
   time: each slide holds 4.8s, each move takes 1.2s, so a photograph is on
   screen for 6s and the cycle is 30s. The sixth slide is the first
   photograph again, so when the animation restarts at translateX(0) the
   pixels are identical and the wrap has nothing to jump over.

   Blur and scale sit on the layer rather than on the slides, deliberately:
   on the slides, the scale makes each one overlap its neighbours and the
   blur's soft edges show up as a seam between two photographs. On the layer
   the track composites first and is blurred as one image, so the only soft
   edges left are the outer ones the scale already hides. */
.home-hero .hero-slideshow {
	position: absolute;
	inset: 0;
	overflow: hidden;
	filter: blur(3px);
	transform: scale(1.06);
	/* The first photograph again, as the floor of the layer. On a slow
	   connection a slide can be scrolled into view before it has arrived,
	   and a slide that has not painted yet is transparent -- this is what
	   shows through instead of an empty hero. Same URL as slide one, so it
	   is the same cache entry and costs no extra request. */
	background: url("/static/images/hero-renovation-01.webp") center / cover
		no-repeat;
}

.home-hero .hero-slideshow__track {
	display: flex;
	width: 600%;
	height: 100%;
	animation: hero-slideshow 30s ease-in-out infinite;
}

.home-hero .hero-slideshow__slide {
	flex: 0 0 16.666667%;
	width: 16.666667%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	filter: none;
	transform: none;
}

@keyframes hero-slideshow {
	0%,
	16% {
		transform: translateX(0);
	}
	20%,
	36% {
		transform: translateX(-16.666667%);
	}
	40%,
	56% {
		transform: translateX(-33.333333%);
	}
	60%,
	76% {
		transform: translateX(-50%);
	}
	80%,
	96% {
		transform: translateX(-66.666667%);
	}
	100% {
		transform: translateX(-83.333333%);
	}
}

@media (prefers-reduced-motion: reduce) {
	.home-hero .hero-slideshow__track {
		animation: none;
	}
}

.service-hero {
	background-color: var(--background-soft);
}

.service-hero .section-photo img {
	object-position: center;
}

.service-hero .section-photo--light::after {
	background: linear-gradient(
		100deg,
		rgba(255, 255, 255, 0.78) 0%,
		rgba(255, 255, 255, 0.66) 42%,
		rgba(247, 247, 245, 0.48) 100%
	);
}

.home-hero .section-photo--light::after {
	background: linear-gradient(
		100deg,
		rgba(255, 255, 255, 0.92) 0%,
		rgba(255, 255, 255, 0.82) 42%,
		rgba(247, 247, 245, 0.56) 100%
	);
}

.home-hero__title {
	font-size: clamp(34px, 4.6vw, 66px);
}

.home-hero__subline,
.home-hero__body {
	max-width: 54rem;
}

@media (min-width: 1024px) {
	.home-hero,
	.home-hero__content {
		min-height: 34rem;
	}

	.home-hero__content {
		padding-top: 3.5rem;
		padding-bottom: 3.5rem;
		justify-content: flex-end;
		align-items: flex-start;
		gap: 1.75rem;
	}

	.home-hero__actions {
		padding-top: 0.25rem;
	}
}

@media (max-width: 1023px) {
	.home-hero,
	.home-hero__content {
		min-height: auto;
	}

	.home-hero__content {
		padding-top: 3.25rem;
		padding-bottom: 4rem;
		justify-content: flex-end;
		align-items: flex-start;
		gap: 1.25rem;
	}

	.home-hero__title {
		max-width: 100%;
		font-size: clamp(2.75rem, 7.2vw, 4rem);
		line-height: 1.02;
	}

	.home-hero__subline {
		font-size: clamp(1.14rem, 2.2vw, 1.52rem);
		line-height: 1.25;
	}

	.home-hero__body {
		max-width: 42rem;
		font-size: clamp(0.86rem, 1.7vw, 1.1rem);
		line-height: 1.58;
	}
}

@media (max-width: 767px) {
	.home-hero {
		overflow-x: clip;
	}

	.home-hero .hero-slideshow {
		filter: blur(1px);
		transform: scale(1.025);
	}

	.home-hero .section-photo--light::after {
		background: linear-gradient(
			100deg,
			rgba(255, 255, 255, 0.94) 0%,
			rgba(255, 255, 255, 0.8) 48%,
			rgba(247, 247, 245, 0.52) 100%
		);
	}

	.home-hero__content {
		padding-top: 2.5rem;
		padding-bottom: 3.25rem;
		padding-left: 1.5rem;
		padding-right: 1.5rem;
		gap: 1rem;
	}

	.home-hero__title {
		font-size: clamp(2.25rem, 8.3vw, 2.9rem);
		line-height: 0.99;
		text-wrap: balance;
	}

	.home-hero__accent {
		width: 9.5rem;
		margin-top: 1.25rem;
	}

	.home-hero__subline {
		font-size: 1.04rem;
		line-height: 1.22;
	}

	.home-hero__body {
		width: 100%;
		max-width: 34rem;
		font-size: 0.91rem;
		line-height: 1.55;
	}

	.home-hero__actions {
		width: 100%;
		flex-direction: column;
		align-items: stretch;
		gap: 0.75rem;
	}

	.home-hero__button {
		width: 100%;
		justify-content: center;
	}
}

@media (max-width: 389px) {
	.home-hero__content {
		padding-left: 1.25rem;
		padding-right: 1.25rem;
	}

	.home-hero__title {
		font-size: clamp(2.05rem, 9vw, 2.6rem);
	}

	.home-hero__subline {
		font-size: 0.94rem;
	}

	.home-hero__body {
		font-size: 0.84rem;
	}
}

/* ==========================================================================
   NAVIGATION — desktop Services dropdown.

   These rules are hand-written here rather than composed from UnoCSS utility
   classes, deliberately. The panel's structural properties (position, and the
   hidden state) have to be correct before any JavaScript runs and before any
   CSS generation happens. In development the UnoCSS browser runtime builds
   utility CSS by scanning the DOM, so a panel whose `position: absolute` came
   from a generated utility is briefly unstyled — that is, `position: static`,
   `display: block`, full width — which drops it into the navbar's flex row and
   pushes the header open. Plain stylesheet rules are never subject to that.

   Visibility is driven by `.is-open` toggling opacity / visibility /
   pointer-events / transform only. `position` and `display` never change, so
   opening the menu cannot affect header height or move sibling nav items.
   ========================================================================== */

/* Alpine strips x-cloak on init, but the attribute does nothing on its own.
   Without this rule every x-cloak element is fully visible until Alpine boots. */
[x-cloak] {
	display: none !important;
}

.services-menu {
	position: relative;
	display: flex;
	align-items: center;
}

.services-dropdown {
	position: absolute;
	top: calc(100% + 10px);
	left: 50%;
	z-index: 60;

	width: 320px;
	margin: 0;
	padding: 8px;
	list-style: none;

	display: flex;
	flex-direction: column;
	gap: 2px;

	background: var(--background-main);
	border: 1px solid var(--border-color);
	border-radius: 14px;
	box-shadow:
		0 14px 35px rgba(42, 33, 27, 0.14),
		0 2px 6px rgba(42, 33, 27, 0.06);

	/* Closed. Never `display: none`, so the panel keeps its absolute
	   positioning and can transition. */
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translateX(-50%) translateY(-6px);
	transition:
		opacity 180ms ease-out,
		transform 180ms ease-out,
		visibility 180ms;
}

.services-dropdown.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translateX(-50%) translateY(0);
}

.services-dropdown__item {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 42px;
	padding: 0 16px 0 18px;
	border-radius: 10px;

	font-family: var(--font-body);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.3;
	color: var(--text-primary);
	text-decoration: none;

	transition:
		background-color 150ms ease,
		color 150ms ease;
}

.services-dropdown__item:hover {
	/* Very light Daylight Yellow, not a solid block. */
	background: rgba(253, 242, 128, 0.35);
}

.services-dropdown__item:focus-visible {
	background: rgba(253, 242, 128, 0.35);
	outline: 2px solid var(--brand-amber-gold);
	outline-offset: -2px;
}

/* "All Services" leads the list. */
.services-dropdown__item--lead {
	font-weight: 600;
}

/* Current page: Daylight Yellow row with an Amber Gold accent bar. */
.services-dropdown__item--current {
	background: var(--brand-daylight-yellow);
}

.services-dropdown__item--current::before {
	content: "";
	position: absolute;
	left: 6px;
	top: 50%;
	transform: translateY(-50%);
	width: 3px;
	height: 16px;
	border-radius: 2px;
	background: var(--brand-amber-gold);
}

.services-dropdown__divider {
	height: 1px;
	margin: 6px 8px;
	background: var(--border-color);
	list-style: none;
}

/* The mobile menu is an accordion in normal flow and shares no positioning
   with the desktop panel above. */
.mobile-submenu {
	position: static;
	display: flex;
	flex-direction: column;
}

@media (prefers-reduced-motion: reduce) {
	.services-dropdown {
		transition: none;
	}
}

/* Staggered entrance for grids of cards. Deliberately a keyframe animation
   rather than a transition: the per-card delay must not also delay that card's
   hover response, and transition-delay would. Elements start at opacity 0 and
   the animation holds its end state via `both`. */
@keyframes card-rise {
	from {
		opacity: 0;
		transform: translateY(14px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

.card-rise {
	animation: card-rise 480ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.faq-heading,
.faq-intro,
.faq-list {
	opacity: 0;
	transform: translateY(14px);
	transition:
		opacity 520ms ease,
		transform 520ms cubic-bezier(0.16, 1, 0.3, 1);
}

.faq-intro {
	transition-delay: 60ms;
}

.faq-list {
	transition-delay: 110ms;
}

.faq-section--visible .faq-heading,
.faq-section--visible .faq-intro,
.faq-section--visible .faq-list {
	opacity: 1;
	transform: none;
}

.faq-item,
.faq-list > details {
	border: 1px solid transparent;
	opacity: 0;
	transform: translateY(10px);
	transition:
		opacity 440ms ease,
		transform 440ms cubic-bezier(0.16, 1, 0.3, 1),
		background-color 200ms ease,
		border-color 200ms ease,
		box-shadow 200ms ease;
}

.faq-section--visible .faq-item,
.faq-section--visible .faq-list > details {
	opacity: 1;
	transform: none;
}

.faq-section--visible .faq-item:nth-child(1),
.faq-section--visible .faq-list > details:nth-child(1) { transition-delay: 160ms; }
.faq-section--visible .faq-item:nth-child(2),
.faq-section--visible .faq-list > details:nth-child(2) { transition-delay: 210ms; }
.faq-section--visible .faq-item:nth-child(3),
.faq-section--visible .faq-list > details:nth-child(3) { transition-delay: 260ms; }
.faq-section--visible .faq-item:nth-child(4),
.faq-section--visible .faq-list > details:nth-child(4) { transition-delay: 310ms; }
.faq-section--visible .faq-item:nth-child(5),
.faq-section--visible .faq-list > details:nth-child(5) { transition-delay: 360ms; }
.faq-section--visible .faq-item:nth-child(6),
.faq-section--visible .faq-list > details:nth-child(6) { transition-delay: 410ms; }

.faq-item:hover,
.faq-list > details:hover {
	transition-delay: 0s;
	background-color: var(--background-warm);
	border-color: rgba(245, 193, 66, 0.32);
	box-shadow: 0 12px 28px -20px rgba(42, 33, 27, 0.34);
}

.faq-summary,
.faq-list > details > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	transition: color 200ms ease;
}

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

.faq-summary::marker,
.faq-list > details > summary::marker {
	content: "";
}

.faq-summary::after,
.faq-list > details > summary::after {
	content: "";
	width: 0.65rem;
	height: 0.65rem;
	flex: none;
	border-right: 2px solid var(--brand-amber-text);
	border-bottom: 2px solid var(--brand-amber-text);
	transform: rotate(45deg) translateY(-2px);
	transition: transform 200ms ease;
}

.faq-item[open] > .faq-summary::after,
.faq-list > details[open] > summary::after {
	transform: rotate(225deg) translateY(-2px);
}

.faq-item[open] > .faq-summary,
.faq-list > details[open] > summary {
	color: var(--brand-amber-text);
}

.faq-answer,
.faq-list > details > div {
	display: grid;
	grid-template-rows: 0fr;
	padding-bottom: 0;
	opacity: 0;
	transition:
		grid-template-rows 220ms ease,
		padding-bottom 220ms ease,
		opacity 160ms ease;
}

.faq-answer > div,
.faq-list > details > div > div {
	min-height: 0;
	overflow: hidden;
}

.faq-item[open] > .faq-answer,
.faq-list > details[open] > div {
	grid-template-rows: 1fr;
	padding-bottom: 2rem;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.card-rise {
		animation: none;
		opacity: 1;
		transform: none;
	}

	.faq-summary::after,
	.faq-list > details > summary::after,
	.faq-answer,
	.faq-list > details > div,
	.faq-heading,
	.faq-intro,
	.faq-list,
	.faq-item,
	.faq-list > details {
		transition: none;
	}

	.faq-heading,
	.faq-intro,
	.faq-list,
	.faq-item {
		opacity: 1;
		transform: none;
	}
}

/* Thin decorative brand rule. Used for the footer top line and hero accents. */
.brand-rule {
	background: var(--brand-gradient);
}

/* ==========================================================================
   ENQUIRY COMPOSITION — the "Get In Touch" band on /contact-us.

   Three parts share one ground: the service list, the enquiry card and the
   photograph. On wide screens the card is deliberately allowed to sit over the
   photograph's leading edge so the group reads as one composition rather than
   three tiles; below `lg` the overlap is dropped and everything stacks.

   Hand-written here rather than composed from utilities because the card is a
   small design system of its own — one field treatment repeated seven times,
   plus two organic shapes that arbitrary-value utilities express badly.
   ========================================================================== */

.enquiry-card {
	background: var(--surface-cream);
	border: 1px solid rgba(245, 193, 66, 0.38);
	border-radius: 18px;
	box-shadow: 0 26px 60px -32px rgba(42, 33, 27, 0.4);
}

.enquiry-composition {
	position: relative;
	/* Local stacking context, so the ring (1), photograph (2) and form (3)
	   order themselves against each other and nothing else on the page. */
	isolation: isolate;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 24px;
}

.enquiry-form-card {
	position: relative;
	z-index: 3;
	width: 100%;
	max-width: 520px;
}

/* Field label. Espresso rather than the secondary grey: the cream ground is
   light enough that #7A736B drops under 4.5:1 at this size. */
.enquiry-label {
	display: block;
	margin-bottom: 6px;
	font-family: var(--font-body);
	font-size: 0.7143rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--text-primary);
}

.enquiry-label__optional {
	margin-left: 6px;
	font-weight: 400;
	letter-spacing: 0.04em;
	text-transform: none;
	color: var(--text-secondary);
}

/* Underlined field. Border width never changes on focus — the colour swap plus
   a 1px shadow doubles the apparent weight without shifting the baseline. */
.enquiry-field {
	width: 100%;
	padding: 8px 2px;
	background: transparent;
	border: none;
	border-bottom: 1px solid rgba(42, 33, 27, 0.18);
	border-radius: 0;
	font-family: var(--font-body);
	font-size: 0.857rem;
	line-height: 1.5;
	color: var(--text-primary);
	transition:
		border-color 200ms ease,
		box-shadow 200ms ease;
}

.enquiry-field::placeholder {
	color: var(--text-secondary);
}

.enquiry-field:focus {
	outline: none;
	border-bottom-color: var(--brand-amber-gold);
	box-shadow: 0 1px 0 0 var(--brand-amber-gold);
}

.enquiry-field[aria-invalid="true"] {
	border-bottom-color: #dc2626;
}

/* Custom enquiry listbox. Styled to match the nav Services dropdown rather than
   the browser-native system menu. */
.enquiry-select-control {
	position: relative;
}

.enquiry-select-trigger {
	width: 100%;
	min-height: 54px;
	padding: 0 16px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	background: var(--background-main);
	border: 1px solid var(--border-color);
	border-radius: 10px;
	font-family: var(--font-body);
	font-size: 0.7857rem;
	font-weight: 500;
	line-height: 1.4;
	color: var(--text-primary);
	text-align: left;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
	transition:
		border-color 200ms ease,
		box-shadow 200ms ease;
}

.enquiry-select-trigger:focus-visible,
.enquiry-select-trigger:hover {
	border-color: var(--brand-amber-gold);
	box-shadow: 0 16px 28px -24px rgba(245, 193, 66, 0.65);
}

.enquiry-select-trigger.is-invalid {
	border-color: #dc2626;
}

.enquiry-select-trigger__text {
	flex: 1;
}

.enquiry-select-trigger__chevron {
	display: inline-flex;
	color: var(--text-primary);
	transition: transform 180ms ease-out;
}

.enquiry-select-trigger__chevron.is-open {
	transform: rotate(180deg);
}

.enquiry-select-panel {
	position: absolute;
	top: calc(100% + 8px);
	left: 0;
	z-index: 2000;
	width: 100%;
	padding: 8px;
	background: var(--background-main);
	border: 1px solid var(--border-color);
	border-radius: 14px;
	box-shadow:
		0 14px 35px rgba(42, 33, 27, 0.1),
		0 2px 6px rgba(42, 33, 27, 0.06);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translateY(-4px);
	transition:
		opacity 180ms ease-out,
		transform 180ms ease-out,
		visibility 180ms;
}

.enquiry-select-panel.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translateY(0);
}

.enquiry-select-panel__inner {
	display: flex;
	flex-direction: column;
	gap: 2px;
	max-height: 320px;
	overflow-y: auto;
}

.enquiry-select-option {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	width: 100%;
	min-height: 42px;
	padding: 10px 14px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	font-family: var(--font-body);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.3;
	color: var(--text-primary);
	text-align: left;
	transition:
		background-color 150ms ease,
		color 150ms ease;
}

.enquiry-select-option:hover,
.enquiry-select-option:focus-visible {
	background: rgba(253, 242, 128, 0.35);
	outline: none;
}

.enquiry-select-option.is-selected {
	background: var(--brand-daylight-yellow);
}

.enquiry-select-option__indicator {
	width: 8px;
	height: 8px;
	flex: none;
	border-radius: 9999px;
	background: var(--brand-amber-gold);
	opacity: 0;
	transform: scale(0.6);
	transition:
		opacity 150ms ease,
		transform 150ms ease;
}

.enquiry-select-option__indicator.is-visible {
	opacity: 1;
	transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
	.enquiry-select-trigger__chevron,
	.enquiry-select-panel,
	.enquiry-select-option__indicator {
		transition: none;
	}
}

/* A six-row box reads badly with only an underline, so the one multi-line
   field takes the "minimal 1px border" variant instead. */
.enquiry-textarea {
	width: 100%;
	padding: 12px 14px;
	background: rgba(255, 255, 255, 0.6);
	border: 1px solid rgba(42, 33, 27, 0.18);
	border-radius: 10px;
	font-family: var(--font-body);
	font-size: 0.857rem;
	line-height: 1.6;
	color: var(--text-primary);
	transition: border-color 200ms ease;
}

.enquiry-textarea::placeholder {
	color: var(--text-secondary);
}

.enquiry-textarea:focus {
	outline: none;
	border-color: var(--brand-amber-gold);
}

/* Service list item on the left. The Amber Gold rule grows in under the label
   on hover; the glyph lifts 2px with it. */
.enquiry-service {
	position: relative;
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 8px 2px 12px;
	color: var(--text-primary);
}

.enquiry-service::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px;
	background: var(--border-color);
}

.enquiry-service::before {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 1;
	width: 100%;
	height: 2px;
	border-radius: 2px;
	background: var(--brand-amber-gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 220ms ease-out;
}

.enquiry-service:hover::before {
	transform: scaleX(1);
}

.enquiry-service img {
	transition: transform 220ms ease-out;
}

.enquiry-service:hover img {
	transform: translateY(-2px);
}

/* Organic photo mask. Kept close to a circle-ish rounded rectangle rather than
   a lopsided blob — the corners differ enough to read as drawn, not generated. */
.enquiry-figure {
	overflow: hidden;
	border-radius: 46% 54% 44% 56% / 40% 38% 62% 60%;
}

.enquiry-visual {
	position: relative;
	z-index: 2;
	width: min(100%, 380px);
	align-self: flex-end;
	aspect-ratio: 4 / 5;
	box-shadow: 0 24px 50px -36px rgba(42, 33, 27, 0.35);
}

.enquiry-figure img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}

.enquiry-figure:hover img {
	transform: scale(1.02);
}

/* Decorations. Three, all inert. */
.enquiry-blob {
	background: rgba(220, 220, 220, 0.5);
	border-radius: 58% 42% 50% 50% / 45% 52% 48% 55%;
}

.enquiry-ring {
	border: 1.5px dashed rgba(245, 193, 66, 0.6);
	border-radius: 9999px;
}

.enquiry-ring--behind {
	position: absolute;
	z-index: 1;
	left: -40px;
	bottom: 40px;
	width: 180px;
	height: 180px;
	pointer-events: none;
}

.enquiry-swatch {
	background: rgba(253, 242, 128, 0.55);
	border-radius: 40% 60% 55% 45% / 55% 45% 55% 45%;
}

@media (prefers-reduced-motion: reduce) {
	.enquiry-figure:hover img,
	.enquiry-service:hover img {
		transform: none;
	}
}

@media (min-width: 1024px) {
	.enquiry-composition {
		min-height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		padding-block: 12px;
	}

	.enquiry-form-card {
		margin-right: auto;
	}

	.enquiry-visual {
		position: absolute;
		top: 50%;
		right: 0;
		width: min(72%, 420px);
		transform: translateY(-50%);
	}
}

@media (max-width: 1023.98px) {
	/* The column layout collapses here, but the photograph stays a decorative
	   background element instead of becoming another block under the form:
	   taken out of flow, tucked behind the card's lower-right corner, and
	   clipped by the section's own overflow rather than the page's. Inert, so
	   it can never intercept a tap meant for a field. */
	.enquiry-visual {
		position: absolute;
		z-index: 2;
		right: -24px;
		bottom: -40px;
		width: clamp(180px, 55vw, 320px);
		pointer-events: none;
	}

	.enquiry-ring--behind {
		left: -18px;
		bottom: 120px;
		width: 140px;
		height: 140px;
	}
}

::selection {
	background: var(--brand-daylight-yellow);
	color: var(--brand-espresso);
}

:focus-visible {
	outline: 2px solid var(--brand-amber-gold);
	outline-offset: 2px;
}

dialog {
	max-width: unset;
	max-height: unset;
	background-color: white;
}

dialog::backdrop {
	display: none;
}

button:not(:disabled) {
	cursor: pointer;
}

/* Blog article content rendered from the Quill editor.
   The UnoCSS preflight resets lists, headings and tables, which stripped the
   bullet/number markers and table borders that authors add in the back-office
   editor. These rules restore that formatting on the live blog pages. */
#contents {
	line-height: 1.7;
}

#contents p {
	margin: 0.75em 0;
}

#contents ul,
#contents ol {
	margin: 0.75em 0;
	padding-left: 1.75em;
}

#contents ul {
	list-style: disc;
}

#contents ol {
	list-style: decimal;
}

#contents ul ul {
	list-style: circle;
}

#contents li {
	margin: 0.35em 0;
	display: list-item;
}

#contents h1 {
	font-size: 2.12em;
	font-weight: 700;
	margin: 0.8em 0 0.4em;
}

#contents h2 {
	font-size: 1.66em;
	font-weight: 700;
	margin: 0.8em 0 0.4em;
}

#contents h3 {
	font-size: 1.32em;
	font-weight: 600;
	margin: 0.8em 0 0.4em;
}

#contents a {
	color: var(--text-primary);
	text-decoration: underline;
	text-decoration-color: var(--color-primary);
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
}

#contents a:hover {
	color: var(--brand-amber-gold-dark);
}

#contents blockquote {
	border-left: 4px solid var(--color-primary);
	padding-left: 1em;
	margin: 1em 0;
	color: var(--text-secondary);
}

#contents img {
	max-width: 100%;
	height: auto;
}

#contents pre {
	background: var(--background-soft);
	padding: 1em;
	border-radius: 8px;
	overflow-x: auto;
}

#contents table {
	border-collapse: collapse;
	width: 100%;
	margin: 1em 0;
	overflow-x: auto;
	display: block;
}

#contents table th,
#contents table td {
	border: 1px solid var(--border-color);
	padding: 0.5em 0.75em;
	text-align: left;
}

#contents table th {
	background: var(--background-soft);
	font-weight: 600;
}

/* Keep display text boxes and descenders clear on the two audited pages. */
.home-page :is(h1, h2, h3, .font-display, .same-as-h2),
.about-page :is(h1, h2, h3, .font-display, .same-as-h2) {
	display: block;
	height: auto;
	max-height: none;
	overflow: visible;
	line-height: 1.2;
	padding-bottom: 0.112em;
}

.home-page :is(.text-highlight, .fx-foil),
.about-page :is(.text-highlight, .fx-foil) {
	display: inline-block;
	height: auto;
	max-height: none;
	overflow: visible;
	line-height: inherit;
	padding-bottom: 0.056em;
}
