/* ==========================================================================
   Externo - Site menu (xm-*)
   One fullscreen menu for every page. The markup is injected by
   assets/js/site-menu.js; any element with [data-xm-menu-toggle] opens it.
   Self-contained: no dependency on style.css or home.css tokens.
   ========================================================================== */

:root {
  /* the site's ink, not pure black - flat and slightly warm reads as a
     designed surface where #000 + a glow read as an effect */
  --xm-ink: #0b0b0d;
  --xm-gold: #ffc13d;
  --xm-gold-deep: #f2a900;
  --xm-soft: #ffe09e;
  --xm-snow: #fdfcfa;
  --xm-line: rgba(253, 252, 250, 0.14);
  --xm-font-display: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --xm-font-body: "Urbanist", ui-sans-serif, system-ui, sans-serif;
  --xm-gutter: clamp(20px, 4.2vw, 64px);
  --xm-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --xm-ease-io: cubic-bezier(0.83, 0, 0.17, 1);
}

/* ---------------------------- scroll lock -------------------------------
   style.css keeps a stable scrollbar gutter, so hiding overflow does not
   widen the page. --ext-sbw (site-menu.js) is the fallback for engines
   without scrollbar-gutter; it reports 0 wherever the gutter holds.

   Only html is clipped, never body: making body a scroll container of its own
   re-parents the sticky site header to it, so on a scrolled page the header
   drops back to the top of the document and pops into place again the moment
   the lock lifts. Hiding overflow on the root stops the page just as well. */
html.xm-lock {
  overflow: hidden;
}

html.xm-lock body {
  padding-right: var(--ext-sbw, 0px);
}

/* ------------------------------ shell ----------------------------------- */
.xm-menu {
  position: fixed;
  inset: 0;
  /* 100vw, not 100%: the reserved scrollbar gutter is outside the fixed
     containing block, and without this the page background shows through it
     as a bright stripe down the side of the blackout. The panel's own
     alignment is measured against this box, so it stays exact either way. */
  width: 100vw;
  z-index: 940;
  visibility: hidden;
  pointer-events: none;
  overflow: clip;
}

.xm-menu.is-open,
.xm-menu.is-closing {
  visibility: visible;
}

.xm-menu.is-open {
  pointer-events: auto;
}

/* Curtain: three full-cover sheets cascade down (soft → gold → ink) and
   leave on close in reverse (ink → gold → soft). No leftover stripes. */
.xm-sheet {
  position: absolute;
  inset: 0;
  transform: translateY(-101%);
  transition: transform 0.6s var(--xm-ease-io);
  will-change: transform;
}

.xm-sheet-soft {
  background: var(--xm-soft);
}

.xm-sheet-gold {
  background: var(--xm-gold);
}

.xm-sheet-ink {
  background: var(--xm-ink);
}

.xm-menu.is-open .xm-sheet {
  transform: none;
}

.xm-menu.is-open .xm-sheet-gold {
  transition-delay: 0.07s;
}

.xm-menu.is-open .xm-sheet-ink {
  transition-delay: 0.14s;
}

/* Closing order is: panel content clears (0 - 0.2s), then the curtain lifts.
   The sheets used to start on frame 1 and finish before the top row had even
   begun its 0.32s-delayed fade, so the logo and close button hung in mid-air
   over the revealed page. Everything inside now exits first, by design. */
.xm-menu.is-closing .xm-sheet {
  transition-duration: 0.52s;
}

.xm-menu.is-closing .xm-sheet-ink {
  transition-delay: 0.1s;
}

.xm-menu.is-closing .xm-sheet-gold {
  transition-delay: 0.17s;
}

.xm-menu.is-closing .xm-sheet-soft {
  transition-delay: 0.24s;
}

/* ------------------------------- inner ----------------------------------
   One flex column: header row, body, footer row. The column is pinned to the
   host header's own content box - site-menu.js measures the toggle and the
   logo at open time and writes --xm-pad-*, so the menu's logo and close button
   land exactly where the header's pair sat. The literal values below are the
   fallback for when that measurement is skipped (header hidden off-screen, or
   JS bailed). */
.xm-inner {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 3.4vh, 40px);
  padding: var(--xm-pad-t, clamp(18px, 3vh, 30px)) var(--xm-pad-r, var(--xm-gutter))
    clamp(20px, 3.4vh, 34px) var(--xm-pad-l, var(--xm-gutter));
  max-width: var(--xm-col-max, 1500px);
  margin: 0 auto;
  /* scrollable only as a safety net on tiny viewports - never show bars */
  overflow-y: auto;
  overflow-x: clip;
  scrollbar-width: none;
  overscroll-behavior: contain;
}

/* Body: links beside the context panel on desktop, stacked below tablet.
   `min-height: 0` lets it shrink inside the scrolling column instead of
   pushing the footer row off the bottom on short viewports. */
.xm-mid {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  min-height: 0;
  gap: clamp(24px, 5vw, 96px);
}

.xm-inner::-webkit-scrollbar {
  display: none;
}

/* the dialog takes programmatic/click focus (tabindex="-1") - never show
   the browser's default ring around the whole panel */
.xm-inner:focus {
  outline: none;
}

/* ------------------------------ top row --------------------------------- */
.xm-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* same row height as the header the menu replaced, so both pairs share a
     vertical centre line */
  min-height: var(--xm-close-h, 48px);
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.4s ease 0.32s, transform 0.5s var(--xm-ease-out) 0.32s;
  /* on very short viewports the inner scrolls - keep the close control
     pinned so the exit never scrolls away */
  position: sticky;
  top: 0;
  z-index: 5;
}

.xm-menu.is-open .xm-top {
  opacity: 1;
  transform: none;
}

/* the top row must be gone before the curtain uncovers the page behind it */
.xm-menu.is-closing .xm-top {
  opacity: 0;
  transform: translateY(-8px);
  transition-delay: 0s;
  transition-duration: 0.18s;
}

.xm-logo {
  display: inline-flex;
  line-height: 0;
}

.xm-logo img {
  width: var(--xm-logo-w, clamp(108px, 9vw, 132px));
  height: auto;
}

/* The right-hand pair, mirroring the header's .ext-button-area-start: same
   order, same 12px gap, same two shapes. The close control is measured onto
   the toggle's exact box by site-menu.js (--xm-close-*), so between closed and
   open only the glyph inside it changes - dots to a cross. */
.xm-tools {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 12px;
}

/* Deliberate copies of .ext-btn / .ext-menu-btn (style.css). This file stays
   self-contained by design - it must not inherit page tokens - so the two
   header skins are restated here rather than borrowed. */
.xm-hire {
  display: inline-flex;
  flex: 0 0 auto;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  padding: 0 24px;
  color: #ffffff;
  font-family: var(--xm-font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  border: none;
  border-radius: 12px;
  background: #292c2e;
  transition: transform 0.18s ease, background-color 0.18s ease;
}

.xm-hire:hover,
.xm-hire:focus-visible {
  background: #3a3f44;
  transform: translateY(-1px);
}

.xm-close {
  flex: 0 0 auto;
  width: var(--xm-close-w, 48px);
  height: var(--xm-close-h, 48px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid #d7d7d7;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.72);
  color: #111315;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    0 4px 14px rgba(17, 19, 21, 0.08);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  cursor: pointer;
  transition: background-color 0.3s ease, border-color 0.3s ease,
    transform 0.3s var(--xm-ease-out);
}

.xm-close svg {
  width: 18px;
  height: 18px;
}

.xm-close:hover,
.xm-close:focus-visible {
  background: rgba(255, 255, 255, 0.92);
  border-color: #cfcfcf;
  transform: translateY(-1px);
}

/* the header's own two steps down (style.css breakpoints, not this file's) -
   the close control is measured, so only the button beside it needs them */
@media (max-width: 767px) {
  .xm-tools {
    gap: 8px;
  }

  .xm-hire {
    min-height: 46px;
    padding: 0 18px;
    font-size: 13px;
  }
}

@media (max-width: 420px) {
  .xm-hire {
    min-height: 42px;
    padding: 0 12px;
    font-size: 12px;
  }
}

/* -------------------------------- nav ----------------------------------- */
.xm-nav {
  flex: 1 1 auto;
  min-width: 0;
}

.xm-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(2px, 0.8vh, 10px);
}

.xm-link {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  color: var(--xm-snow);
  text-decoration: none;
  transition: transform 0.4s var(--xm-ease-out);
  will-change: transform;
}

.xm-link:hover,
.xm-link:focus-visible {
  transform: translateX(10px);
}

/* word reveal (open) + gold roll (hover) */
.xm-mask {
  display: block;
  overflow: hidden;
  padding: 0.06em 0;
  margin: -0.06em 0;
  min-width: 0;
}

.xm-reveal {
  display: block;
  transform: translateY(115%);
  transition: transform 0.7s var(--xm-ease-out);
  will-change: transform;
}

.xm-menu.is-open .xm-reveal {
  transform: none;
}

.xm-menu.is-open .xm-item:nth-child(1) .xm-reveal { transition-delay: 0.4s; }
.xm-menu.is-open .xm-item:nth-child(2) .xm-reveal { transition-delay: 0.445s; }
.xm-menu.is-open .xm-item:nth-child(3) .xm-reveal { transition-delay: 0.49s; }
.xm-menu.is-open .xm-item:nth-child(4) .xm-reveal { transition-delay: 0.535s; }
.xm-menu.is-open .xm-item:nth-child(5) .xm-reveal { transition-delay: 0.58s; }
.xm-menu.is-open .xm-item:nth-child(6) .xm-reveal { transition-delay: 0.625s; }
.xm-menu.is-open .xm-item:nth-child(7) .xm-reveal { transition-delay: 0.67s; }
.xm-menu.is-open .xm-item:nth-child(8) .xm-reveal { transition-delay: 0.715s; }

.xm-menu.is-closing .xm-reveal {
  transform: translateY(-115%);
  transition-duration: 0.26s;
  transition-delay: 0s;
}

/* The gold hover-face sits one line below its white twin, so rolling the whole
   stack up on close pulled it straight into the mask - the words went gold and
   sat there until the curtain carried them off. Drop it out of the way so the
   mask actually empties. */
.xm-menu.is-closing .xm-face-gold {
  opacity: 0;
}

.xm-roll {
  display: block;
  position: relative;
  transition: transform 0.5s var(--xm-ease-io);
  will-change: transform;
}

.xm-link:hover .xm-roll,
.xm-link:focus-visible .xm-roll {
  transform: translateY(-100%);
}

/* Sized off both axes: a purely vh-based size ballooned on a tall phone and
   collapsed on a short laptop. */
.xm-face {
  display: block;
  font: 600 clamp(26px, calc(2.4vh + 1.6vw), 46px)/1.16 var(--xm-font-display);
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.xm-face-gold {
  position: absolute;
  top: 100%;
  left: 0;
  color: var(--xm-gold);
}

/* current page (or the section a child page belongs to) stays gold */
.xm-link[aria-current="page"] .xm-face,
.xm-link.is-active .xm-face {
  color: var(--xm-gold);
}

/* ------------------------------- aside ---------------------------------- */
.xm-aside {
  position: relative;
  display: flex;
  flex: 0 1 380px;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
}

.xm-aside > * {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.5s ease, transform 0.6s var(--xm-ease-out);
}

.xm-menu.is-open .xm-aside > * {
  opacity: 1;
  transform: none;
}

.xm-menu.is-open .xm-eyebrow { transition-delay: 0.55s; }
.xm-menu.is-open .xm-desc { transition-delay: 0.62s; }
.xm-menu.is-open .xm-cta-row { transition-delay: 0.69s; }

.xm-menu.is-closing .xm-aside > * {
  opacity: 0;
  transition-delay: 0s;
  transition-duration: 0.18s;
}

.xm-eyebrow {
  margin: 0;
  font: 700 13px/1 var(--xm-font-body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(253, 252, 250, 0.72);
}

.xm-desc {
  margin: 0;
  max-width: 30ch;
  min-height: 4.5em;
  font: 500 clamp(17px, 1.5vw, 21px)/1.5 var(--xm-font-body);
  color: rgba(253, 252, 250, 0.82);
}

.xm-desc.is-swapping {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.16s ease, transform 0.16s ease;
}

/* One solid primary + one outlined icon button, both on the site's button
   geometry (52px tall, 12px corners) so the panel's controls match the
   header's rather than introducing a second button language. */
.xm-cta-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.xm-wa {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--xm-line);
  border-radius: 12px;
  color: var(--xm-snow);
  transition: background-color 0.25s ease, border-color 0.25s ease,
    color 0.25s ease;
}

.xm-wa svg {
  width: 22px;
  height: 22px;
}

.xm-wa:hover,
.xm-wa:focus-visible {
  border-color: var(--xm-snow);
  background: var(--xm-snow);
  color: var(--xm-ink);
}

.xm-cta,
.xm-cta.ext-capsule-meet-btn {
  display: inline-flex;
  width: auto;
  height: auto;
  min-height: 52px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 26px;
  border: none;
  border-radius: 12px;
  background: var(--xm-gold);
  color: var(--xm-ink);
  font: 700 15px/1.2 var(--xm-font-body);
  text-decoration: none;
  transition: background-color 0.25s ease;
}

.xm-cta:hover,
.xm-cta:focus-visible,
.xm-cta.ext-capsule-meet-btn:hover,
.xm-cta.ext-capsule-meet-btn:focus-visible {
  background: var(--xm-soft);
  transform: none;
}

/* ------------------------------- footer --------------------------------- */
.xm-foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 20px;
  border-top: 1px solid var(--xm-line);
  padding-top: 16px;
  opacity: 0;
  transition: opacity 0.5s ease 0.8s;
}

.xm-menu.is-open .xm-foot {
  opacity: 1;
}

.xm-menu.is-closing .xm-foot {
  opacity: 0;
  transition-delay: 0s;
  transition-duration: 0.18s;
}

.xm-mail {
  color: var(--xm-snow);
  font: 600 clamp(15px, 1.2vw, 17px)/1.2 var(--xm-font-body);
  text-decoration: none;
}

.xm-mail:hover,
.xm-mail:focus-visible {
  color: var(--xm-gold);
}

.xm-social {
  display: flex;
  flex-wrap: wrap;
  gap: 8px clamp(14px, 2vw, 26px);
}

.xm-social a {
  position: relative;
  color: rgba(253, 252, 250, 0.66);
  font: 500 14px/1.2 var(--xm-font-body);
  text-decoration: none;
  transition: color 0.2s ease;
}

.xm-social a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 2px;
  background: var(--xm-gold);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--xm-ease-out);
}

.xm-social a:hover,
.xm-social a:focus-visible {
  color: var(--xm-gold);
}

.xm-social a:hover::after,
.xm-social a:focus-visible::after {
  transform: scaleX(1);
}

/* ---------------------------- focus rings ------------------------------- */
.xm-menu a:focus-visible,
.xm-menu button:focus-visible {
  outline: 2px solid var(--xm-gold);
  outline-offset: 4px;
}

/* ----------------------------- responsive -------------------------------
   Tablet and below: the body stacks, so the row becomes a column - links
   first, then the CTA pair. The description panel is a hover affordance for
   the pointer, so it leaves with the two-column layout. */
@media (max-width: 1023px) {
  .xm-mid {
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    gap: clamp(22px, 3.6vh, 40px);
  }

  .xm-nav {
    flex: 0 0 auto;
  }

  .xm-aside {
    flex: 0 0 auto;
    gap: 14px;
  }

  .xm-eyebrow,
  .xm-desc {
    display: none;
  }
}

@media (max-width: 640px) {
  .xm-link:hover,
  .xm-link:focus-visible {
    transform: translateX(6px);
  }

  .xm-cta-row {
    align-self: stretch;
  }

  /* full-width primary, icon button parked beside it - the same pairing the
     hero actions use on a phone */
  .xm-cta,
  .xm-cta.ext-capsule-meet-btn {
    flex: 1 1 auto;
    min-height: 50px;
    padding: 0 20px;
  }

  .xm-wa {
    width: 50px;
    height: 50px;
  }

  .xm-foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .xm-social a {
    font-size: 13px;
  }
}

/* short viewports: tighten the list so 8 items always fit */
@media (max-height: 640px) {
  .xm-face {
    font-size: clamp(20px, 4vh, 30px);
  }

  .xm-list {
    gap: 0;
  }

  .xm-desc {
    min-height: 0;
  }
}

/* Landscape phones and the like: the panel genuinely scrolls here, and the top
   row stays pinned so the exit is always reachable - so give it something to
   sit on, or the links slide across the logo. Scoped to these heights only:
   at normal sizes the panel never scrolls. */
@media (max-height: 560px) {
  .xm-top::after {
    content: "";
    position: absolute;
    z-index: -1;
    left: calc(0px - var(--xm-pad-l, var(--xm-gutter)));
    right: calc(0px - var(--xm-pad-r, var(--xm-gutter)));
    top: calc(0px - var(--xm-pad-t, 24px));
    bottom: -18px;
    background: linear-gradient(180deg, var(--xm-ink) 0%, var(--xm-ink) 66%, transparent 100%);
    pointer-events: none;
  }
}

/* --------------------------- reduced motion ----------------------------- */
@media (prefers-reduced-motion: reduce) {
  .xm-sheet,
  .xm-reveal,
  .xm-roll,
  .xm-link,
  .xm-top,
  .xm-aside > *,
  .xm-cta,
  .xm-wa,
  .xm-foot,
  .xm-social a::after,
  .xm-hire,
  .xm-close {
    transition-duration: 0.01s !important;
    transition-delay: 0s !important;
  }

  .xm-reveal {
    transform: none !important;
  }
}
