// sw-components.jsx — Shared design system components
// Almanac preview: blue-hour ground, frost text, Ember as the one warm accent

const C = {
  black: '#0e1520',      // blue hour
  slate: '#17202d',
  deep: '#0a1019',
  line: '#273345',
  lineStrong: '#43516a',
  white: '#eae7df',      // frost
  pink: '#17202d',       // the draft's blush band becomes slate
  greenBright: '#3f5a3a',
  greenForest: '#9fb38a', // lichen
  greenDeep: '#eae7df',
  grey3: '#8e95a0',
  grey4: '#c3c4c2',      // mist
  amber: '#dda149',      // ember
  ember: '#dda149',
  blueGrade: '#1e2b44',
  parchment: '#f4efe6',  // light reading sections
  ink: '#1c1e1a',
  driftwood: '#6b675f',
  emberDeep: '#7a4e0e',
};

// The logomark's two triangles, exactly as in Logos/SVGs/KS_logo_mark.svg (500 × 500 box)
const MARK_DOWN = '246.7,80.95 405.98,80.95 326.34,218.89 246.7,356.83 167.06,218.89 87.42,80.95';
const MARK_UP = '246.7,418.95 87.42,418.95 167.06,281 246.7,143.06 326.34,281 405.98,418.95';

// Real links for moving between pages: a plain click stays in the page as before,
// while Cmd/Ctrl-click or a middle click opens a new tab, and keyboards can reach them
const plainClick = (e) => e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;
// Clean page addresses (/wheel, /about…), since the domain moved (13 Nov 2026).
// goPage changes the address and tells the app, which listens for popstate.
const goPage = (id) => {
  const path = id === 'home' ? '/' : `/${id}`;
  if (window.location.pathname !== path) window.history.pushState({}, '', path);
  window.dispatchEvent(new PopStateEvent('popstate'));
};
window.goPage = goPage;
const linkTo = (navigate, id) => (e) => {
  if (!plainClick(e)) return;
  e.preventDefault(); navigate(id); window.scrollTo(0, 0);
};

const T = {
  font: "'Gill Sans', 'Cabin', sans-serif",
  serif: "'IM Fell English', Georgia, serif",
  serifStyle: 'italic', // back to italic (Krish, 29 Oct 2026); 'normal' sets IM Fell upright
  light: 300,
};

// ── Shared design tokens (6 Nov 2026): the values the refined pages share, in one place ──
// See "Site design rules (6 Nov 2026).md". The same values are CSS variables in index.html (:root) for the style rules there.
const TOK = {
  cream: 'rgba(234,231,223,0.9)',      // body text on dark grounds
  creamSoft: 'rgba(234,231,223,0.8)',  // quieter body text on dark grounds (panels, descriptions)
  body: 17,                            // body text, px
  bodyLg: 18,                          // body text in open sections, px
  leading: 1.8,                        // body line height
  measure: '33em',                     // the widest a paragraph runs
  padSection: '88px 0',                // standard section padding
  padKey: 'clamp(88px,9vw,120px) 0',   // a page's key sections
  padFeature: 'clamp(88px, 10vw, 128px) 0', // the home page's sections
  tap: 44,                             // smallest tap target, px
  rule: (c) => `2px solid ${c}`,       // the gold edge on panels and quotes
};

// The Druid gates in order, with the dates used for the almanac line
const GATES = [
  { name: 'Imbolc', m: 1, d: 1 },
  { name: 'Alban Eilir', season: 'spring equinox', m: 2, d: 20 },
  { name: 'Beltane', m: 4, d: 1 },
  { name: 'Alban Hefin', season: 'summer solstice', m: 5, d: 21 },
  { name: 'Lughnasadh', m: 7, d: 1 },
  { name: 'Alban Elfed', season: 'autumn equinox', m: 8, d: 22 },
  { name: 'Samhain', m: 9, d: 31 },
  { name: 'Alban Arthan', season: 'winter solstice', m: 11, d: 21 },
];
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

function nextGate(now = new Date()) {
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  for (const g of GATES) {
    const date = new Date(now.getFullYear(), g.m, g.d);
    if (date >= today) return { ...g, date };
  }
  return { ...GATES[0], date: new Date(now.getFullYear() + 1, GATES[0].m, GATES[0].d) };
}

// Reworded (Krish, 5 Nov 2026): full month, season in plain words, no year. It must start "Next gate",
// as the footer's hover countdown (sw-interactions.js) finds the line by those words
const MONTHS_FULL = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
function gateLine() {
  const g = nextGate();
  return `Next gate: ${g.name}${g.season ? `, the ${g.season}` : ''}, ${g.date.getDate()} ${MONTHS_FULL[g.date.getMonth()]}`;
}

// ── The wheel: eight gates, Alban Hefin at the top, the next gate marked in Ember ──
function Wheel({ size = 560, opacity = 0.35, color = C.white }) {
  // Clockwise from the top: Alban Hefin, Lughnasadh, Alban Elfed, Samhain, Alban Arthan, Imbolc, Alban Eilir, Beltane
  const order = ['Alban Hefin', 'Lughnasadh', 'Alban Elfed', 'Samhain', 'Alban Arthan', 'Imbolc', 'Alban Eilir', 'Beltane'];
  const active = order.indexOf(nextGate().name);
  const pt = (i, r) => [300 + r * Math.sin(i * Math.PI / 4), 300 - r * Math.cos(i * Math.PI / 4)];
  return (
    <svg viewBox="0 0 600 600" fill="none" style={{ width: size, height: size, display: 'block' }} aria-hidden="true">
      <g stroke={color} opacity={opacity}>
        <circle cx="300" cy="300" r="290" strokeWidth="1" />
        <circle cx="300" cy="300" r="240" strokeWidth="0.6" opacity="0.5" />
        {order.map((_, i) => {
          const [x1, y1] = pt(i, 278); const [x2, y2] = pt(i, 300);
          return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} strokeWidth="1.4" />;
        })}
        {/* The logomark at the centre, true to its geometry */}
        <g transform="translate(300 300) scale(0.5) translate(-246.7 -250)" strokeLinejoin="round">
          <polygon points={MARK_DOWN} strokeWidth="3.2" />
          <polygon points={MARK_UP} strokeWidth="3.2" />
        </g>
      </g>
      {active >= 0 && <circle cx={pt(active, 290)[0]} cy={pt(active, 290)[1]} r="8" fill={C.ember} />}
    </svg>
  );
}

// ── Manifesto shapes, drawn as lines so they sit on any ground ──
function AlmanacShape({ kind, color = C.greenForest, size = 96 }) {
  const s = { fill: 'none', stroke: color, strokeWidth: 1.2 };
  const star = [0, 30, 60, 90, 120, 150].map(a => {
    const r = a * Math.PI / 180;
    return [30 + 22 * Math.cos(r), 30 + 22 * Math.sin(r), 30 - 22 * Math.cos(r), 30 - 22 * Math.sin(r)];
  });
  return (
    <svg viewBox="0 0 60 60" style={{ width: size, height: size, display: 'block', margin: '0 auto' }} aria-hidden="true">
      {kind === 'circle' && <circle cx="30" cy="30" r="24" {...s} />}
      {kind === 'dodecagon' && <polygon {...s} points="55.1,36.7 48.4,48.4 36.7,55.1 23.3,55.1 11.6,48.4 4.9,36.7 4.9,23.3 11.6,11.6 23.3,4.9 36.7,4.9 48.4,11.6 55.1,23.3" />}
      {kind === 'star' && star.map((l, i) => <line key={i} x1={l[0]} y1={l[1]} x2={l[2]} y2={l[3]} {...s} />)}
      {kind === 'nested' && <>
        <polygon points="30,4 56,50 4,50" {...s} />
        <polygon points="30,18 47,46 13,46" {...s} opacity="0.7" />
        <polygon points="30,28 40,44 20,44" {...s} opacity="0.45" />
      </>}
      {kind === 'triangle' && <>
        <polygon points="30,6 50.78,42 9.22,42" {...s} />
        <polygon points="30,54 9.22,18 50.78,18" {...s} />
      </>}
      {kind === 'drop' && <path d="M30 5 C30 5 50 30 50 39 A20 20 0 0 1 10 39 C10 30 30 5 30 5 Z" {...s} />}
      {/* Marks for the belief cards */}
      {kind === 'seed' && <><circle cx="30" cy="30" r="22" {...s} /><circle cx="30" cy="30" r="5" {...s} fill={color} /></>}
      {kind === 'sunrise' && <>
        <line x1="6" y1="42" x2="54" y2="42" {...s} />
        <path d="M14 42 A16 16 0 0 1 46 42" {...s} />
        {[-60, -30, 0, 30, 60].map(a => {
          const r = a * Math.PI / 180;
          return <line key={a} x1={30 + 21 * Math.sin(r)} y1={42 - 21 * Math.cos(r)} x2={30 + 27 * Math.sin(r)} y2={42 - 27 * Math.cos(r)} {...s} />;
        })}
      </>}
      {kind === 'flame' && <>
        <path d="M30 6 C38 18 44 26 44 36 A14 14 0 0 1 16 36 C16 26 22 18 30 6 Z" {...s} />
        <path d="M30 26 C34 31 36 35 36 39 A6 6 0 0 1 24 39 C24 35 26 31 30 26 Z" {...s} />
      </>}
      {kind === 'sprout' && <>
        <line x1="8" y1="40" x2="52" y2="40" {...s} />
        <ellipse cx="30" cy="48" rx="5" ry="3.5" {...s} />
        <path d="M30 44 L30 20" {...s} />
        <path d="M30 28 C22 28 17 22 17 15 C24 15 30 20 30 28 Z" {...s} />
        <path d="M30 24 C38 24 43 18 43 11 C36 11 30 16 30 24 Z" {...s} />
      </>}
      {kind === 'leaf' && <>
        <path d="M30 54 C12 40 12 18 30 6 C48 18 48 40 30 54 Z" {...s} />
        <line x1="30" y1="12" x2="30" y2="58" {...s} />
        {[20, 30, 40].map(y => <React.Fragment key={y}><line x1="30" y1={y + 6} x2="20" y2={y} {...s} /><line x1="30" y1={y + 6} x2="40" y2={y} {...s} /></React.Fragment>)}
      </>}
      {kind === 'ripple' && [6, 13, 20, 27].map((r, i) => <circle key={r} cx="30" cy="30" r={r} {...s} opacity={1 - i * 0.2} />)}
      {kind === 'logomark' && <g transform="translate(30 30) scale(0.1) translate(-246.7 -250)" strokeLinejoin="round">
        <polygon points={MARK_DOWN} {...s} strokeWidth={12} />
        <polygon points={MARK_UP} {...s} strokeWidth={12} />
      </g>}
    </svg>
  );
}

const maxW = {
  maxWidth: 1200,
  margin: '0 auto',
  padding: '0 clamp(24px, 8vw, 120px)',
};

// ── Logomark SVG (Krish's own mark) ──────────────────────────
function Logomark({ size = 32, color = C.white, weight = 14 }) {
  return (
    <svg viewBox="0 0 500 500" fill="none" style={{ width: size, height: size, flexShrink: 0 }}>
      <polygon points={MARK_DOWN} fill="none" stroke={color} strokeWidth={weight} strokeLinejoin="round" />
      <polygon points={MARK_UP} fill="none" stroke={color} strokeWidth={weight} strokeLinejoin="round" />
    </svg>
  );
}

// ── Full wordmark SVG ─────────────────────────────────────────
function FullLogo({ height = 40, color = C.white }) {
  // Renders just the KRISH SURROY wordmark paths + logomark from the uploaded SVG
  // Cropped to the text+mark region: roughly x:560-1260, y:240-840
  return (
    <svg viewBox="555 235 810 610" fill="none" style={{ height, width: 'auto', flexShrink: 0 }}>
      {/* Logomark */}
      <polygon points="961.56,241.51 1041.21,241.51 1001.38,310.48 961.56,379.46 921.74,310.48 881.92,241.51 961.56,241.51"
        fill="none" stroke={color} strokeWidth="8" strokeLinejoin="round" />
      <polygon points="961.56,410.51 881.92,410.51 921.74,341.54 961.56,272.57 1001.38,341.54 1041.21,410.51 961.56,410.51"
        fill="none" stroke={color} strokeWidth="8" strokeLinejoin="round" />
      {/* KRISH */}
      <path fill={color} d="M741.48,480.29h20.99l-50.89,55.68,63.4,61.64h-22.93l-59.97-57.95v57.95h-16.8v-117.33h16.8v53.67l49.39-53.67Z"/>
      <path fill={color} d="M816.82,597.62v-117.33h29.39c11.87,0,21.29,2.94,28.26,8.82s10.46,13.83,10.46,23.85c0,6.83-1.71,12.74-5.12,17.72-3.42,4.98-8.31,8.71-14.7,11.17,3.75,2.46,7.42,5.82,11,10.08,3.58,4.26,8.62,11.67,15.12,22.26,4.09,6.66,7.36,11.67,9.83,15.03l6.21,8.4h-19.99l-5.12-7.73c-.17-.28-.5-.76-1.01-1.43l-3.27-4.62-5.2-8.57-5.62-9.16c-3.47-4.82-6.64-8.65-9.53-11.5-2.89-2.85-5.49-4.91-7.82-6.16-2.33-1.26-6.24-1.89-11.73-1.89h-4.37v51.06h-16.8ZM838.66,494.57h-5.04v37.04h6.38c8.51,0,14.35-.73,17.51-2.18,3.16-1.46,5.63-3.65,7.39-6.59s2.65-6.28,2.65-10.04-.98-7.04-2.94-10.04c-1.96-2.99-4.72-5.11-8.27-6.34-3.56-1.23-9.45-1.85-17.68-1.85Z"/>
      <path fill={color} d="M954.77,480.29h16.8v117.33h-16.8v-117.33Z"/>
      <path fill={color} d="M1061.07,548.46l-12.77-7.76c-8.01-4.89-13.7-9.7-17.09-14.43-3.39-4.73-5.08-10.17-5.08-16.33,0-9.24,3.2-16.74,9.62-22.51,6.41-5.77,14.74-8.65,24.99-8.65s18.78,2.75,26.96,8.25v19.06c-8.46-8.13-17.55-12.2-27.29-12.2-5.49,0-9.99,1.27-13.52,3.81s-5.29,5.79-5.29,9.75c0,3.51,1.3,6.81,3.9,9.87,2.6,3.07,6.78,6.29,12.53,9.66l12.83,7.59c14.31,8.55,21.47,19.43,21.47,32.64,0,9.41-3.15,17.05-9.45,22.93s-14.49,8.82-24.57,8.82c-11.59,0-22.14-3.56-31.66-10.69v-21.33c9.07,11.49,19.57,17.24,31.49,17.24,5.26,0,9.64-1.46,13.14-4.39,3.5-2.93,5.25-6.6,5.25-11,0-7.14-5.15-13.92-15.45-20.32Z"/>
      <path fill={color} d="M1227.91,480.29h16.8v117.33h-16.8v-51.06h-65.93v51.06h-16.8v-117.33h16.8v50.73h65.93v-50.73Z"/>
      {/* SURROY */}
      <path fill={color} d="M597.92,718.86l-12.77-7.76c-8.01-4.89-13.7-9.7-17.09-14.43-3.39-4.73-5.08-10.17-5.08-16.33,0-9.24,3.2-16.74,9.62-22.51,6.41-5.77,14.74-8.65,24.99-8.65s18.78,2.75,26.96,8.25v19.06c-8.46-8.13-17.55-12.2-27.29-12.2-5.49,0-9.99,1.27-13.52,3.81s-5.29,5.79-5.29,9.75c0,3.51,1.3,6.81,3.9,9.87,2.6,3.07,6.78,6.29,12.53,9.66l12.83,7.59c14.31,8.55,21.47,19.43,21.47,32.64,0,9.41-3.15,17.05-9.45,22.93s-14.49,8.82-24.57,8.82c-11.59,0-22.14-3.56-31.66-10.69v-21.33c9.07,11.49,19.57,17.24,31.49,17.24,5.26,0,9.64-1.46,13.14-4.39,3.5-2.93,5.25-6.6,5.25-11,0-7.14-5.15-13.92-15.45-20.32Z"/>
      <path fill={color} d="M763.68,650.69h16.88v66.6c0,9.02-.66,15.82-1.97,20.41-1.32,4.59-2.94,8.41-4.87,11.46-1.93,3.05-4.3,5.78-7.1,8.19-9.29,8.01-21.44,12.01-36.45,12.01s-27.55-3.97-36.79-11.93c-2.8-2.46-5.17-5.22-7.1-8.27-1.93-3.05-3.53-6.79-4.79-11.21-1.26-4.42-1.89-11.37-1.89-20.83v-66.43h16.88v66.6c0,11.03,1.26,18.7,3.78,23.01,2.52,4.31,6.35,7.77,11.51,10.37,5.15,2.6,11.23,3.91,18.22,3.91,9.97,0,18.08-2.6,24.36-7.81,3.3-2.8,5.68-6.1,7.14-9.91,1.46-3.81,2.18-10.33,2.18-19.57v-66.6Z"/>
      <path fill={color} d="M838.72,768.02v-117.33h29.39c11.87,0,21.29,2.94,28.26,8.82s10.46,13.83,10.46,23.85c0,6.83-1.71,12.74-5.12,17.72-3.42,4.98-8.31,8.71-14.7,11.17,3.75,2.46,7.42,5.82,11,10.08,3.58,4.26,8.62,11.67,15.12,22.26,4.09,6.66,7.36,11.67,9.83,15.03l6.21,8.4h-19.99l-5.12-7.73c-.17-.28-.5-.76-1.01-1.43l-3.27-4.62-5.2-8.57-5.62-9.16c-3.47-4.82-6.64-8.65-9.53-11.5-2.89-2.85-5.49-4.91-7.82-6.16-2.33-1.26-6.24-1.89-11.73-1.89h-4.37v51.06h-16.8ZM860.56,664.97h-5.04v37.04h6.38c8.51,0,14.35-.73,17.51-2.18,3.16-1.46,5.63-3.65,7.39-6.59s2.65-6.28,2.65-10.04-.98-7.04-2.94-10.04c-1.96-2.99-4.72-5.11-8.27-6.34-3.56-1.23-9.45-1.85-17.68-1.85Z"/>
      <path fill={color} d="M977.01,768.02v-117.33h29.39c11.87,0,21.29,2.94,28.26,8.82s10.46,13.83,10.46,23.85c0,6.83-1.71,12.74-5.12,17.72-3.42,4.98-8.31,8.71-14.7,11.17,3.75,2.46,7.42,5.82,11,10.08,3.58,4.26,8.62,11.67,15.12,22.26,4.09,6.66,7.36,11.67,9.83,15.03l6.21,8.4h-19.99l-5.12-7.73c-.17-.28-.5-.76-1.01-1.43l-3.27-4.62-5.2-8.57-5.62-9.16c-3.47-4.82-6.64-8.65-9.53-11.5-2.89-2.85-5.49-4.91-7.82-6.16-2.33-1.26-6.24-1.89-11.73-1.89h-4.37v51.06h-16.8ZM998.85,664.97h-5.04v37.04h6.38c8.51,0,14.35-.73,17.51-2.18,3.16-1.46,5.63-3.65,7.39-6.59s2.65-6.28,2.65-10.04-.98-7.04-2.94-10.04c-1.96-2.99-4.72-5.11-8.27-6.34-3.56-1.23-9.45-1.85-17.68-1.85Z"/>
      <path fill={color} d="M1337.26,650.69h20.39l-43.34,55.26v62.06h-17.22v-62.06l-43.34-55.26h20.28l31.4,40.45,31.82-40.45Z"/>
      {/* Circle O with dot */}
      <circle cx="1161.78" cy="709.01" r="14.5" fill={color}/>
      <path fill={color} d="M1161.78,647.39c-34.03,0-61.62,27.59-61.62,61.62s27.59,61.62,61.62,61.62,61.62-27.59,61.62-61.62-27.59-61.62-61.62-61.62ZM1161.78,756.16c-26.04,0-47.14-21.11-47.14-47.14s21.11-47.14,47.14-47.14,47.14,21.11,47.14,47.14-21.11,47.14-47.14,47.14Z"/>
      {/* Horizontal rule */}
      <line x1="564.28" y1="837.51" x2="1348.28" y2="837.51" stroke={color} strokeWidth="4"/>
    </svg>
  );
}

// ── Nav ───────────────────────────────────────────────────────
function Nav({ page, navigate }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    const h = () => setScrolled(window.scrollY > 40);
    window.addEventListener('scroll', h);
    return () => window.removeEventListener('scroll', h);
  }, []);

  const links = [
    { id: 'one-to-one', label: 'One-to-one', items: [
      { id: 'coaching', label: 'Soul Aligned Coaching' },
      { id: 'readings', label: 'Intuitive Readings' },
      { id: 'supervision', label: 'Supervision' },
    ] },
    { id: 'group-programmes', label: 'Group programmes', items: [
      { id: 'soul-compass', label: 'The Soul’s Compass' },
      { id: 'wheel', label: 'The Wheel of Becoming' },
    ] },
    { id: 'transmissions', label: 'Transmissions' },
    { id: 'about', label: 'About' },
  ];
  const goTo = (id) => { setMenuOpen(false); setDropOpen(null); navigate(id); window.scrollTo(0,0); };
  // The two headings open the Work with me page at their own section
  const goToGroup = (id) => {
    goTo('work');
    // Wait for the fonts and the photos above the section to load first (at most 1.5 seconds),
    // so the section is measured where it will really sit; then jump straight there, as a smooth
    // glide got cut short when the scroll animations recalculated
    setTimeout(async () => {
      const el = document.getElementById(id); if (!el) return;
      const above = [...document.querySelectorAll('#root img')]
        .filter(i => !i.complete && (i.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING));
      const loaded = i => new Promise(r => { i.addEventListener('load', r, { once: true }); i.addEventListener('error', r, { once: true }); });
      await Promise.race([Promise.all([document.fonts.ready, ...above.map(loaded)]), new Promise(r => setTimeout(r, 1500))]);
      window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 68, behavior: 'instant' });
    }, 50);
  };
  const [dropOpen, setDropOpen] = React.useState(null);

  return (
    <>
    {menuOpen && (
      <div style={{ position: 'fixed', top: 68, left: 0, right: 0, zIndex: 199, background: 'rgba(14,21,32,0.98)', borderBottom: `1px solid ${C.line}`, padding: '16px 24px 28px' }}>
        {links.concat([{ id: 'book', label: 'Book a free call' }]).map(l => (
          <React.Fragment key={l.id}>
            <button onClick={() => l.items ? goToGroup(l.id) : goTo(l.id)}
              aria-current={page === l.id ? 'page' : undefined}
              style={{ display: 'block', width: '100%', minHeight: TOK.tap, textAlign: 'left', fontSize: 20, padding: '14px 0', color: (l.id === 'book' || page === l.id) ? C.ember : C.white, border: 'none', borderBottom: `1px solid ${C.line}`, background: 'none', cursor: 'pointer', fontFamily: T.font, fontWeight: 300 }}
            >{l.label}</button>
            {l.items && l.items.map(w => (
              <button key={w.id} onClick={() => goTo(w.id)}
                aria-current={page === w.id ? 'page' : undefined}
                style={{ display: 'block', width: '100%', minHeight: TOK.tap, textAlign: 'left', fontSize: 17, padding: '12px 0 12px 20px', color: page === w.id ? C.ember : C.grey4, border: 'none', borderBottom: `1px solid ${C.line}`, background: 'none', cursor: 'pointer', fontFamily: T.font, fontWeight: 300 }}
              >{w.label}</button>
            ))}
          </React.Fragment>
        ))}
      </div>
    )}
    <nav style={{
      position: 'fixed', top: 0, left: 0, right: 0, zIndex: 200,
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      padding: '0 clamp(20px, 4vw, 56px)', height: 68,
      background: scrolled ? 'rgba(14,21,32,0.97)' : 'rgba(14,21,32,0.72)',
      backdropFilter: 'blur(16px)',
      borderBottom: `1px solid rgba(255,255,255,${scrolled ? '0.08' : '0.04'})`,
      transition: 'background 500ms ease',
      boxSizing: 'border-box',
    }}>
      {/* Logo */}
      <a href="/" onClick={e => { if (!plainClick(e)) return; e.preventDefault(); goTo('home'); }}
        style={{ display: 'flex', alignItems: 'center', gap: 14, minHeight: TOK.tap, cursor: 'pointer', textDecoration: 'none', flexShrink: 0 }}>
        <Logomark size={36} color={C.white} />
        <span style={{ fontSize: 14, letterSpacing: '0.22em', textTransform: 'uppercase', color: C.white, fontFamily: T.font }}>Krish Surroy</span>
      </a>

      {/* Desktop links */}
      <div className="nav-links" style={{ display: 'flex', gap: 28, alignItems: 'center' }}>
        {links.map(l => l.items ? (
          // Keyboard: Enter or Space opens the menu (Tab then moves through it, Escape closes it);
          // a mouse click on the heading still opens Work with me at its section
          <div key={l.id} style={{ position: 'relative' }} onMouseEnter={() => setDropOpen(l.id)} onMouseLeave={() => setDropOpen(null)}
            onKeyDown={e => { if (e.key === 'Escape' && dropOpen === l.id) { setDropOpen(null); e.currentTarget.querySelector('button').focus(); } }}
            onBlur={e => { if (!e.currentTarget.contains(e.relatedTarget)) setDropOpen(o => (o === l.id ? null : o)); }}>
            <button aria-haspopup="true" aria-expanded={dropOpen === l.id}
              onClick={e => { if (e.detail === 0) { setDropOpen(o => (o === l.id ? null : l.id)); return; } goToGroup(l.id); }}
              style={{ fontSize: 17, letterSpacing: '0.02em', color: (dropOpen === l.id || l.items.some(w => w.id === page)) ? C.white : 'rgba(234,231,223,0.88)', cursor: 'pointer', border: 'none', background: 'none', fontFamily: T.font, fontWeight: 400, padding: '24px 0' }}
            >{l.label} <span style={{ fontSize: 10, color: C.ember }}>▾</span></button>
            {dropOpen === l.id && (
              <div style={{ position: 'absolute', top: '100%', left: -20, minWidth: 260, background: 'rgba(14,21,32,0.98)', border: `1px solid ${C.line}`, borderTop: `2px solid ${C.ember}`, padding: '8px 0', boxShadow: '0 12px 32px rgba(0,0,0,0.4)' }}>
                {l.items.map(w => (
                  <button key={w.id} onClick={() => goTo(w.id)}
                    aria-current={page === w.id ? 'page' : undefined}
                    style={{ display: 'block', width: '100%', minHeight: TOK.tap, textAlign: 'left', padding: '11px 20px', fontSize: 17, color: page === w.id ? C.ember : C.grey4, border: 'none', background: 'none', cursor: 'pointer', fontFamily: T.font, fontWeight: 400 }}
                    onMouseOver={e => e.currentTarget.style.color = C.white}
                    onMouseOut={e => e.currentTarget.style.color = page === w.id ? C.ember : C.grey4}
                  >{w.label}</button>
                ))}
              </div>
            )}
          </div>
        ) : (
          <button key={l.id} onClick={() => goTo(l.id)}
            style={{
              fontSize: 17, letterSpacing: '0.02em',
              color: page === l.id ? C.white : 'rgba(234,231,223,0.88)',
              cursor: 'pointer', border: 'none', background: 'none',
              fontFamily: T.font, fontWeight: 400, transition: 'color 200ms', padding: '24px 0',
            }}
            aria-current={page === l.id ? 'page' : undefined}
            onMouseOver={e => e.currentTarget.style.color = C.white}
            onMouseOut={e => e.currentTarget.style.color = page === l.id ? C.white : 'rgba(234,231,223,0.88)'}
          >{l.label}</button>
        ))}
      </div>

      {/* Phone menu button */}
      <button className="nav-burger" onClick={() => setMenuOpen(o => !o)} aria-label="Menu"
        style={{ display: 'none', flexDirection: 'column', alignItems: 'flex-end', justifyContent: 'center', gap: 6, minWidth: TOK.tap, minHeight: TOK.tap, padding: 8, border: 'none', background: 'none', cursor: 'pointer' }}>
        <span style={{ display: 'block', width: 26, height: 1.5, background: C.white }} />
        <span style={{ display: 'block', width: 26, height: 1.5, background: C.white }} />
        <span style={{ display: 'block', width: 18, height: 1.5, background: C.ember }} />
      </button>

      {/* CTA */}
      <button className="nav-cta" onClick={() => goTo('book')}
        style={{
          fontSize: 15, letterSpacing: '0.03em',
          color: C.black, background: C.ember, padding: '14px 22px', minHeight: TOK.tap,
          borderRadius: 2, cursor: 'pointer', border: 'none',
          fontFamily: T.font, fontWeight: 400, transition: 'opacity 200ms', flexShrink: 0,
          lineHeight: 1,
        }}
        onMouseOver={e => e.currentTarget.style.opacity = '0.78'}
        onMouseOut={e => e.currentTarget.style.opacity = '1'}
      >Book a free call</button>
    </nav>
    </>
  );
}

// ── Green Photo Wrapper ───────────────────────────────────────
function GreenPhoto({ src, style, imgStyle, warm }) {
  // Almanac grade: lightly desaturated, cooled towards blue hour; "warm" keeps the photo's own colour
  const overlayColor = C.blueGrade;
  const overlayOpacity = warm ? 0.12 : 0.5;
  return (
    <div style={{ position: 'relative', overflow: 'hidden', ...style }}>
      <img className="photo-m" src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', filter: warm ? 'none' : 'grayscale(0.3) brightness(0.9)', ...imgStyle }} />
      <div style={{
        position: 'absolute', inset: 0,
        background: overlayColor,
        mixBlendMode: 'multiply',
        opacity: overlayOpacity,
      }} />
    </div>
  );
}

// ── Hero Section ──────────────────────────────────────────────
function HeroSection({ image, eyebrow, title, subtitle, cta, onCta, direction, minH }) {
  return (
    <section style={{ position: 'relative', minHeight: minH || '100vh', overflow: 'hidden', display: 'flex', alignItems: 'flex-end', paddingTop: 68, background: C.black }}>
      <div style={{ position: 'absolute', inset: 0, backgroundImage: `url('${image}')`, backgroundSize: 'cover', backgroundPosition: 'center 30%', filter: 'grayscale(0.35) brightness(0.8)' }} />
      <div style={{ position: 'absolute', inset: 0, background: C.blueGrade, mixBlendMode: 'multiply', opacity: 0.6 }} />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(90deg, rgba(14,21,32,0.94) 0%, rgba(14,21,32,0.62) 45%, rgba(14,21,32,0.1) 80%)' }} />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(14,21,32,0.85) 0%, rgba(14,21,32,0) 45%)' }} />
      {/* The wheel, with the next gate marked */}
      <div className="hero-wheel" style={{ position: 'absolute', top: '50%', right: 'clamp(-320px, -14vw, -80px)', transform: 'translateY(-46%)', pointerEvents: 'none', zIndex: 1 }}>
        <Wheel size={620} opacity={0.32} />
      </div>
      <div style={{ position: 'relative', zIndex: 2, width: '100%', maxWidth: 1200, margin: '0 auto', padding: '80px clamp(24px, 8vw, 120px) clamp(72px, 10vh, 120px)' }}>
        {eyebrow !== false && (
          <span className="fade-up" style={{ display: 'block', fontSize: 13, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.ember, marginBottom: 24, fontFamily: T.font, fontVariantNumeric: 'tabular-nums' }}>
            {eyebrow ? `${eyebrow} · ` : ''}{gateLine()}
          </span>
        )}
        <h1 className="fade-up-2" style={{ fontSize: 'clamp(44px, 6.4vw, 92px)', letterSpacing: '-0.01em', color: C.white, lineHeight: 1.04, marginBottom: 28, fontFamily: T.font, fontWeight: 300, maxWidth: 820 }}>
          {title}
        </h1>
        {subtitle && (
          <p className="fade-up-3" style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 'clamp(20px, 2vw, 28px)', lineHeight: 1.45, color: 'rgba(234,231,223,0.8)', maxWidth: 620, marginBottom: 40 }}>
            {subtitle}
          </p>
        )}
        {cta && (
          <button className="fade-up-4" onClick={onCta} style={{
            fontSize: 17, letterSpacing: '0.03em',
            color: C.black, background: C.ember, padding: '16px 34px',
            borderRadius: 2, cursor: 'pointer', border: 'none',
            fontFamily: T.font, fontWeight: 400, transition: 'opacity 300ms', lineHeight: 1,
          }}
            onMouseOver={e => e.currentTarget.style.opacity = '0.82'}
            onMouseOut={e => e.currentTarget.style.opacity = '1'}
          >{cta}</button>
        )}
      </div>
    </section>
  );
}

// ── Typography helpers ────────────────────────────────────────
function SectionLabel({ children, color }) {
  return (
    <span style={{ display: 'block', fontSize: 13, letterSpacing: '0.2em', textTransform: 'uppercase', color: color || C.ember, marginBottom: 18, fontFamily: T.font, fontWeight: 400, fontVariantNumeric: 'tabular-nums' }}>
      {children}
    </span>
  );
}

function SectionHeading({ children, style = {}, color }) {
  return (
    <h2 style={{ fontSize: 'clamp(32px, 4vw, 54px)', letterSpacing: '-0.005em', color: color || C.white, lineHeight: 1.1, fontFamily: T.font, fontWeight: 300, ...style }}>
      {children}
    </h2>
  );
}

function BodyText({ children, style = {} }) {
  return (
    <p style={{ fontSize: 18, lineHeight: 1.7, color: C.grey4, fontFamily: T.font, fontWeight: 400, letterSpacing: '0.005em', maxWidth: '31em', ...style }}>
      {children}
    </p>
  );
}

function Hairline({ color = 'rgba(255,255,255,0.1)', style = {} }) {
  return <div style={{ height: 1, background: color, ...style }} />;
}

function GreenAccentLine({ width = 40 }) {
  return <div style={{ width, height: 2, background: C.greenBright, marginBottom: 32 }} />;
}

// ── Buttons ───────────────────────────────────────────────────
function PillBtn({ children, onClick, dark }) {
  return (
    <button onClick={onClick} style={{
      display: 'inline-block', fontSize: 17, letterSpacing: '0.03em',
      color: dark ? C.white : C.black, background: dark ? 'transparent' : C.ember,
      border: dark ? `1px solid ${C.lineStrong}` : 'none',
      padding: '15px 32px', borderRadius: 2, cursor: 'pointer',
      fontFamily: T.font, fontWeight: 400, transition: 'opacity 200ms', lineHeight: 1,
    }}
      onMouseOver={e => e.currentTarget.style.opacity = '0.72'}
      onMouseOut={e => e.currentTarget.style.opacity = '1'}
    >{children}</button>
  );
}

function OutlineBtn({ children, onClick, color = C.white, hoverText = C.black }) {
  const [hov, setHov] = React.useState(false);
  return (
    <button onClick={onClick}
      onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
      style={{
        display: 'inline-block', fontSize: 17, letterSpacing: '0.03em',
        color: hov ? hoverText : color, background: hov ? color : 'transparent',
        border: `1px solid ${hov ? color : C.lineStrong}`, padding: '15px 32px', borderRadius: 2,
        cursor: 'pointer', fontFamily: T.font, fontWeight: 400, transition: 'all 250ms', lineHeight: 1,
      }}
    >{children}</button>
  );
}

// ── Contact Section ───────────────────────────────────────────
function ContactSection({ navigate }) {
  const [form, setForm] = React.useState({ name: '', email: '', message: '' });
  const [sent, setSent] = React.useState(false);
  const inp = { background: C.slate, border: `1px solid ${C.line}`, color: C.white, padding: '16px 18px', fontSize: 17, fontFamily: T.font, fontWeight: 400, letterSpacing: '0.01em', outline: 'none', width: '100%', boxSizing: 'border-box', borderRadius: 2 };
  return (
    <section style={{ background: C.black, padding: '128px 0', borderTop: `1px solid ${C.line}` }}>
      <div style={{ ...maxW }}>
        <div style={{ maxWidth: 640, margin: '0 auto', textAlign: 'center' }}>
          <SectionLabel>Begin</SectionLabel>
          <SectionHeading style={{ marginBottom: 20 }}>Begin the conversation</SectionHeading>
          <BodyText style={{ marginBottom: 52, marginLeft: 'auto', marginRight: 'auto' }}>
            If something here has landed, reach out. A short message is enough to begin.
          </BodyText>
          {sent ? (
            <p style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 22, color: C.white, lineHeight: 1.65 }}>
              Your message has been received.<br />Krish will be in touch.
            </p>
          ) : (
            <form onSubmit={e => { e.preventDefault(); setSent(true); }} style={{ display: 'flex', flexDirection: 'column', gap: 14, textAlign: 'left' }}>
              <input type="text" placeholder="Your name" required value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} style={inp} />
              <input type="email" placeholder="Your email" required value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} style={inp} />
              <textarea placeholder="Your message" required rows={5} value={form.message} onChange={e => setForm({ ...form, message: e.target.value })} style={{ ...inp, resize: 'vertical' }} />
              <div><PillBtn>Send message</PillBtn></div>
            </form>
          )}
        </div>
      </div>
    </section>
  );
}

// ── Social icons (footer) ─────────────────────────────────────
const SOCIALS = [
  { label: 'YouTube', href: 'https://www.youtube.com/@krishsurroy',
    icon: <><rect x="2" y="5" width="20" height="14" rx="4" /><path d="M10 9.2l5 2.8-5 2.8z" fill="currentColor" stroke="none" /></> },
  { label: 'Instagram', href: 'https://www.instagram.com/krishsurroy/',
    icon: <><rect x="3" y="3" width="18" height="18" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.3" cy="6.7" r="1" fill="currentColor" stroke="none" /></> },
  { label: 'LinkedIn', href: 'https://www.linkedin.com/in/krishsurroy/',
    icon: <><rect x="3" y="3" width="18" height="18" rx="3" /><path d="M8 10.5V17M8 7.5v.01M12 17v-6.5M12 13.5a2.75 2.75 0 0 1 5.5 0V17" /></> },
  { label: 'Substack', href: 'https://krishsurroy.substack.com/',
    icon: <><path d="M5 4.5h14M5 8.5h14" /><path d="M5 12.5h14V21l-7-4-7 4z" fill="currentColor" stroke="none" /></> },
];

function SocialIcons() {
  return (
    <div style={{ display: 'flex', gap: 0, marginTop: 13 }}>
      {SOCIALS.map(s => (
        <a key={s.label} href={s.href} target="_blank" rel="noopener" aria-label={s.label} title={s.label}
          style={{ color: C.grey3, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: TOK.tap, height: TOK.tap, transition: 'color 200ms' }}
          onMouseOver={e => e.currentTarget.style.color = C.ember}
          onMouseOut={e => e.currentTarget.style.color = C.grey3}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{s.icon}</svg>
        </a>
      ))}
    </div>
  );
}

// ── Footer ────────────────────────────────────────────────────
function Footer({ navigate }) {
  const links = [
    { id: 'soul-awakened-man', label: 'Soul Awakened Man' }, { id: 'work', label: 'Work with me' },
    { id: 'about', label: 'About' }, { id: 'transmissions', label: 'Transmissions' },
    { id: 'contact', label: 'Contact' }, { id: 'privacy', label: 'Privacy' }, { id: 'terms', label: 'Terms' },
  ];
  return (
    <footer style={{ background: C.deep, padding: '64px 0 40px', borderTop: `1px solid ${C.line}` }}>
      <div style={{ ...maxW }}>
        {/* Newsletter */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 24, paddingBottom: 48, marginBottom: 48, borderBottom: `1px solid ${C.line}` }}>
          <div style={{ maxWidth: 440 }}>
            <span style={{ display: 'block', fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 24, color: C.white, marginBottom: 8 }}>The newsletter</span>
            <span style={{ fontSize: 15, color: C.grey3, fontFamily: T.font, lineHeight: 1.6 }}>New transmissions and news of the work, as the year turns.</span>
          </div>
          <NewsletterForm />
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 48, flexWrap: 'wrap', gap: 32 }}>
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
            <a href="/" onClick={linkTo(navigate, 'home')} aria-label="Krish Surroy, home" style={{ cursor: 'pointer', display: 'block' }}>
              <FullLogo height={64} color="rgba(234,231,223,0.6)" />
            </a>
            <SocialIcons />
          </div>
          <div>
            <div style={{ display: 'flex', gap: '0 28px', flexWrap: 'wrap', marginTop: -8 }}>
              {links.map(l => (
                <button key={l.id} onClick={() => { navigate(l.id); window.scrollTo(0,0); }}
                  style={{ fontSize: 16, color: C.grey4, border: 'none', background: 'none', cursor: 'pointer', fontFamily: T.font, fontWeight: 400, transition: 'color 200ms', padding: 0, minHeight: TOK.tap, display: 'inline-flex', alignItems: 'center' }}
                  onMouseOver={e => e.currentTarget.style.color = C.white}
                  onMouseOut={e => e.currentTarget.style.color = C.grey4}
                >{l.label}</button>
              ))}
            </div>
          </div>
        </div>
        <Hairline color={C.line} />
        <div style={{ marginTop: 28, display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12 }}>
          {/* Sentence case rather than spaced capitals, so the longer almanac wording reads easily (Krish, 5 Nov 2026) */}
          <span style={{ fontSize: 14, lineHeight: 1.6, letterSpacing: '0.01em', color: C.grey3, fontFamily: T.font, fontVariantNumeric: 'tabular-nums' }}>© 2026 Krish Surroy · 1569566 BC Ltd · krish@krishsurroy.com · {gateLine()}</span>
        </div>
      </div>
    </footer>
  );
}

// ── Forms: spam check (Cloudflare Turnstile) and sending to /api/forms ──
const LOCAL = ['localhost', '127.0.0.1'].includes(window.location.hostname);
// Cloudflare's published test key on this Mac only. The real one goes in site-config.js.
const turnstileKey = () => (LOCAL ? '1x00000000000000000000AA' : window.SITE.turnstileSiteKey);
let turnstileLoading = null;
function loadTurnstile() {
  if (!turnstileLoading) {
    turnstileLoading = new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit';
      script.async = true;
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }
  return turnstileLoading;
}

function useSiteForm(kind, theme = 'dark') {
  const [status, setStatus] = React.useState('idle');
  const holder = React.useRef(null);
  const widget = React.useRef(null);
  const token = React.useRef('');
  React.useEffect(() => {
    let gone = false;
    if (turnstileKey()) {
      loadTurnstile().then(() => {
        if (gone || !holder.current) return;
        widget.current = window.turnstile.render(holder.current, {
          sitekey: turnstileKey(), theme, appearance: 'interaction-only',
          callback: t => { token.current = t; },
          'expired-callback': () => { token.current = ''; },
        });
      }).catch(() => {});
    }
    return () => { gone = true; if (widget.current != null && window.turnstile) window.turnstile.remove(widget.current); };
  }, []);
  const submit = async (e) => {
    e.preventDefault();
    const data = Object.fromEntries(new FormData(e.target).entries());
    setStatus('sending');
    try {
      if (LOCAL) { await new Promise(r => setTimeout(r, 400)); setStatus('done'); return; }
      // The spam check runs quietly and can take a moment to finish
      for (let i = 0; i < 40 && !token.current && turnstileKey(); i++) await new Promise(r => setTimeout(r, 200));
      const r = await fetch('/api/forms', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...data, kind, newsletter: data.newsletter === 'yes', token: token.current }),
      });
      if (!r.ok) throw new Error('not sent');
      setStatus('done');
    } catch (err) {
      token.current = '';
      if (widget.current != null && window.turnstile) window.turnstile.reset(widget.current);
      setStatus('error');
    }
  };
  return { status, submit, holder };
}

// A field only bots fill in. People never see it.
function HoneypotField() {
  return (
    <div aria-hidden="true" style={{ position: 'absolute', left: '-9999px', width: 1, height: 1, overflow: 'hidden' }}>
      <label>Company<input type="text" name="company" tabIndex={-1} autoComplete="off" /></label>
    </div>
  );
}

function FormError({ color }) {
  return <p role="alert" style={{ fontSize: 15, lineHeight: 1.6, color, fontFamily: T.font, flexBasis: '100%', margin: 0 }}>Sorry, that didn’t go through. Please try again, or email me at krish@krishsurroy.com.</p>;
}

function NewsletterForm({ light }) {
  const { status, submit, holder } = useSiteForm('newsletter', light ? 'light' : 'dark');
  if (status === 'done') {
    return <span style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 19, color: light ? C.ink : C.white }}>Thank you, you’re on the list.{LOCAL ? ' (In the mock-up, nothing is sent.)' : ''}</span>;
  }
  const field = { background: light ? '#fff' : C.slate, border: `1px solid ${light ? 'rgba(28,30,26,0.2)' : C.line}`, color: light ? C.ink : C.white, padding: '14px 16px', fontSize: 16, fontFamily: T.font, outline: 'none', borderRadius: 2, minWidth: 0 };
  return (
    <form onSubmit={submit} style={{ position: 'relative', display: 'flex', gap: 10, flexWrap: 'wrap', maxWidth: 620 }}>
      <HoneypotField />
      <input type="text" name="name" required placeholder="First name" autoComplete="given-name" className={light ? 'field-light' : undefined} style={{ ...field, flex: '1 1 150px' }} />
      <input type="email" name="email" required placeholder="Your email" autoComplete="email" className={light ? 'field-light' : undefined} style={{ ...field, flex: '1 1 220px' }} />
      <PillBtn>{status === 'sending' ? 'Sending…' : 'Sign up'}</PillBtn>
      <div ref={holder} />
      {status === 'error' && <FormError color={light ? C.ink : C.grey4} />}
    </form>
  );
}

// ── YouTube video: shows the thumbnail, and loads YouTube's privacy-enhanced player only when pressed ──
// New uploads appear by themselves: /api/videos reads the channel's feed. videos.js is the fallback (and what this Mac shows).
let videosLoading = null;
function useVideos() {
  const [videos, setVideos] = React.useState(window.VIDEOS);
  React.useEffect(() => {
    if (!videosLoading) videosLoading = fetch('/api/videos').then(r => r.ok ? r.json() : null).catch(() => null);
    let gone = false;
    videosLoading.then(d => { if (!gone && d && d.videos && d.videos.length) { window.VIDEOS = d.videos; setVideos(d.videos); } });
    return () => { gone = true; };
  }, []);
  return videos;
}

function VideoPlayer({ video, playSize = 44 }) {
  const [playing, setPlaying] = React.useState(false);
  const box = { position: 'relative', display: 'block', width: '100%', aspectRatio: '16 / 9', overflow: 'hidden', border: `1px solid ${C.line}`, padding: 0, background: C.black };
  if (playing) {
    return (
      <div style={box}>
        <iframe src={`https://www.youtube-nocookie.com/embed/${video.id}?autoplay=1&rel=0`} title={video.title}
          allow="autoplay; encrypted-media; picture-in-picture; fullscreen" allowFullScreen referrerPolicy="strict-origin-when-cross-origin"
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', border: 0 }} />
      </div>
    );
  }
  const r = playSize / 68;
  return (
    <button type="button" onClick={() => setPlaying(true)} aria-label={`Play: ${video.title}`} style={{ ...box, cursor: 'pointer' }}>
      <img src={`https://i.ytimg.com/vi/${video.id}/maxresdefault.jpg`} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      <span style={{ position: 'absolute', right: 12, bottom: 12 }}>
        <span style={{ width: playSize, height: playSize, borderRadius: '50%', background: C.ember, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <span style={{ width: 0, height: 0, borderTop: `${12 * r}px solid transparent`, borderBottom: `${12 * r}px solid transparent`, borderLeft: `${19 * r}px solid ${C.black}`, marginLeft: 6 * r }} />
        </span>
      </span>
    </button>
  );
}

Object.assign(window, { TOK, useVideos, C, T, MARK_DOWN, MARK_UP, maxW, GATES, nextGate, gateLine, Wheel, AlmanacShape, Logomark, FullLogo, Nav, GreenPhoto, HeroSection, SectionLabel, SectionHeading, BodyText, Hairline, GreenAccentLine, PillBtn, OutlineBtn, ContactSection, Footer, VideoPlayer, useSiteForm, HoneypotField, FormError, NewsletterForm, LOCAL });
