:root {
    --navy: #0e2239;
    --gold: #d4af37;
    --ink: #183047;
    --muted: #667583;
    --warm: #f8f5ef;
    --white: #fff;
    --line: #dfe3e2;
    --serif: Georgia, "Times New Roman", serif;
    --sans: Inter, ui-sans-serif, system-ui, sans-serif;

    /* P2.71 customer typography calibration — three shared tokens, so the
       same semantic role is corrected once rather than through dozens of
       isolated overrides.

       Measured first (Georgia width probe at 40px, "Handgloves"):
         weight 300/400/500 -> 209.2px   (all resolve to Georgia REGULAR)
         weight 600/700/800 -> 242.8px   (all resolve to Georgia BOLD)
       So the serif headings already render Regular at their declared 500,
       and the perceived heaviness was never the serif's weight. It came
       from the sans layer: every eyebrow/metadata label sat at 800
       (ExtraBold) in uppercase with wide tracking, so 10-12px gold and
       navy micro-type was optically louder than the property identity and
       the photography it sits beside.

       --weight-eyebrow  quiets that whole class to a confident-but-calm
                         650 (the codebase's own existing "confident, not
                         bold" sans step, already used by .differentiators
                         span / .stepper-value / .transfer-select-price).
       --tracking-eyebrow normalises uppercase tracking that ranged from
                         .08em to .19em; .1em stays legible in caps without
                         shouting.
       --lh-display      loosens display headings from 1.05, which read as
                         dense on a sturdy screen serif. Weight is what
                         changes here, not size. */
    --weight-eyebrow: 650;
    --tracking-eyebrow: .1em;
    --lh-display: 1.14;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* P2.70B — every existing "X img" / "X > img" sizing rule below
   (.card-media img, .hero-media > img, .gallery-tile img, .room-media
   img, .media-dialog-stage img, .highlight-card img) was written for a
   bare <img>. responsive-media.blade.php wraps a WebP-capable image in
   a <picture> instead; `display: contents` makes the <picture> generate
   no box of its own, so its child <img> is styled exactly as if the
   <picture> wrapper wasn't there at all — no per-component rule below
   needed to change. Excluded whenever [hidden] is also present (a
   carousel slide toggle, e.g. Room Explorer's own [data-room-slide]) so
   this rule never fights the standard [hidden] -> display:none behavior
   with a competing author-stylesheet display value. */
picture:not([hidden]) { display: contents; }
body { margin: 0; color: var(--ink); background: #fff; font-family: var(--sans); line-height: 1.55; }
/* P2.48E — standard visually-hidden-but-announced utility, mirroring
   catalogue-booking.css's own identical rule (that stylesheet isn't
   loaded on this page, so it's defined once here too rather than
   pulling in an unrelated file). */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.skip { position: fixed; left: 1rem; top: -5rem; z-index: 99; background: var(--navy); color: #fff; padding: .8rem 1rem; }
.skip:focus { top: 1rem; }
.site-header { height: 74px; display: flex; align-items: center; justify-content: space-between; padding: 0 clamp(1.2rem, 5vw, 5rem); border-bottom: 1px solid #eef0ef; background: rgba(255, 255, 255, .96); }
.site-header a { color: var(--navy); text-decoration: none; }
.brand { font-family: var(--serif); font-size: 1.65rem; font-weight: 700; }
.site-header span { color: var(--muted); font-size: .85rem; }
/* P2.52 §G — the customer navigation itself: on every page but the one
   it targets, links to Search and to the existing (previously
   undiscoverable) /recover-booking route. A plain flex+gap group, not
   a second `justify-content` participant, so `.site-header` keeps its
   simple two-child space-between layout regardless of how many links
   this holds on a given page. */
.site-nav { display: flex; align-items: center; gap: clamp(1rem, 2.5vw, 1.75rem); font-size: .85rem; font-weight: 550; }
@media (max-width: 430px) {
    .site-nav { gap: .7rem; font-size: .78rem; }
}
@media (max-width: 360px) {
    /* Comfortable margin rather than a hairline fit: at the very
       narrowest supported width, both the brand mark and two nav
       links must sit on one row without wrapping. */
    .brand { font-size: 1.4rem; }
    .site-header { padding: 0 .85rem; }
    .site-nav { gap: .6rem; font-size: .72rem; }
}

/* P2.52 §I — a small, honest closing shell (see partials/site-footer)
   so the journey never just stops mid-page. Deliberately plain: no
   multi-column link farm, matching the header's own restraint. */
.site-footer { border-top: 1px solid var(--line); margin-top: clamp(2rem, 5vw, 4rem); padding: clamp(1.6rem, 4vw, 2.4rem) clamp(1.2rem, 5vw, 5rem); }
.site-footer-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem 1.5rem; color: var(--muted); font-size: .82rem; }
.site-footer-brand { font-family: var(--serif); font-weight: 700; color: var(--navy); }
.site-footer-support a, .site-footer-support a:visited { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.site-footer-copyright { color: var(--muted); flex-basis: 100%; order: 5; }
.site-footer-legal { display: flex; flex-wrap: wrap; gap: .4rem 1rem; }
.site-footer-legal a, .site-footer-legal a:visited { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.footer-company-details { flex-basis: 100%; order: 6; margin-top: .4rem; }
.eyebrow { font-size: .72rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); color: #8c741f; }
h1, h2, h3 { font-family: var(--serif); color: var(--navy); line-height: var(--lh-display); margin: .25em 0; }

/* P2.52 — top/bottom padding tightened again (was clamp(2.25rem,5vw,
   4.75rem) / clamp(1.6rem,3.5vw,3rem)): the owner's typography/density
   review found the hero block, even with P2.51B's already-reduced H1,
   still consumed too much vertical space before the search instrument
   and — combined with the results header below — pushed all inventory
   below the fold on a standard desktop viewport. */
.search-hero { background: var(--warm); padding: clamp(1.75rem, 3.5vw, 3rem) clamp(1.2rem, 7vw, 7rem) clamp(1.2rem, 2.5vw, 1.9rem); }
/* P2.51B §H reduced this once already; P2.52 narrows it further (was
   clamp(1.75rem, 3vw, 2.75rem) / max-width 640px) per the owner's
   explicit target range (~40-48px desktop) and instruction that
   functional OTA surfaces should not read as a magazine headline — a
   narrowly-scoped reduction, still this selector only. */
/* P2.52 — ONE fluid curve for the full 320-1440px+ range (anchored at
   320px≈28px and 1440px≈44px, the owner's own desktop target), not a
   base rule plus two separate breakpoint overrides. The previous
   three-rule version (this rule plus two @media overrides below)
   produced a real, visible backward jump in size right at the 900px
   boundary once the base value changed — found live while checking
   intermediate widths, not merely the named breakpoints. A single
   clamp() cannot jump. */
.search-hero h1 { font-size: clamp(1.75rem, 1.46rem + 1.43vw, 2.75rem); max-width: 580px; font-weight: 500; line-height: 1.1; letter-spacing: -.01em; text-wrap: balance; }
.search-form { margin-top: 2rem; display: grid; grid-template-columns: 2fr repeat(3, 1fr) auto; gap: 1px; background: #d8d9d5; border: 1px solid #d8d9d5; border-radius: 14px; overflow: hidden; box-shadow: 0 16px 45px #0e223912; }
.search-form label { min-width: 0; padding: .65rem 1rem; background: #fff; font-size: .66rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
.search-form input { display: block; width: 100%; min-width: 0; border: 0; margin-top: .2rem; padding: .2rem 0; color: var(--ink); font: inherit; font-size: .94rem; background: transparent; }
.search-form button, .button { border: 0; background: var(--navy); color: #fff; padding: 1rem 1.6rem; font-weight: 750; text-decoration: none; cursor: pointer; }
.search-form button:hover, .search-form button:focus-visible, .button:hover, .button:focus-visible { outline: 3px solid #d4af3780; outline-offset: -3px; }

.results, .rooms-section, .review-section { padding: clamp(3rem, 7vw, 7rem) clamp(1.2rem, 7vw, 7rem); }
/* P2.51B §H — the search-results section specifically (never
   rooms-section/review-section, whose own rhythm is unrelated to the
   benchmarked "hero-to-first-results" gap) sits directly below the
   search instrument; narrowing just its own top padding keeps related
   decisions (search → results) visually closer, matching the tighter
   rhythm observed across every competitor studied. */
/* P2.52 — narrowed again (was clamp(2rem, 4vw, 3.5rem)) alongside the
   results-header changes below it, so the property grid is reachable
   without scrolling on a standard desktop viewport. */
.results { padding-top: clamp(1.3rem, 2.5vw, 2.2rem); }
/* P2.53 final visual gate — .rooms-section is markup-exclusive to the
   customer property page (grep-verified: never shared with search
   results or any other template), so unlike the P2.51B-era comment
   above (written before Highlights existed), narrowing ITS OWN top
   padding here cannot touch review-section's unrelated rhythm. With
   "Why stay here" now sitting directly above Room Explorer, the full
   7vw/7rem padding read as a second unexplained gap stacked on top of
   Highlights' own bottom spacing, pushing Room Explorer's heading and
   intro copy down before any room card could appear. Matches
   .results' own precedent exactly. */
.rooms-section { padding-top: clamp(1.3rem, 2.5vw, 2.2rem); }
.section-title { display: flex; justify-content: space-between; align-items: end; margin-bottom: 1.1rem; }
.rooms-section h2, .review-section h2 { font-size: clamp(1.5rem, 2.6vw, 2.35rem); font-weight: 500; letter-spacing: -.01em; }
/* P2.52 — split out of the shared `.section-title h2, .rooms-section
   h2, .review-section h2` rule above (which stays serif/2.35rem
   exactly as it was — it still governs Room Explorer's own heading,
   explicitly protected, and the review section's). `.section-title h2`
   is markup-exclusive to the search-results count
   (search.blade.php's "N properties") and nothing else: a functional
   navigation/wayfinding number, not a content heading, so it now takes
   the sans-serif hierarchy instead of the serif one — smaller and
   lighter, so it reads as information rather than a second hero
   statement stacked under the first. */
/* P2.69 typography audit — 700 (full bold) gave this functional count
   heading more visual weight than the property/room titles it sits above,
   an inverted hierarchy. 650 matches this codebase's own established sans
   "confident but not bold" token (.differentiators span, .stepper-value,
   .transfer-select-price all already use it). */
.section-title h2 { font-family: var(--sans); font-size: clamp(1.19rem, .96rem + 1.16vw, 2rem); font-weight: 550; color: var(--ink); }
.section-title > p, .section-intro { color: var(--muted); }
/* P2.69 — mobile-first default is a single column; the 601px+ rule below
   sets the 2-column landscape card layout, and the 1280px+ rule further
   below densifies to 3 columns on wide desktop. (A `repeat(3, ...)`
   default lived here previously, but the unconditional 601px+ override
   further down the cascade always won over it at every width ≥601px —
   dead code that never actually rendered; removed rather than kept as
   misleading intent.) */
.property-grid { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; gap: clamp(1.1rem, 2vw, 2rem); }
.property-card { min-width: 0; border: 1px solid var(--line); border-radius: 20px; overflow: hidden; background: #fff; }
/* P2.51C §E — .card-media is an <a>; without this, the browser's
   default link underline/blue paints through every descendant
   (including the "aA" / "Photography coming soon" fallback), which
   read as a broken/unstyled prototype link rather than the intended
   navy placeholder mark. */
.card-media { display: block; aspect-ratio: 16 / 10; overflow: hidden; color: inherit; text-decoration: none; }
.card-media:hover, .card-media:focus { color: inherit; text-decoration: none; }
.card-media img, .hero-media > img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s; }
.property-card:hover .card-media img { transform: scale(1.025); }
.media-fallback { height: 100%; min-height: 260px; background: linear-gradient(145deg, #e9e5dc, #f8f5ef); display: grid; place-content: center; text-align: center; color: var(--navy); }
.media-fallback span { font-family: var(--serif); font-size: 4rem; }
.media-fallback small { letter-spacing: .12em; text-transform: uppercase; }
.card-body { padding: 1.2rem 1.35rem 1.3rem; }
.card-location { margin: 0 0 .25rem; font-size: .72rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: #92791f; }
/* P2.52 — was font-size: 1.6rem with the browser's implicit h3 bold
   (700): at that size/weight the serif title outweighed the price
   (1.12rem) by a wide margin, competing with the property photograph
   above it and undersELLING price/commercial value relative to
   identity. Kept comfortably inside the owner's 22-28px target range
   and still serif (property identity is one of the strategic uses the
   brief names) — only weight and size trimmed, and margin tightened to
   match. */
/* P2.52 — a single fluid clamp (≈19px at 320px → 24px at 1280px+)
   rather than a base size plus a separate mobile-breakpoint override,
   so card titles scale continuously with viewport width instead of
   stepping between two fixed values at 600px. */
/* P2.69 final micro-correction — 600 still rendered visually heavy: `--serif`
   (Georgia/Times New Roman) ships only two real faces, Regular(400) and
   Bold(700); browsers resolve any font-weight without an exact face to the
   NEAREST one, and 600 is numerically closer to 700 than 400, so it was
   rendering identically to bold. 500 is the lightest value that reliably
   resolves to the font's actual Regular face across engines — a real
   optical change, not just a smaller number. */
.card-body h3 { margin: 0 0 .4rem; font-size: clamp(1.19rem, 1.08rem + .52vw, 1.5rem); font-weight: 500; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card-body a { color: inherit; text-decoration: none; }
.summary { margin: 0; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* P2.69 — `.card-rail` replaces the former `.card-foot`: on mobile it is
   still a simple row beneath the body (verified-stay score, price, then a
   full-width CTA); from 901px it becomes the card's third zone. */
.card-rail { padding: 0 1.35rem 1.3rem; display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: .85rem 1rem; font-size: .8rem; color: var(--muted); }
.price { text-align: right; display: grid; }
/* P2.52 — raised from 1.12rem to sit closer to Room Explorer's own
   established price scale (.room-price strong, 1.3rem) instead of
   reading as secondary metadata beneath a heavier title. */
.price strong { color: var(--navy); font-size: 1.28rem; font-weight: 700; }
.quiet-state { max-width: 180px; text-align: right; }

/* P2.69 — the room actually being quoted, surfaced on the comparison row.
   Sans throughout: this is commercial comparison information, not
   identity. Kept to one name plus a short fact row so the card answers
   "which room, for how many, on what terms" without becoming a spec
   table — aAlabu answers the full version in Room Explorer. */
.card-room { margin: .85rem 0 0; padding: .6rem .75rem; border-radius: 10px; background: var(--warm); }
.card-room-name { margin: 0; font-family: var(--sans); font-size: .84rem; font-weight: 650; color: var(--ink); }
.card-room-facts { display: flex; flex-wrap: wrap; gap: .25rem .5rem; margin: .2rem 0 0; font-size: .76rem; color: var(--muted); }
.card-room-facts span:not(:last-child)::after { content: "·"; margin-left: .5rem; color: #b9b3a4; }
.card-trust-source { margin: 0 0 .1rem; font-size: .63rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--navy); }
.card-trust p { margin: 0; }
.price span, .price small, .card-room-name, .card-room-facts, .card-trust p { font-family: var(--sans); }
.more { display: table; margin: 3rem auto 0; border: 1px solid var(--navy); border-radius: 99px; padding: .8rem 1.5rem; color: var(--navy); text-decoration: none; }
.empty { padding: 3rem; background: var(--warm); border-radius: 18px; }

.property-hero { padding: clamp(1.75rem, 5vw, 4.5rem) clamp(1.2rem, 5vw, 5rem); display: grid; grid-template-columns: minmax(0, .95fr) minmax(420px, 1.05fr); align-items: center; gap: clamp(2rem, 4vw, 4rem); background: var(--warm); }
.property-hero > *, .hero-copy { min-width: 0; }
/* P2.51B §H — reduced from clamp(2.5rem, 4.2vw, 3.9rem): the property
   name must read as clear, premium identity without visually
   overpowering stay selection, Room Explorer, price or the booking CTA
   below it — narrowly scoped to this selector only. */
.hero-copy h1 { max-width: 100%; font-size: clamp(1.9rem, 3vw, 2.9rem); font-weight: 500; line-height: 1.08; letter-spacing: -.02em; overflow-wrap: break-word; hyphens: auto; text-wrap: balance; }
.location { font-size: .78rem; letter-spacing: var(--tracking-eyebrow); font-weight: var(--weight-eyebrow); text-transform: uppercase; }
/* P2.53 §7 — Brand sits inline with location (same restrained label
   treatment, not a second heading); Group is deliberately a separate,
   quieter line below — secondary information, never mechanically next
   to the property name. */
.brand-name { color: var(--navy); }
.brand-group { margin: .2rem 0 0; font-size: .72rem; letter-spacing: normal; text-transform: none; font-weight: 500; color: var(--muted); }
.lead { font-family: var(--serif); font-size: clamp(1.2rem, 2vw, 1.65rem); color: var(--muted); max-width: 600px; }
/* P2.71 surgical correction — same collapsed-reading treatment as
   .review-body.is-collapsed (7-line clamp) below, at a 6-line count
   that falls inside both the desktop (~5-6 line) and mobile (~5-7
   line) targets without needing a separate breakpoint override.
   Family/size/color above are completely unchanged. */
.lead.is-collapsed { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
.lead-toggle { display: block; margin: .4rem 0 0; padding: 0; border: 0; background: none; color: var(--navy); font: inherit; font-size: .85rem; font-weight: 650; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.lead-toggle[hidden] { display: none; }
.lead-toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.button { display: inline-block; border-radius: 99px; margin-top: 1.3rem; }
/* P2.51C §E — the arch/dome radius here (was 180px 180px 24px 24px)
   read as boutique-hospitality/editorial rather than a calm modern OTA,
   and was the one surface in the whole journey not sharing the
   property-card/room-card 20px rounded-rect language. Normalized to
   match. */
/* P2.53 final visual gate — was aspect-ratio 1.1 (near-square): P2.52's
   own pass fixed this element's SHAPE (arch -> rounded-rect) but never
   checked its PROPORTIONS, which stayed the one image on the entire
   site not sharing the 16/10 ratio every card/highlight/room image
   already uses. At a realistic 1440x900 laptop viewport this alone
   measured 591px tall — 66% of the viewport — pushing the first
   room's Select button to 2.3x viewport height before any scroll.
   16/10 matches every other image site-wide (family resemblance) and
   is the single largest contributor to reaching Room Explorer sooner. */
.hero-media { position: relative; min-width: 0; aspect-ratio: 16 / 10; border-radius: 20px; overflow: hidden; }

/* P2.53 §D — compact, real "why stay here" content (catalog_property_
   highlights); deliberately lighter-weight than .amenities below it —
   this is a handful of cards, not a dense fact list, and must not add
   vertical ceremony before Room Explorer. auto-fit means 1/2/3 cards
   read as intentional regardless of how many highlights a property
   actually has. */
/* P2.71 surgical correction — Room Explorer/.highlights/.amenities/
   .getting-there previously ran as four consecutive sections with no
   background of their own (all inheriting the plain white body), the
   longest unbroken plane on the page. Tinting this one section reuses
   the exact white-card-on-warm treatment already proven elsewhere on
   this same page (.review-section/.review-grid article) rather than
   inventing a new pattern — .highlight-card's own white background is
   unchanged. */
.highlights { padding: clamp(2rem, 4vw, 3rem) clamp(1.2rem, 7vw, 7rem) 0; background: var(--warm); }
.highlights h2 { font-size: clamp(1.3rem, 2vw, 1.75rem); font-weight: 500; letter-spacing: -.01em; margin: 0 0 1.1rem; }
.highlights-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.1rem; }
.highlight-card { min-width: 0; border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: #fff; }
.highlight-card img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; display: block; }
.highlight-body { padding: 1rem 1.15rem 1.2rem; }
.highlight-category { margin: 0 0 .3rem; font-size: .68rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: #8c741f; }
/* P2.71 surgical correction — 600 has no real Georgia face and was
   resolving to the same Bold glyphs as 700, reading heavier than this
   card's own parent (.highlights h2, 500) sitting directly above it.
   500 resolves to Georgia's actual Regular face, matching the same fix
   already applied to the sibling .card-body h3/.room-content h3 (see
   their own P2.69 comments above). */
.highlight-body h3 { margin: 0 0 .4rem; font-size: 1.15rem; font-weight: 500; overflow-wrap: anywhere; }
.highlight-body p:last-child { margin: 0; color: var(--muted); font-size: .88rem; line-height: 1.5; }

/* P2.53 §G/§H — the strongest 2-4 room-comparison facts (view/
   beachfront/private pool/etc.), styled distinctly from the plain
   grey .chips (generic amenities) below so they read as the higher-
   priority signal the brief calls for — a warm gold tint rather than
   a new colour, staying inside the existing accent family. */
.differentiators { display: flex; flex-wrap: wrap; gap: .4rem; margin: .6rem 0 0; }
.differentiators span { border: 1px solid #d9c48a; background: var(--warm); color: #7a5f14; border-radius: 99px; padding: .3rem .7rem; font-size: .74rem; font-weight: 650; }

.amenities { padding: 3.5rem clamp(1.2rem, 7vw, 7rem); display: grid; grid-template-columns: .8fr 1fr; gap: 2rem; background: #fff; }
/* P2.53 final visual gate — .amenities has 3 direct grid children
   (eyebrow, h2, the chips div) across a 2-column grid with no explicit
   placement, so default row-major auto-flow put the eyebrow and h2
   side-by-side on row 1 (splitting the intended "eyebrow above
   heading" pairing used by every other section) and left the chips
   div alone on row 2 — an empty column-2 rectangle roughly half the
   section's height, not a deliberate composition. Explicit placement
   restores the eyebrow+heading stack in column 1 and lets the chips
   list occupy column 2 for the section's full height, matching the
   left-label/right-content composition the .8fr/1fr split was
   clearly authored for. The @media(max-width:900px) override below
   switches to display:block, where these placements simply don't
   apply and DOM order (eyebrow, h2, div) already stacks correctly. */
.amenities p.eyebrow { grid-column: 1; grid-row: 1; }
.amenities h2 { grid-column: 1; grid-row: 2; font-size: clamp(1.5rem, 2.6vw, 2.35rem); font-weight: 500; letter-spacing: -.01em; }
.amenities > div { grid-column: 2; grid-row: 1 / span 2; align-self: center; display: grid; grid-template-columns: repeat(2, 1fr); gap: .8rem 1.5rem; align-content: center; }
.amenities span { border-bottom: 1px solid var(--line); padding: .6rem 0; }

/* P2.73 — the property-level commercial transfer selector. A single
   restrained, calm card (never the same large section-title treatment
   as .rooms-section — a decision aid, not a competing primary section),
   sitting between the stay-picker form and Room Explorer. Mirrors
   .transfer-summary's own established "plain class sets display: flex
   unconditionally, so [hidden] (0,1,1) must stay more specific than the
   bare class (0,1,0) to actually collapse to zero visual space" fix. */
.transfer-selector {
    margin: 1.4rem clamp(1.2rem, 7vw, 7rem) 0; padding: 1.2rem 1.4rem;
    background: var(--warm); border: 1px solid var(--line); border-radius: 16px;
    display: flex; flex-direction: column; gap: .5rem;
}
.transfer-selector[hidden] { display: none; }
.transfer-selector .eyebrow { margin: 0; }
.transfer-selector h2 { margin: 0; font-size: clamp(1.05rem, 1.6vw, 1.3rem); font-weight: 500; }
.transfer-select-intro { margin: 0; color: var(--muted); font-size: .85rem; }
.transfer-select-blocked { margin: 0; color: #8c3a1f; font-size: .88rem; line-height: 1.5; }

.transfer-select-list { list-style: none; margin: .3rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
/* CLOSE-4D.2 — the optional property-arranged transfer picker offered
   at Review Total/checkout (never before Room Explorer) is a single-
   click "Add transfer" per row, never a radiogroup + separate confirm
   step (adding an optional ancillary needs no deliberate confirmation
   the way a mandatory decision once did) — so this is the row's own
   layout directly, not a wrapping <label>/<input radio>. */
.transfer-select-option {
    display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .7rem;
    border: 1px solid var(--line); border-radius: 12px; background: #fff; padding: .75rem .9rem;
}
.transfer-select-option.is-disabled { opacity: .6; }
.transfer-select-option .transfer-select-confirm-button { flex: 0 0 auto; padding: .5rem 1rem; min-height: 38px; }
.transfer-select-option-body { display: flex; flex-direction: column; gap: .15rem; }
.transfer-select-option-name { font-weight: 650; color: var(--ink); font-size: .92rem; }
.transfer-select-price { color: var(--navy); font-weight: 650; font-size: .85rem; }
/* P2.72/P2.73 — a lighter weight than the price itself so the amount
   stays the visual lead, while still reading as a distinct commercial fact. */
.transfer-select-payable-note { font-weight: 500; color: var(--muted); }
.transfer-select-note { font-size: .74rem; color: var(--muted); }
.transfer-select-note-ineligible { color: #8c3a1f; }

.transfer-select-confirm-button {
    align-self: flex-start; border: 0; border-radius: 10px; background: var(--navy); color: #fff;
    padding: .7rem 1.3rem; font-weight: 650; font-size: .86rem; cursor: pointer; min-height: 44px;
}
.transfer-select-confirm-button:disabled { opacity: .5; cursor: not-allowed; }
.transfer-select-confirm-button:not(:disabled):hover, .transfer-select-confirm-button:not(:disabled):focus-visible { outline: 3px solid #d4af3780; outline-offset: -3px; }

.transfer-select-confirmed { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; font-size: .88rem; color: var(--ink); }
.transfer-select-change {
    border: 1px solid var(--line); background: #fff; border-radius: 8px; padding: .3rem .7rem;
    font-size: .78rem; font-weight: 650; color: var(--navy); cursor: pointer; min-height: 32px;
}
.transfer-select-change:hover, .transfer-select-change:focus-visible { outline: 3px solid #d4af3780; outline-offset: -2px; }

/* CLOSE-4D.2 — the optional transfer picker's own container inside
   `.checkout-summary`, visually subordinate to the accommodation price
   above it (smaller eyebrow, no card/border of its own — the picker's
   OWN option rows already carry their own border via
   .transfer-select-option). */
.checkout-transfer-picker { margin-top: .6rem; }
.checkout-transfer-picker[hidden] { display: none; }
.checkout-transfer-picker .eyebrow { margin: 0 0 .3rem; }
.transfer-select-picker-body { margin-top: .6rem; display: flex; flex-direction: column; gap: .5rem; }
.transfer-select-picker-body[hidden] { display: none; }

.room-scroll-hint { display: none; color: var(--muted); font-size: .83rem; font-weight: 600; }
.room-scroller { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; gap: 1.4rem; max-width: 100%; padding: 1rem 1px 2rem; }
.room-card { min-width: 0; height: 100%; display: flex; flex-direction: column; border: 1px solid var(--line); background: #fff; color: var(--ink); border-radius: 20px; overflow: hidden; box-shadow: 0 10px 26px #0e223912; }
.room-card > img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; flex: 0 0 auto; }
.room-fallback { min-height: 230px; display: grid; place-items: center; padding: 1rem; background: linear-gradient(145deg, #e9e5dc, #f8f5ef); color: var(--navy); text-align: center; }
/* P2.53 final visual gate — a flex column so .room-commercial (the
   price/CTA/unavailable block) can anchor to the bottom via
   margin-top: auto below, instead of leaving a large blank gap under
   shorter-content cards once .room-scroller stretches every card in a
   row to equal height. */
.room-content { min-width: 0; padding: 1.3rem; flex: 1; display: flex; flex-direction: column; }
.room-commercial { margin-top: auto; padding-top: .9rem; }
/* P2.69 typography audit — no font-weight was set here, so this fell
   through to the browser's default bold (~700) for h3: heavier than the
   Property title's own explicit 500 one level up. 600 matches the
   secondary-serif-heading weight already used for .card-body h3 (search
   result name) and .highlight-body h3, giving Room Explorer's room name a
   calmer, but still prominent, sibling to those. */
/* P2.69 final micro-correction — 600 still read as visually bold: Georgia
   has no real 600 face, so the browser was resolving it to the same Bold
   glyphs as 700. 500 resolves to the font's actual Regular face, the
   lightest weight that is a genuine optical change rather than a numeric
   one — see .card-body h3's comment above for the full explanation. */
.room-content h3 { margin: 0 0 .55rem; color: var(--navy); font-weight: 500; font-size: clamp(1.4rem, 1.8vw, 1.7rem); letter-spacing: -.01em; line-height: 1.16; overflow-wrap: anywhere; }
.room-content > p { margin: 0; color: var(--muted); line-height: 1.5; overflow-wrap: anywhere; }
.room-content dl { margin: 1rem 0; }
.room-content dl div { display: grid; grid-template-columns: 34% minmax(0, 66%); padding: .52rem 0; border-top: 1px solid var(--line); }
.room-content dt { color: #8a711d; font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; }
.room-content dd { min-width: 0; margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.chips { display: flex; flex-wrap: wrap; gap: .38rem; }
.chips span { border: 1px solid var(--line); background: var(--warm); color: var(--ink); border-radius: 99px; padding: .27rem .6rem; font-size: .72rem; }

/* P2.31 — the property page's own compact dates/guests form, sharing
   .search-form's field/button styling but with its own column count
   (no destination field) and no extra top margin since it sits directly
   under the Room Explorer intro rather than a hero. */
.stay-picker-form.search-form { grid-template-columns: repeat(3, 1fr) auto; margin: 1.25rem 0 2rem; }

.room-price { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: .1rem; }
.room-price strong { font-size: 1.3rem; color: var(--navy); }
.room-price span { font-size: .78rem; color: var(--muted); }

/* P2.48E §C — restrained strike-through + concise benefit label,
   suppressed entirely (see accommodation-price.blade.php) unless a
   Promotion actually moved the displayed price. Reused identically by
   both the primary .room-price block and each .rate-option-action row —
   sized by its ancestor's own existing `strong`/`span` rules, never a
   separate size system. */
.price-original { font-size: .78rem; color: var(--muted); }
.price-original s { text-decoration-thickness: 1.5px; }
.promotion-badge { display: inline-block; margin-top: .15rem; font-size: .72rem; font-weight: 700; color: #8a711d; }
.room-select {
    display: block; width: 100%; margin-top: .8rem; border: 0; border-radius: 99px; padding: .75rem 1rem;
    background: var(--navy); color: #fff; font-weight: 750; font-size: .88rem; cursor: pointer;
}
.room-select:hover:not(:disabled) { background: #17334e; }
.room-select:disabled { opacity: .6; cursor: not-allowed; }
.room-select-status { min-height: 1rem; margin: .5rem 0 0; font-size: .76rem; color: var(--muted); }
.room-select-status[data-kind="error"] { color: #9c3b2c; font-weight: 650; }
.room-select-status[data-kind="success"] { color: #3f7d4a; }
.room-unavailable { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line); font-size: .82rem; color: var(--muted); }

/* P2.32 — RatePlan choice: the recommended offer stays the primary CTA
   above (unchanged markup/styling); when a room has more than one
   currently sellable RatePlan, a restrained <details> disclosure below
   it exposes the rest without turning the card into a dense rate table. */
.room-price-eyebrow { margin: 0 0 .15rem; font-size: .66rem; font-weight: var(--weight-eyebrow); text-transform: uppercase; letter-spacing: var(--tracking-eyebrow); color: #8a711d; }

.rate-options { margin-top: .9rem; }
.rate-options summary {
    cursor: pointer; list-style: none; display: flex; align-items: center; gap: .3rem; min-height: 44px;
    color: var(--navy); font-weight: 650; font-size: .82rem;
}
.rate-options summary::-webkit-details-marker { display: none; }
.rate-options summary::after { content: '›'; display: inline-block; transform: rotate(90deg); transition: transform .15s ease; font-size: 1rem; }
.rate-options[open] summary::after { transform: rotate(270deg); }
.rate-options summary:focus-visible { outline: 3px solid var(--navy); outline-offset: 3px; border-radius: 4px; }

.rate-option-list { list-style: none; margin: .7rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.rate-option { display: flex; justify-content: space-between; align-items: flex-end; gap: .8rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.rate-option-info { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.rate-option-info strong { color: var(--navy); font-size: .88rem; }
.rate-option-info span { font-size: .74rem; color: var(--muted); overflow-wrap: anywhere; }
.rate-option-action { display: flex; flex-direction: column; align-items: flex-end; gap: .35rem; flex: 0 0 auto; }
.rate-option-action > strong { font-size: .92rem; color: var(--navy); }
.rate-option-select {
    display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
    border: 1px solid var(--navy); border-radius: 99px; background: transparent; color: var(--navy);
    padding: 0 .9rem; font-weight: 650; font-size: .78rem; cursor: pointer; white-space: nowrap;
}
.rate-option-select:hover:not(:disabled) { background: var(--navy); color: #fff; }
.rate-option-select:disabled { opacity: .6; cursor: not-allowed; }
.rate-option .room-select-status { text-align: right; }

/* P2.37D.5 — "What's included" disclosure. A native <details>/<summary>
   control: keyboard-operable (Tab + Enter/Space), touch-operable, no
   hover dependency — matches .rate-options' own established pattern. */
.meal-plan-disclosure { margin: .5rem 0; }
.meal-plan-disclosure summary {
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .3rem; min-height: 44px;
    color: var(--navy); font-weight: 650; font-size: .78rem; text-decoration: underline; text-underline-offset: 2px;
}
.meal-plan-disclosure summary::-webkit-details-marker { display: none; }
.meal-plan-disclosure summary:focus-visible { outline: 3px solid var(--navy); outline-offset: 3px; border-radius: 4px; }
.meal-plan-disclosure-body { margin-top: .4rem; padding: .7rem .8rem; border-radius: 10px; background: var(--warm); font-size: .78rem; color: var(--muted); }
.meal-plan-summary { margin: 0 0 .4rem; color: var(--navy); font-weight: 600; }
.meal-plan-facts { list-style: none; margin: 0 0 .4rem; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.meal-plan-fact { overflow-wrap: anywhere; }
.meal-plan-fact--not_included { text-decoration: line-through; opacity: .75; }
.meal-plan-description, .meal-plan-conditions { margin: .4rem 0 0; }

.review-section { background: var(--warm); }
/* P2.53 final visual gate — the empty-reviews state ("A new story on
   aAlabu." + one line of body copy) has no grid or averages list to
   fill the section's width, so at large-desktop widths (1440px+) it
   read as an unexplained sparse gap of empty right-hand space rather
   than a deliberate composition. Direct-child selector only: never
   touches review-grid's own nested article paragraphs or the
   populated review-averages layout, both unrelated and unaudited
   here. Matches the existing .search-hero h1 max-width precedent. */
.review-section > h2, .review-section > p { max-width: 640px; }
/* P2.69 §G — compact aligned category summary. Two columns from the
   narrowest supported width up (six stacked label/value pairs was the
   "long vertical list before the actual reviews" the brief called out),
   sans-serif throughout because these are comparison metrics, not
   editorial content. */
.review-averages { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: .7rem 1.4rem; margin: 1.2rem 0 0; font-family: var(--sans); }
.review-averages > div { min-width: 0; }
.review-averages dt { font-size: .78rem; color: var(--ink); }
.review-averages dd { margin: .12rem 0 0; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: .5rem; }
.review-average-value { grid-column: 2; grid-row: 1; font-size: .82rem; font-weight: 700; color: var(--navy); }
.review-average-bar { grid-column: 1; grid-row: 1; height: 4px; border-radius: 99px; background: #e2ded2; }
.review-average-bar::before { content: ""; display: block; width: var(--fill, 0%); height: 100%; border-radius: inherit; background: var(--gold); }

/* align-items: start — review cards size to their own content. Stretched
   to a common height, a two-line review next to a fifteen-line one left a
   large empty card, which read as missing content rather than a short
   review. */
.review-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; align-items: start; }
.review-grid article { min-width: 0; background: #fff; border-radius: 16px; padding: 1.4rem; }
.review-grid article > strong { color: #8a711d; font-size: 1.4rem; }
/* P2.69 typography audit — review titles had no dedicated rule, so they
   fell through to the same browser bold-h3 default as the two rules above,
   visually competing with the score directly beside them. Calmer weight +
   a size closer to body text, still serif so it reads as a small heading
   rather than another paragraph. */
/* P2.69 final micro-correction — same Georgia-has-no-600-face issue as
   .card-body h3 / .room-content h3 above; 500 is the lightest weight that
   resolves to the real Regular face instead of silently matching Bold. */
.review-grid article h3 { margin: .3rem 0 .5rem; font-size: 1.05rem; font-weight: 500; }
/* P2.69 final micro-correction — compact reading state for long reviews.
   `.is-collapsed` uses the same -webkit-line-clamp technique already used
   above for .card-body h3 (search-result name truncation); ~7 lines was
   the requested visual target. The toggle button is revealed by JS only
   when a given review's real content actually overflows that clamp, so a
   short review (e.g. a title-only entry) never grows an empty control. */
.review-body p { margin: 0; }
.review-body.is-collapsed { display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; }
.review-toggle { display: block; margin: .6rem 0 .7rem; padding: 0; border: 0; background: none; color: var(--navy); font: inherit; font-size: .85rem; font-weight: 650; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
/* P2.69 review-toggle verification fix — `display: block` above is
   author-origin CSS, which always wins over the UA stylesheet's own
   `[hidden] { display: none }` rule regardless of selector specificity.
   Without this, a review the JS correctly decided did NOT need expanding
   (so left the button's `hidden` attribute untouched) still rendered as a
   visible, non-functional "Read more" — a real defect found during live
   verification, distinct from the earlier byline-spacing fix. This
   restores the native hidden-attribute behaviour for this one element. */
.review-toggle[hidden] { display: none; }
.review-toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.review-grid blockquote { margin: 1rem 0 0; padding: 1rem; border-left: 2px solid var(--gold); background: var(--warm); font-size: .85rem; }
.review-grid blockquote b { display: block; }
.large { min-height: 100%; }

/* P2.43A §N — a subtle SECONDARY signal, deliberately small and quiet:
   never the same visual weight as the aAlabu score above it, never
   implying a combined rating. Empty (no layout) until the client script
   populates it on demand. */
/* Deliberately NOT hidden via `:empty` — a display:none element has no
   layout box, so IntersectionObserver could never detect it entering
   the viewport and the on-demand fetch would never trigger. The
   client script instead sets `display:none` explicitly (via
   `[data-visible="false"]`) only once a fetch has resolved to nothing
   worth showing. */
.external-reputation { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--line); max-width: 22rem; min-height: 1.2rem; }
.external-reputation[data-visible="false"] { display: none; }
.external-reputation__eyebrow { font-size: .68rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); color: var(--muted); text-transform: uppercase; margin: 0 0 .3rem; }
.external-reputation__score { font-size: 1.1rem; margin: 0; color: var(--ink); }
.external-reputation__score strong { font-size: 1.35rem; }
.external-reputation__count { display: inline-block; margin-left: .5rem; color: var(--muted); font-size: .85rem; }
.external-reputation__link { display: block; margin-top: .3rem; font-size: .85rem; color: var(--navy); }
.external-reputation__attribution { margin: .4rem 0 0; font-size: .72rem; color: var(--muted); }
.external-reputation__hint { font-size: .8rem; color: var(--muted); margin: 0; }

@media (max-width: 1099px) {
    .room-scroll-hint { display: block; margin: 1.25rem 0 .1rem; }
    .room-scroller { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(300px, 62%); overflow-x: auto; overflow-y: visible; scroll-snap-type: inline mandatory; scroll-padding-inline: 1px; overscroll-behavior-inline: contain; scrollbar-color: var(--gold) #e8e5de; }
    .room-card { scroll-snap-align: start; }
}

@media (max-width: 900px) {
    .search-hero { padding-top: clamp(2.1rem, 6vw, 3.4rem); }
    /* P2.52 — font-size override removed here: the base rule's single
       fluid clamp now covers this range too, avoiding the discontinuity
       a second breakpoint-specific clamp previously introduced. */
    .search-form { grid-template-columns: 1fr 1fr; }
    .search-form label:first-child { grid-column: 1 / -1; }
    .search-form button { min-height: 56px; }
    .stay-picker-form.search-form { grid-template-columns: 1fr 1fr; }
    .property-hero { grid-template-columns: minmax(0, 1fr); padding-top: 2.3rem; }
    .hero-copy h1 { font-size: clamp(1.9rem, 5vw, 2.6rem); }
    /* Photography-first on mobile/tablet: the image is decorative relative
       to the copy (a photo, not sequential content), so reordering it
       visually ahead of the text via `order` — without touching DOM/reading
       order — is the low-risk option per the brief's own preference for
       CSS-only presentation changes over structural duplication. */
    /* P2.53 final acceptance verification — was aspect-ratio 1.25 (0.8x
       width tall). At this breakpoint hero-copy and hero-media STACK
       (via `order: -1` above) instead of sitting side by side, so a
       taller ratio here is backwards: it adds height at exactly the
       widths where the image and text already cost vertical space
       twice over. Measured live at 900px width/900px viewport: the
       hero section alone was 989px tall — taller than the entire
       viewport, before any other content. Matches the exact defect
       class already fixed in the base desktop rule above (C3); this
       override was flagged then as unaudited and is fixed now with
       the same 16/10 ratio for consistency with every image site-wide. */
    .hero-media { order: -1; aspect-ratio: 16 / 10; border-radius: 20px; }
    .review-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
    .site-header { height: 64px; padding: 0 1.1rem; }
    .site-header span { display: none; }
    .search-hero { padding: 2.1rem 1rem 1.35rem; }
    /* P2.52 — only line-height tightens here now (a legitimate small-
       size refinement); font-size is governed entirely by the base
       rule's single fluid clamp, so no second breakpoint-specific size
       jump is introduced at this boundary either. */
    .search-hero h1 { line-height: 1.08; }
    .search-form { margin-top: 1.55rem; grid-template-columns: 1fr; }
    .search-form label:first-child { grid-column: auto; }
    .stay-picker-form.search-form { grid-template-columns: 1fr; }
    .results, .rooms-section, .review-section { padding: 3.4rem 1rem; }
    /* P2.52 — .results' own top padding narrowed to match the desktop
       change, same reasoning: reach inventory sooner. */
    .results { padding-top: 1.8rem; }
    .section-title { display: block; margin-bottom: 1.2rem; }
    .property-grid { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
    /* A single-column mobile card has room to wrap naturally without
       creating uneven neighbouring-card heights, so the desktop/tablet
       two-line clamp is lifted here — a genuine layout change, not a
       font-size one; size itself now comes from the base rule's single
       fluid clamp (see above), not a second fixed value here. */
    .card-body h3 { -webkit-line-clamp: unset; display: block; overflow: visible; }
    .card-rail { align-items: start; }
    .card-rail .card-cta { flex: 1 0 100%; }
    .property-hero { padding: 2rem 1rem 1rem; gap: 1.5rem; }
    .hero-copy h1 { font-size: clamp(1.7rem, 8vw, 2.2rem); line-height: 1.06; }
    .lead { font-size: 1.1rem; }
    /* P2.53 final acceptance verification — was aspect-ratio 1/1.08
       (near-square, taller than the tablet override even). Same
       stacked-layout reasoning as the 900px breakpoint above: fixed to
       16/10 for consistency and to stop compounding height at the
       narrowest widths, where hero+copy already stack vertically. */
    .hero-media { aspect-ratio: 16 / 10; border-radius: 18px; }
    .amenities { padding: 2.5rem 1rem; display: block; }
    .amenities > div { gap: .2rem 1rem; }
    .room-scroller { grid-auto-columns: minmax(270px, 86%); gap: .8rem; }
    .room-fallback { min-height: 210px; }
    .room-content { padding: 1.15rem; }
    .room-content h3 { font-size: 1.4rem; }
    .rate-option { flex-direction: column; align-items: stretch; gap: .5rem; }
    .rate-option-action { align-items: stretch; }
    .rate-option-action > strong { text-align: right; }
    .review-grid { grid-template-columns: minmax(0, 1fr); }
    .quiet-state { max-width: 145px; }
    .empty { padding: 2rem 1.2rem; }
}

/* P2.69 final commercial hierarchy: Room Explorer now sits immediately
   after the opening in actual DOM order (moved in property.blade.php,
   not CSS-reordered) — a flex/order reflow here would visually move
   Room Explorer up while leaving it later in the keyboard/screen-reader
   tab order, behind Highlights/Amenities/Getting There. Real DOM order
   keeps visual order and reading/tab order identical. */

.hero-reputation-row { margin-top: 1rem; display: flex; align-items: stretch; gap: .6rem; }
.external-reputation--hero, .hero-native-reputation { flex: 1 1 0; min-width: 0; margin: 0; padding: .7rem .8rem; border: 1px solid #d9ddd9; border-radius: 11px; background: #fff; }
.external-reputation--hero { min-height: 88px; }
.external-reputation--hero .external-reputation__eyebrow, .hero-native-reputation > span { display: block; margin: 0 0 .2rem; color: var(--navy); font-size: .61rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
.external-reputation--hero .external-reputation__score { display: inline; }
.external-reputation--hero .external-reputation__score strong { font-size: 1.2rem; }
.external-reputation--hero .external-reputation__count { display: block; margin: .1rem 0 0; font-size: .7rem; }
.external-reputation--hero .external-reputation__link, .external-reputation--hero .external-reputation__attribution { display: none; }
.hero-native-reputation { display: flex; flex-direction: column; justify-content: center; }
.hero-native-reputation strong { color: var(--navy); font-size: 1rem; }
.hero-native-reputation small { color: var(--muted); font-size: .7rem; }

@media (min-width: 901px) {
    .search-hero { padding-top: 1.65rem; }
    .search-hero h1 { font-size: clamp(1.7rem, 2.3vw, 2.25rem); max-width: 500px; }
    .search-form { margin-top: 1.35rem; }
    .property-hero { min-height: 520px; padding-block: 2rem; grid-template-columns: minmax(320px, .68fr) minmax(560px, 1.32fr); gap: clamp(2rem, 3vw, 3.25rem); }
    .property-gallery-preview { min-height: 430px; }
    .rooms-section { padding-bottom: clamp(2.5rem, 4vw, 4rem); }
    .highlights { padding-top: clamp(2.5rem, 4vw, 3.5rem); border-top: 1px solid var(--line); }
    .review-section { padding-block: clamp(2.5rem, 4vw, 4rem); display: grid; grid-template-columns: minmax(220px, .72fr) minmax(0, 2fr); column-gap: clamp(2rem, 4vw, 4rem); align-items: start; }
    .review-section > * { grid-column: 1; }
    .review-section > .review-grid { grid-column: 2; grid-row: 1 / span 8; }
    .review-section > .review-count-note { grid-column: 2; }
    /* The desktop review layout puts the summary in a narrow left rail
       beside the review cards, so two fixed columns rather than auto-fit. */
    .review-averages { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1rem; }
}

/* P2.69 final benchmark correction — landscape comparison rows.
   Measured against the live customer sites: Booking 815px row / 240px
   media, Agoda ~820/275, Expedia ~755/250, Trip ~865/235. The results
   column is therefore capped rather than stretched to the full 1440
   canvas — a 1240px-wide row would strand the price rail a long scan
   away from the photograph, and an uncapped column is also what made a
   single result look accidental. A capped column means one result and
   twenty results are composed identically and deliberately. */
@media (min-width: 601px) {
    /* Centred, not stretched: the section heading is capped to the same
       measure so the column reads as a deliberate composition rather than
       content stranded against the left edge of a wide canvas. */
    .property-grid, .results > .section-title { gap: 1.15rem; max-width: 1000px; margin-inline: auto; }
    .property-card { display: grid; grid-template-columns: minmax(190px, 260px) minmax(0, 1fr); }
    .card-media { height: 100%; min-height: 208px; aspect-ratio: auto; }
    .card-media img { height: 100%; }
    .media-fallback { min-height: 100%; }
    .card-body { padding: 1.15rem 1.25rem; display: flex; flex-direction: column; }
    /* No truncation of property identity on a comparison row: none of the
       four OTA comparison surfaces truncate a property name (Booking wraps
       to six lines rather than clip). The 2-line clamp stays on the narrow
       mobile card, where uneven card heights would otherwise show. */
    .card-body h3 { display: block; -webkit-line-clamp: none; overflow: visible; font-size: clamp(1.14rem, 1.3vw, 1.34rem); }
    /* 601-900px: two zones, with the commercial rail as a full-width
       footer beneath both — a rail confined to the text column alone left
       an empty band under the photograph. */
    .card-rail { grid-column: 1 / -1; border-top: 1px solid var(--line); margin: 0 1.25rem; padding: .9rem 0 1.1rem; display: flex; align-items: end; justify-content: space-between; gap: 1rem; }
    .card-rail .card-trust { margin: 0; }
    .card-rail .price, .card-rail .quiet-state { margin-left: auto; }
    .card-cta { margin: 0; flex: 0 0 auto; }
}

@media (min-width: 901px) {
    /* Three zones: media | identity | commercial rail. Scanning a column
       of rows, names line up on one vertical axis and prices on another —
       the mechanism that actually makes an OTA list comparable. Reputation
       pins to the top of the rail and price+CTA to the bottom, so those
       two axes hold their line regardless of how much identity content a
       given property has. */
    .property-card { grid-template-columns: 260px minmax(0, 1fr) minmax(206px, 224px); }
    .card-rail { grid-column: 3; grid-row: 1; margin: 0; padding: 1.15rem 1.2rem; border-top: 0; border-left: 1px solid var(--line); flex-direction: column; align-items: stretch; justify-content: flex-start; gap: .7rem; }
    .card-media, .card-body { grid-row: 1; }
    .card-rail .card-trust { margin-bottom: auto; }
    .card-rail .price, .card-rail .quiet-state { margin-left: 0; text-align: left; max-width: none; }
    .card-cta { width: 100%; }
}

@media (max-width: 900px) {
    .hero-reputation-row { max-width: 560px; }
}

@media (max-width: 600px) {
    .hero-reputation-row { margin-top: .8rem; }
    .external-reputation--hero, .hero-native-reputation { padding: .65rem; }
    .external-reputation--hero { min-height: 82px; }
    .property-hero { padding-bottom: 1.35rem; }
    .rooms-section { padding-top: 2.4rem; }
    .highlights { padding-top: 2.5rem; border-top: 1px solid var(--line); }
}

/* P2.69 customer discovery and property foundation. */
.property-card { box-shadow: 0 14px 36px #0e22390d; }
.card-body { display: flex; flex-direction: column; }
.card-trust { display: grid; gap: .08rem; }
.card-trust strong { color: var(--navy); font-size: 1.12rem; }
.price small { color: var(--muted); font-size: .68rem; }
.card-cta { margin-top: 1rem; min-height: 46px; padding: .7rem .9rem; border-radius: 10px; background: var(--navy); color: #fff !important; text-decoration: none; display: flex; align-items: center; justify-content: center; gap: .5rem; white-space: nowrap; font-family: var(--sans); font-weight: 700; font-size: .83rem; }
.card-cta:focus-visible, .gallery-link:focus-visible, .gallery-tile:focus-visible, .media-dialog button:focus-visible, .room-media button:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

.property-hero { align-items: stretch; grid-template-columns: minmax(300px, .72fr) minmax(520px, 1.28fr); }
.hero-copy { align-self: center; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem; margin-top: 1.3rem; }
.hero-actions .button { margin-top: 0; }
.gallery-link { border: 1px solid var(--navy); background: #fff; color: var(--navy); border-radius: 99px; min-height: 46px; padding: .7rem 1rem; font: inherit; font-size: .84rem; font-weight: var(--weight-eyebrow); cursor: pointer; }
.property-gallery-preview { position: relative; min-width: 0; display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; gap: .45rem; min-height: 390px; border-radius: 18px; overflow: hidden; background: #e9e5dc; }
.gallery-tile { border: 0; padding: 0; overflow: hidden; cursor: pointer; background: #e9e5dc; }
.gallery-tile--1 { grid-row: 1 / span 2; }
.property-gallery-preview--single { display: block; }
.property-gallery-preview--single .gallery-tile { width: 100%; height: 100%; display: block; }
.gallery-tile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .25s ease; }
.gallery-tile:hover img { transform: scale(1.02); }
.gallery-count { position: absolute; right: .8rem; bottom: .8rem; background: #fff; color: var(--ink); border-radius: 99px; padding: .45rem .75rem; font-size: .76rem; font-weight: var(--weight-eyebrow); box-shadow: 0 4px 16px #0e223929; }

.media-dialog { width: min(1100px, calc(100% - 2rem)); height: min(800px, calc(100% - 2rem)); max-width: none; max-height: none; padding: 0; border: 0; border-radius: 18px; background: #081a2d; color: #fff; }
.media-dialog::backdrop { background: #071523d9; }
.media-dialog-shell { height: 100%; display: grid; grid-template-rows: auto 1fr auto; }
.media-dialog-header { display: flex; align-items: center; justify-content: space-between; padding: .9rem 1.1rem; }
.media-dialog-header h2 { margin: 0; color: #fff; font-family: var(--sans); font-size: 1rem; }
.media-dialog-header button { width: 42px; height: 42px; border: 1px solid #ffffff66; border-radius: 50%; background: transparent; color: #fff; font-size: 1.4rem; cursor: pointer; }
.media-dialog-stage { position: relative; min-height: 0; display: grid; place-items: center; overflow: hidden; }
.media-dialog-stage figure { margin: 0; width: 100%; height: 100%; display: grid; grid-template-rows: 1fr auto; min-height: 0; }
.media-dialog-stage figure[hidden] { display: none; }
.media-dialog-stage img { width: 100%; height: 100%; min-height: 0; object-fit: contain; }
.media-dialog-stage figcaption { padding: .6rem 4.5rem 0; text-align: center; font-size: .8rem; color: #dce4eb; }
.gallery-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 46px; height: 46px; border: 1px solid #ffffff55; border-radius: 50%; background: #071523b8; color: #fff; font-size: 1.8rem; cursor: pointer; }
.gallery-nav--prev { left: 1rem; }
.gallery-nav--next { right: 1rem; }
.gallery-position { margin: 0; padding: .8rem; text-align: center; color: #dce4eb; font-size: .8rem; }

.external-reputation--card { margin: .85rem 0 0; padding: .75rem 0 0; border-top: 1px solid var(--line); max-width: none; min-height: 1rem; }
.external-reputation--card .external-reputation__eyebrow { color: var(--navy); }
.external-reputation--card .external-reputation__score { display: inline; }
.external-reputation--card .external-reputation__link, .external-reputation--card .external-reputation__attribution { display: none; }
.review-count-note { margin: 1rem 0 0; color: var(--muted); font-size: .82rem; }

.getting-there { margin: 2rem clamp(1.2rem, 7vw, 7rem) 0; padding: 1.15rem 1.3rem; border: 1px solid var(--line); border-radius: 14px; display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
/* P2.71 surgical correction — no font-weight was declared here, so this
   fell through to the browser's default bold (~700) for h2, the one
   section heading on this page never given the explicit 500 every
   sibling heading already has (.rooms-section h2, .amenities h2,
   .transfer-selector h2, .highlights h2). */
.getting-there h2 { margin: .1rem 0 0; font-family: var(--sans); font-size: 1rem; font-weight: 500; }
.getting-there p:last-child { margin: 0; max-width: 540px; color: var(--muted); font-size: .84rem; }

.room-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: #e9e5dc; }
.room-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.room-media img[hidden] { display: none; }
.room-media button { position: absolute; top: 50%; transform: translateY(-50%); width: 36px; height: 36px; border: 0; border-radius: 50%; background: #fff; color: var(--navy); font-size: 1.25rem; cursor: pointer; box-shadow: 0 3px 12px #0e22392e; }
.room-media [data-room-prev] { left: .6rem; }
.room-media [data-room-next] { right: .6rem; }
.room-media > span { position: absolute; right: .6rem; bottom: .6rem; padding: .3rem .55rem; background: #fff; border-radius: 99px; font-size: .7rem; }

@media (max-width: 900px) {
    .property-hero { grid-template-columns: 1fr; }
    .property-gallery-preview { order: -1; min-height: 0; aspect-ratio: 16 / 9; }
}

@media (max-width: 600px) {
    .property-gallery-preview { grid-template-columns: 1fr; grid-template-rows: 1fr; aspect-ratio: 4 / 3; border-radius: 14px; }
    .gallery-tile { display: none; }
    .gallery-tile--1 { display: block; grid-row: auto; }
    .gallery-count { right: .55rem; bottom: .55rem; }
    .hero-actions { align-items: stretch; }
    .hero-actions .button, .gallery-link { flex: 1 1 100%; text-align: center; }
    .getting-there { margin: 1.5rem 1rem 0; display: block; }
    .getting-there p:last-child { margin-top: .5rem; }
    .card-rail { align-items: end; }
    .media-dialog { width: 100%; height: 100%; border-radius: 0; }
    .media-dialog-stage figcaption { padding-inline: 3.5rem; }
}

/* =====================================================================
   P2.51B — search instrument: custom date-range/guest controls,
   progressive-enhancement trigger fields, desktop popovers and the
   shared mobile search sheet. `.search-form`'s own base rules (grid,
   borders, radius, shadow) are untouched and still apply — this section
   only adds the enhanced-state field styling and the popover/sheet
   layer, so a no-JS visit still renders the original, fully-functional
   native form exactly as before.
   ===================================================================== */

.search-form-enhanced { grid-template-columns: 2fr 1.3fr 1.1fr auto; }
.stay-picker-form.search-form-enhanced { grid-template-columns: 1.3fr 1.1fr auto; }

.search-field { min-width: 0; background: #fff; display: flex; flex-direction: column; }
.search-trigger-field { padding: 0; }
.search-field-label { padding: .65rem 1rem 0; font-size: .66rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--muted); }
/* `.search-form button` (the existing navy CTA style, shared with the
   real submit button) matches any <button> inside the form, including
   these trigger buttons — `.search-form button.search-trigger` matches
   the exact same elements at strictly higher specificity, so this
   reliably wins regardless of stylesheet order. */
.search-form button.search-trigger {
    flex: 1; min-width: 0; border: 0; background: transparent; text-align: left; cursor: pointer;
    padding: .15rem 1rem .65rem; font: inherit; font-weight: 400; color: var(--ink); display: flex; flex-direction: column; gap: .05rem;
}
.search-trigger strong { font-weight: 650; font-size: .94rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-trigger span { color: var(--muted); font-size: .78rem; }
.search-form button.search-trigger:hover, .search-form button.search-trigger:focus-visible { background: var(--warm); outline: none; }
.search-form button.search-trigger:focus-visible { box-shadow: inset 0 0 0 3px #d4af3780; }

/* One truthful, restrained reassurance line near the search action —
   P2.51B §G. Deliberately plain text, not a badge/icon row: "one
   truthful signal is better than three generic badges." */
.search-trust { margin: .85rem 0 0; color: var(--muted); font-size: .82rem; }

/* P2.51C §C — destination-discovery typeahead. `.destination-suggest`
   (desktop) is body-appended and positioned in JS from the input's own
   bounding rect, same convention as `.search-popover` below and for the
   same reason (never a descendant of `.search-form`).
   `.destination-suggest-inline` (the mobile sheet's own destination
   input) instead sits in normal document flow directly under that
   input — see mountDestinationAutocomplete's comment in
   search-controls.js for why a floating panel doesn't work inside an
   open <dialog>. */
.destination-suggest {
    position: absolute; z-index: 40; background: #fff; border: 1px solid var(--line);
    border-radius: 14px; box-shadow: 0 20px 50px #0e223924; padding: .4rem;
    max-height: 320px; overflow-y: auto;
}
.destination-suggest-inline { position: static; box-shadow: none; margin-top: .5rem; max-height: none; }
.destination-suggest-status { margin: 0; padding: .6rem .7rem; color: var(--muted); font-size: .85rem; }
.destination-suggest-option {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; width: 100%;
    border: 0; background: transparent; border-radius: 10px; padding: .6rem .7rem;
    font: inherit; font-size: .9rem; color: var(--ink); text-align: left; cursor: pointer;
}
.destination-suggest-option:hover, .destination-suggest-option.is-active { background: var(--warm); }
.destination-suggest-label { font-weight: 600; }
.destination-suggest-sub { flex: 0 0 auto; color: var(--muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }

/* Appended directly to <body> and positioned in JS from the trigger's
   own bounding rect (search-controls.js) — deliberately never a
   descendant of `.search-form`, so none of that form's own button/input
   styling (meant only for the real destination field and submit button)
   can ever apply here. */
.search-popover {
    position: absolute; z-index: 40; background: #fff; border: 1px solid var(--line);
    border-radius: 16px; box-shadow: 0 20px 50px #0e223924; padding: 1.1rem; min-width: 320px;
}
.search-popover-guests { min-width: 300px; }
.search-popover-footer { display: flex; align-items: center; justify-content: space-between; margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.search-popover-footer-end { justify-content: flex-end; }
.search-popover-link { border: 0; background: transparent; color: var(--ink); font: inherit; font-size: .85rem; font-weight: 650; text-decoration: underline; cursor: pointer; padding: .4rem .2rem; }
.search-popover-done {
    border: 0; background: var(--navy); color: #fff; font: inherit; font-weight: 700; font-size: .85rem;
    padding: .6rem 1.2rem; border-radius: 99px; cursor: pointer;
}
.search-popover-done:focus-visible, .search-popover-link:focus-visible { outline: 3px solid #d4af3780; outline-offset: 1px; }

/* ---- Calendar ---- */
.cal-months { display: flex; gap: 1.5rem; }
.cal-month-panel { min-width: 0; }
.cal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.cal-month { margin: 0; font-family: var(--sans); font-weight: 650; font-size: .88rem; color: var(--navy); }
.cal-nav {
    width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--line); background: #fff;
    color: var(--navy); font-size: 1rem; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.cal-nav:hover { background: var(--warm); }
.cal-nav:focus-visible { outline: 3px solid #d4af3780; outline-offset: 1px; }
.cal-grid { border-collapse: collapse; width: 100%; }
.cal-grid th { font-size: .66rem; font-weight: 700; color: var(--muted); padding: .3rem 0; }
.cal-grid td { padding: 1px; text-align: center; }
.cal-day {
    width: 34px; height: 34px; border: 0; border-radius: 50%; background: transparent; color: var(--ink);
    font: inherit; font-size: .82rem; cursor: pointer;
}
.cal-day:hover:not(:disabled) { background: var(--warm); }
.cal-day:focus-visible { outline: 3px solid #d4af3780; outline-offset: 1px; }
.cal-day:disabled { color: #c7ccd2; cursor: default; }
.cal-day.is-in-range { background: var(--warm); border-radius: 0; }
.cal-day.is-selected { background: var(--navy); color: #fff; }
.cal-day.is-range-start { border-radius: 50% 0 0 50%; }
.cal-day.is-range-end { border-radius: 0 50% 50% 0; }
.cal-day.is-selected.is-range-start, .cal-day.is-selected.is-range-end { border-radius: 50%; }

/* ---- Guest stepper ---- */
.stepper-row { display: flex; align-items: center; justify-content: space-between; padding: .6rem 0; border-bottom: 1px solid var(--line); }
.stepper-row:last-child { border-bottom: 0; }
.stepper-label p { margin: 0; font-size: .9rem; color: var(--ink); }
.stepper-hint { color: var(--muted); font-size: .78rem; }
.stepper-controls { display: flex; align-items: center; gap: .7rem; }
.stepper-btn {
    width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: #fff;
    color: var(--navy); font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.stepper-btn:hover:not(:disabled) { border-color: var(--navy); }
.stepper-btn:focus-visible { outline: 3px solid #d4af3780; outline-offset: 1px; }
.stepper-btn:disabled { color: #c7ccd2; border-color: var(--line); cursor: default; }
.stepper-value { min-width: 1.4rem; text-align: center; font-weight: 650; }

/* ---- Mobile search sheet ---- */
.search-sheet { border: 0; padding: 0; margin: 0; width: min(480px, 100vw); max-width: 100vw; height: 100%; max-height: 100vh; border-radius: 0; }
.search-sheet::backdrop { background: rgba(14, 34, 57, .45); }
.search-sheet-inner { display: flex; flex-direction: column; height: 100%; }
.search-sheet-header { display: flex; align-items: center; justify-content: space-between; padding: 1.1rem 1.2rem; border-bottom: 1px solid var(--line); }
.search-sheet-header h2 { margin: 0; font-size: 1.2rem; }
.search-sheet-close { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line); background: #fff; font-size: 1.2rem; line-height: 1; cursor: pointer; }
.search-sheet-close:focus-visible { outline: 3px solid #d4af3780; outline-offset: 1px; }
.search-sheet-body { flex: 1; overflow-y: auto; padding: .5rem 1.2rem 1.2rem; }
.sheet-section { border-bottom: 1px solid var(--line); }
.sheet-section-header { width: 100%; border: 0; background: transparent; text-align: left; padding: 1rem 0; cursor: pointer; display: flex; flex-direction: column; gap: .15rem; font: inherit; }
.sheet-section-label { font-size: .68rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--muted); }
.sheet-section-summary { font-size: 1rem; font-weight: 600; color: var(--navy); }
.sheet-section-header:focus-visible { outline: 3px solid #d4af3780; outline-offset: 2px; }
.sheet-section.is-active .sheet-section-header { cursor: default; }
.sheet-section-body { padding: 0 0 1.1rem; }
.sheet-destination-label { display: block; font-size: .68rem; font-weight: var(--weight-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--muted); }
.sheet-destination-input {
    display: block; width: 100%; margin-top: .5rem; border: 1px solid var(--line); border-radius: 10px;
    padding: .75rem .9rem; font: inherit; font-size: 1rem; color: var(--ink);
}
.sheet-destination-input:focus-visible { outline: 3px solid var(--navy); outline-offset: 1px; }
.search-sheet .cal-months { flex-direction: column; }
.search-sheet .cal-month-panel-second { display: none; }
.search-sheet .cal-day { width: auto; aspect-ratio: 1; }
.search-sheet-footer { padding: 1rem 1.2rem; border-top: 1px solid var(--line); }
/* Deliberately self-contained (never reuses `.checkout-primary`, which
   lives in catalogue-checkout.css — a stylesheet this search sheet must
   never depend on, since the search page itself never loads it). */
.search-sheet-search {
    width: 100%; min-height: 50px; border-radius: 99px; border: 0;
    background: var(--navy); color: #fff; font: inherit; font-weight: 700; font-size: .95rem; cursor: pointer;
}
.search-sheet-search:hover { background: #17334e; }
.search-sheet-search:focus-visible { outline: 3px solid #d4af3780; outline-offset: 2px; }

@media (max-width: 900px) {
    .search-popover { min-width: 280px; }
    .cal-months { gap: 1rem; }
}

@media (max-width: 600px) {
    .search-form-enhanced { grid-template-columns: 1fr; }
    .stay-picker-form.search-form-enhanced { grid-template-columns: 1fr; }
    /* Below the breakpoint search-controls.js itself treats as "mobile"
       (opens the shared sheet instead of a floating popover), the
       trigger fields still render inline so the page never shows a
       popover that would have nowhere sensible to anchor. */
    .cal-months { flex-direction: column; }
    .cal-month-panel-second { display: none; }
}

/* CLOSE-4B.2 — the four static legal pages (/terms, /privacy, /cookies,
   /cancellation-policy). Reuses the same tokens/typography as the rest
   of the customer site (var(--navy)/var(--muted)/var(--line)/var(--serif)
   /var(--sans)) rather than a competing design system — deliberately
   plain: a readable content column, a restrained metadata line, no
   editorial hero, no cards around paragraphs, no gold accents. */
.legal-page-header { padding: clamp(2rem, 5vw, 3.5rem) clamp(1.2rem, 5vw, 5rem) 0; max-width: 720px; margin: 0 auto; }
.legal-page-header h1 { font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.35rem); font-weight: 500; letter-spacing: -.01em; margin: 0 0 .5rem; }
.legal-meta { color: var(--muted); font-size: .84rem; margin: 0; }
.legal-content { max-width: 720px; margin: 0 auto; padding: 1.5rem clamp(1.2rem, 5vw, 5rem) clamp(2.5rem, 6vw, 4rem); font-size: .96rem; line-height: 1.7; }
.legal-content h2 { font-family: var(--sans); font-size: 1.1rem; font-weight: 650; color: var(--navy); margin: 2.1rem 0 .6rem; }
.legal-content h2:first-child { margin-top: 0; }
.legal-content p { margin: 0 0 1rem; }
.legal-content ul, .legal-content ol { margin: 0 0 1rem; padding-left: 1.3rem; }
.legal-content li { margin: 0 0 .4rem; }
.legal-content a { color: var(--navy); text-decoration: underline; text-underline-offset: 2px; }
.legal-content a:hover { color: var(--gold); }
.legal-page-nav { max-width: 720px; margin: 0 auto; padding: 0 clamp(1.2rem, 5vw, 5rem); display: flex; flex-wrap: wrap; gap: .4rem 1rem; font-size: .84rem; }
.legal-page-nav a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.legal-page-nav a[aria-current="page"] { color: var(--navy); font-weight: 650; text-decoration: none; }

/* Compact "Company details" disclosure — satisfies SI 2015/17's
   website-disclosure requirement (registered office address included)
   without permanently enlarging the footer. A native <details> element:
   no JS, keyboard-operable, and announced correctly by screen readers
   without any custom ARIA. */
.company-details { max-width: 720px; margin: 2rem auto 0; padding: 0 clamp(1.2rem, 5vw, 5rem); }
.company-details summary { cursor: pointer; color: var(--muted); font-size: .84rem; text-decoration: underline; text-underline-offset: 2px; }
.company-details-body { margin: .6rem 0 0; color: var(--muted); font-size: .84rem; line-height: 1.6; }
.footer-company-details summary { color: inherit; }
