/* =============================================================
   Mountain Wubz — Night-sky atmosphere + redesigned nav.
   Shared between the public site (views/layouts/main.ejs) and the
   admin shell (views/layout.js). Atmosphere is purely background.
   Content layers must keep their own backgrounds to stay readable.

   Key constraints:
     - GPU-friendly transforms only (translate / opacity); never animate
       top/left/background-position.
     - prefers-reduced-motion: reduce kills ALL motion. Stars become a
       static dust layer; nav hover loses its glow pulse.
     - position: fixed + pointer-events: none on the star layer so it
       never intercepts clicks or scroll.
   ============================================================= */

/* ---- Star-layer container ---------------------------------------------- */
.mw-night-sky {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

/* The static "dust" layer — small low-opacity dots scattered via radial
   gradients. No animation. Provides depth even with reduced-motion on. */
.mw-night-sky::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(1px 1px at 12% 18%,  rgba(255,255,255,0.55), transparent 50%),
    radial-gradient(1px 1px at 28% 72%,  rgba(255,255,255,0.45), transparent 50%),
    radial-gradient(1px 1px at 47% 31%,  rgba(0,229,255,0.35),   transparent 50%),
    radial-gradient(1px 1px at 63% 84%,  rgba(255,255,255,0.55), transparent 50%),
    radial-gradient(1.5px 1.5px at 81% 22%, rgba(255,38,175,0.40), transparent 50%),
    radial-gradient(1px 1px at 92% 58%,  rgba(255,255,255,0.50), transparent 50%),
    radial-gradient(1px 1px at 7% 91%,   rgba(255,255,255,0.40), transparent 50%),
    radial-gradient(1px 1px at 38% 6%,   rgba(255,255,255,0.55), transparent 50%),
    radial-gradient(1.5px 1.5px at 55% 56%, rgba(0,229,255,0.35),  transparent 50%),
    radial-gradient(1px 1px at 71% 47%,  rgba(255,255,255,0.45), transparent 50%);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  opacity: 0.6;
}

/* Subtle aurora wash across the bottom — fixed gradient, no motion.
   Uses brand cyan/magenta at very low alpha so content cards stay
   readable but the backdrop feels alive. */
.mw-night-sky::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 30% at 20% 110%, rgba(0,229,255,0.10),   transparent 60%),
    radial-gradient(ellipse 70% 40% at 85% 105%, rgba(255,38,175,0.10),  transparent 60%),
    radial-gradient(ellipse 50% 25% at 60% -5%,  rgba(178,0,254,0.08),   transparent 60%);
  pointer-events: none;
}

/* ---- Shooting stars ---------------------------------------------------- */
/* Each star is an absolutely-positioned slim element with a magenta-to-
   cyan gradient body. We translate it diagonally with `transform` (GPU
   accelerated) and fade in/out via opacity. Six stars staggered with
   different delays/durations/angles produce subtle, non-meteor-shower
   activity.

   IMPORTANT (mobile rendering): the previous version used
   `filter: drop-shadow(...)` for the cyan glow. On mobile WebKit this
   creates an offscreen render layer that the compositor often skips
   under memory pressure — the entire star layer rendered fine on
   desktop but vanished on phones. We now use `box-shadow` for the
   halo (GPU-friendly, follows the rotated rectangle which is a
   reasonable approximation of the streak shape). `translateZ(0)` and
   `backface-visibility: hidden` force a stable GPU layer.

   The per-variant rotation angle is baked into its own keyframe rule
   (mw-shoot-N) — the legacy approach of setting rotate(...) on the
   base `transform` was dead code, since the shared keyframes always
   overrode it with `rotate(20deg)` on every transform step. */
.mw-shooter {
  position: absolute;
  top: -10%;
  left: -10%;
  width: 140px;
  height: 1.5px;
  border-radius: 999px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.85) 35%,
    #FF26AF 70%,
    #00E5FF 100%);
  opacity: 0;
  transform: translate3d(0, 0, 0) rotate(20deg);
  box-shadow:
    0 0 6px rgba(0, 229, 255, 0.55),
    0 0 14px rgba(255, 38, 175, 0.30);
  will-change: transform, opacity;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  animation: mw-shoot-1 9s linear infinite;
}

/* Distinct timing + angle per star so the cadence feels random. Each
   variant maps to its own keyframe so its rotation is preserved. */
.mw-shooter.s2 {
  top: 18%; left: -15%;
  width: 110px;
  animation: mw-shoot-2 11s linear infinite;
  animation-delay: 4s;
}
.mw-shooter.s3 {
  top: 8%; left: -10%;
  width: 160px;
  animation: mw-shoot-3 13s linear infinite;
  animation-delay: 8s;
}
.mw-shooter.s4 {
  top: 35%; left: -10%;
  width: 90px;
  animation: mw-shoot-4 10s linear infinite;
  animation-delay: 12s;
}
.mw-shooter.s5 {
  top: 50%; left: -10%;
  width: 130px;
  animation: mw-shoot-5 14s linear infinite;
  animation-delay: 16s;
}
.mw-shooter.s6 {
  top: 65%; left: -10%;
  width: 100px;
  animation: mw-shoot-6 12s linear infinite;
  animation-delay: 21s;
}

/* Six near-identical keyframes — the only change is the rotation
   angle per variant. They all run the same fade-in / streak / fade-
   out arc and end with a quiet period. */
@keyframes mw-shoot-1 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(20deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 7vh, 0) rotate(20deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 25vh, 0) rotate(20deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 45vh, 0) rotate(20deg); }
  100% { opacity: 0; transform: translate3d(120vw, 45vh, 0) rotate(20deg); }
}
@keyframes mw-shoot-2 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(15deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 5vh, 0) rotate(15deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 19vh, 0) rotate(15deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 33vh, 0) rotate(15deg); }
  100% { opacity: 0; transform: translate3d(120vw, 33vh, 0) rotate(15deg); }
}
@keyframes mw-shoot-3 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(25deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 9vh, 0) rotate(25deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 33vh, 0) rotate(25deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 56vh, 0) rotate(25deg); }
  100% { opacity: 0; transform: translate3d(120vw, 56vh, 0) rotate(25deg); }
}
@keyframes mw-shoot-4 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(18deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 6vh, 0) rotate(18deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 23vh, 0) rotate(18deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 39vh, 0) rotate(18deg); }
  100% { opacity: 0; transform: translate3d(120vw, 39vh, 0) rotate(18deg); }
}
@keyframes mw-shoot-5 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(22deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 8vh, 0) rotate(22deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 28vh, 0) rotate(22deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 49vh, 0) rotate(22deg); }
  100% { opacity: 0; transform: translate3d(120vw, 49vh, 0) rotate(22deg); }
}
@keyframes mw-shoot-6 {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(12deg); }
  8%   { opacity: 1; transform: translate3d(20vw, 4vh, 0) rotate(12deg); }
  18%  { opacity: 0.9; transform: translate3d(70vw, 15vh, 0) rotate(12deg); }
  25%  { opacity: 0; transform: translate3d(120vw, 26vh, 0) rotate(12deg); }
  100% { opacity: 0; transform: translate3d(120vw, 26vh, 0) rotate(12deg); }
}

/* Admin variant: even calmer. Lower opacity, stars take longer to cross,
   triggered roughly half as often. Functional readability comes first
   in admin so atmosphere stays restrained. */
body.mw-admin .mw-shooter {
  animation-duration: 18s;
  filter: drop-shadow(0 0 4px rgba(0,229,255,0.40));
}
body.mw-admin .mw-shooter.s2 { animation-duration: 22s; animation-delay: 9s; }
body.mw-admin .mw-shooter.s3 { animation-duration: 26s; animation-delay: 17s; }
body.mw-admin .mw-shooter.s4 { animation-duration: 20s; animation-delay: 25s; }
body.mw-admin .mw-shooter.s5 { animation-duration: 28s; animation-delay: 33s; }
body.mw-admin .mw-shooter.s6 { animation-duration: 24s; animation-delay: 41s; }
body.mw-admin .mw-night-sky::before { opacity: 0.45; }

/* Accessibility: kill all star motion when the user prefers reduced
   motion. Static dust layer + aurora wash remain so the look is still
   atmospheric but nothing moves. */
@media (prefers-reduced-motion: reduce) {
  .mw-shooter { animation: none !important; opacity: 0 !important; }
}

/* ---- Body wrapper for stacking ----------------------------------------
   The .mw-night-sky layer sits at z-index 0, fixed-position. To keep
   foreground content above it, wrap content layers in a positioned
   stacking context above the sky. We don't want to force every page
   wrapper to set z-index, so we set position:relative on common shell
   selectors here.
   ---------------------------------------------------------------------- */
body { position: relative; }
#site-header,
.mw-admin-topbar,
.mw-admin-sidebar,
.mw-admin-main,
.mw-admin-shell > main,
main,
footer {
  position: relative;
  z-index: 1;
}

/* =============================================================
   PUBLIC NAV — redesigned with brand cyan→magenta gradient
   underline-glow on hover/active. Replaces the legacy plain
   solid-pink underline that was site.css's .nav-link::after.
   ============================================================= */

/* Override the legacy nav-link styling defined in site.css. We keep
   .nav-link as the canonical class so the existing markup in
   views/layouts/main.ejs continues to work without churn. */
header#site-header .nav-link {
  font-family: var(--font-body, 'Plus Jakarta Sans', sans-serif);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: #fff;
  text-decoration: none;
  padding: 30px 20px;
  display: inline-block;
  position: relative;
  transition: color 200ms ease, text-shadow 200ms ease;
}

/* Underline track — invisible until hover/active. The track itself is a
   ::before so the existing ::after glow can layer over it. */
header#site-header .nav-link::before {
  content: '';
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 22px;
  height: 2px;
  background: linear-gradient(90deg, #00E5FF 0%, #B200FE 50%, #FF26AF 100%);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 240ms cubic-bezier(.65,.05,.36,1);
  border-radius: 1px;
}

/* Soft cyan/magenta glow under the nav link on hover/active. */
header#site-header .nav-link::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 18px;
  width: 60%;
  height: 8px;
  transform: translateX(-50%) scaleY(0);
  transform-origin: bottom;
  background: radial-gradient(ellipse at center,
    rgba(0,229,255,0.55), rgba(255,38,175,0.25) 60%, transparent 80%);
  filter: blur(6px);
  transition: transform 240ms ease, opacity 240ms ease;
  opacity: 0;
  pointer-events: none;
}

header#site-header .nav-link:hover,
header#site-header .nav-link:focus-visible,
header#site-header .nav-link.active {
  color: #fff;
  text-shadow: 0 0 14px rgba(0,229,255,0.55);
  outline: none;
}
header#site-header .nav-link:hover::before,
header#site-header .nav-link:focus-visible::before,
header#site-header .nav-link.active::before {
  transform: scaleX(1);
}
header#site-header .nav-link:hover::after,
header#site-header .nav-link:focus-visible::after,
header#site-header .nav-link.active::after {
  transform: translateX(-50%) scaleY(1);
  opacity: 1;
}

/* Logo glow — subtle drop-shadow on the header logo so it picks up
   the brand cyan against the night-sky background. */
header#site-header .header-logo img {
  filter: drop-shadow(0 0 12px rgba(0,229,255,0.35));
}

/* Mobile hamburger button — keyboard-accessible focus state */
#mobile-menu-btn {
  color: #fff;
  border-radius: 8px;
  transition: color 180ms ease, background 180ms ease;
}
#mobile-menu-btn:hover,
#mobile-menu-btn:focus-visible {
  color: #00E5FF;
  background: rgba(0,229,255,0.08);
  outline: none;
}

/* Mobile nav SIDE-DRAWER — slides from the right. Markup at body level
   in views/layouts/main.ejs (outside the sticky header so z-index isn't
   clipped). Hidden state is translateX(100%) — drawer stays in the DOM
   so focus-trap can work while open. JS toggles `.is-open` on both the
   drawer and the backdrop. `aria-hidden` flips in lockstep.

   Mobile (≤768px): 80% viewport width, max 320px.
   Desktop (>768px): half-page panel, 50% viewport, max 600px. (Defensive
   only — current header has md:hidden on the hamburger so the drawer is
   not normally reachable on desktop. If a future redesign exposes it,
   this rule sizes it correctly.)
*/
#mobile-menu-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 49;
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms ease;
}
#mobile-menu-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

#mobile-menu {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 80%;
  max-width: 320px;
  background: linear-gradient(180deg, #0a0a0a 0%, #11061b 100%);
  border-left: 1px solid rgba(0, 229, 255, 0.18);
  box-shadow: -16px 0 40px rgba(0, 0, 0, 0.5);
  z-index: 50;
  transform: translateX(100%);
  transition: transform 280ms cubic-bezier(.65, .05, .36, 1);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 60px 0 24px;
}
#mobile-menu.is-open {
  transform: translateX(0);
}
@media (min-width: 769px) {
  /* Half-page desktop hamburger panel (defensive — see comment above). */
  #mobile-menu { width: 50%; max-width: 600px; }
}

/* Drawer close button — top-right inside the drawer */
#mobile-menu .mobile-menu-close {
  position: absolute;
  top: 12px;
  right: 12px;
  background: transparent;
  border: 0;
  color: #fff;
  padding: 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: color 180ms ease, background 180ms ease;
}
#mobile-menu .mobile-menu-close:hover,
#mobile-menu .mobile-menu-close:focus-visible {
  color: #00E5FF;
  background: rgba(0, 229, 255, 0.08);
  outline: none;
}

#mobile-menu .nav-link {
  display: block;
  padding: 14px 24px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  font-size: 13px;
  font-weight: 600;
  position: relative;
  transition: color 180ms ease, background 180ms ease;
}
#mobile-menu .nav-link:hover,
#mobile-menu .nav-link:focus-visible,
#mobile-menu .nav-link.active {
  color: #00E5FF;
  background: linear-gradient(90deg, rgba(0, 229, 255, 0.10), rgba(255, 38, 175, 0.04));
  outline: none;
}
#mobile-menu .nav-link::before,
#mobile-menu .nav-link::after {
  content: none; /* don't apply desktop underline-glow inside the drawer */
}

/* Body scroll-lock helper — JS sets `.mw-drawer-open` on <body> while
   the drawer is open to prevent background scroll behind the overlay. */
body.mw-drawer-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  #mobile-menu,
  #mobile-menu-backdrop { transition: none; }
  header#site-header .nav-link,
  header#site-header .nav-link::before,
  header#site-header .nav-link::after {
    transition: none !important;
  }
}
