@import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,600;0,700;1,400&family=Cormorant+Garamond:wght@400;500&display=swap");


@import url("https://fonts.googleapis.com/css2?family=Spinnaker&family=Inter:wght@300;400;500;600&display=swap");


/* base tokens */
/* =====================================================================
 * tokens.css — global CSS custom properties (design tokens).
 * =====================================================================
 *
 * These are the variables every styled component reads via `var(...)`.
 * Defaults here are NEUTRAL — every hotel's specific palette comes
 * from its brand record, applied at runtime when the brand store
 * resolves.
 *
 * Future agents:
 *   · Add a new token here only if it's used across multiple
 *     components. Single-component values stay scoped to that
 *     component's <style scoped>.
 *   · Token names follow `--site-<group>-<role>` (e.g.
 *     `--site-color-fg`, `--site-radius-md`). Stable so brand-
 *     application logic can map onto them deterministically.
 *   · The brand store doesn't yet write into these — that wiring
 *     gets added when the first styled section lands.
 */
:root {
  /* The token NAMES match what services/theme.js writes. Defaults
     here are neutral — every hotel's actual palette comes from its
     brand record at runtime. */
  --site-color-bg:        #fbf9f5;
  --site-color-bg-rgb:    251, 249, 245;  /* used for translucent overlays */
  --site-color-fg:        #1a1815;
  --site-color-fg-muted:  #6b665e;
  --site-color-accent:    #1a1815;
  --site-color-accent-fg: #fbf9f5;
  --site-color-border:    #e3ddd2;

  --site-font-display: system-ui, -apple-system, sans-serif;
  --site-font-body:    system-ui, -apple-system, sans-serif;

  --site-radius-sm:    2px;
  --site-radius-md:    6px;
  --site-radius-lg:    14px;

  /* COOKIE NOTICE tokens — what a GROUP's shared notice is drawn with. Follows
     the fallback chain of the SDK's own notice (components/consent/consent.css),
     so a shared notice and the settings panel it opens match on every hotel. */
  --site-notice-bg:           var(--consent-bg, var(--site-color-surface, var(--site-color-bg)));
  --site-notice-fg:           var(--consent-fg, var(--site-color-fg));
  --site-notice-muted:        color-mix(in srgb, var(--site-notice-fg) 68%, transparent);
  --site-notice-accent:       var(--consent-accent, var(--site-color-accent, var(--site-notice-fg)));
  --site-notice-on-accent:    var(--consent-on-accent, var(--site-color-on-accent, var(--site-notice-bg)));
  --site-notice-rule:         color-mix(in srgb, var(--site-notice-fg) 14%, transparent);
  --site-notice-radius:       var(--consent-radius, var(--site-radius, 14px));
  --site-notice-font-display: var(--site-font-display);
  --site-notice-font-body:    var(--site-font-body);

  /* FOOTER tokens — the surface a GROUP's shared footer is drawn with
     (settings `shared_components`). One footer is written once and linked to
     every site of a group, so it may read nothing a theme invents for itself
     (`--hdt-*`, `--bab-*`, literal hex) — only these. Each falls back to the
     site's general palette and type, so a theme that sets none of them still
     gets a footer in its own colours; a theme that wants its footer ground or
     link colour exact sets the token in its own `tokens.css`. */
  --site-footer-bg:           var(--site-color-fg);
  --site-footer-fg:           var(--site-color-bg);
  --site-footer-muted:        color-mix(in srgb, var(--site-footer-fg) 68%, transparent);
  --site-footer-link:         var(--site-footer-fg);
  --site-footer-accent:       var(--site-color-accent);
  --site-footer-rule:         color-mix(in srgb, var(--site-footer-fg) 18%, transparent);
  --site-footer-font-display: var(--site-font-display);
  --site-footer-font-body:    var(--site-font-body);
  --site-footer-logo-h:       44px;
  /* A texture laid behind the footer (a shared footer's `ground` media): how
     strongly it shows, and the size one tile is drawn at. */
  --site-footer-texture-opacity: 0.18;
  --site-footer-texture-size:    480px;

  /* ⚠️ A SEED, NOT A MEASUREMENT. `App.vue` measures the real bar after mount
     and overwrites this on :root, along with `--site-header-reserve` — what
     the shell actually pads by, which is 0 for a bar in flow. Kept only so
     rules that read it before first measurement have a sane number. */
  --site-header-h:     76px;
  --site-header-reserve: 0px;

  /* ===================================================================
   * STRUCTURAL tokens — the theme's visual RHYTHM, not just its palette.
   * ===================================================================
   *
   * These extend the stable `--site-*` surface beyond colour/font/radius
   * so the LOCKED booking pages (BookView / CheckoutView / Confirmation)
   * can inherit a theme's FULL visual language — type scale, spacing,
   * elevation, and motion — instead of looking like a generic recolour.
   *
   * Defaults here are deliberately NEUTRAL (a clean, calm shell). Each
   * generated theme's `theme/tokens.css` MAPS its bespoke scale onto
   * these names (see the design-tokens skill) so the booking surface
   * picks up the same rhythm as the rest of the site. Setting these is
   * additive + backward-compatible: a theme that sets none of them still
   * renders correctly on the neutral defaults below.
   *
   * As with colours, the names are STABLE so theme-application logic can
   * map onto them deterministically.
   */

  /* --- Type scale ---------------------------------------------------
   * Display sizes for hero/section headings, body sizes for prose +
   * controls. Fluid `clamp()` so the neutral shell reads well at any
   * width; a theme overrides with its own step ladder. */
  --site-font-size-display-xl: clamp(2.25rem, 5vw, 3.5rem);
  --site-font-size-display-lg: clamp(1.75rem, 3.5vw, 2.5rem);
  --site-font-size-display-md: clamp(1.25rem, 2vw, 1.5rem);
  --site-font-size-body-lg:    1.0625rem;
  --site-font-size-body:       0.9375rem;
  --site-font-size-body-sm:    0.8125rem;

  --site-line-height-display:  1.1;
  --site-line-height-body:     1.55;

  --site-letter-spacing-tight:  -0.01em;
  --site-letter-spacing-normal: 0;

  /* --- Spacing ladder ----------------------------------------------
   * A geometric-ish step used for gaps, padding, and rhythm. Themes
   * remap to their own gutter/section scale. */
  --site-space-xs: 0.5rem;
  --site-space-sm: 0.75rem;
  --site-space-md: 1.25rem;
  --site-space-lg: 2rem;
  --site-space-xl: 3rem;

  /* --- Elevation ----------------------------------------------------
   * Soft, neutral shadows. Themes supply brand-tinted equivalents. */
  --site-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --site-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.10);

  /* --- Motion -------------------------------------------------------
   * One easing + one base duration the locked pages reach for on
   * transitions. Themes set their committed curve/timing here so the
   * booking surface moves with the same feel as the rest of the site. */
  --site-ease:     cubic-bezier(0.22, 1, 0.36, 1);
  --site-duration: 240ms;

  /* --- Legacy / alternate token vocabulary (backward-compat) --------
   * Some generated themes' components were authored against an older
   * --site-* naming scheme — a NUMERIC spacing scale (--site-space-1..6)
   * and --site-text-*/--site-track-*/--site-leading-*/--site-dur-* names —
   * rather than the named scale above. When a component reaches for a name
   * not defined anywhere, that custom property resolves to NOTHING and the
   * declaration is dropped (e.g. `gap: clamp(var(--site-space-3),…)` becomes
   * `normal` → a nav with no spacing; `font-size: var(--site-text-h1)` falls
   * back to 16px → collapsed type). Aliasing the legacy names onto the canonical
   * tokens here — the always-loaded base — keeps EVERY component resolving
   * regardless of which vocabulary it was generated against. Purely additive;
   * themes built on the named scale are unaffected. */
  --site-space-1: var(--site-space-xs);
  --site-space-2: var(--site-space-sm);
  --site-space-3: var(--site-space-md);
  --site-space-4: var(--site-space-lg);
  --site-space-5: var(--site-space-xl);
  --site-space-6: var(--site-space-xl);

  --site-text-hero:    var(--site-font-size-display-xl);
  --site-text-display: var(--site-font-size-display-xl);
  --site-text-h1:      var(--site-font-size-display-lg);
  --site-text-h2:      var(--site-font-size-display-md);
  --site-text-h3:      var(--site-font-size-display-md);
  --site-text-lead:    var(--site-font-size-body-lg);
  --site-text-body:    var(--site-font-size-body);
  --site-text-strong:  var(--site-font-size-body);
  --site-text-muted:   var(--site-font-size-body);
  --site-text-sm:      var(--site-font-size-body-sm);
  --site-text-label:   var(--site-font-size-body-sm);
  --site-text-caption: var(--site-font-size-body-sm);
  --site-text-micro:   var(--site-font-size-body-sm);

  --site-leading-tight: var(--site-line-height-display);
  --site-leading-snug:  1.25;
  --site-leading-body:  var(--site-line-height-body);

  --site-track-tight: var(--site-letter-spacing-tight);
  --site-track-caps:  0.08em;
  --site-track-label: 0.12em;
  --site-track-cta:   0.04em;
  --site-track-wide:  0.16em;

  --site-dur-fast: 160ms;
  --site-dur-base: var(--site-duration);
  --site-dur-slow: 420ms;

  --site-radius-none: 0;
  --site-radius-xs:   3px;
  --site-bar-h:       var(--site-header-h);
  --site-max:         1200px;
  --site-hairline-w:  1px;
}

/* =====================================================================
 *  Base typography wiring.
 *
 *  Every visible character on the site reads its font through these
 *  cascaded rules — so flipping `--site-font-*` (which the brand
 *  store does at runtime) instantly changes the font everywhere
 *  without component-by-component overrides.
 *
 *    body, p, button, input, select, textarea  →  --site-font-body
 *    h1..h4                                    →  --site-font-display
 *
 *  Components that want to OPT INTO display type for non-heading
 *  text should add `font-family: var(--site-font-display)` on the
 *  relevant selector (e.g. drawer links). Components that want a
 *  different family for ONE element can override locally. The rule
 *  below establishes the right defaults so ad-hoc overrides are
 *  rare.
 * ===================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

html, body, #app { margin: 0; padding: 0; min-height: 100%; }

body {
  background: var(--site-color-bg);
  color: var(--site-color-fg);
  font-family: var(--site-font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Headings always pull from the display family (Bebas Neue / Fraunces /
   etc., depending on the hotel). If a hotelier picks the same family
   for both display + body, the variable resolves the same way and
   nothing visually changes. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--site-font-display);
  margin: 0;
}

/* Form controls don't inherit font-family by default — wire them
   explicitly so brand fonts apply to inputs, buttons, etc. */
button, input, select, textarea { font: inherit; }

img, video, svg { max-width: 100%; display: block; }
img, video { height: auto; }

/* Preserve author line breaks in CMS prose.
 *
 * Room / amenity / event descriptions, summaries, "the space", etc. are
 * entered in dashboard textareas where newlines are meaningful. HTML's
 * default `white-space: normal` collapses those newlines into spaces, so
 * paragraph breaks the hotelier typed vanished on the live site.
 *
 * `pre-line` behaves EXACTLY like `normal` (collapses runs of spaces,
 * wraps long lines) except it keeps newlines — so this is a no-op for
 * any text without literal line breaks (price rows, labels, button text)
 * and only restores breaks in author-entered prose. Vue's template
 * compiler condenses static whitespace, so the only newlines reaching a
 * text node come from interpolated data — exactly what we want to keep.
 *
 * Scoped to prose-bearing elements (paragraphs + the SDK/theme prose
 * class roles). Components that pin their own white-space (nowrap on
 * price chips, pre-wrap elsewhere) load after this and win. */
p,
[class*="__prose"],
[class*="__description"],
[class*="__lede"],
[class*="__summary"],
[class*="__highlight-body"] {
  white-space: pre-line;
}

a { color: inherit; text-decoration: none; }

/* Minimal global reset so the empty homepage doesn't show a blank
   white page with default browser margins. Section components are
   responsible for their own spacing and type — keep this lean. */
*,
*::before,
*::after { box-sizing: border-box; }
html, body, #app { margin: 0; padding: 0; min-height: 100%; }
html.seo-hub body { background: var(--site-color-bg); }
body {
  background: var(--site-bg);
  color: var(--site-fg);
  font-family: var(--site-font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


/* theme tokens */
/* ==========================================================================
   FONT BRIDGE — must stay the FIRST rule in this file (@import is only
   valid before any other rule).

   The SDK injects the BRAND record's Google Fonts href, not this theme's
   fonts.js, so Spinnaker and Inter were never fetched at all and the
   families below silently fell back to system-ui. Importing them here is
   what actually gets the faces onto the page.
   ========================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Spinnaker&family=Inter:wght@300;400;500;600&display=swap');

/* ==========================================================================
   BLUE APPLE BEACH · Tierra Bomba, Cartagena
   Design tokens — single source of truth for colour + type.

   Calibrated 2026-08-08 against a live DOM measurement of the operator's
   own site, blueapplebeach.com (Playwright, 1440x960). Every value below
   that carries a "src:" note was read off that page, not eyeballed.

   The LOCKED palette the hotelier supplied already matched the live site
   almost exactly, so it is carried verbatim. Two tokens are NEW because
   the live site paints two things the locked set has no name for (the dark
   booking strip and the body-copy ink); both are noted as such.
   ========================================================================== */

:root{

  /* ---------- palette · "ten shades, one island" (LOCKED core) ---------- */
  /* Nº 01 — Midnight Crossing · headlines, nav ink, quote band, inverted CTA
     src: rgb(49,65,110) — nav links, every section heading, the Condé Nast band */
  --site-color-accent: #31416e;

  /* Nº 02 — Salt-Washed Sky · the site's signature full-bleed band, and soft
     tints: underlines, frames, ghost rules. A WASH, never body text on white.
     src: rgb(195,207,223) — 2.7M px² of painted area, second only to white */
  --site-color-fg: #c3cfdf;

  /* Nº 03 — Bleached Linen · the page itself
     src: rgb(255,255,255) — 25.2M px², the dominant ground */
  --site-color-bg: #ffffff;

  /* Nº 09 — Driftwood · captions, eyebrows-at-rest, tertiary prose */
  --site-color-muted: #76839c;

  /* Nº 10 — Shell Line · every hairline and field border */
  --site-color-border: #dde4ee;

  /* ---------- extended island shades (from the chosen palette) ---------- */
  /* Nº 04 — Tierra Bomba Clay · the accolade band
     src: rgb(228,191,174) */
  --site-color-secondary-bg: #e4c0af;

  /* Nº 05 — Frangipani · small flourishes ONLY, never a large field
     src: rgb(218,110,142) — the "Things to do here" link */
  --site-color-secondary-button-colour: #da6e8e;

  /* Nº 06 — Chef's Garden · THE ask: book the boat, stay the night
     src: rgb(72,94,54) — the SPOTIFY US / BOOK A ROOM buttons */
  --site-color-button-colour: #495f37;

  /* Nº 07 — Sea Grape · tertiary background wash
     src: rgb(192,204,154) — the Biodiversity band */
  --site-color-x-bg-3: #c0cc9a;

  /* Nº 08 — Palm Shade · deep-green panels, primary-button hover anchor
     src: rgba(101,119,53,.9) — the Sustainability panel laid over photography */
  --site-color-box-colour: #647834;

  /* ---------- NEW · roles the live site paints that the locked set
       has no name for. Added rather than re-purposing a locked role. ------ */

  /* Booking strip · the persistent dark bar above the logo bar
     src: the #SITE_HEADER html-component strip */
  --site-color-bar: #3d3d3d;

  /* Body ink · what nearly every paragraph on the live site is actually set in.
     src: rgb(84,92,116). Sits between --site-color-accent and --site-color-muted;
     using --site-color-muted for body would be a shade too pale to read at size. */
  --site-color-body-ink: #545c74;

  /* Body ink on the pale-blue band, where the live site lightens it
     src: rgb(143,163,191) */
  --site-color-body-ink-on-wash: #8fa3bf;

  /* ---------- type scale ----------
     The live site sets headings at 20/26–28 and body at 14/19.6 — genuinely
     small for a 1440 viewport. Lifted one notch here (headings ~26, body ~16,
     leading 1.65) as the agreed modernisation; the RATIOS and the tracking
     discipline are unchanged, so the page still reads as the same site. */
  --site-h1:      clamp(1.375rem, 1.15rem + 0.7vw, 1.625rem);  /* 22 → 26 */
  --site-h1-lh:   1.3;
  --site-h2:      clamp(1.25rem, 1.1rem + 0.5vw, 1.4375rem);   /* 20 → 23 */
  --site-h2-lh:   1.32;
  --site-body:    clamp(0.9375rem, 0.9rem + 0.2vw, 1rem);      /* 15 → 16 */
  --site-body-lh: 1.65;
  --site-small:   clamp(0.75rem, 0.72rem + 0.12vw, 0.8125rem); /* 12 → 13 */
  --site-micro:   0.6875rem;                                    /* 11 — footer */

  /* Buttons carry the live site's tracked small-caps voice.
     src: 10px/1px and 14px/3.5px → ~0.1em–0.25em; settled at 0.16em. */
  --site-track-btn: 0.16em;
  --site-track-eyebrow: 0.2em;

  /* ---------- measure ----------
     src: the live content column is 980px, centred, with full-bleed photo
     bands breaking out to the viewport. Widened a touch to 1040. */
  --site-col: 1040px;
  --site-col-wide: 1240px;
  --site-gutter: clamp(1.25rem, 4vw, 3rem);
  --site-band-y: clamp(3rem, 6vw, 5.5rem);

  /* ---------- app-shell reserve ----------
     This theme's header is IN-FLOW — it occupies its own space and
     scrolls away, exactly like the operator's own site — so the shell
     reserves nothing above or beside the page. */
  --site-header-h: 0px;
  --site-header-w: 0px;
}

/* ==========================================================================
   TYPE FAMILIES — declared LAST and with !important, deliberately.

   The brand store writes the hotelier's locked brand fonts as an INLINE
   style attribute on <html> at boot. An inline declaration beats any
   ordinary stylesheet rule, so a plain `:root { --site-font-display: … }`
   here is silently discarded and every surface renders in the brand
   record's Open Sans / Cormorant Garamond instead.

   The families below are the ones the operator's own site actually uses,
   measured off blueapplebeach.com: Spinnaker for every heading, nav item
   and button (57 text nodes), Helvetica Neue Light for body copy (38).
   Helvetica Neue is not a webfont — Apple devices get the real face,
   everyone else falls to Inter, the nearest widely-available grotesque.
   ========================================================================== */
:root {
  --site-font-display: Spinnaker, 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
  --site-font-body: 'Helvetica Neue', HelveticaNeue, Inter, Helvetica, Arial, sans-serif !important;
}

/* [preview] baseline motion tokens (brand book omitted these — keeps reveal animations from hiding content) */
:root {
  --site-duration-reveal: 700ms;
  --site-duration-slow: 600ms;
  --site-duration: 320ms;
  --site-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --site-ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --site-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --site-stagger: 80ms;
  --site-reveal-distance: 24px;
}

/* ==========================================================================
   GLOBAL SDK-SURFACE OVERRIDES — relocated here from SiteFooter.vue's
   unscoped <style> block (2026-09-03): the concierge dock (`aside.cl`)
   and the /book funnel (`.j17-book`) are SDK-rendered outside any theme
   component's scope, so their overrides belong in this global sheet.
   ========================================================================== */

/* ── concierge parking (2026-08-16, Tiger) ──────────────────────────
   `data-bab-page-end` is stamped on <html> by SiteFooter's scroll
   listener the instant the page is FULLY scrolled, and removed the
   instant it is not. The SDK's `aside.cl` is a fixed, centred pill
   (left:50% + translateX(-50%)); parked, it hugs the right-hand
   corner so it stops covering the footer. */
html[data-bab-page-end] aside.cl {
  left: auto !important;
  right: 24px !important;
  transform: none !important;
}
@media (max-width: 720px) {
  html[data-bab-page-end] aside.cl {
    right: 12px !important;
  }
}

/* ── booking funnel: THE RESULTS BAR STAYS ──────────────────────────
   ⚠️ 2026-08-23 this file hid `.j17-book__sortbar` to be rid of the
   "FILTERS … n options" strip. That class is NOT the filter bar — it is
   the RESULTS bar: the option count, the Sort control, and on a phone
   the only way into the filters (`BookView.vue::entryInResultsBar`).
   So the strip stayed and the SORT went away: guests got this hotel's
   `default_sort` (price, high to low) with no control to change it, and
   at 390px no filters at all. Unscoped + `!important`, it beat
   BookView's own scoped `display: flex` and nothing could win it back.
   The second selector, `.j17-book__mobile-bar`, matches no element in
   the funnel at all.

   Removed 2026-09-17. The filter band is `.j17-book__filterbar`; if it
   is still unwanted, switch those filters off in the booking-page
   settings — BookView gates its own filter chrome on `hasPanelFilters`
   and draws nothing when there is nothing to filter. Do not re-add a
   CSS override here. */

/* ── booking cards: footer must never overlap (Tiger, 2026-08-27) ───
   The card foot is a nowrap flex row; the Spanish CTA ("Agregar a la
   estadía") is wide and unshrinkable, so it crushed the price/policy
   column to a 23px sliver and painted over its text. Let the row WRAP
   when the CTA doesn't fit, and stack it cleanly on phones. */
.j17-book .j17-book-card__foot {
  flex-wrap: wrap !important;
  gap: 12px !important;
}
.j17-book .j17-book-card__price {
  flex: 1 1 180px !important;
  min-width: 0 !important;
}
.j17-book .j17-book-card__cta {
  flex: 0 1 auto !important;
  max-width: 100% !important;
}
@media (max-width: 720px) {
  .j17-book .j17-book-card__foot {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .j17-book .j17-book-card__cta {
    width: 100% !important;
    justify-content: center !important;
  }
}

/* ── /book date picker: real ink, not the sky wash (Tiger, 2026-09-23) ──
   The SDK's J17DateRangePicker (`.j17-dp`; its menu is teleported to
   <body>) derives EVERY colour from --site-color-fg / --site-color-fg-muted,
   and on this brand both resolve to Salt-Washed Sky (#c3cfe0) — a WASH,
   never an ink — so the day numerals painted at ~1.6:1 on white, the
   weekday row at 48% of that and past days at 22%. Re-point the picker's
   own token layer at Midnight Crossing, exactly as the theme's
   DateRangePicker.vue does. The SDK rule is scoped (class + data-v attr,
   0,2,0) so the custom properties need !important to win from here. */
.j17-dp,
.j17-dp__menu {
  --j17-dp-ink: var(--site-color-accent, #31416e) !important;
  --j17-dp-ivory: #ffffff !important;
  --j17-dp-stone: #76839c !important;
  --j17-dp-hairline: color-mix(in srgb, var(--site-color-accent, #31416e) 16%, transparent) !important;
  --j17-dp-hairline-strong: color-mix(in srgb, var(--site-color-accent, #31416e) 32%, transparent) !important;
  --j17-dp-tint: color-mix(in srgb, var(--site-color-accent, #31416e) 9%, transparent) !important;
  --j17-dp-tint-strong: color-mix(in srgb, var(--site-color-accent, #31416e) 16%, transparent) !important;
}
/* The rows the SDK paints as translucent ink were still too faint even
   over navy: solid Driftwood for the weekday labels, 42% navy for the
   adjacent-month / past days, 75% navy for the month arrows. */
.j17-dp__menu .j17-dp__dow li {
  color: #76839c !important;
}
.j17-dp__menu .j17-dp__cell--outside .j17-dp__cell-btn,
.j17-dp__menu .j17-dp__cell--disabled .j17-dp__cell-btn {
  color: color-mix(in srgb, var(--site-color-accent, #31416e) 42%, transparent) !important;
}
.j17-dp__menu .j17-dp__nav {
  color: color-mix(in srgb, var(--site-color-accent, #31416e) 75%, transparent) !important;
}


/* brand */
/* bab/brand.css — synthesized GLOBAL finish layer.
 *
 * Global refinements (selection, focus, scrollbar, smoothing) + an
 * OPT-IN texture & editorial-fixture toolkit. Components add the
 * `bab-*` utility classes where the manifest's material direction
 * calls for them. Loaded globally by src/main.js after tokens.css.
 */

/* ── Universal polish — pure upside, applies everywhere ─────────── */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
::selection {
  background: var(--site-color-accent);
  color: var(--site-color-accent-fg);
}
:focus-visible {
  outline: 2px solid var(--site-color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--site-color-fg) 24%, transparent) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--site-color-fg) 22%, transparent);
  border-radius: 999px;
  border: 3px solid var(--site-color-bg);
}
img { -webkit-user-drag: none; user-select: none; }

:root {
  /* Elevation — soft, brand-tinted shadows (depth without harsh black) */
  --bab-shadow-sm: 0 1px 2px color-mix(in srgb, var(--site-color-fg) 8%, transparent);
  --bab-shadow-md: 0 8px 24px -8px color-mix(in srgb, var(--site-color-fg) 22%, transparent);
  --bab-shadow-lg: 0 30px 60px -24px color-mix(in srgb, var(--site-color-fg) 32%, transparent);
  --bab-grain-opacity: 0.045;
}

/* ── OPT-IN texture: film grain ──────────────────────────────────────
 * TWO forms. `bab-grain` puts grain on a section band via ::after
 * (the host must be a normal box — NEVER an <img>/<video>: replaced
 * elements have no ::after, so grain on them renders NOTHING).
 * `bab-grain-overlay` is an explicit absolute layer you place as
 * the LAST child inside a position:relative media host (e.g. over a
 * hero photo) — use this for imagery, never the ::after form. */
.bab-grain { position: relative; }
.bab-grain::after,
.bab-grain-overlay {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  opacity: var(--bab-grain-opacity, 0.045);
  mix-blend-mode: overlay;
}

/* ── OPT-IN imagery treatment: per-brand grade + hover lift + frame ──
 * The grade is synthesized from the manifest (imagery_treatment +
 * color_philosophy) so it's bespoke, not a global preset. A faint inset
 * hairline frames photos so they read placed, not pasted. */
.bab-img-grade {
  filter: sepia(0.08) saturate(1.02) contrast(0.99) brightness(1.01);
  transition: filter var(--bab-dur-slow, 600ms) var(--bab-ease, ease),
              transform var(--bab-dur-slow, 900ms) var(--bab-ease, ease);
}
.bab-img-grade:hover { filter: saturate(1.02) contrast(1.0); }
.bab-img-frame { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--site-color-fg) 9%, transparent); }
.bab-img-zoom { overflow: hidden; }
.bab-img-zoom > img { transition: transform 1200ms var(--bab-ease, cubic-bezier(0.22,1,0.36,1)); will-change: transform; }
@media (prefers-reduced-motion: no-preference) {
  .bab-img-zoom:hover > img { transform: scale(1.04); }
}
/* Real duotone — desaturate the image, then wash ink->accent over it via
 * a blended overlay on a relative wrapper (NOT a filter, so it tints). */
.bab-img-duotone { position: relative; overflow: hidden; }
.bab-img-duotone > img { filter: grayscale(1) contrast(1.05); display: block; width: 100%; height: 100%; object-fit: cover; }
.bab-img-duotone::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--site-color-accent) 38%, transparent),
    color-mix(in srgb, var(--site-color-fg) 46%, transparent));
  mix-blend-mode: multiply;
}

/* ── Editorial fixtures — the small marks that read "designed" ──── */
.bab-dropcap::first-letter {
  float: left;
  font-family: var(--site-font-display);
  font-size: 3.4em;
  line-height: 0.72;
  padding: 0.06em 0.12em 0 0;
  color: var(--site-color-accent);
}
.bab-pullquote {
  font-family: var(--site-font-display);
  font-size: clamp(1.4rem, 3.5vw, 2.25rem);
  line-height: 1.2;
  font-style: italic;
  padding-left: clamp(1rem, 3vw, 2rem);
  border-left: 2px solid var(--site-color-accent);
  color: var(--site-color-fg);
}
.bab-figcaption {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.6rem;
  font-family: var(--bab-mono, ui-monospace, monospace);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--site-color-fg-muted);
}
.bab-figcaption::before {
  content: "";
  width: 1.5rem;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}
.bab-eyebrow {
  font-family: var(--bab-mono, var(--site-font-body));
  font-size: 0.72rem;
  letter-spacing: var(--bab-track-eyebrow, 0.14em);
  text-transform: uppercase;
  color: var(--site-color-fg-muted);
}
/* Tabular figures — self-contained: serif display faces (Fraunces,
 * Newsreader…) often lack tnum, so force the mono stack which always has
 * it. Use on prices, dates, counts, room numbers. */
.bab-tnum {
  font-family: var(--bab-mono, ui-monospace, monospace);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Considered link underline — grows from the baseline on hover, not the
 * browser default. Reach for this on body/inline links. */
.bab-underline-link {
  color: var(--site-color-accent-strong, var(--site-color-accent));
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0% 1px;
  transition: background-size var(--bab-dur, 320ms) var(--bab-ease, ease);
  padding-bottom: 1px;
}
.bab-underline-link:hover { background-size: 100% 1px; }
/* Minimum touch target — wrap small tap affordances (icon buttons, nav
 * links) so mobile hit areas clear 44px. */
.bab-tap { min-height: var(--bab-tap, 44px); min-width: var(--bab-tap, 44px); display: inline-flex; align-items: center; justify-content: center; }
/* Staggered children — set style="--i:0|1|2…" per child. */
@media (prefers-reduced-motion: no-preference) {
  .bab-stagger > * { animation: bab-rise var(--bab-dur-slow, 640ms) var(--bab-ease, ease) both; animation-delay: calc(var(--i, 0) * 90ms); }
}
/* Animated disclosure (accordion) — grid-rows trick, no JS height math,
 * no hard snap. Toggle the `is-open` class. Calm boutique sites never
 * hard-cut a FAQ open/closed. */
.bab-disclosure { display: grid; grid-template-rows: minmax(0, 0fr); transition: grid-template-rows var(--bab-dur, 320ms) var(--bab-ease, ease); }
.bab-disclosure.is-open { grid-template-rows: minmax(0, 1fr); }
.bab-disclosure > * { overflow: hidden; min-height: 0; }
@media (prefers-reduced-motion: reduce) { .bab-disclosure { transition: none; } }

/* ── Readability helpers ────────────────────────────────────────── */
/* Cap line length for body copy — long measures kill readability. */
.bab-measure { max-width: 68ch; }
/* A guaranteed-legible scrim for text laid over imagery. Put on the
 * media wrapper, behind the text, so headlines never sit on raw photo. */
.bab-text-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--site-color-fg) 62%, transparent) 0%,
    color-mix(in srgb, var(--site-color-fg) 30%, transparent) 38%,
    transparent 70%
  );
}

/* ── Safe entrance — CSS-only, auto-plays on load, ALWAYS ends visible.
 * Use this INSTEAD of `opacity:0` + IntersectionObserver: a JS observer
 * that doesn't fire leaves content invisible forever (reads as broken).
 * Under reduced-motion the rule is dropped and content is simply
 * visible. Keep it to a FEW elements per page — not every node. ── */
@media (prefers-reduced-motion: no-preference) {
  .bab-rise { animation: bab-rise 640ms var(--bab-ease, cubic-bezier(0.22,1,0.36,1)) both; }
  .bab-rise-2 { animation-delay: 90ms; }
  .bab-rise-3 { animation-delay: 180ms; }
  @keyframes bab-rise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ── Rhythm & flow — one continuous scroll, not stacked blocks ───── */
/* Every section breathes on the SAME vertical rhythm so the page reads
 * as a single composition. Use these instead of ad-hoc margins. */
.bab-section { padding-block: var(--bab-section-y, clamp(4rem, 10vw, 8rem)); }
.bab-section--tight { padding-block: calc(var(--bab-section-y, 6rem) * 0.55); }
.bab-section--flush-next { padding-bottom: 0; }
/* A breathing hairline divider — soft section break without a hard cut. */
.bab-divider {
  height: 1px;
  border: 0;
  margin: 0 var(--bab-gutter, 2rem);
  background: var(--bab-hairline, color-mix(in srgb, var(--site-color-fg) 12%, transparent));
}
/* Color-block transition that BLEEDS into the next section (overlap),
 * so adjacent bands flow rather than butt up against each other. */
.bab-bleed-top { margin-top: calc(var(--bab-section-y, 6rem) * -0.4); padding-top: calc(var(--bab-section-y, 6rem) * 0.9); }

/* ── Form block labels ──────────────────────────────────────────────
 * The platform's form block paints its labels with `--site-color-fg`.
 * On this site that role is a PALE WASH (#c3cfdf, the colour of the
 * channel band), so on white every label measured 1.58:1 and read as
 * placeholder text at best. Re-point the role for the form, exactly as
 * concierge/skin.css does for the same reason.
 *
 * Wherever a form block is used — contact, the residency application —
 * the label is the only thing telling someone what to type.
 *
 * The component resolves its label ink as
 *   --site-form-label-ink → --site-color-fg-muted → --site-color-fg,
 * and this site defines neither of the first two, so it lands on the wash.
 * `--site-form-label-ink` is the component's own hook, so set that rather
 * than fighting its scoped styles on specificity. */
:root { --site-form-label-ink: #31416e; }


/* theme skin */
/* ==========================================================================
   FONT BRIDGE — must stay the FIRST rule in this file (@import is only
   valid before any other rule).

   Duplicated from tokens.css ON PURPOSE. `theme/tokens.css` and
   `theme/fonts.js` are recomposed server-side from the stored design graph
   on some builds, which silently discards anything added to them. This
   file is preserved verbatim and loaded on every route, so it is where the
   type actually has to be nailed down.
   ========================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Spinnaker&family=Inter:wght@300;400;500;600&display=swap');

/* ==========================================================================
   BLUE APPLE BEACH — durable token layer.

   Everything here is also declared in tokens.css, which stays the readable
   source of truth. These copies exist only to survive a tokens.css
   regeneration, and they carry !important for two reasons:
     · this file is bundled BEFORE tokens.css, so it would otherwise lose
       the cascade;
     · the brand store writes the locked font families as an INLINE style
       attribute on <html>, which beats any ordinary stylesheet rule.

   Values measured 2026-08-08 off the operator's own site,
   blueapplebeach.com (Playwright, 1440x960).
   ========================================================================== */
:root {
  /* type families — src: Spinnaker for headings/nav/buttons (57 nodes),
     Helvetica Neue Light for body (38). Helvetica Neue is not a webfont, so
     Apple devices get the real face and everyone else falls to Inter. */
  --site-font-display: Spinnaker, 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
  --site-font-body: 'Helvetica Neue', HelveticaNeue, Inter, Helvetica, Arial, sans-serif !important;

  /* roles the locked palette has no name for */
  --site-color-bar: #3d3d3d !important;              /* the dark booking strip */
  --site-color-body-ink: #545c74 !important;         /* what body copy is actually set in */
  --site-color-body-ink-on-wash: #8fa3bf !important; /* body ink on the pale-blue band */

  /* type scale — the source sets headings 20/26–28 and body 14/19.6;
     lifted one step here, ratios and tracking unchanged */
  --site-h1: clamp(1.375rem, 1.15rem + 0.7vw, 1.625rem) !important;
  --site-h1-lh: 1.3 !important;
  --site-h2: clamp(1.25rem, 1.1rem + 0.5vw, 1.4375rem) !important;
  --site-h2-lh: 1.32 !important;
  --site-body: clamp(0.9375rem, 0.9rem + 0.2vw, 1rem) !important;
  --site-body-lh: 1.65 !important;
  --site-small: clamp(0.75rem, 0.72rem + 0.12vw, 0.8125rem) !important;
  --site-micro: 0.6875rem !important;
  --site-track-btn: 0.16em !important;
  --site-track-eyebrow: 0.2em !important;

  /* measure — src: a 980px centred column, widened a touch */
  --site-col: 1040px !important;
  --site-col-wide: 1240px !important;
  --site-band-y: clamp(3rem, 6vw, 5.5rem) !important;
}

/* ==========================================================================
   THE BOOKING FUNNEL — readability fix, 2026-08-08.

   The locked funnel derives its INK from the brand palette:

       --j17-ink: var(--site-book-ink, var(--site-color-fg, #1a1815));

   This hotel's `--site-color-fg` is #c3cfe0 — a PALE WASH, the colour of
   the site's blue bands, not a text colour. With no override the funnel
   painted its own body copy, labels and rules in it: "Reserve" and
   "Continue" came out white-on-white at a contrast ratio of 1.0, and
   "Search availability" / "Filters" at 1.58. The page was unreadable.

   The SDK ships a documented escape hatch for exactly this — the
   `--site-book-*` / `--site-checkout-*` tokens — so the fix is to fill
   those in rather than to repurpose the brand role, which the content
   pages legitimately use as a band wash.

   The hero vignette is derived from the same ink, so it was a pale blue
   haze rather than a darkening; correcting the ink restored it too.

   `--site-book-accent-ink` is set EXPLICITLY because BookView's own
   comment warns that this hotel defines `--site-color-accent-fg` distinct
   from its surface, which would put invisible text on the accent button.

   NOTE — do NOT `display: none` the filter sidebar when it is empty. It is
   a GRID CHILD of `.j17-book__shell`; removing it collapses its track and
   the results re-flow into the sidebar's column (room copy squeezed to
   ~65px, words broken mid-syllable). Keep at least one filter enabled in
   the booking config instead. Tried and reverted here.
   ========================================================================== */
:root {
  /* /book */
  --site-book-ink: #31416e;            /* primary text — 9.9:1 on white */
  /* Secondary text. The funnel does NOT print this colour flat — it prints
     it at 0.7–0.8 alpha on the rate rows and legends, which is where the
     unreadable text was after the ink fix ("Non-refundable (stub)" 3.82,
     "2 rates available" 3.32, both under the 4.5 floor). #545c74 measured
     6.6:1 flat but only 3.8:1 once the funnel multiplied it down; #45506d
     is 8.0:1 flat, so it still clears AA at 0.8 alpha (4.74:1). Pick this
     value by what it measures COMPOSITED, not flat. */
  --site-book-muted: #45506d;
  --site-book-surface: #ffffff;
  --site-book-divider: #dde4ee;
  --site-book-card: #ffffff;
  --site-book-card-border: #dde4ee;
  --site-book-field-bg: #ffffff;
  --site-book-field-border: #dde4ee;
  --site-book-accent: #31416e;
  --site-book-accent-ink: #ffffff;
  /* the funnel's body sizes are 0.7–0.95rem; this brings them up to the
     rest of the site without re-laying the page out */
  --site-book-text-scale: 1.08;
  /* every heading on this site is caps — the funnel hero should be too */
  --site-book-hero-title-transform: uppercase;
  --site-book-hero-title-tracking: 0.02em;

  /* /checkout — same derivation, same trap */
  --site-checkout-ink: #31416e;
  --site-checkout-muted: #45506d;
  --site-checkout-surface: #ffffff;
  --site-checkout-divider: #dde4ee;
  --site-checkout-card: #ffffff;
  --site-checkout-card-border: #dde4ee;
  --site-checkout-field-bg: #ffffff;
  --site-checkout-field-border: #dde4ee;
  --site-checkout-accent-ink: #ffffff;
  --site-checkout-text-scale: 1.08;
}

/* Operator request 2026-08-15: no gradient over the /book hero photo.
   The funnel's shared masthead paints an ink-derived vignette
   (`.j17-about__hero-vignette`) over the image; its rules are scoped
   (`[data-v-…]`), so !important is required to beat them from here.
   Scoped under `.j17-book` so /stay and any other funnel page that
   shares the masthead keeps its vignette. */
.j17-book .j17-about__hero-vignette {
  background: none !important;
}

/* Operator request 2026-08-15: the /book hero should carry the title
   alone — no "A residence at …" eyebrow above it, no CONTINUE scroll
   cue. Same scoping + !important story as the vignette rule above. */
.j17-book .j17-about__eyebrow,
.j17-book .j17-about__hero-scrollcue {
  display: none !important;
}

/* Operator request 2026-08-16: the checkout masthead's eyebrow prints
   "№ Checkout · FINANCIAL DISTRICT · NEW YORK" — the SDK's DEMO
   dateline from the template hotel (this hotel sets none, and the
   checkout hero region override is not mounted by this SDK build, so
   the line is removed here). The masthead's title stays. */
.j17-checkout__eyebrow {
  display: none !important;
}

/* `/stay` and the confirmation receipt have NO `--site-*-ink` hatch — they
   read `--site-color-fg` straight. Re-point the ROLE on their own roots
   only, so every content page keeps it as the pale band wash. */
.stay,
.j17-confirm {
  --site-color-fg: #31416e;
}

/* The funnel justifies its prose. That is fine in the wide bands it was
   drawn for, but the room card's copy column is 487px and the room names
   are long compound Spanish words ("standalone bungalow cabañas"), so
   justification opens rivers right where a guest is comparing rooms.
   Ragged right only inside the funnel — the content pages keep the
   justified setting they were designed and signed off with.

   `!important` is required: the funnel's own rules are scoped
   (`.j17-book-card__summary[data-v-…]`), which outranks a bare class. */
.j17-book-card__summary,
.j17-book__group-intro,
.j17-book__note-body {
  text-align: left !important;
}

/* ==========================================================================
   CONTACT — the SDK block fallback, 2026-08-09.

   ContactView renders its own two headings ("Who to write to", "Send us a
   message") through its scoped `.h1`, but hands any OTHER block type to
   the SDK's HomepageBlock. The groups / buy-out / bespoke-events chapters
   go down that path, and HomepageBlock's own `.hp-block__title` measured
   36px in PURE BLACK with no capitalisation — against this page's 26px
   navy caps. Three headings in a different size, weight and colour from
   the two above them read as a different site.

   Styled here rather than in ContactView because the class belongs to the
   SDK component, not to the page; scoping under `.ct` (ContactView's own
   root) keeps it off every other route. Class names measured off the
   rendered DOM, never guessed — HomepageBlock's head markup is not
   documented.
   ========================================================================== */
.ct .hp-block__title {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-weight: 400;
  font-size: var(--site-h1, 1.625rem);
  line-height: var(--site-h1-lh, 1.3);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
}
.ct .hp-block__body,
.ct .hp-block__body p {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-weight: 300;
  font-size: var(--site-body, 1rem);
  line-height: var(--site-body-lh, 1.65);
  color: var(--site-color-body-ink, #545c74);
}

/* ==========================================================================
   Concierge widget skin — quiet and brand-true: navy ink launch bubble
   (the brand's structure), white panel on Shell Line hairlines.
   ========================================================================== */
.cl{
  --site-color-accent: #31416e;
  --site-color-on-accent: #ffffff;
  --site-color-bg: #ffffff;
  --site-color-fg: #31416e;
  --site-color-border: #dde4ee;

  /* the widget wears the site's own type, not the retired brand pairing */
  --site-font-display: Spinnaker, 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --site-font-body: 'Helvetica Neue', HelveticaNeue, Inter, Helvetica, Arial, sans-serif;

  /* Launch bubble — Midnight Crossing ink, white glyph, soft round */
  --concierge-fab-bg: #31416e;
  --concierge-fab-fg: #ffffff;
  --concierge-fab-radius: 50%;

  /* Chat panel — the residential 18px card corner */
  --concierge-panel-radius: 18px;
}


/* chrome components */

/* =====================================================================
   Tuning surface (law H6). A consumer may set any of these on the element
   it gives the class to; none of them re-hue a locked brand role.
   ===================================================================== */
.site-sound[data-v-c47d7e18] {
  --snd-ink:     var(--site-color-fg, #1a1815);
  --snd-paper:   var(--site-color-bg, #fbf9f5);
  --snd-hairline: color-mix(in srgb, var(--snd-ink) 14%, transparent);
  --snd-h:       38px;
  --snd-radius:  999px;
  --snd-dock-lift: 0px;

  position: relative;
  display: inline-flex;
  align-items: center;
  color: var(--snd-ink);
  font-family: var(--site-font-body, inherit);
}

/* ── Floating shell ──────────────────────────────────────────────────
   A hairline plate on frosted paper, not a drop-shadowed bubble. The
   shadow is a single soft lift so it reads as a physical chip over a
   photograph without shouting. */
.site-sound--float[data-v-c47d7e18] {
  position: fixed;
  z-index: 900;
  padding: 3px;
  border-radius: var(--snd-radius);
  background: color-mix(in srgb, var(--snd-paper) 82%, transparent);
  border: 1px solid var(--snd-hairline);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  box-shadow: 0 10px 28px -14px rgba(0, 0, 0, 0.45);
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.22s ease;
}
.site-sound--float[data-v-c47d7e18]:hover { transform: translateY(-1px); box-shadow: 0 14px 34px -14px rgba(0,0,0,0.5);
}

/* Corners. Bottom placements add the measured dock lift, so the control
   sits ABOVE the concierge instead of under it (law E4). */
.site-sound--at-top-right[data-v-c47d7e18]    { top: calc(var(--site-header-h, 64px) + 14px); right: max(14px, env(safe-area-inset-right));
}
.site-sound--at-top-left[data-v-c47d7e18]     { top: calc(var(--site-header-h, 64px) + 14px); left:  max(14px, env(safe-area-inset-left));
}
.site-sound--at-bottom-right[data-v-c47d7e18] { bottom: calc(14px + var(--snd-dock-lift)); right: max(14px, env(safe-area-inset-right));
}
.site-sound--at-bottom-left[data-v-c47d7e18]  { bottom: calc(14px + var(--snd-dock-lift)); left:  max(14px, env(safe-area-inset-left));
}

/* Panels open UPWARD from a bottom-anchored control. */
.site-sound--at-bottom-right .site-sound__panel[data-v-c47d7e18],
.site-sound--at-bottom-left  .site-sound__panel[data-v-c47d7e18] { top: auto; bottom: calc(100% + 0.45rem);
}
.site-sound--at-top-left  .site-sound__panel[data-v-c47d7e18],
.site-sound--at-bottom-left .site-sound__panel[data-v-c47d7e18] { right: auto; left: 0;
}

/* ── The button ──────────────────────────────────────────────────── */
.site-sound__btn[data-v-c47d7e18] {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--snd-h);
  padding: 0 0.7rem 0 0.6rem;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border-radius: inherit;
}
.site-sound__btn[data-v-c47d7e18]:focus-visible { outline: 2px solid currentColor; outline-offset: 3px;
}
.site-sound__glyph[data-v-c47d7e18] {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; line-height: 0; flex: none;
  opacity: 0.9;
}

/* ── The word ────────────────────────────────────────────────────────
   Small caps with wide tracking — the idiom hotel chrome already uses for
   nav and eyebrows, so the control reads as part of the design rather than
   a bolted-on widget. */
.site-sound__label[data-v-c47d7e18] {
  display: flex; flex-direction: column; align-items: flex-start;
  min-width: 0; line-height: 1.2; text-align: left;
}
.site-sound__label-main[data-v-c47d7e18] {
  font-size: 0.66rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--site-tracking-ui, 0.14em);
  white-space: nowrap;
}
.site-sound__label-sub[data-v-c47d7e18] {
  margin-top: 1px;
  font-size: 0.7rem;
  text-transform: none;
  letter-spacing: var(--site-tracking-body, normal);
  opacity: 0.6;
  max-width: 17ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.site-sound__sr[data-v-c47d7e18] {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Player card ─────────────────────────────────────────────────── */
.site-sound--widget[data-v-c47d7e18] { --snd-radius: 12px; padding: 4px;
}
.site-sound--widget .site-sound__btn[data-v-c47d7e18] { gap: 0.6rem; padding: 0.25rem 0.65rem 0.25rem 0.25rem; border-radius: 9px;
}
.site-sound__art[data-v-c47d7e18] {
  flex: none; width: 38px; height: 38px; border-radius: 7px;
  object-fit: cover; display: block;
  box-shadow: inset 0 0 0 1px var(--snd-hairline);
}
.site-sound__cue[data-v-c47d7e18] {
  display: inline-flex; line-height: 0; opacity: 0.45;
  margin-left: 0.1rem;
}
.site-sound__btn:hover .site-sound__cue[data-v-c47d7e18] { opacity: 0.85;
}

/* Icon only. */
.site-sound--mini .site-sound__btn[data-v-c47d7e18] { min-width: var(--snd-h); padding: 0; justify-content: center; gap: 0;
}

/* In the header: no chrome of its own — inherit the bar. */
.site-sound--header[data-v-c47d7e18] { background: none; border: 0; box-shadow: none; backdrop-filter: none; padding: 0;
}
.site-sound--header .site-sound__btn[data-v-c47d7e18] { padding: 0 0.4rem;
}
.site-sound--header .site-sound__label-main[data-v-c47d7e18] { font-size: 0.62rem;
}

/* ── Level meter ─────────────────────────────────────────────────────
   Four bars, visible at rest (law H4) — the animation is enhancement, never
   the only way to read the state. */
.site-sound__eq[data-v-c47d7e18] { display: inline-flex; align-items: flex-end; gap: 2px; height: 13px;
}
.site-sound__eq i[data-v-c47d7e18] { width: 2px; height: 35%; background: currentColor; border-radius: 1px;
}
.site-sound__eq.is-animated i[data-v-c47d7e18] { animation: site-sound-eq-c47d7e18 1s ease-in-out infinite;
}
.site-sound__eq.is-animated i[data-v-c47d7e18]:nth-child(2) { animation-delay: 140ms;
}
.site-sound__eq.is-animated i[data-v-c47d7e18]:nth-child(3) { animation-delay: 300ms;
}
.site-sound__eq.is-animated i[data-v-c47d7e18]:nth-child(4) { animation-delay: 460ms;
}
@keyframes site-sound-eq-c47d7e18 {
0%,100% { height: 28%;
}
50% { height: 100%;
}
}
@media (prefers-reduced-motion: reduce) {
.site-sound__eq.is-animated i[data-v-c47d7e18] { animation: none; height: 60%;
}
.site-sound--float[data-v-c47d7e18] { transition: none;
}
.site-sound--float[data-v-c47d7e18]:hover { transform: none;
}
}

/* ── Secondary controls + panels ─────────────────────────────────── */
.site-sound__more[data-v-c47d7e18] {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-right: 4px; padding: 0;
  background: transparent; border: 0; color: inherit; cursor: pointer;
  opacity: 0.4;
}
.site-sound__more[data-v-c47d7e18]:hover { opacity: 0.9;
}
.site-sound__more[data-v-c47d7e18]:focus-visible { outline: 2px solid currentColor; outline-offset: 2px;
}
.site-sound__panel[data-v-c47d7e18] {
  position: absolute; top: calc(100% + 0.45rem); right: 0;
  min-width: 215px; padding: 0.7rem 0.8rem;
  background: var(--snd-paper);
  color: var(--snd-ink);
  border: 1px solid var(--snd-hairline);
  border-radius: 12px;
  box-shadow: 0 16px 36px -16px rgba(0, 0, 0, 0.45);
  z-index: 1;
}
.site-sound__track[data-v-c47d7e18] { margin: 0; font-size: 0.84rem; line-height: 1.3;
}
.site-sound__artist[data-v-c47d7e18] { margin: 0.12rem 0 0; font-size: 0.73rem; opacity: 0.6;
}
.site-sound__row[data-v-c47d7e18] { display: flex; align-items: center; gap: 0.55rem; margin-top: 0.6rem;
}
.site-sound__vol[data-v-c47d7e18] { flex: 1; min-width: 0; accent-color: currentColor;
}
.site-sound__next[data-v-c47d7e18] {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: transparent; border: 0; color: inherit; cursor: pointer; opacity: 0.65;
}
.site-sound__next[data-v-c47d7e18]:hover { opacity: 1;
}


/* ── Mobile ─────────────────────────────────────────────────────────
   A 38px cover plus two lines is most of a phone's width, so the card
   sheds its artwork and subtitle and becomes a labelled pill. Tap targets
   clear 44px whatever the layout. */
@media (max-width: 640px) {
.site-sound--at-top-right[data-v-c47d7e18], .site-sound--at-top-left[data-v-c47d7e18] { top: calc(var(--site-header-h, 56px) + 10px);
}
.site-sound--at-top-right[data-v-c47d7e18], .site-sound--at-bottom-right[data-v-c47d7e18] { right: max(10px, env(safe-area-inset-right));
}
.site-sound--at-top-left[data-v-c47d7e18],  .site-sound--at-bottom-left[data-v-c47d7e18]  { left:  max(10px, env(safe-area-inset-left));
}
.site-sound--widget .site-sound__art[data-v-c47d7e18],
  .site-sound__label-sub[data-v-c47d7e18] { display: none;
}
.site-sound--widget[data-v-c47d7e18] { --snd-radius: 999px; padding: 3px;
}
.site-sound--widget .site-sound__btn[data-v-c47d7e18] { padding: 0 0.7rem 0 0.6rem; gap: 0.5rem;
}
.site-sound__btn[data-v-c47d7e18] { min-height: 44px;
}
}


.pop-hdr-utils[data-v-d000ae81] {
  display: inline-flex;
  align-items: center;
  gap: clamp(0.35rem, 1vw, 0.75rem);
  color: inherit;
}
.pop-hdr-utils__btn[data-v-d000ae81] {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 40px;
  min-width: 40px;
  justify-content: center;
  padding: 0 0.5rem;
  color: inherit;
  text-decoration: none;
  border-radius: 999px;
  transition: opacity 0.2s ease;
}
.pop-hdr-utils__btn[data-v-d000ae81]:hover { opacity: 0.7;
}
.pop-hdr-utils__btn-label[data-v-d000ae81] {
  /* Icon-only by default; themes can reveal labels via a wrapping class. */
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.pop-hdr-utils__lang[data-v-d000ae81] { position: relative;
}
.pop-hdr-utils__lang-toggle[data-v-d000ae81] {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 40px;
  padding: 0 0.55rem;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border-radius: 999px;
}
.pop-hdr-utils__lang-toggle[data-v-d000ae81]:hover { opacity: 0.7;
}
.pop-hdr-utils__lang-menu[data-v-d000ae81] {
  position: absolute;
  top: calc(100% + 0.35rem);
  right: 0;
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  min-width: 8rem;
  background: var(--site-surface, #fff);
  color: var(--site-ink, #111);
  border: 1px solid color-mix(in srgb, currentColor 14%, transparent);
  border-radius: 0.6rem;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
  z-index: 1200;
}
.pop-hdr-utils__lang-item[data-v-d000ae81] {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.7rem;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border-radius: 0.4rem;
}
.pop-hdr-utils__lang-item[data-v-d000ae81]:hover { background: color-mix(in srgb, currentColor 8%, transparent);
}
.pop-hdr-utils__lang-item.is-current[data-v-d000ae81] { font-weight: 700;
}
@media (prefers-reduced-motion: reduce) {
.pop-hdr-utils__btn[data-v-d000ae81], .pop-hdr-utils__lang-toggle[data-v-d000ae81] { transition: none;
}
}


/* The panel deliberately styles itself from `--site-*` tokens ONLY, so it
 * picks up each theme's palette + type without the theme writing any CSS.
 * Themes that want more control restyle via the class hooks above. */
.sdk-navgrp[data-v-1cbbee91] {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
}
.sdk-navgrp__trigger[data-v-1cbbee91] {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
/* A caret drawn in CSS — no icon font, no SVG asset to ship. */
.sdk-navgrp__caret[data-v-1cbbee91] {
  width: 0.42em;
  height: 0.42em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-0.1em, -0.1em);
  transition: transform 0.18s ease;
  flex: none;
}
.sdk-navgrp--open .sdk-navgrp__caret[data-v-1cbbee91] {
  transform: rotate(-135deg) translate(-0.16em, -0.16em);
}
/* The link-trigger already carries a caret; this separate hit target exists
 * for touch + keyboard. On hover-capable pointers the panel opens on hover,
 * so it's redundant there — but it stays focusable for keyboard users. */
.sdk-navgrp__caret-btn[data-v-1cbbee91] {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  min-height: 32px;
  padding: 0;
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
}
@media (hover: none), (pointer: coarse) {
  /* Touch: the trigger's own caret is decorative — this button is the opener. */
.sdk-navgrp__caret-btn[data-v-1cbbee91] { display: inline-flex;
}
.sdk-navgrp__trigger > .sdk-navgrp__caret[data-v-1cbbee91] { display: none;
}
}
.sdk-navgrp__caret-btn[data-v-1cbbee91]:focus-visible { outline: 2px solid currentColor; outline-offset: 2px;
}
.sdk-navgrp__panel[data-v-1cbbee91] {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;              /* above the concierge bubble (998–999) */
  min-width: max(180px, 100%);
  margin: 0.5rem 0 0;
  padding: 0.4rem;
  list-style: none;
  background: var(--site-color-bg, #fff);
  color: var(--site-color-text, #111);
  border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
  border-radius: var(--site-radius, 4px);
  box-shadow: 0 12px 32px rgb(0 0 0 / 12%);
  font-family: var(--site-font-body, inherit);
}
.sdk-navgrp__panel[hidden][data-v-1cbbee91] { display: none;
}
.sdk-navgrp__item[data-v-1cbbee91] { margin: 0;
}
.sdk-navgrp__link[data-v-1cbbee91] {
  display: block;
  padding: 0.5rem 0.75rem;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
  border-radius: calc(var(--site-radius, 4px) * 0.75);
}
.sdk-navgrp__link[data-v-1cbbee91]:hover,
.sdk-navgrp__link[data-v-1cbbee91]:focus-visible {
  background: color-mix(in srgb, currentColor 8%, transparent);
}
@media (prefers-reduced-motion: reduce) {
.sdk-navgrp__caret[data-v-1cbbee91] { transition: none;
}
}


.sdk-navacc__row[data-v-448a3764] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  background: transparent;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}
.sdk-navacc__caret[data-v-448a3764] {
  width: 0.42em;
  height: 0.42em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.18s ease;
  flex: none;
}
.sdk-navacc--open .sdk-navacc__caret[data-v-448a3764] { transform: rotate(-135deg);
}
.sdk-navacc__list[data-v-448a3764] {
  list-style: none;
  margin: 0.25rem 0 0.5rem;
  padding: 0 0 0 1rem;
  border-left: 1px solid color-mix(in srgb, currentColor 18%, transparent);
}
.sdk-navacc__list[hidden][data-v-448a3764] { display: none;
}
.sdk-navacc__link[data-v-448a3764] {
  display: block;
  padding: 0.4rem 0;
  color: inherit;
  text-decoration: none;
  /* A child sits UNDER its parent in the hierarchy — say so typographically
   * rather than making it look like another top-level destination. */
  font-size: 0.9em;
  opacity: 0.85;
}
.sdk-navacc__link[data-v-448a3764]:hover,
.sdk-navacc__link[data-v-448a3764]:focus-visible { opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.sdk-navacc__caret[data-v-448a3764] { transition: none;
}
}


.sdk-cta[data-v-9df4945d] {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  gap: 1px;   /* a hairline seam between the two halves of the split button */
}
.sdk-cta__primary[data-v-9df4945d] { display: inline-flex; align-items: center;
}
.sdk-cta__caret-btn[data-v-9df4945d] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  cursor: pointer;
  /* Inherits the theme's button class, so it matches the primary half. */
}
.sdk-cta__caret[data-v-9df4945d] {
  width: 0.42em;
  height: 0.42em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-0.1em, -0.1em);
  transition: transform 0.18s ease;
  flex: none;
}
.sdk-cta--open .sdk-cta__caret[data-v-9df4945d] {
  transform: rotate(-135deg) translate(-0.16em, -0.16em);
}
.sdk-cta__panel[data-v-9df4945d] {
  position: absolute;
  top: 100%;
  right: 0;                  /* the CTA lives at the right edge of the bar */
  z-index: 1000;             /* above the concierge bubble (998–999) */
  min-width: max(200px, 100%);
  margin: 0.5rem 0 0;
  padding: 0.4rem;
  list-style: none;
  background: var(--site-color-bg, #fff);
  color: var(--site-color-text, #111);
  border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
  border-radius: var(--site-radius, 4px);
  box-shadow: 0 12px 32px rgb(0 0 0 / 12%);
  font-family: var(--site-font-body, inherit);
}
.sdk-cta__panel[hidden][data-v-9df4945d] { display: none;
}
.sdk-cta__item[data-v-9df4945d] { margin: 0;
}
.sdk-cta__link[data-v-9df4945d] {
  display: block;
  padding: 0.55rem 0.75rem;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
  border-radius: calc(var(--site-radius, 4px) * 0.75);
}
.sdk-cta__link[data-v-9df4945d]:hover,
.sdk-cta__link[data-v-9df4945d]:focus-visible {
  background: color-mix(in srgb, currentColor 8%, transparent);
}
@media (prefers-reduced-motion: reduce) {
.sdk-cta__caret[data-v-9df4945d] { transition: none;
}
}


/* ⚠️⚠️ TEXT COLOUR COMES FROM `inherit` + `opacity`, NEVER A COLOUR TOKEN.
   This is the SDK chrome convention (see RegionSwitcher / LanguageSwitcher)
   and it exists because a theme's colour ROLES are not what their names
   suggest. Townhouse defines:

       --site-color-muted: #F3E6D0   (sun-bleached SAND — a FILL)

   so `color: var(--site-color-muted)` rendered this control's text in
   near-white cream on a #FFFFFF page: invisible. The muted TEXT role there
   is `--site-color-fg-muted` (#7A6350), and other themes spell it
   differently again. Inheriting the page's own ink and dialling it back
   with opacity is the only thing that is true on every theme.

   SURFACES are different — a floating panel must be opaque or the list
   renders over the page behind it — so those do read tokens, in the order
   surface → bg → white, all of which are genuinely background roles.
   Borders read `--site-color-border` (Townhouse: #DCC5A2 tan), radius
   `--radius-sm` (8px there), and the control's type reads
   `--site-font-ui` (Karla) because this is chrome, not body copy. */
.currency-panel[data-v-ddad464d] {
  max-height: min(24rem, 60vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.4rem;
  font-family: var(--site-font-ui, inherit);
  color: inherit;
}
.currency-panel__search[data-v-ddad464d] {
  width: 100%;
  box-sizing: border-box;
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.35rem;
  font: inherit;
  font-size: 0.85rem;
  color: inherit;
  background: transparent;
  border: 1px solid;
  border-color: var(--site-color-border, currentColor);
  border-radius: var(--radius-sm, var(--site-radius-sm, 3px));
}
.currency-panel__search[data-v-ddad464d]::placeholder { color: inherit; opacity: 0.5;
}
.currency-panel__search[data-v-ddad464d]:focus-visible {
  outline: 2px solid var(--site-color-focus-ring, currentColor);
  outline-offset: 1px;
}
.currency-panel__group + .currency-panel__group[data-v-ddad464d] { margin-top: 0.5rem;
}
.currency-panel__group-label[data-v-ddad464d] {
  margin: 0.4rem 0 0.2rem;
  padding: 0 0.45rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: var(--site-tracking-caps, 0.12em);
  text-transform: uppercase;
  opacity: 0.5;
}
.currency-panel__options[data-v-ddad464d] { list-style: none; margin: 0; padding: 0;
}
.currency-panel__option-btn[data-v-ddad464d] {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  width: 100%;
  padding: 0.4rem 0.45rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.85rem;
  color: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm, var(--site-radius-sm, 3px));
}
/* A wash of the page's OWN ink — works on a cream panel and a dark one
   alike, where a fixed grey would muddy one of them. */
.currency-panel__option-btn[data-v-ddad464d]:hover {
  background: color-mix(in srgb, currentColor 8%, transparent);
}
.currency-panel__option-btn[data-v-ddad464d]:focus-visible {
  outline: 2px solid var(--site-color-focus-ring, currentColor);
  outline-offset: -2px;
}
.currency-panel__option-flag[data-v-ddad464d] { font-size: 1em; line-height: 1; flex: 0 0 auto;
}

/* ⚠️ The ellipsis has to live on the NAME, the flex CHILD. `text-overflow`
   on a flex CONTAINER reaches nothing — the text is cut with no "…", so the
   panel shows a currency name that does not exist. `min-width: 0` because a
   flex item will not shrink below its content width without it. */
.currency-panel__option-name[data-v-ddad464d] {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.currency-panel__option-code[data-v-ddad464d] {
  flex: 0 0 auto;
  font-size: 0.74em;
  letter-spacing: 0.06em;
  opacity: 0.55;
  font-variant-numeric: tabular-nums;
}
.currency-panel__option-mark[data-v-ddad464d] { flex: 0 0 auto; opacity: 0.75;
}
.currency-panel__option--active .currency-panel__option-btn[data-v-ddad464d] { font-weight: 600;
}
.currency-panel__empty[data-v-ddad464d] {
  margin: 0;
  padding: 0.6rem 0.45rem;
  font-size: 0.82rem;
  opacity: 0.65;
}


/* UNSCOPED, like HeaderCta's `.sdk-cta-btn`: the trigger sits in a THEME's
   header, beside elements wearing the theme's scope id, and the panel is
   teleported to <body>. Every selector is under an `sdk-hdr-cur` class, so
   nothing here can reach anything else. */

/* ⚠️ THE TRIGGER IS TEXT, LIKE THE HEADER'S OWN LINKS. Colour is the header's
   ink (`inherit`) — the only value right on a dark bar and a cream one alike;
   the type comes from a nav link via `--hc-*` (see `adoptHeaderType`). */
.sdk-hdr-cur {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  flex-shrink: 0;
  min-height: 40px;
  margin: 0;
  padding: 0 0.5em;
  border: 0;
  background: none;
  color: var(--hc-color, inherit);
  font-family: var(--hc-font, inherit);
  font-size: var(--hc-size, inherit);
  font-weight: var(--hc-weight, inherit);
  letter-spacing: var(--hc-track, inherit);
  text-transform: var(--hc-case, none);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sdk-hdr-cur__code {
  font-variant-numeric: tabular-nums;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.3em;
  text-decoration-thickness: 1px;
  transition: text-decoration-color 140ms ease;
}
.sdk-hdr-cur:hover .sdk-hdr-cur__code,
.sdk-hdr-cur--open .sdk-hdr-cur__code {
  text-decoration-color: currentColor;
}
.sdk-hdr-cur:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: 2px;
}
/* The same chevron HeaderCta draws on its own caret button. */
.sdk-hdr-cur__caret {
  width: 0.38em;
  height: 0.38em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.12em) rotate(45deg);
  transition: transform 160ms ease;
  flex: none;
  opacity: 0.8;
}
.sdk-hdr-cur--open .sdk-hdr-cur__caret {
  transform: translateY(0.1em) rotate(-135deg);
}

/* The twin, at <body>: fixed in the header's bar, centred on its anchor. A
   transform on our OWN leaf anchors nothing else (H5). */
.sdk-hdr-cur--docked {
  position: fixed;
  transform: translateY(-50%);
}
/* On a see-through bar (a photograph behind it): a plate of the page's own
   ground under the words, so they read on sky and on shadow alike. */
.sdk-hdr-cur--plate {
  min-height: 36px;
  padding: 0 0.8em;
  background: color-mix(in srgb, var(--site-color-bg, #fff) 86%, transparent);
  border-radius: var(--site-radius-sm, 3px);
  box-shadow: 0 1px 10px rgba(0, 0, 0, 0.08);
}

/* ⚠️ A HEADER THAT CARRIES IT HOLDS STILL. Blue Apple Beach and Bleecker
   slide their header away on scroll-down (`translateY(-100%)` on the header
   itself). The hotelier turned this on so the guest can change currency
   whenever they look up; a control that scrolls off with the bar is not that.
   Only a header holding the control is touched, which only happens on /book
   with the switch on — every other page keeps the theme's behaviour. */
header:has(.sdk-hdr-cur),
[data-site-header]:has(.sdk-hdr-cur) {
  transform: none !important;
}

/* ── The panel, at <body> ───────────────────────────────────────────────
   Above the stay rail (900), the stay sheet (1000) and the concierge (999);
   under the room quick-view (12000), which is a modal over everything. */
.sdk-hdr-cur-pop {
  position: fixed;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--site-font-ui, var(--site-font-body, inherit));
  background: var(--site-color-surface, var(--site-color-bg, #fff));
  color: var(--site-color-fg, #111);
  border: 1px solid;
  border-color: var(--site-color-border, color-mix(in srgb, currentColor 18%, transparent));
  border-radius: var(--site-radius-sm, 3px);
  box-shadow: 0 18px 44px var(--site-color-shadow-strong, var(--site-color-shadow, rgba(0, 0, 0, 0.18)));
  animation: sdk-hdr-cur-in 160ms ease both;
}
/* The list scrolls; the charge line and the heading stay put above it. */
.sdk-hdr-cur-pop > :last-child { min-height: 0; overflow-y: auto;
}
.sdk-hdr-cur-pop__charge {
  margin: 0;
  padding: 0.75rem 0.85rem 0.65rem;
  border-bottom: 1px solid;
  border-bottom-color: var(--site-color-border, color-mix(in srgb, currentColor 14%, transparent));
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.4;
}
.sdk-hdr-cur-pop__charge-sub {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  font-weight: 400;
  opacity: 0.65;
}
.sdk-hdr-cur-pop__head {
  margin: 0;
  padding: 0.6rem 0.85rem 0.15rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: var(--site-tracking-caps, 0.12em);
  text-transform: uppercase;
  opacity: 0.5;
}
@keyframes sdk-hdr-cur-in {
from { opacity: 0; transform: translateY(-4px);
}
to   { opacity: 1; transform: none;
}
}
@media (prefers-reduced-motion: reduce) {
.sdk-hdr-cur-pop { animation: none;
}
.sdk-hdr-cur__caret, .sdk-hdr-cur__code { transition: none;
}
}


.sdk-cta[data-v-5e6a62a1] {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  gap: 1px;   /* a hairline seam between the two halves of the split button */
}
.sdk-cta__primary[data-v-5e6a62a1] { display: inline-flex; align-items: center;
}
.sdk-cta__caret-btn[data-v-5e6a62a1] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  cursor: pointer;
  /* Inherits the theme's button class, so it matches the primary half. */
}
.sdk-cta__caret[data-v-5e6a62a1] {
  width: 0.42em;
  height: 0.42em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-0.1em, -0.1em);
  transition: transform 0.18s ease;
  flex: none;
}
.sdk-cta--open .sdk-cta__caret[data-v-5e6a62a1] {
  transform: rotate(-135deg) translate(-0.16em, -0.16em);
}
.sdk-cta__panel[data-v-5e6a62a1] {
  position: absolute;
  top: 100%;
  right: 0;                  /* the CTA lives at the right edge of the bar */
  z-index: 1000;             /* above the concierge bubble (998–999) */
  min-width: max(200px, 100%);
  margin: 0.5rem 0 0;
  padding: 0.4rem;
  list-style: none;
  background: var(--site-color-bg, #fff);
  color: var(--site-color-text, #111);
  border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
  border-radius: var(--site-radius, 4px);
  box-shadow: 0 12px 32px rgb(0 0 0 / 12%);
  font-family: var(--site-font-body, inherit);
}
.sdk-cta__panel[hidden][data-v-5e6a62a1] { display: none;
}
.sdk-cta__item[data-v-5e6a62a1] { margin: 0;
}
.sdk-cta__link[data-v-5e6a62a1] {
  display: block;
  padding: 0.55rem 0.75rem;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
  border-radius: calc(var(--site-radius, 4px) * 0.75);
}
.sdk-cta__link[data-v-5e6a62a1]:hover,
.sdk-cta__link[data-v-5e6a62a1]:focus-visible {
  background: color-mix(in srgb, currentColor 8%, transparent);
}

/* The multi-button row. Only ever wraps 2+ buttons — one button keeps its
   own element as the root so the theme's scoped CSS lands unaided. */
.sdk-cta-group[data-v-5e6a62a1] {
  display: inline-flex;
  align-items: center;
  gap: var(--site-space-sm, 0.6rem);
  flex-wrap: wrap;
}
@media (prefers-reduced-motion: reduce) {
.sdk-cta__caret[data-v-5e6a62a1] { transition: none;
}
}


/* ⚠️ THE BUTTON NEVER WRAPS, AND THE THEME CANNOT REACH IT TO SAY SO.
   `link-class` lands ON the anchor itself, so a theme's `:deep(.my-cta)`
   descendant selector matches nothing — which is how "BOOK NOW" ended up on
   two lines in a one-line bar on hotel after hotel. One unscoped rule here,
   on a class the SDK stamps on every top-bar branch, is the only place that
   can hold it. */
.sdk-cta-btn {
  white-space: nowrap;
  flex-shrink: 0;
}
.sdk-cta-group .sdk-cta__btn--secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.7em 1.2em;
  border: 1px solid currentColor;
  border-radius: var(--site-radius, 4px);
  background: transparent;
  color: inherit;
  font: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.sdk-cta-group .sdk-cta__btn--secondary:hover,
.sdk-cta-group .sdk-cta__btn--secondary:focus-visible {
  background: color-mix(in srgb, currentColor 10%, transparent);
}
.sdk-cta-group .sdk-cta__btn--link {
  display: inline-flex;
  align-items: center;
  padding: 0.7em 0.2em;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 0.25em;
  cursor: pointer;
}
.sdk-cta-group .sdk-cta__btn--link:hover,
.sdk-cta-group .sdk-cta__btn--link:focus-visible {
  text-decoration-thickness: 2px;
}
@media (prefers-reduced-motion: reduce) {
.sdk-cta-group .sdk-cta__btn--secondary { transition: none;
}
}


/* =====================================================================
 *  THE STAY, IN THE SITE HEADER  (`booking_page.cart_placement: header`)
 *
 *  ⚠️ THIS LIVED IN `styles/mobile-funnel.css` FIRST AND DID NOT BELONG THERE.
 *  That file's whole safety argument is that every rule in it sits inside
 *  `@media (max-width: 720px)`, so a hotel's laptop page cannot move — and
 *  `viewport.css.test.mjs` enforces it. These rules are not phone rules: the
 *  control is rendered at every width, and a hotelier who moves the stay into
 *  the header means it there on a laptop too. Its VISIBILITY is decided in the
 *  script (the setting, a mounted sheet, a non-empty stay), never by a
 *  breakpoint — so there was nothing for a media query to gate, and putting it
 *  in the phone layer was a category error the test correctly refused.
 *
 *  ⚠️ UNSCOPED, like the `sdk-cta__btn--*` fallbacks this file already ships.
 *  The button wears the THEME's own `linkClass`, so the hotel's styling
 *  reaches it; these rules only supply what a button does not have — a glyph
 *  beside a count, and a thumb-sized box.
 * ===================================================================== */
.sdk-stay {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  cursor: pointer;
}
.sdk-stay__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sdk-stay__count {
  font-variant-numeric: tabular-nums;
  line-height: 1;
}


/* ── local structural vars (colour + type stay on --site-* tokens) ── */
.bab-header[data-v-cab4f611],
.bab-drawer-root[data-v-cab4f611] {
  --s1: 4px;  --s2: 8px;  --s3: 16px; --s4: 24px; --s5: 40px;
  /* Wide enough that the nav never has to fight for room, but the row
     inside it is CENTRED and only as wide as its content — see .bab-bar. */
  --bar-max: 1440px;
  --gutter: var(--site-gutter, clamp(1.25rem, 4vw, 3rem));
  --bar-gutter: clamp(1rem, 2.4vw, 2.75rem);
  --ease: cubic-bezier(.22,.8,.3,1);
}

/* ══ shell — in-flow at the top of the page; scrolls away with the
      content, exactly like the operator's own site ══ */
.bab-header[data-v-cab4f611] {
  position: relative;
  z-index: 1000; /* keeps the SDK dropdown panels (z:1000) above the concierge */
  background: var(--site-color-bg, #fff);
  transition: box-shadow .3s var(--ease);
}
.bab-header.is-scrolled[data-v-cab4f611] {
  box-shadow: 0 10px 30px -26px color-mix(in srgb, var(--site-color-accent, #31416e) 70%, transparent);
}

/* ══ tier 1 · direct-booking strip ══ */
.bab-strip[data-v-cab4f611] {
  background: var(--site-color-bar, #3d3d3d);
  color: var(--site-color-bg, #fff);
}
.bab-strip__inner[data-v-cab4f611] {
  max-width: var(--bar-max);
  margin-inline: auto;
  min-height: 52px;
  padding: 6px var(--bar-gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
}
.bab-strip__pitch[data-v-cab4f611] {
  margin: 0;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: var(--site-small, .8125rem);
  letter-spacing: .04em;
  line-height: 1.3;
}
.bab-search[data-v-cab4f611] {
  display: flex;
  align-items: flex-end;
  gap: var(--s2);
  flex-wrap: wrap;
}
.bab-field[data-v-cab4f611] {
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.bab-field__label[data-v-cab4f611] {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: var(--site-small, .8125rem);
  font-weight: 400;
  white-space: nowrap;
  opacity: .92;
}
/* The date control is a form primitive, so it wears the brand's own field
   look rather than a bespoke one: pale ground, hairline, dark ink. */
.bab-field__input[data-v-cab4f611] {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: var(--site-small, .8125rem);
  color: var(--site-color-accent, #31416e);
  background: var(--site-color-bg, #fff);
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 7px 10px;
  min-width: 8.5rem;
  line-height: 1.2;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.bab-field__input[data-v-cab4f611]:hover { border-color: var(--site-color-fg, #c3cfdf);
}
.bab-field__input[data-v-cab4f611]:focus-visible {
  outline: none;
  border-color: var(--site-color-fg, #c3cfdf);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--site-color-fg, #c3cfdf) 45%, transparent);
}
.bab-search__go[data-v-cab4f611] {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: var(--site-small, .8125rem);
  letter-spacing: var(--site-track-btn, .16em);
  text-transform: uppercase;
  color: var(--site-color-bar, #3d3d3d);
  background: var(--site-color-bg, #fff);
  border: 1px solid var(--site-color-bg, #fff);
  border-radius: 4px;
  padding: 8px 22px;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color .25s ease, color .25s ease;
}
.bab-search__go[data-v-cab4f611]:hover {
  background: var(--site-color-fg, #c3cfdf);
  border-color: var(--site-color-fg, #c3cfdf);
}
.bab-search__go[data-v-cab4f611]:focus-visible {
  outline: 2px solid var(--site-color-fg, #c3cfdf);
  outline-offset: 2px;
}

/* ══ tier 2 · the white bar ══════════════════════════════════════════
   src (1440): the row is a CLUSTER ~1176px wide — socials x110, logo
   x230, nav x357–1037, instant book x1071–1188, language to x1286 —
   with 25–35px between each group. It is not spread to the edges.

   So: the groups do NOT flex. Nothing stretches to fill, nothing is
   pushed out with `margin-left:auto`; the row is simply centred and is
   exactly as wide as its contents. `--bar-max` is the ceiling it may
   grow to on a very wide window, not a width it tries to occupy. */
.bab-bar[data-v-cab4f611] {
  max-width: var(--bar-max);
  margin-inline: auto;
  min-height: 96px;
  padding: var(--s3) var(--bar-gutter);
  display: flex;
  align-items: center;
  /* phone: burger left, mini-CTA right. The centred cluster starts at the
     breakpoint where the full nav appears. */
  justify-content: space-between;
  gap: clamp(14px, 1.9vw, 32px);
}
/* the source's hairline under the bar runs the FULL width of the window,
   while the row inside it stays centred */
.bab-header[data-v-cab4f611]::after {
  content: "";
  display: block;
  height: 1px;
  background: var(--site-color-border, #dde4ee);
}

/* left cluster — social marks, then the lockup */
.bab-bar__lead[data-v-cab4f611] {
  display: flex;
  align-items: center;
  gap: clamp(var(--s2), 1.4vw, var(--s4));
  flex: none;
}
.bab-socials[data-v-cab4f611] {
  /* visible on phones too (Tiger, 2026-08-16) — hidden only in the
     1060–1239 window where the centred desktop cluster is tightest */
  display: flex;
  align-items: center;
  gap: var(--s4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.bab-social[data-v-cab4f611] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  /* the source's marks are a neutral grey, not the palette's blue-grey */
  color: #8f8f8f;
  text-decoration: none;
  transition: color .25s ease, transform .3s var(--ease);
}
.bab-social svg[data-v-cab4f611] { width: 20px; height: 20px; fill: currentColor; display: block;
}
.bab-social[data-v-cab4f611]:hover { color: var(--site-color-accent, #31416e); transform: translateY(-1px);
}
.bab-social[data-v-cab4f611]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
  border-radius: 999px;
}
.bab-brand[data-v-cab4f611] {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex: none;
}
.bab-brand img[data-v-cab4f611] {
  display: block;
  height: clamp(40px, 3.8vw, 56px);
  width: auto;
}
.bab-wordmark[data-v-cab4f611] {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: clamp(1rem, .85rem + .7vw, 1.3rem);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
  white-space: nowrap;
}

/* nav — src: 12px, unspaced, caps, x357→x1037 for eight entries.
   `flex: 0 1 auto` — it takes the room its labels need and NO more, so it
   never stretches a gap between itself and the booking circles. It may
   still wrap to a second row rather than collide (Spanish runs a third
   longer than English). */
.bab-nav[data-v-cab4f611] {
  display: none;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  row-gap: 2px;
  column-gap: clamp(10px, 1.15vw, 22px);
  flex: 0 1 auto;
  min-width: 0;
}
.bab-nav[data-v-cab4f611] .bab-navlink {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .75rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
  background: transparent;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: var(--s2) 0;
  line-height: 1;
  white-space: nowrap;
}
.bab-nav[data-v-cab4f611] .bab-navlink::after {
  content: "";
  position: absolute;
  left: 0; right: 100%; bottom: 2px;
  height: 1px;
  background: currentColor;
  transition: right .3s var(--ease);
}
.bab-nav[data-v-cab4f611] .bab-navlink:hover::after,
.bab-nav[data-v-cab4f611] .bab-navlink:focus-visible::after { right: 0;
}
.bab-nav[data-v-cab4f611] .bab-navlink:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 3px;
}
/* src: the operator's header shows plain labels — no caret glyph. The
   groups still open on hover (and stay keyboard-reachable: the trigger
   itself is focusable and opens the panel). */
.bab-nav[data-v-cab4f611] .sdk-navgrp__caret { display: none;
}

/* dropdown panel */
.bab-nav[data-v-cab4f611] .sdk-navgrp__panel {
  background: var(--site-color-bg, #fff);
  border: 1px solid var(--site-color-border, #dde4ee);
  border-radius: 10px;
  box-shadow: 0 24px 48px -30px color-mix(in srgb, var(--site-color-accent, #31416e) 55%, transparent);
  padding: var(--s3);
}
.bab-nav[data-v-cab4f611] .sdk-navgrp__panel a {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: var(--site-small, .8125rem);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
  text-decoration: none;
  white-space: nowrap;
}
.bab-nav[data-v-cab4f611] .sdk-navgrp__panel a:hover { color: var(--site-color-button-colour, #495f37);
}

/* ── the instant-book circles ─────────────────────────────────────── */
.bab-instant[data-v-cab4f611] {
  /* both circles show at every width (Tiger, 2026-08-16) — the phone
     bar compacts them below instead of collapsing to a dropdown */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: none;
}
.bab-instant__eyebrow[data-v-cab4f611] {
  margin: 0;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .6875rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--site-color-body-ink, #545c74);
  line-height: 1;
  white-space: nowrap;
}
.bab-instant__ctas[data-v-cab4f611] { display: flex;
}
.bab-orbrow[data-v-cab4f611] { display: inline-flex; gap: 8px;
}

/* one circle per CTA the hotelier configured. The source paints the first
   pale and the second slate; that maps onto the 'secondary' and 'primary'
   button styles the CTA editor already offers. */
[data-v-cab4f611] .bab-orb {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 57px;
  height: 57px;
  border-radius: 999px;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.15;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  padding: 4px;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), background-color .25s ease;
}
[data-v-cab4f611] .bab-orb--primary {
  background: var(--site-color-accent, #31416e);
  border-color: var(--site-color-accent, #31416e);
  color: var(--site-color-bg, #fff);
}
[data-v-cab4f611] .bab-orb--secondary {
  background: var(--site-color-fg, #c3cfdf);
  border-color: var(--site-color-fg, #c3cfdf);
  color: var(--site-color-accent, #31416e);
}
[data-v-cab4f611] .bab-orb--plain {
  background: transparent;
  border-color: var(--site-color-border, #dde4ee);
  color: var(--site-color-accent, #31416e);
}
[data-v-cab4f611] .bab-orb:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -14px color-mix(in srgb, var(--site-color-accent, #31416e) 75%, transparent);
}
[data-v-cab4f611] .bab-orb:active { transform: translateY(0) scale(.98); transition-duration: .12s;
}
[data-v-cab4f611] .bab-orb:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 3px;
}
.bab-bar__utils[data-v-cab4f611] {
  display: none;
  flex: none;
  color: var(--site-color-muted, #76839c);
}
/* The language control is OPTIONAL, and when it is switched off the SDK
   still renders its slot — as an empty comment node. A zero-width flex
   child costs nothing itself, but it STILL earns a `gap`, and that phantom
   gap pushed the whole centred cluster half a gap (~14px) to the left.
   Take it out of the flow when it holds no element.
   Specificity 0,2,0 so it beats the `display:block` in the 1060px query
   regardless of source order. */
.bab-bar .bab-bar__utils[data-v-cab4f611]:not(:has(*)) { display: none;
}

/* ── the flag language toggle (EN / ES) ─────────────────────────────
   src: Wix linguist round flags — 20x20 PNGs, 23px apart, no ring, no
   shadow, exactly as the operator's live header renders them. */
.bab-langs[data-v-cab4f611] {
  display: flex;
  align-items: center;
  gap: 23px;
}
.bab-lang[data-v-cab4f611] {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  flex: none;
  width: 20px;
  height: 20px;
  min-width: 0 !important;
  min-height: 0 !important;
  border-radius: 999px;
  display: inline-flex;
}
.bab-lang img[data-v-cab4f611] { width: 20px; height: 20px; display: block;
}
.bab-lang[data-v-cab4f611]:focus-visible { outline: 2px solid var(--site-color-accent, #31416e); outline-offset: 2px;
}

/* ── phone controls ───────────────────────────────────────────────── */
.bab-burger[data-v-cab4f611] {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px; height: 44px;
  padding: 11px;
  flex: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.bab-burger span[data-v-cab4f611] {
  display: block;
  height: 1.6px;
  width: 100%;
  background: var(--site-color-accent, #31416e);
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.bab-burger[data-v-cab4f611]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
.bab-burger.is-open span[data-v-cab4f611]:nth-child(1) { transform: translateY(7.5px) rotate(45deg);
}
.bab-burger.is-open span[data-v-cab4f611]:nth-child(2) { opacity: 0;
}
.bab-burger.is-open span[data-v-cab4f611]:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg);
}

/* the collapsed mini-CTA dropdown is retired — the two orbs render at
   every width instead (it showed "DAYS" plus an empty caret circle) */
.bab-bar__mcta[data-v-cab4f611] { display: none;
}
[data-v-cab4f611] .bab-mini-cta {
  display: inline-flex;
  align-items: center;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .6875rem;
  letter-spacing: var(--site-track-btn, .16em);
  text-transform: uppercase;
  color: var(--site-color-bg, #fff);
  background: var(--site-color-accent, #31416e);
  text-decoration: none;
  padding: .8em 1.35em;
  border-radius: 999px;
  white-space: nowrap;
}
[data-v-cab4f611] .bab-mini-cta:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
@media (min-width: 1060px) and (max-width: 1239px) {
.bab-socials[data-v-cab4f611] { display: none;
}
}
@media (min-width: 1060px) {
  /* the full row appears — and now it is a centred cluster rather than a
     space-between spread */
.bab-bar[data-v-cab4f611] { justify-content: center;
}
.bab-nav[data-v-cab4f611] { display: flex;
}
.bab-bar__utils[data-v-cab4f611] { display: block;
}
.bab-burger[data-v-cab4f611] { display: none;
}
}
@media (max-width: 1059px) {
  /* phone bar: burger · socials · logo · both orbs, compacted */
.bab-bar[data-v-cab4f611] { gap: 10px;
}
.bab-instant__eyebrow[data-v-cab4f611] { display: none;
}
.bab-orbrow[data-v-cab4f611] { gap: 6px;
}
[data-v-cab4f611] .bab-orb { width: 46px; height: 46px; font-size: 0.58rem; padding: 2px;
}
.bab-socials[data-v-cab4f611] { gap: 8px;
}
.bab-social[data-v-cab4f611] { width: 26px; height: 26px;
}
.bab-social svg[data-v-cab4f611] { width: 17px; height: 17px;
}
.bab-brand img[data-v-cab4f611] { height: 38px;
}
}
@media (max-width: 720px) {
.bab-strip__inner[data-v-cab4f611] { justify-content: center;
}
.bab-strip__pitch[data-v-cab4f611] { flex: 1 0 100%; text-align: center;
}
.bab-search[data-v-cab4f611] { width: 100%; justify-content: center;
}
.bab-field__input[data-v-cab4f611] { min-width: 0; width: 100%;
}
.bab-field[data-v-cab4f611] { flex: 1 1 9rem;
}
}

/* ══ mobile drawer (teleported to body) ══ */
.bab-drawer-root[data-v-cab4f611] {
  position: fixed;
  inset: 0;
  z-index: 1000; /* above the concierge (998–999) */
}
.bab-drawer__backdrop[data-v-cab4f611] {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--site-color-accent, #31416e) 52%, transparent);
}
.bab-drawer[data-v-cab4f611] {
  position: absolute;
  top: 0; right: 0;
  height: 100%;
  width: min(88vw, 400px);
  background: var(--site-color-bg, #fff);
  border-left: 1px solid var(--site-color-border, #dde4ee);
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 5vw, 2rem);
  overflow-y: auto;
}
.bab-drawer__head[data-v-cab4f611] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
}
.bab-brand--drawer img[data-v-cab4f611] { height: clamp(40px, 9vw, 50px);
}
.bab-drawer__close[data-v-cab4f611] {
  flex: none;
  width: 44px; height: 44px;
  display: inline-grid;
  place-items: center;
  background: transparent;
  border: 1px solid var(--site-color-border, #dde4ee);
  border-radius: 999px;
  cursor: pointer;
  color: var(--site-color-accent, #31416e);
  transition: background-color .25s ease;
}
.bab-drawer__close svg[data-v-cab4f611] {
  width: 18px; height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.bab-drawer__close[data-v-cab4f611]:hover { background: color-mix(in srgb, var(--site-color-fg, #c3cfdf) 40%, transparent);
}
.bab-drawer__close[data-v-cab4f611]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
.bab-drawer__nav[data-v-cab4f611] {
  display: flex;
  flex-direction: column;
  margin-top: var(--s4);
}
.bab-drawer-root[data-v-cab4f611] .bab-mlink {
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .9375rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--site-color-border, #dde4ee);
}
.bab-drawer-root[data-v-cab4f611] .bab-mlink:hover { color: var(--site-color-button-colour, #495f37);
}
/* the pills are now the theme's own children of this wrapper, so its
   gap does the spacing (Tiger asked for clear air between them) */
.bab-drawer__ctawrap[data-v-cab4f611] {
  margin-top: var(--s4);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
[data-v-cab4f611] .bab-dcta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: .75rem;
  letter-spacing: var(--site-track-btn, .16em);
  text-transform: uppercase;
  color: var(--site-color-bg, #fff);
  background: var(--site-color-accent, #31416e);
  text-decoration: none;
  padding: 1em 1.5em;
  border-radius: 999px;
}
[data-v-cab4f611] .bab-dcta:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
/* the DAYS pill wears the pale variant, like its header orb */
[data-v-cab4f611] .bab-dcta--secondary {
  background: var(--site-color-fg, #c3cfdf);
  color: var(--site-color-accent, #31416e);
}
.bab-drawer__foot[data-v-cab4f611] {
  margin-top: auto;
  padding-top: var(--s4);
  border-top: 1px solid var(--site-color-border, #dde4ee);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  color: var(--site-color-muted, #76839c);
}
.bab-socials--drawer[data-v-cab4f611] { display: flex; gap: var(--s3);
}

/* drawer motion */
.bab-drawer-enter-active[data-v-cab4f611],
.bab-drawer-leave-active[data-v-cab4f611] { transition: opacity .3s ease;
}
.bab-drawer-enter-active .bab-drawer[data-v-cab4f611],
.bab-drawer-leave-active .bab-drawer[data-v-cab4f611] { transition: transform .35s var(--ease);
}
.bab-drawer-enter-from[data-v-cab4f611],
.bab-drawer-leave-to[data-v-cab4f611] { opacity: 0;
}
.bab-drawer-enter-from .bab-drawer[data-v-cab4f611],
.bab-drawer-leave-to .bab-drawer[data-v-cab4f611] { transform: translateX(100%);
}
@media (prefers-reduced-motion: reduce) {
.bab-header[data-v-cab4f611],
  .bab-social[data-v-cab4f611],
  .bab-burger span[data-v-cab4f611],
  .bab-drawer__close[data-v-cab4f611],
  .bab-nav[data-v-cab4f611] .bab-navlink::after,[data-v-cab4f611] .bab-orb,
  .bab-drawer-enter-active[data-v-cab4f611],
  .bab-drawer-leave-active[data-v-cab4f611],
  .bab-drawer-enter-active .bab-drawer[data-v-cab4f611],
  .bab-drawer-leave-active .bab-drawer[data-v-cab4f611] { transition: none;
}
.bab-social[data-v-cab4f611]:hover,[data-v-cab4f611] .bab-orb:hover { transform: none;
}
.bab-drawer-enter-from .bab-drawer[data-v-cab4f611],
  .bab-drawer-leave-to .bab-drawer[data-v-cab4f611] { transform: none;
}
}


/* ════ the white footer block — measured from the source at 1440 ════ */
.bab-footer[data-v-176c6cfa] {
  background: #ffffff;
  /* helvetica-w01-light is Wix's Helvetica Light webfont; the closest
     system chain, held with !important against the hidden dashboard
     style-overrides sheet. */
  font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial,
    sans-serif !important;
}

/* 2026-08-16: everything in the footer runs 10% larger than the
   source's measurements, on Tiger's instruction. */
.bab-footer__inner[data-v-176c6cfa] {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 26px 22px 28px;
}
.bab-footer__mark[data-v-176c6cfa] {
  display: inline-flex;
  text-decoration: none;
}
.bab-footer__mark img[data-v-176c6cfa] {
  display: block;
  width: 176px;
  height: 78px;
  object-fit: cover;
}

/* the rich-text column: 8px/11.2px, #545C74, links undecorated */
.bab-footer__text[data-v-176c6cfa] {
  margin-top: 17px;
  max-width: 748px;
}
.bab-footer__text p[data-v-176c6cfa] {
  margin: 0;
  font-size: 8.8px !important;
  line-height: 12.3px;
  font-weight: 400;
  letter-spacing: normal;
  color: #545c74;
}
.bab-footer__text a[data-v-176c6cfa] {
  color: #545c74;
  text-decoration: none;
}
.bab-footer__text a[data-v-176c6cfa]:hover {
  text-decoration: underline;
}
.bab-footer__legal[data-v-176c6cfa] {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font: inherit;
  font-size: 8.8px;
  line-height: 12.3px;
  color: #545c74;
  /* a global tap-target rule pins buttons to min-height 24px, which
     stretches the source's legal lines — undo it here */
  min-height: 0 !important;
  height: 12.3px;
  display: inline;
}
.bab-footer__legal[data-v-176c6cfa]:hover {
  text-decoration: underline;
}

/* social bar: 27px Instagram, 7px gap, 21px WhatsApp (sits 2px lower) */
.bab-footer__social[data-v-176c6cfa] {
  margin-top: 0;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.bab-footer__social a[data-v-176c6cfa] {
  display: inline-flex;
}
.bab-footer__social img[data-v-176c6cfa] {
  display: block;
}
.bab-footer__social a:last-child img[data-v-176c6cfa] {
  margin-top: 2px;
}
.bab-footer__social a[data-v-176c6cfa]:focus-visible {
  outline: 2px solid #545c74;
  outline-offset: 2px;
}

/* ════ legal modal (unchanged) ══════════════════════════════════════ */
.bab-policy[data-v-176c6cfa] {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: grid;
  place-items: center;
  padding: 24px;
  background: color-mix(in srgb, #31416e 55%, transparent);
}
.bab-policy__panel[data-v-176c6cfa] {
  width: min(760px, 100%);
  max-height: min(80vh, 720px);
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.55);
}
.bab-policy__head[data-v-176c6cfa] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px;
  border-bottom: 1px solid var(--site-color-border, #dde4ee);
}
.bab-policy__title[data-v-176c6cfa] {
  margin: 0;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: var(--site-h2, 1.4375rem);
  line-height: 1.2;
  color: var(--site-color-accent, #31416e);
}
.bab-policy__close[data-v-176c6cfa] {
  flex: none;
  width: 40px;
  height: 40px;
  display: inline-grid;
  place-items: center;
  background: transparent;
  border: 1px solid var(--site-color-border, #dde4ee);
  border-radius: 999px;
  cursor: pointer;
  color: var(--site-color-accent, #31416e);
}
.bab-policy__close svg[data-v-176c6cfa] {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.bab-policy__close[data-v-176c6cfa]:hover {
  background: color-mix(in srgb, var(--site-color-fg, #c3cfdf) 40%, transparent);
}
.bab-policy__close[data-v-176c6cfa]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
.bab-policy__tabs[data-v-176c6cfa] {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 16px 24px 0;
}
.bab-policy__tab[data-v-176c6cfa] {
  background: transparent;
  border: 1px solid var(--site-color-border, #dde4ee);
  border-radius: 999px;
  cursor: pointer;
  padding: 7px 16px;
  font-family: var(--site-font-display, Spinnaker, sans-serif);
  font-size: var(--site-micro, 0.6875rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--site-color-accent, #31416e);
  transition: background-color 0.25s ease, color 0.25s ease;
}
.bab-policy__tab.is-active[data-v-176c6cfa] {
  background: var(--site-color-accent, #31416e);
  border-color: var(--site-color-accent, #31416e);
  color: #fff;
}
.bab-policy__tab[data-v-176c6cfa]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: 2px;
}
.bab-policy__body[data-v-176c6cfa] {
  padding: 24px;
  overflow-y: auto;
  white-space: pre-wrap;
  font-size: var(--site-body, 1rem);
  line-height: var(--site-body-lh, 1.65);
  color: var(--site-color-body-ink, #545c74);
  text-align: left;
}
.bab-policy__body[data-v-176c6cfa]:focus-visible {
  outline: 2px solid var(--site-color-accent, #31416e);
  outline-offset: -2px;
}


/* Deliberately quiet and token-driven: this band sits directly under a
   bespoke, agent-designed footer on ~every site, so it has to read as
   part of it rather than as a second footer. Inherits the page's font
   and picks up the theme's own surface/ink tokens where they exist.

   A theme that CLAIMS the extras (see composables/useFooterExtras.js)
   embeds this inside its own footer, where standalone-band chrome would
   be wrong. Rather than have the component guess its context, the band
   values are knobs — set them on the element you put the class on:

     .site-footer__extras { --fx-pad: 0; --fx-max-w: none; }

   Custom properties inherit, and Vue applies a parent's class to a child
   component's root, so a theme's scoped rule reaches these. */
.fx[data-v-607a7acc] {
  padding: var(--fx-pad, 1.5rem 1.25rem);
  background: var(--fx-bg, var(--site-footer-bg, var(--color-surface-alt, transparent)));
  color: var(--fx-ink, var(--site-footer-ink, var(--color-ink, inherit)));
  font-size: var(--fx-size, 0.85rem);
}
.fx__inner[data-v-607a7acc] {
  max-width: var(--fx-max-w, var(--site-max-w, 1200px));
  margin: var(--fx-inner-margin, 0 auto);
  display: flex;
  flex-wrap: wrap;
  gap: 2rem 3rem;
  align-items: flex-start;
}
.fx__group[data-v-607a7acc] { min-width: 0;
}
.fx__group--text[data-v-607a7acc] { flex: 1 1 100%;
}
.fx__heading[data-v-607a7acc] {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.65;
  margin: 0 0 0.6rem;
}
.fx__links[data-v-607a7acc] { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.35rem;
}
.fx__link[data-v-607a7acc] {
  color: inherit;
  text-decoration: none;
  opacity: 0.85;
  transition: opacity 140ms ease;
}
.fx__link[data-v-607a7acc]:hover, .fx__link[data-v-607a7acc]:focus-visible { opacity: 1; text-decoration: underline;
}
.fx__logos[data-v-607a7acc] {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem;
}
.fx__logo[data-v-607a7acc] {
  display: block;
  max-height: 38px;
  max-width: 140px;
  width: auto;
  height: auto;
  object-fit: contain;
}
.fx__texts[data-v-607a7acc] { display: grid; gap: 0.35rem;
}
.fx__text[data-v-607a7acc] { margin: 0; opacity: 0.8;
}
@media (max-width: 640px) {
.fx__inner[data-v-607a7acc] { gap: 1.5rem;
}
.fx__group[data-v-607a7acc] { flex: 1 1 100%;
}
}


/* Deliberately quiet and token-driven: this band sits directly under a
   bespoke, agent-designed footer on ~every site, so it has to read as part of
   it rather than as a second footer. Inherits the page's font and picks up
   the theme's own surface/ink tokens where they exist.

   A theme that CLAIMS the affiliations (composables/useAffiliations.js)
   embeds this inside its own footer, where standalone-band chrome would be
   wrong. Rather than have the component guess its context, the band values
   are knobs — set them on the element you put the class on:

     .site-footer__affiliations { --sa-pad: 0; --sa-max-w: none; }

   Custom properties inherit, and Vue applies a parent's class to a child
   component's root, so a theme's scoped rule reaches these. */
.sa[data-v-566a4cc8] {
  padding: var(--sa-pad, var(--site-space-4, 1.25rem));
  /* ⚠️ `--site-footer-bg` / `--site-footer-ink` DO NOT EXIST in the token
     set — the first version invented them, so every hotel silently got the
     raw fallback. Inherit the footer's own ground instead. */
  background: var(--sa-bg, transparent);
  color: var(--sa-ink, inherit);
}
.sa__inner[data-v-566a4cc8] {
  max-width: var(--sa-max-w, var(--site-max, 1200px));
  margin: var(--sa-inner-margin, 0 auto);
}


/* brand record */
:root {
  --site-color-fg: #c3cfe0;
  --site-color-accent: #31416e;
  --site-color-bg: #ffffff;
  --site-color-on-accent: #ffffff;
  --concierge-bg: rgb(255 255 255);
  --site-color-fg-muted: #c3cfe0;
  --a11y-focus: #31416e;
  --site-color-secondary-bg: #e4c0af;
  --site-color-button-colour: #495f37;
  --site-color-secondary-button-colour: #da6e8e;
  --site-color-box-colour: #647834;
  --site-color-x-bg-3: #c0cc9a;
  --site-font-display: "Open Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --site-font-body: "Cormorant Garamond", system-ui, -apple-system, "Segoe UI", sans-serif;
  --seo-ink: #31416e;
}
