/* ==========================================================================
   Actives International — Site Header

   State switching is pure CSS: hidden inputs + :has(). No script opens,
   closes, or animates anything. The only JS is a scroll-direction watcher,
   which CSS cannot express.

   Architecture: every state writes ONLY to the custom properties in the
   "state channel" below. One set of rules consumes them. To retarget this
   at Bricks variables, redefine the palette block and nothing else.

   (F) measured from Figma   (A) assumed
   ========================================================================== */

.ai-header {
  /* ---------- palette -----------------------------------------------------
     Points at the Bricks variables so a change there reaches this header.
     The Figma hex is kept as a fallback: if a variable is ever renamed or
     the component is used somewhere those variables aren't defined, the
     colour degrades to the right value instead of blanking out. */
  --ai-dark:    var(--color-primary, #3b5e57); /* Primary/Dark    (F) */
  --ai-regular: #80b8ad;                       /* Primary/Regular (F) — chevron, focus ring */
  --ai-bg:      #fdfdf8;   /* Primary/Background (F) — no Bricks var given yet */

  /* Link hover. No hover state exists in the Figma comps, so this is a
     choice, not a measurement. Currently matches the chevron.
     For the lighter sea foam instead: var(--color-sea-foam, #bae2da) */
  --ai-hover: var(--ai-regular);

  /* ---------- type + motion ---------------------------------------------- */
  --ai-font: "Aktiv Grotesk", "Helvetica Neue", Arial, sans-serif;

  /* Mobile menu sizes. Figma named styles "Mobile - H1" / "Mobile - H2" (F).
     Change them here only — tracking is in em and line-height is unitless,
     so both follow the size automatically. */
  --ai-m-h1: 36px;
  --ai-m-h2: 28px;

  /* Chevron size (F). */
  --ai-chev: 20px;

  /* Content column. Figma's desktop frame is 1460 wide including its 40px
     padding, so the column itself is 1380 (F). */
  --ai-max: 1380px;
  --ai-card-max: 1460px;

  --ai-dur: 320ms;   /* (A) */
  --ai-ease: cubic-bezier(.4, 0, .2, 1); /* (A) */

  /* ---------- state channel: defaults are "at top, nothing open" --------- */
  --ai-pad-y: 32px;        /* (F) */
  --ai-pad-x: 40px;        /* (F) */
  --ai-surface: 0;         /* card opacity 0|1 */
  --ai-inset-y: 0px;
  --ai-inset-x: 0px;
  --ai-radius: 0px;
  --ai-shadow: 0 0 0 rgba(59, 94, 87, 0);
  --ai-shift: 0;           /* retreat multiplier 0|-101% */

  /* Ink. Over the hero the bar is transparent, so links are white; once the
     bar has a surface under them they return to the Figma greens. */
  --ai-ink: #ffffff;
  --ai-ink-chev: #ffffff;
  --ai-logo-filter: brightness(0) invert(1); /* knocks the logo out to white */

  /* ---------- icon masks (F) — traced from the exported SVGs ------------- */
  --ai-i-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M6 8L10.5 12.5L15 8' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E");
  --ai-i-burger: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 15.7611' fill='none'%3E%3Cpath d='M0 .716H24' stroke='black' stroke-width='1.433'/%3E%3Cpath d='M0 7.88H24' stroke='black' stroke-width='1.433'/%3E%3Cpath d='M0 15.045H24' stroke='black' stroke-width='1.433'/%3E%3C/svg%3E");
  --ai-i-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 25.414 25.414' fill='none'%3E%3Cpath d='M.707.707l24 24' stroke='black' stroke-width='2'/%3E%3Cpath d='M24.707.707l-24 24' stroke='black' stroke-width='2'/%3E%3C/svg%3E");

  position: fixed;
  inset: 0 0 auto;
  z-index: 1000;
  translate: 0 var(--ai-shift);
  transition: translate var(--ai-dur) var(--ai-ease);
  font-family: var(--ai-font);
}

/* ================================================================== reset */
/* Bricks ships its elements with a default bottom margin (5px on the div
   element). Every box in this header is spaced with gap, so that margin is
   pure noise — and it silently broke nav alignment, because the trigger
   labels are Bricks divs and the plain links are not.
   Same specificity as Bricks' own rule; this file loads after it. */

.ai-header__bar, .ai-header__inner, .ai-header__logo, .ai-header__toggle,
.ai-nav, .ai-nav__list, .ai-nav__item, .ai-nav__trigger, .ai-nav__chevron,
.ai-nav__cta, .ai-backdrop,
.ai-dropdown, .ai-dropdown__clip, .ai-dropdown__body, .ai-dropdown__list,
.ai-dropdown__link,
.ai-mobile, .ai-mobile__clip, .ai-mobile__body, .ai-mobile__list,
.ai-mobile__sublist, .ai-mobile__group, .ai-mobile__link, .ai-mobile__sublink,
.ai-mobile__cta {
  margin: 0;
}

/* ============================================================ state writes */
/* Each block below sets variables only — never properties. */

/* Scrolled: detach into a floating card (F). Set by the scroll watcher. */
.ai-header.is-floating {
  --ai-pad-y: 42px;   /* 18 outer + 24 inner (F) */
  --ai-pad-x: 48px;   /* 24 outer + 24 inner (F) */
  --ai-surface: 1;
  --ai-inset-y: 18px;
  --ai-inset-x: 24px;
  --ai-radius: 8px;
  --ai-shadow: 0 0 12px rgba(59, 94, 87, .6);
  --ai-ink: var(--ai-dark);        /* (F) */
  --ai-ink-chev: var(--ai-regular); /* (F) */
  --ai-logo-filter: none;
  --ai-logo-dark: 1;
  --ai-logo-light: 0;
}

/* Anything open needs solid ground, even over a transparent hero (F) —
   and once there is a surface, the ink goes back to green. */
.ai-header:has(.ai-state:checked:not(.ai-state--none)) {
  --ai-surface: 1;
  --ai-ink: var(--ai-dark);
  --ai-ink-chev: var(--ai-regular);
  --ai-logo-filter: none;
  --ai-logo-dark: 1;
  --ai-logo-light: 0;
}

/* Retreat on scroll-down. Never while something is open. */
.ai-header.is-hidden:not(:has(.ai-state:checked:not(.ai-state--none))) {
  --ai-shift: -101%;
}

/* ================================================================== inputs */

.ai-state {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Focus lives on the visually-hidden input, so the ring has to be forwarded
   to whatever that input controls. Both read an inherited variable. */
.ai-nav__trigger,
.ai-header__toggle {
  outline: var(--ai-ring, none);
  outline-offset: 4px;
}

#ai-menu:focus-visible ~ .ai-header__bar .ai-header__toggle {
  --ai-ring: 2px solid var(--ai-regular);
}

/* ============================================================== bar shell */

.ai-header__bar {
  position: relative;
  padding: var(--ai-pad-y) var(--ai-pad-x);
  transition: padding var(--ai-dur) var(--ai-ease);
}

/* The card is a pseudo-element, so background / radius / shadow animate
   without ever touching layout. */
.ai-header__bar::before {
  content: "";
  position: absolute;
  inset: var(--ai-inset-y) var(--ai-inset-x);		
  max-width: var(--ai-card-max);
  margin-inline: auto; /* centres the card once max-width bites */
  z-index: -1;
  background-color: var(--ai-bg);
  border-radius: var(--ai-radius);
  box-shadow: var(--ai-shadow);
  opacity: var(--ai-surface);
  transition:
    inset var(--ai-dur) var(--ai-ease),
    border-radius var(--ai-dur) var(--ai-ease),
    box-shadow var(--ai-dur) var(--ai-ease),
    opacity var(--ai-dur) var(--ai-ease);
}

/* Content column caps at the Figma frame width and centres. Applied to the
   dropdown and mobile bodies too, so the divider and submenu stay flush with
   the nav row above them on wide screens. */
.ai-header__inner,
.ai-dropdown__body,	
.ai-mobile__body {
  max-width: var(--ai-max);
  margin-inline: auto;	
}

.ai-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

/* =================================================================== logo */

/* Grid so both logo versions occupy the same cell and cross-fade in place. */
.ai-header__logo {
  display: grid;
  flex-shrink: 0;
  line-height: 0;
}

.ai-header__logo img {
  grid-area: 1 / 1;
  display: block;
  width: var(--ai-logo, 147px); /* (F) */
  height: auto;
  transition: opacity var(--ai-dur) var(--ai-ease);
}

.ai-logo--dark  { opacity: var(--ai-logo-dark, 0); }
.ai-logo--light { opacity: var(--ai-logo-light, 1); }

/* Fallback: a single unclassed logo still knocks out to white over the hero.
   Once both images carry .ai-logo--dark / .ai-logo--light this stops
   applying and the real assets take over. */
.ai-header__logo img:not(.ai-logo--dark):not(.ai-logo--light) {
  filter: var(--ai-logo-filter);
  transition: filter var(--ai-dur) var(--ai-ease);
}

/* ============================================================ shared type */
/* Eyebrow: 14 / 1.4 SemiBold, 18% tracking, uppercase (F).
   Used by every desktop nav trigger and dropdown link. */

.ai-nav__trigger,
.ai-dropdown__link {
  font: 600 14px/1.4 var(--ai-font);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ai-ink);
  transition: color 160ms var(--ai-ease);
}

.ai-nav__trigger:hover,
.ai-dropdown__link:hover,
.ai-dropdown__link:focus-visible {
  color: var(--ai-hover);
}

/* ============================================================ desktop nav */

.ai-nav__list {
  display: flex;
  align-items: center;
  gap: 40px; /* (F) */
  margin: 0;
  padding: 0;
  list-style: none;
}

.ai-nav__item {
  display: flex;
  align-items: center;
  position: relative;
}

.ai-nav__trigger {
  position: relative; /* anchors the out-of-flow chevron */
  align-items: center;
  white-space: nowrap;
  cursor: pointer;
}

/* Two stacked triggers per dropdown: one opens it, one closes it. Swapping
   which is visible is what gives click-again-to-close, with no script.
   Both read inherited variables, so the open rule below stays generic. */
.ai-nav__trigger        { display: var(--ai-t-open, inline-flex); }
.ai-nav__trigger--close { display: var(--ai-t-close, none); }

/* The chevron is taken out of flow deliberately.
   In flow it is 20px against a 19.6px text line, so triggers that have one
   resolve to a taller box than triggers that don't — and the two sets of nav
   links stop aligning. Out of flow, every trigger is exactly one text line,
   so alignment holds no matter what Bricks wraps around them. */
.ai-nav__trigger:has(.ai-nav__chevron) {
  padding-right: calc(var(--ai-chev) + 4px);
}

.ai-nav__chevron {
  position: absolute;
  right: 0;
  top: 50%;
  translate: 0 -50%;
  width: var(--ai-chev);  /* (F) */
  height: var(--ai-chev);
  background-color: var(--ai-ink-chev); /* (F) Primary/Regular once docked */
  -webkit-mask: var(--ai-i-chevron) center / contain no-repeat;
  mask: var(--ai-i-chevron) center / contain no-repeat;
}

.ai-nav__trigger--close .ai-nav__chevron { scale: 1 -1; } /* (F) flips open */

/* CTA slot — empty container. The button is your existing Bricks component. */
.ai-nav__cta,
.ai-mobile__cta {
  display: flex;
  align-items: center;
}

/* ====================================================== desktop dropdowns */
/* The bar itself grows; this is not a popover. 0fr -> 1fr animates height
   without anyone hardcoding one. */

.ai-dropdown {
  display: grid;
  grid-template-rows: var(--ai-rows, 0fr);
  transition: grid-template-rows var(--ai-dur) var(--ai-ease);
}

/* visibility, not just overflow — a zero-height panel still puts its links in
   the tab order otherwise. It flips to visible instantly on open, and only
   after the collapse finishes on close. */
.ai-dropdown__clip {
  min-height: 0;
  overflow: hidden;
  visibility: var(--ai-vis, hidden);
  transition: visibility var(--ai-dur);
}

.ai-dropdown__body {
  margin-top: 24px;                     /* (F) */
  padding-top: 24px;                    /* (F) */
  border-top: 1px solid var(--ai-dark); /* (F) */
}

.ai-dropdown__list {
  display: grid;
  justify-items: start;
  gap: 24px; /* (F) */
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --------------------------------------------------------------------------
   THE ONLY PER-MENU CSS IN THE FILE.
   The <li> and its panel share a data-menu value, so this one selector opens
   the panel AND swaps the trigger. To add a dropdown: give the item and panel
   a matching data-menu, add a radio with the matching id, add one line here.
   -------------------------------------------------------------------------- */
#ai-nav-news:checked ~ .ai-header__bar [data-menu="news"] {
  --ai-rows: 1fr;
  --ai-vis: visible;
  --ai-t-open: none;
  --ai-t-close: inline-flex;
}

/* Same pattern, for the keyboard focus ring. */
#ai-nav-news:focus-visible ~ .ai-header__bar [data-menu="news"] {
  --ai-ring: 2px solid var(--ai-regular);
}

/* ========================================================= mobile toggle */

.ai-header__toggle {
  display: none;
  width: 24px;  /* (F) */
  height: 24px;
  background-color: var(--ai-dark);
  -webkit-mask: var(--ai-i-burger) center / contain no-repeat;
  mask: var(--ai-i-burger) center / contain no-repeat;
  cursor: pointer;
}

.ai-header:has(#ai-menu:checked) .ai-header__toggle {
  -webkit-mask-image: var(--ai-i-close);
  mask-image: var(--ai-i-close);
}

/* ========================================================== mobile panel */

.ai-mobile {
  display: none;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--ai-dur) var(--ai-ease);
}

.ai-mobile__clip {
  min-height: 0;
  overflow: hidden;
  visibility: var(--ai-vis, hidden);
  transition: visibility var(--ai-dur);
}

.ai-mobile__body {
  display: grid;
  gap: 42px;                       /* (F) menu block -> CTA */
  justify-items: start;
  padding: 48px 24px;              /* (F) */
  max-height: calc(100dvh - 68px); /* (A) keep long menus reachable */
  overflow-y: auto;
}

.ai-mobile__list,
.ai-mobile__sublist {
  display: grid;
  justify-items: start;
  margin: 0;
  padding: 0;
  list-style: none;
  width: 100%;
}

.ai-mobile__list { gap: 36px; }                    /* (F) */
.ai-mobile__sublist { gap: 18px; padding-left: 32px; } /* (F) */

.ai-mobile__group {
  display: grid;
  gap: 24px; /* (F) parent -> its own submenu */
  width: 100%;
}

/* Mobile H1 36/1.05 -4%, H2 28/1.1 -2% (F) */
.ai-mobile__link,
.ai-mobile__sublink {
  font-weight: 500;
  text-decoration: none;
  color: var(--ai-dark);
}

.ai-mobile__link    { font-size: var(--ai-m-h1); line-height: 1.05; letter-spacing: -.04em; }
.ai-mobile__sublink { font-size: var(--ai-m-h2); line-height: 1.1;  letter-spacing: -.02em; }

/* =============================================================== backdrop */
/* Click anywhere outside to close. A label, not a listener. */

/* A label can only reset one input, so the dropdowns and the mobile menu
   get one each. Only ever one is on screen at a time. */
.ai-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: -2;
  cursor: default;
}

.ai-header:has(input[name="ai-nav"]:checked:not(.ai-state--none)) .ai-backdrop--nav,
.ai-header:has(#ai-menu:checked) .ai-backdrop--menu {
  display: block;
}

/* ============================================================= breakpoint */
/* 1027px (client, 2026-09-12) — the width at which the Contact Us button
   wraps to two lines. Was 991px, Bricks' tablet-portrait default. */

@media (max-width: 1027.98px) {
  .ai-header {
    /* Mobile is never transparent and never floats (F) */
    --ai-pad-y: 12px;
    --ai-pad-x: 20px;
    --ai-surface: 1;
    --ai-inset-y: 0px;
    --ai-inset-x: 0px;
    --ai-radius: 0px;
    --ai-shadow: 0 0 0 rgba(59, 94, 87, 0);
    --ai-logo: 111px; /* (F) */
    --ai-ink: var(--ai-dark);         /* mobile always has a surface (F) */
    --ai-ink-chev: var(--ai-regular);
    --ai-logo-filter: none;
    --ai-logo-dark: 1;
    --ai-logo-light: 0;
    --ai-max: none;
    --ai-card-max: none;
  }

  .ai-header.is-floating {
    --ai-pad-y: 12px;
    --ai-pad-x: 20px;
    --ai-inset-y: 0px;
    --ai-inset-x: 0px;
    --ai-radius: 0px;
    --ai-shadow: 0 0 0 rgba(59, 94, 87, 0);
  }

  .ai-nav,
  .ai-dropdown { display: none; }

  .ai-header__toggle { display: block; }
  .ai-mobile { display: grid; }
		
  .ai-header:has(#ai-menu:checked) .ai-mobile {
    grid-template-rows: 1fr;
    --ai-vis: visible;
  }

  /* Rule under the bar, only while the menu is open (F) */
  .ai-header:has(#ai-menu:checked) .ai-header__inner {
    padding-bottom: var(--ai-pad-y);
    border-bottom: 1px solid var(--ai-dark);
  }
}

/* ========================================================= reduced motion */

@media (prefers-reduced-motion: reduce) {
  .ai-header,
  .ai-header__bar,
  .ai-header__bar::before,
  .ai-dropdown,
  .ai-mobile {
    transition-duration: 1ms;
  }
}

/* ====================================== desktop sticky logo (2026-09-12) */
/* Client request: logo eases down in the floating state. Desktop only.
   Page-load size stays at the 147px fallback; mobile stays at 111px. */

/* 1. The size change. */
@media (min-width: 1028px) {
  .ai-header.is-floating {
    --ai-logo: 110px;
  }
}

/* 2. Make it ease instead of snap.
   Two selectors on purpose. The rule at header.css:222 already sets a
   filter-only transition on a logo image that carries neither
   .ai-logo--dark nor .ai-logo--light, and it does so at a higher
   specificity than `.ai-header__logo img`. The source template ships
   exactly one unclassed logo image, so that rule is very likely live.
   Without the second selector it wins and the width still jumps. */
.ai-header .ai-header__logo img,
.ai-header .ai-header__logo img:not(.ai-logo--dark):not(.ai-logo--light) {
  transition: width   var(--ai-dur) var(--ai-ease),
              opacity var(--ai-dur) var(--ai-ease),
              filter  var(--ai-dur) var(--ai-ease);
}

/* 3. Reduced motion. The logo was not covered by the existing block. */
@media (prefers-reduced-motion: reduce) {
  .ai-header .ai-header__logo img,
  .ai-header .ai-header__logo img:not(.ai-logo--dark):not(.ai-logo--light) {
    transition-duration: 1ms;
  }
}

/* ============================== dropdown surface at the top (2026-09-12) */
/* Opening a menu at scroll zero forces a surface (--ai-surface: 1) but leaves
   the card's 1460px cap in place, so the sheet stopped short of the viewport
   edges while keeping square corners. Neither a sheet nor a card.

   Commit to the sheet: edge to edge, square, with a shadow to lift it off the
   hero. The floating card stays the scrolled-state treatment, so the two
   states remain distinct.

   :not(.is-floating) keeps this off once the header has detached, and the
   desktop bound keeps it off mobile, which never floats and never casts. */

@media (min-width: 1028px) {
  .ai-header:not(.is-floating):has(.ai-state:checked:not(.ai-state--none)) {
    --ai-card-max: none;                             /* edge to edge */
    --ai-shadow: 0 8px 24px rgba(59, 94, 87, .28);   /* (A) */
  }
}
