/* ===========================================================================
   Casa Cali — casacali.rent
   Implements the "Casa Cali" canvas from the Cabo Airbnb Design Direction
   project, including the mobile revision.

   Sizing is fluid — clamp() on type and spacing, auto-fit on the simple grids
   — so most of the layout has no breakpoint at all. Media queries are reserved
   for the four compositions where something other than column count changes
   (source order, inset, border, sticky). See "Stacking" near the bottom.
   =========================================================================== */

/* --- Fonts -------------------------------------------------------------- */
/* Self-hosted, latin subset only. Alegreya is a variable font, so one file
   covers the whole 400-800 range; Alegreya Sans ships static weights.
   Alegreya Sans has no 600 — the `600` labels below resolve up to 700, which
   is exactly what the design canvas rendered. */
@font-face {
	font-family: 'Alegreya';
	src: url('/assets/fonts/alegreya-var.woff2') format('woff2-variations');
	font-weight: 400 800;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Alegreya Sans';
	src: url('/assets/fonts/alegreya-sans-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Alegreya Sans';
	src: url('/assets/fonts/alegreya-sans-500.woff2') format('woff2');
	font-weight: 500;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Alegreya Sans';
	src: url('/assets/fonts/alegreya-sans-700.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* --- Tokens ------------------------------------------------------------- */
:root {
	--bone: #F4F3EF;
	--bone-2: #EDEEEA;
	--ink: #0E1A21;
	--ink-2: #22323A;
	--slate: #3A4750;
	--slate-2: #4A5A61;
	/* --grey and --grey-2 hold the same value since the 2026-08-24 palette
	   revision, which raised both to clear WCAG AA. They stay separate tokens
	   because they mark different roles — nav links vs. labels and captions —
	   so the two can diverge again without hunting through call sites. */
	--grey: #636E72;
	--grey-2: #636E72;
	--teal: #14384A;
	--rust: #966442;
	--rust-lt: #C79A75;
	--focus: #966442;   /* = --rust; re-pointed on dark surfaces below */
	--rule: #D3D6D2;
	--rule-2: #C3CBC9;
	/* Borders on interactive controls need 3:1 against their background
	   (WCAG 1.4.11 non-text contrast); --rule-2 is a decorative hairline at
	   1.35:1 and is not strong enough to outline a button. */
	--rule-strong: #7D8A8E;
	--rule-3: #D9DDD9;
	--rule-dark: #2A3D48;
	--on-teal: #E4EBEE;
	--on-teal-2: #C3D3DA;
	--on-ink: #DCE4E7;
	--on-ink-2: #A9BEC6;
	--on-ink-3: #7E939C;
	--on-ink-4: #6D858E;

	--serif: 'Alegreya', Georgia, 'Times New Roman', serif;
	--sans: 'Alegreya Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

	--shell: 1240px;
	--gutter: clamp(20px, 5vw, 48px);
	--bar-h: 70px;

	/* Recurring fluid ramps, named so a size change happens in one place. */
	--eyebrow-size: clamp(11px, 2.6vw, 12px);
	--h2-size: clamp(31px, 6vw, 44px);
	--prose-size: clamp(17px, 2.1vw, 19px);
	--note-size: clamp(17px, 2vw, 18px);
	--section-gap: clamp(56px, 9vw, 104px);
}

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

html {
	scroll-behavior: smooth;
	/* Sticky header would otherwise cover the top of a jumped-to section. */
	scroll-padding-top: 88px;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--bone);
	color: var(--ink-2);
	font-family: var(--sans);
	font-size: 16px;
	line-height: 1.5;
	overflow-x: hidden;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, p, figure, figcaption { margin: 0; }
img { max-width: 100%; }

a { color: var(--teal); text-decoration: none; }
a:hover { color: var(--rust); }

::selection { background: var(--teal); color: var(--bone); }

/* The focus ring needs 3:1 against whatever sits behind it (WCAG 2.4.11), and
   no single colour clears that on both the bone and the dark sections. --focus
   cascades, so a dark band re-points it once and every control inside follows.
   Rust: 4.50 on bone, 2.48 on teal. Light rust: 4.90 on teal, 6.99 on ink. */
:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 3px;
}
.rooftop, .book, .lightbox { --focus: var(--rust-lt); }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* --- Helpers ------------------------------------------------------------ */
.shell {
	max-width: var(--shell);
	margin: 0 auto;
	padding: 0 var(--gutter);
}

.skip {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--teal);
	color: var(--bone);
	padding: 12px 20px;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.06em;
}
.skip:focus { left: 0; color: var(--bone); }

.eyebrow {
	font-size: var(--eyebrow-size);
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--rust);
}
.eyebrow--light { color: var(--rust-lt); }

.eyebrow-rule { display: flex; align-items: center; gap: 12px; }
.eyebrow-rule::before {
	content: '';
	width: 26px;
	height: 1px;
	background: var(--rust);
	flex: none;
}

.prose {
	font-family: var(--serif);
	font-size: var(--prose-size);
	line-height: 1.62;
	color: var(--slate);
	text-wrap: pretty;
}

.h2 {
	font-family: var(--serif);
	font-size: var(--h2-size);
	font-weight: 500;
	line-height: 1.08;
	letter-spacing: -0.025em;
	color: var(--ink);
	text-wrap: balance;
}

.btn {
	display: inline-block;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	color: var(--bone);
	background: var(--teal);
	padding: 17px clamp(24px, 5vw, 32px);
	text-align: center;
	transition: background-color 0.18s ease;
}
.btn:hover, .btn:focus-visible { background: var(--ink); color: var(--bone); }

.btn--invert {
	font-size: 16px;
	color: var(--ink);
	background: var(--bone);
	padding: 18px clamp(28px, 6vw, 38px);
}
.btn--invert:hover, .btn--invert:focus-visible { background: var(--rust-lt); color: var(--ink); }

.btn--sm {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 11px 20px;
}

.link-rule {
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.06em;
	color: var(--slate);
	border-bottom: 1px solid var(--rust);
	padding-bottom: 3px;
}
.link-rule:hover { color: var(--rust); }

/* --- Header ------------------------------------------------------------- */
.site-header {
	position: sticky;
	top: 0;
	z-index: 40;
	background: var(--bone);
	border-bottom: 1px solid var(--rule);
}
.site-header__inner {
	min-height: 68px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
}
.wordmark {
	font-family: var(--serif);
	font-size: clamp(22px, 5vw, 26px);
	font-weight: 500;
	letter-spacing: -0.015em;
	color: var(--ink);
	white-space: nowrap;
}
.wordmark:hover { color: var(--rust); }

.site-nav {
	display: flex;
	align-items: center;
	gap: clamp(16px, 2.4vw, 32px);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--grey);
}
.site-nav a { color: inherit; }
.site-nav a:hover { color: var(--rust); }
.site-nav .btn--sm { color: var(--bone); }

/* Hamburger. Hidden above the stacking width; see "Stacking". */
.menu-toggle {
	display: none;
	align-items: center;
	gap: 9px;
	background: none;
	border: 1px solid var(--rule-strong);
	padding: 12px 15px;
	min-height: 46px;
	cursor: pointer;
	font-family: var(--sans);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--teal);
}
.menu-toggle__bars {
	display: flex;
	flex-direction: column;
	gap: 4px;
	width: 16px;
}
.menu-toggle__bars span {
	height: 1.5px;
	background: var(--teal);
	display: block;
}
/* One element, two labels — the open state swaps them with no JS text edit. */
.menu-toggle__close { display: none; }
.menu-toggle[aria-expanded="true"] .menu-toggle__open { display: none; }
.menu-toggle[aria-expanded="true"] .menu-toggle__close { display: inline; }

.menu-panel {
	border-top: 1px solid var(--rule);
	background: var(--bone-2);
	display: flex;
	flex-direction: column;
	padding: 8px var(--gutter) 22px;
}
.menu-panel[hidden] { display: none; }
.menu-panel a {
	padding: 15px 0;
	border-bottom: 1px solid var(--rule-3);
	font-family: var(--serif);
	font-size: 21px;
	color: var(--ink);
}
.menu-panel a:last-child { border-bottom: none; }

/* --- Hero --------------------------------------------------------------- */
.hero { border-bottom: 1px solid var(--rule); }
.hero__grid {
	display: grid;
	grid-template-columns: 1fr 1.05fr;
	align-items: stretch;
}
.hero__copy {
	order: 1;
	padding-top: clamp(32px, 6vw, 78px);
	padding-right: clamp(0px, 4vw, 56px);
	padding-bottom: clamp(38px, 5vw, 70px);
	padding-left: clamp(0px, 3.5vw, 52px);
	display: flex;
	flex-direction: column;
	gap: clamp(18px, 2.4vw, 26px);
	justify-content: center;
}
.hero h1 {
	font-family: var(--serif);
	font-size: clamp(38px, 8vw, 62px);
	font-weight: 500;
	line-height: 1.02;
	letter-spacing: -0.03em;
	color: var(--ink);
	text-wrap: balance;
}
.hero__lede {
	font-family: var(--serif);
	font-size: clamp(18px, 2.3vw, 21px);
	line-height: 1.55;
	color: var(--slate);
	max-width: 46ch;
	text-wrap: pretty;
}
.hero__actions {
	display: flex;
	align-items: center;
	gap: clamp(16px, 2.5vw, 22px);
	flex-wrap: wrap;
	padding-top: 6px;
}
.hero__media {
	order: 2;
	border-left: 1px solid var(--rule);
	min-height: clamp(300px, 62vw, 540px);
}

/* Fill-the-slot images: sized by their container, cropped with object-fit. */
.fill, .fill img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --- Facts strip -------------------------------------------------------- */
.facts {
	border-bottom: 1px solid var(--rule);
	background: var(--bone-2);
}
/* The dividers are the grid gap showing the container colour through. Wraps to
   any column count without a single nth-child rule deciding who owns an edge. */
.facts__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 1px;
	background: var(--rule);
}
.fact {
	background: var(--bone-2);
	padding: clamp(18px, 3vw, 26px) clamp(14px, 2vw, 24px);
	display: flex;
	flex-direction: column;
	gap: 5px;
}
.fact__num {
	font-family: var(--serif);
	font-size: clamp(26px, 4vw, 30px);
	font-weight: 500;
	color: var(--teal);
	line-height: 1;
}
.fact__label {
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--grey-2);
}

/* --- The house ---------------------------------------------------------- */
.house { padding-top: var(--section-gap); }
.house__grid {
	display: grid;
	grid-template-columns: 0.85fr 1.15fr;
	gap: clamp(36px, 5vw, 72px);
	align-items: start;
}
.house__copy {
	display: flex;
	flex-direction: column;
	gap: clamp(16px, 2.2vw, 22px);
	position: sticky;
	top: 100px;
}
.chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	padding-top: 8px;
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}
.chips li {
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--slate-2);
	border: 1px solid var(--rule-2);
	padding: 9px 13px;
}
.house__media { display: flex; flex-direction: column; gap: 14px; }
.house__pair {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 14px;
}
.shot { display: flex; flex-direction: column; gap: 10px; }
.shot img { display: block; width: 100%; object-fit: cover; }
.shot--tall img { height: clamp(280px, 50vw, 480px); }
/* height:auto is load-bearing. The HTML width/height attributes map to
   presentational hints for the CSS width and height properties, so the
   height attribute would otherwise beat the implicit auto that aspect-ratio
   depends on, and the image would render at its intrinsic pixel height. */
.shot--short img { aspect-ratio: 3 / 4; height: auto; }
.shot figcaption {
	font-size: 13px;
	letter-spacing: 0.04em;
	color: var(--grey-2);
}

/* --- Rooftop ------------------------------------------------------------ */
.rooftop {
	margin-top: clamp(60px, 9vw, 112px);
	background: var(--teal);
	color: var(--on-teal);
}
.rooftop .shell {
	padding-top: clamp(56px, 8vw, 96px);
	padding-bottom: clamp(58px, 8vw, 100px);
}
.rooftop__head {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
	gap: clamp(26px, 5vw, 72px);
	align-items: end;
	padding-bottom: clamp(34px, 5vw, 56px);
}
.rooftop__intro {
	display: flex;
	flex-direction: column;
	gap: clamp(16px, 2.2vw, 22px);
}
.rooftop h2 {
	font-family: var(--serif);
	font-size: clamp(32px, 6.4vw, 48px);
	font-weight: 500;
	line-height: 1.05;
	letter-spacing: -0.028em;
	color: var(--bone);
	text-wrap: balance;
}
.rooftop__body { display: flex; flex-direction: column; gap: 18px; }
.rooftop__body p {
	font-family: var(--serif);
	font-size: clamp(17px, 2.2vw, 20px);
	line-height: 1.6;
	color: var(--on-teal-2);
	text-wrap: pretty;
}
.rooftop__strip {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
	gap: clamp(10px, 1.5vw, 16px);
}
.rooftop__strip img {
	display: block;
	width: 100%;
	height: clamp(280px, 34vw, 400px);
	object-fit: cover;
}

/* --- Sleeping ----------------------------------------------------------- */
.sleep { padding-top: var(--section-gap); }
.sleep__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: clamp(20px, 4vw, 48px);
	padding-bottom: clamp(28px, 4vw, 44px);
	border-bottom: 1px solid var(--rule);
}
.sleep__title {
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 620px;
	flex: 1 1 300px;
}
.sleep__note {
	font-family: var(--serif);
	font-size: var(--note-size);
	line-height: 1.6;
	color: var(--slate);
	max-width: 40ch;
	flex: 1 1 280px;
	text-wrap: pretty;
}
.rooms {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 215px), 1fr));
	gap: clamp(16px, 2vw, 20px);
	padding-top: clamp(26px, 3.5vw, 40px);
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}
.room { display: flex; flex-direction: column; gap: 14px; }
.room img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	height: auto;   /* see the note on .shot--short img */
	object-fit: cover;
}
.room__meta { display: flex; flex-direction: column; gap: 5px; }
.room__name {
	font-family: var(--serif);
	font-size: 22px;
	font-weight: 500;
	color: var(--ink);
}
.room__beds { font-size: 14.5px; color: var(--slate-2); letter-spacing: 0.02em; }
.room__bath {
	font-size: 11.5px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--rust);
}

/* Steps & access. Deliberately plain and in the flow of the page rather than
   set apart as a disclaimer — it is useful information, not fine print. */
.access {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
	gap: clamp(14px, 3vw, 48px);
	margin-top: clamp(32px, 5vw, 52px);
	padding-top: clamp(22px, 3vw, 28px);
	border-top: 1px solid var(--rule);
}
.access__text {
	font-family: var(--serif);
	font-size: var(--note-size);
	line-height: 1.6;
	color: var(--slate);
	max-width: 62ch;
	text-wrap: pretty;
}

/* --- Cabo Bello --------------------------------------------------------- */
.beach {
	margin-top: clamp(58px, 9vw, 108px);
	border-top: 1px solid var(--rule);
	border-bottom: 1px solid var(--rule);
	background: var(--bone-2);
}
.beach__grid {
	display: grid;
	grid-template-columns: 1.1fr 0.9fr;
	align-items: stretch;
}
.beach__media {
	position: relative;
	border-right: 1px solid var(--rule);
	min-height: clamp(280px, 55vw, 560px);
}
/* The beach panel runs tall beside the copy on desktop and wide once stacked,
   so a centred crop of this 4:3 photo shows mostly sky. Anchor it on the
   sand and the water's edge instead. Tuned for beach-cabo-bello; re-check it
   if the photo changes. */
.beach__media .fill img { object-position: 58% 80%; }

/* Credit for a photograph used with permission. It sits over the image, so
   its background is a translucent --ink rather than a token: at 72% over the
   brightest possible pixel (white sand) it still resolves to about #565F64,
   and --on-ink on that is 5:1. check-a11y.sh cannot test this pair, because
   the backdrop is a photograph, not a colour. */
.photo-credit {
	position: absolute;
	right: 10px;
	bottom: 10px;
	padding: 3px 8px;
	border-radius: 3px;
	background: rgba(14, 26, 33, 0.72);
	color: var(--on-ink);
	font-family: var(--sans);
	font-size: 11.5px;
	letter-spacing: 0.02em;
	line-height: 1.4;
}
.beach__copy {
	padding-top: clamp(40px, 7vw, 88px);
	padding-bottom: clamp(44px, 7vw, 88px);
	padding-left: clamp(0px, 4vw, 60px);
	display: flex;
	flex-direction: column;
	gap: clamp(18px, 2.4vw, 24px);
	justify-content: center;
}

/* Spec rows: label left, value right, hairline between. Used twice. */
.specs {
	display: flex;
	flex-direction: column;
	margin: 0;
	border-top: 1px solid var(--rule);
}
.specs--spaced { padding-top: 12px; }
.spec {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 6px 20px;
	padding: 14px 0;
	border-bottom: 1px solid var(--rule);
}
.spec:last-child { border-bottom: none; }
.spec dt {
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--grey-2);
}
.spec dd {
	margin: 0;
	font-family: var(--serif);
	font-size: 18px;
	color: var(--ink-2);
	text-align: right;
}

/* --- Nearby ------------------------------------------------------------- */
.nearby { padding-top: clamp(56px, 8vw, 100px); }
.nearby__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
	gap: clamp(30px, 5vw, 72px);
	align-items: start;
}
.nearby__intro {
	display: flex;
	flex-direction: column;
	gap: clamp(15px, 2vw, 20px);
}
.nearby h2 { font-size: clamp(30px, 5.6vw, 40px); }
.nearby__note {
	font-family: var(--serif);
	font-size: var(--note-size);
	line-height: 1.6;
	color: var(--slate);
	text-wrap: pretty;
}
.nearby__list {
	display: flex;
	flex-direction: column;
	border-top: 1px solid var(--rule);
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
	counter-reset: nearby;
}
.nearby__item {
	display: flex;
	flex-wrap: wrap;
	gap: 6px clamp(16px, 2.5vw, 24px);
	align-items: baseline;
	padding: clamp(18px, 2.4vw, 22px) 0;
	border-bottom: 1px solid var(--rule);
	counter-increment: nearby;
}
/* The numerals are generated, so an inserted row cannot be numbered wrongly. */
.nearby__item::before {
	content: counter(nearby, decimal-leading-zero);
	font-size: 11.5px;
	font-weight: 700;
	letter-spacing: 0.1em;
	color: var(--rust);
	width: 26px;
	flex: none;
}
.nearby__name {
	font-family: var(--serif);
	font-size: clamp(21px, 3vw, 23px);
	font-weight: 500;
	color: var(--ink);
	letter-spacing: -0.01em;
	flex: 1 1 180px;
}
.nearby__desc {
	font-size: 15px;
	line-height: 1.55;
	color: var(--slate-2);
	flex: 1 1 260px;
}

/* --- Gallery ------------------------------------------------------------ */
.gallery { padding-top: clamp(56px, 8vw, 100px); }
.gallery__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 14px 40px;
	padding-bottom: clamp(22px, 3vw, 32px);
}
.gallery__title { display: flex; flex-direction: column; gap: 14px; }
.gallery h2 { font-size: clamp(30px, 5.6vw, 40px); }
.gallery__hint { font-size: 13px; letter-spacing: 0.04em; color: var(--grey-2); }
/* "Tap" on touch devices, "Click" otherwise — a media query, not a UA sniff. */
.gallery__hint .is-touch { display: none; }
@media (hover: none) and (pointer: coarse) {
	.gallery__hint .is-pointer { display: none; }
	.gallery__hint .is-touch { display: inline; }
}
.gallery__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(48%, 160px), 1fr));
	gap: clamp(8px, 1.2vw, 12px);
}
.thumb {
	padding: 0;
	border: none;
	background: #D9E1E2;
	cursor: pointer;
	display: block;
	overflow: hidden;
	transition: opacity 0.18s ease;
}
.thumb:hover { opacity: 0.88; }
.thumb img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	height: auto;   /* see the note on .shot--short img */
	object-fit: cover;
}

/* --- Book --------------------------------------------------------------- */
.book {
	margin-top: clamp(58px, 9vw, 108px);
	background: var(--ink);
	color: var(--on-ink);
}
.book .shell {
	padding-top: clamp(56px, 8vw, 96px);
	padding-bottom: clamp(52px, 7vw, 84px);
}
.book__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
	gap: clamp(34px, 6vw, 80px);
	align-items: start;
}
.book__copy {
	display: flex;
	flex-direction: column;
	gap: clamp(20px, 2.6vw, 26px);
}
.book h2 {
	font-family: var(--serif);
	font-size: clamp(34px, 6.6vw, 52px);
	font-weight: 500;
	line-height: 1.04;
	letter-spacing: -0.03em;
	color: var(--bone);
	text-wrap: balance;
}
.book__lede {
	font-family: var(--serif);
	font-size: clamp(17px, 2.2vw, 20px);
	line-height: 1.6;
	color: var(--on-ink-2);
	max-width: 52ch;
	text-wrap: pretty;
}
.book__actions {
	display: flex;
	align-items: center;
	gap: clamp(16px, 3vw, 24px);
	flex-wrap: wrap;
	padding-top: 4px;
}
.book__aside { font-size: 14px; letter-spacing: 0.04em; color: var(--on-ink-3); }

.book .specs { border-top-color: var(--rule-dark); }
.book .spec { border-bottom-color: var(--rule-dark); gap: 4px 20px; padding: 16px 0; }
.book .spec dt { color: var(--on-ink-3); font-size: 12px; letter-spacing: 0.14em; }
.book .spec dd { color: var(--on-teal); }

.site-footer { border-top: 1px solid var(--rule-dark); }
.site-footer__inner {
	padding-top: 24px;
	padding-bottom: 24px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px 32px;
	flex-wrap: wrap;
}
.site-footer__name {
	font-family: var(--serif);
	font-size: clamp(18px, 2.4vw, 20px);
	color: var(--on-ink-2);
}
.site-footer__note { font-size: 13px; letter-spacing: 0.06em; color: var(--on-ink-4); }

/* --- Mobile booking bar ------------------------------------------------- */
/* Hidden by default and above the stacking width; site.js adds .is-visible
   once the hero has scrolled past. */
.book-bar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 50;
	background: var(--bone);
	border-top: 1px solid var(--rule-2);
	box-shadow: 0 -6px 24px rgba(14, 26, 33, 0.08);
	padding: 11px clamp(16px, 4vw, 24px) calc(11px + env(safe-area-inset-bottom));
	display: none;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	transform: translateY(100%);
	/* visibility, not just transform: a bar parked off-screen with transform
	   alone stays focusable, so a keyboard user tabs into a "Check dates" link
	   they cannot see. visibility removes it from the tab order and the
	   accessibility tree, and still animates because it is delayed out and
	   applied instantly on the way in. */
	visibility: hidden;
	transition: transform 0.22s ease, visibility 0s linear 0.22s;
}
.book-bar.is-visible {
	transform: translateY(0);
	visibility: visible;
	transition: transform 0.22s ease, visibility 0s linear 0s;
}
.book-bar__meta {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}
.book-bar__name {
	font-family: var(--serif);
	font-size: 19px;
	font-weight: 500;
	color: var(--ink);
	line-height: 1.15;
}
.book-bar__facts {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--grey-2);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.book-bar__cta {
	flex: none;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.05em;
	color: var(--bone);
	background: var(--teal);
	padding: 15px 22px;
	min-height: 48px;
	display: flex;
	align-items: center;
}
.book-bar__cta:hover, .book-bar__cta:focus-visible { background: var(--ink); color: var(--bone); }

/* --- Lightbox ----------------------------------------------------------- */
.lightbox {
	position: fixed;
	inset: 0;
	z-index: 90;
	background: rgba(14, 26, 33, 0.96);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: clamp(52px, 7vw, 64px) clamp(12px, 8vw, 88px) clamp(74px, 9vw, 88px);
	touch-action: pan-y;
}
.lightbox[hidden] { display: none; }
.lightbox__img {
	max-width: 100%;
	/* dvh rather than vh so mobile browser chrome cannot crop the photograph. */
	max-height: calc(100dvh - 210px);
	object-fit: contain;
	display: block;
}
.lightbox__caption {
	padding-top: 18px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	text-align: center;
}
.lightbox__alt {
	font-family: var(--serif);
	font-size: clamp(16px, 3.6vw, 18px);
	color: var(--on-ink);
	max-width: 40ch;
}
.lightbox__count { font-size: 12px; letter-spacing: 0.12em; color: var(--on-ink-4); }

.lightbox button {
	background: none;
	border: none;
	color: var(--on-ink-2);
	cursor: pointer;
	font-family: var(--sans);
	transition: color 0.18s ease;
}
.lightbox button:hover, .lightbox button:focus-visible { color: var(--bone); }

.lightbox__close {
	position: absolute;
	top: 12px;
	right: 12px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	padding: 14px;
	min-width: 48px;
	min-height: 48px;
}
/* Both arrows sit along the bottom edge, within thumb reach on a phone. */
.lightbox__nav {
	position: absolute;
	bottom: 14px;
	font-size: 34px;
	line-height: 1;
	padding: 12px 22px;
	min-width: 52px;
	min-height: 52px;
}
.lightbox__nav--prev { left: 4px; }
.lightbox__nav--next { right: 4px; }

body.is-locked { overflow: hidden; }

/* ===========================================================================
   Stacking

   Most of the layout is fluid and needs no breakpoint. These four
   compositions do, because when they collapse to one column something other
   than the column count changes: source order, an inset, a border, or sticky
   positioning. Each width is where that grid's columns stop fitting.

   The design canvas achieved this by measuring resolved grid tracks in
   JavaScript, because inline styles cannot carry media queries. CSS states it
   directly, which also means the layout is correct on the first paint rather
   than after a measure-and-correct pass.
   =========================================================================== */

/* Hero: photo leads once stacked, so a phone opens on the pool rather than
   on a wall of type. */
@media (max-width: 940px) {
	.hero__grid { grid-template-columns: 1fr; }
	.hero__copy {
		order: 2;
		padding-left: 0;
		padding-right: 0;
	}
	.hero__media { order: 1; border-left: none; }
}

/* Below here the nav collapses to the hamburger and the booking bar exists. */
@media (max-width: 860px) {
	.site-nav { display: none; }
	.site-nav.is-open { display: flex; }
	.menu-toggle { display: flex; }

	.book-bar { display: flex; }
	/* Reserve the bar's height so the footer is never trapped underneath it.
	   Done on the body rather than with a spacer element. */
	body { padding-bottom: calc(var(--bar-h) + env(safe-area-inset-bottom)); }

	.house__grid { grid-template-columns: 1fr; }
	.house__copy { position: static; }

	.beach__grid { grid-template-columns: 1fr; }
	.beach__media {
		border-right: none;
		border-bottom: 1px solid var(--rule);
	}
	.beach__copy { padding-left: 0; }
}

@media (max-width: 620px) {
	.spec dd { text-align: left; }
}

/* --- Error pages -------------------------------------------------------- */
/* Lives here rather than in a <style> block on 404.html / 500.html so the
   strict Content-Security-Policy (default-src 'self', no 'unsafe-inline')
   does not leave the error pages unstyled.
   These were lost once already, in the wholesale rewrite of this file for the
   mobile revision. check-a11y.sh now fails if a class used in any HTML file
   has no rule here. */
.err {
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	gap: 22px;
	padding: 40px 24px;
}
.err h1 {
	font-family: var(--serif);
	font-size: var(--h2-size);
	font-weight: 500;
	line-height: 1.08;
	letter-spacing: -0.025em;
	color: var(--ink);
	text-wrap: balance;
}
.err p { max-width: 42ch; }
