/* ═══════════════════════════════════════════════════════════════════════════
   nav.css — the Divisions dropdown.  NAV1 §2b.
   Added 2026-08-14.

   🚨 WHY THIS IS A SEPARATE FILE AND NOT AN ADDITION TO styles.css.
   The nav is styled in THREE places and they have already drifted from each
   other:
       · css/styles.css          — the ten column-footer pages
       · css/athenaeum.css       — the seven Athenaeum room pages
       · an inline <style> block — division/{bastion,foundry,mythrilworks}/
                                   and llypses/*, which load NEITHER of the above
   Putting the dropdown in styles.css would have shipped it to ten pages out of
   twenty-two. This file is linked from every page that has a nav, so the
   component exists once and behaves the same everywhere.

   ⚠️ It LAYERS ON TOP of whatever nav CSS the page already has. It deliberately
   does not restyle .nav, .nav-links or .nav-mobile — that refactor is real work
   with real regression risk across three stylesheets, and it is not what NAV1
   asked for.

   ⚠️ EVERY var() HERE HAS A LITERAL FALLBACK. The division pages define their
   own token set inline and it is not identical to :root in styles.css. A
   missing token must degrade to a correct colour, not to nothing.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── The trigger ───────────────────────────────────────────────────────────
   A <button>, not a link. The overview page is not lost — it is the last item
   in the panel ("All divisions →"), per §2b: "Never remove the overview route
   while adding the direct one."
   Inherits font/size/colour from the sibling .nav-links a rules on whichever
   stylesheet the page loaded, so it cannot drift away from its neighbours. */
.navdd { position: relative; display: flex; align-items: center; }

.navdd-trigger {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-family: var(--font-heading, 'Cinzel', Georgia, serif);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(245, 245, 245, .75);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .55);
  transition: color .2s;
}
.navdd-trigger:hover,
.navdd-trigger[aria-expanded="true"],
.navdd-trigger.active { color: var(--rws-white, #fff); }

/* The caret. A rotated border box rather than a glyph, so it needs no font. */
.navdd-caret {
  width: .42em; height: .42em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-.15em) rotate(45deg);
  transition: transform .25s var(--ease-out, cubic-bezier(.16, 1, .3, 1));
}
.navdd-trigger[aria-expanded="true"] .navdd-caret {
  transform: translateY(.1em) rotate(225deg);
}

/* Match the underline the other nav items grow on hover. */
.navdd-trigger::after {
  content: '';
  position: absolute;
  bottom: -4px; left: 0;
  width: 0; height: 1px;
  background: var(--rws-crimson, #C0392B);
  transition: width .25s var(--ease-out, cubic-bezier(.16, 1, .3, 1));
}
.navdd-trigger:hover::after,
.navdd-trigger.active::after,
.navdd-trigger[aria-expanded="true"]::after { width: 100%; }

/* ─── The panel ─────────────────────────────────────────────────────────────
   z-index sits above the header's own stacking context (.nav is z-index 100)
   so the panel is never clipped by the chamber hero beneath it. */
.navdd-panel {
  position: absolute;
  top: calc(100% + 1.15rem);
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  /* width:max-content + nowrap on the name is what stops "RED WARDEN
     MYTHRILWORKS" wrapping onto a second line, which made that one row taller
     than the other three and broke the alignment down the panel. Sizing to
     content also means adding a division later cannot silently re-wrap the
     list. Clamped so it can never outrun a narrow desktop window. */
  width: max-content;
  min-width: 300px;
  max-width: min(92vw, 400px);
  padding: .5rem;
  background: rgba(8, 8, 9, .97);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--rws-border, rgba(255, 255, 255, .10));
  border-radius: 2px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, .6);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s, transform .18s var(--ease-out, cubic-bezier(.16, 1, .3, 1)), visibility .18s;
  z-index: 120;
}
.navdd.open > .navdd-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* An invisible bridge across the gap between trigger and panel. Without it the
   pointer crosses dead space on the way down and the hover intent is lost —
   the single most common way a hover menu feels broken. */
.navdd-panel::before {
  content: '';
  position: absolute;
  top: -1.15rem; left: 0; right: 0;
  height: 1.15rem;
}

/* ─── Items ─────────────────────────────────────────────────────────────────
   The name carries --rws-label (white). The descriptor is the one piece of
   secondary text here and it sits at 0.72rem, which is the project's hard type
   floor — do not go below it. rgba(255,255,255,.62) is the value nav-logo-sub
   already uses and was chosen for contrast over lit stone. */
.navdd-item {
  display: grid;
  /* 28px, not 24. The emblems are dark, detailed art on a dark panel; at 24
     they resolved as smudges. This is the smallest size at which all four are
     told apart at a glance - which is the whole reason they are here. */
  grid-template-columns: 28px 1fr;
  align-items: center;
  gap: .85rem;
  padding: .62rem .75rem;
  min-height: 44px;                 /* touch target */
  border-radius: 2px;
  transition: background .16s;
}
.navdd-item:hover,
.navdd-item:focus-visible { background: rgba(255, 255, 255, .06); }
.navdd-item:focus-visible {
  outline: 2px solid var(--rws-label, #fff);
  outline-offset: -2px;
}
.navdd-item img { width: 28px; height: 28px; object-fit: contain; }

.navdd-name {
  display: block;
  font-family: var(--font-heading, 'Cinzel', Georgia, serif);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--rws-label, #fff);
  line-height: 1.3;
  white-space: nowrap;
}
.navdd-desc {
  display: block;
  font-family: var(--font-body, 'Inter', system-ui, sans-serif);
  font-size: .72rem;
  letter-spacing: .02em;
  text-transform: none;
  color: rgba(255, 255, 255, .62);
  line-height: 1.4;
}

.navdd-sep {
  height: 1px;
  margin: .45rem .75rem;
  background: var(--rws-border, rgba(255, 255, 255, .10));
}
.navdd-all {
  grid-template-columns: 28px 1fr;
}
.navdd-all .navdd-name { letter-spacing: .16em; }

/* ─── Mobile ────────────────────────────────────────────────────────────────
   §2b: "Mobile: no hover dropdown." 37% of pageviews are mobile and a hover
   menu does not exist on touch. On mobile the divisions appear as an indented
   group inside the existing .nav-mobile sheet, which the existing .nav-toggle
   already opens and closes.

   ⚠️ An earlier version of this comment claimed "900px is where .nav-links is
   hidden in all three stylesheets." THAT WAS FALSE and it is what produced the
   bug documented below — styles.css hides it at 640px and athenaeum.css at
   860px. The claim was never checked against the files it described. */
/* 🚨 THIS FILE NOW OWNS THE ONE BREAKPOINT FOR THE WHOLE SITE. Added
   2026-08-15 (session 15). Read the history before changing the number.

   ── What this replaced ──────────────────────────────────────────────────
   An earlier version of this block hid .navdd below 901px and .navm-div above
   900px, and 900 was a number nothing else agreed with. The site had FIVE
   different nav breakpoints:

       css/styles.css                    hid .nav-links at  max-width: 640px
       css/athenaeum.css                                    max-width: 860px
       division/{bastion,foundry,mythrilworks}/  inline at  max-width: 860px
       llypses/index.html                        inline at  max-width: 900px
       llypses/download/index.html               inline at  max-width: 900px

   That was fixed once by DELETING the breakpoint from this file and letting
   `.navdd` inherit `display:none` from `.nav-links`. That fix was correct
   about Divisions and wrong about the nav as a whole, because it left the
   five parents disagreeing — and every one of them was too low.

   ── The measurement that set 1024 ───────────────────────────────────────
   Measured 2026-08-15 as `.nav-inner.scrollWidth - clientWidth`, in a sized
   iframe, with every stylesheet force-loaded from the server (the page's own
   cached copy was stale — see the ?v= note below). Signed OUT → signed IN:

       styles.css pages (7 nav items + 191px logo)   overflowed 641–1075 · needs 1160
       athenaeum.css pages                                     861–975  · needs 1080
       division inline pages                                   861–975  · needs 1080
       llypses inline pages (`.nav-in`, a FIFTH variant)       901–1010 · needs 1100

   Worst case was +414px on `/` at 641px signed out, +490px signed in. The
   beacon is NOT the cause — it adds a flat +80px to a band that was already
   broken. `styles.css` is the binding constraint because it carries the most
   items, so a single sitewide number has to satisfy IT, not the average.

   ⚠️ RAISING THE HAMBURGER TO ~1000 — the fix the TASKS row proposed — DOES
   NOT WORK. The homepage nav needs 1150px at full spacing. Compression alone
   does not work either: the tightest sane spacing still bottoms out at ~980.
   It takes both, which is why there are two queries below and not one.

   ── Why the compression band is scoped, not global ──────────────────────
   The gaps and tracking below are deliberately confined to 1024–1199px. At
   1200px and up NOTHING here applies and the nav renders exactly as approved.
   The tightening is what buys the drop from 1160 to 1024; it is a fix for a
   band, so it lives in that band and nowhere else.

   ── Specificity, and why it is `header.nav ...` ─────────────────────────
   `header.nav .nav-links` is (0,2,1) and beats the bare `.nav-links` (0,1,0)
   in all five places above **regardless of source order**. That matters: on
   the division pages the inline <style> is at line 11 and this file loads at
   line ~202, but on llypses the order is reversed. Do not rely on order here.

   ⚠️ The five local breakpoints were removed in the same commit. If you find
   one again, something re-added a second owner — delete it, do not tune it. */
@media (max-width: 1023px) {
  header.nav .nav-links  { display: none; }
  header.nav .nav-toggle { display: flex; }
}
/* `.nav-in` is llypses' name for `.nav-inner`. Both, always — they are the
   same box and forgetting the second one is how llypses got missed before. */
@media (min-width: 1024px) and (max-width: 1199px) {
  header.nav .nav-inner,
  header.nav .nav-in        { gap: 1.25rem; }
  header.nav .nav-links     { gap: 1.15rem; }
  header.nav .nav-links a,
  header.nav .navdd-trigger { letter-spacing: .12em; }
}

/* The panel is positioned by JS, which decides anchored-vs-sheet from WHERE
   THE PRESSED MARK LIVES, not from a width. See place() in js/nav.js. */

/* 🚨 THE SHEET MUST SCROLL. THIS IS NOT OPTIONAL - IT IS A REGRESSION FIX.
   Reported by Andrew from a real S25 on 2026-08-14: "the beacon system is
   completely gone on mobile."

   It was not gone. .nav-mobile shipped with `overflow-y: visible` and no
   max-height, which was survivable while the sheet held six items. Adding the
   four-division group made it ~256px taller, and at a REAL phone viewport the
   sheet ran 83px past the bottom of the screen with no way to scroll it. The
   beacon was clipped and Account was fully off-screen. The page behind cannot
   scroll either, because opening the sheet sets body overflow:hidden - so the
   two bottom items were simply unreachable.

   ⚠️ WHY MY OWN MOBILE TEST MISSED IT: I measured at 390x844 - the S25's FULL
   SCREEN. The browser content area is ~690 CSS px once Chrome's URL bar and
   the Android nav bar are subtracted. The component fit; the page did not.
   TEST THE WHOLE SHEET AGAINST ~690px, NOT THE COMPONENT AGAINST 844.

   `dvh` matters here specifically: the URL bar collapses on scroll, so `vh`
   describes a viewport the user does not actually have. `vh` first as the
   fallback for anything without dvh support.

   Selector is `nav.nav-mobile` (0,1,1) rather than `.nav-mobile` (0,1,0) so it
   wins regardless of where this file lands in the cascade - the sheet is
   styled in THREE places (styles.css, athenaeum.css, and an inline block on
   the division pages) and this must beat all of them. */
nav.nav-mobile {
  max-height: calc(100vh - var(--nav-h, 72px));
  max-height: calc(100dvh - var(--nav-h, 72px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Stops a flick at the end of the list from scrolling the page underneath. */
  overscroll-behavior: contain;
  /* Clears the home-indicator / gesture bar so the last item is tappable. */
  padding-bottom: max(2rem, env(safe-area-inset-bottom, 0px));
}

/* The mobile group. It is plain markup inside .nav-mobile, so the existing
   "close on link click" handler in main.js (and the inline equivalents on the
   division pages) picks these links up with no JS change.
   The group carries no heading of its own - the "Divisions" link sits directly
   above it and is the heading. */
.navm-div { margin-top: -0.4rem; }
.navm-div-list {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding-left: 1rem;
  border-left: 1px solid var(--rws-border, rgba(255, 255, 255, .10));
}
.navm-div-list a {
  display: flex;
  align-items: center;
  gap: .7rem;
  min-height: 44px;
  font-size: .92rem !important;   /* .nav-mobile a is 1rem; the group sits under it */
}
.navm-div-list img { width: 22px; height: 22px; object-fit: contain; flex-shrink: 0; }

/* ─── Motion ────────────────────────────────────────────────────────────────
   Project rule: every motion respects prefers-reduced-motion. The panel still
   opens and closes — only the movement stops. */
@media (prefers-reduced-motion: reduce) {
  .navdd-panel,
  .navdd-caret,
  .navdd-trigger,
  .navdd-trigger::after,
  .navdd-item { transition: none; }
  .navdd-panel { transform: translateX(-50%); }
  .navdd.open > .navdd-panel { transform: translateX(-50%); }
}
