/**
 * Hermitage Nevis — front-end stylesheet. v0.2.20 (Task 06D mobile type
 * scale + responsive spacing; previous: v0.2.17 Task 05.6B comparison
 * table, v0.2.10 Task 05.2 accommodation two-width layout).
 *
 * Naming: BEM-flavoured with an `hn-` prefix (.hn-header, .hn-card,
 * .hn-card--accommodation …). Design tokens come from theme.json custom
 * properties (--wp--preset--*); this file must not introduce new colours
 * or sizes outside that system.
 *
 * Visual direction (approved Task 03): warm, calm, personal, editorial.
 * Deep heritage green + warm orange accent + warm off-white, serif
 * display headings, restrained decoration. No page builder, no JS.
 *
 * No build pipeline: this file is authored and served as-is.
 */

/* ---------------------------------------------------------------------
 * Accessibility foundations
 * ------------------------------------------------------------------- */

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute !important;
	width: 1px;
	word-wrap: normal !important;
}

.screen-reader-text:focus {
	background-color: var(--wp--preset--color--surface);
	clip-path: none;
	color: var(--wp--preset--color--ink);
	display: block;
	font-size: 1rem;
	height: auto;
	left: 5px;
	line-height: normal;
	padding: 15px 23px 14px;
	text-decoration: none;
	top: 5px;
	width: auto;
	z-index: 100000;
}

/* Visible focus for keyboard users. The focus token passes 3:1 against
 * light and dark surfaces, so one outline works everywhere. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--focus);
	outline-offset: 2px;
	border-radius: 1px;
}

/* Skip link target shouldn't hide behind anything. */
main {
	scroll-margin-top: 2rem;
}

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

/* ---------------------------------------------------------------------
 * Base element refinements (core blocks, restrained)
 * ------------------------------------------------------------------- */

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

a {
	text-underline-offset: 0.15em;
	transition: color 120ms ease;
}

h1, h2, h3 {
	text-wrap: balance;
}

.wp-block-table {
	overflow-x: auto;
}

.wp-block-table table {
	border-collapse: collapse;
	width: 100%;
}

.wp-block-table th,
.wp-block-table td {
	border: 1px solid var(--wp--preset--color--line);
	padding: 0.5rem 0.75rem;
	text-align: left;
}

.wp-block-details {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 2px;
	padding: 0.75rem 1rem;
}

.wp-block-details summary {
	cursor: pointer;
	font-weight: 600;
}

.wp-block-search__button {
	margin-left: 0.5rem;
}

/* Search / text inputs pick up the token system. */
.wp-block-search__input {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 2px;
	padding: 0.5rem 0.75rem;
}

/* ---------------------------------------------------------------------
 * Shared editorial atoms
 * ------------------------------------------------------------------- */

/* Eyebrow label. On light surfaces the eyebrow is muted green (orange
 * fails AA contrast on off-white); on the dark green surface it becomes
 * warm orange, which passes. */
.hn-eyebrow,
.hn-section-intro__eyebrow,
.hn-hero__eyebrow {
	color: var(--wp--preset--color--text-muted);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

/* NOTE (Task 58 Phase 2, v0.2.85): the `.wp-block-cover.hn-hero` arm of the
 * rule below is once again the ONLY colour rule for a cover-hero eyebrow.
 * Task 32 (v0.2.63) had overridden photographic heroes to the `surface`
 * token for contrast; the owner has since ruled that every hero eyebrow is
 * the brand `accent` orange (see "TASK 58" at the foot of this stylesheet),
 * so the Task 32 rule is retired and this atom governs everywhere. */
.has-surface-dark-background-color .hn-eyebrow,
.has-surface-dark-background-color .hn-section-intro__eyebrow,
.has-brand-dark-background-color .hn-eyebrow,
.has-brand-dark-background-color .hn-section-intro__eyebrow,
.wp-block-cover.hn-hero .hn-hero__eyebrow {
	color: var(--wp--preset--color--accent);
}

/* Pending factual fields are visually flagged until approved. */
.hn-pending {
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	color: var(--wp--preset--color--text-muted);
	font-style: italic;
	padding: 0 0.25em;
}

.has-surface-dark-background-color .hn-pending,
.has-brand-dark-background-color .hn-pending {
	background-color: var(--wp--preset--color--brand-dark);
	color: var(--wp--preset--color--surface-warm);
}

/* Rank Math breadcrumbs: quiet, readable, never dominant. */
.rank-math-breadcrumb {
	font-size: var(--wp--preset--font-size--x-small);
}

.rank-math-breadcrumb a {
	color: inherit;
	text-decoration: none;
}

.rank-math-breadcrumb a:hover,
.rank-math-breadcrumb a:focus {
	text-decoration: underline;
}

.rank-math-breadcrumb .separator {
	opacity: 0.6;
	padding: 0 0.35em;
}

/* ---------------------------------------------------------------------
 * Buttons
 * -------------------------------------------------------------------
 * Primary        = default button (orange, deep-green text — AA 5.9:1).
 * Secondary      = .is-style-outline (green outline on light surfaces,
 *                  automatically white outline on dark green surfaces).
 * Text link      = .is-style-text-link (registered in inc/setup.php).
 * Dark primary   = default button on a dark surface (unchanged: orange
 *                  reads strongly on deep green).
 * Enquiry action = .is-style-outline inside .hn-cta--enquiry (quieter
 *                  than booking actions by design).
 */

.wp-block-button__link {
	min-height: 44px;
	transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

/* Secondary (outline). */
.wp-block-button.is-style-outline .wp-block-button__link {
	background-color: transparent;
	border: 1.5px solid var(--wp--preset--color--brand);
	color: var(--wp--preset--color--brand);
	padding-top: calc(0.75rem - 1.5px);
	padding-bottom: calc(0.75rem - 1.5px);
}

.wp-block-button.is-style-outline .wp-block-button__link:hover,
.wp-block-button.is-style-outline .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--surface);
}

/* Secondary on dark green surfaces: white outline. */
.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link {
	border-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--surface);
}

.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:hover,
.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:focus,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:hover,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--brand);
}

/* Task 58 Phase 2 (v0.2.85): the `.wp-block-cover.hn-hero` arm that used to
 * share the two rules above (transparent white-outline secondary on a
 * photograph) is retired. A hero secondary CTA is now a self-contained
 * white-filled control on every hero — see "TASK 58" at the foot of this
 * stylesheet. The dark-section arms above are unchanged. */

/* Text-link button style: reads as an emphasised link, not a box. */
.wp-block-button.is-style-text-link .wp-block-button__link {
	background-color: transparent;
	border: 0;
	color: var(--wp--preset--color--brand);
	font-weight: 600;
	padding-left: 0;
	padding-right: 0;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.wp-block-button.is-style-text-link .wp-block-button__link:hover,
.wp-block-button.is-style-text-link .wp-block-button__link:focus {
	color: var(--wp--preset--color--accent-hover);
}

.has-surface-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link,
.has-brand-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link {
	color: var(--wp--preset--color--surface-warm);
}

.has-surface-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link:hover,
.has-surface-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link:focus,
.has-brand-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link:hover,
.has-brand-dark-background-color .wp-block-button.is-style-text-link .wp-block-button__link:focus {
	color: var(--wp--preset--color--accent);
}

/* ---------------------------------------------------------------------
 * Header
 * ------------------------------------------------------------------- */

.hn-header {
	background-color: var(--wp--preset--color--surface-dark);
}

/* Logo: wide script mark — keep it legible but never dominant.
 * 2560×779 source; rendered ~200px desktop, ~150px at 320px width. */
.hn-header .wp-block-site-logo {
	flex-shrink: 0;
}

.hn-header .wp-block-site-logo img {
	display: block;
	height: auto;
	width: clamp(140px, 40vw, 200px);
}

/* Navigation links: white on deep green. */
.hn-header .wp-block-navigation,
.hn-header .wp-block-navigation a {
	color: var(--wp--preset--color--surface);
}

.hn-header .wp-block-navigation a {
	text-decoration: none;
}

.hn-header .wp-block-navigation a:hover {
	color: var(--wp--preset--color--accent);
}

/* Accessible current-page indication (aria-current comes from core). */
.hn-header .wp-block-navigation a[aria-current="page"],
.hn-header .wp-block-navigation .current-menu-item > a {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.45em;
}

/* Hamburger + close controls inherit white; enforce target size. */
.hn-header .wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	color: var(--wp--preset--color--surface);
	min-height: 44px;
	min-width: 44px;
}

/* Open mobile overlay: deep green, generous type, breathing room.
 * Colours also come from the navigation block's overlay attributes;
 * these rules keep the overlay on-system even if attributes drift. */
.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--surface-dark);
	color: var(--wp--preset--color--surface);
	padding: var(--wp--preset--spacing--lg) var(--wp--custom--gutter);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: var(--wp--preset--spacing--xl);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item a {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
}

/* Task 06D: overlay link tap target. Core zeroes the overlay link padding
 * with a four-class selector, so the padding half of the rule above never
 * applied and links rendered 36px tall. This matches core's specificity;
 * 0.5rem vertical padding yields a measured 52px target (>=44px). */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item a.wp-block-navigation-item__content {
	padding: 0.5rem 0;
}

.wp-block-navigation__responsive-container-close {
	color: var(--wp--preset--color--surface);
}

/* Book Now in the header stays compact and never wraps. */
.hn-header .hn-button-book .wp-block-button__link {
	white-space: nowrap;
}

@media (max-width: 781px) {
	/* At mobile widths the Book Now button sits beside the hamburger;
	 * tighten padding so logo + controls fit at 320px with no overflow. */
	.hn-header .hn-button-book .wp-block-button__link {
		font-size: var(--wp--preset--font-size--small);
		padding: 0.6rem 0.9rem;
	}

	.hn-header .hn-header__navigation {
		gap: var(--wp--preset--spacing--xs);
	}
}

@media (max-width: 380px) {
	/* Smallest phones: keep the wide script logo as large as legibility
	 * allows while guaranteeing zero horizontal overflow at 320px. */
	.hn-header .wp-block-site-logo img {
		width: 124px;
	}

	.hn-header .hn-button-book .wp-block-button__link {
		padding: 0.6rem 0.7rem;
	}
}

/* ---------------------------------------------------------------------
 * Hero
 * ------------------------------------------------------------------- */

.hn-hero {
	/* Blocks inside covers get their own gap rhythm. */
}

/* Task 12.3 — the base hero inner-container previously set
 * padding-top / padding-bottom: var(--wp--preset--spacing--2xl). WordPress
 * does not emit a CSS custom property for digit-leading spacing slugs
 * (2xs / 2xl), so that reference was always empty and the whole declaration
 * was dropped, rendering 0. The only hero governed by this base rule is the
 * homepage hero (.hn-hero--home), which takes its vertical rhythm from the
 * cover's own padding + min-height and was accepted at 0 inner padding; the
 * accommodation and wedding hero families set their own inner-container
 * padding below. Applying the intended 6rem would have added ~101px to the
 * accepted homepage hero (measured), so the invalid declaration is removed
 * rather than "fixed" — rendered output is identical (Home 560px, inner
 * padding 0/0 before and after). */

/* Hero text measure: headings and supporting copy never exceed a calm,
 * readable width regardless of viewport (Task 03.1 §4). Children of the
 * constrained cover stay centred as a column; text is left-aligned. */
.wp-block-cover.hn-hero h1 {
	max-width: 21ch;
}

.wp-block-cover.hn-hero p:not(.hn-hero__eyebrow) {
	max-width: 34rem;
}

/* Deliberate vertical rhythm inside the hero.
 *
 * Task 29 - eyebrow-to-H1 harmonisation. Verified on the live pages, not
 * inferred from this selector: of the fourteen principal hero eyebrows,
 * twelve sit in .hn-hero--accommodations / .hn-hero--accommodation covers
 * and take the documented SM step (1rem) from their
 * `inner-container > *` rule (Tasks 06F / 10.1a, specificity 0,3,0), which
 * outranks this one. The Weddings hero is not a cover at all - it is a
 * group with a photograph and a brand band - so this selector never
 * matched it either; its 0.5rem comes from
 * `.hn-hero--wedding .hn-wed-hero__band > h1` (Task 18.1). So the only
 * hero this rule has ever governed is the homepage, and its 0.5rem was
 * the single 8px outlier against twelve heroes at 16px - not the ~20px
 * sitewide gap the Task 29 brief hypothesised. Aligning it to the same SM
 * step gives one gap across all thirteen cover heroes with no new
 * selector. The Weddings band keeps 8px as a documented exception: at
 * 320x568 its CTA already sits 38px below the fold, so adding 8px there
 * would worsen an accepted Task 18.1 constraint for a cosmetic gain. The
 * short-mobile homepage block (max-width 374px and max-height 620px)
 * still overrides this to 0.375rem, which is deliberate and unchanged. */
.wp-block-cover.hn-hero h1 {
	margin-top: 1rem;
}

.wp-block-cover.hn-hero .wp-block-buttons {
	margin-top: 1.25rem;
}

/* Cover-based heroes (photo + overlay): white text. Scoped to covers so
 * the light accommodation hero keeps standard ink/heading colours. */
.wp-block-cover.hn-hero h1,
.wp-block-cover.hn-hero p {
	color: var(--wp--preset--color--surface);
}

/* Accommodation hero: warm band, standard text colours. Applies only to
 * a hero that is still a plain group — the Task 05.6 image heroes are
 * cover blocks and carry their own photograph. */
.hn-hero--accommodation:not(.wp-block-cover) {
	background-color: var(--wp--preset--color--surface-warm);
}

/* ---------------------------------------------------------------------
 * Footer
 * ------------------------------------------------------------------- */

.hn-footer {
	background-color: var(--wp--preset--color--surface-dark);
	border-top: 1px solid var(--wp--preset--color--brand-dark);
	color: var(--wp--preset--color--surface-warm);
}

.hn-footer .wp-block-site-logo img {
	display: block;
	height: auto;
	width: clamp(160px, 30vw, 210px);
}

.hn-footer h2 {
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	letter-spacing: 0.1em;
	margin-bottom: 0.6rem;
	opacity: 0.85;
	text-transform: uppercase;
}

/* Task 03.1: the logo/property column anchors the footer; link columns
 * stay subordinate. The property line keeps a narrow measure. */
.hn-footer .hn-footer__brand p {
	max-width: 30ch;
}

/* Tighter link rhythm so four columns read as one quiet block. */
.hn-footer .wp-block-list {
	margin-top: 0;
}

.hn-footer a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--surface-warm);
	text-decoration: none;
}

.hn-footer a:not(.wp-block-button__link):hover,
.hn-footer a:not(.wp-block-button__link):focus {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
}

.hn-footer .wp-block-list {
	list-style: none;
	padding-left: 0;
}

.hn-footer .wp-block-list li {
	margin-bottom: 0.3rem;
}

/* Mobile stacking: modest gap between stacked footer columns. */
@media (max-width: 781px) {
	.hn-footer .hn-footer__columns.wp-block-columns {
		gap: var(--wp--preset--spacing--md);
	}
}

.hn-footer .wp-block-separator {
	border-color: var(--wp--preset--color--brand-dark);
	opacity: 1;
}

/* ---------------------------------------------------------------------
 * Cards (accommodation, story)
 * ------------------------------------------------------------------- */

.hn-card {
	background-color: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 2px;
	overflow: hidden;
}

.hn-card--accommodation .wp-block-post-featured-image img,
.hn-card--accommodation figure img {
	aspect-ratio: 3 / 2;
	object-fit: cover;
	width: 100%;
}

.hn-card--accommodation .hn-card__image {
	margin: 0;
}

.hn-card--accommodation h3 {
	margin-top: 0.25rem;
}

/* Story cards read as journal entries: no box, a warm rule above,
 * so they never look like accommodation cards. */
.hn-card--story {
	background-color: transparent;
	border: 0;
	border-top: 2px solid var(--wp--preset--color--accent);
	border-radius: 0;
}

.hn-card--story .wp-block-post-featured-image img {
	aspect-ratio: 3 / 2;
	object-fit: cover;
	width: 100%;
}

.hn-card--story .wp-block-post-title a {
	color: var(--wp--preset--color--heading);
	text-decoration: none;
}

.hn-card--story .wp-block-post-title a:hover,
.hn-card--story .wp-block-post-title a:focus {
	color: var(--wp--preset--color--accent-hover);
	text-decoration: underline;
}

.hn-card--story .wp-block-post-date,
.hn-card--story .wp-block-post-terms {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.hn-card--story .wp-block-post-excerpt__more-link {
	font-weight: 600;
}

/* ---------------------------------------------------------------------
 * Postcard card — opt-in modifier on .hn-card--story (Task 47, v0.2.70)
 * -------------------------------------------------------------------
 * A story card that reads as a postcard: the photograph sits flush on a
 * warm card surface with one quiet 1px edge, title and excerpt below it
 * on the same surface, and the whole card is the link. Opt in by adding
 * `hn-card--postcard` next to `hn-card hn-card--story` on the article
 * group AND setting that group's block padding to 0 top / 0 left /
 * 0 right (bottom stays `md`) — an editor-controlled value — so the
 * photograph can meet the card edge. The text takes its side padding
 * from the rules below. Existing tokens only; no JavaScript. Used by the
 * Postcards page (current Postcard + archive) and the Home Postcards
 * preview; `inc/image-performance.php` reads the same class to size the
 * flush photograph honestly.
 * ------------------------------------------------------------------- */

.hn-card--story.hn-card--postcard {
	background-color: var(--wp--preset--color--surface-warm);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 2px;
	position: relative;
	transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
}

.hn-card--postcard .wp-block-post-featured-image {
	margin-bottom: var(--wp--preset--spacing--sm);
}

.hn-card--postcard .wp-block-post-featured-image img {
	display: block;
}

.hn-card--postcard .wp-block-post-title,
.hn-card--postcard .wp-block-post-excerpt {
	padding-inline: var(--wp--preset--spacing--sm);
}

.hn-card--postcard .wp-block-post-title {
	margin-top: 0;
}

/* Image-less Postcards: give the text the top breathing room the
 * photograph would otherwise provide. */
.hn-card--postcard > .wp-block-post-title:first-child {
	padding-top: var(--wp--preset--spacing--sm);
}

/* Whole card clickable: the single title anchor is stretched over the
 * card with a pseudo-element. No extra link, no JavaScript, no nesting. */
.hn-card--postcard .wp-block-post-title a::after {
	content: "";
	inset: 0;
	position: absolute;
}

/* Hover: rule darkens, a hair of lift, title underlines. Nothing else.
 * The title keeps the heading colour on hover/focus: the story card's
 * accent-hover colour measures 2.98:1 on the warm surface, just under
 * the 3:1 large-text minimum, so it is not used on this surface. */
.hn-card--postcard:hover {
	border-color: var(--wp--preset--color--text-muted);
	box-shadow: 0 1px 2px rgba(38, 48, 43, 0.08);
	transform: translateY(-1px);
}

.hn-card--postcard .wp-block-post-title a:hover,
.hn-card--postcard .wp-block-post-title a:focus,
.hn-card--postcard:hover .wp-block-post-title a {
	color: var(--wp--preset--color--heading);
	text-decoration: underline;
}

/* Keyboard focus: the ring goes round the whole card (the real hit
 * area), not just the title text; the anchor's own ring is suppressed
 * only inside this component so there is never a double ring. */
.hn-card--postcard .wp-block-post-title a:focus-visible {
	outline: 0;
	text-decoration: underline;
}

.hn-card--postcard:has(.wp-block-post-title a:focus-visible) {
	border-color: var(--wp--preset--color--focus);
	outline: 2px solid var(--wp--preset--color--focus);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.hn-card--postcard:hover {
		transform: none;
	}
}

/* ---------------------------------------------------------------------
 * Image-and-text sections
 * ------------------------------------------------------------------- */

.hn-image-text .wp-block-media-text__media img {
	aspect-ratio: 4 / 3;
	object-fit: cover;
	width: 100%;
}

/* ---------------------------------------------------------------------
 * Practical facts panel
 * ------------------------------------------------------------------- */

.hn-facts {
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
}

.hn-facts__row {
	border-bottom: 1px solid var(--wp--preset--color--line);
	margin: 0;
	padding-bottom: 0.5rem;
}

/* ---------------------------------------------------------------------
 * CTA panels
 * ------------------------------------------------------------------- */

.hn-cta--booking {
	border-radius: 2px;
}

/* Booking CTA dark variant: add the Surface (dark green) — or Brand
 * (darkest green) for the pre-footer closing CTA — background in the
 * editor; text switches automatically. */
.hn-cta--booking.has-surface-dark-background-color,
.hn-cta--booking.has-surface-dark-background-color h2,
.hn-cta--booking.has-surface-dark-background-color p,
.hn-cta--booking.has-brand-dark-background-color,
.hn-cta--booking.has-brand-dark-background-color h2,
.hn-cta--booking.has-brand-dark-background-color p {
	color: var(--wp--preset--color--surface-warm);
}

.hn-cta--booking.has-surface-dark-background-color h2,
.hn-cta--booking.has-brand-dark-background-color h2 {
	color: var(--wp--preset--color--surface);
}

.hn-cta--booking.has-surface-dark-background-color a:not(.wp-block-button__link),
.hn-cta--booking.has-brand-dark-background-color a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--surface-warm);
	text-decoration: underline;
}

.hn-cta--booking.has-surface-dark-background-color a:not(.wp-block-button__link):hover,
.hn-cta--booking.has-brand-dark-background-color a:not(.wp-block-button__link):hover {
	color: var(--wp--preset--color--accent);
}

/* Any generic content on the dark surfaces stays readable. */
.has-surface-dark-background-color h1,
.has-surface-dark-background-color h2,
.has-surface-dark-background-color h3,
.has-brand-dark-background-color h1,
.has-brand-dark-background-color h2,
.has-brand-dark-background-color h3 {
	color: var(--wp--preset--color--surface);
}

.has-surface-dark-background-color,
.has-surface-dark-background-color p,
.has-brand-dark-background-color,
.has-brand-dark-background-color p {
	color: var(--wp--preset--color--surface-warm);
}

.has-surface-dark-background-color a:not(.wp-block-button__link),
.has-brand-dark-background-color a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--surface-warm);
}

.has-surface-dark-background-color a:not(.wp-block-button__link):hover,
.has-brand-dark-background-color a:not(.wp-block-button__link):hover {
	color: var(--wp--preset--color--accent);
}

/* ---------------------------------------------------------------------
 * Mobile booking bar (front end only; rendered from inc/booking.php,
 * enabled via Settings → Hermitage Booking; off by default)
 * ------------------------------------------------------------------- */

.hn-booking-bar {
	background-color: var(--wp--preset--color--surface-dark);
	border-top: 1px solid var(--wp--preset--color--brand-dark);
	bottom: 0;
	display: none;
	left: 0;
	padding: 0.5rem var(--wp--custom--gutter);
	padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
	position: fixed;
	right: 0;
	z-index: 900;
}

.hn-booking-bar__link {
	background-color: var(--wp--preset--color--accent);
	border-radius: 2px;
	color: var(--wp--preset--color--brand-dark);
	display: block;
	font-weight: 600;
	min-height: 44px;
	padding: 0.75rem 1.5rem;
	text-align: center;
	text-decoration: none;
}

.hn-booking-bar__link:hover,
.hn-booking-bar__link:focus {
	background-color: var(--wp--preset--color--accent-hover);
	color: var(--wp--preset--color--brand-dark);
}

@media (max-width: 781px) {
	body.hn-has-booking-bar .hn-booking-bar {
		display: block;
	}

	/* Reserve space so the bar never covers content or footer controls. */
	body.hn-has-booking-bar {
		padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
	}
}

/* =====================================================================
 * Task 03.1 — Visual refinement layer
 * =====================================================================
 * Content width system (documented in readme §Layout):
 *   Reading width   = 42rem  (theme.json contentSize — default constrained children)
 *   Standard width  = 70rem  (theme.json wideSize — `alignwide`: intros, CTA panels,
 *                             image-and-text, footer inner)
 *   Wide grid width = 76rem  (`.hn-w-grid` on alignwide grids: accommodation
 *                             card grids, story grids)
 * Tokens mirrored in theme.json under custom.width.*.
 * ------------------------------------------------------------------- */

/* Wide-grid width class. Higher specificity than the generated
 * `.is-layout-constrained > .alignwide` rule, so no !important needed. */
main :where(.is-layout-constrained) > .hn-w-grid.alignwide {
	max-width: min(var(--wp--custom--width--grid, 76rem), 100%);
}

/* ---------------------------------------------------------------------
 * Accommodation grid: balanced 3 + 2 desktop layout (Task 03.1 §7)
 * -------------------------------------------------------------------
 * Six-column grid; each card spans two columns. With exactly five cards
 * the fourth and fifth are placed at columns 2 and 4, centring the
 * second row with equal card widths. Tablet: two columns with the fifth
 * card centred; small screens: single column.
 */

.hn-grid--accommodations {
	display: grid;
	gap: var(--wp--preset--spacing--md);
	grid-template-columns: 1fr;
}

/* Neutralise flow-layout blockGap margins inside the grid so rows stay
 * perfectly aligned; the grid gap is the single source of spacing. */
.hn-grid--accommodations > * {
	margin-block-start: 0;
	min-width: 0;
}

/* The flex card makes children shrink-to-fit; WordPress constrained
 * layout centres them with `margin-inline: auto !important`, which would
 * visually centre all card content. These two !important declarations
 * are required to counter core's own !important (documented exception to
 * the no-!important rule). */
.hn-card--accommodation > *,
.hn-card--accommodation .hn-card__content > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

@media (min-width: 640px) {
	.hn-grid--accommodations {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Task 53: gated on :last-child so the rule only fires for a
	 * five-card grid. The Home villa row now carries a sixth item (the
	 * navigation card), which must flow normally. */
	.hn-grid--accommodations > :nth-child(5):last-child {
		grid-column: 1 / -1;
		justify-self: center;
		width: calc(50% - (var(--wp--preset--spacing--md) / 2));
	}
}

@media (min-width: 1024px) {
	.hn-grid--accommodations {
		grid-template-columns: repeat(6, 1fr);
	}

	.hn-grid--accommodations > * {
		grid-column: span 2;
	}

	/* Task 53: both placements are gated on the grid holding exactly
	 * five items (:nth-last-child(2) / :last-child). A six-item grid —
	 * the Home villa row with its navigation card — then falls through
	 * to the span-2 default and renders as two balanced rows of three. */
	.hn-grid--accommodations > :nth-child(4):nth-last-child(2) {
		grid-column: 2 / span 2;
	}

	.hn-grid--accommodations > :nth-child(5):last-child {
		grid-column: 4 / span 2;
		justify-self: stretch;
		width: auto;
	}
}

/* Equal visual height: cards stretch; the action pins to the bottom so
 * five buttons align across a row without forcing blank space. */
.hn-grid--accommodations > .wp-block-block,
.hn-grid--accommodations > .hn-card {
	height: 100%;
}

.hn-card--accommodation {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.hn-card--accommodation .hn-card__content {
	display: flex;
	flex-direction: column;
	flex-grow: 1;
}

.hn-card--accommodation .hn-card__content > .wp-block-buttons {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--xs);
}

/* Long card titles (Gingerbread Cottages, Yellow Manor House) balance
 * across lines instead of leaving orphans. */
.hn-card--accommodation h3 {
	text-wrap: balance;
}

/* ---------------------------------------------------------------------
 * Home accommodation-card variation (Task 03.1 §8)
 * -------------------------------------------------------------------
 * `.hn-cards--compact` is a presentation wrapper on the Home grid. The
 * five synced card patterns inside are untouched; this class only
 * changes how they render on Home: no card box, factual metadata row
 * hidden, the outline button reads as an editorial text link. The hub
 * keeps the full comparison treatment.
 */

.hn-cards--compact .hn-card--accommodation {
	background-color: transparent;
	border: 0;
	border-radius: 0;
}

.hn-cards--compact .hn-card--accommodation .hn-card__content {
	padding-left: 0;
	padding-right: 0;
	padding-top: var(--wp--preset--spacing--xs);
}

/* Hide the dense "Sleeps / Best for" metadata row on Home only.
 * Card structure is locked (templateLock: contentOnly), so the row is
 * reliably the second paragraph of the card content. */
.hn-cards--compact .hn-card--accommodation .hn-card__content > p:nth-of-type(2) {
	display: none;
}

/* The card action renders as an editorial link on Home. */
.hn-cards--compact .hn-card--accommodation .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: transparent;
	border: 0;
	color: var(--wp--preset--color--brand);
	font-weight: 600;
	padding: 0.6rem 0;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.hn-cards--compact .hn-card--accommodation .wp-block-button.is-style-outline .wp-block-button__link:hover,
.hn-cards--compact .hn-card--accommodation .wp-block-button.is-style-outline .wp-block-button__link:focus {
	background-color: transparent;
	color: var(--wp--preset--color--accent-hover);
}

/* ---------------------------------------------------------------------
 * Ginger Tales story layouts (Task 03.1 §10)
 * -------------------------------------------------------------------
 * The Query Loop grid adapts to how many stories exist, with no JS and
 * no hardcoded post IDs:
 *   1 post   → single wider featured story
 *   2 posts  → balanced two-column layout
 *   3+ posts → three-column editorial grid
 * (:has() is supported by all current evergreen browsers; without it
 * the layout simply stays a standard grid.)
 */

.hn-stories .wp-block-post-template.is-layout-grid {
	gap: var(--wp--preset--spacing--lg) var(--wp--preset--spacing--md);
	grid-template-columns: 1fr;
}

@media (min-width: 640px) {
	.hn-stories .wp-block-post-template.is-layout-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.hn-stories .wp-block-post-template.is-layout-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	/* Exactly two stories: balanced pair. */
	.hn-stories .wp-block-post-template.is-layout-grid:has(> .wp-block-post:first-child:nth-last-child(2)) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Exactly one story: wider featured presentation, never a stranded card. */
.hn-stories .wp-block-post-template.is-layout-grid:has(> .wp-block-post:only-child) {
	grid-template-columns: 1fr;
}

.hn-stories .wp-block-post-template > .wp-block-post:only-child .hn-card--story {
	margin-inline: auto;
	max-width: 56rem;
	width: 100%;
}

.hn-stories .wp-block-post-template > .wp-block-post:only-child .hn-card--story .wp-block-post-title {
	font-size: var(--wp--preset--font-size--x-large);
}

/* Modest presence increase for story cards (editorial, not product). */
.hn-card--story {
	padding-top: var(--wp--preset--spacing--sm);
}

.hn-card--story .wp-block-post-title {
	line-height: 1.25;
}

/* Editorial link treatment: Read story links are unmistakably links. */
.wp-block-post-excerpt__more-link {
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}


/* ---------------------------------------------------------------------
 * Admin-only build note (Task 03.1 close-out)
 * -------------------------------------------------------------------
 * Internal review notices (e.g. the accommodation-detail skeleton
 * banner) must never render as public content. `.hn-admin-note` is
 * hidden on the front end and shown, quietly, only to logged-in users
 * via the core `logged-in` body class. Editors also see it in the
 * editor (parity rule in editor.css).
 */

.hn-admin-note {
	display: none;
}

body.logged-in .hn-admin-note {
	border: 1px dashed var(--wp--preset--color--line);
	border-radius: 2px;
	color: var(--wp--preset--color--text-muted);
	display: block;
	font-size: var(--wp--preset--font-size--x-small);
	font-style: italic;
	padding: 0.4rem 0.6rem;
}

/* =====================================================================
 * Accommodation detail: controlled two-width layout (Task 05.2, v0.2.10)
 *
 * The five accommodation detail pages use a reading measure for
 * narrative sections and a wider measure for structured/visual content
 * (hero, galleries, full-details grid, cottage comparison table, FAQs).
 *
 * Widths come from theme.json tokens:
 *   --wp--custom--width--detail-reading = 46rem (736px; ~70-78 chars
 *     at the 20px narrative size — tested on staging, Task 05.2 §4.1)
 *   --wp--custom--width--detail-wide    = 62rem (992px; Task 05.2 §4.2)
 *
 * Mechanism: WordPress constrained layout caps children with
 * `max-width: var(--wp--style--global--content-size)` (and
 * `--wp--style--global--wide-size` for .alignwide). Scoping those two
 * custom properties to the accommodation wrappers re-widths every
 * existing page without touching page markup. Caps are max-widths, so
 * below ~1024px they simply stop applying — the mobile layout is
 * unchanged and no media queries are needed.
 * =================================================================== */

/* Narrative sections: comfortable reading measure. */
main .hn-detail__section {
	--wp--style--global--content-size: var(--wp--custom--width--detail-reading, 46rem);
}

/* Structured and image-led sections: wider content measure. */
main .hn-detail__gallery,
main .hn-detail__details,
main .hn-detail__sizes,
main .hn-detail__questions {
	--wp--style--global--content-size: var(--wp--custom--width--detail-wide, 62rem);
	--wp--style--global--wide-size: var(--wp--custom--width--detail-wide, 62rem);
}

/* Accommodation hero: breadcrumbs, title, at-a-glance facts, CTA group
 * and hero image share the wider band so the hero aligns with the
 * structured sections below (Task 05.2 §7). */
main .hn-hero--accommodation {
	--wp--style--global--content-size: var(--wp--custom--width--detail-wide, 62rem);
	--wp--style--global--wide-size: var(--wp--custom--width--detail-wide, 62rem);
}

/* The distinction line keeps a calm measure inside the wider hero band.
 * Constrained layout centres capped children with `margin auto
 * !important`; the max() margin pins the line to the band's left edge
 * instead (0 once the viewport is narrower than the band). Justified
 * !important — counters the core rule, same precedent as the flex-card
 * margins (readme). */
main .hn-hero--accommodation .hn-hero__distinction {
	margin-left: max(0px, calc((100% - var(--wp--custom--width--detail-wide, 62rem)) / 2)) !important;
	max-width: 36rem;
}

/* Intro/caption paragraphs inside wide sections stay at the reading
 * measure, left-aligned to the section edge (sections themselves are
 * the wide band, so 0 is the band edge). */
main .hn-detail__gallery > p,
main .hn-detail__details > p,
main .hn-detail__sizes > p,
main .hn-detail__questions > p {
	margin-left: 0 !important;
	max-width: var(--wp--custom--width--detail-reading, 46rem);
}

/* FAQ rows use the wide container; an opened answer stays readable. */
main .hn-detail__questions .wp-block-details > :not(summary) {
	max-width: var(--wp--custom--width--detail-reading, 46rem);
}

/* A gallery that currently holds a single labelled placeholder tile
 * (Yellow Manor House) keeps a calm 16:9 band instead of scaling the
 * blank 3:2 tile to the full wide measure (Task 05.2 §11). Crops from
 * the top; the IMAGE PENDING corner label sits at the bottom edge. */
main .hn-detail__gallery .wp-block-gallery > .wp-block-image:only-child img {
	aspect-ratio: 16 / 9;
	object-fit: cover;
	object-position: left bottom;
	width: 100%;
}

/* =====================================================================
 * IMAGE HEROES  (Task 05.6)
 * =====================================================================
 *
 * The homepage, the Accommodations hub and the five accommodation
 * detail pages all use one component: a core/cover block carrying the
 * page's principal photograph, with the page's opening content over it.
 *
 * Why core/cover rather than a CSS background image:
 *   - the image stays a real <img> with WordPress srcset/sizes, so the
 *     browser downloads a correctly sized file;
 *   - the owner can swap the photograph in the block toolbar without
 *     touching code;
 *   - the desktop focal point is the cover block's own focal-point
 *     picker (writes object-position inline);
 *   - object-fit: cover gives the required cover/no-repeat behaviour.
 *
 * Modifiers:
 *   .hn-hero--home             homepage (Task 03/05.5A — not restyled here)
 *   .hn-hero--accommodations   Accommodations hub
 *   .hn-hero--accommodation    the five detail pages
 *   .hn-hero--flush            hero sits directly beneath the site header
 * ------------------------------------------------------------------- */

/* --- Header adjacency -------------------------------------------------
 * The gap under the site header is the block-gap margin WordPress puts
 * between the top-level template blocks (header / main / footer). It is
 * removed only for pages whose content opens with a flush hero, so every
 * other page keeps its normal opening spacing (Task 05.6 §3.3, §10). */
.wp-site-blocks > main:has(> .entry-content > .hn-hero--flush) {
	margin-block-start: 0;
	padding-top: 0;
}

/* The detail pages open with the admin-only note, which is display:none
 * for visitors but still counts for the `* + *` block-gap rule, so the
 * hero keeps a 20px top margin. Zero it on the hero itself as well. */
.entry-content > .hn-hero--flush {
	margin-block-start: 0;
}

/* Fallback colour behind the photograph. Invisible in normal use, but if
 * images are disabled or fail to load the hero stays dark green and the
 * white hero text remains readable (Task 05.6 §7). */
.wp-block-cover.hn-hero--accommodations,
.wp-block-cover.hn-hero--accommodation {
	background-color: var(--wp--preset--color--brand);
}

/* --- Height ----------------------------------------------------------
 * Responsive rather than fixed: the clamp keeps the hero inside the
 * agreed 520-620px desktop and 440-520px mobile ranges, and content
 * taller than that simply grows the box (Task 05.6 §3.1, §3.2).
 *
 * Anchoring (Task 06F): content is TOP-anchored, never centred or
 * bottom-anchored, so the breadcrumb/eyebrow keeps one fixed offset
 * from the bottom of the site header at each breakpoint regardless of
 * how much content stacks beneath it. The offset itself is the inner
 * container's padding-top (below); the cover's own 20px padding-top is
 * zeroed here so the token is the whole distance. */
.wp-block-cover.hn-hero--accommodations,
.wp-block-cover.hn-hero--accommodation {
	min-height: clamp(520px, 44vw, 620px);
	align-items: flex-start; /* fixed top offset — see note above */
	padding-top: 0;
}

@media (max-width: 781px) {
	.wp-block-cover.hn-hero--accommodations,
	.wp-block-cover.hn-hero--accommodation {
		min-height: clamp(440px, 120vw, 520px);
	}
}

/* --- Overlay ---------------------------------------------------------
 * HISTORY. Until 0.2.70 the theme painted a brand-green gradient on the
 * cover's background layer. Task 51 (v0.2.72) forced that layer clear
 * (`transparent !important; opacity: 1 !important`) and painted a LOCAL
 * scrim behind the copy stack instead; Task 51.3 (v0.2.78) took the
 * homepage back to the background layer with a theme-fixed 0.40. Both
 * arrangements left the Cover block's own overlay controls (`dimRatio`,
 * `overlayColor`) saving into page content with NO visible effect — the
 * Task 58 Phase 1 audit listed eight covers carrying inert values.
 *
 * TASK 58 PHASE 2 (v0.2.85): THE BLOCK OWNS THE OVERLAY. The theme no
 * longer sets background-color or opacity on `.wp-block-cover__background`
 * for any hero. The support a photograph gets is exactly what the editor
 * shows: the Cover block's "Overlay" colour (the `overlay` preset,
 * #0A241F) and "Overlay opacity" slider, painted by core edge to edge
 * across the whole photograph. Change it in the block toolbar; nothing
 * in this stylesheet will fight it. The local `::before` scrim, the
 * `--hn-hero-scrim-*` custom properties, `--hn-hero-overlay`, the ink
 * variant and the `--scrim-soft` / `--scrim-strong` modifiers are all
 * retired — see "TASK 58" at the foot of this stylesheet for the values
 * each page now carries and the measurements behind them. */

/* --- Focal points ----------------------------------------------------
 * The cover block's focal-point picker writes object-position inline on
 * the background image — no CSS needed, and the owner can change it in
 * the editor. Since Task 51 (v0.2.72) that block value applies at EVERY
 * width: the generic mobile override that used to sit here
 * (`object-position: var(--hn-hero-focus-mobile, 50% 50%) !important`)
 * silently replaced the block's focal point with 50% 50% on every hero
 * that had no page-slug variable — including all five Task 51
 * photographs, which are 2.4:1 and show ~26–35% of their width at 375px,
 * so their mobile crop must be the owner-set focal point. The six pages
 * that were retuned for mobile keep exactly the same values as explicit
 * mobile-only rules in the per-page block at the end of this section. */

/* --- Inner content ---------------------------------------------------
 * Hero text sits in the same 62rem band as the structured sections
 * below it, pinned to the band's left edge. Constrained layout centres
 * capped children with `margin: auto !important`; the max() margin
 * pins them left instead and collapses to 0 once the viewport is
 * narrower than the band (same precedent as Task 05.2, see readme). */
/* Fixed header→breadcrumb/eyebrow offset (Task 06F): XL (4rem) on
 * desktop, LG (2.5rem) at the hero's own 781px breakpoint. These heroes
 * are flush under the header and the cover's padding-top is zeroed, so
 * this padding IS the offset. */
.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container {
	padding-top: var(--wp--preset--spacing--xl);
	padding-bottom: var(--wp--preset--spacing--lg);
}

@media (max-width: 781px) {
	.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container,
	.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container {
		padding-top: var(--wp--preset--spacing--lg);
	}
}

.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container > *,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > * {
	margin-left: max(0px, calc((100% - var(--wp--custom--width--detail-wide, 62rem)) / 2)) !important;
	margin-right: auto;
	max-width: 40rem;
}

/* Text measures inside the image hero. */
.wp-block-cover.hn-hero--accommodations h1,
.wp-block-cover.hn-hero--accommodation h1 {
	max-width: 18ch;
}

.wp-block-cover.hn-hero--accommodations .hn-hero__distinction,
.wp-block-cover.hn-hero--accommodation .hn-hero__distinction,
.wp-block-cover.hn-hero--accommodations .hn-hero__summary {
	max-width: 34rem;
}

/* --- Breadcrumbs over the photograph ---------------------------------
 * Readable but deliberately subordinate to the H1. */
.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs {
	font-size: var(--wp--preset--font-size--small);
	margin-bottom: var(--wp--preset--spacing--sm);
}

/* Full-strength white rather than a faded white: transparency would cut
 * the measured contrast of small text over a photograph. The trail stays
 * subordinate to the H1 through size and letter-spacing instead. */
.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs,
.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs p {
	color: var(--wp--preset--color--surface);
}

.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs a {
	color: var(--wp--preset--color--surface);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs a:hover,
.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs a:focus {
	color: var(--wp--preset--color--accent);
}

/* Hero calls to action keep a 44px minimum touch target. */
.wp-block-cover.hn-hero--accommodations .wp-block-button__link,
.wp-block-cover.hn-hero--accommodation .wp-block-button__link {
	min-height: 44px;
	display: inline-flex;
	align-items: center;
}

/* --- At-a-glance facts, now directly below the hero ------------------
 * The Sleeps / Beds / View rows moved out of the hero so the photograph
 * stays legible (Task 05.6 §6.2). They keep their own class and simply
 * open the page body. */
main .hn-detail__facts {
	--wp--style--global--content-size: var(--wp--custom--width--detail-wide, 62rem);
	--wp--style--global--wide-size: var(--wp--custom--width--detail-wide, 62rem);
	padding-top: var(--wp--preset--spacing--lg);
}

main .hn-detail__facts .hn-hero__facts {
	column-gap: var(--wp--preset--spacing--lg);
	row-gap: var(--wp--preset--spacing--xs);
}

/* --- Shared hero rhythm (Task 06F) -----------------------------------
 * One spacing scale for every element below the breadcrumb/eyebrow,
 * on the hub and all five detail pages, at every breakpoint:
 *
 *   breadcrumb (detail) / eyebrow (hub)   ← fixed offset from header
 *   ↕ SM (1rem)
 *   H1
 *   ↕ SM (1rem)
 *   distinction line (detail) / summary (hub)
 *   ↕ MD (1.5rem)
 *   call-to-action buttons
 *
 * The first rule zeroes core block-gap margins and the older per-element
 * margins (breadcrumb margin-bottom, h1 0.5rem, buttons 1.25rem) so the
 * scale below is the only source of vertical space. Left alignment is
 * unchanged: every child is pinned to the 62rem band's left edge by the
 * max() margin rule in the inner-content section above. */
.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container > *,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/* The breadcrumb trail renders as nav.rank-math-breadcrumb > p inside
 * the group; the paragraph's default margin collapses up through both
 * wrappers and would add ~13px to the fixed offset. Zeroed so the
 * offset is exactly the token. */
.wp-block-cover.hn-hero--accommodation .hn-breadcrumbs p {
	margin-block-start: 0;
	margin-block-end: 0;
}

.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container > h1,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > h1 {
	margin-block-start: var(--wp--preset--spacing--sm);
}

.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container > .hn-hero__summary,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > .hn-hero__distinction,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > .hn-hero__summary {
	margin-block-start: var(--wp--preset--spacing--sm);
}

/* Task 10.1a — heroes carrying BOTH a breadcrumb and an eyebrow separate
 * the two metadata levels with the MD step, so the trail and the editorial
 * eyebrow read as distinct rows rather than one compressed block. Scoped to
 * an eyebrow that immediately follows the breadcrumb trail: the hub / rates /
 * home eyebrow is a first child (no breadcrumb) and is untouched. The
 * eyebrow→H1 gap stays at the shared SM step (H1 keeps margin-block-start:sm),
 * giving the required MD-then-SM stepping. (0,4,0) beats the `> *` reset. */
.wp-block-cover.hn-hero .hn-breadcrumbs + .hn-hero__eyebrow {
	margin-block-start: var(--wp--preset--spacing--md);
}

.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container > .wp-block-buttons,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container > .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* --- Per-page mobile focal points ------------------------------------
 * RETIRED in Task 58 Phase 2 (v0.2.85). Six page-slug rules
 * (`.page-slug-accommodations`, `-hillside-rooms`, `-balcony-rooms`,
 * `-gingerbread-cottages`, `-yellow-manor-house`, `-rose-villa`) used to
 * force a mobile-only `object-position` at <=781px with `!important`.
 * Every one of those sources is a 3:2, 4:3 or 2:1 photograph in a
 * 2.32:1 desktop band and a ~0.75:1 phone band, so the desktop crop only
 * ever moves VERTICALLY and the phone crop only ever moves HORIZONTALLY:
 * one block focal point — the old mobile X paired with the old desktop
 * Y — reproduces both accepted crops from the editor's own picker. The
 * six pages now carry that merged focal point in their block attributes
 * (Task 58 Phase 2 change register), so the picker an editor sees is the
 * value that renders at every width. No slug-scoped hero CSS remains. */

/* --- Gingerbread Cottages mobile overlay -----------------------------
 * RETIRED in Task 06F. The 05.6A override existed because the old
 * bottom-weighted mobile gradient was lightest exactly where this
 * photograph's bright sky sat. The shared mobile gradient is now
 * top-weighted (0.88→0.80 across the text band), which covers the sky
 * directly; measured contrast is recorded in the 06F report. */

/* --- Yellow Manor House / Rose Villa desktop overlay retunes ----------
 * RETIRED in Task 51 (v0.2.72) together with the gradient they retuned
 * (Task 06F deepened the third stop for the YMH pool-view sky; Task
 * 05.6A retuned every stop for Rose Villa). Both pages now take the
 * shared local copy-zone scrim, measured against their own photographs
 * in the Task 51 contrast register; no page-slug overlay rule remains. */


/* =====================================================================
 * COMPARISON TABLES  (Task 05.6B, v0.2.17)
 * =====================================================================
 *
 * The cottage comparison on /accommodations/gingerbread-cottages/ is an
 * eight-column table. Its min-content width is 905px, so on a phone it
 * previously had to scroll sideways: the column headings scrolled out of
 * view, rows could not be compared, and part of the page's main
 * accommodation-selection tool was hidden off screen.
 *
 * Below 1024px the same table is re-laid out as one stacked card per
 * comparison row. Nothing is duplicated: there is still exactly one
 * <table> in the DOM and the owner still edits it as a table.
 *
 * BREAKPOINT — 1024px is measured, not conventional. The table's
 * min-content width is 905px and the detail-wide band is 992px, so the
 * table only fits without scrolling once the viewport is wide enough to
 * give it ~905px of content width. 1024px leaves ~79px of headroom;
 * 768px would leave the table 200px short and force a scrollbar again.
 * At 1024px and above the table renders exactly as it did before this
 * change. Re-measure min-content if a column is added.
 *
 * LABELS — once table elements are given `display:block` the browser
 * drops the table role, and with it the header/value association. The
 * labels are therefore injected as real text nodes by
 * inc/comparison-table.php (read from the table's own <thead>), not as
 * CSS generated content, so they survive with CSS off and appear in the
 * accessibility tree. They are `display:none` at desktop widths, where
 * the real <th> headers do the work — so assistive technology is offered
 * one copy of the information, never two.
 * =================================================================== */

.hn-cottage-comparison__label {
	display: none;
}

@media (max-width: 1023px) {

	/* Nothing overflows any more, so drop the scroll container. */
	.hn-cottage-comparison {
		overflow-x: visible;
	}

	.hn-cottage-comparison table,
	.hn-cottage-comparison tbody,
	.hn-cottage-comparison tbody tr,
	.hn-cottage-comparison tbody th,
	.hn-cottage-comparison tbody td {
		display: block;
		width: auto;
	}

	/* Column headings now travel inside each cell. */
	.hn-cottage-comparison thead {
		display: none;
	}

	/* One card per comparison row. */
	.hn-cottage-comparison tbody tr {
		background-color: var(--wp--preset--color--surface);
		border: 1px solid var(--wp--preset--color--line);
		border-radius: 2px;
		padding: 1rem 1.125rem 1.25rem;
	}

	.hn-cottage-comparison tbody tr + tr {
		margin-top: 1rem;
	}

	/* The row's own <th scope="row"> becomes the card title. */
	.hn-cottage-comparison tbody tr > th {
		border: 0;
		border-bottom: 1px solid var(--wp--preset--color--line);
		color: var(--wp--preset--color--heading);
		font-family: var(--wp--preset--font-family--display);
		font-size: var(--wp--preset--font-size--large);
		font-weight: 600;
		line-height: 1.25;
		margin: 0;
		padding: 0 0 0.625rem;
	}

	.hn-cottage-comparison tbody td {
		border: 0;
		padding: 0.75rem 0 0;
	}

	.hn-cottage-comparison__label {
		color: var(--wp--preset--color--text-muted);
		display: block;
		font-family: var(--wp--preset--font-family--body);
		font-size: var(--wp--preset--font-size--x-small);
		font-weight: 600;
		letter-spacing: 0.1em;
		line-height: 1.4;
		margin-bottom: 0.125rem;
		text-transform: uppercase;
	}

	.hn-cottage-comparison__value {
		display: block;
		overflow-wrap: break-word;
	}
}

/* =====================================================================
 * TASK 11.1 — Gingerbread cottage desktop comparison density (v0.2.40)
 * =====================================================================
 *
 * Scope: ONLY .hn-cottage-comparison, ONLY the desktop table (>=1024px).
 * Below 1024px the stacked-card treatment above is untouched.
 *
 * Measurement (staging, theme 0.2.39) found the desktop table's height
 * was driven by an unusually loose inherited body line-height (computed
 * ~1.65 — editorial prose spacing), NOT by font size or cell padding:
 *   - Cell padding was already tight (0.5rem vertical), below this task's
 *     own recommended 0.6rem floor, so it is deliberately NOT reduced.
 *   - A horizontal-padding trim was tested and proved threshold-fragile:
 *     a 1.6px change swung table height ~6% by tipping cell wrapping, so
 *     padding is left unchanged to keep the result stable, not cramped.
 *   - Body and column-heading FONT SIZES are left unchanged, so body text
 *     stays comfortably readable (~20px, well above the 14px floor) and
 *     the "Cottage for ..." row headings remain the strongest scan anchor.
 *
 * The single restrained change is tightening line-height from ~1.65 to
 * 1.42 (inside this task's 1.4-1.5 target range). Measured result: table
 * height -12.8% at 1024px and -12.7% at 1366/1440px, consistent across
 * widths, with no new wrapping, no overflow and no change below 1024px.
 * No !important needed (no competing desktop rule on these cells).
 * Full before/after measurements: Task11.1 density-refinement report.
 * =================================================================== */
@media (min-width: 1024px) {
	.hn-cottage-comparison th,
	.hn-cottage-comparison td {
		line-height: 1.42;
	}
}

/* =====================================================================
 * MOBILE TYPE SCALE & RESPONSIVE SPACING  (Task 06D, v0.2.20)
 * =====================================================================
 *
 * The type-scale itself is fixed in theme.json, not here. Root cause of
 * the small mobile body text: theme.json v3 shows WordPress core's
 * default font-size presets unless `settings.typography.defaultFontSizes`
 * is false, and when a theme preset reuses a default slug (small, medium,
 * large, x-large) THE CORE DEFAULT WINS SILENTLY. The theme's intended
 * scale never rendered; core's auto-fluid defaults did (body clamp
 * 14px-20px = 14.4px at 375px). v0.2.20 sets defaultFontSizes: false and
 * defines the full scale explicitly, preserving today's desktop sizes
 * (fluid maxes, reached at the same 1120px viewport as before) while
 * raising the mobile minimums to readable values:
 *
 *   small    13px fixed      -> 14px fixed
 *   medium   14px  -> 20px   -> 16px   -> 20px   (body >= 16px on phones)
 *   large    22.04 -> 36px   -> 21px   -> 36px   (H3 / lead)
 *   x-large  25.01 -> 42px   -> 24px   -> 42px   (H2)
 *   xx-large 30px  -> 38px   ->        unchanged (standard H1)
 *   display  36px  -> 52px   -> 34px   -> 52px   (hero H1)
 *   x-small  13px fixed      ->        unchanged (eyebrow / caption)
 *
 * The rules below are the only component-level spacing refinements this
 * task adds; everything else inherits the token change.
 * ------------------------------------------------------------------- */

/* Long-form prose pages (Privacy, Terms, Ginger Tales posts): headings
 * that are direct children of the content column get more air above than
 * the uniform block gap, so sections of a long document read as sections.
 * Scoped to direct children only - headings inside hn- section groups,
 * cards and grids are untouched. */
main .entry-content > h2 {
	margin-block-start: 2.5rem;
}

main .entry-content > h3 {
	margin-block-start: 1.75rem;
}

/* Footer links on small screens: the desktop 0.3rem rhythm packs the
 * stacked link lists too tightly for touch. Slightly more air and an
 * enlarged tappable line, mobile widths only - desktop is unchanged. */
@media (max-width: 781px) {
	.hn-footer .wp-block-list li {
		margin-bottom: 0.55rem;
	}

	.hn-footer a:not(.wp-block-button__link) {
		display: inline-block;
		padding: 0.15em 0;
	}
}

/* ---------------------------------------------------------------------
 * Task 06G - Homepage hero vertical fit and viewport resilience
 * -------------------------------------------------------------------
 * Scope: .hn-hero--home ONLY. The accommodation hero family (06F) is
 * untouched. Composition, image, copy, type scale and CTA labels are
 * unchanged; this block adjusts vertical geometry only.
 *
 * Problems measured on 0.2.22 (visitor state, 1440w):
 *   - eyebrow sat 20px under the header at every desktop height (the
 *     cover's default padding was the whole separation);
 *   - the content stack is 601px tall, so the CTA row bottom landed at
 *     714px: clipped at 650px viewports, zero margin at 720px.
 *
 * Fixes:
 *   1. Viewport-height-aware min-height: the hero box never asks for
 *      more than the viewport minus the header (svh with vh fallback).
 *      The page markup carries an inline min-height:72vh, so the
 *      override needs !important (same precedent as the focal-point
 *      override above). Content taller than the box still grows it -
 *      normal cover behaviour.
 *   2. Protected padding: LG (2.5rem) top and bottom on desktop, MD
 *      (1.5rem) on mobile, on the cover itself. The eyebrow can never
 *      sit closer to the header than this, centred or not.
 *   3. Centred alignment is kept whenever the content fits inside the
 *      box (unchanged align-items:center).
 *   4. Short desktop viewports (<=750px tall, where 601px of stack +
 *      93px of header cannot fit): top-anchored fallback with MD
 *      protected padding, and the H1 / supporting-line measures relax
 *      (21ch -> 28ch, 34rem -> 44rem) so the stack shortens by about
 *      120px and the full CTA row clears the fold with room to spare.
 *      Type sizes are NOT changed; only line wrapping tightens, and
 *      only in this fallback. At >=751px heights the composition is
 *      pixel-identical to 0.2.22 apart from the protected padding.
 *
 * Header heights measured 0.2.22: 93px desktop, 76px at 320-375,
 * 100px at 768. --hn-home-header only feeds the min-height cap, so a
 * small drift if the header changes is cosmetic, not breaking.
 * ------------------------------------------------------------------- */

/* Task 29 supersedes the desktop min-height only (mobile block below and
 * the short-desktop fallback are otherwise unchanged). 0.2.53 asked for
 * clamp(560px, 72svh, 760px) capped at the viewport minus the header, so
 * the hero stopped short of the fold at every normal desktop height and
 * left an unexplained blank band: measured header+hero against viewport
 * was 653/720 (-67px), 774/900 (-126px) and 853/1080 (-227px), while the
 * following section adds 20px block-gap + 64px of its own top padding, so
 * the fold fell inside 84-210px of empty space. The hero now asks for
 * exactly the viewport minus the measured header, which puts its bottom
 * edge on the fold and starts the next section immediately below it
 * without deliberately exposing a slice of it (measured 0px difference at
 * 1024x650, 1366x650, 1440x720, 1440x900, 1920x1080, 899/959/960x700).
 * This is min-height, not height: content taller than the box still grows
 * it, which is why nothing clips on short screens - see the fallback
 * below. The 1040px ceiling keeps the treatment honest above about
 * 1130px of viewport height (it covers the tallest mandated viewport,
 * 1920x1080, which needs 987px, plus headroom): past that, filling the
 * screen only floats the content stack in the middle of a badly cropped
 * photograph. svh, not vh, so mobile browser UI cannot make the hero
 * taller than the visible viewport; the vh line is the fallback for
 * engines without svh. !important is still required because the page
 * markup carries an inline min-height:72vh (unchanged precedent). */
.wp-block-cover.hn-hero--home {
	--hn-home-header: 93px;
	min-height: min(calc(100vh - var(--hn-home-header)), 1040px) !important;
	min-height: min(calc(100svh - var(--hn-home-header)), 1040px) !important;
	padding-top: var(--wp--preset--spacing--lg);
	padding-bottom: var(--wp--preset--spacing--lg);
}

@media (max-width: 781px) {
	.wp-block-cover.hn-hero--home {
		--hn-home-header: 76px;
		min-height: min(clamp(440px, 72vh, 620px), calc(100vh - var(--hn-home-header))) !important;
		min-height: min(clamp(440px, 72svh, 620px), calc(100svh - var(--hn-home-header))) !important;
		padding-top: var(--wp--preset--spacing--md);
		padding-bottom: var(--wp--preset--spacing--md);
	}
}

/* Short-desktop fallback: relax the text measures so the complete CTA row
 * stays inside the first viewport.
 *
 * Task 29: the top-anchor (align-items: flex-start) is removed. It existed
 * because the 0.2.53 hero was capped at clamp(...,760px) and could be
 * shorter than the space above the fold; with the hero now sized to the
 * viewport minus the header, top-anchoring left the stack 24px under the
 * header with 183-196px of dead space beneath it (measured at 1440x720,
 * 899x700, 959x700) - the same blank-band defect, moved inside the hero.
 * Centring distributes that space evenly instead and is what gives the
 * eyebrow its breathing room at short heights: header-to-eyebrow went
 * from a flat 24px to 64-99px, with 64-99px still clear below the CTA row.
 * Content safety is unaffected: because the box is sized with min-height,
 * a stack taller than the box grows the box rather than overflowing it,
 * so the stack top never rises above the hero top (verified down to
 * 1024x500 and 1366x520, where the CTA row falls below the fold but
 * nothing is clipped, hidden or unreachable). The relaxed measures below
 * are what keep the stack short enough to fit in the first place and are
 * unchanged. */
/* Task 58 Phase 2 (v0.2.85): the height gate rises from 750px to 800px so
 * that 768px-tall laptops (1024x768, 1366x768) take the fallback too —
 * Phase 1 measured the Home CTA row at 836/864px on those viewports,
 * below the fold, because the gate missed them by 18px. 900px-tall and
 * taller desktops are untouched. */
@media (min-width: 782px) and (max-height: 800px) {
	.wp-block-cover.hn-hero--home {
		padding-top: var(--wp--preset--spacing--md);
		padding-bottom: var(--wp--preset--spacing--md);
	}

	.wp-block-cover.hn-hero--home h1 {
		max-width: 28ch;
	}

	.wp-block-cover.hn-hero--home p:not(.hn-hero__eyebrow) {
		max-width: 44rem;
	}
}

/* ---------------------------------------------------------------------
 * Task 06G.1 - Homepage short-mobile fit and tablet header breakpoint
 * -------------------------------------------------------------------
 * Two corrections, both measured on 0.2.23 (visitor state):
 *
 * A. SHORT MOBILE (320x568): the hero content stack ran to 611px from
 *    the top of the viewport (header 76 + MD padding 24 + eyebrow 21 +
 *    gaps 8/20/20 + H1 120 + paragraph 208 + stacked CTA group 113),
 *    so the second CTA bottom sat 43px below the 568px fold. Spacing
 *    alone cannot recover the required 59px (43 + 16 clearance):
 *    maximum reasonable spacing savings measured ~34px. Per the task's
 *    escalation order a small homepage-only, short-screen-only type
 *    adjustment is therefore included alongside the spacing changes:
 *    H1 display -> xx-large preset (34px -> 30px at 320w) and the
 *    supporting paragraph large -> medium preset (21px -> 16px at
 *    320w). Both remain comfortable; the H1 stays clearly dominant.
 *    Measured result at 320x568: second CTA bottom 483px, 85px of
 *    viewport clear below it. Normal-height mobiles (320x667, 375x667)
 *    are excluded by the max-height condition and render identically
 *    to 0.2.23.
 *    !important on the two font-size overrides is required because
 *    core emits preset classes (.has-display-font-size,
 *    .has-large-font-size) with !important; scope is one media
 *    condition on one page variant only.
 *
 * B. TABLET HEADER (600-899px): the core navigation block switches to
 *    its overlay at <600px, but the full desktop menu (6 items), logo
 *    and Book Now need a measured 858px minimum to hold one line, so
 *    "Contact" wrapped at 600-857px, including 768. The overlay
 *    breakpoint is raised to 900px (858 measured + ~42px headroom for
 *    font-rendering and scrollbar variance). One condition governs
 *    the desktop-menu hide and the hamburger show; the open overlay
 *    (.is-menu-open) is deliberately excluded from the hide rule so
 *    the modal still renders while open. The compact Book Now and
 *    tightened header gap that previously applied <=781px are
 *    extended across 782-899.98px so the whole hamburger range shares
 *    one coherent header state. Selectors are scoped to .hn-header;
 *    footer navigation is untouched. Above 900px the header is
 *    byte-identical to 0.2.23.
 * ------------------------------------------------------------------- */

@media (max-width: 374px) and (max-height: 620px) {
	.wp-block-cover.hn-hero--home {
		padding-top: var(--wp--preset--spacing--sm);
		padding-bottom: var(--wp--preset--spacing--sm);
	}

	.wp-block-cover.hn-hero--home .wp-block-cover__inner-container > * {
		margin-block-start: 0.75rem;
	}

	.wp-block-cover.hn-hero--home .wp-block-cover__inner-container > :first-child {
		margin-block-start: 0;
	}

	.wp-block-cover.hn-hero--home h1 {
		margin-block-start: 0.375rem;
		font-size: var(--wp--preset--font-size--xx-large) !important; /* core preset class carries !important */
	}

	.wp-block-cover.hn-hero--home p:not(.hn-hero__eyebrow) {
		font-size: var(--wp--preset--font-size--medium) !important; /* core preset class carries !important */
	}

	.wp-block-cover.hn-hero--home .wp-block-buttons {
		gap: 0.75rem;
	}
}

/* ------------------------------------------------------------------
   TASK 26 (0.2.52) — header overlay breakpoint 900px -> 960px
   Measured cause: the primary navigation gained a seventh item
   ("Explore Nevis" -> /nevis/). At the tightest horizontal-nav width
   the six-item header row measured 780px used against 836px available
   (900px viewport, 32px gutters) = 56px of headroom, while the
   shortest sensible seventh label ("Nevis") costs 37px of text plus
   the 20px flex gap = 57px. Simulated in-page at every width:
     900px  - 6 items 1 row (header 93px) | +"Nevis" 2 rows (101px)
                                          | +"Explore Nevis" 2 rows (101px)
     940px  - +"Nevis" 1 row              | +"Explore Nevis" 2 rows
     960px+ - both labels 1 row
   So ANY seventh item wraps the header at 900-939px, and shortening
   the label does not fix it. The Task 26 brief forbids reducing the
   sitewide font size, tightening all navigation spacing, or adding
   page-specific CSS to force the label. The smallest reusable
   correction is therefore to hold the hamburger 60px further up, at
   959.98px, so the horizontal menu only appears where seven items
   genuinely fit. Same three media queries introduced by 0.2.24 and
   0.2.26, same selectors, one constant changed in each; at >=960px
   the header is byte-identical in behaviour to 0.2.51.
------------------------------------------------------------------- */

@media (min-width: 600px) and (max-width: 959.98px) {
	/* Hold the hamburger until the desktop menu genuinely fits (>=900px). */
	.hn-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.hn-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

@media (min-width: 782px) and (max-width: 959.98px) {
	/* Extend the compact header state across the whole hamburger range. */
	.hn-header .hn-button-book .wp-block-button__link {
		font-size: var(--wp--preset--font-size--small);
		padding: 0.6rem 0.9rem;
	}

	.hn-header .hn-header__navigation {
		gap: var(--wp--preset--spacing--xs);
	}
}

/* ------------------------------------------------------------------
   TASK 06H (0.2.25) — real-device / cross-browser / accessibility QA
   DEF-01 correction: the long unbreakable email link text
   (contactus@…) forces page-level horizontal overflow on narrow
   viewports when OS/browser TEXT-ONLY enlargement scales the rem-based
   type (measured: +47px overflow @150% text on the 375px homepage,
   +8px on the cottage page; grows further at 200%). Default-size and
   full-page-zoom rendering were unaffected. Allow email addresses to
   wrap at any character. Scoped to mailto links only — phone and
   WhatsApp link text is short and unaffected. No !important needed.
------------------------------------------------------------------- */
a[href^="mailto:"] {
	overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------
   TASK 06H.1 (0.2.26) — DEF-02: 200% text-enlargement header overflow
   Measured cause (375px viewport, root font 16px -> 32px proxy):
   every horizontal cost in the compact header scales with rem except
   the fixed-width logo — Book Now font 14->28px, its padding
   11.2->22.4px/side, header blockGap 20->40px, control gap 8->16px —
   while all three flex rows were nowrap. Preferred row width reached
   ~435px in a 360px client (=+75px page overflow in the QA iframe;
   +8px at 150%). Correction (Step 2 of the task's preferred order,
   after Step 1 alone proved insufficient): allow the compact header
   row to wrap into a controlled two-row layout — logo on row one,
   menu trigger + Book Now pushed to the right on row two. At 100%
   text every width 320-899px still fits on one line, so the accepted
   single-row presentation is unchanged; the second row appears only
   when enlarged text genuinely needs it. Scoped to the compact-header
   range; >=900px desktop header is untouched. No !important needed:
   .hn-header .hn-header__inner (0,2,0) beats core's emitted
   .wp-container-* layout rules (0,1,0).
------------------------------------------------------------------- */
@media (max-width: 959.98px) {
	.hn-header .hn-header__inner {
		flex-wrap: wrap;
		row-gap: 0.25rem;
	}

	.hn-header .hn-header__navigation {
		margin-left: auto;
		min-width: 0;
	}
}

/* Narrowest band (<=344px): with wrapping enabled, classic-scrollbar
   environments (desktop windows, the QA iframe) left the 100% row
   ~13px short, which would have wrapped it at normal text size and
   changed the accepted presentation. Tighten only gaps and Book Now
   side padding (Step 1 allowance) so the single row fits at 100%
   with ~4px headroom even beside a classic scrollbar. Element sizes
   (logo 124px, 44px trigger) are unchanged; previously the row bled
   ~13px into the right gutter at 320px, which this also corrects. */
@media (max-width: 344.98px) {
	.hn-header .hn-header__inner {
		column-gap: 8px;
	}

	.hn-header .hn-header__navigation {
		column-gap: 6px;
	}

	.hn-header .hn-button-book .wp-block-button__link {
		padding-left: 0.6rem;
		padding-right: 0.6rem;
	}
}

/* ------------------------------------------------------------------
   TASK 06H.1 (0.2.27) — DEF-03: 200% text-enlargement content overflow
   Found during 06H.1 regression (previously masked by the DEF-02
   header overflow): at 200% text-only enlargement on 320-375px
   viewports, long single words in content headings ("accommodation",
   "straightforward" at 48px display size) exceed the constrained
   column, and on the 404 template the suggestion-link text and the
   search form (input + button on a nowrap flex row) overflow the
   page (+68px worst case at 320px). Same defect class and same
   remedy as 06H's DEF-01 mailto fix: permit wrapping only where
   overflow would otherwise occur. overflow-wrap:anywhere is inert
   until a word cannot fit its line, so normal-size rendering is
   unchanged; the search form wraps the button under the input only
   when one row is impossible. Scoped to main content — header,
   footer and navigation are untouched. Tony approved widening 06H.1
   scope to include this fix (2026-07-22). No !important needed.
------------------------------------------------------------------- */
main :is(h1, h2, h3, h4) {
	overflow-wrap: anywhere;
}

main li a:not(.wp-block-button__link) {
	overflow-wrap: anywhere;
}

.wp-block-search__inside-wrapper {
	flex-wrap: wrap;
	row-gap: 0.5rem;
}

/* =====================================================================
 * TASK 07.1 — Rates hero viewport fit (v0.2.28)
 * ---------------------------------------------------------------------
 * Scope: ONLY the Rates & Booking Guidance hero, via the page-specific
 * class `hn-hero--rates` added to that page's cover block. The shared
 * accommodation hero family (hub + 5 detail pages) and the homepage
 * hero are untouched — the rules below never match them.
 *
 * Measured defect (DEF-07-01): at normal text the hero CTA group fell
 * below the fold at 320×568 (2nd CTA bottom 594px, −26px clearance),
 * 1366×650 (−114px) and 1440×720 (−44px). Measured causes:
 *   1. H1 measure — `.hn-hero--accommodation(s) h1` caps at 18ch, so
 *      the 26-character H1 wraps to two lines (123px) from ~1153px up.
 *   2. Support-copy measure — `.wp-block-cover.hn-hero p:not(…)` caps
 *      paragraphs at 34rem, forcing 5–6 lines at the fluid 29–36px
 *      size (up to 356px tall).
 *   3. Short-mobile stack — 40px offset + 16/16/24px rhythm + ~19px
 *      button gap exceeds a 568px viewport by 26px.
 * Hero min-heights were verified NOT to be a cause (content-driven),
 * so no geometry/min-height change is made.
 *
 * Specificity notes (no !important anywhere):
 *   - h1 measure must beat `.wp-block-cover.hn-hero h1` (0,2,1) and
 *     `.wp-block-cover.hn-hero--accommodations h1` (0,2,1)
 *     → `.wp-block-cover.hn-hero.hn-hero--rates h1` (0,3,1).
 *   - paragraph measure must beat
 *     `.wp-block-cover.hn-hero p:not(.hn-hero__eyebrow)` (0,3,1)
 *     → `.wp-block-cover.hn-hero.hn-hero--rates p.hn-hero__summary`
 *     (0,4,1).
 *   - short-mobile rhythm rules mirror the 06F selectors with
 *     `--rates` at equal specificity, later in file → they win.
 * ================================================================== */

/* Step 3 — text measure. One-line H1 (26ch ≈ 676px comfortably holds
 * the 26-character heading at the 52px display size) and a 44rem
 * support measure (~41ch at 36px — same relaxation precedent as the
 * 06G homepage short-height fallback). Desktop CTA row rises ~180px:
 * 1366×650 clearance −114 → +67, 1440×720 −44 → +137. */
.wp-block-cover.hn-hero.hn-hero--rates h1 {
	max-width: 26ch;
}

.wp-block-cover.hn-hero.hn-hero--rates p.hn-hero__summary {
	max-width: 44rem;
}

/* Step 2 — short-mobile compaction. Engages only when BOTH the width
 * is in the compact-header range AND the viewport is short (≤620px,
 * same height gate as the 06G.1 homepage short-mobile block), so
 * 375×667 and taller phones keep the standard rhythm. Spacing only —
 * type sizes untouched. 320×568: 2nd CTA bottom 594 → 546 (22px
 * clearance, ≥16 required). Also covers landscape phones (e.g.
 * 667×375). */
@media (max-width: 781.98px) and (max-height: 620px) {

	/* Header→eyebrow offset LG(40px) → MD(24px) on this page only. */
	.wp-block-cover.hn-hero--rates .wp-block-cover__inner-container {
		padding-top: var(--wp--preset--spacing--md);
	}

	/* Stack rhythm 16/16/24 → 10/10/16. */
	.wp-block-cover.hn-hero--rates .wp-block-cover__inner-container > h1 {
		margin-block-start: 0.625rem;
	}

	.wp-block-cover.hn-hero--rates .wp-block-cover__inner-container > .hn-hero__summary {
		margin-block-start: 0.625rem;
	}

	.wp-block-cover.hn-hero--rates .wp-block-cover__inner-container > .wp-block-buttons {
		margin-block-start: var(--wp--preset--spacing--sm);
	}

	/* Stacked-button gap ~19px → 8px. */
	.wp-block-cover.hn-hero--rates .wp-block-cover__inner-container .wp-block-buttons {
		gap: 0.5rem;
	}
}

/* =====================================================================
 * TASK 08 — Dining / Nevis Food page (v0.2.29)
 * ---------------------------------------------------------------------
 * Adds three page/component-scoped things and nothing else:
 *   1. hn-hero--dining  — the Dining hero variant. It reuses the whole
 *      accommodation-detail hero component (breadcrumb, top-anchored
 *      header offset, gradient, 44px CTAs) through hn-hero--accommodation
 *      and only re-tunes the measures/rhythm for the taller dining stack
 *      (breadcrumb + eyebrow + H1 + summary + two CTAs), mirroring the
 *      07.1 Rates-hero treatment so it still fits every required
 *      viewport including 320x568.
 *   2. hn-dining-event + hn-dining-facts — the Wednesday Pig Roast and
 *      Friday Pizza Night feature blocks (core media-text + an
 *      accessible label/value facts panel).
 *   3. hn-dining-experience-card — the editor-duplicable October-forward
 *      upsell card ("Hermitage — Dining Experience Card" pattern).
 * Everything is scoped to these classes: the shared hero family, the
 * homepage hero, header, footer, navigation and every approved page are
 * untouched. No !important anywhere.
 * ================================================================== */

/* --- Dining hero -----------------------------------------------------
 * Restore the shared vertical rhythm for the two children the singular
 * .hn-hero--accommodation selectors do not target on this page: the
 * eyebrow (it sits between the breadcrumb and the H1) and the summary
 * line (the detail hero styles .hn-hero__distinction; this page uses
 * .hn-hero__summary). Specificity (0,5,0) beats the shared `> *` reset
 * (0,3,0). */
/* (Task 10.1a) The eyebrow + summary rhythm is now supplied by the shared
 * accommodation-hero scale above — the summary through the extended
 * `> .hn-hero__summary` rule (SM), the eyebrow through the
 * `.hn-breadcrumbs + .hn-hero__eyebrow` rule (MD). The former dining-only
 * SM override on the eyebrow is removed so the MD breadcrumb→eyebrow
 * separation is not overridden back to SM on this page family. */

/* H1 measure — the editorial H1 wraps to two balanced lines at the 52px
 * display size instead of the shared 18ch cap (which would force three
 * or four lines and push the CTA group down). (0,3,1) beats the shared
 * (0,2,1) caps. */
.wp-block-cover.hn-hero.hn-hero--dining h1 {
	max-width: 22ch;
}

/* Support-copy measure — 44rem (~41ch), the same relaxation precedent as
 * the 07.1 Rates hero and the 06G homepage short-height fallback.
 * (0,4,1) beats `.wp-block-cover.hn-hero p:not(.hn-hero__eyebrow)`
 * (0,3,1). */
.wp-block-cover.hn-hero.hn-hero--dining p.hn-hero__summary {
	max-width: 44rem;
}

/* Short-mobile compaction — engages only when the viewport is both in
 * the compact-header range AND short (<=620px high), so 375x667 and
 * taller phones keep the standard rhythm. Spacing only; type sizes are
 * untouched. Mirrors the 07.1 Rates block, with the eyebrow gap tightened
 * as well because the dining hero carries one extra line. Also covers
 * landscape phones (e.g. 667x375). */
@media (max-width: 781.98px) and (max-height: 620px) {

	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container {
		padding-top: var(--wp--preset--spacing--md);
	}

	/* Task 10.1a — keep the breadcrumb→eyebrow separation visible even under
	 * short-screen compaction: the eyebrow holds the SM step while the H1 and
	 * summary tighten to 0.5rem, so the two metadata levels stay distinct. */
	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > .hn-hero__eyebrow {
		margin-block-start: var(--wp--preset--spacing--sm);
	}

	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > h1,
	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > .hn-hero__summary {
		margin-block-start: 0.5rem;
	}

	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > .wp-block-buttons {
		margin-block-start: var(--wp--preset--spacing--sm);
	}

	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container .wp-block-buttons {
		gap: 0.5rem;
	}

	/* Reduce the hero padding-bottom too so the whole stack clears a
	 * 568px viewport. */
	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container {
		padding-bottom: var(--wp--preset--spacing--md);
	}

	/* Type reduction — the dining H1 and summary are longer than the
	 * Rates hero's, so on a short phone they also step down a size (the
	 * same approach as the 06G.1 homepage short-mobile block). The
	 * !important is required because WordPress core's font-size preset
	 * classes (has-display-font-size / has-large-font-size) themselves
	 * carry !important; documented in the theme readme. Height-gated at
	 * <=620px, so 375x667 and taller phones keep the full display sizes. */
	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > h1.has-display-font-size {
		font-size: 1.75rem !important;
		line-height: 1.15 !important;
	}

	/* Task 58 Phase 2: the summary now carries the `lead` preset (was `large`);
	 * the selector follows it so this compaction still engages. */
	.wp-block-cover.hn-hero--dining .wp-block-cover__inner-container > .hn-hero__summary.has-lead-font-size {
		font-size: 1rem !important;
		line-height: 1.4 !important;
	}
}

/* The mobile-only focal point for the former dining hero photograph
 * (`.page-slug-nevis-food .hn-hero { --hn-hero-focus-mobile: 50% 42%; }`)
 * was retired in Task 51 (v0.2.72) with that photograph; the new hero
 * carries its focal point on the block. */

/* --- Dining event feature (Pig Roast / Pizza Night) ------------------
 * Built on core media-text: the photograph on one side, the event
 * content on the other, stacking media-above-content on mobile in a
 * logical reading order. Event identity is carried by the text label and
 * heading, never by colour alone. Alternate the image side per event
 * from the block toolbar — one DOM structure, no duplicate markup. */
.hn-dining-event {
	margin-block: var(--wp--preset--spacing--xl);
}

.hn-dining-event .wp-block-media-text__content {
	padding-block: var(--wp--preset--spacing--md);
	align-self: center;
}

.hn-dining-event .hn-eyebrow {
	margin-block-end: var(--wp--preset--spacing--xs);
}

.hn-dining-event .hn-dining-facts {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* --- Dining facts panel ---------------------------------------------
 * Accessible label/value rows in a quiet panel: each row is a strong
 * label followed by its value, so essential facts are never carried by
 * layout or colour alone (brief §6/§12). Single column, so it collapses
 * to mobile with no change. */
.hn-dining-facts {
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
	display: grid;
	gap: var(--wp--preset--spacing--xs);
}

.hn-dining-facts .hn-dining-facts__row {
	margin: 0;
}

.hn-dining-facts .hn-dining-facts__row strong {
	color: var(--wp--preset--color--heading);
}

/* --- Dining experience card (October-forward upsells) ---------------
 * Editor-duplicable card for a CONFIRMED dining offer. Registered as the
 * "Hermitage — Dining Experience Card" pattern; the owner adds, edits,
 * reorders or removes cards in the block editor with no code changes. No
 * card is published until its offer, inclusions and price are approved. */
.hn-dining-experience-card {
	background-color: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 4px;
	padding: var(--wp--preset--spacing--md);
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--sm);
	height: 100%;
}

.hn-dining-experience-card img {
	border-radius: 2px;
}

.hn-dining-experience-card .hn-dining-experience-card__meta {
	color: var(--wp--preset--color--text-muted);
	margin: 0;
}

.hn-dining-experience-card .wp-block-buttons {
	margin-block-start: auto;
}

/* =====================================================================
 * TASK 09 — Sample menu pages (v0.2.32)
 * =====================================================================
 * Three coordinated pages — /dinner-menu/, /breakfast/, /lunch/ — share
 * one lightweight system: a compact editorial header (content leads, not
 * a full-bleed photo), a clear "sample menu" notice, quietly styled menu
 * sections built from headings and plain lists (never tables or price
 * columns), a dietary note, and menu cross-links. Scoped to the hn-menu
 * classes; no new JavaScript. The "Hermitage — Sample Menu Section"
 * pattern (patterns/sample-menu-section.php) is the editable unit.
 * ================================================================== */

/* --- Compact editorial header ---------------------------------------
 * Menu pages lead with words, not a hotel hero. A constrained intro
 * (breadcrumb, eyebrow, H1, one lead line) then one modest image. */
.hn-menu-intro .hn-eyebrow {
	margin-block-end: var(--wp--preset--spacing--xs);
}

.hn-menu-intro .hn-menu-intro__lead {
	color: var(--wp--preset--color--text-muted);
	max-width: 44rem;
}

.hn-menu-image img {
	border-radius: 2px;
}

/* --- Sample-menu notice ---------------------------------------------
 * Appears before any dish listing, in normal reading order. A quiet warm
 * panel with a single accent rule so it is prominent but not alarming;
 * its meaning is carried by its heading and text, never by colour. */
.hn-sample-menu-notice {
	background-color: var(--wp--preset--color--surface-warm);
	border-left: 3px solid var(--wp--preset--color--accent);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
	margin-block: var(--wp--preset--spacing--lg);
}

.hn-sample-menu-notice > :first-child { margin-block-start: 0; }
.hn-sample-menu-notice > :last-child { margin-block-end: 0; }

/* The notice heading sits below the page H1 in importance, so it is set
 * one step down from a standard section H2. */
.hn-sample-menu-notice h2 {
	font-size: var(--wp--preset--font-size--large);
	margin-block-end: var(--wp--preset--spacing--xs);
}

/* --- Menu sections --------------------------------------------------- */
.hn-menu-section {
	margin-block-start: var(--wp--preset--spacing--xl);
}

.hn-menu-section__intro {
	color: var(--wp--preset--color--text-muted);
	margin-block-start: var(--wp--preset--spacing--xs);
}

/* Dish list: a plain semantic list — no bullets, no price column, no
 * table, no printed-menu border box. Generous row spacing does the work;
 * the dish name is set in the display face to separate it from its
 * description. Long names wrap rather than overflow at narrow widths. */
.hn-menu-items {
	list-style: none;
	margin-block: var(--wp--preset--spacing--md) 0;
	padding-left: 0;
	display: grid;
	gap: var(--wp--preset--spacing--sm);
}

.hn-menu-items > li {
	margin: 0;
	line-height: 1.5;
	max-width: 44rem;
	overflow-wrap: break-word;
}

.hn-menu-items > li strong {
	color: var(--wp--preset--color--heading);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 400;
}

/* --- Dietary / current-menu note and dinner event note --------------
 * Quiet warm panels that set practical notes apart from the menu itself
 * without shouting. Single column, so they collapse to mobile unchanged. */
.hn-menu-note {
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
	margin-block: var(--wp--preset--spacing--lg);
}

.hn-menu-note > :first-child { margin-block-start: 0; }
.hn-menu-note > :last-child { margin-block-end: 0; }

/* --- Menu cross-links ----------------------------------------------- */
.hn-menu-crosslinks {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--md);
	margin-block-start: var(--wp--preset--spacing--sm);
	padding-left: 0;
	list-style: none;
}

.hn-menu-crosslinks li {
	margin: 0;
}

/* =====================================================================
 * TASK 09.1 — Sample menu visual refinement (v0.2.33)
 * =====================================================================
 * Turns the three sample-menu pages and the Dining menu navigation into a
 * coordinated editorial family: a wider (~57rem) layout band with still-
 * controlled text measures, an image+notice feature composition, menu
 * sections separated by a restrained rule with a small accent marker, a
 * responsive two-column dish grid (name in the display face, description
 * muted), a designed sample-notice, a compact menu-family strip, and a
 * three-card Dining navigation. Extends the TASK 09 classes; no new JS.
 * ================================================================== */

/* Wider editorial band for the menu body. Higher specificity than core's
 * generated `.alignwide` rule, so no !important (mirrors .hn-w-grid). Text
 * measures inside stay controlled by the per-element caps below. */
main :where(.is-layout-constrained) > .hn-menu-w.alignwide {
	max-width: 57rem;
}

.hn-menu-intro__lead { max-width: 44rem; }

/* --- Feature area: image + sample notice as one opening composition --- */
.hn-menu-feature { margin-block: var(--wp--preset--spacing--lg); }

.hn-menu-feature > .hn-menu-image { margin: 0; }
.hn-menu-feature > .hn-menu-image img { border-radius: 2px; }

@media (min-width: 782px) {
	.hn-menu-feature {
		display: grid;
		grid-template-columns: 1.5fr 1fr;
		gap: var(--wp--preset--spacing--md);
		align-items: center;
	}
	.hn-menu-feature > .hn-sample-menu-notice { margin: 0; }
	.hn-menu-feature > .hn-menu-image img { width: 100%; }
}

/* --- Sample-menu notice: designed, not a disclaimer --- */
.hn-sample-menu-notice {
	background-color: var(--wp--preset--color--surface-warm);
	border-left: 3px solid var(--wp--preset--color--accent);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
}
.hn-sample-menu-notice > :first-child { margin-block-start: 0; }
.hn-sample-menu-notice > :last-child { margin-block-end: 0; }
.hn-sample-menu-notice .hn-eyebrow { margin-block-end: 0.25rem; /* Task 12.3: was var(--wp--preset--spacing--2xs); digit-leading slug is not emitted as a CSS var and collapsed to 0 — restored to the intended 2XS value (0.25rem) */ }
.hn-sample-menu-notice h2 {
	font-size: var(--wp--preset--font-size--large);
	margin-block: 0 var(--wp--preset--spacing--xs);
}
.hn-sample-menu-notice p { margin-block-end: 0; }

/* --- Menu sections: restrained rule + small accent marker --- */
.hn-menu-layout { margin-block-start: var(--wp--preset--spacing--lg); }

.hn-menu-section {
	margin-block-start: var(--wp--preset--spacing--lg);
	padding-block-start: var(--wp--preset--spacing--md);
	border-top: 1px solid var(--wp--preset--color--line);
	position: relative;
}
/* small orange category marker sitting on the section rule */
.hn-menu-section::before {
	content: "";
	position: absolute;
	top: -2px;
	left: 0;
	width: 2.5rem;
	height: 3px;
	background-color: var(--wp--preset--color--accent);
}
.hn-menu-section__heading { margin-block: 0; }
.hn-menu-section__intro {
	color: var(--wp--preset--color--text-muted);
	max-width: 44rem;
	margin-block: var(--wp--preset--spacing--xs) 0;
}

/* Dish grid: one column on narrow screens, two comfortable columns when
 * each fits >=21rem. min(100%,21rem) prevents overflow at 320px. */
.hn-menu-items {
	list-style: none;
	margin-block: var(--wp--preset--spacing--md) 0;
	padding-left: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
	gap: var(--wp--preset--spacing--sm) var(--wp--preset--spacing--xl);
}
.hn-menu-items > li {
	margin: 0;
	max-width: none;
	line-height: 1.5;
	overflow-wrap: break-word;
	color: var(--wp--preset--color--text-muted);
}
.hn-menu-items > li strong {
	color: var(--wp--preset--color--heading);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 400;
	font-size: 1.0625rem;
}

/* --- Compact menu-family navigation (menu pages) --- */
.hn-menu-familynav {
	margin-block-start: var(--wp--preset--spacing--lg);
	padding-block-start: var(--wp--preset--spacing--md);
	border-top: 1px solid var(--wp--preset--color--line);
}
.hn-menu-familynav .hn-menu-familynav__links {
	list-style: none;
	padding-left: 0;
	margin-block: var(--wp--preset--spacing--sm) 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--lg);
}
.hn-menu-familynav .hn-menu-familynav__links li { margin: 0; }
.hn-menu-familynav .hn-menu-familynav__links a {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.0625rem;
	text-decoration: none;
}
.hn-menu-familynav .hn-menu-familynav__links a:hover,
.hn-menu-familynav .hn-menu-familynav__links a:focus { text-decoration: underline; }

/* --- Stay cross-sell + dietary note panels (reuse hn-menu-note) --- */
.hn-menu-crosssell { margin-block-start: var(--wp--preset--spacing--lg); }

/* --- Dining page: three-card sample-menu navigation --- */
.hn-menu-cards {
	list-style: none;
	padding-left: 0;
	margin-block: var(--wp--preset--spacing--md) 0;
	display: grid;
	gap: var(--wp--preset--spacing--md);
	/* auto-fit rem tracks: three across on wide screens, and gracefully
	 * down to one as the viewport narrows or text is enlarged (15rem grows
	 * with the root font-size, so 200% text collapses the row). */
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/* The card row fills the full width of its wrap even when the wrap uses a
 * constrained layout, so wide screens show three across (the wrap's
 * heading and intro keep the reading measure). */
.hn-menu-cards-wrap > .hn-menu-cards { max-width: none; }
.hn-menu-cards > li { margin: 0; }
.hn-menu-card {
	background-color: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-top: 3px solid var(--wp--preset--color--accent);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md);
	display: flex;
	flex-direction: column;
	gap: 0.25rem; /* Task 12.3: was var(--wp--preset--spacing--2xs); digit-leading slug is not emitted as a CSS var and collapsed to 0 — restored to the intended 2XS value (0.25rem). Note: .hn-menu-card display is overridden to grid by the Task 09.2 rule below; this gap applies as the grid row-gap. */
	height: 100%;
}
.hn-menu-card .hn-menu-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	color: var(--wp--preset--color--heading);
	margin: 0;
}
.hn-menu-card .hn-menu-card__desc {
	color: var(--wp--preset--color--text-muted);
	margin: 0;
	flex: 1 1 auto;
}
.hn-menu-card .hn-menu-card__cta {
	margin-block-start: var(--wp--preset--spacing--xs);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	text-decoration: none;
}
.hn-menu-card .hn-menu-card__cta::after { content: "\00a0\2192"; }
.hn-menu-card .hn-menu-card__cta:hover,
.hn-menu-card .hn-menu-card__cta:focus { text-decoration: underline; }

/* =====================================================================
 * TASK 09.2 — Menu card alignment correction (v0.2.36)
 * =====================================================================
 * Alignment only — no copy, colour, border or width change. Two causes of
 * the visible drop: (1) an inherited 20px block margin on the 2nd and 3rd
 * cards, and (2) unequal heading heights (one line vs two) pushing the
 * description and CTA out of line. Fix: reset the inherited margins, give
 * each card an internal grid (eyebrow / heading / description / CTA) so the
 * description fills and the CTA pins to a common baseline, and reserve a
 * consistent two-line heading area on desktop. The reserve is 3.3em, not
 * the 2.35em of a tight-leading heading, because this card title is a
 * paragraph at 1.65 line-height (two lines = 2 x 1.65em). Actual classes
 * used (hn-menu-card__title / __desc / __ctawrap, hn-eyebrow). */
.hn-menu-cards { align-items: stretch; }

.hn-menu-card {
	display: grid;
	grid-template-rows: auto auto 1fr auto;
	height: 100%;
	margin-top: 0;
}

.hn-menu-card > * { margin-block: 0; }

.hn-menu-card .hn-menu-card__ctawrap {
	margin-block-start: var(--wp--preset--spacing--sm);
	align-self: end;
}

@media (min-width: 900px) {
	.hn-menu-card .hn-menu-card__title { min-height: 3.3em; }
}

/* =====================================================================
 * TASK 09.3 — Dining hero "View our sample menus" text link (v0.2.37)
 * =====================================================================
 * The sample-menu navigation was repositioned (after "The restaurant",
 * before Pig Roast) with anchor #sample-menus and a restrained hero text
 * link. The is-style-text-link default colour is brand green, which is
 * invisible on the dark dining hero, so lift hero text links to the
 * surface colour (accent on hover/focus). Scoped to .hn-hero; the underline
 * and text-link treatment are otherwise unchanged, and no other text link
 * on the site is affected. This is the only reason for the version bump. */
.hn-hero .wp-block-button.is-style-text-link .wp-block-button__link {
	color: var(--wp--preset--color--surface);
}

.hn-hero .wp-block-button.is-style-text-link .wp-block-button__link:hover,
.hn-hero .wp-block-button.is-style-text-link .wp-block-button__link:focus {
	color: var(--wp--preset--color--accent);
}

/* =====================================================================
 * TASK 09.3a — Breathing room above the repositioned menu navigation (v0.2.38)
 * =====================================================================
 * After moving the sample-menu navigation to sit between "The restaurant"
 * and the Pig Roast, it began too abruptly under the restaurant block's
 * "Ask about dining" button. Add space ABOVE the section only (not inside
 * the cards, not between heading and intro) so it reads as a new major
 * section: LG (40px) on mobile, XL (64px) from 782px up. Actual wrapper
 * class hn-menu-cards-wrap; overrides the flow block-gap (:where, 0 spec). */
.hn-menu-cards-wrap {
	margin-block-start: var(--wp--preset--spacing--lg);
}

@media (min-width: 782px) {
	.hn-menu-cards-wrap {
		margin-block-start: var(--wp--preset--spacing--xl);
	}
}

/* =====================================================================
 * TASK 12.1 — Weddings & Events visual hierarchy & conversion (v0.2.43)
 * =====================================================================
 * Page-scoped refinement of the Task 12 Weddings landing page
 * (/weddings-and-events/, body class .page-slug-weddings).
 * No global tokens changed; every rule is scoped to the page slug or to
 * the page-only hero/section classes added in the page markup
 * (.hn-hero--wedding, .hn-wed-*). Other pages are untouched.
 * ------------------------------------------------------------------- */

/* --- 5.5 One comfortable reading measure for the page body -----------
 * The Task 12 intro (and body copy) sat at the 42rem global reading
 * width and read tall/narrow on desktop. Widen the whole weddings main
 * to 44rem so the intro and every default constrained block share one
 * calm measure; alignwide sections keep the 70rem standard width. */
body.page-slug-weddings main {
	--wp--style--global--content-size: 44rem;
}

/* --- 5.2 (Task 12.2) Opening paragraph: wider, less tall -------------
 * The intro read as a tall 8-line column at the 44rem page measure.
 * Widen the intro block ONLY to a 52rem lead measure (page body copy
 * stays 44rem). Mobile is unaffected: 52rem exceeds the viewport, so the
 * paragraph still fills the available width as before. */
body.page-slug-weddings .hn-wed-intro {
	--wp--style--global--content-size: 52rem;
	max-width: 52rem;
}

/* --- 5.1 Header-to-hero gap ------------------------------------------
 * The cream strip under the header is the block-gap margin WordPress
 * puts between the top-level template blocks (header / main / footer).
 * The Task 12 hero was not flush, so it kept that 20px margin. The hero
 * now also carries .hn-hero--flush (existing rule zeroes it); this
 * page-scoped rule is the belt-and-braces guarantee that header bottom
 * and hero top meet at 0px on the Weddings page only. */
body.page-slug-weddings .wp-site-blocks > main {
	margin-block-start: 0;
	padding-top: 0;
}

/* --- 5.2 (Task 18.1) Editorial hero: photograph above a title band --
 * The Task 12/18 overlay hero was engineered for a right-weighted
 * subject: a left text column over a left-weighted gradient. The
 * Task 18.1 hero photograph (source 03734) carries the couple
 * centre-frame with guests reaching in from BOTH sides, so no overlay
 * column can sit on it without covering a face, and no gradient can
 * darken a side without erasing half the guests. The hero is therefore
 * recomposed as two stacked areas inside one flush, full-width group:
 * the photograph, carrying no text and no gradient, and a brand-green
 * title band beneath it carrying the eyebrow, H1 and CTAs. Two
 * art-directed image files serve the two shapes: a wide frame at
 * >=782px and a tighter portrait crop (couple, bouquet, nearest
 * guests) below 782px, so faces still read at phone sizes. Overlay
 * dim, focal-point and cover rules from the previous hero are removed
 * with the cover block itself. Page-scoped: nothing here touches the
 * other hero families. */
.hn-hero--wedding {
	background-color: var(--wp--preset--color--brand);
}

.hn-hero--wedding .hn-wed-hero__img {
	margin: 0;
}

.hn-hero--wedding .hn-wed-hero__img img {
	display: block;
	height: clamp(340px, 32vw, 480px);
	object-fit: cover;
	object-position: 50% 45%;
	width: 100%;
}

/* Wide frame on desktop; portrait crop on mobile. display:none also
 * removes the hidden duplicate from the accessibility tree, so the
 * photograph is announced once at every width. */
.hn-hero--wedding .hn-wed-hero__img--tall {
	display: none;
}

@media (max-width: 781px) {
	.hn-hero--wedding .hn-wed-hero__img--wide {
		display: none;
	}
	.hn-hero--wedding .hn-wed-hero__img--tall {
		display: block;
	}
	.hn-hero--wedding .hn-wed-hero__img--tall img {
		height: clamp(180px, 58vw, 430px);
		object-position: 50% 30%;
	}
}

/* Title band: brand green, gutters that line up with the alignwide
 * sections below (70rem band), calm vertical padding. */
.hn-hero--wedding .hn-wed-hero__band {
	background-color: var(--wp--preset--color--brand);
	padding-block: clamp(1.25rem, 4vw, 2.5rem);
	padding-inline: max(var(--wp--style--root--padding-left, 1.25rem), calc((100% - 70rem) / 2));
}

/* Band text colours (the band is a group, not a cover, so the cover
 * hero colour rules do not reach it). */
.hn-hero--wedding .hn-wed-hero__band h1,
.hn-hero--wedding .hn-wed-hero__band p {
	color: var(--wp--preset--color--surface);
}

.hn-hero--wedding .hn-wed-hero__band .hn-hero__eyebrow {
	color: var(--wp--preset--color--accent);
}

/* Task 58 Phase 2 (v0.2.85): the band's secondary CTA takes the sitewide
 * self-contained white fill at rest (surface fill, brand label — 13.53:1)
 * and inverts to brand fill / surface label on interaction. The band, its
 * grid, the photograph and the picture pair are untouched. Declared with
 * the interaction rule in "TASK 58" at the foot of this stylesheet so the
 * cover heroes and the band share one rule. */

/* Band rhythm (mobile-first stack). */
.hn-hero--wedding .hn-wed-hero__band > * {
	margin-block: 0;
}

.hn-hero--wedding .hn-wed-hero__band > h1 {
	margin-block-start: 0.5rem;
	max-width: 28ch;
	text-wrap: balance;
}

/* Short/narrow phones (Task 06G.1 discipline): at 320px the stacked
 * band pushed the primary CTA just past the 568px fold. A slightly
 * smaller H1 below 360px keeps the enquiry action inside the first
 * viewport; 360px+ phones are unaffected. */
@media (max-width: 359px) {
	.hn-hero--wedding .hn-wed-hero__band > h1 {
		font-size: 1.85rem;
	}
}

.hn-hero--wedding .hn-wed-hero__band > .wp-block-buttons {
	margin-block-start: 1.25rem;
}

/* Desktop band: two columns — eyebrow + H1 left, CTAs right, centred
 * against the H1 block so the enquiry action sits at eye level. */
@media (min-width: 782px) {
	.hn-hero--wedding .hn-wed-hero__band {
		align-items: center;
		column-gap: 3rem;
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		grid-template-rows: auto auto;
	}
	.hn-hero--wedding .hn-wed-hero__band > .hn-hero__eyebrow {
		grid-column: 1;
		grid-row: 1;
	}
	.hn-hero--wedding .hn-wed-hero__band > h1 {
		grid-column: 1;
		grid-row: 2;
	}
	.hn-hero--wedding .hn-wed-hero__band > .wp-block-buttons {
		grid-column: 2;
		grid-row: 1 / span 2;
		margin-block-start: 0;
	}
}

/* Hero CTAs keep a 44px minimum touch target. */
.hn-hero--wedding .wp-block-button__link {
	align-items: center;
	display: inline-flex;
	min-height: 44px;
}

/* Editorial image captions (Task 18.1): quiet, factual, tied to the
 * photograph they describe. Page-scoped. */
body.page-slug-weddings .wp-block-image figcaption,
body.page-slug-weddings .wp-block-media-text figcaption {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--small);
	margin-block-start: 0.6rem;
}

/* Food section detail pairing (Task 18.1): the reception table with its
 * dusk candle detail, bottom-aligned so the pair reads as one composed
 * unit rather than two stray images. */
body.page-slug-weddings .hn-wed-food-images {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* Task 18.2 — keep the complete reception table dominant when the pair
 * stacks. The pair is a 75/25 alignwide Columns block, so on desktop the
 * table photograph leads and the candle detail sits beside it as a small
 * bottom-aligned inset. Below the core Columns stacking breakpoint (781px)
 * every column is forced to 100% width by core, which would render the
 * portrait candle detail full-bleed and roughly twice the height of the
 * landscape table photograph — inverting the intended hierarchy on every
 * phone. Core blocks expose no per-breakpoint width for a stacked column,
 * so the detail column is capped here instead. Page-scoped: no other page
 * uses .hn-wed-food-images. */
@media (max-width: 781px) {
	body.page-slug-weddings .hn-wed-food-images > .wp-block-column:last-child {
		max-width: 50%;
	}
}


/* --- 5.6 "Why couples choose Hermitage" — two-column editorial --------
 * Each reason (H3 + paragraph) is one grid cell; two columns on wider
 * screens, one column on mobile. No boxes, no icons; the short H3s stay
 * the scan anchor. */
body.page-slug-weddings .hn-wed-why__grid {
	display: grid;
	grid-template-columns: 1fr;
	/* Task 12.2 fix: the 2XL spacing preset is NOT emitted as a CSS
	 * custom property (its slug begins with a digit), so the previous
	 * gap:var(--...--xl) var(--...--2xl) contained an empty value, made the
	 * whole shorthand invalid and collapsed to 0 — the reasons touched and
	 * the section read cramped. Use resolvable values: a 40px row rhythm so
	 * one reason cannot run into the next, and a 56px column channel.
	 * align-items:start keeps each reason its natural height (no
	 * equal-height cards). The top margin gives the intro sentence air. */
	gap: var(--wp--preset--spacing--lg) 3.5rem;
	align-items: start;
	margin-block-start: var(--wp--preset--spacing--lg);
}
@media (min-width: 880px) {
	/* Switch to two columns only when each column stays comfortable;
	 * through tablet portrait the reasons stay a single readable column. */
	body.page-slug-weddings .hn-wed-why__grid {
		grid-template-columns: 1fr 1fr;
	}
}
body.page-slug-weddings .hn-wed-why__grid > .hn-wed-reason {
	margin-block-start: 0;
}
body.page-slug-weddings .hn-wed-reason > * {
	margin-block-start: 0;
}
body.page-slug-weddings .hn-wed-reason > :is(h2, h3, h4) + p {
	margin-block-start: var(--wp--preset--spacing--xs);
}

/* --- 5.8 "How planning usually unfolds" — numbered steps -------------
 * The ordered list becomes a numbered grid with a strong accent number
 * as the scan anchor; two columns on desktop, one on mobile. No JS. */
body.page-slug-weddings .hn-wed-steps ol {
	list-style: none;
	margin: 0;
	padding: 0;
	counter-reset: hn-step;
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--md);
}
@media (min-width: 768px) {
	body.page-slug-weddings .hn-wed-steps ol {
		grid-template-columns: 1fr 1fr;
		/* Task 12.2 fix: column-gap:var(--...--2xl) was an empty value and
		 * collapsed to 0, so the two step columns touched. The steps
		 * container is capped at the 44rem page measure, so three columns
		 * would leave each step too narrow — two comfortable columns with a
		 * 40px row rhythm and a 48px column channel is the measured choice. */
		gap: var(--wp--preset--spacing--lg) 3rem;
	}
	/* Five steps in two columns leaves a lone fifth step. Centre it under
	 * the two columns so the second row reads as intentional, not orphaned. */
	body.page-slug-weddings .hn-wed-steps li:nth-child(5) {
		grid-column: 1 / -1;
		max-width: calc((100% - 3rem) / 2);
		margin-inline: auto;
	}
}
/* More air before the italic disclaimer so it reads as a closing note. */
body.page-slug-weddings .hn-wed-steps ol + p {
	margin-block-start: var(--wp--preset--spacing--lg);
}
body.page-slug-weddings .hn-wed-steps li {
	counter-increment: hn-step;
	position: relative;
	margin: 0;
	padding-left: 2.75rem;
	min-height: 1.9rem;
}
body.page-slug-weddings .hn-wed-steps li::before {
	content: counter(hn-step);
	position: absolute;
	left: 0;
	top: -0.1em;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--accent);
}

/* --- 5.9 "Helpful things to tell us" — calm preparation panel --------
 * The prompts become one restrained two-column checklist on a warm
 * panel (not a wall of cards). Heading stays outside the panel. */
body.page-slug-weddings .hn-wed-helpful {
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--lg) var(--wp--preset--spacing--xl);
}
body.page-slug-weddings .hn-wed-helpful > * {
	margin-block-start: var(--wp--preset--spacing--sm);
}
body.page-slug-weddings .hn-wed-helpful > :first-child {
	margin-block-start: 0;
}
body.page-slug-weddings .hn-wed-helpful ul {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.45rem 2rem;
	margin: 0;
	padding-left: 1.15rem;
}
@media (min-width: 640px) {
	body.page-slug-weddings .hn-wed-helpful ul {
		grid-template-columns: 1fr 1fr;
	}
}

/* --- 5.10 Enquiry form presentation ---------------------------------
 * The plugin form and its logic are unchanged; only page-scoped spacing
 * and width so it reads calmer, not administrative. Wider container,
 * more generous row rhythm, comfortable two-column rows. */
body.page-slug-weddings .hn-enquiry-section .hn-res {
	max-width: 46rem;
}
body.page-slug-weddings .hn-enquiry-section .hn-res-grid {
	gap: var(--wp--preset--spacing--md) var(--wp--preset--spacing--lg);
}
body.page-slug-weddings .hn-enquiry-section .hn-res-form textarea {
	min-height: 8.5rem;
}

/* --- 5.11 FAQ now follows the form: clear separation -----------------
 * Task 12.2 fix: margin-block-start:var(--...--2xl) was an empty value and
 * collapsed to 0, so the FAQ heading hugged the form's reassurance line.
 * Resolvable values give 40px on mobile and 64px on desktop, so the FAQ
 * reads as a new section rather than a continuation of the form. */
body.page-slug-weddings .hn-wed-faq {
	margin-block-start: var(--wp--preset--spacing--lg);
}
@media (min-width: 768px) {
	body.page-slug-weddings .hn-wed-faq {
		margin-block-start: var(--wp--preset--spacing--xl);
	}
}

/* --- Section rhythm for the added wrappers --------------------------- */
body.page-slug-weddings .hn-wed-intro,
body.page-slug-weddings .hn-wed-steps,
body.page-slug-weddings .hn-wed-closing {
	margin-block-start: var(--wp--preset--spacing--xl);
}

/* --- 5.4 Restrained mid-page CTA ------------------------------------- */
body.page-slug-weddings .hn-wed-midcta {
	margin-block-start: var(--wp--preset--spacing--lg);
}


/* ---------------------------------------------------------------------
 * Query pagination target size (Task 16)
 * -------------------------------------------------------------------
 * Core renders the pagination numbers as bare inline links. Measured on
 * the Ginger Tales index at 375px they are 9x22 CSS px with a 4px gap,
 * which fails WCAG 2.2 SC 2.5.8 (24x24 minimum, and the spacing
 * exception does not apply at 4px) and the project's 44px touch-target
 * rule. Give every pagination control a real target box.
 *
 * Deliberately scoped to .wp-block-query-pagination so the single
 * correction serves the Ginger Tales index, archive.html and
 * index.html with no page-specific override.
 */
.wp-block-query-pagination {
	gap: var(--wp--preset--spacing--xs);
}

.wp-block-query-pagination .wp-block-query-pagination-numbers {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs);
	justify-content: center;
}

.wp-block-query-pagination > a,
.wp-block-query-pagination .wp-block-query-pagination-numbers > a,
.wp-block-query-pagination .wp-block-query-pagination-numbers > .current {
	align-items: center;
	display: inline-flex;
	justify-content: center;
	min-height: 44px;
	min-width: 44px;
	padding-inline: 0.5rem;
}

/* The current page is announced with aria-current; make it visible too. */
.wp-block-query-pagination .wp-block-query-pagination-numbers > .current {
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 0.25em;
}


/* =====================================================================
 * TASK 27 — Secondary hero CTA interaction states (v0.2.53)
 * =====================================================================
 * DEFECT
 * A secondary call to action using the outline block style became white
 * text on a white background on hover, keyboard focus and press, on the
 * Dining, Weddings and Ginger Tales heroes. Measured on staging before
 * this change: colour rgb(255, 255, 255) on background rgb(255, 255, 255)
 * — a contrast ratio of 1.00:1. The label disappeared completely; the
 * focus ring stayed visible, so a keyboard user saw an empty white box.
 *
 * CAUSE
 * WordPress prints every theme.json colour preset as a utility class in
 * the global-styles inline stylesheet, and it prints them !important:
 *     .has-surface-color { color: var(--wp--preset--color--surface) !important; }
 * Specificity 0,1,0 — but !important. The three affected buttons carry
 * textColor:"surface" in their block attributes, which renders that class
 * on the anchor. The theme's own interaction rule for the outline style,
 *     .wp-block-cover.hn-hero .wp-block-button.is-style-outline
 *         .wp-block-button__link:hover
 * is specificity 0,6,0 with no !important, so it won the background-color
 * swap (to white) and lost the colour swap (to green). Background and
 * text moved independently, and met in the middle at white on white.
 *
 * CORRECTION
 * The theme owns the colour of this component in its interaction states,
 * because the theme is what changes the background underneath. The three
 * interactive states below therefore set colour with !important. Nothing
 * in the cascade gets past an !important declaration except another one,
 * so this is the only available correction in CSS — and it follows the
 * precedent this stylesheet already sets twice for exactly the same
 * mechanism: the Task 06G.1 home-hero and Task 12.1 rules counter core's
 * !important font-size preset classes the same way (see the notes near
 * `.has-large-font-size` above). Every value is an existing theme token;
 * no colour is hardcoded, no page, slug or ID is named, and no JavaScript
 * is involved. The normal state is deliberately left alone: there the
 * author's colour choice sits on a background they can see.
 *
 * :active is added in the same pass. Before this change the pressed state
 * had no rule of its own and merely inherited whatever :hover happened to
 * be doing, which is not true for touch or for keyboard activation.
 *
 * Scope is limited to contexts where the theme swaps to a LIGHT
 * background on interaction — dark green sections, hero covers, and the
 * Weddings hero band. The light-surface outline rule higher up this file
 * is untouched, so the Home accommodation-card links
 * (.hn-cards--compact ... .is-style-outline, which are deliberately
 * restyled as text links) keep their own colours.
 *
 * Resulting contrast: #04352D on #FFFFFF = 13.53:1 (WCAG AAA).
 * =================================================================== */

.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:hover,
.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:focus,
.has-surface-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:active,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:hover,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:focus,
.has-brand-dark-background-color .wp-block-button.is-style-outline .wp-block-button__link:active {
	background-color: var(--wp--preset--color--surface);
	border-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--brand) !important;
}

/* Task 58 Phase 2 (v0.2.85): the `.wp-block-cover.hn-hero` and
 * `.hn-hero--wedding .hn-wed-hero__band` arms left this rule. Their
 * secondary CTA now RESTS on the surface fill, so the interaction state
 * is the inverse (brand fill, surface label) — see "TASK 58" at the foot
 * of this stylesheet. The dark-section arms above are unchanged. */

/* =====================================================================
 * TASK 30 — Section rhythm, CTA panels and footer refinement.
 *
 * RHYTHM RULE: a boundary between two TRANSPARENT sections is paid for
 * once, by the section below it — `padding-block-start` only. Coloured
 * bands keep symmetric padding, because theirs sits inside their own
 * background. Do not add a bottom padding to a transparent section, and
 * do not add a Spacer block to correct a gap a section boundary owns.
 *
 * Full audit, measurements at 375/768/1024/1440, the alternatives that
 * were tested and rejected, and the reasoning behind each value are in
 * readme.md (0.2.58) and the Task 30 completion report.
 * ================================================================== */

/* Rhythm scale, mapped onto existing theme.json presets. */

:root {
	--hn-rhythm-section: var(--wp--preset--spacing--section);
	--hn-rhythm-related: var(--wp--preset--spacing--lg);
	--hn-rhythm-open: var(--wp--preset--spacing--xl);
}

/* Accommodations hub — opening introduction between a flush hero and
 * the card grid. Prose stays at the reading measure. */

.hn-hub-intro {
	padding-block: var(--hn-rhythm-open) var(--wp--preset--spacing--sm);
}

.hn-hub-intro > * {
	max-width: var(--wp--custom--width--reading, 42rem);
	margin-inline: auto;
}

/* Dining — closing section boundary before "Come and eat with us". */

.hn-dining-closing {
	padding-block-start: var(--hn-rhythm-section);
}

/* Weddings — space below the process heading.
 *
 * Set on the HEADING, not on the list: the counter styling below sets
 * `margin: 0` on the ol to control the numeral gutter, and that reset
 * outranks any component-level rule on the ol itself. Without this the
 * gap is 0 and the step-1 numeral overlaps the heading's descenders.
 * Item-to-item spacing is untouched. */

.hn-wed-steps > h2 {
	margin-block-end: var(--hn-rhythm-related);
}

/* Compare other stays — compact sibling-accommodation module on the five
 * accommodation-detail pages. Deliberately not the large accommodation
 * cards used on Home and the hub. `min(17rem, 100%)` lets the track
 * collapse below its floor, which a bare 17rem cannot do at large text
 * sizes. The grid container is a core Group, so it also carries core's
 * flow-layout child margin — zeroed here because `gap` owns the
 * spacing. */

.hn-compare__lead {
	margin-block-end: 0;
	color: var(--wp--preset--color--text-muted);
}

.hn-compare__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--md);
	margin-block-start: var(--wp--preset--spacing--md);
}

.hn-compare__grid > * {
	margin-block-start: 0;
}

.hn-compare__item {
	padding-inline-start: var(--wp--preset--spacing--md);
	border-inline-start: 2px solid var(--wp--preset--color--line);
}

h3.hn-compare__name {
	margin: 0;
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.25;
}

.hn-compare__note {
	margin-block-start: 0.4rem;
	color: var(--wp--preset--color--text-muted);
}

.hn-compare__more {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* Closing enquiry panel. Kept subordinate to a booking panel: shorter
 * measure, heading one step down, and its action keeps the outline
 * style this stylesheet reserves for enquiry actions. */

.hn-cta--enquiry {
	border-radius: 2px;
}

.hn-cta--enquiry > * {
	max-width: 34rem;
	margin-inline: auto;
}

.hn-cta--enquiry > h2 {
	font-size: var(--wp--preset--font-size--large);
}

/* Footer legal/utility row and the Internet Sofa credit. The explicit
 * row gap keeps the row short when it wraps; the credit link stays on
 * one line so "Internet" and "Sofa" are never split. */

.hn-footer__legal {
	row-gap: var(--wp--preset--spacing--xs);
	column-gap: var(--wp--preset--spacing--md);
}

.hn-footer__credit {
	color: var(--wp--preset--color--surface-warm);
	opacity: 0.85;
}

.hn-footer__credit a {
	white-space: nowrap;
}


/* =====================================================================
 * TASK 31 — Story-list anchor target (v0.2.59)
 * =====================================================================
 * The Ginger Tales pagination links carry a `#stories` fragment so a
 * visitor moving between result pages lands on the story list rather
 * than back at the top of the hero (inc/ginger-tales.php).
 *
 * This site has no sticky header, so nothing overlays the heading; the
 * offset exists only so the heading is not flush against the top edge
 * of the viewport. One token, applied to a component class on the
 * heading itself rather than to a page-ID or #id selector, so the same
 * behaviour is available to any future anchored listing.
 * ------------------------------------------------------------------- */

.hn-stories-anchor {
	scroll-margin-top: var(--wp--preset--spacing--lg);
}


/* =====================================================================
 * TASK 32 — Hero eyebrow contrast over photography (v0.2.63)
 * =====================================================================
 * Closes T29-01. The shared hero eyebrow rendered the `accent` token
 * (#EE7F38) over hero photography. Measured against the composited
 * backdrop actually painted behind the glyphs (photograph + the cover's
 * overlay colour and gradient layers), the accent eyebrow ran from
 * 2.19:1 (Home, 375px) to 6.01:1 (Our Team, 1024px) — below the 4.5:1
 * WCAG AA requirement for 13px/600 text on thirteen of the thirteen
 * photographic cover heroes at one or more of 375/1024/1440px.
 *
 * The `surface` token (#FFFFFF) in the same positions was re-measured on
 * the deployed build. Two methods, both reported because they answer
 * different questions:
 *
 *   - MODELLED backdrop sampling (the composite described above, over the
 *     glyph bounding box): worst median 5.90:1, worst 10th percentile
 *     5.15:1, worst single pixel 4.46:1 — all on Home at 1440x900.
 *   - EMPIRICAL painted-glyph sampling (two screenshots of the deployed
 *     page, one with the eyebrow visible and one with it hidden, diffed
 *     so that only the pixels the glyphs actually paint are measured):
 *     Home at 1440x900 median 5.82:1, 10th percentile 5.21:1, and ONE of
 *     633 painted glyph pixels at 4.35:1 (0.16%). At 1440x640 the same
 *     method gives median 6.71:1 and no pixel below 4.5:1.
 *
 * So AA is met on every representative measure at every tested position,
 * with the preferred 5:1 operating margin met on both the median and the
 * 10th percentile everywhere — but this is NOT a claim that every single
 * sampled pixel clears 4.5:1, because on Home at 1440x900 one does not.
 * White is the same colour the hero H1 and summary already use, so the
 * correction adds no new colour and no new token.
 *
 * Home is the marginal case for a structural reason: it is the only cover
 * hero with a flat 60% overlay dim and NO gradient scrim. Deliberately not
 * addressed here — changing a hero overlay is out of scope for a contrast
 * correction.
 *
 * SCOPE. `:has(img.wp-block-cover__image-background)` is what makes the
 * rule photographic rather than merely "a cover hero": a cover hero
 * built on a solid colour has no such child and keeps the accent
 * eyebrow from the rule near the head of this stylesheet, and the light
 * -surface `.hn-eyebrow` / `.hn-section-intro__eyebrow` atoms are not
 * matched at all, so no eyebrow on a light background can be turned
 * white by this rule. The Weddings hero is a `core/group` with a solid
 * `brand` band, not a cover, so it is also unmatched — its eyebrow
 * measures 4.98:1 against #04352D and already passes AA.
 *
 * SPECIFICITY. (0,4,1): `.wp-block-cover` + `.hn-hero` + the `:has()`
 * argument's `.wp-block-cover__image-background` + `img`, plus
 * `.hn-hero__eyebrow`. That beats the (0,3,0) accent rule above on
 * specificity alone, and this block is also later in the cascade. No
 * `!important` is required or used: nothing in this stylesheet and no
 * WordPress-generated preset utility class sets a colour on these
 * elements (the eyebrow paragraphs carry no `has-*-color` class and no
 * inline colour — Task 29 stripped those from page content).
 *
 * Size, weight, uppercase treatment, letter-spacing, line-height and
 * every margin are inherited unchanged from the shared atom. No text
 * shadow is added: the token alone clears AA at every tested position.
 * ------------------------------------------------------------------- */

/* RETIRED in Task 58 Phase 2 (v0.2.85). The rule that stood here —
 *   .wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .hn-hero__eyebrow { color: surface }
 * — is removed on the owner's explicit instruction that every hero eyebrow
 * is the brand `accent` orange. The measurements above remain the record
 * of why white was chosen in Task 32; the Task 58 Phase 2 contrast register
 * records the orange eyebrow's measured values, including the widths where
 * it falls below 4.5:1, as an owner-accepted visual trade-off. */


/* =====================================================================
 * TASK 32.1 — Interactive hero text over photography (v0.2.64)
 * =====================================================================
 * Task 32 corrected the hero eyebrow but its own interaction audit found
 * the same defect in two INTERACTIVE controls: both turn the `accent`
 * token orange on hover and keyboard focus while sitting directly on a
 * hero photograph. Measured on the deployed 0.2.63 build, per rendered
 * pixel behind the glyphs (photograph + overlay colour + gradient layers):
 *
 *   T32-01  Dining hero text-link CTA "View our sample menus"
 *           hover/focus 4.03:1 median, 3.89 p10, 3.71 worst pixel
 *           (16px/600 — requires 4.5:1)
 *   T32-04  Hero breadcrumb links on the seven heroes that carry a trail
 *           hover/focus 3.85–4.68 median, 3.33–4.22 worst pixel
 *           (13px/400 — requires 4.5:1)
 *
 * CORRECTION: keep the text white in every state and carry the hover /
 * focus affordance on the UNDERLINE instead of on the colour. Contrast
 * therefore stays at the resting white value in all four states —
 * 10.94:1 for the Dining CTA, 10.46–12.72:1 for the breadcrumb links.
 *
 * `text-decoration-thickness` and `text-underline-offset` are painted
 * properties: they change no box, no line height and no layout, so the
 * "no geometry change between interaction states" guarantee holds. The
 * theme already uses exactly this pair to mark the current page in the
 * primary navigation, so the vocabulary is not new.
 *
 * SCOPE. Same `:has(img.wp-block-cover__image-background)` test as the
 * Task 32 eyebrow rule, for the same reason: it is the photographic case
 * that fails, and only that case is corrected. Ordinary in-body text
 * links, footer links, card links and the light-surface button styles are
 * not matched. A hero built on a solid colour keeps its accent hover from
 * the Task 09.3 and breadcrumb rules above, where accent measures 4.98:1
 * against #04352D and passes.
 *
 * SPECIFICITY. (0,7,1) for the CTA against the (0,4,0) Task 09.3 rule it
 * overrides, and (0,5,2) for the breadcrumb against (0,4,1). Both also sit
 * later in the cascade. No `!important` is required or used.
 *
 * NOT changed: CTA wording, CTA destination, padding, font size, line
 * height, display, position, the `:focus-visible` outline, the hero
 * photograph, the overlay, or any page content.
 * ------------------------------------------------------------------- */

/* A — hero text-link CTA (T32-01). The underline is already present in
 * the resting state, so hover and focus thicken it and push it clear of
 * the descenders rather than introducing one. */
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .wp-block-button.is-style-text-link .wp-block-button__link:hover,
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .wp-block-button.is-style-text-link .wp-block-button__link:focus,
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .wp-block-button.is-style-text-link .wp-block-button__link:active {
	color: var(--wp--preset--color--surface);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.28em;
}

/* B — hero breadcrumb links (T32-04). These rest with NO underline, so
 * the underline appearing IS the affordance; `.rank-math-breadcrumb
 * a:hover/:focus` already adds it. Declared here as well so the pressed
 * state matches, and thickened to 2px so it reads at 13px over a
 * photograph. */
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .hn-breadcrumbs a:hover,
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .hn-breadcrumbs a:focus,
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) .hn-breadcrumbs a:active {
	color: var(--wp--preset--color--surface);
	text-decoration-line: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.2em;
}

/* =====================================================================
 * TASK 34 — Sample-menu page opening band (v0.2.65)
 * =====================================================================
 * The three sample-menu pages opened on plain cream while both dining
 * landing pages (Dining and Restaurant Reservations) open on a dark
 * green photographic band, so the menus read as supporting documents
 * rather than as part of the dining family. Measured: the openings were
 * never the wrong SIZE — 466px at 375 against the Restaurant
 * Reservations hero at 450 and the Dining hero at 522 — they were
 * simply uncoloured. `.hn-menu-intro` carried two declarations in the
 * whole stylesheet and `.hn-breadcrumbs` was styled only inside a hero
 * cover, so the breadcrumb rendered as unstyled default text.
 *
 * This paints the existing wrapper. It does NOT introduce a hero: no
 * photograph, no viewport height, no overlay. The full-bleed comes from
 * core's own `alignfull` on the group — a block setting — so nothing
 * here has to fight the forced auto inline margins core applies to
 * constrained children, and no override of that kind is added.
 *
 * Contrast on brand #04352D: eyebrow accent 4.98:1, H1 surface 13.53:1,
 * lead and breadcrumb surface-warm 11.60:1 — the breadcrumb holds
 * 11.60:1 in all four states because hover/focus/active carry the
 * UNDERLINE, not a colour change (Task 32.1 rule).
 * ================================================================== */

.hn-menu-intro {
	background-color: var(--wp--preset--color--brand);
	padding-block: var(--wp--preset--spacing--md);
}

.hn-menu-intro > :first-child { margin-block-start: 0; }
.hn-menu-intro > :last-child { margin-block-end: 0; }

.hn-menu-intro .hn-eyebrow { color: var(--wp--preset--color--accent); }
.hn-menu-intro h1 { color: var(--wp--preset--color--surface); }
.hn-menu-intro .hn-menu-intro__lead { color: var(--wp--preset--color--surface-warm); }

.hn-menu-intro .hn-breadcrumbs,
.hn-menu-intro .hn-breadcrumbs p {
	color: var(--wp--preset--color--surface-warm);
}

.hn-menu-intro .hn-breadcrumbs a {
	color: var(--wp--preset--color--surface-warm);
	text-decoration-line: none;
}

/* The affordance matches the resting decoration: these rest with no
 * underline, so the underline appearing is the affordance and the
 * colour never moves. */
.hn-menu-intro .hn-breadcrumbs a:hover,
.hn-menu-intro .hn-breadcrumbs a:focus,
.hn-menu-intro .hn-breadcrumbs a:active {
	color: var(--wp--preset--color--surface-warm);
	text-decoration-line: underline;
	text-underline-offset: 0.2em;
}

/* --- Menu-page closing CTA ------------------------------------------
 * `.hn-menu-cta` was in the markup of all three pages and in none of
 * the stylesheet, so the menu pages' closing area had no boundary while
 * the Dining page's equivalent (`.hn-dining-closing`) has carried one
 * since Task 30. Same convention: padding on the section that OPENS the
 * boundary, and no new value introduced. */
.hn-menu-cta {
	padding-block-start: var(--hn-rhythm-related);
	border-top: 1px solid var(--wp--preset--color--line);
}

/* =====================================================================
 * Task 35 — Mobile visual and actual-device closeout (0.2.66)
 * =================================================================== */

/* --- T35-01: art-directed Weddings hero as a single <picture> ---------
 * inc/image-performance.php rebuilds the --wide/--tall figure pair into
 * one <picture> whose <img> is eager (the Task 22 both-halves-lazy policy
 * left the VISIBLE hero unfetched until first scroll). The base
 * `.hn-wed-hero__img img` rule already provides the desktop frame
 * (clamp(340px, 32vw, 480px), object-position 50% 45%); this block
 * carries the mobile crop the --tall wrapper used to provide, applied to
 * the same single <img> when the tall <source> is active. The original
 * --wide/--tall display rules above are deliberately retained: they are
 * the styling for the no-transform fallback path. */
@media (max-width: 781px) {
	.hn-hero--wedding .hn-wed-hero__pic img {
		height: clamp(180px, 58vw, 430px);
		object-position: 50% 30%;
	}
}

/* --- T35-05: filled buttons must keep a boundary in forced colours ----
 * Genuine Windows forced colours (Task 35, `forced-colors: active`)
 * strips background fills, and the filled button style had no border —
 * every solid Book Now / Check availability / Request a table rendered
 * as bare text. A transparent border is invisible in normal rendering
 * but is drawn in the system ButtonText/LinkText colour under forced
 * colours, which restores the boundary without hardcoding any system
 * colour. Padding is compensated by the border width so the rendered box
 * does not change size — the same compensation convention the outline
 * style has used since Task 03 (`calc(0.75rem - 1.5px)`).
 * Scope: filled buttons only. `.is-style-outline` (real border) and
 * `.is-style-text-link` (deliberately borderless, underline affordance)
 * keep their accepted styling; the reservations plugin submit button
 * carries its own real border and passed the Task 35 forced-colours
 * check unchanged.
 * `:where()` keeps this selector at (0,2,0): a plain `:not()` would add
 * its argument's class specificity, out-ranking the (0,3,0) compact
 * header padding rules above and growing the header button at phone
 * widths (caught in Task 35 Phase 2 verification). */
.wp-block-button:where(:not(.is-style-outline)):where(:not(.is-style-text-link)) .wp-block-button__link {
	border: 1px solid transparent;
	padding: calc(0.75rem - 1px) calc(1.5rem - 1px);
}

/* The header Book Now narrows its padding at phone widths (accepted
 * Task 03/29 rules earlier in this file); restate those values with the
 * same 1px compensation so the compact button keeps its accepted size. */
@media (max-width: 781px) {
	.hn-header .hn-button-book .wp-block-button__link {
		padding: calc(0.6rem - 1px) calc(0.9rem - 1px);
	}
}

@media (max-width: 380px) {
	.hn-header .hn-button-book .wp-block-button__link {
		padding: calc(0.6rem - 1px) calc(0.7rem - 1px);
	}
}

/* --- T35-02: Book Now inside the open mobile navigation overlay ------
 * Rendered by inc/booking.php after the seven navigation items. Hidden
 * everywhere except the OPEN overlay, so it can never appear as an
 * eighth desktop item; the desktop boundary stays at the accepted 960px
 * because the overlay simply cannot open there. `wp-element-button`
 * gives it the sitewide filled-button treatment; border + compensated
 * padding follow the T35-05 rule above (it has no .wp-block-button
 * wrapper, so the values are restated here); the rendered box measures
 * ~47px tall, clearing the 44px target without a min-height that would
 * bloat it to 68px. On short viewports (<=667px) the button sits past
 * the first overlay screen and the overlay's own overflow-y:auto
 * scrolls to it; at 390x844 and taller it is visible without scrolling. */
.hn-nav-book {
	display: none;
}

.wp-block-navigation__responsive-container.is-menu-open .hn-nav-book {
	border: 1px solid transparent;
	display: inline-block;
	margin-top: var(--wp--preset--spacing--md);
	padding: calc(0.75rem - 1px) calc(1.5rem - 1px);
	text-align: center;
	width: auto;
}

/* Task 71.1 (v0.2.101), T71-01: overlay Book Now text colour.
 * The button sits inside the overlay container, which carries
 * `.has-surface-dark-background-color`, so the generic dark-surface link
 * rules in this file (`.has-surface-dark-background-color
 * a:not(.wp-block-button__link)` and its :hover) caught it — it is a
 * `.wp-element-button`, not a `.wp-block-button__link`. Measured on
 * 0.2.100: resting/focus #F2EDE4 on #EE7F38 = 2.33:1, hover #EE7F38 on
 * #D96A22 = 1.28:1, pressed #EE7F38 on #EE7F38 = 1.00:1. This restores
 * the sitewide button text colour (brand-dark, as on the header Book
 * Now) in every state: 5.87:1 on accent, 4.59:1 on the existing
 * accent-hover background. Colour only — background, size, focus ring
 * and position are untouched. Specificity (0,3,1) / (0,4,1) beats the
 * (0,2,1) / (0,3,1) dark-surface rules with no important flag. */
.wp-block-navigation__responsive-container.is-menu-open a.hn-nav-book,
.wp-block-navigation__responsive-container.is-menu-open a.hn-nav-book:is(:hover, :focus, :focus-visible, :active) {
	color: var(--wp--preset--color--brand-dark);
}


/* =====================================================================
 * TASK 51 / 51.1 / 51.2 / 51.3 / 51.4 — Photograph-first hero family
 * (v0.2.72 – v0.2.79) — LARGELY RETIRED in Task 58 Phase 2 (v0.2.85)
 * =====================================================================
 * WHAT THIS SECTION USED TO HOLD, AND WHY IT IS GONE
 * Tasks 51–51.4 painted a LOCAL scrim behind the copy stack of every
 * standard photographic hero: a pseudo-element of the cover's inner
 * container (`::before`), sized to the copy stack, tinted with the
 * `overlay` token at a flat 0.55 (0.35 `--scrim-soft`, 0.68
 * `--scrim-strong`), feathered on its right edge and foot, with a white
 * graduated variant for the two `--ink` heroes and a theme-fixed 0.40
 * full-frame tint for the homepage (`--hn-hero-overlay`). The Task 58
 * Phase 1 audit measured that box at 69% of the frame width at 1440 and
 * 60–93% of the hero area on phones, and identified it as the "dark-green
 * left panel" the owner asked to lose.
 *
 * Owner direction (Richie via Tony, Task 58 Phase 2): the photograph is
 * the hero; where support is needed at all it covers the WHOLE
 * photograph, lightly, and is never a panel. Every rule that drew or
 * configured the local box — the `--hn-hero-scrim-*` custom properties,
 * both `::before` rules and their <=781px branch, the `.hn-hero--ink`
 * variant (its colours, its footprint, its `:has(.wp-block-buttons)`
 * branch, its CTA rules and its fallback fill), `.hn-hero--scrim-soft`,
 * `.hn-hero--scrim-strong`, `--hn-hero-overlay` and the homepage
 * background-layer override — is removed here rather than left inert.
 * The overlay now belongs to the Cover block's own controls (see the
 * "Overlay" note in the image-hero section above and "TASK 58" below).
 *
 * WHAT SURVIVES FROM TASK 51 (still needed, unchanged in effect)
 *   1. The inner-container stacking context (below): keeps the copy
 *      above the cover's background layer, which every hero now paints.
 *   2. The glyph-local text-shadow on light copy (below): a permitted
 *      low-impact aid that obscures nothing. The `:not(.hn-hero--ink)`
 *      exclusion is gone with the variant; the outline CTA is dropped
 *      from the list because it is now a dark label on a light fill.
 *   3. The homepage children pinned to the 62rem band's left edge (below).
 * ------------------------------------------------------------------- */

/* --- 1. Copy above the background layer ----------------------------- */
/* The inner container already has z-index: 1 from core; making it
 * positioned turns that into a stacking context, so the copy stack sits
 * above the cover's own background layer (the overlay). */
.wp-block-cover.hn-hero--accommodations .wp-block-cover__inner-container,
.wp-block-cover.hn-hero--accommodation .wp-block-cover__inner-container,
.wp-block-cover.hn-hero--home .wp-block-cover__inner-container {
	position: relative;
	z-index: 1;
}

/* --- 2. Glyph-local text-shadow (light copy on photographic covers) - */
.wp-block-cover.hn-hero:has(img.wp-block-cover__image-background) :is(h1, p, .hn-breadcrumbs a, .wp-block-button.is-style-text-link .wp-block-button__link) {
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 0 16px rgba(10, 36, 31, 0.55);
}

/* --- 3. Homepage joins the family ----------------------------------- */
/* Children pinned to the 62rem band's left edge (was: each child centred
 * on its own measure by core's constrained layout, which is the centred
 * treatment the owner rejected). Measures are unchanged: H1 21ch
 * (28ch in the short-desktop fallback), supporting line 34rem (44rem). */
.wp-block-cover.hn-hero--home .wp-block-cover__inner-container > * {
	margin-left: max(0px, calc((100% - var(--wp--custom--width--detail-wide, 62rem)) / 2)) !important;
	margin-right: auto;
}

/* ---------------------------------------------------------------------
 * TASK 53 — Accommodation-card typography and the homepage villa-row
 * navigation card (v0.2.80)
 * -------------------------------------------------------------------
 * Owner feedback (Richie): the accommodation cards read as too small.
 * Measured cause: the card descriptive paragraphs carry the "Small body"
 * preset (0.875rem, non-fluid = 14px at every viewport) while the site's
 * standard body preset is "Body" (fluid 1rem -> 1.25rem = 16 -> 20px).
 * Against a 36px card title the copy therefore read as supporting
 * microcopy. The size lives in the five synced cards as an explicit
 * block attribute, so the correction is made there — fontSize
 * "small" -> "medium" on the DESCRIPTIVE paragraph of each card — not
 * by overpowering the preset class from CSS. The practical/spec line
 * (cards 13, 15, 16) deliberately stays on "Small body": it is meant to
 * read as secondary. No sitewide body, heading or eyebrow token changes.
 *
 * Two things do belong in CSS, and only these two:
 *   53.1  the card action, whose size comes from theme.json's button
 *         element style, has to keep pace with the enlarged copy;
 *   53.2  the homepage-only navigation card.
 * The 5-card grid placement rules above (section "Accommodation grid")
 * were additionally gated so a six-item grid flows as 3 + 3.
 * ------------------------------------------------------------------- */

/* --- 53.1 Card action -------------------------------------------------
 * theme.json sets the button element to 1rem, which WordPress renders
 * fluid (14px -> 16px). With the descriptive copy now at 16 -> 20px the
 * action would read smaller and weaker than the sentence above it, so
 * inside the shared accommodation card it adopts the same Body token.
 * Scoped to .hn-card--accommodation: no other button on the site moves.
 * This raises the specificity above core's `:root :where(...)` button
 * rule without !important. */
.hn-card--accommodation .wp-block-button__link {
	font-size: var(--wp--preset--font-size--medium);
}

/* --- 53.2 Homepage villa-row navigation card --------------------------
 * `.hn-accommodation-cta-card` is a HOMEPAGE-ONLY component. It is not
 * an accommodation: no photograph, no placeholder, no occupancy, no
 * facts, no heading — one link to the accommodations hub, and nothing
 * invented to fill the space. It sits between Yellow Manor House and
 * Rose Villa so the villa row reads as three balanced columns on wide
 * desktop, and stretches to the row height so it never looks undersized
 * beside its neighbours. The warm surface token is the site's own quiet
 * panel treatment, which lets the card belong to the section while
 * staying clearly distinct from the five photographic cards. */
.hn-accommodation-cta-card {
	align-items: center;
	align-self: center;
	background-color: var(--wp--preset--color--surface-warm);
	border-radius: 2px;
	display: flex;
	justify-content: center;
	min-height: 10rem;
	padding: var(--wp--preset--spacing--lg) var(--wp--preset--spacing--md);
}

.hn-accommodation-cta-card > * {
	margin-block-start: 0;
	max-width: 100%;
}

/* The action carries the same Body token as the enlarged card copy it
 * sits among, so the one navigational CTA in the section is not the
 * smallest text in it. Horizontal padding comes from the spacing scale. */
.hn-accommodation-cta-card .wp-block-button__link {
	font-size: var(--wp--preset--font-size--medium);
	padding-left: var(--wp--preset--spacing--md);
	padding-right: var(--wp--preset--spacing--md);
}

/* Only on the three-column villa row does the card stretch to the row
 * height — there it reads as the third column and stays visually
 * balanced against Yellow Manor House and Rose Villa. Measured at
 * narrower widths the same rule produced a ~610px empty panel beside a
 * single villa card (768px, two columns) and an equally tall void in
 * the single-column stack, so below 1024px the card is only as tall as
 * it needs to be and centres itself in its row. */
@media (min-width: 1024px) {
	.hn-accommodation-cta-card {
		align-self: stretch;
		height: 100%;
	}
}

/* =====================================================================
 * ACCOMMODATION GALLERY LIGHTBOX  (Task 54)
 *
 * The viewer itself is WordPress core's Image-block lightbox, switched
 * on for the accommodation Gallery sections in inc/gallery-lightbox.php.
 * No theme JavaScript is involved and none of core's dialog semantics,
 * focus handling or navigation is re-implemented here.
 *
 * What the theme owns is how the viewer looks. Core paints the backdrop
 * with the page background — on Hermitage the cream #FAF7F0 — and draws
 * its close and Previous / Next icons in the page ink #26302B, so an
 * enlarged photograph floats on a pale field with no sense of having
 * stepped out of the page. The rules below hand the backdrop to the
 * `overlay` token, the same deep brand green the heroes scrim with, and
 * restate the controls against it. That is the whole of the visual
 * work: no new component, no filmstrip, no dots, no thumbnails, no
 * transition of the theme's own.
 *
 * Core's own animations are already reduced under
 * `prefers-reduced-motion: reduce` twice over — by core's media queries
 * and by the theme's global reduce block near the top of this file — so
 * nothing further is needed for motion.
 *
 * Justified !important throughout this block: core sets the scrim's
 * background-color and the buttons' fill as INLINE style attributes
 * from the render (`background-color: var(--wp--preset--color--background)`
 * and `fill: var(--wp--preset--color--ink)`), which no selector can
 * outrank. Measured on staging, not assumed — a first build of this
 * block without !important left the backdrop cream and the icons
 * cream-on-cream. Same precedent as the flex-card margins (readme).
 * ===================================================================== */

/* The backdrop. `overlay` is the same token the heroes scrim with, so an
 * enlarged photograph sits on the site's own dark green rather than on
 * an arbitrary black. Held just short of opaque: enough to read as a
 * separate layer, enough to keep a hint of the page behind it. */
.wp-lightbox-overlay.wp-lightbox-overlay .scrim {
	background-color: var(--wp--preset--color--overlay) !important;
	opacity: 0.97;
}

/* Core's close and Previous / Next controls are bare icons filled with
 * the page ink, which would be near invisible on the dark backdrop.
 * Restate them in the page background tone — 15.2:1 against the
 * backdrop — so the chevrons and cross read clearly without adding any
 * chrome of their own. `color` covers the close control's optional text
 * label; `fill` covers the icons themselves. */
.wp-lightbox-overlay.wp-lightbox-overlay .wp-lightbox-close-button,
.wp-lightbox-overlay.wp-lightbox-overlay .wp-lightbox-navigation-button {
	color: var(--wp--preset--color--background) !important;
	fill: var(--wp--preset--color--background) !important;
}

/* The focus ring inside the viewer, and on the enlarge control in the
 * page gallery. Core's default is the platform ring, which on a dark
 * field is faint; the Hermitage focus token is the same ring keyboard
 * users meet everywhere else on the site and passes 3:1 against both
 * the backdrop and the photograph. */
.wp-lightbox-overlay .wp-lightbox-close-button:focus-visible,
.wp-lightbox-overlay .wp-lightbox-navigation-button:focus-visible,
.wp-lightbox-container button:focus-visible {
	outline: 2px solid var(--wp--preset--color--focus) !important;
	outline-offset: 2px;
}

/* Touch-target size (Task 54 correction). Core sizes the close control
 * 40x40 and the Previous / Next controls 44x40. WCAG 2.5.8 asks for at
 * least 24x24 and WCAG 2.5.5 for 44x44; the site's own card actions are
 * already 56px tall, so 44 is the floor everything here should meet.
 * Two declarations do it, and nothing else moves: core centres each
 * icon with flex, so the extra pixels grow the hit area around the
 * chevron without touching core's positioning model, its navigation
 * logic or its semantics. Measured after the change at 320, 375,
 * 740x360 landscape and 1440 - every control still fully inside the
 * viewport, image unobscured, zero horizontal overflow. */
.wp-lightbox-overlay.wp-lightbox-overlay .wp-lightbox-close-button,
.wp-lightbox-overlay.wp-lightbox-overlay .wp-lightbox-navigation-button {
	min-height: 44px;
	min-width: 44px;
}

/* =====================================================================
 * TASK 58 PHASE 2 — Sitewide hero presentation (v0.2.85)
 * =====================================================================
 * Owner direction (Richie via Tony): photography first. Every photographic
 * hero starts from the bare photograph; where support helps it is one
 * light tint across the WHOLE frame, never a panel behind the copy; all
 * hero copy is left aligned; every hero eyebrow is the brand orange; the
 * two CTAs have one fixed hierarchy (orange fill, white fill); keyboard
 * focus is unmistakable on any backdrop. Contrast is measured and reported
 * honestly in the Task 58 Phase 2 registers — it is evidence, not a reason
 * to darken the picture.
 *
 * WHERE EACH PART OF THE SYSTEM NOW LIVES
 *   Overlay          the Cover block's own "Overlay" colour + opacity
 *                    (block attributes `overlayColor: overlay`,
 *                    `dimRatio`). The theme sets nothing on
 *                    `.wp-block-cover__background`. Shared value 20;
 *                    Contact 30 (owner-directed "a touch more"); see the
 *                    Phase 2 visual-decision register for every page.
 *   Focal point      the Cover block's focal-point picker, at every width
 *                    (the six slug-scoped mobile rules are gone).
 *   Supporting copy  the `lead` font-size preset (theme.json: "Hero
 *                    lead", fluid 18px -> 28px), set on the summary /
 *                    distinction paragraph in the block; line-height here.
 *   Eyebrow          the shared `.hn-hero__eyebrow` atom (accent orange).
 *   Alignment        the 62rem band pin (image-hero section + Task 51 §3).
 *   Secondary CTA    the self-contained white fill below.
 *   Focus            the two-tone ring below.
 * No page, slug or ID selector; no JavaScript; no new `!important` beyond
 * the two `color` declarations that counter core's `.has-*-color`
 * preset utilities (the Task 27 mechanism, documented there).
 * ------------------------------------------------------------------- */

/* --- 1. Supporting-copy typography ----------------------------------- */
/* Size comes from the `lead` preset on the block (fluid 1.125rem ->
 * 1.75rem). The body line-height (1.65) that a paragraph inherits is
 * generous for a 28px lead measured at 34–44rem: 1.45 keeps the lead
 * visibly a hero line while taking a line or two off the tallest
 * stacks (About, Cottages, Rose Villa — Phase 2 typography register). */
.wp-block-cover.hn-hero :is(.hn-hero__summary, .hn-hero__distinction) {
	line-height: 1.45;
}

/* --- 2. Secondary CTA: a self-contained control on every hero ------- */
/* Task 51.3 / 51.4 gave the Home and ink secondaries this treatment
 * because a transparent outline borrows its contrast from whatever the
 * photograph is doing behind it (Phase 1 measured Dining at 1.67:1 and
 * Gatherings at 2.89:1). Now the standard: surface fill, surface border,
 * brand label (#04352D on #FFFFFF = 13.53:1) at rest, the inverse on
 * hover / focus / press. Covers the cover heroes and the Weddings band.
 * `color` carries `!important` because the anchors carry
 * textColor:"surface" and core prints `.has-surface-color` with
 * `!important` (Task 27). No destination, label, size or padding changes.
 * Specificity (0,5,0) beats the base outline style (0,3,0). */
.wp-block-cover.hn-hero .wp-block-button.is-style-outline .wp-block-button__link,
.hn-hero--wedding .hn-wed-hero__band .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: var(--wp--preset--color--surface);
	border-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--brand) !important;
	text-shadow: none;
}

.wp-block-cover.hn-hero .wp-block-button.is-style-outline .wp-block-button__link:hover,
.wp-block-cover.hn-hero .wp-block-button.is-style-outline .wp-block-button__link:focus,
.wp-block-cover.hn-hero .wp-block-button.is-style-outline .wp-block-button__link:active,
.hn-hero--wedding .hn-wed-hero__band .wp-block-button.is-style-outline .wp-block-button__link:hover,
.hn-hero--wedding .hn-wed-hero__band .wp-block-button.is-style-outline .wp-block-button__link:focus,
.hn-hero--wedding .hn-wed-hero__band .wp-block-button.is-style-outline .wp-block-button__link:active {
	background-color: var(--wp--preset--color--brand);
	border-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--surface) !important;
}

/* --- 3. Two-tone focus ring on hero controls -------------------------- */
/* The sitewide 2px `focus` (#C9631D) ring measured 1.46:1 against the
 * orange primary fill and 1.0–2.7:1 against the photograph behind every
 * hero CTA (Phase 1, S5). Here the ring is two-tone: 2px `brand` green
 * touching the control (4.9:1 against the orange fill, 13.5:1 against
 * the white fill), then 2px `surface` white outside it (13.5:1 against
 * the green ring, and visible on any dark or busy photograph). The pair
 * contrasts with itself, so it reads on orange, white, brand green and
 * on both bright and dark photography without darkening anything. 4px
 * total — no halo. Scoped to hero controls (CTAs, breadcrumb links);
 * the rest of the site keeps the sitewide ring. Existing tokens only. */
.wp-block-cover.hn-hero :is(a, button):focus-visible,
.hn-hero--wedding :is(a, button):focus-visible {
	outline: 2px solid var(--wp--preset--color--surface);
	outline-offset: 2px;
	box-shadow: 0 0 0 2px var(--wp--preset--color--brand);
	border-radius: 1px;
}

/* --- 4. Homepage supporting line on the smallest phones ------------- */
/* Phase 1 measured the Home copy stack (5-line H1 + 5-line summary +
 * two stacked CTAs) at 91–93% of the hero at 320 and 375. With the H1
 * ruled (Task 55) the summary is hidden — presentation only, the text
 * stays in the page — at <=375px, where the H1 and the two CTAs already
 * name Hermitage and the route forward. 390px and wider phones keep it
 * (measured; see the Phase 2 responsive register). */
@media (max-width: 375px) {
	.wp-block-cover.hn-hero--home .hn-hero__summary {
		display: none;
	}
}

/* --- 5. Modifier: .hn-hero--ink (dark copy on a pale photograph) ----- */
/* The one surviving tonal modifier. Postcards (library) and Contact
 * (office) are pale interiors; white copy on them needs more tint than
 * the owner wants to see, so they keep dark `brand` copy with no shadow,
 * and their support is the same whole-frame Cover overlay as every other
 * hero, painted with the `surface` (white) preset instead of `overlay`
 * — chosen in the block toolbar, not here. The eyebrow stays the shared
 * accent orange. `color` needs `!important` because the hero copy carries
 * textColor:"surface" (core prints `.has-surface-color` with
 * `!important`, Task 27). (0,6,2) beats the shadow rule's (0,6,1). */
.wp-block-cover.hn-hero.hn-hero--ink:has(img.wp-block-cover__image-background) .wp-block-cover__inner-container :is(h1, p:not(.hn-hero__eyebrow), .hn-breadcrumbs, .hn-breadcrumbs p, .hn-breadcrumbs a) {
	color: var(--wp--preset--color--brand) !important;
	text-shadow: none;
}

/* Fallback colour behind the photograph is the pale surface, so if the
 * image fails the dark copy stays readable. */
.wp-block-cover.hn-hero--accommodation.hn-hero--ink {
	background-color: var(--wp--preset--color--surface-warm);
}
/* =====================================================================
 * TASK 59 — Gatherings submenu + whole-card accommodation links (v0.2.86)
 * =====================================================================
 * Two owner requests, both interaction-only. Nothing here changes a
 * colour, a size, a spacing token or a piece of copy at rest.
 *
 *   59.1–59.3  the primary navigation gained its first submenu
 *              (Gatherings › Weddings). Core renders the parent as a
 *              real link plus a small toggle button; these three rules
 *              close the gaps core leaves for a keyboard user, a
 *              pointer target and the mobile overlay's hierarchy.
 *   59.4       the five shared accommodation cards become clickable
 *              across their whole surface, using the same stretched
 *              title-anchor technique already accepted for the Postcard
 *              card in Task 47 (v0.2.70). No JavaScript, no nested
 *              interactive elements, one extra link per card.
 * ------------------------------------------------------------------- */

/* --- 59.1 Submenu opens on keyboard focus, with no JavaScript ---------
 * Core's own focus-within rule is written
 * `.has-child:not(.open-on-click):not(.open-on-hover-click):focus-within`,
 * and WordPress renders this menu in `open-on-hover-click` mode, so the
 * rule never matches: measured on staging, tabbing to "Gatherings" left
 * the submenu `visibility: hidden`, which also removes the child link
 * from the tab order. Opening it depends on core's Interactivity script
 * toggling `aria-expanded`. This rule restores the CSS-only path with
 * core's own declarations, so the child is reachable by keyboard even
 * with JavaScript unavailable. Scoped to the header; the toggle button
 * continues to work exactly as core intends. */
.hn-header .wp-block-navigation .has-child.open-on-hover-click:focus-within > .wp-block-navigation__submenu-container {
	height: auto;
	min-width: 200px;
	opacity: 1;
	overflow: visible;
	visibility: visible;
	width: auto;
}

/* --- 59.2 Submenu toggle pointer target -------------------------------
 * Core ships the chevron as a 9x9px button. WCAG 2.2 SC 2.5.8 (AA) asks
 * for 24x24 CSS px. The glyph is unchanged; only the button's box grows,
 * and it grows inside the existing 61px header row, so the header
 * geometry is unaffected (measured at 960–1440px). */
.hn-header .wp-block-navigation-submenu__toggle {
	align-items: center;
	display: flex;
	justify-content: center;
	min-height: 24px;
	min-width: 24px;
}

/* --- 59.3 The child reads as a child in the mobile overlay ------------
 * In the open overlay core makes the submenu static and always visible
 * (the toggle is hidden), which is the behaviour we want — but the
 * container keeps its 200px dropdown width, so in this right-aligned
 * overlay the child link landed left of its parent and read as a
 * seventh peer item. One step of right padding on the child link puts it
 * inboard of "Gatherings" instead (measured: 32px). Spacing token only;
 * the container keeps core's own 200px width, which was measured to
 * cause no horizontal overflow at any tested width from 320px up. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item a.wp-block-navigation-item__content {
	padding-right: var(--wp--preset--spacing--md);
}

/* --- 59.4 Whole accommodation card clickable --------------------------
 * The card's H3 now carries a real anchor to the accommodation detail
 * page, and that one anchor is stretched over the card with a
 * pseudo-element — the technique already in this file for
 * `.hn-card--postcard`. No JavaScript, no click handler on a div, no
 * anchor inside an anchor: the existing CTA button is a SIBLING of the
 * title, not a descendant, and is lifted back above the overlay so it
 * stays operable and keeps its own focus ring. Two links per card, both
 * to the same canonical page, both with meaningful names ("Hillside
 * Rooms" and "Explore Hillside Rooms").
 *
 * The descriptive and factual paragraphs are deliberately lifted back
 * above the overlay (Task 59.1) so they stay ordinary selectable text
 * and are NOT covered by the stretched link. The photograph, the title,
 * the card padding and the corners remain the click target, and the CTA
 * keeps its own. This is the one place this component departs from
 * `.hn-card--postcard`, whose excerpt is still under its overlay.
 *
 * Inherits every card colour, size and spacing unchanged: the title link
 * takes the heading colour and no underline at rest, so the card looks
 * byte-identical until it is hovered or focused. */
.hn-card--accommodation {
	position: relative;
}

.hn-card--accommodation h3 a {
	color: inherit;
	text-decoration: none;
}

.hn-card--accommodation h3 a::after {
	content: "";
	inset: 0;
	position: absolute;
}

/* The card — not its inner content group — must be the overlay's
 * containing block. WordPress core ships
 * `:where(.wp-block-group.wp-block-group-is-layout-constrained){position:relative}`,
 * which applies to `.hn-card__content` and, measured on staging in
 * v0.2.86, confined the overlay to the text half of the card and left
 * the photograph unclickable. Nothing inside the content group is
 * absolutely positioned, so returning it to `static` is safe; the card
 * keeps its own `position: relative` above. */
.hn-card--accommodation .hn-card__content {
	position: static;
}

/* The action keeps its own hit area and focus ring above the overlay. */
.hn-card--accommodation .hn-card__content > .wp-block-buttons {
	position: relative;
	z-index: 1;
}

/* Task 59.1: the card's paragraphs sit above the overlay too, so their
 * text can be selected with the pointer in the ordinary way. They are
 * therefore not part of the card-wide click target; the photograph,
 * title, padding and corners are. No JavaScript, no extra link, and the
 * card still holds exactly two focusable anchors. */
.hn-card--accommodation .hn-card__content > p {
	position: relative;
	z-index: 1;
}

/* Pointer affordance: hovering anywhere on the card underlines the
 * title, which is the link being followed. Nothing else moves. */
.hn-card--accommodation h3 a:hover,
.hn-card--accommodation:hover h3 a {
	text-decoration: underline;
}

/* Keyboard focus: the ring goes round the whole card, which is the real
 * hit area, and the anchor's own ring is suppressed only inside this
 * component so there is never a double ring. Mirrors the Postcard card. */
.hn-card--accommodation h3 a:focus-visible {
	outline: 0;
	text-decoration: underline;
}

.hn-card--accommodation:has(h3 a:focus-visible) {
	outline: 2px solid var(--wp--preset--color--focus);
	outline-offset: 2px;
}

/* =====================================================================
 * TASK 60 — Richie's final presentation refinements (v0.2.90)
 * =====================================================================
 * Six owner requests, each as ONE reusable rule set keyed to a semantic
 * class — no page IDs, no slugs, no JavaScript, no new plugin.
 *
 *   60.1  "Which stay is right for you?" reads as a decision-help panel
 *   60.2  the hospitality note (was a collapsed accordion) is a visible,
 *         highlighted panel on all five accommodation pages
 *   60.3  the whole Dining sample-menu card is the link
 *   60.4  the menu-family opening gets a faint gingerbread/lattice texture
 *   60.5  opt-in local shadow behind dark hero copy (Postcards, Contact)
 *   60.6  forced-colours fallbacks for the new surfaces
 *   60.7  the desktop header stays one row at 960-1023px (v0.2.91)
 *   (60.3 also keeps the menu-card CTA colour fixed on hover, v0.2.92)
 * The Gatherings hero change is NOT here: it is a Cover-block gradient
 * overlay chosen in the block (theme.json preset "Hero fade"), keeping
 * Task 58's rule that the theme paints nothing on the cover background.
 * ------------------------------------------------------------------- */

/* --- 60.1 Decision-help panel: "Which stay is right for you?" -------
 * SUPERSEDED BY TASK 62 (0.2.95). Richie asked for the warm boxed panel
 * to become an open, scannable guide; the rules now live in the TASK 62
 * block (62.5) at the end of this file. Removed here rather than
 * overridden so no dead declarations remain. */

/* --- 60.2 Hospitality note: always visible, highlighted -------------
 * Lives in the two synced patterns "Hospitality accordion — standard"
 * (884, pages 19–22) and "… — Rose Villa" (885, page 23); the
 * core/details wrapper was replaced by a group, so the note is open by
 * default with no disclosure control. Same surface-warm fill, with the
 * accent rule on the leading edge so it reads as a note from the house.
 * The signature ("Richie") is set in the display face, italic. */
.hn-hospitality-note {
	background-color: var(--wp--preset--color--surface-warm);
	border-left: 3px solid var(--wp--preset--color--accent);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--md) clamp(1rem, 4vw, var(--wp--preset--spacing--md));
}

.hn-hospitality-note > * { margin-block: 0; }
.hn-hospitality-note > * + * { margin-block-start: var(--wp--preset--spacing--sm); }

.hn-hospitality-note h3 {
	font-size: var(--wp--preset--font-size--lead);
}

.hn-hospitality-note .hn-hospitality-note__signature {
	font-family: var(--wp--preset--font-family--display);
	font-style: italic;
}

/* --- 60.3 Whole Dining sample-menu card is the link -----------------
 * The card already holds exactly one anchor, its "Explore …" CTA, which
 * is the accessible name ("Explore breakfast" etc.). That anchor's
 * ::before is stretched over the card (::after already draws the arrow),
 * so the eyebrow, title, description, padding and corners all follow
 * the same link. Still one link per card, no nested anchor, no
 * JavaScript, so it works with scripts off.
 * Trade-off, stated: unlike the accommodation cards (Task 59.1), the
 * description is under the overlay, because the owner asked for the
 * WHOLE card. To restore pointer text selection instead, add
 * `.hn-menu-card > .hn-menu-card__desc { position: relative; z-index: 1 }`. */
.hn-menu-card {
	position: relative;
	transition: border-color 0.15s ease;
}

.hn-menu-card .hn-menu-card__cta::before {
	content: "";
	inset: 0;
	position: absolute;
}

/* Pointer affordance: the card's frame darkens and the CTA underlines,
 * which is the link being followed. The accent top rule is unchanged. */
.hn-menu-card:hover {
	border-color: var(--wp--preset--color--text-muted);
	border-top-color: var(--wp--preset--color--accent);
}

.hn-menu-card:hover .hn-menu-card__cta {
	text-decoration: underline;
}

/* The CTA keeps its resting brand colour in every state. Because the
 * stretched ::before is part of the anchor, hovering ANYWHERE on the card
 * now hovers the link, and the sitewide link hover (accent-hover #D96A22)
 * measures 3.48:1 on the white card — under 4.5:1 for this 18px label.
 * Same rule as Task 32.1: the affordance is the underline, the colour
 * never moves (brand on white 13.53:1). (0,2,1) beats core's
 * `:root :where(a…):hover` (0,1,0). (v0.2.92) */
.hn-menu-card a.hn-menu-card__cta:is(:hover, :focus, :active) {
	color: var(--wp--preset--color--brand);
}

/* Keyboard focus: one ring round the card (the real hit area), never a
 * double ring. Mirrors the accommodation and Postcard cards. */
.hn-menu-card .hn-menu-card__cta:focus-visible {
	outline: 0;
	text-decoration: underline;
}

.hn-menu-card:has(.hn-menu-card__cta:focus-visible) {
	outline: 2px solid var(--wp--preset--color--focus);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.hn-menu-card { transition: none; }
}

/* --- 60.4 Menu-family opening: tone-on-tone heritage texture --------
 * Two inline SVGs in the stylesheet — zero extra network requests, no
 * raster, no script. (1) A band of scalloped gingerbread drops with a
 * pierced roundel, after the cottage eaves trim, hung from the top edge
 * at 7% white. (2) An open diagonal veranda lattice across the whole
 * opening at 3% white. Measured on brand #04352D: accent eyebrow 4.57:1
 * on a lattice line (4.98 between lines), H1 surface 12.43, lead and
 * breadcrumb surface-warm 10.66 — every text colour stays above its
 * threshold where the pattern is strongest. The eaves band (26px) ends
 * above the breadcrumb, so it never sits under the eyebrow. */
.hn-menu-intro {
	background-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='26' viewBox='0 0 56 26'%3E%3Cpath fill='white' fill-opacity='.07' fill-rule='evenodd' d='M0 0h56v5c-8 0-12 3-14 8-2 6-7 11-14 11s-12-5-14-11C12 8 8 5 0 5zM28 9.5a3.5 3.5 0 1 0 0 7a3.5 3.5 0 1 0 0-7z'/%3E%3C/svg%3E"),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath stroke='white' stroke-opacity='.03' stroke-width='1.25' fill='none' d='M0 0L28 28M28 0L0 28'/%3E%3C/svg%3E");
	background-position: left top, center top;
	background-repeat: repeat-x, repeat;
	background-size: 56px 26px, 28px 28px;
}

/* --- 60.5 Opt-in local shadow behind dark hero copy -----------------
 * `.hn-hero--copy-shadow` on an ink hero (Postcards, Contact) puts a
 * tight light shadow directly behind the H1 and supporting line — the
 * only shadow that separates DARK glyphs from a busy pale photograph.
 * 0 offset, 2px + 8px blur: it sits behind the letterforms and stops
 * there; no panel, no gradient, no outline, nothing painted on the
 * photograph away from the type. The eyebrow keeps its existing shared
 * treatment and the CTAs are opaque controls, so neither needs it.
 * Opt-in only: no other hero carries the class.
 * (0,7,1) beats the ink rule's `text-shadow: none` (0,6,2). */
.wp-block-cover.hn-hero.hn-hero--ink.hn-hero--copy-shadow:has(img.wp-block-cover__image-background) .wp-block-cover__inner-container :is(h1, .hn-hero__summary) {
	text-shadow:
		0 0 2px color-mix(in srgb, var(--wp--preset--color--surface) 90%, transparent),
		0 0 8px color-mix(in srgb, var(--wp--preset--color--surface) 70%, transparent);
}

/* --- 60.7 Desktop header keeps one row at the 960px breakpoint ------
 * Stay and Dining became submenus, so the bar gained two 24px toggles
 * (59.2). Measured on staging with 0.2.90: the 48px Task 59 spare was
 * used up and the navigation wrapped to two rows from 960 to 988px
 * (header 93 -> 101px). Inside 960-1023px only, the gap between top-level
 * items steps from the 1.25rem block gap to 0.875rem (20 -> 14px), which
 * keeps one row with 29px to spare at 960. The 960px breakpoint itself is
 * unchanged, and from 1024px up the bar is exactly as before. */
@media (min-width: 960px) and (max-width: 1023.98px) {
	.hn-header .wp-block-navigation {
		gap: 0.875rem;
	}
}

/* --- 60.6 Forced colours -------------------------------------------
 * Fills vanish in forced-colours mode, so the two new panels keep a
 * system-colour frame, and the decorative menu texture is dropped. */
@media (forced-colors: active) {
	/* .hn-hub-which removed from this list in Task 62: it has no fill. */
	.hn-hospitality-note {
		border: 1px solid CanvasText;
	}

	.hn-menu-intro {
		background-image: none;
	}
}

/* =====================================================================
 * TASK 60.1 — Task 60 closure corrections (v0.2.93)
 * ---------------------------------------------------------------------
 *   60.1-a  light-copy arm of the opt-in `.hn-hero--copy-shadow`
 *   60.1-b  breadcrumb halo on the same opt-in heroes
 *   60.1-c  desktop submenu dismissed with Escape (pairs with
 *           assets/js/navigation-escape.js)
 *   60.1-d  forced-colours fallback for 60.1-b
 * ===================================================================== */

/* --- 60.1-a Opt-in local separation behind LIGHT hero copy ----------
 * Task 60 gave Gingerbread Cottages and Rose Villa owner-supplied
 * photographs whose phone crops put bright sky behind the white copy.
 * Owner direction stands: no global overlay, no panel. `.hn-hero--copy-
 * shadow` already means "this hero's photograph needs a stronger glyph-
 * local shadow behind its copy" (60.5, ink heroes, light shadow). This is
 * the same modifier's arm for the standard white-copy hero: a tight DARK
 * shadow in the overlay token, 0 offset, layered 1/3/8/18px so the
 * darkening sits against the letterforms and falls away within ~1em. It
 * paints nothing on the photograph away from the type. Replaces the
 * shared Task 51 shadow on these heroes only (0,6,2 beats its 0,4,1).
 * Carried by covers 21 and 23 only; no other hero has the class. */
.wp-block-cover.hn-hero.hn-hero--copy-shadow:not(.hn-hero--ink):has(img.wp-block-cover__image-background) .wp-block-cover__inner-container :is(h1, p) {
	text-shadow:
		0 0 1px color-mix(in srgb, var(--wp--preset--color--overlay) 80%, transparent),
		0 0 3px color-mix(in srgb, var(--wp--preset--color--overlay) 70%, transparent),
		0 0 8px color-mix(in srgb, var(--wp--preset--color--overlay) 60%, transparent),
		0 0 18px color-mix(in srgb, var(--wp--preset--color--overlay) 35%, transparent);
}

/* --- 60.1-b Breadcrumb halo -----------------------------------------
 * At 13px the trail's strokes are too thin for any text-shadow to
 * separate them from white cloud (measured: even a five-layer shadow
 * left "Home" near 2.3:1 on the phone crops). The least intrusive thing
 * that works is a soft, feathered shade that follows the trail itself:
 * the trail paragraph becomes inline (no layout change: it already had
 * 0 margin and the parent's line-height), takes a 50% overlay-token fill
 * with fully rounded ends, and a 10px-blur / 6px-spread shadow of the
 * same colour feathers the edge into the photograph. No border, no
 * solid box, no change to the trail's size, weight, wording or order;
 * links keep their Task 32 underline-on-interaction. A slightly firmer
 * text shadow than 60.1-a sits on the 13px glyphs. */
.wp-block-cover.hn-hero.hn-hero--copy-shadow:not(.hn-hero--ink):has(img.wp-block-cover__image-background) .hn-breadcrumbs :is(p, a) {
	text-shadow:
		0 0 1px color-mix(in srgb, var(--wp--preset--color--overlay) 90%, transparent),
		0 0 3px color-mix(in srgb, var(--wp--preset--color--overlay) 80%, transparent),
		0 0 8px color-mix(in srgb, var(--wp--preset--color--overlay) 60%, transparent);
}

.wp-block-cover.hn-hero.hn-hero--copy-shadow:not(.hn-hero--ink):has(img.wp-block-cover__image-background) .hn-breadcrumbs .rank-math-breadcrumb > p {
	display: inline;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
	border-radius: 999px;
	background-color: color-mix(in srgb, var(--wp--preset--color--overlay) 50%, transparent);
	box-shadow: 0 0 10px 6px color-mix(in srgb, var(--wp--preset--color--overlay) 50%, transparent);
}

/* --- 60.1-c Desktop submenu dismissed with Escape -------------------
 * A desktop submenu is shown by three independent things: core's
 * `:hover` rule, core's `[aria-expanded=true]` rule, and the theme's
 * Task 59.1 `:focus-within` rule. Core's Interactivity script closes a
 * submenu on Escape ONLY when it was opened by clicking the toggle, and
 * no keypress can switch off a pseudo-class, so Escape did nothing for
 * hover- or focus-opened submenus. navigation-escape.js adds
 * `.hn-submenu-dismissed` to the open item on Escape and removes it when
 * pointer and focus have both left the item (or the toggle is used);
 * this rule restores core's own closed-state declarations while it is
 * present. Desktop bar only: never inside the open mobile overlay. */
.hn-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item.has-child.hn-submenu-dismissed > .wp-block-navigation__submenu-container {
	visibility: hidden;
	opacity: 0;
	width: 0;
	height: 0;
	min-width: 0;
	overflow: hidden;
}

/* --- 60.1-d Forced colours ------------------------------------------
 * Shadows are not painted in forced-colours mode and the system already
 * backplates text, so the halo fill is dropped there. */
@media (forced-colors: active) {
	.wp-block-cover.hn-hero.hn-hero--copy-shadow:not(.hn-hero--ink) .hn-breadcrumbs .rank-math-breadcrumb > p {
		background-color: transparent;
	}
}

/* =====================================================================
 * TASK 62 — Richie four-page layout refinement (v0.2.95)
 * ---------------------------------------------------------------------
 * Home, Stay, Dining and Gatherings: reading width, small-text size,
 * section rhythm and scanning. No copy changes.
 *
 *   62.1  .hn-measure--wide    opt-in wider reading measure (48rem)
 *   62.2  .hn-rhythm--compact  opt-in tighter section boundary
 *   62.3  card text +1px (accommodation + Postcard cards); booking-panel
 *         note 14px -> 16px
 *   62.4  Stay: "Which stay is right for you?" as an open, stacked guide (62.1)
 *         on a full-width warm band (62.2; band = block settings)
 *   62.5  Stay: shares in two columns, rates lead, celebration and
 *         Good to Know treatments
 *   62.6  Dining: wider media-text pairs, sample-menu cards
 *   62.7  Gatherings: why-grid, the gatherings band, enquiry intro
 *
 * Tokens (theme.json custom): width.reading-wide 48rem,
 * rhythm.compact clamp(2.5rem, 6vw, 5rem), type.card, type.lead-body.
 * Everything is opt-in through a class set on the block (Advanced →
 * Additional CSS class) or an existing component class. No page-ID or
 * slug selectors and no new important declarations.
 * ===================================================================== */

/* --- 62.1 Wider reading measure --------------------------------------
 * On a group that uses the default content width, its children take
 * 48rem instead of 42rem (the custom property the core constrained
 * layout reads). On a block that is itself a direct child of a
 * constrained container (a top-level heading or paragraph), the block
 * takes 48rem. Wide and full-width children are untouched. Below about
 * 830px the measure is wider than the column, so phones are unaffected.
 * Specificity (0,3,1) outranks core's constrained-layout rules (0,1,0)
 * without an important flag. */
main .hn-measure--wide {
	--wp--style--global--content-size: var(--wp--custom--width--reading-wide, 48rem);
}

main :where(.is-layout-constrained) > .hn-measure--wide:not(.alignwide):not(.alignfull) {
	max-width: var(--wp--custom--width--reading-wide, 48rem);
}

/* A longer line needs a little more leading: 1.65 -> 1.75. */
main .hn-measure--wide p,
main .hn-measure--wide li,
main p.hn-measure--wide {
	line-height: 1.75;
}

/* --- 62.2 Compact section rhythm -------------------------------------
 * Section boundaries are block settings ("Section" spacing preset,
 * clamp(3.5rem, 8vw, 6.5rem)) or the theme's --hn-rhythm-section. This
 * class redefines both on the block it is set on, so the same editor
 * setting resolves to clamp(2.5rem, 6vw, 5rem): 104 -> 80px at desktop,
 * 56 -> 40px on phones. Background bands that do not carry the class
 * keep their full internal padding. */
main .hn-rhythm--compact {
	--wp--preset--spacing--section: var(--wp--custom--rhythm--compact, clamp(2.5rem, 6vw, 5rem));
	--hn-rhythm-section: var(--wp--custom--rhythm--compact, clamp(2.5rem, 6vw, 5rem));
}

/* --- 62.3 Small text ---------------------------------------------------
 * Card descriptions carry the "Medium" preset as a block setting, which
 * core applies as an important declaration; redefining the preset on the card body
 * moves it one pixel up at every width (16 -> 17px on phones, 20 -> 21px
 * on desktop) without fighting that rule. The synced accommodation cards
 * appear on Home, Stay and Rates; the Postcard cards on Home and
 * Postcards — one component, one size everywhere. */
.hn-card--accommodation .hn-card__content {
	--wp--preset--font-size--medium: var(--wp--custom--type--card, clamp(1.0625rem, 1.0625rem + ((1vw - 0.2rem) * 0.5), 1.3125rem));
}

.hn-card--postcard .wp-block-post-excerpt {
	font-size: var(--wp--custom--type--card, clamp(1.0625rem, 1.0625rem + ((1vw - 0.2rem) * 0.5), 1.3125rem));
}

/* Booking-panel supporting line ("Prefer to read first? …"): the
 * "Small" preset (14px) becomes 16px inside the panel only. */
.hn-cta--booking {
	--wp--preset--font-size--small: 1rem;
}

/* --- 62.4 Stay: "Which stay is right for you?" ----------------------
 * Replaces the 60.1 warm panel with an open guide (0.2.97, Task 62.1).
 * Each of the five entries is a stacked pair opened by a hairline:
 * the accommodation choice is the H3 and the dominant line (display
 * face, lead-body size, accommodation name semibold); the "If you..."
 * reason follows directly underneath as a smaller, quieter paragraph.
 * Stacked at every width. Reading order matches visual order. */
main .hn-hub-which > h3 {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--custom--type--lead-body, clamp(1.125rem, 1.125rem + ((1vw - 0.2rem) * 0.5), 1.375rem));
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: normal;
	text-transform: none;
	text-wrap: pretty; /* not the heading default "balance", which broke longer choices early */
	color: var(--wp--preset--color--heading);
	margin-block-start: var(--wp--preset--spacing--md);
	padding-block-start: var(--wp--preset--spacing--md);
	border-top: 1px solid var(--wp--preset--color--line);
}

main .hn-hub-which > h3 a {
	font-weight: 600;
}

main .hn-hub-which > h3 + p {
	font-family: var(--wp--preset--font-family--body);
	font-size: 1.0625rem;
	line-height: 1.6;
	color: var(--wp--preset--color--text-muted);
	margin-block-start: var(--wp--preset--spacing--xs);
}

/* Phones: the choice is ~18px, so the reason drops to 1rem to keep the
 * two lines clearly distinct. */
@media (max-width: 781px) {
	main .hn-hub-which > h3 + p {
		font-size: 1rem;
		line-height: 1.55;
	}
}

/* "Still not sure? ..." closes the guide in the body face. */
main .hn-hub-which > h3 + p + p {
	color: inherit;
	font-size: inherit;
	margin-block-start: var(--wp--preset--spacing--lg);
	padding-block-start: var(--wp--preset--spacing--md);
	border-top: 1px solid var(--wp--preset--color--line);
}

/* Task 62.2 (v0.2.100): the guide sits on a full-width warm band. The
 * band itself is block settings on the existing group (align full,
 * background "Surface (warm)", padding top/bottom "Section", which
 * .hn-rhythm--compact resolves to clamp(2.5rem, 6vw, 5rem)); nothing
 * here paints it. On surface-warm the sitewide link hover (accent-hover
 * #D96A22) measures 2.98:1, so links in the guide keep their resting
 * brand colour (11.60:1) in every state and show hover/focus/active as
 * a heavier underline (Task 32.1 rule). Scoped to the guide only.
 * (0,2,2) beats core's `:root :where(a...):hover` (0,1,0). */
main .hn-hub-which a:where(:not(.wp-element-button)):is(:hover, :focus, :active) {
	color: var(--wp--preset--color--brand);
	text-decoration-thickness: 2px;
}

/* --- 62.5 Stay: lower sections ---------------------------------------- */

/* What Every Hermitage Stay Shares: two balanced columns from 782px. */
main .hn-hub-shares li + li {
	margin-block-start: 0.35em;
}

@media (min-width: 782px) {
	main .hn-hub-shares ul {
		columns: 2;
		column-gap: var(--wp--preset--spacing--lg);
	}

	main .hn-hub-shares li {
		break-inside: avoid;
	}
}

/* Rates and Booking: the first paragraph (where live rates are, and the
 * guidance link) reads as the section's lead; the booking action sits
 * under the copy. */
main .hn-hub-rates > p:first-of-type {
	font-size: var(--wp--custom--type--lead-body, clamp(1.125rem, 1.125rem + ((1vw - 0.2rem) * 0.5), 1.375rem));
	line-height: 1.6;
}

main .hn-hub-rates > .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* Coming for a celebration?: a quiet aside — accent rule on the leading
 * edge, drawn from the heading down (not through the section's top
 * spacing, which is padding set on the block). */
main .hn-hub-groups {
	position: relative;
	padding-inline-start: clamp(1rem, 3vw, var(--wp--preset--spacing--lg));
}

main .hn-hub-groups::before {
	content: "";
	position: absolute;
	inset-block: var(--wp--preset--spacing--section) 0;
	inset-inline-start: 0;
	border-inline-start: 3px solid var(--wp--preset--color--accent);
}

/* Good to Know: a hairline above the heading — reference material, set
 * apart from the aside above without another panel. */
main .hn-hub-practical > h2 {
	padding-block-start: var(--wp--preset--spacing--md);
	border-top: 1px solid var(--wp--preset--color--line);
}

/* --- 62.6 Dining --------------------------------------------------------
 * Media-text pairs that also carry .hn-w-grid take the 76rem grid width
 * (existing token, rule in Task 03.1) and a slightly tighter inner
 * padding, so the copy column widens ~14% and the photograph ~9%.
 * Phones (stacked below 600px) keep core's stacked padding. */
@media (min-width: 600px) {
	main .wp-block-media-text.hn-w-grid > .wp-block-media-text__content {
		padding-inline: 6%;
	}
}

/* Sample menus: wider row (57 -> 66rem), more air between the cards and
 * a title one step larger. Scoped to the Dining wrap — the menu pages'
 * own .hn-menu-w band is unchanged. */
main :where(.is-layout-constrained) > .hn-menu-cards-wrap.hn-menu-w.alignwide {
	max-width: 66rem;
}

.hn-menu-cards-wrap .hn-menu-cards {
	gap: var(--wp--preset--spacing--lg);
}

.hn-menu-cards-wrap .hn-menu-card .hn-menu-card__title {
	font-size: calc(var(--wp--preset--font-size--large) + 0.125rem);
	line-height: 1.2;
}

/* The Task 09.2 two-line reserve was sized for the 1.65 paragraph
 * leading; at 1.2 two lines are 2.4em. */
@media (min-width: 900px) {
	.hn-menu-cards-wrap .hn-menu-card .hn-menu-card__title {
		min-height: 2.4em;
	}
}

/* --- 62.7 Gatherings ----------------------------------------------------- */

/* Why Gatherings Work Here: two columns at the wide reading measure; the
 * subheads use the "Hero lead" size set on the blocks. */
main .hn-gather-why h3 {
	line-height: 1.25;
	margin-block-end: var(--wp--preset--spacing--xs);
}

/* Gatherings of All Kinds: a full-width warm band (block settings). The
 * enquiry button closes the band. */
main .hn-gather-kinds > .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--md);
}

/* Enquiry: the opening invitation reads as a lead into the form. */
main .hn-enquiry--lead > h2 + p {
	font-size: var(--wp--custom--type--lead-body, clamp(1.125rem, 1.125rem + ((1vw - 0.2rem) * 0.5), 1.375rem));
	line-height: 1.6;
}
