/* ==========================================================================
   MUUNGA BUSH LODGE & SPA — website
   Built on the Muunga Design System (Claude Design export).

   Tokens below are carried verbatim from:
     Muunga Design System/tokens/colors.css
     Muunga Design System/tokens/typography.css
     Muunga Design System/tokens/spacing.css
     Muunga Design System/tokens/effects.css

   System rules honoured here:
     · Two closed palettes, never mixed. Digital only on this site.
     · Flat colour fields — no gradients, no blur, no drop shadows.
     · Hairline borders + space for depth. 4px radius, never pills.
     · Motion is 180ms opacity/colour only. No parallax, no scale.
     · Gold is NEVER text on Stone (2.10 — fails). Rules and bands only.
     · Sentence case headings; uppercase utility labels at 0.2em.

   Two documented overrides (approved by Ruan, 10 Aug 2026) — see NOTES.md:
     1. Dark photographic hero band rather than opening on Stone.
     2. A book bar fixed to the bottom on mobile only.
   ========================================================================== */

/* ---- fonts: self-hosted ------------------------------------------------- */
/* Jost and Lato are both SIL Open Font License 1.1 — self-hosting is
   permitted, see fonts/OFL.txt. Served from this origin so the site has no
   third-party font request: nothing renders differently if Google's CDN is
   slow or blocked, and no visitor IP reaches a third party (GDPR/POPIA).
   Jost is a variable font — ONE file covers 300/400/500, hence the
   `font-weight:100 900` range. Do not split it back into per-weight files.
   Lato is static, so it needs one file per weight. */

@font-face{
  font-family:'Jost';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/jost-var-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Jost';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('fonts/jost-var-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:300;
  font-display:swap;
  src:url('fonts/lato-300-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:300;
  font-display:swap;
  src:url('fonts/lato-300-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('fonts/lato-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('fonts/lato-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('fonts/lato-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Lato';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('fonts/lato-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ---- tokens: colour ----------------------------------------------------- */
:root{
  --color-primary-green:#414638;
  --color-primary-green-deep:#2e3127;
  --color-forest:#2e3d2b;
  --color-gold:#b8986e;
  --color-gold-light:#d4b896;
  --color-gold-dark:#7a6e52;
  --color-sage:#6b7a63;
  --color-charcoal:#3a3632;
  --color-stone:#e8e2d8;
  --color-paper:#f5f2ed;
  --color-offwhite:#fafaf7;
  --color-grey-500:#8a8078;
  --color-grey-600:#5a5652;
  --color-bone:#f2ead8;          /* Bone Cream — text on the dark greens */

  --surface-page:var(--color-stone);
  --surface-card:var(--color-paper);
  --surface-panel:var(--color-offwhite);
  --text-body:var(--color-charcoal);
  --text-heading:var(--color-primary-green);
  --text-on-dark:var(--color-bone);
  --accent:var(--color-gold);
  --border-default:var(--color-forest);
}

/* ---- tokens: type ------------------------------------------------------- */
:root{
  --font-display:'Jost','Questrial','Helvetica Neue',sans-serif;
  --font-body:'Lato','Inter',-apple-system,'Helvetica Neue',sans-serif;
  --font-utility:'Jost',Arial,sans-serif;

  --weight-light:300;
  --weight-regular:400;
  --weight-medium:500;

  --tracking-display:0.06em;
  --tracking-utility:0.2em;
  --tracking-wordmark:0.12em;

  --leading-body:1.7;
  --leading-tight:1.2;

  --text-display:52px;
  --text-h1:34px;
  --text-h2:24px;
  --text-h3:19px;
  --text-body-size:17px;
  --text-small:15px;
  --text-utility:13px;
  --text-caption:12px;
}

/* ---- tokens: space + effects -------------------------------------------- */
:root{
  --space-xs:4px;  --space-sm:8px;  --space-md:16px;
  --space-lg:32px; --space-xl:64px; --space-2xl:112px; --space-3xl:160px;

  --radius-sm:4px;
  --hairline:1px;
  --rule-width:50px;
  --motion-duration:180ms;        /* system default — colour and state changes */
  --motion-ease:ease-out;
  /* extended motion (documented override — see NOTES.md). The system's 180ms
     is right for state changes but too abrupt to carry a page. These two are
     for entrances and reveals only. */
  --motion-slow:620ms;
  --motion-enter:cubic-bezier(.22,.61,.36,1);

  --pad:clamp(20px,5vw,var(--space-xl));
  --max:1200px;
}

/* ==========================================================================
   Reset
   ========================================================================== */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{background:var(--surface-page);-webkit-text-size-adjust:100%}
body{
  font-family:var(--font-body);
  font-weight:var(--weight-regular);
  font-size:var(--text-body-size);
  line-height:var(--leading-body);
  color:var(--text-body);
  background:var(--surface-page);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
::selection{background:var(--color-primary-green);color:var(--color-bone)}

a:focus-visible,button:focus-visible,input:focus-visible,
select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--color-primary-green);
  outline-offset:3px;
  border-radius:var(--radius-sm);
}
.on-dark a:focus-visible,.on-dark button:focus-visible{outline-color:var(--color-gold-light)}

.skip{
  position:absolute;left:var(--pad);top:-100px;z-index:200;
  background:var(--color-primary-green);color:var(--color-bone);
  padding:12px 20px;border-radius:var(--radius-sm);
  font-family:var(--font-utility);font-size:var(--text-utility);
  letter-spacing:var(--tracking-utility);text-transform:uppercase;
  transition:top var(--motion-duration) var(--motion-ease);
}
.skip:focus{top:14px}

/* ==========================================================================
   Type roles
   ========================================================================== */
.display,.h1,.h2,.h3{
  font-family:var(--font-display);
  font-weight:var(--weight-light);
  letter-spacing:var(--tracking-display);
  line-height:var(--leading-tight);
  color:var(--text-heading);
}
.display{font-size:clamp(34px,5vw,var(--text-display));line-height:1.14}
.h1{font-size:clamp(27px,3.4vw,var(--text-h1))}
.h2{font-size:clamp(21px,2.4vw,var(--text-h2))}
.h3{font-size:var(--text-h3)}

.lead{font-size:clamp(18px,1.6vw,21px);line-height:1.6;color:var(--text-body)}
.body{color:var(--text-body)}
.body + .body{margin-top:var(--space-md)}
.small{font-size:var(--text-small)}
.muted{color:var(--color-grey-600)}

/* the brand's constant pair: uppercase micro-label + gold hairline rule */
.eyebrow{
  display:flex;align-items:center;gap:var(--space-md);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-utility);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:var(--color-charcoal);
}
.eyebrow::after{content:'';flex:none;width:var(--rule-width);height:1px;background:var(--accent)}
/* the brand's own line-work draws itself in */
.js .eyebrow::after{width:0;transition:width var(--motion-slow) var(--motion-enter)}
.js .eyebrow.seen::after{width:var(--rule-width)}
.eyebrow.center{justify-content:center}
.eyebrow.solo::after{display:none}
.on-dark .eyebrow{color:var(--color-bone)}

.rule{width:var(--rule-width);height:1px;background:var(--accent);border:0}
.rule.center{margin-left:auto;margin-right:auto}

/* facts still to confirm with Ruan */
.tbc{color:var(--color-grey-600);font-style:italic;border-bottom:1px dotted currentColor}
.on-dark .tbc{color:var(--color-gold-light)}

/* ==========================================================================
   Layout
   ========================================================================== */
.wrap{max-width:var(--max);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}
.narrow{max-width:680px;margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}
.block{padding-top:var(--space-2xl);padding-bottom:var(--space-2xl)}
.block-sm{padding-top:var(--space-xl);padding-bottom:var(--space-xl)}

.on-stone{background:var(--surface-page);color:var(--text-body)}
.on-paper{background:var(--surface-card);color:var(--text-body)}
.on-dark{background:var(--color-primary-green);color:var(--color-bone)}
.on-dark .h1,.on-dark .h2,.on-dark .h3,.on-dark .display{color:var(--color-bone)}
.on-dark .body,.on-dark .lead{color:var(--color-bone)}
.on-dark .muted{color:rgba(242,234,216,.72)}

/* ==========================================================================
   Buttons — filled darkens on hover, outline inverts. No scale, no shadow.
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;gap:var(--space-sm);
  font-family:var(--font-utility);font-weight:var(--weight-regular);
  font-size:var(--text-utility);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;
  padding:14px var(--space-lg);border-radius:var(--radius-sm);
  border:var(--hairline) solid var(--color-primary-green);
  background:var(--color-primary-green);color:var(--color-bone);
  cursor:pointer;
  transition:background-color var(--motion-duration) var(--motion-ease),
             color var(--motion-duration) var(--motion-ease),
             border-color var(--motion-duration) var(--motion-ease);
}
.btn:hover{background:var(--color-primary-green-deep);border-color:var(--color-primary-green-deep)}

.btn-outline{background:transparent;color:var(--color-primary-green);border-color:var(--color-primary-green)}
.btn-outline:hover{background:var(--color-primary-green);color:var(--color-bone)}

.btn-on-dark{background:transparent;color:var(--color-bone);border-color:var(--color-bone)}
.btn-on-dark:hover{background:var(--color-bone);color:var(--color-primary-green);border-color:var(--color-bone)}

/* text link — grows a gold underline on hover */
/* Links inside a sentence. .link below is a standalone call to action — uppercase,
   letterspaced, inline-flex — so using it mid-paragraph sets those words in a
   different typeface and case from the sentence carrying them. Prose links keep
   the sentence's own type and take a gold underline instead. */
.body a:not(.link):not(.btn),
.faq-a a:not(.link):not(.btn),
.lead a:not(.link):not(.btn){
  color:inherit;text-decoration:underline;
  text-decoration-color:var(--accent);
  text-decoration-thickness:1px;text-underline-offset:3px;
  transition:text-decoration-color var(--motion-duration) var(--motion-ease);
}
.body a:not(.link):not(.btn):hover,
.faq-a a:not(.link):not(.btn):hover,
.lead a:not(.link):not(.btn):hover{text-decoration-color:currentColor}

.link{
  position:relative;display:inline-flex;align-items:center;gap:var(--space-sm);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-utility);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:var(--color-charcoal);
  padding-bottom:6px;
}
.link::after{
  content:'';position:absolute;left:0;bottom:0;height:1px;width:0;background:var(--accent);
  transition:width 300ms var(--motion-enter);
}
.link:hover::after{width:100%}
.on-dark .link{color:var(--color-bone)}

/* ==========================================================================
   Header — the only fixed element the system allows
   ========================================================================== */
.head{
  position:fixed;top:0;left:0;right:0;z-index:100;
  border-bottom:var(--hairline) solid transparent;
  transition:background-color var(--motion-duration) var(--motion-ease),
             border-color var(--motion-duration) var(--motion-ease);
}
.head.stuck{background:var(--color-primary-green);border-bottom-color:var(--color-forest)}
.head-in{display:flex;align-items:center;justify-content:space-between;gap:var(--space-lg);height:76px}

/* The real logotype, not type set to look like it. Jost was only ever a stand-in
   for Bunderan, and it was close enough to look almost right, which is worse than
   looking obviously wrong. The PNG is pre-trimmed to the artwork's own bounds, so
   height alone places it — there is no baked-in padding to compensate for. */
.mark{display:block;color:var(--color-bone);flex-shrink:0}
/* max-width:none defeats the img{max-width:100%} reset. Without both this and the
   flex-shrink above, the header squashes the logotype horizontally as the viewport
   narrows — it keeps its 44px height and loses more than half its width. */
/* 44px, not 38: the lockup's "Bush Lodge & Spa" line is only 23% of the artwork's
   height, so the wordmark has to run large enough for that line to stay readable
   over a photograph. 44px puts it at roughly 10px, which is where it settles. */
.mark img{display:block;height:44px;width:auto;max-width:none}
.foot .mark img{height:52px}
@media(max-width:560px){ .mark img{height:36px} }

/* Fluid gap: eight items at a flat 32px need ~1130px of viewport and wrapped onto a
   second row below that. This keeps the system's 32px at wide sizes and eases to
   20px as it tightens, so the row survives down to the burger breakpoint. */
.nav{display:flex;align-items:center;gap:clamp(20px,2vw,var(--space-lg))}
.nav a{
  /* nowrap: the two two-word items, "The day" and "The lodge", were breaking onto a
     second line inside their own link as the header tightened, which pushed them out of
     vertical alignment with the rest of the row. */
  white-space:nowrap;
  position:relative;
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-utility);letter-spacing:var(--tracking-utility);
  /* opaque, not .82 — 13px text over the hero video needs every point of contrast */
  text-transform:uppercase;color:var(--color-bone);
  padding-bottom:4px;
  transition:color var(--motion-duration) var(--motion-ease);
}
.nav a::after{
  content:'';position:absolute;left:0;bottom:0;height:1px;width:0;background:var(--accent);
  transition:width 260ms var(--motion-enter);
}
.nav a:hover{color:var(--color-bone)}
.nav a:hover::after,.nav a[aria-current="page"]::after{width:100%}
.nav a[aria-current="page"]{color:var(--color-bone)}

.head-cta{display:flex;align-items:center;gap:var(--space-md)}
.head-cta .btn{padding:11px var(--space-md)}

.burger{display:none;background:none;border:0;padding:10px;cursor:pointer}
.burger span{display:block;width:22px;height:1px;background:var(--color-bone);
  transition:transform var(--motion-duration) var(--motion-ease),opacity var(--motion-duration) var(--motion-ease)}
.burger span + span{margin-top:6px}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

.drawer{
  position:fixed;inset:76px 0 auto 0;z-index:99;display:none;
  background:var(--color-primary-green);border-bottom:var(--hairline) solid var(--color-forest);
  padding:var(--space-md) var(--pad) var(--space-lg);
}
.drawer.open{display:block}
.drawer a{
  display:block;font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--text-h2);letter-spacing:var(--tracking-display);
  color:var(--color-bone);padding:var(--space-md) 0;
  border-bottom:var(--hairline) solid rgba(242,234,216,.16);
}
.drawer .btn{margin-top:var(--space-lg);width:100%;justify-content:center;
  background:var(--color-bone);color:var(--color-primary-green);border-color:var(--color-bone)}

/* ==========================================================================
   Hero — full-bleed photography, the way every reference lodge does it
   ========================================================================== */
.hero{position:relative;min-height:100svh;display:flex;align-items:flex-end;
  background:var(--color-primary-green-deep);overflow:hidden}
.hero .frame{position:absolute;inset:0}
.hero-in{position:relative;z-index:2;width:100%;max-width:var(--max);margin:0 auto;
  padding:0 var(--pad) var(--space-xl)}
.hero .display{color:var(--color-bone);max-width:16ch}
/* 24px is the WCAG large-text threshold. Holding the hero lead at or above it
   means it needs 3:1 rather than 4.5:1 over the photograph, which is what lets
   the scrim stay light enough to keep the picture alive. */
.hero .lead{color:var(--color-bone);max-width:42ch;margin-top:var(--space-md);
  font-size:clamp(19px,1.9vw,24px);line-height:1.55}
.hero-actions{display:flex;align-items:center;gap:var(--space-lg);flex-wrap:wrap;margin-top:var(--space-lg)}

.proof{display:flex;align-items:center;gap:var(--space-md);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-utility);letter-spacing:0.08em;color:rgba(242,234,216,.82)}
.proof b{color:var(--color-gold-light);font-weight:var(--weight-regular)}
.proof .sep{width:3px;height:3px;border-radius:50%;background:rgba(242,234,216,.5)}

/* the hero's own caption sits at the top — the copy owns the bottom */
.hero .frame .shot{top:calc(76px + var(--space-lg));bottom:auto;max-width:46ch}

.cue{position:absolute;right:var(--pad);bottom:var(--space-xl);z-index:2;
  display:flex;flex-direction:column;align-items:center;gap:var(--space-sm);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:rgba(242,234,216,.72)}
.cue::after{content:'';width:1px;height:40px;background:rgba(242,234,216,.4)}

/* ==========================================================================
   Photo slots — flat colour field + hairline + the shot this needs.
   Replace each .frame with Ruan's photograph; the caption is the brief.
   ========================================================================== */
.frame{position:relative;background:var(--color-primary-green-deep);overflow:hidden}
.frame::before{content:'';position:absolute;inset:var(--space-md);
  border:var(--hairline) dashed rgba(242,234,216,.22);border-radius:var(--radius-sm);pointer-events:none}

/* a frame holding Ruan's photograph rather than a brief */
.frame.photo::before{display:none}
.frame.photo img,.frame.photo video{width:100%;height:100%;object-fit:cover;object-position:center}
/* a hero video sits under the still and covers it once it can actually play,
   so a slow connection or a blocked autoplay still shows the photograph */
.frame.photo video{position:absolute;inset:0;opacity:0;transition:opacity 600ms var(--motion-ease)}
.frame.photo video.playing{opacity:1}
/* flat colour scrim, never a gradient — the system permits a plain flat scrim
   and the hero headline needs it to clear AA over a photograph */
/* Re-measured for the video hero (six shots, so six different backgrounds).
   The worst case is the giraffe shot, whose pale sky fills the top strip right
   behind the nav. Measured against the brightest pixel under the nav text:
       scrim .62, nav at 82% alpha ....... 3.43  fails AA
       scrim .74, nav at 82% alpha ....... 4.80  passes, but washes the photo out
       scrim .68, nav fully opaque ....... 5.1   passes with margin
   So the fix is split: a small scrim bump plus opaque header text, rather than
   one heavy scrim. Re-measure if the hero footage changes again. */
.hero .frame.photo::after{content:'';position:absolute;inset:0;background:rgba(30,33,25,.68)}
.frame .shot{
  position:absolute;left:var(--space-lg);right:var(--space-lg);bottom:var(--space-lg);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:rgba(242,234,216,.74);line-height:1.9;
}
.frame .shot::before{content:'photo — ';color:rgba(242,234,216,.5)}
.frame.forest{background:var(--color-forest)}
.frame.green{background:var(--color-primary-green)}

/* ==========================================================================
   Statement
   ========================================================================== */
.statement{text-align:center}
.statement .h1{max-width:20ch;margin:var(--space-md) auto var(--space-md)}
.statement .body{max-width:52ch;margin:0 auto}
.statement .eyebrow{justify-content:center}

/* ==========================================================================
   Rooms — one card shape: Paper, hairline Forest border, 4px radius
   ========================================================================== */
.grid{display:grid;gap:var(--space-lg);margin-top:var(--space-xl)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr);gap:var(--space-md)}

/* gallery — one shape, one border, no captions. The photographs carry it. */
.shot-tile{position:relative;aspect-ratio:3/2;overflow:hidden;
  border:var(--hairline) solid rgba(46,61,43,.28);border-radius:var(--radius-sm)}
.shot-tile img{width:100%;height:100%;object-fit:cover;
  transition:transform 700ms var(--motion-enter)}
.shot-tile:hover img{transform:scale(1.04)}
.shot-tile.tall{aspect-ratio:3/4;grid-row:span 2}

.card{
  display:flex;flex-direction:column;
  background:var(--surface-card);
  border:var(--hairline) solid var(--border-default);
  border-radius:var(--radius-sm);overflow:hidden;
  transition:background-color var(--motion-duration) var(--motion-ease);
}
.card:hover{background:var(--surface-panel)}
.card .frame{aspect-ratio:4/3}
.card .in{padding:var(--space-lg);display:flex;flex-direction:column;flex:1}
.card .h3{margin-bottom:var(--space-sm)}
.card .body{font-size:var(--text-small);flex:1}
/* NB: not `.foot` — that name belongs to the page footer and would inherit
   its dark green ground straight into the card. */
.card-foot{margin-top:var(--space-lg);padding-top:var(--space-md);
  border-top:var(--hairline) solid rgba(46,61,43,.22);
  display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);flex-wrap:wrap}

.badge{
  display:inline-flex;align-items:center;gap:var(--space-sm);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:0.1em;text-transform:uppercase;
  color:var(--color-charcoal);
  border:var(--hairline) solid rgba(46,61,43,.35);border-radius:var(--radius-sm);
  padding:5px 10px;
}
.badges{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-bottom:var(--space-md)}

/* ==========================================================================
   Spec list — the day, the rates, the spa menu.
   Reads like the lodge's own specification sheet.
   ========================================================================== */
.spec{margin-top:var(--space-xl);border-top:var(--hairline) solid rgba(46,61,43,.28)}
.on-dark .spec{border-top-color:rgba(242,234,216,.28)}

.spec-row{
  display:grid;grid-template-columns:124px 1fr auto;
  align-items:baseline;gap:var(--space-lg);
  padding:var(--space-md) 0;
  border-bottom:var(--hairline) solid rgba(46,61,43,.18);
}
.on-dark .spec-row{border-bottom-color:rgba(242,234,216,.18)}

.spec-row .t{
  display:flex;flex-direction:column;gap:10px;
  font-family:var(--font-utility);font-weight:var(--weight-regular);
  font-size:var(--text-utility);letter-spacing:0.14em;
  color:var(--color-primary-green);
}
.on-dark .spec-row .t{color:var(--color-gold-light)}

.phase{white-space:nowrap}

/* Where a thing falls in the day, rather than a clock time — drive and meal
   times move with the season, so the site never states one. The marker slides
   to roughly its point between first light and dark. --at is set per row. */
.track{position:relative;display:block;width:100%;max-width:92px;height:1px;
  background:rgba(46,61,43,.26)}
.on-dark .track{background:rgba(242,234,216,.26)}
/* at rest — also what a browser with no JavaScript shows */
.track::after{content:'';position:absolute;left:0;top:0;height:1px;width:var(--at);
  background:var(--accent);transition:width 900ms var(--motion-enter)}
.track i{position:absolute;top:-2px;left:var(--at);margin-left:-2px;
  width:5px;height:5px;border-radius:50%;background:var(--accent);
  transition:left 900ms var(--motion-enter)}
/* with JavaScript, start at first light and slide across on reveal */
.js .track::after{width:0}
.js .track i{left:0}
.js .spec-row.seen .track::after{width:var(--at)}
.js .spec-row.seen .track i{left:var(--at)}

.spec-row .n{font-size:var(--text-body-size);color:var(--text-body)}
.on-dark .spec-row .n{color:var(--color-bone)}
.spec-row .n .d{display:block;font-size:var(--text-small);color:var(--color-grey-600);margin-top:2px;max-width:56ch}
.on-dark .spec-row .n .d{color:rgba(242,234,216,.72)}

.spec-row .p{
  font-family:var(--font-utility);font-weight:var(--weight-regular);
  font-size:var(--text-body-size);color:var(--color-primary-green);white-space:nowrap;text-align:right;
}
.on-dark .spec-row .p{color:var(--color-gold-light)}
.spec-row .p small{display:block;font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:var(--color-grey-600);font-weight:var(--weight-light);margin-top:3px}
.on-dark .spec-row .p small{color:rgba(242,234,216,.6)}

.spec-row .go{grid-column:2 / -1;margin-top:var(--space-sm)}
.spec-note{margin-top:var(--space-md);font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:0.1em;text-transform:uppercase;color:var(--color-grey-600);line-height:2}
.on-dark .spec-note{color:rgba(242,234,216,.66)}

/* two-column spec (spa menu, rates) with no time column */
.spec-row.no-time{grid-template-columns:1fr auto}
.spec-row.no-time .n{grid-column:1}

/* ==========================================================================
   Split — image beside copy
   ========================================================================== */
.split{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-xl);align-items:center}
.split .frame{aspect-ratio:4/5;border-radius:var(--radius-sm)}
.split.wide .frame{aspect-ratio:4/3}

.stats{display:flex;gap:var(--space-xl);flex-wrap:wrap;margin-top:var(--space-lg);
  padding-top:var(--space-lg);border-top:var(--hairline) solid rgba(242,234,216,.28)}
.stat .v{font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--text-h1);line-height:1;color:var(--color-gold-light)}
.stat .k{font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);text-transform:uppercase;
  color:rgba(242,234,216,.72);margin-top:var(--space-sm)}

/* ==========================================================================
   Journal
   ========================================================================== */
.post{display:flex;flex-direction:column;border-top:var(--hairline) solid rgba(46,61,43,.28);
  padding-top:var(--space-md);transition:border-color var(--motion-duration) var(--motion-ease)}
.post:hover{border-top-color:var(--accent)}
.post .cat{font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:var(--color-grey-600)}
.post .h3{margin:var(--space-md) 0 var(--space-sm)}
.post .body{font-size:var(--text-small);flex:1}
.post .date{font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:0.1em;color:var(--color-grey-600);margin-top:var(--space-md)}

.post-lead{display:grid;grid-template-columns:1.1fr 1fr;gap:var(--space-xl);align-items:center;
  padding-bottom:var(--space-xl);border-bottom:var(--hairline) solid rgba(46,61,43,.28)}
.post-lead .frame{aspect-ratio:16/10;border-radius:var(--radius-sm)}

/* long-form */
.article{max-width:660px;margin:0 auto;padding:0 var(--pad)}
.article p{margin-bottom:var(--space-md)}
.article h2{font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--text-h2);line-height:var(--leading-tight);letter-spacing:var(--tracking-display);
  color:var(--text-heading);margin:var(--space-xl) 0 var(--space-md)}
.article blockquote{border-left:2px solid var(--accent);padding-left:var(--space-lg);
  margin:var(--space-xl) 0;font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:21px;line-height:1.5;color:var(--text-heading)}
.article ul{margin:0 0 var(--space-md) var(--space-md);padding-left:var(--space-md)}
.article li{margin-bottom:var(--space-sm)}

/* ==========================================================================
   Forms
   ========================================================================== */
/* Netlify Forms honeypot. Positioned off-screen rather than display:none —
   some bots skip fields that are display:none, which defeats the point. It is
   aria-hidden and tabindex="-1" in the markup, so it is unreachable by keyboard
   and invisible to screen readers. */
.hp{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.form{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-lg);margin-top:var(--space-xl)}
.field{display:flex;flex-direction:column;gap:var(--space-sm)}
.field.wide{grid-column:1 / -1}
.field label{font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:var(--color-charcoal)}
.field input,.field select,.field textarea{
  background:var(--surface-panel);
  border:var(--hairline) solid rgba(46,61,43,.4);border-radius:var(--radius-sm);
  padding:12px var(--space-md);font-size:var(--text-body-size);color:var(--text-body);
  transition:border-color var(--motion-duration) var(--motion-ease);
}
.field input::placeholder,.field textarea::placeholder{color:var(--color-grey-500)}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--color-primary-green)}
.field textarea{resize:vertical;min-height:104px;line-height:var(--leading-body)}
.form .submit{grid-column:1 / -1;display:flex;align-items:center;gap:var(--space-lg);flex-wrap:wrap}
.result{font-family:var(--font-utility);font-size:var(--text-utility);
  letter-spacing:0.08em;color:var(--color-primary-green)}

.on-dark .field label{color:var(--color-bone)}

/* the availability picker — two dates and a button, on one line where there is
   room for it */
.dates{display:flex;align-items:flex-end;justify-content:center;gap:var(--space-md);
  flex-wrap:wrap;margin-top:var(--space-xl);text-align:left}
.dates .field{flex:0 1 200px;gap:var(--space-sm)}
.dates .btn{flex:0 0 auto}
.dates input{width:100%}
@media(max-width:560px){
  .dates{flex-direction:column;align-items:stretch}
  .dates .field{flex:1 1 auto}
  .dates .btn{justify-content:center}
}

/* ==========================================================================
   Page hero (inner pages) — flat green band, no photo
   ========================================================================== */
.p-hero{padding-top:calc(76px + var(--space-2xl));padding-bottom:var(--space-2xl)}
.p-hero .display{max-width:18ch}
.p-hero .lead{max-width:52ch;margin-top:var(--space-md)}

/* ==========================================================================
   Section head
   ========================================================================== */
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--space-lg);flex-wrap:wrap}
.sec-head .h1{margin-top:var(--space-md)}

/* ==========================================================================
   Footer
   ========================================================================== */
.foot{background:var(--color-primary-green-deep);color:var(--color-bone);
  padding:var(--space-2xl) 0 var(--space-lg)}
.foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.2fr;gap:var(--space-xl)}
.foot h4{font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;color:rgba(242,234,216,.66);margin-bottom:var(--space-md)}
.foot a,.foot p{display:block;font-size:var(--text-small);color:rgba(242,234,216,.88);
  margin-bottom:var(--space-sm);transition:color var(--motion-duration) var(--motion-ease)}
.foot a:hover{color:var(--color-gold-light)}
.foot .mark{margin-bottom:var(--space-md)}
.foot address{font-style:normal}
.foot-bar{display:flex;justify-content:space-between;gap:var(--space-md);flex-wrap:wrap;
  margin-top:var(--space-2xl);padding-top:var(--space-md);
  border-top:var(--hairline) solid rgba(242,234,216,.2);
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:0.1em;color:rgba(242,234,216,.6)}
/* ==========================================================================
   FAQs — native <details>, so a question is still readable and findable with
   JavaScript off, and Google can index every answer whether or not it is open.
   Hairline rules only; the marker is a gold plus that becomes a minus.
   ========================================================================== */
.faq{border-top:var(--hairline) solid currentColor;border-color:rgba(30,33,25,.16)}
.on-dark .faq{border-color:rgba(242,234,216,.22)}
.faq-item{border-bottom:var(--hairline) solid rgba(30,33,25,.16)}
.on-dark .faq-item{border-bottom-color:rgba(242,234,216,.22)}
.faq-item summary{
  position:relative;list-style:none;cursor:pointer;
  padding:var(--space-md) var(--space-xl) var(--space-md) 0;
  font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--text-h3);line-height:1.4;
  transition:color var(--motion-duration) var(--motion-ease);
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{
  content:'';position:absolute;right:4px;top:50%;
  width:13px;height:1px;background:var(--accent);
}
/* the vertical stroke of the plus, rotated away when the item opens */
.faq-item summary::before{
  content:'';position:absolute;right:10px;top:50%;
  width:1px;height:13px;margin-top:-6px;background:var(--accent);
  transition:transform 200ms var(--motion-ease);transform-origin:center;
}
.faq-item[open] summary::before{transform:rotate(90deg)}
.faq-a{padding:0 var(--space-xl) var(--space-lg) 0;max-width:68ch}
.faq-a .body{margin:0}

/* ==========================================================================
   Contact — a plain label/value list, not a table
   ========================================================================== */
.contact-block{font-style:normal;margin-top:var(--space-md)}
.contact-rows{margin-top:var(--space-lg);display:flex;flex-direction:column}
.contact-row{
  display:grid;grid-template-columns:minmax(9rem,auto) 1fr;gap:var(--space-md);
  padding:var(--space-md) 0;border-top:var(--hairline) solid rgba(30,33,25,.16);
}
.contact-row .k{
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
  text-transform:uppercase;opacity:.7;
}
@media(max-width:560px){ .contact-row{grid-template-columns:1fr;gap:var(--space-xs)} }

/* ==========================================================================
   Guest reviews — flat panels, hairline rule, gold mark. No cards-with-shadows,
   no star glyphs, no avatars: the restraint is what stops it reading as a
   plug-in widget bolted onto a considered site.
   ========================================================================== */
.quote{
  display:flex;flex-direction:column;
  padding:var(--space-lg);
  border:var(--hairline) solid rgba(242,234,216,.22);
  border-radius:var(--radius-sm);
}
.quote blockquote{
  margin:0;flex:1;
  font-family:var(--font-display);font-weight:var(--weight-light);
  font-size:var(--text-h3);line-height:1.45;color:var(--color-bone);
}
/* the gold rule that opens every eyebrow, reused to open the quote */
.quote blockquote::before{
  content:'';display:block;width:var(--rule-width);height:1px;
  background:var(--accent);margin-bottom:var(--space-md);
}
.quote figcaption{
  margin-top:var(--space-lg);padding-top:var(--space-md);
  border-top:var(--hairline) solid rgba(242,234,216,.2);
  display:flex;flex-direction:column;gap:2px;
  font-family:var(--font-utility);font-weight:var(--weight-light);
  font-size:var(--text-caption);letter-spacing:var(--tracking-utility);
}
.quote .who{color:var(--color-bone);text-transform:none;letter-spacing:0.04em}
.quote .src{color:rgba(242,234,216,.62);text-transform:uppercase}

.foot-social{display:flex;gap:var(--space-md)}
.foot-social a{color:rgba(242,234,216,.6);
  transition:color var(--motion-duration) var(--motion-ease)}
.foot-social a:hover{color:var(--color-bone)}

/* ==========================================================================
   Book bar — mobile only. Documented override of the "nothing sticky" rule:
   this site's single objective is direct bookings.
   ========================================================================== */
.dock{
  position:fixed;left:0;right:0;bottom:0;z-index:95;display:none;
  padding:var(--space-sm) var(--pad) calc(var(--space-sm) + env(safe-area-inset-bottom));
  background:var(--color-primary-green);border-top:var(--hairline) solid var(--color-forest);
}
.dock .btn{width:100%;justify-content:center;background:var(--color-bone);
  color:var(--color-primary-green);border-color:var(--color-bone)}

/* ==========================================================================
   Motion

   Documented override of the system's "180ms opacity and colour only" rule.
   Everything here is an entrance or a reveal — nothing loops, nothing bounces,
   nothing tracks the scroll position. The 180ms default still governs every
   state change (buttons, links, header).

   The `.js` gate means a browser without JavaScript renders everything at rest
   and fully visible, rather than stuck at opacity 0.
   ========================================================================== */
@keyframes enter{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes settle{from{transform:scale(1.06)}to{transform:scale(1)}}
@keyframes cue-travel{
  0%   {transform:scaleY(0);transform-origin:top}
  45%  {transform:scaleY(1);transform-origin:top}
  55%  {transform:scaleY(1);transform-origin:bottom}
  100% {transform:scaleY(0);transform-origin:bottom}
}

/* the page-load sequence: the photograph settles, then the words arrive */
.js .hero .frame     {animation:settle 2000ms cubic-bezier(.16,.8,.3,1) both}
.js .hero .eyebrow   {animation:enter var(--motion-slow) var(--motion-enter) 140ms both}
.js .hero .display   {animation:enter var(--motion-slow) var(--motion-enter) 260ms both}
.js .hero .lead      {animation:enter var(--motion-slow) var(--motion-enter) 400ms both}
.js .hero-actions    {animation:enter var(--motion-slow) var(--motion-enter) 540ms both}
.js .cue             {animation:enter var(--motion-slow) var(--motion-enter) 720ms both}
.cue::after{animation:cue-travel 2800ms ease-in-out infinite}

/* scroll reveals */
.js .rise{opacity:0;transform:translateY(16px);
  transition:opacity var(--motion-slow) var(--motion-enter),
             transform var(--motion-slow) var(--motion-enter)}
.js .rise.seen{opacity:1;transform:none}

/* a row of cards arrives left to right, not all at once */
.js .grid > .rise:nth-child(3n+2){transition-delay:90ms}
.js .grid > .rise:nth-child(3n+3){transition-delay:180ms}
/* the gallery is four across, so the three-column rhythm above lands wrong in
   it — the fourth tile would restart the stagger mid-row. Same cadence, keyed
   to four. */
.js .grid-4 > .rise:nth-child(4n+2){transition-delay:90ms}
.js .grid-4 > .rise:nth-child(4n+3){transition-delay:180ms}
.js .grid-4 > .rise:nth-child(4n+4){transition-delay:270ms}

/* Photographs settle rather than pop: they come in fractionally over-scaled
   and come to rest. Applied to the frame, not the img, because .shot-tile and
   .card already own the img transform for hover — nesting a second transform
   on the same element would make them fight. */
.js .rise .frame.photo img,
.js .shot-tile.rise img{transform:scale(1.03);
  transition:transform var(--motion-slow) var(--motion-enter)}
.js .rise.seen .frame.photo img,
.js .shot-tile.rise.seen img{transform:none}
/* hover still wins once it has settled */
.js .shot-tile.rise.seen:hover img{transform:scale(1.04)}

/* The hero is the one reveal that runs on load rather than on scroll. Kept
   short and un-delayed on the headline: it is the largest painted element, so
   a long fade here would push Largest Contentful Paint out for no real gain.
   The lead and the actions follow it. */
.js .hero-in > .lift{opacity:0;transform:translateY(12px);
  transition:opacity 360ms var(--motion-enter),transform 360ms var(--motion-enter)}
.js .hero-in > .lift.seen{opacity:1;transform:none}
.js .hero-in > .lift:nth-child(2){transition-delay:120ms}
.js .hero-in > .lift:nth-child(3){transition-delay:240ms}

/* Phones get the still rather than the video, so the frame would otherwise be
   completely inert. A very slow drift gives it breath at no download cost.
   Deliberately long and small — at 24s and 4% it reads as depth, not motion. */
@media(max-width:767px){
  .js .hero .frame.photo img{animation:hero-drift 24s var(--motion-ease) infinite alternate;
    transform-origin:50% 60%}
}
@keyframes hero-drift{from{transform:scale(1)}to{transform:scale(1.04)}}
.js .spec-row:nth-child(2){transition-delay:60ms}
.js .spec-row:nth-child(3){transition-delay:120ms}
.js .spec-row:nth-child(4){transition-delay:180ms}
.js .spec-row:nth-child(5){transition-delay:240ms}
.js .spec-row:nth-child(6){transition-delay:300ms}

/* the photograph eases in its frame on hover */
.card .frame{transition:transform 700ms var(--motion-enter)}
.card:hover .frame{transform:scale(1.04)}

/* a spec row draws a gold hairline under itself on hover */
.spec-row{position:relative}
.spec-row::after{content:'';position:absolute;left:0;bottom:-1px;height:1px;width:0;
  background:var(--accent);transition:width 460ms var(--motion-enter)}
.spec-row:hover::after{width:100%}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media(max-width:1000px){
  .grid-3{grid-template-columns:repeat(2,1fr)}
  .grid-4{grid-template-columns:repeat(3,1fr)}
  .foot-grid{grid-template-columns:1fr 1fr}
}
@media(max-width:1100px){
  /* measured: mark 182 + nav 684 + Book now 80 + two 32px gaps = 1010px, and the wrap
     adds 102px of padding, so the full nav needs ~1113px. Below that it wrapped onto a
     second row while the burger was still hidden. */
  .nav{display:none}
  .head-cta .btn{display:none}
  .burger{display:block}
  .dock{display:block}
  .grid-3,.grid-2{grid-template-columns:1fr}
  .grid-4{grid-template-columns:repeat(2,1fr)}
  .split,.post-lead{grid-template-columns:1fr;gap:var(--space-lg)}
  .split .frame,.split.wide .frame{aspect-ratio:4/3}
  .form{grid-template-columns:1fr}
  .block{padding-top:var(--space-xl);padding-bottom:var(--space-xl)}
  .spec-row{grid-template-columns:1fr auto;gap:var(--space-md)}
  .spec-row .t{grid-column:1 / -1;margin-bottom:var(--space-xs)}
  .spec-row .go{grid-column:1 / -1}
  .hero{min-height:88svh}
  .cue{display:none}
  .foot-bar{margin-top:var(--space-xl)}
}
@media(max-width:560px){
  .foot-grid{grid-template-columns:1fr}
  .hero-actions{gap:var(--space-md)}
}

/* Reduced motion: everything lands at its finished state immediately.
   Nothing moves, nothing loops — including the scroll cue. */
/* ==========================================================================
   NEWSLETTER CAPTURE
   Markup lives in partials/newsletter.html and is stamped into every page by
   build.js.

   TWO presentations of one form, split at the system's 768px breakpoint:
     desktop  a centred dialog over a flat scrim
     mobile   a bottom banner that leaves the page visible and usable

   The mobile case is a banner on purpose. Google demotes mobile pages whose
   content is covered by an intrusive interstitial, and most lodge traffic is
   mobile search — turning this into a full-screen mobile overlay would put the
   ranking at risk. Keep it a strip.

   System rules observed: flat colour fields only (the scrim is a flat rgba, the
   same device the hero already uses — no gradient, no backdrop blur), 4px
   radius, and motion limited to opacity and colour at 180ms.
   ========================================================================== */
.signup[hidden]{display:none}
.signup{position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center}

.signup-scrim{position:absolute;inset:0;background:rgba(30,33,25,.62);
  opacity:0;transition:opacity var(--motion-duration) var(--motion-ease)}
.signup.open .signup-scrim{opacity:1}

.signup-panel{
  position:relative;width:100%;max-width:560px;
  background:var(--surface-card);
  border-top:var(--hairline) solid var(--border-default);
  padding:var(--space-lg) var(--space-lg) var(--space-md);
  opacity:0;transition:opacity var(--motion-duration) var(--motion-ease);
}
.signup.open .signup-panel{opacity:1}

.signup-close{
  position:absolute;top:var(--space-md);right:var(--space-md);
  display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;padding:0;
  background:transparent;border:var(--hairline) solid transparent;border-radius:var(--radius-sm);
  color:var(--color-grey-600);cursor:pointer;
  transition:color var(--motion-duration) var(--motion-ease),
             border-color var(--motion-duration) var(--motion-ease);
}
.signup-close:hover{color:var(--color-primary-green);border-color:rgba(46,61,43,.35)}
.signup-close:focus-visible{outline:2px solid var(--color-primary-green);outline-offset:2px}

.signup-blurb{font-size:var(--text-small);margin-top:var(--space-sm);max-width:46ch}

/* the shared .form grid is two-column; this one is a single stacked column */
.signup-form{display:flex;flex-direction:column;gap:var(--space-md);margin-top:var(--space-lg)}
.signup-form .btn{align-self:flex-start}
.signup-fine{font-family:var(--font-body);font-size:var(--text-caption);
  color:var(--color-grey-600);line-height:1.6;margin:0}
.signup-result{margin:0}

/* ---- desktop: centre it, and let the scrim do the work ------------------- */
@media(min-width:768px){
  .signup{align-items:center}
  .signup-panel{
    border:var(--hairline) solid var(--border-default);border-radius:var(--radius-sm);
    padding:var(--space-xl) var(--space-xl) var(--space-lg);
  }
  .signup-blurb{font-size:var(--text-body-size)}
}

/* ---- mobile: a strip, never a takeover ----------------------------------- */
@media(max-width:767px){
  /* No scrim on mobile. A dimmed page behind a bottom sheet reads as a modal
     to a person and to Google's intrusive-interstitial heuristics alike. */
  .signup-scrim{display:none}
  .signup{pointer-events:none}
  .signup-panel{pointer-events:auto;max-height:72vh;overflow-y:auto}
  .signup-blurb{display:none}   /* the strip carries the heading and the field only */

  /* Clear the booking dock. The dock is z-index 95 and this panel is 60, so
     without this the dock renders over the bottom of the form and swallows the
     consent line — which is the one line that must never be hidden.
     The dock is deliberately NOT hidden while this is open: direct bookings are
     the site's stated objective and outrank a newsletter signup. The panel runs
     to the bottom of the screen and pads its content up out of the way instead. */
  /* Kept deliberately tight. Google's test for a non-intrusive banner is that it
     uses "a reasonable amount of screen space"; a half-screen sheet is not that.
     Trimmed padding and a shorter label keep this to roughly a third. */
  .signup-panel{
    padding:var(--space-md) var(--space-md)
            calc(var(--space-sm) + 68px + env(safe-area-inset-bottom));
  }
  .signup-form{gap:var(--space-sm);margin-top:var(--space-md)}
  .signup-form .btn{align-self:stretch;justify-content:center}
  .signup-fine{font-size:11px;line-height:1.5}
  .signup-close{top:var(--space-sm);right:var(--space-sm)}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .js .rise{opacity:1;transform:none}
  .js .hero-in > .lift{opacity:1;transform:none}
  .js .rise .frame.photo img,
  .js .shot-tile.rise img{transform:none}
  .js .hero .frame.photo img{animation:none}
  .js .eyebrow::after{width:var(--rule-width)}
  /* rows are visible straight away here, so the day marker must already be
     at its position rather than waiting to be scrolled into view */
  .js .track::after{width:var(--at)}
  .js .track i{left:var(--at)}
  .cue::after{animation:none;transform:none}
  .card:hover .frame{transform:none}
  /* the signup fades rather than moves, so there is nothing to disable beyond
     making it appear at once */
  .signup-scrim,.signup-panel{transition-duration:.001ms !important}
}
