/*
 * WayHome theme: self-hosted web fonts (@font-face rules only).
 * Manrope (Mikhail Sharanda), Quicksand (Andrew Paglinawan) and Inter (Rasmus
 * Andersson), all licensed under the SIL Open Font License 1.1, see
 * https://openfontlicense.org/
 * Unmodified latin subsets served by Google Fonts. Each family is a single
 * variable woff2 covering its full weight axis. See LICENSE.txt in this
 * directory for the exact source URLs, designers and date obtained.
 * Paths are relative to this file (the .woff2 files sit next to it).
 *
 * Manrope is the heading and button face. Quicksand is kept for the wordmark
 * echo and the generated social image only.
 */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("https://wayhome.ae/wp-content/themes/wayhome/assets/fonts/manrope-variable.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;
}

@font-face {
  font-family: 'Quicksand';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("https://wayhome.ae/wp-content/themes/wayhome/assets/fonts/quicksand-variable.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;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("https://wayhome.ae/wp-content/themes/wayhome/assets/fonts/inter-variable.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;
}
/*
 * WayHome: design tokens.
 *
 * The single source of truth for colour, type, space, radius, shadow and
 * motion on the front end. theme.json mirrors the subset the block editor
 * needs; change both together. See docs/brand.md for the reasoning, the
 * contrast table and the usage rules these tokens encode.
 */

:root {
	/* --- Core palette (mirrored in theme.json) ---------------------------- */
	--ink: #111111;
	--navy-900: #1d293e;
	--navy-800: #24324a;
	--sky-50: #eef8fb;
	--sky-100: #daf0f7;
	--sky-600: #0e7c94;
	--coral-500: #ff5a5f;
	--coral-600: #e0484d;
	--whatsapp: #25d366;
	--whatsapp-dark: #1eb756;
	--white: #ffffff;
	--grey-50: #f5f6f8;   /* the page canvas: near-white cool grey, 2026-09-18 */
	--grey-100: #f7f7f7;
	--grey-200: #ebebeb;
	--grey-400: #a4a4a4;
	--grey-700: #484848;
	--cream-50: #f6f2ea;  /* kept for table zebra and the warm legacy bands     */
	--cream-100: #efe8dc; /* kept for the few bands still asking for warmth     */

	/*
	 * --- Azure ---------------------------------------------------------------
	 * The accent, added 2026-09-18. One bright blue carries every primary
	 * action and every link, the way the best agency sites in this market do
	 * it. Coral stays, but only on badges; it is no longer a button fill.
	 */
	--azure-100: #e8f3fe; /* ghost-button tint, quiet panels                    */
	--azure-500: #1b8bf0; /* the bright note: icons, rules, focus glow          */
	--azure-600: #0f73d6; /* primary button fill, white label 4.73 AA           */
	--azure-700: #0b5aa8; /* button hover, and the link ink (6.38 on grey-50)   */
	--azure-800: #0a4c8c; /* pressed, and white-on-azure where AAA is wanted    */

	/*
	 * --- Derived shades (CSS only, deliberately not in the editor palette) --
	 * The A3 palette was picked for surfaces. These three close the contrast
	 * gaps: sky-600 misses AA for text on our tinted backgrounds (4.11 on
	 * sky-100), and white on coral-500 is only 3.05:1.
	 */
	--sky-700: #0b6a7e;   /* 6.22 on white, 5.27 on sky-100, the link colour  */
	--coral-700: #c63b40; /* white label 5.12, the primary button fill        */
	--coral-800: #a93135; /* white label 6.61, primary button hover/active    */
	--grey-500: #949494;  /* 3.03 on white, the resting boundary of an input  */

	/* --- Semantic aliases -------------------------------------------------- */
	--color-text: var(--ink);
	--color-text-muted: var(--grey-700);
	--color-text-invert: var(--white);
	/*
	 * The canvas is the cool near-white; a card, a form and a `.section--alt`
	 * band are all plain white, so the page reads as alternating grey and white
	 * stripes rather than as tinted bands.
	 */
	--color-canvas: var(--grey-50);
	--color-bg: var(--white);
	--color-bg-alt: var(--white);
	--color-bg-brand: var(--azure-100);
	--color-bg-dark: var(--navy-900);
	--color-surface: var(--grey-100);
	--color-border: var(--grey-200);
	--color-border-strong: var(--grey-400);
	--color-border-field: var(--grey-500);

	/*
	 * The link ink is azure-700, not azure-600, for the same reason links were
	 * sky-700 and never sky-600: azure-600 is 4.37 on the grey-50 canvas and
	 * 4.20 on the azure-100 tint, both under AA for normal text. azure-700
	 * clears AA on white (6.90), on the canvas (6.38) and on the tint (6.14).
	 * azure-600 stays what it is good at, a fill under a white label.
	 */
	--color-link: var(--azure-700);
	--color-link-hover: var(--ink);
	--color-accent: var(--coral-500);
	--color-cta: var(--azure-600);
	--color-cta-hover: var(--azure-700);
	--color-cta-active: var(--azure-800);
	--color-whatsapp: var(--whatsapp);
	--color-focus: var(--ink);

	/* --- Typography -------------------------------------------------------- */

	/*
	 * Manrope carries the headings and the buttons: a geometric sans with a
	 * tall x-height that holds together at 72px and still reads at 13px on a
	 * pill. Inter stays on body copy and tables. Quicksand is now used only in
	 * the wordmark echo and the generated social image.
	 */
	--font-heading: "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
	--font-body: "Inter", system-ui, -apple-system, "Segoe UI", roboto, sans-serif;
	--font-wordmark: "Quicksand", "Trebuchet MS", "Segoe UI", system-ui, sans-serif;

	/*
	 * Manrope is set lighter than Quicksand was. A 72px headline at 700 shouts;
	 * the same line at 500 reads as confidence. These two are the only heading
	 * weights the site uses.
	 */
	--weight-heading: 500;
	--weight-heading-strong: 600;

	/*
	 * The type scale, reworked 2026-09-30. The 2026-09-18 scale ran one to two
	 * steps large for a property site people scan on a laptop (a 60px page H1,
	 * 20px intros, 24px card titles). This one sits where the reference agency
	 * sites sit: body 16px, dense UI 15px, lead 18px, card titles 20px, H3 24px,
	 * H2 34px, a page H1 42px. Every step is fluid against a 390px to 1440px
	 * viewport and reaches its desktop value by about 1280px, so a laptop and a
	 * wide monitor see the same page. See docs/brand.md section 3.2.
	 */
	--step--2: clamp(0.75rem, 0.73rem + 0.1vw, 0.8125rem);    /* 12 to 13: eyebrows, badges, legal  */
	--step--1: clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem);  /* 13 to 14: meta, captions, crumbs    */
	--step-ui: 0.9375rem;                                      /* 15: nav, buttons, fields, rows      */
	--step-0: 1rem;                                            /* 16: body                            */
	--step-1: clamp(1.0625rem, 1.03rem + 0.15vw, 1.125rem);    /* 17 to 18: lead, H5                  */
	--step-2: clamp(1.125rem, 1.08rem + 0.2vw, 1.25rem);       /* 18 to 20: card title, H4            */
	--step-3: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);         /* 20 to 24: H3, band headings         */
	--step-4: clamp(1.375rem, 1.2rem + 0.6vw, 1.75rem);        /* 22 to 28: prices, stat figures      */
	--step-5: clamp(1.875rem, 1.45rem + 1.9vw, 2.625rem);      /* 30 to 42: H1 on an ordinary page    */
	--step-6: clamp(2.125rem, 1.5rem + 2.6vw, 3.25rem);        /* 34 to 52: alias of --step-hero      */

	/*
	 * Two display sizes that sit outside the column scale: the headline of the
	 * front page and the headline of a section, and nothing else. --step-4
	 * stays below the section size on purpose, because a price and a stat
	 * figure read it and a price as large as the heading above it is two
	 * headlines arguing.
	 */
	--step-hero: clamp(2.125rem, 1.5rem + 2.6vw, 3.25rem);     /* 34 to 52 */
	--step-section: clamp(1.625rem, 1.3rem + 1.2vw, 2.125rem); /* 26 to 34 */

	/*
	 * Loosened slightly with the smaller scale: 1.05 suited a 60px to 72px
	 * headline, and at 34px to 42px it pinches the descenders of one line
	 * into the capitals of the next.
	 */
	--lh-display: 1.1;
	--lh-tight: 1.15;
	--lh-heading: 1.25;
	--lh-body: 1.6;
	--lh-ui: 1.35;

	--tracking-tight: -0.02em;
	--tracking-snug: -0.01em;
	--tracking-wide: 0.08em;

	/*
	 * An eyebrow is set at 12px to 13px, where 0.08em is too tight to read as
	 * one. 0.12em is the usual range for uppercase type at that size.
	 */
	--tracking-eyebrow: 0.12em;

	--measure: 68ch;

	/*
	 * Headings are capped shorter than body copy so a heading breaks into two
	 * or three lines and forms a shape, instead of setting as one long line
	 * across the full column. A `ch` resolves against the heading's own size,
	 * so 34ch is about 850px on a 42px H1 and about 690px on a 34px H2: two
	 * lines for a typical page title, where 28ch at the smaller scale broke
	 * the same title into three or four.
	 */
	--measure-heading: 34ch;

	/* --- Spacing (4px base) ------------------------------------------------ */
	--space-3xs: 0.25rem;
	--space-2xs: 0.5rem;
	--space-xs: 0.75rem;
	--space-s: 1rem;
	--space-m: 1.5rem;
	--space-l: 2rem;
	--space-xl: 3rem;
	--space-2xl: 4rem;
	--space-3xl: 6rem;
	--space-4xl: 8rem;

	--gutter: clamp(1rem, 0.6rem + 1.7vw, 1.5rem);

	/*
	 * --- Rhythm ------------------------------------------------------------
	 * One place to tune the vertical spacing of the whole site. Templates read
	 * these rather than picking their own numbers, so the rhythm stays the
	 * same everywhere. History: 96px sections (too much), then 40px to 56px
	 * (too little once the bands alternated white and grey), then 64px to
	 * 120px with the 2026-09-18 display headings, and now the values below.
	 */
	/*
	 * Tightened 2026-09-30 with the type scale. 120px of air between bands was
	 * sized to 56px section headings; with 34px headings it read as empty
	 * screen. The ordinary section now runs 48px on a phone to 80px on a
	 * desktop, and the long measure 56px to 96px.
	 */
	--section-y: clamp(3rem, 2.2rem + 3.4vw, 5rem);

	/*
	 * The long measure, for the moments that carry a page: a service hero, a
	 * price band, a mood grid, a closing band. Ordinary sections stay on
	 * --section-y.
	 */
	--section-y-lg: clamp(3.5rem, 2.4rem + 4.2vw, 6rem);
	--block-y: clamp(1.75rem, 1.6rem + 0.6vw, 2.25rem);
	--grid-gap: 1.25rem;

	/* 18px on a phone to 20px on a desktop, sized to a 20px card title. */
	--card-pad: clamp(1.125rem, 1.08rem + 0.2vw, 1.25rem);
	--kicker-gap: 0.5rem;
	--head-gap: 0.75rem;
	--para-gap: 0.9em;

	/*
	 * --- Stat tile ----------------------------------------------------------
	 * Every label-and-figure tile on the site reads these: the home market band,
	 * the place market snapshot and the place facts box. One description, so
	 * three different templates cannot drift into three different tiles. The
	 * radius sits between --radius-m and --radius-l because a tile is smaller
	 * than a card and 16px on a 3rem-high box reads as a pill.
	 */
	--tile-pad: 1rem 1.25rem;
	--tile-radius: 12px;
	--tile-bg: var(--white);
	--tile-border: 1px solid var(--color-border);

	/* --- Layout ------------------------------------------------------------ */
	--content-width: 760px;
	--wide-width: 1280px;
	--header-height: 72px;
	--sticky-bar-height: 60px;

	/* --- Radius ------------------------------------------------------------ */
	--radius-s: 4px;
	--radius-m: 12px;

	/*
	 * 24px, up from 16px on 2026-09-18. A card is now the softest shape on the
	 * page and a full-width panel takes the same corner, so a grid of cards and
	 * the band underneath it read as one family.
	 */
	--radius-l: 24px;
	--radius-pill: 999px;

	/* --- Controls ---------------------------------------------------------- */
	--control-height: 48px;
	--control-height-lg: 56px;

	/* --- Shadow (two levels, nothing else) --------------------------------- */
	--shadow-1: 0 1px 2px rgb(17 17 17 / 6%), 0 2px 8px rgb(17 17 17 / 6%);
	--shadow-2: 0 4px 12px rgb(17 17 17 / 8%), 0 12px 32px rgb(17 17 17 / 10%);

	/* --- Motion ------------------------------------------------------------ */
	--ease: cubic-bezier(0.2, 0.6, 0.3, 1);
	--dur-fast: 120ms;
	--dur: 200ms;
	--dur-slow: 320ms;

	/* --- Z-index scale ----------------------------------------------------- */
	--z-base: 1;
	--z-sticky-bar: 60;
	--z-float: 70;
	--z-header: 80;
	--z-mega: 90;
	--z-drawer: 100;
	--z-skip: 110;
}

/*
 * Sections painted on navy invert the text tokens, so every component inside
 * them stays legible without a component-level override.
 */
.on-dark {
	--color-text: var(--white);
	--color-text-muted: var(--azure-100);
	--color-bg: var(--navy-900);
	--color-bg-alt: var(--navy-800);
	--color-surface: var(--navy-800);
	--color-border: rgb(255 255 255 / 16%);
	--color-border-strong: rgb(255 255 255 / 34%);
	--color-link: var(--azure-100);
	--color-link-hover: var(--white);
	--color-focus: var(--white);

	background-color: var(--color-bg-dark);
	color: var(--color-text);
}

@media (prefers-reduced-motion: reduce) {
	:root {
		--dur-fast: 1ms;
		--dur: 1ms;
		--dur-slow: 1ms;
	}
}
/*
 * WayHome: reset, typography and utilities.
 * Depends on tokens.css.
 */

/* --------------------------------------------------------------------------
 * 1. Reset
 * ----------------------------------------------------------------------- */

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

* {
	margin: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--header-height) + var(--space-s));
	tab-size: 4;
}

body {
	min-height: 100svh;
	margin: 0;
	background-color: var(--color-canvas);
	color: var(--color-text);
	font-family: var(--font-body);
	font-size: var(--step-0);
	font-weight: 400;
	line-height: var(--lh-body);
	text-rendering: optimizespeed;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

img,
picture,
video,
canvas,
svg {
	display: block;
	max-width: 100%;
	height: auto;
}

svg {
	fill: none;
}

input,
button,
textarea,
select {
	font: inherit;
	color: inherit;
}

button {
	background: none;
	border: 0;
	cursor: pointer;
}

p,
li,
figcaption {
	overflow-wrap: break-word;
	text-wrap: pretty;
}

ul[class],
ol[class] {
	padding: 0;
	list-style: none;
}

table {
	border-collapse: collapse;
	border-spacing: 0;
}

hr {
	height: 1px;
	margin-block: var(--space-l);
	border: 0;
	background-color: var(--color-border);
}

iframe {
	max-width: 100%;
	border: 0;
}

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

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

/* --------------------------------------------------------------------------
 * 2. Typography
 * ----------------------------------------------------------------------- */

/*
 * Manrope at 500. The old 700 was right for Quicksand, whose light geometric
 * skeleton needed the weight to hold a heading together; Manrope at the same
 * weight is heavy, and at the sizes the new scale uses it shouts. Headings are
 * large and light, which is the whole difference between the two looks.
 */
h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--font-heading);
	font-weight: var(--weight-heading);
	line-height: var(--lh-heading);
	color: var(--color-text);
	text-wrap: balance;
}

h1 {
	font-size: var(--step-5);
	line-height: var(--lh-display);
	letter-spacing: var(--tracking-tight);
}

/*
 * A section heading is the second largest thing on a page and sets its pace.
 * 26px on a phone to 34px on a desktop, at the display leading, so two lines
 * sit close enough to read as one shape.
 */
h2 {
	font-size: var(--step-section);
	line-height: var(--lh-display);
	letter-spacing: var(--tracking-tight);
}

/*
 * Body copy is capped at --measure. A heading set to the same width reads as a
 * single long line, so it takes the shorter cap and breaks into a shape. H3
 * is capped only inside editor content, because elsewhere it is a card title
 * in a column that is already narrower than the cap.
 */
h1,
h2,
.entry-content h3 {
	max-width: var(--measure-heading);
}

/* A centred block keeps its heading centred once the heading is capped. */
.text-center :is(h1, h2),
.error-404 :is(h1, h2),
.no-results :is(h1, h2) {
	margin-inline: auto;
}

h3 {
	font-size: var(--step-3);
	letter-spacing: var(--tracking-snug);
}

h4 {
	font-size: var(--step-2);
	font-weight: var(--weight-heading-strong);
}

h5 {
	font-size: var(--step-1);
	font-weight: var(--weight-heading-strong);
}

h6 {
	font-size: var(--step-0);
	font-weight: var(--weight-heading-strong);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
}

.display {
	font-size: var(--step-hero);
	font-weight: var(--weight-heading);
	line-height: var(--lh-display);
	letter-spacing: var(--tracking-tight);
}

.kicker {
	display: inline-block;
	margin-bottom: var(--kicker-gap);
	font-family: var(--font-heading);
	font-size: var(--step--2);
	font-weight: var(--weight-heading-strong);
	text-transform: uppercase;
	letter-spacing: var(--tracking-eyebrow);
	color: var(--color-text-muted);
}

.lead {
	font-size: var(--step-1);
	line-height: 1.55;
	color: var(--color-text-muted);
}

small,
.text-small {
	font-size: var(--step--1);
}

strong,
b {
	font-weight: 600;
}

a {
	color: var(--color-link);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	transition: color var(--dur-fast) var(--ease);
}

a:hover {
	color: var(--color-link-hover);
	text-decoration-thickness: 2px;
}

code,
kbd,
samp,
pre {
	font-family: ui-monospace, sfmono-regular, "SF Mono", menlo, monospace;
	font-size: 0.9em;
}

blockquote {
	padding-left: var(--space-m);
	border-left: 4px solid var(--azure-600);
	font-size: var(--step-1);
}

/*
 * Flow: vertical rhythm inside editor content. Paragraph to paragraph is set
 * in `em` so the gap tracks the type size rather than sitting at a fixed 24px
 * under everything.
 */
.entry-content > * + * {
	margin-top: var(--para-gap);
}

.entry-content > * + :is(h2, h3) {
	margin-top: var(--space-l);
}

.entry-content > :is(h2, h3, h4) + * {
	margin-top: var(--head-gap);
}

.entry-content :is(ul, ol) {
	padding-left: 1.4em;
}

.entry-content li + li {
	margin-top: var(--space-2xs);
}

.entry-content :is(p, li) {
	max-width: var(--measure);
}

/* --------------------------------------------------------------------------
 * 3. Focus and skip link
 * ----------------------------------------------------------------------- */

:focus-visible {
	outline: 3px solid var(--color-focus);
	outline-offset: 2px;
	border-radius: var(--radius-s);
}

:focus:not(:focus-visible) {
	outline: none;
}

.skip-link {
	position: absolute;
	inset-inline-start: var(--space-s);
	inset-block-start: var(--space-s);
	z-index: var(--z-skip);
	padding: var(--space-xs) var(--space-s);
	background-color: var(--ink);
	color: var(--white);
	font-family: var(--font-heading);
	font-weight: 700;
	text-decoration: none;
	border-radius: var(--radius-m);
	transform: translateY(-200%);
	transition: transform var(--dur) var(--ease);
}

.skip-link:focus {
	transform: translateY(0);
	color: var(--white);
}

/* --------------------------------------------------------------------------
 * 4. Utilities
 * ----------------------------------------------------------------------- */

.container {
	width: 100%;
	max-width: calc(var(--wide-width) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.container--narrow {
	max-width: calc(var(--content-width) + (var(--gutter) * 2));
}

.container--full {
	max-width: none;
}

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

.screen-reader-text:focus,
.visually-hidden:focus {
	position: static !important;
	width: auto;
	height: auto;
	margin: 0;
	overflow: visible;
	clip-path: none;
	white-space: normal;
}

.stack {
	display: flex;
	flex-direction: column;
	gap: var(--stack-gap, var(--space-m));
}

.stack--s {
	--stack-gap: var(--space-2xs);
}

.stack--l {
	--stack-gap: var(--space-l);
}

.cluster {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--cluster-gap, var(--space-s));
}

.cluster--between {
	justify-content: space-between;
}

.cluster--tight {
	--cluster-gap: var(--space-2xs);
}

.grid-auto {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(var(--grid-min, 280px), 100%), 1fr));
	gap: var(--grid-gap, var(--space-m));
}

.grid-auto--wide {
	--grid-min: 340px;
}

.grid-auto--narrow {
	--grid-min: 200px;
}

.flow > * + * {
	margin-top: var(--flow-gap, var(--space-m));
}

.text-center {
	text-align: center;
}

.text-muted {
	color: var(--color-text-muted);
}

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

.nowrap {
	white-space: nowrap;
}

.tabular {
	font-variant-numeric: tabular-nums;
}

.icon {
	display: inline-block;
	flex: none;
	width: 1em;
	height: 1em;
	fill: none;
	stroke: currentcolor;
	stroke-width: 1.75;
	stroke-linecap: round;
	stroke-linejoin: round;
	vertical-align: -0.125em;
}

.icon--whatsapp {
	fill: currentcolor;
	stroke: none;
}

.aspect-4-3 {
	aspect-ratio: 4 / 3;
}

.aspect-3-2 {
	aspect-ratio: 3 / 2;
}

.aspect-16-9 {
	aspect-ratio: 16 / 9;
}

.cover {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
/*
 * WayHome: page shell: header, navigation, mega-menu, mobile drawer, footer,
 * sticky mobile CTA bar and section rhythm.
 * Depends on tokens.css and base.css.
 */

/* --------------------------------------------------------------------------
 * 1. Page shell
 * ----------------------------------------------------------------------- */

.site {
	display: flex;
	flex-direction: column;
	min-height: 100svh;
}

.site-main {
	flex: 1 0 auto;
}

/* Room for the sticky mobile CTA bar so it never covers the footer. */
@media (width <= 899px) {
	.site {
		padding-bottom: var(--sticky-bar-height);
	}
}

.section {
	padding-block: var(--section-y);
}

.section--tight {
	padding-block: calc(var(--section-y) * 0.6);
}

/*
 * The long measure, for the few moments on a page that carry it: a hero, a
 * price band, a closing band. See --section-y-lg in tokens.css.
 */
.section--lg {
	padding-block: var(--section-y-lg);
}

.section--alt {
	background-color: var(--color-bg-alt);
}

.section--brand {
	background-color: var(--color-bg-brand);
}

.section__head {
	max-width: var(--measure);
	margin-bottom: var(--space-m);
}

.section__head > :is(h1, h2, h3) {
	margin-top: 0;
}

.section__head p {
	margin-top: var(--head-gap);
	color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
 * 2. Header
 * ----------------------------------------------------------------------- */

.header-sentinel {
	position: absolute;
	inset-block-start: 0;
	width: 1px;
	height: 1px;
}

.site-header {
	position: sticky;
	inset-block-start: 0;
	z-index: var(--z-header);
	background-color: var(--white);
	border-bottom: 1px solid transparent;
	transition:
		background-color var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

.site-header.is-stuck {
	border-bottom-color: var(--color-border);
	box-shadow: var(--shadow-1);
}

/*
 * Over the home hero the bar is transparent and everything in it is white, so
 * the photograph starts at the very top of the window. nav.js adds `is-stuck`
 * as soon as the sentinel leaves the viewport, and the bar becomes the
 * ordinary white one. A text shadow rather than a scrim keeps the photograph
 * clean: the items are large and the shadow only has to survive a bright patch
 * of sky.
 */
.site-header--over:not(.is-stuck) {
	background-color: transparent;
}

.site-header--over:not(.is-stuck) :is(.logo, .primary-nav .menu > .menu-item > a, .rating-badge) {
	color: var(--white);
	text-shadow: 0 1px 12px rgb(17 17 17 / 45%);
}

.site-header--over:not(.is-stuck) .rating-badge {
	border-color: rgb(255 255 255 / 45%);
}

.site-header--over:not(.is-stuck) .primary-nav .menu > .menu-item > a:hover,
.site-header--over:not(.is-stuck) .primary-nav .menu > .menu-item.is-open > a {
	background-color: rgb(255 255 255 / 18%);
	color: var(--white);
}

.site-header--over:not(.is-stuck) .nav-hamburger {
	color: var(--white);
	border-color: rgb(255 255 255 / 45%);
}

/*
 * The header carries eight top-level items plus the contact actions, which do
 * not fit inside the content container. It gets its own, wider shell.
 */
.site-header__inner {
	display: flex;
	align-items: center;
	gap: var(--space-m);
	max-width: 1840px;
	/*
	 * The bar's 1px bottom border is part of --header-height, not added to
	 * it. The front-page hero pulls itself up by exactly --header-height to
	 * sit under the transparent bar, so an extra pixel here showed as a
	 * line of canvas above the photograph.
	 */
	min-height: calc(var(--header-height) - 1px);
	padding-block: var(--space-2xs);
}

@media (width >= 1440px) {
	.site-header__inner {
		padding-inline: var(--space-xl);
	}
}

.site-branding {
	display: flex;
	flex: 1 1 0;
	align-items: center;
	gap: var(--space-s);
	min-width: 0;
}

/* --- Review rating pill -------------------------------------------------- */

.rating-badge {
	display: none;
	align-items: center;
	gap: var(--space-3xs);
	flex: none;
	padding: 6px var(--space-2xs) 6px 6px;
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: var(--weight-heading-strong);
	line-height: 1;
	color: var(--ink);
	text-decoration: none;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-pill);
}

@media (width >= 1024px) {
	.rating-badge {
		display: inline-flex;
	}
}

.rating-badge:hover {
	color: var(--ink);
	border-color: var(--color-border-strong);
}

.rating-badge__mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	color: var(--azure-600);
	background-color: var(--azure-100);
	border-radius: var(--radius-pill);
}

.site-header--over:not(.is-stuck) .rating-badge__mark {
	color: var(--white);
	background-color: rgb(255 255 255 / 22%);
}

.rating-badge__star {
	width: 0.95em;
	height: 0.95em;
	color: var(--coral-500);
	fill: currentcolor;
}

.rating-badge__count {
	color: var(--color-text-muted);
	font-weight: 400;
}

.site-header--over:not(.is-stuck) .rating-badge__count {
	color: inherit;
}

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

.logo:hover {
	color: var(--ink);
}

.logo__svg,
.logo__img {
	display: block;
	width: clamp(120px, 14vw, 168px);
	height: auto;
	color: currentcolor;
}

.site-header.is-stuck .logo__svg,
.site-header.is-stuck .logo__img {
	width: clamp(110px, 12vw, 140px);
	transition: width var(--dur) var(--ease);
}

.site-header__actions {
	display: flex;
	flex: 1 1 0;
	align-items: center;
	justify-content: flex-end;
	gap: var(--space-2xs);
}

/* --------------------------------------------------------------------------
 * 3. Primary navigation (desktop)
 * ----------------------------------------------------------------------- */

.primary-nav {
	display: none;
}

@media (width >= 1200px) {
	.primary-nav {
		display: block;
		flex: 0 1 auto;
	}
}

.primary-nav .menu {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-3xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

.primary-nav .menu > .menu-item {
	position: relative;

	/*
	 * The submenu toggle is a sibling of the anchor, so the item has to be a
	 * flex row or the chevron wraps onto its own line.
	 */
	display: flex;
	align-items: center;
}

/*
 * Eight top-level items plus the contact actions have to share 1200px, so the
 * bar starts compact and only relaxes once there is room for it (see the
 * >=1440px block at the end of this section).
 */
/*
 * Plain text, not a row of buttons: 15px Manrope at 500 with a pill hover, so
 * the bar reads as a line of words with the one azure button at the end of it.
 */
.primary-nav .menu > .menu-item > a {
	display: inline-flex;
	align-items: center;
	padding: var(--space-2xs) var(--space-xs);
	font-family: var(--font-heading);
	font-size: var(--step-ui);
	font-weight: var(--weight-heading);
	line-height: var(--lh-ui);
	color: var(--ink);
	text-decoration: none;
	border-radius: var(--radius-pill);
	white-space: nowrap;
}

.primary-nav .menu > .menu-item > a:hover,
.primary-nav .menu > .menu-item.is-open > a {
	background-color: var(--grey-100);
	color: var(--ink);
}

.primary-nav .menu > .menu-item.current-menu-item > a,
.primary-nav .menu > .menu-item.current-menu-ancestor > a {
	font-weight: var(--weight-heading-strong);
	box-shadow: inset 0 -2px 0 0 var(--azure-600);
}

.site-header--over:not(.is-stuck) .primary-nav .menu > .menu-item.current-menu-item > a,
.site-header--over:not(.is-stuck) .primary-nav .menu > .menu-item.current-menu-ancestor > a {
	box-shadow: inset 0 -2px 0 0 var(--white);
}

.primary-nav .menu > .menu-item-has-children > a {
	padding-inline-end: var(--space-2xs);
}

.nav__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 2rem;
	margin-inline-start: -2px;
	padding: 0;
	color: var(--ink);
	border-radius: var(--radius-m);
}

.nav__toggle .icon {
	width: 0.9em;
	height: 0.9em;
	transition: transform var(--dur) var(--ease);
}

.nav__toggle[aria-expanded="true"] .icon {
	transform: rotate(180deg);
}

@media (width >= 1600px) {
	.primary-nav .menu > .menu-item > a {
		padding: var(--space-2xs) var(--space-s);
	}

	.nav__toggle {
		width: 1.75rem;
	}
}

/* --- Mega menu ---------------------------------------------------------- */

.primary-nav .sub-menu {
	position: absolute;
	inset-block-start: calc(100% + var(--space-2xs));
	inset-inline-start: 0;
	z-index: var(--z-mega);
	display: grid;
	grid-template-columns: repeat(2, minmax(210px, 1fr));
	gap: var(--space-3xs);
	min-width: 480px;
	margin: 0;
	padding: var(--space-s);
	list-style: none;
	background-color: var(--white);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
	box-shadow: var(--shadow-2);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	transition:
		opacity var(--dur) var(--ease),
		transform var(--dur) var(--ease),
		visibility 0s linear var(--dur);
}

.primary-nav .menu-item:last-child .sub-menu,
.primary-nav .menu-item:nth-last-child(2) .sub-menu {
	inset-inline-start: auto;
	inset-inline-end: 0;
}

.primary-nav .menu-item.is-open > .sub-menu,
.primary-nav .menu-item:hover > .sub-menu,
.primary-nav .menu-item:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
	transition-delay: 0s;
}

.primary-nav .sub-menu a {
	display: block;
	padding: var(--space-2xs) var(--space-xs);
	color: var(--ink);
	text-decoration: none;
	border-radius: var(--radius-m);
}

.primary-nav .sub-menu a:hover {
	background-color: var(--grey-100);
}

.menu-item__label {
	display: block;
	font-family: var(--font-heading);
	font-weight: 700;
	line-height: var(--lh-ui);
}

.menu-item__description {
	display: block;
	margin-top: 2px;
	font-size: var(--step--1);
	line-height: 1.4;
	color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
 * 4. Mobile drawer
 * ----------------------------------------------------------------------- */

.nav-hamburger {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	color: var(--ink);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-m);
}

.nav-hamburger .icon {
	width: 1.4em;
	height: 1.4em;
}

.nav-hamburger .icon--close,
.nav-hamburger[aria-expanded="true"] .icon--menu {
	display: none;
}

.nav-hamburger[aria-expanded="true"] .icon--close {
	display: block;
}

@media (width >= 1200px) {
	.nav-hamburger {
		display: none;
	}
}

.drawer {
	position: fixed;
	inset: 0;
	z-index: var(--z-drawer);
	display: grid;
	grid-template-columns: 1fr;
	visibility: hidden;
}

.drawer[data-open="true"] {
	visibility: visible;
}

.drawer__backdrop {
	position: absolute;
	inset: 0;
	background-color: rgb(17 17 17 / 50%);
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
}

.drawer[data-open="true"] .drawer__backdrop {
	opacity: 1;
}

.drawer__panel {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	width: min(420px, 92vw);
	height: 100%;
	margin-inline-start: auto;
	padding: var(--space-s) var(--space-m) var(--space-xl);
	overflow-y: auto;
	overscroll-behavior: contain;
	background-color: var(--white);
	box-shadow: var(--shadow-2);
	transform: translateX(100%);
	transition: transform var(--dur-slow) var(--ease);
}

.drawer[data-open="true"] .drawer__panel {
	transform: translateX(0);
}

.drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-s);
	padding-bottom: var(--space-s);
	border-bottom: 1px solid var(--color-border);
}

.drawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	color: var(--ink);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-m);
}

.drawer__close .icon {
	width: 1.3em;
	height: 1.3em;
}

.drawer .menu {
	margin: var(--space-s) 0 0;
	padding: 0;
	list-style: none;
}

.drawer .menu > .menu-item {
	position: relative;
	border-bottom: 1px solid var(--color-border);
}

.drawer .menu > .menu-item > a {
	display: block;
	padding: var(--space-xs) 3rem var(--space-xs) 0;
	font-family: var(--font-heading);
	font-size: var(--step-1);
	font-weight: var(--weight-heading-strong);
	color: var(--ink);
	text-decoration: none;
}

.drawer .nav__toggle {
	position: absolute;
	inset-block-start: var(--space-2xs);
	inset-inline-end: 0;
	width: 44px;
	height: 44px;
	border: 1px solid var(--color-border);
}

.drawer .sub-menu {
	display: none;
	margin: 0 0 var(--space-xs);
	padding: 0 0 0 var(--space-s);
	list-style: none;
	border-left: 2px solid var(--color-border);
}

.drawer .menu-item.is-open > .sub-menu {
	display: block;
}

.drawer .sub-menu a {
	display: block;
	padding: var(--space-2xs) 0;
	color: var(--ink);
	text-decoration: none;
}

.drawer .sub-menu .menu-item__description {
	display: none;
}

.drawer__actions {
	display: grid;
	gap: var(--space-2xs);
	margin-top: var(--space-l);
}

.drawer__contact {
	margin-top: var(--space-l);
	padding-top: var(--space-s);
	border-top: 1px solid var(--color-border);
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

body.has-drawer-open {
	overflow: hidden;
}

/* --------------------------------------------------------------------------
 * 5. Header contact actions
 * ----------------------------------------------------------------------- */

/*
 * A round WhatsApp glyph rather than a labelled button. The one labelled
 * action in the bar is the azure pill beside it, and two labelled buttons
 * side by side is two primaries.
 */
/*
 * Scoped to the bar rather than written as a bare class. Both of these are
 * `.btn`s, and `.btn { display: inline-flex }` lives in components.css, which
 * is bundled *after* this file; at equal specificity the later rule wins, so a
 * bare `.header-cta { display: none }` did nothing at all and both buttons
 * showed at every width.
 */
.site-header__actions .header-whatsapp {
	display: none;
}

@media (width >= 768px) {
	.site-header__actions .header-whatsapp {
		display: inline-flex;
	}
}

.site-header__actions .header-cta {
	display: none;
}

@media (width >= 900px) {
	.site-header__actions .header-cta {
		display: inline-flex;
	}
}

/*
 * The header CTA keeps its azure fill over the hero photograph. It is the one
 * element up there that is supposed to be louder than the picture.
 */
.site-header--over:not(.is-stuck) .header-cta {
	box-shadow: 0 2px 16px rgb(17 17 17 / 25%);
}

/*
 * The owner route, as a quiet text link beside the pill rather than a second
 * button. It appears at the width the primary nav appears at, because below
 * that the drawer carries the same link inside Services and two routes to one
 * page in a 390px bar is clutter.
 */
.header-owner {
	display: none;
	padding-inline: var(--space-2xs);
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: var(--weight-heading-strong);
	line-height: var(--lh-ui);
	color: var(--color-text);
	text-decoration: none;
	white-space: nowrap;
	border-bottom: 1px solid transparent;
}

.header-owner:hover {
	border-bottom-color: currentcolor;
}

@media (width >= 1200px) {
	.header-owner {
		display: inline-flex;
	}
}

.site-header--over:not(.is-stuck) .header-owner {
	color: var(--white);
}

/* --------------------------------------------------------------------------
 * 6. Footer
 * ----------------------------------------------------------------------- */

/* The footer is dense UI: link lists and an address, at 15px. */
.site-footer {
	margin-top: var(--block-y);
	padding-top: var(--section-y);
	background-color: var(--navy-900);
	color: var(--white);
	font-size: var(--step-ui);
}

.site-footer a {
	color: var(--azure-100);
	text-decoration: none;
}

.site-footer a:hover {
	color: var(--white);
	text-decoration: underline;
}

.footer-grid {
	display: grid;
	gap: var(--space-l) var(--space-l);
	grid-template-columns: 1fr;
}

@media (width >= 640px) {
	.footer-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (width >= 1024px) {
	.footer-grid {
		grid-template-columns: 1.4fr repeat(4, minmax(0, 1fr));
	}
}

.footer-col__title {
	margin-bottom: var(--space-s);
	font-family: var(--font-heading);
	font-size: var(--step--2);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--tracking-eyebrow);
	color: var(--white);
}

.footer-col .menu {
	display: grid;
	gap: var(--space-2xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer-about .logo__svg,
.footer-about .logo__img {
	width: 180px;
	color: var(--white);
}

.footer-about p {
	margin-top: var(--space-s);
	max-width: 42ch;
	color: var(--azure-100);
}

.footer-nap {
	margin-top: var(--space-m);
	font-style: normal;
	line-height: 1.7;
	color: var(--azure-100);
}

.footer-nap__row {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2xs);
}

.footer-nap__row + .footer-nap__row {
	margin-top: var(--space-2xs);
}

.footer-nap .icon {
	margin-top: 0.35em;
	color: var(--azure-100);
}

.footer-licence {
	margin-top: var(--space-m);
	padding: var(--space-2xs) var(--space-xs);
	display: inline-block;
	font-size: var(--step--1);
	color: var(--white);
	background-color: var(--navy-800);
	border-radius: var(--radius-s);
}

.footer-bottom {
	margin-top: var(--block-y);
	padding-block: var(--space-m);
	border-top: 1px solid rgb(255 255 255 / 16%);
}

.footer-bottom__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-s);
	font-size: var(--step--1);
	color: var(--azure-100);
}

.footer-bottom .menu {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s);
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer-social {
	display: flex;
	gap: var(--space-2xs);
}

.footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	color: var(--white);
	border: 1px solid rgb(255 255 255 / 34%);
	border-radius: var(--radius-pill);
}

.footer-social a:hover {
	background-color: var(--navy-800);
	border-color: var(--white);
}

.footer-social .icon {
	width: 1.15em;
	height: 1.15em;
}

.back-to-top {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	font-family: var(--font-heading);
	font-weight: 700;
	color: var(--white);
}

.back-to-top .icon {
	transform: rotate(-90deg);
}

/* --------------------------------------------------------------------------
 * 7. Sticky mobile CTA bar
 * ----------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
 * 7a. Floating contact pair (desktop)
 *
 * Two round buttons in a soft translucent shell, bottom right of every page.
 * Strictly the other half of the sticky bar below: this one is hidden under
 * 900px and the bar is hidden from 900px up, so they can never overlap, and
 * neither can cover the footer because the bar's height is padded out of the
 * page shell at the top of this file.
 * ----------------------------------------------------------------------- */

.float-contact {
	display: none;
	position: fixed;
	inset-block-end: var(--space-m);
	inset-inline-end: var(--space-m);
	z-index: var(--z-float);
	flex-direction: column;
	gap: var(--space-2xs);
	padding: var(--space-2xs);
	background-color: rgb(255 255 255 / 72%);
	backdrop-filter: blur(10px);
	border: 1px solid rgb(255 255 255 / 60%);
	border-radius: var(--radius-pill);
	box-shadow: 0 6px 28px rgb(17 17 17 / 18%);
}

@media (width >= 900px) {
	.float-contact {
		display: flex;
	}
}

.float-contact__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: var(--radius-pill);
	text-decoration: none;
	transition:
		background-color var(--dur-fast) var(--ease),
		transform var(--dur-fast) var(--ease);
}

.float-contact__btn:hover {
	transform: translateY(-2px);
}

.float-contact__btn .icon {
	width: 1.5em;
	height: 1.5em;
}

.float-contact__btn--call {
	background-color: var(--azure-600);
	color: var(--white);
}

.float-contact__btn--call:hover {
	background-color: var(--azure-700);
	color: var(--white);
}

/* Ink on WhatsApp green: white on #25D366 is 1.98:1 and is forbidden. */
.float-contact__btn--whatsapp {
	background-color: var(--whatsapp);
	color: var(--ink);
}

.float-contact__btn--whatsapp:hover {
	background-color: var(--whatsapp-dark);
	color: var(--ink);
}

.float-contact__btn--whatsapp .icon {
	fill: currentcolor;
	stroke: none;
}

.sticky-cta {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: var(--z-sticky-bar);
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	min-height: var(--sticky-bar-height);
	background-color: var(--white);
	border-top: 1px solid var(--color-border);
	box-shadow: 0 -2px 12px rgb(17 17 17 / 8%);
	padding-bottom: env(safe-area-inset-bottom);
}

@media (width >= 900px) {
	.sticky-cta {
		display: none;
	}
}

.sticky-cta__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	padding: var(--space-2xs) var(--space-3xs);
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: 700;
	color: var(--ink);
	text-decoration: none;
}

.sticky-cta__item + .sticky-cta__item {
	border-left: 1px solid var(--color-border);
}

.sticky-cta__item .icon {
	width: 1.35em;
	height: 1.35em;
}

.sticky-cta__item--whatsapp {
	background-color: var(--whatsapp);
	color: var(--ink);
}

.sticky-cta__item--enquire {
	background-color: var(--azure-600);
	color: var(--white);
}

.sticky-cta__item--enquire:hover {
	background-color: var(--azure-700);
	color: var(--white);
}
/*
 * WayHome: components: buttons, cards, badges, forms, accordion, tables,
 * breadcrumb, pagination, stats strip, CTA band, notice.
 * Depends on tokens.css and base.css. See docs/brand.md sections 5 to 7.
 */

/* --------------------------------------------------------------------------
 * 1. Buttons
 * ----------------------------------------------------------------------- */

/*
 * Every button is a pill, 48px tall, set in Manrope 600. A pill is the one
 * shape on the page with no corner at all, which is what makes an action read
 * as an action next to a 24px card.
 */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
	min-height: var(--control-height);
	padding: var(--space-xs) var(--space-m);
	font-family: var(--font-heading);
	font-size: var(--step-ui);
	font-weight: var(--weight-heading-strong);
	line-height: var(--lh-ui);
	text-align: center;
	text-decoration: none;
	white-space: nowrap;
	border: 1.5px solid transparent;
	border-radius: var(--radius-pill);
	cursor: pointer;
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease),
		transform var(--dur-fast) var(--ease);
}

/* Hover lifts, active puts it back down. */
.btn:hover {
	transform: translateY(-1px);
}

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

.btn .icon {
	width: 1.25em;
	height: 1.25em;
}

.btn--sm {
	min-height: 40px;
	padding: var(--space-2xs) var(--space-s);
	font-size: var(--step--1);
}

.btn--lg {
	min-height: var(--control-height-lg);
	padding: var(--space-s) var(--space-l);
	font-size: var(--step-0);
}

.btn--block {
	width: 100%;
}

/* Primary: white on azure-600 is 4.73:1; hover darkens, never lightens. */
.btn--primary {
	background-color: var(--color-cta);
	color: var(--white);
}

.btn--primary:hover,
.btn--primary:focus-visible {
	background-color: var(--color-cta-hover);
	color: var(--white);
}

.btn--primary:active {
	background-color: var(--color-cta-active);
}

/*
 * Ghost: the azure tint under azure-700 ink (6.14:1). The quiet sibling of the
 * primary, for "See all projects" and anything else that is a second choice
 * rather than a lesser one.
 */
.btn--ghost-azure {
	background-color: var(--azure-100);
	color: var(--azure-700);
}

.btn--ghost-azure:hover,
.btn--ghost-azure:focus-visible {
	background-color: #d7e9fd;
	color: var(--azure-800);
}

/* The one button that sits on the deep blue band. */
.btn--on-blue {
	background-color: var(--white);
	color: var(--azure-800);
}

.btn--on-blue:hover,
.btn--on-blue:focus-visible {
	background-color: var(--azure-100);
	color: var(--azure-800);
}

.btn--secondary {
	background-color: transparent;
	border-color: var(--navy-800);
	color: var(--navy-800);
}

.btn--secondary:hover,
.btn--secondary:focus-visible {
	background-color: var(--navy-800);
	color: var(--white);
}

.on-dark .btn--secondary {
	border-color: var(--white);
	color: var(--white);
}

.on-dark .btn--secondary:hover,
.on-dark .btn--secondary:focus-visible {
	background-color: var(--white);
	color: var(--navy-900);
}

/* WhatsApp: ink label; white on #25D366 is 1.98:1 and is forbidden. */
.btn--whatsapp {
	background-color: var(--whatsapp);
	color: var(--ink);
}

.btn--whatsapp:hover,
.btn--whatsapp:focus-visible {
	background-color: var(--whatsapp-dark);
	color: var(--ink);
}

.btn--whatsapp .icon {
	fill: currentcolor;
	stroke: none;
}

.btn--call {
	background-color: var(--navy-900);
	color: var(--white);
}

.btn--call:hover,
.btn--call:focus-visible {
	background-color: var(--ink);
	color: var(--white);
}

.btn--ghost {
	background-color: transparent;
	color: var(--ink);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
	background-color: var(--grey-100);
	color: var(--ink);
}

.on-dark .btn--ghost {
	color: var(--white);
}

.on-dark .btn--ghost:hover {
	background-color: var(--navy-800);
	color: var(--white);
}

.btn[aria-disabled="true"],
.btn:disabled {
	background-color: var(--grey-200);
	border-color: transparent;
	color: var(--grey-400);
	cursor: not-allowed;
	pointer-events: none;
	transform: none;
}

.btn--icon {
	width: var(--control-height);
	min-height: var(--control-height);
	padding: 0;
	border-radius: var(--radius-pill);
}

.btn--icon.btn--sm {
	width: 40px;
	min-height: 40px;
}

/* --------------------------------------------------------------------------
 * 2. Cards
 * ----------------------------------------------------------------------- */

.card {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background-color: var(--white);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
	transition:
		box-shadow var(--dur) var(--ease),
		transform var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

.card:hover,
.card:has(:focus-visible) {
	border-color: transparent;
	box-shadow: var(--shadow-2);
	transform: translateY(-2px);
}

.card__media {
	position: relative;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	background-color: var(--grey-100);
}

.card--guide .card__media {
	aspect-ratio: 3 / 2;
}

.card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--dur-slow) var(--ease);
}

.card:hover .card__media img {
	transform: scale(1.04);
}

/* --------------------------------------------------------------------------
 * 2a. The no-photograph panel
 *
 * One description of "there is no picture of this yet", used by every card,
 * tile and hero on the site. A soft navy gradient with the name set across it
 * in white, at the ratio the real image would have taken, so a grid never
 * shows a hole, a key icon in a grey box or a broken image.
 * ----------------------------------------------------------------------- */

.media--empty {
	display: flex;
	align-items: flex-end;
	width: 100%;
	height: 100%;
	min-height: 100%;
	padding: var(--space-m);
	background-image:
		radial-gradient(120% 120% at 15% 0%, #2f4468 0%, transparent 60%),
		linear-gradient(160deg, var(--navy-800) 0%, var(--navy-900) 70%);
	color: var(--white);
}

.media--empty__label {
	font-family: var(--font-heading);
	font-size: var(--step-1);
	font-weight: var(--weight-heading);
	line-height: var(--lh-heading);
	letter-spacing: var(--tracking-snug);
	color: var(--white);
	text-wrap: balance;
}

/*
 * A guide card's panel carries "Guide · Checked <date>" rather than the title
 * (see template-parts/components/card-generic.php), so it is set as an eyebrow.
 */
.type-guide .media--empty__label {
	font-size: var(--step--2);
	font-weight: var(--weight-heading-strong);
	line-height: var(--lh-ui);
	text-transform: uppercase;
	letter-spacing: var(--tracking-eyebrow);
	color: rgb(255 255 255 / 86%);
}

.card__badges {
	position: absolute;
	inset-block-start: var(--space-2xs);
	inset-inline-start: var(--space-2xs);
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-2xs);
}

.card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: var(--space-2xs);
	padding: var(--card-pad);
}

/*
 * A card title is 20px Manrope medium everywhere: place, project, property,
 * guide, service and agent. One size, so a mixed grid does not step.
 */
.card__title {
	font-family: var(--font-heading);
	font-size: var(--step-2);
	font-weight: var(--weight-heading);
	line-height: var(--lh-heading);
	letter-spacing: var(--tracking-snug);
	max-width: none;
}

/*
 * One link per card: the title anchor is stretched over the whole card, so
 * assistive technology announces a single target.
 */
.card__title a {
	color: var(--ink);
	text-decoration: none;
}

.card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.card:hover .card__title a {
	color: var(--azure-700);
}

/*
 * Focus, for every card whose title link is stretched over the whole card.
 *
 * The ring goes round the card, because the card is the target: a ring round
 * the title alone drew a box inside the card that looked like a stray border.
 * The lift reads `:has(:focus-visible)` rather than `:focus-within`, because
 * focus-within also matches after a mouse click and after the browser puts
 * focus back on the link when a visitor returns with the back button, which
 * left one card in a grid raised and shadowed for no visible reason.
 */
:is(.card__title, .place-card__title, .project-card__title) a:focus-visible {
	outline: none;
}

:is(.card, .place-card, .project-card):has(:is(.card__title, .place-card__title, .project-card__title) a:focus-visible) {
	outline: 3px solid var(--color-focus);
	outline-offset: 3px;
}

.card__meta {
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

.card__excerpt {
	font-size: var(--step-ui);
	color: var(--color-text-muted);
}

.card__price {
	font-family: var(--font-heading);
	font-size: var(--step-2);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--ink);
}

.card__price span {
	font-size: var(--step--1);
	font-weight: 600;
	color: var(--color-text-muted);
}

.card__facts {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s);
	margin-top: auto;
	padding-top: var(--space-2xs);
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

.card__facts li {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
}

.card__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2xs);
	margin-top: var(--space-2xs);
	padding-top: var(--space-2xs);
	border-top: 1px solid var(--color-border);
}

/* Anything genuinely separate sits above the stretched title link. */
.card__action {
	position: relative;
	z-index: 2;
}

.card--service {
	background-color: var(--color-bg);
	border-color: var(--color-border);
}

.card--service .card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	color: var(--azure-600);
	background-color: var(--azure-100);
	border-radius: var(--radius-pill);
}

.card--service .card__icon .icon {
	width: 1.5em;
	height: 1.5em;
}

/*
 * The default card grid. Described once here rather than nine times over in
 * the template sheets, where two of them disagreed and whichever happened to
 * be queued second won.
 */
.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
	gap: var(--grid-gap);
}

/* --------------------------------------------------------------------------
 * 2b. Place and project cards
 *
 * These two used to be described three times over, once each in
 * archive-place.css, new-projects.css and single-place.css, which meant a
 * place card rendered anywhere else (the front page) had no styling at all.
 * There is one description now, in the core bundle, so a place card looks the
 * same wherever it is printed.
 * ----------------------------------------------------------------------- */

.place-card,
.project-card {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background-color: var(--color-bg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
	transition:
		box-shadow var(--dur) var(--ease),
		transform var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

.place-card:hover,
.place-card:has(:focus-visible),
.project-card:hover,
.project-card:has(:focus-visible) {
	border-color: transparent;
	box-shadow: var(--shadow-2);
	transform: translateY(-2px);
}

.place-card__media,
.project-card__media {
	position: relative;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	background-color: var(--grey-100);
}

.place-card__media .media,
.place-card__media img,
.project-card__media .media,
.project-card__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	aspect-ratio: auto;
	transition: transform var(--dur-slow) var(--ease);
}

/*
 * The no-photograph panel is a flex box that sets its name along the bottom
 * edge. The `display: block` above is for a real <picture>, and on the panel
 * it lifted the name to the top, under the tags that share that corner.
 */
.place-card__media .media--empty,
.project-card__media .media--empty {
	display: flex;
}

.place-card:hover .place-card__media img,
.project-card:hover .project-card__media img {
	transform: scale(1.04);
}

/*
 * Top right, because the "For living" / "For investment" tags take the top
 * left on the cards that carry them and two stacks in one corner is a pile.
 */
.place-card__status,
.project-card__status {
	position: absolute;
	inset-block-start: var(--space-2xs);
	inset-inline-end: var(--space-2xs);
	z-index: 2;
}

/*
 * On a card that carries "For living" / "For investment" tags the status is
 * printed as one more item in that row (see template-parts/place/card.php),
 * so the row wraps instead of two corners colliding on a 300px card.
 */
.area-tags__status {
	display: inline-flex;
	align-items: center;
}

.place-card__body,
.project-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: var(--space-2xs);
	padding: var(--card-pad);
}

.place-card__title,
.project-card__title {
	margin: 0;
	max-width: none;
	font-family: var(--font-heading);
	font-size: var(--step-2);
	font-weight: var(--weight-heading);
	line-height: var(--lh-heading);
	letter-spacing: var(--tracking-snug);
}

/* One link per card: the title anchor stretches over the whole card. */
.place-card__title a,
.project-card__title a {
	color: var(--ink);
	text-decoration: none;
}

.place-card__title a::after,
.project-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.place-card:hover .place-card__title a,
.project-card:hover .project-card__title a {
	color: var(--azure-700);
}

.place-card__type {
	margin: 0;
	font-size: var(--step--1);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	color: var(--color-text-muted);
}

.place-card__summary,
.project-card__summary {
	margin: 0;
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

.place-card__count {
	margin-block-start: auto;
	padding-block-start: var(--space-2xs);
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: var(--weight-heading-strong);
	color: var(--azure-700);
}

.project-card__facts {
	margin: 0;
	margin-block-start: auto;
	padding-block-start: var(--space-2xs);
	border-block-start: 1px solid var(--color-border);
	font-size: var(--step--1);
}

.project-card__facts > div {
	display: grid;
	grid-template-columns: 7rem 1fr;
	gap: var(--space-2xs);
	padding-block: var(--space-3xs);
}

.project-card__facts dt {
	font-family: var(--font-heading);
	font-weight: var(--weight-heading-strong);
	color: var(--color-text-muted);
}

.project-card__facts dd {
	margin: 0;
}

/* --------------------------------------------------------------------------
 * 3. Badges
 * ----------------------------------------------------------------------- */

.badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	padding: 4px 10px;
	font-family: var(--font-heading);
	font-size: var(--step--2);
	font-weight: 700;
	line-height: 1.3;
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	border-radius: var(--radius-pill);
	background-color: var(--grey-200);
	color: var(--grey-700);
}

.badge--featured {
	background-color: var(--coral-500);
	color: var(--ink);
}

.badge--offplan {
	background-color: var(--azure-100);
	color: var(--azure-800);
}

.badge--sold {
	background-color: var(--grey-200);
	color: var(--grey-700);
}

.badge--new {
	background-color: var(--ink);
	color: var(--white);
}

/* --------------------------------------------------------------------------
 * 4. Forms
 * ----------------------------------------------------------------------- */

/*
 * One form component, used by the search widget, the listing enquiry card and
 * every lead form the plugin renders. Calm by default: a white field on a
 * one-pixel boundary, a 15px label with a quiet asterisk where the field is
 * required, and 14px hints. The plugin's own stylesheet deliberately leaves all
 * of this to the theme.
 */

.field {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
}

.field__label {
	font-family: var(--font-body);
	font-size: var(--step-ui);
	font-weight: 500;
	line-height: var(--lh-ui);
}

/*
 * The control carries `required` and `aria-required`, so the mark is decoration
 * and is hidden from assistive technology. It stays a small muted asterisk
 * rather than a coral one: a column of red marks reads as a column of errors.
 */
.field__req {
	color: var(--color-text-muted);
	font-weight: 400;
}

.field__hint {
	font-size: var(--step--1);
	line-height: 1.45;
	color: var(--color-text-muted);
}

.field__error {
	display: flex;
	align-items: center;
	gap: var(--space-3xs);
	font-size: var(--step--1);
	font-weight: 500;
	color: var(--coral-700);
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="search"],
input[type="date"],
input[type="password"],
select,
textarea {
	width: 100%;
	min-height: 48px;
	padding: 12px 14px;
	background-color: var(--white);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--step-ui);
	line-height: var(--lh-ui);

	/*
	 * grey-500 rather than grey-400: a resting boundary is a UI component and
	 * has to clear 3:1 against the surface behind it, which grey-400 (2.49)
	 * does not. See docs/brand.md section 2.3, rule 7.
	 */
	border: 1px solid var(--color-border-field);
	border-radius: var(--radius-m);
	transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

/*
 * Mobile Safari zooms the page whenever a focused control is under 16px, which
 * throws the layout sideways mid-form. The calm 15px is a desktop refinement;
 * a phone keeps the full 16px and nothing jumps.
 */
@media (width <= 640px) {
	input[type="text"],
	input[type="email"],
	input[type="tel"],
	input[type="url"],
	input[type="number"],
	input[type="search"],
	input[type="date"],
	input[type="password"],
	select,
	textarea {
		font-size: 1rem;
	}
}

textarea {
	min-height: 8rem;
	resize: vertical;
}

input:hover,
select:hover,
textarea:hover {
	border-color: var(--grey-700);
}

input:focus,
select:focus,
textarea:focus {
	background-color: var(--white);
	border-color: var(--ink);
	outline: 3px solid var(--color-focus);
	outline-offset: 2px;
}

input::placeholder,
textarea::placeholder {
	color: var(--grey-700);
	opacity: 1;
}

select {
	appearance: none;
	padding-inline-end: 2.5rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23111111' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5 12 15.5 18 9.5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--space-xs) center;
	background-size: 1.1em;
}

.field--error input,
.field--error select,
.field--error textarea {
	border-color: var(--coral-700);
}

.search-form {
	display: flex;
	gap: var(--space-2xs);
}

.search-form .search-field {
	flex: 1;
}

.honeypot {
	position: absolute !important;
	left: -9999px;
}

/* --------------------------------------------------------------------------
 * 4a. Lead forms
 *
 * The plugin prints the markup and leaves the look to the theme, so the rules
 * that give every lead form its rhythm live here next to the field styling
 * rather than in the plugin's stylesheet.
 * ----------------------------------------------------------------------- */

.wh-form-wrap {
	--wh-form-gap: 0.75rem;
}

.wh-form__title {
	font-size: var(--step-2);
}

.wh-form__intro {
	margin-block-end: var(--space-s);
	font-size: var(--step-ui);
	line-height: 1.5;
}

/* A reference is a quiet line of context, not a highlighted panel. */
.wh-form__ref {
	padding: 0;
	font-size: var(--step--2);
	color: var(--color-text-muted);
	background-color: transparent;
	border-radius: 0;
}

.wh-form__ref-label,
.wh-form__ref-value {
	font-family: var(--font-body);
	font-size: inherit;
	font-weight: 400;
	color: inherit;
}

.wh-form__ref-value {
	font-weight: 600;
	color: var(--ink);
}

.wh-form__actions {
	gap: var(--space-2xs) var(--space-s);
	margin-block-start: var(--space-3xs);
}

.wh-form .field--consent {
	font-size: var(--step--2);
	line-height: 1.5;
}

/*
 * A form inside a side card: the submit is the card's one filled control, so it
 * runs the full width, and the two-up field grid stacks because two columns
 * inside a 340px card is not a column.
 */
.form-card .wh-form__submit,
.enquiry-card .wh-form__submit {
	width: 100%;
}

.enquiry-card .wh-form__grid {
	grid-template-columns: 1fr;
}

.enquiry-card .wh-form__grid > .field--half {
	grid-column: 1 / -1;
}

.form-card .wh-form-wrap,
.enquiry-card .wh-form-wrap {
	max-width: none;
}

/*
 * The quiet pair of fallback actions under a form: call and WhatsApp as outline
 * buttons, never two filled blocks. One primary action per card is the rule in
 * docs/brand.md section 5, and the submit above is it.
 */
.form-contact-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-2xs);
	margin-block-start: var(--space-s);
	padding-block-start: var(--space-s);
	border-block-start: 1px solid var(--color-border);
}

.form-contact-row .btn {
	min-height: 44px;
	padding-inline: var(--space-2xs);
	font-size: var(--step--1);
}

.form-contact-row .btn .icon {
	width: 1.15em;
	height: 1.15em;
}

/* --------------------------------------------------------------------------
 * 4b. "More filters" disclosure
 *
 * A native <details>, so a visitor with no JavaScript gets the same control.
 * It is opened server-side whenever one of the filters inside it is set, which
 * is what stops a filtered page hiding its own filters.
 * ----------------------------------------------------------------------- */

.more-filters {
	margin-block-start: var(--space-s);
}

.more-filters > summary {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	padding: var(--space-3xs) 0;
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: 700;
	color: var(--color-link);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	cursor: pointer;
	list-style: none;
}

.more-filters > summary::-webkit-details-marker {
	display: none;
}

.more-filters > summary:hover {
	color: var(--color-link-hover);
}

.more-filters > summary .icon {
	width: 1em;
	height: 1em;
	transition: transform var(--dur) var(--ease);
}

.more-filters[open] > summary .icon {
	transform: rotate(180deg);
}

.more-filters__panel {
	display: grid;
	gap: var(--space-s);
	grid-template-columns: 1fr;
	margin-block-start: var(--space-s);
	padding-block-start: var(--space-s);
	border-block-start: 1px solid var(--color-border);
}

@media (width >= 700px) {
	.more-filters__panel {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.more-filters__panel .field {
	margin: 0;
	min-width: 0;
}

/* --------------------------------------------------------------------------
 * 5. Accordion (native <details>)
 * ----------------------------------------------------------------------- */

.accordion {
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
	overflow: hidden;
}

.accordion + .accordion {
	margin-top: var(--space-2xs);
}

.accordion > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-s);
	min-height: 48px;
	padding: var(--space-xs) var(--space-s);
	font-family: var(--font-heading);
	font-size: var(--step-1);
	font-weight: var(--weight-heading-strong);
	cursor: pointer;
	list-style: none;
}

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

.accordion > summary:hover {
	background-color: var(--grey-100);
}

.accordion > summary .icon {
	flex: none;
	transition: transform var(--dur) var(--ease);
}

.accordion[open] > summary .icon {
	transform: rotate(180deg);
}

.accordion__body {
	padding: 0 var(--space-s) var(--space-s);
	color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
 * 6. Tables
 * ----------------------------------------------------------------------- */

.table-wrap {
	overflow-x: auto;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
}

.table-wrap:focus-visible {
	outline: 3px solid var(--color-focus);
}

/* Table rows are dense UI, at 15px. */
table {
	width: 100%;
	font-size: var(--step-ui);
	font-variant-numeric: tabular-nums;
}

caption {
	padding: var(--space-2xs) var(--space-s);
	font-size: var(--step--1);
	color: var(--color-text-muted);
	text-align: left;
}

th,
td {
	padding: var(--space-xs) var(--space-s);
	text-align: left;
	border-bottom: 1px solid var(--color-border);
}

thead th {
	background-color: var(--grey-100);
	font-family: var(--font-heading);
	font-size: var(--step--1);
	font-weight: 700;
	white-space: nowrap;
}

/*
 * Zebra in the canvas cream rather than grey-100. On a warm page a cool grey
 * band reads as a different surface; cream reads as the same page, which is
 * the quieter result and the one a long comparison table needs.
 */
tbody tr:nth-child(even) {
	background-color: var(--cream-50);
}

tbody tr:last-child td {
	border-bottom: 0;
}

/* --------------------------------------------------------------------------
 * 7. Breadcrumb
 * ----------------------------------------------------------------------- */

.breadcrumb {
	padding-block: var(--space-s);
	font-size: var(--step--1);
}

.breadcrumb ol {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

.breadcrumb li {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	color: var(--color-text-muted);
}

.breadcrumb a {
	color: var(--color-text-muted);
	text-decoration: none;
}

.breadcrumb a:hover {
	color: var(--ink);
	text-decoration: underline;
}

.breadcrumb [aria-current="page"] {
	color: var(--ink);
	font-weight: 500;
}

.breadcrumb .icon {
	width: 0.9em;
	height: 0.9em;
	color: var(--grey-400);
}

/* --------------------------------------------------------------------------
 * 8. Pagination
 * ----------------------------------------------------------------------- */

.pagination {
	margin-top: var(--space-l);
}

.pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-3xs);
	min-width: 44px;
	min-height: 44px;
	padding-inline: var(--space-xs);
	font-family: var(--font-heading);
	font-weight: 700;
	color: var(--ink);
	text-decoration: none;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-pill);
}

.pagination .page-numbers:hover {
	background-color: var(--azure-100);
}

.pagination .page-numbers.current {
	background-color: var(--ink);
	border-color: var(--ink);
	color: var(--white);
}

.pagination .page-numbers.dots {
	border-color: transparent;
}

/* The prev control reuses the chevron-right symbol, mirrored. */
.pagination .icon--prev {
	transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
 * 9. Stats strip
 * ----------------------------------------------------------------------- */

/*
 * One stat tile, shared by the home market band, the place market snapshot,
 * the place facts box and the listing key facts. The figure sits in the body
 * face at reading size: it is a number to be read next to its label, not a
 * display headline, and the old heading-face treatment made three short figures
 * shout across the page.
 *
 * The `--tile-*` tokens are the one description of a stat tile on the site. Any
 * grid that wants the same treatment reads those rather than picking its own
 * numbers, so the home band, the market snapshot and the facts box stay one
 * family.
 */

.stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
	gap: var(--space-2xs);
	margin: 0;
	padding: 0;
	list-style: none;
	background-color: transparent;
	text-align: start;
}

/*
 * The markup writes the figure before its label; `order` puts the label on top
 * without asking every template that prints a stat to be rewritten.
 */
.stats > li,
.stats > div {
	display: flex;
	flex-direction: column;
	padding: var(--tile-pad);
	background-color: var(--tile-bg);
	border: var(--tile-border);
	border-radius: var(--tile-radius);
}

.stats__value {
	display: block;
	order: 2;
	font-family: var(--font-body);
	font-size: var(--step-0);
	font-weight: 500;
	line-height: 1.4;
	color: var(--navy-900);
	overflow-wrap: anywhere;
	text-wrap: pretty;
}

.stats__label {
	display: block;
	order: 1;
	margin-top: 0;
	margin-bottom: var(--space-3xs);
	font-size: var(--step--2);
	line-height: 1.35;
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	color: var(--grey-700);
}

/* --------------------------------------------------------------------------
 * 10. CTA band
 * ----------------------------------------------------------------------- */

.cta-band {
	padding-block: var(--block-y);
	background-color: var(--navy-900);
	color: var(--white);
}

.cta-band__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-m);
}

.cta-band__text {
	max-width: 48ch;
}

.cta-band h2 {
	font-size: var(--step-3);
	color: var(--white);
}

.cta-band p {
	margin-top: var(--space-2xs);
	color: rgb(255 255 255 / 80%);
}

.cta-band__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

/* --------------------------------------------------------------------------
 * 11. Notice
 * ----------------------------------------------------------------------- */

.notice-box {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2xs);
	padding: var(--space-s);
	background-color: var(--color-bg);
	border-left: 4px solid var(--azure-600);
	border-radius: var(--radius-m);
}

.notice-box--error {
	border-left-color: var(--coral-700);
}

.notice-box--success {
	border-left-color: var(--whatsapp-dark);
}

.notice-box .icon {
	margin-top: 0.25em;
	color: inherit;
}

/* --------------------------------------------------------------------------
 * 12. Misc content
 * ----------------------------------------------------------------------- */

.entry-header {
	padding-block: var(--space-m) var(--space-s);
}

.entry-meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s);
	margin-top: var(--space-2xs);
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

.entry-thumb {
	margin-bottom: var(--space-m);
	overflow: hidden;
	border-radius: var(--radius-l);
}

.wp-caption,
figure {
	margin: 0;
}

figcaption,
.wp-caption-text {
	margin-top: var(--space-2xs);
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

.alignwide {
	max-width: var(--wide-width);
	margin-inline: auto;
}

.alignfull {
	max-width: none;
}

.alignleft {
	float: left;
	margin: 0 var(--space-m) var(--space-s) 0;
}

.alignright {
	float: right;
	margin: 0 0 var(--space-s) var(--space-m);
}

.aligncenter {
	margin-inline: auto;
}

/* --------------------------------------------------------------------------
 * 14. Phase 6: page furniture shared by the site pages
 * ----------------------------------------------------------------------- */

.page-hero {
	padding-block: var(--space-s) var(--block-y);
	background-color: var(--color-bg);
}

.page-hero h1 {
	max-width: var(--measure-heading);
	margin-block-start: var(--space-2xs);
}

.page-hero__lead {
	max-width: var(--measure);
	margin-block-start: var(--head-gap);
	font-size: var(--step-1);
	line-height: 1.5;
	color: var(--grey-700);
}

.page-hero__links {
	margin-block-start: var(--space-s);
	font-size: var(--step--1);
}

.page-hero__links a {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
}

.page-section {
	margin-block-start: var(--block-y);
	scroll-margin-block-start: calc(var(--header-height) + var(--space-s));
}

.page-section > h2 {
	margin-block-end: var(--head-gap);
}

.page__layout,
.service__layout {
	max-width: var(--wide-width);
	padding-block: var(--space-m) var(--block-y);
}

.page__layout--narrow {
	max-width: 48rem;
}

/*
 * The sections inside a layout already space themselves with .page-section, so
 * the layout itself adds nothing; the first one opens flush with the top of the
 * column.
 */
.page__layout > .page-section:first-child,
.service__layout > .page-section:first-child,
.page__main > .page-section:first-child {
	margin-block-start: 0;
}

/* --------------------------------------------------------------------------
 * 15. Content beside a sticky enquiry form
 *
 * Content left, form right, and on a desktop the card stays under the header
 * while the page scrolls. Below 900px the columns collapse, the card falls in
 * after the content, and the sticky bar in the footer offers the way to it.
 * ----------------------------------------------------------------------- */

.form-aside {
	margin-block-start: var(--block-y);
}

@media (width >= 900px) {
	.page__layout--form,
	.service__layout--form {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(20rem, 24rem);
		gap: var(--space-xl);
		align-items: start;
		max-width: var(--wide-width);
	}

	.form-aside {
		position: sticky;
		inset-block-start: calc(var(--header-height) + 1rem);
		margin-block-start: 0;
	}
}

.form-card {
	padding: var(--card-pad);
	background-color: var(--color-bg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
	box-shadow: var(--shadow-1);
	font-size: var(--step-0);
	line-height: 1.5;
}

.form-card__title {
	margin: 0;
	font-size: var(--step-2);
	line-height: var(--lh-heading);
	letter-spacing: 0;
}

.form-card__note {
	margin: var(--space-3xs) 0 var(--space-s);
	font-size: var(--step--1);
	color: var(--color-text-muted);
}

/* Section heads that carry a link on the right. */
.section__head--row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s) var(--space-m);
	align-items: flex-end;
	justify-content: space-between;
}

.section__lead {
	max-width: var(--measure);
	margin-block-start: var(--head-gap);
	color: var(--grey-700);
}

.section__link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	font-family: var(--font-heading);
	font-weight: 700;
	white-space: nowrap;
}

/* Lists of links used on the static guides, the 404 and the reviews page. */
.link-list {
	display: grid;
	gap: var(--space-2xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

.link-list a {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
}

/* Stats with a source note under each figure. */
.stats__note {
	display: block;
	order: 3;
	margin-top: var(--space-3xs);
	font-size: var(--step--2);
	line-height: 1.4;
	color: var(--grey-700);
}

/* Testimonials. */
.testimonials {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
	gap: var(--grid-gap);
}

.testimonial {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	margin: 0;
	padding: var(--card-pad);
	background-color: var(--grey-100);
	border-radius: var(--radius-l);
}

.testimonial__rating {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	margin: 0;
	font-size: var(--step--1);
	color: var(--grey-700);
}

.testimonial__rating .icon {
	color: var(--coral-700);
}

.testimonial blockquote {
	margin: 0;
	padding: 0;
	border: 0;
}

.testimonial blockquote p {
	margin: 0;
}

.testimonial figcaption {
	margin-top: auto;
	font-family: var(--font-heading);
	font-weight: 700;
	color: var(--ink);
}

.testimonial__meta {
	display: block;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: var(--step--1);
	color: var(--grey-700);
}

/* Name, address, phone block. */
.nap__list {
	display: grid;
	gap: var(--space-s);
	margin: 0;
}

.nap__list > div {
	display: grid;
	gap: var(--space-3xs);
}

.nap__list dt {
	font-size: var(--step--1);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	color: var(--grey-700);
}

.nap__list dd {
	margin: 0;
}

.nap__list address {
	font-style: normal;
}

.nap__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
	margin-top: var(--space-s);
}

/* Site search results, grouped by what each result is. */
.search-group {
	margin-block-start: var(--block-y);
}

.search-group:first-child {
	margin-block-start: 0;
}

.search-group__count {
	display: inline-block;
	margin-inline-start: var(--space-2xs);
	padding: 2px 10px;
	font-family: var(--font-body);
	font-size: var(--step--1);
	font-weight: 500;
	color: var(--grey-700);
	background-color: var(--grey-100);
	border-radius: var(--radius-pill);
	vertical-align: middle;
}

/* --------------------------------------------------------------------------
 * 18. Section eyebrow
 *
 * A category word above a heading. Two lines, learned in two scrolls: what
 * this block is, then what it says.
 * ----------------------------------------------------------------------- */

.section-eyebrow {
	margin-block-end: var(--space-2xs);
	font-family: var(--font-heading);
	font-size: var(--step--2);
	font-weight: 700;
	line-height: var(--lh-ui);
	text-transform: uppercase;
	letter-spacing: var(--tracking-eyebrow);
	color: var(--azure-700);
}

.on-dark .section-eyebrow {
	color: var(--azure-100);
}

/* --------------------------------------------------------------------------
 * 19. Price
 *
 * One treatment everywhere: lowercase "from", then AED and the figure with a
 * comma and tabular numerals, so a price column cannot jitter and a package
 * price can be read against a rent figure without re-reading.
 * ----------------------------------------------------------------------- */

.price {
	display: block;
	font-family: var(--font-heading);
	font-size: var(--step-4);
	font-weight: 700;
	line-height: var(--lh-tight);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--tracking-tight);
	color: var(--navy-900);
}

.price__from {
	display: block;
	font-family: var(--font-body);
	font-size: var(--step--1);
	font-weight: 500;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
	color: var(--grey-700);
}

.price__note {
	margin-block-start: var(--space-3xs);
	font-size: var(--step--1);
	color: var(--grey-700);
}

/* --------------------------------------------------------------------------
 * 20. Specification list
 *
 * Ruled rows rather than bullets. A specification is a document, and rows
 * that align across two columns read like one.
 * ----------------------------------------------------------------------- */

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

.spec-list li {
	display: flex;
	gap: var(--space-xs);
	align-items: baseline;
	padding-block: var(--space-xs);
	font-size: var(--step-ui);
	line-height: var(--lh-ui);
	border-block-end: 1px solid var(--color-border);
}

.spec-list--check li .icon {
	flex: 0 0 auto;
	width: 1.15em;
	height: 1.15em;
	color: var(--azure-600);
	transform: translateY(0.15em);
}

.spec-list--muted li {
	color: var(--grey-700);
}

/* --------------------------------------------------------------------------
 * 21. Mood card
 *
 * The one card variant with no border and no surface: the image is the card.
 * Used where a picture carries the meaning and a box would only get in the
 * way. See docs/brand.md section 6.
 * ----------------------------------------------------------------------- */

.card--mood {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	transition: none;
}

.card--mood:hover,
.card--mood:has(:focus-visible) {
	border-color: transparent;
	box-shadow: none;
	transform: none;
}

.card--mood .card__media {
	aspect-ratio: 16 / 10;
	border-radius: var(--radius-l);
	background-color: var(--color-surface);
}

.card--mood .card__media img {
	transition: transform var(--dur-slow) var(--ease);
}

.card--mood:hover .card__media img {
	transform: scale(1.04);
}

.card--mood .card__title {
	margin: 0;
	font-size: var(--step-1);
	max-width: none;
}

.card--mood .card__excerpt {
	max-width: 34ch;
	font-size: var(--step--1);
	line-height: var(--lh-body);
}

.swatches {
	display: flex;
	gap: var(--space-3xs);
	margin: 0;
	padding: 0;
	list-style: none;
}

.swatches li {
	width: 24px;
	height: 24px;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-pill);
}

/* --------------------------------------------------------------------------
 * 22. Comparison table
 *
 * A tiered product compared line by line. The first column stays put while
 * the figures scroll, and a tick or a dash carries a visually hidden word so
 * the meaning does not depend on the glyph.
 * ----------------------------------------------------------------------- */

.compare {
	min-width: 40rem;
}

.compare th,
.compare td {
	vertical-align: top;
}

.compare tbody th {
	position: sticky;
	inset-inline-start: 0;
	z-index: 1;
	font-family: var(--font-body);
	font-size: var(--step--1);
	font-weight: 600;
	background-color: var(--color-bg);
	border-inline-end: 1px solid var(--color-border);
}

.compare tbody tr:nth-child(even) th {
	background-color: var(--cream-50);
}

.compare td {
	font-variant-numeric: tabular-nums;
}

.compare thead th:not(:first-child) {
	font-size: var(--step-ui);
}

.compare .icon {
	width: 1.15em;
	height: 1.15em;
	color: var(--azure-600);
}

.compare__absent {
	color: var(--grey-400);
}

/* --------------------------------------------------------------------------
 * 23. Section heading row
 *
 * Heading left, ghost link and carousel arrows right, on one line from 768px.
 * ----------------------------------------------------------------------- */

.section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-s) var(--space-l);
	margin-bottom: var(--space-m);
}

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

.section-head__title {
	margin: 0;
}

.section-head__lead {
	max-width: 56ch;
	margin-top: var(--head-gap);
	color: var(--color-text-muted);
}

.section-head__aside {
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
}

.section-head__arrows {
	display: flex;
	gap: var(--space-3xs);
}

.section-head__arrows[hidden] {
	display: none;
}

.carousel__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	color: var(--ink);
	background-color: var(--white);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-pill);
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		opacity var(--dur-fast) var(--ease);
}

.carousel__arrow:hover:not(:disabled) {
	background-color: var(--azure-100);
	border-color: var(--azure-100);
	color: var(--azure-700);
}

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

.carousel__arrow .icon {
	width: 1.15em;
	height: 1.15em;
}

.carousel__arrow .icon--prev {
	transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
 * 24. Carousel track
 *
 * A scroll-snap row at every width. It scrolls with a finger or a trackpad on
 * its own; the arrows in the heading row are an addition, not the mechanism.
 * ----------------------------------------------------------------------- */

.carousel {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(78vw, 1fr);
	gap: var(--grid-gap);
	margin-inline: calc(var(--gutter) * -1);
	padding-inline: var(--gutter);
	padding-block-end: var(--space-2xs);
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.carousel::-webkit-scrollbar {
	display: none;
}

.carousel > * {
	scroll-snap-align: start;
}

@media (width >= 640px) {
	.carousel {
		grid-auto-columns: minmax(20rem, 1fr);
	}
}

@media (width >= 1024px) {
	.carousel {
		grid-auto-columns: minmax(22rem, 1fr);
	}
}

/* --------------------------------------------------------------------------
 * 25. Owner CTA
 *
 * The one block on the site addressed to the person who owns the property
 * rather than the person looking for one. Three sizes of the same message: a
 * band on a page, a card in a sidebar, a strip in a list of routes.
 *
 * The band is a pale azure panel rather than the navy CTA band, because most
 * of the pages it appears on already carry the navy band at the foot and two
 * dark panels in one scroll read as a billboard.
 * ----------------------------------------------------------------------- */

.owner-cta--band {
	display: block;
	padding: var(--space-l) var(--space-l);
	background-color: var(--azure-100);
	border-radius: var(--radius-l);
}

.owner-cta--band .owner-cta__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-m) var(--space-l);
}

.owner-cta--band .owner-cta__text {
	max-width: 46ch;
}

.owner-cta__title {
	max-width: var(--measure-heading);
	margin: 0;
	font-size: var(--step-3);
}

.owner-cta__lead {
	margin-top: var(--space-2xs);
	color: var(--color-text-muted);
	text-wrap: pretty;
}

.owner-cta__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

/* The compact card, for an enquiry column or a sidebar. */
.owner-cta--card {
	display: block;
	margin-top: var(--space-m);
	padding: var(--card-pad);
	background-color: var(--color-bg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-l);
}

.owner-cta--card .owner-cta__title {
	font-size: var(--step-2);
}

.owner-cta--card .owner-cta__lead {
	font-size: var(--step--1);
}

.owner-cta--card .owner-cta__actions {
	display: grid;
	gap: var(--space-2xs);
	margin-top: var(--space-s);
}

/* One line and two text links, under a list of routes. */
.owner-cta--strip {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-2xs) var(--space-m);
	margin-top: var(--space-l);
	padding-top: var(--space-s);
	border-top: 1px solid var(--color-border);
	text-align: start;
}

.owner-cta__line {
	max-width: 52ch;
	margin: 0;
	color: var(--color-text-muted);
}

.owner-cta__links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s);
	margin: 0;
	font-weight: 500;
}

/* --------------------------------------------------------------------------
 * 26. Process steps
 *
 * The numbered steps printed by template-parts/service/process.php. Moved here
 * from service.css on 2026-09-30: the part is also printed on ordinary pages
 * (/list-your-property/), which load page.css, and there it had no styling
 * and its headings sat flush against the paragraph above. The deep-band
 * variant stays in service.css.
 * ----------------------------------------------------------------------- */

.process__list {
	display: grid;
	gap: var(--space-m);
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: wh-step;
}

.process__step {
	position: relative;
	padding-inline-start: 3.25rem;
	counter-increment: wh-step;
}

.process__step::before {
	content: counter(wh-step);
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	font-family: var(--font-heading);
	font-weight: 700;
	color: var(--white);
	background-color: var(--navy-900);
	border-radius: var(--radius-pill);
}

.process__step h3 {
	font-size: var(--step-1);
	line-height: 2.25rem;
}

.process__step p {
	margin-top: var(--space-3xs);
	color: var(--grey-700);
}