/* ══════════════════════════════════════════════════════════════════════
   NAV FLOAT — the bar has two homes: the top edge, and parked at the
   bottom as a pill. It travels between them as the first screen scrolls
   away, and settles onto the floor as the page runs out.

   Ported from thatwednesday-website (assets/expressive.css §5,
   assets/navstate.css). The travel itself is driven by nav-float.js,
   which writes --p (top → pill) and --dock (pill → floor) onto the bar
   every frame; everything here reads those two numbers.
   ────────────────────────────────────────────────────────────────────── */

body.xp-nav-float header.nav {
  position: fixed; left: 50%; transform: translateX(-50%);
  top: 0; width: 100%; border-radius: 0;
  background: rgba(251,250,247,0.90);
  /* no will-change: the bar is pinned at the top now and none of these
     properties animate, so the hint only kept a layer alive for nothing */
}

/* in flight, and parked: the bar earns its edges once it leaves the top */
body.xp-nav-float header.nav.floating {
  border: 1px solid rgba(16,64,59,0.12);
  background: rgba(251,250,247,0.95);
  box-shadow: 0 2px 8px rgba(16,64,59,0.08), 0 20px 48px rgba(16,64,59,0.18);
}

/* the amber tab grows as the bar travels */
body.xp-nav-float header.nav::after {
  content: ""; position: absolute; left: 50%; bottom: -5px;
  transform: translateX(-50%);
  width: calc(10px + var(--p, 0) * 46px); height: 5px;
  border-radius: 0 0 6px 6px;
  background: var(--midday);
  opacity: calc(0.15 + var(--p, 0) * 0.85);
  pointer-events: none;
}

/* nothing in the bar may wrap as it narrows into the pill */
body.xp-nav-float header.nav .nav-inner { flex-wrap: nowrap; }
body.xp-nav-float header.nav .brand,
body.xp-nav-float header.nav .menu > a,
body.xp-nav-float header.nav .nav-inner > .btn { white-space: nowrap; flex: none; }
body.xp-nav-float header.nav .menu { gap: calc(34px - var(--p, 0) * 14px); }
body.xp-nav-float header.nav .nav-inner > .btn { padding-inline: calc(22px - var(--p, 0) * 5px); }
body.xp-nav-float header.nav .byline { overflow: hidden; white-space: nowrap; display: inline-block; }

/* the wordmark is the first thing to go as the bar narrows — the mark and
   the byline carry the brand in the pill */
body.xp-nav-float header.nav .brand .wordmark {
  max-width: calc(200px - var(--p, 0) * 200px);
  overflow: hidden; white-space: nowrap; display: inline-block;
  opacity: calc(1 - var(--p, 0) * 1.6);
  transition: none;
}

.menu a { transition: color 180ms cubic-bezier(.2,0,0,1), transform 320ms cubic-bezier(.34,1.4,.64,1); }
.menu > a:hover { transform: translateY(-2px); }
.menu a[aria-current="true"] { color: var(--ink); box-shadow: inset 0 -3px 0 0 var(--midday); }

/* ── docked: the last stretch of the page settles the pill onto the floor */
body.xp-nav-float header.nav.docked {
  border-left: 0; border-right: 0; border-bottom: 0;
  border-top: 1px solid rgba(16,64,59,0.12);
  background: rgba(251,250,247,0.97);
  box-shadow: 0 -2px 8px rgba(16,64,59,0.06), 0 -18px 44px rgba(16,64,59,0.14);
}
/* the amber tab moves to the top edge so it stays on screen */
body.xp-nav-float header.nav.docked::after {
  bottom: auto; top: -5px; border-radius: 6px 6px 0 0;
}

/* ── the scroll progress hairline */
.xp-progress {
  position: fixed; left: 0; top: 0; height: 3px; width: 0; z-index: 200;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(90deg, var(--midday), var(--signal));
}

/* ── NAV STATE — the bar is only a target when it is parked.
   While it is travelling, or left resting in mid-air by a scroll that
   stopped early, it is not something you can aim at: the menu blurs and
   the bar goes inert until it lands. */
.xp-label { display: inline-flex; align-items: center; gap: 8px; }

header.nav .menu,
header.nav .xp-label {
  transition: filter 220ms cubic-bezier(.05,.7,.1,1),
              opacity 220ms cubic-bezier(.05,.7,.1,1);
}
body.nav-flight header.nav .menu,
body.nav-flight header.nav .xp-label {
  filter: blur(3px); opacity: 0.55;
  transition: filter 140ms cubic-bezier(.05,.7,.1,1),
              opacity 140ms cubic-bezier(.05,.7,.1,1);
}
/* the bar itself keeps its pointer events so it still shields the content
   sliding underneath it — otherwise a click meant for the nav lands on the
   page behind it */
body.nav-flight header.nav * { pointer-events: none !important; }
body.nav-flight header.nav { pointer-events: auto; cursor: progress; }

/* ── narrow screens keep the plain sticky bar */
@media (max-width: 900px) {
  body.xp-nav-float header.nav {
    position: sticky; width: 100% !important; top: 0 !important;
    border-radius: 0 !important; left: auto; transform: none;
    border: 0; border-bottom: 1px solid rgba(16,64,59,0.10);
    box-shadow: none;
  }
  body.xp-nav-float header.nav::after { display: none; }
  body.xp-nav-float header.nav .brand .wordmark { max-width: none; opacity: 1; }
  body { padding-top: 0 !important; padding-bottom: 0 !important; }
  /* the pill's no-wrap rules would stop the bar fitting a phone: put the
     shrinking back */
  body.xp-nav-float header.nav .nav-inner { flex-wrap: nowrap; }
  body.xp-nav-float header.nav .brand,
  body.xp-nav-float header.nav .nav-inner > .btn { flex: 0 1 auto; min-width: 0; }
  /* The gap above is set on a selector four classes deep and outside any
     query, so it reached the dropdown too and stood the rows 34px apart.
     Cancelled here rather than out-specified in nav-menu.css, which has
     no business knowing this file's selectors. */
  body.xp-nav-float header.nav .menu { gap: 0; }
  body.xp-nav-float header.nav .nav-inner > .btn { padding-inline: 22px; }
  /* nowrap, not normal. Allowed to wrap, "that wednesday" broke to two
     lines inside a bar one line tall, and the second line was clipped
     mid-word. It stays on one line; the block below makes the room. */
  body.xp-nav-float header.nav .brand .wordmark { white-space: nowrap; }
}

/* ── phones: the bar has to stay one line ─────────────────────────────
   At 375px the brand and the CTA were fighting over the same 40px and
   "by CSV" ended up underneath the button. The byline goes, the wordmark
   comes down a step and the CTA tightens — the same three moves the
   EcoKo microsite's nav already makes at this width. */
@media (max-width: 620px) {
  body.xp-nav-float header.nav .nav-inner { height: 62px; gap: 12px; }
  body.xp-nav-float header.nav .brand { gap: 9px; }
  body.xp-nav-float header.nav .brand .byline { display: none; }
  body.xp-nav-float header.nav .brand .wordmark { font-size: 19px; }
}

/* ── and on a phone the mark carries it alone ─────────────────────────
   The three-line button takes 42px that this bar did not have to find
   before, and at 375px "that wednesday" was clipped again — 108px of
   type in 96px of room. The twi mark is itself a wordmark, so dropping
   the spelt-out name costs nothing and the bar stops fighting itself. */
@media (max-width: 520px) {
  body.xp-nav-float header.nav .brand .wordmark { display: none; }
  body.xp-nav-float header.nav .nav-inner > .btn {
    padding: 10px 15px; font-size: 13.5px; white-space: nowrap;
  }
  body.xp-nav-float header.nav .nav-inner > .btn svg { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  body.xp-nav-float header.nav { will-change: auto; }
  body.nav-flight header.nav .menu,
  body.nav-flight header.nav .xp-label { filter: none; opacity: 1; }
}

/* ══════════════════════════════════════════════════════════════════════
   MEGA MENU — the two-column panel under Services.

   From thatwednesday-website (assets/site.css "NAV MEGA MENU", plus the
   float/dock behaviour in assets/expressive.css). On that site it hangs
   off Products; this repo has no products.html, so it hangs off Services
   and every row points into #services.
   ────────────────────────────────────────────────────────────────────── */

.menu .m-item { position: relative; display: flex; align-items: center; height: 78px; }
.menu .m-item > a { display: inline-flex; align-items: center; gap: 6px; }
.menu .m-item > a .cv2 { transition: transform 0.18s ease; transform-box: fill-box; transform-origin: center; }
.menu .m-item:hover > a { color: var(--ink); }
.menu .m-item:hover > a .cv2 { transform: rotate(180deg); }

.mega {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  display: none; z-index: 60; width: 660px;
  background: #FFFFFF; border: 1px solid rgba(16,64,59,0.12);
  border-radius: 20px; box-shadow: 0 26px 60px rgba(14,42,36,0.18);
  padding: 26px; grid-template-columns: 1fr 1fr; gap: 28px;
  transition: opacity 340ms cubic-bezier(.2,0,0,1),
              transform 340ms cubic-bezier(.34,1.4,.64,1);
}
.menu .m-item:hover .mega, .menu .m-item:focus-within .mega { display: grid; }
@media (max-width: 1080px) { .mega { width: min(660px, calc(100vw - 48px)); } }

/* Three columns for the three phases. The services used to be one flat
   list with the phase repeated on every row as a tag; heading each column
   with the phase says the same thing once and lets the specifics hang
   under it. Wider than the two-column panel because it carries a third. */
.mega.mega-3 { width: 880px; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 22px 26px; }
/* The panel is centred on its menu item, not on the screen, so a width
   that merely fits the viewport still hangs off the right of it: at 940px
   the three-column panel ran 18px past the edge. It folds to two columns
   at the width the two-column panel is already known to clear. */
@media (max-width: 1200px) {
  .mega.mega-3 {
    width: min(660px, calc(100vw - 48px));
    grid-template-columns: repeat(2, minmax(0,1fr));
  }
}
.mega .mega-foot {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px 26px;
  border-top: 1px solid rgba(16,64,59,0.1); padding-top: 13px; margin-top: 2px;
}
.mega .mega-foot .mfoot { margin-top: 0; padding-top: 0; }

.mega-col { min-width: 0; display: flex; flex-direction: column; }
.mega .mh { display: block; font-size: 17px; font-weight: 500; letter-spacing: -0.03em; color: var(--ink); }
.mega .mh:hover { text-decoration: underline; text-underline-offset: 3px; }
.mega .msub { font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--text-muted); margin: 5px 0 12px; }
.mega .mrule { height: 1px; background: rgba(16,64,59,0.1); margin-bottom: 10px; }
.mega .mlist { display: flex; flex-direction: column; gap: 2px; }
.mega .mlist a {
  display: block; padding: 7px 10px; border-radius: 10px; font-size: 15px;
  color: var(--ink); letter-spacing: -0.015em; line-height: 1.25;
}
.mega .mlist a:hover { background: #ECF3E1; }
.mega .mlist a em {
  display: block; font-style: normal; font-size: 12.5px; font-weight: 400;
  line-height: 1.35; color: var(--text-secondary); margin-top: 1px;
}
.mega .mlist a.soon { color: var(--text-muted); cursor: default; }
.mega .mlist a.soon:hover { background: transparent; color: var(--text-muted); }
.mega .mfoot {
  margin-top: auto; padding-top: 14px; display: inline-flex; align-items: center; gap: 7px;
  font-size: 13.5px; font-weight: 500; color: var(--ink);
  transition: gap 180ms cubic-bezier(.2,0,0,1);
}
.mega .mfoot svg { width: 14px; height: 14px; }
.mega .mfoot:hover { gap: 10px; }

/* Never taller than the space it opens into, in either direction. */
body.xp-nav-float header.nav .mega {
  max-height: calc(100vh - var(--navh, 79px) - 28px);
  overflow-y: auto; overscroll-behavior: contain;
}
/* Once the bar has left the top it opens upward, not down. The source
   flips this only on .docked, which is right for its own last-150px
   dock but leaves the panel hanging off the bottom of the screen for
   the whole stretch where the bar is parked as a pill — which is most
   of the page. .floating covers both: it is set from the moment the bar
   starts travelling, and docking implies it. */
body.xp-nav-float header.nav.floating .mega { top: auto; bottom: 100%; margin-bottom: 10px; }
/* That 10px is dead space: moving the pointer from the link up to the menu
   crossed it, hover dropped, and the menu closed before you arrived. This
   bridges the gap so the pointer never leaves the item. */
body.xp-nav-float header.nav.floating .mega::before {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 12px;
}
/* nothing opens while the bar is in flight */
body.nav-flight header.nav .mega { display: none !important; }

/* A coarse pointer has no hover at all, so the first tap opens the panel
   and the second follows the link — nav-float.js sets the class. */
.menu .m-item.open .mega { display: grid; }
.menu .m-item.open > a .cv2 { transform: rotate(180deg); }

@media (max-width: 900px) { .menu .m-item { height: auto; } }
