/* ============================================================
   topbar.css — the site top bar. Shared by the home page and
   portal mode (and, once built, Documentation / Material
   Database / Canyon Prototype). NOT loaded by Analytic Mode,
   which has no top bar.

   Owns everything inside .topbar and nothing outside it. Every
   selector is prefixed .topbar, so this file can be dropped into
   any page without leaking — no ID selectors, no second block
   elsewhere.

   This file owns geometry AND colour, for both pages, full stop —
   the portal panel is permanently dark, so both pages want the
   exact same colours and there is nothing left for a page-local
   block to own. If a future page ever needs its topbar to differ
   in colour, that is a `body.theme-light .topbar { … }` override
   HERE — never a second #topbar-* block in that page's own
   style.css. Reintroducing a page-local split is exactly the drift
   this file's structure exists to avoid.
   ============================================================ */

.topbar {
  flex: none;
  height: var(--h-topbar);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: 0 var(--sp-4);
  background: var(--bg-panel);
  border-bottom: var(--border) solid var(--line);
  /* RULE: REQUIRED, NOT TIDINESS. A static bar has no z-index to compare, so
     it loses the paint order to any positioned sibling that overlaps it —
     and it still LOOKS right while doing so, because the thing winning is
     usually transparent. The failure is silent and pointer-only:
     elementFromPoint over a nav item returns the other element, and every
     link in the bar is dead.
     The home page has a fixed section rail (z-index 25) and a sticky
     footer (z-index 20) in the same stacking context, and styles/home.css
     raises THIS bar to 30 to sit above both. Remove the position here and
     that override has nothing to apply to.
     Harmless on the portal page — the bar is a flex band there with nothing
     overlapping it, and #viewer-root (z-index 100, inside .stage) still
     wins in analytic mode, where the bar is display:none anyway. */
  position: relative;
  z-index: 10;
}

/* ---- brand ------------------------------------------------ */
.topbar-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }

/* width/height HTML attributes on the <img> (96, the SVG's own viewBox) are
   load-bearing, not decoration — they reserve this box's space before the
   file loads, so a slow load never shifts the wordmark sideways once the
   image finally gets a size. Do not remove them just because the CSS below
   also fixes the rendered size. */
.topbar-mark { width: 22px; height: 22px; flex: none; display: block; }

.topbar-name      { font-size: var(--fs-topbar-brand); font-weight: 600; letter-spacing: 0.01em; color: var(--text-1); }
.topbar-name .tld { font-weight: 400; color: var(--text-3); }

.topbar-badge {
  font-size: var(--fs-micro); font-weight: var(--fw-micro);
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  padding: 2px 6px; color: var(--text-2);
  border: var(--border) solid var(--line-strong); border-radius: var(--radius);
}

.topbar-spacer { flex: 1; }

/* ---- nav ------------------------------------------------
   Items take their natural width — a label is as wide as its word. The row
   is inset 9px from the bar's top and bottom edges, so each item is a 30px
   box floating inside the 48px bar: the current-page rule then sits clear
   of the bar's own bottom border instead of merging with it, and the hover
   bed has air above and below. Items are separated by a centred 14px
   hairline, not by whitespace, and the current page is marked by a rule
   UNDER the item — never a box. */
.topbar-nav {
  margin-left: auto;
  display: flex;
  align-items: stretch;
  box-sizing: border-box;  /* the 9px padding must eat INTO the 48px, not add
                              to it — without this the row overflows the bar */
  height: 100%;
  padding: 9px 0;          /* the gap; 48 - 9 - 9 = 30px items */
  min-width: 0;
  overflow: hidden;
}

/* Base layout applies to BOTH real links and the not-built-yet placeholders
   below — a bare `.topbar-nav a` selector would miss every `<span
   class="is-soon">`, leaving them unpadded and flush against their
   neighbours, which reads as one run-on word with no divider between the
   placeholder labels. `.is-soon` below narrows only colour/cursor/hover,
   never re-declares layout. */
.topbar-nav a,
.topbar-nav .is-soon {
  position: relative;
  display: flex; align-items: center;
  height: 100%; padding: 0 18px;
  white-space: nowrap;
  font-size: var(--fs-topbar-nav); font-weight: 500; letter-spacing: var(--ls-topbar-nav);
  text-transform: uppercase; color: var(--text-2);
  text-decoration: none;
}
.topbar-nav a:hover { color: var(--text-1); background: var(--bg-inset); }

/* placeholders for pages that do not exist yet. Not an <a> (a <span> cannot
   navigate, cannot 404 and cannot leave a # in the address bar), and coloured
   rather than dimmed with opacity — the audit that started this restructure
   flagged opacity-as-disabled as a contrast violation. cursor:default (not
   not-allowed) because nothing is being refused; the item simply is not a
   destination yet. */
.topbar-nav .is-soon { color: var(--text-off); cursor: default; user-select: none; }
.topbar-nav .is-soon:hover { background: none; color: var(--text-off); }

/* divider between items, centred and short — a full-height line would read
   as four separate buttons. `> * + *` matches any direct child (link or
   placeholder span) that follows another one, i.e. every item except the
   first, regardless of which tag either side is. */
.topbar-nav > * + *::before {
  content: ""; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 1px; height: 14px; background: var(--line);
}

/* the current page is the top bar's single accent — nothing else here may
   be amber (one accent per region) */
.topbar-nav a[aria-current="page"] { color: var(--accent); }
.topbar-nav a[aria-current="page"]::after {
  /* Underline shorter than the button itself: 12px in from each side
     rather than flush (was left: 0; right: 0). Only the line moved —
     button size, gap and text are unchanged. */
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 0;
  height: 1px; background: var(--accent);
}

/* ---- narrow screens ------------------------------------- */
@media (max-width: 900px) {
  .topbar-nav a   { padding: 0 10px; letter-spacing: 0.1em; }
  .topbar-badge   { display: none; }
}

/* Below this the nav items cannot fit next to the brand even at the reduced
   900px padding. Hidden rather than wrapped: a wrapping nav would double the
   bar's height, which nothing downstream (the docked .stage, the status bar)
   is built to absorb. The brand — the one item that actually navigates home
   — always survives.

   RULE: THIS NUMBER IS MEASURED, NOT CHOSEN. .topbar-nav is
   overflow:hidden, so a clipped item looks exactly like a shorter word —
   raising the nav font size or item padding narrows the slack before the
   last item is silently cut, with no visible error.
   WARNING: re-measure this if you touch --fs-topbar-nav, --ls-topbar-nav,
   the item padding above, or the number of nav items. The failure is
   silent. */
@media (max-width: 800px) {
  .topbar-nav { display: none; }
}
