*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --black:   #000000;
  --surface: #0a0a0a;
  --border:  #1e1e1e;
  --border2: #2a2a2a;
  --dim:     #444;
  --mid:     #666;
  --light:   #999;
  --text:    #d4d0c8;
  --bright:  #f0ece0;
  --red:     #c0392b;
  --mono:    'Space Mono', monospace;
}

html { scroll-behavior: smooth; }

/* Lock both <html> and <body> against horizontal scroll. On mobile, the
   hero-marquee track (9044px wide, scrolled by CSS animation inside a
   parent with overflow-x: hidden) plus a couple of position:fixed
   elements (status-bar, dock) were leaking past body's overflow-x:hidden
   alone — expanding the layout viewport to ~568px on a 375px device.
   That pushed the nav's MENU button off the right edge of the visible
   viewport, making the mobile menu effectively unreachable. Setting
   overflow-x:hidden on the html element too is the standard lock that
   prevents any descendant from expanding the layout viewport. */
html { overflow-x: hidden; }
body {
  background: var(--black);
  color: var(--text);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.5;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }

/* ─── SCROLLBAR ─── */
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: #000; }
::-webkit-scrollbar-thumb { background: #222; }

/* Nav lives in assets/nav.css. */

/* ─── BOOT + STATIC IGNITION ─── */
#ignition {
  position: fixed; inset: 0; z-index: 200;
  background: #000; color: var(--text); font-family: var(--mono);
  overflow: hidden;
  transition: opacity 0.45s;
}
#ignition.gone { opacity: 0; pointer-events: none; }
#ignition::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, transparent 40%, rgba(0,0,0,0.85) 100%);
  pointer-events: none; z-index: 4;
}
#ignition::after {
  content: ''; position: absolute; inset: 0;
  background: repeating-linear-gradient(0deg, transparent 0, transparent 2px, rgba(255,255,255,0.025) 2px, rgba(255,255,255,0.025) 3px);
  pointer-events: none; z-index: 3;
}

/* Phase 1 — boot terminal */
.ig-boot {
  position: absolute; inset: 0; z-index: 2;
  padding: clamp(20px, 6vw, 60px) clamp(20px, 6vw, 60px) clamp(20px, 6vw, 60px) clamp(60px, 9vw, 120px);
  display: flex; flex-direction: column; justify-content: center;
  font-size: clamp(11px, 1.3vw, 13px);
  letter-spacing: 1.2px;
  line-height: 1.9;
  transition: opacity 0.25s;
}
.ig-boot-head {
  font-family: 'VT323', monospace;
  font-size: 16px; letter-spacing: 4px; color: var(--red);
  margin-bottom: 14px;
  text-transform: uppercase;
}
.ig-boot-host {
  font-family: 'Major Mono Display', monospace;
  font-weight: 400;
  font-size: clamp(28px, 4.4vw, 56px);
  letter-spacing: clamp(4px, 0.6vw, 10px);
  color: var(--bright);
  margin-bottom: 6px; text-transform: lowercase;
  line-height: 1; padding: 4px 0;
  text-shadow: 0 0 12px rgba(240,236,224,0.25);
  min-height: 1.1em;
  /* Always include a unicode fallback so foreign-script glyphs render */
  font-family: 'Major Mono Display', 'Noto Sans', 'Arial Unicode MS', system-ui, monospace;
}
.ig-boot-host .glyph { display: inline-block; transition: color 0.2s; }
.ig-boot-host .glyph.scram { color: var(--red); text-shadow: 0 0 12px rgba(192,57,43,0.55); }
/* When a real letter of "chris arvan" is ghosting through during the late
   teasing phase, it appears in cream — distinct from the red noise so the
   eye catches the fragments without it ever looking "resolved". */
.ig-boot-host .glyph.ghost {
  color: var(--bright);
  text-shadow: 0 0 18px rgba(240,236,224,0.55), 0 0 6px rgba(192,57,43,0.4);
}
.ig-boot-sub {
  font-family: 'VT323', monospace; font-size: 14px;
  letter-spacing: 5px; color: var(--mid); margin-bottom: 22px; text-transform: uppercase;
}
.ig-boot-sub .br { color: var(--red); }
.ig-line { display: flex; gap: 10px; min-height: 1.9em; align-items: baseline; }
.ig-line .pmt { color: var(--red); font-weight: 700; }
.ig-line .addr { color: var(--dim); font-size: 0.85em; min-width: 5em; }
.ig-line .msg { color: var(--text); flex: 1; white-space: nowrap; overflow: hidden; }
.ig-line .pct { color: var(--mid); font-size: 0.85em; min-width: 4em; text-align: right; font-variant-numeric: tabular-nums; }
.ig-line .dots { color: var(--dim); }
.ig-line .ok { color: #6fbf73; font-weight: 700; }
.ig-line .fail { color: var(--red); font-weight: 700; }
.ig-line .lock { color: var(--bright); font-weight: 700; letter-spacing: 2px; }
.ig-cursor { display: inline-block; width: 8px; height: 1em; background: var(--bright); animation: ig-blink 0.7s infinite step-end; vertical-align: -2px; margin-left: 4px; }
@keyframes ig-blink { 50% { opacity: 0; } }

/* Side rail — channel strip */
.ig-rail {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: clamp(48px, 7vw, 88px); z-index: 5;
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  font-family: 'VT323', monospace; font-size: 13px;
  color: var(--dim); letter-spacing: 1.5px;
  background: rgba(0,0,0,0.3);
}
.ig-rail-block {
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.ig-rail-block .lbl { font-size: 9px; letter-spacing: 3px; color: var(--mid); }
.ig-rail-block .val { font-family: 'Space Mono', monospace; font-size: 11px; color: var(--bright); font-variant-numeric: tabular-nums; }
.ig-rail-bars { flex: 1; display: flex; flex-direction: column; gap: 1px; padding: 8px 6px; }
.ig-rail-bars .b { height: 4px; background: var(--border); transition: background 0.1s; }
.ig-rail-bars .b.on { background: var(--red); }
.ig-rail-bars .b.hot { background: var(--bright); }
.ig-rail-foot { padding: 8px 4px; text-align: center; font-size: 9px; color: var(--mid); letter-spacing: 2px; border-top: 1px solid var(--border); }
.ig-rail-foot .blink { color: var(--red); animation: ig-blink 0.6s infinite step-end; }

/* Right rail — frequency drift */
.ig-rail-r {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: clamp(48px, 7vw, 88px); z-index: 5;
  border-left: 1px solid var(--border);
  background: rgba(0,0,0,0.3);
  display: flex; flex-direction: column; justify-content: space-between;
  font-family: 'VT323', monospace; font-size: 13px;
  color: var(--dim); letter-spacing: 1.5px;
}
.ig-rail-r .stack { display: flex; flex-direction: column; gap: 2px; padding: 12px 6px; align-items: center; text-align: center; }
.ig-rail-r .num { font-family: 'Space Mono', monospace; font-size: 11px; color: var(--bright); font-variant-numeric: tabular-nums; }
.ig-rail-r .lbl { font-size: 9px; letter-spacing: 3px; color: var(--mid); margin-top: 6px; }

/* Final flash */
.ig-flash {
  position: absolute; inset: 0; z-index: 10;
  background: var(--red); opacity: 0; pointer-events: none;
}
.ig-flash.on { animation: ig-flash 0.18s 1; }
@keyframes ig-flash { 0%, 100% { opacity: 0; } 30% { opacity: 0.7; } }

/* ─── PERSISTENT SIGNAL: LIVE INDICATOR (top of hero) ───
   2026-05-16: stripped from a bracketed [< • SIGNAL · LIVE >] box to a
   single pulsing dot, positioned directly above the stat-rail's 88.x MHz
   reading and centered over the period of "88.5" (visual midpoint of
   the four-char number in 11px Space Mono). Stat rail right edge = 14px,
   number is ~32px wide → period sits ~22px in from the right; dot center
   at right:25px lands directly above it. */
.signal-live {
  position: absolute;
  top: 70px; right: 22px;
  z-index: 5;
  display: flex; align-items: center; justify-content: flex-end;
  pointer-events: none;
}
.signal-live .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 6px var(--red);
  animation: sig-pulse 2.4s infinite ease-in-out;
}
@keyframes sig-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 6px var(--red); }
  50% { opacity: 0.35; box-shadow: 0 0 2px var(--red); }
}
@media (max-width: 600px) {
  /* 2026-05-16 — was hidden because the menu button carried a dot. Now
     the menu button is just bars, so the live-signal dot returns and
     sits in the same place as desktop: above the stat-rail's 88.x MHz,
     centered over the period. Mobile stat-rail is at top:50px right:10px,
     so dot at top:32px right:18px puts it ~18px above + centered over
     the period of "88.5" at narrow-phone widths. */
  .signal-live { top: 32px; right: 18px; }
  .ig-rail-r { display: none; }
  .ig-boot { padding-left: clamp(56px, 14vw, 70px); }
}

/* ─── HERO AMBIENT DETAILS — quiet machine readouts ─── */
.hero-glyph-rail {
  position: absolute; left: 14px; top: 60px; bottom: 100px;
  z-index: 4;
  display: flex; flex-direction: column; gap: 18px;
  pointer-events: none;
  font-family: 'VT323', monospace;
  color: var(--light);
  opacity: 0.55;
}
.hgr-cell { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 38px; transition: opacity 0.6s; }
.hgr-cell .glyph {
  font-family: 'Noto Sans', 'Major Mono Display', monospace;
  font-size: 22px; line-height: 1; color: var(--bright);
  letter-spacing: 0; transition: color 0.4s;
  text-shadow: 0 0 8px rgba(240,236,224,0.15);
}
.hgr-cell .lbl { font-size: 10px; letter-spacing: 2px; color: var(--mid); text-transform: uppercase; }

.hero-stat-rail {
  /* 2026-05-16 — mirrored to .hero-glyph-rail's vertical positioning:
     same top (60), same bottom (100), same gap (18). Left rail has 6
     cells, right rail has 5, so the right rail will naturally end a
     little higher — but the *spacing between cells* is identical,
     which is what reads as "same spacing." */
  position: absolute; right: 14px; top: 60px; bottom: 100px;
  z-index: 4;
  display: flex; flex-direction: column; gap: 18px;
  pointer-events: none;
  font-family: 'VT323', monospace;
  color: var(--light);
  text-align: right;
  opacity: 0.55;
}
.hsr-block { display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 2px; min-height: 38px; }
.hsr-block .num { font-family: 'Space Mono', monospace; font-size: 11px; color: var(--bright); font-variant-numeric: tabular-nums; letter-spacing: 1px; }
.hsr-block .lbl { font-size: 10px; letter-spacing: 2.5px; color: var(--mid); text-transform: uppercase; }

.hero-marquee {
  position: relative;
  z-index: 4;
  width: 100%;
  height: 22px; overflow: hidden;
  border-top: 1px solid var(--border);
  background: rgba(0,0,0,0.45);
  pointer-events: none;
  font-family: 'Space Mono', monospace; font-size: 10px;
  letter-spacing: 2px; color: var(--mid);
  display: flex; align-items: center;
}
.hero-marquee-track {
  display: inline-flex; gap: 40px;
  white-space: nowrap;
  animation: marquee 90s linear infinite;
  padding-left: 100%;
}
.hero-marquee-track span { color: var(--light); }
.hero-marquee-track .red { color: var(--red); }
.hero-marquee-track .dim { color: var(--dim); }
@keyframes marquee {
  0% { transform: translateX(0); }
  100% { transform: translateX(-100%); }
}

@media (max-width: 768px) {
  /* 2026-05-16 — kanji glyph column AND stat rail (88.x MHz / BPM / SIG /
     CH / NODE) both hidden on mobile for a cleaner, more uniform black
     hero. Markup stays in place — to bring either back, delete the
     matching `display: none` rule. */
  .hero-glyph-rail { display: none; }
  .hero-stat-rail  { display: none; }
  .hgr-cell .glyph { font-size: 18px; }
  .hgr-cell .lbl { font-size: 8px; letter-spacing: 1.5px; }
  .hero-marquee { font-size: 9px; height: 20px; }

  /* (Mobile .hero-bracket-tag rule moved to AFTER the base rule below —
     cascade-order requirement. See note near the new rule.) */
}
@media (max-width: 600px) {
  /* Stat rail dormant rules — kept for the day we want to bring it back.
  .hero-stat-rail { top: 50px; bottom: auto; gap: 12px; right: 10px; }
  .hsr-block .num { font-size: 12px; letter-spacing: 0.5px; }
  .hsr-block .lbl { font-size: 8px; letter-spacing: 1.5px; }
  */
}

/* ─── HERO ───────────────────────────────────────────────────────────────
   ⚠ LOAD-BEARING LAYOUT — DO NOT REGRESS ⚠

   Locked behavior (confirmed correct by user 2026-05-02):
   • #hero has NO min-height and NO justify-content. It sizes to the natural
     height of its children (canvas + content + marquee), stacked tightly.
   • The canvas (.hero-fluid) drives hero height via its aspect-ratio:
       desktop  → 2346 / 1180  (wide cinematic)
       mobile   → 1661 / 2038  (tall portrait, fills with hoodie photo)
   • .hero-content (ARTIST · COMPOSER … + < ENTER >) is in NORMAL FLOW
     directly under the canvas — NOT absolute, NOT pinned to viewport bottom.
     Solid #000 background, no gradient overlay.
   • .hero-marquee is also in NORMAL FLOW directly under hero-content —
     NOT absolute. Sits at bottom of hero block.

   WHY: when the browser narrows, the canvas's aspect ratio makes it shorter.
   If hero is 100vh and content is absolute-bottom, you get a big black gap
   between the canvas and the text. With normal flow, the text always hugs
   the bottom of the canvas — no gaps at any width.

   IF YOU NEED TO ADD A FLOATING ELEMENT OVER THE CANVAS, do it inside
   .hero-art-wrap (which is position: relative) — never restore absolute
   positioning to .hero-content or .hero-marquee.
   ──────────────────────────────────────────────────────────────────────── */
#hero {
  margin-top: 44px;
  position: relative;
  width: 100%;
  overflow: hidden;
  cursor: pointer;
  background: #000;
  display: flex;
  flex-direction: column;
  align-items: center;
}

@media (min-width: 769px) {
  /* Hero sizes naturally: canvas at its aspect ratio, then content + marquee
     immediately below in normal flow — no min-height, no centering, so the
     text never separates from the bottom of the canvas as the browser shrinks. */
  .hero-art-wrap {
    width: 100%;
    display: flex;
  }
  .hero-art {
    width: 100%;
    height: auto;
    object-fit: contain;
  }
  .hero-content {
    width: 100%;
    max-width: none;
  }
}

.hero-art-wrap {
  width: 100%;
  display: block;
  position: relative;
}

/* WebGL liquid-symbols overlay — dark wash baked into shader, logo stays bright */
.hero-art-wrap::after { display: none; }
.hero-art-wrap::before { display: none; }

/* WebGL liquid-symbols overlay — sits in the art slot, content flows below */
.hero-fluid {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2346 / 1180;
  pointer-events: auto;
  cursor: crosshair;
  border: 0;
  background: #000;
}
@media (max-width: 768px) {
  /* Mobile hero canvas — shortened 2026-05-16. Was 1661/2038 (tall
     portrait, ~482px on a 393px-wide phone), which pushed THE FEED
     button below the music dock on initial load. New 1 / 1.05 saves
     ~70px of vertical, lifting the FEED above the dock with breathing
     room. The portrait image inside the canvas is still readable —
     just slightly less head-room at top, which Chris wanted anyway. */
  .hero-fluid {
    aspect-ratio: 1 / 1.05;
  }
}

/* iPad / tablet hero canvas — 2026-05-16 v2: REVERTED earlier same-day
   attempt at 2346/1000 (wider/shorter) because at that ratio the bg
   image's head was cropping off the top (image face is in upper third;
   sy = 0.71 cuts past it). Reverting to inherit the desktop 2346/1180
   ratio which was tuned weeks ago and confirmed correct on 2026-05-02.
   If the FEED button later crowds the player dock on iPad we'll fix
   that with a different lever (smaller dock height, or tighter role
   list line-height) — NOT by cropping the hero image. */

.hero-art {
  width: 100%;
  height: auto;
  display: block;
  filter: brightness(0.95);
  transition: filter 0.6s;
}

#hero:hover .hero-art { filter: brightness(0.9); }

/* Placeholder for hero art */
.hero-placeholder {
  width: 100%;
  height: 100%;
  background:
    radial-gradient(ellipse 60% 70% at 45% 40%, #1a0a0a 0%, transparent 70%),
    radial-gradient(ellipse 40% 50% at 70% 60%, #0a0a14 0%, transparent 60%),
    linear-gradient(160deg, #080808 0%, #0f0808 40%, #050505 100%);
  position: relative;
  overflow: hidden;
}

.hero-placeholder::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(0deg, transparent, transparent 3px, rgba(255,255,255,0.008) 3px, rgba(255,255,255,0.008) 4px);
}

.hero-placeholder-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #1a1a1a;
  font-size: 12px;
  letter-spacing: 3px;
  text-align: center;
  pointer-events: none;
}

.hero-overlay { display: none; }

.hero-content {
  position: relative;
  z-index: 5;
  width: 100%;
  /* 2026-05-16 — matched horizontal constraints to .ex-content
     (max-width 1200 + 48px right padding) so THE FEED button sits at
     the same right-edge X as LISTEN / ENTER / WATCH below. Background
     keeps the full-width #000 wash via the parent — the inner content
     is what we cap. */
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  /* center the role list vertically opposite the ENTER button itself,
     rather than bottom-aligning with the trailing "click to explore"
     hint — keeps the two columns reading as siblings at the same
     vertical height. */
  align-items: center;
  justify-content: space-between;
  padding: 18px 48px 22px;
  background: #000;
  border-top: none;
  gap: 24px;
}

@media (max-width: 600px) {
  .hero-content {
    /* Mobile: stack vertically and center as a group. Title block
       (ARTIST · COMPOSER) + THE FEED button share a centered axis.
       2026-05-16 — to nudge role-list up WITHOUT moving FEED: pull
       container up another 8px (margin-top -14 → -22) AND expand the
       gap by the same 8px (20 → 28). Net: role list shifts up 8px,
       FEED stays exactly where it was. */
    margin-top: -22px;
    padding: 0 18px 26px;
    flex-direction: column;
    align-items: center;
    gap: 28px;
    text-align: center;
  }
  .hero-meta {
    text-align: center !important;
    align-self: center;
  }
  .hero-meta br { display: none; }
  .hero-meta .hero-enter-hint { display: none; }
}

.hero-title-block {}

.hero-label {
  font-size: 13px;
  letter-spacing: 3px;
  color: var(--red);
  margin-bottom: 6px;
}

/* Desktop only: nudge the role list up to align with the ENTER
   button's vertical center specifically (not the geometric center of
   the right column, which is pulled down by the small "click to
   explore" hint sitting under the button). */
@media (min-width: 601px) {
  .hero-title-block {
    transform: translateY(-9px);
  }
}

.hero-name {
  font-family: 'Chakra Petch', sans-serif;
  font-size: clamp(32px, 5.5vw, 64px);
  font-weight: 700;
  color: var(--bright);
  letter-spacing: 4px;
  line-height: 1;
  text-transform: uppercase;
}

.hero-tagline {
  font-size: 12px;
  color: var(--light);
  margin-top: 10px;
  letter-spacing: 1px;
}

.hero-meta {
  /* Anchor now (links to /explore.html), formerly a div — preserve
     block-like layout and kill default link decoration so the visual
     is identical to before the wire-up. */
  display: block;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  text-align: right;
  transition: opacity 0.2s;
}
.hero-meta:hover { opacity: 0.85; }
.hero-meta:hover .hero-bracket-tag { color: var(--red); border-color: var(--red); }

.hero-bracket-tag {
  /* Bracketed CTA. Matches the section CTAs (ex-cta) so the four primary
     buttons on the homepage read as one family — including the slight
     dark wash background, so the hover/press red-tint lands identically
     across all four. white-space: nowrap prevents "THE FEED" (two words)
     from wrapping to two lines at narrow-but-not-mobile viewports like
     iPad portrait. */
  display: inline-block;
  white-space: nowrap;
  border: 1px solid var(--mid);
  background: rgba(0, 0, 0, 0.4);
  padding: 18px 28px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 4px;
  color: var(--bright);
  margin-bottom: 8px;
  text-transform: uppercase;
  font-family: var(--mono);
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
/* Brackets in white (inherit) — Chris trying all-white look 2026-05-16.
   Easy revert: set color: var(--red); */
.hero-bracket-tag .br { color: inherit; }
.hero-meta:hover .hero-bracket-tag { background: rgba(220, 50, 47, 0.12); }

/* Mobile sizing for .hero-bracket-tag — placed AFTER the base rule above
   so cascade order lets the mobile override win at narrow viewports.
   Slightly tighter than .ex-cta mobile sizing because "THE FEED" is a
   longer string than "ENTER / LISTEN / WATCH" — at identical padding it
   looks visually heavier. Trimming pad + font a notch lets it sit in the
   same family without dominating. */
@media (max-width: 600px) {
  .hero-bracket-tag {
    padding: 12px 16px;
    font-size: 10px;
    letter-spacing: 2.5px;
    border-color: var(--light);
    box-shadow: 0 0 0 1px rgba(192, 57, 43, 0.18) inset, 0 0 12px rgba(192, 57, 43, 0.12);
  }
}

.hero-enter-hint {
  font-size: 10px;
  color: var(--light);
  letter-spacing: 2px;
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: flex-end;
}

.hero-enter-hint::before {
  content: '';
  display: block;
  width: 20px;
  height: 1px;
  background: var(--light);
}

/* ─── GALLERY HEADER ───────────────────────────────────────
   Shared with explore.html so the page reads as part of the
   gallery family (transmissions, movements, cult-of-the-null,
   evocation). Each per-gallery CSS still ships its own copy
   of these rules — this one only fires on pages that load
   index.css (currently home + explore). Added 2026-05-14 when
   explore.html absorbed the old-home content and Chris flagged
   that the assemblage grid was reading too dominant without
   a framing header up top. */
.gallery-header {
  margin-top: 44px;
  padding: 32px 28px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
  flex-wrap: wrap;
}
.gallery-header .gallery-tag {
  font-size: 10px; letter-spacing: 3px; color: var(--red); margin-bottom: 8px;
}
.gallery-header .gallery-title {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 36px; font-weight: 700; letter-spacing: 4px;
  color: var(--bright); text-transform: uppercase;
}
.gallery-header .gallery-blurb {
  font-size: 12px; color: var(--light);
  margin-top: 10px; max-width: 64ch; line-height: 1.6;
}
.gallery-header .gallery-blurb .br { color: var(--dim); }
.gallery-header .gallery-meta {
  font-size: 11px; color: var(--dim); letter-spacing: 2px; text-align: right;
}
@media (max-width: 600px) {
  .gallery-header { padding: 24px 18px; }
  .gallery-header .gallery-title { font-size: 24px; letter-spacing: 3px; }
}

/* ─── SECTION HEADER ─── */
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}

.section-title {
  font-size: 11px;
  letter-spacing: 3px;
  color: var(--dim);
}

.section-title span { color: var(--red); }

.section-count {
  font-size: 10px;
  color: var(--dim);
  border: 1px solid var(--border);
  padding: 2px 8px;
}

/* ─── ASSEMBLAGE GRID ─── */
#assemblage {
  border-top: 1px solid var(--border);
}

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}

.grid-tile {
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.grid-tile:nth-child(4n) { border-right: none; }

.grid-thumb {
  width: 100%;
  aspect-ratio: 1;
  display: block;
  object-fit: cover;
  transition: transform 0.4s ease, filter 0.3s;
  filter: brightness(0.85) saturate(0.9);
}

.grid-tile:hover .grid-thumb {
  transform: scale(1.04);
  filter: brightness(1) saturate(1);
}

/* Art placeholder */
.art-placeholder {
  width: 100%;
  aspect-ratio: 1;
  background: var(--surface);
  position: relative;
  overflow: hidden;
  transition: filter 0.3s;
}

.art-placeholder::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 8px,
    rgba(255,255,255,0.018) 8px,
    rgba(255,255,255,0.018) 9px
  );
}

.art-placeholder .art-label {
  position: absolute;
  bottom: 8px;
  right: 8px;
  font-size: 9px;
  color: var(--border2);
  letter-spacing: 2px;
}

/* Color variants for placeholder art */
.ap-1 { background: linear-gradient(135deg, #0d0408 0%, #1a0510 60%, #080408 100%); }
.ap-2 { background: linear-gradient(135deg, #04080d 0%, #05101a 60%, #040808 100%); }
.ap-3 { background: linear-gradient(135deg, #080d04 0%, #0f1a05 60%, #080804 100%); }
.ap-4 { background: linear-gradient(135deg, #0d0d04 0%, #1a1a05 60%, #080804 100%); }
.ap-5 { background: linear-gradient(135deg, #0a0408 0%, #170510 60%, #080308 100%); }
.ap-6 { background: linear-gradient(135deg, #04080a 0%, #050f17 60%, #040808 100%); }
.ap-7 { background: linear-gradient(135deg, #0a0a0a 0%, #141414 60%, #080808 100%); }
.ap-8 { background: linear-gradient(135deg, #0d0408 0%, #200508 60%, #0a0404 100%); }

.grid-tile-label {
  padding: 8px 10px 10px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.tile-title {
  font-size: 11px;
  color: var(--light);
  letter-spacing: 0.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.tile-title .br { color: var(--dim); }

.tile-plus {
  width: 18px;
  height: 18px;
  border: 1px solid var(--border2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--dim);
  flex-shrink: 0;
  transition: border-color 0.2s, color 0.2s;
}

.grid-tile:hover .tile-plus {
  border-color: var(--red);
  color: var(--red);
}

/* Wide tile */
.grid-tile.wide {
  grid-column: span 2;
}
.grid-tile.tall-row {
  display: flex;
  flex-direction: column;
}
.grid-thumb-fillwrap {
  flex: 1;
  position: relative;
  overflow: hidden;
  width: 100%;
  min-height: 0;
}
.grid-thumb-fill {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

.grid-tile.wide .art-placeholder {
  aspect-ratio: 2/1;
}

.grid-tile.tall {
  grid-row: span 2;
}

.grid-tile.tall .art-placeholder {
  aspect-ratio: 1/2;
}

.grid-thumb-frame {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.grid-thumb-frame iframe {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0; left: 0;
  border: none;
  pointer-events: none;
  transform-origin: top left;
}

.frame-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
  transition: opacity 0.2s;
}

/* On hover: let iframe be interactive */
.grid-tile:hover .grid-thumb-frame iframe {
  pointer-events: all;
}

.grid-tile:hover .frame-overlay {
  pointer-events: none;
  opacity: 0;
}

.frame-expand-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  width: 28px;
  height: 28px;
  background: rgba(0,0,0,0.7);
  border: 1px solid var(--border2);
  color: var(--dim);
  font-family: var(--mono);
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s, color 0.15s, border-color 0.15s;
  pointer-events: all;
}

.grid-tile:hover .frame-expand-btn {
  opacity: 1;
}

.frame-expand-btn:hover {
  color: var(--bright);
  border-color: var(--red);
}

/* Lightbox iframe */
.lb-art-frame {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
}

#lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0,0,0,0.97);
  display: none;
  opacity: 0;
  transition: opacity 0.2s;
}

#lightbox.open {
  display: flex;
  opacity: 1;
}

.lb-inner {
  display: flex;
  width: 100%;
  height: 100%;
}

.lb-art {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 40px 60px 40px;
  border-right: 1px solid var(--border);
  position: relative;
}

.lb-art-placeholder {
  width: 100%;
  max-width: 600px;
  aspect-ratio: 1;
  background: var(--surface);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lb-art-placeholder img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  display: block;
}

.lb-info {
  width: 340px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 0;
}

.lb-info-top {
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
}

.lb-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--dim);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.lb-close:hover { color: var(--bright); border-color: var(--mid); }

.lb-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--bright);
  letter-spacing: 1px;
  margin-bottom: 4px;
}

.lb-artist {
  font-size: 11px;
  color: var(--red);
  letter-spacing: 2px;
}

.lb-description {
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  color: var(--light);
  line-height: 1.8;
}

.lb-meta-table {
  flex: 1;
}

.lb-meta-row {
  display: flex;
  justify-content: space-between;
  padding: 10px 24px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
}

.lb-meta-key { color: var(--dim); }
.lb-meta-val { color: var(--text); text-align: right; }

.lb-actions {
  padding: 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid var(--border);
}

.lb-btn {
  padding: 10px;
  border: 1px solid var(--border2);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--dim);
  cursor: pointer;
  background: transparent;
  text-align: center;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.lb-btn:hover { color: var(--bright); border-color: var(--mid); }
.lb-btn.primary { border-color: var(--red); color: var(--red); }
.lb-btn.primary:hover { background: var(--red); color: #000; }

.lb-nav {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0;
}

.lb-nav-btn {
  padding: 6px 16px;
  border: 1px solid var(--border2);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--dim);
  cursor: pointer;
  background: #000;
  transition: color 0.15s;
}

.lb-nav-btn:hover { color: var(--bright); }
.lb-nav-sep { padding: 6px 12px; border-top: 1px solid var(--border2); border-bottom: 1px solid var(--border2); font-size: 10px; color: var(--dim); background: #000; }

/* ─── MUSIC SECTION ─── */
#music {
  border-top: 1px solid var(--border);
}

/* ─── FREQUENCY ARCHIVE FEATURE (music hub link block) ─── */
.music-archive-feature {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0;
  padding: 40px 36px 36px;
  border-bottom: 1px solid var(--border);
  background: #000;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  min-height: 460px;
  cursor: crosshair;
}
.maf-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  display: block;
}
.maf-edge-fade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right,  #000 0%, transparent 20%, transparent 80%, #000 100%),
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, transparent 18%, transparent 78%, rgba(0,0,0,0.75) 100%);
  pointer-events: none;
  z-index: 1;
}

.maf-scanlines {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 3px,
    rgba(0,0,0,0.1) 3px,
    rgba(0,0,0,0.1) 4px
  );
  pointer-events: none;
  z-index: 1;
}

/* top meta row */
.maf-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  position: relative;
  z-index: 2;
  margin-bottom: 24px;
}
.maf-station-tag {
  font-size: 10px;
  letter-spacing: 3.5px;
  color: var(--red);
  margin-bottom: 10px;
}
.maf-live-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--dim);
}
.maf-live-dot {
  width: 7px; height: 7px;
  background: var(--red);
  border-radius: 50%;
  box-shadow: 0 0 8px var(--red);
  flex-shrink: 0;
  animation: maf-pulse 1.6s ease-in-out infinite;
}
@keyframes maf-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 8px var(--red); }
  50%       { opacity: 0.35; box-shadow: 0 0 2px var(--red); }
}
.maf-freq { color: var(--red); font-size: 11px; letter-spacing: 1px; margin-left: 6px; }
.maf-freq-lbl { color: var(--dim); font-size: 9px; letter-spacing: 2px; }
.maf-meta-rail {
  display: flex;
  gap: 24px;
  text-align: right;
}
.maf-rail-block { display: flex; flex-direction: column; align-items: flex-end; }
.maf-rnum {
  font-family: 'Chakra Petch', sans-serif;
  font-size: 18px; font-weight: 700;
  color: #1e1e1e;
  letter-spacing: 2px; line-height: 1;
}
.maf-rlbl { font-size: 8px; letter-spacing: 3px; color: #1a1a1a; }

/* MUSIC label — centered over the canvas, exclusion blend for letter-knockback */
.maf-music-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 3;
  pointer-events: none;
}
.maf-music-text {
  font-family: 'Chakra Petch', sans-serif;
  font-size: clamp(48px, 7vw, 96px);
  font-weight: 700;
  letter-spacing: 0.25em;
  color: transparent; /* WebGL renders the text; HTML element is for a11y only */
  user-select: none;
  line-height: 1;
}

/* bottom row */
.maf-bottom {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  position: relative;
  z-index: 2;
  gap: 16px;
}
.maf-cta {
  font-size: 10px;
  letter-spacing: 3.5px;
  color: var(--mid);
  white-space: nowrap;
  flex-shrink: 0;
  transition: color 0.2s;
}
.music-archive-feature:hover .maf-cta {
  color: var(--red);
}

@media (max-width: 900px) {
  .music-archive-feature { padding: 32px 24px 28px; min-height: 320px; }
  .maf-meta-rail { display: none; }
}
@media (max-width: 600px) {
  .music-archive-feature { padding: 24px 20px 22px; min-height: 260px; }
}

/* ─── MUSIC FEATURE (replaces old .music-player on home) ─── */
.music-feature {
  display: block;
  position: relative;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  background: #000;
  overflow: hidden;
  /* NOT cursor:pointer on the wrapper — only the CTA pill is clickable
     so the WebGL fluid sim can receive mouse events. */
}
.mf-art-wrap {
  position: relative;
  width: 100%;
  display: block;
  background: #000;
}
.mf-frame {
  display: block;
  width: 100%;
  height: 460px;
  border: 0;
  background: #000;
  /* iframe receives mouse events for the fluid sim */
}
@media (max-width: 900px) { .mf-frame { height: 380px; } }
@media (max-width: 600px) { .mf-frame { height: 280px; } }

.mf-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 24px 32px;
  pointer-events: none; /* do not block fluid sim */
  background: linear-gradient(to top, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.35) 100%);
}
.mf-overlay-tag {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--red);
  text-transform: uppercase;
  margin-bottom: 8px;
  text-shadow: 0 0 12px rgba(0,0,0,0.7);
}
.mf-overlay-title {
  font-family: 'Chakra Petch', 'Space Mono', monospace;
  font-size: clamp(20px, 2.4vw, 30px);
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--light);
  text-shadow: 0 2px 14px rgba(0,0,0,0.85);
  line-height: 1;
}
.mf-cta {
  /* Desktop: anchored top-right, mirroring the hero's ENTER button
     placement (left text column / right CTA column). Mobile rule
     below centers it horizontally for the single-column stack. */
  position: absolute;
  top: 24px;
  right: 32px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--light);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid rgba(255,255,255,0.3);
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: border-color 0.25s, background 0.25s, color 0.25s, transform 0.25s;
  cursor: pointer;
  pointer-events: auto;
  text-decoration: none;
  z-index: 2;
}
.mf-cta:hover {
  border-color: var(--red);
  background: rgba(192,57,43,0.25);
  color: #fff;
  transform: translateY(-2px);
}
.mf-arrow {
  display: inline-block;
  transition: transform 0.25s;
}
.mf-cta:hover .mf-arrow {
  transform: translateX(4px);
}
@media (max-width: 600px) {
  .mf-overlay { padding: 18px 18px; }
  /* Mobile: only the padding + font size on .mf-cta. The actual
     position is set further down on `.music-archive .ma-listen`
     (higher specificity) — see that rule for the mobile centering. */
  .mf-cta { padding: 8px 12px; font-size: 9px; }
}

/* ─── MUSIC ARCHIVE (clone of music-feature with FREQUENCY ARCHIVE chrome) ─── */
.music-archive .ma-broadcast {
  position: absolute;
  top: 24px; left: 32px;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--light);
  text-transform: uppercase;
  text-shadow: 0 0 12px rgba(0,0,0,0.7);
  pointer-events: none;
  z-index: 2;
}
.music-archive .ma-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 6px var(--red);
  animation: sig-pulse 2.4s infinite ease-in-out;
}
/* LISTEN button at bottom-right (overrides .mf-cta's top-right default) */
.music-archive .ma-listen {
  top: auto;
  bottom: 24px;
  right: 32px;
}
@media (max-width: 600px) {
  .music-archive .ma-broadcast { top: 14px; left: 18px; font-size: 9px; }
  /* Mobile: center the CTA horizontally (mirrors how the hero ENTER
     button centers on mobile). Desktop keeps bottom-right above. */
  .music-archive .ma-listen {
    top: auto;
    bottom: 12px;
    right: auto;
    left: 50%;
    transform: translateX(-50%);
  }
  .music-archive .ma-listen:hover { transform: translate(-50%, -2px); }
}

.music-player {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--border);
}

.music-cover {
  width: 120px;
  height: 120px;
  flex-shrink: 0;
  border-right: 1px solid var(--border);
  background: linear-gradient(135deg, #0d0408 0%, #1a0510 100%);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.music-cover::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(45deg, transparent, transparent 6px, rgba(255,255,255,0.02) 6px, rgba(255,255,255,0.02) 7px);
}

.music-play-btn {
  width: 52px;
  height: 52px;
  border: 1.5px solid var(--red);
  background: rgba(192,57,43,0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  z-index: 1;
  transition: border-color 0.2s, background 0.2s, box-shadow 0.25s, transform 0.2s;
  /* hide any textContent — we use a CSS triangle for crispness */
  font-size: 0;
  color: transparent;
  box-shadow: 0 0 0 1px rgba(192,57,43,0);
}
/* crisp triangle play glyph (works regardless of font support) */
.music-play-btn::before {
  content: '';
  width: 0; height: 0;
  border-left: 12px solid var(--bright);
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  margin-left: 3px; /* optical center */
  transition: border-left-color 0.15s, transform 0.2s;
}
/* paused → triangle, playing → two bars (driven by .is-playing class set in JS) */
.music-play-btn.is-playing::before {
  content: '';
  width: 14px; height: 14px;
  margin-left: 0;
  border: none;
  background:
    linear-gradient(var(--bright), var(--bright)) left/4px 100% no-repeat,
    linear-gradient(var(--bright), var(--bright)) right/4px 100% no-repeat;
  box-shadow: none;
}

/* ── HOVER: animated frame, label slide-in, slight pulse ── */
/* ── HOVER: single red frame expands, triangle pulses ── */
.music-play-btn:hover {
  background: rgba(192,57,43,0.18);
  box-shadow: 0 0 14px rgba(192,57,43,0.55), inset 0 0 10px rgba(192,57,43,0.18);
  transform: scale(1.12);
}
.music-play-btn:hover::before {
  animation: mp-pulse 1.1s ease-in-out infinite;
}
.music-play-btn.is-playing:hover::before {
  animation: none;
}
@keyframes mp-pulse {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(2px); }
}

.music-info {
  flex: 1;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-right: 1px solid var(--border);
}
.music-info-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.music-info-titles { min-width: 0; }
.music-transport {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}
.music-progress { margin-top: 10px; }

.music-track-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--bright);
  letter-spacing: 0.5px;
}

.music-track-name .br { color: var(--dim); font-weight: 400; }

.music-album {
  font-size: 10px;
  color: var(--dim);
  letter-spacing: 2px;
  margin-top: 4px;
}

.music-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}

.progress-bar {
  flex: 1;
  height: 18px; /* big hit area */
  background: transparent;
  position: relative;
  cursor: pointer;
  display: flex;
  align-items: center;
  touch-action: none;
}
.progress-bar::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 2px;
  background: var(--border2);
  transform: translateY(-50%);
}
.progress-fill {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 2px;
  width: 0%;
  background: var(--red);
  transition: width 0.08s linear;
  pointer-events: none;
}
.progress-handle {
  position: absolute;
  top: 50%;
  left: 0%;
  transform: translate(-50%, -50%);
  width: 12px;
  height: 12px;
  background: var(--red);
  border-radius: 50%;
  pointer-events: none;
  box-shadow: 0 0 0 4px rgba(192,57,43,0.18);
  transition: transform 0.15s;
}
.progress-bar:hover .progress-handle,
.progress-bar.dragging .progress-handle {
  transform: translate(-50%, -50%) scale(1.2);
}

.time-label { font-size: 10px; color: var(--dim); white-space: nowrap; }

.music-controls {
  display: none; /* transport now lives inside .music-info */
}
.ctrl-btn-mid {
  color: var(--bright) !important;
}

.ctrl-btn {
  width: 44px;
  height: 44px;
  border: none;
  background: transparent;
  font-family: var(--mono);
  font-size: 14px;
  color: var(--dim);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s;
}

.ctrl-btn:hover { color: var(--bright); }

.music-tracklist {
  flex: 1;
  overflow-y: auto;
}

.track-row {
  display: flex;
  align-items: center;
  padding: 0 16px;
  height: 40px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
  gap: 12px;
}

.track-row:hover { background: rgba(255,255,255,0.03); }
.track-row.playing { background: rgba(192,57,43,0.06); }

.track-num { width: 20px; font-size: 10px; color: var(--dim); text-align: right; flex-shrink: 0; }
.track-row.playing .track-num { color: var(--red); }
.track-name { font-size: 11px; color: var(--light); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 700; letter-spacing: 0.04em; }
.track-row.playing .track-name { color: var(--bright); }
.track-sub { flex: 1; font-size: 9px; color: var(--dim); letter-spacing: 0.12em; text-transform: uppercase; margin-left: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-dur { font-size: 10px; color: var(--dim); }

/* ─── ABOUT / SIGNAL STRIP ─── */
#about {
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* Portrait sits behind the SIGNAL column, full-bleed, duotoned */
.about-portrait-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 53.5%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  border-right: 1px solid var(--border);
}
.about-portrait-bg img {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 30% center;
  filter: grayscale(100%) contrast(1.18) brightness(0.78);
  mix-blend-mode: luminosity;
  opacity: 0.55;
}
.about-portrait-bg::before {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 25% 40%, rgba(192,57,43,0.22), transparent 60%),
    linear-gradient(90deg, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.7) 55%, rgba(0,0,0,0.95) 100%);
  z-index: 1;
}
.about-portrait-bg::after {
  content: '';
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(0deg, transparent 0 2px, rgba(192,57,43,0.04) 2px 3px);
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: overlay;
}
.about-portrait-frame {
  position: absolute;
  bottom: 16px; left: 18px;
  z-index: 3;
  font-size: 9px; letter-spacing: 2.5px; color: rgba(192,57,43,0.85);
  font-family: 'Space Mono', monospace; font-weight: 700;
  display: flex; flex-direction: column; gap: 4px;
}
.about-portrait-frame .pf-tag::before { content: '> '; opacity: 0.7; }
.about-portrait-frame .pf-meta { color: rgba(212,208,200,0.55); font-weight: 400; letter-spacing: 1.5px; }

.about-left {
  padding: 56px 40px;
  border-right: 1px solid var(--border);
  position: relative;
  z-index: 1;
  display: flex; flex-direction: column;
  justify-content: flex-start;
  gap: 14px;
}

.about-tag {
  font-size: 10px;
  letter-spacing: 3px;
  color: var(--red);
  margin-bottom: 16px;
}

.about-text {
  font-size: 15px;
  color: var(--text);
  line-height: 1.85;
  max-width: none;
}

.about-text strong { color: var(--bright); font-weight: 700; }
.about-text em { color: var(--red); font-style: normal; font-weight: 600; }

.about-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--dim);
  border-bottom: 1px solid var(--border2);
  padding-bottom: 4px;
  transition: color 0.15s, border-color 0.15s;
  cursor: pointer;
}

.about-link:hover { color: var(--bright); border-color: var(--mid); }

.about-right {
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  position: relative;
  z-index: 1;
  background: var(--black);
}

.stat-block {
  padding: 16px;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.stat-block:nth-child(2n) { border-right: none; }
.stat-block:nth-last-child(-n+2) { border-bottom: none; }

.stat-num {
  font-size: 28px;
  font-weight: 700;
  color: var(--bright);
  letter-spacing: -1px;
}

.stat-label {
  font-size: 10px;
  color: var(--dim);
  letter-spacing: 2px;
  margin-top: 4px;
}

/* ─── FOOTER ─── */
footer {
  border-top: 1px solid var(--border);
  padding: 0 20px 28px; /* reserve space so status-bar doesn't sit on top */
  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; }

/* ── DESKTOP-ONLY footer trim (2026-05-16) ───────────────────────────
   On desktop, hide the PFP + social icons (Chris is moving those
   somewhere else later) and collapse the footer to a single thin row
   with just © 2026 CHRIS ARVAN · TERMS centered, sitting tight under
   the page content. Mobile keeps the full footer treatment (see
   @media max-width: 600px block further down). */
@media (min-width: 601px) {
  .footer-block--pfp,
  .footer-block--socials { display: none; }
  /* Footer-level padding zeroed top+bottom so the block's own 8px padding
     controls spacing on both sides — symmetric 8px above + 8px below the
     copyright line. */
  footer {
    padding: 0 20px;
    justify-content: center;
  }
  .footer-block--copy {
    padding: 8px 0;
    border-right: none;
    margin-left: 0;
    font-size: 10px;
  }
}

/* © glyph alignment — the default © sits high in monospace fonts and
   reads smaller than the surrounding "2026 CHRIS ARVAN" text. This
   wrapper bumps it to the same visual weight + drops the baseline a
   hair so it sits on the same line. */
.footer-block .cr-mark {
  display: inline-block;
  font-size: 1.25em;
  line-height: 1;
  vertical-align: -0.07em;
  letter-spacing: 0;
}

/* OPEN A CHANNEL — bracket-tag CTA in footer.
   2026-05-16 — color treatment unified with the homepage CTAs (THE FEED /
   ENTER / LISTEN / WATCH): white text, white brackets, brighter gray border,
   subtle red wash on hover. Arrow removed for consistency. */
.footer-channel {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  padding: 9px 16px;
  border: 1px solid var(--mid);
  background: transparent;
  color: var(--bright);
  transition: background 0.18s, border-color 0.18s, color 0.18s;
}
.footer-channel:hover { background: rgba(220, 50, 47, 0.12); border-color: var(--red); }
.footer-channel .fc-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  white-space: nowrap;
}
.footer-channel .fc-label .br { color: inherit; }

.footer-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dim);
}

.footer-dot.live { background: var(--red); animation: pulse 2s infinite; }

.footer-socials { display: flex; align-items: center; gap: 8px; }

/* PFP — social avatar — circle, subtle border, lives in © 2026 block */
.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;
  flex-shrink: 0;
  position: relative;
}
.footer-pfp img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(15%) contrast(1.05);
  transition: filter 0.25s;
}
.footer-pfp:hover { border-color: var(--red); }
.footer-pfp:hover img { filter: grayscale(0%) contrast(1.1); }

/* ─── HOVER STATES ON GRID ─── */
.grid-tile:hover .art-placeholder { filter: brightness(1.2); }

/* ─── STATUS INDICATOR ─── */
.status-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  height: 28px;
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 20px;
  background: rgba(0,0,0,0.9);
  border-top: 1px solid var(--border);
  z-index: 50;
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--dim);
}

.status-item { display: flex; align-items: center; gap: 6px; }
.status-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--dim); }
.status-dot.active { background: var(--red); animation: pulse 2s infinite; }
.status-spacer { flex: 1; }

/* ─── RESPONSIVE ─── */
@media (max-width: 900px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
  .grid-tile.wide { grid-column: span 2; }
  /* #about stays 2-column at iPad/tablet now (was collapsing at 900). Per
     Chris 2026-05-15 — keep the desktop "glyphs on the right" layout for
     iPad, only collapse on mobile phone. */
  .lb-inner { flex-direction: column; }
  .lb-info { width: 100%; flex-shrink: 0; height: 50%; }
  .lb-art { height: 50%; }
}

@media (max-width: 600px) {
  .grid { grid-template-columns: repeat(2, 1fr); }

  /* Music player: small square cover top-left, info to its right, tracklist below full-width */
  .music-player {
    display: grid;
    grid-template-columns: 96px 1fr;
    grid-template-areas:
      "cover info"
      "tracks tracks";
    flex-direction: unset;
  }
  .music-cover {
    grid-area: cover;
    width: 96px; height: 96px;
    aspect-ratio: auto;
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
  }
  .music-info {
    grid-area: info;
    width: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 12px 16px;
    min-height: 96px;
    box-sizing: border-box;
    column-gap: 8px;
    row-gap: 6px;
  }
  .music-tracklist {
    grid-area: tracks;
    width: 100%;
    max-height: 240px;
  }
  .music-play-btn { width: 44px; height: 44px; }
  .music-play-btn::before {
    border-left-width: 10px;
    border-top-width: 7px;
    border-bottom-width: 7px;
  }

  /* About: overlay treatment — portrait sits BEHIND the SIGNAL text on
     mobile, same as the desktop pattern + the /about subject hero. Chris
     2026-05-15: "the words should be over my black-and-white image."
     Was previously stacked (portrait on top, text below). Now portrait is
     full-bleed absolute behind, vitals overlay with the gradient making
     the text readable. */
  #about {
    display: flex;
    flex-direction: column;
    position: relative;
    isolation: isolate;
  }
  .about-portrait-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    order: 0;
    z-index: 0;
    border-right: none;
    border-bottom: none;
    pointer-events: none;
  }
  .about-portrait-bg img {
    mix-blend-mode: normal;
    opacity: 0.55;
    /* Chris 2026-05-15: portrait positioning. The container on mobile is
       taller than the image's scaled aspect so y-axis object-position has
       no visible effect (no vertical overflow to crop). Using transform
       translateY to physically shift the image up. -8% lifts the head
       visibly without going off the top. */
    object-position: 30% 0%;
    transform: translateY(-4%);
    filter: grayscale(0.55) contrast(1.08) brightness(0.65);
  }
  .about-portrait-bg::before {
    background:
      radial-gradient(ellipse at 50% 30%, transparent 0%, rgba(0,0,0,0.45) 55%, rgba(0,0,0,0.88) 100%),
      linear-gradient(180deg, rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.65) 60%, rgba(0,0,0,0.92) 100%);
  }
  .about-left {
    padding: 32px 22px;
    border-right: none;
    border-bottom: 1px solid var(--border);
    position: relative;
    z-index: 1;
    background: transparent;
  }
  .about-right { grid-template-columns: 1fr; position: relative; z-index: 1; }

  .gallery-mobile-btn { display: flex !important; }

  /* Footer mobile layout — 2026-05-16:
       row 1: Instagram · X · PFP   (centered as a unified set, PFP on the right)
       row 2: © 2026 CHRIS ARVAN · < TERMS >   (centered)
     CSS `order` re-arranges visual sequence without touching HTML order
     (HTML stays: pfp → socials → channel → copy). column-gap on the footer
     PLUS gap on .footer-socials, both set to the same value (14px), so
     IG↔X and X↔PFP have identical spacing. */
  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; }

  /* Order on mobile: socials (IG · X) first, then PFP last (right side
     of the centered cluster), then copyright on its own row.
     Socials + PFP blocks get zero padding so the column-gap is the ONLY
     spacing rule between them — keeps X→PFP identical to IG→X. */
  .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; }

  /* Size on mobile — IG/X icons bumped up, PFP shrunk so the three
     items read as one balanced set rather than a big avatar + small
     icons. Final visual size 34px for all three. */
  .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; }
}

/* ──────────────────────────────────────────────────────────────────────
   ARCHIVE STREAM LOADER — explore.html only
   Sits at the top of <main> (between gallery-header and the first
   curated section). Single-row status + thin progress bar. No console
   feed, no green — strictly the site's red/white/dim palette. Fades
   1.8s after the EXPLORATION FEED tiles finish loading.
   ────────────────────────────────────────────────────────────────────── */
.archive-stream {
  border-bottom: 1px solid var(--border);
  padding: 14px 28px 12px;
  background: transparent;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-dim, #888);
  transition: opacity 0.6s ease, max-height 0.7s ease, padding 0.5s ease, border-color 0.5s ease;
  overflow: hidden;
  max-height: 80px;
}
.archive-stream.as-gone {
  opacity: 0;
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-bottom-color: transparent;
  pointer-events: none;
}
.archive-stream .as-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 8px;
}
.archive-stream .as-status {
  letter-spacing: 0.06em;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dim, #888);
}
.archive-stream .as-status .br { color: var(--accent, #ff2e2e); opacity: 0.7; }
.archive-stream .as-sep { color: var(--text-dim, #555); }
.archive-stream .as-state {
  display: inline-block;
  min-width: 110px;
  color: var(--accent, #ff2e2e);
  text-align: left;
}
.archive-stream .as-freq {
  color: #fff;
  font-variant-numeric: tabular-nums;
  min-width: 96px;
  display: inline-block;
}
.archive-stream .as-count,
.archive-stream .as-pct {
  color: #ddd;
  font-variant-numeric: tabular-nums;
}
.archive-stream .as-bar {
  height: 2px;
  background: rgba(255, 255, 255, 0.05);
  position: relative;
  overflow: hidden;
}
.archive-stream .as-fill {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 0%;
  background: var(--accent, #ff2e2e);
  transition: width 0.3s ease;
}
.archive-stream.as-complete .as-state { color: #fff; }
.archive-stream.as-complete .as-fill { background: #fff; opacity: 0.85; }

@media (max-width: 720px) {
  .archive-stream { padding: 12px 16px 10px; }
  .archive-stream .as-row { gap: 8px; flex-wrap: wrap; }
  .archive-stream .as-state { min-width: 88px; }
  .archive-stream .as-freq { min-width: 80px; }
}

/* ──────────────────────────────────────────────────────────────────────
   EXPLORATION FEED — section header + grid hookup + footnote
   ────────────────────────────────────────────────────────────────────── */
#exploration-feed {
  border-top: 1px solid var(--border);
  margin-top: 0;
}
#exploration-feed .ef-header {
  border-bottom: 1px solid var(--border);
}

.ef-footnote {
  text-align: center;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--text-dim, #555);
  letter-spacing: 0.12em;
  padding: 22px 16px 36px;
  border-top: 1px solid var(--border);
  transition: color 0.4s ease;
}
.ef-footnote.ef-pulse { color: var(--accent, #ff2e2e); }
.ef-footnote .br { opacity: 0.7; }

#ef-sentinel {
  height: 1px;
  margin-top: -1px;
}

@media (max-width: 720px) {
  .ef-footnote { padding: 18px 12px 28px; }
}

/* ──────────────────────────────────────────────────────────────────────
   EXPLORATION FEED — varied tile sizes (masonry-feel)
   The grid is 4 columns at desktop, 2 columns on mobile. Row height is
   driven by JS to match column width so squares stay square + spans
   produce clean 1×2 / 2×1 / 2×2 proportions. Dense auto-flow packs gaps.
   ────────────────────────────────────────────────────────────────────── */
#explore-feed-grid {
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
  /* grid-auto-rows set inline by JS to match column width */
}
.ef-tile {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  background: #0a0a0a;
}
.ef-tile.ef-tile-sq      { grid-column: span 1; grid-row: span 1; }
.ef-tile.ef-tile-tall    { grid-column: span 1; grid-row: span 2; }
.ef-tile.ef-tile-wide    { grid-column: span 2; grid-row: span 1; }
.ef-tile.ef-tile-feature { grid-column: span 2; grid-row: span 2; }

/* 2026-05-16 — LISTEN tile, inserted into the feed every N items.
   FULL-WIDTH (spans every column of the feed grid) and 2 rows tall on
   wider viewports — a major break in the visual rhythm that drops the
   swirly WebGL "LISTEN" visualization in as a mouse-reactive moment.
   Click → /music. */
.ef-tile.ef-tile-listen {
  /* Full-width 16:9 — same proportions across desktop and mobile so the
     interactive WebGL piece reads consistent. aspect-ratio overrides the
     grid-auto-rows height; grid-row: auto lets it size by aspect. */
  grid-column: 1 / -1;
  grid-row: auto;
  aspect-ratio: 16 / 9;
  position: relative;
  background: #050505;
  overflow: hidden;
  cursor: pointer;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.ef-tile.ef-tile-listen .ef-listen-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  pointer-events: auto;
}
.ef-tile.ef-tile-listen .ef-listen-overlay {
  /* Mirrors the original homepage music-feature overlay: subtle dark
     vignette at top + bottom so the < MUSIC > tag and < FREQUENCY
     ARCHIVE > button stay readable as the white blob moves underneath. */
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background: linear-gradient(to top,
    rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.35) 100%);
}
.ef-tile.ef-tile-listen .ef-listen-tag {
  /* Top-left small red label, with text-shadow for readability. */
  position: absolute;
  top: 24px; left: 32px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--red);
  font-weight: 700;
  text-transform: uppercase;
  text-shadow: 0 0 12px rgba(0,0,0,0.7);
  pointer-events: none;
}
.ef-tile.ef-tile-listen .ef-listen-cta {
  /* Bottom-right CTA chip with backdrop-blur — matches the original
     music-archive .ma-listen treatment. Pointer-events on so the chip
     itself is hoverable; click bubbles up to the tile's anchor for nav. */
  position: absolute;
  bottom: 24px; right: 32px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--bright);
  text-transform: uppercase;
  padding: 10px 16px;
  border: 1px solid rgba(255,255,255,0.3);
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  pointer-events: auto;
  text-decoration: none;
  transition: border-color 0.25s, background 0.25s, color 0.25s, transform 0.25s;
}
.ef-tile.ef-tile-listen:hover .ef-listen-cta {
  border-color: var(--red);
  background: rgba(192,57,43,0.25);
  color: #fff;
  transform: translateY(-2px);
}
@media (max-width: 600px) {
  /* Tighten label positions for the smaller mobile box (16:9 tile). */
  .ef-tile.ef-tile-listen .ef-listen-tag { top: 14px; left: 18px; font-size: 9px; }
  .ef-tile.ef-tile-listen .ef-listen-cta {
    bottom: 14px; right: auto;
    left: 50%; transform: translateX(-50%);
    font-size: 9px; padding: 8px 12px;
  }
  .ef-tile.ef-tile-listen:hover .ef-listen-cta { transform: translate(-50%, -2px); }
}
/* Transmissions / On Something promo videos — vertical, MUST NOT be
   cropped (Chris 2026-05-15). Portrait 1×2 tile with contain-fit. */
.ef-tile.ef-tile-vtall   { grid-column: span 1; grid-row: span 2; }
/* Movements videos — square tiles (Chris 2026-05-15: "I want all that
   stuff to be square. Don't mess with that."). 1×1 with contain-fit. */
.ef-tile.ef-tile-vsq     { grid-column: span 1; grid-row: span 1; }

/* Images cover-fit so they fill their tile box edge-to-edge */
.ef-tile .ef-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease, filter 0.3s;
  filter: brightness(0.85) saturate(0.9);
}
.ef-tile:hover .ef-thumb {
  transform: scale(1.04);
  filter: brightness(1.05) saturate(1.05);
}

/* Videos contain-fit — never cropped. Letterboxes against the tile
   background where aspect doesn't match. */
.ef-tile .ef-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  display: block;
  transition: filter 0.3s;
  filter: brightness(0.92) saturate(0.95);
}
.ef-tile:hover .ef-video {
  filter: brightness(1.0) saturate(1.0);
}

/* Feature tiles get a slight painterly treatment — softer, slightly desaturated
   resting state so when they "wake up" on hover the contrast lands. Mirrors
   how evocation features the painterly stills on its gallery page. */
.ef-tile-feature .ef-thumb {
  filter: brightness(0.78) saturate(0.85) contrast(1.04);
}
.ef-tile-feature:hover .ef-thumb {
  filter: brightness(1.0) saturate(1.0) contrast(1.05);
}

/* Video tiles — subtle "▶" cue in the corner */
.ef-tile-vtall .tile-plus,
.ef-tile-vsq .tile-plus {
  color: var(--accent, #ff2e2e);
  font-size: 14px;
}

@media (max-width: 900px) {
  #explore-feed-grid { grid-template-columns: repeat(3, 1fr); }
  .ef-tile.ef-tile-feature { grid-column: span 2; grid-row: span 2; }
}
@media (max-width: 600px) {
  #explore-feed-grid { grid-template-columns: repeat(2, 1fr); }
  .ef-tile.ef-tile-feature { grid-column: span 2; grid-row: span 2; }
  .ef-tile.ef-tile-wide    { grid-column: span 2; grid-row: span 1; }
}
