/*
Theme Name: a Vero Resort
Theme URI: https://poweredbyvero.com
Author: Vero (RVolve)
Description: The data-driven white-label park-site theme for Vero, built on the "Lakeside Field Guide" design system (DESIGN.md). One theme, many resorts — each site sets its own brand, video, photos, and booking property via the Customizer; the booking widget talks to the Vero engine. Ships as the Rimrock Lake Resort instance.
Version: 2.27.9
Requires at least: 6.4
Requires PHP: 8.1
License: Proprietary
Text Domain: vero-resort
*/

/* ---- Lakeside Field Guide tokens (DESIGN.md) ------------------------------
   Three voices: Fraunces (display) / Instrument Sans (body) / IBM Plex Mono
   (data). Amber acts (CTAs only), teal is live (real-time only). Radius
   4/8/12 — no pills. Dark theme via html[data-theme="dark"]. */
:root{
  --paper:#F4F1E9; --surface:#FBF9F4; --ink:#16211D; --muted:#5D6B60;
  --spruce:#0B2422; --spruce-2:#14332F; --bar:#081A18;
  --amber:#E8A14C; --amber-ink:#231604; --amber-text:#C77E2D;
  --live:#1F7A6F; --live-bright:#7FD1C8;
  --line:rgba(22,33,29,.16);
  /* "the dates you chose" -- named for the role, not the hue, so a future
     colour change never means a rename. --picked-live / --picked-muted are
     NOT --live / --muted with a new name: they exist only because the gold
     itself fails 4.5:1 for those two small text elements (see the calendar
     shading comment below), so selected cells use these instead. */
  --picked:#DCBA7D; --picked-live:#14524A; --picked-muted:#3F4A42;
  /* "the half of a day you cannot have" -- the dark side of the check-out-only
     split in the pop-up calendar. A translucent ink so it darkens whatever it
     is laid over and inverts on its own in dark mode, and so it can never be
     mistaken for --picked, which means the opposite (a day you DO have). */
  --unavailable:rgba(22,33,29,.26);
  --radius-sm:4px; --radius-md:8px; --radius-lg:12px;
  --display:"Fraunces",Georgia,serif;
  --body:"Instrument Sans",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono",Menlo,Consolas,monospace;
}
html[data-theme="dark"]{
  --paper:#101D1A; --surface:#1A2B26; --ink:#F2EDE3; --muted:#8CA39A;
  --line:rgba(242,237,227,.16); --live:#7FD1C8; --amber-text:#E8A14C;
  --picked:#705A2E; --picked-live:#ACE5DB; --picked-muted:#D2DCD6;
  --unavailable:rgba(242,237,227,.22);
}
*{box-sizing:border-box}
html,body{overflow-x:clip} /* clip, not hidden: hidden creates a scroll container and kills position:sticky */
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ---- anchor targets vs. the two stacked sticky bars -----------------------
   .utilbar (top:0) and .sitebar (top:var(--utilbar-h,29px)) are BOTH
   position:sticky, so an in-page `#anchor` click with no scroll-margin-top
   lands the target's y=0 directly under them -- the target scrolls to
   exactly where the ribbon covers it. That produced three separate bug
   reports (Marina #onsite, Stay #stay, Find us #location) that all read like
   three different bugs and were actually this one.

   The fix is derived, not a magic number: --utilbar-h is already measured by
   theme.js's measureBars() (it drives .sitebar's own `top`); --sitebar-h is
   the same function's new companion measurement of the bar below it. Adding
   them gives the exact combined height of both sticky bars at ANY width --
   including where .utilbar wraps onto two lines (narrow phones) or where
   .sitenav disappears and the hamburger takes over (≤1240px), so this holds
   without a breakpoint override. The `+12px` is breathing room so a heading
   does not sit flush against the ribbon's bottom edge.

   Fallbacks (29px / 84px) only apply before theme.js's first paint or with
   JS disabled -- close enough to not be jarring, and the real measured
   values used, take over on the very next animation frame either way. */
:root{--sitebar-h:84px}
#stay,#onsite,#conditions,#life,#seasons,#book,#location,#faq{
  scroll-margin-top:calc(var(--utilbar-h,29px) + var(--sitebar-h,84px) + 12px)
}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;transition:background .3s,color .3s}
.wrap{max-width:1140px;margin:0 auto;padding:0 24px}
h1,h2,h3{font-family:var(--display);font-weight:400;line-height:1.08;letter-spacing:-.01em;margin:0}
a{color:inherit}
img{max-width:100%}
.mono{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase}
.skip-link{position:absolute;left:-9999px}
.skip-link:focus{left:8px;top:8px;z-index:99;background:var(--surface);color:var(--ink);padding:8px 12px;border-radius:var(--radius-sm)}
.sec-label{font-family:var(--mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--live);margin-bottom:10px}
.sec-label.amber{color:var(--amber-text)}
.sec-title{font-size:clamp(1.6rem,3vw,2.3rem);margin-bottom:28px}
section{padding:72px 0}

/* ---- utility bar (very top): icons left, contact links right -------------- */
.utilbar{position:sticky;top:0;z-index:41;display:flex;justify-content:flex-end;align-items:center;gap:38px;
  padding:6px 26px 6px 96px;background:var(--bar);color:#C9D6D1;flex-wrap:wrap}
html[data-topbar="hide"] .utilbar{position:static}
.utilbar a{display:inline-flex;align-items:center;gap:7px;color:inherit;text-decoration:none;
  font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}
.utilbar a:hover{color:var(--live-bright)}
.utilbar a svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;flex:none}
.icon-btn{position:absolute;top:50%;transform:translateY(-50%);background:none;border:0;padding:4px;color:#C9D6D1;cursor:pointer;line-height:0}
.icon-btn svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;display:block}
.icon-btn:hover{color:#F2EDE3}
#theme-btn{left:14px}
#sound-btn{left:46px}
#theme-btn .i-moon{display:none}
html[data-theme="dark"] #theme-btn .i-sun{display:none}
html[data-theme="dark"] #theme-btn .i-moon{display:block}
#sound-btn.on{color:var(--live-bright)}
#sound-btn .mute-mark{display:none}
#sound-btn:not(.on) .mute-mark{display:block}
#sound-btn:not(.on) .s-wave{display:none}
#sound-btn:not(.on) .s-body{transform:translateX(5.5px)}

/* ---- sticky main bar: brand | booking controls | nav ----------------------- */
.sitebar{position:sticky;top:var(--utilbar-h,29px);z-index:40;display:flex;justify-content:space-between;align-items:center;gap:18px;
  padding:12px 26px;background:var(--spruce);color:#F2EDE3}
@supports (backdrop-filter:blur(8px)){
  .sitebar{background:color-mix(in srgb,var(--spruce) 92%,transparent);backdrop-filter:blur(8px)}
}
html[data-topbar="hide"] .sitebar{top:0}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none;color:inherit}
.brand img{height:44px;width:auto;display:block;filter:drop-shadow(0 2px 6px rgba(0,0,0,.4))}
.brand .bt{display:flex;flex-direction:column;line-height:1.15}
.brand .bt b{font-family:var(--display);font-weight:600;font-size:1.15rem}
.brand .bt .pbv{font-family:var(--mono);font-size:.56rem;letter-spacing:.3em;text-transform:uppercase;color:var(--amber);margin-top:5px;text-decoration:none}
.brand .bt .pbv:hover{text-decoration:underline}
.bookbar{display:flex;gap:8px;align-items:center}
.bookbar input,.bookbar select{height:38px;font-family:var(--mono);font-size:.72rem;letter-spacing:.04em;color:#F2EDE3;
  background:rgba(242,237,227,.08);border:1px solid rgba(242,237,227,.28);border-radius:var(--radius-md);padding:0 10px;color-scheme:dark}
.bookbar select{appearance:none;-webkit-appearance:none;padding-right:22px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23F2EDE3'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center}
.bookbar .go{height:38px;background:var(--amber);color:var(--amber-ink);font-family:var(--body);font-weight:600;font-size:.85rem;
  border:0;border-radius:var(--radius-md);padding:0 16px;cursor:pointer}
.bookbar .go:hover{filter:brightness(1.05)}

/* ---- booking bar: one range-picker dropdown in place of the two date boxes
   Two <input type=date> let a guest pick a check-out BEFORE their check-in.
   theme.js builds this control and only THEN adds .has-rangepicker, so the
   native boxes below stay visible (and usable) with JS off or broken -- they
   are still the values of record either way. Modelled on .sites-menu-panel
   above so the header has one dropdown treatment, not two. ------------------ */
.bookbar.has-rangepicker input[type=date]{display:none}
.bb-range-wrap{position:relative}
.bb-range{height:38px;font-family:var(--mono);font-size:.72rem;letter-spacing:.04em;color:#F2EDE3;
  background:rgba(242,237,227,.08);border:1px solid rgba(242,237,227,.28);border-radius:var(--radius-md);
  padding:0 14px;cursor:pointer;white-space:nowrap}
.bb-range:hover,.bb-range[aria-expanded="true"]{background:rgba(242,237,227,.14)}
.bb-range:focus-visible,.bb-cal button:focus-visible{outline:2px solid var(--live-bright);outline-offset:2px}
/* Anchored RIGHT, unlike .sites-menu-panel: the bar sits in the middle-right
   of the header, so a two-month panel hung off its left edge runs past the
   viewport. Extending leftwards always fits -- below 1100px it is one month
   wide, and below 900px the whole control is hidden. */
.bb-cal{position:absolute;top:calc(100% + 14px);right:0;z-index:60;width:max-content;max-width:92vw;
  background:var(--paper);color:var(--ink);border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:0 20px 44px -18px rgba(0,0,0,.5);padding:14px 16px}
.bb-cal[hidden]{display:none}
.bb-cal-nav{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}
.bb-cal-title{font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.bb-cal-arrow{width:28px;height:28px;line-height:1;font-size:1rem;color:var(--ink);background:none;
  border:1px solid var(--line);border-radius:var(--radius-sm);cursor:pointer}
.bb-cal-arrow:hover:not(:disabled){color:var(--live);border-color:var(--live)}
.bb-cal-arrow:disabled{opacity:.3;cursor:default}
.bb-cal-months{display:flex;gap:22px}
.bb-cal-caption{font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink);text-align:center;margin-bottom:6px}
.bb-cal-row{display:grid;grid-template-columns:repeat(7,32px)}
.bb-dow{font-family:var(--mono);font-size:.6rem;color:var(--muted);text-align:center;line-height:24px}
.bb-day{height:32px;font:inherit;font-size:.8rem;color:var(--ink);background:none;border:0;
  cursor:pointer;padding:0;position:relative}
.bb-day.is-blank{cursor:default}
.bb-day:disabled,.bb-day.is-past{color:var(--muted);opacity:.4;cursor:default}
/* The band sits behind the number so start/end caps can round independently. */
.bb-day.is-mid,.bb-day.is-preview{background:color-mix(in srgb,var(--live) 18%,transparent)}
.bb-day.is-preview{background:color-mix(in srgb,var(--live) 10%,transparent)}
/* --surface, not a fixed colour: --live is dark teal in light mode and pale
   teal in dark mode, so the text has to invert with it. */
.bb-day.is-start,.bb-day.is-end{background:var(--live);color:var(--surface);font-weight:600}
.bb-day.is-start{border-radius:var(--radius-sm) 0 0 var(--radius-sm)}
.bb-day.is-end{border-radius:0 var(--radius-sm) var(--radius-sm) 0}
.bb-day.is-start.is-end{border-radius:var(--radius-sm)}
.bb-day.is-today:not(.is-start):not(.is-end){box-shadow:inset 0 -2px 0 var(--amber)}
.bb-day:hover:not(:disabled):not(.is-start):not(.is-end){background:color-mix(in srgb,var(--live) 30%,transparent)}
.bb-cal-foot{display:flex;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
.bb-cal-nights{flex:1;font-family:var(--mono);font-size:.66rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.bb-cal-clear{font:inherit;font-size:.8rem;color:var(--muted);background:none;border:0;cursor:pointer;padding:6px 8px}
.bb-cal-clear:hover{color:var(--ink)}
.bb-cal-done{font-family:var(--body);font-weight:600;font-size:.8rem;background:var(--amber);
  color:var(--amber-ink);border:0;border-radius:var(--radius-sm);padding:7px 16px;cursor:pointer}
.bb-cal-done:hover{filter:brightness(1.05)}
/* One month at a time once two no longer fit beside each other. */
@media(max-width:1100px){.bb-cal-months>.bb-cal-month:last-child{display:none}}

/* ---- the bar once the guest is inside a reservation ------------------------
   Past the dates step the four controls are behind them, so theme.js hides
   every one of them and shows this instead:

       [ Continue Reservation ]   Start over

   THE `[hidden]` GUARDS BELOW ARE THE LOAD-BEARING PART. `[hidden]{display:none}`
   is a USER-AGENT rule and any author `display` on the same element beats it
   outright -- that is how the sound gate came to be painted on every single
   page load (#659), and why two earlier fixes that only touched theme.js could
   not have worked. `.bookbar>[hidden]` covers every control the collapse hides,
   including any added later; `.bb-continue-wrap[hidden]` covers this block's own
   `display:flex`. theme.js hides with the ATTRIBUTE, never a class, so a
   collapsed control is also out of the tab order.

   PHP renders the ordinary bar and knows nothing about any of this: with JS off
   the guest gets four working controls, never a dead "Continue" button. ----- */
.bookbar>[hidden]{display:none}
.bb-continue-wrap{display:flex;align-items:center;gap:14px}
.bb-continue-wrap[hidden]{display:none}
.bb-continue{white-space:nowrap} /* the rest is .bookbar .go -- one amber CTA treatment */
.bb-startover{font:inherit;font-size:.8rem;color:#F2EDE3;opacity:.75;background:none;border:0;
  padding:6px 2px;cursor:pointer;text-decoration:underline;white-space:nowrap}
.bb-startover:hover{opacity:1}
.bb-continue:focus-visible,.bb-startover:focus-visible{outline:2px solid var(--live-bright);outline-offset:2px}
.sitenav{display:flex;gap:20px;align-items:center;font-size:.84rem}
.sitenav a{color:#F2EDE3;opacity:.85;text-decoration:none;white-space:nowrap}
.sitenav a:hover{opacity:1}
/* One block, on purpose: .sitenav's disappearance and .nav-toggle's reveal
   (further down, next to its own rules) must never drift to different
   widths, so both live under this exact same @media condition. */
@media(max-width:1240px){.sitenav{display:none}}
@media(max-width:1240px){.nav-toggle{display:inline-flex;align-items:center}}

/* ---- Marina ▾: the nav bar's own dropdown, .sites-menu-panel's treatment
   copied rather than a second idiom invented (header.php's own comment on
   this). Unlike .sites-menu-btn the trigger is NOT [hidden] by default --
   every link inside is static PHP output with no API fetch to wait for, so
   there is nothing for theme.js to "finish loading" first. ------------------ */
.nav-drop{position:relative}
.nav-drop-btn{display:inline-flex;align-items:center;gap:4px;font:inherit;font-size:.84rem;
  color:#F2EDE3;opacity:.85;background:none;border:0;padding:0;cursor:pointer;white-space:nowrap}
.nav-drop-btn:hover,.nav-drop-btn[aria-expanded="true"]{opacity:1}
.nav-drop-btn:focus-visible{outline:2px solid var(--live-bright);outline-offset:4px}
.nav-drop-caret{font-size:.7em;line-height:1}
.nav-drop-panel{position:absolute;top:calc(100% + 14px);left:0;z-index:60;min-width:200px;
  display:flex;flex-direction:column;gap:2px;background:var(--paper);color:var(--ink);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:0 20px 44px -18px rgba(0,0,0,.5);padding:10px}
.nav-drop-panel[hidden]{display:none}
.nav-drop-panel a{display:block;padding:8px 10px;font-size:.88rem;color:var(--ink);
  text-decoration:none;border-radius:var(--radius-sm);white-space:nowrap}
.nav-drop-panel a:hover,.nav-drop-panel a:focus-visible{background:var(--surface);color:var(--live)}

/* ---- mobile nav toggle: the hamburger that replaces .sitenav at ≤1240px --
   The two must NEVER both show -- .sitenav's own `display:none` is set in
   the SAME @media block just above the Marina dropdown rules, and this
   button's `display:inline-flex` counterpart sits right next to it there on
   purpose (a HiddenDrawerAndToggleTests case in wordpress/test_nav_items.py
   pins the two to that shared condition). `[hidden]` gets its own explicit
   guard for the usual reason (the [hidden]-vs-author-`display` trap this
   stylesheet has been bitten by more than once, see .sound-gate below):
   without it, `display:inline-flex` would beat the `hidden` attribute
   header.php ships this button with, and it would show on every load
   regardless of whether theme.js ever ran. ---------------------------------- */
.nav-toggle{display:none;background:none;border:0;color:#F2EDE3;cursor:pointer;padding:6px;line-height:0}
.nav-toggle[hidden]{display:none}
.nav-toggle-icon{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;display:block}

/* ---- mobile nav drawer: slides in from the right over a scrim -------------
   Ships `hidden` in header.php; theme.js is the only thing that ever clears
   it, on a click of .nav-toggle above. `[hidden]` needs its own explicit
   `display:none` here for the exact reason `.sound-gate[hidden]` below does
   -- `display:flex` is an author rule and beats the user-agent `[hidden]`
   rule outright, which is exactly how the sound gate came to paint on every
   page load (#659). Getting this one wrong would put a drawer over the
   ENTIRE page on every visit, on every device, not just a stray panel. */
.nav-drawer{position:fixed;inset:0;z-index:95;display:flex}
.nav-drawer[hidden]{display:none}
.nav-drawer-scrim{position:absolute;inset:0;background:rgba(8,26,24,.6)}
.nav-drawer-panel{position:relative;margin-left:auto;width:min(320px,86vw);height:100%;
  display:flex;flex-direction:column;gap:2px;padding:18px 22px 28px;overflow-y:auto;
  background:var(--spruce);color:#F2EDE3;box-shadow:-20px 0 44px -18px rgba(0,0,0,.5);
  transform:translateX(100%);transition:transform .28s ease}
.nav-drawer.is-open .nav-drawer-panel{transform:translateX(0)}
@media(prefers-reduced-motion:reduce){.nav-drawer-panel{transition:none}}
.nav-drawer-close{align-self:flex-end;background:none;border:0;color:#F2EDE3;
  font:400 1.7rem/1 var(--body);cursor:pointer;padding:4px;margin-bottom:6px}
.nav-drawer-close:focus-visible,.nav-drawer-group-btn:focus-visible,
.nav-drawer-list a:focus-visible{outline:2px solid var(--live-bright);outline-offset:2px}
.nav-drawer-list{display:flex;flex-direction:column}
.nav-drawer-list a{display:block;padding:14px 2px;color:#F2EDE3;text-decoration:none;
  font-size:1rem;border-top:1px solid rgba(242,237,227,.14)}
.nav-drawer-list>a:first-child{border-top:0}
.nav-drawer-group{border-top:1px solid rgba(242,237,227,.14)}
.nav-drawer-group-btn{display:flex;width:100%;justify-content:space-between;align-items:center;
  background:none;border:0;color:#F2EDE3;font:inherit;font-size:1rem;padding:14px 2px;
  cursor:pointer;text-align:left}
.nav-drawer-group-btn::after{content:"+";font-family:var(--mono);color:var(--live-bright);transition:transform .25s}
.nav-drawer-group-btn[aria-expanded="true"]::after{transform:rotate(45deg)}
.nav-drawer-group-list{display:flex;flex-direction:column;padding-left:16px}
.nav-drawer-group-list[hidden]{display:none}
.nav-drawer-group-list a{display:block;padding:11px 2px;color:#F2EDE3;opacity:.85;
  text-decoration:none;font-size:.92rem}
.nav-drawer-group-list a:hover,.nav-drawer-group-list a:focus-visible{opacity:1}

/* ---- Sites dropdown: four submenus of bookable sites, filled by theme.js
   from the engine's /units (header.php's inert shell + comment for why). --- */
.sites-menu{position:relative}
.sites-menu-btn{font:inherit;font-size:.86rem;color:#F2EDE3;opacity:.85;background:none;border:0;
  padding:0;cursor:pointer;white-space:nowrap}
.sites-menu-btn:hover,.sites-menu-btn[aria-expanded="true"]{opacity:1}
.sites-menu-btn:focus-visible{outline:2px solid var(--live-bright);outline-offset:4px}
.sites-menu-panel{position:absolute;top:calc(100% + 14px);left:0;z-index:60;width:min(440px,92vw);
  max-height:70vh;overflow-y:auto;background:var(--paper);color:var(--ink);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:0 20px 44px -18px rgba(0,0,0,.5);padding:16px 18px}
.sites-menu-panel[hidden]{display:none}
.sites-group+.sites-group{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.sites-group-header{display:block;width:100%;font-family:var(--mono);font-size:.68rem;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);background:none;border:0;
  padding:4px 0;cursor:pointer;text-align:left}
.sites-group-header:hover,.sites-group-header:focus-visible{color:var(--live)}
.sites-list{list-style:none;margin:8px 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
.sites-list[hidden]{display:none}
.sites-item{display:block;width:100%;text-align:left;font:inherit;font-size:.85rem;color:var(--ink);
  background:none;border:0;padding:6px 0;cursor:pointer}
.sites-item:hover,.sites-item:focus-visible{color:var(--live)}
@media(max-width:900px){.bookbar input[type=date],.bb-range-wrap{display:none}}

/* ---- hero: full-bleed video, centered title, live strip -------------------- */
.hero{position:relative;min-height:86vh;display:flex;flex-direction:column;justify-content:center;overflow:hidden;background:var(--spruce)}
.hero-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 45%}
@media (prefers-reduced-motion:reduce){.hero-media{display:none}.hero{background-size:cover;background-position:center 45%}}
.hero-veil{position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,36,34,.5),rgba(11,36,34,.1) 34%,rgba(11,36,34,.28) 60%,rgba(11,36,34,.9))}
.hero-center{position:relative;z-index:2;text-align:center;padding:0 24px;color:#F2EDE3;margin:auto 0}
.hero h1{font-size:clamp(2.8rem,5.4vw,4.8rem);font-weight:300;max-width:16ch;margin:0 auto;text-shadow:0 2px 26px rgba(0,0,0,.45)}
.hero .coords{display:inline-block;margin-top:22px;color:var(--amber);background:rgba(11,36,34,.55);backdrop-filter:blur(6px);
  border-radius:var(--radius-md);padding:9px 16px;box-shadow:0 10px 24px -10px rgba(0,0,0,.55)}
.rightnow{position:absolute;bottom:36px;left:50%;transform:translateX(-50%);z-index:2;display:flex;flex-direction:column;gap:8px;
  align-items:center;background:rgba(11,36,34,.55);backdrop-filter:blur(6px);
  border:1px solid rgba(127,209,200,.35);border-radius:var(--radius-md);padding:11px 24px;width:fit-content;max-width:calc(100% - 48px);color:#F2EDE3}
.rn-head{display:flex;align-items:center;justify-content:center}
.rn-chips{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:6px 20px}
.rn-chips .wk{flex-basis:100%;text-align:center} /* weekend availability on its own line */
.rightnow .v{padding:0}
.rightnow .v.warn{color:#F0C462}
.rightnow .v.ban{color:#F09A8C;font-weight:600}
.rightnow[hidden]{display:none}
.rightnow .k{font-family:var(--mono);font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--amber)}
.rightnow .v{font-family:var(--mono);font-size:.86rem;color:#F2EDE3;white-space:nowrap}
.rightnow .v.hot{color:var(--live-bright)}
.rightnow .dot{width:7px;height:7px;border-radius:50%;background:var(--live-bright);box-shadow:0 0 8px var(--live-bright);animation:pulse 2.4s infinite}
@keyframes pulse{50%{opacity:.4}}
@media (prefers-reduced-motion:reduce){.rightnow .dot{animation:none}}
/* The strip now carries ~10 chips (wind bearing, level trend, below-full,
   storage percent). On a phone that WRAPS by design — so make the wrap
   deliberate: pin the box to both gutters instead of centring a fit-content box
   (with left:50% the shrink-to-fit width is only HALF the hero, which squeezes
   the chips into a ragged one-per-line column), then tighten gap and type. */
@media(max-width:700px){
  .rightnow{left:12px;right:12px;transform:none;width:auto;max-width:none;
    bottom:20px;padding:10px 12px;gap:6px}
  .rn-chips{gap:5px 14px}
  .rightnow .v{font-size:.72rem}
  .rightnow .k{font-size:.6rem;letter-spacing:.16em}
}

/* ---- sound gate: one elegant tap unlocks video + music together ------------ */
.sound-gate{position:fixed;inset:0;z-index:100;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:18px;
  background:rgba(8,26,24,.72);backdrop-filter:blur(10px);opacity:1;transition:opacity .5s}
/* THE SAME `hidden` TRAP AS .um-body BELOW, and this is the one that actually
   reached visitors. front-page.php ships the gate as `<div id="sound-gate"
   hidden>` and theme.js only ever clears that attribute (`gate.hidden = false`)
   for a visitor who has not answered yet. But `[hidden]{display:none}` is a
   USER-AGENT rule and the `display:flex` above is an author rule, so it won
   outright: the gate was painted on EVERY front-page load no matter what
   `readGateAnswer()` returned. Clicking a button only removed that one
   instance, so it came back on the next navigation — the "pop-up every time I
   go back to the home page" report.
   Note what this means for the two earlier fixes (#580 "honour the answer",
   #629 "ask at most once per 24h"): both rewrote the localStorage logic in
   theme.js, and that logic was never what was broken. The gate was not being
   shown by JavaScript at all. It was being shown by this stylesheet. */
.sound-gate[hidden]{display:none}
.sound-gate.bye{opacity:0;pointer-events:none}
.sound-gate .sg-brand{font-family:var(--mono);font-size:.66rem;letter-spacing:.32em;text-transform:uppercase;color:var(--live-bright)}
.sound-gate h2{font-family:var(--display);font-weight:300;font-size:clamp(1.8rem,4vw,2.8rem);color:#F2EDE3;text-align:center;max-width:16ch}
.sound-gate .sg-enter{background:var(--amber);color:var(--amber-ink);font-family:var(--body);font-weight:600;font-size:1rem;
  border:0;border-radius:var(--radius-md);padding:15px 28px;cursor:pointer}
.sound-gate .sg-quiet{background:none;border:0;color:#8CA39A;font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;cursor:pointer}
.sound-gate .sg-quiet:hover{color:#C9D6D1}

/* ---- stay cards ------------------------------------------------------------ */
/* Two chooser blocks (Cabins / Camping Sites) sit above two panels, one per
   group. Each panel's tile grid is a plain, even 3-across grid: unlike the
   old nine-box layout this replaced, a panel's card count varies per group
   (Cabins has 6, Camping Sites has 3) and per park, so there is no fixed
   total to build an offset layout around. */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
@media(max-width:1000px){.cards{grid-template-columns:repeat(2,1fr)}}
@media(max-width:540px){.cards{grid-template-columns:1fr}}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;display:flex;flex-direction:column}
.card img{height:190px;width:100%;object-fit:cover;transition:transform .5s ease}
.card:hover img{transform:scale(1.04)}
@media(prefers-reduced-motion:reduce){.card:hover img{transform:none}}
.card .body{padding:18px 20px 20px}
.card .kind{font-family:var(--mono);font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.card h3{font-size:1.35rem;margin:8px 0 4px}
/* Reserves exactly two lines' worth of height, whether the text wraps to one
   line ("Sleeps 2") or two ("Water, power & sewer · to 50 ft") — so every
   card's "Check availability" lines up regardless of meta length. --meta-lh is the
   single source for the line-height, referenced both by the `line-height`
   property and by the height calc, so the two can't drift apart; the height
   is in em (tied to font-size), never a hardcoded pixel value. Copy is not
   padded to fill the second line — a one-line meta just leaves it blank. */
.card .meta{font-size:.86rem;color:var(--muted);--meta-lh:1.4;line-height:var(--meta-lh);height:calc(var(--meta-lh) * 2em);overflow:hidden}
.card .foot{display:flex;justify-content:space-between;align-items:center;margin-top:16px}
.card .price{font-family:var(--mono);font-size:1rem}
.card .price small{color:var(--muted);font-size:.7rem}
.card .go{font-weight:600;font-size:.88rem;color:var(--live);text-decoration:none}
/* Not-yet-bookable unit: same muted mono treatment as .card .kind, no new
   colour and no new font. Deliberately a <span>, never a styled-down <a> — a
   disabled-looking link that still navigates is a bug. */
.card .soon{font-family:var(--mono);font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}

/* ---- group chooser blocks: pick Cabins or Camping Sites, panel pops open below
   Two buttons, half-width, equal height regardless of image count. Each shows
   a single rotating photo (.group-rotator below), not a grid -- the old
   mosaic set height:200px with grid-auto-rows:1fr, but a grid item's
   min-height defaults to auto, so a row could never shrink below its image's
   intrinsic size and photos overflowed the box in production, covering the
   label. Fixed here structurally, not by tuning numbers: the rotator is a
   plain relatively-positioned box with overflow:hidden, and every image is
   position:absolute so it contributes nothing to the parent's height -- no
   intrinsic size can leak out no matter what photo is dropped in. */
.group-blocks{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:32px}
@media(max-width:700px){.group-blocks{grid-template-columns:1fr}}
.group-block{display:flex;flex-direction:column;width:100%;padding:0;margin:0;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  overflow:hidden;cursor:pointer;text-align:left;font:inherit;color:inherit}
.group-block:hover{border-color:var(--live)}
.group-block:focus-visible{outline:2px solid var(--live);outline-offset:2px}
/* Crossfading rotator, one photo visible at a time (theme.js). No-JS / JS-
   broken fallback is pure CSS, no PHP state involved: every image defaults to
   opacity:0 except :first-child, which is the single static photo a visitor
   with JS off ever sees -- never a blank box, never a stack of overlapping
   photos. theme.js adds `is-live` to the container once it takes over, then
   moves `.is-active` on a timer; PHP must never emit either class itself, or
   a JS failure would show nothing (is-live with no is-active) instead of
   falling back to the first photo. */
.group-rotator{position:relative;height:200px;overflow:hidden}
.group-rotator img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity 1s ease}
.group-rotator img:first-child{opacity:1}
.group-rotator.is-live img:first-child{opacity:0}
.group-rotator.is-live img.is-active{opacity:1}
/* Auto-playing crossfade is motion a visitor cannot pause -- theme.js already
   skips starting it under reduced motion (first photo just stays put); this
   belt-and-suspenders rule also kills the transition itself, the same idiom
   this file already uses for .card:hover img and the wave edges. */
@media(prefers-reduced-motion:reduce){.group-rotator img{transition:none}}
.group-label{display:flex;flex-direction:column;gap:3px;padding:16px 20px}
.group-label .name{font-family:var(--display);font-size:1.3rem}
.group-label .count{font-family:var(--mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}

/* ---- group panels ------------------------------------------------------------
   Render OPEN in the PHP output (progressive enhancement — see front-page.php's
   #stay section); theme.js collapses them on load. [hidden] gets its own
   explicit `display:none` here, the same idiom this file already uses for
   .rightnow / .fire-bar / .lakebar-band / .cam-band, rather than relying on the
   UA default — an author rule of equal specificity elsewhere could otherwise
   silently defeat it. */
.group-panel{margin-top:28px}
.group-panel[hidden]{display:none}
.group-panel+.group-panel{margin-top:36px}

/* ---- stay cards: the photo well and its ‹ › arrows --------------------------
   Same idiom as .group-rotator above, for the same reason: every image is
   position:absolute so no photo can leak an intrinsic size into the card (the
   bug that once let images overflow the chooser blocks), and the no-JS
   fallback is pure CSS -- opacity:0 on all but :first-child, so with JS off or
   theme.js broken the card shows exactly the one static photo it shows today.
   theme.js adds `is-live` only once it has taken over and set `.is-active`;
   PHP must never emit either class.

   The arrows are display:none until a SECOND photo actually exists, and that
   test is CSS, not JS state: `img + img` matches only when two images are
   adjacent siblings, so the arrows appear the moment engine photos arrive and
   disappear again if they are removed -- nothing to keep in sync. No Rimrock
   unit has engine photos yet, so today every card holds one Customizer photo
   and shows no arrows. That is correct, not broken: two arrows that only ever
   step between one photo would be furniture.

   Arrows reuse .lb-arrow from the lake bar rather than inventing a second
   arrow idiom (DESIGN.md). The nav layer is inset:0 with pointer-events:none
   so it does not steal clicks from .card-open underneath it -- only the two
   buttons take pointer events back. */
.shots{position:relative;height:190px;overflow:hidden}
.shots img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .35s ease,transform .5s ease}
.shots img:first-child{opacity:1}
.shots.is-live img:first-child{opacity:0}
.shots.is-live img.is-active{opacity:1}
@media(prefers-reduced-motion:reduce){.shots img{transition:none}}
.shots-nav{display:none;position:absolute;inset:0;align-items:center;justify-content:space-between;
  padding:0 10px;pointer-events:none}
.shots:has(img + img) .shots-nav,.um-shots:has(img + img) .shots-nav{display:flex}
.shots-nav .lb-arrow{position:relative;z-index:3;pointer-events:auto;background:var(--surface)}

/* ---- stay cards: click anywhere to open the unit pop-up ---------------------
   theme.js lays .card-open over the whole card -- a real <button>, so Enter and
   Space work with no keyboard code of our own, and only ever added to a
   BOOKABLE card. The coming-soon card (position 6 in front-page.php's row
   shape) never gets one, so it stays exactly as inert as it is today.

   A button laid over the card, not an <a> wrapped around it: the ‹ › arrows and
   the "Check availability" link sit ABOVE it in z-order as siblings rather than as
   descendants, so no interactive element is nested inside another and an arrow
   click cannot also open the pop-up -- structurally, with no stopPropagation
   to forget. `is-openable` (JS-added) gates the hover border for the same
   reason: no affordance on a card that cannot be opened. */
.card{position:relative}
.card-open{position:absolute;inset:0;z-index:1;margin:0;padding:0;border:0;
  background:transparent;color:transparent;font:inherit;cursor:pointer}
.card-open:focus-visible{outline:2px solid var(--live);outline-offset:-3px;border-radius:var(--radius-lg)}
.card.is-openable:hover{border-color:var(--live)}
.card .go{position:relative;z-index:2}

/* ---- unit pop-up: gallery + details + availability calendar -----------------
   Built by theme.js and appended to <body>; PHP never renders any of it, so
   with JS off there is no dialog in the markup at all and "Check availability"
   remains the booking path. Near-fullscreen on a desktop, edge-to-edge on a
   phone where a floating card would waste the only screen there is. */
.unit-modal{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center}
.unit-modal[hidden]{display:none}
.um-scrim{position:absolute;inset:0;background:rgba(8,26,24,.72)}
.um-panel{position:relative;display:flex;flex-direction:column;width:min(1100px,96vw);height:min(940px,92vh);
  background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  animation:um-rise .22s ease}
@keyframes um-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.um-panel{animation:none}}
@media(max-width:700px){.um-panel{width:100vw;height:100%;border:0;border-radius:0}}
/* Locked on <html> AND <body>: iOS Safari honours one and not the other. */
html.um-open,body.um-open{overflow:hidden}
.um-close{position:absolute;top:12px;right:12px;z-index:4;display:flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;cursor:pointer;font:400 1.5rem/1 var(--body);
  background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:var(--radius-md)}
.um-close:hover{border-color:var(--live);color:var(--live)}
.um-close:focus-visible{outline:2px solid var(--live);outline-offset:2px}
/* Two columns, and the RIGHT one is the scroller -- not the whole body. The
   photo then fills its column edge to edge for the panel's full height, which
   is what "almost full screen" is for, and the details scroll independently
   instead of dragging the picture off the top. .um-shots is absolute inside a
   min-height:0 grid item, so the photo takes its height from the panel and
   never from its own intrinsic size.

   Below 900px the columns stack and the whole body becomes the single
   scroller, so the photo needs a height of its own. That height goes on the
   GALLERY, not on .um-shots: an aspect-ratio box inside an auto-sized grid row
   collapsed the row to 38px and let the photo spill straight over the title
   and details (seen at 560px). A definite height on the grid item is what
   actually sizes the row, and it keeps .um-shots absolutely positioned at both
   breakpoints -- one mechanism, not two. */
.um-body{flex:1;min-height:0;display:grid;grid-template-columns:1.05fr 1fr}
/* THE `hidden` ATTRIBUTE NEEDS SAYING TWICE HERE. `[hidden]{display:none}` is a
   USER-AGENT rule, and any author `display` beats it outright — so the
   `display:grid` above (and the `display:flex` on .um-foot) quietly cancelled
   `body.hidden = true` / `foot.hidden = true` in theme.js's showBooking().
   Both stayed on screen, both kept their `flex:1` share of the panel, and the
   booking widget — also flex:1 — was left splitting the column with them: the
   "widget is only the bottom half" the owner reported. Every other component
   in this file with an author `display` already carries its own [hidden] rule
   (.um-filter, .um-book-host, .um-directions, .um-map, .group-panel …); these
   two were the ones that got missed. */
.um-body[hidden]{display:none}
.um-gallery{position:relative;min-height:0;overflow:hidden;background:var(--spruce)}
.um-shots{position:absolute;inset:0;overflow:hidden}
.um-info{overflow-y:auto}
@media(max-width:900px){
  .um-body{grid-template-columns:1fr;overflow-y:auto}
  .um-gallery{height:56vw;min-height:190px;max-height:340px}
  .um-info{overflow:visible}
}
.um-shots img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .35s ease}
.um-shots img.is-active{opacity:1}
@media(prefers-reduced-motion:reduce){.um-shots img{transition:none}}

/* ── Whole photo, always, with a blurred fill behind it ──────────────────────
   Site photos are a real mix of shapes -- the park's own files run 540x720 and
   615x820 portrait alongside 820x615 and 1000x622 landscape, and guest-facing
   boxes here are all landscape. `object-fit:cover` filled the box by CROPPING,
   so a portrait cabin photo lost its top and bottom and a wide lake shot lost
   its sides.

   Now the photo is CONTAINed -- whole thing visible, never cropped, whatever
   its shape -- and the space that leaves over is filled with an enlarged,
   blurred copy of that same photo: above and below a tall photo, left and
   right of a wide one.

   The backdrop is painted on the container's ::before from a `--fill` custom
   property, NOT as a second <img>. That is deliberate: .shots, .um-shots and
   .group-rotator all stack their photos and let theme.js move `.is-active`
   between them BY INDEX, so a duplicate backdrop image per photo would double
   every index and break the rotator and both arrows. One backdrop per
   container sidesteps that entirely.

   front-page.php seeds `--fill` with the first photo, so with JS off or broken
   the box is still filled rather than showing a bare letterbox. theme.js
   updates it wherever it moves `.is-active`. */
.shots,.um-shots,.group-rotator{--fill:none;isolation:isolate}
.shots::before,.um-shots::before,.group-rotator::before{
  content:"";position:absolute;inset:0;z-index:0;background-image:var(--fill);
  background-size:cover;background-position:center;
  /* A blur samples past the element's edge, where there is nothing, which
     leaves a pale rim. Scaling the backdrop up pushes that rim out of sight. */
  transform:scale(1.3);filter:blur(24px) saturate(1.3) brightness(.86)}
/* No photo yet (--fill:none) means no ::before paint at all, so the well keeps
   its own background rather than showing a grey rectangle. */
.shots img,.um-shots img,.group-rotator img{object-fit:contain;z-index:1}
/* The pop-up gallery is the one box tall enough to letterbox badly on a phone,
   where it is 56vw. A softer blur there keeps the fill from reading as fog. */
@media(max-width:900px){.um-shots::before{filter:blur(16px) saturate(1.3) brightness(.86)}}
@media(prefers-reduced-motion:reduce){
  .shots::before,.um-shots::before,.group-rotator::before{transition:none}}
.um-count{position:absolute;left:12px;bottom:10px;font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;
  color:#F2EDE3;background:rgba(8,26,24,.62);padding:3px 7px;border-radius:var(--radius-sm)}
.um-count:empty{display:none}
.um-info{display:flex;flex-direction:column;gap:14px;padding:26px 28px 22px}
@media(max-width:700px){.um-info{padding:20px 18px 18px}}
.um-kind{font-family:var(--mono);font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.um-title{font-family:var(--display);font-weight:400;font-size:1.9rem;line-height:1.1;margin:0}
/* Engine descriptions are PLAIN TEXT carrying real paragraph breaks (Lake
   View's is three paragraphs of CRLF). pre-line honours them while still
   wrapping, so the copy keeps its shape without the body ever being treated as
   HTML -- it is set with textContent, never innerHTML. */
.um-desc{margin:0;max-width:54ch;color:var(--muted);font-size:.95rem;line-height:1.55;white-space:pre-line}
.um-details{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0 20px}
@media(max-width:560px){.um-details{grid-template-columns:1fr}}
.um-details li{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding:9px 0;border-top:1px solid var(--line);font-size:.9rem}
.um-details .dk{font-family:var(--mono);font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);flex:none}
.um-details .dv{text-align:right}
/* Availability. Teal is reserved for "true right now" (DESIGN.md), so it marks
   the live open-site counts and nothing else -- the picked range is ink, which
   is selection, not a live fact. */
.um-cal{margin-top:2px;padding-top:16px;border-top:1px solid var(--line)}
.um-cal-head{display:flex;align-items:center;gap:12px;margin:10px 0 12px}
.um-month{flex:1;text-align:center;font-family:var(--mono);font-size:.76rem;letter-spacing:.18em;text-transform:uppercase}
.um-dow{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:4px}
.um-dow span{text-align:center;font-family:var(--mono);font-size:.56rem;letter-spacing:.1em;color:var(--muted)}
.um-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.um-day{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  min-height:48px;padding:4px 2px;cursor:pointer;font:inherit;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm)}
.um-day .n{font-family:var(--mono);font-size:.8rem}
.um-day .o{font-family:var(--mono);font-size:.52rem;letter-spacing:.02em;color:var(--live);text-align:center}
.um-day:hover:not(:disabled){border-color:var(--live)}
.um-day:focus-visible{outline:2px solid var(--live);outline-offset:1px}
.um-day:disabled{opacity:.34;cursor:default}
.um-day.is-blank{background:transparent;border-color:transparent;cursor:default}
.um-day.is-in{background:var(--picked);border-color:var(--ink)}
.um-day.is-edge{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.um-day.is-edge .o{color:var(--paper);opacity:.72}

/* The day's price range under the count. Mono, because prices are instruments
   (DESIGN.md) — but muted rather than teal, so the teal availability count
   above it stays the loudest thing in the cell. The element only exists when
   the calendar sent both minCents and maxCents, so there is nothing here to
   collapse: a day without prices renders no .p at all. */
.um-day .p{font-family:var(--mono);font-size:.5rem;letter-spacing:.01em;color:var(--muted);text-align:center}
.um-day.is-edge .p{color:var(--paper);opacity:.66}

/* ---- a full day the guest can still LEAVE on -------------------------------
   Exclusive end: a stay from the 13th to the 14th occupies the night of the
   13th only, so the 14th being full has nothing to do with it. theme.js
   therefore enables a full day as a CHECK-OUT once there is a check-in to
   leave from (popupDayEnabled), and :disabled's dimming stops applying to it
   at exactly that moment. `.is-full` is what keeps the cell reading as a night
   nobody can stay in either state — it is never allowed to look bookable. The
   cell already says "Full" in words; this is the weight behind it.

   The one exception is the cell they actually chose: a picked check-out day is
   full-strength, because a selection the guest just made must not look greyed
   out. Declared last, so it wins the tie on equal specificity. */
.um-day.is-full{opacity:.34}
.um-day.is-full:not(:disabled){opacity:.52}
.um-day.is-full.is-checkout{opacity:1}

/* ---- ...and what that day looks like while it is offering itself -----------
   The cell now SAYS "Check out only" instead of "Full" (theme.js's
   paintSelection, wording in bookbar-sync.js's fullDayStatusText), and this is
   the same fact in colour: a corner-to-corner split, TOP-RIGHT dark and
   BOTTOM-LEFT light. Half the day is unavailable and half of it is yours.

   Same idiom as the arrival/departure shading documented below -- `to top
   right` with a hard 50% stop, no blend and no image -- so read that block for
   which stop is which half. The FIRST colour fills the lower-left, the SECOND
   the upper-right, which is why the light --surface is written first here.

   --unavailable is translucent, so the gradient is layered OVER a solid
   --surface base rather than being the only background: a `background:
   linear-gradient(...)` on its own resets background-color to transparent and
   the cell would blend into whatever sits behind the grid. Both colours are
   tokens, so the split follows the dark/light toggle without a media query.

   Declared BEFORE .is-checkin/.is-checkout: equal specificity, so the later
   rule wins, and the day the guest actually PICKS must read as the departure
   of their stay rather than as an offer they have already accepted. (The two
   cannot co-occur today -- popupDayEnabled disables a full day again once the
   range is complete, so is-checkout-only is gone by the time is-checkout
   arrives -- but the ordering is what makes that a design rather than luck.)

   "Check out only" is three words in a 44px cell, so the count line is pulled
   in a size: it wraps to two lines instead of three and the row keeps its
   height. */
.um-day.is-checkout-only{background:linear-gradient(to top right,var(--surface) 0 50%,var(--unavailable) 50% 100%),var(--surface)}
.um-day.is-checkout-only .o{font-size:.46rem;line-height:1.15;color:var(--muted)}

/* ---- arrival / departure shading -------------------------------------------
   Both are split corner to corner from top-left to bottom-right, and the gold
   half must point INTO the stay, so arrival -> nights -> departure reads as
   one unbroken band. A check-in day keeps --picked in its UPPER-RIGHT
   triangle (the nights ahead); a check-out day keeps it in its LOWER-LEFT
   (the nights just stayed). `to top right` puts the gradient's axis across
   that diagonal with the FIRST colour filling the lower-left half and the
   SECOND the upper-right — so check-in's gold is the second stop and
   check-out's is the first. A hard 50% stop, no blend, no image.

   --picked (#DCBA7D light / #705A2E dark) is the token .um-day.is-in already
   fills an in-range day with — the split and the fill agree. Its other half
   is --surface, the ordinary day colour, so a shaded cell reads as half
   "picked", half "everyday" rather than half blacked out (the old --ink half
   the owner rejected) or half "picked, half nothing" (an outward-pointing
   split reads as broken, which is the entire reason this file exists).

   Both colours stay theme tokens, so the split follows the dark/light toggle.
   These rules sit AFTER .is-edge and only override its `background`, so the
   selected range's border is untouched, and `:focus-visible` draws an outline
   — not a background — so the keyboard ring is unaffected too.

   No backing plates. The number and the count used to sit on a solid --surface
   chip because half the cell was dark and nothing centred on that diagonal was
   readable against both halves at once. With both halves light (or, in dark
   mode, both halves dark enough) they read on the cell like every other day,
   so the chip stays gone -- PR #642 removed it and it must not come back. What
   survives is the COLOUR: .is-edge paints its text --paper for the dark fill
   it no longer has, which on a light gold cell would be paper-on-paper, so
   ink/picked-live/picked-muted are put back explicitly below — and the
   opacity .is-edge dims .o and .p with is returned to 1.

   CONTRAST (see the token comment above --picked): gold is lighter than --ink
   but darker than --surface in light mode, and the mirror in dark mode, which
   is why fixing .o/.p against --picked alone is enough to also cover the
   --surface half of this same gradient -- --surface is always the MORE
   contrasty side. --picked-live/--picked-muted apply on .is-in too, since a
   whole in-range day is filled solid gold, not just half. */
.um-day.is-checkin{background:linear-gradient(to top right,var(--surface) 0 50%,var(--picked) 50% 100%)}
.um-day.is-checkout{background:linear-gradient(to top right,var(--picked) 0 50%,var(--surface) 50% 100%)}
.um-day.is-checkin .n,.um-day.is-checkout .n,
.um-day.is-checkin .o,.um-day.is-checkout .o,
.um-day.is-checkin .p,.um-day.is-checkout .p{opacity:1}
.um-day.is-checkin .n,.um-day.is-checkout .n{color:var(--ink)}
.um-day.is-in .o,.um-day.is-checkin .o,.um-day.is-checkout .o{color:var(--picked-live)}
.um-day.is-in .p,.um-day.is-checkin .p,.um-day.is-checkout .p{color:var(--picked-muted)}
.um-cal-note{margin-top:10px;font-size:.82rem;line-height:1.45;color:var(--muted)}
.um-cal-note:empty{display:none}

/* ---- the pop-up's filter row, above the calendar ---------------------------
   The guest's answers here are handed to the booking widget when they press
   "Check availability". 38px controls, per DESIGN.md's booking-control height;
   the rig fields and the people field swap in and out with the accommodation
   type, and a hidden one is `[hidden]` (out of the tab order), never merely
   transparent. */
.um-filters{display:flex;flex-wrap:wrap;gap:10px;margin:10px 0 2px}
/* The ROW goes when it has nothing left to ask. A card that names one unit
   shows neither the accommodation type nor the party size — the unit answers
   both — which on a cabin empties the row completely, and an empty strip above
   the calendar is worse than no strip. Needed explicitly for the same reason
   .um-body[hidden] is: `display:flex` above is an author rule and would beat
   the UA's `[hidden]{display:none}` on its own. */
.um-filters[hidden]{display:none}
.um-filter{display:flex;flex-direction:column;gap:4px;flex:1 1 150px;min-width:0}
.um-filter[hidden]{display:none}
.um-filter-label{font-family:var(--mono);font-size:.56rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.um-filter select{height:38px;padding:0 8px;font:inherit;font-size:.86rem;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm)}
.um-filter select:focus-visible{outline:2px solid var(--live);outline-offset:1px}
.um-filter select:disabled{opacity:.7;cursor:default}

/* ---- the booking widget, mounted inside the pop-up -------------------------
   Swaps in for the gallery/details/calendar body AND the footer when the guest
   presses "Check availability" — same panel, same × button, same scrim, same
   Esc. Scrolls on its own so the widget's site list, map and Compare table
   have somewhere to go inside a fixed-height dialog.

   FILL THE WHOLE PANEL. `flex:1` inside .um-panel's tall column is what makes
   the widget the entire pop-up rather than a band in the middle of it, and
   `min-height:0` is what lets `overflow-y:auto` actually scroll instead of the
   host growing to fit its content and pushing its own bottom out of the panel
   — that is how the widget reaches its payment step and its long site lists.
   The mounted element gets `min-height:100%` for the opposite case: a SHORT
   widget (the date step, a no-results message) still paints down the whole
   panel instead of leaving a bare strip of --paper beneath it.

   Both hold at the phone breakpoint, where .um-panel goes 100vw/100% and the
   only thing that changes here is the padding. */
.um-book-host{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:26px 28px 22px}
.um-book-host[hidden]{display:none}
.um-book-host:focus{outline:none}
.um-book-host>.um-widget{display:block;width:100%;min-height:100%}
@media(max-width:700px){.um-book-host{padding:20px 18px 18px}}

/* "Back" — out of the mounted widget, back to the calendar, WITHOUT closing
   the pop-up. Mirrors .um-close on the opposite corner because it is the same
   kind of control: panel chrome that belongs to the dialog rather than to
   whatever is inside it. It is `hidden` (theme.js) whenever the calendar is
   the thing on screen, so it never competes with the footer's own button. */
.um-back{position:absolute;top:12px;left:12px;z-index:4;display:flex;align-items:center;
  gap:6px;height:36px;padding:0 12px;cursor:pointer;font:600 .82rem/1 var(--body);
  background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:var(--radius-md)}
.um-back[hidden]{display:none}
.um-back::before{content:"\2039";font-size:1.15rem;line-height:1}
.um-back:hover{border-color:var(--live);color:var(--live)}
.um-back:focus-visible{outline:2px solid var(--live);outline-offset:2px}

/* ---- "Getting there": unit.directions, hidden entirely when there is none */
.um-directions{margin-top:2px;padding-top:16px;border-top:1px solid var(--line)}
.um-directions[hidden]{display:none}
.um-directions-text{margin:0;color:var(--muted);font-size:.92rem;line-height:1.55;white-space:pre-line}

/* ---- map panel: a zoomed crop + the full map, same pin, both stacked -----
   Hidden entirely unless this unit has a placed position (loadMapPanel in
   theme.js) -- same fail-soft rule as photos and directions above. The crop
   is a fixed box; theme.js positions/sizes its <img> in JS (clamped pixel
   math, not expressible as a CSS percentage) once the 3.6MB image is loaded.
   The full map is plain -- image scaled to the box by CSS alone, pin at
   left/top %. */
.um-map{margin-top:2px;padding-top:16px;border-top:1px solid var(--line)}
.um-map[hidden]{display:none}
.um-map-crop{position:relative;height:170px;overflow:hidden;border-radius:var(--radius-md);
  background:var(--surface);margin-bottom:10px}
.um-map-crop img{position:absolute;top:0;left:0;max-width:none}
.um-map-full{position:relative;border-radius:var(--radius-md);overflow:hidden;line-height:0}
.um-map-full img{display:block;width:100%;height:auto}
.um-map-pin{position:absolute;width:14px;height:14px;margin:-9px 0 0 -7px;border-radius:50%;
  background:var(--amber);border:2px solid var(--paper);box-shadow:0 0 0 2px rgba(0,0,0,.28);
  pointer-events:none}

.um-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:14px 28px;background:var(--surface);border-top:1px solid var(--line)}
/* Same reason as .um-body[hidden] above: an author `display` beats the UA's
   `[hidden]{display:none}`, so without this line the footer stayed on screen
   underneath the mounted booking widget. */
.um-foot[hidden]{display:none}
@media(max-width:700px){.um-foot{padding:12px 18px}}
.um-sel{font-family:var(--mono);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.um-book{cursor:pointer;padding:12px 20px;font-family:var(--body);font-weight:600;font-size:.92rem;
  background:var(--amber);color:var(--amber-ink);border:0;border-radius:var(--radius-md)}
.um-book:disabled{opacity:.45;cursor:default}
.um-book:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ---- on-site amenities ------------------------------------------------------ */
.onsite .split{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:center}
@media(max-width:800px){.onsite .split{grid-template-columns:1fr;gap:30px}}
.onsite img{width:100%;border-radius:var(--radius-lg);box-shadow:0 18px 40px -22px rgba(11,36,34,.5)}
.onsite h2{font-size:clamp(1.7rem,3vw,2.4rem);max-width:15ch;margin:12px 0 8px;font-weight:300}
.onsite .lead{color:var(--muted);margin:0 0 20px;max-width:44ch}
.amen{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:1fr 1fr;gap:0 26px}
@media(max-width:480px){.amen{grid-template-columns:1fr}}
.amen li{display:flex;gap:12px;align-items:baseline;padding:13px 0;border-top:1px solid var(--line);font-size:.96rem}
.amen li .n{font-family:var(--mono);font-size:.68rem;color:var(--live);letter-spacing:.08em;min-width:24px}

/* ---- polaroids: warm off-white in BOTH themes ------------------------------- */
.snaps{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;align-items:start}
@media(max-width:900px){.snaps{grid-template-columns:1fr 1fr}}
.snap{background:#FAF7EF;border:1px solid rgba(22,33,29,.12);border-radius:var(--radius-sm);padding:10px 10px 14px;
  box-shadow:0 14px 28px -18px rgba(11,36,34,.5)}
html[data-theme="dark"] .snap{box-shadow:0 18px 34px -16px rgba(0,0,0,.7)}
.snap:nth-child(odd){transform:rotate(-1.6deg)}
.snap:nth-child(even){transform:rotate(1.2deg) translateY(10px)}
.snap img{width:100%;height:150px;object-fit:cover;border-radius:2px}
.snap .cap{font-family:var(--mono);font-size:.64rem;letter-spacing:.1em;text-transform:uppercase;color:#6B7A6F;margin-top:10px;text-align:center}

/* ---- wave edges: the one big water moment ----------------------------------- */
.wave-edge{position:relative;height:64px;overflow:hidden;line-height:0}
.wave-edge svg{position:absolute;bottom:0;left:0;width:200%;height:100%}
.wave-edge .back{opacity:.3}
.wave-edge.exit{background:var(--spruce)}
.wave-edge .fill-spruce{fill:var(--spruce)}
.wave-edge .fill-paper{fill:var(--paper)}
.wave-edge .fill-teal{fill:var(--live)}

/* ---- dark seasons band ------------------------------------------------------ */
.seasons-band{background:var(--spruce);color:#E6EEEB;padding:64px 0 72px}
.seasons-band .sec-label{color:var(--live-bright)}
.seasons-band h2{color:#F2EDE3;font-weight:300;font-size:clamp(1.7rem,3vw,2.4rem);margin-bottom:34px}
.season-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:0}
@media(max-width:760px){.season-grid{grid-template-columns:1fr 1fr}}
@media(max-width:440px){.season-grid{grid-template-columns:1fr}}
.season{padding:4px 26px;border-left:1px solid rgba(242,237,227,.16)}
.season:first-child{border-left:0;padding-left:0}
.season .n{font-family:var(--mono);font-size:.64rem;letter-spacing:.2em;text-transform:uppercase;color:var(--amber)}
.season h3{color:#fff;font-size:1.3rem;margin:12px 0 8px}
.season p{color:#A9BDB8;font-size:.9rem;margin:0}

/* ---- location --------------------------------------------------------------- */
.loc{display:grid;grid-template-columns:1.2fr .8fr;gap:48px;align-items:start}
@media(max-width:760px){.loc{grid-template-columns:1fr;gap:28px}}
.loc h2{font-size:clamp(1.8rem,3vw,2.6rem);max-width:14ch;margin:12px 0 18px;font-weight:300}
.loc p{max-width:48ch;color:var(--muted)}
.data{font-family:var(--mono);font-size:.78rem;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface)}
.data div{display:flex;justify-content:space-between;gap:16px;padding:13px 16px;letter-spacing:.04em}
.data div + div{border-top:1px solid var(--line)}
.data .dk{color:var(--muted);text-transform:uppercase;font-size:.64rem;letter-spacing:.12em}
.contact-line{margin-top:24px;font-family:var(--mono);font-size:.8rem;letter-spacing:.04em}
.contact-line a{color:var(--live);text-decoration:none}

/* ---- booking section --------------------------------------------------------- */
.booking-panel{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:28px}

/* ---- fire-restriction warning bar (below the hero) --------------------------- */
.fire-bar{background:#7A241C;color:#FDECEA}
.fire-bar[data-stage="1"]{background:#8A5A12;color:#FBF0D8}
.fire-bar[hidden]{display:none}
.fire-bar-inner{display:flex;align-items:center;gap:14px;padding:12px 24px}
.fire-noflame{width:26px;height:26px;flex:none}
.fire-noflame .fl{fill:currentColor;opacity:.9}
.fire-noflame .ring,.fire-noflame .slash{stroke:#FF5A4D;stroke-width:2;fill:none;stroke-linecap:round}
.fire-bar[data-stage="1"] .fire-noflame .ring,.fire-bar[data-stage="1"] .fire-noflame .slash{stroke:#F0C462}
.fire-text{font-size:.92rem;line-height:1.4}
.fire-text b{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;margin-right:6px}
.fire-link{margin-left:auto;color:inherit;font-weight:600;font-size:.85rem;white-space:nowrap;text-decoration:underline}
@media(max-width:640px){.fire-bar-inner{flex-wrap:wrap}.fire-link{margin-left:0}}

/* ---- lake conditions bar: full-bleed band, day stepper, six tiles -------------
   Tokens only, so the existing dark theme (html[data-theme="dark"], set from
   prefers-color-scheme by the boot script) recolours it with no extra rules.
   The band takes --surface and the tiles take --paper — the inverse of the rest
   of the page, which is what separates the band from the sections either side. */
.lakebar-band{background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:52px 0 56px}
.lakebar-band[hidden]{display:none}
.lb-title{font-size:clamp(1.5rem,2.6vw,2.1rem);font-weight:300;margin-bottom:22px}
.lb-head{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:18px}
.lb-day{font-family:var(--mono);font-size:.78rem;letter-spacing:.2em;text-transform:uppercase;color:var(--ink);
  min-width:11ch;text-align:center}
.lb-arrow{display:inline-flex;align-items:center;justify-content:center;flex:none;width:34px;height:34px;padding:0;cursor:pointer;
  background:var(--paper);color:var(--ink);border:1px solid var(--line);border-radius:var(--radius-md);
  font-family:var(--mono);font-size:1.1rem;line-height:1}
.lb-arrow:hover:not(:disabled){border-color:var(--live);color:var(--live)}
.lb-arrow:disabled{opacity:.32;cursor:default}
.lb-arrow:focus-visible{outline:2px solid var(--live);outline-offset:2px}
/* flex, not grid: a grid's explicit fr tracks stay put even when fewer tiles
   are placed, so a quiet day's 4 tiles sat left-aligned with two empty
   columns to the right. flex-wrap + justify-content:center lets a short row
   centre itself; each flex-basis below is the exact same math the old grid's
   1fr tracks produced (100% minus the gaps, divided by the column count), so
   a FULL row is pixel-identical to before and tiles never grow to fill the
   gap — flex:0 0 <basis> fixes the width instead of letting it flex. */
.lb-tiles{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
.lb-tile{flex:0 0 calc((100% - 60px)/6)}
@media(max-width:1000px){.lb-tile{flex-basis:calc((100% - 24px)/3)}}
@media(max-width:560px){.lb-tile{flex-basis:calc((100% - 12px)/2)}}
.lb-tile{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  min-height:132px;padding:16px 12px;text-align:center;text-decoration:none;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-lg)}
.lb-tile.go:hover{border-color:var(--live)}
.lb-tile.go:hover .lb-v{color:var(--live)}
.lb-k{font-family:var(--mono);font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.lb-v{font-family:var(--display);font-weight:400;font-size:1.5rem;line-height:1.12}
.lb-tile.hot .lb-v{color:var(--live)}
/* the fishing tile's value is a phrase, not a datum — body voice, not display */
.lb-tile.go .lb-v{font-family:var(--body);font-weight:600;font-size:.95rem;line-height:1.35}
.lb-note{font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;line-height:1.45;color:var(--muted)}
.lb-badge{font-family:var(--mono);font-size:.54rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:var(--radius-sm);padding:2px 6px;margin-bottom:2px}
.lb-foot{display:flex;justify-content:space-between;align-items:baseline;gap:16px;flex-wrap:wrap;margin-top:18px}
.lb-level{font-family:var(--mono);font-size:.72rem;letter-spacing:.06em;color:var(--muted)}
.lb-more{font-weight:600;font-size:.88rem;color:var(--live);text-decoration:none;white-space:nowrap}
.lb-more:hover{text-decoration:underline}
@media(max-width:420px){.lakebar-band{padding:40px 0 44px}.lb-title{margin-bottom:16px}
  .lb-tile{min-height:116px;padding:14px 10px}.lb-v{font-size:1.28rem}}

/* ---- live park camera (vero-webcam plugin) -------------------------------------
   One frame, one line. The image is the section, so there is no card chrome
   around it beyond the 12px frame; the "updated" line is mono + teal because it
   is live data (DESIGN.md: teal = true right now).

   Top gap: every OTHER section on this page reaches the standard 72px gap by
   zeroing its own top padding and letting the section above supply the full
   72px (section{padding:72px 0}, untouched — there is no narrower-width
   override of it anywhere, so 72px is the target at EVERY width). This
   section is different — the element above it, .lakebar-band, is a <div>
   with its OWN smaller padding (52px 0 56px at rest), not a plain <section>,
   so its bottom contributes only 56px, not 72px. padding-top:0 here measured
   out to a 56px gap while every other transition on the page measured 72px
   (measured live, see PR). 16px makes up the difference (56 + 16 = 72) so
   this section reads at the same rhythm as the rest of the page instead of
   sitting visibly tighter under the band above it. Do NOT change this to the
   base 72px — that would double-count the .lakebar-band's own bottom padding
   and open a 128px gap, wider than anywhere else on the page.

   IMPORTANT: this 56+16 math holds only above 420px. .lakebar-band has its
   OWN narrower-width override above (padding:40px 0 44px at ≤420px), which
   drops its bottom contribution to 44px there — so the media query right
   below bumps .cam-band's own top padding to 28px at that width (44+28=72).
   If .lakebar-band's padding ever changes at any width, .cam-band's top
   padding has to be re-derived at that width too — it is not a fixed
   constant, it is "72 minus whatever .lakebar-band's bottom padding is at
   this breakpoint".

   This override MUST come after the unconditional rule below, not before —
   CSS breaks ties on equal specificity by source order, not by which rule's
   @media condition is narrower, so a ≤420px override placed earlier in the
   file (e.g. inside the .lakebar-band media query above) would silently
   lose to the unconditional rule at every width, including ≤420px. */
.cam-band{padding-top:16px}
@media(max-width:420px){.cam-band{padding-top:28px}}
.cam-band[hidden]{display:none}
.cam-title{font-size:clamp(1.5rem,2.6vw,2.1rem);font-weight:300;margin-bottom:20px}
.cam-shot{margin:0}
.cam-shot .cam-img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:0 18px 40px -22px rgba(11,36,34,.5)}
html[data-theme="dark"] .cam-shot .cam-img{box-shadow:0 20px 42px -20px rgba(0,0,0,.7)}
.cam-cap{display:flex;align-items:center;gap:9px;margin-top:12px}
.cam-updated{font-family:var(--mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--live)}
.cam-dot{width:7px;height:7px;flex:none;border-radius:50%;background:var(--live);
  box-shadow:0 0 8px var(--live);animation:pulse 2.4s infinite}
@media (prefers-reduced-motion:reduce){.cam-dot{animation:none}}

/* ---- live conditions (ski + road, winter) ------------------------------------- */
.cond-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:20px}
.cond-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:16px 18px}
.cond-card.wide{grid-column:1 / -1}
.cond-k{font-family:var(--mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.cond-v{font-family:var(--mono);font-size:1.05rem;color:var(--ink);margin-top:6px}
.cond-bite{font-family:var(--display);font-weight:400;font-size:1.9rem;color:var(--live);margin-top:4px}
.cond-note{font-size:.9rem;color:var(--muted);margin-top:8px;line-height:1.5}
.cond-btns{display:flex;gap:12px;flex-wrap:wrap}
.cond-btn{display:inline-flex;align-items:center;background:transparent;color:var(--ink);border:1.5px solid var(--ink);border-radius:var(--radius-md);padding:11px 18px;font-weight:600;font-size:.9rem;text-decoration:none}
.cond-btn:hover{border-color:var(--live);color:var(--live)}

/* ---- FAQ: one answer open at a time, amber when open -------------------------- */
.faq details{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-md);margin-bottom:10px;overflow:hidden}
.faq summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:14px;padding:16px 18px;font-weight:600;font-size:.98rem}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--mono);font-size:1.1rem;color:var(--live);flex:none;transition:transform .25s}
.faq details[open] summary::after{transform:rotate(45deg);color:inherit}
.faq details[open] summary{color:var(--amber-text)}
.faq .a{padding:0 18px 16px;color:var(--muted);font-size:.94rem;max-width:70ch}

/* ---- footer ------------------------------------------------------------------ */
.site-footer{background:var(--spruce);color:#9FB3AE;padding:36px 0}
.site-footer .foot{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap}
.site-footer .f-brand{display:flex;flex-direction:column;line-height:1.2}
.site-footer .f-brand b{font-family:var(--display);font-weight:600;color:#F2EDE3;font-size:1.05rem}
.site-footer .f-brand .pbv{font-family:var(--mono);font-size:.56rem;letter-spacing:.3em;text-transform:uppercase;color:var(--amber);margin-top:5px;text-decoration:none}
.site-footer .f-brand .pbv:hover{text-decoration:underline}
.site-footer .f-legal{display:flex;gap:26px;flex-wrap:wrap}
.site-footer .f-legal a{color:#C9D6D1;text-decoration:none;font-size:.85rem}
.site-footer .f-legal a:hover{color:var(--live-bright)}
.site-footer .f-copy{color:#7E948E;font-size:.66rem}

/* ---- Resort Conditions page (page-conditions.php) -------------------------------
   Tokens only, so the existing dark theme recolours all of it with no extra
   rules — and specifically NOT Lakebrief's own blue, which lives inside their
   cross-origin iframe and stays there.
   The page is: title → live camera → our ten-day bar → their dashboard → link
   out. The camera and the bar are the same components the front page uses; the
   only page-specific rules here are the header block and the embed wrapper. */
.cond-head{padding-bottom:40px}
.cond-h1{font-size:clamp(2rem,4vw,3rem);font-weight:300}
.cond-intro{margin-top:20px;max-width:62ch;color:var(--muted)}
.cond-intro p{margin:0 0 14px}
.cond-intro a{color:var(--live)}
/* .cam-band ships padding-top:0 because on the front page it tucks under the
   conditions band. Here it follows a heading block, so give it its own top gap
   and let the bar below keep the band separation it already has. */
.page-template-page-conditions .cam-band{padding-top:0;padding-bottom:56px}
.cond-embed{padding-top:56px}
/* The wrapper, not the iframe: their loader writes border-radius:16px inline, so
   clipping it at our 12px is the only way to hold the design system without an
   !important war. The frame only appears once an iframe actually lands, so a
   blocked, offline or ad-blocked loader leaves no empty bordered box behind. */
.lb-embed{width:100%}
.lb-embed > [data-lakebrief]{width:100%}
.lb-embed:has(iframe){background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-lg);overflow:hidden}
/* Height only until their `lakebrief:embed-height` postMessage arrives — that
   handler sets an inline height, which wins over this. Without it an un-resized
   iframe would sit at the 150px HTML default and scroll internally. */
.lb-embed iframe{display:block;width:100%;height:clamp(620px,86vh,1000px);border:0}
.cond-embed .cond-btns{margin-top:24px}
@media(max-width:560px){
  .cond-head{padding-bottom:28px}
  .cond-embed{padding-top:40px}
  .lb-embed iframe{height:clamp(560px,92vh,900px)}
}

/* ---- inner pages (index.php fallback) ----------------------------------------- */
.page-body{padding:56px 0}
.page-body h1{font-weight:300;font-size:clamp(2rem,4vw,3rem);margin-bottom:24px}
.page-body article + article{margin-top:40px}
/* Widget-embed pages (Book, Camp Store, Rentals, Day Use). The widget is a
   centred max-width column inside the 1140px wrap, so the title centres over it
   instead of hanging off the far left. Prose pages keep the left-aligned h1 —
   the class is only emitted for embeds (vero_page_is_widget_embed). */
.page-body-embed h1{text-align:center;margin-bottom:32px}
