/* Unique World Holidays — Home page navbar + hero (Step 8: PHP/ACF migration)
   Scoped to the Home page only (enqueued conditionally in functions.php).

   Architecture: #uwh-header is a slim, constant-height (~84px) navbar,
   position:fixed, that animates its own background-color on scroll
   (transparent -> navy) via a single scroll-linked custom property
   --uwh-progress (0 -> 1, set on :root by header-scroll.js/GSAP
   ScrollTrigger so both the header and the hero text below can read it).

   There is only ONE visible "UNIQUE WORLD" text in the whole system: the
   giant hero heading (#uwh-hero-title). It is position:fixed (not part of
   the hero section's normal flow), so it stays on screen the entire time
   and is continuously transformed — font-size, position and color all
   interpolate off the same --uwh-progress variable — from its
   big/gradient/lower-hero look at progress 0 to a small/white look
   sitting exactly where the navbar's own logo spot would be at progress 1.
   It's one element changing shape, not two elements crossfading.

   As of Step 8, the navbar + hero heading are rendered by
   partials/home-header.php and front-page.php (plain PHP + ACF), not
   Elementor/Header Footer Elementor — so class names here are our own
   (uwh-*), not the old Elementor/HFE-generated ones
   (.elementor-widget-navigation-menu, .hfe-menu-item, etc.). Every
   property value below is unchanged from the Elementor-rendered version;
   only the selectors were renamed to match the new markup. */

:root {
  --uwh-progress: 0;

  /* Second, independent scroll range — page-bottom instead of page-top.
	   --uwh-progress and --uwh-bottom-progress are scrubbed by two separate
	   ScrollTrigger instances (header-scroll.js) over two scroll ranges
	   that never overlap (top-of-page vs. just-before-the-footer), so
	   there's no real "which one wins" conflict to resolve — see
	   --uwh-effective-progress on #uwh-hero-title below. */
  --uwh-bottom-progress: 0;
  /* Where the title lands at bottom-progress=1. Was a fixed 45vh (matched
	   by hand to the old fixed 'top 45%' end trigger) — as of Step 18,
	   header-scroll.js's bottom ScrollTrigger computes its `end` point
	   dynamically (it has to: a fixed percentage could land past the
	   page's actual max scroll position once the gap before the footer
	   shrank, see that file's comment) and sets THIS variable in lockstep
	   with whatever it lands on, every refresh — so the value here is only
	   the static fallback for the brief window before that first runs (or
	   if GSAP fails to load entirely, see header-scroll.js's early-return
	   guard), not the real controlling value. 20vh approximates the
	   typical live-computed result closely enough that fallback frame
	   never looks jarring. */
  --uwh-bottom-top: 20vh;

  /* Where the animated title lands at progress=1, hand-matched to the
	   navbar's own geometry: 84px-tall bar, align-items:center, and the
	   top-row padding-left used below. Keep these in sync if that geometry
	   ever changes. */
  --uwh-hero-end-left: 48px;
  --uwh-hero-end-top: 31px;

  /* --uwh-hero-char-count is set inline on #uwh-hero-title by
	   front-page.php (PHP knows the ACF text's length at render time — no
	   JS/flash-of-wrong-size needed). Both font-size formulas below scale
	   the ENTIRE original clamp() output by a 12/N ratio (12 = length of
	   "UNIQUE WORLD", what the original fixed values were tuned for) —
	   at N=12 the ratio is 1, so the reference text renders pixel-identical
	   to before. Scaling the whole clamp() output (not just its "preferred"
	   viewport-based term) means the min/max bounds shrink too, which
	   matters: a fixed rem floor doesn't help long text on a narrow phone
	   (the floor itself would still overflow) — it has to shrink with N as
	   well. The outer max()/min() on each formula below is a second,
	   independent safety net in both directions: it stops absurdly short
	   text (e.g. "GO") from blowing past the original max size, and stops
	   absurdly long text from shrinking past legibility. */
  --uwh-hero-end-font: max(
    0.85rem,
    min(1.6rem, calc(1.4rem * 12 / var(--uwh-hero-char-count, 12)))
  );

  /* Horizontal center point for .uwh-nav-menu (pills or hamburger icon,
     whichever is visible — see html.uwh-nav-fits below). Set by
     updateNavFit() in header-scroll.js, computed fresh from the docked
     title's and #uwh-cta-button's actual rendered positions on every
     load/resize/scroll — 50% here is only the pre-JS fallback, never
     visible for real (see that function's own comment for why). */
  --uwh-nav-center-x: 50%;
}

/* ---- Step 11: reload-safe reveal gate ----
   #uwh-header and #uwh-hero-title stay hidden until header-scroll.js adds
   `uwh-ready` to <html>. That happens synchronously, right after it forces
   ScrollTrigger to sync --uwh-progress/--uwh-bottom-progress (and the
   dock/undock position) to the CURRENT scroll position on load — see that
   file's Step 11 comment. Without this gate, a mid-scroll reload would
   paint one or more frames using the :root defaults above (0) before JS
   gets a chance to correct them: the wrong size/position/color, visibly
   flashing then snapping. visibility:hidden (not display:none) is
   deliberate — hidden elements are still laid out and measurable, which
   header-scroll.js relies on (getBoundingClientRect() for the dock
   handoff) while this gate is still active. If JS never runs at all
   (blocked/failed), header-scroll.js's own fallback path still adds
   `uwh-ready` immediately, so this never leaves the header stuck invisible
   permanently. */
html:not(.uwh-ready) #uwh-header,
html:not(.uwh-ready) #uwh-hero-title {
  visibility: hidden;
}

/* Logged-in-admin-only: WP's own admin toolbar pushes the fixed header down,
   so the animated title's landing spot needs the same offset (visitors
   never see this). */
body.admin-bar {
  --uwh-hero-end-top: 63px;
}

#uwh-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 9999;
  height: 84px;
  background-color: color-mix(
    in srgb,
    transparent calc((1 - var(--uwh-progress)) * 100%),
    #012245 calc(var(--uwh-progress) * 100%)
  ) !important;
}

body.admin-bar #uwh-header {
  top: 32px;
}
@media (max-width: 782px) {
  body.admin-bar #uwh-header {
    top: 46px;
  }
}

/* ---- Top row: fills the slim navbar; nav menu + button share it ---- */
#uwh-header .uwh-top-row {
  position: relative;
  z-index: 5;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: 16px 48px;
}

/* ---- Nav menu wrapper: fixed-positioned, horizontally centered within
   whatever space is actually free between the docked #uwh-hero-title
   "logo" (left neighbor) and #uwh-cta-button (right neighbor) — NOT the
   viewport's own midpoint.

   This wrapper only ever holds the pill row (#uwh-nav-menu-list) now —
   the hamburger trigger (#uwh-nav-toggle / .uwh-nav-toggle) lives OUTSIDE
   it, as its own flex item in .uwh-top-row right after #uwh-cta-button
   (see home-header.php + the "Mobile hamburger trigger" rule below), so
   that when pills don't fit the icon sits fixed at the row's right end
   instead of being dynamically centered like the pills are. That split
   is why this wrapper's own centering math never needs to account for
   the icon's width any more — it only ever has the pill row's width to
   worry about (see updateNavFit()'s `fits` branch in header-scroll.js).

   position:fixed (not absolute) is deliberate: this wrapper's own nearest
   positioned ancestor is a narrow flex row-item, not the full 84px-wide
   top row, so left:50% there would center within that narrow box, not the
   page. Fixed positioning is anchored to the true viewport instead
   (nothing between here and <html> uses transform/filter/will-change).

   HISTORY, why this isn't a breakpoint any more: this used to be a
   viewport-width media query (783px, then 1024px, then 1480px in turn) —
   each raise "fixed" whichever collision had just been found (pills vs.
   button, then pills vs. the docked title) but pushed hamburger mode
   further into genuinely common desktop widths each time (1480px meant
   1280/1366/1440px laptops all got hamburger instead of the full pill
   row — confirmed unacceptable). The actual problem was never the
   viewport width itself, it was that this wrapper never measured its
   two neighbors at all. Fixed now by never guessing: --uwh-nav-center-x
   is set on <html> by updateNavFit() in header-scroll.js, computed from
   each neighbor's REAL rendered position on every load/resize/scroll —
   see that function's own comment for the exact measurement. 50% is
   only the pre-JS fallback (matches the old default, invisible anyway
   since #uwh-header stays hidden until `uwh-ready`, same reload-safe
   gate updateNavFit() itself plugs into).

   Visibility (pills vs. hamburger icon) is class-driven the same way —
   html.uwh-nav-fits below — not a second, independent breakpoint, so the
   "does it fit" question only ever has one answer coming from one
   measurement, not two systems that could disagree. */
#uwh-header .uwh-nav-menu {
  position: fixed;
  left: var(--uwh-nav-center-x, 50%);
  top: 42px;
  transform: translate(-50%, -50%);
  z-index: 6;
}
body.admin-bar #uwh-header .uwh-nav-menu {
  top: 74px;
}
html:not(.uwh-nav-fits) #uwh-header .uwh-nav-menu-list {
  display: none;
}
#uwh-header .uwh-nav-menu-list {
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: nowrap;
}
#uwh-header .menu-item > a.uwh-menu-link {
  display: inline-flex;
  align-items: center;
  padding: 10px 22px !important;
  border-radius: 999px !important;
  background: color-mix(
    in srgb,
    rgba(255, 255, 255, 0.14),
    rgba(255, 255, 255, 0.08) calc(var(--uwh-progress) * 100%)
  );
  border: 1px solid
    color-mix(
      in srgb,
      rgba(255, 255, 255, 0.55),
      rgba(255, 255, 255, 0.3) calc(var(--uwh-progress) * 100%)
    );
  color: #ffffff !important;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition:
    background-color 0.25s ease,
    color 0.25s ease,
    border-color 0.25s ease;
  text-decoration: none;
}
#uwh-header .menu-item > a.uwh-menu-link:hover,
#uwh-header .menu-item > a.uwh-menu-link:focus {
  background: #feae02 !important;
  color: #012245 !important;
  border-color: #feae02 !important;
}

/* ---- Mobile hamburger trigger + flyout panel. Previously provided by
   Header Footer Elementor's own widget JS/CSS — rebuilt here from scratch
   (new behaviour, matched to the colours/spacing the old flyout used)
   since that plugin no longer renders this markup. See
   assets/js/home-nav-toggle.js for the open/close logic.

   Positioning: a plain in-flow flex item in .uwh-top-row (see
   home-header.php — it's a sibling of #uwh-cta-button, placed right
   after it in the DOM), NOT inside the fixed/centered .uwh-nav-menu
   wrapper the pills use. #uwh-cta-button's own margin-left:auto already
   pushes itself (and anything after it, i.e. this button) flush to the
   row's right edge, so no position/left/transform is needed here — it
   naturally lands right after the CTA button, right-aligned, whenever
   html:not(.uwh-nav-fits) makes it visible. display defaults to none
   (desktop pill row) and switches to flex below. ---- */
#uwh-header .uwh-nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  margin-left: 12px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  color: #ffffff;
}
html:not(.uwh-nav-fits) #uwh-header .uwh-nav-toggle {
  display: flex;
}
#uwh-header .uwh-nav-toggle-icon,
#uwh-header .uwh-nav-toggle-icon::before,
#uwh-header .uwh-nav-toggle-icon::after {
  display: block;
  width: 24px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
#uwh-header .uwh-nav-toggle-icon {
  position: relative;
}
#uwh-header .uwh-nav-toggle-icon::before,
#uwh-header .uwh-nav-toggle-icon::after {
  content: "";
  position: absolute;
  left: 0;
}
#uwh-header .uwh-nav-toggle-icon::before {
  top: -7px;
}
#uwh-header .uwh-nav-toggle-icon::after {
  top: 7px;
}

/* overflow-y:auto genuinely scrolls on a tall menu (many items on a short
   viewport) — markup also carries .uwh-custom-scrollbar
   (assets/css/uwh-utilities.css) so that shows a slim themed scrollbar,
   not the browser default, same as the two card-back-text use cases. */
.uwh-nav-flyout {
  position: fixed;
  inset: 0;
  z-index: 10001;
  background-color: #012245 !important;
  display: flex;
  flex-direction: column;
  padding: 90px 24px 24px;
  transform: translateX(100%);
  transition: transform 0.3s ease;
  overflow-y: auto;
}
.uwh-nav-flyout.is-open {
  transform: translateX(0);
}
.uwh-nav-flyout-close {
  position: absolute;
  top: 24px;
  right: 24px;
  background: none;
  border: none;
  color: #ffffff !important;
  font-size: 32px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
}
.uwh-nav-flyout-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.uwh-nav-flyout-list > li.menu-item {
  margin-bottom: 10px;
}
.uwh-nav-flyout .menu-item > a.uwh-menu-link {
  display: block;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: #ffffff !important;
  border-radius: 999px !important;
  padding: 10px 22px !important;
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
}

/* ---- Get in touch button ---- */
#uwh-cta-button {
  display: inline-flex !important;
  align-items: center;
  white-space: nowrap;
  background-color: color-mix(
    in srgb,
    #feae02 calc((1 - var(--uwh-progress)) * 100%),
    transparent calc(var(--uwh-progress) * 100%)
  ) !important;
  color: color-mix(
    in srgb,
    #012245 calc((1 - var(--uwh-progress)) * 100%),
    #ffffff calc(var(--uwh-progress) * 100%)
  ) !important;
  border: 2px solid
    color-mix(
      in srgb,
      transparent calc((1 - var(--uwh-progress)) * 100%),
      #ffffff calc(var(--uwh-progress) * 100%)
    ) !important;
  border-radius: 999px !important;
  padding: 13px 28px !important;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: filter 0.2s ease;
  flex-shrink: 0;
  margin-left: auto;
}
#uwh-cta-button:hover {
  filter: brightness(1.08);
}

/* =========================================================================
   Home page hero section — normal page content (NOT fixed), sits right
   below the navbar in the document flow. The destination wheel (background
   crossfade + rotating tour list) is injected into it by
   hero-destination-wheel.js; the giant "UNIQUE WORLD" text itself is
   fixed/animated (see below), so it's independent of this section's own
   scroll position. */

.uwh-home-hero {
  position: relative;
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  background-color: #012245;
}

/* Belt-and-suspenders: #uwh-hero-title's font-size is bounded to fit the
   viewport by the char-count-aware clamp() above, so this shouldn't ever
   trigger — but since the title is position:fixed (and so can't be
   clipped by .uwh-home-hero's own overflow:hidden), this guards against
   an extreme/unanticipated text length still causing a page-level
   horizontal scrollbar. Safe to add here since this file only loads on
   the front page. */
body.home {
  overflow-x: hidden;
}

/* ---- The one giant/animated "UNIQUE WORLD" title — the ONLY instance of
   this text anywhere in the DOM. position:fixed so it stays on screen and
   can slide from the hero's "just below the navbar" spot up into the
   navbar's own logo slot, AND (independently) back out into
   #uwh-hero-bottom-slot near the footer. Every property below is a
   continuous function of --uwh-progress and/or --uwh-bottom-progress
   (both 0->1, scrubbed by two separate ScrollTrigger instances in
   header-scroll.js over two non-overlapping scroll ranges) — no opacity,
   no fade, just one shape changing into another and smoothly reversing on
   scroll in either direction.

   Near the very end of the bottom range, header-scroll.js also switches
   this element from position:fixed to position:absolute (an inline style
   override, so it wins over the `position: fixed` below without
   !important) once the user scrolls past the settle point — see its
   onLeave/onEnterBack handlers. That's the one thing these CSS formulas
   can't do on their own: a fixed element would otherwise stay pinned in
   the viewport forever and float over the footer instead of letting it
   scroll in normally underneath. ---- */
#uwh-hero-title {
  /* See the --uwh-hero-end-font comment above for the general approach.
	   The original fixed clamp(3.5rem, 11vw, 9.5rem) is scaled as a whole
	   by 12/N — floor and ceiling shrink along with the viewport-based
	   term, so long text on a narrow phone can't hit a fixed floor that's
	   too wide to fit. Outer max()/min() bound the result a second time,
	   independent of viewport, as an absolute worst-case guard. */
  --uwh-hero-preferred-font: max(
    1.75rem,
    min(
      9.5rem,
      calc(clamp(3.5rem, 11vw, 9.5rem) * 12 / var(--uwh-hero-char-count, 12))
    )
  );

  /* header-scroll.js measures the ACTUAL rendered text at this
	   char-count-estimated size and sets these two shrink-only correction
	   factors (default 1, i.e. no correction) if real glyph widths still
	   overflow — see its comment for why the char-count estimate alone
	   isn't precise enough. */
  --uwh-hero-preferred-font-fitted: calc(
    var(--uwh-hero-preferred-font) * var(--uwh-hero-fit-scale-preferred, 1)
  );
  --uwh-hero-end-font-fitted: calc(
    var(--uwh-hero-end-font) * var(--uwh-hero-fit-scale-end, 1)
  );

  /* Cancels --uwh-progress back toward 0 as --uwh-bottom-progress rises
	   to 1. This is exact, not an approximation: the bottom slot's target
	   look for left/transform/font-size/gradient is IDENTICAL to the
	   hero's own progress=0 look (big, centered, vivid) — reusing those
	   same existing two-state formulas against this derived value gets
	   the bottom-slot state for free, no separate three-way formulas
	   needed for these four properties. Only `top` genuinely needs a
	   third waypoint (--uwh-top-stage1 below), since the bottom slot
	   sits at a different height than the hero's 18vh, not the same one. */
  --uwh-effective-progress: calc(
    var(--uwh-progress) * (1 - var(--uwh-bottom-progress))
  );

  /* Stage 1: the original hero -> navbar formula, unchanged. `top`
	   below blends stage 1's result the rest of the way to the bottom
	   slot's landing spot as --uwh-bottom-progress rises — a genuine
	   three-way blend (hero-top -> navbar-top -> bottom-top), since
	   those are three different values, not two. */
  --uwh-top-stage1: calc(
    18vh - (18vh - var(--uwh-hero-end-top)) * var(--uwh-progress)
  );

  position: fixed;
  z-index: 10000;
  margin: 0;
  font-family: "Cinzel", serif;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  white-space: nowrap;
  pointer-events: none;

  top: calc(
    var(--uwh-top-stage1) - (var(--uwh-top-stage1) - var(--uwh-bottom-top)) *
      var(--uwh-bottom-progress)
  );

  /* Horizontal: from perfectly centered (left:50% + translateX(-50%),
	   the standard centering trick) to left-aligned at the navbar's
	   padding edge, and back to centered again for the bottom slot. The
	   translateX blend (-50% -> 0%) rides on the element's own shrinking
	   width, so the centering stays exact at every step without needing
	   to know the text's pixel width. */
  left: calc(
    50% - (50% - var(--uwh-hero-end-left)) * var(--uwh-effective-progress)
  );
  transform: translateX(calc(-50% + 50% * var(--uwh-effective-progress)));

  font-size: calc(
    var(--uwh-hero-preferred-font-fitted) -
      (
        var(--uwh-hero-preferred-font-fitted) - var(--uwh-hero-end-font-fitted)
      ) *
      var(--uwh-effective-progress)
  );

  background: linear-gradient(
    90deg,
    color-mix(
      in srgb,
      #feae02,
      #ffffff calc(var(--uwh-effective-progress) * 100%)
    ),
    color-mix(
      in srgb,
      #fecd48,
      #ffffff calc(var(--uwh-effective-progress) * 100%)
    )
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---- Landing target for #uwh-hero-title near the footer. Empty spacer —
   see partials/home-hero-bottom-slot.php — its only job is reserving
   vertical space in the normal document flow so nothing jumps when
   header-scroll.js docks the title here (position:fixed -> absolute).

   No margin-top here (removed — earlier steps added one, up to 60vh at
   one point, purely to keep header-scroll.js's growth animation clear of
   Testimonials above). header-scroll.js's bottom ScrollTrigger no longer
   reads Testimonials' position at all — its start/end are now derived
   entirely from THIS element's own box ('top bottom' / 'top top', see
   that file's comment), so there's nothing left for a spacer margin to
   protect against. Whatever section sits above this slot, the animation
   times itself off the slot's own scroll position only. */
#uwh-hero-bottom-slot {
  position: relative;
  width: 100%;
  min-height: 200px;
}

/* ---- Responsive ---- */
/* Purely cosmetic compacting at narrower widths — tighter top-row
   padding, a smaller CTA button, the docked title landing 18px from the
   edge instead of 48px. NOT the nav-fits/hamburger decision any more
   (that moved to JS measurement, see updateNavFit() in
   header-scroll.js and html.uwh-nav-fits above) — this breakpoint no
   longer needs to line up with that logic at all, it's independent now.
   1479px is kept simply because it already matched this site's other
   "roomier tablet" tier; nothing here depends on that specific number. */
@media (max-width: 1479px) {
  #uwh-header .uwh-top-row {
    padding: 14px 18px;
  }
  #uwh-cta-button {
    padding: 10px 18px !important;
    font-size: 13px;
  }
  :root {
    --uwh-hero-end-left: 18px;
  }
}

@media (max-width: 782px) {
  .uwh-home-hero {
    min-height: 70vh;
  }
  :root {
    --uwh-hero-end-top: 33px;
    /* Same 12/N scaling approach as desktop, against the smaller 1.1rem
		   base and a lower floor — mobile has much less horizontal room. */
    --uwh-hero-end-font: max(
      0.7rem,
      min(1.3rem, calc(1.1rem * 12 / var(--uwh-hero-char-count, 12)))
    );
  }
  body.admin-bar {
    --uwh-hero-end-top: 79px;
  }
  #uwh-hero-title {
    /* Same whole-clamp 12/N scaling as desktop (see its comment) against
		   the original clamp(2.4rem, 15vw, 4rem), with a lower absolute
		   floor since mobile viewports are already narrow. Uses
		   --uwh-effective-progress (not raw --uwh-progress), same reasoning
		   as the desktop rule above — otherwise the bottom slot would stay
		   shrunk on mobile instead of growing back out. */
    --uwh-hero-preferred-font: max(
      1.1rem,
      min(
        4rem,
        calc(clamp(2.4rem, 15vw, 4rem) * 12 / var(--uwh-hero-char-count, 12))
      )
    );
    font-size: calc(
      var(--uwh-hero-preferred-font-fitted) -
        (
          var(--uwh-hero-preferred-font-fitted) -
            var(--uwh-hero-end-font-fitted)
        ) *
        var(--uwh-effective-progress)
    );
  }
  #uwh-hero-bottom-slot {
    min-height: 160px;
  }
}
