// Shared theme tokens, chrome (top bar / footer), and small primitives for the Operator's Console site.

const A = {
  bg: '#0E0C09',
  panel: '#15120D',
  panel2: '#191510',
  line: '#2A2520',
  lineSoft: '#1F1B16',
  cream: '#EFE6D2',
  creamDim: '#9A9183',
  creamFaint: '#5D584F',
  ink: '#0A0907',
  terracotta: '#C25A2E',
  ochre: '#D89A3F',
  olive: '#9C9648',
  rust: '#8A3B1E',
  signal: '#F2C14E',
  signalSoft: 'rgba(242,193,78,0.08)',
};
window.A = A;

const ROUTES = [
  { id: 'home',     num: '01', label: 'OVERVIEW', href: 'index.html' },
  { id: 'about',    num: '02', label: 'BRIEF',    href: 'about.html' },
  { id: 'numbers',  num: '03', label: 'METRICS',  href: 'numbers.html' },
  { id: 'work',     num: '04', label: 'RECORD',   href: 'record.html' },
  { id: 'reach',    num: '05', label: 'REACH',    href: 'reach.html' },
  { id: 'contact',  num: '06', label: 'CONTACT',  href: 'contact.html' },
];
window.ROUTES = ROUTES;

function useClock() {
  const [t, setT] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  return t;
}
window.useClock = useClock;

function useViewportWidth() {
  const [w, setW] = React.useState(() => typeof window !== 'undefined' ? window.innerWidth : 1440);
  React.useEffect(() => {
    const onResize = () => setW(window.innerWidth);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return w;
}
window.useViewportWidth = useViewportWidth;

// Shared responsive primitives — every page-*.jsx reads these.
function useResponsive() {
  const w = useViewportWidth();
  return {
    w,
    isPhone:  w < 640,
    isTablet: w < 960,
    isWide:   w >= 1200,
  };
}
window.useResponsive = useResponsive;

function TopBar({ active }) {
  const t = useClock();
  const w = useViewportWidth();
  const isPhone = w < 640;
  const isTablet = w < 960;
  const showTagline = w >= 1100; // hide the tagline on phones; logo stays via the dot
  const showClock = w >= 720;
  const showLocation = w >= 1200;
  const navGap = w >= 1440 ? 22 : (w >= 1200 ? 14 : (w >= 720 ? 12 : 10));
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: isPhone ? '10px 14px' : '14px 28px',
      borderBottom: `1px solid ${A.line}`,
      position: 'sticky', top: 0, zIndex: 50,
      background: A.bg,
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: isPhone ? 11 : 12, letterSpacing: '0.08em',
      gap: isPhone ? 8 : 16,
      flexWrap: isPhone ? 'wrap' : 'nowrap',
    }}>
      <a href="index.html" style={{
        display: 'flex', alignItems: 'center', gap: 10, color: A.cream, textDecoration: 'none',
        whiteSpace: 'nowrap', flexShrink: 0,
      }}>
        <span style={{ width: 10, height: 10, background: A.signal, borderRadius: '50%', boxShadow: `0 0 8px ${A.signal}`, flexShrink: 0 }} />
        {showTagline
          ? <span style={{ color: A.cream, fontWeight: 600 }}>CHIEF OF STAFF · OPERATIONS LEADER · STRATEGY-TO-DELIVERY TRANSLATOR</span>
          : <span style={{ color: A.cream, fontWeight: 600 }}>A.O.C.</span>}
      </a>
      <div style={{
        display: 'flex',
        gap: `6px ${navGap}px`,
        color: A.creamDim,
        flexWrap: isPhone ? 'wrap' : 'nowrap',
        minWidth: 0,
        order: isPhone ? 3 : 0,
        flexBasis: isPhone ? '100%' : 'auto',
        justifyContent: isPhone ? 'flex-start' : 'flex-start',
        marginTop: isPhone ? 4 : 0,
      }}>
        {ROUTES.map(r => (
          <a key={r.id} href={r.href} style={{
            color: r.id === active ? A.signal : A.creamDim,
            textDecoration: 'none',
            transition: 'color 0.15s',
            whiteSpace: 'nowrap',
            padding: isPhone ? '4px 0' : 0,
            fontSize: isPhone ? 10.5 : 'inherit',
          }}
            onMouseEnter={e => { if (r.id !== active) e.currentTarget.style.color = A.cream; }}
            onMouseLeave={e => { if (r.id !== active) e.currentTarget.style.color = A.creamDim; }}
          >
            {r.label}
          </a>
        ))}
      </div>
      <div style={{
        display: 'flex', gap: isPhone ? 10 : 16, color: A.creamDim,
        whiteSpace: 'nowrap', flexShrink: 0,
      }}>
        {showLocation && <span>JHB · UTC+2</span>}
        {showClock && <span style={{ color: A.cream }}>{t.toLocaleTimeString('en-GB', { hour12: false }).slice(0, 5)}</span>}
        <span style={{ color: A.signal }}>● LIVE</span>
      </div>
    </div>
  );
}
window.TopBar = TopBar;

function GridBg() {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      backgroundImage: `linear-gradient(${A.line} 1px, transparent 1px), linear-gradient(90deg, ${A.line} 1px, transparent 1px)`,
      backgroundSize: '64px 64px',
      opacity: 0.32, pointerEvents: 'none',
    }} />
  );
}
window.GridBg = GridBg;

function SectionHeader({ num, kicker, title, italic, sub }) {
  void num; // numbering retired — kicker carries the meaning now
  const w = useViewportWidth();
  const isPhone = w < 640;
  return (
    <div style={{
      padding: isPhone ? '36px 18px 24px' : '56px 48px 28px',
      borderBottom: `1px solid ${A.line}`, position: 'relative',
    }}>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: isPhone ? 10 : 11, letterSpacing: '0.22em',
        color: A.ochre, marginBottom: isPhone ? 14 : 18, fontWeight: 700, lineHeight: 1.4,
      }}>{kicker}</div>
      <h1 style={{
        margin: 0, color: A.cream, lineHeight: 0.92, letterSpacing: '-0.03em',
        fontFamily: "'Fraunces', serif",
        fontVariationSettings: '"opsz" 144, "wght" 600, "SOFT" 30, "WONK" 1',
        fontSize: 'clamp(44px, 11vw, 96px)',
      }}>
        {title}
        {italic && <span style={{
          fontStyle: 'italic',
          fontVariationSettings: '"opsz" 144, "wght" 400, "SOFT" 100, "WONK" 1',
          color: A.terracotta,
        }}> {italic}</span>}
      </h1>
      {sub && <div style={{
        marginTop: isPhone ? 16 : 22, maxWidth: 740,
        fontFamily: "'Inter', sans-serif",
        fontSize: isPhone ? 15 : 17, lineHeight: 1.55, color: A.creamDim,
      }}>{sub}</div>}
    </div>
  );
}
window.SectionHeader = SectionHeader;

function Footer({ active }) {
  const w = useViewportWidth();
  const isPhone = w < 640;
  return (
    <div style={{
      borderTop: `1px solid ${A.line}`, marginTop: isPhone ? 48 : 80,
      padding: isPhone ? '14px 18px' : '20px 48px',
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      flexWrap: 'wrap', gap: 8,
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: isPhone ? 9 : 10, letterSpacing: '0.2em',
      color: A.creamFaint,
    }}>
      <span>© 2026 A. ORDONEZ CARDENAS</span>
      <span style={{ color: A.signal, opacity: 0.7 }}>● ALL SYSTEMS NOMINAL</span>
    </div>
  );
}
window.Footer = Footer;

// Custom cursor + global keyboard easter egg + ?-help overlay
function GlobalChrome() {
  const [pos, setPos] = React.useState({ x: -100, y: -100 });
  const [pointer, setPointer] = React.useState(false);
  const [help, setHelp] = React.useState(false);
  const [konami, setKonami] = React.useState(false);
  const [hasFinePointer, setHasFinePointer] = React.useState(false);
  const buf = React.useRef('');

  React.useEffect(() => {
    // Only render the custom cursor on devices with a fine pointer (mouse / trackpad).
    // Touch devices keep the native cursor + native scrolling behaviour.
    if (typeof window !== 'undefined' && window.matchMedia) {
      const mql = window.matchMedia('(pointer: fine)');
      setHasFinePointer(mql.matches);
      const onChange = (e) => setHasFinePointer(e.matches);
      mql.addEventListener?.('change', onChange);
      return () => mql.removeEventListener?.('change', onChange);
    }
  }, []);

  React.useEffect(() => {
    if (!hasFinePointer) return;
    document.body.style.cursor = 'none';
    return () => { document.body.style.cursor = ''; };
  }, [hasFinePointer]);

  React.useEffect(() => {
    const onMove = (e) => {
      setPos({ x: e.clientX, y: e.clientY });
      const el = document.elementFromPoint(e.clientX, e.clientY);
      const isLink = el && (el.closest('a') || el.closest('button') || el.closest('[data-cursor="pointer"]'));
      setPointer(!!isLink);
    };
    const onKey = (e) => {
      if (e.key === '?') { setHelp(h => !h); return; }
      if (e.key === 'Escape') { setHelp(false); setKonami(false); return; }
      if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) return;
      // ROUTES shortcuts: 1..7
      const idx = parseInt(e.key, 10);
      if (!isNaN(idx) && idx >= 1 && idx <= ROUTES.length) {
        location.href = ROUTES[idx - 1].href; return;
      }
      // word buffer for "ops"
      buf.current = (buf.current + e.key.toLowerCase()).slice(-6);
      if (buf.current.endsWith('ops')) { setKonami(true); buf.current = ''; }
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('keydown', onKey);
    return () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('keydown', onKey);
    };
  }, []);

  return (
    <>
      {/* custom cursor — only on fine-pointer devices */}
      {hasFinePointer && <div style={{
        position: 'fixed', left: pos.x, top: pos.y,
        transform: `translate(-50%, -50%) scale(${pointer ? 1.6 : 1})`,
        width: 14, height: 14, borderRadius: '50%',
        background: 'transparent', border: `1.5px solid ${A.signal}`,
        pointerEvents: 'none', zIndex: 9999,
        mixBlendMode: 'difference',
        transition: 'transform 0.12s ease, border-color 0.12s ease',
      }} />}
      {hasFinePointer && <div style={{
        position: 'fixed', left: pos.x, top: pos.y,
        transform: 'translate(-50%, -50%)',
        width: 3, height: 3, borderRadius: '50%',
        background: A.signal, pointerEvents: 'none', zIndex: 9999,
      }} />}

      {help && (
        <div style={{
          position: 'fixed', inset: 0, zIndex: 9998,
          background: 'rgba(14,12,9,0.86)', backdropFilter: 'blur(4px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: "'JetBrains Mono', monospace", color: A.cream,
        }} onClick={() => setHelp(false)}>
          <div style={{ background: A.panel, border: `1px solid ${A.line}`, padding: 36, minWidth: 480, maxWidth: 560 }}>
            <div style={{ fontSize: 11, letterSpacing: '0.22em', color: A.signal, marginBottom: 18 }}>KEYBOARD · COMMANDS</div>
            {[
              ['1 — 7', 'JUMP TO SECTION'],
              ['?', 'TOGGLE THIS HELP'],
              ['ESC', 'DISMISS OVERLAYS'],
              ['TYPE "OPS"', 'RUN THE BOOT SEQUENCE'],
            ].map(([k, v]) => (
              <div key={k} style={{ display: 'grid', gridTemplateColumns: '160px 1fr', padding: '10px 0', borderTop: `1px solid ${A.line}`, fontSize: 13 }}>
                <span style={{ color: A.ochre, letterSpacing: '0.14em' }}>{k}</span>
                <span style={{ color: A.creamDim, letterSpacing: '0.14em' }}>{v}</span>
              </div>
            ))}
            <div style={{ marginTop: 18, fontSize: 11, color: A.creamFaint, letterSpacing: '0.2em' }}>CLICK ANYWHERE TO CLOSE</div>
          </div>
        </div>
      )}

      {konami && (
        <div style={{
          position: 'fixed', inset: 0, zIndex: 9998,
          background: 'rgba(14,12,9,0.94)',
          fontFamily: "'JetBrains Mono', monospace", color: A.signal,
          padding: 48, fontSize: 13, lineHeight: 1.7, overflow: 'hidden',
        }} onClick={() => setKonami(false)}>
          <BootSequence />
          <div style={{ position: 'absolute', bottom: 24, right: 36, color: A.creamFaint, fontSize: 11, letterSpacing: '0.2em' }}>CLICK TO CLOSE</div>
        </div>
      )}
    </>
  );
}
window.GlobalChrome = GlobalChrome;

function BootSequence() {
  const lines = [
    '> aoc.ops --boot',
    'mounting / .................................. ok',
    'starting reconciliation.daemon ............... ok  [2M records / mo · 90% auto]',
    'starting programme.scheduler ................. ok  [12 critical / yr]',
    'starting hire.pipeline ....................... ok  [t-to-hire: 14d, was 42d]',
    'starting reporting.bus ....................... ok  [+30% transparency]',
    'mounting /workspaces/current ................. ok',
    'mounting /workspaces/consulting .............. ok',
    'mounting /workspaces/early ................... ok',
    'attaching co-operators ....................... ok',
    '',
    '[ INFO ] 11 years, 9 industries, 4 continents online.',
    '[ INFO ] currently bottleneck-free.',
    '[ READY ] awaiting next mandate.',
    '',
    '> _',
  ];
  const [shown, setShown] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setShown(s => Math.min(lines.length, s + 1)), 110);
    return () => clearInterval(id);
  }, []);
  return (
    <div>
      {lines.slice(0, shown).map((l, i) => (
        <div key={i} style={{
          color: l.startsWith('>') ? A.cream : (l.includes('[ READY ]') ? A.signal : (l.includes('[ INFO ]') ? A.ochre : A.creamDim)),
        }}>{l || '\u00a0'}</div>
      ))}
    </div>
  );
}

function PageShell({ active, children }) {
  return (
    <div style={{
      minHeight: '100vh', background: A.bg, color: A.cream,
      fontFamily: "'Space Grotesk', 'Inter', sans-serif",
      position: 'relative',
      overflowX: 'clip',
    }}>
      <GlobalChrome />
      <TopBar active={active} />
      <GridBg />
      {/* No z-index here — must NOT create a stacking context, or modals/popups inside
         (e.g. the metrics case study) get trapped below the top nav. */}
      <div style={{ position: 'relative' }}>
        {children}
      </div>
      <Footer active={active} />
    </div>
  );
}
window.PageShell = PageShell;
