/* Shared nav styling - RP-nav-consolidation. Hand-authored, NOT Vite build output (same as
   theme.css/footer.js - vite.config.js sets emptyOutDir:false so this survives `npm run build`).

   Uses var(--token, literal-fallback) throughout, not bare literal hex - a change from this
   file's own original design (site-wide restyle, 2026-09-04). The original reasoning still
   matters and is why every declaration keeps its literal fallback: static_assets/theme.css and
   frontend/src/styles.css used to define --green (and --border/--blue vs --line/--link) with
   DIFFERENT names, and --green with a DIFFERENT color, between the two - redeclaring :root here
   to "unify" them would have silently re-colored whatever a page's OWN stylesheet drew with its
   own var(--green). That's resolved now: static_assets/theme-tokens.css is the one canonical
   source every page loads, and every OTHER page-local :root now aliases onto it rather than
   redeclaring its own values (see static_admin.html's :root for the pattern). This file reads
   theme-tokens.css's names directly, but keeps a literal fallback on every single declaration so
   it still can't go visibly wrong on a page that somehow loads this without that file - the same
   safety property the old "no vars at all" approach had, without needing to stay dark-only
   forever to get it.

   Base .site-nav layout (link row, badges, current-page highlight) plus the mobile hamburger +
   slide-in drawer, built from RP-240's live-tested Variant A after a real A/B/C comparison.
   nav.js (frontend/src/nav.js) is drawer-aware: it reads real heights from whichever of
   .site-nav-mobile-bar / .site-nav is actually visible (see currentHeaderEl() there), so nothing
   here needs !important to fight an inline style nav.js sets - that was RP-240/241's bug, fixed
   at the source this time. */

.site-nav { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 0 0 4px;
  position: sticky; top: 0; z-index: 50; background: var(--ground, #0d1117); padding: 8px 0; }
/* .nav-group-label-only joined here too (RP-302: "the community text in the nav button is
   still not uniform in font size") - it's a <span>, not an <a>, so it never matched any of
   .site-nav a's own font-size rules (this one or the two breakpoint overrides below) and was
   left at whatever size it inherited by default, different from every sibling link around it
   at every viewport width. Joined at the source instead of copying the number, so the two can't
   drift out of sync the way a copied literal eventually would. */
.site-nav a, .nav-group-label-only { font-size: 0.8rem; }
.site-nav a { color: var(--accent, #58a6ff); text-decoration: none; }
.site-nav a:hover { text-decoration: underline; }
.site-nav a.brand { font-size: 1.15rem; font-weight: 700; color: var(--ink, #e6edf3);
  text-decoration: none; margin-right: 4px; }
.site-nav a.brand:hover { text-decoration: none; }
/* Segmented tabs: the current page is a filled pill, not an underline - the owner's pick from
   the theme-preview artifact, 2026-09-04 (replaces RP-251's underline treatment, itself a fix for
   an earlier font-weight:bold reflow bug - see below for why that constraint still matters here).
   align-items:center (was baseline, above) so the pill's own padding doesn't throw off vertical
   alignment against the plain-text siblings next to it.
   UPDATE (RP-286-ish, owner asked twice for "the underline with icon one"): reintroduced as a
   WIDE-VIEWPORT-ONLY override below, deliberately NOT touching font-weight this time - RP-251's
   own reflow bug came from the active tab's text becoming bold (wider) than the inactive ones
   around it, shifting every link after it sideways whenever the current page changed; this
   version changes only color and a bottom border, both of which take zero extra horizontal space,
   so the same failure mode can't recur. The base filled-pill rule stays exactly as-is below for
   the mobile drawer (a full-width block highlight, not a tight underline, is still the right
   shape for a 100%-wide row - see the drawer's own comment on this same point). */
/* .nav-group.has-here .nav-group-label-only joins every .here rule below (RP-297: "the community
   button doesnt highlight purple when clicked") - real gap, not a typo: Community's own row has
   no primary <a> to carry a .here class at all (makeGroup's primaryHref is null for it, on
   purpose - there's no single page "Community" itself goes to any more, Forum took that job when
   it got its own real child link). here-detection already added `.has-here` to the group whenever
   one of ITS children is the current page - correctly tracking the state - but nothing ever
   painted it, so Agent (a real <a class="here">) highlighted purple on /agent while Community
   never visibly did on /forum, /room, /orgs, or /messages, despite both being equally "the
   current section." Same declarations as the sibling .here rule in every case, not a new look. */
/* Soft tinted background + the link's own accent color, not a solid fill + inverted white text
   (owner, referencing TailAdmin's own demo: "right now... it has a purple box and the text
   turns to white. they have theirs be a lighter color to the original font color but keeping
   the font color the same") - the exact same soft-background/colored-text pattern this codebase
   already uses elsewhere (`.tt-btn-tonal`/`.tt-chip-active` in theme-tokens.css, for Status
   Updates' kind and credential badges), reused here instead of inventing a second one. */
.site-nav a.here, .nav-group.has-here .nav-group-label-only {
  font-weight: 500; text-decoration: none;
  color: var(--accent, #58a6ff); background: var(--accent-soft, #3b0764);
  border-radius: var(--radius-pill, 999px); padding: 4px 12px; margin: -4px 0; }
.site-nav a.here:hover { text-decoration: none; filter: brightness(1.08); }
/* A child link's own "here" (e.g. Forum, when a group is expanded and Forum is the current page)
   used to get the identical solid pill its own parent group gets - Community's row (has-here,
   above) AND its current child both painting the same filled block at once read as two stacked
   "you are here" signals for one fact (owner: "the community funny looks different and not
   unintended"). Reused the green already used for a session's own currently-open chat row
   instead of inventing a new color ("I like how the word font colors change to green, can we do
   this for community too") - text-only, no fill, so it reads as "and specifically this one"
   nested under the parent's own pill rather than repeating it. Higher specificity than every
   .here rule above (three classes, not two) so it wins regardless of source order or breakpoint. */
.nav-group .nav-group-children a.here {
  background: none; color: var(--success, #3fb950); }
.nav-group .nav-group-children a.here:hover { filter: none; text-decoration: underline; }
.site-nav .badge { display: inline-block; min-width: 18px; text-align: center; font-size: 0.7rem;
  padding: 1px 6px; border-radius: 999px; background: var(--accent, #1f6feb); color: #fff;
  margin-left: 4px; }

/* One icon per destination, keyed by href/data-attribute rather than editing every page's own
   copy of this nav block (it's duplicated verbatim across ~30 static HTML files, not templated) -
   a single rule here reaches every page that links there, with zero HTML changes and zero risk
   of missing a page. */
.site-nav a[href="/agent"]::before { content: '\1F916\A0'; }
.site-nav a[href="/messages"]::before { content: '\1F4AC\A0'; }
.site-nav a[href="/people"]::before { content: '\1F91D\A0'; }
.site-nav a[href="/room"]::before { content: '\1F5E8\FE0F\A0'; }
.site-nav a[href="/forum"]::before { content: '\1F465\A0'; }
.site-nav a[href="/orgs"]::before { content: '\1F3E2\A0'; }
.site-nav a.site-nav-cta::before { content: '\1F4B0\A0'; }
.site-nav a[data-nav-builds]::before { content: '\1F3D7\FE0F\A0'; }
.site-nav a[data-nav-account]::before { content: '\1F464\A0'; }
.site-nav a[href="/admin"]::before, .site-nav a[data-nav-admin]::before { content: '\1F6E1\FE0F\A0'; }
/* Two selectors: most pages mark this link with data-nav-logout, but static_admin.html's own
   copy of this nav block only ever had the onclick handler - caught by actually screenshotting
   every representative page rather than assuming one selector would reach all of them. */
.site-nav a[data-nav-logout]::before, .site-nav a[onclick="doLogout()"]::before { content: '\1F6AA\A0'; }
/* The commercial CTA - styled apart from the section links because it's a different kind of
   thing: those move you around the app, this starts a sales conversation.

   Real bug, caught live at every breakpoint (owner: "check the middle ground on the get a quote
   button color" - turned out not to be middle-only, `getComputedStyle` at 390/900/1600px all
   showed the same wrong value): a bare `.site-nav-cta` selector (specificity 0,1,0) loses to the
   base `.site-nav a { color: var(--accent) }` rule above (0,1,1, one class + one element) for the
   `color` property specifically - the border already carried its own `.site-nav a` qualifier
   pattern elsewhere (RP-286's border-bottom fix, per-breakpoint), but the base rule's `color`
   itself never got the same treatment, so the pill's text silently rendered in the site's violet
   accent instead of the green its own border and 💰 icon promised. Qualified here once, at the
   root rule, rather than patched per breakpoint again - fixes every mode (drawer, top bar,
   sidebar) from the one place. */
.site-nav a.site-nav-cta { color: var(--success, #3fb950); border: 1px solid var(--success, #238636);
  border-radius: 999px; padding: 1px 9px; text-decoration: none; }
.site-nav a.site-nav-cta:hover { text-decoration: none; }

/* Collapsible nav groups (RP-292), modeled on TailAdmin's own "AI Assistant" sidebar item
   (checked live on their public demo): a toggle row with a chevron, expanding to reveal indented
   children in the same column. Built by nav.js (frontend/src/nav.js's buildNavGroups) wrapping
   the SAME <a> elements every page already carries - zero markup changes here either, matching
   how the icon rules above reach every page from this one file. Base rules here apply in the two
   vertical-list contexts (mobile drawer, wide sidebar); the middle 701-1099px top-bar range
   unwraps the grouping entirely via `display: contents` rather than attempting a third visual
   language (dropdown) a horizontal bar has no established pattern for yet - see that block below. */
.nav-group { width: 100%; }
.nav-group-row { display: flex; align-items: center; width: 100%; gap: 2px; }
.nav-group-row .nav-group-link { flex: 1; min-width: 0; }
/* Real bug (owner: "the community nav button is missing an icon and is still a bold white
   font... was there a reason it was left this way") - Community's row has no real href to carry
   it, so it never matched the href-keyed `.site-nav a[href="..."]::before` icon rules OR the
   base `.site-nav a { color: var(--accent) }` link color every sibling destination gets for
   free - it fell back to plain body text styling (--ink, the default 500 weight this element
   itself declares) instead, reading as heavier and differently-colored than Agent, Forum, or
   anything else in the list. Not a deliberate choice, just a gap this rule never closed. */
.nav-group-label-only { display: block; padding: 12px 4px; font-weight: normal;
  color: var(--accent, #58a6ff); }
.nav-group[data-group="community"] .nav-group-label-only::before { content: '\1F310\A0'; }
.nav-group-toggle-btn { background: none; border: none; color: var(--dim, #8b949e);
  cursor: pointer; padding: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; }
.nav-group-toggle-btn:hover { color: var(--ink, #e6edf3); }
.nav-group-toggle-btn .chevron { display: inline-block; font-size: 1rem; line-height: 1;
  transition: transform .15s ease; }
.nav-group.open > .nav-group-row .nav-group-toggle-btn .chevron { transform: rotate(90deg); }
.nav-group-children { display: none; padding-left: 10px; margin-left: 12px;
  border-left: 1px solid var(--line-faint, #30363d33); }
.nav-group.open > .nav-group-children { display: block; }
.nav-group-children a { font-size: 0.82rem; }

/* Agent's dynamic session children (nav.js's populateAgentChildren/renderAgentChildren) - each
   row pairs a link with a delete button, not a plain <a>, so these get their own rules rather
   than reusing `.nav-group-children a` alone. Delete stays fully visible by default (this is the
   rule a touch-only drawer actually uses - there's no hover to reveal it with); the wide sidebar
   below switches it to a hover reveal instead, since a mouse-driven context can afford that and
   it reads as less cluttered with 8 rows showing at once. */
/* Green, not the accent every other link in this list gets (owner: "can we also make the +
   buttons that adds things a color") - matches #newChatBtn just below and the same treatment
   given to "+ New group"/"+ Add people" elsewhere, so "starts something new" reads as one
   consistent color across the whole app rather than blending into the rest of the list. */
.nav-session-new { display: block; width: 100%; box-sizing: border-box; text-align: left;
  background: none; border: none; color: var(--success, #3fb950); cursor: pointer;
  padding: 8px 4px; font-size: 0.82rem; }
.nav-session-new:hover { text-decoration: underline; }
.nav-session-row { display: flex; align-items: center; gap: 4px; }
.nav-session-row .nav-session-link { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; padding: 6px 4px; font-size: 0.8rem; }
.nav-session-row.current .nav-session-link { color: var(--success, #3fb950); font-weight: 600; }
.nav-session-del, .nav-session-ren { background: none; border: none; color: var(--dim, #8b949e);
  cursor: pointer; padding: 4px 6px; font-size: 0.75rem; flex-shrink: 0; }
.nav-session-del:hover { color: var(--danger, #f85149); }
.nav-session-ren:hover { color: var(--accent, #58a6ff); }
/* Inline rename (owner: "rename the agent chats and project folders directly on display
   folder or chat" - in place, not a prompt() popup). Sized to sit flush in the same row/summary
   the label it replaces was in, not a bigger standalone form control. */
.nav-inline-rename { flex: 1; min-width: 0; font-size: 0.8rem; font-family: inherit;
  background: var(--surface-3, #21262d); color: var(--ink, #e6edf3);
  border: 1px solid var(--accent, #1f6feb); border-radius: 4px; padding: 3px 5px; }
.nav-folder-ren, .nav-folder-del { background: none; border: none; color: var(--dim, #8b949e);
  cursor: pointer; font-size: 0.72rem; padding: 2px 4px; flex-shrink: 0; float: right; }
.nav-folder-ren:hover { color: var(--accent, #58a6ff); }
.nav-folder-del:hover { color: var(--danger, #f85149); }
/* Section labels (RP: "clean up the + new chat, starred, active chats in a chat section and
   projects in a projects like section") - plain uppercase dividers, not another collapsible
   level; matches ChatsPanel.jsx's own .chat-group-label treatment for its date buckets, the
   same "small label heading a run of rows" shape already used elsewhere in this app. "Conver-
   sations", not "Chats" - Community's own top-level nav destination already owns that word;
   reusing it one level down would read as the same place. */
.nav-section-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--faint, #6e7681); padding: 10px 4px 4px; font-weight: 600; }
.nav-section-label:first-child { padding-top: 4px; }
.nav-session-empty, .nav-session-more { display: block; padding: 8px 4px; font-size: 0.78rem;
  color: var(--dim, #8b949e); }
.nav-session-more { color: var(--accent, #58a6ff); text-decoration: none; }
/* Owner: "can we add a search field for /agent to find conversations or projects?" -
   persistent, next to the "+ New chat" slot above it, same reasoning as that element:
   must survive the sessions list's own innerHTML rebuild on every refresh. */
.nav-session-search { display: block; width: 100%; box-sizing: border-box;
  background: var(--surface-2, #1c2128); border: 1px solid var(--line, #30363d);
  border-radius: 6px; color: var(--ink, #e6edf3); font-size: 0.8rem;
  padding: 6px 8px; margin: 2px 0 6px; }
.nav-session-search::placeholder { color: var(--faint, #6e7681); }
.nav-session-search:focus { outline: none; border-color: var(--accent, #58a6ff); }
.nav-session-more:hover { text-decoration: underline; }

/* Agent's action buttons (RP-294) - chat.jsx's own chat-actions row, portaled into
   #navGroup-agent-actions on /agent itself (see nav.js's comment on navActionsTarget). Sits
   BELOW #navGroup-agent-sessions in the same expanded group (RP-379: "move the starred, active
   and projects above the agent chat action buttons" - swapped from the original RP-294 order,
   where this used to sit above the session list) - a top border on the container (not each
   button) reads as one divided list, picking a chat first and then acting on it, rather than
   the actions looking like they belong to the same visual group as the folder/session list
   above them. Empty (zero height, invisible) on every page other than /agent, where nothing
   ever portals into it.

   Staged reveal (RP-297): hidden by default even ON /agent - only `.nav-group.chat-selected`
   (nav.js, set once per page load from a flag a session-row/"+ New chat" click leaves behind
   right before navigating there) shows it. Expanding Agent starts on just the folder/session
   list; the tools only appear once a specific chat has actually been picked from it. */
.nav-group:not(.chat-selected) #navGroup-agent-actions { display: none; }
#navGroup-agent-actions:not(:empty) { padding-top: 6px; margin-top: 6px;
  border-top: 1px solid var(--line-faint, #30363d33); }
.nav-agent-action-btn { display: block; width: 100%; box-sizing: border-box; text-align: left;
  background: none; border: none; color: var(--text, var(--ink, #e6edf3)); cursor: pointer;
  padding: 6px 4px; font-size: 0.8rem; }
.nav-agent-action-btn:hover { color: var(--accent, #58a6ff); }
/* #newChatBtn only, not every .nav-agent-action-btn - green specifically for the one button in
   this row that starts something new (owner: "can we also make the + buttons that adds things a
   color"), matching .nav-session-new below it and "+ New group"/"+ Add people" elsewhere; the
   other nine share the plain text color on purpose, since Settings/Templates/etc. aren't "add"
   actions. */
#newChatBtn.nav-agent-action-btn { color: var(--success, #3fb950); }
#newChatBtn.nav-agent-action-btn:hover { color: var(--success, #3fb950); filter: brightness(1.15); }

/* The "⋯ More" fold (owner: "does feel a bit cluttered... common users are overwhelmed") -
   plain <details>/<summary> again, matching this file's own established idiom for "a
   collapsed-by-default list of extra things" rather than a one-off dropdown widget. The
   buttons inside keep their own .nav-agent-action-btn styling untouched; only the summary and
   a little breathing room around the fold are new. */
.more-actions summary { cursor: pointer; font-size: 0.8rem; font-weight: 600;
  color: var(--dim, #8b949e); padding: 6px 4px; list-style: none; margin-top: 4px; }
.more-actions summary::-webkit-details-marker { display: none; }
.more-actions summary:hover { color: var(--ink, #e6edf3); }
.more-actions[open] summary { margin-bottom: 2px; }

/* RP-298: "+ New chat" split out of #navGroup-agent-actions into its own always-visible
   sibling (see nav.js's comment on navNewChatTarget) - deliberately NOT covered by the
   .nav-group:not(.chat-selected) rule above, that's the whole point. Same divider treatment as
   #navGroup-agent-actions above it, so it still reads as one visually separated block sitting
   above the folder/session list rather than blending into it. */
#navGroup-agent-newchat:not(:empty) { padding-bottom: 6px; margin-bottom: 6px;
  border-bottom: 1px solid var(--line-faint, #30363d33); }

/* Folders (RP-297) - plain <details>/<summary>, the native disclosure widget doing exactly what
   a folder needs with no extra JS. Matches the compact, muted look the rest of this group
   already has rather than styling it like a bigger, bolder section heading. */
.nav-session-folder { margin: 2px 0; }
.nav-session-folder summary { cursor: pointer; font-size: 0.78rem; font-weight: 600;
  color: var(--dim, #8b949e); padding: 6px 4px; list-style: none; }
.nav-session-folder summary::-webkit-details-marker { display: none; }
.nav-session-folder summary::before { content: '▸'; display: inline-block; width: 1em;
  transition: transform .12s ease; }
/* Real bug (owner: "the collapse arrow for projects also shows as collapsed for the child
   projects within it") - a plain descendant selector here matches ANY summary nested anywhere
   inside an open folder, not just that folder's OWN summary. Once real projects started nesting
   under a parent "Projects" folder (this same restore point), an open parent's [open] attribute
   started rotating every closed CHILD sub-folder's arrow too, because `summary` with no `>`
   doesn't care how deep it is - so a still-closed child looked like it thought it was open (or,
   depending on which nested state you were looking at, the reverse: a child's own true state
   got masked by its parent's). `>` restricts the match to each folder's own direct summary. */
.nav-session-folder[open] > summary::before { transform: rotate(90deg); }
.nav-session-folder summary:hover { color: var(--ink, #e6edf3); }
/* Nested folders (RP-299 - real projects now sit one level deeper, under a single "Projects"
   parent rather than flooding the top level one-per-project) - a touch of left padding on the
   nested <details> itself is enough to read as a sub-level without a full indent guide/rule the
   compact, muted look of this list doesn't otherwise use anywhere. */
.nav-session-folder .nav-session-folder { padding-left: 10px; }

/* Drag-and-drop into a project folder (owner: "agent chats click and drag able to a project
   folder"). A dragged row dims rather than disappearing - it's still the same row, just being
   moved, and a card that vanishes mid-drag reads as "did I just delete this." The drop
   highlight targets the whole folder's border, not just the summary text, since that's the
   entire hit area wireDropTarget() actually listens on. */
.nav-session-row.dragging { opacity: 0.4; }
.nav-session-folder.drag-over { outline: 2px dashed var(--accent, #1f6feb); outline-offset: 2px;
  border-radius: 6px; }
.nav-session-folder.drag-over > summary { color: var(--accent, #1f6feb); }
.nav-session-row .nav-session-link { cursor: grab; }
.nav-session-row.dragging .nav-session-link { cursor: grabbing; }

/* Star toggle - same compact-icon-button shape as the delete button beside it, same hover-reveal
   split between drawer (always visible, no hover on touch) and sidebar (hover-reveal, quieter at
   rest) the delete button already established below. */
.nav-session-star { background: none; border: none; color: var(--dim, #8b949e); cursor: pointer;
  padding: 4px 2px; font-size: 0.8rem; flex-shrink: 0; }
.nav-session-star.starred { color: var(--warn, #d29922); }
.nav-session-star:hover { color: var(--warn, #d29922); }

.site-nav-mobile-bar { display: none; }
.site-nav-backdrop { display: none; }
@media (max-width: 700px) {
  .site-nav-mobile-bar {
    display: flex; align-items: center; justify-content: space-between;
    position: fixed; top: 0; left: 0; right: 0; z-index: 210;
    background: var(--ground, #0d1117); border-bottom: 1px solid var(--line, #30363d);
    padding: 10px 14px;
  }
  .site-nav-mobile-bar .brand { font-weight: 700; color: var(--ink, #e6edf3);
    text-decoration: none; font-size: 1.05rem; }
  /* display:flex + centering, not just a plain button relying on the browser's own default
     text/line-height centering for the glyph - that default isn't guaranteed identical across
     browsers/fonts (real report: the icon looked off-center on some pages vs others, not
     reproducible in Chromium at all - a rendering-engine difference, most likely Safari, is the
     one explanation left once the button's own position measured pixel-identical everywhere).
     Flexbox centering has no such ambiguity: the glyph sits in the exact geometric center of the
     box regardless of the character's own font metrics or which engine is rendering it. */
  .site-nav-toggle { display: flex; align-items: center; justify-content: center;
    background: none; border: 1px solid var(--line, #30363d); color: var(--ink, #e6edf3);
    line-height: 1; border-radius: 8px; width: 38px; height: 38px; font-size: 1.1rem;
    cursor: pointer; padding: 0; box-sizing: border-box; }
  body { padding-top: 60px !important; }
  /* flex-wrap: nowrap - real bug, caught live from an owner screenshot (RP-296): the base
     top-bar rule above sets `flex-wrap: wrap` for ITS OWN reason (letting the horizontal link
     row wrap onto a second line on a narrow-but-not-drawer width) - this block changes
     flex-direction to column but never explicitly reset flex-wrap, so that same `wrap` kept
     applying here too. With flex-direction:column, "wrap" means the flex container starts a NEW
     COLUMN once content exceeds its own height instead of just letting overflow-y:auto scroll
     it - exactly what the screenshot showed: once Agent's group (a whole session list) expanded
     past one screen's height, everything after it (Community, Get a quote, My Builds...) jumped
     into a second column to the right instead of continuing to scroll down, with the page's own
     content visible through the gap between the two columns. This was always latently possible
     (the original flat 9-link list could in principle have been tall enough on some device too),
     just far more likely now that a single expanded group can be many rows tall on its own. */
  .site-nav {
    position: fixed; top: 0; left: 0; bottom: 0; width: 80%; max-width: 300px;
    background: var(--surface, #161b22); border-right: 1px solid var(--line, #30363d);
    padding: 20px 16px; margin: 0; box-sizing: border-box;
    display: flex; flex-direction: column; align-items: flex-start; gap: 0; flex-wrap: nowrap;
    overflow-y: auto; z-index: 220; transform: translateX(-105%); transition: transform .25s ease;
  }
  body.site-nav-open .site-nav { transform: translateX(0); }
  .site-nav a { display: block; width: 100%; box-sizing: border-box; padding: 12px 4px;
    font-size: 0.95rem; border-bottom: 1px solid var(--line-faint, #30363d33); }
  .nav-group-label-only { font-size: 0.95rem; }
  .site-nav a.brand { font-size: 1.2rem; font-weight: 700; padding-bottom: 14px; margin-bottom: 6px;
    border-bottom: 1px solid var(--line, #30363d); }
  /* Full-width highlighted row rather than a tight pill - a pill sized to the text alone would
     look stranded on an already block-width, 100%-wide row (every link here already spans the
     full drawer width). radius-md rather than a full pill for the same reason: at this width, a
     999px radius would look like an oversized rounded-rect at each end, not a "chip." Joined by
     .nav-group.has-here .nav-group-label-only for the same reason as the base rule above -
     Community's own row needs the identical highlight, it just never has a .here <a> to carry it.
     margin: 0 - real bug ("the my builds button highlights over the green for get a quote"),
     confirmed via bounding boxes: the base (top-bar) .here rule's `margin: -4px 0` exists to
     compensate for THAT rule's own extra padding/border so a highlighted top-bar tab doesn't grow
     taller than its plain-text siblings - this override block never redeclared margin, so that
     -4px kept applying here too, where every row is already its own full-width block with no such
     height mismatch to compensate for. My Builds' highlighted block ended up starting 4px above
     where it should, overlapping Get a quote's pill directly above it in the list. */
  .site-nav a.here, .nav-group.has-here .nav-group-label-only {
    border-radius: var(--radius-md, 10px); padding: 12px 4px; margin: 0;
    border-bottom-color: transparent; }
  /* Real bug, caught live (screenshotted on an actual phone): .site-nav-cta's own `border: 1px
     solid var(--success)` sets all four sides, but this rule's `border-bottom` above targets that
     one edge with higher specificity (class+element beats a single class) and wins for it alone -
     the pill's bottom edge silently rendered in the divider's faint grey instead of green, which
     border-radius:999px then blends into the adjoining corners too, reading as the border fading
     out on one side. Same fix .here already needed for the same reason, just the other value. */
  .site-nav a.site-nav-cta { border-bottom-color: var(--success, #238636); }
  .site-nav-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 190; }
  body.site-nav-open .site-nav-backdrop { display: block; }
}

/* Underline treatment for the current page, MIDDLE viewports only (701-1099px) - the mobile
   drawer above keeps its own full-width block highlight untouched (a tight underline looks
   stranded on a 100%-wide row), and so does the persistent sidebar below (same reasoning, same
   shape - a vertical list of full-width rows, not a horizontal one). Color + border only, no
   font-weight change - see the base .here rule's own comment for why that specific property is
   off-limits here (RP-251's reflow bug). Capped at 1099px (was unbounded) once the sidebar
   below claimed everything from 1100px up - this and that block would otherwise both apply and
   fight each other in the overlap. */
@media (min-width: 701px) and (max-width: 1099px) {
  .site-nav a.here { background: none; border-radius: 0; padding: 4px 2px 6px;
    margin: -4px 0 -6px; color: var(--ink, #e6edf3); border-bottom: 2px solid var(--accent, #58a6ff); }
  .site-nav a.here:hover { filter: none; }
  /* Real bug, caught live from a screenshot (RP-296): Agent's dropdown (below) is the only thing
     at this breakpoint that visually extends outside .site-nav's own row into the page content
     underneath - z-index:60 on .nav-group-children only wins WITHIN .site-nav's own local
     stacking context, and can't escape it. .site-nav itself and #chatActions (chat.jsx's sticky
     greeting bar) both sit at z-index:50, as siblings rather than nested - equal z-index between
     non-nested elements falls back to DOM order, and #chatActions comes later in the document,
     so it painted OVER the open dropdown ("Copy whole chat" specifically sat right behind the
     greeting text in the reported screenshot). Scoped to this one breakpoint rather than raised
     globally - the drawer and persistent sidebar don't have this problem (position:fixed there
     escapes the same trap on its own), and there's no reason to risk touching an already-correct
     stacking order everywhere else for a fix only this width range needs. */
  .site-nav { z-index: 70; }
  /* Community unwraps entirely at this width rather than growing a third accordion/dropdown
     treatment - `display: contents` removes .nav-group/.nav-group-row/.nav-group-children from
     the box model while leaving their child <a> tags in place, so they flow as ordinary direct
     flex items of .site-nav again, exactly like every other link in this row. Its toggle button
     and label-only span have nothing to do in a flat row, so they're hidden rather than left as
     inert clutter. Scoped to [data-group="community"] specifically (was every .nav-group,
     unscoped) since RP-296 gave Agent a real dropdown of its own at this width instead - see
     below - once its own separate chat-actions hamburger was removed (the one thing that used to
     cover this width for it) it needed SOME way to be reachable here too, and Community's real
     destination links and Agent's contextual session list/actions were never the same kind of
     content to begin with. */
  /* Real bug, caught live (Direct Messages and Group Chats rendering with zero space between
     them, though every pair here was actually touching): the base `.nav-group.open >
     .nav-group-children { display: block }` rule (specificity 0,2,0) beats a plain
     `.nav-group-children { display: contents }` here (0,1,0) whenever the group happens to be
     open - which Community always is on /forum itself, since here-detection auto-opens whichever
     group contains the current page. Once it's `block` instead of `contents`, its <a> children
     stop being flex items of .site-nav (gap:12px has nothing to apply to) and fall back to their
     own inline flow, touching with zero space - not "gap missing", `display:contents` was never
     winning in the first place. Repeating the higher-specificity selector here, not just the
     plain one, is what actually wins regardless of the .open state. */
  .nav-group[data-group="community"], .nav-group[data-group="community"] .nav-group-row,
  .nav-group[data-group="community"] .nav-group-children,
  .nav-group[data-group="community"].open > .nav-group-row,
  .nav-group[data-group="community"].open > .nav-group-children { display: contents; }
  .nav-group[data-group="community"] .nav-group-toggle-btn,
  .nav-group[data-group="community"] .nav-group-label-only { display: none; }

  /* Agent's own dropdown at this width (RP-296) - a real, standard "click a nav item, get an
     anchored popover" pattern, not unwrapped like Community above: its content (a live session
     list plus contextual actions - Settings, Templates, Copy...) only means something with a
     conversation in view, never reads as standalone destinations worth scattering into a flat
     bar the way Community's real links do. This became load-bearing, not just nicer, once the
     chat page's own separate "☰" hamburger (the only thing that used to cover this width for it)
     was removed entirely in the same change - there has to be SOME way to reach Settings/
     Templates/etc. here now. */
  .nav-group[data-group="agent"] { position: relative; }
  /* max-height subtracts the composer's own real height (owner: "check the middle breakpoint
     dropdown for the same issue" - confirmed live: a plain 75vh cap has no idea the composer
     sits fixed at the bottom of the page, so on a short-enough viewport with enough sessions
     expanded to actually reach that cap, the dropdown extended right over it, same class of bug
     as #inputForm's own sidebar overlap just fixed. --composer-h (chat.jsx, set from the
     composer's real measured offsetHeight - same variable .chat-rail and #pending already
     anchor themselves to) is the right number, not a second hardcoded guess; the 62px fallback
     matters on every OTHER page this dropdown can also open on, which never set the variable
     at all since they have no composer to measure. */
  .nav-group[data-group="agent"] .nav-group-children {
    display: none; position: absolute; top: 100%; left: 0; z-index: 60;
    width: 260px; max-height: calc(75vh - var(--composer-h, 62px)); overflow-y: auto;
    background: var(--surface, #161b22); border: 1px solid var(--line, #30363d);
    border-radius: var(--radius-md, 10px); box-shadow: 0 8px 28px #0006; padding: 6px 0;
    margin: 0; border-left: none;
  }
  /* BOTH .open AND .user-opened (RP-304: "the agent chat on the left is covered by the pane") -
     here-detection auto-adds .open on every /agent page load to drive the drawer/sidebar's own
     inline expansion, but THIS dropdown floats on top of the page rather than pushing it aside,
     so auto-opening it here left it permanently covering the content underneath with no click
     ever having asked for that. .user-opened only comes from an actual click on the row (see
     nav.js's own comment on it) and never gets removed again once set, so requiring it ALONGSIDE
     .open - rather than instead of it - still lets a second click close the dropdown normally:
     .user-opened marks "a click has happened here at least once," .open still does the actual
     toggling from then on. */
  .nav-group[data-group="agent"].open.user-opened .nav-group-children { display: block; }
  .nav-group[data-group="agent"] .nav-group-children a,
  .nav-group[data-group="agent"] .nav-session-row .nav-session-link,
  .nav-group[data-group="agent"] .nav-agent-action-btn,
  .nav-group[data-group="agent"] .nav-session-new { padding: 8px 14px; font-size: 0.85rem; }
  .nav-group[data-group="agent"] #navGroup-agent-actions:not(:empty),
  .nav-group[data-group="agent"] #navGroup-agent-newchat:not(:empty) {
    padding: 0 0 6px; margin: 0 0 6px; border-bottom: 1px solid var(--line-faint, #30363d33);
  }
}

/* Persistent left sidebar, RP-291 ("should we just put all the nav in the same sidebar for
   desktop too?" - owner chose the widest option, every page site-wide). Same breakpoint admin's
   own .tabs sidebar already uses (RP-278) - a deliberate match, not a coincidence: on /admin
   specifically the two now sit side by side rather than fighting (see the html padding-left
   note below for why they don't overlap).

   Reuses the drawer's own shape wholesale (full-width block links, a filled-pill "current page"
   highlight) rather than inventing a third visual language - a vertical list of rows is a
   vertical list of rows whether it slides in from off-canvas or sits pinned in place, and this
   is the exact same one already proven and screenshotted at the mobile breakpoint above.

   Fixed positioning, not sticky-inside-a-new-flex-wrapper - the deliberate choice that keeps
   this a CSS-only change with ZERO HTML edits across the 10 real pages that carry this nav block
   (it's duplicated verbatim, not templated - editing one shared file reaches every one of them,
   the same reasoning the icon rules above already rely on). The gutter it needs is reserved on
   <html> itself (padding-left, not body's own margin, which every page's own custom max-width
   already spends on centering) so each page's independently-tuned max-width keeps auto-centering
   correctly - just within the remaining (100vw - sidebar width) space instead of the full
   viewport, no per-page width math needed. One page (static_chat.html) computes its wide-viewport
   rail positions from raw `vw` units for the same reason body used to be full-viewport-centered;
   its own stylesheet block corrects for the new offset directly rather than duplicating that math
   here. */
@media (min-width: 1100px) {
  html { padding-left: 220px; }
  /* flex-wrap: nowrap - same fix, same reason as the drawer block above (RP-296): without it
     this inherits `flex-wrap: wrap` from the base top-bar rule, and a tall enough expanded
     group (Agent's session list, easily 8+ rows) would start a second column instead of just
     scrolling. Latent here too even though it wasn't what the owner's screenshot happened to
     show (that was the drawer) - same container shape, same inherited property, same fix. */
  .site-nav {
    position: fixed; top: 0; left: 0; bottom: 0; width: 220px;
    display: flex; flex-direction: column; align-items: flex-start; gap: 0; flex-wrap: nowrap;
    overflow-y: auto; padding: 20px 16px; margin: 0; box-sizing: border-box;
    border-right: 1px solid var(--line, #30363d); background: var(--ground, #0d1117);
  }
  .site-nav a { display: block; width: 100%; box-sizing: border-box; padding: 12px 4px;
    font-size: 0.88rem; border-bottom: 1px solid var(--line-faint, #30363d33); }
  .nav-group-label-only { font-size: 0.88rem; }
  .site-nav a.brand { font-size: 1.15rem; font-weight: 700; padding-bottom: 14px; margin-bottom: 6px;
    border-bottom: 1px solid var(--line, #30363d); }
  /* Joined by .nav-group.has-here .nav-group-label-only, same reason as the drawer's identical
     rule above - Community's row needs the same highlight here too, not just in the drawer.
     margin: 0 - same leftover -4px overlap bug the drawer block just needed this exact fix for
     (see its comment above), a fresh copy because this sidebar block has its own separate rule. */
  .site-nav a.here, .nav-group.has-here .nav-group-label-only {
    border-radius: var(--radius-md, 10px); padding: 12px 4px; margin: 0;
    border-bottom-color: transparent; }
  /* Same specificity bug the drawer already needed this exact fix for (see above) - a fresh copy
     because .site-nav-cta's border-bottom is beaten by THIS block's own `.site-nav a` rule now,
     not the drawer's. */
  .site-nav a.site-nav-cta { border-bottom-color: var(--success, #238636); }
  .site-nav .badge { float: right; }
  /* This breakpoint has no mobile bar to trigger a drawer - the sidebar is simply always there,
     so the toggle/backdrop machinery is permanently irrelevant here rather than just unused. */
  .site-nav-mobile-bar, .site-nav-backdrop, .site-nav-toggle { display: none !important; }
  /* Hover-reveal for a session row's delete button - only here, not the drawer's base rule
     above, which stays fully-visible-always since a touch drawer has no hover to reveal it with.
     A mouse-driven sidebar can afford the quieter default; 8 rows of "✕" sitting there
     unconditionally read as more cluttered than they're worth at this width. */
  .nav-session-del, .nav-session-ren { opacity: 0; transition: opacity .15s ease; }
  .nav-session-row:hover .nav-session-del, .nav-session-row:focus-within .nav-session-del,
  .nav-session-row:hover .nav-session-ren, .nav-session-row:focus-within .nav-session-ren { opacity: 1; }
  .nav-folder-ren, .nav-folder-del { opacity: 0; transition: opacity .15s ease; }
  .nav-session-folder summary:hover .nav-folder-ren, .nav-session-folder summary:focus-within .nav-folder-ren,
  .nav-session-folder summary:hover .nav-folder-del, .nav-session-folder summary:focus-within .nav-folder-del { opacity: 1; }
}
