/* ==========================================================================
   HAWEHUIS — main stylesheet
   Custom classes prefixed hw-. Plain CSS, no preprocessor.
   ========================================================================== */

.hw-page {
	/* Ultra-premium palette pass (2026-07-20, per client-supplied ChatGPT
	   design brief) — warmed down from the original brighter cream/navy. */
	--hw-navy: #0c2238;
	--hw-navy-deep: #071829;
	--hw-gold: #daaf5a;
	--hw-gold-light: #e9c988;
	/* Darkened, same-hue gold for text sitting directly on --hw-cream —
	   the base --hw-gold computes to ~1.8:1 there (fine over the hero's
	   dark photo overlay or the navy bands, where it's also used, but
	   fails badly on flat cream). Verified via WCAG relative-luminance
	   math: ~4.95:1 against --hw-cream, comfortably clears 4.5:1. Only
	   for on-cream contexts (welcome/units kickers, tagline outline
	   button) — leave --hw-gold everywhere else. */
	--hw-gold-ink: #7c6433;
	--hw-cream: #f4f0e8;
	--hw-cream-light: #faf7f1;
	--hw-white: #ffffff;
	--hw-text: #26313b;
	/* Was #68727b (~4.32:1 on cream, just under the 4.5:1 AA floor for
	   body text) — darkened slightly. Verified: ~5.0:1 on --hw-cream. */
	--hw-text-light: #5d6870;
	--hw-border: #e0d9cb;
	/* One deliberate, single-use accent (2026-07-20) — the real red
	   harbour beacon light the "Welcome to Die Hawehuis" copy already
	   describes, given an actual visual presence instead of only being
	   told in text. Used nowhere else on the page on purpose; see
	   .hw-beacon-mark. */
	--hw-beacon: #c84a3a;
	--hw-radius: 16px;
	--hw-radius-sm: 10px;
	--hw-shadow: 0 20px 50px rgba(7, 24, 41, 0.18);
	--hw-shadow-sm: 0 8px 24px rgba(7, 24, 41, 0.12);

	/* Type scale — significantly larger than the original build, with a
	   controlled hierarchy (hero / section / medium) rather than
	   indiscriminately enlarging everything. The design brief suggested
	   clamp(4.2rem,7vw,7.5rem) for the hero; the 6.2rem max tried first
	   (2026-07-19/20) still wrapped to 4 lines on real desktop screenshots
	   (measured live 2026-07-20: broke past 2 lines above ~95px, and the
	   safe ceiling drops further on ultra-wide viewports as .hw-hero-content's
	   vw-based side padding eats more of its 700px max-width — see the
	   padding fix on .hw-hero-content below). 5.25rem (84px) is the verified
	   safe max — holds at exactly 2 lines from 1024px through 2560px+,
	   confirmed via live line-count measurement, not guessed. */
	--hw-size-hero: clamp(3rem, 6vw, 5.25rem);
	--hw-size-section: clamp(2.4rem, 4.5vw, 3.6rem);
	/* Was clamp(1.7rem,3vw,2.4rem), bumped once to clamp(2.1rem,3.6vw,3rem)
	   2026-07-20 — still read as too small against a real screenshot
	   ("Die Hawehuis" and other section headings), so pushed further
	   rather than nudging again. */
	--hw-size-medium: clamp(2.6rem, 4.5vw, 3.8rem);

	font-family: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	font-size: 16px;
	color: var(--hw-text);
	background: var(--hw-cream);
	line-height: 1.65;
	/* .hw-tagline-split's full-bleed photo breakout (below) uses 100vw,
	   which on any browser with a reserved-space scrollbar (most desktop
	   Windows browsers) is a few pixels wider than the true visible
	   viewport — confirmed live 2026-07-20: caused real horizontal
	   overflow, not just a cosmetic sliver. This is the standard,
	   low-risk fix rather than JS-measuring scrollbar width; nothing on
	   this page relies on intentional horizontal scroll. */
	overflow-x: hidden;

	/*
	 * WordPress's "flow" layout support injects margin-block-start on every
	 * non-first child of a wp:group (via a uniquely-generated per-block
	 * selector reading this variable — see wp-includes/block-supports/
	 * layout.php) regardless of any custom display:flex/grid set on that
	 * same element. That's what was pushing the 2nd+ item in every custom
	 * row (feature items, unit cards, amenities, gallery strip) down by
	 * ~19px relative to the 1st. Zeroing it here kills that injection
	 * sitewide — all spacing in this file is handled explicitly via gap/
	 * padding/margin already, none of it relies on WP's automatic spacing.
	 */
	--wp--style--block-gap: 0px;
}

.hw-page * {
	box-sizing: border-box;
}

/* :where() keeps these resets at zero specificity so any single-class
   component override (e.g. .hw-hero-title, .hw-booking-note) always wins
   regardless of source order — avoids the override-chain bugs Knusrus's
   CSS accumulated. */
:where(.hw-page h1, .hw-page h2, .hw-page h3, .hw-page h4) {
	font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
	font-weight: 500;
	line-height: 1.1;
	letter-spacing: -0.01em;
	margin: 0;
	color: var(--hw-navy);
}

:where(.hw-page p) {
	margin: 0;
}

.hw-page a {
	color: inherit;
	text-decoration: none;
}

.hw-page ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.hw-page img {
	max-width: 100%;
	display: block;
}

.hw-icon {
	width: 26px;
	height: 26px;
	flex-shrink: 0;
	color: var(--hw-gold);
}

.hw-kicker {
	font-size: 0.68rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--hw-gold);
	font-weight: 600;
	margin-bottom: 0.85rem;
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
}

/* Fine gold divider line after eyebrow labels — restrained decorative
   detail per the luxury design brief, used instead of gold surfaces. */
.hw-kicker::after {
	content: "";
	display: inline-block;
	width: 28px;
	height: 1px;
	background: var(--hw-gold);
	opacity: 0.7;
}

.hw-section {
	/* Was clamp(5rem,9vw,9rem), then clamp(3.5rem,6.5vw,6.5rem) — still
	   read as "drowning in open space" against a real screenshot
	   (2026-07-20 second pass): measured live, #units alone was 1008px
	   tall with ~187px of that being pure top+bottom section padding, one
	   of nine sections stacking the same amount. Cut further — still real
	   separation between sections, not cramped, but the padding no longer
	   out-weighs the content it's separating. */
	padding: clamp(2.75rem, 5vw, 5rem) 6vw;
	max-width: 1440px;
	margin: 0 auto;
}

/* Welcome/beacon section reads as having extra open space above and below
   even after the general .hw-section trim above (2026-07-23, user request)
   — cut further just here rather than shrinking every section again. */
.hw-welcome-section {
	padding-top: clamp(1.5rem, 3vw, 2.5rem);
	padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

/* Full-bleed navy sections (amenities strip, distances, testimonial) use
   this instead of .hw-section directly, then constrain an inner wrapper —
   lets the background run edge to edge while content stays contained. */
.hw-band {
	padding: clamp(2.75rem, 4.5vw, 4.5rem) 6vw;
}

.hw-band-inner {
	max-width: 1440px;
	margin: 0 auto;
}

/*
 * WordPress's "flow" layout support also injects a literal (not
 * var(--wp--style--block-gap)) margin-block-start on every non-first child
 * of a wp:group, via a uniquely-generated per-block selector — see
 * wp-includes/block-supports/layout.php's wp_get_layout_style(). That
 * doesn't respond to the --wp--style--block-gap:0 reset above since it
 * isn't reading that variable at all. !important is the reliable way to
 * beat a rule that's regenerated fresh per block instance. Every custom
 * flex/grid row in this file needs this, not just the ones below — add a
 * new row here whenever a new one gets built, or its 2nd+ item will drift
 * down by ~19px exactly like the bug this fixes.
 *
 * .hw-booking-bar-wrap is excluded from the .hw-page > * reset below —
 * this same "block-gap" !important was silently canceling its own
 * -5.5rem overlap margin (see BOOKING BAR below), since margin-top and
 * margin-block-start resolve to the same physical property here. That
 * killed the whole "glass panel floats over the hero" effect without
 * any visual error — caught 2026-07-20 via critique, not by eye, since
 * this project's .local origin blocks screenshot-based review. Any
 * future top-level section that also needs a deliberate negative
 * margin-top must get the same :not() exclusion, or add its offset via
 * transform/top instead of margin so this can't recur a 4th time.
 */
.hw-page > *:not(.hw-booking-bar-wrap),
.hw-logo-wrap > *,
.hw-logo-mark-row > *,
.hw-feature-row > *,
.hw-unit-grid > *,
.hw-amenities-row > *,
.hw-distance-row > *,
.hw-gallery-strip > *,
.hw-tagline-split > *:not(.hw-tagline-content),
.hw-testimonial-inner > *,
.hw-footer-inner > *,
.hw-welcome-title-row > *,
.hw-welcome > *,
.hw-page-hero-stats > *,
.hw-unit-deepdive > *,
.hw-unit-deepdive-intro > *,
.hw-unit-gallery > *,
.hw-experience-feature__content > *,
.hw-experience-editorial-grid > *,
.hw-experience-editorial__body > *,
.hw-experience-mini-grid > *,
.hw-experience-mini-card > *,
.hw-explore-grid > *,
.hw-explore-card > *,
.hw-pill-row > *,
.hw-film-intro > *,
.hw-film-split > *,
.hw-gallery-intro > *,
.hw-area-map-split > *,
.hw-area-info-panel > *,
.hw-message-split > *,
.hw-contact-cta-card > *,
.hw-gallery-grid > * {
	margin-block-start: 0 !important;
}

/* -------------------------------------------------------------------------
   LIQUID GLASS — originally ported verbatim from Knusrus's "TRUE EDGE-LIT
   LIQUID GLASS" mixin (above-beyond-global-motion.css's sibling,
   knusrus_landing_page_css.css) at the user's explicit request, replacing
   the earlier lightened/flattened adaptation — see Known issues for why
   that adaptation existed and was superseded 2026-07-20. Shared here:
   border/box-shadow edge-lighting and the ::before/::after pseudo-overlays
   below, still identical across all three. The background tint and
   backdrop-filter strength diverged 2026-07-20 (see the two rule blocks
   right after this one) once it became clear the booking bar's photo
   backdrop and the unit-card/footer-cta flat-color backdrops needed
   different amounts of tint to both read as glass — the nav bar and hero
   button still use their own separate Knusrus-ported recipes further
   below (smart-header shell / V10 definitive glass button).
   ------------------------------------------------------------------------- */
.hw-booking-bar,
.hw-unit-card {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	color: #fff;
	/* Border + inset highlights + top-edge sheen (::before below) all
	   boosted past the literal Knusrus numbers (2026-07-20, second pass —
	   the blur read visibly after the first amplification, but the panel
	   still looked flat rather than glassy: blur alone isn't what sells
	   "glass," the edge-lit highlights are, and at 1px/thin-opacity they
	   were too subtle to read at normal viewing scale). Dominant
	   background tint below is still untouched. */
	border: 1px solid rgba(255, 255, 255, 0.26);
	border-radius: var(--hw-radius);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.78),
		inset 1px 0 0 rgba(255, 255, 255, 0.45),
		inset 0 -1px 0 rgba(255, 255, 255, 0.16),
		inset -1px 0 0 rgba(255, 255, 255, 0.11),
		inset 0 0 34px rgba(255, 255, 255, 0.05),
		0 28px 70px rgba(0, 0, 0, 0.34);
	transition: border-color 0.5s ease, box-shadow 0.5s cubic-bezier(0.25, 1, 0.5, 1);
}

/* .hw-unit-card keeps the original ported tint — it sits over flat cream,
   not the hero photo, so a lighter tint (see .hw-booking-bar below) would
   just look washed out rather than glassy; the user explicitly asked to
   leave .hw-unit-card's glass as-is 2026-07-20. This is where the "exact
   port" background/backdrop-filter values still live. (.hw-footer-cta,
   which used to share this rule, was removed 2026-07-23 along with the
   footer's "Check Availability" box.) */
.hw-unit-card {
	/* Dominant tint darkened from .54/.48/.62 (2026-07-23) — measured via
	   WCAG contrast math: the old tint composited over this card's cream
	   backdrop landed around L~0.18, which put both the gold meta line and
	   the 72%-opacity body copy below 4.5:1. Still translucent, not
	   opaque — paired with the text-color changes below rather than
	   pushed all the way to solid. */
	/* Dominant tint recolored from near-black neutral to --hw-navy's own rgb
	   values (2026-07-23, user request: unit cards should share the navbar/
	   "Die Hawehuis" heading color) — same alphas as before, only the hue
	   changed, so the earlier contrast-fix pass above is untouched. */
	/* backdrop-filter deliberately REMOVED here (2026-07-31) — this was the
	   real cause of the scroll stutter over these panels, and removing it is
	   visually lossless rather than a quality trade-off. These panels sit on
	   a flat solid colour: .hw-page sets `background: var(--hw-cream)` and
	   .hw-section sets no background of its own, so the entire backdrop
	   behind every .hw-unit-card (including .hw-area-info-panel on Area
	   Guide and .hw-contact-cta-card on Contact) is uniform #f4f0e8.
	   Blurring a uniform colour returns that same uniform colour, so
	   blur(20px) rendered nothing at all here — it only forced the browser
	   to re-rasterise the whole panel's backdrop every scroll frame, which
	   is why the worst offender was .hw-area-info-panel (the ~12-row
	   distances list, by far the tallest of these panels, so the most
	   pixels to reprocess per frame — matching the "especially the one on
	   the area guide page" report). saturate(150%) was likewise a no-op on
	   a near-neutral cream.

	   Only the brightness(0.92) had a visible effect, and that is preserved
	   exactly by folding it into the tint below instead: the navy alphas
	   went .74/.70/.82 -> .767/.727/.845, solved algebraically so the panel
	   composites to the same final RGB over #f4f0e8 that it did with the
	   filter applied (e.g. midpoint: .70 over brightness-dimmed cream gave
	   rgb(72,83,93); .727 over raw cream gives the same). The documented
	   WCAG contrast work on the text inside these cards is therefore
	   unchanged — if anything a hair darker, which is the safe direction.

	   .hw-booking-bar keeps its own backdrop-filter (see below): that one
	   genuinely overlaps the hero photograph, where there is real texture
	   to blur. Same for .hw-header. */
	background:
		radial-gradient(105% 36% at 50% -8%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0.08) 31%, transparent 61%),
		radial-gradient(48% 120% at -6% 45%, rgba(255, 255, 255, 0.105) 0%, transparent 68%),
		linear-gradient(145deg, rgba(12, 34, 56, 0.767) 0%, rgba(7, 24, 41, 0.727) 48%, rgba(5, 17, 29, 0.845) 100%);
}

/* .hw-booking-bar's dominant tint cut nearly in half vs. .hw-unit-card
   above (2026-07-20, third pass on this component specifically) — this is
   the actual reason its blur kept reading as weak across two prior rounds
   of radius/brightness-only tweaks: at .54/.48/.62 opacity, that gradient
   alone supplied most of the panel's visible color, so no amount of blur
   radius could make more of the backdrop show through it. A real
   departure from the literal Knusrus "exact port" values for this one
   component — Knusrus's own booking-card presumably sits over a backdrop
   where .5+ opacity still reads as glass; this page's booking bar sits
   over the hero's already-heavily-overlaid bottom edge, which needed
   less tint, not just more blur, to read as glass at all.

   Blur/overlap increased again 2026-07-23 (user report: "zero blur" on
   the live page) — diagnosed live via getBoundingClientRect(), not
   guessed: the CSS was always being applied (backdrop-filter computed
   correctly), but at the old -5.5rem overlap only ~88px of the bar's
   ~268px height actually sat over the hero photo, and that sliver was
   the photo's darkest, most uniform overlay region (see .hw-hero::after)
   — blurring a near-flat dark area produces almost no visible distortion,
   which is what read as "no blur" even though it was active. Removing
   the hero's own "Check Availability" button (below) freed up room to
   pull the bar further up without covering the headline, so more of it
   now overlaps photo with actual texture to blur.

   Same complaint recurred, same day — re-diagnosed rather than re-guessed:
   sampled the hero photo pixels actually sitting behind the bar (canvas
   getImageData over the exact overlap rect) and found real texture there
   (luminance stddev ~36 out of 255, not a flat region this time — the
   overlap-position fix above worked). The real cause this round was the
   opposite problem: blur(46px) is large enough relative to the bar's own
   ~130px height that it smooths away *all* recognizable structure from
   the backdrop, leaving a uniform wash — which looks identical to "no
   blur, just a tinted panel" because there's nothing softened-but-still-
   visible left to read as glass. A frosted-glass look needs blur strong
   enough to obscure detail but not so strong it erases all variation.
   Brought back down to a moderate 20px (matching .hw-unit-card's own
   already-working blur radius) so soft shapes/color variation from the
   photo remain visible through the panel. */
.hw-booking-bar {
	background:
		radial-gradient(105% 36% at 50% -8%, rgba(255, 255, 255, 0.24) 0%, rgba(255, 255, 255, 0.08) 31%, transparent 61%),
		radial-gradient(48% 120% at -6% 45%, rgba(255, 255, 255, 0.105) 0%, transparent 68%),
		linear-gradient(145deg, rgba(17, 19, 20, 0.30) 0%, rgba(8, 11, 13, 0.24) 48%, rgba(4, 8, 10, 0.36) 100%);
	/* Now that backdrop-filter is confirmed actually rendering (2026-07-23
	   — the real bug was a transform on an ancestor, see .hw-booking-bar-wrap
	   and hawehuis-motion.js), the blur reads as strong at 20px; dropped
	   significantly per user request now that it's a real, visible effect
	   rather than a value tuned blind against a non-rendering property. */
	-webkit-backdrop-filter: blur(8px) saturate(170%) brightness(1.05);
	backdrop-filter: blur(8px) saturate(170%) brightness(1.05);
}

.hw-booking-bar::before,
.hw-unit-card::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	border-radius: inherit;
	background:
		linear-gradient(90deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0.06) 9%, transparent 25%, transparent 91%, rgba(255, 255, 255, 0.04) 100%),
		linear-gradient(180deg, rgba(255, 255, 255, 0.36) 0%, rgba(255, 255, 255, 0.07) 10%, transparent 27%, transparent 88%, rgba(214, 173, 103, 0.07) 100%);
}

.hw-booking-bar::after,
.hw-unit-card::after {
	content: "";
	position: absolute;
	inset: 1px;
	z-index: 0;
	pointer-events: none;
	border-radius: calc(var(--hw-radius) - 1px);
	box-shadow:
		inset 0 0 0 1px rgba(255, 255, 255, 0.035),
		inset 0 0 24px rgba(255, 255, 255, 0.018);
}

.hw-booking-bar > *,
.hw-unit-card > * {
	position: relative;
	z-index: 2;
}

.hw-booking-bar:hover,
.hw-unit-card:hover {
	border-color: rgba(214, 173, 103, 0.28);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.42),
		inset 1px 0 0 rgba(255, 255, 255, 0.20),
		inset 0 0 64px rgba(214, 173, 103, 0.028),
		0 42px 112px rgba(0, 0, 0, 0.42);
}

/* Real photo fill — a wp:image's <figure>/<img>, used once a real photo
   replaces a .hw-photo-placeholder. Scoped per-context (hero = absolute
   full-bleed, tagline-split = fills its grid cell) same as the
   placeholder it replaces. */
.hw-photo-fill {
	margin: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

.hw-photo-fill img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}

/* Only present when a wp:image block uses "linkDestination":"media" (the
   Gallery page's lightbox-enabled photos) — the resulting <a> defaults to
   shrink-wrapping the image's own intrinsic aspect ratio instead of
   stretching to fill .hw-photo-fill, so the img's height:100% above
   resolves against that undersized anchor box rather than the real
   container. Confirmed live via getBoundingClientRect(): the anchor was
   rendering at the image's intrinsic ratio (e.g. 301x200) inside a
   301x320 figure, leaving a visible gap — this forces it to fill instead. */
.hw-photo-fill a {
	display: block;
	width: 100%;
	height: 100%;
}

/* HEADER / NAV — floating smoked-glass bar
   ------------------------------------------------------------------------- */
/*
 * .hw-menu (wp:navigation) and .hw-nav-button (wp:buttons) are real
 * Gutenberg blocks nested as siblings inside this <header> — they can't be
 * authored as raw HTML inside the wp:html blocks that open/close the tag,
 * since the block parser won't parse nested wp:comments inside opaque
 * wp:html content. All four children (logo, menu, button, toggle) still
 * end up inside one <header> element at render time, since block output is
 * just concatenated in source order — the header tag opens in the first
 * wp:html block and closes in a later one, with real blocks in between.
 */
.hw-header {
	position: fixed;
	top: 20px;
	left: 4%;
	right: 4%;
	max-width: 1360px;
	margin: 0 auto;
	z-index: 100;
	display: flex;
	align-items: center;
	gap: 2rem;
	/* Vertical padding cut roughly in half (0.9rem -> 0.5rem, 2026-07-31)
	   to partly offset .hw-logo-mark's own 50% size bump right below —
	   the logo is the row's tallest item, so growing it can't be fully
	   absorbed by padding alone (the logo alone is already taller than the
	   old total bar height), but this keeps the increase to roughly two
	   thirds of what it would otherwise be. See .hw-logo-mark's own
	   comment for the exact before/after numbers. */
	padding: 0.5rem 1.75rem;
	border-radius: 18px;

	/* Ported verbatim from Knusrus's .kn-smart-header__shell (the
	   floating glass bar Knusrus reveals on scroll-up) — see the LIQUID
	   GLASS comment above for why this replaced the earlier flatter
	   version. Base tint recolored from near-black neutral to --hw-navy's
	   own rgb values (2026-07-23, user request: nav bar should match the
	   "Die Hawehuis" heading color) — same gold glow overlay kept. */
	background:
		radial-gradient(85% 170% at 12% -62%, rgba(214, 173, 103, 0.13), transparent 62%),
		linear-gradient(180deg, rgba(12, 34, 56, 0.91), rgba(7, 24, 41, 0.86));
	border: 1px solid rgba(255, 255, 255, 0.09);
	box-shadow:
		0 18px 58px rgba(0, 0, 0, 0.30),
		inset 0 1px 0 rgba(255, 255, 255, 0.06);
	-webkit-backdrop-filter: blur(18px) saturate(135%);
	backdrop-filter: blur(18px) saturate(135%);

	transition: transform 0.5s cubic-bezier(0.25, 1, 0.5, 1), top 0.3s ease;
}

/* Smart hide-on-scroll-down / reveal-on-scroll-up — toggled by
   hawehuis-ui.js's initSmartNav(). */
.hw-header.hw-header--hidden {
	transform: translateY(-140%);
}

/* WordPress adds a fixed 32px admin toolbar at the very top when logged
   in — .hw-header is position:fixed so it ignores the body's own
   admin-bar margin-top and needs its own compensation, same pattern
   Knusrus already uses for its smart-header. Missing before 2026-07-20;
   the kicker/heading intruding under the header in the client's own
   logged-in screenshot was this plus the oversized hero title above. */
body.admin-bar .hw-header {
	top: 52px;
}

/* Logo mark (image) + the two-line "Die Hawehuis"/"Stilbaai" text stack,
   side by side (2026-07-31 — replaces the old inline beacon SVG, which
   only sat next to the first text line, not spanning both). align-items
   defaults to stretch in a row-direction flex container, so .hw-logo-mark
   naturally stretches to .hw-logo-wrap's full two-line height with no
   hardcoded pixel value to keep in sync if the text ever changes size. */
.hw-logo-mark-row {
	display: flex;
	align-items: stretch;
	gap: 0.6rem;
	/* Pushes menu/nav-button/toggle to the right edge, clustered together,
	   instead of spreading all flex children evenly across the row. */
	margin-right: auto;
}

/* The image is absolutely positioned on purpose — this is the fix for the
   logo rendering at its full 1024px intrinsic size (2026-07-31). The first
   attempt used an in-flow `<img height:100%; width:auto>`, which is
   circular: the row's height comes from its tallest item, the figure's
   height comes from the stretch, and the img's `height:100%` resolves
   against the figure — so nothing supplies a definite height first and the
   img falls back to its intrinsic 1024px, which then *becomes* the row
   height. (Same percentage-height-needs-a-definite-parent trap already
   documented for .hw-tagline-split .hw-photo-fill.) Taking the img out of
   flow makes the figure contribute zero content height, so the row is
   sized purely by the text stack, the figure stretches to exactly that,
   and aspect-ratio derives the width from it. Still no hardcoded pixel
   value — it re-fits automatically if the logo text sizes ever change. */
.hw-logo-mark {
	flex-shrink: 0;
	margin: 0;
	/* Explicit square size, NOT stretch/aspect-ratio — both auto-sizing
	   attempts failed and the reasons are worth keeping:
	     1. in-flow `height:100%` -> circular (nothing has a definite height
	        first), so the img fell back to its intrinsic 1024px.
	     2. `align-self:stretch` + `aspect-ratio:1` + absolute img -> the
	        logo vanished. In a row flex container an item's main size
	        (width) is resolved BEFORE cross-size stretch, so at width-
	        resolution time the height isn't known yet and aspect-ratio has
	        nothing to derive from; with the img out of flow the figure had
	        no content either, so it computed to width 0.
	   Base size is the measured height of the text stack beside it: .hw-logo
	   1.4rem + .hw-logo-sub 0.64rem, both at the inherited line-height 1.65,
	   plus the 0.15rem column gap = (1.4 x 1.65) + (0.64 x 1.65) + 0.15 =
	   3.516rem, rounded to 3.5rem. In rem, so it still tracks the text if
	   the root font-size changes; if either logo font-size or the gap is
	   ever edited, redo that sum. **Sized ~50% above that base per explicit
	   request (2026-07-31)** — 3.5rem x 1.5 = 5.25rem — so it now
	   deliberately overshoots the text-stack height rather than matching it
	   exactly. .hw-logo-mark-row's align-items:stretch (unchanged) still
	   stretches .hw-logo-wrap to the row's new, taller height — but
	   .hw-logo-wrap's own justify-content:center (added when this was
	   first built) centers the two text lines inside that stretched box,
	   so the net effect is the text reading vertically centered against
	   the now-larger mark, not pinned to its top. */
	/* Sized up another 50% on top of that (2026-07-31) — 5.25rem x 1.5 =
	   7.875rem. Since the logo is the tallest thing in .hw-logo-mark-row,
	   this also became the header's own tallest content, so the header
	   grows too: with the padding cut above (0.9rem -> 0.5rem), total bar
	   height goes from ~112.8px to ~140.4px (+27.6px) — the padding cut on
	   its own can't cancel the +42px the logo's growth alone would add
	   (its 42px increase already exceeds the 28.8px the old padding could
	   ever give back), so it isn't literally the same height, just closer
	   than doing nothing would leave it. */
	width: 7.875rem;
	height: 7.875rem;
}

.hw-logo-mark img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

.hw-logo-wrap {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 0.15rem;
}

.hw-logo {
	color: var(--hw-white);
	font-size: 1.4rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.hw-logo-sub {
	color: rgba(255, 255, 255, 0.7);
	font-size: 0.64rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
}

.hw-menu {
	display: flex;
	align-items: center;
	gap: 2rem;
}

/* !important on color: wp:navigation's own core CSS sets
   .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content
   { color: inherit } — a deliberately doubled-class selector at (0,3,0),
   confirmed live via document.styleSheets before writing this, which beats
   any plain .hw-menu a rule regardless of source order. Same (0,2,0)+
   trap already documented in Conventions above for wp:navigation/
   wp:buttons/wp:columns, just on `color` instead of `display` this time. */
.hw-menu a {
	color: rgba(255, 255, 255, 0.92) !important;
	font-size: 0.82rem;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	padding-bottom: 4px;
	border-bottom: 2px solid transparent;
	transition: border-color 0.2s ease, color 0.2s ease;
}

.hw-menu a:hover,
.hw-menu .hw-active a {
	border-color: var(--hw-gold);
	color: var(--hw-white) !important;
}

/* Hidden on desktop — the header already has its own separate gold
   "Book" button (.hw-nav-button) there. Only shown inside the mobile
   drawer (see @media (max-width:900px) below), which otherwise drops
   the booking CTA entirely once .hw-nav-button is hidden.
   !important: wp:navigation's core CSS sets
   .wp-block-navigation .wp-block-navigation-item { display: flex } at
   (0,2,0), beating this plain single-class selector — confirmed live via
   document.styleSheets, same trap as the color rule above. */
.hw-menu-book {
	display: none !important;
}

.hw-nav-button .wp-block-button__link {
	border: 1px solid var(--hw-gold);
	color: var(--hw-navy-deep);
	background: var(--hw-gold);
	padding: 0.6rem 1.4rem;
	font-size: 0.78rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	border-radius: 6px;
	transition: background 0.2s ease, transform 0.2s ease;
}

.hw-nav-button .wp-block-button__link:hover {
	background: var(--hw-gold-light);
	transform: translateY(-1px);
}

.hw-nav-toggle {
	display: none;
	background: none;
	border: 1px solid rgba(255, 255, 255, 0.5);
	border-radius: 8px;
	/* Widened slightly (44px -> 54px, 2026-07-31 request) — was reading as
	   narrow/cramped against the header's rounded end; height stays 44px
	   (already meets the 44px touch-target minimum). margin-left:auto is
	   redundant with .hw-logo-mark-row's own margin-right:auto (only one
	   flex child follows it on mobile) but margin-right gives the button
	   real clearance from the header's inner right edge on top of the
	   header's own (now-reduced) right padding. */
	width: 54px;
	height: 44px;
	margin-right: 0.5rem;
	/* Without this, the toggle was the one flex item flex-shrink actually
	   picked to compress on narrow phones (measured live at 390px: the
	   126px logo image can't shrink below its own explicit size — an
	   image's automatic minimum size floors at its intrinsic size — so
	   .hw-logo-wrap's text silently absorbed most of the row's own
	   shrinkage by wrapping to 2 lines, but the toggle still isn't
	   protected the same way and rendered at ~32px instead of 54px). Zero
	   shrink here pushes any remaining pressure onto .hw-logo-wrap
	   instead, which just wraps its text a little more — a safe overflow
	   valve, unlike a compressed tap target. */
	flex-shrink: 0;
	color: var(--hw-white);
	font-size: 1.3rem;
	cursor: pointer;
}

/* HERO
   ------------------------------------------------------------------------- */
.hw-hero {
	position: relative;
	/* Was clamp(650px,94vh,980px) — pushed taller 2026-07-20 per request,
	   capped at the source photo's real ceiling: header.png is a native
	   1537×1023px photo (checked directly, not guessed), so anything much
	   past ~1023px of rendered height starts upscaling past its own
	   resolution and will soften. 100vh (was 94vh) also removes the
	   ~6vh sliver of the next section that used to always be visible at
	   the bottom of the viewport, which is most of what makes this read
	   as "significantly taller" on ordinary laptop screens — the 1023px
	   cap only matters on unusually tall displays. A genuinely taller hero
	   beyond this needs a higher-resolution source photo, not more CSS.
	   */
	min-height: clamp(700px, 100vh, 1023px);
	display: flex;
	align-items: flex-end;
	/* Defensive header clearance — .hw-header is position:fixed, so it
	   reserves no space in normal flow the way Knusrus's in-flow nav does.
	   Without this, hero-content (bottom-anchored) can still intrude under
	   the header whenever its own content runs tall, regardless of the
	   hero-title size fix above. */
	padding-top: clamp(110px, 13vh, 150px);
	/* Was 6.5rem — increased 2026-07-23 so the booking bar's deeper
	   -9rem overlap (see .hw-booking-bar-wrap) has room to sit without
	   covering the hero title/paragraph text; verified live via
	   getBoundingClientRect() that .hw-hero-content's bottom edge now
	   clears .hw-booking-bar's top edge. */
	padding-bottom: 11rem;
	/* overflow:hidden clips the Ken Burns hero-photo zoom to the hero box.
	   NOTE: this does NOT interfere with .hw-booking-bar's backdrop-filter,
	   even though the booking bar is a separate section overlapping the
	   hero's bottom from outside — the "zero blur" bug was never about this
	   clip or the DOM structure. It was a transform on the booking bar's
	   own wrapper (from the .ab-reveal motion class), now removed; see
	   hawehuis-motion.js and the .hw-booking-bar-wrap comment below. */
	overflow: hidden;
}

.hw-hero .hw-photo-fill {
	position: absolute;
	inset: 0;
}

/* Slow "settling into the view" zoom on load — a single orchestrated
   moment rather than the uniform scroll-triggered fade-ups used
   elsewhere on the page (2026-07-20 design-consultation request).
   .hw-hero already has overflow:hidden, so the scale-up stays cropped
   within the hero at all times, no edge gaps. Scoped to the hero photo
   specifically, not the shared .hw-photo-fill img rule other cards use
   for their own hover-zoom. */
@keyframes hw-hero-kenburns {
	from {
		transform: scale(1);
	}
	to {
		transform: scale(1.08);
	}
}

@media (prefers-reduced-motion: no-preference) {
	.hw-hero .hw-photo-fill img {
		animation: hw-hero-kenburns 18s cubic-bezier(0.25, 1, 0.5, 1) forwards;
	}
}

/* Directional overlay: dark on the left (where the heading sits) fading to
   near-transparent over the bright sunset on the right, plus a soft
   vertical gradient top/bottom so the floating nav and booking panel stay
   legible without flattening the photo's warmth.

   Bottom stop found and fixed 2026-07-23 as the real root cause of the
   recurring "zero blur" complaint on .hw-booking-bar, after the user asked
   to compare against Knusrus's working .kn-stat-card glass (which sits
   over .kn-hero's own overlay — checked directly, that overlay peaks at
   just 0.16 alpha and is fully transparent again by 82% of the hero's
   height). This overlay's bottom stop was 0.6 — nearly 4x darker — plus
   the booking bar's own dark glass tint stacked on top of an already
   dim patch of the source photo in that spot (measured via canvas
   getImageData: mean luminance ~58/255 there even before this overlay).
   Compositing the numbers: at 0.6 alpha the effective backdrop luminance
   drops to ~33/255 and its variance (the actual "texture" blur diffuses)
   roughly halves again to ~14 — there just wasn't enough brightness or
   variation left under the glass for any blur radius to visibly soften.
   Tuning .hw-booking-bar's own blur/tint across three earlier rounds
   never could have fixed this, since the problem was what's behind it,
   not the glass itself. Dropped to 0.18 (much closer to Knusrus's own
   peak) — the booking bar's text still gets its contrast from its own
   glass tint, not from this overlay, so legibility there is unaffected. */
.hw-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(180deg, rgba(7, 17, 28, 0.5) 0%, rgba(7, 17, 28, 0) 18%, rgba(7, 17, 28, 0) 72%, rgba(7, 17, 28, 0.18) 100%),
		linear-gradient(90deg, rgba(7, 17, 28, 0.72) 0%, rgba(7, 17, 28, 0.4) 38%, rgba(7, 17, 28, 0.08) 68%, rgba(7, 17, 28, 0) 88%);
}

.hw-hero-content {
	position: relative;
	z-index: 5;
	max-width: 700px;
	/* Capped, not pure 6vw — uncapped side padding keeps eating into the
	   700px container as the viewport widens past ~1600px, which is what
	   let the hero title wrap to 4 lines at 1920/2560px even after the
	   font-size fix above (verified live). */
	padding: 0 clamp(24px, 6vw, 96px);
}

.hw-hero-title {
	color: var(--hw-white);
	font-size: var(--hw-size-hero);
	line-height: 0.98;
	letter-spacing: -0.02em;
	font-style: normal;
	font-weight: 500;
	margin-bottom: 1.5rem;
	text-shadow: 0 2px 24px rgba(0, 0, 0, 0.25);
}

.hw-hero-text {
	color: rgba(255, 255, 255, 0.88);
	font-size: 1.08rem;
	line-height: 1.7;
	max-width: 440px;
	margin-bottom: 1.25rem;
}

/* Restrained gold divider under the hero copy, per the design brief's
   "short decorative detail beneath the copy." Was .hw-hero-content::after
   — a ::after always generates as the LAST box in its element, so it was
   rendering below the button (the actual last child), not between the
   text and button as the comment intended. Flagged 2026-07-20 against a
   real screenshot ("a line beneath the check availability button").
   Scoped to .hw-hero-text::after instead — .hw-hero-text is itself the
   element directly before the button, so its ::after lands exactly
   where the divider was meant to sit, no markup change needed. */
.hw-hero-text::after {
	content: "";
	display: block;
	width: 64px;
	height: 2px;
	margin-top: 0.75rem;
	background: var(--hw-gold);
}

/* .hw-glass-button (hero "Check Availability" CTA) and .hw-gold-button
   (footer "Check Availability" box's submit) were both removed 2026-07-23
   along with the elements that used them — the hero button was redundant
   with the real booking bar overlapping the hero right below it, and the
   footer box duplicated the same booking bar a second time. Their CSS
   (Knusrus's V10 "definitive hero glass" recipe and the flat gold-button
   recipe) is removed with them; `.hw-nav-button`/`.hw-menu-book` below
   still use their own separate rules and are unaffected. */

/* BOOKING BAR
   ------------------------------------------------------------------------- */
.hw-booking-bar-wrap {
	position: relative;
	z-index: 6;
	/* Pulls the booking bar up to overlap the hero photo above it — the
	   "floating glass panel over the hero" look. This element is a normal
	   in-flow section right after .hw-hero, so the negative margin-top
	   reserves less vertical space and the following section sits flush
	   below it (verified live). Excluded from the .hw-page > * block-gap
	   reset above via :not() so that reset's !important can't cancel this
	   overlap.

	   IMPORTANT: this negative margin was NOT the cause of the long "zero
	   blur" saga, despite several rounds of suspecting it — a negative
	   margin creates no transform/stacking context and doesn't affect
	   backdrop-filter. The real cause was the .ab-reveal motion class
	   putting transform + will-change:transform on THIS element, which
	   established a backdrop root that blocked .hw-booking-bar (its child)
	   from sampling the hero photo. Fixed by removing this element from the
	   reveal selector list in hawehuis-motion.js. Do not re-add any
	   transform/filter/will-change/perspective here or on any ancestor of
	   .hw-booking-bar, or the blur breaks again. */
	margin-top: -9rem;
	padding: 0 24px;
	/* Both the floating "Reserve Your Stay" button's scrollIntoView() and a
	   plain #booking fragment link (e.g. from another page's nav) align
	   this element's own top edge to the viewport's top edge — which sits
	   right under the fixed .hw-header (~163px tall including its own
	   20px top offset at desktop width, confirmed live via
	   getBoundingClientRect()), covering the bar's top edge. scroll-margin-top
	   shifts the landing position down by this much so the bar clears the
	   header instead of hiding under it; the 768px-breakpoint value below
	   matches the header's shorter mobile height (~151px). */
	scroll-margin-top: 190px;
}

.hw-booking-bar {
	padding: 1.25rem 1.5rem;
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	align-items: end;
	max-width: 1180px;
	min-height: 96px;
	margin: 0 auto;
}

/* Ported from Knusrus's .kn-booking-field — an inset dark panel nested
   inside the glass bar, with transparent, light-on-dark inputs, rather
   than the earlier opaque white input fields designed for the old light
   frosted bar. */
.hw-booking-field {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	flex: 1 1 160px;
	min-width: 140px;
	padding: 0.55rem 0.85rem;
	border: 1px solid rgba(255, 255, 255, 0.105);
	border-radius: 10px;
	background: linear-gradient(145deg, rgba(255, 255, 255, 0.025), rgba(0, 0, 0, 0.18));
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.035),
		inset 0 0 20px rgba(0, 0, 0, 0.10);
	transition: border-color 0.32s ease, background 0.32s ease, box-shadow 0.32s ease;
}

.hw-booking-field:focus-within {
	border-color: rgba(214, 173, 103, 0.42);
	background: linear-gradient(145deg, rgba(255, 255, 255, 0.04), rgba(0, 0, 0, 0.15));
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.05),
		0 0 0 3px rgba(214, 173, 103, 0.32);
}

.hw-booking-field label {
	font-size: 0.66rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.6);
	font-weight: 600;
}

.hw-booking-field input,
.hw-booking-field select {
	border: 0;
	padding: 0;
	font-size: 0.95rem;
	font-family: inherit;
	color: rgba(255, 255, 255, 0.94);
	background: transparent;
	color-scheme: dark;
	min-height: 44px;
	display: flex;
	align-items: center;
}

.hw-booking-field input:focus,
.hw-booking-field select:focus {
	outline: none;
}

/* The select's own closed box stays white-on-glass (color above), but the
   native dropdown popup is a separate OS-rendered surface that doesn't
   inherit the glass background — without an explicit option background,
   the inherited white text renders on the browser's default white popup,
   making every option but the currently-selected one invisible. */
.hw-booking-field select option {
	color: var(--hw-navy);
	background-color: #fff;
}

/* Ported from Knusrus's champagne reservation-CTA recipe (same gradient
   used on .kn-nav-button/.kn-floating-reserve) — flat navy read as too low
   contrast against the new dark glass bar. */
.hw-booking-submit {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	color: #fff;
	background:
		radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.28), transparent 38%),
		linear-gradient(135deg, #efc878, #b98035);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.38),
		0 24px 70px rgba(214, 173, 103, 0.22);
	border: none;
	border-radius: var(--hw-radius-sm);
	padding: 0.85rem 1.5rem;
	font-size: 0.85rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	min-height: 44px;
	transition: filter 0.2s ease;
}

.hw-booking-submit:hover {
	filter: brightness(1.07);
}

/* Visible submit feedback — previously the form only logged to the
   console when data-booking-url was empty, giving the visitor zero
   confirmation their click registered. Doubles as the inline validation
   message when dates fail the min-stay/order check. Forces its own row
   in the flex-wrap bar via flex-basis:100%. */
.hw-booking-status {
	flex: 1 1 100%;
	font-size: 0.85rem;
	line-height: 1.5;
	padding: 0.7rem 0.9rem;
	border-radius: 10px;
	background: rgba(255, 255, 255, 0.08);
	color: rgba(255, 255, 255, 0.94);
	border: 1px solid rgba(255, 255, 255, 0.16);
}

.hw-booking-status[data-state="error"] {
	background: rgba(200, 74, 58, 0.16);
	border-color: rgba(200, 74, 58, 0.4);
	color: #fff;
}

.hw-booking-note {
	text-align: center;
	font-size: 0.72rem;
	letter-spacing: 0.04em;
	color: var(--hw-text-light);
	margin: 0.85rem auto 0;
	max-width: 1180px;
	padding: 0 24px;
}

/* WELCOME SECTION
   ------------------------------------------------------------------------- */
.hw-welcome {
	display: grid;
	grid-template-columns: 0.85fr 1.15fr;
	gap: clamp(2.5rem, 5vw, 5rem);
	align-items: center;
}

/* Harbour-beacon signature mark (2026-07-20) — the "Welcome to Die
   Hawehuis" copy already tells the story ("Die Hawehuis" translates to
   "The Harbour House", named for the real red light beacon marking the
   end of the Stilbaai harbour wall), but nothing on the page showed it.
   One small, specific detail rather than a generic ocean-view flourish —
   the tower uses the existing gold icon system's stroke convention, the
   light is the one place --hw-beacon appears on the whole page. */
/* Icon + heading sit side by side (2026-07-23, user request — was stacked
   above the "Welcome to" kicker, now moved down next to "Die Hawehuis"
   itself). .hw-welcome-title-row's own children are covered by the
   block-gap reset list above (same flex-row bug class documented there),
   or the heading would sit lower than the icon. */
.hw-welcome-title-row {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.hw-beacon-mark {
	display: flex;
	margin-bottom: 0;
}

.hw-beacon-icon {
	/* Was 30x30px, enlarged 3x to 90px (2026-07-23) while stacked above the
	   kicker; scaled back down by a third to 60px the same day once moved
	   inline next to the "Die Hawehuis" heading, where 90px overpowered
	   the heading text next to it. */
	width: 60px;
	height: 60px;
	color: var(--hw-gold);
}

.hw-beacon-light {
	fill: var(--hw-beacon);
}

@media (prefers-reduced-motion: no-preference) {
	.hw-beacon-light {
		animation: hw-beacon-pulse 2.6s ease-in-out infinite;
		transform-origin: 12px 7px;
	}
}

@keyframes hw-beacon-pulse {
	0%,
	100% {
		opacity: 1;
		filter: drop-shadow(0 0 1px rgba(200, 74, 58, 0.6));
	}
	50% {
		opacity: 0.55;
		filter: drop-shadow(0 0 5px rgba(200, 74, 58, 0.85));
	}
}

/* .hw-kicker's base gold fails contrast on the flat cream this section
   (and the units header below) sits on — swap to --hw-gold-ink here. The
   hero's own kicker stays --hw-gold since it sits on the dark photo
   overlay, where the base gold is fine. */
.hw-welcome .hw-kicker,
.hw-units-header .hw-kicker {
	color: var(--hw-gold-ink);
}

.hw-welcome .hw-kicker::after,
.hw-units-header .hw-kicker::after {
	background: var(--hw-gold-ink);
}

.hw-welcome-title {
	font-size: var(--hw-size-medium);
	margin-bottom: 1.1rem;
}

.hw-welcome-text {
	color: var(--hw-text-light);
	font-size: 1.02rem;
	line-height: 1.75;
	max-width: 480px;
	margin-bottom: 2.25rem;
}

.hw-feature-row {
	display: flex;
	flex-wrap: wrap;
	gap: 1.75rem 0;
}

.hw-feature-item {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	flex: 1 1 33%;
	min-width: 150px;
	padding-right: 1.5rem;
	border-left: 1px solid var(--hw-border);
	padding-left: 1.5rem;
}

.hw-feature-item:first-child {
	border-left: none;
	padding-left: 0;
}

.hw-feature-item p {
	font-size: 0.85rem;
	line-height: 1.35;
	color: var(--hw-text);
	font-weight: 500;
}

.hw-video-card {
	position: relative;
	border-radius: var(--hw-radius);
	overflow: hidden;
	box-shadow: var(--hw-shadow);
}

.hw-video-card .hw-photo-fill {
	aspect-ratio: 16 / 10;
}

.hw-video-card:hover .hw-photo-fill img {
	transform: scale(1.025);
}

.hw-video-caption {
	position: absolute;
	bottom: 1.25rem;
	left: 0;
	right: 0;
	text-align: center;
}

.hw-video-caption strong {
	font-size: 0.72rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--hw-white);
	text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
}

/* UNIT CARDS
   ------------------------------------------------------------------------- */
.hw-units-header {
	text-align: center;
	margin-bottom: 2rem;
}

.hw-units-header h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 0.75rem !important;
}

.hw-units-header p:not(.hw-kicker) {
	color: var(--hw-text-light);
	font-size: 1.02rem;
	max-width: 560px;
	margin: 0 auto !important;
}

.hw-unit-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 2.5rem;
}

/* Dark edge-lit liquid glass (background/border/box-shadow/backdrop-filter
   come from the shared .hw-booking-bar/.hw-unit-card/.hw-footer-cta mixin
   above) — the whole card, photo included, reads as one glass tile against
   the section's cream background, same pattern as Knusrus's
   .kn-bedroom-mini-card (padded glass shell with an inset-radius photo,
   not a full-bleed photo with a separate solid body beneath it). */
.hw-unit-card {
	display: flex;
	flex-direction: column;
	padding: 20px;
	gap: 1rem;
	transition: transform 0.3s ease, border-color 0.5s ease, box-shadow 0.5s cubic-bezier(0.25, 1, 0.5, 1);
}

.hw-unit-card:hover {
	transform: translateY(-5px);
}

.hw-unit-card .hw-photo-fill {
	aspect-ratio: 16 / 11;
	border-radius: calc(var(--hw-radius) - 6px);
}

.hw-unit-card:hover .hw-photo-fill img {
	transform: scale(1.02);
}

.hw-unit-body {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	flex: 1;
}

.hw-unit-body h3 {
	color: var(--hw-white);
	font-size: 2.4rem;
}

.hw-unit-meta {
	font-size: 0.8rem;
	letter-spacing: 0.03em;
	/* --hw-gold measured under 3:1 against this card's darkened glass —
	   --hw-gold-light clears it with the panel darkening above. */
	color: var(--hw-gold-light);
	font-weight: 600;
	text-transform: uppercase;
}

.hw-unit-body p.hw-unit-detail {
	font-size: 0.95rem;
	line-height: 1.6;
	/* Was rgba(255,255,255,.72) — the opacity itself was diluting contrast
	   twice over (against the glass panel behind it), landing ~3.35:1.
	   Bumped to .92; the panel darkening above does the rest. */
	color: rgba(255, 255, 255, 0.92);
	margin-top: 0.25rem !important;
}

.hw-unit-body .wp-block-buttons {
	margin-top: auto !important;
	padding-top: 1.25rem;
}

.hw-outline-button .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	border: 1px solid var(--hw-gold);
	color: var(--hw-gold);
	background: transparent;
	padding: 0.6rem 1.3rem;
	font-size: 0.78rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	border-radius: var(--hw-radius-sm);
	transition: background 0.2s ease, color 0.2s ease;
}

.hw-outline-button .wp-block-button__link:hover {
	background: var(--hw-gold);
	color: var(--hw-navy-deep);
}

/* EXTERIOR / TAGLINE BAND
   ------------------------------------------------------------------------- */
/* Was a 2-column grid boxed in a rounded/bordered/shadowed card (the
   "template reflex" flagged in the 2026-07-20 design consultation) — now
   a full-bleed photo band with a simple centered text block beneath it.
   Photo and .hw-tagline-content are already DOM siblings in that order,
   so dropping the grid/card chrome alone stacks them correctly with no
   markup change. */
.hw-tagline-split {
	display: block;
}

/* Standard "break out of a centered max-width ancestor" bleed — works
   regardless of .hw-section's own padding/max-width because the formula
   re-centers a 100vw box against the viewport, not against the immediate
   parent. Verify with getBoundingClientRect() after any change here:
   left should be ~0 and right should be ~window.innerWidth at every
   viewport width, not just the one you happened to test. */
.hw-tagline-split .hw-photo-fill {
	/* Was `min-height: 560px` — that left a large empty band below the
	   visible photo on narrow/mobile viewports (reported 2026-07-24, worse
	   the narrower the screen, "only on mobile"). Cause: the inner <img>
	   has `height: 100%` (from the shared .hw-photo-fill img rule), but a
	   percentage height can only resolve against a parent with a *definite*
	   height — `min-height` doesn't count, so the img fell back to its
	   intrinsic height (~227px at 414px wide) while the figure itself was
	   still forced to 560px, leaving ~333px of dead cream space inside the
	   figure before the tagline text. A definite, responsive `height` lets
	   `height:100%` + `object-fit:cover` actually fill the figure at every
	   width, so there's no dead space — and it scales the banner down on
	   phones instead of a fixed 560px (which was also unnecessarily tall
	   there). clamp caps back at 560px on desktop, unchanged. */
	height: clamp(300px, 52vw, 560px);
	width: 100vw;
	margin-left: calc(50% - 50vw);
}

.hw-tagline-content {
	max-width: 640px;
	margin: 2.5rem auto 0;
	text-align: center;
}

.hw-tagline-content h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 1.1rem;
}

.hw-tagline-content p {
	color: var(--hw-text-light);
	font-size: 1rem;
	line-height: 1.7;
	margin-bottom: 1.75rem;
}

.hw-tagline-content .wp-block-buttons {
	justify-content: center;
}

/* "Explore the Property" sits on flat cream here (unlike the unit-card
   outline buttons, which sit on dark glass where base --hw-gold is
   fine) — same on-cream contrast fix as the kickers above. */
.hw-tagline-content .hw-outline-button .wp-block-button__link {
	color: var(--hw-gold-ink);
	border-color: var(--hw-gold-ink);
}

.hw-tagline-content .hw-outline-button .wp-block-button__link:hover {
	background: var(--hw-gold-ink);
	border-color: var(--hw-gold-ink);
	color: #fff;
}

/* AMENITIES STRIP — full-bleed navy band
   ------------------------------------------------------------------------- */
.hw-amenities-band {
	background: var(--hw-navy);
}

.hw-amenities-row {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 0;
}

.hw-amenity {
	flex: 1 1 150px;
	max-width: 190px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.75rem;
	text-align: center;
	padding: 0.5rem 1.25rem;
	border-left: 1px solid rgba(255, 255, 255, 0.14);
}

.hw-amenity:first-child {
	border-left: none;
}

.hw-amenity .hw-icon {
	color: var(--hw-gold);
}

.hw-amenity p {
	font-size: 0.76rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.92);
	line-height: 1.4;
}

/* DISTANCE BAND ("Featured amenities" — nearby points of interest)
   ------------------------------------------------------------------------- */
.hw-distance-band {
	background: var(--hw-navy-deep);
}

.hw-distance-band .hw-units-header p:not(.hw-kicker),
.hw-distance-band h2 {
	color: var(--hw-white);
}

.hw-distance-row {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 1.5rem 1rem;
	text-align: center;
}

.hw-distance-item {
	border-left: 1px solid rgba(255, 255, 255, 0.16);
	padding-left: 1rem;
}

.hw-distance-item:first-child {
	border-left: none;
	padding-left: 0;
}

.hw-distance-value {
	font-family: "Cormorant Garamond", Georgia, serif;
	font-size: 2.4rem;
	color: var(--hw-white);
	font-weight: 500;
	margin-bottom: 0.3rem !important;
}

.hw-distance-label {
	font-size: 0.72rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.6);
}

/* TESTIMONIAL + GALLERY BAND
   ------------------------------------------------------------------------- */
.hw-testimonial-band {
	background: var(--hw-navy);
	color: var(--hw-white);
}

.hw-testimonial-inner {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: 3rem;
	align-items: center;
}

.hw-testimonial-quote {
	font-family: "Cormorant Garamond", Georgia, serif;
	/* Was var(--hw-size-medium) (41.6px-60.8px) — shared with section
	   headings like "Die Hawehuis", way oversized for a supporting quote
	   next to a 1fr gallery column ("silly big", 2026-07-23 user report).
	   Own fixed clamp instead of a shared variable so shrinking it here
	   can't also shrink an actual heading elsewhere. Roughly 55-60%
	   smaller than the previous range. */
	font-size: clamp(1.15rem, 1.6vw, 1.5rem);
	font-style: italic;
	line-height: 1.5;
	margin-bottom: 1.5rem !important;
	color: rgba(255, 255, 255, 0.97);
}

.hw-testimonial-author {
	font-size: 0.85rem;
	color: rgba(255, 255, 255, 0.65);
	letter-spacing: 0.04em;
	margin-bottom: 0.5rem;
}

.hw-stars {
	color: var(--hw-gold);
	letter-spacing: 0.2em;
	margin-bottom: 1.25rem !important;
}

.hw-gallery-strip {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0.85rem;
}

.hw-gallery-strip .hw-photo-fill {
	aspect-ratio: 4 / 3;
	border-radius: var(--hw-radius-sm);
}

/* FOOTER
   ------------------------------------------------------------------------- */
.hw-footer {
	background: var(--hw-navy-deep);
	color: rgba(255, 255, 255, 0.75);
	padding: clamp(3.5rem, 6vw, 5.5rem) 6vw 0;
}

.hw-footer-inner {
	/* Was 1.3fr 1fr 1fr 1.1fr (4 columns) — the 4th column (.hw-footer-cta,
	   a "Check Availability" box) was removed 2026-07-23: the hero already
	   has the real booking bar for that job, and duplicating it in the
	   footer's bottom-right corner was redundant. */
	display: grid;
	grid-template-columns: 1.2fr 1fr 1fr;
	gap: 2.5rem;
	padding-bottom: 3rem;
	border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.hw-footer-col p {
	font-size: 0.88rem;
	line-height: 1.7;
	margin-bottom: 0.5rem !important;
}

.hw-footer-logo {
	font-family: "Cormorant Garamond", Georgia, serif;
	font-size: 1.5rem;
	color: var(--hw-white);
	margin-bottom: 0.85rem !important;
}

.hw-footer-heading {
	font-size: 0.68rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--hw-gold);
	margin-bottom: 1rem !important;
}

.hw-footer-col ul li {
	margin-bottom: 0.6rem;
}

.hw-footer-col ul a {
	display: inline-block;
	padding: 4px 0;
	font-size: 0.88rem;
	color: rgba(255, 255, 255, 0.75);
	transition: color 0.2s ease;
}

.hw-footer-col ul a:hover {
	color: var(--hw-gold);
}

.hw-footer-bottom {
	text-align: center;
	font-size: 0.76rem;
	color: rgba(255, 255, 255, 0.5);
	padding: 1.75rem 0;
}

.hw-footer-legal {
	text-align: center;
	padding-top: 1.25rem;
	margin-top: 0.5rem;
	border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.hw-footer-legal a {
	font-size: 0.76rem;
	color: rgba(255, 255, 255, 0.55);
	text-decoration: underline;
	text-underline-offset: 3px;
	margin: 0 0.85rem;
}

.hw-footer-legal a:hover {
	color: var(--hw-gold);
}

/* LEGAL PAGES (Privacy Policy, Booking Terms) — plain text content, no
   hero photo, so the intro band needs its own top padding to clear the
   fixed .hw-header (every other page's tall hero does this implicitly). */
.hw-legal-hero {
	padding: clamp(8rem, 14vw, 10.5rem) 6vw 2rem;
	max-width: 1440px;
	margin: 0 auto;
	text-align: center;
}

.hw-legal-hero .hw-kicker {
	justify-content: center;
}

.hw-legal-updated {
	color: var(--hw-text-light);
	font-size: 0.85rem;
	margin-top: 0.5rem;
}

.hw-legal-content {
	max-width: 760px;
	margin: 0 auto;
}

.hw-legal-content h2 {
	font-size: clamp(1.5rem, 2.5vw, 1.9rem);
	margin-top: 2.5rem;
	margin-bottom: 0.9rem;
}

.hw-legal-content h2:first-child {
	margin-top: 0;
}

.hw-legal-content p,
.hw-legal-content li {
	color: var(--hw-text);
	font-size: 0.98rem;
	line-height: 1.75;
}

.hw-legal-content p {
	margin-bottom: 1.1rem;
}

.hw-legal-content ul {
	margin: 0 0 1.1rem 1.25rem;
	padding: 0;
}

.hw-legal-content li {
	margin-bottom: 0.5rem;
}

/* FLOATING RESERVE BUTTON
   ------------------------------------------------------------------------- */
/* Mirrors Knusrus's .kn-floating-reserve pattern (same champagne-gold
   recipe as .hw-booking-submit/.hw-nav-button, not a new visual language):
   a bottom-right CTA that appears once the fixed header has hidden itself
   on scroll (see initSmartNav() in hawehuis-ui.js) and the hero's own
   booking bar has scrolled out of view, toggled by initFloatingReserve()
   in hawehuis-ui.js. Appended directly to <body>, outside .hw-page, so it
   needs its own reduced-motion handling below rather than relying on the
   .hw-page * blanket reset. */
.hw-floating-reserve {
	position: fixed;
	right: clamp(16px, 2.2vw, 34px);
	bottom: clamp(16px, 2.2vw, 34px);
	z-index: 150;
	display: inline-flex;
	align-items: center;
	gap: 0.65rem;
	min-height: 54px;
	padding: 0 0.85rem 0 1.4rem;
	border: none;
	border-radius: var(--hw-radius-sm);
	color: #fff;
	background:
		radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.28), transparent 38%),
		linear-gradient(135deg, #efc878, #b98035);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.38),
		0 16px 42px rgba(0, 0, 0, 0.3),
		0 20px 58px rgba(214, 173, 103, 0.22);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-decoration: none;
	opacity: 0;
	transform: translateY(18px);
	pointer-events: none;
	transition:
		opacity 0.5s cubic-bezier(0.25, 1, 0.5, 1),
		transform 0.5s cubic-bezier(0.25, 1, 0.5, 1),
		filter 0.2s ease;
}

.hw-floating-reserve.is-visible {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

.hw-floating-reserve:hover {
	filter: brightness(1.07);
	transform: translateY(-3px);
}

.hw-floating-reserve__icon {
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: 999px;
	font-size: 0.85rem;
	line-height: 1;
}

@media (max-width: 640px) {
	.hw-floating-reserve {
		min-height: 48px;
		padding: 0 0.7rem 0 1.1rem;
		font-size: 0.64rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.hw-floating-reserve {
		transition: none;
	}
}

/* ==========================================================================
   THE UNITS PAGE
   ========================================================================== */

/* Shorter hero variant for interior pages — reuses .hw-hero's own photo/
   overlay/Ken-Burns-zoom/parallax wiring untouched (see hawehuis-motion.css/
   js, which target .hw-hero generically, not just Home) and just caps the
   height and drops the deep bottom padding Home's booking-bar overlap
   needed, since this page has no booking bar of its own — booking stays
   centralised on Home, this page's CTAs link to /#booking. */
/* Height raised from clamp(520px,64vh,780px) 2026-07-31. Experience and
   Area Guide always *looked* taller than The Units/Gallery/Contact, but
   not because of any height rule — they simply carry more hero content
   (the .hw-page-hero-stats row), which pushed them past the old 64vh
   floor while the emptier pages sat right on it. A first attempt added a
   separate .hw-hero--tall class to just the three short pages; that left
   two different heights to keep in sync and still didn't match by eye,
   so it was consolidated back into this one shared rule instead of
   layering an override on top (same "consolidate, don't stack overrides"
   principle as the heading/paragraph resets above). At 86vh the floor is
   now above what the stats-row pages reach on their own, so all five
   interior heroes land at the same height on any given screen. Capped at
   960px: the shortest of the five hero photos is 940px tall, so this
   stays effectively within source resolution. */
.hw-hero.hw-hero--page {
	min-height: clamp(680px, 86vh, 960px);
	padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

.hw-page-hero-stats {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(1.5rem, 4vw, 3rem);
	margin-top: 2rem;
}

.hw-page-hero-stat-value {
	font-family: "Cormorant Garamond", Georgia, serif;
	font-size: clamp(2rem, 3vw, 2.6rem);
	color: var(--hw-white);
	font-weight: 500;
	margin-bottom: 0.2rem !important;
}

.hw-page-hero-stat-label {
	font-size: 0.68rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.68);
}

/* UNIT DEEP-DIVE — alternating text/photo section, one per unit. DOM order
   always keeps the text column first (reading order, no visual-only content
   before the heading) — the --reverse modifier flips the *visual* order via
   grid `order` only, so Unit Two's photo can sit on the left without
   touching accessibility/reading order. */
.hw-unit-deepdive {
	display: grid;
	grid-template-columns: 1fr 1.15fr;
	gap: clamp(2.5rem, 5vw, 5rem);
	align-items: center;
}

.hw-unit-deepdive--reverse .hw-unit-deepdive-intro {
	order: 2;
}

.hw-unit-deepdive--reverse .hw-unit-photo-hero {
	order: 1;
}

.hw-unit-deepdive-meta {
	font-size: 0.85rem;
	letter-spacing: 0.03em;
	/* Sits on flat cream, not dark glass — needs the on-cream-safe gold
	   token, same reasoning as the welcome/units kickers (see top of file). */
	color: var(--hw-gold-ink);
	font-weight: 600;
	text-transform: uppercase;
	margin-bottom: 1rem !important;
}

.hw-unit-deepdive-intro h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 1rem !important;
}

.hw-unit-deepdive-intro > p {
	color: var(--hw-text-light);
	font-size: 1.02rem;
	line-height: 1.75;
	margin-bottom: 1.75rem !important;
}

.hw-unit-deepdive-intro .hw-feature-row {
	margin-bottom: 2rem !important;
	gap: 1.25rem 0;
}

.hw-unit-deepdive-intro .hw-feature-item {
	flex: 1 1 45%;
}

/* The base .hw-feature-item:first-child rule strips the divider off the
   very first item (needed on Home's 3-across welcome-highlights row, where
   the row sits flush against the section's own left edge with nothing to
   divide from) — but this row's items wrap 2-per-line, so "first item" here
   just means "top-left of the grid," not "edge of a stand-alone row," and
   losing its divider read as a real inconsistency next to every other item
   (reported live, 2026-07-31: "Queen Bed" has no pipe, every other feature
   does, on both units). Restored scoped to this page only — Home's row is
   untouched. */
.hw-unit-deepdive-intro .hw-feature-item:first-child {
	border-left: 1px solid var(--hw-border);
	padding-left: 1.5rem;
}

/* Reuses .hw-video-card's own CSS wholesale (border-radius/shadow/hover-
   zoom) by sharing the literal class, not duplicating it — also means this
   photo automatically inherits .hw-video-card's existing reveal/hover/
   parallax wiring in hawehuis-motion.js with zero JS changes. */
.hw-unit-photo-hero .hw-photo-fill {
	aspect-ratio: 4 / 3;
}

/* GALLERY MOSAIC — asymmetric grid of the remaining room photos per unit
   (2 wide + 4 narrower = 6 per unit). 12-column base so the wide pair
   (span 6 each) and the narrow row (span 3 each, 4 across) both divide the
   row evenly — grown from an earlier 6-column/5-photo version; a 6-col base
   couldn't split 4 narrow items into whole-number spans. */
.hw-unit-gallery {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: clamp(10px, 1.4vw, 16px);
	margin-top: clamp(2.5rem, 5vw, 4rem);
}

.hw-unit-gallery-item {
	position: relative;
	border-radius: var(--hw-radius-sm);
	overflow: hidden;
	box-shadow: var(--hw-shadow-sm);
}

.hw-unit-gallery-item:nth-child(1),
.hw-unit-gallery-item:nth-child(2) {
	grid-column: span 6;
}

.hw-unit-gallery-item:nth-child(3),
.hw-unit-gallery-item:nth-child(4),
.hw-unit-gallery-item:nth-child(5),
.hw-unit-gallery-item:nth-child(6) {
	grid-column: span 3;
}

.hw-unit-gallery-item:nth-child(1) .hw-photo-fill,
.hw-unit-gallery-item:nth-child(2) .hw-photo-fill {
	aspect-ratio: 16 / 11;
}

.hw-unit-gallery-item:nth-child(3) .hw-photo-fill,
.hw-unit-gallery-item:nth-child(4) .hw-photo-fill,
.hw-unit-gallery-item:nth-child(5) .hw-photo-fill,
.hw-unit-gallery-item:nth-child(6) .hw-photo-fill {
	aspect-ratio: 4 / 3;
}

.hw-unit-gallery-item .hw-photo-fill {
	border-radius: inherit;
}

.hw-unit-gallery-item:hover .hw-photo-fill img {
	transform: scale(1.04);
}

.hw-unit-gallery-item__label {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 1.5rem 1rem 0.85rem;
	background: linear-gradient(0deg, rgba(7, 24, 41, 0.68) 0%, transparent 100%);
	color: var(--hw-white) !important;
	font-size: 0.68rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-weight: 600;
	pointer-events: none;
}

/* SIGNATURE DIVIDER — brief navy band between the two deep-dives, reusing
   the harbour-beacon icon/pulse already established on Home (see
   .hw-beacon-mark/.hw-beacon-icon/.hw-beacon-light) rather than inventing a
   new decorative device for this page. */
.hw-unit-divider {
	background: var(--hw-navy-deep);
	padding: clamp(2rem, 4vw, 3rem) 6vw;
	text-align: center;
}

.hw-unit-divider-inner {
	display: inline-flex;
	align-items: center;
	gap: 0.85rem;
	color: rgba(255, 255, 255, 0.7);
	font-size: 0.72rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.hw-unit-divider .hw-beacon-icon {
	width: 26px;
	height: 26px;
}

/* WHOLE-HOUSE CTA BAND — see the shared .hw-whole-house-band/
   .hw-experience-cta rule further down (just above RESPONSIVE), which
   covers this component's actual CSS so it isn't duplicated per page. */

/* Solid champagne-gold CTA — reuses the exact gradient/shadow recipe already
   established for .hw-booking-submit/.hw-floating-reserve, just packaged as
   a .wp-block-buttons modifier (same pattern as .hw-outline-button/
   .hw-nav-button) for this page's own primary CTAs. */
.hw-gold-cta .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	min-height: 44px;
	color: #fff;
	background:
		radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.28), transparent 38%),
		linear-gradient(135deg, #efc878, #b98035);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.38),
		0 20px 50px rgba(214, 173, 103, 0.22);
	border: none;
	border-radius: var(--hw-radius-sm);
	padding: 0.85rem 1.6rem;
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	transition: filter 0.2s ease, transform 0.2s ease;
}

.hw-gold-cta .wp-block-button__link:hover {
	filter: brightness(1.07);
	transform: translateY(-2px);
}

/* Closing CTA band on The Experience page — visually identical to
   .hw-whole-house-band/.hw-whole-house-inner (Units page), reused here
   under a semantically-fitting name rather than duplicating the rule. */
.hw-whole-house-band,
.hw-experience-cta {
	background: var(--hw-navy);
	text-align: center;
}

.hw-whole-house-inner,
.hw-experience-cta-inner {
	max-width: 680px;
	margin: 0 auto;
}

.hw-whole-house-inner h2,
.hw-experience-cta-inner h2 {
	color: var(--hw-white);
	margin-bottom: 1.1rem !important;
}

.hw-whole-house-inner p,
.hw-experience-cta-inner p {
	color: rgba(255, 255, 255, 0.78);
	font-size: 1.02rem;
	line-height: 1.7;
	margin-bottom: 2rem !important;
}

/* .wp-block-buttons is a flex row that defaults to flex-start — the
   ancestor's text-align:center (above) only centers text/inline content,
   it doesn't touch a flex child's own alignment, so the button was hugging
   the left edge of this centered 680px column instead of sitting under the
   centered heading/paragraph. Same bug on every page using this shared
   closing-CTA band (Units, Experience, Gallery, Area Guide, Contact). */
.hw-whole-house-inner .wp-block-buttons,
.hw-experience-cta-inner .wp-block-buttons {
	justify-content: center;
}

/* ==========================================================================
   THE EXPERIENCE PAGE
   ========================================================================== */

/* Small text-only tag chips — used on both dark photo bands (spotlight,
   scenic band) and flat cream cards (editorial pairs, mini cards). Base
   rule is the on-dark variant since it's used first/most; on-cream contexts
   override via the scoped rule below (same on-cream contrast pattern as
   --hw-gold-ink elsewhere in this file). */
.hw-pill-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

.hw-pill {
	font-size: 0.68rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	font-weight: 600;
	padding: 0.4rem 0.85rem;
	border-radius: 999px;
	border: 1px solid rgba(255, 255, 255, 0.35);
	color: rgba(255, 255, 255, 0.92);
	background: rgba(255, 255, 255, 0.08);
}

.hw-experience-editorial .hw-pill,
.hw-experience-mini-card .hw-pill,
.hw-contact-intro .hw-pill {
	border-color: var(--hw-border);
	color: var(--hw-text);
	background: var(--hw-cream-light);
}

/* FEATURE BAND — full-bleed photo with overlaid text, used for the
   "doorstep" spotlight (Stilbaai harbour, a real Hawehuis photo — not the
   Jongensfontein-area photos reused further down this page) and the
   shorter "scenic band" (Goukou Meander). A generic overlay (simple top-
   to-bottom tint) rather than reusing .hw-hero's own directional overlay,
   which was tuned specifically for the home hero photo's composition. */
.hw-experience-feature {
	position: relative;
	min-height: clamp(420px, 62vh, 620px);
	display: flex;
	align-items: flex-end;
	overflow: hidden;
	padding: clamp(2.5rem, 5vw, 4rem) 6vw;
}

.hw-experience-feature--compact {
	min-height: clamp(320px, 46vh, 460px);
}

.hw-experience-feature .hw-photo-fill {
	position: absolute;
	inset: 0;
}

.hw-experience-feature::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(7, 24, 41, 0.15) 0%, rgba(7, 24, 41, 0.74) 100%);
}

.hw-experience-feature__content {
	position: relative;
	z-index: 2;
	max-width: 640px;
}

.hw-experience-feature__content h2 {
	color: var(--hw-white);
	font-size: var(--hw-size-medium);
	margin-bottom: 1rem !important;
}

.hw-experience-feature__content p {
	color: rgba(255, 255, 255, 0.86);
	font-size: 1.02rem;
	line-height: 1.7;
	margin-bottom: 1.5rem !important;
}

/* EDITORIAL PAIR — two larger experience cards side by side (photo with a
   circular icon badge overlapping its bottom edge, then heading/text/
   pills). The badge sits outside .hw-photo-fill's own overflow:hidden
   clip by being a sibling of the figure, not a child of it — same
   "escape the photo's own clip" structure this file already uses
   elsewhere for absolutely-positioned overlays. */
.hw-experience-editorial-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(2rem, 4vw, 3rem);
}

.hw-experience-editorial__image {
	position: relative;
}

.hw-experience-editorial__image .hw-photo-fill {
	aspect-ratio: 4 / 3;
	border-radius: var(--hw-radius);
	box-shadow: var(--hw-shadow-sm);
}

.hw-experience-editorial__badge {
	position: absolute;
	left: 1.5rem;
	bottom: -1.25rem;
	width: 52px;
	height: 52px;
	border-radius: 999px;
	background: var(--hw-navy);
	color: var(--hw-gold);
	display: grid;
	place-items: center;
	box-shadow: var(--hw-shadow-sm);
	border: 3px solid var(--hw-cream);
}

.hw-experience-editorial__badge svg {
	width: 22px;
	height: 22px;
}

.hw-experience-editorial__body {
	padding-top: 2.25rem;
}

.hw-experience-editorial__body h3 {
	font-size: 1.7rem;
	margin-bottom: 0.75rem !important;
}

.hw-experience-editorial__body > p {
	color: var(--hw-text-light);
	line-height: 1.7;
	margin-bottom: 1.25rem !important;
}

/* MINI GRID — four smaller experience cards, same badge-on-photo idea at a
   more compact scale. */
.hw-experience-mini-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: clamp(1.5rem, 3vw, 2rem);
}

.hw-experience-mini-card__image {
	position: relative;
	margin-bottom: 1.5rem;
}

.hw-experience-mini-card__image .hw-photo-fill {
	aspect-ratio: 4 / 3;
	border-radius: var(--hw-radius-sm);
	box-shadow: var(--hw-shadow-sm);
}

.hw-experience-mini-card__badge {
	position: absolute;
	left: 0.9rem;
	bottom: -1rem;
	width: 40px;
	height: 40px;
	border-radius: 999px;
	background: var(--hw-navy);
	color: var(--hw-gold);
	display: grid;
	place-items: center;
	box-shadow: var(--hw-shadow-sm);
	border: 3px solid var(--hw-cream);
}

.hw-experience-mini-card__badge svg {
	width: 17px;
	height: 17px;
}

.hw-experience-mini-card h3 {
	font-size: 1.3rem;
	margin-bottom: 0.6rem !important;
}

.hw-experience-mini-card__text {
	color: var(--hw-text-light);
	font-size: 0.92rem;
	line-height: 1.6;
	margin-bottom: 1rem !important;
}

.hw-experience-mini-card__note {
	font-size: 0.78rem;
	font-style: italic;
	color: var(--hw-text-light);
	opacity: 0.8;
}

/* EXPLORE GRID — four icon-only cards (no photos), plain cream cards with a
   restrained border/shadow rather than the liquid-glass treatment — glass
   stays reserved for the signal moments established on Home/Units (nav,
   booking, unit cards), not every card on every page. */
.hw-explore-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: clamp(1.5rem, 3vw, 2rem);
}

.hw-explore-card {
	padding: clamp(1.75rem, 3vw, 2.25rem);
	border: 1px solid var(--hw-border);
	border-radius: var(--hw-radius);
	background: var(--hw-cream-light);
	transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.hw-explore-card:hover {
	transform: translateY(-4px);
	border-color: var(--hw-gold);
	box-shadow: var(--hw-shadow-sm);
}

.hw-explore-card .hw-icon {
	width: 30px;
	height: 30px;
	margin-bottom: 1.1rem;
}

.hw-explore-card h3 {
	font-size: 1.25rem;
	margin-bottom: 0.6rem !important;
}

.hw-explore-card p {
	color: var(--hw-text-light);
	font-size: 0.92rem;
	line-height: 1.6;
}

/* Icon on the hero stat row when used with 4 stats (this page) instead of
   the plain value/label pair Units uses with 3 — purely additive, Units'
   markup has no icon element so this rule simply never matches there. */
.hw-page-hero-stats .hw-icon {
	width: 22px;
	height: 22px;
	color: var(--hw-gold);
	margin-bottom: 0.6rem;
}

/* ==========================================================================
   THE GALLERY PAGE
   ========================================================================== */

/* REAL VIDEO FACADE (2026-07-31) — replaces the honest "coming soon"
   placeholder this page shipped with (the old .hw-video-teaser__overlay/
   __badge, described here for over a week) now that a real YouTube video
   exists. Click-to-load, same shape as Knusrus's own proven
   .kn-video-frame/initVideoFacade() pattern: the iframe is only created on
   click (initVideoFacade() in hawehuis-ui.js), so a page view alone never
   pulls in YouTube's player assets. Sits inside .hw-video-card, which
   already supplies the border-radius/overflow:hidden/box-shadow shell (and
   is one of hawehuis-motion.js's scroll-parallax targets — see the
   .hw-video-launch rule below for why that matters). */
.hw-video-frame {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
}

.hw-video-frame__poster {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hw-video-frame::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(11, 27, 42, 0.24) 0%, rgba(11, 27, 42, 0.58) 100%);
	pointer-events: none;
}

/* Solid tint, deliberately NOT backdrop-filter glass — .hw-video-card (this
   button's own ancestor) is one of initParallax()'s scroll-tracked
   elements in hawehuis-motion.js, which keeps a live `transform` on it
   throughout the scroll. This project's CLAUDE.md documents an entire
   multi-round saga caused by exactly this: a transform on ANY ancestor
   blocks backdrop-filter on a descendant from sampling anything behind it.
   A flat tint sidesteps that whole bug class rather than risk reintroducing
   it for a play button that doesn't need to be glass. */
.hw-video-launch {
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	padding: 1rem 1.9rem;
	transform: translate(-50%, -50%);
	border: 1px solid rgba(255, 255, 255, 0.32);
	border-radius: 999px;
	color: var(--hw-white);
	background: rgba(11, 27, 42, 0.68);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.35s ease, border-color 0.35s ease, transform 0.35s cubic-bezier(0.25, 1, 0.5, 1);
}

.hw-video-launch:hover {
	background: rgba(11, 27, 42, 0.82);
	border-color: rgba(214, 173, 103, 0.5);
	transform: translate(-50%, -50%) scale(1.03);
}

.hw-video-launch__icon {
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	border-radius: 999px;
	background: var(--hw-gold);
	color: var(--hw-navy-deep);
}

.hw-video-launch__icon svg {
	margin-left: 2px;
}

.hw-video-frame iframe {
	position: absolute;
	inset: 0;
	z-index: 2;
	width: 100%;
	height: 100%;
	border: 0;
}

.hw-video-fallback {
	margin-top: 0.9rem !important;
	text-align: center;
	font-size: 0.68rem;
	letter-spacing: 0.1em;
}

.hw-video-fallback a {
	color: var(--hw-text-light);
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.3s ease;
}

.hw-video-fallback a:hover {
	color: var(--hw-gold-ink);
}

/* Text column + video card sit side by side rather than stacked, same
   "text column / visual column" split recipe as .hw-message-split
   elsewhere on this site. */
.hw-film-split {
	display: grid;
	grid-template-columns: 0.85fr 1.15fr;
	gap: clamp(2.5rem, 5vw, 4rem);
	align-items: center;
}

/* #film and #photos are two independently-padded .hw-section elements
   stacked back to back — the standard sitewide pattern (each section's own
   padding-bottom + the next one's padding-top, ~128px combined at desktop
   widths) reads fine everywhere else, but felt like too much dead space
   specifically between the video and the gallery grid below it (reported
   live, 2026-07-31: measured 128px from the video card's bottom edge to
   "Photo Gallery"). Tightened only this one boundary rather than the
   shared .hw-section value, which would affect every section on every
   page. */
#film {
	padding-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

#photos {
	padding-top: clamp(1.25rem, 2.5vw, 2rem);
}

.hw-film-intro h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 1rem !important;
}

.hw-film-intro p {
	color: var(--hw-text-light);
	font-size: 1.02rem;
	line-height: 1.7;
	margin-bottom: 0 !important;
}

/* GALLERY INTRO */
.hw-gallery-intro h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 2rem !important;
}

/* FILTER TABS */
.hw-gallery-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-bottom: clamp(2rem, 4vw, 2.75rem);
}

.hw-gallery-filter {
	font-family: inherit;
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-weight: 600;
	padding: 0.6rem 1.25rem;
	min-height: 44px;
	border-radius: 999px;
	border: 1px solid var(--hw-border);
	background: var(--hw-cream-light);
	color: var(--hw-text-light);
	cursor: pointer;
	transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}

.hw-gallery-filter:hover {
	border-color: var(--hw-gold);
	color: var(--hw-text);
}

.hw-gallery-filter.is-active {
	background: var(--hw-navy);
	border-color: var(--hw-navy);
	color: var(--hw-white);
}

/* PHOTO GRID */
.hw-gallery-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1rem;
}

.hw-gallery-item {
	border-radius: var(--hw-radius-sm);
	overflow: hidden;
	box-shadow: var(--hw-shadow-sm);
}

.hw-gallery-item[hidden] {
	display: none;
}

.hw-gallery-item .hw-photo-fill {
	aspect-ratio: 1 / 1;
	border-radius: inherit;
}

.hw-gallery-item:hover .hw-photo-fill img {
	transform: scale(1.05);
}

/* ==========================================================================
   THE AREA GUIDE PAGE
   ========================================================================== */

/* MAP + "EVERYTHING WITHIN REACH" — stacked, not side-by-side: the map
   reads better full-width/bigger, with the distances card as a full-width
   horizontal band underneath rather than squeezed into a narrow column. */
.hw-area-map-split {
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 4vw, 3rem);
}

/* Holds the real Stilbaai Kaart illustration (2026-07-31) — was a
   click-to-load Google Maps iframe facade before real map artwork existed;
   replaced wholesale rather than kept alongside it. The gradient background
   is just a loading-state fallback behind the photo now, and the panel
   keeps its own class (rather than being renamed) so it keeps the
   scroll-reveal treatment already targeting it in hawehuis-motion.js. */
.hw-area-map-panel {
	position: relative;
	aspect-ratio: 16 / 9;
	border-radius: var(--hw-radius);
	overflow: hidden;
	box-shadow: var(--hw-shadow);
	background:
		linear-gradient(180deg, rgba(7, 24, 41, 0.55) 0%, rgba(7, 24, 41, 0.82) 100%),
		linear-gradient(135deg, var(--hw-navy) 0%, #3c5876 100%);
}

/* Reuses .hw-unit-card's liquid-glass shell verbatim (applied as a second
   class in the markup) — this panel sits on the same flat-cream .hw-section
   background .hw-unit-card was already built for, so its dark-glass recipe
   and white/gold-light text conventions apply directly, no new glass CSS
   needed. Only the list-specific styling below is new. */
.hw-area-info-panel {
	padding: clamp(1.75rem, 3vw, 2.5rem);
}

.hw-area-info-panel h2 {
	color: var(--hw-white);
	font-size: 1.7rem;
	margin-bottom: 0.25rem !important;
}

/* Now that the panel spans the full page width (below the bigger map,
   not squeezed into a narrow side column — see .hw-area-map-split above),
   the 12 distance rows read better as a horizontal multi-column grid than
   one long vertical list. */
.hw-area-info-list {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0 clamp(1.5rem, 3vw, 2.5rem);
	margin: 1.5rem 0 !important;
}

.hw-area-info-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.85rem 0;
	border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

/* Drops the divider under the grid's actual last row (the last 3 of 12
   items, at the current 3-column width — the count/column assumption to
   revisit if this list's item count or column count ever changes). */
.hw-area-info-row:nth-last-child(-n+3) {
	border-bottom: 0;
}

.hw-area-info-row__label {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.hw-area-info-row__icon {
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: 8px;
	background: rgba(255, 255, 255, 0.05);
	color: var(--hw-gold);
	flex-shrink: 0;
}

.hw-area-info-row__icon svg {
	width: 15px;
	height: 15px;
}

.hw-area-info-row__text {
	color: rgba(255, 255, 255, 0.9);
	font-size: 0.88rem;
}

.hw-area-info-row__value {
	color: rgba(255, 255, 255, 0.6);
	font-size: 0.85rem;
	white-space: nowrap;
}

.hw-area-info-note {
	font-size: 0.72rem;
	font-style: italic;
	color: rgba(255, 255, 255, 0.55);
	margin-bottom: 1.5rem !important;
}

/* DIRECTIONS CARDS — reuses .hw-explore-grid/.hw-explore-card verbatim
   (built for the Experience page's icon-only cards); only the 3-column
   variant and the link-list inside the "Open in Maps" card are new. */
.hw-explore-grid--3 {
	grid-template-columns: repeat(3, 1fr);
}

.hw-explore-grid--2 {
	grid-template-columns: repeat(2, 1fr);
}

.hw-directions-card__links {
	display: flex;
	flex-direction: column;
	gap: 0.65rem;
	margin-top: 1.25rem;
}

.hw-directions-card__links a,
.hw-directions-card__links button {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	border: 0;
	background: none;
	padding: 0;
	margin: 0;
	font-family: inherit;
	color: var(--hw-gold-ink);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	transition: color 0.2s ease;
}

.hw-directions-card__links a:hover,
.hw-directions-card__links button:hover {
	color: var(--hw-navy);
}

/* ==========================================================================
   THE CONTACT PAGE
   ========================================================================== */

/* "Send a Message" split — text/pills column beside the WhatsApp CTA card,
   same 2-column-collapsing-to-1 pattern as .hw-film-split. */
.hw-message-split {
	display: grid;
	grid-template-columns: 0.85fr 1.15fr;
	gap: clamp(2.5rem, 5vw, 4rem);
	/* Was align-items:start — the intro column (heading + paragraph + a
	   4-pill row that wraps to 2 lines at most widths) runs noticeably
	   taller than the WhatsApp card's own shorter copy, so top-aligning
	   left ~100px of bare section background visible below the card before
	   the next section's own padding even started, reading as a much
	   bigger gap than any other section boundary on the site (measured
	   live, 2026-07-31: 213px from the card's bottom edge to the next
	   section's kicker, vs. the standard 128px = two stacked .hw-section
	   paddings everywhere else). Stretch instead, so the card's glass
	   shell fills the row — paired with justify-content:center below so
	   its own content settles in the middle of that taller shell rather
	   than leaving empty glass at the bottom. */
	align-items: stretch;
}

.hw-contact-intro h2 {
	font-size: var(--hw-size-medium);
	margin-bottom: 1rem !important;
}

.hw-contact-intro > p {
	color: var(--hw-text-light);
	font-size: 1.02rem;
	line-height: 1.75;
	margin-bottom: 1.75rem !important;
}

/* Reuses .hw-unit-card's liquid-glass shell verbatim (second class in the
   markup), same pattern as .hw-area-info-panel — the WhatsApp CTA sits on
   the same flat-cream .hw-section background that shell was already built
   for. Was a real contact form's card until the 2026-07-28 switch to
   WhatsApp-as-primary-contact (no domain email to reliably deliver form
   submissions from); see Known issues in CLAUDE.md. */
.hw-contact-cta-card {
	padding: clamp(1.75rem, 3vw, 2.5rem);
	justify-content: center;
}

.hw-contact-cta-card h2 {
	color: var(--hw-white);
	font-size: 1.7rem;
	margin-bottom: 0.4rem !important;
}

.hw-contact-cta-card > p {
	color: rgba(255, 255, 255, 0.68);
	font-size: 0.92rem;
	margin-bottom: 1.75rem !important;
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 1024px) {
	.hw-welcome,
	.hw-testimonial-inner,
	.hw-unit-deepdive,
	.hw-message-split,
	.hw-film-split {
		grid-template-columns: 1fr;
	}

	.hw-area-info-list {
		grid-template-columns: repeat(2, 1fr);
	}

	/* The desktop 3-column border-removal rule (nth-last-child(-n+3)) would
	   strip the divider off the last 3 rows instead of the last 2 that
	   actually form the bottom row at 2 columns. */
	.hw-area-info-row:nth-last-child(-n+3) {
		border-bottom: 1px solid rgba(255, 255, 255, 0.12);
	}

	.hw-area-info-row:nth-last-child(-n+2) {
		border-bottom: 0;
	}

	/* Reset the desktop-only visual reorder — on a single column, Unit
	   Two's photo should sit in normal DOM order (text, then photo) like
	   Unit One's, not float above the heading. */
	.hw-unit-deepdive--reverse .hw-unit-deepdive-intro,
	.hw-unit-deepdive--reverse .hw-unit-photo-hero {
		order: 0;
	}

	.hw-experience-editorial-grid,
	.hw-experience-mini-grid,
	.hw-explore-grid,
	.hw-explore-grid--3 {
		grid-template-columns: repeat(2, 1fr);
	}

	.hw-gallery-grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.hw-tagline-content {
		/* .hw-tagline-split is display:block, not grid, since the
		   2026-07-20 full-bleed rework — this only needs horizontal
		   breathing room now, the base rule has none since desktop relies
		   on max-width:640px + auto margins. */
		padding: 0 1.5rem;
	}

	.hw-distance-row {
		grid-template-columns: repeat(3, 1fr);
	}

	.hw-distance-item:nth-child(3n + 1) {
		border-left: none;
		padding-left: 0;
	}

	.hw-distance-item:nth-child(n + 4) {
		border-top: 1px solid rgba(255, 255, 255, 0.16);
		padding-top: 1.25rem;
	}

	.hw-footer-inner {
		grid-template-columns: 1fr 1fr;
		row-gap: 2.5rem;
	}
}

@media (max-width: 900px) {
	/* !important needed for both: wp:buttons and wp:navigation each carry
	   their own is-layout-flex class (specificity 0,2,0), which otherwise
	   beats a plain single-class override at any source order (see
	   Conventions in CLAUDE.md — the .hw-menu is wp:navigation again as of
	   2026-07-28, restored with overlayMenu:"never" after the 2026-07-20
	   plain-HTML detour; this !important was already needed for exactly
	   this reason before that detour too). */
	.hw-menu,
	.hw-nav-button {
		display: none !important;
	}

	/* .hw-menu is a sibling of .hw-header, not a child (wp:navigation can't
	   nest inside the raw wp:html header block) — position:fixed with a
	   hand-matched top offset avoids depending on ancestor positioning. */
	.hw-menu.hw-menu-open {
		display: flex !important;
		position: fixed;
		top: 84px;
		left: 4%;
		right: 4%;
		z-index: 99;
		flex-direction: column;
		align-items: flex-start;
		gap: 0;
		background: var(--hw-navy-deep);
		border-radius: 14px;
		padding: 1rem 1.5rem 1.5rem;
		box-shadow: var(--hw-shadow);
		max-height: calc(100vh - 104px);
		overflow-y: auto;
	}

	/* The <ul class="wp-block-navigation__container"> (also carrying our
	   own .hw-menu class, per how wp:navigation duplicates its className
	   onto the inner container) computes to display:none inside the open
	   mobile drawer, collapsing every link inside it to a 0x0 rect —
	   confirmed live (getComputedStyle + getBoundingClientRect, not
	   guessed) that this is a real cascade conflict, not a state/timing
	   artifact: forcing display:flex via an inline !important override
	   restored all 7 links to real, correct sizes immediately. The exact
	   source rule couldn't be pinned down via document.styleSheets
	   enumeration (checked every top-level and @media/@supports-nested
	   rule; none matched via Element.matches()) — flagged as weaker
	   verification than this project's usual root-cause standard, but the
	   fix itself IS confirmed effective, not a guess. */
	.hw-menu.hw-menu-open .wp-block-navigation__container {
		display: flex !important;
		/* Core's own is-layout-flex support defaults this inner <ul> to
		   flex-direction:row + flex-wrap:wrap regardless of the outer <nav>'s
		   column direction (they're two separate flex containers — the <nav>
		   just has one child, this <ul>) — confirmed live 2026-07-31: without
		   this, the 7 drawer links pack 3-per-row instead of stacking, since
		   nothing here had ever overridden the row axis, only visibility. */
		flex-direction: column !important;
		align-items: stretch !important;
		width: 100%;
	}

	.hw-menu.hw-menu-open a {
		display: block;
		padding: 0.75rem 0;
		width: 100%;
		border-bottom: 1px solid rgba(255, 255, 255, 0.12);
	}

	/* The "always-reachable Book CTA" the desktop pill nav has, restored
	   inside the mobile drawer — .hw-nav-button is hidden entirely at
	   this width (above) with nothing replacing it until now.
	   !important on display: the desktop .hw-menu-book{display:none!important}
	   rule above (needed to beat wp:navigation's own (0,2,0) core rule)
	   would otherwise also beat THIS rule despite its higher specificity —
	   !important always wins over specificity regardless of selector, so
	   this needs its own !important to win the tie against that one. */
	.hw-menu.hw-menu-open .hw-menu-book {
		display: flex !important;
		align-items: center;
		justify-content: center;
		margin-top: 0.75rem;
		padding: 0.85rem 1rem;
		border-bottom: none;
		background: var(--hw-gold);
		color: var(--hw-navy-deep);
		border-radius: var(--hw-radius-sm);
		font-size: 0.78rem;
		font-weight: 600;
		letter-spacing: 0.08em;
		text-transform: uppercase;
	}

	/* .hw-menu-book's className lands on the <li> (wp:navigation wraps every
	   link's className there, not on the <a> — confirmed via render_block()
	   before writing this), so the pill styling above is on the <li> while
	   the actual clickable element is still the child <a>. Without this
	   reset, the sibling ".hw-menu.hw-menu-open a" rule's own padding/
	   border-bottom would double up inside the pill. */
	.hw-menu.hw-menu-open .hw-menu-book a {
		display: block;
		width: 100%;
		padding: 0;
		border-bottom: none;
		color: inherit;
		text-align: center;
	}

	.hw-nav-toggle {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.hw-unit-grid {
		grid-template-columns: 1fr;
	}

	.hw-gallery-strip {
		grid-template-columns: repeat(3, 1fr);
	}

	.hw-unit-gallery {
		grid-template-columns: repeat(2, 1fr);
	}

	.hw-unit-gallery-item:nth-child(1),
	.hw-unit-gallery-item:nth-child(2),
	.hw-unit-gallery-item:nth-child(3),
	.hw-unit-gallery-item:nth-child(4),
	.hw-unit-gallery-item:nth-child(5),
	.hw-unit-gallery-item:nth-child(6) {
		grid-column: span 1;
	}

	.hw-feature-item {
		flex: 1 1 100%;
		border-left: none;
		padding-left: 0;
		border-top: 1px solid var(--hw-border);
		padding-top: 1.25rem;
	}

	.hw-feature-item:first-child {
		border-top: none;
		padding-top: 0;
	}
}

/* Touch-target enhancement — screen size doesn't tell you input method
   (a touch laptop can be 1440px wide), so this targets coarse pointers
   directly rather than a viewport breakpoint. Desktop-nav links and
   footer links stay visually compact for mouse users; touch users get
   a full 44px hit area without any layout/type-scale change. */
@media (pointer: coarse) {
	.hw-menu a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	.hw-footer-col ul a {
		padding: 12px 0;
	}
}

@media (max-width: 768px) {
	.hw-section {
		padding: 3.5rem 6vw;
	}

	.hw-welcome-section {
		padding-top: 2rem;
		padding-bottom: 2rem;
	}

	.hw-header {
		top: 12px;
		left: 4vw;
		right: 4vw;
		/* Asymmetric on purpose (2026-07-31 request) — left cut ~50% (1.1rem
		   -> 0.55rem) so the logo sits further left, right cut ~20% (1.1rem
		   -> 0.88rem) rather than matching, since the toggle button below
		   needs its own added margin-right for breathing room and an equal
		   50% cut here would have left it flush against the pill's rounded
		   corner. */
		padding: 0.35rem 0.88rem 0.35rem 0.55rem;
		/* The base 2rem gap was sized for the desktop row's 4 children
		   (logo/menu/button/toggle); mobile only ever shows 2 (logo row +
		   toggle, the other two are display:none below 900px), so that much
		   gap was pure unused space — confirmed live at 390px it was the
		   difference between the toggle fitting at its full 54px vs. being
		   forced to shrink to ~32px by flex-shrink. */
		gap: 0.5rem;
	}

	/* Space between the round logo mark and the "DIE HAWEHUIS / Stilbaai"
	   text stack cut ~40% (0.6rem -> 0.36rem, 2026-07-31 request) — reads
	   more balanced on mobile than the desktop gap, which has more room
	   either side of the whole lockup to begin with. */
	.hw-logo-mark-row {
		gap: 0.36rem;
	}

	.hw-menu.hw-menu-open {
		top: 68px;
		max-height: calc(100vh - 88px);
	}

	.hw-hero {
		min-height: 100svh;
		align-items: flex-end;
		padding-bottom: 5.5rem;
	}

	.hw-experience-feature {
		min-height: clamp(360px, 56vh, 520px);
		padding: 2.5rem 6vw;
	}

	.hw-experience-feature--compact {
		min-height: clamp(280px, 40vh, 380px);
	}

	.hw-booking-bar-wrap {
		/* Kept under .hw-hero's own 5.5rem padding-bottom here so it can't
		   creep up over the hero-content text on small screens. */
		margin-top: -5rem;
		padding: 0 6vw;
		scroll-margin-top: 170px;
	}

	.hw-booking-note {
		padding: 0 6vw;
	}

	.hw-booking-bar {
		flex-direction: column;
		align-items: stretch;
	}

	/* .hw-booking-field's base `flex: 1 1 160px` sets a 160px *width* basis
	   for the desktop row layout — reinterpreted as a *height* basis once
	   flex-direction switches to column here, and combined with flex-grow:1
	   across 4 stacked fields with nothing capping the container's height,
	   each field visually inflated to fill leftover vertical space (huge
	   grey boxes, confirmed via a real screenshot 2026-07-24). Reset to
	   auto-sized-to-content on the column axis; min-width:0 since width no
	   longer needs a minimum once the field spans the full stretched row. */
	.hw-booking-field {
		flex: 0 0 auto;
		min-width: 0;
	}

	.hw-booking-submit {
		width: 100%;
		justify-content: center;
	}

	.hw-gallery-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.hw-distance-row {
		grid-template-columns: repeat(2, 1fr);
	}

	.hw-distance-item:nth-child(3n + 1) {
		border-left: 1px solid rgba(255, 255, 255, 0.16);
		padding-left: 1rem;
	}

	.hw-distance-item:nth-child(2n + 1) {
		border-left: none;
		padding-left: 0;
	}

	.hw-distance-item:nth-child(n + 4) {
		border-top: none;
		padding-top: 0;
	}

	.hw-distance-item:nth-child(n + 3) {
		border-top: 1px solid rgba(255, 255, 255, 0.16);
		padding-top: 1.25rem;
	}

	.hw-footer-inner {
		grid-template-columns: 1fr;
		text-align: center;
	}

	.hw-feature-item {
		justify-content: center;
	}
}

@media (max-width: 430px) {
	.hw-hero-content {
		max-width: 100%;
	}

	.hw-gallery-strip {
		grid-template-columns: repeat(3, 1fr);
		gap: 0.5rem;
	}

	.hw-unit-gallery {
		grid-template-columns: 1fr;
	}

	.hw-area-info-list {
		grid-template-columns: 1fr;
	}

	/* The desktop 3-column border-removal rule (nth-last-child(-n+3)) would
	   otherwise strip the divider off the last 3 rows here instead of just
	   the true last one, now that it's back to a single column. */
	.hw-area-info-row:nth-last-child(-n+3) {
		border-bottom: 1px solid rgba(255, 255, 255, 0.12);
	}

	.hw-area-info-row:last-child {
		border-bottom: 0;
	}

	.hw-experience-editorial-grid,
	.hw-experience-mini-grid,
	.hw-explore-grid,
	.hw-explore-grid--3,
	.hw-explore-grid--2 {
		grid-template-columns: 1fr;
	}
}

/* Respect reduced-motion preference for any future animation on this site. */
@media (prefers-reduced-motion: reduce) {
	.hw-page * {
		animation: none !important;
		transition: none !important;
	}

	.hw-header.hw-header--hidden {
		transform: none;
	}
}
