/* Shared chrome ONLY. Nav, More disclosure, drawer, skip link, footer.
 *
 * WHY THIS IS A SEPARATE FILE. The port adds a navigation to 152 pages that
 * link production's style.css and nothing else - the chrome pass adds no
 * rru.css link, and it should not: rru.css restyles body, cards, buttons and
 * grids, and dropping it onto legacy pages would change far more than the
 * chrome.
 *
 * But style.css has no rule for anything the shared nav introduces. Measured
 * in a browser on a backfilled page:
 *
 *   #more-panel   display:block, height > 0     -> the More menu renders
 *                                                  PERMANENTLY OPEN at desktop
 *   .skip-link    transform: translateX(-87px)  -> visible on screen instead
 *                                                  of hidden until focused
 *   .menu-close   unstyled inline-block         -> a bare glyph in the drawer
 *
 * So the chrome ships its own stylesheet, scoped to the classes the chrome
 * region emits. rru.css keeps its own copies for port-generated pages; this
 * file is what makes the same markup behave on the other 152.
 *
 * Nothing here styles page content. Every selector below is inside the NAV or
 * FOOTER region.
 */

/* ---------------------------------------------------------------- skip link */
.skip-link {
  position: absolute; left: 8px; top: 8px; z-index: 200;
  transform: translateY(calc(-100% - 16px));
  background: #ff2d87; color: #05010f; font-weight: 700;
  padding: 12px 18px; border-radius: 10px; text-decoration: none;
}
.skip-link:focus { transform: none; }

/* ---------------------------------------------------------------- the mark */
/* style.css sizes these through `.nav-logo .logo-img` / `.footer-logo
   .logo-img`, so the markup carries that class and these are a fallback for
   any page whose sheet has neither rule. */
.nav-logo .logo-img { width: 132px; height: auto; display: block; }
.footer-logo .logo-img { width: 150px; height: auto; display: block; }

/* ------------------------------------------------------- the header bar */
/* THE CHROME SHEET OWNS THE WHOLE HEADER, not just the parts style.css had no
   rule for. Leaving the rest to style.css left the same markup looking like
   two different headers depending on the page. Measured:

     production      .nav-links { gap: 32px }  a { 14px; uppercase;
                     opacity: .7 } - and `display: flex` with no phone rule,
                     so the phone header also carried a full-size Join button
     port (rru.css)  .nav-links { gap: 4px }   a { .9375rem; sentence case;
                     44px hit target } and hidden below 900px

   The port treatment is the approved one and is restated here so both
   families render it. Equal specificity, and this sheet loads after
   style.css, so these win without !important. */

/* THE BAR ITSELF. Measured, the same markup produced two different headers:

     legacy page (style.css)   .nav 88px tall - padding 20px 40px, and the
                               logo anchor `display:block` with no padding, so
                               the mark had a 25px-tall hit target
     port page   (rru.css)     .nav 69px tall - padding 10px/gutter, logo
                               anchor inline-flex with a 48px minimum

   The port treatment is the approved one: it matches work/preview/index.html
   exactly at both review sizes (nav 69px, logo anchor 144x48, toggle 48x48).
   Restated here so legacy pages render the approved header too.

   The 69px is not a magic number - it is 10px + 48px + 10px + the 1px border,
   and verify_items_2_3.py asserts the measured bar height against the hero's
   reserved clearance rather than against a literal. */
.nav {
  padding: 10px 64px;
  display: flex; align-items: center;

  /* The approved SURFACE, measured off work/preview/index.html: a translucent
     dark bar with a blur and a hairline, 24px between groups, and default
     justification (the port spaces the groups with auto margins on
     `.nav-links` / `.nav-actions` below - `space-between`, which style.css
     sets, fights those and produced different gaps on the two families). */
  gap: 24px;
  justify-content: normal;
  background: rgba(8,0,16,.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(255,255,255,.1);
}

/* NOT position. The approved header is `position: sticky` and the port pages
   already are; style.css makes the legacy header `fixed` (131) and the 152
   backfilled pages lay out under that assumption. Swapping them to sticky
   would insert 69px of flow at the top of every one of them, which is a
   structural change to pages this pass has no way to review. The homepage
   composition reserves the bar's height explicitly instead (see the clearance
   note on .hero--doorlist in rru.css), and check_bar_overlap.py asserts that
   no candidate page starts its content underneath the bar. */
@media (max-width: 899px) { .nav { padding: 10px 20px; } }

/* style.css:143 gives `.nav.scrolled` `padding: 14px 40px` at (0,2,0), so the
   legacy header CHANGED HEIGHT the moment main.js added the class past 60px
   of scroll - an 8px jump on every page load that scrolled. Matched to the
   resting padding at the same specificity so the bar stays put. */
.nav.scrolled { padding: 10px 64px; }
@media (max-width: 899px) { .nav.scrolled { padding: 10px 20px; } }

/* Notched phones: style.css folded the safe-area inset into its own
   padding-top (3005/3012). Overriding `padding` wholesale would have dropped
   it, so it is restated. env() resolves to 0 where there is no inset. */
@supports (padding: env(safe-area-inset-top)) {
  .nav { padding-top: calc(10px + env(safe-area-inset-top)); }
}

/* The mark's anchor. style.css styles `.nav-logo` as display text (font-size,
   letter-spacing, text-shadow) because the legacy mark was a word, not an
   image; with an image inside, that left a 25px-tall tap target. */
.nav-logo {
  flex: none; display: inline-flex; align-items: center;
  min-height: 48px; line-height: 0; padding: 0 6px; margin-left: -6px;
}

.nav-links {
  display: none; margin: 0 auto 0 12px; padding: 0; list-style: none; gap: 4px;
}
@media (min-width: 900px) { .nav-links { display: flex; } }
.nav-links a, .nav-more-btn {
  display: inline-flex; align-items: center; min-height: 48px; padding: 0 14px;
  font-size: 0.9375rem; font-weight: 500; letter-spacing: normal;
  text-transform: none; opacity: 1; color: #fff; text-decoration: none;
  border-radius: 10px; background: none; border: 0; cursor: pointer;

  /* NOT `inherit`. The two families define --font-body differently -
     style.css:18 has 'DM Sans','Inter',sans-serif and rru.css:15 has
     'DM Sans','Inter',system-ui,sans-serif - so inheriting handed the nav a
     different fallback chain on each, and the same word measured 74px on one
     page and 72px on the other. Identical by declaration rather than by two
     token definitions happening to agree. */
  font-family: 'DM Sans', 'Inter', system-ui, sans-serif;
}
.nav-links a:hover, .nav-more-btn:hover {
  background: rgba(255,255,255,.07); opacity: 1; text-shadow: none;
}
.nav-more-btn::after {
  content: "\25BE"; margin-left: 6px; font-size: 0.75rem; opacity: .7;
}
.nav-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
/* THE PHONE HEADER IS LOGO AND TOGGLE. Join lives in the drawer and in the
   page's own signup flow; a full-size Join in a 390px header crowded the
   toggle and differed from every generated page. */
@media (max-width: 899px) { .nav-actions .btn { display: none; } }

/* --------------------------------------------------------- More disclosure */
.nav-more { position: relative; }
.nav-more-panel {
  display: none;                     /* THE RULE style.css does not have */
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  min-width: 12rem; padding: 6px; border-radius: 10px;
  background: #160033; border: 1px solid rgba(255,255,255,.18);
  box-shadow: 0 18px 40px rgba(0,0,0,.55);
}
.nav-more-panel a {
  display: flex; align-items: center; min-height: 44px; padding: 0 12px;
  border-radius: 8px; color: #fff; text-decoration: none; font-size: 0.9375rem;
  white-space: nowrap;
}
.nav-more-panel a:hover { background: rgba(255,255,255,.08); }
/* Without JavaScript the panel opens on hover and on :focus-within, so the
   destinations behind More stay reachable and the button claims no state.
   js/rru-chrome.js adds .rru-js-nav, which switches these off and hands the
   panel to the button's own aria-expanded - exactly one mechanism at a time,
   so what is announced can never contradict what is visible. */
:root:not(.rru-js-nav) .nav-more:hover .nav-more-panel,
:root:not(.rru-js-nav) .nav-more:focus-within .nav-more-panel { display: block; }
.rru-js-nav .nav-more-panel.is-open { display: block; }

/* --------------------------------------------------------- the toggle */
/* The SAME omission as the drawer, one element earlier. The shared nav emits
   `<button class="nav-toggle"><span class="bar"></span></button>` and relies on
   ::before/::after for the other two lines; production's style.css expects
   three <span> children and styles those, so on every page it owns the
   hamburger rendered as ONE bare line under the header. Visible in the mobile
   capture, invisible to any markup test. */
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  background: none; border: 1px solid rgba(255,255,255,.18);
  border-radius: 10px; color: #fff; cursor: pointer; padding: 0;
}
@media (min-width: 900px) { .nav-toggle { display: none; } }
.nav-toggle .bar {
  display: block; width: 20px; height: 2px; background: currentColor;
  position: relative;
}
.nav-toggle .bar::before, .nav-toggle .bar::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 2px;
  background: currentColor;
}
.nav-toggle .bar::before { top: -6px; }
.nav-toggle .bar::after  { top: 6px; }

/* --------------------------------------------------------------- the drawer */
/* THE SHARED DRAWER OWNS ITS OWN PRESENTATION.
 *
 * An earlier version of this file deliberately left style.css in control, on
 * the reasoning that overriding it would change 152 pages for no reason. The
 * capture showed why that was wrong: the SAME markup looked like two different
 * components depending on which page it was on. Measured on the homepage -
 *
 *   .mobile-menu  z-index 99   -> painted UNDER both of these
 *   .nav          z-index 100  -> the header's Join button competed above it
 *   .chat-widget  z-index 400  -> the chat FAB floated over the open drawer
 *
 * - plus 36px display type that pushed eight links past a short viewport with
 *   no way to scroll, a centred Close, and a second oversized Join.
 *
 * The transition stays style.css's (opacity/visibility on .open) so the drawer
 * animates exactly as it does today; everything below is layout, sizing and
 * stacking, which is what was inconsistent. */

/* ABOVE EVERYTHING, and "everything" was measured rather than assumed. The
   first pass used 500, which cleared .chat-widget (400) and .nav (100) but not
   three widgets that only show up in a live DOM:

     #rru-sfx-toggle    9999   the SFX button, bottom left
     .rru-pulse-bar     9996   the beat bar along the bottom edge
     .audio-artist-info 1000   the now-playing panel

   None of them appears in style.css by those names; they are created at
   runtime. Enumerating every fixed, visible, positive-z element in the open
   page found them. The drawer sits above all of it, and they are hidden while
   it is open so nothing behind a full-screen overlay stays clickable. */
.mobile-menu.open { z-index: 10000; }

/* Short screens and enlarged text: the panel scrolls INTERNALLY, and the Close
   control stays reachable because it is pinned to the top of that scroller
   rather than centred in a column that has overflowed. `justify-content` is
   reset from production's `center`, which is what pushed the last links out of
   reach once the list grew past the viewport. */
.mobile-menu {
  justify-content: flex-start; align-items: stretch;
  gap: 0; padding: 12px 20px calc(24px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto; overscroll-behavior: contain;
}
.mobile-menu ul { list-style: none; margin: 0; padding: 0; width: 100%; }
.mobile-menu li { margin: 0; }
/* Compact, readable, comfortably tappable: 1.375rem instead of 36px, a 56px
   row, and a rule between items so eight links read as a list rather than a
   stack of headlines. */
/* THE LIST OWNS ITS OWN TYPE, including the properties it used to inherit.
   This rule set only `font-size` and `letter-spacing`, so everything else came
   from whichever sheet the page happened to load: on a legacy page
   `style.css:212` supplied `font-family: display`, `font-weight: 800` and
   `text-transform: uppercase`, while a port page supplied none of them. The
   same drawer therefore read EVENTS / GALLERY / JOIN FUN CLUB on the homepage
   and Events / Gallery / Join Fun Club on a detail page. Title case is the
   selected treatment, so it is declared here rather than left to inheritance. */
.mobile-menu a {
  display: flex; align-items: center; min-height: 56px;
  font-family: 'Clash Display', 'Arial Black', sans-serif;
  font-size: 1.375rem; font-weight: 700; letter-spacing: .04em;
  text-transform: none;
  color: #fff; text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,.10);
}
.mobile-menu .btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%; margin-top: 20px; min-height: 52px;
  font-size: 1rem; letter-spacing: .04em;
  /* `.mobile-menu .btn` (0,2,0) outranks `.mobile-menu a` (0,1,1), so the
     button needs its own copy or Join alone would keep the inherited casing. */
  text-transform: none;
}
/* The drawer's Join is a PRIMARY button and takes the primary treatment: dark
   text on pink, like every other primary action on the site. `.mobile-menu a`
   sets a light colour for the link list and was winning on source order, so
   the one button in the drawer came out white-on-pink while the doorcard's
   identical button was dark. Stated explicitly rather than left to ordering. */
.mobile-menu a.btn-primary,
.mobile-menu .btn-primary { color: #12000a; background: #ff2d87; }
.mobile-menu a.btn-primary:hover { background: #ff4d9c; color: #12000a; }

/* Close: top right, stable, and never scrolled away from. */
.menu-close-row {
  display: flex; justify-content: flex-end; align-items: center;
  position: sticky; top: 0; z-index: 1;
  margin: 0 0 4px; padding: 4px 0 8px;
  background: rgba(8,0,16,0.96);
}
/* EXPLICIT BOX, not a minimum. Stating `min-width`/`min-height` left the final
   size to whatever else declared `width`/`height`: on a legacy page nothing
   did, so the control resolved to its 44px minimum, while on a port page
   `rru.css:258` supplied `width/height: var(--tap)` and it came out 48px. Two
   different circles in two captures of the same drawer. Fixed at 48px on both
   - comfortably over the 44px touch-target floor - with box-sizing and padding
   stated so no other sheet can grow it. */
.menu-close {
  box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; min-width: 48px; min-height: 48px; padding: 0;
  background: none; border: 1px solid rgba(255,255,255,.18); border-radius: 9999px;
  color: #fff; font-family: inherit; font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}
.menu-close:hover, .menu-close:focus-visible { border-color: #ff2d87; color: #ff2d87; }

/* THE BACKGROUND STOPS RESPONDING while the drawer is open, and comes back
   when it closes. Without this the chat FAB and the SFX toggle stayed
   clickable underneath a full-screen overlay - and one of them sat visually
   on top of it. Driven by the class js/rru-chrome.js already sets and clears,
   so there is no second source of truth. */
body.rru-drawer-open { overflow: hidden; }
body.rru-drawer-open .chat-widget,
body.rru-drawer-open .chat-toggle,
body.rru-drawer-open #rru-sfx-toggle,
body.rru-drawer-open .sfx-toggle,
body.rru-drawer-open .rru-pulse-bar,
body.rru-drawer-open .audio-artist-info,
body.rru-drawer-open .bpm-badge,
body.rru-drawer-open .hero-video-play { visibility: hidden; pointer-events: none; }

/* ------------------------------------------------------------- focus target */
/* The skip link's destination. Zero-height and unfocusable by pointer, but a
   valid programmatic focus target, so "skip to content" actually lands. */
#rru-main { scroll-margin-top: 80px; }
#rru-main:focus { outline: none; }
