/*
Theme Name: Softouch V2 — JS Web Design Services
Theme URI: https://junsanchez.com
Author: JS Web Design Services
Author URI: https://junsanchez.com
Description: Child theme for Softouch Property Development Corporation. Presentation layer only.
Template: hello-elementor
Version: 1.1.0
License: GPL-2.0-or-later
Text Domain: softouch-v2
*/

/* ==========================================================================
   DECORATION LAYER

   Everything here is ambient decoration from the approved Figma design that
   Elementor's global-class editor cannot express: pseudo-elements and the
   [open] state. The class API silently DISCARDS a whole style that contains
   a pseudo-element, so these cannot live as global classes.

   Structural and visual styling belongs in Elementor global classes, not
   here. Only add a rule to this file when the class editor genuinely
   cannot express it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The sticky offset

   Every sticky column on the site clears the fixed masthead by the same amount.
   The masthead is 73px, so 120px leaves a 47px gap beneath it.

   The admin bar is the part that is easy to miss: it is 32px of fixed chrome
   that only logged-in users see, so a single hardcoded offset looks right to a
   visitor and sits almost flush against the header for whoever is reviewing the
   page signed in. The token absorbs that difference, and both cases land on the
   same 47px gap.

   Only desktop needs it — every sticky column on the site unsticks below 1024,
   where the admin bar stops being fixed anyway.
   -------------------------------------------------------------------------- */
:root {
	--sticky-offset: 120px;
}

body.admin-bar {
	--sticky-offset: 152px;
}

/* Bands establish a stacking context so decoration sits behind content. */
.elementor .page-section,
.elementor .page-section-feature,
.elementor .page-section-tall,
.elementor .contact-cta.contact-cta,
.elementor .page-footer {
	position: relative;
	isolation: isolate;
}

/* Decoration bleeds past the band edge by design (Figma clips it at the frame).
   `overflow-x: clip` contains it WITHOUT creating a scroll container, so the
   sticky columns in Why Choose and FAQ keep working. `overflow: hidden` would
   silently break them. */
.elementor .page-section,
.elementor .page-section-feature,
.elementor .page-section-tall,
.elementor .contact-cta.contact-cta,
.elementor .page-footer {
	overflow-x: clip;
	overflow-y: visible;
}

/* Content always rides above the decoration. */
.elementor .section-inner,
.elementor .contact-cta__layout {
	position: relative;
	z-index: 1;
}

/* --------------------------------------------------------------------------
   Decoration — Brand Glow
   Figma: a 720px radial wash bled off the top-left of every band.

   `contact-cta` was left out of this list because the Home get-in-touch band
   used to be a photograph under a navy wash, where the glow was invisible. The
   band is white now (Figma revision, 2026-10-05) and the glow is the only
   decoration left on it, so it has to be listed — Figma node 18:54,
   `Decoration — Brand Glow`, 720x720 at the band's top-left corner.
   -------------------------------------------------------------------------- */
.elementor .page-section::after,
.elementor .page-section-feature::after,
.elementor .page-section-tall::after,
.elementor .contact-cta.contact-cta::after {
	content: "";
	position: absolute;
	top: -150px;
	left: -200px;
	z-index: 0;
	width: 720px;
	height: 720px;
	pointer-events: none;
	background-image: radial-gradient(
		circle closest-side,
		rgba(76, 198, 232, 0.18),
		rgba(76, 198, 232, 0) 70%
	);
}

/* The property detail page's bands are FLAT. Measured off Figma node 610:14 on
   2026-10-06: the Nearby Landmarks band renders #FFFFFF edge to edge, and a scan
   down the whole 12,554px frame finds four ground colours accounting for 94% of
   every row — white, two pale blues and a warm cream — with no gradient spread
   at all. A radial wash would leave hundreds of intermediate values behind it.

   The build was painting the glow over them: measured #F5FAFD at the band's left
   edge against #FFFFFF in the middle, which is the wash, not the ground.

   The glow itself is not wrong — it is Figma node 18:54 from the site-wide
   system, and it stays on every other template. It is simply not in THIS page's
   design, so it comes off the bands this template owns. */
.elementor .page-section[class*="community-"]::after {
	content: none;
}

/* --------------------------------------------------------------------------
   Decoration — Column Rules
   Figma: faint vertical hairlines on the 6-column grid, on selected bands.
   Applied via the `has-column-rules` marker class in Elementor.
   -------------------------------------------------------------------------- */
.elementor .has-column-rules::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 50%;
	z-index: 0;
	width: 100%;
	max-width: 1248px;
	transform: translateX(-50%);
	pointer-events: none;
	background-image: repeating-linear-gradient(
		to right,
		rgba(11, 16, 32, 0.055) 0 1px,
		rgba(0, 0, 0, 0) 1px 208px
	);
}

/* Reversed for the dark bands (footer, Milestones, Testimonials). */
.elementor .page-footer.has-column-rules::before,
.elementor .section-ink.has-column-rules::before {
	background-image: repeating-linear-gradient(
		to right,
		rgba(255, 255, 255, 0.07) 0 1px,
		rgba(0, 0, 0, 0) 1px 208px
	);
}

/* --------------------------------------------------------------------------
   FAQ accordion indicator
   Native <details>/<summary>; Figma shows + closed and − open.
   -------------------------------------------------------------------------- */
.elementor .faq-item__header {
	list-style: none;
}

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

.elementor .faq-item__header::after {
	content: "+";
	flex: none;
	font-family: Poppins, sans-serif;
	font-size: 26px;
	font-weight: 400;
	line-height: 1;
	color: #147E9F;
	transition: color 0.15s ease;
}

.elementor details[open] > .faq-item__header::after {
	content: "\2212"; /* true minus sign, not a hyphen */
}

.elementor .faq-item__header:hover::after {
	color: #0B1020;
}

/* --------------------------------------------------------------------------
   Milestones — the rail and dots are now real elements in Elementor
   (`milestone-rail`, `milestone-dot`), matching the Figma structure: a
   full-width 2px Brand Sweep gradient with the dots sitting 32px below it at
   the top of each column, NOT on the rail. Nothing needed here.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Testimonials slider
   Dot nav is built by assets/js/testimonial-slider.js from the slide count,
   so adding a Testimonial in the admin needs no template change. Positioned
   to sit at the right of the attribution row, as the design has it.
   -------------------------------------------------------------------------- */
.elementor .testimonial-slider {
	position: relative;
}

/* The loop layout may ship its own grid; the track must stay a single row. */
.elementor .testimonial-slider__track {
	display: flex !important;
	grid-template-columns: none !important;
	flex-wrap: nowrap;
}

.elementor .testimonial-slider__nav {
	position: absolute;
	inset-inline-end: 0;
	inset-block-end: 18px;
	z-index: 2;
	display: flex;
	align-items: center;
	gap: 8px;
}

.elementor .testimonial-slider__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background-color: rgba(255, 255, 255, 0.35);
	cursor: pointer;
	transition: width 0.25s ease, background-color 0.25s ease;
}

.elementor .testimonial-slider__dot:hover {
	background-color: rgba(255, 255, 255, 0.6);
}

.elementor .testimonial-slider__dot.is-active {
	width: 24px;
	background-color: #48C6E9;
}

.elementor .testimonial-slider__dot:focus-visible {
	outline: 2px solid #8FDCF2;
	outline-offset: 3px;
}

/* Leave room for the nav so it never collides with the attribution text. */
.elementor .testimonial-slider .testimonial__attribution {
	padding-inline-end: 96px;
}

/* Without JS the track scrolls instead of hiding the other testimonials. */
.elementor .testimonial-slider:not(.is-enhanced) .testimonial-slider__track {
	overflow-x: auto;
	scroll-snap-type: x mandatory;
}

.elementor .testimonial-slider:not(.is-enhanced) .testimonial-slider__slide {
	scroll-snap-align: start;
}

@media (max-width: 767px) {
	.elementor .testimonial-slider__nav {
		inset-block-end: -8px;
	}

	.elementor .testimonial-slider .testimonial__attribution {
		padding-inline-end: 0;
		padding-block-end: 28px;
	}
}

/* --------------------------------------------------------------------------
   Homebuyer's Journey — number hover
   Figma shows step 01 in its hover state; the resting colour for every step is
   the muted grey. Hovering anywhere on the row lifts its number to brand blue,
   which needs a descendant selector the global-class editor cannot express.
   :focus-within keeps it reachable by keyboard once the rows become links.
   -------------------------------------------------------------------------- */
.elementor .journey-row:hover .journey-number,
.elementor .journey-row:hover .journey-number-alt,
.elementor .journey-row:focus-within .journey-number,
.elementor .journey-row:focus-within .journey-number-alt {
	color: #354B8E;
}

@media (hover: none) {
	/* No hover on touch — leave every number at its resting colour. */
	.elementor .journey-row:hover .journey-number,
	.elementor .journey-row:hover .journey-number-alt {
		color: #6B7285;
	}
}

/* --------------------------------------------------------------------------
   Financing Options — panel hover
   Figma shows panel 02 in its hover state; every panel rests white with dark
   text and lifts to the ink gradient with reversed text on hover. The text
   colours need descendant selectors, so they live here rather than in a
   global class. Scoped under .financing-panel so the shared heading-4 /
   body-small classes are only affected inside this component.
   -------------------------------------------------------------------------- */
.elementor .financing-panel {
	transition: background-color 0.25s ease, background-image 0.25s ease;
}

.elementor .financing-panel:hover,
.elementor .financing-panel:focus-within {
	background-color: #22305C;
	background-image: linear-gradient(180deg, #22305C 0%, #3D56A6 100%);
}

.elementor .financing-panel:hover .heading-4,
.elementor .financing-panel:focus-within .heading-4 {
	color: #FFFFFF;
}

.elementor .financing-panel:hover .body-small,
.elementor .financing-panel:focus-within .body-small {
	color: #FFFFFF;
	opacity: 0.82;
}

.elementor .financing-panel:hover .financing-panel__number,
.elementor .financing-panel:focus-within .financing-panel__number {
	color: #8FDCF2;
}

.elementor .financing-panel:hover .financing-panel__tag,
.elementor .financing-panel:focus-within .financing-panel__tag {
	background-color: rgba(255, 255, 255, 0.18);
	color: #FFFFFF;
}

@media (hover: none) {
	/* No hover on touch — every panel stays in its resting state. */
	.elementor .financing-panel:hover {
		background-color: #FFFFFF;
		background-image: none;
	}

	.elementor .financing-panel:hover .heading-4 {
		color: #0B1020;
	}

	.elementor .financing-panel:hover .body-small {
		color: #6B7285;
		opacity: 1;
	}

	.elementor .financing-panel:hover .financing-panel__number {
		color: #147E9F;
	}

	.elementor .financing-panel:hover .financing-panel__tag {
		background-color: #F0FBFE;
		color: #147E9F;
	}
}

/* --------------------------------------------------------------------------
   News & Events rows
   The row is the click target, so hovering anywhere on it tints the title.
   The `news-row__title` global class carries the same colour on its own
   :hover; this rule only widens the trigger area, which the class API
   cannot express (descendant selector).
   -------------------------------------------------------------------------- */
@media (hover: hover) {

	.elementor .news-row:hover .news-row__title,
	.elementor .news-row:focus-within .news-row__title {
		color: #354B8E;
	}
}

/* --------------------------------------------------------------------------
   Developments grid (collection loop over Location terms)
   Two things the global-class API cannot express: an nth-child rule for the
   feature card, and a generated counter for the 01/02/03 chapter marks.
   -------------------------------------------------------------------------- */
.elementor .development-loop__layout {
	counter-reset: development;
}

.elementor .development-loop__item {
	counter-increment: development;
}

/* First term is the tall feature card; the rest stack in the second column. */
@media (min-width: 768px) {

	.elementor .development-loop__item:first-child {
		grid-row: span 2;
	}
}

/* 01, 02, 03 — derived from position, so the numbering can never drift out of
   step with the content the loop actually returns. */
.elementor .development-loop__index::before {
	content: counter(development, decimal-leading-zero);
}

/* The card is an <a>; keep the heading and body colours from the link. */
.elementor .development-loop__card:hover .development-card__name {
	text-decoration: none;
}

/* --------------------------------------------------------------------------
   Site header (Elementor site part)
   The approved design overlays a transparent header on the homepage hero.
   Every other page has no hero behind it, so there the header has to become
   a solid band and stop overlapping the content.
   -------------------------------------------------------------------------- */
/* ==========================================================================
   THE MAGENTA BUTTON RESET

   hello-elementor's `reset.css` ships a theme colour that is not ours and
   paints it on EVERY button on the site:

     [type=button], [type=submit], button          border + text  #c36
     …:hover, …:focus                              background     #c36
     button:focus-visible                          4px white halo + black ring

   `:hover` gets noticed in review. `:focus` does not, because a button KEEPS
   focus after a mouse click — so a control turns magenta on the first click
   and stays magenta until something else is clicked. That is how it reached
   the gallery viewer's next-photo arrow.

   Corrected ONCE, here, at the source, rather than per component. Anything
   added later inherits the brand colour instead of the magenta, so this
   cannot come back in a part of the site nobody is looking at.
   ========================================================================== */

:root {
	--brand: #405BA9;
	--brand-ink: #32498A;
}

[type="button"],
[type="submit"],
button {
	border-color: var(--brand);
	color: var(--brand);
}

/* `a` carries the same #c36 in that reset. It stayed invisible for months
   because every link on this site sat inside an Elementor element that set
   its own colour — until the header nav became real anchors from a WordPress
   menu and the magenta came straight through. Anywhere this shows is a place
   nothing else had an opinion, and brand is the right answer there. */
a {
	color: var(--brand);
}

[type="button"]:hover,
[type="button"]:focus,
[type="submit"]:hover,
[type="submit"]:focus,
button:hover,
button:focus {
	background-color: var(--brand);
	color: #FFFFFF;
}

button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
	box-shadow: none;
	outline: 2px solid var(--brand);
	outline-offset: 2px;
}

:root {
	/* The bar's real height: padding 20 + logo 60 + padding 20 + 1px border.
	   It moved from 97 when the logo was enlarged (2026-10-05) — the hero top
	   padding is `calc(var(--masthead-height) + N)`, so leaving it behind would
	   put every hero's first line under the header. */
	--masthead-height: 101px;
}

/* The admin bar is fixed too, so a fixed masthead has to sit below it. */
body.admin-bar .elementor .site-masthead {
	top: 32px;
}

@media (max-width: 782px) {

	body.admin-bar .elementor .site-masthead {
		top: 46px;
	}
}

/* Transparent over the hero, solid once the page moves under it. The class is
   added by assets/js/site-nav.js; without JavaScript the header simply stays
   transparent, which is how the approved design shows it. */
.elementor .site-masthead {
	transition: background-color 220ms ease, box-shadow 220ms ease,
		border-color 220ms ease;
}

/* The band is painted on the header itself: flat white, no feather, no
   backdrop blur. An earlier pass faded the bottom edge with a masked
   pseudo-element; Jun asked for solid white with the drop shadow doing the
   separating, so the mask is gone and only the shadow below remains. */
/* ---------------------------------------------------------------------------
   THE WHITE HEADER

   Two states share one treatment: scrolled away from the top, and an interior
   page that has no hero for the header to sit over. Both are listed on every
   rule below — if a third solid state ever appears, add it to all of them.

   The header is built for a dark ground: the logo is the reversed lock-up, the
   nav is white and the burger bars are white. Every one of those has to invert
   on white, so the switch is five properties, not one.
   --------------------------------------------------------------------------- */

/* Everything that used to draw a hard bottom edge comes off: the flat
   background, the drop shadow under it, and the 1px hairline the
   `site-masthead` global class carries. The hairline stays while the header is
   transparent over a hero — that divider is in the approved design — and is
   dropped the moment the white band takes over. */
.elementor .site-masthead.is-scrolled,
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead {
	background: #FFFFFF;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
	/* The 1px hairline the `site-masthead` global class carries was drawn for a
	   dark ground; the shadow replaces it. The hairline stays while the header
	   is transparent over a hero — that divider is in the approved design. */
	border-block-end-color: rgba(255, 255, 255, 0);
	/* A white bar over a white section has no edge at all — the heading below
	   it ran straight under the nav. Diffuse enough that there is no line
	   anywhere in it (28px blur against a -16px spread). */
	box-shadow: 0 12px 28px -16px rgba(11, 16, 32, 0.28);
}

/* The coloured lock-up, supplied by Jun as `logo/logo.png` (898x300) and
   installed here at 449x150 — 3x the largest size the header ever draws it
   (151x50 on phones), and the same 2.993 aspect ratio as the reversed mark, so
   `background-size: contain` swaps it with no change in geometry. */
.elementor .site-masthead.is-scrolled .site-logo,
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead .site-logo {
	background-image: url('assets/logo-colour.png');
}

/* Nav ink only inverts above the drawer breakpoint. At 1200px and below the
   nav is the off-canvas panel, which is dark in both states — flipping it
   there would put near-black links on a near-black drawer. */
@media (min-width: 1201px) {

	.elementor .site-masthead.is-scrolled .main-nav__link,
	body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead .main-nav__link {
		color: #0B1020;
	}

	.elementor .site-masthead.is-scrolled .main-nav__link:hover,
	.elementor .site-masthead.is-scrolled .main-nav__link:focus-within,
	body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead .main-nav__link:hover,
	body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead .main-nav__link:focus-within {
		color: #405BA9;
	}
}

/* The burger is on the bar itself, so it inverts at every width — except while
   the drawer is open, when it sits over the dark panel and goes back to white. */
/* No plate. The toggle has NO border — it never did; `border-width` computes
   to 0 and the theme states `border: 0`. What read as one was this 6% wash
   with a 2px radius sitting behind the bars: against a white header it draws
   a faint grey box and the eye calls that an outline. The bars are #0B1020 on
   #FFFFFF, so they need nothing behind them to be seen. Kept on the
   transparent header, where the bars sit over a photograph. */
.elementor .site-masthead.is-scrolled:not(.is-nav-open) .site-masthead__toggle,
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead:not(.is-nav-open) .site-masthead__toggle {
	background: transparent;
}

.elementor .site-masthead.is-scrolled:not(.is-nav-open) .site-masthead__toggle-bar,
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead:not(.is-nav-open) .site-masthead__toggle-bar {
	background: #0B1020;
}

/* The Enquire button is unchanged. `#48C6E9` is a saturated cyan that holds
   its shape against white, and its `#0B1020` label is 11.6:1 on it — the
   brand accent survives the swap, so it is the one element that does not
   need a white-ground variant. */

/* An interior page with no hero behind the header needs it solid from the
   start, with the content pushed clear of it. A page that opens with a
   full-bleed hero does not: there the header sits over the photograph and only
   takes a background once scrolled, exactly as the homepage does.

   EVERY hero class must be listed here. `page-hero-compact` was added for the
   secondary pages and missed this selector, so About, both Guides, News,
   Careers and Contact all fell into the "no hero" branch — solid header band,
   photograph pushed below it. If you add another hero variant, add it here. */
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor-location-main,
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .site-main,
/* `:not(.e-loop-item)` is load-bearing. A loop item's root carries the
   `elementor` class too, so on a page with no hero EVERY card in EVERY loop was
   getting `padding-block-start: var(--masthead-height)` — 101px of dead space
   above each one. It showed up as a huge gap under "More from Softouch". */
body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor:not(.elementor-location-header):not(.elementor-location-footer):not(.e-loop-item),
/* `search.php` is a plain template, not an Elementor document, so none of the
   selectors above reach it and its first line sat under the fixed bar. */
body.search .sresults {
	padding-block-start: var(--masthead-height);
}

@media (max-width: 767px) {

	:root {
		--masthead-height: 76px;
	}
}

/* --- Mobile navigation ---------------------------------------------------
   The toggle is injected by assets/js/site-nav.js; with JavaScript off the
   nav stays hidden exactly as it does now, so nothing regresses.
   -------------------------------------------------------------------------- */
.site-masthead__toggle {
	display: none;
	position: relative;
	z-index: 2;
	flex-direction: column;
	/* Without this the bars sit at flex-start and the icon reads 4px high
	   inside its own hit area. */
	justify-content: center;
	align-items: center;
	gap: 5px;
	width: 44px;
	height: 44px;
	padding: 10px;
	border: 0;
	border-radius: 2px;
	background: rgba(255, 255, 255, 0.12);
	cursor: pointer;
}

.site-masthead__toggle:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 2px;
}

.site-masthead__toggle-bar {
	display: block;
	width: 100%;
	height: 2px;
	border-radius: 2px;
	background: #FFFFFF;
	transition: transform 180ms ease, opacity 180ms ease;
}

/* The drawer takes over on tablet too. Measured: at 1085px four nav links
   still wrap to two lines; at 1185px they do not. The threshold sits on
   Elementor's own tablet_extra breakpoint. */
@media (max-width: 1200px) {

	.site-masthead__toggle {
		display: flex;
	}

	.site-masthead.is-nav-open .site-masthead__toggle-bar:nth-child(1) {
		transform: translateY(7px) rotate(45deg);
	}

	.site-masthead.is-nav-open .site-masthead__toggle-bar:nth-child(2) {
		opacity: 0;
	}

	.site-masthead.is-nav-open .site-masthead__toggle-bar:nth-child(3) {
		transform: translateY(-7px) rotate(-45deg);
	}
}

/* --------------------------------------------------------------------------
   Footer social row
   Only Facebook and the sales address are verified. Elementor renders a social
   mark without a URL as a plain div rather than an <a>, so hiding the non-links
   keeps the row honest: fill the field in Softouch → Contact Details and the
   icon reappears on its own.
   -------------------------------------------------------------------------- */
.elementor .social-row > *:not(a) {
	display: none;
}

/* --------------------------------------------------------------------------
   Hero clearance under the fixed masthead
   The header used to be a flex child of the hero, so it pushed this content
   down by its own height. Now that it is a fixed site part, the hero starts at
   the top of the viewport and slid under it. The original breathing room is
   kept and the masthead height added on top.

   Specificity beats Elementor's `.home-hero__body`, which loads after this
   stylesheet.
   -------------------------------------------------------------------------- */
body.home .elementor .home-hero__body {
	padding-block-start: calc(var(--masthead-height) + clamp(24px, 4vh, 72px));
}

@media (max-width: 1024px) {

	body.home .elementor .home-hero__body {
		padding-block-start: calc(var(--masthead-height) + 32px);
	}
}

@media (max-width: 767px) {

	body.home .elementor .home-hero__body {
		padding-block-start: calc(var(--masthead-height) + 24px);
	}
}

/* --------------------------------------------------------------------------
   Reveal on scroll
   Nothing is hidden until assets/js/site-enhance.js adds `js-reveal` to <html>,
   so with JavaScript off — or with reduced motion requested — every section
   renders normally and nothing can get stuck invisible.
   -------------------------------------------------------------------------- */
.js-reveal .will-reveal {
	opacity: 0;
	transform: translate3d(0, 18px, 0);
	will-change: opacity, transform;
}

.js-reveal .will-reveal.is-revealed {
	opacity: 1;
	transform: none;
	transition: opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1),
		transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
	will-change: auto;
}

/* Interactive polish: the small state changes that make the page feel settled
   rather than snapping between states. Deliberately narrow — a blanket
   `* { transition: all }` fights Elementor's own animations and costs paint. */
.elementor a,
.elementor .main-nav__link,
.elementor .footer-link,
.elementor .text-link,
.elementor .social-link,
.elementor .spec-chip,
.elementor .button-primary,
.elementor .button-secondary,
.elementor .button-accent,
.elementor .button-submit {
	transition: color 180ms ease, background-color 180ms ease, border-color 180ms ease,
		opacity 180ms ease, transform 180ms ease;
}

.elementor .development-loop__card,
.elementor .model-loop__card,
.elementor .faq-item__header,
.elementor .financing-panel,
.elementor .news-row {
	transition: background-color 220ms ease, box-shadow 220ms ease, transform 220ms ease;
}

@media (hover: hover) {

	.elementor .development-loop__card:hover,
	.elementor .model-loop__card:hover {
		transform: translate3d(0, -4px, 0);
		box-shadow: 0 10px 22px rgba(11, 16, 32, 0.12), 0 24px 56px rgba(11, 16, 32, 0.16);
	}
}

@media (prefers-reduced-motion: reduce) {

	.js-reveal .will-reveal,
	.js-reveal .will-reveal.is-revealed {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.elementor .development-loop__card:hover,
	.elementor .model-loop__card:hover {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   Compact masthead on scroll
   Resting: 24px block padding, 132x44 logo, 15px nav, 48px button -> 97px tall.
   Scrolled: roughly three-quarters of that -> about 62px, so more of the page
   stays visible without the header ever losing its hit areas.

   Every value is a transition target, so the shrink animates rather than
   snapping. Reduced motion keeps the smaller size but drops the animation.
   -------------------------------------------------------------------------- */
.elementor .site-masthead {
	transition: background-color 220ms ease, box-shadow 220ms ease,
		padding-block 220ms ease, border-color 220ms ease, color 220ms ease;
}

.elementor .site-masthead .site-logo,
.elementor .site-masthead .main-nav,
.elementor .site-masthead .main-nav__link,
.elementor .site-masthead .button-accent {
	transition: width 220ms ease, height 220ms ease, gap 220ms ease,
		font-size 220ms ease, padding 220ms ease, color 220ms ease,
		background-color 220ms ease;
}

.elementor .site-masthead.is-scrolled {
	padding-block: 12px;
}

.elementor .site-masthead.is-scrolled .site-logo {
	width: 105px;
	height: 35px;
}

.elementor .site-masthead.is-scrolled .main-nav {
	gap: 24px;
}

.elementor .site-masthead.is-scrolled .main-nav__link {
	font-size: 14px;
}

.elementor .site-masthead.is-scrolled .button-accent {
	padding-block: 9px;
	padding-inline: 18px;
	font-size: 14px;
}

@media (max-width: 1366px) {

	.elementor .site-masthead.is-scrolled .main-nav {
		gap: 18px;
	}
}

@media (max-width: 767px) {

	.elementor .site-masthead.is-scrolled {
		padding-block: 10px;
	}

	.elementor .site-masthead.is-scrolled .site-logo {
		width: 110px;
		height: 37px;
	}

	.site-masthead.is-scrolled .site-masthead__toggle {
		width: 38px;
		height: 38px;
		padding: 9px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .site-masthead,
	.elementor .site-masthead .site-logo,
	.elementor .site-masthead .main-nav,
	.elementor .site-masthead .main-nav__link,
	.elementor .site-masthead .button-accent {
		transition: none;
	}
}

/* ==========================================================================
   MOBILE REFINEMENTS
   ========================================================================== */

/* --- Header ---------------------------------------------------------------
   Mobile uses the icon on its own, not the full lock-up: at header size the
   "PROPERTY DEVELOPMENT CORP." strapline is an illegible smudge. The icon was
   cropped from the master logo and lives in the theme, so it moves with the
   code rather than depending on a media-library ID.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .site-masthead {
		gap: 12px;
	}

	.elementor .site-masthead .site-logo,
	.elementor .site-masthead.is-scrolled .site-logo {
		width: 40px;
		height: 42px;
		background-image: url('assets/img/softouch-icon-reversed.png');
		background-position: left center;
	}

	/* The white header needs the coloured icon, not the reversed one — with the
	   reversed mark the logo vanished completely on phones, since white artwork
	   on a white bar leaves nothing but the Enquire button and the burger. This
	   has to be repeated at this breakpoint because the desktop rule swaps in
	   the full lock-up, which is the wrong artwork here. */
	.elementor .site-masthead.is-scrolled .site-logo,
	body:not(.home):not(:has(.page-hero, .page-hero-compact)) .elementor .site-masthead .site-logo {
		background-image: url('assets/img/softouch-icon.png');
	}

	/* The wordmark heading is visually hidden, so the icon still has an
	   accessible name — nothing to restore here. */

}

/* Applies wherever the drawer is in charge, tablet included. */
@media (max-width: 1200px) {

	/* The nav is out of flow here, so `space-between` would spread the logo,
	   button and toggle across the whole bar. Pushing the button to the right
	   groups it with the toggle. */
	.elementor .site-masthead .button-accent {
		margin-inline-start: auto;
	}

	.site-masthead__toggle {
		background: none;
		width: 36px;
		height: 36px;
		padding: 6px 0;
	}

	.site-masthead.is-scrolled .site-masthead__toggle {
		width: 34px;
		height: 34px;
		padding: 5px 0;
	}

	/* …but NOT while the drawer is open. The bar compacts on scroll, which is
	   right for a bar; once the drawer is open this control is the panel's
	   close button and belongs on the panel's axis. At 34px its centre landed
	   at 338 against the chevrons' 337 — the right edges agreed, the glyphs
	   did not. Holding 36px also stops the X being a different size depending
	   on whether the reader had scrolled before opening the menu. */
	.site-masthead.is-scrolled.is-nav-open .site-masthead__toggle {
		width: 36px;
		height: 36px;
		padding: 6px 0;
	}
}

/* --- Gutters --------------------------------------------------------------
   Every band and card row sits on the same 20px mobile margin.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .page-section,
	.elementor .page-section-feature,
	.elementor .page-section-tall,
	.elementor .contact-cta.contact-cta,
	.elementor .page-footer,
	.elementor .home-hero__body,
	.elementor .site-masthead {
		padding-inline: 20px;
	}
}

/* --- Section headings -----------------------------------------------------
   "Seventeen years of" needs 311px at 32px but only has 287px, so it wrapped
   and the heading ran to three lines instead of the two its <br> intends.
   28px fits every first line on this page at 375px.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .display-m {
		font-size: 28px;
		line-height: 36px;
	}
}

/* --- Company milestones ---------------------------------------------------
   Year reduced ~10%: 40px -> 36px.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .milestone-item__year {
		font-size: 36px;
		line-height: 44px;
	}
}

/* --- Homebuyer's journey --------------------------------------------------
   The step number sits above its title on mobile and reads as a label rather
   than a display figure — smaller than the 19px title it introduces.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .journey-number,
	.elementor .journey-number-alt {
		order: -1;
		font-size: 13px;
		line-height: 18px;
		letter-spacing: 0.12em;
		margin-block-end: 4px;
	}
}

/* --- Testimonials ---------------------------------------------------------
   The attribution carries the divider rule, and the homeowner's name was
   sitting hard against it.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .testimonial__attribution.attribution-divider {
		padding-block-start: 20px;
	}
}

/* --- Section CTA below the cards -----------------------------------------
   On mobile the "View all communities" and "All news & events" links belong
   under the list they refer to, not stranded in the section header. The link
   is two levels deep, so `display: contents` promotes the header and its aside
   into the section's own column and `order` then places each part. The header's
   own gap is lost that way, so the spacing is restored explicitly.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .section-inner:has(.development-loop) > .section-head,
	.elementor .section-inner:has(.news-loop) > .section-head,
	.elementor .section-inner:has(.development-loop) .section-head__aside,
	.elementor .section-inner:has(.news-loop) .section-head__aside {
		display: contents;
	}

	.elementor .section-inner:has(.development-loop) > .section-head > .section-head__title,
	.elementor .section-inner:has(.news-loop) > .section-head > .section-head__title {
		order: 1;
	}

	.elementor .section-inner:has(.development-loop) .section-head__aside > .body-base,
	.elementor .section-inner:has(.news-loop) .section-head__aside > .body-base {
		order: 2;
		margin-block-start: 16px;
	}

	.elementor .section-inner:has(.development-loop) > .development-grid,
	.elementor .section-inner:has(.news-loop) > .news-index {
		order: 3;
	}

	.elementor .section-inner:has(.development-loop) .section-head__aside > .text-link,
	.elementor .section-inner:has(.news-loop) .section-head__aside > .text-link {
		order: 4;
		margin-block-start: 28px;
		align-self: flex-start;
	}
}

/* --------------------------------------------------------------------------
   Collection loop wrappers carry no padding of their own
   Elementor's `.e-con` base gives every container 10px of padding. A loop is
   three nested containers — loop, layout, item — so each card sat 30px inside
   its section's gutter. Nothing in these wrappers should add inset: spacing
   belongs to the section and to the card.
   -------------------------------------------------------------------------- */
.elementor [data-e-type="e-collection-loop"],
.elementor [data-e-type="e-collection-loop-layout"],
.elementor [data-e-type="e-collection-loop-item"] {
	padding: 0;
}

/* ==========================================================================
   MOBILE REFINEMENTS — SECOND PASS
   ========================================================================== */

/* The toggle is a <button>, so it inherits a UA background on press and a tap
   highlight on touch. Neither is wanted — the burger is three bare rules. */
.site-masthead__toggle,
.site-masthead__toggle:hover,
.site-masthead__toggle:focus,
.site-masthead__toggle:active,
.site-masthead__toggle[aria-expanded="true"] {
	background: none;
	box-shadow: none;
	-webkit-tap-highlight-color: transparent;
}

@media (max-width: 767px) {

	/* --- Section CTAs sit centred under the list they refer to --- */
	.elementor .section-inner:has(.development-loop) .section-head__aside > .text-link,
	.elementor .section-inner:has(.news-loop) .section-head__aside > .text-link {
		align-self: center;
		text-align: center;
	}

	/* --- About: the facts read before the prose --- */
	.elementor .about-panel {
		display: flex;
		flex-direction: column;
	}

	.elementor .about-panel > .eyebrow {
		order: 1;
	}

	.elementor .about-panel > .display-m {
		order: 2;
	}

	.elementor .about-panel > .fact-list {
		order: 3;
	}

	.elementor .about-panel > .about-panel__columns {
		order: 4;
	}

	/* --- Company milestones: a further 10%, 36px -> 32px --- */
	.elementor .milestone-item__year {
		font-size: 32px;
		line-height: 40px;
	}

	/* --- Featured house models: two up --- */
	.elementor .model-loop__layout {
		grid-template-columns: repeat(2, 1fr);
		gap: 12px;
	}

	.elementor .model-loop__card {
		height: 258px;
	}

	.elementor .model-loop__card .model-card__body {
		padding: 14px;
		gap: 6px;
	}

	.elementor .model-loop__card .model-card__title {
		font-size: 16px;
		line-height: 22px;
	}

	.elementor .model-loop__card .model-card__availability {
		font-size: 10px;
		line-height: 14px;
		padding: 3px 7px;
		inset-block-start: 12px;
		inset-inline-start: 12px;
	}

	.elementor .model-loop__card .model-card__specs {
		gap: 4px;
	}

	.elementor .model-loop__card .spec-chip {
		font-size: 10px;
		line-height: 15px;
		padding: 2px 6px;
	}

	/* --- Testimonials: pagination centred and easier to see --- */
	.testimonial-slider__nav {
		justify-content: center;
		gap: 10px;
		margin-block-start: 24px;
	}

	.testimonial-slider__dot {
		width: 9px;
		height: 9px;
	}

	/* --- FAQ heading, 5% down: 28px -> 27px --- */
	.elementor .faq-sticky .display-m {
		font-size: 27px;
		line-height: 35px;
	}

	/* --- Get in touch: description, then the form, then the details ---
	   The form is a sibling of the copy block, so `display: contents` promotes
	   the copy's children into the layout and `order` interleaves them. */
	.elementor .contact-cta__layout {
		display: flex;
		flex-direction: column;
	}

	.elementor .contact-cta__layout > .contact-cta__copy {
		display: contents;
	}

	.elementor .contact-cta__copy > .eyebrow-accent {
		order: 1;
	}

	.elementor .contact-cta__copy > .display-m {
		order: 2;
	}

	.elementor .contact-cta__copy > .body-lead {
		order: 3;
	}

	.elementor .contact-cta__layout > .enquiry-form {
		order: 4;
		margin-block-start: 28px;
	}

	.elementor .contact-cta__copy > .contact-details {
		order: 5;
		margin-block-start: 28px;
	}
}

/* ==========================================================================
   MOBILE NAVIGATION DRAWER
   Slides in from the right over a scrim, with the links staggering in behind
   it. `--nav-item-index` is set per item by site-nav.js, so the stagger does
   not care how many menu items there are.
   ========================================================================== */
.site-nav-scrim {
	position: fixed;
	inset: 0;
	z-index: 40;
	background: rgba(5, 7, 15, 0.55);
	opacity: 0;
	transition: opacity 320ms ease;
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
}

.site-nav-scrim.is-visible {
	opacity: 1;
}

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

@media (max-width: 1200px) {

	/* Beats the class API's `display: none` without !important. */
	.elementor .site-masthead .main-nav {
		display: flex;
		position: fixed;
		inset-block: 0;
		inset-inline-end: 0;
		z-index: 50;
		width: min(82vw, 316px);
		flex-direction: column;
		justify-content: flex-start;
		align-items: stretch;
		gap: 0;
		/* 20px, not 28. The site's mobile gutter is 20px — every band and card
		   row already sits on it — and so does the masthead above, which is
		   what puts the burger's centre at 337 on a 375px screen. At 28 the
		   drawer's controls sat on their own axis 10px inside the one the
		   close button uses, which reads as a misalignment because it is one.
		   One gutter down the whole right-hand side now. */
		padding: 104px 20px 40px;
		/* WHITE, WITH THE SITE'S OWN DECORATION — not a new one.

		   Both washes are `Decoration — Brand Glow`, Figma node 18:54: the same
		   `rgba(76, 198, 232, 0.18)` circle every page band already carries at
		   the top of this file. Two of them, at opposite corners, so the panel
		   reads as a piece of the site rather than a tinted sheet over it.

		   `closest-side` resolves against the background LAYER, so each layer
		   is sized explicitly — the shorthand cannot express that, which is why
		   these are listed longhand. */
		background-color: #FFFFFF;
		background-image:
			radial-gradient(circle closest-side, rgba(76, 198, 232, 0.18), rgba(76, 198, 232, 0) 70%),
			radial-gradient(circle closest-side, rgba(64, 91, 169, 0.10), rgba(64, 91, 169, 0) 70%);
		background-size: 520px 520px, 420px 420px;
		background-position: -170px -120px, right -130px bottom -90px;
		background-repeat: no-repeat, no-repeat;
		box-shadow: -24px 0 60px rgba(11, 16, 32, 0.18);
		overflow-y: auto;
		overscroll-behavior: contain;
		transform: translate3d(100%, 0, 0);
		visibility: hidden;
		transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1),
			visibility 0s linear 420ms;
	}

	.elementor .site-masthead.is-nav-open .main-nav {
		transform: translate3d(0, 0, 0);
		visibility: visible;
		transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.elementor .site-masthead .main-nav > * {
		padding-block: 15px;
		border-block-start: 1px solid rgba(11, 16, 32, 0.1);
		font-size: 17px;
		text-align: start;
		opacity: 0;
		transform: translate3d(22px, 0, 0);
		transition: opacity 360ms ease, transform 360ms cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.elementor .site-masthead .main-nav > *:first-child {
		border-block-start: 0;
	}

	.elementor .site-masthead.is-nav-open .main-nav > * {
		opacity: 1;
		transform: none;
		/* Items follow the panel in, one after the next. */
		transition-delay: calc(180ms + var(--nav-item-index, 0) * 55ms);
	}

	/* The toggle sits above the panel so the burger-to-cross stays reachable. */
	.elementor .site-masthead {
		z-index: 60;
	}

	/* `backdrop-filter` makes an element a containing block for its
	   position: fixed descendants, so while the scrolled masthead had it the
	   drawer was trapped inside the 77px header instead of filling the
	   viewport. Dropped while the drawer is open — the scrim covers the page
	   anyway, so the blur has nothing left to do. */
	.elementor .site-masthead.is-nav-open,
	.elementor .site-masthead.is-scrolled.is-nav-open {
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}

	/* Above the panel's z-index: 50, so the burger-turned-cross stays on top
	   of the drawer it closes. */
	.site-masthead__toggle {
		position: relative;
		z-index: 55;
	}

	/* THE DRAWER'S INK COMES FROM THE DRAWER, NOT FROM THE BAR.

	   Every nav-ink rule in this stylesheet is gated behind `min-width: 1201px`
	   — correctly, because below that the nav is this panel and inverting it
	   would put near-black links on near-black. But the rule that paints them
	   WHITE is scoped to `:not(.is-scrolled)`, for the bar. So scrolling the
	   page and then opening the drawer dropped the only colour the links had,
	   and they fell all the way back to the bare `a { color: var(--brand) }`:
	   #405BA9 on a #22305C→#0B1020 panel, which measures 2.00:1 at the light
	   end of the gradient and 2.96:1 at the dark end, against a 4.5:1 floor.

	   The drawer's ink is set here from the drawer's own state, not from the
	   bar's. White on the panel's lightest point is 12.8:1. */
	.elementor .site-masthead.is-nav-open .main-nav__link {
		color: #0B1020;
	}

	/* FIRST LEVEL ONLY: uppercase, at the inherited 17px.

	   Scoped to `.main-nav__item > .main-nav__link` — a direct child — so it
	   cannot reach the links inside an open mega panel. Those are the second
	   level and stay sentence case at 15px; setting them in caps too would
	   flatten the two levels into one and lose the thing the indent is doing.

	   Caps still need the tracking even at 17px: with `normal` spacing the
	   counters close up and "BUYER'S GUIDE" reads as one long word. 0.02em is
	   about a third of a pixel per character — enough to separate them without
	   the letters drifting apart. The size is left alone deliberately; caps
	   already read larger than sentence case at the same point size, which is
	   why 19px came out too heavy here. */
	.elementor .site-masthead .main-nav__item > .main-nav__link {
		text-transform: uppercase;
		letter-spacing: 0.02em;
	}

	/* The current page in brand blue — 6.4:1 on white, and the same mark the
	   bar itself uses above the drawer breakpoint. */
	.elementor .site-masthead.is-nav-open .main-nav__item.is-current > .main-nav__link {
		color: var(--brand);
	}

	/* The burger-turned-cross sits ON the white panel once it opens, so it
	   takes the panel's ink rather than the bar's. Without this it stays white
	   and vanishes the moment the drawer turns light — the same disappearing
	   act the search overlay pulled. */
	.elementor .site-masthead.is-nav-open .site-masthead__toggle-bar {
		background: #0B1020;
	}

}

/* --- Enquire: secondary to the logo, on phones only ---
   It was matching the icon logo's height and competing with it. Tablet keeps
   the full-size button, which sits comfortably beside the full lock-up. */
@media (max-width: 767px) {

	.elementor .site-masthead .button-accent,
	.elementor .site-masthead.is-scrolled .button-accent {
		/* The class sets an explicit height: 42px at this breakpoint, which is
		   the logo's height — padding alone could not shrink it. */
		height: auto;
		padding-block: 7px;
		padding-inline: 14px;
		font-size: 13px;
		line-height: 18px;
		border-radius: 3px;
	}

	/* ...and on phones it comes off the bar entirely. Four controls across a
	   375px header left the logo, a magnifier, a button and a burger fighting
	   for the same row. The enquiry route is not lost: the drawer now ends in
	   the four contact channels, and Contact Us is in the menu. */
	.elementor .site-masthead .button-accent {
		display: none;
	}

	/* The auto margin moves with it. It was on `.button-accent`, which is what
	   pushed the right-hand group over; with the button gone the search host
	   inherits the job, so the magnifier sits beside the burger instead of
	   stranded in the middle of the bar. */
	.elementor .site-masthead .site-search-host {
		margin-inline-start: auto;
	}

	/* Optical, not geometric: the magnifier's glyph is inset inside its box
	   while the burger's bars run the full width, so equal boxes read as a
	   gap. 4px closes it. */
	.elementor .site-masthead .site-search-host + .site-masthead__toggle,
	.elementor .site-masthead .site-search-host ~ .site-masthead__toggle {
		margin-inline-start: -4px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .site-masthead .main-nav,
	.elementor .site-masthead .main-nav > *,
	.site-nav-scrim {
		transition: none;
	}
}

/* ==========================================================================
   SECOND-LEVEL NAVIGATION
   Scaffolding — no menu item uses this yet. Add a `.main-nav__submenu`
   container inside a nav item and it activates itself; see
   assets/js/site-submenu.js for the expected markup. A nav item that gains a
   submenu must be a container, not the current <p>, since a paragraph cannot
   legally contain a list.
   ========================================================================== */
.elementor .main-nav__item--has-submenu {
	position: relative;
	display: flex;
	align-items: center;
	gap: 6px;
}

.main-nav__submenu-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

.main-nav__submenu-toggle:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 2px;
	border-radius: 2px;
}

.main-nav__chevron {
	width: 7px;
	height: 7px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg) translate(-1px, -1px);
	transition: transform 200ms ease;
}

.is-submenu-open > .main-nav__submenu-toggle .main-nav__chevron {
	transform: rotate(-135deg) translate(-1px, -1px);
}

.elementor .main-nav__submenu {
	display: flex;
	flex-direction: column;
}

/* --- Desktop: an overlay panel beneath the parent item ------------------- */
@media (min-width: 1201px) {

	.elementor .main-nav__submenu {
		position: absolute;
		inset-block-start: 100%;
		inset-inline-start: 0;
		z-index: 70;
		min-width: 216px;
		padding: 10px 0;
		border-radius: 4px;
		background: linear-gradient(180deg, #22305C 0%, #0B1020 100%);
		box-shadow: 0 18px 44px rgba(5, 7, 15, 0.36);
		opacity: 0;
		visibility: hidden;
		transform: translate3d(0, 6px, 0);
		transition: opacity 180ms ease, transform 180ms ease, visibility 0s linear 180ms;
	}

	.elementor .main-nav__item--has-submenu:hover > .main-nav__submenu,
	.elementor .main-nav__item--has-submenu.is-submenu-open > .main-nav__submenu {
		opacity: 1;
		visibility: visible;
		transform: none;
		transition: opacity 180ms ease, transform 180ms ease;
	}

	/* Keeps the pointer inside the item while it travels to the panel. */
	.elementor .main-nav__item--has-submenu::after {
		content: '';
		position: absolute;
		inset-block-start: 100%;
		inset-inline: 0;
		height: 10px;
	}

	.elementor .main-nav__submenu > * {
		padding: 9px 18px;
		font-size: 14px;
		line-height: 20px;
		white-space: nowrap;
	}
}

/* --- Drawer: an accordion in place (phone and tablet) -------------------- */
@media (max-width: 1200px) {

	.elementor .main-nav__item--has-submenu {
		flex-wrap: wrap;
		justify-content: space-between;
	}

	.elementor .main-nav__submenu {
		flex-basis: 100%;
		display: grid;
		grid-template-rows: 0fr;
		padding-inline-start: 14px;
		transition: grid-template-rows 280ms cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	/* One wrapper, so 0fr -> 1fr has a single row to animate. */
	.elementor .main-nav__submenu > .main-nav__submenu-inner {
		overflow: hidden;
		min-height: 0;
	}

	.elementor .main-nav__item--has-submenu.is-submenu-open > .main-nav__submenu {
		grid-template-rows: 1fr;
	}

	.elementor .main-nav__submenu a {
		display: block;
		padding-block: 11px;
		font-size: 15px;
		opacity: 0.86;
	}

	.main-nav__submenu-toggle {
		width: 34px;
		height: 34px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .main-nav__submenu,
	.main-nav__chevron {
		transition: none;
	}
}

/* Submenu links inherit the nav's own colour, so a plain <a> added by the
   client looks right without needing an Elementor class. */
.elementor .main-nav__submenu a {
	color: #FFFFFF;
	text-decoration: none;
}

.elementor .main-nav__submenu a:hover,
.elementor .main-nav__submenu a:focus-visible {
	color: #8FDCF2;
}

/* --------------------------------------------------------------------------
   Footer bottom bar on mobile
   Legal links read first, the copyright line sits under them.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .page-footer__bottom {
		display: flex;
		flex-direction: column;
	}

	/* The copyright and the agency credit are grouped in `.footer-meta`, so the
	   order belongs on that wrapper — an `order` on `.footer-copyright` does
	   nothing now that it is no longer a direct child of this row. */
	.elementor .page-footer__bottom > .footer-legal {
		order: 1;
	}

	.elementor .page-footer__bottom > .footer-meta {
		order: 2;
		margin-block-start: 16px;
	}
}

/* ==========================================================================
   TABLET PORTRAIT CORRECTIONS
   ========================================================================== */

/* --- Hero chip ------------------------------------------------------------
   The "Developer, not a broker" chip is dropped from tablet portrait down.
   It is absolutely positioned against the hero's right edge and there is no
   room for it once the hero narrows — it was covering "Book a site visit".
   The same claim is made by the hero copy directly above it, so removing it
   costs the page nothing at these widths.
   -------------------------------------------------------------------------- */
@media (max-width: 1024px) {

	.elementor .home-hero .glass-chip {
		display: none;
	}
}

/* --- Hero stats -----------------------------------------------------------
   The figure and its label are baseline-aligned, so as soon as a label wrapped
   to two lines the number sat level with the first line instead of centring
   against the pair. Only visible once labels wrap, which is why it reads fine
   on a wide desktop.
   -------------------------------------------------------------------------- */
@media (max-width: 1200px) {

	.elementor .stat-item {
		align-items: center;
	}
}

/* --- About panel ----------------------------------------------------------
   The panel is pulled up over the image by a negative margin and inset from
   the left. On tablet it simply sits below the image at the image's own width.
   -------------------------------------------------------------------------- */
@media (min-width: 768px) and (max-width: 1024px) {

	.elementor .about-panel {
		width: 100%;
		margin-block-start: 0;
		margin-inline: 0;
	}
}

/* --- Testimonial attribution ---------------------------------------------
   The attribution carries the divider rule, and the homeowner's name sat hard
   against it at every width — the earlier fix only covered phones.
   -------------------------------------------------------------------------- */
.elementor .testimonial__attribution.attribution-divider {
	padding-block-start: 20px;
}


/* --------------------------------------------------------------------------
   Larger header logo on wide screens
   The lock-up was reading small beside the nav. Up ~14% (132x44 -> 151x50),
   and the block padding drops by the half-pixel that keeps the bar at exactly
   97px — the logo overtakes the 48px button as the tallest child, so without
   this the header would grow with it.
   -------------------------------------------------------------------------- */
@media (min-width: 1025px) {

	.elementor .site-masthead {
		/* 20 + 60 logo + 20 + the 1px bottom border = `--masthead-height`, 101px.
		   The padding came down 3px as the logo went up 10, so the bar grew by
		   4px rather than 10 — the lock-up gains the room, not the header. */
		padding-block: 20px;
	}

	/* The strapline, "PROPERTY DEVELOPMENT CORP.", is about a fifth of the
	   artwork's height. At the old 50px that left it roughly 11px to render
	   in and it was barely legible; 60px gives it 13px. Dropping the Contact
	   item from the nav is what freed the width to do this. */
	.elementor .site-masthead .site-logo {
		width: 180px;
		height: 60px;
	}

	/* Compact state scales with it; the 42px button still sets the floor. */
	.elementor .site-masthead.is-scrolled .site-logo {
		width: 144px;
		height: 48px;
	}
}

/* ==========================================================================
   EDITOR PARITY — decorative empty elements
   Elementor's editor gives any empty atomic element a 120px minimum so it can
   be selected and dropped into:

       .e-atomic-element:has(> .elementor-empty-view) { min-height: 120px }

   Every rule, scrim, dot and motif in this build is an intentionally empty div,
   so each one ballooned in the canvas — the milestone rail is 2px on the front
   end and was rendering 120px, which is where the extra space came from.

   These elements never take children, so the minimum buys nothing and the
   editor should show their real size.

   NOTE: `.elementor-empty-view` markup IS emitted on the front end too, but
   the 120px rule lives in editor-preview.min.css, which the front end never
   loads. Setting min-height: 0 there is therefore a no-op — verified: every
   one of these renders at the same size before and after.
   ========================================================================== */
.e-atomic-element.milestone-rail:has(> .elementor-empty-view),
.e-atomic-element.milestone-dot:has(> .elementor-empty-view),
.e-atomic-element.home-hero__marker-rule:has(> .elementor-empty-view),
.e-atomic-element.home-hero__overlay:has(> .elementor-empty-view),
.e-atomic-element.home-hero__scrim:has(> .elementor-empty-view),
.e-atomic-element.financing-panel__rule:has(> .elementor-empty-view),
.e-atomic-element.section-motif:has(> .elementor-empty-view),
.e-atomic-element.development-card__scrim:has(> .elementor-empty-view),
.e-atomic-element.contact-cta__overlay:has(> .elementor-empty-view),
.e-atomic-element.social-link:has(> .elementor-empty-view),
.e-atomic-element.reason-item__icon:has(> .elementor-empty-view),
.e-atomic-element.chapter-mark-inverse:has(> .elementor-empty-view),
.e-atomic-element.about-media:has(> .elementor-empty-view),
.e-atomic-element.media-hero:has(> .elementor-empty-view),
.e-atomic-element.media-contact:has(> .elementor-empty-view) {
	min-height: 0;
}

/* The placeholder inherits the minimum, so it has to be released too. */
.e-atomic-element.milestone-rail > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.milestone-dot > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.home-hero__marker-rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.financing-panel__rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.section-motif > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.social-link > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.reason-item__icon > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.chapter-mark-inverse > .elementor-empty-view.elementor-empty-view {
	min-height: 0;
	height: 100%;
}

/* ==========================================================================
   CUSTOM SELECT
   Site-wide. The native <select> is kept for submission and validation but
   taken out of sight; everything visible is the listbox, because a browser
   will not let CSS style the native option list.
   ========================================================================== */
.softouch-select {
	position: relative;
	width: 100%;
}

/* Visually hidden, not display:none — the control must stay focusable for
   validation messages and must still submit.

   The selector is doubled and `.elementor` prefixed because the form's own
   `enquiry-form__input` class (0,2,0) otherwise keeps the native control at
   its full 464x40. Clipped it is invisible, but it sits at exactly the
   trigger's position, so it also has pointer events removed rather than being
   left to compete for the click. */
.elementor .softouch-select .softouch-select__native,
.softouch-select .softouch-select__native {
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	width: 1px;
	height: 1px;
	min-height: 0;
	margin: -1px;
	padding: 0;
	border: 0;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	overflow: hidden;
	white-space: nowrap;
	pointer-events: none;
}

.softouch-select__trigger {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 9px 14px;
	border: 1px solid #D6D5D5;
	border-radius: 3px;
	background: #FFFFFF;
	color: #0B1020;
	font-family: Poppins, sans-serif;
	font-size: 15px;
	line-height: 22px;
	text-align: start;
	cursor: pointer;
	transition: border-color 160ms ease, box-shadow 160ms ease;
}

.softouch-select__trigger:hover {
	border-color: #8FDCF2;
}

.softouch-select__trigger:focus-visible {
	outline: none;
	border-color: #48C6E9;
	box-shadow: 0 0 0 3px rgba(72, 198, 233, 0.24);
}

.softouch-select.is-open .softouch-select__trigger {
	border-color: #48C6E9;
	box-shadow: 0 0 0 3px rgba(72, 198, 233, 0.18);
}

/* The prompt reads as placeholder text until a real choice is made. */
.softouch-select.is-placeholder .softouch-select__value {
	color: #6B7285;
}

.softouch-select__value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.softouch-select__chevron {
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	margin-block-start: -4px;
	border-right: 1.5px solid #6B7285;
	border-bottom: 1.5px solid #6B7285;
	transform: rotate(45deg);
	transition: transform 200ms ease, border-color 160ms ease;
}

.softouch-select.is-open .softouch-select__chevron {
	margin-block-start: 2px;
	border-color: #147E9F;
	transform: rotate(-135deg);
}

.softouch-select__list {
	position: absolute;
	inset-inline: 0;
	inset-block-start: calc(100% + 6px);
	z-index: 30;
	max-height: 264px;
	margin: 0;
	padding: 6px;
	border: 1px solid #E3DFD7;
	border-radius: 4px;
	background: #FFFFFF;
	box-shadow: 0 14px 34px rgba(11, 16, 32, 0.14);
	list-style: none;
	overflow-y: auto;
	overscroll-behavior: contain;
	opacity: 0;
	transform: translate3d(0, -4px, 0);
	transition: opacity 150ms ease, transform 150ms ease;
}

.softouch-select.is-open .softouch-select__list {
	opacity: 1;
	transform: none;
}

.softouch-select__option {
	padding: 9px 12px;
	border-radius: 3px;
	color: #2A3145;
	font-family: Poppins, sans-serif;
	font-size: 15px;
	line-height: 22px;
	cursor: pointer;
}

.softouch-select__option.is-placeholder {
	color: #6B7285;
}

.softouch-select__option.is-active {
	background: #F0FBFE;
	color: #0B1020;
}

.softouch-select__option[aria-selected="true"] {
	background: #147E9F;
	color: #FFFFFF;
	font-weight: 500;
}

.softouch-select__option[aria-disabled="true"] {
	opacity: 0.45;
	cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {

	.softouch-select__list,
	.softouch-select__chevron,
	.softouch-select__trigger {
		transition: none;
	}
}

/* ==========================================================================
   NEUTRALISE HELLO'S BUTTON RESET
   hello-elementor/assets/css/reset.css sets, for every button on the page:

       button:focus, button:hover { background-color: #c36; color: #fff }

   #c36 is a magenta that belongs to nothing in this brand. The Elementor
   button classes each declare their own hover, so they already outrank it —
   but the controls built in this theme did not, which is why the select
   trigger turned red on hover and a slider dot would have flashed red while
   focused. Each one below states the background it should actually keep.
   ========================================================================== */
.softouch-select__trigger:hover,
.softouch-select__trigger:focus,
.softouch-select__trigger:focus-visible,
.softouch-select__trigger:active {
	background-color: #FFFFFF;
	color: #0B1020;
}

.elementor .testimonial-slider__dot:focus,
.elementor .testimonial-slider__dot:focus-visible {
	background-color: rgba(255, 255, 255, 0.6);
}

.elementor .testimonial-slider__dot.is-active:hover,
.elementor .testimonial-slider__dot.is-active:focus,
.elementor .testimonial-slider__dot.is-active:focus-visible {
	background-color: #48C6E9;
}

.main-nav__submenu-toggle:hover,
.main-nav__submenu-toggle:focus,
.main-nav__submenu-toggle:focus-visible,
.main-nav__submenu-toggle:active {
	background: none;
	color: inherit;
}

/* ==========================================================================
   LOCATION PICKER (Communities — By location)
   Six panels stacked in one box, six rows beside them, both from the same
   taxonomy loop. Only the class API cannot express the parts below: a
   generated counter, a cross-fade between siblings, and the row hover states.
   ========================================================================== */

/* The loop element itself takes no `classes` prop — Elementor refuses it on
   e-collection-loop — and `.e-con` gives it `position: relative`. That made it
   the containing block for the absolutely positioned panel layout inside,
   which then resolved `inset: 0` against a zero-height element instead of the
   media box. Returning it to static hands the panels back to .locator__media. */
.elementor .locator__media [data-e-type="e-collection-loop"] {
	position: static;
}

/* 01-06, derived from position so the numbering can never drift from the
   locations the loop actually returns. */
.elementor .locator__index::before {
	content: counter(locator, decimal-leading-zero);
}

/* Panels cross-fade; the active one is the only one that can be read. */
.elementor .locator__panel {
	opacity: 0;
	visibility: hidden;
	transform: scale(1.04);
	transition: opacity 420ms ease, transform 620ms ease, visibility 0s linear 420ms;
}

.elementor .locator__panel.is-active {
	opacity: 1;
	visibility: visible;
	transform: none;
	transition: opacity 420ms ease, transform 620ms ease;
}

/* The badge is a term field: no value, no pill. */
.elementor .locator__badge:empty {
	display: none;
}

/* Row states. The whole row is the link, so hover and keyboard focus behave
   identically — the panel swap is driven from both.

   NOTE: literal hex, not var(--e-gv-…). Elementor resolves its global
   variables to literals when it generates class CSS and never emits them as
   custom properties, so they are undefined in this stylesheet. */
.elementor .locator__row:hover .locator__name,
.elementor .locator__row:focus-visible .locator__name,
.elementor .locator__row.is-active .locator__name {
	color: #354B8E;
}

.elementor .locator__row:hover .locator__arrow,
.elementor .locator__row.is-active .locator__arrow {
	transform: translate3d(6px, 0, 0);
}

.elementor .locator__row:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 4px;
	border-radius: 2px;
}

/* Last row needs a closing rule, since the border sits on the top edge. */
.elementor .locator__rows > *:last-child .locator__row {
	border-block-end: 1px solid #E3DFD7;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .locator__panel,
	.elementor .locator__arrow {
		transition: none;
	}

	.elementor .locator__panel {
		transform: none;
	}
}

/* ==========================================================================
   COMMUNITIES — PROPERTY TYPE INDEX
   Section 04 of the approved Communities design. A collection loop renders
   identical markup for every term, so nothing in the row can carry the slug —
   except the row itself, which is a link to that term's archive. The icons key
   off that href.

   Sizes and offsets are the design's own: each SVG keeps its intrinsic
   dimensions and sits at its authored position inside the 40px box, rather
   than being scaled to fit, which would shift each icon's optical weight by a
   different amount.
   ========================================================================== */

.elementor .type-row__icon {
	display: block;
	flex: none;
	width: 40px;
	height: 40px;
	margin: 0;
	padding: 0;
	background-repeat: no-repeat;
}

.elementor .type-row[href$="/socialized/"] .type-row__icon {
	background-image: url('assets/icons/type-socialized.svg');
	background-size: 25.67px 19px;
	background-position: 7.17px 13.83px;
}

.elementor .type-row[href$="/economic/"] .type-row__icon {
	background-image: url('assets/icons/type-economic.svg');
	background-size: 29px 25.67px;
	background-position: 5.5px 7.17px;
}

.elementor .type-row[href$="/townhouse/"] .type-row__icon {
	background-image: url('assets/icons/type-townhouse.svg');
	background-size: 31.5px 22.33px;
	background-position: 3.83px 10.5px;
}

.elementor .type-row[href$="/duplex/"] .type-row__icon {
	background-image: url('assets/icons/type-duplex.svg');
	background-size: 32.33px 24px;
	background-position: 3.83px 8.83px;
}

.elementor .type-row[href$="/single-attached/"] .type-row__icon {
	background-image: url('assets/icons/type-single-attached.svg');
	background-size: 27.33px 22.33px;
	background-position: 3.83px 10.5px;
}

.elementor .type-row[href$="/single-detached/"] .type-row__icon {
	background-image: url('assets/icons/type-single-detached.svg');
	background-size: 29px 25.67px;
	background-position: 5.5px 7.17px;
}

.elementor .type-row[href$="/shophouse/"] .type-row__icon {
	background-image: url('assets/icons/type-shophouse.svg');
	background-size: 29px 25.67px;
	background-position: 5.5px 7.17px;
}

.elementor .type-row__arrow {
	display: block;
	flex: none;
	width: 26px;
	height: 26px;
	background-image: url('assets/icons/arrow-right.svg');
	background-repeat: no-repeat;
	background-size: 16.9px 14.73px;
	background-position: 4.55px 5.63px;
	transition: transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* The whole row is the link, so hover belongs to the row, not the arrow. */
.elementor .type-row:hover .type-row__arrow,
.elementor .type-row:focus-visible .type-row__arrow {
	transform: translate3d(6px, 0, 0);
}

.elementor .type-row:hover .type-row__name,
.elementor .type-row:focus-visible .type-row__name {
	color: #8FDCF2;
}

.elementor .type-row:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 4px;
	border-radius: 2px;
}

/* Rows carry their line on the top edge, so the list needs a closing rule. */
.elementor .type-index > *:last-child .type-row {
	border-block-end: 1px solid rgba(255, 255, 255, 0.24);
}

/* ==========================================================================
   COMMUNITIES — FOOTPRINT
   Section 07. The map is a flat decorative plate: a grid, the Cebu spine and
   Mactan, with the six pins over it. Pin coordinates are a fraction of the
   600x620 plate so the whole thing scales as one piece, and each pin finds its
   place from the location archive it links to.
   ========================================================================== */

.elementor .footprint__map {
	position: relative;
	aspect-ratio: 600 / 620;
}

.elementor .footprint__map::before {
	content: "";
	position: absolute;
	inset: -1px auto auto -1px;
	/* The plate is 600x620; the artwork is 680 wide and clipped on the right,
	   so express the overflow as a ratio to keep it true at any width. */
	width: 113.3333%;
	height: calc(100% + 2px);
	background-image: url('assets/icons/cebu-map.svg');
	background-repeat: no-repeat;
	background-size: 100% 100%;
	pointer-events: none;
}

/* `.e-con` makes a collection loop `position: relative`, which would trap the
   pins inside it instead of over the plate. Same trap as the locator panel. */
.elementor .footprint__map [data-e-type="e-collection-loop"],
.elementor .footprint__map [data-e-type="e-collection-loop-layout"],
.elementor .footprint__map [data-e-type="e-collection-loop-item"] {
	position: static;
}

.elementor .footprint__pin {
	position: absolute;
	z-index: 2;
	display: none;
	gap: 8px;
	align-items: center;
	margin: 0;
	padding: 4px 8px;
	border: 1px solid rgba(255, 255, 255, 0.24);
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.24);
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 180ms ease;
}

.elementor .footprint__pin:hover,
.elementor .footprint__pin:focus-visible {
	background: rgba(255, 255, 255, 0.38);
}

.elementor .footprint__pin-name {
	margin: 0;
	font-family: Poppins, sans-serif;
	font-weight: 600;
	font-size: 14px;
	line-height: 20px;
	letter-spacing: 0.03em;
	color: #FFFFFF;
}

/* Positions are the design's own, expressed against the 600x620 plate. A
   location with no place on the map stays hidden rather than stacking at the
   origin, so adding a seventh location cannot corrupt the artwork. */
.elementor .footprint__pin[href$="/danao/"]       { display: flex; inset-inline-start: 42.50%; inset-block-start: 19.19%; }
.elementor .footprint__pin[href$="/liloan/"]      { display: flex; inset-inline-start: 39.50%; inset-block-start: 33.39%; }
.elementor .footprint__pin[href$="/consolacion/"] { display: flex; inset-inline-start: 37.83%; inset-block-start: 45.32%; }
.elementor .footprint__pin[href$="/mactan/"]      { display: flex; inset-inline-start: 78.17%; inset-block-start: 53.06%; }
.elementor .footprint__pin[href$="/talisay/"]     { display: flex; inset-inline-start: 40.83%; inset-block-start: 67.58%; }
.elementor .footprint__pin[href$="/minglanilla/"] { display: flex; inset-inline-start: 39.17%; inset-block-start: 80.16%; }

.elementor .footprint__pin::before {
	content: "";
	flex: none;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: #48C6E9;
}

/* The dot belongs to the location name, so it hangs off the name rather than
   off the row. Centring it against the row means its position depends on the
   row's tallest child — the corridor label, the New badge — and it drifts.
   `.footprint__name` is itself a centred flex line, so a pseudo-element inside
   it lands on the text's own vertical centre whatever else the row contains. */
.elementor .footprint__name::before {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: #48C6E9;
	/* `align-items: center` centres the dot on the LINE BOX. Poppins' ascent
	   and descent are not symmetrical, so the glyphs' optical centre sits
	   below that and a box-centred dot reads high. The nudge is in `em` so it
	   tracks the type down the breakpoints instead of drifting. */
	transform: translateY(0.12em);
}

.elementor .footprint__legend-row:hover .footprint__name,
.elementor .footprint__legend-row:focus-visible .footprint__name {
	color: #8FDCF2;
}

/* Legend rows carry their line on the top edge — close the list. */
.elementor .footprint__legend > *:last-child .footprint__legend-row {
	border-block-end: 1px solid rgba(255, 255, 255, 0.24);
}

/* ==========================================================================
   COMMUNITIES — NEW BADGE
   `badge` is an ACF term field filled in for Danao only, so every other term
   renders the element empty. An empty pill is a visual bug, so hide it.
   ========================================================================== */

.elementor .term-badge:empty {
	display: none;
}

/* The location rail and the footprint legend sit on different grounds, so the
   badge takes its colour from the surface it lands on. */
.elementor .pill-rail .term-badge {
	background: #405BA9;
}

.elementor .footprint__legend .term-badge {
	background: #48C6E9;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .type-row__arrow {
		transition: none;
	}
}

/* ==========================================================================
   COLLECTION LOOPS THAT MUST NOT BE A BOX
   A loop renders a wrapper and a layout. Where the loop's items need to be
   flex children of the section around it — pills sitting in the rail beside
   its label — the wrapper has to step out of the way. `e-collection-loop`
   refuses a class prop, so the layout it contains identifies it instead.
   ========================================================================== */

.elementor [data-e-type="e-collection-loop"]:has(> .pill-rail__items),
.elementor [data-e-type="e-collection-loop"]:has(> .type-index),
.elementor [data-e-type="e-collection-loop"]:has(> .footprint__legend) {
	display: contents;
}

/* Every atomic container is born `--width: 100%`, so each loop item would take
   a whole row of the rail. The items have no class of their own — the layout
   around them is the only handle. */
.elementor .pill-rail__items > .e-con {
	--width: auto;
}

/* The design fills the first chip, but nothing is filtered on the Communities
   hub — every chip is just a link to a location. A filled chip there reads as
   a selected state that does not exist, so all six render identically and the
   fill is kept for the real hover/focus states. */


/* ==========================================================================
   COMMUNITIES — SECTIONS 02, 05, 06, 09, 11, 12
   Rules the Elementor class API cannot express: first-child exceptions,
   pillar icons, and the CTA's photographic plate.
   ========================================================================== */

/* The first card in each divided row has no rule before it. */
.elementor .stat-row > .stat-cell:first-child {
	border-inline-start: 0;
}

@media (max-width: 767px) {

	.elementor .stat-row > .stat-cell:first-child {
		border-block-start: 0;
	}
}

/* The design shows step one picked out in brand blue; that is the hover
   state, not a permanent mark on the first step. Every step takes it in turn,
   and the rule and the figure move together. Keyboard users get it on focus
   for the same reason. */
.elementor .journey-col {
	transition: border-color 180ms ease;
}

.elementor .journey-col .journey-step__num {
	transition: color 180ms ease;
}

/* The active rule is the brand GRADIENT, not a flat blue. A border cannot take
   a gradient, so the 3px top border stays where it is as the resting hairline
   and a 3px strip is laid over it on hover. `inset-block-start: -3px` puts the
   strip on the border itself rather than below it — the column is already
   `position: relative`, so there is nothing else to add. */
.elementor .journey-steps > .journey-col::before {
	content: "";
	position: absolute;
	inset-block-start: -3px;
	inset-inline: 0;
	height: 3px;
	opacity: 0;
	pointer-events: none;
	background-image: linear-gradient(
		115deg,
		#48C6E9 0%,
		#405BA9 100%
	);
	transition: opacity 180ms ease;
}

.elementor .journey-steps > .journey-col:hover::before,
.elementor .journey-steps > .journey-col:focus-within::before {
	opacity: 1;
}

/* The figure takes the same ramp, clipped to the glyphs. At 56px there is room
   for the gradient to read across a two-character number. The fallback keeps
   the flat blue, because `color: transparent` with no clip is an invisible
   number rather than a differently-coloured one. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {

	.elementor .journey-steps > .journey-col:hover .journey-step__num,
	.elementor .journey-steps > .journey-col:focus-within .journey-step__num {
		background-image: linear-gradient(
			115deg,
			#48C6E9 0%,
			#405BA9 100%
		);
		-webkit-background-clip: text;
		background-clip: text;
		color: transparent;
		-webkit-text-fill-color: transparent;
	}
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {

	.elementor .journey-steps > .journey-col:hover .journey-step__num,
	.elementor .journey-steps > .journey-col:focus-within .journey-step__num {
		color: #354B8E;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .journey-col,
	.elementor .journey-col .journey-step__num {
		transition: none;
	}
}

/* --- Why Softouch pillars -------------------------------------------------
   The icons are 26px line art centred in a 48px wash, each keeping its own
   intrinsic dimensions rather than being stretched to a common box.
   -------------------------------------------------------------------------- */
/* The artwork is a background on the wash itself. A child element has to be
   centred by the parent's flex rules, which is one more thing that can be
   overridden; `background-position: center` cannot drift. */
.elementor .pillar__icon {
	background-repeat: no-repeat;
	background-position: center center;
}

.elementor .pillar--quality   .pillar__icon { background-image: url('assets/icons/pillar-quality.svg');   background-size: 19.28px 17.12px; }
.elementor .pillar--locations .pillar__icon { background-image: url('assets/icons/pillar-locations.svg'); background-size: 16.03px 19.83px; }
.elementor .pillar--safe      .pillar__icon { background-image: url('assets/icons/pillar-safe.svg');      background-size: 17.12px 21.45px; }
.elementor .pillar--life      .pillar__icon { background-image: url('assets/icons/pillar-life.svg');      background-size: 17.12px 15.98px; }

/* --- Final CTA ------------------------------------------------------------
   The photograph is a background on the section itself so the overlay and the
   content can sit above it without a separate image element in the flow.
   -------------------------------------------------------------------------- */
.elementor .final-cta.final-cta {
	background-image: url('/wp-content/uploads/2026/09/softouch-hero-family.jpg');
	background-size: cover;
	background-position: center 30%;
	background-repeat: no-repeat;
}

/* --- Communities FAQ ------------------------------------------------------
   Same accordion as the homepage; only the title column is narrower, per the
   design's 400px rail.
   -------------------------------------------------------------------------- */
.elementor .faq-communities__title .heading-2 {
	max-width: none;
}

/* --- Communities FAQ: cards, not hairline rows ----------------------------
   The homepage accordion is reused wholesale so the open/close behaviour and
   the first-open script keep working. The Communities design draws each entry
   as a bordered card instead, with the open one marked in brand blue, so the
   difference is carried here rather than by forking the accordion.
   -------------------------------------------------------------------------- */

.elementor .faq-cards .faq-loop__layout {
	gap: 12px;
}

.elementor .faq-cards .faq-item {
	padding: 32px;
	border: 1px solid #E3DFD7;
	border-radius: 4px;
	background: #FFFFFF;
	transition: border-color 180ms ease;
}

.elementor .faq-cards .faq-item[open],
.elementor .faq-cards .faq-item.is-open {
	border-color: #405BA9;
}

.elementor .faq-cards .faq-item__header {
	padding: 0;
	border: 0;
}

.elementor .faq-cards .faq-item__content {
	padding-inline: 0;
}

@media (max-width: 767px) {

	.elementor .faq-cards .faq-item {
		padding: 20px;
	}
}

/* The dot now sits inside the name, so the row only needs its own 4px inset
   and the name carries the 12px the design puts between dot and word. */
.elementor .footprint__name {
	gap: 12px;
}

/* --- Communities FAQ: answer copy --------------------------------------
   The accordion is the homepage's, whose answers are Body/Base. The
   Communities design sets them at Body/Small against the 21px question.
   -------------------------------------------------------------------------- */
.elementor .faq-cards .faq-item__content .body-base {
	font-size: 15px;
	line-height: 25px;
}

@media (max-width: 767px) {

	.elementor .faq-cards .faq-item__content .body-base {
		font-size: 14px;
		line-height: 23px;
	}
}

/* --- "Find a Community Near You" ------------------------------------------
   The locator heading is one line in the design. At Display/M it wraps as soon
   as the container drops below ~1000px, so it scales with the viewport and
   only gives up the single line on phones.
   -------------------------------------------------------------------------- */
.elementor .display-m-fit {
	font-size: min(52px, 5.2vw);
	line-height: 1.12;
}

@media (max-width: 767px) {

	.elementor .display-m-fit {
		font-size: 30px;
		line-height: 1.2;
	}
}

/* ==========================================================================
   BREADCRUMBS — YOAST
   The trail and the page's BreadcrumbList structured data both come from
   Yoast, so they cannot disagree. Yoast emits plain nested spans and links
   with no classes of its own beyond `.breadcrumb_last`, so the design's
   treatment is applied here rather than on the elements.
   ========================================================================== */

.elementor .breadcrumb a {
	color: rgba(255, 255, 255, 0.72);
	text-decoration: none;
	transition: color 180ms ease;
}

.elementor .breadcrumb a:hover,
.elementor .breadcrumb a:focus-visible {
	color: #FFFFFF;
}

.elementor .breadcrumb .breadcrumb_last {
	color: #FFFFFF;
}

/* Belt and braces: the current crumb is marked by the theme filter, but style
   the last child too so the trail still reads correctly if Yoast changes how
   it renders that crumb. */
.elementor .breadcrumb > span > span > span:last-child {
	color: #FFFFFF;
}

/* --- Agency credit --------------------------------------------------------
   Only the agency name is the link. Underline on hover rather than always, and
   lift the colour so the hover state is followable, not just visible.
   -------------------------------------------------------------------------- */
.elementor .footer-credit a {
	color: rgba(255, 255, 255, 0.82);
	text-decoration: none;
	transition: color 180ms ease;
}

.elementor .footer-credit a:hover,
.elementor .footer-credit a:focus-visible {
	color: #8FDCF2;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Loop items default to `.e-con`'s 10px padding. The attribute-based reset
   higher up misses them here, which left the first five legend rows 68px tall
   against the last row's 47 — measured, not guessed — with the name pinned to
   the top of its row. Reset by descent instead, which cannot miss. */
.elementor .footprint__legend > *,
.elementor .type-index > *,
.elementor .pill-rail__items > * {
	padding: 0;
}

/* ==========================================================================
   FULL-BLEED BANDS ON THE SAME MEASURE AS THE SECTIONS
   The masthead, the hero body and the location rail are full-width bands:
   the header's rule, the hero photograph and the rail's white fill all have to
   run edge to edge, so they cannot use `section-inner`'s max-width — that would
   cap their backgrounds too.

   Every section below them puts its content on a 1248px measure inside a 96px
   gutter, which is the whole viewport at 1440 and narrower. Past 1440 the
   gutter has to grow instead, or these three bands keep spreading while the
   sections below stand still. Below 1441 this rule is inert and the existing
   gutter ladder (96 / 64 / 56 / 48 / 24) applies untouched.

   EVERY full-bleed band belongs in this list. A band whose content is capped
   by an inner max-width:1248 block (`page-section` > `guide-stack`) does not,
   because the inner block already holds the measure. A band that pads itself
   with a fixed 96px and has no such inner block DOES — otherwise it keeps
   widening past 1441 while every neighbouring section stands still, which is
   exactly how jump-nav, midcta, stat-band and the contact panels drifted.
   ========================================================================== */
@media (min-width: 1441px) {

	.elementor .site-masthead,
	.elementor .page-hero__body.page-hero__body,
	.elementor .pill-rail,
	.elementor .home-hero__header,
	.elementor .home-hero__body,
	.elementor .home-hero__stats,
	.elementor .jump-nav,
	.elementor .midcta,
	.elementor .stat-band {
		padding-inline: calc((100% - 1248px) / 2);
	}

	/* The contact split is two full-bleed panels, so the measure has to be
	   applied to their OUTER edges only — the 64px gutter between them stays.
	   A padding percentage resolves against the containing block (the split,
	   which is full width), not against the panel, so the same formula gives
	   the same inset it gives a full-width band. */
	.elementor .contact-info {
		padding-inline-start: calc((100% - 1248px) / 2);
	}

	.elementor .contact-form-panel {
		padding-inline-end: calc((100% - 1248px) / 2);
	}
}

/* ==========================================================================
   HARD LINE BREAKS THAT STOP HELPING
   A <br> in a heading is art direction for the wide layout: it picks where the
   line turns so no word is left stranded. That only holds while the first
   segment still fits the measure. Once it does not, the segment wraps AND the
   <br> fires, producing a one-word orphan line — "Building Quality Homes /
   and / Communities Since 2008".

   Measured against the 327px mobile measure at 28px: this is the only heading
   on the site whose first segment overflows (~379px). Every other break fits
   and is doing its job, so they are left alone — blanket-hiding them would
   re-wrap headings that are currently correct and strand different words,
   which is the same fault in a new place.
   ========================================================================== */
@media (max-width: 767px) {

	.elementor .dev-intro__copy h2 br {
		display: none;
	}
}

/* The facts card already has its own border, so the first row's top rule
   doubles it. */
.elementor .facts-card.facts-card > .fact-row:first-child {
	border-block-start: 0;
}

/* ==========================================================================
   LOCATION ARCHIVE
   ========================================================================== */

/* --- Filter chips ---------------------------------------------------------
   The controls are nested lists of links, because Elementor's shortcode
   sanitiser removes `select`, `label` and `button` outright and strips every
   class and data attribute from what it does keep. So everything here selects
   by element and position.

   Links are the better control regardless: each filtered view is a real URL,
   and the panel works with no JavaScript at all.
   -------------------------------------------------------------------------- */

.elementor .location-filters > ul {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Each top-level item is a chip. */
.elementor .location-filters > ul > li {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 11px 18px;
	border: 1px solid #E3DFD7;
	border-radius: 999px;
	background: #FFFFFF;
	font-size: 15px;
	line-height: 24px;
	color: #0B1020;
	white-space: nowrap;
}

/* The location is a statement of what you are looking at, not a control. */
.elementor .location-filters > ul > li:first-child {
	background: #405BA9;
	border-color: #405BA9;
	color: #FFFFFF;
}

/* A chip holding a value has one applied — give it the active treatment. */
.elementor .location-filters > ul > li:has(> strong) {
	border-color: #405BA9;
	background: #F0FBFE;
}

.elementor .location-filters > ul > li:first-child:has(> strong) {
	background: #405BA9;
}

.elementor .location-filters > ul > li > strong {
	font-weight: 600;
}

/* Chips that open a menu get the caret and the pointer. */
.elementor .location-filters > ul > li:has(ul) {
	cursor: pointer;
}

.elementor .location-filters > ul > li:has(ul)::after {
	content: "▾";
	color: #6B7285;
	font-size: 12px;
}

/* "Clear filters" is the one item with no caption span — a bare link. */
.elementor .location-filters > ul > li:not(:has(span)) {
	border-color: transparent;
	background: none;
	padding-inline: 4px;
}

.elementor .location-filters > ul > li:not(:has(span)) > a {
	color: #354B8E;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* --- the menus --------------------------------------------------------- */

.elementor .location-filters ul ul {
	position: absolute;
	z-index: 20;
	inset-block-start: calc(100% + 8px);
	inset-inline-start: 0;
	min-width: 200px;
	margin: 0;
	padding: 6px;
	list-style: none;
	border: 1px solid #E3DFD7;
	border-radius: 8px;
	background: #FFFFFF;
	box-shadow: 0 16px 40px rgba(11, 16, 32, 0.14);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-4px);
	transition: opacity 160ms ease, transform 160ms ease, visibility 160ms;
}

.elementor .location-filters > ul > li:hover > ul,
.elementor .location-filters > ul > li:focus-within > ul,
.elementor .location-filters > ul > li.is-open > ul {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.elementor .location-filters ul ul li {
	display: block;
	margin: 0;
	padding: 0;
	white-space: nowrap;
}

.elementor .location-filters ul ul a {
	display: block;
	padding: 9px 12px;
	border-radius: 4px;
	color: #0B1020;
	text-decoration: none;
	font-size: 15px;
	line-height: 22px;
}

.elementor .location-filters ul ul a:hover,
.elementor .location-filters ul ul a:focus-visible {
	background: #F0FBFE;
	color: #354B8E;
}

.elementor .location-filters ul ul strong {
	color: #354B8E;
}

@media (max-width: 767px) {

	.elementor .location-filters > ul {
		gap: 8px;
	}

	.elementor .location-filters > ul > li {
		padding: 9px 14px;
		font-size: 14px;
	}

	.elementor .location-filters ul ul {
		min-width: 180px;
	}
}

/* --- Result cards ---------------------------------------------------------
   The photograph is an image element behind the text rather than a background,
   so it can be the property's own featured image via a dynamic tag.
   -------------------------------------------------------------------------- */

.elementor .result-card__media,
.elementor .result-card__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: cover;
}

.elementor .result-card__meta:empty {
	display: none;
}

.elementor .result-card:hover .result-card__media img,
.elementor .result-card:focus-visible .result-card__media img {
	transform: scale(1.04);
}

.elementor .result-card__media img {
	transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- Related communities index --------------------------------------------
   Numbered from position so the sequence can never drift from the locations
   the loop actually returns.
   -------------------------------------------------------------------------- */

.elementor .loc-index {
	counter-reset: loc;
}

.elementor .loc-index > * {
	counter-increment: loc;
	padding: 0;
}

.elementor .loc-index__num::before {
	content: counter(loc, decimal-leading-zero);
}

.elementor .loc-index > *:last-child .loc-index__row {
	border-block-end: 1px solid #E3DFD7;
}

.elementor .loc-index__row:hover .loc-index__name,
.elementor .loc-index__row:focus-visible .loc-index__name {
	color: #354B8E;
}

/* --- At a glance ----------------------------------------------------------
   A list rather than a definition list, since `dl`/`dt`/`dd` do not survive
   the shortcode sanitiser either.
   -------------------------------------------------------------------------- */

.elementor .location-facts ul {
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .location-facts li {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0;
	padding-block: 20px;
	border-block-end: 1px solid rgba(203, 197, 186, 0.5);
}

.elementor .location-facts li:first-child {
	padding-block-start: 0;
}

.elementor .location-facts li:last-child {
	border-block-end: 0;
	padding-block-end: 0;
}

.elementor .location-facts span {
	font-family: Poppins, sans-serif;
	font-weight: 600;
	font-size: 14px;
	line-height: 20px;
	color: #147E9F;
}

.elementor .location-facts strong {
	font-family: Poppins, sans-serif;
	font-weight: 400;
	font-size: 17px;
	line-height: 26px;
	color: #2A3145;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .result-card__media img {
		transition: none;
	}
}

/* --- Locations without copy yet -------------------------------------------
   Five of the six locations have no intro or guide written. Rather than render
   an empty heading and a blank column, the section removes itself until the
   field is filled. `:empty` matches because the shortcodes return an empty
   string, so the element is genuinely childless.
   -------------------------------------------------------------------------- */

.elementor .loc-seo-section:has(.heading-2:empty) {
	display: none;
}

.elementor .glance-card.glance-card:has(.location-facts:empty) {
	display: none;
}

.elementor .loc-about-section:has(.loc-about__copy > .body-base:empty):has(.location-facts:empty) {
	display: none;
}

/* With the card gone the copy should not keep a two-column measure. */
.elementor .loc-about:has(.glance-card:not(:has(.location-facts:empty))) .loc-about__copy {
	max-width: 640px;
}

/* --- Property card details ------------------------------------------------
   Badge, place line, spec chips and price. The chips come from a shortcode as
   a plain list, so they are styled by element within the card.
   -------------------------------------------------------------------------- */

/* A sold-out property is wrapped in <em> by the shortcode — the one signal
   that survives Elementor's sanitiser, and the right semantic for it. */
.elementor .result-card__badge:has(em) {
	background: rgba(11, 16, 32, 0.72);
	color: rgba(255, 255, 255, 0.82);
}

.elementor .result-card__badge em {
	font-style: normal;
}

.elementor .result-card__badge:empty {
	display: none;
}

.elementor .result-card__place:empty,
.elementor .result-card__price:empty {
	display: none;
}

.elementor .result-card__specs ul {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .result-card__specs li {
	margin: 0;
	padding: 4px 12px;
	border: 1px solid rgba(255, 255, 255, 0.42);
	border-radius: 999px;
	font-family: Poppins, sans-serif;
	font-size: 13px;
	line-height: 20px;
	color: #FFFFFF;
}

/* --- Card scrims ----------------------------------------------------------
   Both card families put white text over a photograph, so both need a wash
   under it. The model card had none at all — its title sat directly on the
   image, which is legible against a dark roof and not against a bright sky.

   Two layers rather than one, because a gradient cannot be transitioned: the
   resting wash is on `::after` and a stronger one sits on `::before` at zero
   opacity, fading in on hover and focus. That way the photograph reads at
   rest and the words win the moment you point at the card.
   -------------------------------------------------------------------------- */

.elementor .result-card::after,
.elementor .model-loop__card::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(11, 16, 32, 0) 28%, rgba(11, 16, 32, 0.88) 100%);
	pointer-events: none;
}

.elementor .result-card::before,
.elementor .model-loop__card::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	opacity: 0;
	background: linear-gradient(180deg, rgba(11, 16, 32, 0.14) 0%, rgba(11, 16, 32, 0.58) 45%, rgba(11, 16, 32, 0.97) 100%);
	pointer-events: none;
	transition: opacity 260ms ease;
}

.elementor .result-card:hover::before,
.elementor .result-card:focus-visible::before,
.elementor .model-loop__card:hover::before,
.elementor .model-loop__card:focus-visible::before {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .result-card::before,
	.elementor .model-loop__card::before {
		transition: none;
	}
}

@media (max-width: 767px) {

	.elementor .result-card__specs li {
		padding: 2px 8px;
		font-size: 11px;
		line-height: 17px;
	}

	.elementor .result-card__specs ul {
		gap: 5px;
	}
}

/* --- Property card and pillars on phones ----------------------------------
   At two-up on a phone each card is roughly 155px wide. The development and
   municipality line is the longest string on it ("ANAMI HOMES NORTH,
   CONSOLACION") and was wrapping to three lines, pushing the whole stack up
   past the top of the card and underneath the status badge. One line with an
   ellipsis keeps the card's height predictable whatever the development is
   called.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

	.elementor .result-card__place {
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
	}

	/* A long model name still wraps, but never past two lines. */
	.elementor .result-card__title {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}

	.elementor .result-card__specs li {
		padding: 2px 7px;
		font-size: 10px;
		line-height: 15px;
	}

	.elementor .result-card__specs ul {
		gap: 4px;
	}

	/* The pillars are two-up here too, so the heading comes down with them. */
	.elementor .pillar.pillar h3 {
		font-size: 15px;
		line-height: 21px;
	}

	.elementor .pillar__icon::before {
		width: 20px;
		height: 20px;
		background-size: contain;
	}
}

/* ==========================================================================
   CONTACT PAGE — states a global class cannot express
   Elementor's class API silently discards pseudo-elements, and it has no
   `:has()` support at all, so the pill-radio's selected state, the select's
   "nothing chosen yet" colour and every focus ring live here.
   ========================================================================== */

/* The pill IS a radio: the input covers the chip at zero opacity so the whole
   pill is the hit target and keyboard/screen-reader behaviour stays native. */
.elementor .cf-chip:has(.cf-chip__input:checked) {
	background-color: #405BA9;
	border-color: #405BA9;
}

.elementor .cf-chip:has(.cf-chip__input:checked) .cf-chip__label {
	color: #FFFFFF;
}

.elementor .cf-chip:hover:not(:has(.cf-chip__input:checked)) {
	border-color: #B9C4DE;
	background-color: #F7F9FD;
}

/* Focus follows the invisible input, so the ring has to be drawn on the pill. */
.elementor .cf-chip:has(.cf-chip__input:focus-visible) {
	outline: 2px solid #405BA9;
	outline-offset: 2px;
}

.elementor .cf-chip__input:focus-visible {
	outline: none;
}

/* A select still showing its prompt reads as placeholder text; once a real
   option is chosen it becomes content and takes the body colour. */
.elementor .cf-select:has(option[value=""]:checked) {
	color: #6B7285;
}

.elementor .cf-select:not(:has(option[value=""]:checked)) {
	color: #0B1020;
}

.elementor .cf-input::placeholder,
.elementor .cf-textarea::placeholder {
	color: #9AA1B2;
	opacity: 1;
}

.elementor .cf-input:focus,
.elementor .cf-select:focus,
.elementor .cf-textarea:focus {
	border-color: #405BA9;
	box-shadow: 0 0 0 3px rgba(64, 91, 169, 0.16);
}

.elementor .cf-textarea {
	resize: vertical;
	min-height: 96px;
}

.elementor .cf-submit:hover {
	background-color: #33498A;
}

/* Hello Elementor paints every <button> magenta on hover AND focus; the
   submit button is a real <button>, so it needs its own focus background. */
.elementor .cf-submit:focus {
	background-color: #33498A;
	color: #FFFFFF;
}

/* The info panel's values are links (tel:, mailto:) and must not look like
   body text that happens to be blue — they inherit, and underline on hover. */
.elementor .contact-info__value a,
.elementor .contact-info__note a {
	color: inherit;
	text-decoration: none;
}

.elementor .contact-info__value a:hover,
.elementor .contact-info__note a:hover,
.elementor .contact-info__value a:focus-visible,
.elementor .contact-info__note a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* ==========================================================================
   ABOUT PAGE
   ========================================================================== */

/* The glow is decoration only and must never intercept a click or extend the
   scroll width of the page.

   `clip`, not `hidden`. Both clip the glow identically, but `hidden` makes the
   band a scroll container, and a scroll container becomes the nearest scrollport
   for everything inside it — which silently kills `position: sticky` in any band
   that carries a glow. That is what stopped the Careers filter rail sticking.
   `clip` clips without creating a scrollport, the same reasoning as the
   `overflow-x: clip` at the top of this file. */
.elementor .page-section:has(> .brand-glow),
.elementor .contact-split:has(> .brand-glow) {
	position: relative;
	overflow: clip;
}

.elementor .brand-glow {
	inset-inline-start: -260px;
	inset-block-start: -73px;
}

.elementor .section-ink .brand-glow {
	inset-inline-start: auto;
	inset-inline-end: -260px;
	inset-block-start: 78px;
}

.elementor .contact-split .brand-glow {
	inset-block-start: 248px;
}

/* An empty div is what every rule, scrim and photo placeholder on this build
   is; Elementor otherwise drops a min-height placeholder into it. */
.e-atomic-element.brand-glow:has(> .elementor-empty-view),
.e-atomic-element.about-story__photo:has(> .elementor-empty-view),
.e-atomic-element.about-story__backdrop:has(> .elementor-empty-view),
.e-atomic-element.team-card__media:has(> .elementor-empty-view),
.e-atomic-element.mv-rule:has(> .elementor-empty-view),
.e-atomic-element.mv-pillar__icon:has(> .elementor-empty-view),
.e-atomic-element.team-label__rule:has(> .elementor-empty-view),
.e-atomic-element.hero-accent-rule:has(> .elementor-empty-view),
.e-atomic-element.contact-info__icon:has(> .elementor-empty-view),
.e-atomic-element.contact-info__rule:has(> .elementor-empty-view),
.e-atomic-element.cf-rule:has(> .elementor-empty-view) {
	min-height: 0;
}

.e-atomic-element.brand-glow > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.about-story__photo > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.about-story__backdrop > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.team-card__media > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.mv-rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.mv-pillar__icon > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.team-label__rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.hero-accent-rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.contact-info__icon > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.contact-info__rule > .elementor-empty-view.elementor-empty-view,
.e-atomic-element.cf-rule > .elementor-empty-view.elementor-empty-view {
	display: none;
}

/* The manager row is the one place on the site that still shows unwritten
   copy. Mark it so nobody mistakes it for finished content. */
.elementor .placeholder-flag {
	padding: 10px 14px;
	border-radius: 4px;
	border-left: 3px solid #C9A227;
	background-color: rgba(201, 162, 39, 0.08);
	color: #6B5A18;
}

/* ==========================================================================
   GUIDE PAGES — list semantics without list decoration
   The checklists, firm rails and scheme bullets are real <ul>/<li> so they
   announce as lists, but they carry their own tick, pill or dot. The class
   API cannot set list-style, so the browser default marker and indent are
   removed here.
   ========================================================================== */

.elementor .req-grid,
.elementor .firm-wrap,
.elementor .firm-list,
.elementor .scheme-bullets {
	list-style: none;
	padding-inline-start: 0;
	margin-block: 0;
}

.elementor .req-grid > li,
.elementor .firm-wrap > li,
.elementor .firm-list > li,
.elementor .scheme-bullets > li {
	list-style: none;
}

.elementor .req-grid > li::marker,
.elementor .firm-wrap > li::marker,
.elementor .firm-list > li::marker,
.elementor .scheme-bullets > li::marker {
	content: "";
}

/* The jump-to rail is a row of in-page links; give the current target and
   hover a visible state the class API has no room for. */
.elementor .jump-nav__link:hover,
.elementor .jump-nav__link:focus-visible {
	background-color: #405BA9;
	border-color: #405BA9;
	color: #FFFFFF;
}

.elementor .firm-pill:hover {
	border-color: #B9C4DE;
}

/* Scroll-margin so an anchored section is not hidden under the fixed header.

   This used to name the Buyer's Guide's five ids one by one, which meant every
   page that gained a jump nav landed its first line under the masthead until
   somebody remembered to extend the list. It is keyed on the band classes
   instead: `scroll-margin` does nothing at all unless the element is actually
   scrolled to, so covering every band costs nothing and cannot be forgotten.

   The offset is the same `--sticky-offset` the sticky columns use, so "clear the
   header" is one number in one place — and it already accounts for the admin
   bar, which the flat 96px did not. */
.elementor [id]:is(
	.page-section,
	.page-section-tinted,
	.page-section-tall,
	.page-section-feature,
	.stat-band,
	.section-ink,
	.midcta,
	.contact-cta,
	.final-cta
) {
	scroll-margin-top: var(--sticky-offset);
}

/* ==========================================================================
   NEWS & EVENTS
   The category rail comes from a shortcode, and Elementor's sanitiser strips
   every class from shortcode output — so the chips are selected by element
   and the current one by the <strong> the shortcode nests inside its link.
   ========================================================================== */

.elementor .news-filter__rail {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.elementor .news-filter__rail a {
	display: inline-flex;
	align-items: center;
	padding: 9px 16px;
	border: 1px solid #E3DFD7;
	border-radius: 999px;
	background-color: #FFFFFF;
	color: #0B1020;
	font-size: 13px;
	font-weight: 500;
	line-height: 20px;
	text-decoration: none;
	transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

.elementor .news-filter__rail a:hover,
.elementor .news-filter__rail a:focus-visible {
	border-color: #B9C4DE;
	background-color: #F7F9FD;
}

/* The current category. `strong` is the only hook the sanitiser leaves. */
.elementor .news-filter__rail a:has(strong) {
	background-color: #405BA9;
	border-color: #405BA9;
	color: #FFFFFF;
}

.elementor .news-filter__rail a strong {
	font-weight: 500;
}

/* Cards are whole-card links; lift them a little so the target reads as one. */
.elementor .news-card,
.elementor .news-featured {
	transition: transform .18s ease, box-shadow .18s ease;
}

.elementor .news-card:hover {
	transform: translateY(-2px);
	box-shadow: 0 12px 26px rgba(13, 20, 51, 0.1);
}

.elementor .news-card:hover .news-card__title,
.elementor .news-featured:hover .news-featured__title {
	color: #405BA9;
}

.elementor .news-featured:hover .news-featured__title {
	color: #8FDCF2;
}

.elementor .news-card:focus-visible,
.elementor .news-featured:focus-visible {
	outline: 3px solid #405BA9;
	outline-offset: 3px;
}

/* An excerpt that runs long would push the date out of alignment across a row. */
.elementor .news-card__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.elementor .news-featured__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.e-atomic-element.news-featured__scrim:has(> .elementor-empty-view),
.e-atomic-element.news-card__media:has(> .elementor-empty-view) {
	min-height: 0;
}

.e-atomic-element.news-featured__scrim > .elementor-empty-view.elementor-empty-view {
	display: none;
}

/* Careers: the hero trust chips and the job rail are real lists. */
.elementor .hero-chips,
.elementor .job-row,
.elementor .benefit-row {
	list-style: none;
	padding-inline-start: 0;
	margin-block: 0;
}

.elementor .hero-chips > li::marker { content: ""; }

.elementor .job-card__apply:hover,
.elementor .job-card__apply:focus-visible {
	background-color: #405BA9;
	color: #FFFFFF;
}

/* The Apply button should sit on the card's bottom edge however long the
   description runs, so a row of cards lines up. */
.elementor .job-card__apply {
	margin-block-start: auto;
}

/* A post with no featured image still renders the <img>, with no src. Hide it
   so the card falls back to the placeholder underneath instead of showing a
   broken-image glyph. Two posts have no image in their content at all. */
.elementor .news-card__photo:not([src]),
.elementor .news-card__photo[src=""],
.elementor .news-featured__photo:not([src]),
.elementor .news-featured__photo[src=""] {
	display: none;
}

/* ==========================================================================
   OUR TEAM — loop over the team_member CPT
   Five of six leadership portraits exist; the president's and all four
   manager photos do not. An ACF image field with no value still renders an
   <img> with no src, so hide it and let the card's placeholder show through.
   ========================================================================== */

.elementor .team-card__photo:not([src]),
.elementor .team-card__photo[src=""] {
	display: none;
}

/* The manager cards carry a contact address under the department. None are
   known yet, so the line collapses rather than leaving a gap. */
.elementor .team-card__email:empty {
	display: none;
}

.elementor .team-card__email a {
	color: inherit;
	text-decoration: none;
}

.elementor .team-card__email a:hover,
.elementor .team-card__email a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* The media box is the positioning context for the portrait. */
.elementor .team-card__media {
	position: relative;
	overflow: hidden;
}

.e-atomic-element.team-card__media:has(> .elementor-empty-view) {
	min-height: 0;
}

/* The company team photo was dropped INSIDE the placeholder card rather than
   replacing it, so it rendered at its natural size on top of the placeholder
   icon. Make any image placed in that card fill it, and retire the icon once a
   real one is there — so the card works whether or not a photo has been set. */
.elementor .about-story__photo.about-story__photo {
	overflow: hidden;
}

.elementor .about-story__photo.about-story__photo img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	margin: 0;
}

.elementor .about-story__photo.about-story__photo:has(img[src]) {
	background-image: none;
}

/* The team rows are classic Loop Grids now, so their gutter comes from
   Elementor's grid defaults — 30px columns — not from the 24px the rest of the
   page uses. The widget exposes a row gap control but no column one, so it is
   set here. */
.elementor .about-team__stack .elementor-loop-container {
	--grid-column-gap: 24px;
	column-gap: 24px;
}

@media (max-width: 767px) {

	.elementor .about-team__stack .elementor-loop-container {
		--grid-column-gap: 16px;
		column-gap: 16px;
	}
}

/* A Loop Item document wraps each card in .elementor.e-loop-item; the card
   must fill that wrapper so a row of cards stays level. */
.elementor .about-team__stack .e-loop-item,
.elementor .about-team__stack .e-loop-item > .team-card-loop {
	height: 100%;
}

/* The stack is a flex column with align-items:flex-start, so a child sizes to
   its content rather than stretching. The atomic loop carried width:100% in
   its own class; the Loop Grid widget has no such class, so the 3-column row
   settled at 993px inside a 1233px stack while the 4-column row filled it. */
.elementor .about-team__stack > .elementor-widget-loop-grid {
	width: 100%;
	align-self: stretch;
}

/* ==========================================================================
   HOME LOOPS — classic Loop Grid
   These five loops moved from the atomic collection loop to Elementor's Loop
   Grid so their cards render in the editor canvas. Two consequences:

   1. The loop's own global class is now applied as a plain `_css_classes`
      string, so Elementor no longer emits that class's CSS — every rule it
      carried has to live here.
   2. The layout moved from the loop's layout class to Elementor's
      `.elementor-loop-container`, which ships its own uniform grid. The
      original templates are restored below; the developments row in
      particular is NOT a uniform 3-up.
   ========================================================================== */

/* --- the widgets themselves (was each loop's own class) ------------------ */
.elementor .development-loop,
.elementor .model-loop {
	width: 100%;
	min-width: 0;
	flex: 1 1 100%;
}

.elementor .news-loop {
	width: 100%;
}

/* The FAQ loop sits beside a sticky column; without its flex basis it took
   the full row and overlapped the heading. */
.elementor .faq-accordion {
	width: 100%;
	min-width: 0;
	display: flex;
	flex-direction: column;
	flex: 672 1 0;
}

.elementor .testimonial-slider {
	width: 100%;
	overflow: hidden;
	position: relative;
	padding: 0;
	display: block;
}

/* --- the layouts (was each loop's __layout class) ------------------------ */
/* The developments row is a REEL, not a grid — see "The locations reel" at the
   foot of this file. It was a bespoke 768fr/456fr two-row grid showing three
   hand-picked locations; it now scrolls through every location that has homes
   in it, so a uniform card is the only shape that works. */
.elementor .dev-loop-grid .elementor-loop-container {
	display: grid;
	grid-auto-flow: column;
	grid-template-columns: none;
	grid-template-rows: none;
	grid-auto-columns: 396px;   /* 3 x 396 + 2 x 30 = 1248, the site measure */
	/* 480 matches the home-types cards further down the same page, so the two
	   card rows on the homepage share a height. Raised from 340 on 2026-10-05. */
	grid-auto-rows: 480px;
	gap: 30px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	/* The card lifts 4px and casts a 56px shadow on hover. `overflow-x: auto`
	   makes the track a scroll container on BOTH axes — `overflow-y: visible`
	   is not honoured next to it — so without room inside the box the lift and
	   the shadow are clipped. The negative margin takes the room back out of
	   the layout, so the band's spacing is unchanged. */
	padding-block: 8px 24px;
	margin-block: -8px -24px;
	counter-reset: development;
}

.elementor .dev-loop-grid .elementor-loop-container::-webkit-scrollbar {
	display: none;
}

.elementor .dev-loop-grid .e-loop-item {
	min-width: 0;
	scroll-snap-align: start;
	/* 01, 02, 03 … The original counter was scoped to `development-loop__item`,
	   a class from the hand-built markup that the Loop Grid conversion left
	   behind — nothing incremented any more and every badge rendered `00`. */
	counter-increment: development;
}

.elementor .mdl-loop-grid .elementor-loop-container {
	display: grid;
	gap: 20px;
	grid-template-columns: repeat(4, 1fr);
	grid-auto-rows: auto;
	align-items: stretch;
}

.elementor .news-loop-grid .elementor-loop-container,
.elementor .faq-loop-grid .elementor-loop-container {
	display: grid;
	gap: 0;
	grid-template-columns: 1fr;
	grid-auto-rows: auto;
	align-items: start;
}

/* The slider's track. Transform is animated, so the items must not wrap. */
.elementor .testimonial-slider .elementor-loop-container {
	width: 100%;
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	gap: 0;
	align-items: stretch;
	padding: 0;
	transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.elementor .testimonial-slider .elementor-loop-container > .e-loop-item {
	flex: 0 0 100%;
	min-width: 100%;
}

@media (max-width: 1365px) {

	.elementor .mdl-loop-grid .elementor-loop-container {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 767px) {

	/* Card size for this breakpoint is set with the rest of the reel chrome at
	   the foot of this file. A `max-width: 1365px` rule lives there, later in
	   source order and at the same specificity, so a size declared here was
	   silently overridden — the card rendered 360px wide inside a 335px
	   viewport. Only the properties the laptop rule does not touch stay here. */

	/* Two up, not one. A single column gave each card the full 335px measure,
	   so four models cost four screens of scrolling and the section read as a
	   list rather than a range to compare. The Communities index and the
	   taxonomy archives were already 2-up at this width; this is the odd one
	   out being brought into line. */
	.elementor .mdl-loop-grid .elementor-loop-container {
		gap: 12px;
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ==========================================================================
   WHY SO MANY DOUBLED CLASSES (`.final-cta.final-cta`)

   Elementor emits a global class as `.the-class` and a per-element local style
   as `.elementor .e-xxxxxxxx` — (0,1,0) and (0,2,0). An override written as
   `.elementor .the-class` is also (0,2,0), so against a local style it is a TIE
   broken by source order.

   On the front end style.css is enqueued at priority 20 and lands at #18, after
   every Elementor stylesheet, so the tie falls our way and everything looks
   right. IN THE EDITOR CANVAS Elementor injects its CSS after ours and the tie
   flips: the About closing CTA kept its navy ground and its photograph in the
   builder while rendering white on the site (reported 2026-10-05).

   Doubling the class makes the override (0,3,0), which wins on specificity in
   both contexts and cannot be unseated by load order. It is only needed where
   the override targets a property the global class ITSELF sets — a descendant
   rule like `.elementor .final-cta .display-m-inverse` is already (0,3,0) and
   was never affected, which is why the heading was the right colour in the
   builder while the band behind it was not.
   ========================================================================== */

/* ==========================================================================
   CTA BANDS ON WHITE  (Figma revision, 2026-10-05)
   The closing CTA and the Home "get in touch" band were photo + navy wash.
   Jun: the site carried too much blue. They are white grounds now.

   Scoped to the two bands on purpose: `button-primary`, `button-secondary`,
   `display-m` and `eyebrow-accent` are all shared with the heroes, which still
   sit on photographs. Changing the global classes would strip those too.

   Specificity note: Elementor emits a per-element local style as
   `.elementor .e-xxxxxxxx` — the SAME (0,2,0) as a global class, winning only
   on order. A two-class override here (0,3,0) is what actually beats it; the
   Home heading is white from exactly such a local style.
   ========================================================================== */

.elementor .final-cta.final-cta,
.elementor .contact-cta.contact-cta {
	background-color: #FFFFFF;
	background-image: none;          /* retires the media-contact photograph */
}

.elementor .final-cta__overlay.final-cta__overlay,
.elementor .contact-cta__overlay.contact-cta__overlay {
	display: none;                   /* the navy wash over the photo */
}

/* --- the closing CTA, five pages ---------------------------------------- */
.elementor .final-cta.final-cta .eyebrow-plain {
	color: #405BA9;                  /* the old #8FDCF2 is unreadable on white */
}

.elementor .final-cta.final-cta .display-m-inverse {
	color: #0B1020;
}

.elementor .final-cta.final-cta .lead-inverse {
	color: #6B7285;
}

.elementor .final-cta.final-cta .button-primary {
	background-color: #405BA9;
	border-color: #405BA9;
	color: #FFFFFF;
}

.elementor .final-cta.final-cta .button-primary:hover,
.elementor .final-cta.final-cta .button-primary:focus-visible {
	background-color: #33498A;
	border-color: #33498A;
	color: #FFFFFF;
}

.elementor .final-cta.final-cta .button-secondary {
	background-color: rgba(0, 0, 0, 0);
	border-color: #405BA9;
	color: #405BA9;
}

.elementor .final-cta.final-cta .button-secondary:hover,
.elementor .final-cta.final-cta .button-secondary:focus-visible {
	background-color: #405BA9;
	color: #FFFFFF;
}

/* --- the Home "get in touch" band --------------------------------------- */

/* The eyebrow's leading rule is not CSS — the `eyebrow-accent` global class
   paints it as a 67x16 background image, `chapter-label-dark.png`, drawn in
   #8FDCF2 for a dark ground. On the white band that rule all but vanished and
   the mark beside it read as a stray cyan speck. `chapter-label-light.png` is
   the same artwork in #405BA9; it is copied into the theme as
   `chapter-label-navy.png` so the band does not depend on an uploads path. */
.elementor .contact-cta.contact-cta .eyebrow-accent {
	color: #405BA9;
	background-image: url('assets/motifs/chapter-label-navy.png');
}

.elementor .contact-cta.contact-cta .display-m {
	color: #0B1020;
}

.elementor .contact-cta.contact-cta .body-lead {
	color: #6B7285;
}

.elementor .contact-cta.contact-cta .contact-details {
	border-top-color: #E3DFD7;
}

.elementor .contact-cta.contact-cta .contact-details__item {
	color: #2A3145;
	opacity: 1;
}

/* The enquiry card is white; on a white band it needs an edge of its own. */
.elementor .contact-cta.contact-cta .enquiry-form {
	border: 1px solid #E3DFD7;
}

/* The map-pin motif is drawn in white strokes and would disappear. */
.elementor .contact-cta.contact-cta .motif-map-pin {
	background-image: url('assets/motifs/map-pin-navy.svg');
	opacity: 0.14;
}

/* ==========================================================================
   THE LOCATIONS REEL

   A horizontally scrolling strip of location cards, modelled on the pattern
   already proven on DigiPlus Careers ("Our Employee Activities").

   The strip itself is CSS — scroll-snap over a grid row — so it works with
   JavaScript off, on a trackpad, and under touch. All `site-reel.js` adds is
   the pair of buttons and the progress rail, both driven from the track's own
   `scrollLeft`, so adding a seventh location needs no change here. A reel with
   nothing to scroll marks itself `static` and the controls are hidden rather
   than shown dead.

   The track rules live with the other loop-grid layouts above, so the two
   cannot drift apart. What follows is only the chrome.
   ========================================================================== */

.elementor .sv-reel__nav {
	display: flex;
	justify-content: flex-end;
	gap: 12px;
	margin-block-start: 24px;
}

.elementor .sv-reel__btn {
	position: relative;
	width: 48px;
	height: 48px;
	padding: 0;
	border: 1px solid #E3DFD7;
	border-radius: 50%;
	background-color: #FFFFFF;
	cursor: pointer;
	transition: background-color 160ms ease, border-color 160ms ease,
		opacity 160ms ease;
}

/* The chevron is two borders on a rotated square — no icon font, no SVG. */
.elementor .sv-reel__btn::before {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 9px;
	height: 9px;
	margin: -5px 0 0 -3px;
	border-inline-end: 2px solid #6B7285;
	border-block-end: 2px solid #6B7285;
	transform: rotate(135deg);
}

.elementor .sv-reel__btn--next {
	border-color: #405BA9;
	background-color: #405BA9;
}

.elementor .sv-reel__btn--next::before {
	margin-inline-start: -6px;
	border-color: #FFFFFF;
	transform: rotate(-45deg);
}

@media (hover: hover) {

	.elementor .sv-reel__btn:not(:disabled):hover {
		border-color: #405BA9;
		background-color: #F2F5FB;
	}

	.elementor .sv-reel__btn--next:not(:disabled):hover {
		background-color: #33498A;
		border-color: #33498A;
	}
}

.elementor .sv-reel__btn:disabled {
	opacity: 0.45;
	cursor: default;
}

.elementor .sv-reel__btn:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 3px;
}

.elementor .sv-reel__rail {
	position: relative;
	height: 2px;
	margin-block-start: 22px;
	border-radius: 1px;
	background-color: #E3DFD7;
	overflow: hidden;
}

.elementor .sv-reel__thumb {
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	display: block;
	width: 75%;
	border-radius: 1px;
	background-color: #405BA9;
}

/* The track is a focusable scrolling region, so it needs a visible focus ring
   of its own — a keyboard user arrowing through the reel is otherwise left
   with no indication of where they are. */
.elementor .dev-loop-grid .elementor-loop-container:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 4px;
}

/* Nothing to scroll: no controls, rather than dead ones. */
.elementor [data-sv-reel="static"] .sv-reel__nav,
.elementor [data-sv-reel="static"] .sv-reel__rail {
	display: none;
}

/* Below the full measure the cards step down so three still fit the band. */
@media (max-width: 1365px) {

	.elementor .dev-loop-grid .elementor-loop-container {
		grid-auto-columns: 360px;
		gap: 24px;
	}
}

@media (max-width: 767px) {

	/* Must come after the 1365px rule above: same specificity, later wins. */
	.elementor .dev-loop-grid .elementor-loop-container {
		grid-auto-columns: 280px;
		grid-auto-rows: 400px;
		gap: 16px;
	}

	.elementor .sv-reel__nav {
		justify-content: flex-start;
		margin-block-start: 20px;
	}

	.elementor .sv-reel__btn {
		width: 44px;
		height: 44px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .dev-loop-grid .elementor-loop-container {
		scroll-behavior: auto;
	}
}

/* --------------------------------------------------------------------------
   Card badges — the availability chip and the location index

   Both were `rgba(255, 255, 255, 0.24)` with a white label. Over a dark
   photograph that reads; over a bright one — a white facade, a pale sky — the
   chip and its text both wash out to roughly #E8E8E8 on white, a ratio of
   1.23:1. The "09 AVAILABLE" label on the Townhouse card was invisible.

   Solid brand cyan #48C6E9 fixes the chip's own visibility on any photograph.

   The label is #0B1020, the same pairing the Enquire button uses, at 9.49:1.
   White on this cyan is 1.99:1 — worse than the washed-out chip it replaced —
   so it was tried and reverted on 2026-10-05. Do not reintroduce it.

   The two badges are the same component in two places, so they are corrected
   together — fixing only the one that was reported would leave the location
   cards with the identical defect.
   -------------------------------------------------------------------------- */
.elementor .model-card__availability.model-card__availability,
.elementor .development-card__index.development-card__index {
	background-color: #48C6E9;
	color: #0B1020;
}

/* --------------------------------------------------------------------------
   Card scrim — strengthened for real photography

   The approved gradient was tuned against the stock images the cards shipped
   with, which were dark. The locations now carry real Softouch photographs —
   white facades, bright Cebu skies — and measured against the actual composited
   pixels the old profile failed WCAG AA badly:

       11 PROPERTIES (12px #8FDCF2)   2.27:1   needs 4.5
       description   (15px #CBC5BA)   4.05:1   needs 4.5
       location name (30px #FFFFFF)   4.56:1   needs 3.0  (large text — passed)

   The profile below was solved for, not guessed: it is the lightest of five
   candidates that clears AA on every element of every card with headroom —

       11 PROPERTIES  5.96:1    description  6.84:1    name  9.95:1

   The first 24% of the card is still almost clear, so the photograph reads as
   a photograph; the compression is in the band where the text actually sits.

   `development-card__scrim` is shared with the home-types row, but those cards
   are 480px tall against the reel's 340px and their title sits at 77% rather
   than 56%, so this profile buries far more of their photograph than their text
   needs. The override is therefore scoped to the reel; the home-types row is
   measured separately below. Re-measure if the photography changes again.
   -------------------------------------------------------------------------- */
/* AT REST the scrim is held off the photograph as long as it possibly can be.
   The text block starts at 68% of a 480px card, so everything above that is
   free — the gradient is clear to 48% and only 34% at 57%, where the old
   profile was already 80%.

   This is the lightest of eight candidates that still clears AA. One step
   lighter (clear to 52%, 30% at 62%) drops the 12px eyebrow to 3.90:1, under
   the 4.5 it needs. That line is what sets the floor, not the heading. */
.elementor .dev-loop-grid .development-card__scrim {
	background-image: linear-gradient(
		180deg,
		rgba(22, 32, 60, 0) 0%,
		rgba(22, 32, 60, 0.02) 48%,
		rgba(22, 32, 60, 0.34) 57%,
		rgba(22, 32, 60, 0.80) 68%,
		rgba(22, 32, 60, 0.93) 100%
	);
}

/* ON HOVER the full wash comes in, so the card reads as a single dark panel
   the moment you point at it.

   `background-image` is not an animatable property — swapping it on the scrim
   snaps. The deep wash is therefore a second layer on the scrim's own
   `::after`, and what animates is its opacity, which crossfades. */
.elementor .dev-loop-grid .development-card__scrim::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: 0;
	transition: opacity 260ms ease;
	background-image: linear-gradient(
		180deg,
		rgba(22, 32, 60, 0) 0%,
		rgba(22, 32, 60, 0.22) 24%,
		rgba(22, 32, 60, 0.80) 48%,
		rgba(22, 32, 60, 0.97) 100%
	);
}

.elementor .dev-loop-grid .development-loop__card:hover .development-card__scrim::after,
.elementor .dev-loop-grid .development-loop__card:focus-visible .development-card__scrim::after {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .dev-loop-grid .development-card__scrim::after {
		transition: none;
	}
}

/* The reel is draggable with a mouse (site-reel.js); the cursor has to say so.
   `overscroll-behavior-x: contain` stops a swipe that runs off the end of the
   strip from triggering the browser's back gesture. */
.elementor .dev-loop-grid .elementor-loop-container {
	cursor: grab;
	overscroll-behavior-x: contain;
	-webkit-overflow-scrolling: touch;
}

/* A card is a link; it keeps its own pointer. */
.elementor .dev-loop-grid .development-loop__card {
	cursor: pointer;
}

/* --------------------------------------------------------------------------
   HERO RHYTHM — one top/bottom gap for every page

   `page-hero__body` is `flex: 1 1 auto` with `justify-content: center` inside a
   hero that carries a `min-height`. When the content is shorter than that
   min-height the slack splits evenly top and bottom, so the padding you declare
   is a floor, not the gap you get. Measured at 1496px, every page was different:

       /location/consolacion/   96 top / 48 bottom   (content fills 736px)
       /about-us/              126 top / 78 bottom   (60px of slack, split)
       /communities/            96 top / 156 bottom  (a pill-rail below the body)

   The declared padding was also asymmetric by design — 96/48 on desktop, a 2:1
   ratio. Squaring it off means the centred slack adds the same amount to each
   side, so top and bottom stay equal to one another on EVERY page, whatever the
   content height. The responsive ladder is kept; only the bottom value moves.

       desktop   96 / 48  ->  96 / 96
       <=1200    72 / 40  ->  72 / 72
       <=767     40 / 32  ->  40 / 40

   The top value is `calc(var(--masthead-height) + N)` because the header is
   `position: fixed` and overlays the hero, so the visible gap below the header
   is N — which is what has to match the bottom.

   KNOWN EXCEPTION: the Communities hero has a `pill-rail` AFTER the body, so its
   bottom gap is the rail's own 20px, not 96. That rail is a designed component,
   not padding drift.
   -------------------------------------------------------------------------- */
.elementor .page-hero__body.page-hero__body {
	padding-block-end: 96px;
}

@media (max-width: 1200px) {

	.elementor .page-hero__body.page-hero__body {
		padding-block-end: 72px;
	}
}

@media (max-width: 767px) {

	.elementor .page-hero__body.page-hero__body {
		padding-block-end: 40px;
	}
}

/* ==========================================================================
   HOME-TYPES HOVER PREVIEW

   Hovering a row in "Find a Home That Fits Your Family" floats a card on the
   right of the list, after the DigiPlus homepage routing rows.

   The panel is built by `assets/js/type-preview.js` and inserted as a SIBLING
   of the row — the row is an `<a>`, so a panel containing its own call to
   action cannot be nested inside it. Everything below is keyed off the row's
   wrapper, `.type-row-host`, which the script marks.

   The list only takes `type-index--has-preview` once a panel has actually been
   built, so the row shifts and the right-hand gutter only appear when there is
   something to reveal.
   ========================================================================== */

.elementor .type-index--has-preview {
	position: relative;
}

.elementor .type-row-host {
	position: relative;
}

/* The row's own "View homes" link sits where the panel lands, so it fades out
   as the panel comes in rather than showing through it. */
.elementor .type-row-host:hover .type-row__cta,
.elementor .type-row-host:hover .type-row__arrow {
	opacity: 0;
	transition: opacity 140ms ease;
}

.elementor .type-preview {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: 0;
	z-index: 3;
	width: 420px;
	overflow: hidden;
	transform: translateY(-50%) translateY(6px);
	border-radius: 4px;
	background-color: #FFFFFF;
	box-shadow: 0 18px 48px rgba(11, 16, 32, 0.28),
		0 2px 8px rgba(11, 16, 32, 0.12);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 180ms ease, transform 180ms ease,
		visibility 0s linear 180ms;
}

/* `:focus-within` carries the whole thing for keyboard users — tabbing onto the
   row reveals the same panel the mouse does. */
.elementor .type-row-host:hover .type-preview,
.elementor .type-row-host:focus-within .type-preview {
	opacity: 1;
	visibility: visible;
	transform: translateY(-50%);
	/* The panel is taller than the row it belongs to, so it covers its
	   neighbours. Without this it stays transparent to the pointer and moving
	   towards its button re-hovers whatever row is underneath — the panel
	   swaps out from under the cursor and the button cannot be reached. */
	pointer-events: auto;
	transition: opacity 180ms ease, transform 180ms ease;
}

/* The hovered row owns the stack while it is open, so its panel can never be
   painted under a later sibling's. */
.elementor .type-row-host:hover,
.elementor .type-row-host:focus-within {
	z-index: 4;
}

.elementor .type-preview__cta {
	text-decoration: none;
}

.elementor .type-preview__cta:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 3px;
}

.elementor .type-preview__media {
	display: block;
	width: 100%;
	height: 212px;
	object-fit: cover;
}

.elementor .type-preview__body {
	padding: 24px 28px 28px;
}

.elementor .type-preview__count {
	margin: 0;
	font-family: var(--font-primary);
	font-weight: 600;
	font-size: 12px;
	letter-spacing: 0.12em;
	line-height: 16px;
	text-transform: uppercase;
	color: #405BA9;
}

.elementor .type-preview__title {
	margin: 8px 0 0;
	font-family: var(--font-primary);
	font-weight: 600;
	font-size: 24px;
	letter-spacing: -0.01em;
	line-height: 32px;
	color: #0B1020;
}

.elementor .type-preview__summary {
	margin: 8px 0 0;
	font-family: var(--font-primary);
	font-weight: 400;
	font-size: 15px;
	line-height: 25px;
	color: #6B7285;
}

.elementor .type-preview__where {
	margin-block-start: 20px;
	padding-block-start: 18px;
	border-block-start: 1px solid #E3DFD7;
}

.elementor .type-preview__where-label {
	margin: 0;
	font-family: var(--font-primary);
	font-weight: 600;
	font-size: 11px;
	letter-spacing: 0.12em;
	line-height: 16px;
	text-transform: uppercase;
	color: #8A8F9C;
}

.elementor .type-preview__locations {
	margin: 10px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	list-style: none;
}

.elementor .type-preview__location {
	padding: 4px 10px;
	border: 1px solid #E3DFD7;
	border-radius: 999px;
	font-family: var(--font-primary);
	font-weight: 500;
	font-size: 13px;
	line-height: 18px;
	color: #2A3145;
}

/* Not a link — the whole row already is one, and a second interactive target
   saying the same thing is noise for anyone navigating by keyboard. */
.elementor .type-preview__cta {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	margin-block-start: 22px;
	padding: 11px 20px;
	border-radius: 4px;
	background-color: #405BA9;
	font-family: var(--font-primary);
	font-weight: 600;
	font-size: 14px;
	line-height: 20px;
	color: #FFFFFF;
	transition: background-color 160ms ease;
}

.elementor .type-row-host:hover .type-preview__cta {
	background-color: #33498A;
}

/* The arrow is a chevron plus a rule, drawn rather than shipped as an icon. */
.elementor .type-preview__cta-arrow {
	position: relative;
	width: 16px;
	height: 2px;
	background-color: currentColor;
}

.elementor .type-preview__cta-arrow::after {
	content: "";
	position: absolute;
	inset-inline-end: 0;
	inset-block-start: 50%;
	width: 7px;
	height: 7px;
	border-inline-end: 2px solid currentColor;
	border-block-start: 2px solid currentColor;
	transform: translateY(-50%) rotate(45deg);
}

/* Below the measure the panel would cover the row it describes, so it is not
   built at all — the script checks `(hover: hover)` too, which rules out
   touch devices, where a panel would swallow the first tap on a real link. */
@media (max-width: 1200px) {

	.elementor .type-preview {
		display: none;
	}

	.elementor .type-row-host:hover .type-row__cta,
	.elementor .type-row-host:hover .type-row__arrow {
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .type-preview {
		transform: translateY(-50%);
		transition: opacity 180ms ease, visibility 0s linear 180ms;
	}
}

/* Tablet keeps the enlarged lock-up in proportion. The global class sets
   132x44 here; without this the logo would jump down a third at 1024px. */
@media (min-width: 768px) and (max-width: 1024px) {

	.elementor .site-masthead {
		padding-block: 21px;
	}

	.elementor .site-masthead .site-logo {
		width: 162px;
		height: 54px;
	}

	.elementor .site-masthead.is-scrolled .site-logo {
		width: 132px;
		height: 44px;
	}
}

/* ==========================================================================
   NEVER TWO DARK BANDS IN A ROW

   On Communities, Track Record and Footprint are both `section-ink`, so the
   page ran two full-height navy gradients back to back and read as one very
   heavy block.

   Rather than hard-code "make Track Record light", the rule is written as what
   it actually is: an ink band immediately followed by another ink band gives
   way. `:has(+ .section-ink)` means the page self-corrects if the sections are
   ever reordered, and a third ink band inserted between them would be caught
   too. Footprint keeps the dark ground because its map is drawn in pale
   strokes meant for it.

   Everything inside the band is built for a dark ground, so the whole set has
   to invert with it — figure, label, note, the hairlines between cells, and
   the eyebrow's artwork, which is a background PNG and not a colour.
   ========================================================================== */
.elementor .section-ink:has(+ .section-ink) {
	background-image: linear-gradient(180deg, #FAF8F5 0%, #EFF3FA 100%);
	background-color: #FAF8F5;
}

.elementor .section-ink:has(+ .section-ink) .eyebrow-inverse {
	color: #646B7D;
	background-image: url('assets/motifs/chapter-label-navy.png');
}

.elementor .section-ink:has(+ .section-ink) .ink-title {
	color: #0B1020;
}

/* The band is a gradient, so a muted grey has to clear AA against BOTH stops.
   The house #6B7285 is 4.53:1 on #FAF8F5 at the top but only 4.32:1 on
   #EFF3FA at the bottom, where the notes sit. #646B7D clears both (5.03 /
   4.79) and is the smallest step that does. */
.elementor .section-ink:has(+ .section-ink) .ink-lead {
	color: #646B7D;
}

.elementor .section-ink:has(+ .section-ink) .stat-cell__figure {
	color: #0B1020;
}

/* #8FDCF2 is 1.9:1 on this ground. #405BA9 is the blue the site already uses
   for a label on white, at 6.4:1. */
.elementor .section-ink:has(+ .section-ink) .stat-cell__label {
	color: #405BA9;
}

.elementor .section-ink:has(+ .section-ink) .stat-cell__note {
	color: #646B7D;
}

.elementor .section-ink:has(+ .section-ink) .stat-cell {
	border-inline-start-color: #E3DFD7;
	border-block-start-color: #E3DFD7;
}

/* The column rules are drawn in white at 7% for the dark bands. */
.elementor .section-ink:has(+ .section-ink).has-column-rules::before {
	background-image: repeating-linear-gradient(
		to right,
		rgba(11, 16, 32, 0.055) 0 1px,
		rgba(0, 0, 0, 0) 1px 208px
	);
}

/* ==========================================================================
   GRADIENT-RING CARDS

   A white card with a brand-blue gradient hairline that comes up to full
   strength on hover. Used by the closing CTA (`final-cta__inner`, on
   Communities / Buyer's / Seller's / News / About) and by the benefit cards
   (`benefit-card`, on Seller's and Careers).

   The border is a MASKED RING, not a `border-image` — `border-image` cannot
   follow a `border-radius`. `padding` on the pseudo-element sets the ring's
   weight and the mask punches the middle out, so only that band of the
   gradient paints.

   Two rings are stacked, the resting one and the saturated one, and the hover
   crossfades them by opacity: a `background-image` swap is not animatable and
   would snap.

   Each card sets `--ring` for its own weight; `border-radius: inherit` on the
   ring means a 4px card and a 16px card both work with no per-card rule.

   WHAT IS IN: the closing CTA and the things that read as cards —
   `apply-step`, `benefit-card`, `facts-card`, `filter-panel`, `glance-card`,
   `job-card`, `notice`, `pillar`, `pull-quote`, `scheme-card`, `step-card`,
   `team-card-loop`, `upside-card`.

   WHAT IS DELIBERATELY OUT, and why:

   - buttons (`button-outline`, `button-secondary`, `job-card__apply`) — they
     have their own hover state and two competing ones fight;
   - form fields (`cf-input`, `cf-select`, `cf-textarea`, the `e-form-*` base
     classes) — a field's border carries focus and validation meaning, which a
     decorative gradient would drown;
   - chips and pills (`cf-chip`, `firm-pill`, `glass-chip`, `hero-chip`,
     `jump-nav__link`, `pill`, `spec-chip`) — too small to read as anything but
     noise, and several are filters where the border signals state;
   - anything on a dark band (`footprint__map`, `rto-panel`, `social-link`,
     `placeholder-flag`) — their borders are white at 24% and a blue gradient
     disappears against navy;
   - Elementor's own widget internals (`e-pagination-*`, `elementor-widget-n-*`).

   If a new card needs the ring, add its class to the five selector lists below
   — they must stay in step.
   ========================================================================== */
.elementor .final-cta__inner.final-cta__inner,
.elementor .benefit-card.benefit-card,
.elementor .apply-step.apply-step,
.elementor .facts-card.facts-card,
.elementor .filter-panel.filter-panel,
.elementor .glance-card.glance-card,
.elementor .job-card.job-card,
.elementor .notice.notice,
.elementor .pillar.pillar,
.elementor .pull-quote.pull-quote,
.elementor .scheme-card.scheme-card,
.elementor .step-card.step-card,
.elementor .team-card-loop.team-card-loop,
.elementor .upside-card.upside-card {
	position: relative;
	transition: box-shadow 240ms ease;
}

.elementor .final-cta__inner.final-cta__inner,
.elementor .benefit-card.benefit-card {
	background-color: #FFFFFF;
}

/* Every card in this set already carried a flat 1px #E3DFD7 (or #DCE7F0)
   hairline. It is kept at its own width so nothing reflows, and made
   transparent — the ring replaces it. `team-card-loop` had no border at all,
   so there it is new definition rather than a replacement. */
.elementor .apply-step.apply-step,
.elementor .facts-card.facts-card,
.elementor .filter-panel.filter-panel,
.elementor .glance-card.glance-card,
.elementor .job-card.job-card,
.elementor .notice.notice,
.elementor .pillar.pillar,
.elementor .pull-quote.pull-quote,
.elementor .scheme-card.scheme-card,
.elementor .step-card.step-card,
.elementor .team-card-loop.team-card-loop,
.elementor .upside-card.upside-card {
	--ring: 1.5px;
	border-color: rgba(0, 0, 0, 0);
}

.elementor .final-cta__inner.final-cta__inner {
	--ring: 2px;
	padding: 56px 64px;
	border-radius: 12px;
	box-shadow: 0 2px 6px rgba(11, 16, 32, 0.05),
		0 16px 40px rgba(11, 16, 32, 0.08);
}

/* The cards carried a flat 1px #E3DFD7 border. It is kept at the same width so
   nothing reflows, but made transparent — the ring replaces it. */
.elementor .benefit-card.benefit-card {
	--ring: 1.5px;
	border-color: rgba(0, 0, 0, 0);
	box-shadow: 0 1px 3px rgba(11, 16, 32, 0.04),
		0 10px 26px rgba(11, 16, 32, 0.06);
}

.elementor .final-cta__inner.final-cta__inner:hover {
	box-shadow: 0 4px 10px rgba(11, 16, 32, 0.07),
		0 22px 56px rgba(11, 16, 32, 0.13);
}

.elementor .benefit-card.benefit-card:hover {
	box-shadow: 0 2px 6px rgba(11, 16, 32, 0.06),
		0 16px 38px rgba(11, 16, 32, 0.10);
}

.elementor .final-cta__inner.final-cta__inner::before,
.elementor .final-cta__inner.final-cta__inner::after,
.elementor .benefit-card.benefit-card::before,
.elementor .benefit-card.benefit-card::after,
.elementor .apply-step.apply-step::before,
.elementor .apply-step.apply-step::after,
.elementor .facts-card.facts-card::before,
.elementor .facts-card.facts-card::after,
.elementor .filter-panel.filter-panel::before,
.elementor .filter-panel.filter-panel::after,
.elementor .glance-card.glance-card::before,
.elementor .glance-card.glance-card::after,
.elementor .job-card.job-card::before,
.elementor .job-card.job-card::after,
.elementor .notice.notice::before,
.elementor .notice.notice::after,
.elementor .pillar.pillar::before,
.elementor .pillar.pillar::after,
.elementor .pull-quote.pull-quote::before,
.elementor .pull-quote.pull-quote::after,
.elementor .scheme-card.scheme-card::before,
.elementor .scheme-card.scheme-card::after,
.elementor .step-card.step-card::before,
.elementor .step-card.step-card::after,
.elementor .team-card-loop.team-card-loop::before,
.elementor .team-card-loop.team-card-loop::after,
.elementor .upside-card.upside-card::before,
.elementor .upside-card.upside-card::after {
	content: "";
	position: absolute;
	inset: 0;
	/* ABOVE the content, not behind it. Card children are `position: relative`
	   with `z-index: auto` — the team card's photo is one — so they paint in the
	   same layer as a `z-index: 0` ring but later in DOM order and cover it. The
	   ring vanished along the top and sides of every team photo while still
	   showing against the white body below. A border belongs on top anyway, and
	   the mask means only a 1.5px band at the very edge ever paints over
	   anything. */
	z-index: 3;
	padding: var(--ring, 2px);
	border-radius: inherit;
	pointer-events: none;
	-webkit-mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	mask-composite: exclude;
}

/* At rest: the brand gradient at just over half strength — present, not loud. */
.elementor .final-cta__inner.final-cta__inner::before,
.elementor .benefit-card.benefit-card::before,
.elementor .apply-step.apply-step::before,
.elementor .facts-card.facts-card::before,
.elementor .filter-panel.filter-panel::before,
.elementor .glance-card.glance-card::before,
.elementor .job-card.job-card::before,
.elementor .notice.notice::before,
.elementor .pillar.pillar::before,
.elementor .pull-quote.pull-quote::before,
.elementor .scheme-card.scheme-card::before,
.elementor .step-card.step-card::before,
.elementor .team-card-loop.team-card-loop::before,
.elementor .upside-card.upside-card::before {
	background-image: linear-gradient(
		135deg,
		rgba(72, 198, 233, 0.55) 0%,
		rgba(64, 91, 169, 0.55) 100%
	);
}

/* On hover the ring comes up to full strength AND starts travelling.

   A `conic-gradient` is what makes it travel: its `from` angle is rotated a
   full turn, so the colour stops chase each other round the perimeter rather
   than sliding across it, which is what a linear gradient would do.

   `--sv-ring-angle` has to be REGISTERED with `@property` or it is just a
   string to the animation engine and the keyframes jump from 0 to 360 with
   nothing in between. Where `@property` is unsupported the ring still appears
   at full strength on hover and simply does not rotate — the affordance
   survives, only the flourish is lost.

   Four stops rather than two so the cyan passes twice per turn; with a single
   cyan band a wide box like the CTA can look static for most of the sweep.

   ONE sweep, not a loop. A ring going round forever pulls the eye away from the
   thing it is meant to be pointing at, and on a page with four of these side by
   side it would never settle. The easing is the site's own
   `cubic-bezier(.22,.61,.36,1)`, so the sweep arrives rather than stopping
   dead. Re-entering the card restarts it, because dropping `:hover` drops the
   animation entirely. */
@property --sv-ring-angle {
	syntax: "<angle>";
	inherits: false;
	initial-value: 0deg;
}

@keyframes sv-ring-run {
	to {
		--sv-ring-angle: 360deg;
	}
}

.elementor .final-cta__inner.final-cta__inner::after,
.elementor .benefit-card.benefit-card::after,
.elementor .apply-step.apply-step::after,
.elementor .facts-card.facts-card::after,
.elementor .filter-panel.filter-panel::after,
.elementor .glance-card.glance-card::after,
.elementor .job-card.job-card::after,
.elementor .notice.notice::after,
.elementor .pillar.pillar::after,
.elementor .pull-quote.pull-quote::after,
.elementor .scheme-card.scheme-card::after,
.elementor .step-card.step-card::after,
.elementor .team-card-loop.team-card-loop::after,
.elementor .upside-card.upside-card::after {
	opacity: 0;
	transition: opacity 240ms ease;
	background-image: conic-gradient(
		from var(--sv-ring-angle),
		#405BA9 0%,
		#48C6E9 15%,
		#405BA9 35%,
		#405BA9 50%,
		#48C6E9 65%,
		#405BA9 85%,
		#405BA9 100%
	);
}

.elementor .final-cta__inner.final-cta__inner:hover::after,
.elementor .final-cta__inner.final-cta__inner:focus-within::after,
.elementor .benefit-card.benefit-card:hover::after,
.elementor .benefit-card.benefit-card:focus-within::after,
.elementor .apply-step.apply-step:hover::after,
.elementor .apply-step.apply-step:focus-within::after,
.elementor .facts-card.facts-card:hover::after,
.elementor .facts-card.facts-card:focus-within::after,
.elementor .filter-panel.filter-panel:hover::after,
.elementor .filter-panel.filter-panel:focus-within::after,
.elementor .glance-card.glance-card:hover::after,
.elementor .glance-card.glance-card:focus-within::after,
.elementor .job-card.job-card:hover::after,
.elementor .job-card.job-card:focus-within::after,
.elementor .notice.notice:hover::after,
.elementor .notice.notice:focus-within::after,
.elementor .pillar.pillar:hover::after,
.elementor .pillar.pillar:focus-within::after,
.elementor .pull-quote.pull-quote:hover::after,
.elementor .pull-quote.pull-quote:focus-within::after,
.elementor .scheme-card.scheme-card:hover::after,
.elementor .scheme-card.scheme-card:focus-within::after,
.elementor .step-card.step-card:hover::after,
.elementor .step-card.step-card:focus-within::after,
.elementor .team-card-loop.team-card-loop:hover::after,
.elementor .team-card-loop.team-card-loop:focus-within::after,
.elementor .upside-card.upside-card:hover::after,
.elementor .upside-card.upside-card:focus-within::after {
	opacity: 1;
	animation: sv-ring-run 820ms cubic-bezier(0.22, 0.61, 0.36, 1) 1 forwards;
}

/* The small cards sweep quicker so the two read as the same speed — the same
   angular rate travels a much shorter perimeter on a 290px card than on the
   1217px CTA. */
.elementor .benefit-card.benefit-card:hover::after,
.elementor .benefit-card.benefit-card:focus-within::after,
.elementor .apply-step.apply-step:hover::after,
.elementor .apply-step.apply-step:focus-within::after,
.elementor .facts-card.facts-card:hover::after,
.elementor .facts-card.facts-card:focus-within::after,
.elementor .filter-panel.filter-panel:hover::after,
.elementor .filter-panel.filter-panel:focus-within::after,
.elementor .glance-card.glance-card:hover::after,
.elementor .glance-card.glance-card:focus-within::after,
.elementor .job-card.job-card:hover::after,
.elementor .job-card.job-card:focus-within::after,
.elementor .notice.notice:hover::after,
.elementor .notice.notice:focus-within::after,
.elementor .pillar.pillar:hover::after,
.elementor .pillar.pillar:focus-within::after,
.elementor .pull-quote.pull-quote:hover::after,
.elementor .pull-quote.pull-quote:focus-within::after,
.elementor .scheme-card.scheme-card:hover::after,
.elementor .scheme-card.scheme-card:focus-within::after,
.elementor .step-card.step-card:hover::after,
.elementor .step-card.step-card:focus-within::after,
.elementor .team-card-loop.team-card-loop:hover::after,
.elementor .team-card-loop.team-card-loop:focus-within::after,
.elementor .upside-card.upside-card:hover::after,
.elementor .upside-card.upside-card:focus-within::after {
	animation-duration: 620ms;
}

@media (max-width: 1200px) {

	.elementor .final-cta__inner.final-cta__inner {
		padding: 44px 40px;
	}
}

@media (max-width: 767px) {

	.elementor .final-cta__inner.final-cta__inner {
		padding: 32px 24px;
		border-radius: 10px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .final-cta__inner.final-cta__inner,
	.elementor .final-cta__inner.final-cta__inner::after,
	.elementor .benefit-card.benefit-card,
	.elementor .benefit-card.benefit-card::after,
	.elementor .apply-step.apply-step::after,
	.elementor .facts-card.facts-card::after,
	.elementor .filter-panel.filter-panel::after,
	.elementor .glance-card.glance-card::after,
	.elementor .job-card.job-card::after,
	.elementor .notice.notice::after,
	.elementor .pillar.pillar::after,
	.elementor .pull-quote.pull-quote::after,
	.elementor .scheme-card.scheme-card::after,
	.elementor .step-card.step-card::after,
	.elementor .team-card-loop.team-card-loop::after,
	.elementor .upside-card.upside-card::after {
		transition: none;
	}

	/* The ring still brightens on hover; it just stops going round. */
	.elementor .final-cta__inner.final-cta__inner:hover::after,
	.elementor .final-cta__inner.final-cta__inner:focus-within::after,
	.elementor .benefit-card.benefit-card:hover::after,
	.elementor .benefit-card.benefit-card:focus-within::after,
	.elementor .apply-step.apply-step:hover::after,
	.elementor .facts-card.facts-card:hover::after,
	.elementor .filter-panel.filter-panel:hover::after,
	.elementor .glance-card.glance-card:hover::after,
	.elementor .job-card.job-card:hover::after,
	.elementor .notice.notice:hover::after,
	.elementor .pillar.pillar:hover::after,
	.elementor .pull-quote.pull-quote:hover::after,
	.elementor .scheme-card.scheme-card:hover::after,
	.elementor .step-card.step-card:hover::after,
	.elementor .team-card-loop.team-card-loop:hover::after,
	.elementor .upside-card.upside-card:hover::after {
		animation: none;
	}
}

/* ==========================================================================
   ABOUT — the group photograph was being cropped 39%

   `about-story__photo` was a fixed 440x480 box (ratio 0.917) holding a
   1424x949 landscape photograph (ratio 1.501) under `object-fit: cover`.
   Measured: **38.9% of the image width was cut**, ~19.5% off each side, which
   is precisely where the people at the ends of the group were standing.

   The box now takes the photograph's own ratio instead of the other way round,
   and the copy column gives up 60px so the picture has somewhere to go.

   The photo also comes out of absolute positioning so it DRIVES the media
   column's height — otherwise the column keeps its old fixed 520px and leaves
   a gap under a now-shorter picture, at every breakpoint separately. The
   backdrop stays absolute, offset 40px, and the column pads 40px at the foot
   so that offset is contained rather than overlapping the next band.
   ========================================================================== */
@media (min-width: 1025px) {

	.elementor .about-story__col.about-story__col {
		flex-basis: 540px;
	}
}

.elementor .about-story__media.about-story__media {
	height: auto;
	padding-block-end: 40px;
}

.elementor .about-story__photo.about-story__photo {
	position: relative;
	inset: auto;
	width: calc(100% - 40px);
	height: auto;
	max-width: none;
	max-height: none;
	/* 3/2 against the source's 1.501 loses 0.07% — a sliver, and it keeps the
	   box on a round design value if the photograph is ever replaced. */
	aspect-ratio: 3 / 2;
}

.elementor .about-story__backdrop.about-story__backdrop {
	width: calc(100% - 40px);
	height: auto;
	max-width: none;
	max-height: none;
	aspect-ratio: 3 / 2;
}

/* ==========================================================================
   ACTION ICONS — a button says what it will do

   Every button that goes somewhere gets a trailing icon, chosen from its OWN
   href rather than from its label:

     a file  (.pdf .doc .docx .xls .xlsx .zip, or a `download` attribute)
             -> a download glyph
     anything else -> an arrow

   Keying on the href is what makes this self-correcting. A button labelled
   "Download Buyer's Manual" that currently points at /contact-us/ gets an
   ARROW, which is the truth — it navigates, it does not download — and the
   moment the real PDF is uploaded and the link repointed, the icon changes by
   itself with no edit here.

   NOTE 2026-10-05: there is not a single `.pdf` href on the site yet, so no
   download glyph is rendering anywhere. All four "Download …" buttons point at
   /contact-us/ because the Buyer's Manual and the Seller's Accreditation Form
   do not exist. The rule is live and waiting for them.

   The glyphs are inline SVG used as a MASK, not as a background image, so each
   one is painted in `currentColor` and inherits its button's own label colour —
   white on navy, navy on cyan, blue on white — with no per-button rule.

   DELIBERATELY EXCLUDED: `button-accent` (the header's Contact button — nav
   chrome, not a page action), `button-submit` (a form submit has no
   destination) and `text-link` (its own underlined affordance already).
   ========================================================================== */
.elementor a.button-primary[href]::after,
.elementor a.button-secondary[href]::after,
.elementor a.button-outline[href]::after,
.elementor a.button-accent-sm[href]::after,
.elementor a.button-ink-sm[href]::after,
.elementor a.button-white-sm[href]::after,
.elementor a.job-card__apply[href]::after {
	content: "";
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	margin-inline-start: 10px;
	background-color: currentColor;
	/* arrow: a shaft and a head */
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 8h11M8.75 4.25 12.5 8l-3.75 3.75' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 8h11M8.75 4.25 12.5 8l-3.75 3.75' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
	transition: transform 180ms ease;
}

/* A file: an arrow coming down into a tray. */
.elementor a.button-primary[href$=".pdf" i]::after,
.elementor a.button-secondary[href$=".pdf" i]::after,
.elementor a.button-outline[href$=".pdf" i]::after,
.elementor a.button-accent-sm[href$=".pdf" i]::after,
.elementor a.button-ink-sm[href$=".pdf" i]::after,
.elementor a.button-white-sm[href$=".pdf" i]::after,
.elementor a.button-primary[href$=".doc" i]::after,
.elementor a.button-primary[href$=".docx" i]::after,
.elementor a.button-primary[href$=".xls" i]::after,
.elementor a.button-primary[href$=".xlsx" i]::after,
.elementor a.button-primary[href$=".zip" i]::after,
.elementor a.button-secondary[href$=".docx" i]::after,
.elementor a.button-ink-sm[href$=".docx" i]::after,
.elementor a.button-accent-sm[href$=".docx" i]::after,
.elementor a.button-primary[download]::after,
.elementor a.button-secondary[download]::after,
.elementor a.button-outline[download]::after,
.elementor a.button-accent-sm[download]::after,
.elementor a.button-ink-sm[download]::after,
.elementor a.button-white-sm[download]::after {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.75v8M4.5 6.5 8 10l3.5-3.5M2 13.75h12' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.75v8M4.5 6.5 8 10l3.5-3.5M2 13.75h12' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* The arrow nudges on hover; a download glyph stays put, because a file does
   not move anywhere. */
@media (hover: hover) {

	.elementor a.button-primary[href]:hover::after,
	.elementor a.button-secondary[href]:hover::after,
	.elementor a.button-outline[href]:hover::after,
	.elementor a.button-accent-sm[href]:hover::after,
	.elementor a.button-ink-sm[href]:hover::after,
	.elementor a.button-white-sm[href]:hover::after,
	.elementor a.job-card__apply[href]:hover::after {
		transform: translateX(3px);
	}

	.elementor a[href$=".pdf" i]:hover::after,
	.elementor a[download]:hover::after {
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor a[href]::after {
		transition: none;
	}
}

/* ==========================================================================
   STAT BAND — the first figure sat 10px above the other five

   Measured on Careers: all six cells share `top: 504`, but the figure inside
   cell 1 started at 504 while cells 2-6 started at 514.

   The cause is Elementor's `e-div-block-base { padding: 10px }`. The plain cell
   resets it with an explicit `padding: 0px`; `stat-band__cell-ruled` sets only
   `padding-inline-start` (32px desktop, 24px mobile) for its divider and never
   touches the block axis, so the base 10px survives on the top, bottom and
   right of every ruled cell.

   So the five ruled cells were the ones out of place, not the first — it just
   reads as the odd one out at 1 against 5. Fixed at source by clearing the two
   axes the ruled cell never meant to set, leaving its inline-start padding
   alone so the divider gap survives at both breakpoints.

   Doubled class: at `.elementor .x` this would tie with Elementor's own output
   and lose in the editor canvas — see the note on specificity above.
   ========================================================================== */
.elementor .stat-band__cell-ruled.stat-band__cell-ruled {
	padding-block: 0;
	padding-inline-end: 0;
}

/* ==========================================================================
   THE NEWS ARTICLE

   Template: elementor_library 1430, "Softouch — News Article",
   condition `include/singular/post`.

   Before this, a post fell through to Hello Elementor's `single.php`: a bare
   `entry-title` over `page-content` at the full 1140px, 16px/24px, images at
   whatever size the import left them, and the tags printed as the sentence
   "Tagged Blessing, Groundbreaking". No hero, no date, no category, no
   breadcrumb, and no way onward from the end of the article.
   ========================================================================== */

/* --- the reading column -------------------------------------------------- */

/* 720px at 18px/32px is about 72 characters — the comfortable band. The old
   1140px line ran past 160. */
.elementor .article-stack.article-stack {
	width: 100%;
	max-width: 720px;
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	gap: 40px;
	align-items: stretch;
}

.elementor .article-hero-photo.article-hero-photo {
	width: 100%;
	height: auto;
	border-radius: 12px;
	display: block;
}

/* An article with no featured image emits an `<img>` with no src; hide it
   rather than render a broken frame. Two of the thirteen posts are like this. */
.elementor .article-hero-photo:not([src]) {
	display: none;
}

/* --- the body ------------------------------------------------------------ */

.elementor .article-body {
	font-family: var(--font-primary);
	font-size: 18px;
	line-height: 32px;
	color: #2A3145;
}

.elementor .article-body > :first-child {
	margin-block-start: 0;
}

.elementor .article-body > :last-child {
	margin-block-end: 0;
}

.elementor .article-body p {
	margin-block: 0 24px;
}

/* The import left empty paragraphs between blocks; they were showing as
   unexplained gaps. `:empty` cannot see a `&nbsp;`, so the `<br>`-only case is
   caught too. */
.elementor .article-body p:empty,
.elementor .article-body p:has(> br:only-child) {
	display: none;
}

.elementor .article-body h2 {
	margin-block: 48px 16px;
	font-weight: 600;
	font-size: 28px;
	line-height: 38px;
	letter-spacing: -0.01em;
	color: #0B1020;
}

.elementor .article-body h3 {
	margin-block: 36px 12px;
	font-weight: 600;
	font-size: 21px;
	line-height: 30px;
	color: #0B1020;
}

.elementor .article-body a {
	color: #147E9F;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.elementor .article-body ul,
.elementor .article-body ol {
	margin-block: 0 24px;
	padding-inline-start: 24px;
}

.elementor .article-body li {
	margin-block-end: 8px;
}

.elementor .article-body blockquote {
	margin: 32px 0;
	padding: 4px 0 4px 24px;
	border-inline-start: 3px solid #48C6E9;
	font-size: 20px;
	line-height: 34px;
	color: #0B1020;
}

/* Imported images carry inline width/height from the old editor. They are
   released to the column and rounded; a caption sits under its own image. */
.elementor .article-body img {
	display: block;
	width: 100%;
	height: auto;
	margin-block: 32px;
	border-radius: 12px;
}

.elementor .article-body figure {
	margin: 32px 0;
}

.elementor .article-body figure img {
	margin-block: 0;
}

.elementor .article-body figcaption {
	margin-block-start: 10px;
	font-size: 14px;
	line-height: 22px;
	color: #6B7285;
}

/* --- tags ---------------------------------------------------------------- */

.elementor .article-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin: 0;
	padding-block-start: 32px;
	border-block-start: 1px solid #E3DFD7;
}

/* No tags, no rule and no gap. */
.elementor .article-tags:empty {
	display: none;
}

.elementor .article-tags__label {
	margin-inline-end: 4px;
	font-weight: 600;
	font-size: 12px;
	letter-spacing: 0.12em;
	line-height: 16px;
	text-transform: uppercase;
	color: #6B7285;
}

.elementor a.article-tag {
	padding: 6px 14px;
	border: 1px solid #E3DFD7;
	border-radius: 999px;
	font-size: 14px;
	line-height: 20px;
	color: #2A3145;
	text-decoration: none;
	transition: border-color 160ms ease, color 160ms ease,
		background-color 160ms ease;
}

.elementor a.article-tag:hover {
	border-color: #405BA9;
	background-color: #F2F5FB;
	color: #405BA9;
}

/* --- previous / next ----------------------------------------------------- */

.elementor .article-nav {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	margin: 0;
	padding-block-start: 32px;
	border-block-start: 1px solid #E3DFD7;
}

.elementor .article-nav:empty {
	display: none;
}

.elementor a.article-nav__link {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 18px 20px;
	border: 1px solid #E3DFD7;
	border-radius: 8px;
	text-decoration: none;
	transition: border-color 160ms ease, background-color 160ms ease;
}

.elementor a.article-nav__link:hover {
	border-color: #405BA9;
	background-color: #F2F5FB;
}

/* The empty cell holds the column so "Next" stays right-aligned when there is
   no "Previous" — the first and last articles in a category. */
.elementor .article-nav__link--empty {
	border: 0;
}

.elementor .article-nav__link--next {
	text-align: end;
}

.elementor .article-nav__dir {
	font-weight: 600;
	font-size: 11px;
	letter-spacing: 0.12em;
	line-height: 16px;
	text-transform: uppercase;
	color: #6B7285;
}

.elementor .article-nav__title {
	font-weight: 600;
	font-size: 16px;
	line-height: 24px;
	color: #0B1020;
}

/* --- more articles ------------------------------------------------------- */

.elementor .article-related-head {
	width: 100%;
	max-width: 1248px;
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	gap: 32px;
	align-items: stretch;
}

/* Reuses the archive's own `news-card` classes, so the cards here and the ones
   on /news-events/ cannot drift apart. The shortcode emits them as `<a>` and
   `<span>`, which is why the card elements are given an explicit display. */
.elementor .article-related {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 32px;
	margin: 0;
}

.elementor .article-related .news-card {
	display: flex;
	flex-direction: column;
	text-decoration: none;
}

.elementor .article-related .news-card__media {
	display: block;
	position: relative;
}

.elementor .article-related .news-card__body {
	display: flex;
	flex-direction: column;
}

.elementor .article-related .news-card__title,
.elementor .article-related .news-card__excerpt,
.elementor .article-related .news-card__date {
	display: block;
}

@media (max-width: 1024px) {

	.elementor .article-related {
		grid-template-columns: repeat(2, 1fr);
		gap: 24px;
	}
}

@media (max-width: 767px) {

	.elementor .article-stack.article-stack {
		gap: 28px;
	}

	.elementor .article-body {
		font-size: 17px;
		line-height: 30px;
	}

	.elementor .article-body h2 {
		margin-block: 36px 12px;
		font-size: 24px;
		line-height: 32px;
	}

	.elementor .article-nav {
		grid-template-columns: 1fr;
	}

	.elementor .article-nav__link--empty {
		display: none;
	}

	.elementor .article-nav__link--next {
		text-align: start;
	}

	.elementor .article-related {
		grid-template-columns: 1fr;
	}
}

/* The closing CTA band kept the 128px it had when its content sat bare on the
   band. The content is a bordered card now with 56px of its own padding, so the
   band was adding a 224px gap above it once the previous section's own 96px is
   counted. Halved; the card does the containing. */
.elementor .final-cta.final-cta {
	padding-block: 64px;
}

@media (max-width: 1200px) {

	.elementor .final-cta.final-cta {
		padding-block: 48px;
	}
}

@media (max-width: 767px) {

	.elementor .final-cta.final-cta {
		padding-block: 40px;
	}
}

/* --- the article hero, with no photograph -------------------------------- */

/* Dropping `page-hero-compact` is what turns the header white: the solid-header
   rule keys off `body:not(:has(.page-hero, .page-hero-compact))`, so an article
   now satisfies it automatically and gets the coloured lock-up and dark nav
   with no extra rule. The same `:has()` test also makes the main content clear
   the fixed header, which is why the hero body's own masthead offset comes off
   below — otherwise the header height would be counted twice. */
.elementor .article-hero.article-hero {
	width: 100%;
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	/* `e-div-block-base` pads every atomic section by 10px. A full-bleed band
	   has to shed it or everything inside starts 10px right of the masthead.
	   It is invisible at >=1441 by arithmetic, not by luck: the measure is
	   `(100% - 1248px) / 2` of the body, and the body is 20px narrower than the
	   band, so the formula gives back exactly the 10px the padding took. Below
	   1441 the gutter is a flat 56px, nothing cancels, and the drift shows. */
	padding-inline: 0;
	background-image: linear-gradient(180deg, #FAF8F5 0%, #EFF3FA 100%);
	background-color: #FAF8F5;
	border-block-end: 1px solid #E3DFD7;
}

/* No `max-width` / `margin-inline: auto` here. `page-hero__body` is already in
   the site's 1441px measure rule, which pads it by `calc((100% - 1248px) / 2)`
   — adding a centred 1248 block on top applied the measure TWICE and indented
   the hero text 149px past the logo it is meant to line up with. The body runs
   full width and the measure rule alone holds the column, exactly as the other
   heroes and the masthead do. */
.elementor .article-hero .page-hero__body {
	padding-block: 72px 56px;
	gap: 16px;
}

/* The hero furniture was built for a photographic ground. */
.elementor .article-hero .breadcrumb,
.elementor .article-hero .breadcrumb a,
.elementor .article-hero .page-hero__lead-sm {
	color: #646B7D;
}

.elementor .article-hero .page-hero__title-sm {
	max-width: 900px;
	color: #0B1020;
}

.elementor .article-hero .news-featured__pill {
	background-color: #48C6E9;
	color: #0B1020;
}

@media (max-width: 1200px) {

	.elementor .article-hero .page-hero__body {
		padding-block: 56px 40px;
	}
}

@media (max-width: 767px) {

	.elementor .article-hero .page-hero__body {
		padding-block: 40px 32px;
	}
}

/* --- the classic shortcode widget wraps its output ------------------------
   A classic widget renders into `.elementor-shortcode` inside the element, so
   a `display: grid` on the element itself had exactly ONE item — that wrapper —
   and the two prev/next cards stacked in a single column instead of sitting
   side by side. `display: contents` lifts the shortcode's own children into the
   outer grid or flex, which is where the layout rules are.
   ------------------------------------------------------------------------- */
.elementor .article-tags > .elementor-shortcode,
.elementor .article-nav > .elementor-shortcode,
.elementor .article-share > .elementor-shortcode,
.elementor .article-tags > .elementor-widget-container,
.elementor .article-nav > .elementor-widget-container,
.elementor .article-share > .elementor-widget-container {
	display: contents;
}

/* --- share --------------------------------------------------------------- */

.elementor .article-share {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
	margin: 0;
	padding-block-start: 32px;
	border-block-start: 1px solid #E3DFD7;
}

.elementor .article-share__label {
	margin-inline-end: 4px;
	font-weight: 600;
	font-size: 12px;
	letter-spacing: 0.12em;
	line-height: 16px;
	text-transform: uppercase;
	color: #6B7285;
}

.elementor .article-share__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 1px solid #E3DFD7;
	border-radius: 50%;
	background-color: #FFFFFF;
	color: #405BA9;
	cursor: pointer;
	transition: border-color 160ms ease, background-color 160ms ease,
		color 160ms ease;
}

.elementor .article-share__link:hover {
	border-color: #405BA9;
	background-color: #405BA9;
	color: #FFFFFF;
}

.elementor .article-share__link:focus-visible {
	outline: 2px solid #48C6E9;
	outline-offset: 3px;
}

/* The brand networks' marks are solid shapes; the copy glyph is stroked. */
.elementor .article-share__icon {
	width: 18px;
	height: 18px;
	fill: currentColor;
}

.elementor .article-share__done {
	position: absolute;
	inset-block-end: calc(100% + 8px);
	padding: 4px 10px;
	border-radius: 4px;
	background-color: #0B1020;
	font-size: 12px;
	line-height: 18px;
	color: #FFFFFF;
	white-space: nowrap;
}

/* --- related, now a Loop Grid -------------------------------------------- */

.elementor .article-related .elementor-loop-container {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 32px;
}

@media (max-width: 1024px) {

	.elementor .article-related .elementor-loop-container {
		grid-template-columns: repeat(2, 1fr);
		gap: 24px;
	}
}

@media (max-width: 767px) {

	.elementor .article-related .elementor-loop-container {
		grid-template-columns: 1fr;
	}
}

/* Yoast marks the current page `breadcrumb_last` and the site styles it white
   for the photographic heroes. The article hero is light, so it was invisible —
   the trail read "Home / News & Events /" and then nothing. */
.elementor .article-hero .breadcrumb_last {
	color: #0B1020;
}

/* A Loop Grid widget does not stretch inside a flex column; without this its
   track collapses and the three cards render at a third of their width. */
.elementor .article-related.article-related {
	width: 100%;
	align-self: stretch;
}

/* The Loop Grid's own track needs the width too — stretching the widget alone
   left the container at 382px inside a 1210px widget, so the three cards came
   out at 106px each. */
.elementor .article-related .elementor-loop-container {
	width: 100%;
}

/* "More from Softouch" borrows the hero's title class, which is white for the
   photographic heroes. On this light band it was white on white. */
.elementor .article-related-head .page-hero__title-sm {
	color: #0B1020;
}

/* --------------------------------------------------------------------------
   Two corrections to the related block

   1. `.article-related` was given `display: grid` when it was a shortcode
      widget emitting cards directly. It is a Loop Grid now, so that grid made
      `.elementor-widget-container` a shrink-to-fit GRID ITEM — 382px inside a
      1210px widget, three 106px cards. The widget goes back to a block and the
      grid lives only on the loop's own container.

   2. `.elementor .breadcrumb .breadcrumb_last` is (0,3,0) and sits later in
      this file than the article-hero override, which was also (0,3,0) — a tie
      lost on source order, so the current crumb stayed white on the light hero.
      Matching the trail class too makes it (0,4,0).
   -------------------------------------------------------------------------- */
.elementor .article-related.article-related {
	display: block;
}

.elementor .article-related > .elementor-widget-container {
	width: 100%;
}

.elementor .article-hero .breadcrumb .breadcrumb_last {
	color: #0B1020;
}

/* Taller thumbnails, site-wide. The archive's global class sets 140px (104 on
   phones), which was fine for a card holding only a title and a date; with an
   excerpt and a "Read more" under it the picture read as a thin strip. The
   related row and the News & Events grid are the same card, so this is one
   rule for both rather than a value in two places. */
.elementor .news-card__media {
	height: 220px;
}

/* Site-wide, not just the related row: the News index uses the same card, and
   a ragged set of excerpt lengths makes a grid of cards look broken. Three
   lines, then ellipsis. */
.elementor .news-card__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* "Read more" sits on the card's floor, so it lines up across a row whatever
   the title and excerpt do above it. */
.elementor .news-card {
	height: 100%;
}

.elementor .news-card__body {
	flex: 1 1 auto;
}

@media (max-width: 767px) {

	.elementor .news-card__media {
		height: 200px;
	}
}

/* ==========================================================================
   ONE KNOB: THE SPACE AFTER A SECTION HEADING

   Change `--sv-head-gap` and every section on the site moves together.

   The rule finds the container by what it HOLDS rather than by a list of
   container names, so a new section picks the spacing up with no edit here —
   `:has(> .heading)` matches only the heading's direct parent, not every
   ancestor.

   Hero bodies are excluded: there the heading sits in a stack with a
   breadcrumb, a pill and a meta line, and those want to stay tight to it.
   ========================================================================== */
:root {
	--sv-head-gap: 32px;
}

.elementor *:has(> .ink-title):not(.page-hero__body),
.elementor *:has(> .section-head__title):not(.page-hero__body),
.elementor *:has(> .guide-section__title):not(.page-hero__body),
.elementor *:has(> .team-title):not(.page-hero__body),
.elementor *:has(> .display-m):not(.page-hero__body),
.elementor *:has(> .display-m-inverse):not(.page-hero__body),
.elementor .article-related-head {
	row-gap: var(--sv-head-gap);
}

/* --- "Read more" on a news card ------------------------------------------
   A span, not a link: the whole card is already an `<a>` to the post and a
   link inside a link is invalid. No background — it reads as a text action,
   with the same drawn arrow the buttons use.
   ------------------------------------------------------------------------- */
.elementor .news-card__more {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-block-start: auto;
	padding-block-start: 14px;
	background: none;
	border: 0;
	font-family: var(--font-primary);
	font-weight: 600;
	font-size: 14px;
	line-height: 20px;
	color: #405BA9;
}

.elementor .news-card__more::after {
	content: "";
	width: 15px;
	height: 15px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 8h11M8.75 4.25 12.5 8l-3.75 3.75' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1.5 8h11M8.75 4.25 12.5 8l-3.75 3.75' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
	transition: transform 180ms ease;
}

@media (hover: hover) {

	.elementor .news-card:hover .news-card__more {
		color: #33498A;
	}

	.elementor .news-card:hover .news-card__more::after {
		transform: translateX(3px);
	}
}

/* ==========================================================================
   WIDER ARTICLE CONTAINER

   The column was 720px. Jun marked ~1040, so the container takes that and the
   PHOTOGRAPHS now use all of it — at 720 inside a 1248 band they were the thing
   actually looking cramped.

   The text keeps a cap of its own at 860px. At 18px that is ~86 characters,
   already the top of the comfortable band; the full 1040 would be ~104, well
   past where the eye starts losing its place returning to the next line. The
   line-height goes 32 -> 34 to carry the longer measure.

   Both are centred in the stack, so the text sits inside a wider image — a
   deliberate editorial shape rather than a ragged left edge.
   ========================================================================== */
.elementor .article-stack.article-stack {
	max-width: 1040px;
}

.elementor .article-body {
	line-height: 34px;
}

.elementor .article-body > p,
.elementor .article-body > h2,
.elementor .article-body > h3,
.elementor .article-body > ul,
.elementor .article-body > ol,
.elementor .article-body > blockquote {
	max-width: 860px;
	margin-inline: auto;
}

/* The tail furniture follows the text, not the photographs. */
.elementor .article-share,
.elementor .article-tags,
.elementor .article-nav {
	width: 100%;
	max-width: 860px;
	margin-inline: auto;
}

@media (max-width: 1200px) {

	.elementor .article-stack.article-stack {
		max-width: 860px;
	}
}

@media (max-width: 900px) {

	.elementor .article-stack.article-stack,
	.elementor .article-body > p,
	.elementor .article-body > h2,
	.elementor .article-body > h3,
	.elementor .article-body > ul,
	.elementor .article-body > ol,
	.elementor .article-body > blockquote,
	.elementor .article-share,
	.elementor .article-tags,
	.elementor .article-nav {
		max-width: 100%;
	}
}

/* `wpautop` wraps a bare `<img>` in a paragraph, so the image-only paragraphs
   were caught by the 860px text cap and the photographs never reached the
   1040 the container gives them. A paragraph that holds nothing but an image
   (or an image in a link) is a figure, not text. */
.elementor .article-body > p:has(> img:only-child),
.elementor .article-body > p:has(> a:only-child > img),
.elementor .article-body > figure {
	max-width: none;
}

/* The tag, share and nav rows are widgets whose own `width: 100%` was set
   earlier in this file at the same specificity; the cap needs to outrank it. */
.elementor .article-share.article-share,
.elementor .article-tags.article-tags,
.elementor .article-nav.article-nav {
	max-width: 860px;
	margin-inline: auto;
}

/* Elementor ships `.elementor.elementor .e-con > .elementor-widget { max-width:
   100% }` — four classes, (0,4,0). Any override of a widget's max-width inside
   a container has to outrank THAT, not just the global class. Matching its own
   shape and adding the component class makes this (0,5,0).

   Without it the tags, share and nav rows ran to the full 1040 while the text
   they belong to stopped at 860. */
.elementor.elementor .e-con > .elementor-widget.article-share,
.elementor.elementor .e-con > .elementor-widget.article-tags,
.elementor.elementor .e-con > .elementor-widget.article-nav {
	max-width: 860px;
	margin-inline: auto;
}

/* The News & Events grid is a Loop Grid over the SAME loop item as the related
   row (1433), so the layout that used to live on the `news-grid` global class
   moves to the loop's own container. The widget itself stays a block — making
   it the grid would turn `.elementor-widget-container` into a single
   shrink-to-fit item, which is what collapsed the related row earlier. */
.elementor .news-archive-grid.news-archive-grid {
	display: block;
	width: 100%;
}

.elementor .news-archive-grid > .elementor-widget-container {
	width: 100%;
}

.elementor .news-archive-grid .elementor-loop-container {
	width: 100%;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	grid-auto-rows: auto;
	align-items: start;
	gap: 24px;
}

@media (max-width: 1024px) {

	.elementor .news-archive-grid .elementor-loop-container {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {

	.elementor .news-archive-grid .elementor-loop-container {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 16px;
	}
}

/* The job-card summaries are now the client's own paragraphs from
   careers.docx — 269 to 486 characters against the ~150 the agency-written
   placeholders ran to. Clamped rather than rewritten: the copy is the client's
   and the full description lives on the role's own post. */
.elementor .job-card__body {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}


/* ==========================================================================
   COMMUNITY DETAIL
   `/area/<community>/` — the property_area term template (Elementor 1500).

   Everything below styles markup produced by the shortcodes in
   `inc/community-detail.php`, which render through Elementor's CLASSIC
   shortcode widget. Those classes are plain CSS names, not Elementor global
   classes, so nothing competes with them and single specificity is enough —
   unlike the band wrappers, which share `page-section` with the rest of the
   site.

   Values are measured off the approved frames:
   COMMUNITY DETAIL — ANAMI HOMES NORTH — DESKTOP (1440) and — MOBILE (390).
   ========================================================================== */

:root {
	--cd-ink: #0B1020;
	--cd-body: #2A3145;
	--cd-muted: #6B7285;
	--cd-rule: #E3DFD7;
	--cd-brand: #405BA9;
	/* Measured off Figma 610:80 — the Overview figures are a DEEPER blue than
	   --cd-brand, not the same token. #354B8E is the solid stroke core (2,028px
	   of it); everything lighter in that panel is an antialiased glyph edge. */
	--cd-brand-deep: #354B8E;
	--cd-accent: #48C6E9;
	--cd-tint: #E7F6FC;
	--cd-aside: #F0FBFE;
	--cd-plate: #E6E8EE;
}

/* The classic shortcode widget wraps its output in `.elementor-shortcode`.
   That wrapper would become the grid/flex item and collapse every layout
   below into a single column, so it is lifted out of the box model. */
.elementor .community-shortcode,
.elementor .community-shortcode > .elementor-widget-container,
.elementor .community-shortcode .elementor-shortcode {
	display: contents;
}

/* Because the wrapper above is `display: contents`, THIS element is the flex
   item inside `section-inner` — and `section-inner` is a column flexbox with
   `align-items: flex-start`, so a flex item is only as wide as its content.
   The grids whose children are absolutely positioned (the model cards) have no
   content width at all and collapsed to 9px. Every shortcode root therefore
   states its own stretch rather than relying on the band to provide it. */
.cfacts,
.cfigures,
.camenities,
.cmodels,
.cschemes,
.csiteplan,
.cmap,
.clandmarks,
.cvideo,
.cupdates,
.crelated,
.cgallery,
.caside,
.csticky {
	align-self: stretch;
	width: 100%;
}

.cicon {
	width: 20px;
	height: 20px;
	flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   02 — QUICK PROJECT FACTS
   A five-cell rule-separated row. The dividers are borders on the cells rather
   than separate elements, so a community with four facts loses a divider
   instead of keeping a stray line.
   -------------------------------------------------------------------------- */

.elementor .community-facts.community-facts {
	padding-block: 8px 32px;
	background-color: #FFFFFF;
}

/* A CARD, bounded like the two it sits between. This band used to be a
   full-bleed white strip whose only edges were where the white stopped — so
   on a page where the aside above and the Project Overview panel below are
   both 1px #E3DFD7 cards on the 1248 measure, the facts ran to the window.
   Three containers of facts, two of them bounded and one not. Now it follows
   the same border, the same radius and the same measure as its neighbours. */
/* One row, however many cells — kept deliberately after splitting Floor Area
   and Lot Area apart took a model with a Status to seven.

   Wrapping was tried and is worse here: `auto-fit` leaves a single orphan cell
   on a second row, and because the dividers are left borders on each cell,
   that orphan carries a vertical rule with nothing to its left. CSS cannot
   target "first cell of a row" under `auto-fit`, so the rule cannot be
   suppressed. A seventh cell is 174px and the longest values take two lines,
   which the card already allowed for. */
/* The grey edge becomes the brand gradient, drawn by the shared ring. */
.cfacts {
	position: relative;
	isolation: isolate;
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	margin: 0;
	padding: 24px 8px;
	border: 0;
	border-radius: 16px;
	background-color: #FFFFFF;
}

/* 28px down to 20px: at seven cells that is 16px more content per cell, which
   is the difference between "Single Detached" sitting on one line and breaking. */
.cfacts__cell {
	padding-inline: 20px;
	border-inline-start: 1px solid var(--cd-rule);
}

/* The outer border is the card's now, so the first cell keeps its padding —
   dropping it would push the first label hard against the new edge.
   `:first-child` alone is not enough once the grid can wrap: the first cell of
   a second row would carry a divider with nothing to its left. */
.cfacts__cell:first-child {
	border-inline-start: 0;
}

.cfacts__label {
	margin: 0;
	font-size: 11px;
	line-height: 17px;
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var(--cd-muted);
}

.cfacts__value {
	margin: 6px 0 0;
	font-size: 15px;
	line-height: 23px;
	font-weight: 600;
	color: var(--cd-ink);
}

/* --------------------------------------------------------------------------
   03 — PROJECT OVERVIEW
   -------------------------------------------------------------------------- */

.elementor .community-overview .section-inner {
	flex-direction: row;
	align-items: flex-start;
	gap: 80px;
}

/* An `e-flexbox` is `row` by default, and these wrappers carry global classes
   with no CSS of their own, so every one of them needs the direction stated —
   without it the eyebrow, the heading and the body copy sat side by side in
   three narrow columns. */
.elementor .community-overview__copy,
.elementor .community-overview__panel,
.elementor .community-landmarks__copy,
.elementor .community-landmarks__aside {
	flex-direction: column;
}

.elementor .community-overview__copy {
	flex: 1 1 720px;
	max-width: 720px;
	gap: 20px;
}

/* The RIGHT COLUMN of the Overview band: the project mark, then the figures box
   under it. The wrapper exists so the logo sits ABOVE the box rather than inside
   its gradient ring, and an atomic container with no global class has no
   direction or width of its own — so both are stated here, targeted by
   structure because the class never reaches the DOM.

   It takes the 448px the panel used to own; the panel now fills it. */
.elementor .community-overview .section-inner > .e-con:last-child {
	flex: 0 0 448px;
	flex-direction: column;
	align-items: flex-start;
	gap: 20px;
	width: auto;
	max-width: 448px;
	/* Same 10px side padding the hero's aside column carried, and the same
	   consequence: the box inside drew at 428 against the hero panel's 448. */
	padding-inline: 0;
}

/* The grey border is gone; the gradient ring draws the edge. `relative` and
   `isolation` are what the ring's absolutely-positioned ::before needs. */
.elementor .community-overview__panel {
	position: relative;
	isolation: isolate;
	flex: 0 0 auto;
	align-self: stretch;
	max-width: none;
	padding: 0;
	background-color: #FFFFFF;
	border: 0;
	border-radius: 4px;
}

.cfigures {
	display: flex;
	flex-direction: column;
	padding: 32px;
}

.cfigures__row {
	display: flex;
	align-items: baseline;
	gap: 20px;
	padding-block: 24px;
	border-block-start: 1px solid var(--cd-rule);
}

.cfigures__row:first-child {
	padding-block-start: 0;
	border-block-start: 0;
}

.cfigures__row:last-child {
	padding-block-end: 0;
}

.cfigures__figure {
	margin: 0;
	flex: 0 0 auto;
	font-size: 40px;
	line-height: 52px;
	font-weight: 600;
	letter-spacing: -1px;
	/* Brand, not ink. These are the one accent in the panel and the design
	   paints them #354B8E; near-black made them read as body copy at 40px. */
	color: var(--cd-brand-deep);
}

.cfigures__label {
	margin: 0;
	font-size: 15px;
	line-height: 25px;
	color: var(--cd-body);
}

/* --------------------------------------------------------------------------
   04 — FEATURES & AMENITIES
   -------------------------------------------------------------------------- */

.camenities {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	column-gap: 24px;
	row-gap: 40px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.camenities__item {
	display: flex;
	align-items: center;
	gap: 16px;
}

.camenities__badge {
	display: grid;
	place-items: center;
	flex: 0 0 44px;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

.camenities__label {
	font-size: 15px;
	line-height: 20px;
	color: var(--cd-ink);
}

/* --------------------------------------------------------------------------
   05 — TYPES OF HOMES
   The cards reuse `model-loop__card` so they inherit the radius, scrim and
   hover ring the model cards already have elsewhere. Only the place line and
   the price are new — the loop item has no slot for either.
   -------------------------------------------------------------------------- */

.cmodels {
	display: flex;
	flex-direction: column;
	gap: 32px;
}

.cmodels__group {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cmodels__phase {
	margin: 0;
	font-size: 18px;
	line-height: 27px;
	font-weight: 600;
	color: var(--cd-ink);
}

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

/* The card itself is the shared property card — see PROPERTY CARDS — SPLIT
   LAYOUT at the end of this file. Only the grid it sits in belongs here.
   Nothing about the card's geometry, ink or chips is repeated: when the split
   layout changed, it had to change in ONE place for the archive, the
   Communities page and this one together. */

/* --------------------------------------------------------------------------
   06 — PAYMENT & DISCOUNT SCHEMES
   -------------------------------------------------------------------------- */

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

/* THE GRADIENT RING — the payment cards and the hero's price/address panel.

   The brand gradient as the edge, using the SAME masked ring as the header
   Enquire button and the property cards: a `::before` holding the gradient with
   `mask-composite` punching the middle out.

   A pseudo-element rather than a `border`, because a gradient cannot BE a
   border colour — `border-image` loses the radius, and `background-clip`
   tricks break the moment the element has its own background, which this card
   does. The grey `border` goes entirely; keeping it would sit underneath and
   darken the gradient by a pixel on every edge. */
.cscheme {
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 32px 24px;
	background-color: #FFFFFF;
	border: 0;
	border-radius: 16px;
}

.elementor .cscheme::before,
.elementor .caside::before,
.elementor .community-overview__panel::before,
.elementor .community-landmarks__aside::before,
.elementor .cfacts::before,
.elementor .button-outline::before,
.elementor .community-hero__copy .page-hero__actions > .button-primary::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	/* 2px, as on the header Enquire button. 1.5px straddled the pixel grid and
	   antialiased against white on both sides, so the gradient sampled out at
	   about a quarter strength — it read as a pale grey hairline, which is the
	   thing it was replacing. */
	padding: var(--ring, 2px);
	border-radius: inherit;
	pointer-events: none;
	background-image: linear-gradient(
		135deg,
		#48C6E9 0%,
		#405BA9 100%
	);
	-webkit-mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	mask-composite: exclude;
}

/* Where `mask-composite` is unsupported the ::before would paint a solid
   gradient PLATE over the card and hide its contents. This restores a plain
   edge there instead — the card keeps a border, just not a gradient one. */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {

	.elementor .cscheme::before,
	.elementor .caside::before,
	.elementor .community-overview__panel::before,
	.elementor .community-landmarks__aside::before,
	.elementor .cfacts::before,
	.elementor .button-outline::before,
	.elementor .community-hero__copy .page-hero__actions > .button-primary::before {
		content: none;
	}

	.cscheme,
	.caside,
	.elementor .community-overview__panel,
	.elementor .community-landmarks__aside,
	.cfacts {
		border: 1px solid var(--cd-rule);
	}

	/* Its own 2px edge back, since the ring that replaced it cannot draw here. */
	.elementor .button-outline {
		border: 2px solid var(--cd-brand);
		padding-block: 16px;
		padding-inline: 32px;
	}
}

.cscheme__badge {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

.cscheme__title {
	margin: 0;
	font-size: 19px;
	line-height: 29px;
	font-weight: 600;
	color: var(--cd-ink);
}

.cscheme__body {
	margin: 0;
	font-size: 13px;
	line-height: 19px;
	color: var(--cd-muted);
}

/* --------------------------------------------------------------------------
   07 — SITE DEVELOPMENT PLAN
   The thumbnail links to the full-size file rather than opening a lightbox:
   the plan is a drawing full of small type, and a phone's own image viewer
   pinch-zooms better than anything worth shipping here.
   -------------------------------------------------------------------------- */

.csiteplan {
	position: relative;
	margin: 0;
	border: 1px solid var(--cd-rule);
	border-radius: 16px;
	background-color: var(--cd-plate);
	overflow: hidden;
}

.csiteplan__link {
	display: block;
	position: relative;
	text-decoration: none;
}

.csiteplan__image {
	display: block;
	width: 100%;
	height: auto;
}

/* Bottom RIGHT. On the left it sat over the plan's own title block — "SITE
   DEVELOPMENT PLAN" is lettered across the foot of the drawing — so the hint
   covered the words it was inviting you to read. */
.csiteplan__hint {
	position: absolute;
	inset-block-end: 24px;
	inset-inline-end: 24px;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px;
	border-radius: 999px;
	background-color: #FFFFFF;
	box-shadow: 0 8px 20px -12px rgba(11, 16, 32, 0.45);
	font-size: 13px;
	line-height: 20px;
	font-weight: 600;
	color: var(--cd-ink);
}

.csiteplan__hint .cicon {
	width: 16px;
	height: 16px;
}

/* --------------------------------------------------------------------------
   08 — NEARBY LANDMARKS
   -------------------------------------------------------------------------- */

.elementor .community-landmarks .section-inner {
	flex-direction: row;
	align-items: flex-start;
	gap: 96px;
}

.elementor .community-landmarks__copy {
	flex: 1 1 752px;
	gap: 20px;
}

/* The grey edge becomes the brand gradient, as on the Overview figures panel.
   The 4px radius is kept: the Overview panel is 4px too, so the two asides on
   this page agree. */
.elementor .community-landmarks__aside {
	position: relative;
	isolation: isolate;
	flex: 0 0 400px;
	max-width: 400px;
	padding: 32px;
	background-color: var(--cd-aside);
	border: 0;
	border-radius: 4px;
}

.cmap {
	height: 260px;
	border: 1px solid var(--cd-rule);
	border-radius: 12px;
	background-color: var(--cd-plate);
	overflow: hidden;
}

.cmap__frame {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

/* No embed supplied yet. A captioned plate says where the community is
   instead of framing an empty grey box. */
.cmap--empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	color: var(--cd-muted);
}

.cmap--empty .cicon {
	width: 32px;
	height: 32px;
}

.cmap__label {
	margin: 0;
	font-size: 14px;
	line-height: 20px;
	font-weight: 600;
}

.clandmarks__label {
	margin: 0 0 20px;
	font-size: 12px;
	line-height: 18px;
	font-weight: 600;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--cd-muted);
}

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

.clandmarks__item {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding-block: 18px;
	border-block-start: 1px solid var(--cd-rule);
}

.clandmarks__item:first-child {
	padding-block-start: 0;
	border-block-start: 0;
}

.clandmarks__name {
	font-size: 15px;
	line-height: 23px;
	font-weight: 600;
	color: var(--cd-ink);
}

.clandmarks__note {
	font-size: 13px;
	line-height: 19px;
	color: var(--cd-muted);
}

/* --------------------------------------------------------------------------
   14 — PROJECT VIDEO
   A facade. The player's own script is third party, weighs more than the rest
   of the page and sets cookies before anyone has asked to watch anything, so
   the real iframe only arrives on click (assets/js/community-video.js).
   -------------------------------------------------------------------------- */

/* Full width of the band's 1248px measure, at 16 / 7.245 — that is the 16:9
   height raised 15% and then cut 30% (9 x 1.15 x 0.7), so 1248 wide lands at
   about 565px rather than 807.

   This was capped at 640px when the player moved into a dialog, on the argument
   that a section most readers pass should not cost a screen of scrolling. That
   traded the wrong thing — it left the still floating in a container sized for
   something larger, which reads as a broken image rather than a restrained one.
   The height is no longer the video's footprint anyway: nothing loads until the
   dialog opens, so this is a photograph, and a photograph is allowed to be the
   width of everything else on the page. */
.cvideo {
	max-width: none;
}

.cvideo__trigger {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 16 / 7.245;
	padding: 0;
	border: 0;
	border-radius: 16px;
	background-color: #21293D;
	overflow: hidden;
	cursor: pointer;
}

/* The class is DOUBLED. Elementor ships `.elementor img { height: auto }` at
   (0,1,1), which beats a single `.cvideo__poster` at (0,1,0) — so the poster
   took its natural height instead of the box's and the navy plate showed
   through underneath it. The bug was latent while the box was 16:9, because the
   still is 16:9.03 and the two heights agreed to within a pixel; widening the
   box to 16:10.35 opened a ~100px band at the bottom. */
.elementor .cvideo__poster.cvideo__poster {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
	transition: transform 320ms ease;
}

.cvideo__play {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	transform: translate(-50%, -50%);
	display: grid;
	place-items: center;
	width: 88px;
	height: 88px;
	border-radius: 999px;
	background-color: rgba(255, 255, 255, 0.92);
	color: var(--cd-brand);
	transition: transform 160ms ease, background-color 160ms ease;
}

/* The trigger is the button now, so the hover state is driven from it — the
   play disc is a span inside it and never receives :hover of its own when the
   pointer is over the poster. */
.cvideo__trigger:hover .cvideo__play,
.cvideo__trigger:focus-visible .cvideo__play {
	transform: translate(-50%, -50%) scale(1.06);
	background-color: #FFFFFF;
}

/* Doubled to match the rule above — a single class here would lose its
   transform to nothing, but keeping the pair consistent avoids the next person
   wondering why one of them is doubled and the other is not. */
.elementor .cvideo__trigger:hover .cvideo__poster.cvideo__poster {
	transform: scale(1.03);
}

.cvideo__play .cicon {
	width: 28px;
	height: 28px;
	margin-inline-start: 4px;   /* optical centring of the triangle */
}

/* --------------------------------------------------------------------------
   The player, over the page.

   Same shape as the gallery's `.cviewer`: a fixed backdrop with a panel inside
   it, `has-cvlb` on the root element for the scroll lock, and `display: flex`
   restated under `[hidden]` because flex beats the attribute and the dialog
   would otherwise be open on every page load.
   -------------------------------------------------------------------------- */

.cvlb {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	background-color: rgba(11, 16, 32, 0.78);
}

.cvlb[hidden] {
	display: none;
}

.cvlb__panel {
	position: relative;
	width: min(1280px, 100%);
	aspect-ratio: 16 / 9;
	/* The ceiling wins on a short screen: a 16:9 box 1280 wide is 720 tall, and
	   a laptop viewport is often less than that once the padding is paid. */
	max-height: calc(100vh - 48px);
	border-radius: 16px;
	background-color: #000000;
	overflow: hidden;
	box-shadow: 0 24px 70px rgba(11, 16, 32, 0.46);
}

.cvlb__frame {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

.cvlb__close {
	position: absolute;
	inset-block-start: 20px;
	inset-inline-end: 20px;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background-color: rgba(255, 255, 255, 0.14);
	color: #FFFFFF;
	cursor: pointer;
	transition: background-color 160ms ease;
}

.cvlb__close:hover,
.cvlb__close:focus-visible {
	background-color: rgba(255, 255, 255, 0.28);
}

/* hello-elementor's reset.css paints every <button> #CC3366 — border, text and
   focus ring alike. Same trap the gallery's close button hit: it is (0,0,1) so
   it loses on background-color, but `color` has to be restated or the glyph is
   magenta, and focus is the state that bites because a button keeps focus
   after a click. */
.cvlb__close::before,
.cvlb__close::after {
	content: "";
	position: absolute;
	width: 18px;
	height: 2px;
	border-radius: 2px;
	background-color: currentColor;
}

.cvlb__close::before { transform: rotate(45deg); }
.cvlb__close::after  { transform: rotate(-45deg); }

/* The page behind must not scroll while the player is open. Set on the root
   element by the script, so it is removed again on close even if the dialog has
   been moved to <body> — which it has. */
.has-cvlb,
.has-cvlb body {
	overflow: hidden;
}

/* The whole band goes when there is no footage, rather than leaving a titled
   empty section. Same for the site plan and the updates. */
.elementor .community-video:not(:has(.cvideo)),
.elementor .community-siteplan:not(:has(.csiteplan)),
.elementor .community-updates:not(:has(.cupdates)),
.elementor .community-schemes:not(:has(.cschemes)),
.elementor .community-amenities:not(:has(.camenities)),
.elementor .community-models:not(:has(.cmodels)) {
	display: none;
}

/* --------------------------------------------------------------------------
   15 — DEVELOPMENT UPDATES   ·   18 — RELATED COMMUNITIES
   Two card strips that differ only in media height, so they share everything
   except that one line.
   -------------------------------------------------------------------------- */

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

/* The related band draws the SHARED property card now, so it borrows the models
   band's grid rather than keeping one of its own at a different gap. Its old
   card rules went with the markup: `.crelated__card`, `__media`, `__image`,
   `__body`, `__where`, `__title`, `__blurb` and `__more` match nothing. */
.crelated {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
}

.elementor .cupdate {
	display: flex;
	flex-direction: column;
	background-color: #FFFFFF;
	border: 1px solid var(--cd-rule);
	border-radius: 14px;
	overflow: hidden;
	text-decoration: none;
	transition: transform 180ms ease, box-shadow 180ms ease;
}

.elementor .cupdate:hover {
	transform: translateY(-2px);
	box-shadow: 0 18px 32px -24px rgba(11, 16, 32, 0.45);
}

.cupdate__media {
	position: relative;
	display: block;
	background-color: var(--cd-plate);
}

.cupdate__media {
	height: 180px;
}

.cupdate__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cupdate__pill {
	position: absolute;
	inset-block-start: 14px;
	inset-inline-start: 14px;
	padding: 6px 10px;
	border-radius: 999px;
	background-color: var(--cd-accent);
	font-size: 11px;
	line-height: 15px;
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var(--cd-ink);
}

.cupdate__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 8px;
	padding: 20px;
}

.cupdate__date {
	font-size: 13px;
	line-height: 18px;
	color: var(--cd-muted);
}

.cupdate__title {
	font-size: 17px;
	line-height: 24px;
	font-weight: 600;
	color: var(--cd-ink);
}

.cupdate__excerpt {
	font-size: 13px;
	line-height: 19px;
	color: var(--cd-muted);
}

.cupdate__more {
	margin-block-start: auto;
	padding-block-start: 6px;
	font-size: 13px;
	line-height: 20px;
	font-weight: 600;
	color: var(--cd-brand);
}

.cupdate__more::after {
	content: ' \2192';
}

/* --------------------------------------------------------------------------
   17 — INQUIRY
   The panel chrome is the Contact page's; only these two direct-contact lines
   are new, and they take both label and href from the same stored field so
   they cannot drift apart.
   -------------------------------------------------------------------------- */

.elementor .cdirect {
	display: block;
	font-size: 15px;
	line-height: 23px;
	font-weight: 500;
	color: var(--cd-ink);
	text-decoration: none;
}

.elementor .cdirect:hover .cdirect__value,
.elementor .cdirect:focus-visible .cdirect__value {
	text-decoration: underline;
}

.cdirect__verb {
	color: var(--cd-muted);
}

/* --------------------------------------------------------------------------
   STICKY CTA — phones only
   Two links, no script, so it costs nothing to the people who never see it.
   -------------------------------------------------------------------------- */

/* EVERY WIDTH, not phones only — and driven by scroll direction, not by
   scroll position. It is off the bottom of the screen until `community-sticky.js`
   adds `is-visible`, which it does only when the reader scrolls UP past the
   hero and the enquiry form is not already on screen. Transformed rather than
   hidden so it slides; `visibility` comes off the transition so it is not in
   the tab order while it is down. */
.elementor .community-sticky {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: 90;
	display: block;
	visibility: hidden;
	transform: translateY(100%);
	border-block-start: 1px solid var(--cd-rule);
	background-color: #FFFFFF;
	box-shadow: 0 -8px 28px rgba(11, 16, 32, 0.12);
	transition: transform 260ms ease, visibility 0s linear 260ms;
	padding-block-end: env(safe-area-inset-bottom, 0px);
}

.elementor .community-sticky.is-visible {
	visibility: visible;
	transform: translateY(0);
	transition: transform 260ms ease, visibility 0s;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .community-sticky {
		transition: none;
	}
}

/* The bar's own contents are styled with the rest of the enquiry furniture,
   under PROPERTY HERO below — it shares `.ccall` and `.csend` with the hero
   and the mid-page band, so styling it twice would let the three drift. */

/* ==========================================================================
   COMMUNITY DETAIL — ≤1200
   ========================================================================== */

@media (max-width: 1200px) {

	.elementor .community-overview .section-inner,
	.elementor .community-landmarks .section-inner {
		gap: 48px;
	}

	.elementor .community-overview__panel {
		flex-basis: 380px;
	}

	.elementor .community-landmarks__aside {
		flex-basis: 340px;
	}

	.camenities {
		grid-template-columns: repeat(3, 1fr);
	}

	.cschemes {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Three up. The first cell in each row drops its leading padding so the
	   column aligns, which means the card has to carry the inset instead —
	   otherwise "Property Types" sits on the card's own 8px and runs into
	   the border. */
	.cfacts {
		grid-auto-flow: row;
		grid-template-columns: repeat(3, 1fr);
		gap: 24px;
		padding: 24px;
	}

	.cfacts__cell:nth-child(3n + 1) {
		padding-inline-start: 0;
		border-inline-start: 0;
	}
}

/* ==========================================================================
   COMMUNITY DETAIL — ≤767
   The mobile frame stacks every one of these, and turns the fact row into a
   rule-separated list. The sticky bar appears here and nowhere else.
   ========================================================================== */

@media (max-width: 767px) {

	.elementor .community-overview .section-inner,
	.elementor .community-landmarks .section-inner {
		flex-direction: column;
		gap: 32px;
	}

	.elementor .community-overview__copy,
	.elementor .community-overview__panel,
	.elementor .community-landmarks__copy,
	.elementor .community-landmarks__aside {
		flex: 1 1 auto;
		max-width: none;
		width: 100%;
	}

	.cfigures,
	.elementor .community-landmarks__aside {
		padding: 24px;
	}

	.cfigures__figure {
		font-size: 32px;
		line-height: 42px;
	}

	/* Column dividers become row dividers: the cells are full width now, so a
	   vertical rule between them would be a line to nowhere.

	   The inset moves from the CELLS to the CARD. The cells drop to zero so
	   the dividers reach the full inner width — a rule that stops short on
	   both sides reads as a mistake — and the card takes the 20px instead.
	   Without that swap the labels sat on the card's own 8px and ran almost
	   into the border. */
	.cfacts {
		grid-auto-flow: row;
		grid-template-columns: 1fr;
		gap: 0;
		padding: 8px 20px;
	}

	.cfacts__cell {
		padding-inline: 0;
		padding-block: 14px;
		border-inline-start: 0;
		border-block-end: 1px solid var(--cd-rule);
	}

	.cfacts__cell:last-child {
		border-block-end: 0;
	}

	.camenities {
		grid-template-columns: 1fr;
		row-gap: 20px;
	}

	/* Payment schemes and update cards stay single file — they are read, not
	   compared, and each carries a paragraph. */
	.cschemes,
	.cupdates {
		grid-template-columns: 1fr;
	}

	/* The two PROPERTY CARD grids go 2-up, matching the Communities index and
	   the taxonomy archives. Same card, same width, same page. */
	.crelated,
	.cmodels__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 12px;
	}

	.csiteplan__hint {
		inset-block-end: 16px;
		inset-inline-end: 16px;
	}

	.cvlb {
		padding: 12px;
	}

	.cvlb__close {
		inset-block-start: 12px;
		inset-inline-end: 12px;
	}

	.cvideo__play {
		width: 64px;
		height: 64px;
	}

	.cvideo__play .cicon {
		width: 22px;
		height: 22px;
	}

	/* The bar's own pinning now applies at EVERY width and lives with the
	   rest of its rules — what was here was the phones-only version, and it
	   re-showed the bar unconditionally, defeating the scroll-direction
	   behaviour. Only the clearance below is still a phone concern. */
	body.is-community-detail .elementor .community-related {
		padding-block-end: 120px;
	}
}

/* --------------------------------------------------------------------------
   17 — INQUIRY: the band's own grounds

   The chrome is the Contact page's, but its colours are not: Contact pairs a
   pale blue info panel with a warm cream form. The community frame measures

     band        #FFFFFF
     form panel  linear-gradient(180deg, #F4FBFE 0%, #FAFCFE 50%, #F7F5F1 100%)
                 with a 1px #E3DFD7 edge
     info panel  #FFFFFF

   — the same soft gradient every other band on this page uses, so the form
   reads as a panel sitting ON the page rather than a second colour scheme
   arriving at the bottom of it.

   Scoped to `community-inquiry` throughout. The Contact page shares every one
   of these class names and must keep its own pairing.
   -------------------------------------------------------------------------- */

.elementor .community-inquiry {
	background-color: #FFFFFF;
}

.elementor .community-inquiry .contact-info {
	background-color: #FFFFFF;
	background-image: none;
}

.elementor .community-inquiry .contact-form-panel {
	background-color: #FAFCFE;
	background-image: linear-gradient(
		180deg,
		#F4FBFE 0%,
		#FAFCFE 50%,
		#F7F5F1 100%
	);
	border-inline-start: 1px solid var(--cd-rule);
}

@media (max-width: 1200px) {

	/* Stacked: the edge that separated the two panels is now above the form,
	   not beside it. */
	.elementor .community-inquiry .contact-form-panel {
		border-inline-start: 0;
		border-block-start: 1px solid var(--cd-rule);
	}
}


/* ==========================================================================
   PROPERTY CARDS — SPLIT LAYOUT                              2026-10-05

   Both property card families moved from "white text over the photograph" to
   "photograph on top, details on a white body beneath it". The overlay was
   fighting the subject matter: house photographs are mostly bright sky and
   pale render, so the wash needed to carry the type kept eating the house.
   Separating them means the photograph is never darkened at all and the
   details are read on plain white.

   TWO families, one change: `model-loop__card` (the Model Card loop item, the
   Communities page, and the community detail page) and `result-card` (the
   taxonomy archive results grid). Both already have the same three children —
   media, badge, body — as siblings of a `position: relative` card, so the
   conversion needs no document edits at all: the media stops being absolute,
   the body stops being an overlay, and the badge stays pinned over the photo.

   WHY HERE AND NOT IN THE GLOBAL CLASS PROPS. The overlay geometry lives in
   each class's Elementor props, which emit as single-class selectors — (0,1,0).
   Doubling the class here gives (0,3,0), so these win without rewriting prop
   JSON that the builder also reads. style.css is enqueued in the editor canvas
   too, so the builder shows the same thing.
   ========================================================================== */

.elementor .model-loop__card.model-loop__card,
.elementor .result-card.result-card {
	/* Stated, not inherited. The badge is positioned against this, and the
	   `position: relative` that used to come from the class's own Elementor
	   props does not reach the community page's cards, which are plain markup
	   carrying the class name rather than atomic elements. Without it the
	   badge anchored to an ancestor and floated off the top of the card. */
	position: relative;
	height: auto;
	min-height: 0;
	aspect-ratio: auto;
	padding: 0;
	overflow: hidden;
	border-radius: 14px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	background: #FFFFFF;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	align-items: stretch;
}

/* The photograph. `order: -1` is belt and braces — it is already the first
   child in both documents, but a card is a flex column now and the badge must
   never be able to push it down. */
.elementor .model-loop__card.model-loop__card .model-loop__media,
.elementor .result-card.result-card .result-card__media {
	order: -1;
	position: static;
	inset: auto;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
	border-radius: 0;
}

/* The details, on white. */
.elementor .model-loop__card.model-loop__card .model-card__body,
.elementor .result-card.result-card .result-card__body {
	position: relative;
	z-index: 2;
	flex: 1 1 auto;
	width: 100%;
	padding: 20px;
	gap: 8px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* The badge is the one thing that stays on the photograph. It is absolute to
   the card, and the photograph is now the top of the card, so it lands in the
   same place it always did. */
.elementor .model-loop__card.model-loop__card .model-card__availability,
.elementor .result-card.result-card .result-card__badge {
	position: absolute;
	inset-block-start: 16px;
	inset-inline-start: 16px;
	inset-inline-end: auto;
	z-index: 2;
	margin: 0;
	padding: 6px 12px;
	border-radius: 999px;
	font-size: 11px;
	line-height: 15px;
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
}

/* The scrim and both wash layers are now drawing over a photograph that has
   no text on it. `development-card__scrim` is a real element in the Model Card
   loop item, so it is hidden rather than deleted — the Development cards share
   the class and still need theirs. */
.elementor .model-loop__card.model-loop__card .development-card__scrim {
	display: none;
}

.elementor .model-loop__card.model-loop__card::after,
.elementor .model-loop__card.model-loop__card::before,
.elementor .result-card.result-card::after,
.elementor .result-card.result-card::before {
	content: none;
}

/* --- the copy, re-inked for a white ground -------------------------------- */

.elementor .model-loop__card.model-loop__card .model-card__place,
.elementor .result-card.result-card .result-card__place {
	font-size: 11px;
	line-height: 15px;
	font-weight: 600;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--cd-muted, #6B7285);
}

.elementor .model-loop__card.model-loop__card .model-card__title,
.elementor .result-card.result-card .result-card__title {
	font-size: 18px;
	line-height: 26px;
	font-weight: 600;
	color: var(--cd-ink, #0B1020);
}

.elementor .model-loop__card.model-loop__card .model-card__price,
.elementor .result-card.result-card .result-card__price {
	margin-block-start: auto;
	padding-block-start: 4px;
	font-size: 15px;
	line-height: 22px;
	font-weight: 600;
	color: var(--cd-ink, #0B1020);
}

/* Chips were translucent white for a photographic ground. On white they need
   a real tint and real ink. The archive's chips arrive as `<li>` from a
   shortcode; the loop item's are `spec-chip` paragraphs. Same treatment. */
.elementor .model-loop__card.model-loop__card .spec-chip,
.elementor .result-card.result-card .result-card__specs li {
	padding: 3px 10px;
	border: 0;
	border-radius: 6px;
	background-color: #F1F4F8;
	font-size: 13px;
	line-height: 19px;
	font-weight: 500;
	color: var(--cd-body, #2A3145);
}

/* The hover lift stays; the card is white now, so it also takes an edge. */
@media (hover: hover) {

	.elementor .model-loop__card.model-loop__card:hover,
	.elementor .result-card.result-card:hover {
		border-color: #CBD5E6;
	}
}

/* --- sold out ------------------------------------------------------------- */

/* The shortcode wraps a sold-out badge in <em> — the one signal that survives
   Elementor's sanitiser. Over a photograph it was a dark translucent chip;
   that still reads here, and keeps sold-out visually quieter than for-sale. */
.elementor .model-loop__card.model-loop__card .model-card__availability em,
.elementor .result-card.result-card .result-card__badge em {
	font-style: normal;
}

@media (max-width: 767px) {

	.elementor .model-loop__card.model-loop__card,
	.elementor .result-card.result-card {
		height: auto;
	}

	.elementor .model-loop__card.model-loop__card .model-card__body,
	.elementor .result-card.result-card .result-card__body {
		padding: 16px;
	}

	.elementor .model-loop__card.model-loop__card .model-card__title,
	.elementor .result-card.result-card .result-card__title {
		font-size: 16px;
		line-height: 23px;
	}
}

/* --------------------------------------------------------------------------
   Spec chip icons

   Drawn as a mask rather than a background image so each icon takes the chip's
   own `currentColor` — the same technique the download/arrow action icons use.
   A background-image SVG would be a fixed colour and would have to be reissued
   for every ground the chip can sit on.

   `data-spec` is set by inc/community-detail.php where it renders its own
   cards, and by assets/js/spec-icons.js everywhere else. A chip with no
   attribute simply keeps no icon, which is what the cards looked like before.
   -------------------------------------------------------------------------- */

.elementor .spec-chip[data-spec]::before,
.elementor .result-card__specs li[data-spec]::before {
	content: "";
	display: inline-block;
	vertical-align: -2px;
	width: 14px;
	height: 14px;
	margin-inline-end: 6px;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	opacity: 0.72;
}

.elementor .spec-chip[data-spec="bed"]::before,
.elementor .result-card__specs li[data-spec="bed"]::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 17v-4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4'/%3E%3Cpath d='M2 17v3M22 17v3M2 13V6'/%3E%3Cpath d='M6 11V9a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 17v-4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4'/%3E%3Cpath d='M2 17v3M22 17v3M2 13V6'/%3E%3Cpath d='M6 11V9a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2'/%3E%3C/svg%3E");
}

.elementor .spec-chip[data-spec="bath"]::before,
.elementor .result-card__specs li[data-spec="bath"]::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12V6a2 2 0 0 1 4 0'/%3E%3Cpath d='M2 12h20v2a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5v-2z'/%3E%3Cpath d='M6 19l-1 2M18 19l1 2'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12V6a2 2 0 0 1 4 0'/%3E%3Cpath d='M2 12h20v2a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5v-2z'/%3E%3Cpath d='M6 19l-1 2M18 19l1 2'/%3E%3C/svg%3E");
}

.elementor .spec-chip[data-spec="area"]::before,
.elementor .result-card__specs li[data-spec="area"]::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5'/%3E%3C/svg%3E");
}

/* The archive's chips come from a shortcode as a plain list, so the icon has
   to sit on an `<li>` that is also a flex item of the chip row. */
.elementor .result-card__specs li[data-spec] {
	display: inline-flex;
	align-items: center;
}

/* --------------------------------------------------------------------------
   Bands with nothing to say

   The data-driven sections hide themselves — their shortcode returns nothing
   and the `:has()` rules above collapse the band. These two cannot: their copy
   is an atomic Elementor paragraph, and an empty paragraph is still an element,
   so an unpopulated development printed "About Preciousville" over a blank.

   The test is done in PHP (`body_class`) rather than here, because "does this
   development have an overview" is a question about two ACF fields and a post
   body, which CSS cannot ask.
   -------------------------------------------------------------------------- */

body.cd-no-overview .elementor .community-overview,
body.cd-no-landmarks .elementor .community-landmarks {
	display: none;
}

/* The pillars underneath are site-wide and still worth showing, so only the
   missing lead goes — not the band. */
body.cd-no-why-lead .elementor .community-why__lead {
	display: none;
}

/* ==========================================================================
   PROPERTY HERO — GALLERY, ASIDE, ENQUIRY ROUTES
   Added 2026-10-05 with the revamped property detail page. Everything in this
   block is NEW furniture; the bands below the hero were already built and are
   untouched.

   Four things live here, and they are together because they share parts:

     .cgallery   the mosaic that replaced the single hero photograph
     .cviewer    the full-screen viewer it opens
     .caside     the price / address / share panel beside the title
     .cchannels  the contact routes — and `.ccall` / `.csend`, which the hero,
                 the mid-page band and the sticky bar all draw, so they are
                 defined ONCE here rather than three times

   The page is long and the enquiry form sits at the bottom of it. That is the
   problem this furniture exists to solve: a reader decides in the hero and
   should not have to scroll past nine sections to act on it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The band
   White, because the header above it is now solid white with the coloured
   lock-up — the old dark hero is gone, and `.page-hero` is deliberately NOT
   on this band so the site's white-header rule picks it up. If you ever add
   `page-hero` here the header goes transparent over a white photograph grid.
   -------------------------------------------------------------------------- */

.elementor .community-hero.community-hero {
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding-block: 28px 56px;
	background-color: #FFFFFF;
}

/* Each of the three rows is its own `section-inner`, so each is measured by
   the site's own 1248 measure rather than by a width stated here. */
.elementor .community-hero__crumbs {
	padding-block: 0;
}

/* The `breadcrumb` class is white — it was written for the dark hero this
   band replaced, and on white it rendered a trail nobody could see. Recoloured
   here only, so every other hero on the site keeps it. */
.elementor .community-hero__crumbs .breadcrumb,
.elementor .community-hero__crumbs .breadcrumb span {
	color: var(--cd-muted);
}

.elementor .community-hero__crumbs .breadcrumb a {
	color: var(--cd-body);
	text-decoration: none;
}

.elementor .community-hero__crumbs .breadcrumb a:hover,
.elementor .community-hero__crumbs .breadcrumb a:focus-visible {
	color: var(--cd-brand);
	text-decoration: underline;
}

/* Doubled, because Elementor's `.e-con` base sets `flex-direction: column`
   at the same specificity and loads after the theme — the aside dropped under
   the title at full width instead of sitting beside it. */
.elementor .community-hero__body.community-hero__body {
	display: flex;
	flex-direction: row;
	align-items: flex-start;
	gap: 56px;
}

.elementor .community-hero__copy {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	min-width: 0;
}

/* The lead is an atomic paragraph, and an atomic paragraph cannot collapse
   itself — an empty one is still an element with line-height. No property in
   the database carries an excerpt today, so this fired on all 26 model pages
   and left a 30px hole between the title and the buttons. `:empty` rather
   than a body class because it stays true the day somebody writes one. */
.elementor .community-hero__copy .ink-lead:empty {
	display: none;
}

/* `ink-lead` is the site's INVERSE pair — white, drawn for dark bands. The
   hero is white now, so the class that came over from the old dark hero would
   render the lead invisible the moment a property gets an excerpt. Recoloured
   here rather than swapped in the template, because the template's prop JSON
   is also read by the builder and the class is correct everywhere else. */
.elementor .community-hero__copy .ink-lead {
	max-width: 62ch;
	color: var(--cd-body);
}

.elementor .community-hero__copy .page-hero__title-sm {
	margin: 0;
	color: var(--cd-ink);
}

/* `button-primary` is a WHITE button with dark text — the kit defines it that
   way because it was drawn for the dark hero this band replaced, so on white
   it was a white label on white with no edge at all. The design shows a solid
   brand-blue button, which is what this makes it. Scoped to the new white
   bands rather than changed in the kit, because every dark band on the site
   still wants the white one. */
.elementor .community-hero__copy .button-primary,
.elementor .community-midcta .button-primary {
	border: 0;
	background-color: var(--cd-brand);
	color: #FFFFFF;
}

.elementor .community-hero__copy .button-primary:hover,
.elementor .community-hero__copy .button-primary:focus-visible,
.elementor .community-midcta .button-primary:hover,
.elementor .community-midcta .button-primary:focus-visible {
	background-color: #32498A;
	color: #FFFFFF;
}

/* The kit's button draws a trailing arrow from the href. On a filled button
   it crowded the label, and the design does not show one. */
.elementor .community-hero__copy a.button-primary[href]::after {
	content: none;
}

/* The hero's own CTA is WHITE with the brand gradient as its edge, the same
   treatment as the header Enquire button — not a solid blue block. The fill it
   had comes from `.community-hero__copy .button-primary` above; this rule is
   more specific and reaches only the hero's action row, so the mid-page CTA
   that shares the class keeps its solid fill. */
.elementor .community-hero__copy .page-hero__actions > .button-primary {
	position: relative;
	isolation: isolate;
	border: 0;
	/* The pale tint and the brand label are the RESTING state, not the hover —
	   white-on-white gave the ring nothing to sit against and the button read as
	   an outline with no weight. */
	background-color: #F4FBFE;
	color: var(--cd-brand);
}

/* Hover goes one step deeper on both, so there is still somewhere to travel. */
.elementor .community-hero__copy .page-hero__actions > .button-primary:hover,
.elementor .community-hero__copy .page-hero__actions > .button-primary:focus-visible {
	background-color: var(--cd-tint);
	color: var(--cd-brand-deep);
}

/* --------------------------------------------------------------------------
   The inquiry band's two direct routes
   Beside the form, for the reader who would rather not fill one in.
   -------------------------------------------------------------------------- */

/* The three cards in the inquiry panel used to be `inline-flex`, so each one
   shrank to its own content: a short telephone number made a narrow box and a
   long email address a wide one, and the column read as three unrelated
   fragments rather than one list. They are `flex` at a shared max-width now, so
   their left AND right edges line up.

   The max-width stops the email card running the full width of a 600px column
   on a wide screen, which would leave the label stranded at one end. */
.cdirect {
	display: flex;
	align-items: center;
	gap: 14px;
	width: 100%;
	max-width: 360px;
	/* No box. The border, the plate and the side padding are gone: three
	   outlined cards on a white panel were three frames around nothing, and the
	   padding pushed the labels off the column's left edge so they no longer
	   lined up with the heading above them. Vertical padding only, so the rows
	   still have air between them. */
	padding-block: 6px;
	padding-inline: 0;
	border: 0;
	border-radius: 0;
	background-color: transparent;
	color: var(--cd-ink);
	text-decoration: none;
	transition: color 200ms ease;
}

/* The icon is the one fixed-width thing in the row; without this it shrinks
   when the value beside it is long, and the three glyphs stop aligning down
   the column. */
.cdirect > .cicon {
	flex: 0 0 auto;
	color: var(--cd-brand);
}

/* The email address is the one value that can outgrow its card. Breaking on the
   @ and the dots keeps it inside rather than widening the box or spilling. */
.cdirect--email .cdirect__value {
	overflow-wrap: anywhere;
}

.elementor .cdirect:hover,
.elementor .cdirect:focus-visible {
	color: var(--cd-brand);
}

/* The mobile row is a DIV, not a link — it holds three numbers, so there is no
   single destination for the row itself to have. Only the numbers inside it are
   tappable, so it must not take the hover colour its neighbours do. */
.elementor .cdirect--mobile:hover,
.elementor .cdirect--mobile:focus-visible {
	color: var(--cd-ink);
}

.cdirect__value--stack {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.elementor .cdirect__line {
	color: var(--cd-ink);
	text-decoration: none;
	transition: color 160ms ease;
}

.elementor .cdirect__line:hover,
.elementor .cdirect__line:focus-visible {
	color: var(--cd-brand);
	text-decoration: underline;
}

/* Each card sits in its own Elementor shortcode widget, and those widgets
   shrink to their content — so the Mobile card, whose numbers are narrower than
   an email address, ended up a different width from its two neighbours. Giving
   the wrappers the full column makes `.cdirect`'s own `width: 100%` resolve
   against the same box for all three. */
.elementor .contact-info > .elementor-widget-shortcode,
.elementor .contact-info > .elementor-widget-shortcode > .elementor-shortcode {
	width: 100%;
}

/* The panel is a column with `gap: 40px`, which is right between the heading,
   the lead and the first row — and far too much BETWEEN the rows, where it made
   four related controls look like four sections. Cancelling most of it on each
   row after the first leaves about 12px, without touching the spacing above the
   stack or anywhere else `.contact-info` is used. */
.elementor .community-inquiry .contact-info > .elementor-widget-shortcode + .elementor-widget-shortcode {
	margin-block-start: -28px;
}

/* The panel's gap is NOT 40px everywhere — Elementor sets 32px at tablet and
   28px at phone. A flat -28px would leave 4px at tablet and zero at phone, so
   each breakpoint cancels its own gap down to the same 12px. */
@media (max-width: 1024px) {

	.elementor .community-inquiry .contact-info > .elementor-widget-shortcode + .elementor-widget-shortcode {
		margin-block-start: -20px;
	}
}

@media (max-width: 767px) {

	.elementor .community-inquiry .contact-info > .elementor-widget-shortcode + .elementor-widget-shortcode {
		margin-block-start: -16px;
	}
}

/* The messaging row sits under the cards, left-aligned with them. Its own label
   is small print rather than the heading weight the hero row uses — here it is
   the third option on the panel, not the headline. */
.elementor .inquiry-channels .cchannels {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
	margin-block-start: 6px;
}

.elementor .inquiry-channels .cchannels__label {
	font-size: 13px;
	line-height: 18px;
	font-weight: 600;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var(--cd-muted);
}

.cdirect__text {
	display: flex;
	flex-direction: column;
	gap: 1px;
}

.cdirect__label {
	color: var(--cd-muted);
	font-size: 12px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.cdirect__value {
	color: var(--cd-ink);
	font-size: 16px;
	line-height: 22px;
	font-weight: 600;
}

.elementor .community-hero__copy .page-hero__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px 24px;
	margin-block-start: 8px;
	padding: 0;
}

/* --------------------------------------------------------------------------
   The gallery mosaic
   Figma: an 824x520 lead with four 200x254 tiles beside it on the 1248
   measure — 824 + 12 + 200 + 12 + 200 = 1248, and 254 + 12 + 254 = 520. The
   columns are stated as those exact ratios so the proportions survive at any
   width, and the height comes from `aspect-ratio` rather than a pixel value
   so it scales with them.
   -------------------------------------------------------------------------- */

.cgallery {
	display: grid;
	grid-template-columns: 824fr 200fr 200fr;
	grid-template-rows: 1fr 1fr;
	gap: 12px;
	aspect-ratio: 1248 / 520;
	/* The ratio is the height. Stated as a ceiling as well so that no future
	   content — a taller tile, an added row — can reopen the same hole. */
	max-height: 560px;
	align-self: stretch;
	width: 100%;
	min-height: 0;
}

.cgallery__tile {
	position: relative;
	display: block;
	overflow: hidden;
	/* THE REASON `aspect-ratio` ON THE GRID WORKS AT ALL. A grid item defaults
	   to `min-height: auto`, which is its CONTENT's minimum — and the content
	   is a photograph whose intrinsic height is real pixels, not the 100% it
	   is told to render at. A portrait phone shot (768x1024) therefore held
	   the row open at its own height: the mosaic came out 1085px tall instead
	   of 514 and ate the whole screen, while `aspect-ratio: 1248/520` sat
	   there being quietly ignored. `min-width` for the same reason sideways. */
	min-width: 0;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 14px;
	background-color: var(--cd-plate);
	cursor: zoom-in;
	/* A tile is a <button>; without this it inherits the UA's centred,
	   11px system font and the "+N photos" label would come out tiny. */
	font: inherit;
	color: inherit;
	-webkit-appearance: none;
	appearance: none;
}

.cgallery__tile--lead {
	grid-row: span 2;
}

/* `.elementor img { height: auto }` is (0,1,1) and beat a bare
   `.cgallery__image` (0,1,0) — every tile but the lead letterboxed inside its
   own frame with the plate showing above and below. Doubling the class takes
   this to (0,3,0) without touching Elementor's own rule. */
.elementor .cgallery__image.cgallery__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 420ms ease;
}

.cgallery__tile:hover .cgallery__image,
.cgallery__tile:focus-visible .cgallery__image {
	transform: scale(1.04);
}

.cgallery__tile:focus-visible {
	outline: 3px solid var(--cd-brand);
	outline-offset: 2px;
}

/* A LONE PHOTOGRAPH IS NOT A BUTTON.

   The viewer only exists for two photographs or more, so below that the mosaic
   renders the tile as a <div> rather than a <button> — see
   `softouch_community_gallery_mosaic`. The tile styles are shared, and two of
   them promise an interaction the <div> does not have: `cursor: zoom-in` and
   the hover scale both say "this opens something". They are withdrawn here
   rather than redefined on the button, so the button form is untouched.

   `:not(button)` adds a type to the selector, which takes the hover reset to
   (0,3,1) against the (0,3,0) rule above — enough, and nothing more. */
.cgallery__tile:not(button) {
	cursor: default;
}

.cgallery__tile:not(button):hover .cgallery__image {
	transform: none;
}

/* The remainder badge. The count is derived in PHP from the same array the
   viewer is built from, so it cannot promise photographs that are not there.
   A full-tile wash rather than a corner pill: this tile is a door, and it
   should read as one at a glance. */
.cgallery__more {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: rgba(11, 16, 32, 0.56);
	color: #FFFFFF;
	font-size: 16px;
	line-height: 22px;
	font-weight: 600;
	letter-spacing: 0.01em;
	transition: background-color 240ms ease;
}

.cgallery__tile:hover .cgallery__more,
.cgallery__tile:focus-visible .cgallery__more {
	background-color: rgba(11, 16, 32, 0.68);
}

/* Fewer than five photographs would leave holes in the grid. Three fallbacks,
   by tile count, so the mosaic always reads as a deliberate arrangement —
   properties in the database run from 2 photographs to 28. */

/* Four: the last tile takes the whole bottom-right row rather than leaving a
   gap beside itself. */
.cgallery:has(> :nth-child(4)):not(:has(> :nth-child(5))) > :nth-child(4) {
	grid-column: 2 / span 2;
}

/* Three: two columns, one tile per row. */
.cgallery:has(> :nth-child(3)):not(:has(> :nth-child(4))) {
	grid-template-columns: 824fr 412fr;
}

/* Two: side by side on a single row. */
.cgallery:has(> :nth-child(2)):not(:has(> :nth-child(3))) {
	grid-template-columns: 824fr 412fr;
	grid-template-rows: 1fr;
}

.cgallery:has(> :nth-child(2)):not(:has(> :nth-child(3))) > .cgallery__tile--lead {
	grid-row: auto;
}

/* One: the whole width, as a hero rather than a mosaic with a hole in it.

   The lead otherwise keeps its 824fr column and the two 200fr columns stay
   open, so a property with a single photograph drew the picture across three
   fifths of the band and nothing across the other two. Anami Homes South is
   the first property to have exactly one, which is why this case was never
   written.

   The ratio relaxes with it. 1248/520 is the FIVE-tile ratio: a 2.4:1 letterbox
   that is right for a mosaic and wrong for one photograph, which would lose a
   quarter of its height to the crop. 16/9 across the full width is the same
   band the rest of the site uses for a single image, and the ceiling rises to
   match so `max-height` does not quietly put the letterbox back. */
.cgallery:not(:has(> :nth-child(2))) {
	grid-template-columns: 1fr;
	grid-template-rows: 1fr;
	aspect-ratio: 16 / 9;
	max-height: 702px;
}

.cgallery:not(:has(> :nth-child(2))) > .cgallery__tile--lead {
	grid-row: auto;
}

/* --------------------------------------------------------------------------
   The aside — price, address, share
   A narrow panel beside the title. Not a card: a hairline on its leading edge
   and nothing else, so it reads as a column of facts rather than as a second
   piece of content competing with the heading.
   -------------------------------------------------------------------------- */

/* 448px, matching the Overview figures panel below — the two right-hand boxes
   on this page share an edge now. The column is what sets the box's width: the
   `.caside` inside it is capped by `max-width: 100%`, so widening the box alone
   did nothing until this came with it. */
.elementor .community-hero__aside.community-hero__aside {
	display: flex;
	flex: 0 0 448px;
	flex-direction: column;
	max-width: 448px;
	/* The column carried 10px of side padding, so the panel inside it drew at
	   428px against the Overview panel's 448 — a 10px misalignment on both
	   edges. The column IS the measure now; the box fills it. */
	padding-inline: 0;
}

/* `.community-shortcode` is `display: contents`, so THIS is the flex item of
   the aside column — and that column is `align-items: flex-start`, which made
   it hug its longest line at 182px inside a 316px slot. The same trap the
   fact grids hit; the same fix. */
/* A card, per the design — not the hairline column this first shipped as.
   The difference matters: a bordered panel says "these are the facts you act
   on", which is what the price, the address and the share row are. The rows
   are separated by their own top borders rather than by divider elements, so
   a property with no price loses a line instead of keeping a stray rule. */
/* The gradient edge, shared with the payment cards — see THE GRADIENT RING
   below, which lists both. Only the OUTER edge is the gradient; the hairlines
   between Starting price, Address and Share stay `--cd-rule`, because they
   separate rows inside one panel rather than bounding it. */
.caside {
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	align-self: stretch;
	/* 448px, matching the Overview figures panel below it — the two right-hand
	   boxes on this page now share an edge. It was shrink-wrapping to 296px:
	   `width: 100%` resolves against `.elementor-shortcode`, which is a
	   zero-width wrapper, so the percentage had nothing to measure against.
	   `max-width: 100%` keeps it inside narrower columns. */
	width: 448px;
	max-width: 100%;
	padding: 28px;
	border: 0;
	border-radius: 16px;
	background-color: #FFFFFF;
}

.caside__row {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding-block: 18px;
	border-block-start: 1px solid var(--cd-rule);
}

.caside__row:first-child {
	padding-block-start: 0;
	border-block-start: 0;
}

.caside__row:last-child {
	padding-block-end: 0;
}

.caside__label {
	margin: 0;
	color: var(--cd-muted);
	font-size: 12px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.caside__value {
	margin: 0;
	color: var(--cd-ink);
	font-size: 17px;
	line-height: 24px;
	font-weight: 500;
}

.caside__value--price {
	font-size: 22px;
	line-height: 30px;
	font-weight: 700;
}

.caside__share {
	display: flex;
	gap: 10px;
}

/* --------------------------------------------------------------------------
   Share buttons
   Share and contact are different sets and look different on purpose. These
   are quiet outlines — passing the page on is a secondary act. The contact
   routes below are filled, because starting a conversation is the point of
   the page.
   -------------------------------------------------------------------------- */

.cshare {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var(--cd-rule);
	border-radius: 999px;
	background-color: #FFFFFF;
	color: var(--cd-body);
	cursor: pointer;
	transition: border-color 200ms ease, color 200ms ease, background-color 200ms ease;
}

.elementor .cshare:hover,
.elementor .cshare:focus-visible {
	border-color: var(--cd-brand);
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

/* The confirmation after a copy. Absolute so it cannot push the row wider
   when it appears — a layout that jumps on success feels like a failure. */
.cshare__done {
	position: absolute;
	inset-block-end: calc(100% + 8px);
	inset-inline-start: 50%;
	transform: translateX(-50%);
	padding: 5px 10px;
	border-radius: 6px;
	background-color: var(--cd-ink);
	color: #FFFFFF;
	font-size: 12px;
	line-height: 16px;
	white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Contact routes
   The label and the icons sit on ONE line — the row is the sentence, and
   breaking "Talk to a Property Specialist" above its own buttons made it read
   as a heading for a section that is not there.
   -------------------------------------------------------------------------- */

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

.cchannels__label {
	color: var(--cd-body);
	font-size: 15px;
	line-height: 22px;
	font-weight: 600;
}

.cchannels__row {
	display: inline-flex;
	gap: 8px;
}

/* Brand colours AT REST, not on hover. These marks are recognised by colour
   before they are recognised by shape — a row of four identical pale discs
   made the reader stop and look at each one, which is the opposite of what a
   row of shortcuts is for. The design shows them filled. */
.cchannel {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 999px;
	background-color: var(--cd-brand);
	color: #FFFFFF;
	text-decoration: none;
	transition: filter 200ms ease, transform 200ms ease;
}

/* NOT prefixed with `.elementor`, and that is load-bearing. The gallery
   viewer is reparented to <body> on open — it has to be, or a `position:
   fixed` dialog paints under the page — so inside it nothing matches
   `.elementor .thing`. The base `.cchannel` rule is unprefixed and kept
   working, which is exactly why this was hard to see: all three discs simply
   fell back to brand blue and looked deliberate.

   Doubled instead, which buys the same specificity without depending on an
   ancestor that is not always there. */
.cchannel--whatsapp.cchannel--whatsapp {
	background-color: #25D366;
	color: #FFFFFF;
}

.cchannel--viber.cchannel--viber {
	background-color: #7360F2;
	color: #FFFFFF;
}

.cchannel--messenger.cchannel--messenger {
	background-color: #0084FF;
	color: #FFFFFF;
}

/* The form is the house route, so it keeps the house colour. */
.cchannel--form.cchannel--form {
	background-color: var(--cd-brand);
	color: #FFFFFF;
}

.cchannel:hover,
.cchannel:focus-visible {
	filter: brightness(1.08);
	transform: translateY(-1px);
}

/* --------------------------------------------------------------------------
   Call and Send — the two buttons, shared by three places
   -------------------------------------------------------------------------- */

.ccall,
.csend {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 13px 22px;
	border-radius: 8px;
	font-size: 16px;
	line-height: 22px;
	font-weight: 500;
	text-align: center;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.elementor .ccall--ghost {
	border: 1px solid var(--cd-rule);
	background-color: #FFFFFF;
	color: var(--cd-ink);
}

.elementor .ccall--ghost:hover,
.elementor .ccall--ghost:focus-visible {
	border-color: var(--cd-brand);
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

.elementor .csend {
	background-color: var(--cd-brand);
	color: #FFFFFF;
}

.elementor .csend:hover,
.elementor .csend:focus-visible {
	background-color: #32498A;
	color: #FFFFFF;
}

/* --------------------------------------------------------------------------
   Mid-page enquiry band
   Sits straight after Types of Homes, which is where a reader has just seen
   something they like and has the furthest still to scroll.
   -------------------------------------------------------------------------- */

.elementor .community-midcta.community-midcta {
	padding-block: 48px;
	background-color: var(--cd-aside);
}

/* `flex-direction` is stated, not assumed. Leaving it out let the element's
   own Elementor prop keep this a COLUMN — and in a column `flex: 1 1 420px`
   on the copy sets its HEIGHT, which opened a 250px void between the sentence
   and the buttons. The basis is a width; the direction has to say so. */
.elementor .community-midcta__inner.community-midcta__inner {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 28px 48px;
}

.elementor .community-midcta__copy {
	display: flex;
	flex: 1 1 420px;
	flex-direction: column;
	gap: 10px;
	min-width: 0;
}

.elementor .community-midcta__copy .heading-2 {
	margin: 0;
}

.elementor .community-midcta__copy .body-base {
	margin: 0;
	max-width: 56ch;
}

/* `width: 100%` is an Elementor atomic default and it defeats the row: with
   an `auto` basis the actions resolved to the full 1233px measure, took a
   flex line of their own and dropped under the copy. Stating `width: auto`
   is what makes `space-between` mean anything here. */
.elementor .community-midcta__actions.community-midcta__actions {
	display: flex;
	flex: 0 0 auto;
	flex-wrap: wrap;
	align-items: center;
	width: auto;
	gap: 14px 20px;
}

/* --------------------------------------------------------------------------
   The sticky bar — phones only
   The band's own fixed positioning is set further up, with the rest of the
   community detail CSS. This is only its contents.
   -------------------------------------------------------------------------- */

.csticky {
	display: flex;
	align-items: center;
	gap: 16px;
	width: min(1248px, 100%);
	margin-inline: auto;
	padding: 12px 24px;
}

.csticky__what {
	flex: 1 1 auto;
	min-width: 0;
}

.csticky__title,
.csticky__where {
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.csticky__title {
	color: var(--cd-ink);
	font-size: 15px;
	line-height: 20px;
	font-weight: 600;
}

.csticky__where {
	color: var(--cd-muted);
	font-size: 13px;
	line-height: 18px;
}

.csticky__actions {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 8px;
}

.elementor .csticky__cta {
	display: inline-flex;
	align-items: center;
	padding: 11px 16px;
	border-radius: 8px;
	background-color: var(--cd-brand);
	color: #FFFFFF;
	font-size: 15px;
	line-height: 20px;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

.csticky__actions .cchannel {
	width: 44px;
	height: 44px;
}

.elementor .csticky__cta:hover,
.elementor .csticky__cta:focus-visible {
	background-color: #32498A;
	color: #FFFFFF;
}

/* ==========================================================================
   THE GALLERY VIEWER
   White, not the usual black lightbox. These are photographs of houses a
   family is deciding about, and a black room makes a bright exterior shot
   look like evidence. The rail on the right is what makes it better than a
   centred image: every photograph is visible as a thumbnail, the position is
   always stated, and the two things a reader might want to do next are in it.
   ========================================================================== */

/* A panel over the page, not a takeover of it. Full-screen made a decision
   for the reader — it said "you are now in the gallery" — when all they did
   was tap a photograph. At 60% of the viewport the page stays visible behind
   it, so closing it feels like putting something down rather than going back. */
.cviewer {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	background-color: rgba(11, 16, 32, 0.62);
}

.cviewer__panel {
	display: flex;
	overflow: hidden;
	width: min(1280px, 100%);
	/* 60% is the design target. The floor stops the rail's buttons from
	   colliding with its thumbnails on a short laptop screen, and the ceiling
	   keeps the backdrop visible on a tall one. */
	height: 60vh;
	min-height: 440px;
	max-height: 86vh;
	border-radius: 16px;
	background-color: #FFFFFF;
	box-shadow: 0 24px 70px rgba(11, 16, 32, 0.34);
}

/* `display: flex` beats the `hidden` attribute, so it has to be restated.
   Without this line the viewer is open on every page load. */
.cviewer[hidden] {
	display: none;
}

/* hello-elementor's `reset.css` paints EVERY <button> in #CC3366 — a magenta
   border, magenta text and a magenta focus ring. It is (0,0,1) so it loses on
   background, but `color` and `outline-color` were never restated here, and
   the close button is focused the instant the viewer opens: it came up as a
   magenta ring around a magenta glyph. Every button this build adds is named
   here once, so no new control inherits that colour again. */
/* hello-elementor's `reset.css` is the whole story here:

     button:focus, button:hover { background-color: #c36; color: #fff }
     button:focus-visible       { box-shadow: 0 0 0 4px #fff; outline: 2px solid #000 }

   `:hover` was already answered, `:focus` was not — and a button KEEPS focus
   after a mouse click. So the first click on the next-photo arrow turned it
   magenta and it stayed that way for the rest of the session. Every state is
   answered here, for every button this build adds, so no new control inherits
   that colour again. */
.cviewer__nav,
.cviewer__close,
.cviewer__thumb,
.cgallery__tile {
	color: var(--cd-ink);
}

/* The share marks are BRAND, measured #405BA9 off Figma 613:34 — they were
   taking the near-black the reset-override above hands the gallery controls,
   which made them read as punctuation rather than as the one accent in the
   panel. Listed separately so the gallery controls keep their ink. */
.elementor .cshare {
	color: var(--cd-brand);
}

.cviewer__nav:focus,
.cviewer__nav:hover,
.cviewer__close:focus,
.cviewer__close:hover {
	background-color: #FFFFFF;
	color: var(--cd-ink);
}

.elementor .cshare:focus,
.elementor .cshare:hover {
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

.cviewer__nav:hover,
.cviewer__nav:focus-visible,
.cviewer__close:hover,
.cviewer__close:focus-visible {
	background-color: var(--cd-tint);
	border-color: var(--cd-brand);
}

.cgallery__tile:focus,
.cgallery__tile:hover,
.cviewer__thumb:focus,
.cviewer__thumb:hover {
	background-color: var(--cd-plate);
}

/* The reset's focus ring is a white halo and a black outline, drawn for a
   dark theme. Ours is the brand colour, and the halo has to be cancelled
   explicitly or it sits under the outline as a 4px white band. */
.cviewer__nav:focus-visible,
.cviewer__close:focus-visible,
.cviewer__thumb:focus-visible,
.cgallery__tile:focus-visible,
.cshare:focus-visible {
	outline: 3px solid var(--cd-brand);
	outline-offset: 2px;
	box-shadow: none;
}

/* A click should not leave a ring behind; the keyboard still gets one. */
.cviewer__nav:focus:not(:focus-visible),
.cviewer__close:focus:not(:focus-visible),
.cviewer__thumb:focus:not(:focus-visible),
.cgallery__tile:focus:not(:focus-visible),
.cshare:focus:not(:focus-visible) {
	outline: none;
	box-shadow: none;
}

/* The page behind must not scroll while it is open. Set on the root element
   by the script, so it is removed again on close even if the viewer is
   somewhere unexpected in the document. */
.has-cviewer,
.has-cviewer body {
	overflow: hidden;
}

.cviewer__stage {
	position: relative;
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	min-width: 0;
	padding: 32px 72px 60px;
}

.cviewer__frame {
	position: relative;
	width: 100%;
	height: 100%;
	/* Say it is draggable before anyone tries. The arrows are still there for
	   people who would rather click, and the keyboard still works. */
	cursor: grab;
	/* The horizontal gesture belongs to us; vertical and pinch stay with the
	   browser so a photograph can still be zoomed on a phone. */
	touch-action: pan-y pinch-zoom;
}

.cviewer__frame.is-dragging {
	cursor: grabbing;
}

/* The image must not be the drag target itself, or the browser offers its own
   "drag this picture out" gesture and a ghost follows the cursor. */
.cviewer__image {
	-webkit-user-drag: none;
	user-select: none;
}

/* While a drag is in progress the slide follows the pointer directly — a
   transition here would make it lag behind the finger. It comes back for the
   release, which is what makes the snap-back feel like a spring. */
.cviewer__slide {
	transition: opacity 260ms ease, transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.cviewer__frame.is-dragging .cviewer__slide {
	transition: opacity 260ms ease;
}

.cviewer__slide {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	margin: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity 260ms ease;
}

.cviewer__slide.is-current {
	opacity: 1;
	visibility: visible;
}

.cviewer__image {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	border-radius: 12px;
	object-fit: contain;
}

/* Below the photograph, not over it. Nothing in the library carries a caption
   today — all 333 gallery attachments are blank — so this renders only when
   somebody writes one, and the slot is here so they can. */
.cviewer__caption {
	flex: 0 0 auto;
	max-width: 72ch;
	color: var(--cd-muted);
	font-size: 14px;
	line-height: 20px;
	text-align: center;
}

/* --- Stage furniture ----------------------------------------------------- */

.cviewer__nav {
	position: absolute;
	inset-block-start: 50%;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	padding: 0;
	transform: translateY(-50%);
	border: 1px solid var(--cd-rule);
	border-radius: 999px;
	background-color: #FFFFFF;
	cursor: pointer;
	transition: border-color 200ms ease, background-color 200ms ease;
}

.cviewer__nav:hover,
.cviewer__nav:focus-visible {
	border-color: var(--cd-brand);
	background-color: var(--cd-tint);
}

.cviewer__nav--prev {
	inset-inline-start: 14px;
}

.cviewer__nav--next {
	inset-inline-end: 14px;
}

/* The chevrons are drawn rather than shipped — two borders on a rotated
   square. The buttons are empty in the markup on purpose, so there is no
   icon file to go missing. */
/* A chevron is an L rotated 45°, and an L's optical centre is not its
   geometric one — the corner sits on the diagonal, so a plain rotation leaves
   it hanging toward the point. The nudge is applied along the BOX axes after
   the rotation (margin, not a second translate inside the rotated frame),
   which is why the two directions take opposite signs. */
.cviewer__nav::before {
	content: "";
	width: 10px;
	height: 10px;
	border-top: 2px solid currentColor;
	border-right: 2px solid currentColor;
}

.cviewer__nav--prev::before {
	transform: rotate(-135deg);
	margin-inline-start: 3px;
}

.cviewer__nav--next::before {
	transform: rotate(45deg);
	margin-inline-end: 3px;
}

.cviewer__count {
	position: absolute;
	inset-block-end: 34px;
	inset-inline-start: 50%;
	transform: translateX(-50%);
	margin: 0;
	color: var(--cd-muted);
	font-size: 14px;
	line-height: 20px;
	font-variant-numeric: tabular-nums;
}

/* A thin line under the stage. Decorative — the count above it and the live
   region in the script both state the position in words. */
.cviewer__progress {
	position: absolute;
	inset-block-end: 0;
	inset-inline: 0;
	display: block;
	height: 3px;
	background-color: var(--cd-plate);
}

/* Scaled, not resized. Animating `width` makes the browser lay out on every
   frame of the transition; `transform` is composited and does not. The bar is
   only 3px tall, so the cost was small — but it is the one thing in this build
   that animates a layout property, and there is no reason for it to be. */
.cviewer__progress-fill {
	display: block;
	width: 100%;
	height: 100%;
	transform: scaleX(0);
	transform-origin: left center;
	background-color: var(--cd-brand);
	transition: transform 300ms ease;
}

/* --- The rail ------------------------------------------------------------ */

.cviewer__rail {
	position: relative;
	display: flex;
	flex: 0 0 404px;
	flex-direction: column;
	gap: 18px;
	padding: 28px 28px 24px;
	border-inline-start: 1px solid var(--cd-rule);
	background-color: #FDFDFC;
}

.cviewer__eyebrow {
	margin: 0;
	padding-inline-end: 48px;
	color: var(--cd-ink);
	font-size: 20px;
	line-height: 27px;
	font-weight: 700;
}

.cviewer__total {
	margin: -12px 0 0;
	color: var(--cd-muted);
	font-size: 13px;
	line-height: 18px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.cviewer__close {
	position: absolute;
	inset-block-start: 22px;
	inset-inline-end: 24px;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var(--cd-rule);
	border-radius: 999px;
	background-color: #FFFFFF;
	cursor: pointer;
	transition: border-color 200ms ease, background-color 200ms ease;
}

.cviewer__close:hover,
.cviewer__close:focus-visible {
	border-color: var(--cd-brand);
	background-color: var(--cd-tint);
}

.cviewer__close::before,
.cviewer__close::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 15px;
	height: 2px;
	background-color: var(--cd-ink);
}

.cviewer__close::before {
	transform: translate(-50%, -50%) rotate(45deg);
}

.cviewer__close::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

/* Every photograph, visible at once — this is the thing a centred lightbox
   cannot do, and the reason the rail is worth 404px. It scrolls; the CTA
   below it does not, so the two actions never move. */
.cviewer__thumbs {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	/* `align-content` keeps few thumbnails from being spread down a tall rail.
	   `grid-auto-rows: min-content` is the other half, and it is the one that
	   matters most: the rail is a flex item with a DEFINITE height, so `auto`
	   rows were sized by dividing that height between them. With a short
	   viewport that gave a 29px row pitch for 81px thumbnails — twenty-six
	   photographs piled on top of each other, each showing through the one
	   above because they are drawn at 58% opacity. */
	align-content: start;
	grid-auto-rows: min-content;
	gap: 8px;
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	margin-inline: -4px;
	padding: 4px;
	scrollbar-width: thin;
}

.cviewer__thumb {
	position: relative;
	display: block;
	overflow: hidden;
	/* Not stretched. A grid item that stretches takes its height from the
	   row, and the row takes its height from the item — `aspect-ratio` loses
	   that argument, and the square becomes whatever is left over. Starting
	   the item breaks the circle: width comes from the column, height from
	   the ratio, and the row follows. */
	align-self: start;
	aspect-ratio: 1;
	padding: 0;
	border: 0;
	border-radius: 8px;
	background-color: var(--cd-plate);
	cursor: pointer;
	opacity: 0.58;
	transition: opacity 200ms ease, box-shadow 200ms ease;
}

.elementor .cviewer__thumb img,
.cviewer__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cviewer__thumb:hover,
.cviewer__thumb:focus-visible {
	opacity: 1;
}

/* The current thumbnail is marked by a ring AND full opacity — opacity alone
   is not a reliable signal for anyone who cannot compare two greys. */
.cviewer__thumb.is-current {
	opacity: 1;
	box-shadow: 0 0 0 2px var(--cd-brand);
}

.cviewer__cta {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 12px;
	padding-block-start: 16px;
	border-block-start: 1px solid var(--cd-rule);
}

/* The chat icons keep their own size; the Call button takes what is left.
   Without this the icon row is a flex item like any other and shared the
   width equally with the button, which stretched three 42px discs across
   half the rail. */
.cviewer__cta .cchannels {
	flex: 0 0 auto;
	gap: 0;
}

.cviewer__cta .cchannels__row {
	gap: 10px;
}

.cviewer__btn--ghost {
	flex: 1 1 auto;
}

.cviewer__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 12px 14px;
	border: 1px solid transparent;
	border-radius: 8px;
	font-size: 15px;
	line-height: 21px;
	font-weight: 500;
	text-align: center;
	text-decoration: none;
	transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.cviewer__btn--ghost {
	border-color: var(--cd-rule);
	background-color: #FFFFFF;
	color: var(--cd-ink);
}

.cviewer__btn--ghost:hover,
.cviewer__btn--ghost:focus-visible {
	border-color: var(--cd-brand);
	background-color: var(--cd-tint);
	color: var(--cd-brand);
}

.cviewer__btn--solid {
	background-color: var(--cd-brand);
	color: #FFFFFF;
}

.cviewer__btn--solid:hover,
.cviewer__btn--solid:focus-visible {
	background-color: #32498A;
	color: #FFFFFF;
}

.cviewer__hint {
	flex: 0 0 auto;
	margin: 0;
	color: var(--cd-muted);
	font-size: 12px;
	line-height: 16px;
	text-align: center;
}

/* ==========================================================================
   PROPERTY HERO — 1200 and below
   ========================================================================== */

@media (max-width: 1200px) {

	.elementor .community-hero__body.community-hero__body {
		gap: 36px;
	}

	.elementor .community-hero__aside.community-hero__aside {
		flex-basis: 380px;
		max-width: 380px;
	}

	.caside {
		padding-inline-start: 22px;
	}

	.elementor .community-midcta.community-midcta {
		padding-block: 40px;
	}

	.cviewer__rail {
		flex-basis: 332px;
	}

	.cviewer__thumbs {
		grid-template-columns: repeat(3, 1fr);
	}

	.cviewer__stage {
		padding: 36px 64px 70px;
	}
}

/* ==========================================================================
   PROPERTY HERO — 1024 and below
   The aside drops under the copy. Below this width a 268px column beside a
   heading leaves neither of them a comfortable measure.
   ========================================================================== */

@media (max-width: 1024px) {

	/* Doubled to match the base rule. The base had to be doubled to beat
	   Elementor's own `.e-con` column default, which left THIS override at a
	   lower specificity than the rule it was written to undo — the aside
	   stayed beside the title all the way down to 390px, where the heading
	   and the address overlapped and the primary button ran off the screen. */
	.elementor .community-hero__body.community-hero__body {
		flex-direction: column;
		gap: 28px;
	}

	.elementor .community-hero__aside.community-hero__aside {
		flex: 1 1 auto;
		max-width: none;
		width: 100%;
	}

	/* No longer a column beside anything, so the hairline moves from its
	   leading edge to its top and the rows go side by side. */
	/* Still a card below 1024, just a wider one whose rows sit side by side.
	   The row borders become leading edges so they still separate. */
	.caside {
		flex-direction: row;
		flex-wrap: wrap;
		gap: 0 32px;
		padding: 22px 24px;
	}

	.caside__row {
		flex: 1 1 180px;
		padding-block: 0;
		padding-inline-start: 32px;
		border-block-start: 0;
		border-inline-start: 1px solid var(--cd-rule);
	}

	.caside__row:first-child {
		padding-inline-start: 0;
		border-inline-start: 0;
	}

	/* The rail becomes a strip under the photograph. This is the PANEL, not
	   the backdrop — `.cviewer` is the dimmed sheet that centres it, and
	   turning THAT into a column stacked nothing and left an empty white box. */
	.cviewer {
		padding: 16px;
	}

	.cviewer__panel {
		flex-direction: column;
		height: 72vh;
		min-height: 420px;
	}

	.cviewer__stage {
		flex: 1 1 auto;
		min-height: 0;
		padding: 20px 52px 48px;
	}

	.cviewer__rail {
		flex: 0 0 auto;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		gap: 12px 20px;
		padding: 16px 20px;
		border-inline-start: 0;
		border-block-start: 1px solid var(--cd-rule);
	}

	/* One scrolling ROW now, so the grid rules that keep square thumbnails in
	   a column layout have to be unwound or the row collapses to one item. */
	.cviewer__thumbs {
		grid-auto-rows: auto;
		align-content: center;
	}

	.cviewer__thumb {
		align-self: center;
		height: 64px;
	}

	.cviewer__eyebrow {
		padding-inline-end: 0;
		font-size: 17px;
		line-height: 23px;
	}

	.cviewer__total,
	.cviewer__hint {
		margin: 0;
	}

	.cviewer__hint {
		display: none;
	}

	/* One scrolling row of thumbnails rather than a grid — a grid here would
	   be taller than the photograph it belongs to. */
	.cviewer__thumbs {
		flex: 1 1 100%;
		grid-template-columns: none;
		grid-auto-flow: column;
		grid-auto-columns: 76px;
		overflow-x: auto;
		overflow-y: hidden;
	}

	.cviewer__close {
		inset-block-start: 14px;
		inset-inline-end: 16px;
		width: 36px;
		height: 36px;
	}

	.cviewer__cta {
		flex: 1 1 100%;
		padding-block-start: 12px;
	}
}

/* ==========================================================================
   PROPERTY HERO — phones
   ========================================================================== */

@media (max-width: 767px) {

	.elementor .community-hero.community-hero {
		gap: 18px;
		padding-block: 20px 36px;
	}

	/* Figma: a 342x240 lead on the phone measure, with the remaining tiles as
	   a strip of thumbs beneath it. All five tiles stay — hiding the last one
	   would take the "+N photos" badge with it and leave the count wrong. */
	.cgallery {
		grid-template-columns: repeat(4, 1fr);
		grid-template-rows: auto auto;
		gap: 8px;
		aspect-ratio: auto;
	}

	.cgallery__tile {
		border-radius: 10px;
	}

	.cgallery__tile--lead {
		grid-column: 1 / -1;
		grid-row: auto;
		aspect-ratio: 342 / 240;
	}

	.cgallery__tile:not(.cgallery__tile--lead) {
		aspect-ratio: 1;
	}

	/* The single-photograph case takes a 16/9 band on the desktop measure. The
	   phone does not want it: the lead tile already carries its own 342/240,
	   and with the grid asserting a second ratio over it the band computed
	   taller than the tile inside it — the breadcrumb below rode up into the
	   photograph. The tile's ratio is the one that should win here, so the
	   grid withdraws. */
	.cgallery:not(:has(> :nth-child(2))) {
		aspect-ratio: auto;
		max-height: none;
	}

	/* The fallbacks for small sets are a desktop concern — on one column per
	   tile there are no holes to fill. */
	.cgallery:has(> :nth-child(4)):not(:has(> :nth-child(5))) > :nth-child(4),
	.cgallery:has(> :nth-child(3)):not(:has(> :nth-child(4))),
	.cgallery:has(> :nth-child(2)):not(:has(> :nth-child(3))) {
		grid-column: auto;
		grid-template-columns: repeat(4, 1fr);
	}

	.cgallery__more {
		font-size: 13px;
		line-height: 18px;
		text-align: center;
	}

	.elementor .community-hero__copy .page-hero__actions {
		gap: 14px 18px;
	}

	/* The primary button goes full width; the channels row stays inline
	   beneath it rather than becoming a second stack of blocks. */
	.elementor .community-hero__copy .page-hero__actions > .button-primary {
		width: 100%;
	}

	/* One row per line here, so the LEADING border the tablet layout uses is
	   no longer dividing anything — it was a 1px tick floating to the left of
	   each label. Rows divide the way they do in the card at full width and
	   in the facts card below: a rule across the top of each one, so there is
	   a line under the price and a line under the address. */
	.caside {
		flex-direction: column;
		gap: 0;
		padding: 22px 24px;
	}

	.caside__row {
		flex: 1 1 auto;
		padding-block: 16px;
		padding-inline-start: 0;
		border-inline-start: 0;
		border-block-start: 1px solid var(--cd-rule);
	}

	.caside__row:first-child {
		padding-block-start: 0;
		border-block-start: 0;
	}

	.caside__row:last-child {
		padding-block-end: 0;
	}

	.caside__value--price {
		font-size: 20px;
		line-height: 27px;
	}

	/* The property's name comes off the bar entirely at this width. There is
	   no room for it beside a telephone, two or three chat icons and the
	   enquiry button, and it was losing — the name and locality were being
	   overlapped by the actions rather than pushing them anywhere. Nothing is
	   lost by dropping it: the reader is ON that property's page, and the
	   title is a few centimetres up the screen. */
	.csticky__what {
		display: none;
	}

	/* On a 360px screen the number pushes the enquiry button off the bar, so
	   here — and only here — the call button is the icon alone. The href
	   still carries the number and the label is still read aloud. */
	.csticky {
		gap: 10px;
		padding: 10px 16px;
	}

	/* With the name gone the actions own the bar, so they spread across it
	   rather than huddling at the right-hand end. */
	.csticky__actions {
		flex: 1 1 auto;
		justify-content: space-between;
	}

	.elementor .csticky__cta {
		flex: 1 1 auto;
		justify-content: center;
	}

	.csticky .ccall {
		padding: 11px;
		gap: 0;
	}

	.csticky .ccall span {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
	}

	/* Two routes is all that fits beside the name and the enquiry button. */
	.csticky__actions .cchannel {
		width: 40px;
		height: 40px;
	}

	.elementor .community-midcta.community-midcta {
		padding-block: 32px;
	}

	.elementor .community-midcta__inner.community-midcta__inner {
		flex-direction: column;
		align-items: flex-start;
	}

	/* A basis of 420px would be the copy's height again once this is a
	   column. It only ever meant "do not wrap above 420px wide". */
	.elementor .community-midcta__copy {
		flex: 0 1 auto;
		width: 100%;
	}

	.elementor .community-midcta__actions.community-midcta__actions {
		width: 100%;
	}

	.elementor .community-midcta__actions .ccall {
		flex: 1 1 auto;
	}

	.cviewer__stage {
		padding: 16px 16px 48px;
	}

	/* The arrows move off the sides of the photograph and sit beside the
	   count — at this width they were over the image and under a thumb. */
	.cviewer__nav {
		inset-block-start: auto;
		inset-block-end: 14px;
		width: 40px;
		height: 40px;
		transform: none;
	}

	.cviewer__nav--prev {
		inset-inline-start: 50%;
		margin-inline-start: -84px;
	}

	.cviewer__nav--next {
		inset-inline-end: 50%;
		margin-inline-end: -84px;
	}

	.cviewer__count {
		inset-block-end: 26px;
	}

	.cviewer__rail {
		gap: 10px 14px;
		padding: 12px 16px 16px;
	}

	.cviewer__thumbs {
		grid-auto-columns: 64px;
		gap: 6px;
	}

	.cviewer__cta {
		gap: 8px;
	}

	.cviewer__btn {
		padding: 11px 12px;
		font-size: 14px;
		line-height: 20px;
	}
}

/* The `#inquire` target. A zero-size marker rather than an id on the band,
   because atomic elements drop their own CSS ID — see inc/community-hero.php.
   `scroll-margin` is the whole point of giving it a box at all: without it the
   jump lands the band's first line underneath the fixed header. */
.canchor {
	display: block;
	width: 0;
	height: 0;
	scroll-margin-block-start: calc(var(--masthead-height, 96px) + 24px);
}

/* ==========================================================================
   THE HEADER ENQUIRE BUTTON

   Was a solid cyan block. Now white with the brand gradient as its border —
   the same masked ring the cards use (`--ring` + a `::before` holding the
   gradient, `mask-composite` punching the middle out), so the one accent on
   the bar is the same accent as the rest of the site rather than a second
   one.

   The ring is a pseudo-element, not a `border`: a gradient cannot be a border
   colour, and `background-clip` tricks break the moment the button has its
   own background — which this one does, because it must stay opaque over a
   photograph on a transparent header.
   ========================================================================== */

.elementor .button-accent {
	position: relative;
	/* The ring sits ON the edge, so the label needs clearance from it. */
	border: 0;
	background-color: #FFFFFF;
	background-image: none;
	color: #0B1020;
}

.elementor .button-accent::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	padding: var(--ring, 2px);
	border-radius: inherit;
	pointer-events: none;
	background-image: linear-gradient(
		135deg,
		#48C6E9 0%,
		#405BA9 100%
	);
	-webkit-mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	mask-composite: exclude;
}

/* The label has to clear the ring's own stacking context. */
.elementor .button-accent {
	isolation: isolate;
}

/* On hover the ring thickens and the plate takes the faintest brand tint —
   enough to feel pressed without the label moving. */
.elementor .button-accent:hover,
.elementor .button-accent:focus-visible {
	background-color: #F4FBFE;
	color: #0B1020;
}

.elementor .button-accent:hover::before,
.elementor .button-accent:focus-visible::before {
	padding: 3px;
}

/* Over a photograph the header is transparent and the bar behind this button
   is not white, so the plate stays opaque white there too — that is already
   the rule above; nothing extra is needed. Stated so the next person does not
   "fix" it by making it transparent. */

/* "View Available Homes" offers something only when there is something to
   view. The body carries `cd-no-children` when the property being viewed has
   no child properties picked in its own `house_groups` repeater — true of all
   26 house models, false of all 6 developments. An atomic button cannot
   collapse itself, so it is hidden here, the same way the empty overview and
   landmark bands are.

   The contact row beside it is untouched: on a model, talking to somebody is
   still the next step, it is just not "view the homes in this home". */
body.cd-no-children .elementor .community-hero__copy .page-hero__actions > .button-primary {
	display: none;
}

/* ==========================================================================
   THE DATE FIELD

   The calendar panel belongs to the browser and cannot be styled — no
   selector reaches inside it. `color-scheme` is the one lever there is, and
   it is the whole bug: with nothing declared, Chrome follows the OPERATING
   SYSTEM, so anyone on a dark desktop got a charcoal calendar hanging off a
   white form. Declaring `light` on the control pins the panel to the page
   rather than to the machine.

   The indicator is styleable, and is the one part of the control the reader
   is meant to aim at, so it gets a real size and the brand colour instead of
   the browser's 12px grey glyph.
   ========================================================================== */

.cf-input[type="date"],
.cf-input[type="time"],
.cf-input[type="datetime-local"],
.cf-input[type="month"],
.cf-input[type="week"] {
	color-scheme: light;
	cursor: pointer;
}

/* Empty until something is chosen, so it should read as a prompt rather than
   as an answer somebody already gave. */
.cf-input[type="date"]:not(:valid),
.cf-input[type="date"]:placeholder-shown {
	color: var(--cd-muted, #6B7285);
}

.cf-input[type="date"]:focus,
.cf-input[type="date"]:valid {
	color: var(--cd-ink, #0B1020);
}

.cf-input[type="date"]::-webkit-calendar-picker-indicator {
	width: 20px;
	height: 20px;
	padding: 2px;
	border-radius: 4px;
	cursor: pointer;
	opacity: 0.55;
	transition: opacity 180ms ease, background-color 180ms ease;
}

.cf-input[type="date"]:hover::-webkit-calendar-picker-indicator,
.cf-input[type="date"]:focus::-webkit-calendar-picker-indicator {
	opacity: 1;
	background-color: var(--cd-tint, #E7F6FC);
}

/* Firefox and Safari draw no indicator at all. The field still opens on
   click, so nothing is unreachable — but the cursor has to say so. */

/* ==========================================================================
   PROPERTY CARDS — THE GRADIENT RING ON HOVER

   The same masked ring the rest of the site's cards use, now on every card
   that represents a property: the home-type cards on Communities and on a
   development page, the taxonomy archive's results, the related-properties
   row, and the development cards themselves.

   ON HOVER ONLY. Every other card family carries a soft resting ring as
   well — these do not, deliberately: property cards appear six and nine to a
   grid and are photograph-led, and a permanent coloured edge on all of them
   turns a page of houses into a page of borders. The ring is an answer to
   pointing, not a decoration.

   `::after` rather than `::before`, and this block sits at the END of the
   stylesheet on purpose. `result-card` was already listed in the shared ring
   selectors far above — and then the split-layout change killed BOTH its
   pseudo-elements with `content: none` to get rid of the old photo wash, so
   that ring has never actually drawn. Re-stating `content` here is what
   brings it back; anything earlier in the file loses to that kill.
   ========================================================================== */

.elementor .model-loop__card.model-loop__card::after,
.elementor .result-card.result-card::after,
.elementor .development-loop__card.development-loop__card::after {
	content: "";
	position: absolute;
	inset: 0;
	/* Above the photograph. A card's children are `position: relative` with
	   `z-index: auto`, so a ring at 0 or 1 is painted over by the image. */
	z-index: 3;
	padding: var(--ring, 2px);
	border-radius: inherit;
	pointer-events: none;
	opacity: 0;
	/* The old wash set a linear gradient on this element; it is replaced, not
	   layered, or the two composite into a murky edge. */
	background: conic-gradient(
		from var(--sv-ring-angle),
		#405BA9 0%,
		#48C6E9 15%,
		#405BA9 35%,
		#405BA9 50%,
		#48C6E9 65%,
		#405BA9 85%,
		#405BA9 100%
	);
	transition: opacity 240ms ease;
	-webkit-mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	mask-composite: exclude;
}

.elementor .model-loop__card.model-loop__card:hover::after,
.elementor .model-loop__card.model-loop__card:focus-visible::after,
.elementor .model-loop__card.model-loop__card:focus-within::after,
.elementor .result-card.result-card:hover::after,
.elementor .result-card.result-card:focus-visible::after,
.elementor .result-card.result-card:focus-within::after,

.elementor .development-loop__card.development-loop__card:hover::after,
.elementor .development-loop__card.development-loop__card:focus-visible::after {
	opacity: 1;
	animation: sv-ring-run 820ms cubic-bezier(0.22, 0.61, 0.36, 1) 1 forwards;
}

@media (prefers-reduced-motion: reduce) {

	.elementor .model-loop__card.model-loop__card:hover::after,
	.elementor .result-card.result-card:hover::after,
	.elementor .development-loop__card.development-loop__card:hover::after {
		animation: none;
	}
}

/* --------------------------------------------------------------------------
   …and over a photograph.

   The white plate is right on a white bar and wrong on the hero: a solid
   white block with dark ink reads as something stuck ON the photograph rather
   than sitting in the header, and it is the heaviest thing on the screen
   before the headline. The brand gradient also all but disappears against
   blue — a #405BA9 ring on a #405BA9 wash is not an edge.

   So the transparent state is a ghost: no fill, a white hairline, a white
   label. That is the same treatment "Book a site visit" already uses two
   hundred pixels below it in the hero, so the two agree instead of competing.

   The condition is the exact inverse of the white-header rule near the top of
   this file: the bar is transparent on the homepage and on any page that
   opens with a hero, until it scrolls. If another hero class is added there,
   add it here too.
   -------------------------------------------------------------------------- */

body.home .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent {
	background-color: transparent;
	color: #FFFFFF;
}

body.home .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent::before,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent::before {
	/* A flat white hairline, not the gradient. The gradient is a brand accent
	   for a white ground; over the hero it would be a blue ring on blue. */
	background-image: none;
	background-color: rgba(255, 255, 255, 0.85);
}

body.home .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:hover,
body.home .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:focus-visible,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:hover,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:focus-visible {
	/* Fills to white on hover and the label flips to ink — the same two
	   colours, swapped, so the hover state is the resting state of the bar it
	   is about to become. */
	background-color: #FFFFFF;
	color: #0B1020;
}

body.home .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:hover::before,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-search-open):not(.is-mega-open) .button-accent:hover::before {
	background-color: #FFFFFF;
}

/* ==========================================================================
   THE HEADER MENU AND ITS MEGA PANEL

   The nav is a WordPress menu now (Appearance → Menus → Header), rendered by
   `[softouch_nav]`. The seven items used to be hardcoded Elementor
   paragraphs; `.main-nav__link` is kept as the class name so every existing
   rule for the bar — the white-header ink swap, the drawer — still applies
   without being rewritten.
   ========================================================================== */

.elementor .main-nav__list {
	display: flex;
	align-items: center;
	gap: 30px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .main-nav__item {
	position: relative;
	display: flex;
	align-items: center;
	gap: 4px;
	/* The panel is `position: absolute` against the BAR, not against the item —
	   it is full width. The item stays the hover target. */
	list-style: none;
}

.elementor .main-nav__item .main-nav__link {
	display: inline-block;
}

/* The current page, named by `aria-current` as well as drawn. */
.elementor .main-nav__item.is-current > .main-nav__link {
	color: var(--brand);
}

/* --- the disclosure button ------------------------------------------------ */

.elementor .main-nav__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: transparent;
	color: currentColor;
	cursor: pointer;
	/* It has a 20px box but a 44px hit area, which is the minimum a finger
	   can land on. The box stays small so the nav rhythm is unaffected. */
	position: relative;
}

.elementor .main-nav__toggle::after {
	content: "";
	position: absolute;
	inset: -12px;
}

.elementor .main-nav__toggle svg {
	width: 10px;
	height: 6px;
	transition: transform 200ms ease;
}

.elementor .main-nav__item.is-open .main-nav__toggle svg {
	transform: rotate(180deg);
}

.elementor .main-nav__toggle:hover,
.elementor .main-nav__toggle:focus {
	background: transparent;
	color: currentColor;
}

.elementor .main-nav__toggle:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
	box-shadow: none;
}

/* --- the panel ------------------------------------------------------------ */

/* FIXED, not absolute. `absolute` resolves against the nearest positioned
   ancestor, and the nearest one is the <li> — the panel came out 119px wide,
   the width of the word "Communities". The bar's own wrappers are positioned
   too, so walking up and unsetting them would be a game of whack-a-mole.
   `fixed` leaves that chain entirely; the script sets `top` from the bar's
   real bottom edge, which is the only number that survives the admin bar,
   a scrolled page and a changed bar height. */
.mega {
	position: fixed;
	inset-inline: 0;
	top: var(--masthead-height, 101px);
	z-index: 40;
	background-color: #FFFFFF;
	border-block-start: 1px solid var(--cd-rule, #E3DFD7);
	box-shadow: 0 18px 36px -10px rgba(11, 16, 32, 0.12);
}

/* `display` is set by the rules below, so the `hidden` attribute has to be
   restated or the panel is open on every page load. */
.mega[hidden] {
	display: none;
}

.mega__inner {
	display: flex;
	gap: 56px;
	width: min(1248px, calc(100% - 192px));
	margin-inline: auto;
	padding-block: 36px 32px;
}

.mega__col {
	flex: 1 1 0;
	min-width: 0;
}

/* The communities column is widest: it is the one carrying two lines a row,
   and it is the way most people will choose. */
.mega__col--lead {
	flex: 0 0 368px;
}

.mega__head {
	margin: 0 0 12px;
	padding-block-end: 10px;
	border-block-end: 1px solid var(--cd-rule, #E3DFD7);
	color: var(--cd-muted, #6B7285);
	font-size: 11px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1.1px;
	text-transform: uppercase;
}

.mega__col--lead .mega__head {
	margin-inline-start: 14px;
}

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

/* --- a development row ---------------------------------------------------- */

.elementor .mega__dev {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 14px;
	border-radius: 10px;
	color: var(--cd-ink, #0B1020);
	text-decoration: none;
	transition: background-color 180ms ease, color 180ms ease;
}

.elementor .mega__dev:hover,
.elementor .mega__dev:focus-visible {
	background-color: #F4FBFE;
	color: var(--brand);
}

.mega__dev-text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.mega__dev-name {
	font-size: 16px;
	line-height: 23px;
	font-weight: 500;
}

.mega__dev-place {
	color: var(--cd-muted, #6B7285);
	font-size: 12.5px;
	line-height: 18px;
}

.elementor .mega__dev:hover .mega__dev-place,
.elementor .mega__dev:focus-visible .mega__dev-place {
	color: var(--brand);
}

.mega__chev {
	flex: 0 0 auto;
	width: 8px;
	height: 12px;
	color: #B0B5C2;
	transition: transform 180ms ease, color 180ms ease;
}

.elementor .mega__dev:hover .mega__chev,
.elementor .mega__dev:focus-visible .mega__chev {
	transform: translateX(3px);
	color: var(--brand);
}

/* --- a term row ----------------------------------------------------------- */

.elementor .mega__term {
	display: block;
	padding: 10px 0;
	color: var(--cd-ink, #0B1020);
	font-size: 15px;
	line-height: 22px;
	font-weight: 500;
	text-decoration: none;
	transition: color 180ms ease;
}

.elementor .mega__term:hover,
.elementor .mega__term:focus-visible {
	color: var(--brand);
}

/* The nav ink over a photograph. Scoped to the transparent state only, so the
   white-bar rules further up this file keep their own state — the condition
   here is their exact inverse, plus `is-mega-open`, because an open panel
   turns the bar solid and the ink has to follow it. */
/* `:not(.is-nav-open)` belongs in this chain for exactly the reason the other
   two exclusions do. An open mega panel or search sheet turns the bar solid and
   the ink has to follow it; an open DRAWER does the same thing, and since the
   drawer turned white its links are painted on white. Without this exclusion
   the rule — (0,7,1), against (0,4,0) for anything written about the drawer —
   wins on an unscrolled hero page and paints every link in the open drawer
   white on white. They disappeared completely, and only on the pages that
   open with a hero, which is most of them. */
body.home .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open):not(.is-nav-open) .main-nav__link,
body.home .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open) .main-nav__toggle,
body.home .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open) .site-search__open,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open):not(.is-nav-open) .main-nav__link,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open) .main-nav__toggle,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open) .site-search__open {
	color: #FFFFFF;
}

/* --------------------------------------------------------------------------
   Over a photograph

   The bar is transparent on the homepage and on any page that opens with a
   hero. A white panel hanging off a transparent bar reads as a sheet floating
   in front of the photograph rather than as part of the header, so opening it
   puts the bar into its solid state for as long as it is open — `is-mega-open`
   is added by the script and mirrors the `is-scrolled` treatment exactly.
   -------------------------------------------------------------------------- */

.elementor .site-masthead.is-mega-open {
	background: #FFFFFF;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
	border-block-end-color: rgba(255, 255, 255, 0);
	box-shadow: 0 12px 28px -16px rgba(11, 16, 32, 0.28);
}

.elementor .site-masthead.is-mega-open .site-logo {
	background-image: url('assets/logo-colour.png');
}

@media (min-width: 1201px) {

	.elementor .site-masthead.is-mega-open .main-nav__link {
		color: #0B1020;
	}

	.elementor .site-masthead.is-mega-open .main-nav__link:hover,
	.elementor .site-masthead.is-mega-open .main-nav__item.is-current > .main-nav__link {
		color: var(--brand);
	}
}

.elementor .site-masthead.is-mega-open .button-accent {
	background-color: #FFFFFF;
	color: #0B1020;
}

.elementor .site-masthead.is-mega-open .button-accent::before {
	background-image: linear-gradient(135deg, #48C6E9 0%, #405BA9 100%);
	background-color: transparent;
}

.elementor .site-masthead.is-mega-open:not(.is-nav-open) .site-masthead__toggle-bar {
	background: #0B1020;
}

/* --------------------------------------------------------------------------
   Below the drawer breakpoint the off-canvas menu owns navigation, and a
   1248px panel has nowhere to go. The script does not run here; this makes
   sure nothing shows even if it somehow did.
   -------------------------------------------------------------------------- */

@media (max-width: 1200px) {

	.mega,
	.elementor .main-nav__toggle {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .main-nav__toggle svg,
	.mega__chev,
	.elementor .mega__dev,
	.elementor .mega__term {
		transition: none;
	}
}

/* ==========================================================================
   THE SEARCH OVERLAY

   Lives at the end of <body>, not in the header: a `position: fixed` panel
   inside the bar inherits the bar's stacking context, and this build has
   already been bitten by that twice — the gallery viewer painted under the
   page, the mega panel came out 119px wide. Out there it has no positioned
   ancestor at all, and the script sets its top from the bar's real bottom.
   ========================================================================== */

/* The header row is SPACE_BETWEEN with four children — logo, nav, search,
   Enquire — so the search icon was floating in the middle of the gap. Giving
   the nav the free space instead clusters search and Enquire together at the
   right, which is where a reader expects the actions to be. No template
   surgery: the Elementor row is untouched. */
.elementor .main-nav-host {
	margin-inline-end: auto;
}

.elementor .site-search-host {
	margin-inline-end: 4px;
}

.site-search__open {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: transparent;
	color: currentColor;
	cursor: pointer;
	position: relative;
}

/* 24px box, 44px hit area — the box keeps the bar's rhythm, the finger gets
   something it can actually land on. */
.site-search__open::after {
	content: "";
	position: absolute;
	inset: -10px;
}

.site-search__open svg {
	width: 24px;
	height: 24px;
}

.elementor .site-search__open:hover,
.elementor .site-search__open:focus {
	background: transparent;
	color: currentColor;
}

.elementor .site-search__open:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
	box-shadow: none;
}

.site-search {
	position: fixed;
	inset: 0;
	/* Under the masthead, which is raised to 130 while this is open. The scrim
	   was dimming the header along with the page — including the button that
	   closes the overlay, which is the one thing that must stay crisp and
	   clickable. */
	z-index: 120;
}

.elementor .site-masthead.is-search-open,
.elementor .site-masthead.is-mega-open {
	z-index: 130;
}

.site-search[hidden] {
	display: none;
}

.has-search,
.has-search body {
	overflow: hidden;
}

.site-search__scrim {
	position: absolute;
	inset: 0;
	background-color: rgba(11, 16, 32, 0.55);
}

.site-search__panel {
	position: absolute;
	inset-inline: 0;
	top: var(--masthead-height, 101px);
	background-color: #FFFFFF;
	box-shadow: 0 20px 44px -12px rgba(11, 16, 32, 0.22);
}

.site-search__inner {
	width: min(1248px, calc(100% - 192px));
	margin-inline: auto;
	padding-block: 36px 32px;
}

/* --- the field ------------------------------------------------------------ */

.site-search__form {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 18px 24px;
	border: 2px solid var(--brand);
	border-radius: 12px;
	background-color: #FFFFFF;
}

.site-search__icon {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	color: var(--cd-muted, #6B7285);
}

/* Doubled. hello-elementor's reset styles every text input by ATTRIBUTE —
   `input[type="search"] { border: 1px solid #666; border-radius: 3px;
   padding: .5rem 1rem }` — which is (0,1,1) and beats a single class. It drew
   a second grey box inside the field. Same reset, third time: it also paints
   buttons and links magenta. */
.site-search__input.site-search__input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--cd-ink, #0B1020);
	font-family: inherit;
	font-size: 19px;
	line-height: 28px;
	font-weight: 500;
}

.site-search__input::placeholder {
	color: var(--cd-muted, #6B7285);
	font-weight: 400;
}

/* The field is the focus ring — a second one inside it is noise. */
.site-search__input:focus,
.site-search__input:focus-visible {
	outline: none;
	box-shadow: none;
}

/* Safari draws its own clear button, at its own size, in its own grey. */
.site-search__input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.site-search__kbd {
	flex: 0 0 auto;
	padding: 4px 9px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	border-radius: 5px;
	background-color: #F6F7F9;
	color: var(--cd-muted, #6B7285);
	font-size: 11px;
	line-height: 16px;
	font-weight: 500;
	letter-spacing: 0.6px;
}

/* --- before typing: the routes that work ---------------------------------- */

.site-search__browse {
	display: flex;
	gap: 56px;
	margin-block-start: 30px;
}

/* THE THIRD TIME this exact bug has appeared in this build: `display` beats
   the `hidden` attribute, so an element given `display: flex` stays visible
   however many times the script sets `hidden`. The browse columns sat under
   the results the whole time typing. Any element in this stylesheet that
   carries both a `display` and a `hidden` state needs this line —
   `.cviewer[hidden]` and `.mega[hidden]` are the other two. */
.site-search__browse[hidden],
.site-search__results[hidden] {
	display: none;
}

.site-search__col {
	flex: 1 1 0;
	min-width: 0;
}

.site-search__col--lead {
	flex: 0 0 368px;
}

.site-search__head {
	margin: 0 0 10px;
	padding-block-end: 10px;
	border-block-end: 1px solid var(--cd-rule, #E3DFD7);
	color: var(--cd-muted, #6B7285);
	font-size: 11px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1.1px;
	text-transform: uppercase;
}

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

.elementor .site-search__list a,
.site-search__list a {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding-block: 9px;
	color: var(--cd-ink, #0B1020);
	text-decoration: none;
}

.site-search__list a:hover .site-search__name,
.site-search__list a:focus-visible .site-search__name {
	color: var(--brand);
}

.site-search__name {
	font-size: 15px;
	line-height: 22px;
	font-weight: 500;
	transition: color 160ms ease;
}

.site-search__place {
	color: var(--cd-muted, #6B7285);
	font-size: 12.5px;
	line-height: 18px;
}

/* --- results -------------------------------------------------------------- */

.site-search__results {
	margin-block-start: 22px;
}

.site-search__meta {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 24px;
	padding-block-end: 10px;
	border-block-end: 1px solid var(--cd-rule, #E3DFD7);
}

.site-search__count {
	margin: 0;
	color: var(--cd-muted, #6B7285);
	font-size: 11px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1.1px;
	text-transform: uppercase;
}

.site-search__hint {
	margin: 0;
	color: var(--cd-muted, #6B7285);
	font-size: 12px;
	line-height: 17px;
}

.site-search__hits {
	margin: 8px 0 0;
	padding: 0;
	list-style: none;
}

.elementor .site-search__hit,
.site-search__hit {
	display: flex;
	align-items: center;
	gap: 18px;
	padding: 10px 12px;
	border-radius: 10px;
	color: var(--cd-ink, #0B1020);
	text-decoration: none;
	transition: background-color 160ms ease;
}

.site-search__hit:hover,
.site-search__hit:focus-visible {
	background-color: #F4FBFE;
}

.site-search__thumb {
	flex: 0 0 auto;
	width: 76px;
	height: 57px;
	border-radius: 8px;
	object-fit: cover;
	background-color: var(--cd-plate, #E6E8EE);
}

.site-search__hit-text {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 0;
	flex: 1 1 auto;
}

.site-search__hit-name {
	font-size: 16.5px;
	line-height: 24px;
	font-weight: 500;
}

.site-search__hit:hover .site-search__hit-name,
.site-search__hit:focus-visible .site-search__hit-name {
	color: var(--brand);
}

.site-search__hit-meta {
	color: var(--cd-muted, #6B7285);
	font-size: 12.5px;
	line-height: 18px;
}

.site-search__hit-chev {
	flex: 0 0 auto;
	width: 8px;
	height: 12px;
	color: #B0B5C2;
	transition: transform 160ms ease, color 160ms ease;
}

.site-search__hit:hover .site-search__hit-chev {
	transform: translateX(3px);
	color: var(--brand);
}

.site-search__none {
	margin: 18px 0 0;
	color: var(--cd-muted, #6B7285);
	font-size: 14px;
	line-height: 21px;
}

/* The bar goes solid while the overlay is open, for the same reason the mega
   panel does it: a white sheet hanging off a transparent bar is not attached
   to anything. */
.elementor .site-masthead.is-search-open {
	background: #FFFFFF;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
	box-shadow: 0 12px 28px -16px rgba(11, 16, 32, 0.28);
}

.elementor .site-masthead.is-search-open .site-logo {
	background-image: url('assets/logo-colour.png');
}

/* THE OPEN SEARCH BAR IS A WHITE BAR, AND PHONES NEVER HEARD ABOUT IT.

   `is-search-open` turns the masthead white — the same thing `is-scrolled`
   does — but every phone-sized rule that follows from that was written
   against `is-scrolled` alone. Opening search therefore left a white bar
   carrying the artwork of a transparent one:

     · the logo fell back to the full lock-up, which is 449x150 of wordmark
       and strapline squeezed into the 40x42 box phones draw, i.e. a smudge
     · the burger bars stayed WHITE on the new white bar and disappeared
       outright, so the menu became unreachable while search was open

   Both are the same omission, so both are fixed in one place. */
@media (max-width: 767px) {

	.elementor .site-masthead.is-search-open .site-logo {
		background-image: url('assets/img/softouch-icon.png');
	}
}

/* The burger is dark whenever the bar is light. `is-scrolled` already said so
   a thousand lines up; `is-search-open` is the same condition and was never
   added to it. Still excluded while the drawer is open, where the bars sit
   over the dark panel and belong white. */
.elementor .site-masthead.is-search-open:not(.is-nav-open) .site-masthead__toggle-bar {
	background: #0B1020;
}

/* --- The magnifier becomes a cross while the overlay is open ---------------
   The control is a toggle — it closes what it opened — and a magnifier that
   closes a search panel gives no sign of it. The drawer's burger already
   turns into a cross; this is the same promise on the same bar.

   Drawn with `::before` rather than by swapping the SVG, so the button keeps
   its one accessible name and nothing has to re-run on state change.
   `::after` is NOT free here — it carries the 44px hit area. A mask, not a
   background image, so the cross inherits `currentColor` and stays correct on
   both the white bar and the photograph. */
.elementor .site-masthead.is-search-open .site-search__open svg {
	opacity: 0;
}

.elementor .site-masthead.is-search-open .site-search__open::before {
	content: "";
	position: absolute;
	inset: 2px;
	background-color: currentColor;
	-webkit-mask: var(--search-close-mark) center / 20px 20px no-repeat;
	mask: var(--search-close-mark) center / 20px 20px no-repeat;
}

:root {
	--search-close-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 4l12 12M16 4L4 16'/%3E%3C/svg%3E");
}

@media (min-width: 1201px) {

	.elementor .site-masthead.is-search-open .main-nav__link {
		color: #0B1020;
	}
}

.elementor .site-masthead.is-search-open .site-search__open,
.elementor .site-masthead.is-search-open .button-accent {
	color: #0B1020;
}

.elementor .site-masthead.is-search-open .button-accent {
	background-color: #FFFFFF;
}

@media (max-width: 1024px) {

	.site-search__inner {
		width: calc(100% - 40px);
		padding-block: 24px 28px;
	}

	.site-search__browse {
		flex-direction: column;
		gap: 24px;
	}

	.site-search__col--lead {
		flex: 1 1 auto;
	}

	.site-search__kbd {
		display: none;
	}

	.site-search__form {
		padding: 14px 18px;
	}

	/* The 17px that used to sit here was DEAD. The base rule is written
	   `.site-search__input.site-search__input` at (0,2,0) and this was
	   (0,1,0), so the field stayed at 19px on every phone and tablet since the
	   rule was written. It is superseded by the doubled rule in the panel
	   sizing block below; nothing is lost by removing it, because nothing was
	   ever gained by it. */
}

@media (prefers-reduced-motion: reduce) {

	.site-search__name,
	.site-search__hit,
	.site-search__hit-chev {
		transition: none;
	}
}

/* ==========================================================================
   THE SEARCH RESULTS PAGE  (search.php)
   ========================================================================== */

.sresults {
	background-color: #FFFFFF;
}

.sresults__inner {
	width: min(1248px, calc(100% - 48px));
	margin-inline: auto;
}

.sresults__head {
	padding-block: 44px 36px;
	background-image: linear-gradient(180deg, #F4FBFE 0%, #FAFCFE 100%);
}

.sresults__title {
	margin: 0 0 20px;
	color: var(--cd-ink, #0B1020);
	font-size: 34px;
	line-height: 44px;
	font-weight: 600;
	letter-spacing: -0.4px;
}

.sresults__form {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 10px 10px 10px 22px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	border-radius: 12px;
	background-color: #FFFFFF;
}

.sresults__form:focus-within {
	border-color: var(--brand);
	box-shadow: 0 0 0 1px var(--brand);
}

.sresults__icon {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	color: var(--cd-muted, #6B7285);
}

/* Doubled: hello-elementor styles inputs by attribute at (0,1,1), which beats
   a single class and draws its own grey box inside the field. */
.sresults__input.sresults__input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 12px 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--cd-ink, #0B1020);
	font-family: inherit;
	font-size: 18px;
	line-height: 26px;
	font-weight: 500;
}

.sresults__input:focus,
.sresults__input:focus-visible {
	outline: none;
	box-shadow: none;
}

.sresults__input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.elementor .sresults__go,
.sresults__go {
	flex: 0 0 auto;
	padding: 11px 24px;
	border: 0;
	border-radius: 8px;
	background-color: var(--brand);
	color: #FFFFFF;
	font-family: inherit;
	font-size: 14px;
	line-height: 20px;
	font-weight: 600;
	cursor: pointer;
}

.elementor .sresults__go:hover,
.sresults__go:hover,
.sresults__go:focus {
	background-color: #32498A;
	color: #FFFFFF;
}

/* --- body ----------------------------------------------------------------- */

.sresults__body {
	padding-block: 32px 72px;
}

.sresults__filters {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.elementor .sresults__chip,
.sresults__chip {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 9px 16px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	border-radius: 999px;
	background-color: #FFFFFF;
	color: var(--cd-ink, #0B1020);
	font-size: 14px;
	line-height: 20px;
	font-weight: 500;
	text-decoration: none;
	transition: border-color 160ms ease, background-color 160ms ease;
}

.sresults__chip:hover {
	border-color: var(--brand);
	background-color: #F4FBFE;
}

.elementor .sresults__chip.is-on,
.sresults__chip.is-on {
	border-color: var(--brand);
	background-color: var(--brand);
	color: #FFFFFF;
}

.sresults__chip-n {
	color: var(--cd-muted, #6B7285);
	font-size: 13px;
	font-weight: 400;
}

.sresults__chip.is-on .sresults__chip-n {
	color: rgba(255, 255, 255, 0.82);
}

.sresults__count {
	margin: 26px 0 14px;
	color: var(--cd-muted, #6B7285);
	font-size: 13px;
	line-height: 19px;
}

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

/* --- one result ----------------------------------------------------------- */

.elementor .sresult__link,
.sresult__link {
	display: flex;
	align-items: center;
	gap: 20px;
	padding-block: 18px;
	border-block-end: 1px solid var(--cd-rule, #E3DFD7);
	color: var(--cd-ink, #0B1020);
	text-decoration: none;
}

.sresult__link:hover .sresult__title,
.sresult__link:focus-visible .sresult__title {
	color: var(--brand);
}

.sresult__thumb {
	flex: 0 0 auto;
	width: 104px;
	height: 78px;
	border-radius: 10px;
	object-fit: cover;
	background-color: #E8EEF5;
}

/* The designed empty thumbnail. Six properties have no photograph, and a
   bare grey rectangle in a list of houses reads as a broken image. */
.sresult__thumb--none {
	display: flex;
	align-items: center;
	justify-content: center;
	color: #A0B2C7;
}

.sresult__thumb--none svg {
	width: 40px;
	height: 40px;
}

/* Non-property rows keep the same left edge as the ones with pictures, so the
   titles line up down the page instead of stepping in and out. */
.sresult__gutter {
	flex: 0 0 auto;
	width: 104px;
}

.sresult__text {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 5px;
	min-width: 0;
}

.sresult__kind {
	color: var(--cd-muted, #6B7285);
	font-size: 10px;
	line-height: 14px;
	font-weight: 600;
	letter-spacing: 1.1px;
	text-transform: uppercase;
}

.sresult--property .sresult__kind {
	color: var(--brand);
}

.sresult__title {
	font-size: 17px;
	line-height: 25px;
	font-weight: 500;
	transition: color 160ms ease;
}

.sresult--property .sresult__title {
	font-size: 19px;
	line-height: 27px;
}

.sresult__meta {
	color: var(--cd-muted, #6B7285);
	font-size: 13.5px;
	line-height: 20px;
}

.sresult__chev {
	flex: 0 0 auto;
	width: 8px;
	height: 12px;
	color: #B0B5C2;
	transition: transform 160ms ease, color 160ms ease;
}

.sresult__link:hover .sresult__chev {
	transform: translateX(3px);
	color: var(--brand);
}

/* --- pagination ----------------------------------------------------------- */

.sresults__pager {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-block-start: 32px;
}

.elementor .sresults__pager .page-numbers,
.sresults__pager .page-numbers {
	display: inline-flex;
	align-items: center;
	padding: 10px 15px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	border-radius: 8px;
	background-color: #FFFFFF;
	color: var(--cd-ink, #0B1020);
	font-size: 14px;
	line-height: 20px;
	font-weight: 500;
	text-decoration: none;
}

.sresults__pager .page-numbers:hover {
	border-color: var(--brand);
	background-color: #F4FBFE;
}

.elementor .sresults__pager .page-numbers.current,
.sresults__pager .page-numbers.current {
	border-color: var(--brand);
	background-color: var(--brand);
	color: #FFFFFF;
}

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

/* --- nothing matched ------------------------------------------------------ */

.sresults__empty {
	padding-block: 28px 20px;
}

.sresults__empty-title {
	margin: 0 0 12px;
	color: var(--cd-ink, #0B1020);
	font-size: 26px;
	line-height: 36px;
	font-weight: 600;
	letter-spacing: -0.2px;
}

.sresults__empty-lead {
	max-width: 62ch;
	margin: 0 0 26px;
	color: var(--cd-muted, #6B7285);
	font-size: 15px;
	line-height: 24px;
}

.sresults__suggest {
	margin-block-end: 24px;
}

.sresults__suggest-head {
	margin: 0 0 12px;
	color: var(--cd-muted, #6B7285);
	font-size: 11px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1.1px;
	text-transform: uppercase;
}

.sresults__suggest-row {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.elementor .sresults__pill,
.sresults__pill {
	display: inline-flex;
	align-items: center;
	padding: 9px 16px;
	border: 1px solid var(--cd-rule, #E3DFD7);
	border-radius: 999px;
	background-color: #FFFFFF;
	color: var(--cd-ink, #0B1020);
	font-size: 14px;
	line-height: 20px;
	font-weight: 500;
	text-decoration: none;
	transition: border-color 160ms ease, background-color 160ms ease;
}

.sresults__pill:hover {
	border-color: var(--brand);
	background-color: #F4FBFE;
}

@media (max-width: 767px) {

	.sresults__head {
		padding-block: 28px 24px;
	}

	.sresults__title {
		font-size: 27px;
		line-height: 36px;
	}

	.sresults__form {
		flex-wrap: wrap;
		gap: 12px;
		padding: 12px 14px;
	}

	/* Only the BUTTON wraps. `min-width: 0` let the input collapse far enough
	   to drop onto its own line, which left the magnifier sitting alone above
	   the query like a third control. */
	.sresults__input.sresults__input {
		flex: 1 1 60%;
		min-width: 120px;
		padding-block: 8px;
	}

	.sresults__go {
		width: 100%;
		margin-block-start: 2px;
	}

	.sresult__thumb,
	.sresult__thumb--none {
		width: 82px;
		height: 62px;
	}

	/* The gutter goes on phones — 82px of nothing beside a news headline is
	   a third of the screen spent on alignment. */
	.sresult__gutter {
		display: none;
	}

	.sresult__link {
		gap: 14px;
	}

	.sresult--property .sresult__title {
		font-size: 17px;
		line-height: 25px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.sresult__title,
	.sresult__chev,
	.sresults__chip,
	.sresults__pill {
		transition: none;
	}
}

/* ==========================================================================
   THE SINGLE ROLE — /careers/<role>/

   Elementor template "Softouch — Role Detail" (single, include/singular/job).
   The hero reuses `article-hero`, so the band, gradient, measure and breadcrumb
   colours come from the news article and cannot drift from it; `job-hero` only
   adds what a role needs that an article does not.

   This lives here rather than in the global class editor because the layout
   needs media queries, descendant selectors and `:has()`, none of which the
   class editor's CSS field accepts.
   ========================================================================== */

/* --- Hero ---------------------------------------------------------------- */

/* The chip list sits between the title and the CTA, so it supplies its own
   rhythm rather than relying on the hero body's single gap. */
.elementor .job-hero .job-facts {
	width: 100%;
}

.elementor .job-facts__list {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .job-fact {
	display: inline-flex;
	align-items: center;
	min-height: 28px;
	padding: 4px 12px;
	border: 1px solid #D7DEEE;
	border-radius: 999px;
	background-color: #FFFFFF;
	color: #405BA9;
	font-size: 13px;
	line-height: 20px;
	font-weight: 500;
}

/* The hero CTA is the house solid button. `e-button-base` sets its own
   padding and colour, so every property is restated. */
.elementor .job-hero-cta.job-hero-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 0 28px;
	border: 0;
	border-radius: 8px;
	background-color: #405BA9;
	color: #FFFFFF;
	font-size: 15px;
	line-height: 22px;
	font-weight: 500;
	text-decoration: none;
	transition: background-color 160ms ease;
}

.elementor .job-hero-cta.job-hero-cta:hover,
.elementor .job-hero-cta.job-hero-cta:focus-visible {
	background-color: #32487F;
	color: #FFFFFF;
}

/* --- The two-column body ------------------------------------------------- */

/* A grid, not flex: the aside is a fixed measure and the article takes the
   rest, and `minmax(0, 1fr)` is what stops a long unbroken string in the
   content from widening the column past its track. */
/* The band is a `page-section`, which Elementor's own section base style pads
   96px top and bottom. That is the site's band rhythm and is right for a band
   that opens with a section heading — this one opens with running text, and the
   96 landed on top of the layout's own 72 for a 168px void where Figma 683:2
   has 56 (band top 399, lede top 455). The band's rhythm is handed to the
   layout, which owns it alone. Scoped by `:has()` so no other band moves. */
.elementor .page-section:has(> .job-layout) {
	padding-block: 0;
}

.elementor .job-layout.job-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 348px;
	gap: 64px;
	align-items: start;
	width: 100%;
	max-width: 1248px;
	margin-inline: auto;
	/* Shorthand, so `e-div-block-base`'s 10px inline padding is cleared too —
	   left in, it pushed the text column 10px right of the hero title it is
	   meant to line up with. */
	padding: 56px 0 32px;
}

/* Every atomic container is padded 10px by `e-div-block-base`. In a two-column
   grid that is 20px taken off each track and 20px of misalignment against the
   heading above, so both columns shed it. */
.elementor .job-article.job-article {
	display: block;
	min-width: 0;
	padding: 0;
}

/* `article-body` centres its own paragraphs on an 860px measure, which is
   right for a full-width article and wrong inside a column — it indented the
   text away from the heading above it. The measure comes off here; the column
   is already the measure. */
/* `article-body` sets 34px on 17px — a 2.0 ratio, pitched for the news
   article's 860px measure. The job column is 275px at 375, about 32 characters
   a line, where that ratio sprawls a bulleted list down the page. */
.elementor .job-body {
	line-height: 28px;
}

.elementor .job-body > p,
.elementor .job-body > h2,
.elementor .job-body > h3,
.elementor .job-body > ul,
.elementor .job-body > ol,
.elementor .job-body > blockquote {
	max-width: none;
	margin-inline: 0;
}

/* Every role is authored with real headings — "Duties and Responsibilities"
   and "Qualifications" as h2, and the AP/AR splits in the accounting role as
   h3. `article-body` sizes those for a 28px editorial article, which shouts in
   a 760px job column, so the scale steps down one rung. Nothing about the copy
   or its markup changes. */
.elementor .job-body h2 {
	margin-block: 36px 12px;
	font-size: 22px;
	line-height: 30px;
}

.elementor .job-body h2:first-child {
	margin-block-start: 0;
}

/* Figma sets the third-level heads ("Accounting Operations", "Tax and
   Regulatory Compliance") in the brand blue, which is what separates them from
   the h2 sections at a glance. */
.elementor .job-body h3 {
	margin-block: 24px 10px;
	color: #405BA9;
	font-size: 17px;
	line-height: 26px;
}

.elementor .job-body > ul {
	margin-block: 0 24px;
	padding-inline-start: 22px;
}

.elementor .job-body > ul > li {
	margin-block-end: 8px;
	padding-inline-start: 2px;
}

.elementor .job-body > ul > li::marker {
	color: #405BA9;
}

/* --- The aside ----------------------------------------------------------- */

/* `position: sticky` needs a flow root that is not a flex item with a
   definite height; the grid's `align-items: start` gives it one. 112px clears
   the fixed masthead. */
.elementor .job-aside.job-aside {
	display: flex;
	flex-direction: column;
	gap: 20px;
	position: sticky;
	top: var(--sticky-offset);
	min-width: 0;
	padding: 0;
}

.elementor .job-apply-card.job-apply-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 12px;
	padding: 28px;
	border: 1px solid #E3E6ED;
	border-radius: 14px;
	background-color: #FFFFFF;
}

.elementor .job-apply-card.job-apply-card h2 {
	margin: 0;
	color: #0B1020;
	font-size: 20px;
	line-height: 28px;
	font-weight: 600;
}

.elementor .job-apply-card.job-apply-card p {
	margin: 0;
	color: #646B7D;
	font-size: 15px;
	line-height: 24px;
}

.elementor .job-apply-card__cta.job-apply-card__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	margin-block-start: 4px;
	padding: 0 24px;
	border: 0;
	border-radius: 8px;
	background-color: #405BA9;
	color: #FFFFFF;
	font-size: 15px;
	line-height: 22px;
	font-weight: 500;
	text-decoration: none;
	transition: background-color 160ms ease;
}

.elementor .job-apply-card__cta.job-apply-card__cta:hover,
.elementor .job-apply-card__cta.job-apply-card__cta:focus-visible {
	background-color: #32487F;
	color: #FFFFFF;
}

/* Figma 683:2 has no card here — just the label, a rule, and the rows on the
   page ground. The cream panel it used to sit in competed with the apply card
   directly above it. */
.elementor .job-others.job-others {
	display: flex;
	flex-direction: column;
	gap: 0;
	padding: 8px 0 0;
	border: 0;
	background-color: transparent;
}

.elementor .job-others.job-others h2 {
	margin: 0 0 12px;
	padding-block-end: 12px;
	border-block-end: 1px solid #E3E6ED;
	color: #8A90A0;
	font-size: 12px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1px;
	text-transform: uppercase;
}

.elementor .job-others__items {
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .job-others__items > li + li {
	border-block-start: 1px solid #EDEFF3;
}

.elementor .job-others__items a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-block: 14px;
	color: #0B1020;
	font-size: 15px;
	line-height: 22px;
	text-decoration: none;
}

.elementor .job-others__items a:hover,
.elementor .job-others__items a:focus-visible {
	color: #405BA9;
}

.elementor .job-others__items svg {
	flex: 0 0 auto;
	width: 7px;
	height: 11px;
	color: #9AA2B4;
	transition: transform 160ms ease;
}

.elementor .job-others__items a:hover svg {
	transform: translateX(3px);
	color: #405BA9;
}

/* --- The apply band ------------------------------------------------------ */

.elementor .job-apply.job-apply {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
	padding: 64px 0 88px;
	background-image: linear-gradient(180deg, #FAF8F5 0%, #EFF3FA 100%);
	border-block-start: 1px solid #E3DFD7;
}

/* The anchor is an empty span, so it must not occupy a row in the band's
   column flex. Its offset clears the fixed masthead when the CTA jumps here. */
.elementor .job-anchor {
	width: 0;
	height: 0;
}

.elementor .job-anchor__target {
	display: block;
	position: relative;
	top: -112px;
}

/* The heading and lead sit on the band, left-aligned with the field card. */
.elementor .job-apply__head.job-apply__head {
	display: flex;
	flex-direction: column;
	gap: 10px;
	width: 100%;
	max-width: 920px;
	margin-inline: auto;
	padding: 0 0 28px;
}

.elementor .job-apply__head .cf-lead {
	max-width: 620px;
}

/* `contact-form-panel` was built as one half of the contact split, so it
   carries `flex-grow: 1` and would stretch the full band width here. Figma
   makes it a white card, not the cream the contact page uses. */
.elementor .job-apply .contact-form-panel {
	flex: 0 1 auto;
	width: 100%;
	max-width: 920px;
	margin-inline: auto;
	padding: 40px;
	border: 1px solid #E3E6ED;
	border-radius: 16px;
	background-color: #FFFFFF;
}

/* --- The two fields the enquiry form does not have ----------------------- */

/* --- The CV drop zone -----------------------------------------------------
   `job-apply.js` wraps the file input in `.cf-drop` and builds the face beside
   it. Everything here is written so the field is still usable if that script
   never runs: without `.cf-drop` the input simply keeps the dashed box and the
   browser's own button.
   -------------------------------------------------------------------------- */
.elementor .cf-file.cf-file {
	width: 100%;
	height: auto;
	min-height: 44px;
	padding: 10px 14px;
	border: 1px dashed #C9D3E8;
	border-radius: 8px;
	background-color: #FFFFFF;
	color: #0B1020;
	font-size: 14px;
	line-height: 22px;
}

.elementor .cf-file.cf-file::file-selector-button {
	margin-inline-end: 12px;
	padding: 6px 14px;
	border: 1px solid #C9D3E8;
	border-radius: 6px;
	background-color: #EFF3FA;
	color: #405BA9;
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
}

.elementor .cf-drop {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 76px;
	padding: 16px 18px;
	border: 1px dashed #AFC0E4;
	border-radius: 8px;
	background-color: #FBFCFE;
	transition: border-color 160ms ease, background-color 160ms ease;
}

/* Once the zone exists the input is only a hit area: it covers the zone,
   invisible, and keeps every one of its own attributes. */
.elementor .cf-drop .cf-file.cf-file {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 8px;
	background: none;
	opacity: 0;
	cursor: pointer;
}

.elementor .cf-drop__face {
	display: flex;
	align-items: center;
	gap: 14px;
	pointer-events: none;
}

.elementor .cf-drop__icon {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	color: #405BA9;
}

.elementor .cf-drop__text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.elementor .cf-drop__prompt {
	color: #405BA9;
	font-size: 15px;
	line-height: 22px;
	font-weight: 600;
	overflow-wrap: anywhere;
}

.elementor .cf-drop__note {
	color: #8A90A0;
	font-size: 13px;
	line-height: 18px;
}

.elementor .cf-drop.is-dragging,
.elementor .cf-drop.is-focused {
	border-color: #405BA9;
	background-color: #F2F6FD;
}

.elementor .cf-drop.is-filled {
	border-style: solid;
	border-color: #AFC0E4;
	background-color: #F7FAFF;
}

/* The Position field is filled from the role and cannot be edited. Left
   looking like every other input it reads as a field someone forgot to
   complete, so it is tinted and loses the text caret. */
.elementor .cf-input[readonly] {
	background-color: #F4F6FA;
	color: #3C445A;
	cursor: default;
}

.elementor .cf-input[readonly]:focus {
	border-color: #E3DFD7;
}

/* The consent row is a checkbox beside a full sentence, so the label must not
   inherit `cf-label`'s uppercase 12px treatment. */
.elementor .cf-consent.cf-consent {
	display: flex;
	flex-direction: row;
	align-items: flex-start;
	gap: 12px;
}

.elementor .cf-consent input[type="checkbox"] {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	margin: 2px 0 0;
	accent-color: #405BA9;
}

.elementor .cf-consent .cf-label {
	margin: 0;
	color: #646B7D;
	font-size: 14px;
	line-height: 22px;
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
	cursor: pointer;
}

/* --- Narrower ------------------------------------------------------------ */

@media (max-width: 1200px) {

	.elementor .job-layout.job-layout {
		grid-template-columns: minmax(0, 1fr) 312px;
		gap: 48px;
		padding: 48px 56px 32px;
	}

	.elementor .job-apply.job-apply {
		padding: 64px 56px 72px;
	}

	.elementor .job-apply__head.job-apply__head,
	.elementor .job-apply .contact-form-panel {
		max-width: 100%;
	}
}

/* The aside stops being a column and becomes a pair of cards under the text:
   a 312px sticky rail beside a 400px measure is a worse read than one column. */
@media (max-width: 1024px) {

	.elementor .job-layout.job-layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 40px;
	}

	.elementor .job-aside.job-aside {
		position: static;
		top: auto;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: stretch;
		gap: 20px;
	}

	.elementor .job-apply-card.job-apply-card,
	.elementor .job-others.job-others {
		flex: 1 1 320px;
		min-width: 0;
	}
}

@media (max-width: 767px) {

	/* `padding-inline` is reset, not omitted: the <=1200 rule above sets 56px
	   and it still applies here. The band is `page-section`, which is already in
	   the site's 20px mobile gutter rule, so any inline padding here is the
	   gutter applied twice — it took the text column to 203px of a 375px
	   screen. */
	.elementor .job-layout.job-layout {
		gap: 32px;
		padding: 36px 0 28px;
	}

	.elementor .job-apply.job-apply {
		padding: 48px 20px 56px;
	}

	.elementor .job-apply .contact-form-panel {
		padding: 24px 20px;
	}

	.elementor .job-apply__head.job-apply__head {
		padding-block-end: 20px;
	}

	.elementor .cf-drop {
		min-height: 68px;
		padding: 14px;
	}

	.elementor .job-aside.job-aside {
		flex-direction: column;
	}

	.elementor .job-apply-card.job-apply-card {
		padding: 24px 20px;
	}

	.elementor .job-others.job-others {
		padding: 20px 20px 4px;
	}

	.elementor .job-body h2 {
		margin-block: 28px 10px;
		font-size: 20px;
		line-height: 28px;
	}

	.elementor .job-hero-cta.job-hero-cta {
		width: 100%;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .job-others__items svg,
	.elementor .job-others__items a:hover svg {
		transition: none;
		transform: none;
	}
}

/* ==========================================================================
   THE CAREERS JOB BOARD — /careers/

   `[softouch_job_board]` replaced the hardcoded cards and the two department
   headings. The headings became the rail on the left; the cards are rendered
   from the `job` posts and reuse `job-card`, `job-row` and `job-card__*`
   unchanged, so the card design is exactly what it was.
   ========================================================================== */

.elementor .job-board {
	display: grid;
	grid-template-columns: 232px minmax(0, 1fr);
	gap: 48px;
	align-items: start;
	width: 100%;
}

/* The classic shortcode widget wraps its output in `.elementor-shortcode`,
   which would otherwise be the grid's only child. */
.elementor .job-board-mount,
.elementor .job-board-mount > .elementor-shortcode {
	display: block;
	width: 100%;
}

/* --- The rail ------------------------------------------------------------ */

.elementor .job-board__rail {
	position: sticky;
	top: var(--sticky-offset);
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.elementor .job-board__rail-head {
	margin: 0 0 12px;
	padding-block-end: 12px;
	border-block-end: 1px solid #E3E6ED;
	color: #8A90A0;
	font-size: 12px;
	line-height: 16px;
	font-weight: 600;
	letter-spacing: 1px;
}

.elementor .job-board__filters {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.elementor .job-board__filter {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 10px 12px;
	border-radius: 8px;
	color: #3C445A;
	font-size: 15px;
	line-height: 22px;
	text-decoration: none;
	transition: background-color 140ms ease, color 140ms ease;
}

.elementor .job-board__filter:hover,
.elementor .job-board__filter:focus-visible {
	background-color: #F2F6FD;
	color: #405BA9;
}

.elementor .job-board__filter.is-current {
	background-color: #405BA9;
	color: #FFFFFF;
	font-weight: 500;
}

.elementor .job-board__filter-name {
	min-width: 0;
}

/* The count is a secondary number, so it never competes with the label —
   including on the selected row, where the ground is brand blue. */
.elementor .job-board__filter-count {
	flex: 0 0 auto;
	min-width: 24px;
	padding: 1px 7px;
	border-radius: 999px;
	background-color: #EDF1F9;
	color: #6B7285;
	font-size: 12px;
	line-height: 18px;
	font-weight: 600;
	text-align: center;
}

.elementor .job-board__filter.is-current .job-board__filter-count {
	background-color: rgba(255, 255, 255, 0.22);
	color: #FFFFFF;
}

/* --- The results --------------------------------------------------------- */

.elementor .job-board__results {
	display: flex;
	flex-direction: column;
	gap: 16px;
	min-width: 0;
}

.elementor .job-board__count {
	margin: 0;
	color: #8A90A0;
	font-size: 13px;
	line-height: 18px;
	letter-spacing: 0.4px;
	text-transform: uppercase;
}

.elementor .job-board__grid {
	min-width: 0;
	transition: opacity 160ms ease;
}

/* A swap is fast enough that a spinner would flash; dimming is honest about
   something happening without redrawing the page. */
.elementor .job-board.is-loading .job-board__grid {
	opacity: 0.45;
	pointer-events: none;
}

.elementor .job-board__empty {
	margin: 0;
	padding: 32px;
	border: 1px dashed #D7DEEE;
	border-radius: 12px;
	background-color: #FBFCFE;
	color: #646B7D;
	font-size: 15px;
	line-height: 24px;
}

/* --- The cards -----------------------------------------------------------
   The card's look used to live in the Elementor global classes `job-card`,
   `job-card__title` and the rest. Elementor only emits a global class's CSS
   when an element on the document still uses it — the moment the hardcoded
   cards went, that CSS stopped being printed and the rendered cards came out
   unstyled. The values below are those same global-class props, measured off
   the classes and restated here.

   The gradient hover ring, the arrow glyph and the hover colours are NOT
   repeated: those were always plain selectors in this file and still apply.
   -------------------------------------------------------------------------- */
.elementor .job-board .job-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
	width: 100%;
	padding: 0;
}

.elementor .job-board .job-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
	min-width: 0;
	padding: 28px;
	border: 1px solid #E3DFD7;
	border-radius: 4px;
	background-color: #FFFFFF;
}

.elementor .job-board .job-card__title {
	width: 100%;
	margin: 0;
	color: #0B1020;
	font-size: 20px;
	line-height: 28px;
	font-weight: 600;
}

.elementor .job-board .job-card__body {
	width: 100%;
	margin: 0;
	color: #6B7285;
	font-size: 14px;
	line-height: 22px;
	font-weight: 400;
}

/* The pill's padding came from the atomic paragraph's base style, which a
   rendered <p> never receives, so it is stated outright. */
.elementor .job-board .job-card__tag {
	flex: 0 0 auto;
	margin: 0;
	padding: 5px 12px;
	border-radius: 999px;
	background-color: #F0FBFE;
	color: #177E9F;
	font-size: 12px;
	line-height: 18px;
	font-weight: 500;
}

/* Likewise the button's box: `e-button-base` supplied it before. */
.elementor .job-board .job-card__apply {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	margin-block: auto 0;
	padding: 9px 18px;
	border: 1px solid #405BA9;
	border-radius: 4px;
	background-color: transparent;
	color: #405BA9;
	font-size: 13px;
	line-height: 20px;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 160ms ease, color 160ms ease;
}

/* The button's own hover lives at the top of this file on `.job-card__apply`,
   which is the same specificity as the rule above but earlier in the file — so
   restating the base box here silently killed it. It is restored at a weight
   that beats the base, and extended to the whole card: hovering anywhere on a
   card now lights its Apply button, since the card is the thing the pointer is
   aiming at.

   `:focus-within` covers the keyboard: tabbing to the Apply link lights the
   button the same way a pointer does. */
.elementor .job-board .job-card__apply:hover,
.elementor .job-board .job-card__apply:focus-visible,
.elementor .job-board .job-card:focus-within .job-card__apply {
	background-color: #405BA9;
	color: #FFFFFF;
}

@media (hover: hover) {

	/* Card-level hover is gated: on a touch screen a tap leaves the hover state
	   stuck on the card until something else is tapped. */
	.elementor .job-board .job-card:hover .job-card__apply {
		background-color: #405BA9;
		color: #FFFFFF;
	}

	/* The arrow is a mask painted with `currentColor`, so it turns white on its
	   own — only the nudge has to be repeated for the card-level hover. */
	.elementor .job-board .job-card:hover .job-card__apply::after {
		transform: translateX(3px);
	}
}

@media (max-width: 767px) {

	.elementor .job-board .job-card {
		padding: 22px;
	}

	.elementor .job-board .job-card__title {
		font-size: 18px;
		line-height: 26px;
	}
}

@media (max-width: 1200px) {

	.elementor .job-board {
		grid-template-columns: 200px minmax(0, 1fr);
		gap: 32px;
	}

	.elementor .job-board .job-row {
		gap: 20px;
	}
}

/* Below the two-column threshold the rail becomes a scrollable chip row above
   the results — a sidebar at this width would leave the cards too narrow. */
@media (max-width: 1024px) {

	.elementor .job-board {
		grid-template-columns: minmax(0, 1fr);
		gap: 24px;
	}

	.elementor .job-board__rail {
		position: static;
		top: auto;
	}

	.elementor .job-board__rail-head {
		margin-block-end: 10px;
		padding-block-end: 10px;
	}

	.elementor .job-board__filters {
		flex-direction: row;
		flex-wrap: nowrap;
		gap: 8px;
		overflow-x: auto;
		padding-block-end: 4px;
		scrollbar-width: thin;
	}

	.elementor .job-board__filter {
		flex: 0 0 auto;
		border: 1px solid #E3E6ED;
		border-radius: 999px;
		white-space: nowrap;
	}

	.elementor .job-board__filter.is-current {
		border-color: #405BA9;
	}
}

@media (max-width: 767px) {

	.elementor .job-board .job-row {
		grid-template-columns: minmax(0, 1fr);
		gap: 16px;
	}

	.elementor .job-board__empty {
		padding: 24px 20px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.elementor .job-board__filter,
	.elementor .job-board__grid {
		transition: none;
	}
}

/* ==========================================================================
   THE SECTION EYEBROW ON `team-label`

   The site has one eyebrow: 12px uppercase text behind the Softouch chapter
   mark, a 67x16 PNG, with the text starting 79px in. Home, Communities, the
   taxonomy archive and the community detail all use the `eyebrow` class, which
   paints it as a background image.

   Who We Are, the Seller's Guide and Careers were built with `team-label`
   instead — a flex row of a bare 40x1px CSS line and the text. Same intent,
   different component, and it lost the mark: six labels across three pages
   render as a grey dash.

   The component is kept (replacing it would mean re-authoring six blocks in
   three documents); its rule is given the artwork. 67px + the row's existing
   12px gap reproduces the eyebrow's 79px exactly, so the two now line up.
   ========================================================================== */
.elementor .team-label__rule.team-label__rule {
	width: 67px;
	height: 16px;
	background-color: transparent;
	background-image: url('assets/motifs/chapter-label-navy.png');
	background-repeat: no-repeat;
	background-position: left center;
	background-size: 67px 16px;
}

/* The mark is drawn in navy for a light ground. On a dark band the label is
   `eyebrow-inverse`'s territory and `team-label` is not used, so no inverse
   variant is needed here — if one ever is, it is the same rule with
   `chapter-label-dark.png`. */

/* ==========================================================================
   THE CURRENT MENU ITEM ON A TRANSPARENT BAR

   `main-nav__item.is-current > .main-nav__link` paints the current page in the
   brand blue, which is right on the solid white bar. On the homepage and on any
   page that opens with a hero the bar is transparent over a photograph, and the
   rule that whitens the nav ink there is far more specific — body + `:has()` +
   three `:not()`s — so the current item came out white like every other link
   and the active state simply did not exist on those pages.

   The ink is `#8FDCF2`, the accent this site already uses on dark grounds
   (`eyebrow-accent`, the stat labels), not the brand blue, which is too dark to
   read against a photograph.

   The selectors mirror the whitening rule exactly and add `.is-current`, so
   they win on specificity rather than on order, and they stop applying the
   moment the bar turns solid — at which point the brand-blue rule takes over
   again. `aria-current="page"` is already emitted by the walker, so the state
   is never carried by colour alone.
   ========================================================================== */
body.home .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open):not(.is-nav-open) .main-nav__item.is-current > .main-nav__link,
body:has(.page-hero, .page-hero-compact) .elementor .site-masthead:not(.is-scrolled):not(.is-mega-open):not(.is-search-open):not(.is-nav-open) .main-nav__item.is-current > .main-nav__link {
	color: #8FDCF2;
}

/* ==========================================================================
   THE NAV'S PLACE IN THE BAR

   The nav host carries a local style of `margin-right: 113.352px` — a fraction
   of a pixel, so it was dragged to position in the editor rather than chosen.
   It pins the nav against the logo: 24px of breathing room on the left (just
   the bar's flex gap) against 137px on the right, which reads as the nav having
   fallen into the wordmark.

   `margin-inline: auto` hands that slack back to the flexbox, which splits it
   evenly — about 80px each side. It also self-corrects: a longer button label,
   a translated menu or a different logo all stay balanced, where a hardcoded
   margin would need measuring again.

   Desktop only. Below 1201 the nav is the drawer and is positioned by its own
   rules, which must not inherit a centring margin.
   ========================================================================== */
@media (min-width: 1201px) {

	.elementor .site-masthead .main-nav-host {
		margin-inline: auto;
	}
}

/* ==========================================================================
   THE "ON THIS PAGE" MEGA PANEL

   The Communities panel is three columns of content and fills the bar's full
   width. This one is a handful of section links, so the same full-bleed shell
   with one narrow column in it would read as a mostly-empty sheet. The links
   run as a row instead, which is also what they look like on the page itself —
   the dropdown and the jump nav are the same list, so they should look alike.
   ========================================================================== */

.mega--anchors .mega__inner {
	display: block;
	padding-block: 28px 26px;
}

.mega--anchors .mega__col--anchors {
	flex: 0 1 auto;
	min-width: 0;
}

.mega--anchors .mega__list {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.mega--anchors .mega__term {
	display: inline-flex;
	align-items: center;
	min-height: 38px;
	padding: 0 18px;
	border: 1px solid #E3E6ED;
	border-radius: 999px;
	color: #3C445A;
	font-size: 15px;
	line-height: 22px;
	text-decoration: none;
	white-space: nowrap;
	transition: border-color 140ms ease, background-color 140ms ease, color 140ms ease;
}

.mega--anchors .mega__term:hover,
.mega--anchors .mega__term:focus-visible {
	border-color: #405BA9;
	background-color: #F2F6FD;
	color: #405BA9;
}

/* The page itself. On desktop the menu item's own link becomes a disclosure
   button, so without this there is no way left to reach the page from the bar. */
.mega--anchors .mega__term--all {
	border-color: #405BA9;
	background-color: #405BA9;
	color: #FFFFFF;
	font-weight: 500;
}

.mega--anchors .mega__term--all:hover,
.mega--anchors .mega__term--all:focus-visible {
	border-color: #32487F;
	background-color: #32487F;
	color: #FFFFFF;
}

@media (max-width: 1200px) {

	/* In the drawer the panel is a stacked list, not a bar, so the row becomes
	   a column and the pills become plain rows like every other drawer link. */
	.mega--anchors .mega__list {
		flex-direction: column;
		gap: 2px;
	}

	.mega--anchors .mega__term {
		width: 100%;
		border-color: transparent;
		border-radius: 8px;
		white-space: normal;
	}
}

@media (prefers-reduced-motion: reduce) {

	.mega--anchors .mega__term {
		transition: none;
	}
}

/* ==========================================================================
   THE DRAWER, AFTER THE NAV BECAME A WORDPRESS MENU

   The drawer's per-item rules are written as `.main-nav > *` — they date from
   when the seven links were the nav's own children. The menu renders a
   <ul class="main-nav__list"> now, so that selector matches the LIST and
   nothing else: the list got the padding, the hairline and the reveal, while
   the items inside kept the desktop row and wrapped into three ragged columns
   off the side of the panel.

   The selectors are structural, not class-based, so the comment above
   `.main-nav__list` — that keeping the class names would keep every existing
   rule working — holds for the ink swap but could not hold for these.

   Fixed by neutralising the list and re-homing the chrome onto the items.
   `site-nav.js` was indexing `nav.children` for the stagger and hitting the
   same wall; it reads `.main-nav__item` now.
   ========================================================================== */

@media (max-width: 1200px) {

	.elementor .site-masthead .main-nav > .main-nav__list {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		width: 100%;
		/* The list is a wrapper, not a row: the chrome belongs to the items. */
		padding-block: 0;
		border-block-start: 0;
	}

	.elementor .site-masthead .main-nav__item {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		width: 100%;
		padding-block: 15px;
		border-block-start: 1px solid rgba(11, 16, 32, 0.1);
		font-size: 17px;
		text-align: start;
	}

	.elementor .site-masthead .main-nav__item:first-child {
		border-block-start: 0;
	}

	.elementor .site-masthead .main-nav__item .main-nav__link {
		display: block;
		width: 100%;
	}
}

/* ==========================================================================
   THE MISSION & VISION PULL QUOTE — Who We Are

   The quote block opens flush against the paragraph above it: the lead ends at
   the exact pixel the block begins, 0px between them. On its own that would
   merely be tight, but the mark is 96px type set on a 60px line-height, so the
   glyph's ink overflows its line box upward and lands on the lead's last line.

   Spacing the mark rather than the block because the mark is the block's first
   child and the block has no ground of its own — the whole stack moves, and
   nothing else has to know the block's shape.
   ========================================================================== */
/* Doubled: Elementor emits the element's own local style as
   `.elementor .e-xxxxxxxx`, the same (0,2,0) as a single-class rule here, and
   it comes later in the cascade — a plain `.elementor .mv-quote__mark` lost to
   it silently and the margin never applied. */
.elementor .mv-quote__mark.mv-quote__mark {
	margin-block-start: 44px;
}

@media (max-width: 1200px) {

	.elementor .mv-quote__mark.mv-quote__mark {
		margin-block-start: 32px;
	}
}

@media (max-width: 767px) {

	.elementor .mv-quote__mark.mv-quote__mark {
		margin-block-start: 24px;
	}
}

/* ==========================================================================
   THE PROJECT LOGO IN THE PROPERTY HERO

   Sits above the development's name. The mark is the client's artwork at
   whatever proportions they drew it, so it is constrained by HEIGHT and left to
   find its own width — a fixed width would squash a wide lock-up or blow up a
   square one. `object-fit: contain` is belt and braces for a logo that arrives
   with padding baked into the file.
   ========================================================================== */

.elementor .plogo-mount {
	width: 100%;
}

.elementor .plogo {
	display: block;
	margin-block-end: 18px;
}

.elementor .plogo__img {
	display: block;
	width: auto;
	max-width: 200px;
	height: auto;
	max-height: 84px;
	object-fit: contain;
	object-position: left center;
}

/* No plate. The property hero's copy column sits on white since the gallery
   revamp — measured `rgb(255, 255, 255)` — so a white panel behind a mark drawn
   for a light ground is invisible, and its padding was eating the artwork: the
   box measured 78x72 with only about 50px of actual logo inside it. */

/* The mark moved out of the hero and onto the Overview band, between the heading
   and the body copy. That stack is `.community-overview__copy`, a column with
   `gap: 20px`, so the gap already spaces the mark on both sides — the 18px
   bottom margin it carried from the hero would have made it 38px below against
   20px above, which reads as the mark belonging to the heading rather than
   sitting between the two. */

.elementor .community-overview__copy .plogo {
	margin-block-end: 0;
}

@media (max-width: 767px) {

	.elementor .plogo {
		margin-block-end: 14px;
	}

	.elementor .plogo__img {
		max-width: 150px;
		max-height: 64px;
	}
}

/* A fact can be several lines — "2 bedrooms" over "1 bathroom" — so each one is
   its own block rather than a comma-joined string left to break wherever the
   174px cell runs out. A single-line value is unaffected: one block is
   indistinguishable from plain text. */
.cfacts__line {
	display: block;
}

/* The route up from a house model to its development.
   `align-self: flex-start` so the button hugs its label — `.cmodels` is a
   column flexbox with stretched children, and without it the link would run the
   full width of the grid above it. */

/* The Types of Homes head is a ROW: the eyebrow-and-title stack on the left, the
   "View <development>" button opposite it, in the space that row's right half
   had standing empty.

   Scoped through `.community-models`. The head's class is `section-head-stack`,
   which EVERY section on this template shares — turning that into a row
   unscoped would put every eyebrow beside its own heading.

   The inner stack is targeted by STRUCTURE: an atomic `e-flexbox` takes its
   classes as global-class IDs, so the plain class name I gave it never reached
   the DOM. It is the only `e-con` in the head, the button being a widget, so the
   child combinator is exact. Without the `column` it inherits the row and the
   eyebrow sits beside the heading — the default this template trips over
   everywhere.

   `align-items: flex-end` keeps the button on the heading's baseline edge rather
   than floating at the top of a two-line title. */
.elementor .community-models .section-head-stack {
	flex-direction: row;
	flex-wrap: nowrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 24px;
}

/* `width: auto` is load-bearing. Elementor gives an atomic container
   `width: 100%`, which in a row makes the copy stack claim the whole line and
   pushes the button onto the next one — the layout still looks like a column
   even though the row is applied. `flex: 1 1 auto` then lets it give the button
   the space it needs. */
.elementor .community-models .section-head-stack > .e-con {
	flex: 1 1 auto;
	flex-direction: column;
	/* 20px, matching every other section head. The wrapper this rule targets was
	   added to carry the button, and an atomic container with no global class
	   has no gap of its own — so this one section's eyebrow sat hard against its
	   heading while the rest of the page kept its 20px. */
	gap: 20px;
	width: auto;
	min-width: 0;
}

.elementor .community-models .section-head-stack > .elementor-widget-shortcode {
	flex: 0 0 auto;
	width: auto;
}

/* Below the laptop breakpoint the title needs the whole measure, so the button
   drops under it rather than squeezing the heading into three lines. */
@media (max-width: 1024px) {

	.elementor .community-models .section-head-stack {
		flex-direction: column;
		align-items: flex-start;
		gap: 18px;
	}
}

/* The margin and the self-alignment belonged to its old home at the foot of the
   card grid. In the head it is a flex item of a row that already spaces it. */
.elementor .cmodels__parent {
	align-self: flex-start;
}

/* ==========================================================================
   PROPERTY DETAIL — TYPE SCALE, 10% DOWN

   The page title and the section headings are 10% smaller HERE only. Both
   classes are site-wide (`page-hero__title-sm` is every inner hero's title,
   `heading-2` is every section heading on the site), so the reduction is scoped
   to `body.is-property-detail` rather than applied to the classes themselves —
   editing those would resize the Communities index, the guides and the Careers
   board with them.

   Every breakpoint is restated because Elementor sets a different size at each
   one, and overriding only the desktop value would leave the phone at full
   size. Values are the original x 0.9, rounded to the nearest pixel:

     title     48/56 -> 43/50    tablet 40/48 -> 36/43    phone 30/38 -> 27/34
     heading   42/52 -> 38/47    laptop 38/48 -> 34/43    tablet+ 36/46 -> 32/41
                                 tablet 34/44 -> 31/40    phone   28/36 -> 25/32

   `.elementor` is in each selector to match the specificity Elementor's own
   global-class rules carry; the body class then outweighs them.
   ========================================================================== */

body.is-property-detail .elementor .page-hero__title-sm {
	font-size: 43px;
	line-height: 50px;
}

body.is-property-detail .elementor .heading-2 {
	font-size: 38px;
	line-height: 47px;
}

@media (max-width: 1366px) {

	body.is-property-detail .elementor .heading-2 {
		font-size: 34px;
		line-height: 43px;
	}
}

@media (max-width: 1200px) {

	body.is-property-detail .elementor .heading-2 {
		font-size: 32px;
		line-height: 41px;
	}
}

@media (max-width: 1024px) {

	body.is-property-detail .elementor .page-hero__title-sm {
		font-size: 36px;
		line-height: 43px;
	}

	body.is-property-detail .elementor .heading-2 {
		font-size: 31px;
		line-height: 40px;
	}
}

@media (max-width: 767px) {

	body.is-property-detail .elementor .page-hero__title-sm {
		font-size: 27px;
		line-height: 34px;
	}

	body.is-property-detail .elementor .heading-2 {
		font-size: 25px;
		line-height: 32px;
	}
}

/* ==========================================================================
   OUTLINE BUTTONS — THE GRADIENT EDGE

   `.button-outline` is an Elementor global class used across the site (the
   buyer-journey CTA on every guide, the route up from a house model, and so on).
   Its 2px solid #405BA9 edge becomes the brand gradient, drawn by the shared
   ring above.

   The border is REMOVED and the padding grown by the same 2px rather than left
   in place as `transparent`. An absolutely positioned `::before` is contained by
   the PADDING box, so with the border still there the ring would draw 2px inside
   the old edge and leave a transparent gap around it. Removing the border and
   paying the 2px back as padding keeps the button's outer size identical to the
   pixel while putting the ring exactly where the border was.

   The hover fill is untouched: it still goes solid `--cd-brand` with a white
   label, and the gradient ring stays visible around it.
   ========================================================================== */

.elementor .button-outline {
	position: relative;
	isolation: isolate;
	border: 0;
	padding-block: 18px;
	padding-inline: 34px;
}

/* ==========================================================================
   PROPERTY DETAIL — GRADIENT EYEBROWS

   Every section label on this page ("PROJECT OVERVIEW", "KEEP LOOKING", …) is
   painted with the brand gradient instead of grey, scoped to
   `body.is-property-detail` because `.eyebrow` is used on every page.

   The awkward part: `.eyebrow` ALREADY uses `background-image` for the little
   rule graphic to the left of the text (a 67x16 PNG, with 79px of padding
   holding the text clear of it). Clipping that background to the text would clip
   the rule away with it. So the rule is re-drawn as a `::before` and the
   element's own background is handed over to the gradient.

   ACCESSIBILITY — the cyan end of this gradient measures 1.99:1 on white. At
   12px bold that is far below the 4.5:1 AA floor, so the first few characters of
   each label are genuinely hard to read. `--cd-eyebrow-from` exists to fix that
   in one place: set it to #2E7F95 (the same hue at 64%) and the whole gradient
   clears AA at 4.58:1 while still reading as cyan-to-navy. It is left on the
   literal brand cyan because that is what was asked for.
   ========================================================================== */

body.is-property-detail {
	--cd-eyebrow-from: #48C6E9;
	--cd-eyebrow-to: #405BA9;
}

@supports ((background-clip: text) or (-webkit-background-clip: text)) {

	body.is-property-detail .elementor .eyebrow {
		position: relative;
		/* The box is stretched by its flex parent — measured 638px against a
		   ~130px label — so the gradient crossed the text in its first fifth and
		   every eyebrow read as flat cyan. Hugging the text makes the ramp run
		   end to end across the words themselves. */
		width: fit-content;
		max-width: 100%;
		background-image: linear-gradient(
			115deg,
			var(--cd-eyebrow-from) 0%,
			var(--cd-eyebrow-to) 100%
		);
		/* The PNG's sizing and placement came with the old background and would
		   squash the gradient into a 67px strip. */
		background-position: 0 0;
		background-size: auto;
		background-repeat: repeat;
		-webkit-background-clip: text;
		background-clip: text;
		color: transparent;
		-webkit-text-fill-color: transparent;
	}

	/* The rule graphic, back as its own layer so the clip above cannot reach it.
	   `currentColor` is transparent here, so nothing is inherited from the text. */
	/* The rule graphic, re-drawn here so the text clip above cannot reach it —
	   and MASKED rather than drawn, so it takes the same gradient as the words.

	   The PNG carries real alpha (3,813 transparent pixels of 4,288), with the
	   kite already #405BA9 and the rule beside it a warm grey #CBC5BA. Using it
	   as a mask throws its colours away and keeps only its shape, so both parts
	   come out in brand blue instead of only the kite. */
	body.is-property-detail .elementor .eyebrow::before {
		content: "";
		position: absolute;
		inset-inline-start: 0;
		inset-block-start: 50%;
		width: 67px;
		height: 16px;
		transform: translateY(-50%);
		background-image: linear-gradient(
			115deg,
			var(--cd-eyebrow-from) 0%,
			var(--cd-eyebrow-to) 100%
		);
		-webkit-mask-image: url("../../uploads/2026/09/chapter-label-light.png");
		-webkit-mask-repeat: no-repeat;
		-webkit-mask-size: 67px 16px;
		-webkit-mask-position: left center;
		mask-image: url("../../uploads/2026/09/chapter-label-light.png");
		mask-repeat: no-repeat;
		mask-size: 67px 16px;
		mask-position: left center;
	}
}

/* ==========================================================================
   PROPERTY DETAIL — INQUIRY FIELDS, BRAND BLUE EDGE

   The fields rest on the warm grey `#E3DFD7` the rest of the site uses. Here
   they take the brand blue instead, scoped to `.community-inquiry` — the Contact
   page uses the SAME `cf-*` components and is deliberately left alone.

   Focus had been signalled by the border turning brand blue. With the resting
   border already brand blue there is nothing left for focus to say, so it gains
   a soft halo and a deeper edge instead. Without that, moving through the form
   on a keyboard would give no visible indication of where you are, which is a
   worse failure than the one this change is fixing.
   ========================================================================== */

.elementor .community-inquiry .cf-input,
.elementor .community-inquiry .cf-select,
.elementor .community-inquiry .cf-textarea {
	border-color: var(--cd-brand);
}

.elementor .community-inquiry .cf-input:focus,
.elementor .community-inquiry .cf-select:focus,
.elementor .community-inquiry .cf-textarea:focus {
	border-color: var(--cd-brand-deep);
	box-shadow: 0 0 0 3px rgba(64, 91, 169, 0.18);
	outline: none;
}

/* A read-only field is not editable, so it must not claim the active edge. */
.elementor .community-inquiry .cf-input[readonly],
.elementor .community-inquiry .cf-input[readonly]:focus {
	border-color: #E3DFD7;
	box-shadow: none;
}

/* ==========================================================================
   PROPERTY DETAIL — ONE VERTICAL RHYTHM

   Every band on this page takes the same top and bottom padding as the "Talk to
   a Property Specialist" band, which is the measure asked for. Its ladder:

     > 1200px   55px        (was 96px on most bands)
     <= 1200px  40px        (was 88 / 72)
     <= 767px   32px        (was 44)

   The desktop step was 48px — the mid-CTA's own value — and was raised to 55px
   on 2026-10-06. The narrower steps were left where they are: 40 and 32 still
   read as a descending ladder under 55, and nothing asked for them to move.

   TWO band classes, not one. Most bands are `.page-section`; the FAQ band is
   `.page-section-feature`, which carried 128px and so sat well outside the
   rhythm until it was listed here too. Anything new on this template needs to
   use one of these two names or it will quietly keep its own spacing.

   The class is DOUBLED for (0,4,0). The hero and the facts strip set their
   padding through `.community-hero.community-hero` and
   `.community-facts.community-facts`, which are (0,3,0) — a single-class rule
   here would tie with them and win only on source order, which is not something
   to depend on.

   NOTE: this deliberately pulls the hero (28/56) and the facts strip (8/32) onto
   the same rhythm. Those two were a tight pair — the strip read as part of the
   hero block rather than as a band of its own — and they now sit apart like
   everything else.
   ========================================================================== */

body.is-property-detail .elementor .page-section.page-section,
body.is-property-detail .elementor .page-section-feature.page-section-feature {
	padding-block: 55px;
}

@media (max-width: 1200px) {

	body.is-property-detail .elementor .page-section.page-section,
	body.is-property-detail .elementor .page-section-feature.page-section-feature {
		padding-block: 40px;
	}
}

@media (max-width: 767px) {

	body.is-property-detail .elementor .page-section.page-section,
	body.is-property-detail .elementor .page-section-feature.page-section-feature {
		padding-block: 32px;
	}
}

/* --------------------------------------------------------------------------
   …except the seam between the hero and the facts strip.

   Those two read as one block — the strip is the hero's summary, not a band in
   its own right — so the full gap between them was 96px of nothing. Both sides
   are halved and track the section value: 55 -> 28 each side and the same proportion down the
   ladder. Everything else keeps the full rhythm.

   (0,5,0), so it outranks the blanket `.page-section.page-section` rule above
   on specificity rather than on source order.
   -------------------------------------------------------------------------- */

body.is-property-detail .elementor .community-hero.community-hero {
	padding-block-end: 28px;
}

body.is-property-detail .elementor .community-facts.community-facts {
	padding-block-start: 28px;
}

@media (max-width: 1200px) {

	body.is-property-detail .elementor .community-hero.community-hero {
		padding-block-end: 20px;
	}

	body.is-property-detail .elementor .community-facts.community-facts {
		padding-block-start: 20px;
	}
}

@media (max-width: 767px) {

	body.is-property-detail .elementor .community-hero.community-hero {
		padding-block-end: 16px;
	}

	body.is-property-detail .elementor .community-facts.community-facts {
		padding-block-start: 16px;
	}
}

/* ==========================================================================
   PROPERTY DETAIL — ONE CORNER RADIUS

   Every box on this page takes the Project Overview panel's 4px. The page had
   six different radii on surfaces that sit within a screen of each other:

     16px  the hero aside, the facts strip, the scheme cards, the site plan,
           the video trigger
     14px  the property cards and the gallery tiles
     12px  the map frame
      8px  the form fields and the two contact buttons
      6px  the spec chips
      4px  the Overview panel, the landmarks aside, the FAQ items, the buttons

   CIRCLES AND PILLS ARE NOT BOXES and keep their 999px: the share buttons, the
   scheme badges, the "Click to view full plan" hint and the availability badge.
   Flattening those to 4px would turn deliberate round controls into squares.

   Doubled classes for (0,5,0): several of these are set by rules that already
   double their own class, so a single-class rule here would tie and win only on
   source order.
   ========================================================================== */

body.is-property-detail .elementor .caside.caside,
body.is-property-detail .elementor .cfacts.cfacts,
body.is-property-detail .elementor .cscheme.cscheme,
body.is-property-detail .elementor .csiteplan.csiteplan,
body.is-property-detail .elementor .cvideo__trigger.cvideo__trigger,
body.is-property-detail .elementor .cmap.cmap,
body.is-property-detail .elementor .cmap__frame.cmap__frame,
body.is-property-detail .elementor .model-loop__card.model-loop__card,
body.is-property-detail .elementor .cmodels__card.cmodels__card,
body.is-property-detail .elementor .cgallery__tile.cgallery__tile,
body.is-property-detail .elementor .cupdate.cupdate,
body.is-property-detail .elementor .spec-chip.spec-chip,
body.is-property-detail .elementor .ccall.ccall,
body.is-property-detail .elementor .csend.csend,
body.is-property-detail .elementor .cf-input.cf-input,
body.is-property-detail .elementor .cf-select.cf-select,
body.is-property-detail .elementor .cf-textarea.cf-textarea {
	border-radius: 4px;
}

/* ==========================================================================
   FINAL CTA — HEADING DOWN 20%

   "Stay in the Loop" was 56px against the site's 42px `heading-2`, so the last
   band on the page shouted louder than every section above it. 20% off the
   whole ladder puts it at 45px — still the largest heading on the page, by a
   margin that reads as emphasis rather than as a different document.

     desktop      56/64 -> 45/51
     <= 1366px    50/58 -> 40/46
     <= 1200px    46/54 -> 37/43
     <= 1024px    40/48 -> 32/38
     <= 767px     32/40 -> 26/32

   Scoped through `.final-cta`, which is where every instance of
   `display-m-inverse` on this site sits (News & Events, Communities and the
   Buyer's Guide — one each). Doubled for (0,4,0) over Elementor's (0,2,0).
   ========================================================================== */

.elementor .final-cta .display-m-inverse.display-m-inverse {
	font-size: 45px;
	line-height: 51px;
}

@media (max-width: 1366px) {

	.elementor .final-cta .display-m-inverse.display-m-inverse {
		font-size: 40px;
		line-height: 46px;
	}
}

@media (max-width: 1200px) {

	.elementor .final-cta .display-m-inverse.display-m-inverse {
		font-size: 37px;
		line-height: 43px;
	}
}

@media (max-width: 1024px) {

	.elementor .final-cta .display-m-inverse.display-m-inverse {
		font-size: 32px;
		line-height: 38px;
	}
}

@media (max-width: 767px) {

	.elementor .final-cta .display-m-inverse.display-m-inverse {
		font-size: 26px;
		line-height: 32px;
	}
}

/* ==========================================================================
   PROPERTY DETAIL — ONE LEFT EDGE

   Five bands were indented 10px against the other seven. Their copy columns
   carry `padding-inline: 10px` — the same stray padding the hero aside and the
   Overview right column had — so their headings landed at 137px while the
   section measure, the facts strip and every other band's heading sat at 127.

   The models band is included through its inner `.e-con` rather than a class:
   that wrapper was added to carry the "View <development>" button and an atomic
   container with no global class never gets one in the DOM.

   The aside columns keep their own padding — `.community-landmarks__aside` is a
   tinted panel whose 32px is the inset of a box, not the indent of a column.
   ========================================================================== */

body.is-property-detail .elementor .community-hero__copy,
body.is-property-detail .elementor .community-overview__copy,
body.is-property-detail .elementor .community-midcta__copy,
body.is-property-detail .elementor .community-midcta__actions,
body.is-property-detail .elementor .community-landmarks__copy,
body.is-property-detail .elementor .community-models .section-head-stack > .e-con {
	padding-inline: 0;
}

/* ==========================================================================
   PHONE TYPE — FAQ QUESTIONS AND TESTIMONIALS

   Both were set for the desktop measure and carried straight down. At 375px
   the column is 335px wide, and a 26px quote wraps every four or five words:
   the reader gets a column of fragments rather than a sentence.

   Measured before changing anything, at 375px:

     .faq-item__title      21px / 30px   — a question, not a section heading
     .testimonial__quote   26px / 38px   — four to five words per line
     .fact-item__value     21px / 30px   — an attribution set larger than the
                                           body copy it is attributed from

   The doubled class is load-bearing. Elementor emits a global class as
   `.the-class` (0,1,0) and the element's own local style as
   `.elementor .e-xxxxxxxx` (0,2,0); each of these elements carries one. A
   single `.elementor .the-class` is also (0,2,0) — a tie, broken by source
   order, which is not a thing to rely on. Doubling takes it to (0,3,0) and the
   question stops being "which rule came last".
   ========================================================================== */

@media (max-width: 767px) {

	/* A question is a question. 17/25 keeps it clearly above the 14px answer
	   beneath it without competing with the section heading above. */
	.elementor .faq-item__title.faq-item__title {
		font-size: 17px;
		line-height: 25px;
	}

	/* 18/28 puts roughly eight words on a line instead of four, which is what
	   makes it read as speech again. Still the largest thing in the card, so
	   it keeps its weight in the section. */
	.elementor .testimonial__quote.testimonial__quote {
		font-size: 18px;
		line-height: 28px;
	}

	/* Scoped to the slider: `.fact-item__value` is shared with the facts strip,
	   where 21px is correct and this would shrink numbers that should be big. */
	.elementor .testimonial-slider .fact-item__value.fact-item__value {
		font-size: 16px;
		line-height: 24px;
	}

	.elementor .testimonial-slider .body-small.body-small {
		font-size: 13px;
		line-height: 21px;
	}
}

/* ==========================================================================
   THE MOBILE DRAWER'S SECOND LEVEL, AND ITS CONTACT ROW

   Two additions, both scoped to the drawer breakpoint:

   1. The mega panels every top-level item already carries are shown here as
      collapsible lists. They were in the markup all along, only
      `display: none` — so the phone menu was hiding a level, not missing one.
   2. The channel row the header's Enquire button no longer provides.

   The panel is WHITE, carrying two `Decoration — Brand Glow` washes (Figma
   node 18:54) — the same circular gradient the page bands use. So everything
   here is dark-on-light: #0B1020 for links, #5B6478 for labels, brand blue for
   the current page and the contact marks.
   ========================================================================== */

@media (max-width: 1200px) {

	/* The item becomes the row that holds link + chevron. */
	/* GRID, NOT WRAPPING FLEX.

	   The first attempt made the item a wrapping flex row and gave the panel
	   `flex-basis: 100%` to push it onto its own line. It never wrapped: the
	   link, the panel and the chevron all stayed on one line and ran 519px
	   wide inside a 252px item, so the chevron sat off-screen at x=575 and the
	   panel sat beside the link rather than under it — which is also where the
	   74px of dead space per item came from.

	   Grid states the placement instead of inferring it from how things
	   happen to measure: link and chevron share row 1, the panel owns row 2
	   across both columns. There is nothing left for the browser to decide. */
	.elementor .site-masthead .main-nav__item.has-mega {
		display: grid;
		grid-template-columns: 1fr auto;
		align-items: center;
	}

	/* EVERY cell is named. The chevron is appended AFTER the panel in the DOM
	   (the script adds it last), so leaving placement to auto-flow put the
	   panel on row 2 and pushed the chevron down to row 3 — 41px below the
	   link it belongs to. Naming the rows makes DOM order irrelevant. */
	.elementor .site-masthead .main-nav__item.has-mega > .main-nav__link {
		grid-row: 1;
		grid-column: 1;
		min-width: 0;
	}

	.main-nav__disclose {
		grid-row: 1;
		grid-column: 2;
	}

	.elementor .site-masthead .main-nav__item.has-mega > .mega {
		grid-row: 2;
		grid-column: 1 / -1;
	}

	.main-nav__disclose {
		flex: 0 0 auto;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		/* Same 36px box as `.site-masthead__toggle`, so with the shared gutter
		   above the two centres land on the same axis rather than merely
		   close to it. The finger gets 44px from the `::after` below. */
		position: relative;
		width: 36px;
		height: 36px;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 8px;
		background: rgba(11, 16, 32, 0.05);
		color: #0B1020;
		cursor: pointer;
		transition: background-color 180ms ease;
	}

	/* 36px box, 44px hit area — the box keeps the column's alignment, the
	   finger gets something it can land on. Same trick as
	   `.site-search__open`. */
	.main-nav__disclose::after {
		content: "";
		position: absolute;
		inset: -4px;
	}

	.main-nav__disclose svg {
		width: 12px;
		height: 8px;
		transition: transform 240ms cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.is-panel-open > .main-nav__disclose svg {
		transform: rotate(180deg);
	}

	/* HOVER IS BRAND BLUE — and the colour has to be stated, not left alone.

	   hello-elementor's reset.css paints a button's :hover and :focus, so the
	   glyph was being recoloured out from under this rule and washing out to
	   near-invisible on the hover tint. `.elementor` doubles the specificity
	   enough to take it back. See [[hello-elementor-magenta-buttons]] — the
	   same reset, the same lesson, a different state. */
	.elementor .main-nav__disclose:hover {
		background: rgba(64, 91, 169, 0.12);
		color: var(--brand);
	}

	.main-nav__disclose:focus-visible {
		outline: 2px solid var(--brand);
		outline-offset: 2px;
	}

	/* A button KEEPS focus after a click, so a :focus fill would leave one
	   chevron lit in a different colour from the rest for as long as the
	   drawer stayed open. The ring is the focus signal; the fill is not. */
	.elementor .main-nav__disclose:focus,
	.elementor .main-nav__disclose:active {
		background: rgba(11, 16, 32, 0.05);
		color: #0B1020;
	}

	.elementor .main-nav__disclose:focus:hover,
	.elementor .main-nav__disclose:active:hover {
		background: rgba(64, 91, 169, 0.12);
		color: var(--brand);
	}

	/* The open panel's own chevron keeps the brand colour, so the item that is
	   expanded is marked by more than a rotation. */
	.elementor .is-panel-open > .main-nav__disclose {
		color: var(--brand);
	}

	/* The panel itself. `grid-template-rows: 0fr → 1fr` animates to the
	   content's real height without anyone measuring it in JavaScript and
	   without `max-height` guesswork that clips a long list. */
	.elementor .site-masthead .main-nav__item.has-mega > .mega {
		display: grid;
		grid-template-rows: 0fr;
		position: static;
		width: auto;
		min-width: 0;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;
		opacity: 1;
		visibility: visible;
		transform: none;
		pointer-events: auto;
		/* Belt and braces with `align-content` above: this one stops the item
		   itself being stretched even if a future rule puts a height on the
		   row. */
		align-self: start;
		transition: grid-template-rows 280ms cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.elementor .site-masthead .main-nav__item.is-panel-open > .mega {
		grid-template-rows: 1fr;
	}

	/* The row that collapses has to own the overflow, not the panel. */
	.elementor .site-masthead .main-nav__item.has-mega > .mega > .mega__inner {
		display: block;
		overflow: hidden;
		min-height: 0;
		width: auto;
		max-width: none;
		margin: 0;
		padding: 0;
		gap: 0;
		background: none;
	}

	.elementor .site-masthead .main-nav__item.is-panel-open > .mega > .mega__inner {
		padding-block: 4px 14px;
	}

	.elementor .site-masthead .main-nav .mega__col {
		width: auto;
		max-width: none;
		padding: 0;
		border: 0;
		background: none;
	}

	.elementor .site-masthead .main-nav .mega__col + .mega__col {
		margin-block-start: 14px;
	}

	.elementor .site-masthead .main-nav .mega__head {
		margin: 0 0 6px;
		font-size: 11px;
		line-height: 16px;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		/* 5.9:1 on white — a label, quieter than the links it heads, but still
		   past AA rather than merely visible. */
		color: #5B6478;
	}

	.elementor .site-masthead .main-nav .mega__list {
		display: block;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.elementor .site-masthead .main-nav .mega__term,
	.elementor .site-masthead .main-nav .mega__dev {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 10px;
		/* 44px of finger, not 44px of box: the padding is what makes the row
		   tappable, so the text can stay at a readable size. */
		min-height: 44px;
		padding: 6px 0;
		border: 0;
		background: none;
		color: #0B1020;
		font-size: 15px;
		line-height: 22px;
		text-decoration: none;
	}

	.elementor .site-masthead .main-nav .mega__dev-text {
		display: flex;
		flex-direction: column;
		gap: 1px;
	}

	.elementor .site-masthead .main-nav .mega__dev-name {
		font-size: 15px;
		line-height: 21px;
		color: #0B1020;
	}

	.elementor .site-masthead .main-nav .mega__dev-place {
		font-size: 12px;
		line-height: 17px;
		color: #5B6478;
	}

	.elementor .site-masthead .main-nav .mega__chev {
		flex: 0 0 auto;
		width: 7px;
		height: 11px;
		color: #8A92A6;
	}

	/* --- The contact row at the foot of the drawer ------------------------ */

	.nav-channels {
		margin-block-start: auto;
		padding-block-start: 24px;
	}

	.nav-channels__label {
		margin: 0 0 12px;
		font-size: 11px;
		line-height: 16px;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		color: #5B6478;
	}

	.nav-channels__row {
		display: flex;
		align-items: center;
		gap: 12px;
	}

	.nav-channel {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		border-radius: 50%;
		background: rgba(64, 91, 169, 0.09);
		color: var(--brand);
		transition: background-color 180ms ease, transform 180ms ease;
	}

	.nav-channel svg {
		width: 20px;
		height: 20px;
	}

	.nav-channel:hover,
	.nav-channel:focus-visible {
		background: rgba(64, 91, 169, 0.17);
		color: var(--brand);
	}

	.nav-channel:focus-visible {
		outline: 2px solid var(--brand);
		outline-offset: 2px;
	}

	/* The drawer is a column, so `margin-block-start: auto` on the channel row
	   can push it to the bottom — but only once the nav is told to be one. */
	.elementor .site-masthead .main-nav {
		display: flex;
		flex-direction: column;
	}

	.elementor .site-masthead .main-nav > .main-nav__list {
		flex: 0 0 auto;
	}
}

/* Above the drawer breakpoint the nav is an inline row, where a stack of
   contact icons in the middle of it would make no sense — and the mega panels
   open on hover, so the disclosure chevron has nothing to disclose.

   BOTH are injected or rendered at every width, so hiding them is not
   optional: all the styling above sits inside `max-width: 1200px`, which left
   the chevron on the desktop bar as an unstyled browser button beside every
   link. A control is hidden by saying so, not by declining to style it. */
@media (min-width: 1201px) {

	.nav-channels,
	.main-nav__disclose {
		display: none;
	}
}

/* ==========================================================================
   THE SEARCH PANEL HAS TO FIT THE PHONE IT OPENS ON

   The panel grew to its content and the content is a full browse index — four
   communities, six locations, seven home types. On a 375x812 phone that runs
   off the bottom of the screen and simply stops: the list was cut mid-word at
   "Townhouse" with nothing to scroll, because the panel is `position:
   absolute` inside a `position: fixed` root and neither was ever given a
   height to work against.

   The field stays put and the list below it scrolls. That is the right split:
   the input is the control you came for and it must not scroll away from the
   thumb, while the index under it is a list and lists scroll.
   ========================================================================== */

@media (max-width: 1024px) {

	.site-search__panel {
		display: flex;
		/* `dvh` tracks the phone's collapsing address bar; `vh` is the fallback
		   for anything that does not know it, and is only wrong by the height
		   of that bar. */
		max-height: calc(100vh - var(--masthead-height, 72px));
		max-height: calc(100dvh - var(--masthead-height, 72px));
	}

	.site-search__inner {
		display: flex;
		flex-direction: column;
		/* Without this the flex item refuses to shrink below its content and
		   the overflow never engages — the usual reason an `overflow-y: auto`
		   that looks right does nothing at all. */
		min-height: 0;
		max-height: 100%;
	}

	.site-search__form {
		flex: 0 0 auto;
		/* 60px tall for a 19px placeholder was a desktop field dropped onto a
		   phone. 11px padding against a 24px line gives 48px — still a
		   comfortable target, and it hands the ~12px back to the results list
		   below, which is the part that was running out of room. */
		padding-block: 11px;
		padding-inline: 14px;
		gap: 10px;
	}

	/* 16px IS THE FLOOR, and it is not a taste decision. iOS Safari zooms the
	   whole page in when a focused input is under 16px, which throws the
	   layout sideways and leaves the reader pinch-zooming back out. 19 → 16 is
	   as far down as this can go; anything smaller has to come out of the
	   padding instead. */
	.site-search__input.site-search__input {
		font-size: 16px;
		line-height: 24px;
	}

	.site-search__icon {
		width: 20px;
		height: 20px;
	}

	.site-search__browse,
	.site-search__results {
		flex: 1 1 auto;
		min-height: 0;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		/* The page behind is already locked while the overlay is open; this
		   stops a flick at the end of the list from scrolling it anyway. */
		overscroll-behavior: contain;
	}

	/* Breathing room under the last row, so it does not sit flush on the
	   panel's edge when scrolled to the end. */
	.site-search__browse {
		padding-block-end: 20px;
	}
}


/* ==========================================================================
   THE TESTIMONIAL QUOTE ON LARGER SCREENS

   56px/68px in a 980px column is about thirty characters a line — a pull quote
   so large the reader is scanning a wall rather than reading a sentence, and
   the longest of the three testimonials filled the whole band with eight lines
   of it.

   32/44 holds roughly fifty-five characters, which is inside the comfortable
   50–75 measure, and still sets the quote well above the 15px attribution
   under it so it keeps its billing as the feature of the band. The phone value
   (18/28) is set with the rest of the phone type above; this is the step
   between.

   Doubled class for the usual reason — the 56px is an Elementor LOCAL style at
   (0,2,0), so a single `.elementor .testimonial__quote` would only tie it.
   ========================================================================== */

@media (min-width: 768px) {

	.elementor .testimonial__quote.testimonial__quote {
		font-size: 28px;
		line-height: 40px;
	}
}

@media (min-width: 1201px) {

	.elementor .testimonial__quote.testimonial__quote {
		font-size: 32px;
		line-height: 44px;
	}
}
