/**
 * Main stylesheet — CV Infotech Real Estate.
 *
 * Owns all visual design for the theme: color and type design tokens (as
 * CSS custom properties), base typography, site chrome (header, nav,
 * footer), the Property archive grid, and pagination. style.css is
 * reserved for the theme header block and required WordPress core
 * classes only — everything visual belongs here.
 *
 * Page-builder content areas (page.php, single.php, single-property.php,
 * front-page.php) are intentionally left unstyled beyond layout resets so
 * Elementor retains full control within the_content().
 */

:root {
	/* Color palette: a premium, editorial real-estate system — a warm
	   stone/ivory neutral family (background/surface/border), a deep
	   charcoal-black for headings, body ink, and every "dark" section
	   (nav, secondary buttons, footer, CTA bands, photo overlays), and a
	   single warm terracotta accent, rather than a large, competing
	   color set. --accent-color(-dark) and --secondary-color(-dark) are
	   the theme's Primary/Secondary Color — these two defaults are
	   overridden, per whatever is set in Appearance > Customize > Theme
	   Colors & Fonts, by the inline style cvit_realestate_design_css()
	   adds after this stylesheet (see functions.php); the values here
	   are only what a visitor sees before that Customizer setting is
	   ever touched.

	   The terracotta accent is deliberately split into two shades with
	   two distinct jobs, not used interchangeably:
	   — --accent-color (the lighter "Terracotta") is for large fills —
	     button/badge backgrounds — paired with white text (5:1+).
	   — --accent-color-dark ("Deep Clay") is for terracotta used AS
	     text, an icon, or a thin line directly on the light background
	     (nav/link hover, price emphasis, small icons) — the lighter
	     shade measures under 4.5:1 as running text there; the darker
	     shade clears it comfortably (6.5:1+). It's also the hover/focus
	     fill for buttons built with --accent-color, darkening further on
	     interaction the same way --secondary-color-dark does. Every such
	     spot in this file uses --accent-color-dark on purpose — don't
	     "simplify" it back to --accent-color. */
	--bg-color: #f6f3ee;
	--surface-color: #ece6db;
	--heading-color: #211d1b;
	--text-color: #332f2c;
	--text-muted-color: #756e68;
	--accent-color: #ad5a2b;
	--accent-color-dark: #8a431e;
	--secondary-color: #211d1b;
	--secondary-color-dark: #171310;
	--border-color: #e0d9cd;
	/* The text color paired with --accent-color (and --secondary-color)
	   as a background fill (buttons, the "For Rent"/"For Sale" badges) —
	   white reads clearly against both at their default shades. */
	--on-accent-color: #ffffff;

	/* Typography — likewise overridden per the Heading/Body Font choice. */
	--font-heading: "Playfair Display", Georgia, "Times New Roman", serif;
	--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	/* Shared motion timing for hover/reveal micro-interactions — one
	   dial so the whole site's motion feels consistent, and one place
	   to slow everything down (or effectively disable it) at once. */
	--ease: cubic-bezier( 0.22, 0.61, 0.36, 1 );
	--motion-fast: 0.2s;
	--motion-slow: 0.6s;

	/* Layout tokens — the boxed content width and section rhythm every
	   .content-section-based page already shares (see main.css further
	   down); centralized here so a future adjustment is one number
	   instead of a find-and-replace across the file.

	   --section-space and --section-space-tight are themselves
	   responsive (redefined below at the tablet and mobile breakpoints),
	   so every rule that consumes them via var() — .content-section,
	   .site-footer, .closing-cta, .footer-band, etc. — automatically
	   gets the right value at each breakpoint with no per-selector media
	   query of its own required. */
	--content-width: 1200px;
	--content-width-narrow: 46rem;
	--section-space: 6rem;
	--section-space-tight: 4rem;

	/* A small, deliberately short scale for spacing *within* a section
	   (eyebrow → heading → description → content) — as opposed to the
	   two tokens above, which are for spacing *between* sections. Not
	   every value in the file is threaded through these yet (several
	   pre-date this scale and were already close to one of these steps),
	   but any new spacing decision should reach for one of these first. */
	--space-3xs: 0.25rem;
	--space-2xs: 0.5rem;
	--space-xs: 0.75rem;
	--space-sm: 1rem;
	--space-md: 1.5rem;
	--space-lg: 2rem;
	--space-xl: 3rem;

	/* The horizontal edge padding every full-bleed section/bar uses —
	   one token so the page's left/right "margin" reads as one
	   consistent measure rather than each section picking its own. */
	--space-inline: 2rem;
}

/* Tablet: desktop's spacing carried straight down to a mid-size screen
   reads as too much dead space to scroll past, but it isn't mobile
   either — its own, intermediate step, not just "the mobile value a bit
   early" or "the desktop value unchanged". */
@media ( max-width: 900px ) {
	:root {
		--section-space: 4.5rem;
		--section-space-tight: 3rem;
	}
}

@media ( max-width: 600px ) {
	:root {
		--section-space: 3.5rem;
		--section-space-tight: 2.5rem;
		--space-inline: 1.25rem;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	:root {
		--motion-fast: 0.001s;
		--motion-slow: 0.001s;
	}
}

/* Base typography */
body {
	margin: 0;
	font-family: var(--font-body);
	font-size: 1rem;
	line-height: 1.65;
	color: var(--text-color);
	background-color: var(--bg-color);
	-webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--font-heading);
	font-weight: 600;
	color: var(--heading-color);
	line-height: 1.15;
	letter-spacing: -0.01em;
}

h2 {
	font-size: clamp( 1.75rem, 1.3rem + 1.6vw, 2.75rem );
}

h3 {
	font-size: 1.375rem;
}

/* Body copy links (post/page content, contact details, etc.) read as
   charcoal — the lighter terracotta accent measures under 4.5:1 as
   running text at body sizes, however legible it is as a button/badge
   fill. Terracotta is reserved for the hover/focus moment, where
   --accent-color-dark still clears the threshold and the underline
   provides a second, non-color cue. */
a {
	color: var(--secondary-color);
	text-decoration-color: currentColor;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
	transition: color var(--motion-fast) var(--ease);
}

a:hover,
a:focus {
	color: var(--accent-color-dark);
	text-decoration: underline;
}

/* Skip-to-content link (visually hidden via .screen-reader-text in
   style.css; this adds the on-focus appearance for keyboard users). */
.skip-link:focus {
	position: absolute;
	top: 0.5rem;
	left: 0.5rem;
	z-index: 100000;
	width: auto;
	height: auto;
	padding: 0.75rem 1.25rem;
	clip: auto;
	background-color: var(--text-color);
	color: #ffffff;
	font-size: 0.875rem;
	text-decoration: none;
}

/* Site chrome — centered, understated, "boutique agency" styling.
   .site-footer's own background (dark Secondary Color, not this warm
   background) is set further down, alongside the rest of its styling —
   not repeated here. */
.site-header {
	background-color: var(--bg-color);
}

.site-footer {
	padding: var(--section-space-tight) var(--space-inline);
	border-top: 1px solid rgba( 255, 255, 255, 0.12 );
}

.site-header {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 1.75rem var(--space-inline);
	border-bottom: 1px solid var(--border-color);
}

/* The Header & Footer Builder plugin's own Header template (see
   cvit_realestate_header_elementor_data()) — a clean, minimal bar with
   the same bottom border as .site-header above, so the transition
   between this theme's own header and that plugin's replacement for it
   isn't visually noticeable. */
.site-header-bar {
	padding: 1.75rem var(--space-inline);
	border-bottom: 1px solid var(--border-color);
}

/* Boxes the header bar's actual content (logo, nav) to the same content
   width as the rest of the site, while letting .site-header-bar's own
   background/border above still reach both edges — same "box the inner
   container, not the section" technique as
   .hero-slideshow-section > .elementor-container elsewhere in this file.
   cvit_realestate_header_elementor_data() deliberately builds this
   section as Elementor's "Full Width" layout (so the bar's background
   and border can be genuinely edge-to-edge); without this, that also
   left the logo and nav pinned flush against the browser's own edges
   instead of lining up with where every other section's boxed content
   starts and ends. */
.site-header-bar > .elementor-container {
	max-width: var(--content-width);
	margin: 0 auto;
}

/* Deliberately unstyled — see .site-main:not(.full-width) below for why
   the box constraint lives there instead of here. */
.site-content {
	display: block;
}

.site-branding {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.site-branding .custom-logo-link img {
	max-height: 60px;
	width: auto;
}

.site-branding .site-title {
	margin: 0;
	font-family: var(--font-heading);
	font-size: 1.5rem;
	letter-spacing: 0.02em;
}

.site-branding .site-title a {
	color: var(--heading-color);
}

#primary-menu {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 0.75rem 2rem;
	list-style: none;
	margin: 0.75rem 0 0;
	padding: 0;
}

/* Mobile hamburger toggle — hidden on desktop; assets/js/mobile-menu.js
   toggles .is-open on .primary-navigation and aria-expanded here. */
.menu-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	gap: 5px;
	width: 2.25rem;
	height: 2.25rem;
	margin-top: 0.5rem;
	padding: 0;
	border: none;
	background: none;
	cursor: pointer;
}

.menu-toggle__bar {
	display: block;
	width: 1.5rem;
	height: 2px;
	background-color: var(--text-color);
	transition: transform 0.25s ease, opacity 0.25s ease;
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(2) {
	transform: translateY( 7px ) rotate( 45deg );
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(3) {
	opacity: 0;
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bar:nth-child(4) {
	transform: translateY( -7px ) rotate( -45deg );
}

@media ( max-width: 768px ) {
	.menu-toggle {
		display: flex;
	}

	.primary-navigation {
		display: none;
		width: 100%;
	}

	.primary-navigation.is-open {
		display: block;
	}

	#primary-menu {
		flex-direction: column;
		align-items: center;
		gap: 1rem;
		margin-top: 1rem;
	}
}

@media ( max-width: 600px ) {
	.site-header {
		padding: 0.875rem var(--space-inline);
	}

	#primary-menu {
		gap: 0.75rem;
	}
}

/* Sticky header — enabled via Appearance > Customize > Header Settings.
   .is-stuck is toggled by assets/js/sticky-header.js once the page has
   scrolled past the header, shrinking padding and adding a shadow so a
   pinned header still reads as "sticky", not just "static in place". */
body.has-sticky-header .site-header {
	position: sticky;
	top: var( --wp-admin--admin-bar--height, 0px );
	z-index: 999;
	transition: padding 0.25s ease, box-shadow 0.25s ease;
}

body.has-sticky-header .site-header.is-stuck {
	padding-top: 0.625rem;
	padding-bottom: 0.625rem;
	box-shadow: 0 2px 16px color-mix( in srgb, var(--secondary-color-dark) 12%, transparent );
}

#primary-menu a {
	position: relative;
	display: inline-block;
	padding-bottom: 0.35rem;
	color: var(--heading-color);
	font-size: 0.75rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	transition: color var(--motion-fast) var(--ease);
}

/* An underline that grows in from the left on hover, rather than an
   instant color/border swap — the kind of quiet, considered detail a
   template's nav usually skips. */
#primary-menu a::after {
	content: '';
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	height: 1px;
	background-color: var(--accent-color);
	transform: scaleX( 0 );
	transform-origin: left;
	transition: transform var(--motion-fast) var(--ease);
}

#primary-menu a:hover,
#primary-menu a:focus {
	color: var(--accent-color-dark);
	text-decoration: none;
}

#primary-menu a:hover::after,
#primary-menu a:focus::after {
	transform: scaleX( 1 );
}

#primary-menu .current-menu-item > a::after {
	transform: scaleX( 1 );
}

/* Dark Secondary-Color band — the same charcoal family as the header/
   nav and the closing CTA band below, rather than a third, lighter
   surface color of its own; white/muted-white text and a terracotta
   hover follow the same pairing used everywhere else a section fills
   with Secondary Color. Holds two things, stacked: the 4-column brand/links/services/
   contact block (.footer-columns, built by
   cvit_realestate_footer_columns_html() — shared with .footer-band
   below) and the copyright/credit bar (.footer-bottom). */
.site-footer {
	background-color: var(--secondary-color-dark);
	color: rgba( 255, 255, 255, 0.7 );
}

.footer-columns {
	display: grid;
	grid-template-columns: 1.3fr 1fr 1fr 1.2fr;
	gap: var(--space-xl);
	max-width: var(--content-width);
	margin: 0 auto;
	padding: var(--section-space-tight) var(--space-inline) var(--space-xl);
	text-align: left;
}

@media ( max-width: 900px ) {
	.footer-columns {
		grid-template-columns: repeat( 2, 1fr );
		row-gap: var(--space-lg);
	}
}

@media ( max-width: 600px ) {
	.footer-columns {
		grid-template-columns: 1fr;
		text-align: center;
	}
}

.footer-brand {
	margin: 0 0 0.75rem;
	color: #ffffff;
	font-family: var(--font-heading);
	font-size: 1.375rem;
}

.footer-tagline {
	max-width: 24rem;
	margin: 0;
	color: rgba( 255, 255, 255, 0.65 );
	font-size: 0.9375rem;
}

@media ( max-width: 600px ) {
	.footer-tagline {
		margin: 0 auto;
	}
}

.footer-column__title {
	margin: 0 0 1.25rem;
	color: #ffffff;
	font-family: var(--font-heading);
	font-size: 1rem;
	font-weight: 600;
}

.footer-links,
.footer-contact {
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer-links li,
.footer-contact li {
	margin-bottom: 0.75rem;
	color: rgba( 255, 255, 255, 0.65 );
	font-size: 0.9375rem;
	line-height: 1.4;
}

.footer-links a,
.footer-contact a {
	color: inherit;
	text-decoration: none;
}

.footer-links a:hover,
.footer-links a:focus,
.footer-contact a:hover,
.footer-contact a:focus {
	color: var(--accent-color);
	text-decoration: underline;
}

/* Copyright/credit bar — a hairline above it separates it from the
   columns block whether it's rendered here (.site-footer, the plain
   fallback) or as a second, visually-adjacent .footer-band section
   (the Header & Footer Builder version — see
   cvit_realestate_footer_elementor_data()), which gets this same
   treatment via its own .footer-bottom-bar rule further down. */
.footer-bottom {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	max-width: var(--content-width);
	margin: 0 auto;
	padding: var(--space-lg) var(--space-inline);
	border-top: 1px solid rgba( 255, 255, 255, 0.12 );
	text-align: left;
}

@media ( max-width: 600px ) {
	.footer-bottom {
		justify-content: center;
		text-align: center;
	}
}

.footer-bottom p {
	margin: 0;
	font-size: 0.875rem;
}

.site-footer__copyright {
	color: #ffffff;
}

.site-footer__copyright a {
	color: #ffffff;
}

.site-footer__credit {
	font-size: 0.6875rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.site-footer__credit a {
	color: rgba( 255, 255, 255, 0.7 );
	text-decoration: underline;
}

.site-footer__credit a:hover,
.site-footer__credit a:focus {
	color: var(--accent-color);
}

/* The theme's page-content box (archive-property.php,
   template-property-archive.php, index.php, taxonomy-property_type.php
   — every template that renders plain content rather than handing the
   page to Elementor). This used to live on the parent .site-content div
   (printed by header.php/footer.php) instead of here, which broke as
   soon as a Header/Footer Builder plugin (Header Footer Elementor /
   Ultimate Addons for Elementor) took over rendering the header and
   footer: that plugin replaces get_header()'s/get_footer()'s entire
   output — including .site-content's opening/closing tags — with its
   own markup, so the box constraint silently disappeared and templates
   like the Property grid rendered full-viewport-width with no padding.
   Living on .site-main instead is resilient to that, since .site-main
   is printed by the template file itself, not by header.php. */
.site-main:not( .full-width ) {
	max-width: var(--content-width);
	margin: 0 auto;
	padding: var(--section-space-tight) var(--space-inline);
}

/* Full-width template wrapper (page.php, single.php, single-property.php,
   front-page.php, 404.php) — so builder content (e.g. Elementor) can
   render edge to edge with no sidebar. Elementor's own "Elementor Full
   Width" page template (assigned to every Page by
   cvit_realestate_default_elementor_template() once it has real
   Elementor content) prints straight into .site-content with no
   .site-main wrapper at all, which is fine now that .site-content
   itself carries no box constraint of its own to undo. */
.site-main.full-width {
	max-width: none;
	margin: 0;
	padding: 0;
}

/* Archive/taxonomy/404 page headers */
.page-header {
	margin: 0 0 var(--space-lg);
}

.page-title {
	margin: 0 0 var(--space-2xs);
}

.taxonomy-description {
	max-width: 65ch;
	color: var(--text-muted-color);
}

/* Default (index.php) post loop */
.entry-title {
	font-size: 1.5rem;
}

.entry-title a {
	color: var(--heading-color);
}

.entry-title a:hover,
.entry-title a:focus {
	color: var(--accent-color-dark);
	text-decoration: none;
}

.post-thumbnail img {
	max-width: 100%;
	height: auto;
}

/* Property archive grid — also used, with the --preview modifier below,
   for the Home page's [cvit_property_preview] shortcode, and by the
   Property Elementor widget (see inc/class-cvit-property-widget.php).
   Each card carries its status/featured badges, price, location, and
   a bed/bath/area meta line — the information a property listing needs
   to be useful at a glance, not just a numbered lookbook tile.

   --property-grid-columns defaults to 3 (this file's own default, used
   everywhere except the Elementor widget) but can be overridden
   per-instance — the widget's own "Columns" control sets it via an
   inline custom property instead of needing a matching set of
   .property-grid--2-col/--4-col etc. modifier classes. */
.property-grid {
	display: grid;
	grid-template-columns: repeat( var( --property-grid-columns, 3 ), 1fr );
	gap: 1.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

@media ( max-width: 768px ) {
	.property-grid {
		/* Falls back to 1 (not the desktop default of 3) so every
		   existing, non-widget use of this grid keeps its current
		   single-column mobile layout unchanged; the widget's own
		   "Columns" control can still override this on mobile too,
		   same as it does on desktop/tablet, since it's the same
		   custom property either way. */
		grid-template-columns: repeat( var( --property-grid-columns, 1 ), 1fr );
	}
}

/* An editorial "featured + two supporting" composition for the Home
   page's preview specifically (always exactly 3 items) — the full
   Property archive above stays a uniform tiled grid, appropriate for
   browsing an arbitrary, unbounded number of listings. Any items beyond
   the first 3 (a site owner passing a larger `count` to the shortcode)
   simply continue in the ordinary 3-column flow below this composition
   — a graceful, non-broken fallback rather than a hard requirement of
   exactly 3. */
@media ( min-width: 769px ) {
	.property-grid--preview {
		grid-template-columns: repeat( 2, 1fr );
	}

	.property-grid--preview .property-grid__item:first-child {
		grid-row: span 2;
		aspect-ratio: 3 / 4;
	}

	.property-grid--preview .property-grid__item:nth-child(2),
	.property-grid--preview .property-grid__item:nth-child(3) {
		aspect-ratio: 16 / 11;
	}
}

.property-grid__item {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	background-color: var(--surface-color);
	color: inherit;
}

.property-grid__item:hover,
.property-grid__item:focus {
	color: inherit;
	text-decoration: none;
}

.property-grid__item img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--motion-slow) var(--ease);
}

/* Elementor's own base stylesheet ships `.elementor img { height: auto; }`,
   which ties in specificity with the rule above and can win by load order
   when this grid is rendered inside an Elementor page (e.g. via the
   [cvit_property_preview] shortcode widget on the Home page) — shrinking
   images to their natural height and leaving empty space in the crop.
   This selector is more specific, so it always wins regardless of load
   order. */
.elementor .property-grid__item img {
	height: 100%;
	object-fit: cover;
}

.property-grid__item:hover img,
.property-grid__item:focus img {
	transform: scale( 1.04 );
}

/* Status/Featured/New badges — always visible (not a hover reveal), top
   left, since a listing's availability is exactly the kind of thing a
   visitor scanning a grid should never have to hover to discover. Small,
   quiet pill chips rather than a loud ribbon, so a card can carry two or
   three at once without looking cluttered. */
.property-grid__badges {
	position: absolute;
	top: 1rem;
	left: 1rem;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.property-grid__badge {
	padding: 0.3rem 0.7rem;
	background-color: color-mix( in srgb, var(--bg-color) 92%, transparent );
	color: var(--heading-color);
	font-family: var(--font-body);
	font-size: 0.6875rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

.property-grid__badge--sale {
	background-color: var(--secondary-color);
	color: #ffffff;
}

.property-grid__badge--rent {
	background-color: var(--accent-color);
	color: var(--on-accent-color);
}

.property-grid__badge--sold {
	background-color: color-mix( in srgb, var(--secondary-color-dark) 88%, transparent );
	color: #ffffff;
}

.property-grid__badge--featured,
.property-grid__badge--new {
	background-color: color-mix( in srgb, var(--bg-color) 92%, transparent );
	color: var(--heading-color);
}

/* A permanent (not hover-only) gradient scrim across the lower third of
   every card, so a listing's price and location are always legible
   against any photo — real-estate browsing depends on that information
   being scannable at a glance, unlike a photography portfolio tile where
   the title is a bonus reveal. The category/title/date/tags elements
   below still exist and read light-on-dark against this same scrim. */
.property-grid__overlay {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 1;
	padding: 2.5rem 1.25rem 1.25rem;
	background-image: linear-gradient(
		180deg,
		color-mix( in srgb, var(--secondary-color-dark) 0%, transparent ),
		color-mix( in srgb, var(--secondary-color-dark) 82%, transparent ) 60%,
		color-mix( in srgb, var(--secondary-color-dark) 90%, transparent )
	);
}

.property-grid__category {
	margin-bottom: 0.4rem;
	/* var(--secondary-color) (charcoal) was nearly invisible here — this
	   sits on the same dark, semi-transparent .property-grid__overlay as
	   .property-grid__title, so it needs the same light-on-dark
	   treatment as that title (white), just visually quieter — same
	   "muted white" convention used for body text on other dark bands
	   (e.g. the closing CTA), rather than a color meant for light
	   backgrounds like the rest of this theme's eyebrow labels. */
	color: rgba( 255, 255, 255, 0.75 );
	font-size: 0.6875rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.15em;
}

.property-grid__title {
	margin: 0 0 0.3rem;
	color: #ffffff;
	font-family: var(--font-heading);
	font-size: 1.125rem;
}

.property-grid__location {
	margin: 0 0 0.6rem;
	color: rgba( 255, 255, 255, 0.75 );
	font-size: 0.8125rem;
}

.property-grid__price {
	display: block;
	margin-bottom: 0.4rem;
	color: #ffffff;
	font-family: var(--font-heading);
	font-size: 1.3125rem;
	font-weight: 600;
}

/* Bed/bath/area summary line — plain typographic separators rather than
   icon glyphs, so it never depends on an icon font being loaded outside
   Elementor (the plain-HTML fallback grid has no such dependency). */
.property-grid__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0 0.6rem;
	color: rgba( 255, 255, 255, 0.88 );
	font-size: 0.8125rem;
	letter-spacing: 0.02em;
}

.property-grid__meta span:not( :last-child )::after {
	content: '\00b7';
	margin-left: 0.6rem;
	color: rgba( 255, 255, 255, 0.5 );
}

/* Optional per-item date/tags — off by default (see
   inc/class-cvit-property-widget.php's "Show Date"/"Show Location"
   controls), styled to sit quietly below the meta line rather than
   compete with it. */
.property-grid__date,
.property-grid__tags {
	display: block;
	margin-top: 0.4rem;
	color: rgba( 255, 255, 255, 0.65 );
	font-size: 0.75rem;
	letter-spacing: 0.03em;
}

/* Pagination */
.pagination {
	display: flex;
	justify-content: center;
	gap: 0.5rem;
	margin: var(--space-xl) 0 0;
	padding: 0;
	list-style: none;
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	height: 2.25rem;
	padding: 0 0.5rem;
	border: 1px solid var(--border-color);
	color: var(--text-color);
	font-size: 0.875rem;
	text-decoration: none;
}

.pagination .page-numbers:hover,
.pagination .page-numbers:focus {
	border-color: var(--accent-color-dark);
	color: var(--accent-color-dark);
	text-decoration: none;
}

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

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

/* Front-page fallback hero slideshow (front-page.php + assets/js/hero-
   slideshow.js) — shown until the front page has been designed in
   Elementor, so the homepage is fully functional and full-width from
   the moment the theme is activated. Full-bleed: front-page.php's
   <main class="site-main full-width"> already carries no box constraint
   (see .site-main.full-width above), so this section reaches both edges
   with no extra work needed here. */
.hero-slideshow {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	/* A fluid ~88vh rather than a fixed vh value: generous and cinematic
	   on most screens, but never so tall it forces scrolling past an
	   almost-empty frame on a short/landscape-phone viewport, and never
	   so tall it towers absurdly on an ultra-wide desktop monitor. */
	min-height: clamp( 32rem, 88vh, 50rem );
	overflow: hidden;
	background-color: var(--text-color);
	text-align: center;
}

.hero-slideshow__slides {
	position: absolute;
	inset: 0;
}

.hero-slideshow__slide {
	position: absolute;
	inset: 0;
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
	opacity: 0;
	transition: opacity 1s ease;
}

.hero-slideshow__slide.is-active {
	opacity: 1;
}

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

.hero-slideshow__content {
	position: relative;
	z-index: 1;
	max-width: var(--content-width-narrow);
	padding: var(--space-lg);
}

.hero-slideshow__title {
	margin: 0 0 1.5rem;
	color: #ffffff;
	font-size: clamp( 2.5rem, 2rem + 3vw, 5rem );
	letter-spacing: -0.02em;
}

.hero-slideshow__subtitle {
	margin: 0 0 2.5rem;
	color: rgba( 255, 255, 255, 0.88 );
	font-family: var(--font-heading);
	font-size: clamp( 1.0625rem, 1rem + 0.3vw, 1.3125rem );
	font-style: italic;
	font-weight: 400;
}

.hero-slideshow__arrow {
	position: absolute;
	top: 50%;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	transform: translateY( -50% );
	border: 1px solid rgba( 255, 255, 255, 0.6 );
	border-radius: 50%;
	background-color: color-mix( in srgb, var(--secondary-color-dark) 45%, transparent );
	color: #ffffff;
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

.hero-slideshow__arrow:hover,
.hero-slideshow__arrow:focus {
	border-color: var(--accent-color);
	background-color: color-mix( in srgb, var(--secondary-color-dark) 70%, transparent );
}

.hero-slideshow__arrow--prev {
	left: 1.5rem;
}

.hero-slideshow__arrow--next {
	right: 1.5rem;
}

.hero-slideshow__dots {
	position: absolute;
	bottom: 1.5rem;
	left: 50%;
	z-index: 2;
	display: flex;
	gap: 0.625rem;
	transform: translateX( -50% );
}

.hero-slideshow__dot {
	width: 0.625rem;
	height: 0.625rem;
	padding: 0;
	border: 1px solid rgba( 255, 255, 255, 0.8 );
	border-radius: 50%;
	background-color: rgba( 255, 255, 255, 0.3 );
	cursor: pointer;
	transition: background-color 0.2s ease, transform 0.2s ease;
}

.hero-slideshow__dot:hover,
.hero-slideshow__dot:focus {
	background-color: rgba( 255, 255, 255, 0.7 );
}

.hero-slideshow__dot.is-active {
	background-color: var(--accent-color);
	border-color: var(--accent-color);
	transform: scale( 1.2 );
}

@media ( max-width: 600px ) {
	.hero-slideshow {
		min-height: 60vh;
	}

	.hero-slideshow__arrow {
		width: 2.25rem;
		height: 2.25rem;
		font-size: 1.25rem;
	}

	.hero-slideshow__arrow--prev {
		left: 0.75rem;
	}

	.hero-slideshow__arrow--next {
		right: 0.75rem;
	}
}

/* Elementor's native hero (cvit_realestate_home_elementor_data(), using
   Elementor's own "Background Slideshow" background type) — this section
   is full_width (edge-to-edge, no boxed side margins), but its text
   content still needs a readable max-width instead of stretching the
   full viewport, matching the fallback hero's .hero-slideshow__content
   above. */
.hero-slideshow-section > .elementor-container > .elementor-column > .elementor-widget-wrap {
	max-width: var(--content-width-narrow);
	margin: 0 auto;
	padding: var(--space-lg);
}

/* Matches .hero-slideshow__title/__subtitle above exactly, so the
   Elementor-built hero and the dependency-free fallback hero it
   replaces read as the same design rather than two different ones. */
.hero-slideshow-section .elementor-heading-title {
	margin: 0 0 1.5rem;
	font-size: clamp( 2.5rem, 2rem + 3vw, 5rem );
	letter-spacing: -0.02em;
	line-height: 1.1;
}

.hero-slideshow-section .elementor-widget-text-editor {
	margin-bottom: 2.5rem;
}

.hero-slideshow-section .elementor-widget-text-editor p {
	font-family: var(--font-heading);
	font-size: clamp( 1.0625rem, 1rem + 0.3vw, 1.3125rem );
	font-style: italic;
}

/* The one consistent button treatment used everywhere on the site: the
   raw-HTML fallback (.btn, below), Elementor's native button widget
   (via cvit_realestate_elementor_button() in functions.php, which binds
   to the same Primary/Secondary Global Color rather than a literal hex
   value), and Contact Form 7's submit button (further down). Sharp
   corners and restrained letter-spacing rather than the heavier, all-
   caps "SIGN UP NOW" treatment a solid-color pill button usually gets —
   deliberately quieter, so it reads as part of the page rather than a
   marketing-template CTA. .btn--secondary is the same in Secondary
   Color, for a page's lower-emphasis CTA; .btn--outline-light is for a
   button placed on a dark/colored background (the closing CTA band, the
   hero), where a solid fill would compete with it. */
.btn {
	display: inline-block;
	padding: 0.875rem 2rem;
	border: 1px solid var(--accent-color);
	background-color: var(--accent-color);
	/* White — clears 4.5:1 against this accent's default shade. See the
	   --on-accent-color note in the :root block. */
	color: var(--on-accent-color);
	font-family: var(--font-body);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.04em;
	transition: background-color var(--motion-fast) var(--ease),
		border-color var(--motion-fast) var(--ease),
		transform var(--motion-fast) var(--ease);
}

.btn:hover,
.btn:focus {
	border-color: var(--accent-color-dark);
	background-color: var(--accent-color-dark);
	color: var(--on-accent-color);
	text-decoration: none;
	transform: translateY( -2px );
}

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

/* White reads clearly against both Secondary Color and its darker
   hover shade, same as .btn's accent fill above. */
.btn--secondary {
	border-color: var(--secondary-color);
	background-color: var(--secondary-color);
	color: #ffffff;
}

.btn--secondary:hover,
.btn--secondary:focus {
	border-color: var(--secondary-color-dark);
	background-color: var(--secondary-color-dark);
	color: #ffffff;
}

.btn--outline-light {
	border-color: rgba( 255, 255, 255, 0.55 );
	background-color: transparent;
	color: #ffffff;
}

.btn--outline-light:hover,
.btn--outline-light:focus {
	border-color: #ffffff;
	background-color: #ffffff;
	color: var(--heading-color);
}

/* Starter-content sections (Home, About Us, Services, Contact Us pages)
   — these live inside page.php's bare, full-width <main>, so unlike the
   hero above they bring their own contained max-width and padding. */
.content-section {
	max-width: var(--content-width);
	margin: 0 auto;
	padding: var(--section-space) var(--space-inline);
}

/* Scroll-reveal fade-up — see assets/js/scroll-reveal.js and
   cvit_realestate_scroll_reveal_class_inline_script() in functions.php
   for why this only ever applies once <html> already carries
   .has-scroll-reveal (added synchronously, before paint): without that
   guard, a visitor without JS — or whose browser lacks
   IntersectionObserver — would never see this content at all. */
html.has-scroll-reveal .content-section,
html.has-scroll-reveal .closing-cta {
	opacity: 0;
	transform: translateY( 24px );
	transition: opacity var(--motion-slow) var(--ease), transform var(--motion-slow) var(--ease);
}

html.has-scroll-reveal .content-section.is-visible,
html.has-scroll-reveal .closing-cta.is-visible {
	opacity: 1;
	transform: translateY( 0 );
}

/* Second, independent safety net for the rule above: forces every
   section visible whenever this theme's own PHP-side check has
   identified an Elementor editor/preview context (see
   cvit_realestate_is_elementor_editing_context() in functions.php),
   regardless of whether `has-scroll-reveal` also ended up on <html> —
   the editor's iframe canvas doesn't reliably generate the scroll
   activity assets/js/scroll-reveal.js's IntersectionObserver needs, so
   without this, every section past the first would stay permanently
   invisible (and unselectable) while editing, even though its content
   is really there and renders correctly on the actual front end. */
body.cvit-elementor-editing .content-section,
body.cvit-elementor-editing .closing-cta {
	opacity: 1 !important;
	transform: none !important;
}

/* When this section is rendered by Elementor (as opposed to the plain
   HTML fallback used when Elementor is inactive), Elementor's own
   widgets already carry their own default vertical spacing — the full
   --section-space above would stack on top of that. Trim it back only
   in that case, but still generously — tight vertical rhythm between
   sections is exactly the "template" feeling a premium editorial
   layout needs to avoid. Responsive at every breakpoint via the token
   itself (see :root) — no separate mobile/tablet override needed here.

   Also resets the max-width/margin the base rule above sets, so this
   section's actual rendered width comes entirely from Elementor's own
   "Content Width" (Boxed/Full Width) setting instead — see
   cvit_realestate_elementor_section()'s docblock in functions.php for
   why: forcing the same boxed width here regardless of that setting
   left it non-functional in the editor (switching Boxed/Full Width
   never visibly changed anything). The base .content-section rule
   above still applies as-is for the plain-HTML fallback rendered when
   Elementor is inactive, which has no such native mechanism of its
   own to defer to. */
.elementor-section.content-section {
	max-width: none;
	margin: 0;
	padding: var(--section-space-tight) var(--space-inline);
}

.content-section h2 {
	margin: 0 0 var(--space-md);
}

/* A heading-only "section header" (eyebrow + h2, no other content) kept
   as its own Elementor section so its content grid below (icon-box/stat
   cards, image-box trio, etc.) stays independently editable — but the
   two are meant to read as ONE section, not two. Left alone, each side's
   own --section-space-tight top+bottom padding stacked into a gap
   roughly double this theme's normal section-to-section rhythm (visibly
   inconsistent next to sections like "Our Story" that keep their
   heading and content together in a single section). This collapses
   that stacked gap down to a single, deliberate one. */
.elementor-section.content-section.content-section--heading {
	padding-bottom: var(--space-lg);
}

.content-section--heading + .elementor-section.content-section {
	padding-top: var(--space-lg);
}

.content-section__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: center;
	gap: 3rem;
}

@media ( max-width: 768px ) {
	.content-section__grid {
		grid-template-columns: 1fr;
	}
}

.content-section__media img {
	display: block;
	width: 100%;
	height: auto;
}

.home-property-preview__cta {
	margin-top: var(--space-lg);
	text-align: center;
}

/* Services grid */
.services-grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 2rem;
}

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

.service-card {
	padding: 2.5rem 2rem;
	border: 1px solid var(--border-color);
	text-align: center;
}

.service-card__index {
	display: block;
	margin-bottom: var(--space-2xs);
	color: var(--accent-color-dark);
	font-family: var(--font-heading);
	font-size: 1.5rem;
}

.service-card h3 {
	margin: 0 0 var(--space-sm);
	font-size: 1.125rem;
}

.service-card p {
	margin: 0;
	color: var(--text-muted-color);
	font-size: 0.9375rem;
}

/* Editorial feature list (Home page, native Elementor version of the
   .service-card trio above — see cvit_realestate_elementor_editorial_feature())
   — a large serif numeral above a left-aligned title and line of text,
   no card border or background, so three of these in a row don't read
   as the same bordered-card grid the Services/About Us pages already
   use elsewhere on the site. */
.editorial-feature {
	text-align: left;
}

.editorial-feature__number .elementor-heading-title {
	margin: 0 0 var(--space-2xs);
	font-size: 2.25rem;
	font-weight: 500;
	line-height: 1;
}

.editorial-feature__title .elementor-heading-title {
	margin: 0 0 var(--space-sm);
	font-size: 1.25rem;
}

/* "By the Numbers" stat cards (About Us page) — 4 across instead of the
   default 3, with a larger, accent-colored number. */
.stats-grid {
	grid-template-columns: repeat( 4, 1fr );
}

@media ( max-width: 768px ) {
	.stats-grid {
		grid-template-columns: repeat( 2, 1fr );
	}
}

.stat-card .elementor-icon-box-title {
	margin-top: 0.5rem;
	font-size: 2rem;
}

.stat-card .elementor-icon-box-description,
.stat-card p {
	color: var(--text-muted-color);
	font-size: 0.9375rem;
}

/* Services page "What's Included" checklist — the fallback rendering
   used when Elementor is inactive (see cvit_realestate_services_page_content()'s
   docblock); the Elementor version uses a real icon-list widget instead
   (see cvit_realestate_elementor_icon_list()), sharing the same
   .inclusions-list css_class so both get this same treatment.

   A 2-column grid rather than one narrow single-file list: 4 short,
   single-line items in one column left a large, obviously-unbalanced
   gap of empty space beside them under the centered heading. Two
   columns of two reads as a deliberately composed block instead. */
.inclusions-list {
	max-width: 44rem;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

ul.inclusions-list,
.inclusions-list .elementor-icon-list-items {
	display: grid;
	grid-template-columns: repeat( 2, 1fr );
	gap: var(--space-md) var(--space-xl);
}

@media ( max-width: 600px ) {
	ul.inclusions-list,
	.inclusions-list .elementor-icon-list-items {
		grid-template-columns: 1fr;
	}
}

/* Tag-qualified (ul.inclusions-list, not any .inclusions-list) so this
   fake checkmark bullet only applies to the plain-HTML fallback's real
   <ul> — the Elementor icon-list widget above already renders its own
   real icon per item; without this qualifier, these rules would also
   match its <li> items (it's a nested descendant of the same class)
   and draw a second, conflicting checkmark next to Elementor's own. */
ul.inclusions-list li {
	position: relative;
	padding-left: 1.75rem;
	color: var(--text-color);
}

ul.inclusions-list li::before {
	content: '\2713';
	position: absolute;
	left: 0;
	color: var(--accent-color-dark);
	font-weight: 700;
}

/* The Elementor icon-list widget's own real icon+text, sized and
   spaced to match the fallback's checkmark treatment above. */
.inclusions-list .elementor-icon-list-icon {
	margin-right: var(--space-2xs);
	font-size: 0.875rem;
}

.inclusions-list .elementor-icon-list-text {
	color: var(--text-color);
}

/* Services page FAQ — shared visual language between the Elementor
   Accordion widget (.services-faq, see
   cvit_realestate_services_elementor_data()) and the plain-HTML
   fallback's native <details>/<summary> (.faq-list, see
   cvit_realestate_services_page_content()): a quiet, bordered list
   rather than a bordered/padded "card" accordion, in keeping with the
   rest of this theme's restrained component language. Scoped to
   .services-faq (rather than a bare .elementor-accordion-item) since a
   site owner could add a second, unrelated Accordion widget elsewhere
   that shouldn't automatically pick up this exact treatment. */
.services-faq .elementor-accordion-item,
.faq-list__item {
	border-bottom: 1px solid var(--border-color);
}

.services-faq .elementor-accordion-item:first-child,
.faq-list__item:first-child {
	border-top: 1px solid var(--border-color);
}

.services-faq .elementor-tab-title,
.faq-list__question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	padding: var(--space-md) var(--space-inline);
	cursor: pointer;
}

/* The Accordion widget always renders its icon <span> before the title
   <a> in markup, regardless of the widget's own "Icon Position" setting
   (that setting only changes the CSS class suffix, not DOM order) — so
   without this, space-between above pushes the icon to the left edge
   and the question text all the way to the right. Flex `order` puts
   the question on the left and the icon on the right, the more
   familiar reading order for a question list — matching the fallback's
   <summary>, where the text naturally comes before its own ::after
   icon already. */
.services-faq .elementor-accordion-title {
	order: 1;
}

.faq-list__question {
	list-style: none;
}

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

.services-faq .elementor-accordion-title,
.faq-list__question {
	color: var(--heading-color);
	font-family: var(--font-heading);
	font-size: 1.125rem;
	font-weight: 500;
	text-decoration: none;
	transition: color var(--motion-fast) var(--ease);
}

.services-faq .elementor-tab-title:hover .elementor-accordion-title,
.services-faq .elementor-tab-title.elementor-active .elementor-accordion-title,
.faq-list__item:hover .faq-list__question,
.faq-list__item[open] .faq-list__question {
	color: var(--accent-color-dark);
}

.services-faq .elementor-accordion-icon {
	order: 2;
	flex-shrink: 0;
	color: var(--accent-color-dark);
	font-size: 0.875rem;
}

/* The fallback's own hand-rolled plus/minus, matching the Elementor
   widget's default icon pair — a "+" that rotates into a "×" when
   open, rather than relying on the browser's own disclosure triangle. */
.faq-list__question::after {
	content: '+';
	flex-shrink: 0;
	color: var(--accent-color-dark);
	font-size: 1.25rem;
	font-weight: 400;
	line-height: 1;
	transition: transform var(--motion-fast) var(--ease);
}

.faq-list__item[open] .faq-list__question::after {
	transform: rotate( 45deg );
}

.services-faq .elementor-tab-content,
.faq-list__answer {
	padding: var(--space-md) var(--space-inline);
	color: var(--text-muted-color);
}

.services-faq .elementor-tab-content p,
.faq-list__answer p {
	margin: 0;
}

/* Contact Us page — two-column layout: business details on one side,
   the form on the other (see cvit_realestate_contact_page_content()
   and cvit_realestate_contact_elementor_data()). Top-aligned rather
   than centered like .content-section__grid's image+text rows
   elsewhere, since the form column is usually taller than the details
   column and centering would leave that column floating oddly midway
   down the (taller) form beside it. */
.contact-columns {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: start;
	gap: var(--space-xl);
}

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

/* The plain-HTML fallback's own contact-details list — the Elementor
   icon-list version below reuses cvit_realestate_elementor_icon_list()'s
   own markup/styling instead, since it's a completely different widget. */
.contact-details {
	margin: 0 0 var(--space-lg);
	padding: 0;
	list-style: none;
}

.contact-details li {
	position: relative;
	margin-bottom: var(--space-sm);
	padding-left: 1.5rem;
	color: var(--text-color);
}

.contact-details li::before {
	content: '\2014';
	position: absolute;
	left: 0;
	color: var(--accent-color-dark);
}

.contact-details a {
	color: inherit;
	text-decoration: none;
}

.contact-details a:hover,
.contact-details a:focus {
	color: var(--accent-color-dark);
}

.contact-details-list .elementor-icon-list-item {
	margin-bottom: var(--space-sm);
}

.contact-details-list .elementor-icon-list-text {
	color: var(--text-color);
}

.contact-social-icons {
	margin-top: var(--space-lg);
}

.contact-fallback {
	padding: 1.5rem;
	background-color: var(--surface-color);
	border: 1px solid var(--border-color);
}

/* No color override here — its link inherits the sitewide `a` color
   (charcoal, terracotta on hover) like every other link on the site,
   rather than quietly picking its own. */

/* Contact Form 7 default markup, restyled to match the theme. */
.wpcf7-form input[type="text"],
.wpcf7-form input[type="email"],
.wpcf7-form input[type="tel"],
.wpcf7-form textarea {
	box-sizing: border-box;
	width: 100%;
	margin-bottom: 1rem;
	padding: 0.75rem 1rem;
	border: 1px solid var(--border-color);
	font-family: var(--font-body);
	font-size: 1rem;
}

.wpcf7-form input[type="submit"] {
	padding: 0.875rem 2.25rem;
	border: 1px solid var(--accent-color);
	background-color: var(--accent-color);
	color: var(--on-accent-color);
	font-size: 0.8125rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	cursor: pointer;
	transition: background-color 0.3s ease, border-color 0.3s ease;
}

.wpcf7-form input[type="submit"]:hover,
.wpcf7-form input[type="submit"]:focus {
	border-color: var(--accent-color-dark);
	background-color: var(--accent-color-dark);
	color: var(--on-accent-color);
}

/* Icon-box cards (Home page "Welcome" feature trio) — reuses the
   .service-card border/padding treatment already defined above for the
   Services page, so both look like the same card component. */
.service-card {
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.service-card:hover {
	transform: translateY( -4px );
	box-shadow: 0 8px 24px color-mix( in srgb, var(--secondary-color-dark) 12%, transparent );
}

.service-card .elementor-icon-box-title {
	margin-top: 0.75rem;
}

/* Image-box "cards" (Services preview) — deliberately not a bordered,
   padded card: the photo runs full-bleed to the column's edges, with
   the caption sitting quietly underneath, closer to a gallery wall
   label than a stock-template feature card. */
.elementor-image-box-img {
	overflow: hidden;
}

.elementor-image-box-img img {
	transition: transform var(--motion-slow) var(--ease);
}

.elementor-image-box-title {
	margin-top: 1.25rem;
}

.elementor-image-box-description {
	margin-top: 0.375rem;
}

/* Crop every card's photo to the same height regardless of its natural
   aspect ratio (portrait vs. landscape source photos otherwise produce
   visibly uneven card heights in the same row). Prefixed with .elementor
   for the same reason as the property-grid rule above: it ties in
   specificity with Elementor's own `.elementor img { height: auto; }`
   default, and needs to win regardless of stylesheet load order. */
.elementor .elementor-image-box-img img {
	width: 100%;
	height: 300px;
	object-fit: cover;
}

.elementor-widget-image-box:hover .elementor-image-box-img img {
	transform: scale( 1.03 );
}

.elementor-image-box-title a {
	transition: color var(--motion-fast) var(--ease);
}

.elementor-image-box-title a:hover,
.elementor-image-box-title a:focus {
	color: var(--accent-color-dark);
	text-decoration: none;
}

/* Elementor's native button widget (every "View Property" / "Get in
   Touch" / etc. CTA built by cvit_realestate_elementor_button() — the
   one actually rendered site-wide; .btn/.btn--secondary above are only
   for the raw-HTML content shown before Elementor is installed) ships
   Elementor's own 3px corner rounding and defaults, not this theme's
   own — brought in line with .btn's sharp-cornered, quietly-tracked,
   lift-on-hover treatment here. `a.elementor-button` (a class plus the
   element itself) is deliberately more specific than both Elementor's
   own bare `.elementor-button` rule and the global `a:hover` rule
   above, so this wins regardless of stylesheet load order. */
a.elementor-button {
	border-radius: 0;
	letter-spacing: 0.04em;
	transition: background-color var(--motion-fast) var(--ease),
		border-color var(--motion-fast) var(--ease),
		transform var(--motion-fast) var(--ease);
}

a.elementor-button:hover,
a.elementor-button:focus {
	text-decoration: none;
	transform: translateY( -2px );
}

a.elementor-button:active {
	transform: translateY( 0 );
}

.elementor-icon-list-items {
	justify-content: center;
}

/* The plain-HTML fallback's closing CTA (About Us/Services pages, shown
   before Elementor is active — see cvit_realestate_about_page_content()/
   cvit_realestate_services_page_content()) — same dark Secondary-Color
   band, white heading/text, as .closing-cta below, so a visitor sees
   the same component whether or not the page has been designed in
   Elementor yet. Needs its own heading/paragraph color here since
   .content-section h2 (dark Heading Color) would otherwise be
   unreadable against this dark background. */
.cta-band {
	background-color: var(--secondary-color-dark);
	text-align: center;
}

.cta-band h2 {
	color: #ffffff;
}

.cta-band p {
	color: rgba( 255, 255, 255, 0.85 );
}

.cta-band .elementor-icon-list-item {
	font-weight: 600;
}

/* The Header & Footer Builder plugin's own Footer template (see
   cvit_realestate_footer_elementor_data()) — two stacked sections
   sharing this same dark Secondary-Color band (matching .site-footer's
   own): the brand/links/services/contact columns (built the same way
   as the plain fallback's — see cvit_realestate_footer_columns_html(),
   embedded here via a text-editor widget) and, directly below it, the
   copyright/credit bar (.footer-bottom-bar). No padding/border of its
   own — .footer-columns below already carries its own padding, and
   .footer-bottom-bar carries the hairline + its own tighter padding —
   so the two sections read as one continuous band, not two competing
   ones. */
.footer-band {
	background-color: var(--secondary-color-dark);
}

/* The bottom bar (copyright + "Designed by" credit) — a hairline above
   it separates it from the columns section directly above, the same
   way .footer-bottom does for the plain-HTML fallback. */
.footer-bottom-bar {
	padding: var(--space-lg) var(--space-inline);
	border-top: 1px solid rgba( 255, 255, 255, 0.12 );
	text-align: center;
}

.footer-bottom-bar .elementor-widget-copyright {
	margin-bottom: 1.25rem;
	color: #ffffff;
}

.footer-bottom-bar .hfe-copyright-wrapper,
.footer-bottom-bar .elementor-widget-text-editor p {
	color: rgba( 255, 255, 255, 0.7 );
	font-size: 0.875rem;
}

.footer-bottom-bar .elementor-widget-text-editor p {
	font-size: 0.6875rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.footer-band a:hover,
.footer-band a:focus {
	color: var(--accent-color);
}

/* Home/About Us/Services closing CTA (see
   cvit_realestate_elementor_closing_cta()) — full-bleed, dark Secondary-
   Color band with white text, for a bolder, more deliberate page
   conclusion than any plain light section elsewhere on the site. */
.closing-cta {
	padding: var(--section-space-tight) var(--space-inline);
	text-align: center;
}

/* Centers the standalone "View All Services" button section. */
.services-cta {
	padding-top: 0;
	text-align: center;
}

/* Small uppercase label above a section heading (e.g. "Our Story" above
   "Welcome") — an Elementor heading widget with header_size 'p'. Quiet
   and wide-tracked rather than heavy/bold, with generous room below it
   before the heading starts — the kind of restrained editorial label a
   template's "eyebrow" text usually isn't given room to be. */
.section-eyebrow .elementor-heading-title {
	margin: 0 0 var(--space-xs);
	color: var(--secondary-color);
	font-family: var(--font-body);
	font-size: 0.75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.22em;
}

/* Image half of a 2-column "image + text" section (Home's "Welcome",
   About Us's "Our Story" and "Meet Our Founder") — capped and cropped to
   a fixed height so a tall source photo can't dictate the row height
   and dwarf the (usually much shorter) text column beside it. Prefixed
   with .elementor for the same specificity reason as the property-grid/
   image-box rules above: it needs to beat Elementor's own `.elementor
   img { height: auto; }` regardless of stylesheet load order. */
.elementor .split-section-image img {
	display: block;
	width: 100%;
	height: clamp( 22rem, 20rem + 8vw, 34rem );
	object-fit: cover;
}

/* Single Property listing fallback header/hero (single-property.php) —
   shown only for a listing that hasn't been designed in Elementor. */
.property-item-header {
	padding-bottom: 1rem;
}

.property-item-hero img {
	display: block;
	width: 100%;
	max-height: 70vh;
	object-fit: cover;
}

/* Native Elementor hero image on a Property listing's single page (see
   cvit_realestate_sample_property_elementor_data()). Same
   .elementor-prefix specificity reasoning as split-section-image above. */
.elementor .property-item-hero-image img {
	display: block;
	width: 100%;
	max-height: 70vh;
	object-fit: cover;
}

/* Plain-HTML fallback's key-facts list on a single Property page (price,
   status, bedrooms, bathrooms, area, address) — the Elementor version
   uses the same icon-list widget/treatment as the Contact page's
   details list (.contact-details-list) instead. A quiet, single-column
   list rather than a card grid, so it reads as a fact sheet, not
   another set of stat cards competing with "By the Numbers" elsewhere
   on the site. */
.property-details {
	margin: 0 0 var(--space-lg);
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--border-color);
}

.property-details li {
	display: flex;
	justify-content: space-between;
	gap: var(--space-md);
	padding: var(--space-sm) 0;
	border-bottom: 1px solid var(--border-color);
	color: var(--text-color);
}

.property-details li strong {
	color: var(--text-muted-color);
	font-weight: 500;
}

.property-details .property-details__price {
	color: var(--accent-color-dark);
	font-family: var(--font-heading);
	font-size: 1.25rem;
	font-weight: 600;
}

/* Additional-photos gallery on a single Property listing's page — see
   cvit_realestate_sample_property_content() (the plain-HTML fallback, a
   simple <div> grid) and cvit_realestate_sample_property_elementor_data()
   (Elementor's Basic Gallery widget, which renders WordPress core's
   classic [gallery] shortcode markup nested two levels deep instead —
   .gallery > .gallery-item — hence the extra rules below it). Both get
   square-cropped tiles, matching .property-grid__item's treatment
   elsewhere, instead of each photo's natural (here, inconsistently
   mixed portrait/landscape) aspect ratio, which would otherwise leave
   a jagged row of uneven heights. */
.property-item-gallery {
	margin: var(--space-lg) 0;
}

.property-item-gallery,
.property-item-gallery .gallery {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 1.5rem;
}

@media ( max-width: 600px ) {
	.property-item-gallery,
	.property-item-gallery .gallery {
		grid-template-columns: repeat( 2, 1fr );
	}
}

/* Elementor's own widget-image-gallery.min.css sets
   `.elementor-image-gallery .gallery-columns-3 .gallery-item` (3
   classes) to inline-block + max-width: 33.33% at this same
   min-width: 768px breakpoint — higher specificity than a plain
   `.property-item-gallery .gallery-item`, so it would otherwise keep
   winning regardless of source order. !important here is deliberately
   overriding that specific, narrowly-scoped ruleset, not a general
   shortcut. */
.property-item-gallery .gallery-item {
	display: block !important;
	max-width: none !important;
	width: 100% !important;
	margin: 0 !important;
}

.property-item-gallery__item img,
.property-item-gallery .gallery-item img {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

/* Agent/team cards (About Us page "Meet Our Agents") — a photo, name,
   role, and short bio line per card. Shares .service-card's border and
   hover lift so it reads as the same component family as the rest of
   the site's 3-column grids, rather than a one-off new card style. */
.agent-grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 2rem;
}

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

.agent-card {
	overflow: hidden;
	border: 1px solid var(--border-color);
	text-align: center;
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.agent-card:hover {
	transform: translateY( -4px );
	box-shadow: 0 8px 24px color-mix( in srgb, var(--secondary-color-dark) 12%, transparent );
}

.agent-card__photo {
	overflow: hidden;
}

.agent-card__photo img,
.elementor .agent-card__photo img {
	display: block;
	width: 100%;
	height: 20rem;
	object-fit: cover;
	transition: transform var(--motion-slow) var(--ease);
}

.agent-card:hover .agent-card__photo img {
	transform: scale( 1.04 );
}

.agent-card__body {
	padding: 1.75rem 1.5rem 2rem;
}

.agent-card__name {
	margin: 0 0 0.2rem;
	font-size: 1.125rem;
}

.agent-card__role {
	display: block;
	margin-bottom: 0.75rem;
	color: var(--accent-color-dark);
	font-size: 0.75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
}

.agent-card__bio {
	margin: 0;
	color: var(--text-muted-color);
	font-size: 0.9375rem;
}

/* Client testimonials (Home page) — a quote mark, the testimonial copy,
   then a small photo/name/context byline, on a white card so it lifts
   slightly off the page's warm background. Bordered like .service-card
   rather than a heavier "review card" treatment (star ratings, shadowed
   boxes), keeping it in the same restrained editorial language as the
   rest of the site. */
.testimonial-grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: 2rem;
}

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

.testimonial-card {
	display: flex;
	flex-direction: column;
	padding: 2.25rem 2rem;
	background-color: #ffffff;
	border: 1px solid var(--border-color);
}

.testimonial-card__quote {
	flex-grow: 1;
	margin: 0 0 1.5rem;
	color: var(--text-color);
	font-family: var(--font-heading);
	font-size: 1.0625rem;
	font-style: italic;
	line-height: 1.5;
}

/* A small, quiet terracotta accent on the quote marks — restrained
   enough not to compete with the property photography, but enough to
   keep it reading as the site's one recurring accent even in a section
   with no button. */
.testimonial-card__quote::before,
.testimonial-card__quote::after {
	color: var(--accent-color-dark);
}

.testimonial-card__quote::before {
	content: '\201C';
}

.testimonial-card__quote::after {
	content: '\201D';
}

.testimonial-card__byline {
	display: flex;
	align-items: center;
	gap: 0.875rem;
}

.testimonial-card__photo,
.elementor .testimonial-card__photo {
	flex-shrink: 0;
	width: 3rem;
	height: 3rem;
	overflow: hidden;
	border: 1px solid var(--accent-color);
	border-radius: 50%;
}

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

.testimonial-card__name {
	display: block;
	color: var(--heading-color);
	font-size: 0.9375rem;
	font-weight: 600;
}

.testimonial-card__context {
	display: block;
	color: var(--text-muted-color);
	font-size: 0.8125rem;
}
