/* =============================================================================
   ReLeaf: site navigation
   -----------------------------------------------------------------------------
   A floating card under the bar, redrawn on 9 October 2026 from a mock the
   team drew:

   · The open tab turns into a pale green pill; the card drops just under the
     bar, lined up with the logo on the left and the last tab on the right.
   · One row of pages, split by hairlines. Each page is a large leaf-green
     circle with its icon and the title under it. No captions: the titles carry
     the panel on their own.
   · Solid glyphs (Material Design Icons) instead of the old line art.
   · The page behind still softens while a card is open.
   · The three special-prize pages (Measurement, Hardware, Integrated Human
     Practices) carry a faint wash of colour in their circle. It is meant to be
     noticed on a second look, not announced.
   · The phone drawer keeps the old list rows, without captions.
   ========================================================================== */

/* Colours that exist in tokens.css point at the token. The hardware pages load
   this file without tokens.css, so each carries the token's own value as the
   fallback. */
:root {
  --nv-h:       68px;
  --nv-max:     1280px;
  --nv-900:     #14402b;
  --nv-700:     #23684a;
  --nv-500:     #4f9c6f;
  --nv-200:     #cfe4d8;
  --nv-100:     var(--leaf-100, #e3f0e8);
  --nv-50:      #f4f9f6;
  --nv-ink:     #171717;
  --nv-muted:   var(--gray-450, #6e6e6e);   /* was #6b7280; gray-500 would be 4.45:1 on --nv-50 */
  --nv-line:    #e5e5e5;
  /* one frosting recipe for the bar, the panel and the drawer */
  --nv-frost:   saturate(180%) blur(20px);
}

.sitenav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               Helvetica, Arial, sans-serif;
}

/* ---- bar ----------------------------------------------------------------- */

/* Translucent enough that the page moving under it reads through the frost,
   opaque enough to carry the labels. It firms up while a panel is open, so the
   bar and the panel are one surface. */
.sitenav__bar {
  background: rgb(251 252 251 / .8);
  -webkit-backdrop-filter: var(--nv-frost); backdrop-filter: var(--nv-frost);
  border-bottom: 1px solid var(--nv-line);
  transition: background .25s, border-color .25s;
}
.sitenav.has-panel .sitenav__bar {
  background: rgb(251 252 251 / .94);
}

.sitenav__inner {
  max-width: var(--nv-max);
  margin: 0 auto;
  padding: 0 1.25rem;
  height: var(--nv-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
}
@media (min-width: 640px) { .sitenav__inner { padding: 0 2rem; } }

.sitenav__brand {
  display: flex; align-items: center; gap: .6rem;
  text-decoration: none; color: var(--nv-ink);
  flex: none;
}
.sitenav__logo {
  width: 50px; height: 50px;
  border-radius: 50%;
  display: block;
  box-shadow: 0 0 0 1px rgb(23 23 23 / .08);
}
.sitenav__word {
  font-size: 1.4rem; font-weight: 700; letter-spacing: -.015em;
}

/* ---- tabs ---------------------------------------------------------------- */

.sitenav__tabs { display: none; align-items: stretch; height: var(--nv-h); }
@media (min-width: 940px) { .sitenav__tabs { display: flex; } }

.sitenav__tab {
  position: relative;
  display: flex; align-items: center; gap: .4rem;
  height: 42px;
  margin: auto .1rem;
  padding: 0 1.05rem;
  border-radius: 12px;
  font: inherit;
  font-size: 1.075rem; font-weight: 600;
  color: var(--gray-700, #404040);
  background: none; border: 0;
  cursor: pointer;
  transition: color .25s, background .25s;
}
.sitenav__tab:hover { color: var(--nv-900); background: var(--nv-50); }
.sitenav__tab.is-open { color: var(--nv-900); background: var(--nv-100); }

/* the tab you are currently inside keeps its green, without the pill */
.sitenav__tab.is-section { color: var(--nv-700); }

/* chevron drawn in CSS, no icon font */
.sitenav__chev {
  width: 7px; height: 7px;
  border-right: 1.8px solid currentColor;
  border-bottom: 1.8px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  opacity: .55;
  transition: transform .3s, opacity .25s;
}
.sitenav__tab.is-open .sitenav__chev,
.sitenav__grouptop[aria-expanded="true"] .sitenav__chev {
  transform: translateY(1px) rotate(-135deg);
  opacity: 1;
}

/* ---- panel --------------------------------------------------------------- */

.sitenav__panels { position: relative; }

/* A white card that floats a little under the bar, as wide as the bar's
   content: its left edge sits under the logo, its right under the last tab. */
.sitenav__panel {
  position: absolute; top: 12px; left: 0; right: 0;
  width: min(calc(var(--nv-max) - 4rem), calc(100% - 2.5rem));
  margin-inline: auto;
  display: none;
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 0 0 1px rgb(20 64 43 / .06), 0 18px 48px -12px rgb(20 40 30 / .28);
}
@media (min-width: 640px) { .sitenav__panel { width: min(calc(var(--nv-max) - 4rem), calc(100% - 4rem)); } }
.sitenav__panel.is-open { display: block; animation: nv-drop .26s cubic-bezier(.2, .7, .3, 1); }
@keyframes nv-drop {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* 9 Oct (owner): the card sits a little smaller */
.sitenav__panelinner { padding: 1.5rem 1rem; }

/* ---- the light ------------------------------------------------------------
   10 Oct: a soft light follows the pointer across the card (nav.js sets --mx,
   --my and --lit on the panel). It is wide and faint, ambient rather than a
   beam, and it carries a whisper of the section's banner colour (the same
   values as bannerhead.css), so each card is felt to belong to the page it
   opens. Circles and the open-tab pill stay leaf green. */
@property --lit { syntax: "<number>"; inherits: false; initial-value: 0; }
.sitenav__panel {
  --mx: 50%; --my: 0%; --lit: 0;
  --nv-glow: 133 188 189;
  background:
    radial-gradient(560px circle at var(--mx) var(--my),
      rgb(var(--nv-glow) / calc(.13 * var(--lit))), transparent 65%),
    #fff;
  transition: --lit .35s;
}
.sitenav__panel[data-tab="project"]    { --nv-glow: 246 160 177; }
.sitenav__panel[data-tab="drylab"]     { --nv-glow: 143 204 214; }
.sitenav__panel[data-tab="engagement"] { --nv-glow: 237 171 150; }
.sitenav__panel[data-tab="team"]       { --nv-glow: 149 200 139; }

/* an invisible bridge over the gap above the card, so the pointer can travel
   from the tab down into the card without the card closing */
.sitenav__panel::before {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 100%;
  height: 14px;
}

/* ---- entries ------------------------------------------------------------- */

/* One row, the pages sharing the width evenly, split by hairlines. Seven
   Engagement pages fit a laptop; a long title wraps to a second line under
   its circle. */
.sitenav__list {
  display: flex;
  align-items: stretch;
}

.sitenav__entry {
  position: relative;
  display: grid;
  grid-template-columns: 36px 1fr;
  align-items: center;
  gap: .85rem;
  padding: .7rem .75rem;
  border-radius: 12px;
  text-decoration: none;
  transition: background .22s;
  /* resting state of the rise below; handed back under reduced motion */
  opacity: 0;
  transform: translateY(6px);
}
.sitenav__panel.is-open .sitenav__entry {
  animation: nv-rise .38s cubic-bezier(.2, .7, .3, 1) forwards;
  animation-delay: calc(60ms + var(--i, 0) * 25ms);
}
@keyframes nv-rise { to { opacity: 1; transform: none; } }

.sitenav__entry::before {          /* accent grows down the left edge */
  content: "";
  position: absolute; left: 0; top: 50%; bottom: 50%;
  width: 3px; border-radius: 3px;
  background: var(--nv-500);
  transition: top .25s cubic-bezier(.2,.7,.3,1), bottom .25s cubic-bezier(.2,.7,.3,1);
}
.sitenav__entry:hover { background: var(--nv-50); }
.sitenav__entry:hover::before,
.sitenav__entry.is-current::before { top: 18%; bottom: 18%; }

.sitenav__tile {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--nv-100);
  color: var(--nv-700);
  transition: background .22s, color .22s;
}
.sitenav__tile svg {
  width: 20px; height: 20px;
  fill: currentColor;
}
.sitenav__entry:hover .sitenav__tile { background: var(--nv-700); color: #fff; }

.sitenav__entrytext { display: grid; gap: .1rem; min-width: 0; }
.sitenav__entrytitle {
  font-size: 1rem; font-weight: 600;
  color: var(--nv-ink);
  letter-spacing: -.01em; line-height: 1.25;
}

.sitenav__entry:hover .sitenav__entrytitle { color: var(--nv-900); }
.sitenav__entry.is-current { background: var(--nv-50); }
.sitenav__entry.is-current .sitenav__tile { background: var(--nv-700); color: #fff; }
.sitenav__entry.is-current .sitenav__entrytitle { color: var(--nv-900); }

/* ---- the card's entries: circle over title ---- */
.sitenav__panel .sitenav__entry {
  flex: 1 1 0;
  min-width: 0;
  grid-template-columns: none;
  justify-items: center;
  align-content: start;
  gap: .8rem;
  padding: .4rem .7rem .55rem;
  border-radius: 0;
  text-align: center;
  background: none;
}
/* the hairlines fade out at both ends instead of running edge to edge */
.sitenav__panel .sitenav__entry + .sitenav__entry::after {
  content: "";
  position: absolute; left: 0; top: 12%; bottom: 12%; width: 1px;
  background: linear-gradient(to bottom, transparent, var(--nv-line) 25%, var(--nv-line) 75%, transparent);
  opacity: calc(1 - .6 * var(--lit, 0));
}
.sitenav__panel .sitenav__entry::before { display: none; }
.sitenav__panel .sitenav__tile {
  width: 58px; height: 58px;
  border-radius: 50%;
  transition: background .22s, color .22s, transform .22s;
}
.sitenav__panel .sitenav__tile svg { width: 28px; height: 28px; }
.sitenav__panel .sitenav__entry:hover .sitenav__tile { transform: translateY(-2px); }
.sitenav__panel .sitenav__entrytitle {
  font-size: 1.1rem; font-weight: 700;
  text-wrap: balance;
}

/* ---- special-prize pages ------------------------------------------------
   `prize: true` in site-nav.js. The circle's flat green becomes a soft pastel
   wash, leaf to sky to apricot, and on hover or when current the dark green
   picks up the same turn of hue. Kept pale on purpose. */
.sitenav__entry.is-prize .sitenav__tile {
  background:
    linear-gradient(135deg, #dff0e5 0%, #dcebf6 52%, #f8e9d8 100%);
}
.sitenav__entry.is-prize:hover .sitenav__tile,
.sitenav__entry.is-prize.is-current .sitenav__tile {
  background: linear-gradient(135deg, #23684a 0%, #2a6a78 55%, #8a6a3a 100%);
}

/* Each prize icon moves a little on hover, in its own way: the gear turns a
   tooth, the gauge's needle rocks, the group leans in. Once per hover, and
   small enough to read as life rather than as a signal. */
.sitenav__entry.is-prize:hover .sitenav__tile svg { animation: .9s cubic-bezier(.3, .7, .3, 1) both; }
.sitenav__entry.is-prize:hover [data-icon="hardware"] svg    { animation-name: nv-turn; }
.sitenav__entry.is-prize:hover [data-icon="measurement"] svg { animation-name: nv-rock; }
.sitenav__entry.is-prize:hover [data-icon="ihp"] svg         { animation-name: nv-lean; }
@keyframes nv-turn { to { transform: rotate(60deg); } }
@keyframes nv-rock {
  25% { transform: rotate(-12deg); } 60% { transform: rotate(8deg); }
  85% { transform: rotate(-3deg); }  100% { transform: none; }
}
@keyframes nv-lean {
  30% { transform: translateY(-3px) scale(1.08); } 65% { transform: translateY(1px) scale(.98); }
  100% { transform: none; }
}


/* ---- the page behind ------------------------------------------------------
   While a panel is open the page under it is blurred and dimmed a little, so
   the eye has one place to be. It is decoration: it never takes a click, and
   the click that closes the panel reaches the page underneath as before. */
.sitenav__scrim {
  position: fixed; inset: var(--nv-h) 0 0 0;
  z-index: -1;                      /* under the panel, over the page */
  background: rgb(20 30 24 / .08);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  opacity: 0; visibility: hidden;
  transition: opacity .3s, visibility 0s .3s;
  pointer-events: none;
}
.sitenav.has-panel .sitenav__scrim {
  opacity: 1; visibility: visible;
  transition: opacity .3s, visibility 0s;
}

/* ---- mobile -------------------------------------------------------------- */

.sitenav__burger {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem;
  background: none; border: 0; cursor: pointer;
}
@media (min-width: 940px) { .sitenav__burger { display: none; } }
.sitenav__burger span { width: 1.45rem; height: 2px; background: var(--gray-700, #404040); transition: all .3s; }
.sitenav__burger span + span { margin-top: .34rem; }
.sitenav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(-45deg); }
.sitenav__burger[aria-expanded="true"] span:nth-child(2) { width: 0; }
.sitenav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(45deg); }

.sitenav__drawer {
  display: none;
  max-height: calc(100dvh - var(--nv-h));
  overflow-y: auto;
  background: rgb(251 252 251 / .97);
  -webkit-backdrop-filter: var(--nv-frost); backdrop-filter: var(--nv-frost);
  border-top: 1px solid var(--nv-line);
  padding: .5rem 1.5rem 2rem;
}
.sitenav.drawer-open .sitenav__drawer { display: block; }
@media (min-width: 940px) { .sitenav.drawer-open .sitenav__drawer { display: none; } }

/* the five section names are the whole of this screen, so they are set like
   headings rather than like list rows */
.sitenav__grouptop {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.05rem .1rem;
  font: inherit;
  font-size: 1.35rem; font-weight: 650; letter-spacing: -.015em;
  color: var(--nv-900);
  background: none; border: 0; border-bottom: 1px solid var(--nv-line);
  cursor: pointer;
}
.sitenav__groupbody { display: none; padding: .5rem 0 1rem; }
.sitenav__group.is-open .sitenav__groupbody { display: grid; gap: .2rem; }

/* the entries rise as the section unfolds. A closed drawer never runs the animation, so they rest visible. */
.sitenav__groupbody .sitenav__entry { opacity: 1; transform: none; }
.sitenav__group.is-open .sitenav__groupbody .sitenav__entry {
  animation: nv-rise .32s cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 25ms);
  opacity: 0; transform: translateY(6px);
}

/* ---- page offset --------------------------------------------------------- */

.sitenav-spacer { height: var(--nv-h); }

@media (prefers-reduced-motion: reduce) {
  .sitenav *, .sitenav *::before { transition: none !important; animation: none !important; }
  /* an entry rests invisible and is brought in by the animation above, so
     without the animation it has to be handed its finished state, or the
     panel opens empty */
  .sitenav__entry { opacity: 1 !important; transform: none !important; }
}

/* ---- skip link (added by nav.js) ----------------------------------------- */
.sitenav-skip {
  position: absolute; left: 8px; top: -60px; z-index: 1000;
  padding: .6rem 1rem; border-radius: 0 0 6px 6px;
  background: #14402b; color: #fff;
  font: 600 .875rem/1.2 var(--font-body, system-ui, sans-serif);
  text-decoration: none;
}
.sitenav-skip:focus { top: 0; outline: 2px solid #4f9c6f; outline-offset: 2px; }
main:focus { outline: none; }

/* =============================================================================
   Drafting marks
   -----------------------------------------------------------------------------
   Student writing is in the normal ink. Text an AI assistant drafted to fill a
   page, and that no student has rewritten yet, carries class="ai" (on a block,
   or a <span class="ai"> inside a student paragraph) and shows in orange, so
   the team can see at a glance what is theirs and what still needs a student.
   Lives in nav.css because every page loads it, the dark hardware pages too.
   Off switch: window.AI_MARK = false in assets/data/site-nav.js.

   Two inks, and which one is used follows the background, not the page. The
   hardware pages are dark only while the reader is on the machine: past the
   3D walkthrough, hardware/js/polish.js puts `doc-light` on <body> and the
   page turns to ink on paper, and the hub's notebook band (.nb-zone) is cream
   at every scroll position. The bright orange is 2.26:1 on those, so it is
   scoped away from them and the deep orange, 5.18:1 on white, is used instead.
   ========================================================================== */
:root { --ai-ink: #c2410c; }                       /* 5.18:1 on white */
body:has(.sitenav--dark):not(.doc-light) {
  --ai-ink: #fb923c;                               /* 8.95:1 on the #05060a field */
}
body:has(.sitenav--dark) .nb-zone { --ai-ink: #c2410c; }   /* 4.87:1 on the cream */
html:not(.ai-off) .ai,
html:not(.ai-off) .ai :is(p, li, dt, dd, td, th, h2, h3, h4, h5, strong, b, em, i, span, figcaption, small, blockquote, cite, label, summary, div) {
  color: var(--ai-ink);
}
html:not(.ai-off) .ai a { color: var(--ai-ink); text-decoration-color: currentColor; }
