/* ============== CABINET — FULL-SPA CONSOLE STAGE ============== */

function Bracket() { return <div className="brackets"><span /></div>; }

function ConsoleHeader({ route, sectionLabel, sectionIdx, total }) {
  const [time, setTime] = React.useState('');
  React.useEffect(() => {
    const tick = () => {
      const d = new Date();
      setTime(d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' }));
    };
    tick();
    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, []);
  const r = ROUTES[route];
  return (
    <div className="console-chrome">
      <div className="left">
        <span className="led" />
        <span>TOMORROW TRIBE</span>
        <span className="sep">·</span>
        <span>{r.label}</span>
      </div>
      <div className="right">
        {total > 0 && <span>{sectionLabel} · {sectionIdx + 1}/{total}</span>}
        <span>{time} UTC</span>
        <span className="led amber" />
      </div>
    </div>
  );
}

function DPad({ dir, onUp, onDown, onLeft, onRight }) {
  const btn = (d, handler, keyHint, tooltip) => (
    <div
      className={`dpad-btn ${dir === d ? 'active' : ''}`}
      onClick={handler}
      style={{cursor:'pointer'}}
      role="button"
      aria-label={d}
      title={tooltip}
    >
      <span className="dpad-key">{keyHint}</span>
    </div>
  );
  return (
    <div className="dpad" title="D-PAD · WASD or Arrow keys">
      <div className="c" />
      {btn('up',    onUp,    'W', 'Up / W / ↑ — Prev route')}
      <div className="c" />
      {btn('left',  onLeft,  'A', 'Left / A / ← — Prev section')}
      <div className="dpad-center" />
      {btn('right', onRight, 'D', 'Right / D / → — Next section')}
      <div className="c" />
      {btn('down',  onDown,  'S', 'Down / S / ↓ — Next route')}
      <div className="c" />
    </div>
  );
}

function ABXYButtons({ pressed, onA, onB, onX, onY }) {
  const btn = (id, label, keyHint, onClick, tooltip) => (
    <div
      className={`btn-${id.toLowerCase()} abxy-btn ${pressed === id ? 'press' : ''}`}
      onClick={onClick}
      style={{cursor:'pointer'}}
      title={tooltip}
    >
      <span className="abxy-label">{label}</span>
      <span className="abxy-key">{keyHint}</span>
    </div>
  );
  return (
    <div className="abxy">
      {btn('Y', 'Y', 'I',  onY, 'Y / I — Toggle SFX')}
      {btn('X', 'X', 'U',  onX, 'X / U — Quick-jump menu')}
      {btn('A', 'A', 'J',  onA, 'A / J / Enter — Advance')}
      {btn('B', 'B', 'K',  onB, 'B / K / Esc — Back')}
    </div>
  );
}

/* ========== HOME CAROUSEL ========== */
function CardEmblem({ kind, active }) {
  const stroke = 'var(--fg)';
  const glow = active ? 'drop-shadow(0 0 8px var(--phos-glow))' : 'none';
  const common = { width: '70%', height: '70%', filter: glow, transition: 'filter 0.4s' };
  // viewBox is centered on 0,0 so CSS rotations around `transform-origin:
  // center` line up correctly inside the SVG without needing transform-box
  // overrides on every child element.
  if (kind === 'surgeon') return (
    <svg viewBox="-50 -50 100 100" className={`emb emb-surgeon ${active ? 'is-active' : ''}`} style={common}>
      <polygon className="emb-outer" points="0,-44 44,0 0,44 -44,0" fill="none" stroke={stroke} strokeWidth="2" />
      <polygon className="emb-inner" points="0,-28 28,0 0,28 -28,0" fill="none" stroke={stroke} strokeWidth="2" />
      <circle className="emb-core" cx="0" cy="0" r="4" fill={stroke} />
    </svg>
  );
  if (kind === 'ai') return (
    <svg viewBox="-50 -50 100 100" className={`emb emb-ai ${active ? 'is-active' : ''}`} style={common}>
      <circle className="emb-ring" cx="0" cy="0" r="38" fill="none" stroke={stroke} strokeWidth="2" />
      <ellipse className="emb-orbit emb-orbit-h" cx="0" cy="0" rx="38" ry="14" fill="none" stroke={stroke} strokeWidth="1" opacity="0.6" />
      <ellipse className="emb-orbit emb-orbit-v" cx="0" cy="0" rx="14" ry="38" fill="none" stroke={stroke} strokeWidth="1" opacity="0.6" />
      <circle className="emb-core" cx="0" cy="0" r="6" fill={stroke} />
    </svg>
  );
  // Lazy chevrons — stacked, marching upward in a loop
  return (
    <svg viewBox="-50 -50 100 100" className={`emb emb-lazy ${active ? 'is-active' : ''}`} style={common}>
      <polygon className="emb-chev emb-chev-3" points="-30,-20 0,-40 30,-20 22,-16 0,-28 -22,-16" fill={stroke} />
      <polygon className="emb-chev emb-chev-2" points="-30,5 0,-15 30,5 22,9 0,-3 -22,9" fill={stroke} opacity="0.65" />
      <polygon className="emb-chev emb-chev-1" points="-30,30 0,10 30,30 22,34 0,22 -22,34" fill={stroke} opacity="0.35" />
    </svg>
  );
}

function VentureCard({ v, active, offset, onClick }) {
  const absOff = Math.abs(offset);
  const translateX = offset * 280;
  const translateZ = absOff === 0 ? 0 : -220;
  const rotateY = offset * -36;
  const opacity = absOff >= 2 ? 0 : 1;
  const scale = absOff === 0 ? 1 : 0.82;
  const filter = absOff === 0 ? 'none' : 'blur(1px) brightness(0.55)';
  return (
    <div className={`card ${active ? 'active' : ''}`} onClick={onClick}
      style={{ transform: `translate(-50%, -50%) translate3d(${translateX}px, 0, ${translateZ}px) rotateY(${rotateY}deg) scale(${scale})`, opacity, filter, zIndex: 10 - absOff }}>
      <div className="card-inner">
        <div className="card-tag"><span className="n">◆ {v.num}</span><span>{v.faction}</span></div>
        <div className="card-emblem"><CardEmblem kind={v.id} active={active} /></div>
        <div className="card-title">{v.title}</div>
        <div className="card-role">{v.role}</div>
        <div className="card-stats">
          {Object.entries(v.stats).map(([k, val]) => (
            <div className="stat" key={k}><span className="k">{k}</span><span>{val}</span></div>
          ))}
        </div>
        <div className="card-bar" style={{ '--fill': v.fill }} />
        <div className="card-tag" style={{marginTop: 10}}>
          <span>{v.class}</span>
          <span className="n">{active ? 'SELECTED ●' : 'TAP TO OPEN →'}</span>
        </div>
      </div>
    </div>
  );
}

function HomeCarousel({ idx, setIdx, enter }) {
  const offsetFor = (i) => {
    const n = VENTURES.length;
    let d = i - idx;
    if (d > n / 2) d -= n;
    if (d < -n / 2) d += n;
    return d;
  };
  const active = VENTURES[idx];
  return (
    <div className="home-stage">
      <div className="home-header">
        <div className="hh-line">◆ PICK A VENTURE TO EXPLORE — 3 ON THE TABLE ◆</div>
        <h1 className="hero-title" data-glitch>
          <span className="glitch-layer" data-text="THE TOMORROW TRIBE CREATIVE SOLUTIONS">THE TOMORROW TRIBE CREATIVE SOLUTIONS</span>
        </h1>
        <div className="hero-sub">◆ CREATIVE SOLUTIONS FOR THE BUSINESSES OF TOMORROW ◆</div>
      </div>
      <div className="carousel-stage">
        <div className="carousel">
          {VENTURES.map((v, i) => (
            <VentureCard key={v.id} v={v} active={i === idx}
              offset={offsetFor(i)}
              onClick={() => i === idx ? enter() : setIdx(i)} />
          ))}
        </div>
      </div>
      <div className="home-footer">
        <div className="hf-cur">◇ {active.title}</div>
        <div className="hf-dots" role="tablist" aria-label="Factions">
          {VENTURES.map((v, i) => (
            <span
              key={v.id}
              className={`hf-dot ${i === idx ? 'is-active' : ''}`}
              aria-label={`Go to ${v.title}`}
              role="tab"
              aria-selected={i === idx}
              onClick={() => setIdx(i)}
            />
          ))}
        </div>
        <div className="hf-hint">
          <span className="hf-hint-desktop"><span className="blink">▶</span> PRESS <span className="key-inline">ENTER</span> TO OPEN</span>
          <span className="hf-hint-mobile"><span className="blink">◀</span> SWIPE · TAP A CARD TO OPEN <span className="blink">▶</span></span>
        </div>
      </div>
    </div>
  );
}

/* ========== SLIDE STACK (non-home routes) ========== */
function SlideStack({ route, sectionIdx, dir }) {
  const r = ROUTES[route];
  if (!r || r.sections.length === 0) return null;
  const slides = SLIDE_CONTENT[route];
  return (
    <div className="slide-stack">
      {r.sections.map((sec, i) => {
        const offset = i - sectionIdx;
        const absOff = Math.abs(offset);
        const translateX = offset * 100;
        const opacity = absOff === 0 ? 1 : absOff === 1 ? 0.25 : 0;
        const scale = absOff === 0 ? 1 : 0.9;
        return (
          <div key={sec.id} className={`slide ${absOff === 0 ? 'is-active' : ''}`}
            style={{
              transform: `translateX(${translateX}%) scale(${scale})`,
              opacity,
              pointerEvents: absOff === 0 ? 'auto' : 'none',
            }}>
            <div className="slide-inner">
              {slides && slides[sec.id]}
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ========== QUICK-JUMP OVERLAY (X button) ========== */
function QuickJump({ open, onClose, go, currentRoute, currentSectionIdx }) {
  if (!open) return null;
  return (
    <div className="qjump-overlay" onClick={onClose}>
      <div className="qjump" onClick={e => e.stopPropagation()}>
        <div className="qj-head">
          <span className="qj-eyebrow">◆ QUICK-JUMP</span>
          <span className="qj-hint">ESC / X / B to close</span>
        </div>
        <div className="qj-grid">
          {ROUTE_ORDER.map(rk => {
            const r = ROUTES[rk];
            return (
              <div className={`qj-col ${rk === currentRoute ? 'is-current' : ''}`} key={rk}>
                <button className="qj-route" onClick={() => { go(rk, 0, 'zoom'); onClose(); }}>
                  <span className="qj-r-num">◇ {r.color}</span>
                  <span className="qj-r-label">{r.label}</span>
                </button>
                {r.sections.length > 0 && (
                  <div className="qj-secs">
                    {r.sections.map((s, i) => (
                      <button key={s.id}
                        className={`qj-sec ${rk === currentRoute && i === currentSectionIdx ? 'is-current' : ''}`}
                        onClick={() => { go(rk, i, 'zoom'); onClose(); }}>
                        <span className="qj-n">{String(i+1).padStart(2,'0')}</span>
                        <span>{s.label}</span>
                      </button>
                    ))}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* ========== MAIN CABINET ========== */
function Cabinet() {
  const router = useRouter();
  const { state, dir, go, nextSection, prevSection, nextRoute, prevRoute, back } = router;
  const { route, sectionIdx } = state;

  // HOME carousel index
  const [homeIdx, setHomeIdx] = React.useState(() => {
    const saved = localStorage.getItem('ttt-side');
    return saved != null ? Number(saved) : 0;
  });
  React.useEffect(() => { localStorage.setItem('ttt-side', String(homeIdx)); }, [homeIdx]);

  const [qjOpen, setQjOpen] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [helpOpen, setHelpOpen] = React.useState(false);
  // { target: 'AI', title: 'PURO AI LABS', dir: 'down'|'up' } | null
  const [pendingSwitch, setPendingSwitch] = React.useState(null);
  const [isMobile, setIsMobile] = React.useState(() => window.matchMedia('(max-width: 900px)').matches);
  const [showSwipeHint, setShowSwipeHint] = React.useState(false);
  const [pressed, setPressed] = React.useState(null);
  const [dpadDir, setDpadDir] = React.useState(null);
  const [sfxMuted, setSfxMuted] = React.useState(() => window.sfx ? window.sfx.isSfxMuted() : false);
  const [musicMuted, setMusicMuted] = React.useState(() => window.sfx ? window.sfx.isMusicMuted() : false);

  // Track viewport breakpoint
  React.useEffect(() => {
    const mq = window.matchMedia('(max-width: 900px)');
    const onChange = () => setIsMobile(mq.matches);
    mq.addEventListener('change', onChange);
    return () => mq.removeEventListener('change', onChange);
  }, []);

  // First-visit tutorial (desktop only — mobile navigates like a normal app)
  React.useEffect(() => {
    if (isMobile) return;
    const seen = localStorage.getItem(window.HELP_KEY);
    if (!seen) {
      const t = setTimeout(() => setHelpOpen(true), 700);
      return () => clearTimeout(t);
    }
  }, [isMobile]);
  React.useEffect(() => {
    if (!helpOpen) localStorage.setItem(window.HELP_KEY, '1');
  }, [helpOpen]);

  // Mobile swipe hint (once per session)
  React.useEffect(() => {
    if (!isMobile) return;
    if (sessionStorage.getItem('ttt-swipe-hint')) return;
    const t = setTimeout(() => {
      setShowSwipeHint(true);
      sessionStorage.setItem('ttt-swipe-hint', '1');
      setTimeout(() => setShowSwipeHint(false), 3200);
    }, 1500);
    return () => clearTimeout(t);
  }, [isMobile]);

  const flashBtn = (b, d) => {
    setPressed(b);
    if (d) { setDpadDir(d); }
    setTimeout(() => { setPressed(null); setDpadDir(null); }, 220);
  };

  // Enter/A action: context-aware
  const onA = React.useCallback(() => {
    flashBtn('A');
    if (qjOpen) { setQjOpen(false); return; }
    if (route === 'HOME') {
      // Enter the selected faction
      const v = VENTURES[homeIdx];
      const routeMap = { surgeon: 'SURGEON', ai: 'AI', lazy: 'LAZY' };
      const target = routeMap[v.id];
      if (target) { window.sfx && window.sfx.enter(); go(target, 0, 'zoom'); }
    } else {
      // Advance to next section, or jump to next route if at end
      const advanced = nextSection();
      if (!advanced) { window.sfx && window.sfx.enter(); nextRoute(); }
    }
  }, [qjOpen, route, homeIdx, go, nextSection, nextRoute]);

  const onB = React.useCallback(() => {
    flashBtn('B');
    if (qjOpen) { setQjOpen(false); return; }
    back();
  }, [qjOpen, back]);

  const onX = React.useCallback(() => {
    flashBtn('X');
    setQjOpen(o => !o);
  }, []);

  // Y button / I key = toggle SFX (the arcade bleeps/blops).
  const onY = React.useCallback(() => {
    flashBtn('Y');
    if (window.sfx) {
      const m = window.sfx.toggleSfxMute();
      setSfxMuted(m);
    }
  }, []);

  // Music toggle (separate from Y/I). Wired to the MUSIC button in the header.
  const toggleMusic = React.useCallback(() => {
    if (window.sfx) {
      const m = window.sfx.toggleMusicMute();
      setMusicMuted(m);
    }
  }, []);

  const onLeft = React.useCallback(() => {
    flashBtn(null, 'left');
    if (qjOpen) return;
    if (route === 'HOME') {
      setHomeIdx(i => (i - 1 + VENTURES.length) % VENTURES.length);
      window.sfx && window.sfx.tick();
    } else {
      prevSection();
    }
  }, [qjOpen, route, prevSection]);

  const onRight = React.useCallback(() => {
    flashBtn(null, 'right');
    if (qjOpen) return;
    if (route === 'HOME') {
      setHomeIdx(i => (i + 1) % VENTURES.length);
      window.sfx && window.sfx.tick();
    } else {
      nextSection();
    }
  }, [qjOpen, route, nextSection]);

  const onUp = React.useCallback(() => {
    flashBtn(null, 'up');
    if (qjOpen) return;
    prevRoute();
  }, [qjOpen, prevRoute]);

  const onDown = React.useCallback(() => {
    flashBtn(null, 'down');
    if (qjOpen) return;
    nextRoute();
  }, [qjOpen, nextRoute]);

  // Keyboard
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) return;
      // When help is open, ANY key closes it — no background navigation.
      // Modifier keys alone are ignored so stray Shift/Ctrl releases don't dismiss.
      if (helpOpen) {
        if (['Shift', 'Control', 'Alt', 'Meta'].includes(e.key)) return;
        e.preventDefault();
        e.stopPropagation();
        setHelpOpen(false);
        return;
      }
      // Route-switch confirmation: Enter/Y = confirm, Esc/N = dismiss.
      if (pendingSwitch) {
        if (['Shift', 'Control', 'Alt', 'Meta'].includes(e.key)) return;
        e.preventDefault();
        e.stopPropagation();
        const k = e.key.toLowerCase();
        if (k === 'enter' || k === 'y' || k === ' ') {
          const tgt = pendingSwitch.target;
          const dir = pendingSwitch.dir === 'down' ? 'down' : 'up';
          setPendingSwitch(null);
          window.sfx && window.sfx.enter && window.sfx.enter();
          go(tgt, 0, dir);
        } else {
          setPendingSwitch(null);
        }
        return;
      }
      switch (e.key) {
        // Arrow cluster
        case 'ArrowRight': e.preventDefault(); onRight(); break;
        case 'ArrowLeft':  e.preventDefault(); onLeft();  break;
        case 'ArrowUp':    e.preventDefault(); onUp();    break;
        case 'ArrowDown':  e.preventDefault(); onDown();  break;
        // Confirm / back
        case 'Enter': case ' ': e.preventDefault(); onA(); break;
        case 'Escape': e.preventDefault(); if (qjOpen) setQjOpen(false); else onB(); break;
        // Left-hand D-pad (WASD)
        case 'w': case 'W': onUp(); break;
        case 'a': case 'A': onLeft(); break;
        case 's': case 'S': onDown(); break;
        case 'd': case 'D': onRight(); break;
        // Right-hand buttons (J K U I, emulator-style)
        case 'j': case 'J': onA(); break;
        case 'k': case 'K': onB(); break;
        case 'u': case 'U': onX(); break;
        case 'i': case 'I': onY(); break;
        // Home shortcut
        case 'h': case 'H': go('HOME', 0, 'zoom'); break;
        // Help
        case '?': case '/': e.preventDefault(); setHelpOpen(o => !o); break;
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onA, onB, onX, onY, onLeft, onRight, onUp, onDown, go, qjOpen, helpOpen, pendingSwitch]);

  // Idle auto-open help (30s) + close on any non-keyboard action.
  // Desktop only — mobile is a normal app with no help layer.
  // Keyboard-close is handled by the main onKey handler above.
  React.useEffect(() => {
    if (isMobile) return;
    const IDLE_MS = 30000;
    let idleTimer = null;
    let armed = false;

    const resetIdle = () => {
      if (idleTimer) clearTimeout(idleTimer);
      idleTimer = setTimeout(() => { setHelpOpen(true); }, IDLE_MS);
    };

    const onActiveAction = (e) => {
      resetIdle();
      if (!helpOpen || !armed) return;
      // Don't close if the user is interacting with the help card itself
      // (close button, GOT IT button, scrolling inside, etc.)
      const t = e.target;
      if (t && t.closest && t.closest('.help-card')) return;
      setHelpOpen(false);
    };

    // mousemove alone shouldn't close the help (user might just be reading),
    // but it SHOULD keep the idle timer alive.
    const onMove = () => resetIdle();

    // Re-arm the close-on-action logic shortly after open, so the very
    // click/tap that opened the help (e.g. HELP button click) doesn't
    // immediately re-close it.
    const armTimer = setTimeout(() => { armed = true; }, 120);

    const closeEvents = ['mousedown', 'touchstart', 'wheel'];
    closeEvents.forEach(evt => window.addEventListener(evt, onActiveAction, { passive: true }));
    window.addEventListener('mousemove', onMove, { passive: true });

    resetIdle();

    return () => {
      if (idleTimer) clearTimeout(idleTimer);
      clearTimeout(armTimer);
      closeEvents.forEach(evt => window.removeEventListener(evt, onActiveAction));
      window.removeEventListener('mousemove', onMove);
    };
  }, [helpOpen, isMobile]);

  // Touch swipes on the screen.
  //
  // Horizontal (left/right) = step through the current venture's sections
  //   — kept low-resistance since this is the primary in-venture nav.
  // Vertical (up/down)      = switch between ventures
  //   — when the user is INSIDE a venture, we require a much longer and
  //     more vertically-dominant gesture, because otherwise a casual
  //     swipe while reading can accidentally jump to the next venture.
  //     On HOME (the carousel) the old thresholds stay, because nothing
  //     is being "read" yet.
  const screenRef = React.useRef(null);
  React.useEffect(() => {
    const el = screenRef.current;
    if (!el) return;
    let sx = 0, sy = 0, st = 0, tracking = false;
    const onStart = (e) => {
      if (!e.touches || e.touches.length !== 1) return;
      sx = e.touches[0].clientX; sy = e.touches[0].clientY; st = Date.now();
      tracking = true;
    };
    const onEnd = (e) => {
      if (!tracking) return;
      tracking = false;
      const t = e.changedTouches && e.changedTouches[0];
      if (!t) return;
      const dx = t.clientX - sx;
      const dy = t.clientY - sy;
      const dt = Date.now() - st;
      if (dt > 700) return;
      const ax = Math.abs(dx), ay = Math.abs(dy);

      const inVenture = route !== 'HOME';
      const H_MIN = 40;                      // horizontal keeps its snappy threshold
      const V_MIN = inVenture ? 110 : 40;    // vertical needs a longer throw inside a venture
      const V_DOMINANCE = inVenture ? 1.8 : 1.0; // vertical must clearly out-measure horizontal

      if (ax >= ay) {
        if (ax < H_MIN) return;
        if (dx < 0) onRight(); else onLeft();
      } else {
        if (ay < V_MIN) return;
        if (ay / Math.max(1, ax) < V_DOMINANCE) return;
        if (inVenture) {
          // Don't yank the reader away — ask first.
          const idx = ROUTE_ORDER.indexOf(route);
          const targetKey = dy < 0
            ? ROUTE_ORDER[(idx + 1) % ROUTE_ORDER.length]
            : ROUTE_ORDER[(idx - 1 + ROUTE_ORDER.length) % ROUTE_ORDER.length];
          setPendingSwitch({
            target: targetKey,
            title: ROUTES[targetKey].label,
            dir: dy < 0 ? 'down' : 'up',
          });
          window.sfx && window.sfx.tick && window.sfx.tick();
          return;
        }
        if (dy < 0) onDown(); else onUp();
      }
    };
    el.addEventListener('touchstart', onStart, { passive: true });
    el.addEventListener('touchend', onEnd, { passive: true });
    return () => {
      el.removeEventListener('touchstart', onStart);
      el.removeEventListener('touchend', onEnd);
    };
  }, [onLeft, onRight, onUp, onDown, route]);

  const r = ROUTES[route];
  const curSec = r.sections[sectionIdx];
  const sectionLabel = curSec ? curSec.label : 'HOME';
  const total = r.sections.length;

  // Per-venture accent theming. On a venture route, use that venture's brand
  // accent. On HOME, preview the currently-selected card's accent so the
  // whole console colour-bleeds into the faction you're about to enter.
  const VENTURE_ACCENT = {
    surgeon: { phos: '#E24A4A', glow: 'rgba(226,74,74,0.55)'   }, // Surgeon medical red
    ai:      { phos: '#E36A3B', glow: 'rgba(227,106,59,0.55)'  }, // Puro terracotta
    lazy:    { phos: '#3D7BFF', glow: 'rgba(61,123,255,0.55)'  }, // Lazzzy blue
  };
  const ROUTE_TO_VID = { SURGEON: 'surgeon', AI: 'ai', LAZY: 'lazy' };
  const activeVid = route === 'HOME'
    ? (VENTURES[homeIdx]?.id || 'surgeon')
    : (ROUTE_TO_VID[route] || 'surgeon');
  const accent = VENTURE_ACCENT[activeVid] || VENTURE_ACCENT.surgeon;
  const cabinetThemeStyle = {
    '--phos': accent.phos,
    '--phos-glow': accent.glow,
    '--venture-accent': accent.phos,
    '--venture-accent-glow': accent.glow,
  };

  return (
    <div
      className={`cabinet route-${route.toLowerCase()} venture-${activeVid} ${dir ? `dir-${dir}` : ''} ${qjOpen ? 'qj-open' : ''} ${menuOpen ? 'menu-open' : ''}`}
      style={cabinetThemeStyle}
    >
      <div className="cabinet-header">
        <button
          className="ch-wordmark"
          onClick={() => { window.sfx && window.sfx.click(); go('HOME', 0, 'zoom'); setMenuOpen(false); }}
          aria-label="Go to Home"
          title="Home"
          type="button"
        >
          <img className="ch-logo" src="assets/logo-wide-white.png" alt="The Tomorrow Tribe — Home" />
        </button>
        <button className="ch-hamburger" onClick={() => setMenuOpen(o => !o)} aria-label="Menu">
          <span></span><span></span><span></span>
        </button>
        <div className={`ch-nav ${menuOpen ? 'is-open' : ''}`}>
          <div className="ch-nav-header">
            <span>PAUSE · ROUTES</span>
            <button className="ch-nav-close" onClick={() => setMenuOpen(false)} aria-label="Close menu" title="Resume">×</button>
          </div>
          {ROUTE_ORDER.map(rk => (
            <button key={rk} className={`ch-nav-btn ${rk === route ? 'is-active' : ''}`}
              onClick={() => { go(rk, 0, 'zoom'); setMenuOpen(false); }}>
              ◆ {ROUTES[rk].short || ROUTES[rk].label}
            </button>
          ))}
          {isMobile && (
            <div className="ch-nav-swipe-brief">
              <div className="nsb-head">◆ HOW TO NAVIGATE</div>
              <div className="nsb-row">
                <span className="nsb-glyph">↕</span>
                <div>
                  <strong>Swipe up / down</strong>
                  <small>Switch between ventures</small>
                </div>
              </div>
              <div className="nsb-row">
                <span className="nsb-glyph">↔</span>
                <div>
                  <strong>Swipe left / right</strong>
                  <small>Go deeper within a venture — step through its sections</small>
                </div>
              </div>
            </div>
          )}
        </div>
        {menuOpen && <div className="ch-nav-scrim" onClick={() => setMenuOpen(false)} />}
        <div className="ch-status">
          {!isMobile && (
            <button className="ch-help" onClick={() => setHelpOpen(true)} title="How to navigate (?)" aria-label="Help">
              <span>?</span> HELP
            </button>
          )}
          <button
            className={`ch-mute ch-mute-music ${musicMuted ? 'muted' : ''}`}
            onClick={toggleMusic}
            title="Toggle background music"
            aria-label={musicMuted ? 'Unmute music' : 'Mute music'}
          >
            <span>{musicMuted ? '◌' : '♪'}</span> MUSIC
          </button>
          <button
            className={`ch-mute ch-mute-sfx ${sfxMuted ? 'muted' : ''}`}
            onClick={onY}
            title="Toggle sound effects (Y / I)"
            aria-label={sfxMuted ? 'Unmute SFX' : 'Mute SFX'}
          >
            <span>{sfxMuted ? '◌' : '◉'}</span> SFX
          </button>
          <div className="ch-online"><span className="dot" />ONLINE</div>
        </div>
      </div>

      <div className="console cabinet-console">
        <div className="chassis-hint chassis-hint-top">
          ◆ TAP A VENTURE OR USE THE ARROW KEYS TO EXPLORE — EVERY BUTTON ON THE CONSOLE IS REAL ◆
        </div>
        <Bracket />
        <ConsoleHeader route={route} sectionLabel={sectionLabel} sectionIdx={sectionIdx} total={total} />

        <div className="screen" ref={screenRef}>
          <div className="screen-hud">
            {/* On HOME the route label would say "PICK A VENTURE" — the
                same copy appears above the screen and on the right side
                of this HUD. Leave the left blank here to stop the triple
                repeat the user saw on their phone. */}
            <div>{route === 'HOME' ? '' : r.label}</div>
            <button className="hud-menu-btn" onClick={() => setQjOpen(true)} aria-label="Open quick-jump menu">
              ☰ MENU
            </button>
            <div>{total > 0
              ? <><span className="blink">▶</span> SEC {sectionIdx + 1}/{total}</>
              : <><span className="blink">▶</span> PICK A VENTURE</>}</div>
          </div>

          {showSwipeHint && (
            <div className="swipe-hint">
              <div className="sh-icon">
                <span className="sh-arrow left">◀</span>
                <span className="sh-hand">👆</span>
                <span className="sh-arrow right">▶</span>
              </div>
              <div className="sh-text">SWIPE TO NAVIGATE</div>
            </div>
          )}

          {route === 'HOME'
            ? <HomeCarousel idx={homeIdx} setIdx={setHomeIdx} enter={onA} />
            : <SlideStack route={route} sectionIdx={sectionIdx} dir={dir} />}

          {/* Subtle swipe cues anchored in the screen's top corners on
              venture pages — shows the previous section name on the
              left and the next section name on the right so users
              always know where a swipe will take them. Tappable too. */}
          {route !== 'HOME' && total > 1 && sectionIdx > 0 && (
            <button
              type="button"
              className="swipe-cue swipe-cue-left"
              onClick={() => go(route, sectionIdx - 1, 'left')}
              aria-label={`Previous section: ${r.sections[sectionIdx - 1].label}`}
            >
              <span className="sc-arrow">◀</span>
              <span className="sc-label">{r.sections[sectionIdx - 1].label}</span>
            </button>
          )}
          {route !== 'HOME' && total > 1 && sectionIdx < total - 1 && (
            <button
              type="button"
              className="swipe-cue swipe-cue-right"
              onClick={() => go(route, sectionIdx + 1, 'right')}
              aria-label={`Next section: ${r.sections[sectionIdx + 1].label}`}
            >
              <span className="sc-label">{r.sections[sectionIdx + 1].label}</span>
              <span className="sc-arrow">▶</span>
            </button>
          )}

          {/* Section dots — visible on subpages so users can see how many
              sections exist and where they are. Tapping jumps directly. */}
          {route !== 'HOME' && total > 1 && (
            <div className="section-dots" role="tablist" aria-label={`Sections of ${r.label}`}>
              {r.sections.map((s, i) => (
                <button
                  key={s.id}
                  type="button"
                  className={`section-dot ${i === sectionIdx ? 'is-active' : ''}`}
                  aria-label={`Go to ${s.label}`}
                  aria-selected={i === sectionIdx}
                  role="tab"
                  onClick={() => go(route, i, i > sectionIdx ? 'right' : 'left')}
                />
              ))}
            </div>
          )}

          <QuickJump open={qjOpen} onClose={() => setQjOpen(false)} go={go}
            currentRoute={route} currentSectionIdx={sectionIdx} />

          {route !== 'HOME' && (
            <>
              <button className={`carousel-btn prev ${showSwipeHint ? 'pulse' : ''}`} onClick={onLeft} aria-label="Previous">◀</button>
              <button className={`carousel-btn next ${showSwipeHint ? 'pulse' : ''}`} onClick={onRight} aria-label="Next">▶</button>
            </>
          )}

          <div className="screen-footer">
            <div>◇ {route === 'HOME' ? 'PICK A VENTURE' : sectionLabel}</div>
            <div>CRT · {dir ? dir.toUpperCase() : 'STABLE'}</div>
          </div>
        </div>

        <div className="console-controls">
          <DPad dir={dpadDir} onUp={onUp} onDown={onDown} onLeft={onLeft} onRight={onRight} />
          <div className="console-legend">
            <div><span className="key">WASD</span>MOVE</div>
            <div><span className="key">J</span>{route === 'HOME' ? 'ENTER' : 'NEXT'}</div>
            <div><span className="key">K</span>BACK</div>
            <div><span className="key">U</span>MENU</div>
            <div><span className="key">I</span>MUTE</div>
          </div>
          <ABXYButtons pressed={pressed} onA={onA} onB={onB} onX={onX} onY={onY} />
        </div>
        <div className="chassis-hint chassis-hint-bottom">
          {isMobile ? (
            <>◆ SWIPE OR TAP TO MOVE · TAP <b>?</b> FOR HELP ◆</>
          ) : (
            <>◆ <b>ENTER</b> OPENS · <b>ESC</b> GOES BACK · <b>U</b> MENU · <b>?</b> HELP ◆</>
          )}
        </div>
      </div>
      {isMobile && (
        <button
          className="mobile-help-fab"
          onClick={() => setHelpOpen(true)}
          aria-label="About this site and how to navigate"
          title="What is this? How do I use it?"
        >
          ?
        </button>
      )}
      <HelpOverlay open={helpOpen} onClose={() => setHelpOpen(false)} isMobile={isMobile} />
      {pendingSwitch && (
        <div
          className="route-confirm-overlay"
          onClick={() => setPendingSwitch(null)}
          role="dialog"
          aria-modal="true"
          aria-label="Open another venture?"
        >
          <div className="route-confirm-card" onClick={e => e.stopPropagation()}>
            <div className="rc-eyebrow">◇ Open another venture?</div>
            <div className="rc-title"><span className="rc-target">{pendingSwitch.title}</span></div>
            <div className="rc-buttons">
              <button
                className="rc-btn rc-no"
                onClick={() => { window.sfx && window.sfx.click(); setPendingSwitch(null); }}
                autoFocus
              >
                Keep reading
              </button>
              <button
                className="rc-btn rc-yes"
                onClick={() => {
                  const tgt = pendingSwitch.target;
                  const dir = pendingSwitch.dir === 'down' ? 'down' : 'up';
                  setPendingSwitch(null);
                  window.sfx && window.sfx.enter && window.sfx.enter();
                  go(tgt, 0, dir);
                }}
              >
                Open →
              </button>
            </div>
            <div className="rc-hint">Tip: swipe <b>left</b> or <b>right</b> to stay inside this venture and step through its sections.</div>
          </div>
        </div>
      )}
    </div>
  );
}

window.Cabinet = Cabinet;
