/* ==========================================================================
   apprised.news — site-nav.css  (UNIFIED)
   ONE shared stylesheet for the primary nav on every page family:
     • SPA            public/index.html        leaves = <button data-view>
     • signals.html + 16 static legal/info pages  leaves = <a href>
     • server-rendered /story/ /desk/ /analyst/ /topic/ /entity/  leaves = <a href>
   Pairs with site-nav.js. This file owns LAYOUT + LOOK + ANIMATION only.

   WHY IT LOOKS IDENTICAL ON EVERY PAGE
   ------------------------------------
   The page families declare different, conflicting host variables (--bg1 vs
   --bg vs --bg2, --gold tones ...). To stay pixel-identical the nav reads NONE
   of them: it declares a private --nv-* palette keyed off the [data-theme]
   attribute every <html> already carries (localStorage 'apprised-theme',
   toggled elsewhere). A host page can restyle its body freely; the nav chrome
   does not move.

   FIXED MARKUP CONTRACT
     header (page banner, sticky)
       button#navToggleBtn[aria-controls=mainNav][aria-expanded]   hamburger
       nav#mainNav
         .nav-btn                                                  leaf
         .nav-group[data-group]                                    submenu
           > button.nav-group-btn.nav-btn[aria-haspopup][aria-expanded]
           > .nav-dropdown[role=menu]  >  .nav-btn[role=menuitem]   leaves
   STATE CLASSES (set by site-nav.js only):
     #mainNav.open  drawer open · .nav-group.open / .nav-dropdown.open  submenu open

   MOBILE FLICKER FIX (the reported bug)
   -------------------------------------
   The old code portaled each dropdown to <body> as position:fixed and
   re-anchored it to its trigger with getBoundingClientRect() on every scroll.
   On iOS that recompute lagged the scroll, so the panel blinked. Here EVERY
   dropdown stays in normal document flow: desktop = position:absolute inside
   its .nav-group; mobile = an in-flow accordion inside the drawer. The drawer
   caps its height and scrolls its own content. Nothing is fixed, portaled, or
   re-anchored — there is nothing for a scroll listener to chase, so nothing
   can blink. Only the header is sticky.

   ANIMATION
   ---------
   Open/close height animates with max-height + opacity. (We deliberately do
   NOT use the grid 0fr->1fr trick: the drawer and dropdowns have MANY direct
   children, and that trick only collapses the FIRST child — the rest fall into
   implicit auto rows and never collapse. max-height is robust with N children.)
   Desktop dropdowns fade + scale + un-hide via visibility (display:none can't
   animate). The caret rotates 180deg. Open uses an expressive ease-out; close
   uses the standard curve. All of it is killed under prefers-reduced-motion.

   !! INTEGRATION NOTE (load order is load-bearing) !!
   ---------------------------------------------------
   Reference this AFTER any page's inline <head> styles so it wins over legacy
   inline #mainNav / .nav-* rules (e.g. an old `#mainNav{display:none}` would
   otherwise defeat the mobile drawer). Selectors are id/class-scoped for
   specificity parity, so a later-loaded sheet is the clean, reliable override.
   ========================================================================== */

/* ---- Private palette (never inherits host tokens) ------------------------ */
:root,
[data-theme="dark"]{
  --nv-bg:        #0b1018;            /* drawer / dropdown surface           */
  --nv-bg-elev:   #161d2b;            /* hovered / nested surface            */
  --nv-header-bg: rgba(8,12,20,.92);  /* sticky-header backdrop              */
  --nv-border:    #222b45;
  --nv-txt:       #e6e9f0;            /* primary text / hover                */
  --nv-txt-dim:   #9ba4b8;            /* idle leaf label                     */
  --nv-txt-faint: #6c7589;            /* caret / ext arrow                   */
  --nv-gold:      #c9a84c;            /* brand accent (dark)                 */
  --nv-gold-dim:  rgba(201,168,76,.14);
  --nv-shadow:    0 10px 26px rgba(0,0,0,.45);
  --nv-focus:     #d8bd6e;            /* slightly brighter ring on dark      */
  --nv-radius:    6px;
  --nv-sans:      -apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --nv-serif:     Georgia,"Times New Roman",serif;
  /* motion tokens */
  --nv-dur:       .26s;               /* drawer + accordion height           */
  --nv-dur-fast:  .16s;               /* hover / caret / desktop dropdown    */
  --nv-ease:      cubic-bezier(.4,0,.2,1);    /* standard (close, hover)     */
  --nv-ease-out:  cubic-bezier(.16,1,.3,1);   /* expressive (open)           */
}
[data-theme="light"]{
  --nv-bg:        #ffffff;
  --nv-bg-elev:   #f1f3f5;
  --nv-header-bg: rgba(248,249,250,.95);
  --nv-border:    #dee2e6;
  --nv-txt:       #1a1a2e;
  --nv-txt-dim:   #495057;
  --nv-txt-faint: #6c757d;
  --nv-gold:      #92710c;            /* AA-safe gold on light (5.4:1)       */
  --nv-gold-dim:  rgba(146,113,12,.10);
  --nv-shadow:    0 10px 26px rgba(0,0,0,.14);
  --nv-focus:     #92710c;
}

/* ==========================================================================
   HEADER BAR CHROME — scoped to .site-header (static / server / signals).
   The SPA (index.html) header is #appHeader and keeps its own inline chrome,
   so we never touch it here.
   ========================================================================== */
.site-header{
  position:sticky; top:0; z-index:100;
  background:var(--nv-header-bg);
  -webkit-backdrop-filter:blur(12px);
  backdrop-filter:blur(12px);
  border-bottom:1px solid var(--nv-border);
}
.site-header .header-inner{
  max-width:1200px; margin:0 auto;
  padding:.6rem 1.25rem;
  display:flex; align-items:center; gap:1rem;
}
.site-header .logo{
  font:700 1.35rem var(--nv-serif);
  color:var(--nv-txt); text-decoration:none;
  letter-spacing:-.02em; white-space:nowrap;
  margin-right:auto;                 /* push the nav + controls to the right */
}
.site-header .logo:hover{text-decoration:none}
.site-header .logo .dot{color:var(--nv-gold)}
.site-header .logo .sep{color:var(--nv-txt-faint);margin:0 .15rem}
.site-header .logo .sub{color:var(--nv-txt-dim);font-weight:600;font-size:.9em}
.site-header .theme-toggle,
.site-header .global-search-btn{
  position:static;                   /* neutralise any leftover position:fixed
                                        from a page's old standalone toggle    */
  flex-shrink:0;
  background:transparent;
  border:1px solid var(--nv-border);
  color:var(--nv-txt);
  cursor:pointer; font:inherit;
  transition:border-color .15s, color .15s, background .15s;
}
.site-header .theme-toggle{
  width:36px; height:36px; border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:1.05rem; line-height:1;
}
.site-header .global-search-btn{padding:.35rem .6rem;border-radius:6px;font-size:.85rem}
.site-header .theme-toggle:hover,
.site-header .global-search-btn:hover{border-color:var(--nv-gold);color:var(--nv-gold)}

/* ==========================================================================
   1. NAV CONTAINER  (shared on every page)
   ========================================================================== */
#mainNav{
  display:flex; align-items:center; flex-wrap:wrap;
  gap:.15rem;
  margin-left:auto;                 /* sit to the right of the logo (desktop) */
}

/* ==========================================================================
   2. LEAF + GROUP BUTTONS (shared .nav-btn base)
   ========================================================================== */
#mainNav .nav-btn{
  display:inline-block;
  padding:.35rem .7rem;
  border:none; border-radius:4px;
  background:transparent;
  color:var(--nv-txt-dim);
  font-family:var(--nv-sans);
  font-size:.82rem; font-weight:500; line-height:1.3;
  text-align:left; text-decoration:none;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
  transition:color var(--nv-dur-fast) var(--nv-ease),
             background var(--nv-dur-fast) var(--nv-ease);
}
@media (hover:hover) and (pointer:fine){
  #mainNav .nav-btn:hover{color:var(--nv-txt);background:var(--nv-bg-elev);text-decoration:none}
}
#mainNav a.nav-btn:hover{text-decoration:none}

/* Active leaf + active ancestor group. */
#mainNav .nav-btn.active{color:var(--nv-gold);background:var(--nv-gold-dim)}
#mainNav .nav-group.active > .nav-group-btn,
#mainNav .nav-group > .nav-group-btn.active{color:var(--nv-gold);background:var(--nv-gold-dim)}
#mainNav .nav-btn .ext-arrow{font-size:.62rem;color:var(--nv-txt-faint);margin-left:.2rem;opacity:.75}

/* Group block + caret. */
#mainNav .nav-group{position:relative;display:inline-block;vertical-align:middle}
#mainNav .nav-group-btn{display:inline-flex;align-items:center;gap:.25rem;user-select:none}
#mainNav .nav-group-btn::after{
  content:"\25BE";                  /* down caret */
  font-size:.65rem;line-height:1;color:var(--nv-txt-faint);
  transition:transform var(--nv-dur-fast) var(--nv-ease);
}
#mainNav .nav-group.open > .nav-group-btn::after{transform:rotate(180deg)}

/* ==========================================================================
   3. HAMBURGER  (hidden on desktop; revealed by the <=880px block).
   Styled by #id so it is consistent on every page family.
   ========================================================================== */
#navToggleBtn{
  display:none;
  align-items:center; justify-content:center; gap:.35rem;
  padding:.4rem .65rem;
  border:1px solid var(--nv-border); border-radius:var(--nv-radius);
  background:transparent; color:var(--nv-txt);
  font-family:var(--nv-sans); font-size:1.05rem; font-weight:500; line-height:1;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent; touch-action:manipulation;
  transition:color var(--nv-dur-fast) var(--nv-ease),
             background var(--nv-dur-fast) var(--nv-ease),
             border-color var(--nv-dur-fast) var(--nv-ease);
}
@media (hover:hover) and (pointer:fine){
  #navToggleBtn:hover{border-color:var(--nv-gold);color:var(--nv-gold)}
}
#navToggleBtn[aria-expanded="true"]{
  background:var(--nv-gold-dim);color:var(--nv-gold);border-color:var(--nv-gold);
}
#navToggleBtn .nt-label{font-size:.8rem;letter-spacing:.04em}

/* ==========================================================================
   4. DESKTOP  (>= 881px)
   Absolute, in-flow dropdowns. Fade + scale + un-hide via visibility (so the
   panel is inert + out of the a11y tree while closed yet still transitionable).
   The visibility transition is delayed on close so the fade finishes first.
   No portal, no JS positioning math.
   ========================================================================== */
@media (min-width:881px){
  #mainNav .nav-dropdown{
    position:absolute;
    top:calc(100% + 6px);
    right:0;                                  /* right-anchored, never overflows */
    min-width:200px;
    max-height:min(70vh,560px);
    overflow-y:auto;
    overscroll-behavior:contain;
    display:flex; flex-direction:column; gap:.05rem;
    padding:.35rem;
    background:var(--nv-bg);
    border:1px solid var(--nv-border);
    border-radius:var(--nv-radius);
    box-shadow:var(--nv-shadow);
    z-index:300;
    /* closed */
    opacity:0; visibility:hidden; pointer-events:none;
    transform:translateY(-4px) scale(.98);
    transform-origin:top right;
    transition:opacity var(--nv-dur-fast) var(--nv-ease),
               transform var(--nv-dur-fast) var(--nv-ease),
               visibility 0s linear var(--nv-dur-fast);
  }
  #mainNav .nav-group.open > .nav-dropdown,
  #mainNav .nav-dropdown.open{
    opacity:1; visibility:visible; pointer-events:auto;
    transform:translateY(0) scale(1);
    transition:opacity var(--nv-dur-fast) var(--nv-ease-out),
               transform var(--nv-dur-fast) var(--nv-ease-out),
               visibility 0s linear 0s;
  }
  #mainNav .nav-dropdown .nav-btn{
    width:100%; padding:.55rem .65rem; font-size:.84rem;
    white-space:nowrap; border-radius:5px;
  }
}

/* ==========================================================================
   5. MOBILE  (<= 880px)
   In-flow drawer below the header; accordion submenus. Height animates with
   max-height; once open the drawer caps its height and scrolls its own
   content. Nothing fixed/portaled/re-anchored => no scroll flicker.
   ========================================================================== */
@media (max-width:880px){
  #navToggleBtn{display:inline-flex}

  /* Drawer container: collapsed by default, animates open. The base
     overflow:hidden clips during the height transition; .open swaps in
     internal scrolling once expanded. */
  #mainNav{
    order:99; width:100%; margin:0; gap:0;
    flex-direction:column; align-items:stretch; flex-wrap:nowrap;
    background:var(--nv-bg);
    max-height:0; overflow:hidden; opacity:0;
    border-top:1px solid transparent;
    transition:max-height var(--nv-dur) var(--nv-ease),
               opacity var(--nv-dur) var(--nv-ease),
               border-color var(--nv-dur) var(--nv-ease);
  }
  #mainNav.open{
    max-height:calc(100dvh - var(--nv-header-h,64px));
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
    opacity:1;
    border-top-color:var(--nv-border);
    transition:max-height var(--nv-dur) var(--nv-ease-out),
               opacity var(--nv-dur) var(--nv-ease-out),
               border-color var(--nv-dur) var(--nv-ease-out);
  }

  /* Top-level rows. */
  #mainNav > .nav-btn,
  #mainNav > .nav-group > .nav-group-btn{
    width:100%; padding:.8rem .95rem; border-radius:0; text-align:left;
    border-bottom:1px solid var(--nv-border); font-size:.95rem;
  }
  #mainNav > .nav-btn:last-child{border-bottom:none}
  #mainNav .nav-group{display:block; width:100%; position:static}
  #mainNav .nav-group-btn{justify-content:space-between}
  #mainNav .nav-group-btn::after{margin-left:.5rem}

  /* Accordion submenu: max-height animation, in flow. 40rem clears the
     largest group's content (9 items, even with wrapped labels) so it is
     never clipped; the parent drawer scrolls if the total exceeds the
     viewport. */
  #mainNav .nav-dropdown{
    display:flex; flex-direction:column;
    background:var(--nv-bg-elev);
    border:none; border-radius:0; box-shadow:none; padding:0; min-width:0;
    max-height:0; overflow:hidden; opacity:0;
    transition:max-height var(--nv-dur) var(--nv-ease),
               opacity var(--nv-dur) var(--nv-ease);
  }
  #mainNav .nav-group.open > .nav-dropdown,
  #mainNav .nav-dropdown.open{
    max-height:40rem; opacity:1;
    transition:max-height var(--nv-dur) var(--nv-ease-out),
               opacity var(--nv-dur) var(--nv-ease-out);
  }
  #mainNav .nav-dropdown .nav-btn{
    width:100%; padding:.68rem .9rem .68rem 1.5rem; font-size:.9rem;
    white-space:normal; border-bottom:1px solid var(--nv-border);
  }

  /* .site-header layout on mobile: the Menu button is ABSOLUTELY pinned to the
     top-right so flex-wrapping can never push it left/middle (the header carries
     logo + Subscribe + search + theme + Menu, which overflow and wrap on narrow
     screens — an order/margin approach loses the right-push on the wrapped line).
     Content reserves right padding so nothing underlaps it; the nav drawer wraps
     to its own full-width row below. */
  .site-header .header-inner{position:relative; flex-wrap:wrap; gap:.5rem; padding:.55rem 1rem; padding-right:3.6rem}
  .site-header .logo{margin-right:0}                 /* don't push the controls into the Menu button */
  .site-header .theme-toggle,
  .site-header .global-search-btn,
  .site-header .nav-cta{order:2}
  .site-header #navToggleBtn{position:absolute; right:.8rem; top:.5rem; margin:0; z-index:2; padding:.4rem .55rem}
  .site-header #navToggleBtn .nt-label{display:none} /* icon-only ☰ on mobile so it can't overlap Subscribe/controls */
}

/* ==========================================================================
   6. ACCESSIBILITY
   ========================================================================== */
#mainNav .nav-btn:focus-visible,
#navToggleBtn:focus-visible,
.site-header .theme-toggle:focus-visible,
.site-header .global-search-btn:focus-visible{
  outline:2px solid var(--nv-focus); outline-offset:2px; border-radius:4px;
  color:var(--nv-txt);
}
/* Keep roving keyboard focus visible inside an open dropdown. */
#mainNav .nav-dropdown .nav-btn:focus{background:var(--nv-bg-elev);color:var(--nv-txt)}

/* ==========================================================================
   7. REDUCED MOTION — disable every transition/animation the nav introduces.
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  #mainNav, #mainNav *, #mainNav *::after,
  #navToggleBtn, #navToggleBtn *,
  .site-header .theme-toggle, .site-header .global-search-btn{
    transition:none !important; animation:none !important;
  }
}

/* ==========================================================================
   8. SUBSCRIBE CTA (T0.6) — persistent catch-basin in the header bar, on every
   server-rendered + static + SPA page. Gold filled pill.
   ========================================================================== */
.nav-cta{
  flex-shrink:0;
  display:inline-block;
  padding:.42rem .85rem;
  border-radius:5px;
  background:var(--nv-gold);
  color:#0b1018;
  border:1px solid var(--nv-gold);
  font-family:var(--nv-sans);
  font-size:.82rem; font-weight:700;
  text-decoration:none; white-space:nowrap; cursor:pointer;
  transition:filter .15s, background .15s, border-color .15s;
}
.nav-cta:hover{ filter:brightness(1.08); text-decoration:none; color:#0b1018; }
.nav-cta:focus-visible{ outline:2px solid var(--nv-focus); outline-offset:2px; }
@media (max-width:880px){ .nav-cta{ order:2; } }

/* ==========================================================================
   9. NO-JS DROPDOWN FALLBACK (T0.7) — on desktop, reveal a group's dropdown on
   hover/focus-within, but ONLY when site-nav.js has NOT run (no .site-nav-js on
   <html>). With JS on, the click-to-open persistence stays exactly as designed;
   with JS off (or before boot), keyboard + no-JS users can still reach the 23
   grouped views.
   ========================================================================== */
@media (min-width:881px){
  html:not(.site-nav-js) #mainNav .nav-group:hover > .nav-dropdown,
  html:not(.site-nav-js) #mainNav .nav-group:focus-within > .nav-dropdown{
    opacity:1; visibility:visible; transform:translateY(0) scale(1); pointer-events:auto;
  }
}

/* ── Back-to-top button (paired with site-nav.js) ──────────────────────────
   Floating up-arrow that fades in after the reader scrolls down, so they can
   jump back to the top nav. Theme-aware (light/dark via --nv-* tokens),
   focus-visible, respects prefers-reduced-motion. */
.to-top{
  position:fixed; right:1.1rem; bottom:1.1rem; z-index:1100;
  width:44px; height:44px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; border:1px solid var(--nv-border);
  background:var(--nv-bg); color:var(--nv-gold); box-shadow:var(--nv-shadow);
  cursor:pointer; opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity var(--nv-dur-fast) var(--nv-ease),
             transform var(--nv-dur-fast) var(--nv-ease),
             visibility var(--nv-dur-fast) var(--nv-ease);
}
.to-top.visible{ opacity:1; visibility:visible; transform:translateY(0); }
.to-top:hover{ border-color:var(--nv-gold); background:var(--nv-bg-elev); }
.to-top:focus-visible{ outline:2px solid var(--nv-focus); outline-offset:2px; }
.to-top svg{ display:block; }
/* Don't cover the SPA's "Show breaking news" pill (also fixed bottom-right):
   lift the arrow above it whenever that pill is visible, so they never overlap. */
body:has(.ticker-show-btn.show) .to-top{ bottom:3.6rem; }
@media (max-width:880px){ .to-top{ right:.8rem; bottom:.8rem; width:42px; height:42px; } }
@media (prefers-reduced-motion: reduce){
  .to-top{ transition:opacity var(--nv-dur-fast) linear; transform:none; }
  .to-top.visible{ transform:none; }
}
