/* ============================================================
   BE-9.27 — SELF-HOSTED BRAND FONTS (owner: "do the font locally")
   Was: a render-blocking <link> to fonts.googleapis.com on every page, which
   made the browser resolve Google's DNS, download a CSS file, and only THEN
   discover which files to fetch from fonts.gstatic.com — two extra hosts and
   two round trips BEFORE a single word rendered. On a slow connection that is
   a blank page, and it is the shape 🖼 IMAGES & PAYLOAD rule 3 forbids.
   Now these ship from our own origin on the connection already open for the
   HTML. Both faces are SIL Open Font License, so self-hosting is permitted.

   ⚠️ League Spartan is a VARIABLE font — Google served the identical file for
   400/500/600/700 (four requests, one payload; proven by md5). One file with a
   `font-weight: 400 700` range covers every weight the site uses, which is why
   this is 66 KB and not 195 KB.

   `font-display: swap` keeps text visible while the font loads — the fallback
   face is what a visitor reads for the first moment, which is exactly the
   second font state test-mobile-overflow.mjs already measures.
   ============================================================ */
@font-face {
  font-family: 'Marcellus';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/marcellus-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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Marcellus';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/marcellus-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: 'League Spartan';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/fonts/league-spartan-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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'League Spartan';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/fonts/league-spartan-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;
}

/* =========================================================
   Cedar Pond Farms — ai.cedarpondfarms.com starting site
   Design system pulled from cedarpondfarms.com:
   - Display font: Marcellus (serif) for headings
   - Body font: League Spartan (sans) for nav/body/buttons
   - Palette: near-black #1A1817 (nav/footer/overlays),
     charcoal #231F20 (heading text), body gray #666666,
     white #FFFFFF, hairline borders on buttons
   ========================================================= */

/* ⚠️ BE-9.38 — A TOKEN IS DEFINED WITH A LITERAL. NEVER WITH var() OF ITSELF.
 *
 * BE-9.30's rule — "write the literal as the FALLBACK, not the value:
 * var(--accent, #C29D46)" — is right for a CONSUMER and fatal for a
 * DEFINITION. `--accent: var(--accent, #C29D46)` is a self-reference, which
 * CSS makes INVALID AT COMPUTED-VALUE TIME: the token resolves to nothing at
 * all, and the fallback never runs, because the fallback belongs to the very
 * declaration that was thrown away.
 *
 * Four of the five Vibe tokens were written that way and shipped. Every
 * consumer that said `var(--near-black)` with no fallback of its own — 15 of
 * them, including `.site-header` and `.float-book` — computed to
 * `rgba(0,0,0,0)`. The site header lost its background entirely: white logo
 * text on the cream page behind it, and the Book-your-experience button turned
 * invisible. The page still validated, still loaded, still passed every guard.
 *
 * Vibes presets still work: they set these same names later on :root, and a
 * later declaration wins. The literal here is the DEFAULT, not a lock.
 * Guard: scripts/check-css-tokens.mjs resolves them in a real browser.
 */
:root {
  --charcoal: #231F20;
  --near-black: #1a1817;
  --body-gray: #666666;
  --white: #ffffff;
  --cream: #faf8f5;
  /* BE-5.83 "Vibes": accent is a token so a preset can recolor it site-wide. */
  --accent: #C29D46;
  --accent-dark: #A8863A;
  --hairline: rgba(255,255,255,0.6);
  --hairline-dark: rgba(35,31,32,0.35);
  --font-display: 'Marcellus', Georgia, 'Times New Roman', serif;
  --font-body: 'League Spartan', Helvetica, Arial, sans-serif;
  --max-width: 1280px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
  color: var(--body-gray);
  background: var(--white);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--charcoal);
  font-weight: 500;
  margin: 0 0 0.5em;
  line-height: 1.15;
}

h1 { font-size: 48px; font-weight: 300; }
h2 { font-size: 42px; }
h3 { font-size: 26px; }
h4 { font-size: 20px; letter-spacing: 0.5px; }

p { margin: 0 0 1.2em; }

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

/* ⚠️ height:auto is LOAD-BEARING, and it is the missing half of the FE-1.16
   pass that put width="…" height="…" on every image to stop layout shift.
   Those attributes are presentational hints — height="934" behaves like
   `height:934px`. Paired with an `aspect-ratio` (which .card img sets) the
   browser TRANSFERS that fixed height back into a minimum width: 934 × 16/9 =
   1660px. That minimum is not something `width:100%` can undo, so a grid track
   sized to it dragged the blog index 1310px past the edge of a phone.
   The attributes are meant to supply the RATIO only; height:auto is what keeps
   them from also supplying a size. Never drop it while the attributes exist. */
img { max-width: 100%; display: block; height: auto; }

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 40px;
}

/* ---------- Header / Nav ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--near-black);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 88px;
}

.logo {
  font-family: var(--font-display);
  color: var(--white);
  font-size: 20px;
  letter-spacing: 3px;
  text-transform: uppercase;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 14px;
  line-height: 1.1;
}
.logo img.logo-mark { height: 1.5em; width: auto; display: block; }
.logo span {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 5px;
  color: rgba(255,255,255,0.6);
  margin-top: 4px;
}

nav.main-nav ul {
  list-style: none;
  display: flex;
  gap: 36px;
  margin: 0;
  padding: 0;
}

nav.main-nav a {
  color: var(--white);
  font-size: 14px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 500;
  transition: opacity .2s ease;
}
nav.main-nav a:hover { opacity: 0.65; }
nav.main-nav a.current { border-bottom: 1px solid var(--white); padding-bottom: 4px; }

.nav-toggle { display: none; }

@media (max-width: 860px) {
  nav.main-nav ul { display: none; }
  .nav-toggle {
    display: block;
    background: none;
    border: 1px solid var(--white);
    color: var(--white);
    padding: 8px 14px;
    font-family: var(--font-body);
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
  }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 16px 32px;
  border: 1px solid currentColor;
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--white);
  transition: background .25s ease, color .25s ease;
}
.btn:hover { background: rgba(255,255,255,0.12); }

.btn-dark {
  color: var(--charcoal);
}
.btn-dark:hover { background: rgba(35,31,32,0.06); }
/* BE-12.24 (owner, on the GWB "Start 3D Tour" button reading blank): .btn was
   designed for <a> — transparent, outlined, currentColor. On a <button> the
   UA's own light-gray background shows through instead, and under a dark Vibe
   the charcoal token resolves LIGHT, leaving near-white text on light gray.
   Scoped to button.btn-dark on purpose: a bare `button.btn` rule would outrank
   every funnel page's local .btn-book/.btn-inquire background by specificity
   and blank the money buttons. */
button.btn-dark { background: transparent; cursor: pointer; }
/* ⚠️ ASK-581 — BE-12.24 FIXED HALF OF THIS AND THE OTHER HALF SHIPPED FOR
   MONTHS. That fix was scoped to `button.btn-dark`, so a BARE `<button
   class="btn">` still took the UA's light-grey background under .btn's white
   text: the blog's "Show more stories" measured 1.15:1, and the same shape hid
   "Send my feedback", "Ask about buying" and three Quinceañera CTAs.
   ⚠️ The old comment's warning is respected, not ignored: a plain `button.btn`
   rule (0,1,1) WOULD outrank a funnel's `.btn-book` (0,1,0) and blank the money
   buttons. `:not([class*="btn-"])` excludes every variant, so this reaches only
   buttons that have no styled variant at all — the ones with nothing else to
   give them a background. IDs and inline styles still win, as they must. */
button.btn:not([class*="btn-"]) { background: transparent; cursor: pointer; color: var(--charcoal); }
button.btn:not([class*="btn-"]):hover { background: rgba(35,31,32,0.06); }

.btn-solid {
  background: var(--charcoal);
  border-color: var(--charcoal);
  color: var(--white);
}
.btn-solid:hover { background: var(--near-black); }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: 72vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background-size: cover;
  background-position: center;
  color: var(--white);
}
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(20,18,17,0.55) 0%, rgba(20,18,17,0.35) 45%, rgba(20,18,17,0.75) 100%);
}
/* Homepage flyover hero video — sits behind the gradient overlay + text.
   Poster shows instantly; the clip is attached by JS on wider screens only
   (phones keep the lightweight background image). */
.hero video.hero-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0; background: var(--near-black, #1a1817);
}
/* ASK-892 — night hero. Dark mode shows evening STILLS, never the daytime
   trilogy: the page-wide invert would leave day footage reading as day, and a
   sunlit hero at 10pm is the wrong picture regardless of colour. */
.hero-night { position: absolute; inset: 0; z-index: 0; display: none; }
.hero-night img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity 1.2s ease;
}
.hero-night img.on { opacity: 1; }
/* ⚠️ The dark stack re-inverts .hero to cancel the body invert. An <img> inside
   it matches the img rule too and would inverted a SECOND time — a night photo
   would come out looking like daylight. These opt out explicitly. */
:root[data-theme="dark"] .hero-night img { filter: none !important; }
@media (prefers-reduced-motion: reduce) { .hero-night img { transition: none; } }
.hero-inner {
  position: relative;
  z-index: 2;
  max-width: 780px;
  padding: 0 24px;
  /* ⚠️ .hero is a flex container, so this is a flex item and defaults to
     min-width:auto — it refuses to shrink below its widest child and pushes the
     whole page sideways instead. Every hero on the site is one long word away
     from a horizontal scrollbar without this. */
  min-width: 0;
}
.hero-eyebrow {
  text-transform: uppercase;
  letter-spacing: 4px;
  font-size: 13px;
  margin-bottom: 18px;
  color: rgba(255,255,255,0.85);
  /* The eyebrow carries a bare domain (experiences.cedarpondfarms.com) — one
     unbreakable 30-character token at 4px tracking. In League Spartan it fits;
     measured in a FALLBACK face (a guest whose connection to Google Fonts is
     slow, blocked, or offline) it came to 378px against 342px of usable phone
     width and scrolled the page. So this is not hypothetical hardening — it is
     what every visitor sees before the webfont arrives, and what some see for
     the whole visit. Deliberately no font-size or tracking change: the design
     stays as drawn, the text just bends instead of pushing the page. */
  overflow-wrap: anywhere;
}
.hero h1 { color: var(--white); margin-bottom: 20px; }
.hero p.lead {
  font-size: 19px;
  color: rgba(255,255,255,0.9);
  margin-bottom: 34px;
}
.hero .btn-row { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }

.hero.hero-small { min-height: 52vh; }

/* ---------- Sections ---------- */

section { padding: 100px 0; }
section.tight { padding: 44px 0 36px; }
section.cream { background: var(--cream); }
section.dark {
  background: var(--near-black);
  color: rgba(255,255,255,0.75);
}
section.dark h2, section.dark h3, section.dark h4 { color: var(--white); }

.section-head {
  text-align: center;
  max-width: 720px;
  margin: 0 auto 60px;
}
.section-head .eyebrow {
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 13px;
  color: var(--body-gray);
  margin-bottom: 14px;
  display: block;
}

/* ---------- Pillars (3 businesses) ---------- */

section.pillars { padding: 0; }

.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--hairline-dark);
}

.pillar {
  position: relative;
  overflow: hidden;
  min-height: 560px;
  display: flex;
  align-items: flex-end;
  color: var(--white);
  background-size: cover;
  background-position: center;
  transition: transform .5s ease;
}
.pillar::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20,18,17,0.05) 0%, rgba(20,18,17,0.85) 90%);
}
.pillar-content {
  position: relative;
  z-index: 2;
  padding: 44px 40px;
  width: 100%;
}
.pillar-num {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 3px;
  color: rgba(255,255,255,0.7);
  display: block;
  margin-bottom: 10px;
}
.pillar h3 { color: var(--white); margin-bottom: 12px; }
.pillar p { color: rgba(255,255,255,0.85); font-size: 15px; margin-bottom: 22px; }
.pillar:hover { transform: scale(1.02); }

@media (max-width: 900px) {
  section.pillars { padding: 0; }

.pillars { grid-template-columns: 1fr; }
  .pillar { min-height: 420px; }
}

/* ---------- Grid / Cards ---------- */

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 44px;
}
.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 44px;
}
@media (max-width: 900px) {
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

.card img { margin-bottom: 26px; aspect-ratio: 4/3; object-fit: cover; width: 100%; }
.card h4 { text-transform: uppercase; margin-bottom: 12px; }
.card p { font-size: 15px; }

/* ---------- Split / feature blocks ---------- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 70px;
  align-items: center;
}
.split img { width: 100%; object-fit: cover; aspect-ratio: 4/5; }
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; gap: 30px; }
}

/* ---------- Testimonials ---------- */

.testimonial {
  border-left: 2px solid var(--hairline-dark);
  padding-left: 26px;
  margin-bottom: 34px;
}
.testimonial p { font-style: italic; font-size: 16px; }
.testimonial cite { font-style: normal; font-size: 13px; letter-spacing: 1px; text-transform: uppercase; color: var(--charcoal); }

/* ---------- Property / listing cards ---------- */

.property-card {
  border: 1px solid var(--hairline-dark);
  padding: 28px;
}
.property-card h4 { margin-bottom: 6px; }
.property-meta { display: flex; gap: 18px; font-size: 13px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--body-gray); margin: 14px 0 20px; }

/* ---------- Footer ---------- */

footer.site-footer {
  background: var(--near-black);
  color: rgba(255,255,255,0.65);
  padding: 80px 0 30px;
}
footer .footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 50px;
  margin-bottom: 60px;
}
footer .logo span { color: rgba(255,255,255,0.5); }
footer h4 { color: var(--white); font-size: 14px; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 22px; }
footer ul { list-style: none; margin: 0; padding: 0; }
footer li { margin-bottom: 12px; font-size: 15px; }
footer li a:hover { color: var(--white); }
footer .footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.1);
  padding-top: 26px;
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  flex-wrap: wrap;
  gap: 14px;
}
footer .footer-bottom a { color: rgba(255,255,255,0.65); text-decoration: underline; text-underline-offset: 2px; }
footer .footer-bottom a:hover { color: var(--white); }
.socials { display: flex; gap: 16px; }

@media (max-width: 900px) {
  footer .footer-grid { grid-template-columns: 1fr; gap: 34px; }
}

/* ---------- Floating book button ---------- */

.float-book {
  position: fixed;
  left: 24px;
  bottom: 24px;
  z-index: 200;
  background: var(--charcoal);
  color: var(--white);
  padding: 16px 24px;
  font-size: 14px;
  letter-spacing: 1px;
  text-transform: uppercase;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
}
.float-book:hover { background: var(--near-black); }

/* ---------- Utility ---------- */

.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.note {
  font-size: 13px;
  color: rgba(255,255,255,0.5);
  text-align: center;
  margin-top: 16px;
}

@media(max-width:860px){
  h1{font-size:34px;} h2{font-size:28px;} .hero p.lead{font-size:16px;}
  nav.main-nav ul.open{
    display:flex;flex-direction:column;position:absolute;top:88px;left:0;right:0;
    background:var(--near-black);padding:16px 24px 44px;gap:10px;z-index:99;
    min-height:240px;
    max-height:calc(100vh - 180px);
    max-height:calc(100dvh - 100px);
    overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  }
  nav.main-nav ul.open > li > a{font-size:15px;display:inline-block;padding:4px 0;}
  nav.main-nav ul.open .sub{gap:0;padding:4px 0 2px 16px;}
  nav.main-nav ul.open .sub a{padding:6px 12px;font-size:12.5px;opacity:.9;}
  nav.main-nav ul.open{z-index:250;}
  body:has(nav.main-nav ul.open) .float-book{display:none;}
}

/* ---------- Nav dropdowns (BE-3.9 era) ---------- */
nav.main-nav li { position: relative; }
nav.main-nav .caret { font-size: 9px; opacity: .65; margin-left: 6px; }
nav.main-nav .sub {
  display: none; position: absolute; top: 100%; left: -18px;
  background: var(--near-black); min-width: 230px; padding: 12px 0; margin: 0;
  list-style: none; z-index: 130; border: 1px solid rgba(255,255,255,.09);
  flex-direction: column; gap: 0;
}
nav.main-nav li.has-sub::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 30px; }
nav.main-nav li.has-sub:hover > .sub, nav.main-nav li.has-sub:focus-within > .sub { display: flex; }
nav.main-nav .sub a { display: block; padding: 9px 20px; font-size: 12.5px; border-bottom: none; }
nav.main-nav .sub a:hover { background: rgba(255,255,255,.07); opacity: 1; }
@media (max-width: 860px) {
  nav.main-nav ul.open .sub { display: flex; position: static; background: transparent; border: none; min-width: 0; padding: 8px 0 4px 18px; }
  nav.main-nav ul.open li.has-sub::after { display: none; }
}

/* FE (July 2026, owner): subtle attention pulse on the Experiences nav item —
   the #1 booking path (guided cow experiences). A soft gold glow that
   breathes; respects reduced-motion. */
@keyframes cpfExpGlow{
  0%,100%{ text-shadow: 0 0 0 rgba(194,157,70,0); }
  50%{ text-shadow: 0 0 12px rgba(194,157,70,.95), 0 0 26px rgba(194,157,70,.45); }
}
nav.main-nav > ul > li > a[href="experiences.html"]{ animation: cpfExpGlow 3.4s ease-in-out infinite; }
/* FE (July 19, owner): the glow was invisible on phones on first load — the
   top nav collapses behind MENU, so the only Experiences link in view is the
   hero .btn. Give every .btn that points at experiences.html the same classy
   breathing gold: soft halo + border warms toward brand gold at the peak. */
@keyframes cpfExpBtnGlow{
  0%,100%{ box-shadow: 0 0 0 rgba(194,157,70,0); border-color: currentColor; }
  50%{ box-shadow: 0 0 14px rgba(194,157,70,.85), 0 0 30px rgba(194,157,70,.35),
       inset 0 0 10px rgba(194,157,70,.18); border-color: var(--accent); }
}
.btn[href="experiences.html"], .btn[href="book-experience.html"]{
  animation: cpfExpBtnGlow 3.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){
  nav.main-nav > ul > li > a[href="experiences.html"],
  .btn[href="experiences.html"], .btn[href="book-experience.html"]{ animation: none; }
}

/* ---------- Gold floater (brand-noticeable) ---------- */
.float-book.gold { background: var(--accent); color: var(--charcoal, #231F20); font-weight: 700; }
.float-book.gold:hover { background: var(--accent-dark, #A8863A); color: var(--charcoal, #231F20); }

/* FE (July 2026, owner report): on phones the floater sat on top of the hero's
   third choice button. Two-part fix: the floater shrinks to a compact pill on
   mobile, and heroes get extra bottom padding so stacked CTAs clear it. */
@media (max-width: 860px) {
  /* Compact pill + scroll-reveal (cpf-tags.js adds .fb-show past half a
     screen of scroll) — at the top of the page the hero's own buttons are
     visible, so the floater must not sit on them. */
  .float-book { left: 12px; bottom: 12px; padding: 10px 14px; font-size: 12px; letter-spacing: .5px; border-radius: 4px;
    opacity: 0; transform: translateY(70px); pointer-events: none; transition: opacity .25s ease, transform .25s ease; }
  .float-book.fb-show { opacity: 1; transform: none; pointer-events: auto; }
  /* FE (July 2026, owner report): on phones the mascot chat button, the wedding
     "Plan with us" portal pill and this experience book bar all float at the
     bottom and were stacking on top of each other + the footer. Coordinate them
     into ONE clean stack that never overlaps, and give the page bottom padding
     so the footer clears the floater zone. (Desktop keeps them side-by-side.) */
  .float-book { left: 12px; bottom: 12px; }                    /* tier 0: book bar, bottom-left */
  .cpf-portal-float { right: 12px !important; }
  #cpfMerlinBtn { right: 12px !important; }
  #cpfMerlinBox { right: 12px !important; }
  /* portal pill sits above the book bar once it scroll-reveals (they're wide
     enough to collide mid-screen), else in the bottom-right corner. */
  body:has(.float-book.fb-show) .cpf-portal-float { bottom: 62px !important; }
  /* mascot always sits ABOVE the pill: pill-only → 66px; pill+book → 116px. */
  body:has(.cpf-portal-float) #cpfMerlinBtn { bottom: 66px !important; }
  body:has(.float-book.fb-show):has(.cpf-portal-float) #cpfMerlinBtn { bottom: 116px !important; }
  body { padding-bottom: 132px; }                              /* footer clears the floaters */
}

/* Perk icon-tiles (weddings-events "Six Exceptional Perks") — same 4:3 shape
   as the photo cards, for perks we don't have a photo for yet. */
.perk-tile{aspect-ratio:4/3;width:100%;margin-bottom:26px;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(150deg,#2b2724,var(--near-black, #1a1817));border:1px solid rgba(255,255,255,.06);}
.perk-tile span{font-size:64px;line-height:1;filter:drop-shadow(0 4px 10px rgba(0,0,0,.35));}

/* ============================================================
   BE-4.77 — Light / Dark mode (site-wide, EN + ES)
   Filter-based so every page & bespoke section flips consistently
   without per-element rewrites; media, header, footer, hero and
   dark sections are re-inverted so photos and dark chrome stay true.
   ============================================================ */
:root[data-theme="dark"]{ color-scheme: dark; background:#0f0e0c; }
:root[data-theme="dark"] body{ filter: invert(0.92) hue-rotate(180deg); background:#ffffff; }
:root[data-theme="dark"] img,
:root[data-theme="dark"] video,
:root[data-theme="dark"] iframe,
:root[data-theme="dark"] picture,
:root[data-theme="dark"] svg,
:root[data-theme="dark"] .hero,
:root[data-theme="dark"] header,
:root[data-theme="dark"] .site-header,
:root[data-theme="dark"] footer,
:root[data-theme="dark"] section.dark,
:root[data-theme="dark"] [style*="background-image"],
:root[data-theme="dark"] [style*="background:url"],
:root[data-theme="dark"] [style*="background: url"]{ filter: invert(1) hue-rotate(180deg); }
.footer-bottom{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
#cpfThemeBtn:hover{ background:rgba(255,255,255,.12); }
