/* =============================================================
   Soho Boutique Hotel, Mysore — design system
   Palette sampled directly from the hotel logo:
     charcoal #302B2B (wordmark), yellow #FCE430 (monogram "S"), greys.
   Type: Cormorant Garamond (display serif, echoes the logo wordmark)
         + Jost (geometric sans, matches the letter-spaced "BOUTIQUE HOTEL").
   ============================================================= */

:root {
  /* ---- brand ---- */
  --ink:          #2b2626;   /* logo charcoal */
  --ink-soft:     #4a4342;
  --muted:        #6f6663;
  --line:         #e6e1db;
  --paper:        #ffffff;
  --cream:        #faf8f4;   /* page ground */
  --sand:         #f2ede5;   /* alternating band */

  /* Yellow is the logo accent. #FCE430 on white is only 1.4:1, so it is used
     for FILLS with dark text on top — never for text on a light ground.
     --gold-deep is the accessible text/link tone (5.6:1 on cream). */
  --yellow:       #fce430;
  --yellow-warm:  #f5d312;
  --gold-deep:    #7a5c00;
  --gold-line:    #d9bb3a;

  --ok:           #2e7d32;
  --err:          #b3261e;

  /* ---- type ---- */
  --font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-body:    "Jost", "Helvetica Neue", Arial, sans-serif;

  /* ---- layout ---- */
  --maxw:      1240px;
  --gutter:    clamp(1.15rem, 4vw, 3.5rem);
  /* Single source of truth for the space between cards. Every card grid
     must use this — do not re-declare a local clamp. */
  --card-gap:  clamp(1.1rem, 2.2vw, 1.9rem);
  /* Vertical rhythm between sections. Reduced ~15% from the original
     clamp(3.5rem, 8vw, 7rem); rounded to 3rem/6rem so both ends land on
     the 8px grid the rest of the spacing scale uses. Single source of
     truth — do not re-declare a local padding-block on .section. */
  --section-pad: clamp(3rem, 6.8vw, 6rem);
  --header-h:  86px;
  --radius:    2px;          /* the logo is hard-edged; keep corners crisp */
  --shadow-sm: 0 1px 3px rgba(43,38,38,.07);
  --shadow-md: 0 6px 26px rgba(43,38,38,.10);
  --shadow-lg: 0 18px 60px rgba(43,38,38,.16);
  --ease:      cubic-bezier(.22,.61,.36,1);
}

@media (max-width: 880px) { :root { --header-h: 70px; } }

/* ============================ reset ============================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 1rem;               /* 16px floor */
  font-weight: 400;
  line-height: 1.7;
  overflow-x: hidden;            /* guards off-canvas drawer at zoom */
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
iframe { max-width: 100%; border: 0; }
a { color: var(--gold-deep); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { margin: 0; padding: 0; }

/* Visible focus on every focusable element (never suppressed) */
:focus-visible {
  outline: 3px solid var(--gold-deep);
  outline-offset: 2px;
  border-radius: var(--radius);
}

::selection { background: var(--yellow); color: var(--ink); }

/* Branded scrollbar */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--sand); }
::-webkit-scrollbar-thumb { background: #c9bfae; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-soft); }
html { scrollbar-width: thin; scrollbar-color: #c9bfae var(--sand); }

/* ============================ type ============================ */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 500;
  line-height: 1.15;
  margin: 0 0 .6em;
  letter-spacing: -0.01em;
}
h1 { font-size: clamp(2.4rem, 5.6vw, 4.4rem); }
h2 { font-size: clamp(1.9rem, 3.9vw, 3.25rem); }
h3 { font-size: clamp(1.3rem, 2.1vw, 1.75rem); }
h4 { font-size: 1.15rem; }
p  { margin: 0 0 1.1rem; }
p:last-child { margin-bottom: 0; }

.eyebrow {
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--font-body);
  font-size: .72rem; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: 1rem;
}
.eyebrow::before {
  content: ""; width: 34px; height: 1px;
  background: var(--gold-line); flex: none;
}
.eyebrow--center::after {
  content: ""; width: 34px; height: 1px;
  background: var(--gold-line); flex: none;
}

.lead {
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  color: var(--ink-soft);
  max-width: 62ch;
}

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--section-pad); }
.section--tint { background: var(--sand); }
.section--ink  { background: var(--ink); color: #d8d2cc; }
.section--ink h2, .section--ink h3 { color: #fff; }
.section--ink .eyebrow { color: var(--yellow); }
/* The site-wide WCAG 1.4.1 rule already underlines links inside a paragraph, so
   a border-bottom here drew a second line under the phone number. Colour and
   brightness carry the hover instead. */
.section--ink p a { color: var(--yellow); }
.section--ink p a:hover { color: #fff; }
.section--ink .eyebrow::before, .section--ink .eyebrow--center::after { background: rgba(252,228,48,.5); }
/* Two same-tint sections in a row stack their padding into one oversized gap.
   Drop the first one's tail so the pair is separated by a single --section-pad. */
.section--tight-b { padding-bottom: 0; }
/* Softer variant: keeps a seam but drops most of the tail. Used on the
   meetings capacities + inclusions pair, where a full pad read as a void. */
.section--pad-b-sm { padding-bottom: calc(var(--section-pad) * .35); }

/* The location page is seven short reference blocks in a row — address, routes,
   landmarks, shops, map, CTA, cross-links. At the full pad each seam stacked
   95px + 95px, which reads as dead space rather than rhythm on blocks this
   short. Same proportions, tighter beat; scoped so no other page shifts. */
.page-location { --section-pad: clamp(2.25rem, 4.4vw, 4rem); }

.section-head { max-width: 60ch; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head.center .eyebrow { justify-content: center; }
/* 60ch is a reading measure for the paragraph, but a display heading set at
   ~52px needs more room than that and breaks onto a second line. Widen the
   block for those, and hold the lead text at its readable width instead. */
.section-head--wide { max-width: min(100%, 46rem); }
.section-head--wide .lead { max-width: 60ch; margin-inline: auto; }

/* Wider still, for display headings that need ~750px on one line. Measured:
   the longest of them wants 751px, so 52rem (832px) clears them all. */
.section-head--xwide { max-width: min(100%, 60rem); }
.section-head--xwide .lead { max-width: 60ch; margin-inline: auto; }

/* A heading inside a split column cannot be widened — the column is half the
   row. These sit one step down in size so they still hold a single line at
   543px, where the full h2 size would need up to 746px. */
/* Max 2.2rem, not 2.25: past ~1400px the wrap stops widening but a vw-based
   size keeps growing, so the cap is what has to hold the line. */
.h2--fit { font-size: clamp(1.5rem, 2.8vw, 2.1rem); }

/* Heading with the section's overview link on the same line. Below a slider the
   link reads as another slide; beside the heading it reads as belonging to the
   section. Left-aligned, since a centred heading has nowhere to put it. */
.section-head--row {
  max-width: none; text-align: left;
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: .9rem 2rem;
}
/* 52rem, not 46: a display h2 of ~38 characters needs ~800px at this size and
   the row has room to spare beside the button. */
.section-head--row .section-head__text { max-width: 52rem; }
.section-head--row h2 { margin-bottom: 0; }
.section-head--row .btn { flex: none; }
/* On a phone the row stacks and the heading gets the full column, but the h2
   clamp floor of 1.9rem still wants 456px in a 450px column. A small step down
   below 560px keeps these on one line; above it the full size already fits. */
@media (max-width: 560px) {
  .section-head--row h2 { font-size: 1.75rem; }
}

/* An H1 introducing a two-column block sits above it at full width, where the
   display size has room for one line — the 60ch reading measure on
   .section-head would break it in two. */
.section-head--h1 { max-width: none; margin-bottom: clamp(1.5rem, 3vw, 2.4rem); }
.section-head--h1 h1 { margin-bottom: 0; }

/* Positioning line above the introduction. Display italic so it reads as a
   voice rather than as another heading competing with the H1 above it. */
.tagline {
  font-family: var(--font-display); font-style: italic;
  font-size: clamp(1.25rem, 2vw, 1.6rem); line-height: 1.3;
  color: var(--gold-deep); margin: 0 0 .85rem;
}


/* Homepage dining panel. The copy beside the photograph is short, so centring
   left it floating with ~107px of dead space above and below; aligning the tops
   and cropping the photograph wider closes most of the gap. The tabs follow the
   heading's new left alignment. */
.dine-home .dtabs { justify-content: flex-start; }
.dine-home .dpanel .split { align-items: start; }
.dine-home .dslide img { aspect-ratio: 16/10; }

/* ============================ buttons ============================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 48px; padding: .85rem 1.9rem;
  font-family: var(--font-body); font-size: .8rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  border-radius: var(--radius); border: 1px solid transparent;
  cursor: pointer; text-align: center;
  transition: background .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), transform .3s var(--ease);
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }

/* Yellow fill + charcoal text = 12.6:1. The brand's primary action. */
.btn--primary { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }
.btn--primary:hover { background: var(--yellow-warm); border-color: var(--yellow-warm); }

.btn--dark { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn--dark:hover { background: #171313; }

.btn--outline { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--outline:hover { background: var(--ink); color: #fff; }

.btn--ghost { background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.65); backdrop-filter: blur(4px); }
.btn--ghost:hover { background: #fff; color: var(--ink); border-color: #fff; }

.btn--lg { min-height: 54px; padding: 1rem 2.4rem; font-size: .85rem; }
.btn--sm { min-height: 44px; padding: .6rem 1.2rem; font-size: .72rem; }

.text-link {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 44px;
  font-size: .8rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold-deep);
  border-bottom: 1px solid var(--gold-line);
  transition: gap .3s var(--ease);
}
.text-link:hover { text-decoration: none; gap: .85rem; border-bottom-color: var(--ink); color: var(--ink); }

/* ============================ skip link ============================ */
.skip-link {
  position: absolute; left: 50%; top: -200px; transform: translateX(-50%);
  z-index: 200; background: var(--ink); color: #fff;
  padding: .9rem 1.6rem; font-size: .85rem; letter-spacing: .1em;
  text-transform: uppercase; border-radius: 0 0 var(--radius) var(--radius);
  transition: top .25s var(--ease);
}
.skip-link:focus { top: 0; text-decoration: none; }

/* ============================ header ============================ */
/* Transparent over the hero (gradient scrim keeps the logo and links legible
   against any photograph), solid once the page scrolls. Pages with no hero
   opt out with .header--solid so their nav is never invisible on white. */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: linear-gradient(180deg, rgba(20,17,17,.78) 0%, rgba(20,17,17,.45) 60%, rgba(20,17,17,0) 100%);
  transition: background .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}
.header.is-scrolled,
.header--solid {
  background: var(--paper);
  box-shadow: var(--shadow-sm);
}

/* Over the hero the nav is white; on the solid state it returns to ink. */
.header .nav__link { color: #fff; }

.header .hamburger span { background: #fff; }
.header.is-scrolled .nav__link:not(.nav--drawer .nav__link),
.header--solid .nav__link:not(.nav--drawer .nav__link) { color: var(--ink); }

.header.is-scrolled .hamburger span,
.header--solid .hamburger span { background: var(--ink); }
.header.is-scrolled .nav__link[aria-current="page"]:not(.nav--drawer .nav__link),
.header--solid .nav__link[aria-current="page"]:not(.nav--drawer .nav__link) { color: var(--gold-deep); }
.header .nav__link[aria-current="page"] { color: var(--yellow); }

/* The supplied logo PNG has an OPAQUE white background (verified: 0% alpha,
   79.8% pure white) and Cloudinary background-removal is not enabled on this
   account. mix-blend-mode:screen with invert() drops the white to fully
   transparent and renders the artwork white — correct over the hero photo.
   On the solid header the logo returns to its natural dark form. */
/* One transparent PNG generated from the supplied logo (the original has an
   opaque white background and Cloudinary bg-removal is not enabled on this
   account). The logo keeps its REAL brand colours in both header states; a
   soft shadow carries it over the hero video without recolouring it. */
.header .header__logo img {
  filter: drop-shadow(0 0 3px rgba(255,255,255,.95)) drop-shadow(0 0 9px rgba(255,255,255,.85))
          drop-shadow(0 0 22px rgba(255,255,255,.6));
  transition: filter .35s var(--ease);
}
.header.is-scrolled .header__logo img,
.header--solid .header__logo img { filter: none; }

/* Inside the open drawer the nav sits on white — force ink regardless of state */
/* Dropdown sits on a dark ground now — links are set in the .nav--drawer
   block below; no ink override here. */
.header__inner {
  width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding-inline: var(--gutter);
  min-height: var(--header-h);
  /* flex-start + the two auto margins below, NOT space-between: the hamburger
     is its own child now, and space-between would spread it into the middle of
     the row. The auto margins split the slack the same way space-between did
     (brand | slack | nav+toggle | slack | Book Now) while keeping the toggle
     one nav-gap after the last inline link. */
  display: flex; align-items: center; justify-content: flex-start;
  gap: 1.5rem;
  /* NO flex-wrap. The priority-plus JS moves items into the overflow drawer
     before the row can run out of space, so wrapping must never be an option —
     with it enabled the row silently wrapped instead of collapsing, and every
     width-based measurement then read the ALREADY-WRAPPED geometry. */
  flex-wrap: nowrap;
}
.header__inner > .nav--inline { min-width: 0; overflow: hidden; margin-left: auto; }
/* The toggle rides directly after the inline row, one nav gap away — it must
   never drift over to the Book Now button. */
.header__inner > .hamburger { flex: none; }
/* When every link has moved into the drawer the inline nav is empty; it must
   not keep claiming flex gap, or the row wraps at very narrow widths. */
.header__inner > .nav--inline:empty,
.header__inner > .nav--inline.is-empty { display: none; }
.header__brand { display: flex; align-items: center; gap: .85rem; flex: none; }
.header__logo { flex: none; display: inline-flex; align-items: center; line-height: 0; }
.header__logo img { height: 74px; width: auto; flex: none; transition: height .3s var(--ease); }
.header.is-scrolled .header__logo img { height: 63px; }
@media (max-width: 880px) { .header__logo img { height: 59px; } }

.nav { display: flex; align-items: center; }
.nav__list { display: flex; align-items: center; gap: 1.6rem; list-style: none; }
.nav__link {
  display: inline-flex; align-items: center;
  font-size: .78rem; font-weight: 500; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink); padding: .4rem 0; position: relative;
}
/* Sits INSIDE the link box. .nav--inline is overflow:hidden (it must clip
   horizontally while JS measures the row), and a negative `bottom` put the
   underline outside that clip box — the yellow hover slide never showed. */
.nav__link::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
  height: 2px; background: var(--yellow-warm);
  transition: right .3s var(--ease);
}
.nav__link:hover { text-decoration: none; }
.nav__link:hover::after, .nav__link[aria-current="page"]::after { right: 0; }
.nav__link[aria-current="page"] { color: var(--gold-deep); }

.header__cta { display: flex; align-items: center; gap: .7rem; flex: none; }
.header__inner > .header__cta { margin-left: auto; }

.hamburger[hidden] { display: none; }
.hamburger {
  width: 46px; height: 46px; padding: 0; box-sizing: border-box;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  border: 0; background: none;
}
.hamburger span { display: block; width: 20px; height: 2px; background: var(--ink); transition: transform .3s var(--ease), opacity .2s; }
/* The reference keeps three bars while its dropdown is open — no X morph. The
   button still toggles, and aria-expanded carries the state for screen readers.
   Below 700px it becomes a sheet, where the X is the expected affordance. */
@media (max-width: 700px) {
  .hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

.nav__close { display: none; width: 46px; height: 46px; align-items: center; justify-content: center; align-self: flex-end; }

/* --- collapsed nav (JS adds .is-compact when the row cannot fit) --- */

.nav--drawer[hidden] { display: none; }
/* Compact dropdown anchored under the hamburger — NOT a full-height drawer.
   Sized to its content, dark ground, right-aligned links, matching the
   reference build. Becomes a full sheet only on small screens, where a
   content-sized popover would be unusable. */
.nav--drawer {
  /* Anchored to the HAMBURGER and opening leftward — the panel's right edge
     lines up with the button, so it grows away from the Book Now CTA instead
     of covering it. `right` is set from JS (--drawer-right) because the
     hamburger's distance from the viewport edge changes as the nav collapses. */
  position: absolute; top: 100%; right: var(--drawer-right, var(--gutter));
  inset-inline-start: auto;
  width: max-content; min-width: 210px; max-width: min(88vw, 320px);
  background: #3a3330; box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; align-items: stretch;
  padding: .35rem 0;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
  max-height: min(70vh, 520px); overflow-y: auto; z-index: 120;
}
.nav--drawer.is-open { opacity: 1; visibility: visible; transform: translateY(0); }
.nav--drawer .nav__close { display: none; }          /* click-away/Esc closes it */
.nav--drawer .nav__list { flex-direction: column; align-items: stretch; gap: 0; width: 100%; }
.nav--drawer .nav__list > li { border-bottom: 0; }
.nav--drawer .nav__link {
  /* Left-aligned white text (was right-aligned gold). White on #3a3330 is
     11.6:1 — well clear of AA. */
  min-height: 44px; width: 100%; justify-content: flex-start;
  padding: .5rem 1.15rem; color: #fff; font-size: .74rem;
}
.nav--drawer .nav__link:hover,
.nav--drawer .nav__link:focus-visible { background: rgba(255,255,255,.1); color: #fff; }
.nav--drawer .nav__link::after { display: none; }
.nav--drawer .nav--drawer__foot { display: none; }   /* contact lives in the footer */

/* Small screens: a content-sized popover is too cramped, so use a sheet. */
@media (max-width: 700px) {
  .nav--drawer {
    /* The hamburger sits on the LEFT at this breakpoint, so the sheet opens from
       the left too — a panel arriving on the opposite side from its trigger
       reads as unrelated to the button that opened it. */
    position: fixed; top: var(--header-h); left: 0; right: auto;
    width: min(84vw, 320px); max-width: none; max-height: calc(100dvh - var(--header-h));
    padding: .4rem 0 1.2rem;
  }
  .nav--drawer .nav--drawer__foot {
    display: flex; flex-direction: column; gap: .5rem;
    padding: 1rem 1.15rem 0; margin-top: .6rem;
    border-top: 1px solid rgba(255,255,255,.14);
  }
  .nav--drawer .nav--drawer__foot a { color: var(--yellow-warm); font-size: .82rem;
    display: inline-flex; align-items: center; gap: .55rem; min-height: 44px; }
}
.header.is-compact .nav__link::after { display: none; }

.nav-backdrop {
  position: fixed; inset: 0; background: rgba(43,38,38,.5);
  opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility .3s; z-index: 110;
}
.nav-backdrop.is-visible { opacity: 1; visibility: visible; }

/* ============================ hero ============================ */
.hero {
  position: relative; min-height: 92svh;
  display: flex; align-items: flex-end;
  overflow: hidden;
}
.hero--inner { min-height: 62vh; }
.hero__media { position: absolute; inset: 0; z-index: -2; }
.hero__media img,
.hero__media video {
  width: 100%; height: 100%; object-fit: cover;
  position: absolute; inset: 0;
  opacity: 0;
  /* opacity alone is not enough now that one slide is a <video>: an opacity:0
     video still holds a compositing layer, and inside this negative z-index
     layer that layer suppressed the photographs entirely — the hero went blank
     on every slide but the film (verified: deleting the <video> made the
     photograph appear). visibility takes the off-screen slides out of the
     compositing tree for real, and is held back until the crossfade has
     finished so the outgoing slide is still there to fade. */
  visibility: hidden; transition: opacity 1.4s var(--ease), visibility 0s linear 1.4s;
}
.hero__media img.is-active,
.hero__media video.is-active {
  opacity: 1;
  visibility: visible; transition: opacity 1.4s var(--ease), visibility 0s;
}
/* During the crossfade the outgoing slide is still visible, and therefore still
   in the hit test — and the photographs are painted after the film, so for that
   second and a half one of them lies across the film's control bar and swallows
   the clicks meant for it. Only the slide being shown is ever live. */
.hero__media > :not(.is-active) { pointer-events: none; }
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(28,24,24,.52) 0%, rgba(28,24,24,.18) 38%, rgba(28,24,24,.82) 100%);
  /* Nothing is ever clicked on the scrim, and left in the hit test it takes
     every click meant for the film's controls. */
  pointer-events: none;
}
/* On the film's slide the media layer comes out from behind the scrim. At
   z-index -2 it is painted below .hero's own box, so .hero — not the video —
   wins the hit test and the controls cannot be clicked at all (verified: at
   z-index -2, elementFromPoint over the film returns section.hero). Above the
   scrim the white control icons also keep their contrast, and the header
   carries its own gradient, so the logo and nav stay legible without it. */
.hero.is-video .hero__media { z-index: 1; }
/* Chromium and Safari fade the control bar out after a few seconds of a still
   pointer, even while it is resting on the film. Pin it back while the film is
   hovered, or focus is inside it, so the controls are there whenever the
   visitor is actually looking for them. Chromium fades the panel, Safari the
   whole set, hence both selectors; Firefox exposes neither and keeps its own
   show-on-hover behaviour, which is the same outcome. */
.hero__video:hover::-webkit-media-controls-panel,
.hero__video:focus-within::-webkit-media-controls-panel,
.hero__video:hover::-webkit-media-controls,
.hero__video:focus-within::-webkit-media-controls {
  opacity: 1;
  transition: opacity .2s var(--ease);
}
/* The film fills the hero exactly as the photographs do. .booking rides 46px up
   over the bottom of it, which is the band the native control bar renders in, so
   on a desktop the middle of that bar sits behind the booking form — the play,
   seek and mute controls stay reachable either side of it, and below 981px there
   is no overlap at all. Shortening the film to clear the bar left a strip of
   bare page either side of the form, which read as a broken hero. */
/* Below 981px nothing covers the control bar, so on the film's slide the dots
   step up over it rather than sitting across its middle. Above that the booking
   bar already hides the bar and the dots keep their usual place just above it;
   the transition stops the step from snapping as the carousel leaves the film. */
.hero__dots { transition: bottom .4s var(--ease); }
@media (max-width: 980px) { .hero.is-video .hero__dots { bottom: 4.6rem; } }
.hero__content {
  width: 100%; max-width: var(--maxw); margin-inline: auto;
  /* Top padding reserves the sticky header so hero text can never slide
     under it on a short viewport (the hero is vh-based, the header is not). */
  padding: calc(var(--header-h) + 1.5rem) var(--gutter) clamp(4.5rem, 10vw, 8rem);
  color: #fff;
}
.hero__inner { max-width: 780px; }
.hero h1 { color: #fff; text-shadow: 0 2px 34px rgba(0,0,0,.4); }
.hero .eyebrow { color: var(--yellow); }
.hero .eyebrow::before { background: rgba(252,228,48,.6); }
.hero__tagline {
  font-family: var(--font-display); font-style: italic;
  font-size: clamp(1.2rem, 2.4vw, 1.75rem);
  color: #f3efe7; margin: 0 0 1.8rem;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: .9rem; }

/* Centred on the hero, which is also centred on the booking bar below it. */
.hero__dots { position: absolute; left: 0; right: 0; bottom: clamp(1.6rem, 4vw, 2.6rem); display: flex; justify-content: center; gap: .35rem; z-index: 2; }
/* From 981px .booking rides 46px up over the hero. A dot is a 44px tap target
   around a 10px circle, so anything under 46px leaves the foot of that target
   behind the booking bar, where the click lands on the form instead. Sit the
   whole row just above the bar's top edge. */
@media (min-width: 981px) { .hero__dots { bottom: 3.4rem; } }
.hero__dot { width: 44px; height: 44px; padding: 0; background: none; border: 0; display: grid; place-items: center; cursor: pointer; }
.hero__dot::before {
  content: ""; width: 10px; height: 10px; border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.75); background: transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.hero__dot.is-active::before { background: var(--yellow); border-color: var(--yellow); }

/* Slideshow arrows, centred on the height of the photograph. 46px keeps the
   tap target over the 44px minimum, and the scrim behind them means they stay
   readable whichever frame is showing. */
.hero__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(20,17,17,.34); border: 1px solid rgba(255,255,255,.6); color: #fff;
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.hero__nav:hover, .hero__nav:focus-visible { background: rgba(20,17,17,.6); border-color: var(--yellow); color: var(--yellow); }
.hero:focus-visible { outline: 3px solid var(--yellow); outline-offset: -5px; }
.hero__nav--prev { left: var(--gutter); }
.hero__nav--next { right: var(--gutter); }
.hero__nav svg { stroke-linecap: round; stroke-linejoin: round; }

/* Pages whose header is solid from the start must offset the fixed bar. */
body.has-solid-header { padding-top: var(--header-h); }

/* ============================ page hero (inner pages) ============================ */
.page-hero { position: relative; min-height: min(58vh, 520px); display: flex; align-items: center; overflow: hidden; }
.page-hero__media { position: absolute; inset: 0; z-index: 0; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(28,24,24,.55) 0%, rgba(28,24,24,.35) 50%, rgba(28,24,24,.68) 100%);
}
.page-hero__content {
  position: relative; z-index: 2;
  width: 100%; max-width: var(--maxw); margin-inline: auto;
  padding: calc(var(--header-h) + 1.5rem) var(--gutter) clamp(2.5rem, 6vw, 4rem);
  color: #fff;
}
.page-hero h1 { color: #fff; text-shadow: 0 2px 30px rgba(0,0,0,.4); }
.page-hero .eyebrow { color: var(--yellow); }
.page-hero .eyebrow::before { background: rgba(252,228,48,.6); }
.page-hero p { color: #ece7df; max-width: 60ch; margin: 0; }

/* ============================ breadcrumb ============================ */
.breadcrumb { background: var(--sand); border-bottom: 1px solid var(--line); }
/* margin:0 is load-bearing — the reset zeroes `ul` but not `ol`, so this list
   kept the UA default margin-block:1em (= .82rem here). The top half collapsed
   out through .wrap and .breadcrumb and opened a 13px band under the hero
   image; the bottom half was trapped by .breadcrumb's border and padded the
   bar out. */
.breadcrumb__list { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; list-style: none; margin: 0; padding-block: .85rem; font-size: .82rem; }
.breadcrumb__item { display: flex; align-items: center; gap: .5rem; color: var(--muted); }
.breadcrumb__item:not(:last-child)::after { content: "›"; color: var(--gold-line); }
.breadcrumb__item a { color: var(--gold-deep); }
.breadcrumb__item--current { color: var(--ink-soft); }

/* ============================ booking bar ============================ */
.booking { position: relative; z-index: 20; margin-top: -46px; }
@media (max-width: 980px) { .booking { margin-top: 0; } }
.booking__bar {
  background: var(--paper); box-shadow: var(--shadow-md);
  border-top: 3px solid var(--yellow);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)) auto;
}
@media (max-width: 980px) { .booking__bar { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px) { .booking__bar { grid-template-columns: minmax(0,1fr); } }

.bk-field { display: flex; flex-direction: column; gap: .3rem; padding: 1.05rem 1.25rem; border-right: 1px solid var(--line); min-width: 0; position: relative; }
@media (max-width: 980px) { .bk-field { border-right: 0; border-bottom: 1px solid var(--line); } }
.bk-field__label {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .68rem; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.bk-field__label svg { color: var(--gold-deep); flex: none; }
.bk-field input, .bk-field select {
  font-family: var(--font-body); font-size: .98rem; color: var(--ink);
  border: 0; background: transparent; padding: .25rem 0; width: 100%;
  min-height: 30px; cursor: pointer;
}
.bk-field:focus-within { background: #fdfcf9; }
.bk-submit { display: grid; }
.bk-submit .btn { height: 100%; width: 100%; min-height: 56px; }

.bk-guests__trigger { display: flex; align-items: center; justify-content: space-between; gap: .5rem; width: 100%; text-align: left; font-size: .98rem; color: var(--ink); min-height: 44px; cursor: pointer; }
.bk-pop {
  position: absolute; bottom: calc(100% + 6px); left: 0; width: 320px;
  max-width: calc(100vw - 2rem); z-index: 60;
  background: var(--paper); box-shadow: var(--shadow-lg); border: 1px solid var(--line);
  padding: 1rem 1.1rem;
}
/* display:none when closed — visibility:hidden would still hold layout width
   and push the page into horizontal scroll at high zoom. */
.bk-guests:not([data-expanded="true"]) .bk-pop { display: none; }
.bk-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .55rem 0; }
.bk-row + .bk-row { border-top: 1px solid var(--line); }
.bk-step { display: flex; align-items: center; gap: .2rem; }
.bk-step button { width: 34px; height: 34px; border: 1px solid var(--line); display: grid; place-items: center; font-size: 1.1rem; color: var(--ink); }
.bk-step button:hover { background: var(--sand); }
.bk-step output { min-width: 32px; text-align: center; font-size: .98rem; }

/* ============================ cards ============================ */
.grid { display: grid; gap: var(--card-gap); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.grid > * { min-width: 0; }

.card {
  background: var(--paper); border: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
.card__media { position: relative; overflow: hidden; aspect-ratio: 4 / 3; }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.card:hover .card__media img { transform: scale(1.05); }
.card__body { padding: 1.4rem 1.5rem 1.6rem; display: flex; flex-direction: column; flex: 1 1 auto; gap: .5rem; }
.card__title { margin: 0; }
.card__meta { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; font-size: .82rem; color: var(--muted); }
.card__meta span { display: inline-flex; align-items: center; gap: .35rem; }
.card__foot { margin-top: auto; padding-top: 1.1rem; display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; }
.card__price { font-family: var(--font-display); font-size: 1.25rem; color: var(--ink); }
.card__price small { font-family: var(--font-body); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); display: block; }
.card__badge {
  position: absolute; top: .9rem; left: .9rem; z-index: 2;
  background: var(--yellow); color: var(--ink);
  font-size: .66rem; font-weight: 500; letter-spacing: .13em; text-transform: uppercase;
  padding: .35rem .7rem;
}

/* ============================ USP strip ============================ */
.usps { display: grid; gap: var(--card-gap); grid-template-columns: repeat(auto-fit, minmax(min(100%,215px), 1fr)); }
.usp { text-align: center; padding: 1.6rem 1rem; background: var(--paper); border: 1px solid var(--line); min-width: 0; }
.usp__icon { width: 46px; height: 46px; margin: 0 auto .8rem; display: grid; place-items: center; color: var(--gold-deep); border: 1px solid var(--gold-line); border-radius: 50%; }
.usp h3 { font-size: 1.05rem; margin-bottom: .35rem; }
.usp p { font-size: .88rem; color: var(--muted); margin: 0; }
/* Larger-type variant — same grid, bigger text. */
.usps--lg .usp h3 { font-size: 1.3rem; }
.usps--lg .usp p { font-size: 1.02rem; }
/* At-a-glance figures. Here the number IS the content, so it carries display
   type at headline size — at the shared .usp h3 size of 1.05rem it read as a
   label rather than a statistic, and the caption under it was too small to
   scan comfortably. */
.usps--stats .usp { padding: 1.9rem 1.1rem; }
.usps--stats .usp h3 {
  font-size: clamp(2.6rem, 5.5vw, 3.4rem); line-height: 1;
  color: var(--gold-deep); margin-bottom: .5rem;
}
.usps--stats .usp p { font-size: 1.02rem; color: var(--ink-soft); }

/* A heading that has to hold one line. It already does at every width down to
   about 365px; below that the h2 floor of 1.9rem wants 325px inside a ~320px
   column and wraps. Lowering the floor only there keeps it on one line without
   shrinking the heading at any width where it already fits. */
@media (max-width: 374px) {
  .h2--oneline { font-size: 1.55rem; }
}

/* A page-name H1 carrying the property name runs to ~35 characters, which no
   phone column can hold at the h1 clamp floor. Stepped down below 560px only. */
@media (max-width: 560px) {
  .h1--fit { font-size: 1.6rem; }
}

/* One H1 sits 12px over its column at the 4.4rem cap on a wide screen; a
   fractionally lower ceiling holds it on one line without a visible change. */
.h1--tight { font-size: clamp(2.4rem, 5.6vw, 4.1rem); }

/* ============================ split feature ============================ */
.split { display: grid; gap: clamp(1.6rem, 4vw, 4rem); align-items: center; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); }
.split > * { min-width: 0; }
/* Two text-and-form columns that should read as one block of equal size. The
   default centring floats the shorter column inside the taller one, insetting
   it top and bottom; stretching it and spreading its own parts over the height
   squares the two off. Height-driven, so it holds as the text rewraps — and it
   is inert once the grid stacks, where each column is already its own height. */
/* Two tall columns of unequal height — align their tops rather than centring
   the shorter one against the taller. */
.split--top { align-items: start; }
/* Once these columns stack, the second one — the form — is the point of the
   page, so it should not sit below a screen of thumbnails. 872px is the width
   at which this split stops fitting two columns; gating on it means the
   side-by-side order is never touched. */
@media (max-width: 872px) {
  .split--form-first > :first-child { order: 2; }
}
.split--even { align-items: stretch; }
.split--even > :first-child { display: flex; flex-direction: column; justify-content: space-between; }
/* Photograph sized to the copy beside it rather than to a fixed ratio, so it
   runs the full length of the text however that text rewraps. height:100%
   resolves against the stretched row and wins over the ratio; once the grid
   stacks, the row height is the item's own content and the percentage has
   nothing definite to resolve against, so aspect-ratio takes back over and
   mobile keeps a landscape crop instead of a very tall one. */
.split--match { align-items: stretch; }
.split--match .split__media img { height: 100%; }
.split__media { position: relative; }
.split__media img { width: 100%; aspect-ratio: 5/4; object-fit: cover; }
.split__media--tall img { aspect-ratio: 4/5; }
.split--reverse .split__media { order: 2; }
@media (max-width: 780px) { .split--reverse .split__media { order: 0; } }

/* ============================ direct booking band ============================ */
.direct { background: var(--ink); color: #ded8d1; }
.direct__grid { display: grid; gap: clamp(1.2rem,3vw,2.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,220px),1fr)); }
.direct__item { display: flex; gap: .9rem; align-items: flex-start; min-width: 0; }
.direct__item svg { color: var(--yellow); flex: none; margin-top: 3px; }
.direct__item h3 { font-size: 1.05rem; color: #fff; margin-bottom: .2rem; }
.direct__item p { font-size: .88rem; margin: 0; color: #b9b1aa; }

/* ============================ gallery ============================ */
.gal-grid { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
.gal-item { position: relative; overflow: hidden; aspect-ratio: 1; border: 0; padding: 0; cursor: pointer; background: var(--sand); }
.gal-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--ease); }
.gal-item:hover img { transform: scale(1.07); }
.gal-tabs { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-bottom: 2rem; }
/* Gallery paired beside a form: tabs read left, and thumbnails run two across
   in the half-width column — fewer, larger images, since a venue filter leaves
   only three. Widens to three once the columns stack and the room is there. */
.gal-tabs--start { justify-content: flex-start; margin-bottom: 1.2rem; }
.gal-grid--compact { grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }
.gal-tab { min-height: 44px; padding: .55rem 1.15rem; border: 1px solid var(--line); background: var(--paper); font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.gal-tab.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }

.lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(20,17,17,.94); display: none; align-items: center; justify-content: center; padding: clamp(1rem,4vw,3rem); }
.lightbox.is-open { display: flex; }
.lightbox img { max-width: 100%; max-height: 82vh; object-fit: contain; }
.lightbox__close, .lightbox__nav { position: absolute; width: 48px; height: 48px; display: grid; place-items: center; color: #fff; border: 1px solid rgba(255,255,255,.35); background: rgba(0,0,0,.3); }
.lightbox__close { top: 1.2rem; right: 1.2rem; }
.lightbox__nav--prev { left: 1.2rem; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 1.2rem; top: 50%; transform: translateY(-50%); }
.lightbox__count { position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%); color: #cfc9c2; font-size: .85rem; letter-spacing: .1em; }

/* ============================ forms ============================ */
.form-grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.form-grid > * { min-width: 0; }
.field { display: flex; flex-direction: column; gap: .35rem; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: .74rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.field .req { color: var(--err); }
.field input, .field select, .field textarea {
  font-family: var(--font-body); font-size: 1rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line);
  padding: .8rem .9rem; min-height: 48px; width: 100%; border-radius: var(--radius);
  transition: border-color .25s var(--ease);
}
.field textarea { min-height: 128px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--gold-deep); outline: none; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 3px solid var(--gold-deep); outline-offset: 1px; }
.field__error { font-size: .78rem; color: var(--err); min-height: 1.1rem; }
.form-note { font-size: .8rem; color: var(--muted); }
.form-consent { display: flex; align-items: flex-start; gap: .6rem; margin: 1.2rem 0; font-size: .8rem; color: var(--muted); cursor: pointer; }
.form-consent input { flex: none; width: 18px; height: 18px; min-height: 0; margin-top: 1px; accent-color: var(--gold-deep); }
.form-status { padding: .9rem 1.1rem; font-size: .9rem; border-left: 3px solid; }

/* ============================ tables ============================ */
.table-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; min-width: 460px; font-size: .92rem; }
th, td { text-align: left; padding: .85rem 1rem; border-bottom: 1px solid var(--line); }
th { font-family: var(--font-body); font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink); background: var(--sand); font-weight: 500; }

/* ============================ accordion ============================ */
/* FAQ categories. The chips borrow .dtabs/.dtab for their look but carry their
   own class so the dining-tab script never binds to them — they filter groups
   rather than swapping a single panel, and "All" has no panel of its own. */
.faq-filter { justify-content: flex-start; }
.faq-group[hidden] { display: none; }
.faq-group + .faq-group { margin-top: clamp(2.2rem, 4vw, 3.2rem); }
.faq-group__h { font-size: clamp(1.15rem, 1.9vw, 1.4rem); margin-bottom: .8rem; }

.acc { border-top: 1px solid var(--line); }
.acc details { border-bottom: 1px solid var(--line); }
.acc summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.15rem 0; cursor: pointer; list-style: none;
  font-family: var(--font-display); font-size: 1.15rem; font-weight: 600; color: var(--ink); min-height: 56px;
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after { content: "+"; font-family: var(--font-body); font-size: 1.5rem; color: var(--gold-deep); flex: none; transition: transform .3s var(--ease); }
.acc details[open] summary::after { transform: rotate(45deg); }
/* Jost's 400 sits heavy next to the display serif above it, which read as bold
   against the question. 300 restores the answer to supporting text. */
.acc__body { padding: 0 0 1.3rem; color: var(--ink-soft); font-weight: 300; max-width: 74ch; }

/* ==================== experiences: hover-reveal cards ====================
   Title always on the image; the description slides up on hover. Gated behind
   `hover: hover` so touch devices — which have no hover to give — simply show
   the whole card. The text stays in the DOM either way, so screen readers get
   it regardless of which branch applies. */
.xcard { position: relative; overflow: hidden; background: var(--ink); }
.xcard img { width: 100%; aspect-ratio: 4/5; object-fit: cover; display: block; transition: transform .6s var(--ease); }
.xcard__body {
  position: absolute; inset: auto 0 0 0; padding: 1.2rem 1.35rem 1.4rem;
  background: linear-gradient(to top, rgba(14,12,12,.97), rgba(14,12,12,.9) 45%, rgba(14,12,12,.62) 72%, rgba(14,12,12,0));
}
.xcard__title { color: #fff; font-size: 1.22rem; margin: 0; text-shadow: 0 1px 3px rgba(0,0,0,.55); }
.xcard__text { color: #f3efe9; font-size: .96rem; line-height: 1.65; margin: .5rem 0 0; text-shadow: 0 1px 3px rgba(0,0,0,.5); }
.xcard:focus-visible { outline: 3px solid var(--yellow); outline-offset: 3px; }

@media (hover: hover) {
  .xcard__text {
    max-height: 0; opacity: 0; margin-top: 0; overflow: hidden;
    transition: max-height .45s var(--ease), opacity .35s var(--ease), margin-top .45s var(--ease);
  }
  .xcard:hover .xcard__text,
  .xcard:focus-within .xcard__text { max-height: 14rem; opacity: 1; margin-top: .5rem; }
  .xcard:hover img,
  .xcard:focus-within img { transform: scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .xcard img, .xcard__text { transition: none; }
}

/* ======================== diamond chain rule ========================
   Pages that close on the "Ready when you are" CTA put a --ink section
   directly against the --ink footer, so the seam between them is invisible.
   This band marks it with the logo's diamond, alternating solid gold and
   white outline the way the mark nests them. Decorative only — the markup carries
   aria-hidden, and the tile is inlined so it costs no extra request. */
.diamond-chain {
  height: clamp(2.1rem, 4vw, 2.9rem);
  background-color: var(--ink);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='24'%3E%3Cpath d='M18 6L24 12L18 18L12 12Z' fill='%23d9bb3a'/%3E%3Cpath d='M54 6L60 12L54 18L48 12Z' fill='none' stroke='%23ffffff' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-position: center center;
}

/* ============================ footer ============================ */
.footer { background: var(--ink); color: #b9b1aa; padding-top: clamp(3rem, 6vw, 4.5rem); }
.footer a { color: #d8d2cc; }
.footer a:hover { color: var(--yellow); text-decoration: none; }
.footer__grid { display: grid; gap: clamp(1.6rem, 4vw, 3rem); grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); padding-bottom: 2.5rem; }
.footer__grid > * { min-width: 0; }
/* The footer uses soho-logo-outline.png: the diamond as a white stroke with no
   fill, the S in gold, the strapline reversed to white type. Earlier attempts
   are why — invert() turned the diamond white and the gold S blue; the dark
   original measured 65 luminance on a 43 background, i.e. unreadable;
   soho-logo-light.png only reached a grey fill; and soho-logo-white.png read
   as a solid white block on the dark ground. Drawn at 365x521 for retina. */
.footer__logo img { height: 99px; width: auto; }
.footer h4, .footer .footer__h { color: #fff; font-family: var(--font-body); font-size: .8rem; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; margin-bottom: 1.1rem; line-height: 1.4; }
.footer__links { list-style: none; display: flex; flex-direction: column; gap: .1rem; }
.footer__links a { display: inline-flex; align-items: center; min-height: 40px; font-size: .9rem; }
.footer__contact { list-style: none; display: flex; flex-direction: column; gap: .55rem; font-size: .9rem; }
.footer__contact li { display: flex; gap: .6rem; align-items: flex-start; }
.footer__contact svg { color: var(--yellow); flex: none; margin-top: 4px; }
.footer__contact a { overflow-wrap: anywhere; }
.footer__social { display: flex; gap: .5rem; margin-top: 1.1rem; }
.footer__social a { width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid rgba(255,255,255,.22); }
.footer__social a:hover { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }
.footer__bottom {
  border-top: 1px solid rgba(255,255,255,.12); padding-block: 1.4rem;
  display: flex; flex-wrap: wrap; gap: .8rem 1.5rem; align-items: center; justify-content: space-between;
  font-size: .82rem;
}
.footer__bottom nav { display: flex; flex-wrap: wrap; gap: .3rem 1.2rem; }
.footer__bottom nav a { display: inline-flex; align-items: center; min-height: 40px; }
/* The copyright line picked up the global `p { margin: 0 0 1.1rem }` rhythm while
   .powered escaped it via `p:last-child`. In an align-items:center row that margin
   is part of the centred box, so the copyright's 39.6px margin box filled the 40px
   line the nav links set and its text pinned to the top — 9px above the legal links
   and the credit. Row spacing is the container's `gap`, not paragraph rhythm. */
.footer__bottom p { margin: 0; }
.powered a { color: var(--yellow); }

/* ============================ floating actions ============================ */
.fab-stack { position: fixed; right: clamp(.9rem, 2vw, 1.6rem); bottom: clamp(.9rem, 2vw, 1.6rem); z-index: 90; display: flex; flex-direction: column; gap: .6rem; }
.fab { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; box-shadow: var(--shadow-md); color: #fff; transition: transform .3s var(--ease); }
.fab:hover { transform: scale(1.08); text-decoration: none; }
.fab--wa { background: #25d366; }
.fab--call { background: var(--ink); }
.fab--top { background: var(--paper); color: var(--ink); border: 1px solid var(--line); opacity: 0; visibility: hidden; }
.fab--top.is-visible { opacity: 1; visibility: visible; }

/* ============================ cookie banner ============================ */
.cookie {
  position: fixed; left: clamp(.9rem,2vw,1.6rem); bottom: clamp(.9rem,2vw,1.6rem);
  z-index: 150; max-width: 430px; background: var(--paper);
  box-shadow: var(--shadow-lg); border-top: 3px solid var(--yellow);
  padding: 1.3rem 1.5rem; display: none;
}
.cookie.is-visible { display: block; }
.cookie p { font-size: .88rem; margin-bottom: 1rem; }
.cookie__actions { display: flex; flex-wrap: wrap; gap: .6rem; }

/* ============================ reveal animation ============================ */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: .09s; }
.reveal-d2 { transition-delay: .18s; }
.reveal-d3 { transition-delay: .27s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .hero__media img, .hero__media video { transition: none; }
}

/* ============================ utilities ============================ */
.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;
}
.center { text-align: center; }
.mt-0 { margin-top: 0; }

/* Long unbreakable strings must wrap, not widen the row (400% zoom) */
.footer__contact a, .contact-list a, .field input { overflow-wrap: anywhere; }

/* Vendor-injected reCAPTCHA is a hardcoded 304px; contain the wrapper we own */
[id^="g-recaptcha"] { max-width: 100%; overflow: hidden; }
@media (max-width: 400px) {
  [id^="g-recaptcha"] { transform: scale(.85); transform-origin: 0 0; height: 66px; }
}

/* Links inside a paragraph must be distinguishable without colour alone
   (WCAG 1.4.1) — underline them; standalone/nav/button links are exempt. */
.cookie p a, .acc__body a, .prose a, p a:not(.btn):not(.text-link) {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.powered a { text-decoration: underline; text-underline-offset: 3px; }
.contact-list a, .footer__contact a { text-decoration: underline; text-underline-offset: 3px; }

/* ============================ room slider (homepage) ============================
   Reference pattern: image with a floating white content panel below it,
   arrows either side. Two cards visible on desktop, one on mobile, with
   scroll-snap so it works with touch, keyboard and the arrow buttons. */
.rslider { position: relative; }
.rslider__track {
  display: flex; gap: clamp(1rem, 2.4vw, 2rem);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
  padding-bottom: .5rem;
}
.rslider__track::-webkit-scrollbar { display: none; }
/* Two whole cards to a row, no clipped third: one gap sits inside the visible
   width at that count. The arrows and dots are what say the row scrolls. */
.rslider__slide {
  flex: 0 0 calc((100% - clamp(1rem,2.4vw,2rem)) / 2);
  scroll-snap-align: start; min-width: 0;
}
@media (max-width: 900px) { .rslider__slide { flex: 0 0 100%; } }

.rcard { background: transparent; }
.rcard__media { position: relative; aspect-ratio: 16 / 11; overflow: hidden; }
.rcard__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.rcard:hover .rcard__media img { transform: scale(1.04); }

/* Three key points laid over the photograph */
/* Sits ABOVE the overlapping white panel (which starts at -2.6rem), so the
   key points are never covered by it. */
.rcard__points {
  position: absolute; left: 0; right: 0; bottom: 2.9rem; z-index: 2;
  display: flex; flex-wrap: wrap; justify-content: center; gap: .35rem 1.1rem;
  padding: 2.6rem 1rem .7rem;
  background: linear-gradient(180deg, rgba(20,17,17,0) 0%, rgba(20,17,17,.66) 70%);
  list-style: none;
}
.rcard__points li {
  display: inline-flex; align-items: center; gap: .45rem;
  color: #fff; font-size: .72rem; letter-spacing: .04em;
}
.rcard__points svg { color: var(--yellow); flex: none; }

/* White panel that overlaps the image, as in the reference */
.rcard__body {
  background: var(--paper); border: 1px solid var(--line); border-top: 0;
  margin: -2.6rem 1.4rem 0; position: relative; z-index: 3;
  padding: 1.5rem 1.5rem 1.6rem; text-align: center;
  display: flex; flex-direction: column; gap: .6rem;
}
@media (max-width: 560px) { .rcard__body { margin-inline: .7rem; } }
.rcard__title { font-family: var(--font-display); color: var(--gold-deep); font-size: 1.32rem; margin: 0; }
.rcard__desc { font-size: .85rem; color: var(--ink-soft); margin: 0; }
.rcard__rate { font-size: .74rem; color: var(--muted); letter-spacing: .06em; }
.rcard__rate strong { font-family: var(--font-display); font-size: 1.18rem; color: var(--ink); letter-spacing: 0; }
.rcard__actions { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin-top: .3rem; }

.rslider__nav {
  position: absolute; top: 30%; z-index: 5;
  width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.94); border: 1px solid var(--line);
  color: var(--ink); box-shadow: var(--shadow-sm);
  transition: background .3s var(--ease);
}
.rslider__nav:hover { background: var(--yellow); border-color: var(--yellow); }
.rslider__nav--prev { left: calc(var(--gutter) * -1 + .2rem); }
.rslider__nav--next { right: calc(var(--gutter) * -1 + .2rem); }
@media (max-width: 1340px) {
  .rslider__nav--prev { left: .3rem; }
  .rslider__nav--next { right: .3rem; }
}
.rslider__dots { display: flex; justify-content: center; gap: .3rem; margin-top: 1.4rem; }
.rslider__dot { width: 44px; height: 44px; padding: 0; display: grid; place-items: center; }
.rslider__dot::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--gold-line); background: transparent;
  transition: background .3s var(--ease);
}
.rslider__dot.is-active::before { background: var(--gold-deep); border-color: var(--gold-deep); }

/* ============================ about slider ============================ */
.aslider { position: relative; }
.aslider__track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
}
.aslider__track::-webkit-scrollbar { display: none; }
.aslider__slide { flex: 0 0 100%; scroll-snap-align: center; min-width: 0; }
.aslider__slide img { width: 100%; aspect-ratio: 5/4; object-fit: cover; }
.aslider__dots { display: flex; justify-content: center; gap: .25rem; margin-top: .7rem; }
/* 44px element box with the small visual dot drawn inside via ::before —
   the element's OWN box is what a tap hits (RES-07/BTN-04). */
.aslider__dot { width: 44px; height: 44px; padding: 0; display: grid; place-items: center; }
.aslider__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  border: 1.5px solid var(--gold-line); background: transparent;
  transition: background .3s var(--ease);
}
.aslider__dot.is-active::before { background: var(--gold-deep); border-color: var(--gold-deep); }
.aslider__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.92); border: 1px solid var(--line); color: var(--ink);
}
.aslider__nav:hover { background: var(--yellow); border-color: var(--yellow); }
.aslider__nav--prev { left: .6rem; }
.aslider__nav--next { right: .6rem; }

/* ---------- Priority-plus header (reference pattern) ----------
   A few links stay inline; the toggle sits between the last link and Book Now
   and opens a drawer containing EVERY page, at all widths. */
.nav--inline .nav__list { display: flex; align-items: center; gap: .95rem; }
/* JS decides which items stay inline — no width-based hiding here. */
.nav--inline .nav__list { flex-wrap: nowrap; }
/* An inline item must never wrap onto two lines — it would make the row taller
   than one line and defeat the fit measurement. */
.nav--inline .nav__link { white-space: nowrap; }

/* The full-height drawer block that used to live here has been DELETED. It was a
   stale duplicate that won on source order and silently reverted the compact
   dropdown above back into a fixed full-height panel. */
.nav--drawer .nav__link[aria-current="page"] { color: var(--ink); background: var(--yellow); font-weight: 600; }

/* toggle bars invert with the header state */
.header .hamburger span { background: #fff; }
.header.is-scrolled .hamburger span,
.header--solid .hamburger span { background: var(--ink); }

/* ============================ dining tabs + slider ============================ */
.dtabs { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-bottom: clamp(1.8rem,3vw,2.8rem); }
.dtab {
  min-height: 48px; padding: .6rem 1.6rem;
  font-size: .78rem; font-weight: 500; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-soft); background: transparent;
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.dtab:hover { border-color: var(--gold-line); }
.dtab.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }
.dpanel[hidden] { display: none; }
.dpanel__title { font-size: clamp(1.6rem, 2.6vw, 2.2rem); margin-bottom: .4rem; }
.dslider { position: relative; }
.dslider__track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.dslider__track::-webkit-scrollbar { display: none; }
.dslide { flex: 0 0 100%; scroll-snap-align: center; min-width: 0; }
.dslide img { width: 100%; aspect-ratio: 5/4; object-fit: cover; }
.dslider__dots { display: flex; justify-content: center; gap: .25rem; margin-top: .7rem; }
/* 44px element box with the small visual dot drawn inside via ::before —
   the element's OWN box is what a tap hits (RES-07/BTN-04). */
.dslider__dot { width: 44px; height: 44px; padding: 0; display: grid; place-items: center; }
.dslider__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  border: 1.5px solid var(--gold-line); background: transparent; transition: background .3s var(--ease);
}
.dslider__dot.is-active::before { background: var(--gold-deep); border-color: var(--gold-deep); }

/* ============================ review slider ============================ */
.vslider { position: relative; }
.vslider__track {
  display: flex; gap: clamp(1rem, 2vw, 1.6rem);
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: .4rem;
}
.vslider__track::-webkit-scrollbar { display: none; }
.vslide { flex: 0 0 calc((100% - 2 * clamp(1rem,2vw,1.6rem)) / 3); scroll-snap-align: start; min-width: 0; }
@media (max-width: 1000px) { .vslide { flex: 0 0 calc((100% - clamp(1rem,2vw,1.6rem)) / 2); } }
@media (max-width: 680px)  { .vslide { flex: 0 0 100%; } }
.vcard {
  background: var(--paper); border: 1px solid var(--line);
  padding: 1.7rem 1.6rem 1.5rem; height: 100%;
  display: flex; flex-direction: column; gap: .9rem;
}
.vcard__top { display: flex; align-items: center; gap: .6rem; }
.vcard__stars { display: inline-flex; gap: 1px; color: #f0b429; }
.vcard__score { font-family: var(--font-display); font-size: 1.05rem; color: var(--ink); }
.vcard__tags { display: flex; flex-wrap: wrap; gap: .35rem; }
.vcard__tag {
  font-size: .68rem; letter-spacing: .06em; color: var(--ink-soft);
  background: var(--sand); border: 1px solid var(--line); padding: .2rem .5rem;
}
.vcard__text { font-size: .9rem; line-height: 1.65; color: var(--ink-soft); margin: 0; flex: 1 1 auto; }
.vcard__by { margin: 0; display: flex; flex-direction: column; gap: .1rem; }
.vcard__name { font-family: var(--font-display); font-size: 1.08rem; color: var(--ink); }
.vcard__src { font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.vslider__dots { display: flex; justify-content: center; gap: .25rem; margin-top: 1.4rem; }
/* 44px element box with the small visual dot drawn inside via ::before —
   the element's OWN box is what a tap hits (RES-07/BTN-04). */
.vslider__dot { width: 44px; height: 44px; padding: 0; display: grid; place-items: center; }
.vslider__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  border: 1.5px solid var(--gold-line); background: transparent; transition: background .3s var(--ease);
}
.vslider__dot.is-active::before { background: var(--gold-deep); border-color: var(--gold-deep); }

/* ============================ nearby cards (location) ============================ */
.near-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 265px), 1fr)); }
.near-grid > * { min-width: 0; }
.near { background: var(--paper); border: 1px solid var(--line); padding: 1.25rem 1.35rem; }
.near__head { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; margin-bottom: .4rem; }
.near__head h3 { font-size: 1.12rem; margin: 0; }
.near__dist {
  flex: none; font-size: .72rem; font-weight: 500; letter-spacing: .08em;
  color: var(--ink); background: var(--yellow); padding: .2rem .55rem; white-space: nowrap;
}
.near p { font-size: .88rem; color: var(--muted); margin: 0; }
.section-head .eyebrow svg { color: var(--gold-deep); }

/* ============================ dining page cards ============================ */
.dcards { display: flex; flex-direction: column; gap: clamp(1.6rem, 3vw, 2.6rem); }
.dcard { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); background: var(--paper); border: 1px solid var(--line); overflow: hidden; }
@media (max-width: 880px) { .dcard { grid-template-columns: minmax(0,1fr); } }
.dcard:nth-child(even) .dcard__media { order: 2; }
@media (max-width: 880px) { .dcard:nth-child(even) .dcard__media { order: 0; } }
.dcard__media { position: relative; min-height: 300px; }
.dcard__media img { width: 100%; height: 100%; object-fit: cover; }
.dcard__body { padding: clamp(1.5rem, 3vw, 2.4rem); display: flex; flex-direction: column; gap: .85rem; }
.dcard__body h3 { font-size: clamp(1.5rem, 2.4vw, 2rem); margin: 0; }
.dcard__pitch { font-family: var(--font-display); font-style: italic; font-size: 1.1rem; color: var(--gold-deep); margin: 0; }
.dfacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,120px), 1fr)); gap: .8rem 1rem; margin: .3rem 0; }
.dfact dt { font-size: .66rem; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); margin-bottom: .15rem; }
.dfact dd { margin: 0; font-size: .92rem; color: var(--ink); }
.dchips { display: flex; flex-wrap: wrap; gap: .4rem; }
.dchip { font-size: .72rem; letter-spacing: .05em; color: var(--ink-soft); background: var(--sand); border: 1px solid var(--line); padding: .28rem .6rem; }
.dcard__actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: auto; padding-top: .6rem; }

/* ============================ direct-booking toaster ============================
   A slim vertical tab stitched to the LEFT edge (clear of the WhatsApp/call
   stack on the right). Clicking it slides out the full benefit list. */
.toaster {
  position: fixed; left: 0; top: 50%; transform: translateY(-50%);
  z-index: 95; display: flex; align-items: stretch;
}
.toaster__tab {
  flex: none; width: 46px; padding: 1.1rem .3rem;
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
  background: var(--ink); color: #fff;
  border: 0; border-left: 3px solid var(--yellow);
  border-radius: 0 var(--radius) var(--radius) 0;
  box-shadow: var(--shadow-md); cursor: pointer;
  transition: background .3s var(--ease);
}
.toaster__tab:hover { background: #171313; }
.toaster__tab-label {
  writing-mode: vertical-rl; text-orientation: mixed;
  font-size: .68rem; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  white-space: nowrap;
}
.toaster__tag { color: var(--yellow); flex: none; }
.toaster__chev { flex: none; transition: transform .35s var(--ease); }
.toaster[data-open="true"] .toaster__chev { transform: rotate(180deg); }

.toaster__body {
  width: min(78vw, 310px);
  background: var(--ink); color: #ded8d1;
  box-shadow: var(--shadow-lg);
  padding: 1.35rem 1.4rem 1.45rem;
  max-height: 82vh; overflow-y: auto;
}
.toaster__body[hidden] { display: none; }
.toaster__head {
  font-family: var(--font-display); font-size: 1.15rem; color: #fff;
  margin: 0 0 .9rem; line-height: 1.3;
}
.toaster__list { list-style: none; display: flex; flex-direction: column; gap: .85rem; margin: 0 0 1.2rem; }
.toaster__list li { display: flex; gap: .65rem; align-items: flex-start; }
.toaster__list svg { color: var(--yellow); flex: none; margin-top: 2px; }
.toaster__list strong { display: block; color: #fff; font-weight: 500; font-size: .92rem; margin-bottom: .1rem; }
.toaster__list span { font-size: .82rem; color: #b0a8a1; line-height: 1.5; }

/* Icon-only variant: the tab is just its icon until you hover it, when the
   label unrolls. Keyboard focus and the open state reveal it too, so the
   control is never unlabelled for touch or keyboard users. */
.toaster--icon .toaster__tab-label {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .4s var(--ease), opacity .3s var(--ease);
}
.toaster--icon .toaster__tab:hover .toaster__tab-label,
.toaster--icon .toaster__tab:focus-visible .toaster__tab-label,
.toaster--icon[data-open="true"] .toaster__tab-label { max-height: 9rem; opacity: 1; }

/* Slider inside a toaster body — one detail at a time, arrows and dots below.
   Sized up from the toaster's usual list type: there is only ever one item on
   screen here, so it can be read at a comfortable size rather than scanned. */
.gtk-slides { overflow: hidden; }
.gtk-track { display: flex; transition: transform .45s var(--ease); }
.gtk-slide { flex: 0 0 100%; min-width: 0; }
.gtk-slide svg { color: var(--yellow); display: block; margin-bottom: .7rem; width: 24px; height: 24px; }
.gtk-slide strong { display: block; color: #fff; font-weight: 500; font-size: 1.14rem; line-height: 1.35; margin-bottom: .4rem; }
.gtk-slide p { font-size: .97rem; color: #cdc6bf; line-height: 1.62; margin: 0; }
/* A little wider than the shared body, to carry the larger type on one line. */
.toaster--icon .toaster__body { width: min(84vw, 348px); }
.gtk-nav { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-top: 1.15rem; }
.gtk-arrow {
  flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  background: transparent; color: #ded8d1; border: 1px solid rgba(255,255,255,.22); padding: 0;
  cursor: pointer; transition: border-color .3s var(--ease), color .3s var(--ease);
}
.gtk-arrow:hover { border-color: var(--yellow); color: var(--yellow); }
.gtk-dots { display: flex; gap: .4rem; }
.gtk-dot {
  width: 8px; height: 8px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255,255,255,.28); transition: background .3s var(--ease);
}
.gtk-dot.is-active { background: var(--yellow); }

@media (max-width: 620px) {
  .toaster { top: auto; bottom: 0; transform: none; flex-direction: column-reverse; align-items: flex-start; }
  .toaster__tab { flex-direction: row; width: auto; padding: .7rem 1rem; border-left: 0; border-bottom: 3px solid var(--yellow); border-radius: 0 var(--radius) 0 0; }
  .toaster__tab-label { writing-mode: horizontal-tb; }
  .toaster__body { width: min(94vw, 340px); max-height: 68vh; }
  /* Horizontal tab down here, so the label unrolls sideways instead. */
  .toaster--icon .toaster__tab-label { max-height: none; max-width: 0; transition: max-width .4s var(--ease), opacity .3s var(--ease); }
  .toaster--icon .toaster__tab:hover .toaster__tab-label,
  .toaster--icon .toaster__tab:focus-visible .toaster__tab-label,
  .toaster--icon[data-open="true"] .toaster__tab-label { max-height: none; max-width: 12rem; }
}

/* ======================== inclusions list ========================
   Bulleted benefits, using the same gold tick the site uses for its
   check-mark lists. Sized to be read rather than scanned. */
.inclusions { list-style: none; display: flex; flex-direction: column; gap: .85rem; margin: 0 0 1.5rem; }
.inclusions li { display: flex; gap: .7rem; align-items: flex-start; font-size: 1rem; line-height: 1.55; }
.inclusions svg { color: var(--gold-deep); flex: none; margin-top: 4px; }
.inclusions strong { font-weight: 500; color: var(--ink); }

/* ======================== opening-hours callout ========================
   For pages where the hours are a reason to visit rather than a footnote:
   a tinted panel behind the gold edge, with the time set in display type. */
.hours-note {
  border-left: 3px solid var(--gold-line);
  background: var(--sand);
  padding: .95rem 1.2rem 1.05rem;
  margin: 0 0 1.6rem;
}
.hours-note__label {
  display: block; font-size: .68rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft);
}
.hours-note__time {
  display: block; font-family: var(--font-display); font-weight: 500;
  font-size: 1.5rem; line-height: 1.2; color: var(--ink); margin: .2rem 0 .15rem;
}
.hours-note__sub { display: block; font-size: .84rem; color: var(--muted); }

/* ============================ nearby cards (location) ============================ */
.near-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 265px), 1fr)); }
.near-grid > * { min-width: 0; }
.near { background: var(--paper); border: 1px solid var(--line); padding: 1.25rem 1.35rem; }
.near__head { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; margin-bottom: .4rem; }
.near__head h3 { font-size: 1.12rem; margin: 0; }
.near__dist {
  flex: none; font-size: .72rem; font-weight: 500; letter-spacing: .08em;
  color: var(--ink); background: var(--yellow); padding: .2rem .55rem; white-space: nowrap;
}
.near p { font-size: .88rem; color: var(--muted); margin: 0; }
.section-head .eyebrow svg { color: var(--gold-deep); }

/* ============================ dining page cards ============================ */
.dcards { display: flex; flex-direction: column; gap: clamp(1.6rem, 3vw, 2.6rem); }
.dcard { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); background: var(--paper); border: 1px solid var(--line); overflow: hidden; }
@media (max-width: 880px) { .dcard { grid-template-columns: minmax(0,1fr); } }
.dcard:nth-child(even) .dcard__media { order: 2; }
@media (max-width: 880px) { .dcard:nth-child(even) .dcard__media { order: 0; } }
.dcard__media { position: relative; min-height: 300px; }
.dcard__media img { width: 100%; height: 100%; object-fit: cover; }
.dcard__body { padding: clamp(1.5rem, 3vw, 2.4rem); display: flex; flex-direction: column; gap: .85rem; }
.dcard__body h3 { font-size: clamp(1.5rem, 2.4vw, 2rem); margin: 0; }
.dcard__pitch { font-family: var(--font-display); font-style: italic; font-size: 1.1rem; color: var(--gold-deep); margin: 0; }
.dfacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,120px), 1fr)); gap: .8rem 1rem; margin: .3rem 0; }
.dfact dt { font-size: .66rem; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); margin-bottom: .15rem; }
.dfact dd { margin: 0; font-size: .92rem; color: var(--ink); }
.dchips { display: flex; flex-wrap: wrap; gap: .4rem; }
.dchip { font-size: .72rem; letter-spacing: .05em; color: var(--ink-soft); background: var(--sand); border: 1px solid var(--line); padding: .28rem .6rem; }
.dcard__actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: auto; padding-top: .6rem; }

/* Map embeds: an iframe carries an intrinsic 300px+ width and its wrapper had
   no max-width, so at high zoom it pushed the page into horizontal scroll.
   Constrain the wrapper AND the frame. */
.map-embed { max-width: 100%; overflow: hidden; }
.map-embed iframe { width: 100%; max-width: 100%; display: block; }

/* ============================ room feature rows ============================
   Replaces three cramped equal cards with alternating full-width rows: a large
   hero image plus two detail thumbnails on one side, copy on the other. */
.rrows { display: flex; flex-direction: column; gap: clamp(2.5rem, 5vw, 4.5rem); }
.rrow { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(1.5rem, 3.5vw, 3.2rem); align-items: center; }
@media (max-width: 900px) { .rrow { grid-template-columns: minmax(0,1fr); } }
.rrow--flip .rrow__media { order: 2; }
@media (max-width: 900px) { .rrow--flip .rrow__media { order: 0; } }

.rrow__media { display: flex; flex-direction: column; gap: .55rem; min-width: 0; }
/* The collage the row was written for: one wide photograph over two details. */
.rrow__main, .rrow__thumb { overflow: hidden; }
.rrow__main img, .rrow__thumb img {
  width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; display: block;
}
.rrow__thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem; }
/* Same lift the cards and gallery tiles use, on the photograph that leads. */
.rrow__main img { transition: transform .8s var(--ease); }
.rrow:hover .rrow__main img { transform: scale(1.03); }

.rrow__body { min-width: 0; display: flex; flex-direction: column; gap: .55rem; }
.rrow__pitch {
  font-family: var(--font-body); font-size: .7rem; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold-deep); margin: 0;
}
.rrow__title { font-size: clamp(1.7rem, 3vw, 2.5rem); margin: 0 0 .2rem; }
.rrow__points { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem .5rem; margin: 0 0 .5rem; }
.rrow__points li {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .76rem; color: var(--ink-soft);
  background: var(--sand); border: 1px solid var(--line); padding: .3rem .65rem;
}
.rrow__points svg { color: var(--gold-deep); flex: none; }
/* These icons are drawn in the Lucide idiom, which assumes round caps and
   joins. With the default butt caps a zero-length subpath (the `h.01` trick
   used for the Wi-Fi signal dot and the wardrobe handles) has no geometry to
   cap and so draws nothing at all, and every terminus reads chopped. */
.rrow__points svg, .usp svg, .usp__icon svg, .gtk-slide svg { stroke-linecap: round; stroke-linejoin: round; }

/* Room key facts. These four are the ones a guest scans for before anything
   else, so they get tiles and the display face rather than a muted meta row. */
.spec {
  list-style: none; display: grid;
  /* 210px settles on 2x2 inside the split column: four across would wrap
     "2 adults + 1 child" onto a second line and lose the at-a-glance read. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 185px), 1fr));
  gap: .55rem; margin: 0 0 1.6rem;
}
.spec__item {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .85rem .9rem; background: var(--sand); border: 1px solid var(--gold-line);
}
.spec__icon { color: var(--gold-deep); margin-bottom: .35rem; stroke-linecap: round; stroke-linejoin: round; }
.spec__k {
  font-family: var(--font-body); font-size: .62rem; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; color: var(--muted);
}
.spec__v { font-family: var(--font-display); font-size: 1.15rem; line-height: 1.2; color: var(--ink); }

/* Text jump to a section further down the same page. Deliberately not a button,
   so it never competes with the booking CTA it sits beside. */
.jumplink {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--font-body); font-size: .74rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold-deep); border-bottom: 1px solid var(--gold-line); padding-bottom: .2rem;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.jumplink:hover, .jumplink:focus-visible { color: var(--ink); border-bottom-color: var(--ink); text-decoration: none; }
.jumplink svg { flex: none; stroke-linecap: round; stroke-linejoin: round; }
.rrow__copy { font-size: .95rem; color: var(--ink-soft); margin: 0; }
.rrow__foot {
  margin-top: .9rem; padding-top: 1.1rem; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
}
.rrow__rate { margin: 0; display: flex; flex-direction: column; }
.rrow__rate strong { font-family: var(--font-display); font-size: 1.6rem; color: var(--ink); line-height: 1.1; }
.rrow__rate span { font-size: .74rem; letter-spacing: .06em; color: var(--muted); }
.rrow__actions { display: flex; flex-wrap: wrap; gap: .55rem; }

/* ============================ grouped amenities ============================ */
.agroups { display: grid; gap: var(--card-gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.agroups > * { min-width: 0; }
.agroup { background: var(--paper); border: 1px solid var(--line); padding: 1.6rem 1.6rem 1.7rem; }
.agroup__icon { width: 42px; height: 42px; display: grid; place-items: center; border: 1px solid var(--gold-line); border-radius: 50%; color: var(--gold-deep); margin-bottom: .9rem; }
.agroup h3, .agroup .agroup__h { font-size: 1.2rem; margin: 0 0 .8rem; }
.agroup ul { list-style: none; display: flex; flex-direction: column; gap: .5rem; }
.agroup li { position: relative; padding-left: 1.1rem; font-size: .9rem; color: var(--ink-soft); }
.agroup li::before { content: ""; position: absolute; left: 0; top: .55em; width: 5px; height: 5px; background: var(--gold-line); border-radius: 50%; }

/* ============================ policy tabs ============================ */
.ptabs { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: clamp(1.8rem,3vw,2.6rem); }
.ptab {
  min-height: 46px; padding: .55rem 1.15rem;
  font-size: .74rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft); background: transparent;
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.ptab:hover { border-color: var(--gold-line); }
.ptab.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }
.ppanel[hidden] { display: none; }
.ppanel h2 { font-size: clamp(1.6rem,2.6vw,2.2rem); margin-bottom: 1.2rem; }
.ppanel h3 { font-size: 1.12rem; margin: 1.6rem 0 .5rem; }
.ppanel h3:first-of-type { margin-top: 0; }
.ppanel p { max-width: 74ch; }
.agroup ul a { color: var(--ink-soft); }
.agroup ul a:hover { color: var(--gold-deep); }


/* --- child ages in the booking widget (BKG-08/12/13) --- */
.bk-ages { padding: .75rem 0 .25rem; border-top: 1px solid var(--line); }
.bk-ages__h { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: .6rem; }
.bk-ages__list { display: flex; flex-wrap: wrap; gap: .6rem; }
.bk-age { display: flex; flex-direction: column; gap: .25rem; font-size: .78rem; color: var(--ink-soft); }
.bk-age select {
  min-height: 44px; min-width: 84px; padding: .4rem .6rem;
  border: 1px solid var(--line); background: #fff; color: var(--ink);
  font: inherit; font-size: .85rem; border-radius: 0;
  /* keep the native chevron — an appearance:none select with no affordance
     reads as plain text (BTN-06) */
}
.bk-age select:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 1px; }
.bk-age select.is-error { border-color: #b3261e; box-shadow: 0 0 0 2px rgba(179,38,30,.15); }


/* --- mobile tap-target floor (RES-07 / BTN-04) --- */
/* Footer contact + credit links measured 19-24px tall on a phone. Padding lifts
   the element's own box to 44px without changing the visual type size. */
@media (max-width: 700px) {
  .footer__contact a,
  .footer__bottom nav a,
  .contact-list a {
    display: inline-flex; align-items: center; min-height: 44px;
  }
  .footer__links a { min-height: 44px; }
  /* The inline nav link and the platform credit are the last two controls under
     the 44px mobile floor. Padding only — type size is unchanged. */
  .nav--inline .nav__link { min-height: 44px; }
  .powered a { display: inline-flex; align-items: center; min-height: 44px; }
}


/* ============ MOBILE HEADER: burger left / logo centre / Book Now right ============
   The DOM stays brand -> nav -> hamburger -> cta (correct source order for a
   screen reader: the logo/home link comes first). Flex `order` does the visual
   rearrangement, and the hamburger is fixed into the left-hand slot. */
@media (max-width: 700px) {
  .header__inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;   /* equal side rails keep the logo truly centred */
    align-items: center;
    gap: .5rem;
  }
  /* Every link lives under the hamburger on mobile — the inline row is hidden
     outright, so it cannot occupy a grid cell and push Book Now onto a 2nd row. */
  .header__inner > .nav--inline { display: none; }

  .header__brand { grid-column: 2; justify-self: center; }
  .header__cta   { grid-column: 3; justify-self: end; gap: .5rem; }

  /* Hamburger jumps to the first rail. position:absolute would leave a gap in
     the grid, so it becomes a grid item in its own right. */
  .header__inner > .hamburger {
    position: fixed; left: var(--gutter); top: 0; height: var(--header-h);
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; z-index: 2;
  }
  /* The empty first rail reserves the space the fixed hamburger occupies. */
  .header__inner::before { content: ""; grid-column: 1; }

  .header__cta .btn { white-space: nowrap; }
}


/* ============ MOBILE CAROUSEL for card grids ============
   On a phone a 3-6 card grid stacks into a 1600-2500px column that the guest
   must scroll past to reach the next section. Opt a grid in with `grid--swipe`
   and below 700px it becomes a horizontal scroll-snap row instead — same
   markup, no JS. Cards show ~85% width so the next one peeks, which is what
   signals "swipeable" without needing a hint.

   Uses the SAME scroll-snap pattern as the existing .rslider/.aslider so
   behaviour is identical across the site (FUN-11: one widget, one behaviour). */
@media (max-width: 700px) {
  .grid--swipe {
    display: flex;
    gap: var(--card-gap);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* Bleed to the viewport edge so the row reads as a carousel, not a
       clipped grid, then restore the gutter as scroll padding. */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    padding-bottom: .6rem;
    scroll-padding-inline-start: var(--gutter);
  }
  .grid--swipe::-webkit-scrollbar { display: none; }
  .grid--swipe > * {
    flex: 0 0 85%;
    scroll-snap-align: start;
    min-width: 0;
  }
  /* A swipe row must never trigger the page's own horizontal scrollbar. */
  .grid--swipe { max-width: 100vw; }
}


/* ============ Continue-booking nudge ============ */
/* Continue-booking nudge — structural CSS with design tokens.
   THE TOKEN BLOCK IS THE ONLY PART YOU EDIT PER SITE. Derive every value
   from the target site's own CSS (see SKILL.md STEP 2); the structure below
   is proven and stays as-is. Scoped to .booking-nudge — no :root pollution. */

.booking-nudge {
  /* ---- design tokens: fill from the target site ---- */
  --cbn-surface: #ffffff;            /* card/panel background */
  --cbn-border: #e6e1db;
  --cbn-ink: #2b2626;                /* heading text */
  --cbn-muted: #6f6663;              /* secondary text */
  --cbn-accent: #7a5c00;             /* brand accent: property name, price */
  --cbn-accent-2: #d9bb3a;           /* second accent for the top strip */
  --cbn-cta-bg: #fce430;             /* CTA button background */
  --cbn-cta-ink: #2b2626;            /* CTA label — AA >= 4.5:1 vs --cbn-cta-bg */
  --cbn-cta-hover: #f5d312;
  --cbn-font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;         /* site heading font stack */
  --cbn-font-body: "Jost", "Helvetica Neue", Arial, sans-serif; /* site body font stack */
  --cbn-radius: 2px;                /* match the site's card radius */
  --cbn-cta-radius: 2px;             /* match the site's button radius */
  --cbn-cta-transform: uppercase;    /* match the site's button typography */
  --cbn-cta-tracking: .14em;
  --cbn-ease: cubic-bezier(.25, .8, .25, 1);
  /* ---- end tokens ---- */

  overflow: hidden;
  background: var(--cbn-surface);
  border: 1px solid var(--cbn-border);
  border-radius: var(--cbn-radius);
  box-shadow: 0 20px 60px -16px rgba(0, 0, 0, .25), 0 2px 8px rgba(0, 0, 0, .06);
  display: none;
  opacity: 0;
  position: fixed;
  right: 24px;
  top: 340px; /* adjust so it never covers the site's booking bar / header CTAs */
  transform: translateY(-20px);
  transition: transform .45s var(--cbn-ease), opacity .45s var(--cbn-ease);
  width: min(380px, calc(100vw - 48px));
  z-index: 2900; /* above page chrome, below any cookie-consent overlay */
}
.booking-nudge.show { display: block; }
.booking-nudge.in { opacity: 1; transform: translateY(0); }

.bn-accent { background: linear-gradient(90deg, var(--cbn-accent), var(--cbn-accent-2)); height: 3px; left: 0; position: absolute; right: 0; top: 0; }

.bn-header { align-items: flex-start; display: flex; gap: 12px; justify-content: space-between; padding: 20px 24px 0; }
.bn-name { color: var(--cbn-ink); font-family: var(--cbn-font-display); font-size: 22px; font-weight: 400; letter-spacing: .01em; line-height: 1.25; }
.bn-close { align-items: center; background: transparent; border: 1px solid var(--cbn-border); border-radius: 50%; color: var(--cbn-muted); cursor: pointer; display: flex; flex-shrink: 0; height: 32px; justify-content: center; transition: all .3s var(--cbn-ease); width: 32px; }
.bn-close:hover { background: var(--cbn-ink); border-color: var(--cbn-ink); color: #fff; transform: rotate(90deg); }
.bn-close svg { height: 12px; width: 12px; }

.bn-body { padding: 12px 24px 20px; }
.bn-subtitle { color: var(--cbn-muted); font-family: var(--cbn-font-body); font-size: 14px; font-weight: 300; line-height: 1.6; margin-bottom: 4px; }
.bn-property { color: var(--cbn-accent); font-family: var(--cbn-font-display); font-size: 18px; font-weight: 400; letter-spacing: .01em; }
.bn-price { color: var(--cbn-muted); display: none; font-family: var(--cbn-font-body); font-size: 12px; font-weight: 300; line-height: 1.5; margin-top: 8px; }
.bn-price.loaded { display: block; }
.bn-price .price-msg { color: var(--cbn-accent); font-family: var(--cbn-font-display); font-size: 20px; font-weight: 500; }
.bn-price .general-msg { color: var(--cbn-muted); font-size: 12px; }

.bn-actions { align-items: center; display: flex; gap: 12px; padding: 0 24px 20px; }
.bn-cta { align-items: center; background: var(--cbn-cta-bg); border: 1px solid var(--cbn-cta-bg); border-radius: var(--cbn-cta-radius); color: var(--cbn-cta-ink); display: inline-flex; font-family: var(--cbn-font-body); font-size: 12px; font-weight: 400; gap: 8px; letter-spacing: var(--cbn-cta-tracking); padding: 12px 28px; text-decoration: none; text-transform: var(--cbn-cta-transform); transition: all .35s var(--cbn-ease); }
.bn-cta:hover { background: var(--cbn-cta-hover); border-color: var(--cbn-cta-hover); }
.bn-cta:after { background: currentColor; content: ""; height: 1px; transition: width .3s var(--cbn-ease); width: 14px; }
.bn-cta:hover:after { width: 20px; }

@media (max-width: 600px) {
  .booking-nudge { border-radius: 8px; left: auto; right: 12px; top: 320px; width: calc(100vw - 24px); }
  .bn-header { padding: 16px 18px 0; }
  .bn-body { padding: 10px 18px 16px; }
  .bn-actions { padding: 0 18px 16px; }
  .bn-name { font-size: 19px; }
  .bn-property { font-size: 16px; }
}
