/* ──────────────────────────────────────────────────────────
   NAV — shared across every page
   Sourced from the homepage nav. Wordmark uses the ARCHIVE
   variant only (the variant cycler was removed). Per-gallery
   accent colors for the ART dropdown active state are
   defined in each gallery's own CSS via --astro / --plate /
   default --red.
   ────────────────────────────────────────────────────────── */

/* Global dark baseline. nav.css is loaded on every page and never
   pruned by Swup, so this guarantees there's never a frame of
   "browser-default white" between per-page CSS being pruned and the
   new per-page CSS being applied during Swup navigation. Per-page CSS
   may still override <body>'s background where it wants something
   different. */
html, body { background: #000; }

/* Fallback custom property values. nav.css references --bright / --mid /
   --dim / --border in multiple rules below. Most pages load a per-page
   stylesheet (index.css / music.css / etc.) that defines :root with
   these values, but a couple of leaf pages (terms.html, 404.html) only
   load nav.css. Without these fallbacks, var(--bright) inside .nav-
   wordmark resolves to nothing and the wordmark inherits the browser's
   default :visited link color (purple) from the <a class="nav-logo">
   parent. Page-level :root rules override these — minimal blast radius. */
:root {
  --bright: #f0ece0;
  --text:   #d4d0c8;
  --light:  #999;
  --mid:    #666;
  --dim:    #444;
  --border: #1e1e1e;
  --red:    #c0392b;
}

/* Belt-and-suspenders: explicitly opt the nav-logo (and its descendants)
   out of the :visited color cascade so the wordmark always renders in
   --bright regardless of which page is loaded or whether the user has
   visited the linked target. */
.nav-logo,
.nav-logo:visited,
.nav-logo:hover,
.nav-logo:active {
  color: var(--bright);
}

/* 2026-05-18 — Nav height as a CSS variable so mobile can bump it for
   breathing room without breaking every dependent margin-top/top/inset.
   Desktop stays at 44px (Chris locked this in via iteration). Mobile
   bumps to 56px because Chris reported the wordmark + hamburger felt
   cramped against the browser URL bar on Chrome/Safari mobile.
   Update both files together if either changes. */
:root { --nav-h: 44px; }
@media (max-width: 768px) {
  :root { --nav-h: 56px; }
}

nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  /* 2026-05-17 — was `border-bottom: 1px solid var(--border)` which
     drew a hard hairline between nav and hero/content. Chris flagged
     it as harsh. Replaced with a soft 24px linear-gradient fade
     below the nav so the transition reads as atmospheric depth
     rather than a hard rule. Pseudo-element so it doesn't push
     content. */
  background: rgba(0,0,0,0.92);
  backdrop-filter: blur(8px);
}
nav::after {
  content: '';
  position: absolute;
  top: 100%; left: 0; right: 0;
  height: 24px;
  background: linear-gradient(to bottom, rgba(0,0,0,0.92), rgba(0,0,0,0));
  pointer-events: none;
  z-index: -1;
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  text-decoration: none;
}
.nav-logo-mark { display: none; }

/* ─── WORDMARK (ARCHIVE variant: dotted leader between names) ─── */
.nav-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0;
  color: var(--bright);
  user-select: none;
  position: relative;
  white-space: nowrap;
  line-height: 1;
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  text-transform: uppercase;
}
.nav-wordmark .nw-l {
  display: inline-block;
  line-height: 1;
  font-size: 13px;
  letter-spacing: 3px;
  padding-right: 3px;
  transition: color 0.25s ease;
}
.nav-wordmark .nw-leader {
  display: inline-block;
  width: 14px;
}

/* ─── NAV LINKS ─── */
.nav-links {
  display: flex;
  align-items: center;
  gap: 0;
}
.nav-link {
  padding: 0 14px;
  height: 44px;
  display: flex;
  align-items: center;
  font-size: 11px;
  letter-spacing: 1.5px;
  /* 2026-05-16 — labels brightened from --mid (#666) to --light (#999) so
     the inactive items read clearly without competing with --bright (the
     active/selected state). Borders/brackets/carets unchanged so the
     overall structural frame stays the same gray. */
  color: var(--light);
  border-left: 1px solid var(--border);
  transition: color 0.12s, background 0.12s;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  /* 2026-05-18 — kill iOS tap-zoom delay and the default blue/gray tap
     flash so the :active state below owns the feedback. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.nav-link:hover { color: var(--bright); background: rgba(255,255,255,0.03); }
.nav-link.active { color: var(--bright); }
/* 2026-05-18 — Instant tap-ack on the top-nav. Per Chris: HOME / ART /
   MUSIC / MOTION / ABOUT clicks "feel slow" because there's no visible
   state change between tap and Swup's HTML-fetch dim. Light red wash on
   active gives an immediate cue that the click registered. Applies to
   both the plain .nav-link and the .nl-toplink inside dropdown labels. */
.nav-link:active,
.nav-link.dropdown > .nl-toplink:active {
  color: var(--bright);
  background: rgba(192, 57, 43, 0.18);
}
.nav-link .bracket { color: var(--dim); }
.nav-link .caret { color: var(--dim); margin-left: 6px; font-size: 9px; }

/* Clickable dropdown label — the <a class="nl-toplink"> that wraps
   the ART / MUSIC / MOTION / ABOUT label text inside a .nav-link
   .dropdown. Clicking the label routes to the section's default
   destination (assemblage / music / transmissions / about). Hover
   still opens the menu via the parent .dropdown:hover rule, so the
   menu items remain accessible.
   The :visited override prevents the browser-default purple from
   bleeding through once any of those destinations have been visited. */
.nav-link.dropdown > .nl-toplink,
.nav-link.dropdown > .nl-toplink:visited,
.nav-link.dropdown > .nl-toplink:hover,
.nav-link.dropdown > .nl-toplink:active {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* ─── DROPDOWNS ─── */
.dropdown { position: relative; }
.dropdown-menu {
  position: absolute; top: 100%; left: 0; min-width: 200px;
  background: #050505; border: 1px solid var(--border);
  display: none; flex-direction: column;
  z-index: 110;
}
.dropdown:hover .dropdown-menu { display: flex; }
.dropdown-menu a {
  /* 2026-05-16 v8 — bumped 11→12 to match nav-link font-size. */
  padding: 10px 14px; font-size: 12px; letter-spacing: 1.5px; color: var(--light);
  border-bottom: 1px solid var(--border); transition: color 0.15s, background 0.15s;
  text-decoration: none;
}
.dropdown-menu a:last-child { border-bottom: none; }
.dropdown-menu a:hover { color: var(--bright); background: rgba(192,57,43,0.08); }
/* default active color — per-page CSS can override (e.g. AETHERZ uses --astro,
   PLATES uses --plate) */
.dropdown-menu a.active { color: var(--red); }

/* ─── SOCIAL LINKS (used in nav and footer) ─── */
.social-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid var(--border); border-radius: 2px;
  color: var(--mid);
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.social-link:hover { color: var(--bright); border-color: var(--red); background: rgba(192,57,43,0.06); }
.social-link svg { width: 14px; height: 14px; fill: currentColor; display: block; }

.nav-social {
  display: flex; align-items: center; gap: 8px;
  padding: 0 14px; height: 44px;
  border-left: 1px solid var(--border);
}
.nav-social .social-link { width: 26px; height: 26px; border: none; }
.nav-social .social-link svg { width: 13px; height: 13px; }
.nav-social .social-link:hover { background: transparent; }

/* 2026-05-16 — PFP added as the 3rd item in the nav social cluster
   (Instagram · X · Profile). Circle avatar at ~24px so it sits in the
   same visual weight as the IG/X glyph icons. Links to /about. */
.nav-social .nav-pfp {
  width: 26px; height: 26px;
  border-radius: 50%;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border2);
  transition: border-color 0.2s, transform 0.2s;
}
.nav-social .nav-pfp img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.nav-social .nav-pfp:hover { border-color: var(--red); transform: scale(1.05); }

/* ─── UNIVERSAL FOOTER ────────────────────────────────────────────────
   2026-05-16 — moved here from index.css so every page (not just home)
   gets the same footer treatment. Desktop: thin centered © line only.
   Mobile: Instagram · X · PFP row, then © below. */
footer {
  border-top: 1px solid var(--border);
  padding: 0 20px 28px;
  display: flex;
  align-items: stretch;
}
.footer-block {
  padding: 16px 20px;
  border-right: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10px;
  color: var(--dim);
  letter-spacing: 1.5px;
}
.footer-block:first-child { padding-left: 0; }
.footer-block:last-child { border-right: none; margin-left: auto; }
.footer-block .cr-mark {
  display: inline-block;
  font-size: 1.25em;
  line-height: 1;
  vertical-align: -0.07em;
  letter-spacing: 0;
}
.footer-socials { display: flex; align-items: center; gap: 8px; }
.footer-pfp {
  display: inline-flex;
  width: 44px; height: 44px;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--border2);
  transition: border-color 0.2s, transform 0.2s;
}
.footer-pfp img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(15%) contrast(1.05);
  transition: filter 0.2s;
}
.footer-pfp:hover { border-color: var(--red); }
.footer-pfp:hover img { filter: grayscale(0%) contrast(1.1); }

/* Desktop trim — hide pfp/socials, center thin © line */
@media (min-width: 601px) {
  .footer-block--pfp,
  .footer-block--socials { display: none; }
  footer {
    padding: 0 20px;
    justify-content: center;
  }
  .footer-block--copy {
    padding: 8px 0;
    border-right: none;
    margin-left: 0;
    font-size: 10px;
  }
}

/* Mobile reorder — IG · X · PFP centered row, © below */
@media (max-width: 600px) {
  footer {
    flex-wrap: wrap;
    flex-direction: row;
    padding: 18px 12px 22px;
    row-gap: 12px;
    column-gap: 14px;
    justify-content: center;
    align-items: center;
  }
  .footer-block {
    padding: 6px 6px;
    border-right: none;
    font-size: 9px;
    letter-spacing: 1.2px;
    white-space: nowrap;
  }
  .footer-block:last-child { margin-left: 0; }
  .footer-block--socials { order: 1; padding: 0; }
  .footer-block--pfp     { order: 2; padding: 0; }
  .footer-block--copy    { order: 3; flex-basis: 100%; justify-content: center; padding-top: 6px; font-size: 9px; }
  .footer-socials { gap: 14px; }
  .footer-socials .social-link {
    width: 34px; height: 34px;
    border: 1px solid var(--border2);
  }
  .footer-socials .social-link svg { width: 16px; height: 16px; }
  .footer-pfp { width: 34px; height: 34px; }
}

/* ─── INSTANT NAVIGATION FEEDBACK ───────────────────────────────────
   When the user taps a link, Swup adds .is-navigating to <body> via the
   visit:start hook (see swup-init.js). We dim <main> as a tap-ack so
   users don't repeat-tap during the page-fetch window.

   2026-05-18 v3 — drop the 150ms delay so feedback shows IMMEDIATELY on
   click (the prior delay was hiding the ack on slow fetches too — Chris
   reported homepage Explore clicks feeling "frozen for 3-5s"). The
   transition itself stays fast (90ms ease-out) so it doesn't feel
   sluggish on instant-cached navs.
*/
body.is-navigating main {
  opacity: 0.72;
  pointer-events: none;
  transition: opacity 90ms ease-out;
}
/* 2026-05-18 — Mobile gets a stronger dim. Mobile users tap a button and
   have no hover affordance, so a louder ack is justified. Also mobile
   network/CPU stretches the visible nav window — the brighter dim
   signals "tap received, fetching" clearly. */
@media (max-width: 768px) {
  body.is-navigating main {
    opacity: 0.55;
  }
}

/* 2026-05-18 — Top loading bar during Swup nav. Definitive feedback
   that the click was received and a fetch is in progress; the dim
   alone wasn't enough on mobile where the wait can be 2-4s on cold
   Bluehost. Indeterminate animated red bar across the top edge —
   reads as the universal "loading" affordance without committing
   to a fake progress percentage. */
body::before {
  content: '';
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 0;
  background: linear-gradient(90deg,
    rgba(192,57,43,0.0) 0%,
    rgba(192,57,43,1.0) 40%,
    rgba(220,80,68,1.0) 60%,
    rgba(192,57,43,0.0) 100%);
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
  transition: opacity 90ms ease-out;
}
body.is-navigating::before {
  opacity: 1;
  width: 100%;
  animation: nav-loadbar 1.4s linear infinite;
}
@keyframes nav-loadbar {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* ─── MOBILE TRANSMISSION CONSOLE ─── */
.mobile-menu-btn { display: none; }
@media (max-width: 768px) {
  .nav-social { display: none; }
  .nav-link { display: none; }
  .nav-link.always-mobile { display: flex; }
  .mobile-menu-btn {
    /* 2026-05-16 — stripped to its essence: pulsing signal dot + three
       horizontal bars. The word MENU was redundant once the bars read
       clearly. Bars are larger now (22×16) so they're an unmistakable
       tap target. */
    display: inline-flex;
    align-items: center;
    gap: 12px;
    margin-left: auto;
    margin-right: 6px;        /* pull in from right edge */
    background: transparent;
    border: none;
    color: #fff;
    cursor: pointer;
    padding: 10px 6px;        /* preserve tap target without visible chrome */
    line-height: 1;
  }
  .mobile-menu-btn .mm-label { display: none; }    /* MENU text hidden — keep node in DOM in case we want to reinstate */
  /* 2026-05-16 — dot moved to live above the hero stat-rail's 88.x MHz
     (matching desktop). Mobile button is just the bars now. Keep the node
     in DOM but suppress display so we don't break selectors elsewhere. */
  .mobile-menu-btn .dot { display: none; }
  .mobile-menu-btn .mm-lines {
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; transition: color 0.15s;
  }
  .mobile-menu-btn:hover .mm-lines, .mobile-menu-btn:active .mm-lines { color: var(--light); }
  .mobile-menu-btn .mm-lines svg {
    width: 22px; height: 16px; fill: currentColor; display: block;
  }

  /* Wordmark sized up on phone so CHRIS·ARVAN reads as the primary
     identifier, with more left breathing room. Desktop unchanged. */
  nav { padding: 0 18px 0 24px; }
  .nav-wordmark .nw-l { font-size: 16px; letter-spacing: 3.5px; padding-right: 4px; }
  .nav-wordmark .nw-leader { width: 18px; }
  /* 2026-05-16 — old `.mobile-menu-btn .dot` size+pulse rule removed; the
     dot is hidden above (line ~212) and no longer rendered. To reinstate
     a pulse dot on the button, restore the width/height/animation here AND
     remove the `display: none` line above. */
}

/* ─── DESKTOP + TABLET NAV SIZING ───
   2026-05-16 v6 — Chris: "I wanted them back to where they were... where
   we began today on desktop." Reverted to ORIGINAL pre-today desktop
   sizing (the small/compact version). No bumps. Applied to every viewport
   ≥769px so iPad inherits the same desktop sizing (no switching between
   widths). From this baseline Chris will tell me how/when to nudge up.
   Values match the base rules (wordmark 13px, nav-link 11px / 0 14px,
   social 26px) — kept explicit here so the intent is documented. */
@media (min-width: 769px) {
  /* 2026-05-16 v8 — subtle nudge per Chris: wordmark 14px, nav-link
     12px. Everything else (padding, social/PFP icons, letter-spacing)
     stays at the original baseline. */
  .nav-wordmark .nw-l { font-size: 14px; letter-spacing: 3px; padding-right: 3px; }
  .nav-wordmark .nw-leader { width: 16px; }
  .nav-link { font-size: 12px; letter-spacing: 1.5px; padding: 0 14px; }
  .nav-link .caret { font-size: 9px; margin-left: 6px; }
  .nav-social { padding: 0 14px; gap: 8px; }
  .nav-social .social-link, .nav-social .nav-pfp { width: 26px; height: 26px; }
  .nav-social .social-link svg { width: 13px; height: 13px; }
}

#mobileMenu {
  position: fixed; inset: 0; z-index: 500;
  background: #050505; color: var(--text);
  font-family: var(--mono);
  display: none;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
#mobileMenu.open { display: flex; }
#mobileMenu::before {
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(0deg, transparent 0 2px, rgba(255,255,255,0.022) 2px 3px);
  pointer-events: none;
  z-index: 1;
}
#mobileMenu::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 30% 20%, rgba(192,57,43,0.10), transparent 60%);
  pointer-events: none;
  z-index: 1;
}

/* 2026-05-17 — Menu top bar is dimensionally IDENTICAL to <nav> so
   toggling open ↔ closed feels like the same surface, just with the
   icon swapped (hamburger → X) and the content beneath swapped (page
   → menu). Matches nav.height=44px, padding 0 18px 0 24px (mobile),
   bg rgba(0,0,0,0.92), backdrop-blur. */
.mm-head {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  height: 44px;  /* kept in sync with nav.height for open ↔ closed continuity */
  flex-shrink: 0;
  padding: 0 18px 0 24px;
  border-bottom: 1px solid var(--border);
  background: rgba(0,0,0,0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
/* The mm-logo wraps the wordmark inside .mm-head — same look as
   the <nav>'s .nav-logo. */
.mm-head .mm-logo {
  display: flex; align-items: center; gap: 10px;
  color: var(--bright); text-decoration: none;
}
.mm-head .mm-logo:visited,
.mm-head .mm-logo:hover,
.mm-head .mm-logo:active { color: var(--bright); }
.mm-head .nav-wordmark .nw-l { font-size: 16px; letter-spacing: 3.5px; padding-right: 4px; }
.mm-head .nav-wordmark .nw-leader { width: 18px; }
/* 2026-05-17 — Close button mirrors .mobile-menu-btn exactly so the
   open ↔ closed toggle feels like the same control changing state.
   Padding tuned to match hamburger's 36px-tall button height so the
   X sits inside the 44px nav-style bar without busting it. */
.mm-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 7px 6px;
  line-height: 1;
  transition: color 0.15s;
}
.mm-close:hover, .mm-close:active { color: var(--light); }
.mm-close svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  display: block;
}

.mm-list {
  position: relative; z-index: 2;
  list-style: none;
  margin: 0;
  /* 2026-05-17 v3 — ZERO top padding. Any top padding here creates
     extra cell height above HOME compared to subsequent rows (whose
     cells are border-to-border), which is exactly the "HOME is bigger
     than the others" asymmetry Chris flagged repeatedly. HOME now sits
     flush against the mm-head bottom border so cell heights are
     uniform across the entire list. The "breathing room below my name"
     is achieved by bumping mm-head height instead (44px). */
  padding: 0 0 8px;
  flex: 1;
}
.mm-item {
  border-bottom: 1px solid var(--border);
  padding: 0;
}
.mm-row {
  display: flex; align-items: center;
  /* 2026-05-17 — was 22px 22px; vertical padding tightened to 14px
     per Chris ("menu items are spaced too far apart vertically").
     Font-size kept at 22px so the labels still read big — only the
     gap between rows shrinks. */
  padding: 14px 22px;
  font-family: 'Chakra Petch', sans-serif;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  gap: 14px;
  transition: background 0.12s, color 0.12s;
  /* 2026-05-18 — Kill iOS double-tap zoom delay + default blue tap flash
     so :active below owns the feedback. Per Chris on mobile: drawer link
     taps "feel broken" without instant tap-down state. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.mm-row:hover { background: rgba(192,57,43,0.06); color: var(--bright); }
/* Pronounced :active state — the drawer doesn't close instantly on tap
   (waits for Swup's page:view so the destination is ready before the
   drawer drops). Without this, user taps "Music" and sees nothing happen
   for 1-2 seconds. Now the row lights up red the moment the finger lands. */
.mm-row:active,
.mm-row.is-tapped,
a.mm-row.is-tapped {
  background: rgba(192,57,43,0.28);
  color: #fff;
}
.mm-row .mm-num {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--red);
  font-weight: 700;
  min-width: 28px;
}
.mm-row .br { color: var(--dim); font-size: 18px; margin: 0 4px; }
.mm-row .mm-caret {
  margin-left: auto;
  font-size: 12px;
  color: var(--mid);
  transition: transform 0.2s, color 0.15s;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
}
.mm-row .mm-caret svg {
  width: 12px; height: 12px;
  fill: currentColor;
  display: block;
}
.mm-item.open > .mm-row .mm-caret { transform: rotate(90deg); color: var(--red); }
.mm-row .mm-ext {
  margin-left: auto;
  font-size: 11px; color: var(--mid); font-family: var(--mono); letter-spacing: 2px;
}

.mm-sub {
  display: none;
  list-style: none;
  margin: 0;
  padding: 0 22px 18px 60px;
  background: rgba(0,0,0,0.4);
}
.mm-item.open .mm-sub { display: block; }
.mm-sub a {
  /* 2026-05-16 v2 — bumped 12→16 per Chris: "the dropdown items inside the
     hamburger menu — assemblage, evocation, etc — are too small." Top-level
     items stay at 22px (.mm-row); sub-items now 16px reads as a clear
     hierarchy step down without disappearing. Padding bumped 14→16 so the
     tap targets stay generous. */
  display: flex; align-items: center; gap: 12px;
  padding: 16px 0;
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 2.5px;
  color: var(--light);
  text-decoration: none;
  border-bottom: 1px dashed var(--border);
}
.mm-sub a:last-child { border-bottom: none; }
.mm-sub a:hover, .mm-sub a:active { color: var(--bright); }
.mm-sub a::before {
  content: '';
  display: inline-block;
  width: 18px; height: 1px; background: var(--mid);
}

.mm-foot {
  position: relative; z-index: 2;
  border-top: 1px solid var(--border);
  padding: 18px 22px 28px;
  display: flex; flex-direction: column; gap: 14px;
  background: rgba(0,0,0,0.6);
}
.mm-foot .mm-socials {
  display: flex; gap: 12px;
}
.mm-foot .mm-socials a {
  width: 36px; height: 36px;
  border: 1px solid var(--border2);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--light);
}
.mm-foot .mm-socials a:hover, .mm-foot .mm-socials a:active { color: var(--red); border-color: var(--red); }
.mm-foot .mm-socials svg { width: 14px; height: 14px; fill: currentColor; }
.mm-foot .mm-socials a.mm-pfp { padding: 0; overflow: hidden; border-radius: 50%; }
.mm-foot .mm-socials a.mm-pfp img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  filter: grayscale(10%) contrast(1.05);
}
.mm-foot .mm-socials a.mm-pfp:hover { border-color: var(--red); }
.mm-foot .mm-socials a.mm-pfp:hover img { filter: grayscale(0%) contrast(1.1); }
.mm-foot .mm-meta {
  font-size: 9px; letter-spacing: 2.5px; color: var(--mid);
  display: flex; flex-direction: column; gap: 4px;
}
.mm-foot .mm-meta .mm-meta-strong { color: var(--light); letter-spacing: 3px; }

@keyframes mm-glitch-in {
  0%   { opacity: 0; transform: translateX(8px); filter: brightness(2.0) blur(1px); }
  40%  { opacity: 1; transform: translateX(-2px); filter: brightness(1.4) blur(0); }
  100% { opacity: 1; transform: translateX(0); filter: brightness(1) blur(0); }
}
#mobileMenu.open { animation: mm-glitch-in 0.32s ease-out; }

@keyframes sig-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

body.mm-locked { overflow: hidden; }

/* ─── CROSS-REFERENCE STRIP — reusable site-wide component ───
   Slim inline row of links to other rooms / pages. Drop anywhere
   (top or bottom of any page) with any number of items (1, 2, 3+).
   Compact, monospace, dossier-coded — fits inside the existing
   visual vocab without competing for attention.

   No destination accent colors — the page's own accent stays its
   own; cross-links read uniform. Hover uses the site red (--red)
   only.

   Example markup (any number of links):

     <nav class="cross-ref">
       <span class="cr-tag">< ADJACENT ></span>
       <a class="cr-link" href="other.html">
         <span class="num">07</span>
         <span class="name">CULT OF THE NULL</span>
         <span class="arrow">→</span>
       </a>
       ... more links if any ...
     </nav>
*/
.cross-ref {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 22px;
  padding: 12px 24px;
  border-top: 1px solid #1e1e1e;
  border-bottom: 1px solid #1e1e1e;
  background: rgba(0,0,0,0.4);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: #d4d0c8;
}
.cr-tag {
  color: #666;
  letter-spacing: 3px;
}
.cr-tag .br { color: #444; }
.cr-link {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  color: #d4d0c8;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 180ms, border-color 180ms;
  white-space: nowrap;
}
.cr-link .num {
  color: #666;
  font-size: 9px;
  letter-spacing: 1.5px;
  font-variant-numeric: tabular-nums;
}
.cr-link .name {
  color: #d4d0c8;
  letter-spacing: 2.5px;
}
.cr-link .arrow {
  color: #666;
  font-size: 12px;
  margin-left: 2px;
  transition: transform 180ms, color 180ms;
}
.cr-link:hover { border-bottom-color: #c0392b; }
.cr-link:hover .name { color: #f0ece0; }
.cr-link:hover .arrow { color: #c0392b; transform: translateX(4px); }
.cr-link:hover .num { color: #999; }

@media (max-width: 700px) {
  .cross-ref { padding: 10px 16px; gap: 6px 16px; font-size: 9px; letter-spacing: 2px; }
  .cr-link .name { letter-spacing: 2px; }
}

/* ─── CR-PILLS — inline-pills variant of cross-ref ───
   Use this when you want red-bordered button pills (not a full-width
   strip). Drops anywhere — inside a gallery-header right column,
   alongside other content, or anywhere a small row of CTA links fits.
   1, 2, or 3+ pills work; pills wrap to a new line if the container
   is narrow.

   IMPORTANT — use <div role="navigation">, NOT <nav>. The global
   `nav { position: fixed; top: 0 }` rule in this file applies to
   ANY <nav> element on the page and would otherwise park these pills
   on top of the main site nav. role="navigation" preserves a11y
   semantics without triggering the layout rule.

   Example markup:
     <div class="cr-pills" role="navigation" aria-label="Other rooms">
       <a class="cr-pill" href="…">NAME <span class="arr">→</span></a>
       … more pills if any …
     </div>

   Same caveat applies to `.cross-ref` (the strip variant) above —
   use <div>, not <nav>.
*/
.cr-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
  /* Desktop default: right-aligned (mirrors the gallery title's
     left-aligned weight with a balanced right-side counter). Mobile
     centers — see @media block below. */
  justify-content: flex-end;
}
.cr-pill {
  /* 2026-05-16 — Unified with homepage CTA family (< THE FEED > / < ENTER >
     etc.). Was red-bordered with red arrows; now white text with gray
     border, dark wash, subtle red hover. Arrow removed for consistency. */
  display: inline-flex;
  align-items: center;
  padding: 10px 14px;
  border: 1px solid var(--mid);
  background: rgba(0, 0, 0, 0.4);
  color: var(--bright);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background 200ms, color 200ms, border-color 200ms;
}
.cr-pill .arr { display: none; }   /* arrows removed for button-family consistency */
.cr-pill:hover {
  background: rgba(192, 57, 43, 0.12);
  border-color: var(--red);
}
/* Current-page tab — used on small sibling sets (e.g. motion has
   only 2 pages; self-omitting leaves one pill, which doesn't read
   as a navigation set, so we show BOTH with the current page
   marked. The current pill is dimmed and non-clickable so it
   reads as "you are here" instead of an active CTA. Added
   2026-05-15 for motion top + bottom pills. */
.cr-pill.is-current,
.cr-pill.is-current:hover {
  background: transparent;
  border-color: var(--border2);
  color: var(--dim);
  cursor: default;
  pointer-events: none;
}

@media (max-width: 900px) {
  /* Narrow viewports (tablet + mobile): center the cross-ref pills
     as a group instead of the desktop flex-end.

     Three coordinated rules needed:
       1. The parent `.gh-right` (on /assemblage) is a flex-end column
          that shrinks to fit content. Force it to span the full
          gallery-header width on narrow viewports — otherwise both
          it AND .cr-pills inside it shrink to the pill row's natural
          width and there's nothing to center within.
       2. .cr-pills takes full width of the now-expanded parent.
       3. justify-content: center positions the pills within that
          expanded row. */
  .gh-right {
    width: 100%;
    align-items: stretch;
  }
  .cr-pills {
    justify-content: center;
    width: 100%;
  }
}
@media (max-width: 700px) {
  /* 2026-05-16 — hide the TOP-of-page cross-ref pills on mobile.
     The same pills repeat in .cr-pills-bottom at the page footer
     (universal "two-layer nav" pattern), and Chris wants them only
     at the bottom on phone. Top set is hidden; bottom set is
     re-enabled by the more-specific selector below. */
  .cr-pills { display: none; }
  .cr-pills-bottom .cr-pills {
    display: flex;
    gap: 8px;
    margin-top: 0;
  }
  .cr-pill { font-size: 11px; padding: 11px 14px; letter-spacing: 2.5px; }
}

/* ─── LAYER 1 — Bottom-of-page mirror of the cross-ref pills ───
   The same pills that sit top-right in the gallery-header also
   sit at the bottom of the page so a visitor who's scrolled
   through the whole grid doesn't have to scroll back up to reach
   the top nav. Banked 2026-05-15 — Chris's two-layer nav UX. */
.cr-pills-bottom {
  padding: 28px 28px 24px;
  border-top: 1px solid var(--border);
  background: rgba(0,0,0,0.45);
}
.cr-pills-bottom .cr-pills {
  justify-content: center;
  margin-top: 0;
}
@media (max-width: 700px) {
  .cr-pills-bottom { padding: 20px 16px 18px; }
}

/* ─── CROSS-REF CARDS — bottom-of-gallery preview tiles ─────────
   2026-05-18 — Replaced the bottom .cr-pills-bottom buttons with
   richer preview cards per Chris ("smaller version of the art
   landing page at the bottom of each gallery — three cards across
   on desktop, stacked on mobile"). Each card is a full-tile link
   to a sibling gallery, with a 16:9 hero image background, dark
   gradient scrim, and overlay text (gallery codex number + name +
   ENTER CTA). The current gallery is omitted; on Art pages that
   leaves 3 cards (Evocation/Aetherz/Assemblage/Cult minus self),
   on Motion pages that leaves 1 card. */
.cr-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  padding: 36px 28px 44px;
  background: rgba(0,0,0,0.55);
  border-top: 1px solid var(--border);
}
/* Motion gallery — only 1 sibling, single full-width card */
.cr-cards:has(.cr-card:only-child) {
  grid-template-columns: 1fr;
  max-width: 800px;
  margin: 0 auto;
}
.cr-card {
  position: relative;
  aspect-ratio: 16 / 9;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  background: #0a0a0a;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.2s, transform 0.2s;
  isolation: isolate;
}
.cr-card-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.cr-card-bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: brightness(0.62) saturate(0.85) contrast(1.05);
  transition: filter 0.35s ease, transform 0.45s ease;
}
.cr-card::after {
  /* Dark gradient scrim so the title reads on any image */
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.55) 60%, rgba(0,0,0,0.78) 100%),
    linear-gradient(90deg, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.1) 50%);
  pointer-events: none;
}
.cr-card-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 20px 22px;
  gap: 6px;
  font-family: var(--mono, 'Space Mono', monospace);
}
.cr-card-num {
  font-size: 10px;
  letter-spacing: 4px;
  color: var(--red);
  text-transform: uppercase;
  font-weight: 700;
}
.cr-card-name {
  font-family: 'Chakra Petch', sans-serif;
  font-size: clamp(20px, 2.6vw, 32px);
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--bright);
  text-transform: uppercase;
  line-height: 1;
  margin: 4px 0 8px;
}
.cr-card-cta {
  display: inline-flex;
  font-size: 11px;
  letter-spacing: 2.5px;
  color: var(--text);
  text-transform: uppercase;
  font-weight: 700;
  border: 1px solid var(--mid);
  padding: 7px 12px;
  background: rgba(0,0,0,0.35);
  align-self: flex-start;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.cr-card-cta .br { color: var(--red); }
.cr-card:hover {
  border-color: var(--red);
}
.cr-card:hover .cr-card-bg img {
  filter: brightness(0.78) saturate(1) contrast(1.05);
  transform: scale(1.025);
}
.cr-card:hover .cr-card-cta {
  background: rgba(192, 57, 43, 0.18);
  border-color: var(--red);
  color: var(--bright);
}
.cr-card:active {
  transform: scale(0.985);
}
@media (max-width: 768px) {
  .cr-cards {
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 24px 18px 32px;
  }
  .cr-card-overlay {
    padding: 16px 18px;
  }
}

/* ─── LAYER 2 — Cross-section EXPLORE strip ────────────────────
   Sits at the very bottom of every content page (galleries,
   music, motion, notes, about, contact, terms, 404). Lists the
   major rooms as light text links separated by bullets. The
   current room (where the visitor is now) is dimmed and not
   clickable. Lighter visual weight than .cr-pills — meant to
   feel like a wayfinding rail, not a CTA. Skipped on /index
   (home has ex-blocks) and /explore (explore IS the map).
   Banked 2026-05-15. */
.explore-strip {
  padding: 22px 28px 28px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0;
  flex-wrap: wrap;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 3px;
  color: var(--dim);
  text-transform: uppercase;
  background: rgba(0,0,0,0.65);
}
.explore-strip a {
  color: var(--light);
  padding: 4px 16px;
  text-decoration: none;
  transition: color 200ms;
}
.explore-strip a:hover { color: var(--red); }
.explore-strip .es-current {
  color: var(--dim);
  pointer-events: none;
}
.explore-strip .es-sep {
  color: var(--border2);
}
/* 2026-05-16 — hide on desktop. Top nav is fixed (always visible), so
   the bottom strip just duplicates it. Keep on mobile where the top
   nav collapses to a hamburger and the user has already scrolled here. */
@media (min-width: 601px) {
  .explore-strip { display: none; }
}
@media (max-width: 600px) {
  /* Bumped readability on mobile to match the cr-pill treatment —
     was 10px/dim-light; now 12px/brighter for a real tap target. */
  .explore-strip {
    padding: 18px 14px 22px;
    font-size: 12px;
    letter-spacing: 2.2px;
  }
  .explore-strip a { padding: 6px 12px; color: var(--bright); }
  .explore-strip .es-current { color: var(--mid); }
}

/* ─── IMAGE PROTECTION — casual-friction layer ───
   Pairs with assets/protect.js (right-click + view-source blocks).
   Targets gallery image classes specifically — leaves favicons /
   social-link SVGs / nav logo / music dock art free for normal use.
   `user-select: none` blocks drag-to-desktop on desktop browsers.
   `-webkit-touch-callout: none` blocks long-press-save on iOS Safari.
   `-webkit-user-drag: none` blocks Chrome/Safari's native image drag.
*/
.plate img,
.plate-frame img,
.grid-thumb,
.grid-tile img,
.grid-tile video,
.tile-video,
#lightbox img,
#lightbox video {
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}

/* ─────────────────────────────────────────────────────────
   Status-bar — HIDDEN site-wide 2026-05-15.
   The atmospheric strip (SIGNAL ACTIVE / LOS ANGELES / 2026 /
   chrisarvan.com) duplicated info from the <footer> above it
   (copyright + terms + onsomething link), creating a double-row
   bottom on every page. The footer is the canonical bottom; the
   status-bar gets a !important hide here without removing the
   DOM markup. To restore (e.g. evolve into a richer signal strip
   later), drop the rule below.
   ───────────────────────────────────────────────────────── */
.status-bar { display: none !important; }

/* ─────────────────────────────────────────────────────────
   Accessibility / SEO utility — visually-hidden but exposed
   to screen readers + search crawlers. Used for page-defining
   H1s on image-led pages (homepage, /about) where the design
   doesn't carry a visible H1. Standard sr-only pattern.
   Added 2026-05-16 during SEO deep-dive.
   ───────────────────────────────────────────────────────── */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

