// ═══════════════════════════════════════════════════════════════════════════
// Chrome — the margin of a proof, not a navigation bar.
//
// The left strip carries what a printed proof carries in its margin: the
// mark, the running head of the part you are in, the folio, and the cushion
// readout. The cushion `d` runs 1 → 0 as you descend, and the mark falls with
// it: the four stems settle toward the barrier rule they must not cross.
// ═══════════════════════════════════════════════════════════════════════════

const PARTS = [
  ['research',     'Research',   'I'],
  ['publications', 'Papers',     'II'],
  ['models',       'Models',     'III'],
  ['insights',     'Notes',      'IV'],
  ['philosophy',   'Tenets',     'V'],
  ['team',         'Lab',        'VI'],
  ['contact',      'Correspondence', 'VII'],
];

const SPY_IDS = ['hero', ...PARTS.map(([id]) => id)];

const Arrow = ({ s = 11 }) => (
  <svg width={s} height={s} viewBox="0 0 11 11" fill="none" style={{ flex: 'none' }}>
    <path d="M1.6 9.4L9.4 1.6M9.4 1.6H3.9M9.4 1.6V7.1"
      stroke="currentColor" strokeWidth="1.1" strokeLinecap="square" />
  </svg>
);

// The mark is the Lab's own lettering, used as drawn. The only thing the
// design adds is behaviour: a barrier rule under the wordmark that rises
// toward it as the cushion `d` closes, so the logo reads the document.
// `logo.svg` is the author's original file, byte for byte; `logo-mark.svg`
// and `logo-wordmark.svg` are the same artwork cropped for icon and lockup.
const Mark = ({ d = 1, variant = 'icon', size = 26 }) => (
  <span className={`mark mark-${variant}`} style={{ '--mk': `${size}px` }} aria-hidden="true">
    <i className="mark-glyph" />
    <i className="mark-rule" style={{ transform: `translateY(${((1 - d) * -9).toFixed(2)}px)` }} />
  </span>
);

const ThemeSwitch = ({ theme, setTheme }) => (
  <button className="tsw" data-t={theme}
    aria-label={theme === 'dark' ? 'Switch to stock' : 'Switch to plate'}
    onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
    <span />
  </button>
);

const Margin = ({ theme, setTheme, active, depth }) => {
  const d = 1 - depth;
  return (
    <div className="margin">
      <a href="#hero" aria-label="MMRL — head of document"
        onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>
        <Mark d={d} variant="icon" size={26} />
      </a>

      <nav className="margin-nav">
        <span className="gauge" aria-hidden="true"><i /></span>
        {PARTS.map(([id, label]) => (
          <a key={id} href={`#${id}`} className="folio" data-on={active === id ? '1' : '0'}
            onClick={(e) => { e.preventDefault(); goTo(id); }}>
            {label}
          </a>
        ))}
      </nav>

      <div className="margin-foot">
        <span className="readout" title="cushion — distance to the barrier">
          d {d.toFixed(2)}
        </span>
        <ThemeSwitch theme={theme} setTheme={setTheme} />
      </div>
    </div>
  );
};

const MobileBar = ({ theme, setTheme, active, depth }) => {
  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  const label = (PARTS.find(([id]) => id === active) || [null, 'Head'])[1];

  return (
    <>
      <div className="mbar">
        <span className="mbar-d" />
        <a href="#hero" style={{ display: 'flex', alignItems: 'center', gap: 10 }}
          onClick={(e) => { e.preventDefault(); setOpen(false); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>
          <Mark d={1 - depth} variant="word" size={15} />
        </a>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
          <span className="mono mono-n" style={{ fontSize: 9.5, color: 'var(--text-3)' }}>
            d {(1 - depth).toFixed(2)}
          </span>
          <button className="burger" data-open={open ? '1' : '0'} aria-label="Contents"
            aria-expanded={open} onClick={() => setOpen((o) => !o)}>
            <i /><i />
          </button>
        </div>
      </div>

      <div className="msheet" data-open={open ? '1' : '0'}>
        <div className="sc sc-thin" style={{ marginBottom: 14 }}>Contents · {label}</div>
        {PARTS.map(([id, l, roman]) => (
          <a key={id} href={`#${id}`}
            onClick={(e) => { e.preventDefault(); setOpen(false); setTimeout(() => goTo(id), 260); }}>
            <span>{l}</span>
            <span className="mono mono-n dim">{roman}</span>
          </a>
        ))}
        <div style={{ marginTop: 28, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span className="sc">Appearance</span>
          <ThemeSwitch theme={theme} setTheme={setTheme} />
        </div>
      </div>
    </>
  );
};

// Running head of a part: the numeral sunk into the field, the statement
// lifted off it. Hierarchy in two directions from one ground.
const PartHead = ({ roman, label, note, title }) => (
  <header className="part-head">
    <span className="part-no" aria-hidden="true">{roman}</span>
    <div className="part-rail rv">
      <span className="sc sc-on">{label}</span>
      <hr />
      {note && <span className="mono mono-n dim">{note}</span>}
    </div>
    <h2 className="statement rv" style={{ '--rv-d': '90ms' }}>{title}</h2>
  </header>
);

window.PARTS = PARTS;
window.SPY_IDS = SPY_IDS;
window.Arrow = Arrow;
window.Mark = Mark;
window.ThemeSwitch = ThemeSwitch;
window.Margin = Margin;
window.MobileBar = MobileBar;
window.PartHead = PartHead;
