/* ============================================================
   NAV MUSIC · the phone's music controls, and the menu's scrim
   Paired with nav-music.js. Loaded LAST on every page, after nav-dock.css,
   because the nav's own styles exist in two copies — styles.css for the case
   studies and an inline block in index.html — and this has to win against both
   without needing to be written twice.
   ============================================================ */

:root {
  /* Same stroke as the hero's rules and the status cluster's border, so the
     hamburger's new frame reads as part of that same family of lines. */
  --nav-stroke: var(--lines, #A2A2A2);

  /* The glass the nav and the music block are cut from. The second value is
     what a hover lifts it to. */
  --nav-glass: rgba(255, 247, 226, 0.10);
  --nav-glass-hover: rgba(255, 247, 226, 0.22);
}

/* ── The scrim ─────────────────────────────────────────────
   Sits between the page and the nav: 498 is under the menu (499) and the nav
   (500), over the scroll line (400) and everything in the page.

   Driven entirely by :has() off the menu's existing data-open attribute, so it
   needs no hook in the two duplicated open/close handlers. The site already
   relies on :has() elsewhere (styles.css uses it for image blocks).

   Blurring a fixed overlay cannot blur what is painted above it, which is the
   whole point — the nav and menu stay sharp while the page behind goes soft. */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 498;
  opacity: 0;
  pointer-events: none;
  background: rgba(16, 14, 10, 0.35);
  backdrop-filter: blur(18px) saturate(0.9);
  -webkit-backdrop-filter: blur(18px) saturate(0.9);
  transition: opacity 0.4s ease;
}

html:has(.site-nav-menu[data-open="true"]) .nav-scrim {
  opacity: 1;
  /* Catches every tap that is not on the nav or the menu. The existing
     outside-click handler then closes the menu, so the scrim doubles as the
     dismiss target without needing its own listener. */
  pointer-events: auto;
}

/* Nothing behind the scrim should be reachable while it is up — not by tap, and
   not by tab. The nav and the menu are excluded, so they stay usable. */
html:has(.site-nav-menu[data-open="true"]) body > *:not(.site-nav):not(.site-nav-menu):not(.nav-scrim):not(.cursor):not(.loader) {
  pointer-events: none;
}

/* ── The nav bar's smoke button ────────────────────────────
   Desktop keeps the floating cluster, so this is phone-only. */
.nav-music-icon {
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--extra-yellow, #FFF0B2);
  transition: color 0.45s ease, opacity 0.25s ease, transform 0.3s ease;
}

.nav-music-icon svg {
  display: block;
  width: 27px;
  height: 27px;
  overflow: visible;   /* the wisps swing past their box */
}

.nav-music-icon:active { transform: scale(0.94); }

.nav-music-icon:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 4px;
  border-radius: 4px;
}

/* ── The hamburger, now framed ─────────────────────────────
   It carried no weight against the logo before. A stroked box at 8px radius
   gives it presence and matches the hero's lines.
   Written with the same !important the mobile nav block in styles.css and
   index.html both use for this element — the two copies would otherwise win. */
@media (max-width: 900px) {
  .site-nav-hamburger {
    width: 46px !important;
    height: 46px !important;
    border: 1px solid var(--nav-stroke) !important;
    border-radius: 8px !important;
    background: transparent;
    transition: border-color 0.45s ease, background 0.35s ease, opacity 0.25s ease;
  }

  .site-nav-hamburger:active { background: var(--nav-glass); }
}

/* ── Phone layout: logo · smoke · hamburger ────────────────
   The nav is flex with space-between at this size, which distributes the three
   children but does NOT centre the middle one — that only lands centrally when
   the outer two happen to be the same width, and the logo and the framed
   hamburger are not. Measured 20px off on a 375px viewport.

   So the icon is taken out of the flow and pinned to the nav's centre instead.
   It is exact at any width, and independent of what the logo or hamburger do. */
@media (max-width: 640px) {
  .nav-music-icon {
    display: flex;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  /* Undo the nudge the shared :active rule would otherwise apply on top of the
     centring transform, which would fling it off-centre on tap. */
  .nav-music-icon:active { transform: translate(-50%, -50%) scale(0.94); }

  .site-nav-logo { order: 1; }
  .site-nav-hamburger { order: 3; }

  /* Room for the menu's music block above the nav, and even padding.
     The panel was 12px 20px, so its bottom gap read as half its side gaps and
     the music block sat noticeably tight against the edge. One value, so the
     content is inset the same amount on all four sides. */
  .site-nav-menu {
    bottom: 92px;
    padding: 20px !important;
  }
}

/* ── Menu and nav, same width ──────────────────────────────
   The menu is inset 14px, matching the nav in its contracted pill state. But at
   the very top of the page the nav is DOCKED — full bleed, inset 0 — so opening
   the menu there put a 347px panel above a 375px bar, misaligned at both ends.

   So while the menu is open the nav holds its contracted shape, and the two line
   up whatever the scroll position. The menu itself never resizes.

   The docked rules are in nav-dock.css and win on specificity, so these are
   written against .is-docked directly to outrank them. */
@media (max-width: 640px) {
  html:has(.site-nav-menu[data-open="true"]) .site-nav.is-docked {
    left: 14px;
    right: 14px;
    bottom: 14px;
    border-radius: 6px;
    padding-top: 10px !important;
    padding-bottom: 10px !important;
  }

  /* Docking fades the side and bottom strokes out; bring them back so the
     contracted shape is fully drawn rather than a lidded box. */
  html:has(.site-nav-menu[data-open="true"]) .site-nav.is-docked,
  html:has(.site-nav-menu[data-open="true"]) .site-nav.on-light.is-docked {
    border-left-color: var(--nav-stroke);
    border-right-color: var(--nav-stroke);
    border-bottom-color: var(--nav-stroke);
  }
}

/* ── The block at the foot of the menu ─────────────────────
   Name and label on the left as one large play/pause target, a hairline, then
   the two arrows. Mirrors the desktop cluster's anatomy at menu width. */
.nav-music {
  display: none;
  margin-top: 12px;
  align-items: stretch;
  background: var(--nav-glass);
  border: 1px solid var(--nav-stroke);
  border-radius: 8px;
  overflow: hidden;    /* keeps the divider inside the rounded corners */
  transition: background 0.35s ease, border-color 0.45s ease, color 0.45s ease;

  /* Stated, never inherited. The menu itself sets no colour, so inheriting
     reached <body> — which is cream on the homepage but #202a22 on the case
     studies, where styles.css sets `color: var(--ink)`. That is a dark green, so
     the track name and the Now playing / Click to play label came out almost
     invisible against the dark panel on every project page.
     .site-nav-menu a has always stated its colour for exactly this reason. */
  color: #FFF7E2;
}

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

/* Hover and press lift the glass rather than changing its colour — the same
   move the buttons on the music gate make. */
@media (hover: hover) and (pointer: fine) {
  .nav-music:hover { background: var(--nav-glass-hover); }
}

.nav-music:active,
.nav-music.is-playing { background: var(--nav-glass-hover); }

.nav-music-toggle {
  flex: 1 1 auto;
  min-width: 0;        /* lets the name box shrink instead of forcing overflow */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 12px 16px;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
}

.nav-music-toggle:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: -3px;
  border-radius: 6px;
}

.nav-music-label {
  font-family: 'Satoshi', -apple-system, system-ui, sans-serif;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  opacity: 0.75;
  white-space: nowrap;
}

/* Fixed width, for the same reason as the desktop cluster: eight names of
   different lengths would otherwise resize the block on every skip. */
.nav-music-name {
  width: 100%;
  max-width: 190px;
  font-family: 'Satoshi', -apple-system, system-ui, sans-serif;
  font-size: 17px;
  font-weight: 500;
  line-height: 1.15;
  overflow: hidden;
  display: flex;
  justify-content: center;
}

.nav-music-divider {
  flex: 0 0 1px;
  width: 1px;
  align-self: stretch;
  background: var(--nav-stroke);
}

.nav-music-controls {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 20px;
}

.nav-music-arrow {
  background: none;
  border: none;
  padding: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--extra-yellow, #FFF0B2);
  cursor: pointer;
  transition: color 0.45s ease, opacity 0.25s ease, transform 0.25s ease;
}

.nav-music-arrow svg { display: block; width: 23px; height: 24px; }

/* The supplied arrow points left; the next button is the same path mirrored. */
.nav-music-next svg { transform: scaleX(-1); }

.nav-music-arrow:active { opacity: 0.6; }
.nav-music-prev:active { transform: translateX(-2px); }
.nav-music-next:active { transform: translateX(2px); }

.nav-music-arrow:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── Section-aware inversion ───────────────────────────────
   The nav already flips over cream sections via .on-light, applied by the
   scroll probe. These are new children of it, so they have to follow — the ink
   colour is the same one .site-nav.on-light uses for its own text. */
.site-nav.on-light .nav-music-icon { color: var(--dark-green, #3f5341); }

.site-nav-menu.on-light .nav-music {
  background: rgba(26, 23, 18, 0.05);
  border-color: rgba(26, 23, 18, 0.25);
}

.site-nav-menu.on-light .nav-music:active,
.site-nav-menu.on-light .nav-music.is-playing { background: rgba(26, 23, 18, 0.10); }

@media (hover: hover) and (pointer: fine) {
  .site-nav-menu.on-light .nav-music:hover { background: rgba(26, 23, 18, 0.10); }
}

.site-nav-menu.on-light .nav-music-toggle { color: #1a1712; }
.site-nav-menu.on-light .nav-music-divider { background: rgba(26, 23, 18, 0.25); }
.site-nav-menu.on-light .nav-music-arrow { color: var(--dark-green, #3f5341); }

/* Over a cream section the scrim should darken far less, or the page beneath
   turns to mud. */
.site-nav-menu.on-light ~ .nav-scrim,
html:has(.site-nav-menu.on-light[data-open="true"]) .nav-scrim {
  background: rgba(242, 236, 223, 0.30);
}

/* ── Marquee edges ─────────────────────────────────────────
   A scrolling name that simply stops at the box edge reads as broken text. The
   mask fades both ends so it emerges and disappears instead.

   Applied to BOTH the cluster and the menu block, and wider than the cluster's
   original 10px — at that width the fade was too abrupt to register as one. */
.sb-name.is-scrolling,
.nav-music-name.is-scrolling {
  mask-image: linear-gradient(90deg,
    transparent 0,
    #000 22px,
    #000 calc(100% - 22px),
    transparent 100%);
  -webkit-mask-image: linear-gradient(90deg,
    transparent 0,
    #000 22px,
    #000 calc(100% - 22px),
    transparent 100%);
}

/* Pause on hover so a long name can actually be read. */
.nav-music-name.is-scrolling .sb-name-scroll { animation-play-state: running; }

@media (hover: hover) and (pointer: fine) {
  .nav-music:hover .nav-music-name.is-scrolling .sb-name-scroll { animation-play-state: paused; }
}

/* The gate covers the whole screen; the nav underneath must not be reachable. */
html.mg-active .nav-scrim { opacity: 0; pointer-events: none; }
