/* ============================================================
   00-nav — global navigation
   Transparent over the dark hero; solid + hairline on scroll.
   All selectors scoped to .nav*  ·  every value resolves to a token.
   ============================================================ */

.nav {
  /* -- local aliases: the only place raw numbers may appear, and each
        one is derived from a token so it stays traceable -------- */
  --nav-h:       calc(var(--s-9) + var(--s-6));                      /* 72px */
  /* Every trigger is a touch target: the desktop bar is now served to
     1194px tablets, so 44px is a real requirement here, not a mobile one. */
  --nav-tap:     calc(var(--s-9) - var(--s-1));                      /* 44px */
  /* Distance from the trigger's bottom edge to the panel card. Doubles as the
     hover bridge, so the value is derived once and reused. */
  --nav-bridge:  calc((var(--nav-h) - var(--nav-tap)) / 2 + var(--s-2));
  /* Drawer breakpoint. Declared here so the inline script at the foot of the
     partial can read it — the CSS media queries below and the JS that keeps
     the drawer open across a resize are one value, not two. */
  --nav-bp:      71.25em;
  /* -- Panel geometry. Derived from the one measurement that decides the
        card, the description measure, so no panel width is a free number.
        --nav-measure  200px — the longest description in this nav sets it
                       (~30 characters at --fs-xs); 192px while a scrolled
                       menu is showing its 8px track, still one line.
        --nav-col      = measure + icon column + column-gap + row padding×2
        --nav-card     = two columns + their gap + the card's own padding -- */
  --nav-measure: 12.5rem;                                            /* 200px */
  --nav-col:     calc(var(--nav-measure) + var(--s-5) + var(--s-3) * 3);
  --nav-card:    calc(var(--nav-col) * 2 + var(--s-7) * 3);          /* 608px */
  --nav-rail:    16rem;      /* holds "Managed Payments" + its badge on one line */
  --nav-ink:     var(--c-white);
  --nav-ink-dim: color-mix(in srgb, var(--c-white) 72%, transparent);
  --nav-hit:     color-mix(in srgb, var(--c-white) 12%, transparent);
  --nav-edge:    color-mix(in srgb, var(--c-white) 28%, transparent);
  --nav-edge-hi: color-mix(in srgb, var(--c-white) 45%, transparent);
  --nav-fill:    color-mix(in srgb, var(--c-white) 16%, transparent);
  --nav-fill-hi: color-mix(in srgb, var(--c-white) 26%, transparent);
  --nav-ring:    color-mix(in srgb, var(--c-navy) 5%, transparent);

  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  /* Zero flow height: the hero's dark gradient runs underneath the bar,
     which is what lets the transparent → solid inversion happen at all. */
  margin-bottom: calc(var(--nav-h) * -1);
  color: var(--nav-ink);
}

/* The solid bar lives in a pseudo-element so the swap is pure opacity —
   no border added, no height change, no reflow.
   The fill is the same white as an open panel: a frosted mix only ever
   showed while the bar was already fading, and read as a second surface
   butting into the menu card. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--surface);
  box-shadow: 0 1px 0 var(--c-hairline), var(--sh-sm);
  opacity: 0;
  transition: opacity var(--t-base) var(--ease-out);
  pointer-events: none;
}

.nav.is-scrolled,
.nav.has-menu-open,
.nav.is-open {
  --nav-ink:     var(--c-navy);
  --nav-ink-dim: var(--c-slate);
  --nav-hit:     var(--c-offwhite);
}
.nav.is-scrolled::before,
.nav.has-menu-open::before,
.nav.is-open::before { opacity: 1; }

/* Non-text contrast (WCAG 1.4.11). base.css rings focus in --c-brand, which is
   2.2:1 against the hero gradient showing through the transparent bar. While
   the bar is transparent the ring goes white; the instant it turns solid the
   brand ring from base.css applies again, unchanged. */
.nav:not(.is-scrolled):not(.has-menu-open):not(.is-open) :focus-visible {
  outline-color: var(--c-white);
}

/* Page dimmer behind an open mega menu. Its timings are the panel's timings:
   the dimmer arrives with the card (--t-fast) and clears with it (--t-base).
   Anything slower leaves the page visibly darkened with nothing open. */
.nav__scrim {
  position: fixed;
  inset: var(--nav-h) 0 0;
  z-index: -1;
  background: var(--c-navy);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease-out);
}
.nav.has-menu-open .nav__scrim { opacity: .22; transition-duration: var(--t-fast); }

.nav__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-7);
  height: var(--nav-h);
  /* The container cap is in px but the bar's content is measured in rem, so
     the cap is allowed to grow with the root font — that is what keeps a 200%
     text zoom from driving "Pricing" into "Sign in". 78rem = 1248px sits just
     under the px branch's smallest value (--container-wide + the 20px minimum
     gutter twice = 1280px), so at the default root size it never wins and the
     bar is unchanged; it only takes over once the root font grows, which is
     exactly when the row needs the room. */
  max-width: max(calc(var(--container-wide) + var(--gutter) * 2), 78rem);
}

/* ---------------- Brand ---------------- */

.nav__brand {
  display: flex;
  align-items: center;
  flex: none;
  color: var(--nav-ink);
  border-radius: var(--r-sm);
  transition: color var(--t-base) var(--ease-out), opacity var(--t-fast) var(--ease-out);
}
.nav__brand:hover { color: var(--nav-ink); opacity: .74; }
.nav__wordmark { width: auto; height: var(--s-6); }

/* ---------------- Primary list ---------------- */

.nav__primary { flex: 1 1 auto; min-width: 0; }

.nav__list {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--s-1);
  min-width: 0;
}

/* The panel is anchored to the item that opened it. */
.nav__item { position: relative; }

.nav__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  height: var(--nav-tap);
  padding-inline: var(--s-3);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-snug);
  color: var(--nav-ink);
  white-space: nowrap;
  transition: color var(--t-base) var(--ease-out),
              background-color var(--t-fast) var(--ease-out);
}
.nav__trigger:hover { color: var(--nav-ink); background: var(--nav-hit); }
/* The open item stays lit — this is what ties the panel to its trigger. */
.nav__item.is-active > .nav__trigger { color: var(--nav-ink); background: var(--nav-hit); }

.nav__chev {
  width: .72em;
  height: auto;
  color: var(--nav-ink-dim);
  transition: transform var(--t-base) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.nav__trigger:hover .nav__chev { color: currentColor; }
.nav__item.is-active .nav__chev { transform: rotate(180deg); color: currentColor; }

/* ---------------- Mega panel ----------------
   Panel widths are set from the description measure, not the other way round —
   see --nav-measure / --nav-col / --nav-card above. Every width below resolves
   to those, so nothing here is a number you cannot trace back to a column:
   --nav-card            608px = 2 columns of 256px  (200px measure)
   --nav-card + --s-7    640px = 2 columns of 272px  (216px measure)
   the same + --nav-rail 896px = 2 columns of 256px + the featured rail
   Longest description in the nav is 30 characters, which is ~190px. -------- */

.nav__panel {
  position: absolute;
  top: 100%;
  /* --panel-x / --panel-origin are set per item by the script at the foot of
     the partial: aligned to the trigger, clamped inside the container. */
  left: var(--panel-x, 0px);
  z-index: var(--z-raised);
  width: calc(var(--nav-card) + var(--s-7));
  max-width: calc(100vw - var(--gutter) * 2);
  /* Hover bridge: covers the full gap from the trigger's bottom edge to the
     panel, so a slow pointer never crosses dead space. */
  padding-top: var(--nav-bridge);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(calc(var(--s-2) * -1)) scale(.985);
  transform-origin: var(--panel-origin, 50%) top;
  /* Full dismiss: visibility waits exactly as long as the fade, not longer. */
  transition: opacity var(--t-base) var(--ease-out),
              transform var(--t-base) var(--ease-out),
              visibility 0s linear var(--t-base);
}
.nav__panel--wide   { width: calc(var(--nav-card) + var(--s-7) + var(--nav-rail)); }
.nav__panel--narrow { width: var(--nav-card); }

/* Swapping between menus: the outgoing panel leaves instantly, so two cards of
   different sizes are never painted over each other. */
.nav.has-menu-open .nav__panel { transition: none; }

.nav__item.is-active .nav__panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition: opacity var(--t-fast) var(--ease-out),
              transform var(--t-slow) var(--ease-expo),
              visibility 0s linear 0s;
}

.nav__menu {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding: var(--s-7);
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--nav-ring), var(--sh-xl);
  /* Short viewports (1024×600, a laptop with a toolbar) must still reach the
     last row — the panel is absolute inside a sticky bar, so the page cannot.
     Two bridges: the one above the card plus an equal gap below it, so a
     scrolled menu never runs flush into the viewport edge. */
  max-height: calc(100vh - var(--nav-h) - var(--nav-bridge) * 2);
  max-height: calc(100dvh - var(--nav-h) - var(--nav-bridge) * 2);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Overlay scrollbars hide the fact that a short viewport has cut the list off,
   so a real track is reserved here. The standard `scrollbar-width` /
   `scrollbar-color` pair must NOT be set alongside: in Chromium it switches the
   element to the classic overlay scrollbar and cancels these pseudo-elements,
   which is how the previous pass shipped a card with no track and no cue. */
.nav__menu::-webkit-scrollbar { width: var(--s-2); }
.nav__menu::-webkit-scrollbar-thumb {
  border-radius: var(--r-pill);
  background: var(--c-hairline);
}
/* Firefox has no ::-webkit-scrollbar, so it gets the thin track instead. */
@supports not selector(::-webkit-scrollbar) {
  .nav__menu {
    scrollbar-width: thin;
    scrollbar-color: var(--c-hairline) transparent;
  }
}
/* Second cue, for the case the track alone under-reads: while there is more
   below, the bottom corners square off. A card cut flat behind --r-xl corners
   looks finished; a square edge does not. [data-more] is set by the script at
   the foot of the partial — CSS cannot ask "is this scrolled to the end". */
.nav__menu[data-more] {
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

/* Columns + featured rail. The footer is a sibling of this row, not a child,
   so its hairline spans the full card. */
.nav__body {
  display: flex;
  gap: var(--s-7);
}

.nav__cols {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-7);
}

.nav__coltitle {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-normal);
  color: var(--text-body);
  line-height: var(--lh-normal);
  margin-bottom: var(--s-3);
  padding-inline: var(--s-3);
}

.nav__links > li + li { margin-top: var(--s-1); }

.nav__link {
  display: grid;
  grid-template-columns: var(--s-5) minmax(0, 1fr);
  column-gap: var(--s-3);
  row-gap: var(--s-1);
  padding: var(--s-3);
  border-radius: var(--r-md);
  color: var(--text-strong);
  transition: background-color var(--t-fast) var(--ease-out);
}
.nav__link:hover { background: var(--surface-alt); color: var(--text-strong); }

.nav__ico {
  grid-row: 1 / span 2;
  display: block;
  width: var(--s-5);
  height: var(--s-5);
  margin-top: calc(var(--s-1) / 2);
  color: var(--c-brand);
  transition: color var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}
.nav__ico svg { width: var(--s-5); height: var(--s-5); }
.nav__link:hover .nav__ico { color: var(--c-brand-press); transform: translateY(-1px); }

.nav__t {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  color: var(--text-strong);
}

.nav__d {
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  letter-spacing: var(--tracking-normal);
  color: var(--text-body);
}

/* Featured rail. The title is a sibling of the tinted box, not a child of it:
   padding inside the box would push "Featured" 20px below "Accept money" and
   "Understand money", and three column headings in one card have to sit on one
   line. The box then starts exactly where the first link row starts and
   stretches to the full card height, so its surface reads as a column rather
   than a floating card. Its width is --nav-rail, above. */
.nav__rail {
  flex: 0 0 var(--nav-rail);
  display: flex;
  flex-direction: column;
}
.nav__rail .nav__coltitle { padding-inline: 0; }

/* Top pad is s-3, not s-5, and the first feature drops its own: that puts the
   first line of rail text on exactly the same baseline as the first line in
   each link column, whose s-3 comes from the link's own padding. */
.nav__railbox {
  flex: 1 1 auto;
  padding: var(--s-3) var(--s-5) var(--s-5);
  border-radius: var(--r-lg);
  background: var(--surface-alt);
}
.nav__railbox .nav__feature:first-child { padding-top: 0; }

.nav__feature {
  display: block;
  padding-block: var(--s-3);
  color: var(--text-strong);
}
.nav__feature + .nav__feature { border-top: 1px solid var(--c-hairline); }
.nav__feature:last-child { padding-bottom: 0; }

.nav__feature-t {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-snug);
  margin-bottom: var(--s-1);
  transition: color var(--t-fast) var(--ease-out);
}
.nav__feature:hover .nav__feature-t { color: var(--c-brand-press); }

.nav__badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  height: var(--s-5);
  padding-inline: var(--s-2);
  border-radius: var(--r-pill);
  background: var(--c-brand-tint);
  color: var(--c-brand-press);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-normal);
}

/* Panel footer row — the menu's column gap already spaces it, so no margin.
   These sit at the bottom of a card a thumb has to reach across on a 1194px
   tablet, so they are held to the same --nav-tap as every other control here.
   The row's own padding drops to s-2 to pay for the taller box: hairline to
   label stays the ~32px it was, the hit area is 44px instead of 24px. */
.nav__panelfoot {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  padding-top: var(--s-2);
  border-top: 1px solid var(--c-hairline-soft);
}
.nav__panelfoot a { min-height: var(--nav-tap); }

/* ---------------- Right-hand actions ---------------- */

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  flex: 0 1 auto;
  min-width: 0;
  margin-left: auto;
}

.arrow-link.nav__signin {
  min-height: var(--nav-tap);
  color: var(--nav-ink);
  white-space: nowrap;
  transition: gap var(--t-fast) var(--ease-out), color var(--t-base) var(--ease-out);
}
.arrow-link.nav__signin:hover { color: var(--nav-ink); opacity: .74; }

.btn.nav__cta {
  --btn-bg: var(--nav-fill);
  --btn-fg: var(--c-white);
  height: var(--nav-tap);
  padding-inline: var(--s-5);
  box-shadow: inset 0 0 0 1px var(--nav-edge);
  transition: background-color var(--t-base) var(--ease-out),
              color var(--t-base) var(--ease-out),
              box-shadow var(--t-base) var(--ease-out),
              transform var(--t-fast) var(--ease-out);
}
.btn.nav__cta:hover {
  background: var(--nav-fill-hi);
  color: var(--c-white);
  box-shadow: inset 0 0 0 1px var(--nav-edge-hi);
  transform: translateY(-1px);
}
.nav.is-scrolled .btn.nav__cta,
.nav.has-menu-open .btn.nav__cta,
.nav.is-open .btn.nav__cta {
  --btn-bg: var(--c-brand);
  --btn-fg: var(--c-white);
  box-shadow: inset 0 0 0 1px transparent;
}
.nav.is-scrolled .btn.nav__cta:hover,
.nav.has-menu-open .btn.nav__cta:hover,
.nav.is-open .btn.nav__cta:hover {
  background: var(--c-brand-hover);
  box-shadow: var(--sh-brand);
}

/* ---------------- Hamburger ---------------- */

.nav__burger {
  display: none;
  place-items: center;
  width: var(--s-9);
  height: var(--s-9);
  margin-right: calc(var(--s-3) * -1);
  margin-left: auto;
  border-radius: var(--r-md);
  color: var(--nav-ink);
  transition: color var(--t-base) var(--ease-out), background-color var(--t-fast) var(--ease-out);
}
.nav__burger:hover { background: var(--nav-hit); }

.nav__burger-bars,
.nav__burger-bars::before,
.nav__burger-bars::after {
  display: block;
  width: var(--s-5);
  height: calc(var(--s-1) / 2);
  border-radius: var(--r-pill);
  background: currentColor;
}
.nav__burger-bars {
  position: relative;
  background: transparent;
}
.nav__burger-bars::before,
.nav__burger-bars::after {
  content: "";
  position: absolute;
  left: 0;
  transition: transform var(--t-base) var(--ease-expo);
}
.nav__burger-bars::before { transform: translateY(calc(var(--s-1) * -1)); }
.nav__burger-bars::after  { transform: translateY(var(--s-1)); }

.nav.is-open .nav__burger-bars::before { transform: rotate(45deg); }
.nav.is-open .nav__burger-bars::after  { transform: rotate(-45deg); }

/* ---------------- Mobile drawer ---------------- */

.nav__drawer {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  height: calc(100vh - var(--nav-h));
  height: calc(100dvh - var(--nav-h));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(calc(var(--s-2) * -1));
  transition: opacity var(--t-base) var(--ease-out),
              transform var(--t-base) var(--ease-out),
              visibility 0s linear var(--t-base);
}
.nav.is-open .nav__drawer {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition: opacity var(--t-fast) var(--ease-out),
              transform var(--t-slow) var(--ease-expo),
              visibility 0s linear 0s;
}

.nav__drawer-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--s-6) var(--gutter) var(--s-8);
}

.nav__group + .nav__group {
  margin-top: var(--s-6);
  padding-top: var(--s-6);
  border-top: 1px solid var(--c-hairline-soft);
}

.nav__group-t {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: var(--tracking-normal);
  color: var(--text-body);
  line-height: var(--lh-normal);
  margin-bottom: var(--s-2);
}

.nav__glist { display: flex; flex-direction: column; }

.nav__glist a,
.nav__group-link {
  display: flex;
  align-items: center;
  min-height: var(--nav-tap);
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-snug);
  color: var(--text-strong);
  transition: color var(--t-fast) var(--ease-out);
}
.nav__glist a:hover,
.nav__group-link:hover { color: var(--c-brand-press); }

.nav__group-link { font-weight: var(--fw-semi); }

.nav__drawer-foot {
  flex: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-3);
  padding: var(--s-4) var(--gutter);
  padding-bottom: max(var(--s-4), env(safe-area-inset-bottom));
  border-top: 1px solid var(--c-hairline);
  background: var(--surface);
}
.btn.nav__drawer-btn { width: 100%; height: var(--s-9); }

/* ---------------- Breakpoints ----------------
   Set in em, not px: the bar's content is measured in rem, so a px
   breakpoint can never hold once the root font size changes. Media-query em
   resolves against the browser's default font size, so a reader running 200%
   text gets the drawer at every realistic viewport instead of a collision.

   71.25em (1140px at default) is where the six-item list, the wordmark and
   the actions clear each other with 74px to spare — measured in the browser at
   exactly 1140px: last link ends 808, actions start 882. Measured, not guessed:
   at 67.5em the same row needs exactly the full 1000px content box. Sign in
   is not dropped to buy that room — it only exists here and in the drawer
   foot, so hiding it between the two breakpoints would strand it.

   The value is mirrored in --nav-bp above; the inline script reads it from
   there rather than repeating a threshold of its own. ---------------------- */

@media (max-width: 71.24em) {
  .nav { --nav-h: var(--s-10); }
  .nav__primary,
  .nav__actions { display: none; }
  .nav__burger { display: grid; }
  .nav__scrim { display: none; }
  .nav__wordmark { height: var(--s-5); }
}

@media (min-width: 71.25em) {
  .nav__drawer { display: none; }
}

@media (max-width: 25em) {
  .nav__drawer-foot { grid-template-columns: 1fr; }
}

/* A media query adds no specificity, so `.nav__panel { transition: none }` here
   would lose to `.nav__item.is-active .nav__panel` (0,3,0) and the open panel
   would keep animating. Each selector below is matched to or above the rule it
   has to beat, and delay is zeroed as well as duration — the panel's dismiss is
   a visibility *delay*, not a duration. */
@media (prefers-reduced-motion: reduce) {
  .nav .nav__panel,
  .nav .nav__item.is-active .nav__panel,
  .nav .nav__drawer,
  .nav.is-open .nav__drawer,
  .nav .nav__scrim,
  .nav.has-menu-open .nav__scrim,
  .nav .nav__chev,
  .nav .nav__burger-bars::before,
  .nav .nav__burger-bars::after {
    transition-duration: 0s;
    transition-delay: 0s;
  }
  .nav .nav__link:hover .nav__ico,
  .nav .btn.nav__cta:hover { transform: none; }
}
