/* ================================================================
   sections/menu-line.css
   Source: research/fragments/home/menu-line.html (desktop DOM)
           research/raw/{tablet,phone}/home.html (variant DOM)
   Reference height: 45px at every breakpoint (reference-heights.json).

   Reference class map (for auditing against _stylesheet.css):
     .framer-n5w4k8-container -> .menu-line-fixed
     .framer-WRvs2.framer-tkta92 -> .menu-line-root
     .framer-14w3vrv          -> .menu-line              (data-section)
     .framer-16m7hnn          -> .menu-line__left
     .framer-lkhz4            -> .menu-line__logo
     .framer-17scu59          -> .menu-line__mark
     .framer-9oc38v           -> .menu-line__wordmark
     .framer-194y5pg          -> .menu-line__right
     .framer-1dcgrtt          -> .menu-line__gap
     .framer-luvgjy           -> .menu-line__nav
     .framer-ozge6a           -> .menu-line__actions
     .framer-1ughqml          -> .menu-line__plus
     .framer-wldcrd-container -> .menu-line__book
     .framer-rova0i-container -> .menu-line__burger
     .framer-3sbedv           -> .menu-line__panel
     .framer-jga57y (esrQK)   -> .btn-book
     .framer-72mq0z (Iqr1C)   -> .burger
     .framer-1hhiidg          -> .menu-line__list
     .framer-zy0iqs (tYKN9)   -> .arrow-link

   Structure is IDENTICAL at desktop / laptop / tablet; the phone variant
   (framer-v-1pnjsji) drops the spacer and the "book a call" button. One
   DOM + media queries reproduces all four.
   ================================================================ */

/* ---------- fixed wrapper ---------- */
.menu-line-fixed {
  position: fixed;
  top: var(--menu-top);              /* 13px */
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  height: auto;
  z-index: 10;
}

/* ---------- component root: page inset ---------- */
.menu-line-root {
  display: flex;
  flex-flow: row;
  place-content: center;
  align-items: center;
  gap: 0;
  width: 100%;
  height: min-content;
  padding: 12px var(--page-pad-desktop) 0;   /* 12px 32px 0 */
  position: relative;
  overflow: visible;
}

/* ---------- the measured section ---------- */
.menu-line {
  display: flex;
  flex-flow: row;
  flex: 1 0 0;
  place-content: center;
  align-items: center;
  gap: 0;
  width: 1px;                      /* Framer's flex-basis idiom */
  max-width: var(--page-max);      /* 1520px */
  height: min-content;             /* -> 45px, driven by .menu-line__burger */
  padding: 0;
  position: relative;
  overflow: visible;
}

/* ---------- left: logo ---------- */
.menu-line__left {
  display: flex;
  flex-flow: row;
  flex: 1 0 0;
  place-content: flex-start;
  align-items: flex-start;
  gap: 10px;
  width: 1px;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
}

.menu-line__logo {
  display: flex;
  flex-flow: row;
  flex: none;
  place-content: center flex-start;
  align-items: center;
  gap: 10px;
  width: min-content;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
  text-decoration: none;
}

.menu-line__mark {
  display: block;
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  position: relative;
}
.menu-line__mark svg { width: 100%; height: 100%; }

/* The wordmark box is 24px tall but the type has line-height:78px and is
   vertically centred, so it is clipped top and bottom. Verbatim reference
   behaviour — do not "fix" the line-height. */
.menu-line__wordmark {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  justify-content: center;
  flex: none;
  width: auto;
  height: 24px;
  position: relative;
  white-space: pre;
}
.menu-line__wordmark p {
  font-family: var(--font-logo);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .03em;
  line-height: 78px;
  text-transform: uppercase;
  color: var(--c-black);
}

/* ---------- right: spacer + nav ---------- */
.menu-line__right {
  display: flex;
  flex-flow: row;
  flex: 2 0 0;
  place-content: center;
  align-items: center;
  gap: 0;
  width: 1px;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: visible;
}

.menu-line__gap {
  display: flex;
  flex-flow: row;
  flex: 3 0 0;
  place-content: flex-start;
  align-items: flex-start;
  gap: 0;
  width: 1px;
  min-height: 31px;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
}

.menu-line__nav {
  display: flex;
  flex-flow: row;
  flex: 1 0 0;
  place-content: flex-start;
  align-items: flex-start;
  gap: 0;
  width: 1px;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: visible;
}

.menu-line__actions {
  display: flex;
  flex-flow: row;
  flex: 1 0 0;
  place-content: center flex-start;
  align-items: center;
  gap: 0;
  width: 1px;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: visible;
}

/* the little orange crosshair that overhangs the top-left corner */
.menu-line__plus {
  display: block;
  z-index: 2;
  flex: none;
  width: 15px;
  height: 15px;
  position: absolute;
  top: -7px;
  left: -7px;
}
.menu-line__plus svg { width: 100%; height: 100%; }

/* ---------- "book a call" ---------- */
.menu-line__book {
  z-index: 0;
  flex: 1 0 0;
  align-self: stretch;
  width: 1px;
  height: auto;
  position: relative;
}

.btn-book {
  display: flex;
  flex-flow: row;
  place-content: center;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 100%;
  padding: 0;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
  cursor: pointer;
  text-decoration: none;
  background-color: var(--c-cream);
  border-top: 1px solid var(--c-stone);
  border-left: 1px solid var(--c-stone);
  border-bottom: 1px solid var(--c-stone);
  border-right: 0;
  transition: border-color .25s var(--ease-spring0);
}

/* Animation-QA pass (2026-08-18): hovered the LIVE "book a call" button
   (https://oberon.framer.website/, 1440x900) and diffed the DOM/computed
   style before vs. after a real Playwright mouse hover. The fill never
   changes at all (background-color and the white sliver div both stay
   identical) — only `--border-color` changes, from the resting
   rgb(210,206,202) (`--c-stone`) to rgb(230,88,0) (`--c-orange`), on all
   three visible sides. The previous version of this file had a white
   1px-sliver-to-full-width edge-fill reconstruction (guessed, because
   hover states run through Framer's JS variant runtime and are absent
   from the static capture) — confirmed wrong by the live measurement
   above and replaced with the real border-color swap. `.btn-book__edge`
   is kept: it is a real, always-on 1px sliver that masks the shared left
   border against the adjacent burger button, just no longer animated. */
.btn-book__edge {
  z-index: 1;
  flex: none;
  width: 1px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1px;
  background-color: var(--c-white);
}
.btn-book:hover,
.btn-book:focus-visible { border-color: var(--c-orange); }

.btn-book__text {
  display: flex;
  flex-flow: row;
  flex: none;
  z-index: 1;
  place-content: center;
  align-items: center;
  gap: 10px;
  width: min-content;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
}
.btn-book__text p {
  white-space: pre;
  flex: none;
  width: auto;
  height: auto;
  position: relative;
}

/* ---------- burger ---------- */
.menu-line__burger {
  z-index: 1;
  flex: none;
  width: 45px;
  height: 45px;
  position: relative;
}

.burger {
  display: flex;
  flex-flow: column;
  place-content: center;
  align-items: center;
  gap: 5px;
  width: 100%;
  height: 100%;
  padding: 0 10px;
  position: relative;
  overflow: var(--overflow-clip-fallback, clip);
  cursor: pointer;
  background-color: var(--c-graphite);
  border: 0;
}

.burger__edge {
  z-index: 0;
  flex: none;
  width: 1px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1px;
  background-color: var(--c-orange);
  transition: left .25s var(--ease-spring0), right .25s var(--ease-spring0),
              width .25s var(--ease-spring0);
}
.burger:hover .burger__edge,
.burger:focus-visible .burger__edge { width: auto; left: 0; right: 0; }

.burger__line {
  display: flex;
  flex-flow: row;
  flex: none;
  place-content: center flex-end;
  align-items: center;
  gap: 2px;
  width: 25px;
  height: 2px;
  padding: 0;
  position: relative;
  overflow: visible;
  background-color: var(--c-cream);
  transition: transform .3s var(--ease-spring0), opacity .2s linear;
}

/* open state: the two rules cross (reference variant framer-v-3yacwl stacks
   them both at the vertical centre and rotates them). */
.menu-line--open .burger__line {
  position: absolute;
  z-index: 1;
  top: calc(51.1111% - .75px);
  left: calc(51.1111% - 12.5px);
}
/* FIX (2026-08-16): was `:nth-of-type(1)/(2)`, which counts among ALL <span>
   siblings — .burger__edge is also a <span> and sits first in the DOM, so
   nth-of-type(1) silently matched .burger__edge (rotating nothing visible)
   and nth-of-type(2) matched only the FIRST .burger__line, leaving the
   second one un-rotated. Only one diagonal line rendered (a "/", not an
   "×") — caught visually comparing the clone's open burger against the
   live reference's clean cross at 390x844. `:nth-child()` counts DOM
   position regardless of tag, so (2)/(3) correctly hit the two
   `.burger__line`s (edge is child 1). */
.menu-line--open .burger__line:nth-child(2) { transform: rotate(45deg); }
.menu-line--open .burger__line:nth-child(3) { transform: rotate(-45deg); }

/* ---------- panel behind the burger / mobile menu surface ---------- */
.menu-line__panel {
  aspect-ratio: 1;
  width: var(--framer-aspect-ratio-supported, 45px);
  z-index: 0;
  flex: none;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  overflow: visible;
  background-color: var(--c-graphite);
  border-right: 1px solid var(--c-hairline-dark);
  transition: width .45s var(--ease-spring0), height .45s var(--ease-spring0);
}

.menu-line--open .menu-line__panel {
  aspect-ratio: unset;
  bottom: unset;
  width: 100%;
  height: calc(var(--framer-viewport-height, 100vh) * .48);
}

/* the link list only exists while the panel is open */
.menu-line__list {
  display: none;
  flex-flow: column;
  flex: none;
  place-content: flex-start flex-end;
  align-items: flex-start;
  gap: 10px;
  width: 229px;
  height: min-content;
  padding: 60px 0 0 20px;
  margin: 0;
  list-style: none;
  position: absolute;
  top: 0;
  right: 0;
  overflow: var(--overflow-clip-fallback, clip);
}
.menu-line--open .menu-line__list { display: flex; width: 100%; }

/* ---------- arrow link (shared with the footer) ---------- */
.arrow-link {
  display: flex;
  flex-flow: row;
  place-content: center flex-start;
  align-items: center;
  gap: 10px;
  width: min-content;
  height: min-content;
  padding: 0;
  position: relative;
  /* NOT `overflow:clip` like most components here. `.arrow-link__icon` is an
     absolutely-positioned child parked at `left:-23px` — entirely outside
     this element's own box — so it needs its nearest positioned ancestor
     (this element) to allow overflow, or the hover reveal can never paint
     regardless of its opacity. Found while verifying the opacity-reveal fix
     above: opacity flipped to 1 on hover (confirmed via getComputedStyle)
     but nothing rendered on screen until this was changed. Safe: it only
     affects paint, not any measured box dimension. */
  overflow: visible;
  cursor: pointer;
  text-decoration: none;
}
.arrow-link__icon {
  display: flex;
  flex-flow: row;
  flex: none;
  place-content: center;
  align-items: center;
  gap: 10px;
  width: 12px;
  height: 12px;
  padding: 0;
  position: absolute;
  top: 49%;
  left: -23px;
  transform: translateY(-50%);
  overflow: visible;
  /* Animation-QA pass (2026-08-18): hovered the LIVE footer "home"/"about"/etc
     arrow-links (https://oberon.framer.website/) with a real Playwright mouse
     move and screenshotted before/after — the arrow icon is fully ABSENT at
     rest and fades/slides in only on hover. The clone previously rendered it
     permanently visible with only a 3px hover nudge, i.e. the reveal itself
     (the whole animation) was missing, not just its distance. */
  opacity: 0;
}
.arrow-link__icon svg { width: 100%; height: 100%; }

/* ---- hover (mouse only) -------------------------------------------------
   Reference .framer-tYKN9, variant «Desktop». Measured live 2026-08-18
   (1440x900) with site-clone-kit/scripts/oberon-hover-measure.mjs; timing
   tokens and the bezier fit are in base.css § 5b.

   At rest the link is label-only — "home" measures 36px wide — and the
   12x12 arrow is parked 23px to its left and 6px high. On hover the link
   itself SPRING-GROWS 23px (1px inset + 12px icon + 10px gap), pushing the
   label right by exactly that, while the arrow slides 24px right and 6px
   down into the gap that opens for it. Live deltas: link 36 -> 59px,
   label x +23.0, icon x +24.0. It is much snappier than the CTA sweep —
   150ms in / 155ms out against the pill's 510/500.

   The reveal is an opacity fade here rather than the reference's clip:
   the reference relies on the link's own overflow to hide the parked
   arrow, but `.arrow-link` must stay `overflow: visible` in this clone
   (see the note on the base rule above), so opacity does the hiding. Both
   land on the same resting pixels — no arrow — and the same hover pixels.

   The width growth is the one hover effect here that is not purely
   transform/opacity, i.e. it does change this element's own box. That is
   safe against the height invariant in js/main.js: `.arrow-link__text` is
   `white-space: pre` so the label can never wrap, every list that holds
   these links is a fixed- or full-width column, and the growth is
   horizontal only and exists solely while a mouse is held over the link —
   never at rest, which is when QA measures.
   ------------------------------------------------------------------------ */
@media (hover: hover) and (pointer: fine) {
  .arrow-link {
    transition: padding-left var(--hov-link-dur-out) var(--hov-link-ease-out);
  }
  .arrow-link:hover,
  .arrow-link:focus-visible {
    padding-left: 23px;
    transition-duration: var(--hov-link-dur-in);
    transition-timing-function: var(--hov-link-ease-in);
  }

  .arrow-link__icon {
    transform: translate(0, calc(-50% - 6px));
    transition: transform var(--hov-link-dur-out) var(--hov-link-ease-out),
                opacity   var(--hov-link-dur-out) linear;
  }
  .arrow-link:hover .arrow-link__icon,
  .arrow-link:focus-visible .arrow-link__icon {
    opacity: 1;
    transform: translate(24px, -50%);
    transition-duration: var(--hov-link-dur-in);
    transition-timing-function: var(--hov-link-ease-in), linear;
  }
}
.arrow-link__text {
  white-space: pre;
  flex: none;
  width: auto;
  height: auto;
  position: relative;
}
/* inside the dark panel the labels are cream, not black */
.menu-line__list .arrow-link__text { color: var(--c-cream); }

/* ================================================================
   Breakpoints. Bounds are the reference's own layout-variant queries.
   ================================================================ */

/* tablet + laptop: 810px .. 1439.98px  (variant framer-v-kwb07w) */
@media (min-width: 810px) and (max-width: 1439.98px) {
  .menu-line__gap { flex: 1 0 0; }
}

/* phone: <= 809.98px  (variant framer-v-1pnjsji) */
@media (max-width: 809.98px) {
  .menu-line-root { padding: 12px var(--page-pad-phone) 0; }   /* 12px 26px 0 */
  .menu-line__left { flex: none; width: min-content; }
  .menu-line__wordmark p { font-size: 18px; }
  .menu-line__right { flex: 1 0 0; }
  .menu-line__gap { display: none; }
  .menu-line__book { display: none; }
  .menu-line__plus { display: none; }
  .menu-line__actions { justify-content: flex-end; }
  .menu-line--open .menu-line__list { padding: 70px 0 0 20px; }

  /* Open panel width/position — FIX (verified against the live reference,
     2026-08-16). The base (all-breakpoint) rule anchors .menu-line__panel
     to its immediate flex ancestor .menu-line__actions, which only hugs the
     burger's own content width (~230px at 390px viewport) — so the open
     panel rendered as a narrow floating box pinned to the right, not the
     dark full-bleed overlay the reference shows. Measured on
     https://oberon.framer.website/ at 390x844: the open panel's rect is
     left:26 top:25 width:338 (== the SAME box as the menu-line header row
     itself: --page-pad-phone inset on both sides, starting right at the
     header's own top, not below it). Breaking the panel out to `position:
     fixed` with explicit left/right insets reproduces that exactly,
     independent of how wide its flex ancestor happens to be. Scoped to
     this phone query only — desktop/tablet keep the original anchor (the
     reference's own `.menu-line__plus` crosshair there still needs
     `.menu-line__actions` to stay `position:relative`). */
  .menu-line--open .menu-line__panel {
    position: fixed;
    top: calc(var(--menu-top) + 12px);
    left: var(--page-pad-phone);
    right: var(--page-pad-phone);
    width: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn-book,
  .burger__edge,
  .burger__line,
  .menu-line__panel,
  .arrow-link__icon { transition: none !important; }
}

/* Real Autnex wordmark (autnex-logo-black.svg, 2350x320) replaces the
   template mark + letter-split text. Height matches the old logo row. */
.menu-line__logo-img { flex: none; height: 17px; width: 125px; display: block; }

/* ----------------------------------------------------------------
   Logo inversion over dark sections — class driven by js/effects.js §2.
   The wordmark image is solid black, so brightness(0) invert(1) yields
   the exact white variant without needing a second SVG asset. The rest
   state carries an explicit brightness(0) invert(0) — visually identical
   to none on an already-black image — so both states share one filter
   function list and the browser can interpolate invert() smoothly.
   Timing matches the live template's measured colour tween: ~190ms,
   fast-out (31/78/93/98% at 30/60/90/125ms).
   ---------------------------------------------------------------- */
.menu-line__logo-img {
  filter: brightness(0) invert(0);
  transition: filter 200ms cubic-bezier(.2,.8,.3,1);
}
.menu-line-fixed.is-over-dark .menu-line__logo-img { filter: brightness(0) invert(1); }
@media (prefers-reduced-motion: reduce) {
  .menu-line__logo-img { transition: none; }
}

/* The "+ book a call" cluster exists only while the hero is in view —
   past the hero's bottom edge the reference removes it from the DOM
   entirely (hard swap, reversible on scroll-up). js/effects.js §2
   toggles is-scrolled at the measured threshold. */
.menu-line-fixed.is-scrolled .menu-line__plus,
.menu-line-fixed.is-scrolled .menu-line__book { display: none; }
/* The actions row is left-aligned and exactly filled at rest, and the
   collapsed .menu-line__panel square is absolutely parked at right:0
   BEHIND the burger. With the pill display:none'd, a left-aligned burger
   would slide off its slot and expose the panel as a stray dark tile —
   keep the lone burger pinned at the right edge, where the reference
   keeps it. */
.menu-line-fixed.is-scrolled .menu-line__actions { justify-content: flex-end; }
/* At PHONE the reference removes the LOGO too once past the hero (probed
   live 390: logo link gone from the DOM at scrollY 800, back at rest —
   only the burger remains). Same hard-swap, same threshold. */
@media (max-width: 809.98px) {
  .menu-line-fixed.is-scrolled .menu-line__logo { display: none; }
}
