/* ===========================================================================
   brokeh-nav.css — the one and only nav for brokehsite.com
   ---------------------------------------------------------------------------
   Served by nginx from /static/ (see brokeh.conf: location /static/ { alias
   /app/static/; }) and loaded by every navigable page. Before this file the
   header/hamburger/menu block was copy-pasted into five places and each copy
   drifted; do not re-inline it anywhere.

   Everything themeable is a custom property, so a page can restyle the nav
   without forking it. crumbl does exactly that — see its :root override.
   =========================================================================== */

:root {
  /* Surfaces */
  --nav-header-bg: transparent;
  --nav-panel-bg: #24301f;
  --nav-scrim-bg: rgba(0, 0, 0, 0.5);

  /* Type. --nav-font is the display stack; to self-host a pixel/retro face
     later, add an @font-face rule and prepend its family here — one line, and
     every page's nav retypes with it. */
  --nav-font: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
  --nav-text: #efe6d2;
  --nav-accent: #d9a441;
  --nav-logo-color: var(--nav-accent);
  --nav-logo-size: 1.1rem;
  --nav-logo-weight: 700;

  /* Hamburger bars. Kept as variables so a page can preserve its own icon
     proportions — the tap target is padded out separately and invisibly. */
  --nav-bar-color: var(--nav-text);
  --nav-bar-w: 28px;
  --nav-bar-h: 20px;
  --nav-bar-thickness: 3px;

  --nav-header-pad: 1.5rem 2rem;
}

/* ===== STACKING =============================================================
   The whole point of this block. Previously `header` was either static (so the
   fixed .menu painted over it) or fixed with z-index:1000 (which made it a
   stacking context, trapping .hamburger's z-index:1002 inside and letting the
   sibling .menu at 1001 win). Either way the panel covered the hamburger: on
   crumbl that hid the X, and on the pages with no click-outside handler it made
   the menu impossible to close at all.

   Header above panel. The hamburger stays visible AND hit-testable while open.
   ========================================================================== */

.site-header { z-index: 1002; }
.menu        { z-index: 1000; }
.nav-scrim   { z-index: 999;  }

/* ===== HEADER ===== */
.site-header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--nav-header-pad);
  background: var(--nav-header-bg);
  font-family: var(--nav-font);
  box-sizing: border-box;
}

/* Opt-in for pages whose content scrolls under a pinned bar (crumbl). */
body[data-nav-fixed] .site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

.site-header .logo {
  font-weight: var(--nav-logo-weight);
  font-size: var(--nav-logo-size);
  color: var(--nav-logo-color);
  text-decoration: none;
}

/* ===== HAMBURGER =====
   A real <button>: focusable and announced. Four of the five pages used a bare
   <div>, which is neither. Padding expands the hit area to >=44px without
   changing how big the bars look, so per-page icon proportions survive. */
.hamburger {
  width: var(--nav-bar-w);
  height: var(--nav-bar-h);
  padding: calc((44px - var(--nav-bar-h)) / 2) calc((44px - var(--nav-bar-w)) / 2);
  box-sizing: content-box;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: none;
  border: 0;
  cursor: pointer;
  position: relative;
}

.hamburger span {
  display: block;
  width: 100%;
  height: var(--nav-bar-thickness);
  background: var(--nav-bar-color);
  border-radius: 2px;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

/* Hamburger -> X. Lifted from crumbl, which was the only page that had it and
   the only page where it was invisible. Translate distance is derived from the
   bar box so it stays centred at any --nav-bar-* size. */
.hamburger.open span:nth-child(1) {
  transform: translateY(calc((var(--nav-bar-h) - var(--nav-bar-thickness)) / 2)) rotate(45deg);
}
.hamburger.open span:nth-child(2) {
  opacity: 0;
}
.hamburger.open span:nth-child(3) {
  transform: translateY(calc((var(--nav-bar-h) - var(--nav-bar-thickness)) / -2)) rotate(-45deg);
}

.hamburger:focus-visible {
  outline: 2px solid var(--nav-accent);
  outline-offset: 2px;
}

/* ===== MENU PANEL ===== */
.menu {
  position: fixed;
  top: 0;
  right: 0;
  width: min(260px, 80%);
  height: 100vh;
  background: var(--nav-panel-bg);
  padding: 2rem;
  font-family: var(--nav-font);
  box-shadow: -10px 0 30px rgba(0, 0, 0, 0.4);
  overflow-y: auto;
  box-sizing: border-box;
  /* Translate rather than animating `right`, so the panel is laid out at its
     final position and the width clamp above can't be defeated. */
  transform: translateX(100%);
  transition: transform 0.3s ease;
}

.menu.open {
  transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
  .menu,
  .hamburger span {
    transition: none;
  }
}

.menu ul {
  list-style: none;
  margin: 3rem 0 0;  /* clears the header bar */
  padding: 0;
}

.menu li {
  margin-bottom: 0.5rem;
}

.menu a {
  display: block;
  padding: 0.65rem 0;  /* real tap target; previously just the glyph height */
  text-decoration: none;
  color: var(--nav-text);
  font-size: 1rem;
  transition: color 0.2s;
}

.menu a:hover,
.menu a:focus-visible {
  color: var(--nav-accent);
}

.menu a.active {
  color: var(--nav-accent);
  font-weight: 600;
}

/* ===== SCRIM ===== */
.nav-scrim {
  position: fixed;
  inset: 0;
  background: var(--nav-scrim-bg);
  border: 0;
  padding: 0;
  cursor: pointer;
}

.nav-scrim[hidden] {
  display: none;
}

/* Scroll lock. No page did this before, so the page behind an open panel
   scrolled on all five. */
body.nav-locked {
  overflow: hidden;
}
