/* ==========================================================================
   site-nav — primary navigation in the header.

   Inline links on desktop, a toggle-and-panel on mobile (below the existing
   720px breakpoint).

   The whole nav is sized to fit inside --header-content-h, the height of the
   brand line box it sits beside. That is deliberate: the header is in normal
   flow at the top of the page, so a taller header would push every section
   down. Keeping the nav within the existing content height means adding it
   moves nothing below the header.
   ========================================================================== */

/* No min-height: the nav must never be the tallest thing in the header, or
   it would set the header's height and push the whole page down. Every child
   below is sized to stay under --header-content-h. */
.site-nav {
  display: flex;
  align-items: center;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 24px);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-link {
  position: relative;
  display: inline-block;
  font-size: 14px;
  line-height: 1.4;
  letter-spacing: 0.02em;
  color: var(--stone);
  padding-bottom: 3px;
  transition: color 0.2s ease;
}
.nav-link:hover {
  color: var(--sand);
}

/* Active state.
   Colour alone is not enough, so the active link also grows a rule beneath
   it — the same underline idiom the section labels already use. The bar is
   what carries the meaning; the colour shift just reinforces it. */
.nav-link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--rust);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}
.nav-link[aria-current]::after {
  transform: scaleX(1);
}
.nav-link[aria-current] {
  color: var(--sand);
}

/* The Contact item is the existing .btn, scaled to fit the header's content
   box. Only the metrics change; the fill, colour, weight and radius are all
   inherited from .btn untouched.

   It deliberately does NOT carry .nav-link. It used to, purely so the
   scrollspy could find it, and .nav-link's stone colour then beat .btn's
   charcoal — same specificity, later in the cascade — leaving grey text on
   the rust fill. Scrollspy now selects on [data-spy] alone, so the styling
   hook and the behaviour hook no longer fight over this element. */
.btn.nav-cta {
  padding: 5px 16px;
  font-size: 13.5px;
  line-height: 1.45;
}
/* A rust bar along the bottom of a rust button would say nothing, so the CTA
   marks the current section with a ring instead — still a shape change
   rather than only a colour change. */
.btn.nav-cta[aria-current] {
  box-shadow: 0 0 0 2px var(--charcoal), 0 0 0 3px var(--gold);
}

/* Toggle — mobile only, hidden on desktop.
   Its box is capped at the header's content height so it cannot grow the
   header, but ::before extends the hit area well past that to a comfortable
   touch target without occupying any layout space. */
.nav-toggle {
  display: none;
  position: relative;
  width: var(--header-content-h);
  height: var(--header-content-h);
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--sand);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  transition: border-color 0.2s ease;
}
.nav-toggle:hover {
  border-color: var(--rust);
}
.nav-toggle::before {
  content: '';
  position: absolute;
  inset: -8px;
}
.nav-toggle-bar {
  display: block;
  width: 15px;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.25s ease, opacity 0.2s ease;
}
.site-nav.is-open .nav-toggle-bar:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}
.site-nav.is-open .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}
.site-nav.is-open .nav-toggle-bar:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

@media (max-width: 720px) {
  .nav-toggle {
    display: flex;
  }

  /* The panel drops out of the header. visibility (rather than opacity
     alone) is what keeps its links out of the tab order while closed. */
  .nav-panel {
    position: fixed;
    left: 0;
    right: 0;
    top: calc(var(--header-h) + 1px);
    z-index: 9;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
    padding: 10px 22px 22px;
    visibility: hidden;
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s;
  }
  header.scrolled .nav-panel {
    top: calc(var(--header-h-scrolled) + 1px);
  }
  .site-nav.is-open .nav-panel {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0s;
  }

  .nav-list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .nav-list li {
    border-bottom: 1px solid var(--line);
  }
  .nav-list li:last-child {
    border-bottom: none;
    margin-top: 16px;
  }
  .nav-link {
    display: block;
    font-size: 16px;
    padding: 14px 0 12px;
  }
  /* The sliding rule does not read on a stacked list, so the active item
     takes a leading bar instead — still a shape cue, not just colour. */
  .nav-link::after {
    left: -22px;
    right: auto;
    top: 0;
    bottom: 0;
    width: 3px;
    height: auto;
    transform: scaleY(0);
    transform-origin: top;
    transition: transform 0.25s ease;
  }
  .nav-link[aria-current]::after {
    transform: scaleY(1);
  }
  .btn.nav-cta {
    display: block;
    text-align: center;
    padding: 13px 20px;
    font-size: 15px;
  }
}

/* prefers-reduced-motion is handled centrally in animations.css, but the
   panel also has its own opt-out driven by lib/motion.js, which reacts to the
   preference changing mid-session rather than only at load. */
.site-nav.no-motion .nav-panel,
.site-nav.no-motion .nav-toggle-bar,
.site-nav.no-motion .nav-link::after {
  transition: none;
}
