/* nav.css — the prompt: the terminal's own line at the head of the monitor (Bill's pick, 2026-09-08). Four commands —
   a stranger reads them: home · projects · posts · contact. The prompt at the left types the path (js/nav.js); the
   current command is inverse video.
   Round 4A (Bill, 2026-09-08, N1 · N2 · N4): the row sits ABOVE the frame and the frame's top edge is the rule it sits
   on — the bar has no rule of its own and nothing on it is full-bleed; the prompt's `>` stands at the copy's left edge and
   the last command's text ends at the copy's right edge (the fixed margin — the link's padding is eaten by a negative
   margin so the TEXT aligns); the text a step larger with more padding (13 px desk / 12 phone, the bar 44 / 42); the
   reel counter that slid along the rule is gone — the SHEET cell in the frame's foot carries the count (css/shell.css).
   With the screens layer off (or script off) the bar sticks to the head of the page over the stacked sheets. */

:root{ --nav-top:44px; }
.nv{ position:sticky; top:0; z-index:3; background:rgba(221,227,232,.85); font-family:var(--mono); }
.nv .in{ position:relative; width:min(var(--grid), 100%); margin:0 auto; height:var(--nav-top); padding:0 var(--gut); display:flex; align-items:center; gap:8px; }
/* round 5A (Bill, N2): the prompt's box clips at its own line box (overflow:hidden keeps a long path from pushing the commands off
   the row), and at line-height 1 a descender hangs below it — the j in projects lost its tail. 3 px of padding above and below
   (symmetric, so the text's baseline does not move) gives every descender and ascender room at both tiers (13 px desk / 12 phone;
   Plex Mono's em box is 1.3 of the size, so the ink overhangs a 1-line box by ~2 px each way). */
.nv .pr{ font:500 13px/1 var(--mono); color:var(--ink); white-space:nowrap; margin-right:auto; letter-spacing:.04em; min-width:0; overflow:hidden; padding:3px 0; flex:1 1 auto; }   /* round 18: the prompt takes the row's free space (nothing moves — it has no ground and the commands sit at the right as before), so the path's max-width below is the ROOM, not the path's own width */
/* ROUND 18 (Bill, N2's second half): a path longer than the row — a long post's slug; a small phone — ENDS IN AN ELLIPSIS in the prompt's own face
   instead of pushing the caret off the row or clipping mid-glyph: the path's box is at most the prompt's room less the `> ` and the caret (26 px —
   15.6 + 10 on the desk, 14.4 + 10 on a phone), and --n-path-max (px; the bench) caps it lower for a look. The caret stays at the path's end. Round
   4A's smallest-phone rule (no path under 375 wide) is retired: three commands leave the room, and what does not fit ends in the dots. */
.nv .cmd{ display:inline-block; vertical-align:top; max-width:min(calc(100% - 26px), calc(var(--n-path-max, 9999) * 1px)); }
/* ROUND 19 (item 0, owed from 18): THE CLIP ONLY WHILE THE PATH OVERFLOWS. A clipped inline-block re-rasters its glyphs (round 8A's family), and round 18's
   always-on overflow:hidden moved the desk's rest states by 8–33 px inside the path's rows against main. js/nav.js sets .over on the prompt while the text is
   wider than the box (read as each character lands, after a type, on a resize) — only then the box clips, ends in the dots, and takes the 3 px padding the
   glyphs' overhang needs inside a clipped box (round 5A; the negative margin keeps the line where it is). At rest the path is round 17's plain inline-block. */
.nv .pr.over .cmd{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:3px 0; margin:-3px 0; }
.nv .caret{ display:inline-block; width:8px; height:13px; background:var(--ink); vertical-align:-1px; margin-left:2px; animation:nv-caret 1s steps(2,end) infinite; }
@keyframes nv-caret{ 50%{ opacity:0; } }
@media (prefers-reduced-motion:reduce){ body:not(.fx-motion) .nv .caret{ animation:none; } }
.nv a{ text-decoration:none; color:var(--ink-2); font:500 13px/1 var(--mono); letter-spacing:.04em; padding:7px 10px 6px; white-space:nowrap;
  /* N7 (round 4B): a rule draws under a hovered or focused command, left to right in four steps, and the text lifts to the ink */
  background:linear-gradient(var(--ink), var(--ink)) no-repeat left calc(100% - 3px) / 0 2px; transition:background-size calc(var(--n-hover, 140) * 1ms) steps(4, end), color .12s; }
.nv a:last-of-type{ margin-right:-10px; }   /* the text ends at the margin, not the padding box */
.nv a:hover, .nv a:focus-visible{ color:var(--ink); background-size:100% 2px; }
.nv a:focus-visible{ outline:1px dashed var(--ink); outline-offset:-3px; }
.nv a[aria-current]{ background:var(--ink); color:var(--paper); }
@media (prefers-reduced-motion:reduce){ body:not(.fx-motion) .nv a{ transition:none; } }
/* N3: the caret holds solid while the computer accepts the line */
.nv .caret.acc{ animation:none; opacity:1; }
/* (round 4A: contact is a page, not a jump — the .jump rules are gone with the #) */
/* the typed characters wear the type layer's own hot/cool (css/layers.css .ch.hot / .ch.cool are gated on [data-type]) */
.nv .cmd .ch.hot{ background:var(--ink); color:var(--paper); text-shadow:0 0 6px rgba(30,42,56,.95), 0 0 14px rgba(30,42,56,.6); }
.nv .cmd .ch.cool{ color:var(--ink); text-shadow:0 0 6px rgba(30,42,56,.95), 0 0 14px rgba(30,42,56,.6); }
.nv .cmd .ch{ transition:text-shadow .45s ease-out, color .45s ease-out; }

@media (max-width:720px){   /* one row at 390: the commands keep their size, the prompt gives first */
  :root{ --nav-top:42px; }
  .nv .in{ gap:2px; padding:0 calc(var(--frame-x) + var(--gut)); }   /* the phone's frame is inset; the prompt still aligns with the copy */
  .nv a{ font-size:12px; padding:7px 7px 6px; letter-spacing:.02em; color:var(--ink); }   /* full ink at 12 px on the phone (the tier's ceiling at 11 was 4.2–4.5:1) */
  .nv a:last-of-type{ margin-right:-7px; }
  .nv a[aria-current]{ color:var(--paper); }
  .nv .pr{ font-size:12px; letter-spacing:0; }   /* margin-right stays auto: the commands sit at the right margin here too (N1) */
}

/* ==== ROUND 8B (Bill, 2026-09-11, P1): THE SUBMENUS. The model is <area>/<section>/<screen> (home/story/2): the four commands
   are the AREAS (data-page in the markup — round 3's word for the same thing); a SECTION is section.screen[id]; a SCREEN is one
   monitor-full (the frames engine's frame). A command whose area has more than one section OPENS A MENU of them — js/nav.js builds it
   from the screens themselves, one row per section: the section's id alone — the word the prompt will type (ROUND 8C, Bill,
   2026-09-11: "do not include the sub-text. Just the title, ie, THESIS, STORY, etc." — 8B had its heading beside it in the dim tier,
   and the row was two columns; now one, so the desk's panel is as wide as its widest id, as a pull-down is). A row's click is the
   normal navigation: the prompt types the path, accepts, the flip. A command with one section is
   the plain link it was (a menu of one row that is the area itself would say nothing); an area grows its menu at its second section,
   by construction. His referent for the register: the Contact panel's SEND key — "generic 80's Macintosh" — so the menu is a
   Macintosh pull-down built out of the kit's keycap (css/ui.css .ui-key): a panel hanging off the bar's rule, 1 px ink, the keycap's
   hard 2 px shadow, solid paper; the rows in the keycap's face (11 px mono, tracked, uppercase); the current section inverse (the
   nav's own mark); a pressed row inverse. It rasters DOWN row by row when it opens (the mark's redraw device, --n-menu-open ms, a
   step per row; js/nav.js), and closes at once, as a pull-down does. The pixel chevron after a command (N6's own 7 × 4 glyph) marks
   the commands that open, and turns up while the menu is down. No hover-only state: the same row for a finger and a pointer.
   Keyboard: Enter / Space / ArrowDown on the command opens (Space and ArrowDown land on the current section), arrows walk the rows,
   Escape closes and returns to the command, Tab walks on (and closes). The desk hangs the panel under its command; the phone spans
   the sheet's width with it. Script off there is no menu: the page is one scrolling page and every section is on it. */
.nv .mn-c{ display:inline-block; width:7px; height:4px; margin-left:5px; vertical-align:1px; fill:currentColor; shape-rendering:crispEdges; }
.nv a[aria-expanded="true"]{ background:var(--ink); color:var(--paper); }
.nv a[aria-expanded="true"] .mn-c{ transform:scaleY(-1); }
.nv .mn{ position:absolute; top:100%; left:0; margin:-1px 0 0; z-index:1; min-width:max-content; padding:0; border:1px solid var(--ink);
  background:var(--paper); box-shadow:var(--key-shadow); }
.nv .mn[hidden]{ display:none; }
.nv .mn a{ display:block; margin:0; padding:9px 13px 8px;
  border-bottom:1px solid var(--hair); font:500 11px/1 var(--mono); letter-spacing:.1em; text-transform:uppercase; color:var(--ink);
  background:none; transition:none; }
.nv .mn a:last-child{ border-bottom:0; }
.nv .mn a:hover{ color:var(--ink); background:rgba(30,42,56,.08); }
.nv .mn a:active, .nv .mn a[aria-current]{ background:var(--ink); color:var(--paper); }
.nv .mn a:focus-visible{ outline-offset:-4px; }
@media (max-width:720px){   /* the phone: the panel spans the sheet, frame edge to frame edge — the row is the finger's target, whatever the word's length */
  .nv .mn{ left:var(--frame-x); right:var(--frame-x); min-width:0; }
  .nv .mn a{ padding:10px 12px 9px; }
}

/* ==== ROUND 18 (Bill, 2026-09-14, N1 · N2): ONE MENU ON THE PHONE. His words: "On mobile, combine home & projects into a single menu. Within the
   menu, add a header item for projects with the current sub-items open source & ecosystem" — the reason: "on smaller mobile devices the prompt area
   clips with menu". The markup carries three commands for the two areas — home and projects (data-desk) and menu (data-phone, standing for both):
   a desk shows the first two, a phone the third; js/nav.js builds the menu's pull-down as home's rows, then a HEADER naming projects over its rows
   (N1: the open-source section's row reads OPEN SOURCE — its data-word). THE HEADER is the pull-down's label, not a row: the field-label tier
   (css/ui.css .ui-lbl — 10 px mono, tracked, uppercase, the small tier's ink) on a rule of the ink, no hover, no press, not in the Tab order; a
   Macintosh menu's dimmed heading. The desk keeps its two commands (the fork: the one menu there too — show data-phone, hide data-desk). */
@media (min-width:721px){ .nv .in > a[data-phone], .nv .in > a[data-phone] + .mn{ display:none; } }
@media (max-width:720px){ .nv .in > a[data-desk], .nv .in > a[data-desk] + .mn{ display:none; } }
.nv .mn-h{ display:block; padding:9px 13px 5px; border-top:1px solid var(--ink); border-bottom:1px solid var(--hair); font:500 10px/1 var(--mono); letter-spacing:.12em; text-transform:uppercase; color:var(--ink-2); background:rgba(221,227,232,.6); cursor:default; }
