/* Kingdom Advisors Elementor Widgets — Menu
   A WordPress menu rendered as a row of links inside a rounded track, with a pill that slides
   between them on hover and rests on the current page.

   Structure, and why the pill is NOT inside the <ul>: a <ul> may only contain <li>, <script> and
   <template>. Putting a decorative <span> in there is invalid markup, so the pill is a sibling of
   the list inside a positioned track:

     nav.kaw-menu > div.kaw-menu__track > span.kaw-menu__pill + ul.kaw-menu__list > li > a

   Everything the JS measures is relative to the track. */

/* The <nav> is the alignment wrapper — the alignment control writes justify-content here, and
   Stretch also flips --kaw-mn-grow so the track fills instead of hugging its items. */
.kaw-menu {
  display: flex;
}

.kaw-menu__track {
  position: relative;
  display: inline-flex;
  flex-grow: var(--kaw-mn-grow, 0);
  max-width: 100%;
  box-sizing: border-box;

  /* THE CONTROL DEFAULT IS REPEATED HERE ON PURPOSE. Track Radius and Pill Radius both default to
     10px and both write `border-radius` only through `selectors`, so until now this file said nothing
     about the corners and the rendered radius depended entirely on Elementor emitting a rule.

     It does NOT always emit one. An ABSENT setting is fine — `Base_Data_Control::get_value()`
     (elementor/includes/controls/base-data.php:56) substitutes the registered default, so an
     untouched widget still gets its 10px. But a setting stored EMPTY is not: a DIMENSIONS value of
     four empty strings is `isset()`, so the default never substitutes, and the CSS generator's
     placeholder pass throws on the empty value and drops the whole declaration with a bare `return`
     (core/files/css/base.php:396-412). A control that was cleared, or whose stored shape predates a
     change to the control, therefore emits nothing at all — and with no fallback here the corners
     came out square while the panel still read 10. That is what the client hit.

     The control still wins whenever it emits: `{{WRAPPER}} .kaw-menu__track` is (0,4,0) against this
     rule's (0,1,0), including when it is deliberately set to 0. Keep this number and the control
     default identical — if one moves, move both. */
  border-radius: 10px;

  /* LAST-RESORT OVERFLOW SAFETY. The list never wraps (below), so a menu too wide for its container
     would otherwise push the whole PAGE sideways — a horizontal scrollbar on the document is a
     genuinely nasty way to discover a header is too narrow. Scrolling the track instead keeps it
     contained. The scrollbar chrome is hidden because this is a safety net rather than a feature,
     and a scrollbar under a header nav reads as broken; tabbing still scrolls items into view, so
     nothing becomes unreachable. */
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.kaw-menu__track::-webkit-scrollbar { display: none; }

/* Only emitted when the blur control is above 0 — see the note on that control. An element with a
   backdrop-filter clips its descendants to its border box in WebKit, and it costs a compositing
   layer; at 0 the property is absent entirely rather than set to blur(0px). */
.kaw-menu__track[data-blur="on"] {
  -webkit-backdrop-filter: blur(var(--kaw-mn-blur, 10px));
          backdrop-filter: blur(var(--kaw-mn-blur, 10px));
}

/* Hardened: a bare <ul> is one of the most contested elements on a WordPress site — themes reset
   list-style, margin and padding on it constantly, and a single-class selector loses. No control
   writes any of these three, so the controls still own every number that matters. */
.kaw-menu .kaw-menu__list {
  display: flex;
  flex-wrap: nowrap;          /* never wraps, by design — one row always */
  align-items: center;
  position: relative;
  z-index: 1;                 /* above the pill */
  margin: 0 !important;
  padding: 0 !important;
  list-style: none !important;
}

.kaw-menu .kaw-menu__item {
  margin: 0 !important;
  padding: 0 !important;
  list-style: none !important;
  flex: none;                 /* items keep their natural width; the row never squashes them */
}

.kaw-menu .kaw-menu__link {
  display: block;
  white-space: nowrap;
  text-decoration: none !important;
  color: var(--kaw-mn-color, inherit);
  transition: color 0.3s ease;
}

/* The pill's own colour while it is underneath. `.is-lit` is added by the script and is listed
   AFTER the current-page rule on purpose: when the pill parks on the current item, the lit colour
   is the one that should win. Both selectors are the same specificity, so source order decides. */
.kaw-menu .kaw-menu__link[aria-current="page"] {
  color: var(--kaw-mn-color-current, inherit);
}
/* v1.43.0. Scroll Spy (and root.kawMenuSetCurrent()) mark the item for the section being read with
   aria-current="location" — never "page", which stays the server's. It takes the Current Page Color for
   the same reason the current page does: when the pill moves off to something hovered, the section you
   are in stays findable. It sits HERE, before `.is-lit`, on purpose: same specificity, so the lit colour
   still wins while the pill is under it. Nothing sets "location" unless a menu opts in. */
.kaw-menu .kaw-menu__link[aria-current="location"] {
  color: var(--kaw-mn-color-current, inherit);
}
.kaw-menu .kaw-menu__link.is-lit {
  color: var(--kaw-mn-color-lit, inherit);
}

.kaw-menu .kaw-menu__link:focus-visible {
  outline: 2px solid var(--kaw-mn-focus, currentColor);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------------------------ the pill */
.kaw-menu__pill {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;                 /* under the links */
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
  will-change: transform, width, height;
  /* Same empty-value fallback as the track above — see the note there. This is the one the client
     actually noticed: Pill Radius read 10px in the panel and the pill drew square corners. */
  border-radius: 10px;
}

/* The no-GSAP path. The script sets data-motion="simple" itself when GSAP is not on the page, so
   this is also the fallback for "bouncy was chosen but the library did not load". The easing
   overshoots slightly, which is as close to the bouncy feel as a plain transition gets — what is
   missing is the settle-back and the vertical squash. */
.kaw-menu[data-motion="simple"] .kaw-menu__pill {
  transition:
    transform 0.38s cubic-bezier(0.34, 1.4, 0.64, 1),
    width     0.38s cubic-bezier(0.34, 1.4, 0.64, 1),
    height    0.38s cubic-bezier(0.34, 1.4, 0.64, 1),
    opacity   0.2s ease;
}

/* Jumping the pill into place (first paint, a resize) must not animate from wherever it was. */
.kaw-menu__pill.is-snap {
  transition: opacity 0.2s ease !important;
}

/* ------------------------------------------------------------------------------ no JS / reduced
   Without the script there is no pill at all — it never gets sized, so it must not sit as a stray
   0x0 dot. `.is-ready` is added on init, which makes this the no-JS state too. */
.kaw-menu:not(.is-ready) .kaw-menu__pill {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .kaw-menu[data-motion="simple"] .kaw-menu__pill {
    transition: opacity 0.2s ease;
  }
  .kaw-menu .kaw-menu__link {
    transition: none;
  }
}

/* ------------------------------------------------------------------------- Hover Style: Dim (v1.43.0)
   Only for a menu whose Hover Style is Dim — render() writes data-hover="dim" then and only then, so
   none of this can reach a 1.42.0 menu. No pill is drawn. The script puts `.is-active` on the item being
   pointed at or focused (or, with Scroll Spy, the item for the section being read) and `.is-dimmed` on
   the <nav> while there is one; every OTHER item fades. The active item is never recoloured — it keeps
   its own colour, plain or current — which is why Dim uses `.is-active` and never `.is-lit`: `.is-lit`
   takes the pill's text colour, and in Dim that control is hidden and not emitted at all.
   The three variables come from Style → Dim; the fallbacks repeat the control defaults for a control
   stored empty (CLAUDE.md, state 2). Each var() stays on one line: the v1.41.1 WP Rocket lesson. */
.kaw-menu[data-hover="dim"] .kaw-menu__pill {
  display: none;
}
.kaw-menu[data-hover="dim"] .kaw-menu__link {
  transition: color 0.3s ease, opacity var(--kaw-mn-dim-duration, 0.3s) var(--kaw-mn-dim-ease, ease);
}
.kaw-menu[data-hover="dim"].is-dimmed .kaw-menu__link:not(.is-active) {
  opacity: var(--kaw-mn-dim-opacity, 0.5);
}
/* The state the script applies while building (first paint, a rebuild) must not fade in from nothing —
   the Dim equivalent of the pill's `.is-snap`. */
.kaw-menu[data-hover="dim"].is-instant .kaw-menu__link {
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .kaw-menu[data-hover="dim"] .kaw-menu__link {
    transition: none;
  }
}
