/* Fluid type scale.
   The class is doubled on purpose: Tailwind's preflight resets headings with
   `h1, h2 { font-size: inherit }` from an unlayered stylesheet, which would
   otherwise win over these rules and collapse every heading to 16px. */
.text-fluid-hero.text-fluid-hero {
  font-size: clamp(2.1rem, 5.8vw, 5.25rem);
  line-height: 1.07;
}
.text-fluid-headline.text-fluid-headline {
  font-size: clamp(1.75rem, 3.8vw, 3.6rem);
  line-height: 1.18;
}
.text-fluid-quote.text-fluid-quote {
  font-size: clamp(1.15rem, 2.2vw, 1.95rem);
  line-height: 1.45;
}

::-webkit-scrollbar {
  width: 6px;
}
::-webkit-scrollbar-track {
  background: #061a15;
}
::-webkit-scrollbar-thumb {
  background: #c8963e;
  border-radius: 9999px;
}

/* In-page links must clear the floating nav, which sits higher on desktop
   because of the contact bar above it. */
section[id],
#tailored-inquiry {
  scroll-margin-top: 6rem;
}
@media (min-width: 1024px) {
  section[id],
  #tailored-inquiry {
    scroll-margin-top: 9.5rem;
  }
}

/* Scroll lock applied while the off-canvas menu is open. */
body.nav-locked {
  overflow: hidden;
}

/* Quick-filter pills scroll sideways on phones; hide the scrollbar itself. */
.quick-pill-rail {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.quick-pill-rail::-webkit-scrollbar {
  display: none;
}

/* Keep the trip modal inside the viewport on short/small screens. */
.trip-modal {
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.trip-modal:not([open]) {
  display: none;
}

/* Visible focus for keyboard users, including the checkbox-driven tag pills. */
:focus-visible {
  outline: 2px solid #c8963e;
  outline-offset: 2px;
}
.tag-pill:focus-within {
  outline: 2px solid #c8963e;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* FAQ accordion: suppress the native disclosure triangle in favour of the
   Material Symbols chevron in the markup. */
summary::-webkit-details-marker,
summary::marker {
  display: none;
  content: "";
}
.faq-item summary:focus-visible {
  outline: 2px solid #c8963e;
  outline-offset: -2px;
}

/* ===========================================================================
   MOTION SYSTEM
   ---------------------------------------------------------------------------
   Everything below is progressive enhancement. The hidden-before-reveal states
   are scoped to `html.js`, a class set by an inline script in partials/head.php.
   If that script never runs (JS disabled, script blocked, parse error) the
   class is absent and every element simply renders in its final visible state.
   Never write a `[data-reveal]` rule that is not scoped to `.js`.
   =========================================================================== */

/* --- Reveal on scroll -------------------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
.js [data-reveal="up"]    { transform: translate3d(0, 28px, 0); }
.js [data-reveal="down"]  { transform: translate3d(0, -20px, 0); }
/* Sideways offsets stay under 20px on purpose. Anything larger pokes past the
   right edge while the element waits below the fold, which grows the document
   scroll width. Clipping it at html level would be the obvious fix, but that
   stops `position: sticky` working - so the offset lives inside the narrowest
   page gutter (px-5 = 20px) instead. */
.js [data-reveal="left"]  { transform: translate3d(-18px, 0, 0); }
.js [data-reveal="right"] { transform: translate3d(18px, 0, 0); }
.js [data-reveal="zoom"]  { transform: scale(0.94); }
.js [data-reveal="blur"]  { filter: blur(10px); transition-property: opacity, transform, filter; }

.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Once a reveal has played there is nothing left to composite. */
.js [data-reveal].is-revealed {
  will-change: auto;
}

/* --- Scroll progress bar ----------------------------------------------- */
#scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, #c8963e, #e0b572, #efcb88);
  z-index: 70;
  pointer-events: none;
}

/* --- Header condense on scroll ----------------------------------------- */
#site-header .nav-shell {
  transition:
    height 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.35s ease,
    box-shadow 0.35s ease;
}
#site-header.is-scrolled .nav-shell {
  background-color: rgba(252, 249, 243, 0.96);
  box-shadow: 0 18px 40px -18px rgba(6, 26, 21, 0.4);
}
@media (min-width: 768px) {
  #site-header.is-scrolled .nav-shell { height: 4rem; }
}

/* --- Nav scrim -----------------------------------------------------------
   Sits under the nav (z-50) and over the page, so the pill itself is never
   blurred by it - only whatever scrolls underneath. The mask fades the blur
   out at the bottom edge instead of ending on a hard line, and the whole
   thing is inert so it cannot swallow clicks. */
#nav-scrim {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 6rem;
  z-index: 45;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
  backdrop-filter: blur(14px) saturate(115%);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
}
body.is-scrolled #nav-scrim {
  opacity: 1;
}
@media (min-width: 1024px) {
  /* Taller: the nav starts 2rem down on desktop, so there is more gap to cover. */
  #nav-scrim { height: 7.75rem; }
}

/* --- Back to top -------------------------------------------------------- */
#back-to-top {
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, 14px, 0);
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
}
#back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* ===========================================================================
   HERO CAROUSEL
   =========================================================================== */

.hero-slide {
  opacity: 0;
  transition: opacity 1.2s ease-in-out;
  will-change: opacity;
}
.hero-slide.is-active {
  opacity: 1;
}

/* Slow Ken Burns drift, only on the slide currently on screen. Alternating
   direction stops every slide from pushing the subject the same way. */
.hero-slide.is-active .hero-slide-img {
  animation: kenburns 14s ease-out forwards;
}
.hero-slide:nth-child(even).is-active .hero-slide-img {
  animation-name: kenburns-alt;
}

@keyframes kenburns {
  from { transform: scale(1.04) translate3d(0, 0, 0); }
  to   { transform: scale(1.16) translate3d(-1.5%, -1.5%, 0); }
}
@keyframes kenburns-alt {
  from { transform: scale(1.16) translate3d(1.5%, 1%, 0); }
  to   { transform: scale(1.04) translate3d(0, 0, 0); }
}

/* Caption text swaps with a short lift rather than a hard cut. */
.hero-caption {
  transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.hero-caption.is-swapping {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
}

/* Dots double as an autoplay timer: the fill drains across the slide. */
.hero-dot {
  position: relative;
  overflow: hidden;
  transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.3s ease;
}
.hero-dot-fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: #efcb88;
  border-radius: inherit;
}
.hero-dot.is-active .hero-dot-fill {
  animation: dot-timer var(--hero-delay, 6500ms) linear forwards;
}
.hero-carousel.is-paused .hero-dot.is-active .hero-dot-fill {
  animation-play-state: paused;
}
@keyframes dot-timer {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* --- Reduced motion ------------------------------------------------------
   The global reduced-motion block above already neutralises durations. These
   rules additionally make sure nothing is left stuck in a hidden state and
   that the carousel stops drifting entirely. */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .hero-slide.is-active .hero-slide-img,
  .hero-dot.is-active .hero-dot-fill {
    animation: none !important;
  }
  .hero-slide { transition: opacity 0.2s linear; }
}
