// sw-launch.jsx — the refined layouts for the two launch pages (6 Nov 2026, approved by Krish the same day).
// The Soul's Compass and The Wheel of Becoming only. The copy is in pages-copy.js; only the presentation differs,
// plus the Wheel's "Recordings" row. Remove this file (and its script tag in index.html) to go back to the originals.

const LAUNCH_PAGES = ['soul-compass', 'wheel'];
const lCream = TOK.cream;
const lSoft = TOK.creamSoft;


// A quiet gold text link with an arrow, for the extra "next step" points down the two pages (Krish, 6 Nov 2026)
// The Compass booking link is the one on the page's own closing button, so they always match
const compassHref = () => window.PAGES['soul-compass'].sections.find(x => x.type === 'cta').buttons[0].href;
function StepLink({ label, href, onClick, color = C.ember, style = {} }) {
  return (
    <a href={href} onClick={onClick} style={{ fontFamily: T.font, fontSize: 17, letterSpacing: '0.02em', color, textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, minHeight: 44, ...style }}>
      {label} <span aria-hidden="true">→</span>
    </a>
  );
}
const applyLink = (navigate, color, style) => <StepLink label="Apply for the Wheel" href="/apply" onClick={linkTo(navigate, 'apply')} color={color} style={style} />;

// The page hero as drawn by sw-pagekit.jsx, with one gold button under the italic line (Krish, 6 Nov 2026)
function HeroWithAction({ s, label, onClick, deep }) {
  return (
    <section className={deep ? 'page-hero wash-deep' : 'page-hero'} style={{ position: 'relative', overflow: 'hidden', background: C.black, paddingTop: 68, minHeight: 'min(66vh, 620px)', display: 'flex', alignItems: 'flex-end' }}>
      <div className="hero-photo" style={{ position: 'absolute', inset: 0 }}>
        <img src={s.image} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: s.pos || 'center', filter: 'grayscale(0.15) brightness(0.92)' }} />
        <div style={{ position: 'absolute', inset: 0, background: C.blueGrade, mixBlendMode: 'multiply', opacity: 0.25 }} />
        <div className="hero-fade" style={{ position: 'absolute', inset: 0, background: 'linear-gradient(90deg, rgba(14,21,32,0.92) 0%, rgba(14,21,32,0.8) 45%, rgba(14,21,32,0.15) 75%, rgba(14,21,32,0) 100%), linear-gradient(to top, rgba(14,21,32,0.7) 0%, rgba(14,21,32,0) 40%)' }} />
      </div>
      {s.wheel && (
        <div className="hero-wheel" style={{ position: 'absolute', top: '52%', right: '-6%', transform: 'translateY(-50%)', pointerEvents: 'none' }}>
          <Wheel size={560} opacity={0.3} />
        </div>
      )}
      <div className="hero-words" style={{ ...maxW, position: 'relative', zIndex: 2, width: '100%', padding: '64px clamp(24px, 8vw, 120px) clamp(48px, 8vh, 88px)' }}>
        <div style={{ maxWidth: 640 }}>
          <SectionLabel>{s.label}</SectionLabel>
          <h1 className="fade-up-2" style={{ fontSize: 'clamp(40px, 5.4vw, 80px)', letterSpacing: '-0.01em', color: C.white, lineHeight: 1.05, marginBottom: 22, fontFamily: T.font, fontWeight: 300 }}>{s.title}</h1>
          <p className="fade-up-3" style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 'clamp(19px, 1.8vw, 24px)', lineHeight: 1.45, color: 'rgba(234,231,223,0.88)', marginBottom: 36 }}>{s.sub}</p>
          <div className="fade-up-4"><PillBtn onClick={onClick}>{label}</PillBtn></div>
        </div>
      </div>
    </section>
  );
}

// ── The Soul's Compass ────────────────────────────────────────
const COMPASS = {
  hero: ({ s }) => <HeroWithAction s={s} label="Email to book your place" onClick={() => { window.location.href = compassHref(); }} />,

  // Opening: the words on the left, and a large wheel to the right as on About's "What I believe";
  // its ember travels round the rim as you scroll (the site's "The year turns" touch in sw-interactions.js)
  // A wheel to the right, sized to sit inside the section's usual height, so the motif is there without adding space;
  // its ember travels round the rim as you scroll (the site's "The year turns" touch in sw-interactions.js)
  text: ({ s }) => {
    if (s.heading !== 'A needle that settles') return KIT.text({ s });
    return (
      <Section s={s} style={{ position: 'relative', overflow: 'hidden' }}>
        <div className="underlay-right" aria-hidden="true" style={{ position: 'absolute', top: '50%', left: '74%', transform: 'translate(-50%,-50%)', pointerEvents: 'none' }}>
          <Wheel size={500} opacity={0.16} color={C.ink} />
        </div>
        <div style={{ maxWidth: 760, position: 'relative' }}>
          <Heading s={s}>{s.heading}</Heading>
          <Paras s={s} paras={s.paras} />
        </div>
      </Section>
    );
  },

  // The five outcomes: numbered, larger and spaced, so they scan at a glance
  list: ({ s }) => (
    <Section s={s} style={{ padding: 'clamp(88px,9vw,120px) 0' }}>
      <div className="g2" style={{ display: 'grid', gridTemplateColumns: '7fr 5fr', gap: 'clamp(32px,5vw,80px)', alignItems: 'start' }}>
        <div>
          <SectionHeading style={{ marginBottom: 36 }}>{s.heading}</SectionHeading>
          <ol style={{ listStyle: 'none' }}>
            {s.items.map((it, i) => (
              <li key={it} style={{ display: 'grid', gridTemplateColumns: '44px 1fr', alignItems: 'baseline', padding: '20px 0', borderTop: `1px solid ${C.line}` }}>
                <span style={{ fontFamily: T.serif, fontSize: 30, color: C.ember, lineHeight: 1 }}>{i + 1}</span>
                <span style={{ fontSize: 20, lineHeight: 1.5, color: lCream, fontFamily: T.font }}>{it.charAt(0).toUpperCase() + it.slice(1)}</span>
              </li>
            ))}
          </ol>
          <div style={{ marginTop: 20 }}><StepLink label="Email to book your place" href={compassHref()} /></div>
        </div>
        {s.quote && <div className="list-quote" style={{ paddingTop: 96 }}><Quote {...s.quote} s={s} /></div>}
      </div>
    </Section>
  ),

  // Investment and booking together. "Email to book your place" stays until a direct registration and payment process exists (Krish, 6 Nov 2026)
  price: ({ s }) => (
    <Section s={{ ...s, id: 'investment' }}>
      <div className="g2" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'clamp(32px,5vw,80px)', alignItems: 'center' }}>
        <div>
          <SectionLabel color={C.emberDeep}>{s.label}</SectionLabel>
          <span style={{ display: 'block', fontFamily: T.font, fontWeight: 300, fontSize: 'clamp(56px, 7vw, 88px)', color: C.ink, lineHeight: 1, marginBottom: 12 }}>{s.amount}</span>
          <p style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 22, color: C.ink, marginBottom: 12 }}>{s.note}</p>
          <p style={{ fontSize: 16, lineHeight: 1.6, color: C.driftwood, fontFamily: T.font }}>{s.extra}</p>
        </div>
        <div style={{ borderLeft: '1px solid rgba(28,30,26,0.14)', paddingLeft: 'clamp(24px,4vw,56px)' }} className="price-book">
          <div>
            <PillBtn onClick={() => { window.location.href = 'mailto:krish@krishsurroy.com?subject=The%20Soul%E2%80%99s%20Compass'; }}>Email to book your place</PillBtn>
          </div>
        </div>
      </div>
    </Section>
  ),

  cta: ({ s, navigate }) => KIT.cta({ s: { ...s, buttons: [{ label: 'Email to book your place', href: s.buttons[0].href }] }, navigate }),
};

// ── The Wheel of Becoming ─────────────────────────────────────

const WHEEL = {
  hero: ({ s, navigate }) => <HeroWithAction s={s} deep label="Apply for the Wheel" onClick={() => { navigate('apply'); window.scrollTo(0, 0); }} />,

  // "A council, and a year that works on you", with the way to apply at its end
  text: ({ s, navigate }) => {
    if (s.heading !== 'A council, and a year that works on you') return KIT.text({ s });
    return (
      <Section s={s}>
        <div style={{ maxWidth: 760 }}>
          <Heading s={s}>{s.heading}</Heading>
          <Paras s={s} paras={s.paras} />
          {applyLink(navigate, C.emberDeep, { marginTop: 8 })}
        </div>
      </Section>
    );
  },

  // Who it's for, with the way to apply beside "Who the Soul Awakened Man is"
  who: ({ s, navigate }) => (
    <Section s={s}>
      <div className="g2" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'clamp(32px,5vw,80px)', alignItems: 'start' }}>
        <div>
          <Heading s={s}>{s.heading}</Heading>
          <Paras s={s} paras={s.paras} />
          <div style={{ display: 'flex', gap: '14px 28px', flexWrap: 'wrap', alignItems: 'center' }}>
            {s.buttons && <Buttons buttons={s.buttons} navigate={navigate} align="flex-start" />}
            {applyLink(navigate)}
          </div>
        </div>
        <div>{s.quotes.map(q => <Quote key={q.who} {...q} s={s} />)}</div>
      </div>
    </Section>
  ),

  // The eight gates as an almanac, with the wheel beside them: the ember travels round as you read (see GateAlmanac)
  gates: ({ s }) => <GateAlmanac s={s} />,

  // Movements unchanged, with the recording arrangement added to the details (from the Terms; Krish approved the wording, 6 Nov 2026)
  movements: ({ s }) => (
    <>
      {KIT.movements({ s: { ...s, id: 'how-it-works', details: [...s.details, ['Recordings', 'Ceremonies and councils are recorded, and shared only with the council, in the private course area.']] } })}
    </>
  ),

  covenant: ({ s }) => KIT.covenant({ s: { ...s, id: 'covenant' } }),

  // The six changes as pairs: the soul's words on the left, a gold thread, the plain words on the right
  changes: ({ s }) => (
    <Section s={s}>
      <div style={{ maxWidth: 760 }}>
        <Heading s={s}>{s.heading}</Heading>
        <Paras s={s} paras={[s.intro]} />
      </div>
      <div className="change-head" style={{ display: 'grid', gridTemplateColumns: '1fr 56px 1fr', gap: 'clamp(16px,2.4vw,32px)', marginTop: 40, paddingBottom: 12 }}>
        <span style={{ fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: C.grey3, fontFamily: T.font }}>In the language of the soul</span>
        <span />
        <span style={{ fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: C.ember, fontFamily: T.font }}>In practice</span>
      </div>
      <div style={{ borderTop: `1px solid ${C.line}` }}>
        {s.items.map(([soul, plain]) => (
          <div key={soul} className="change-row" style={{ display: 'grid', gridTemplateColumns: '1fr 56px 1fr', gap: 'clamp(16px,2.4vw,32px)', padding: '28px 0', borderBottom: `1px solid ${C.line}`, alignItems: 'center' }}>
            <p style={{ fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 'clamp(21px,2vw,25px)', lineHeight: 1.4, color: C.white }}>{soul}</p>
            <div aria-hidden="true" className="change-thread" style={{ position: 'relative', height: 1, background: `linear-gradient(to right, ${C.lineStrong}, ${C.ember})` }}>
              <span style={{ position: 'absolute', right: -3, top: -3, width: 7, height: 7, borderRadius: '50%', background: C.ember }} />
            </div>
            <p style={{ fontSize: 17, lineHeight: 1.7, color: lSoft, fontFamily: T.font }}>{plain}</p>
          </div>
        ))}
      </div>
    </Section>
  ),

  // The investment, with the way to apply right beside it
  price: ({ s, navigate }) => (
    <>
      {KIT.price({ s: { ...s, id: 'investment' } })}
      <div style={{ background: C.parchment, marginTop: -40, paddingBottom: 88 }}>
        <div style={{ ...maxW }}>
          <div className="g2" style={{ display: 'grid', gridTemplateColumns: '5fr 7fr', gap: 'clamp(32px,5vw,80px)' }}>
            <span />
            <div><PillBtn onClick={() => { navigate('apply'); window.scrollTo(0, 0); }}>Apply for the Wheel</PillBtn></div>
          </div>
        </div>
      </div>
    </>
  ),
};


// ── One turn of the year: the gates, with the wheel kept in view ──
// The wheel never moves. Only the ember travels along the rim: clockwise as you read down from Imbolc to Alban Arthan,
// back anticlockwise if you scroll up, and it rests at Alban Arthan when the gates end. With reduced motion it steps
// straight to each gate. (The viewBox differs from the site's other wheels on purpose, so sw-interactions.js leaves it alone.)
const RIM = ['Alban Hefin', 'Lughnasadh', 'Alban Elfed', 'Samhain', 'Alban Arthan', 'Imbolc', 'Alban Eilir', 'Beltane'];
const rimPt = (i, r) => [300 + r * Math.sin(i * Math.PI / 4), 300 - r * Math.cos(i * Math.PI / 4)];

function GateWheel({ size, label, sub, compact }) {
  const gid = React.useId().replace(/:/g, '');
  const [ex, ey] = rimPt(RIM.indexOf('Imbolc'), 290); // the ember starts at Imbolc and is turned from there
  return (
    <svg viewBox="-30 -30 660 660" fill="none" style={{ width: size, height: typeof size === 'number' ? size : 'auto', display: 'block', overflow: 'visible' }} aria-hidden="true">
      <defs>
        <radialGradient id={`glow${gid}`}>
          <stop offset="0" stopColor={C.ember} stopOpacity="0.75" />
          <stop offset="1" stopColor={C.ember} stopOpacity="0" />
        </radialGradient>
      </defs>
      <g stroke={C.white} opacity={0.55}>
        <circle cx="300" cy="300" r="290" strokeWidth={compact ? 3 : 1} />
        {!compact && <circle cx="300" cy="300" r="240" strokeWidth="0.6" opacity="0.5" />}
        {RIM.map((_, i) => { const [x1, y1] = rimPt(i, 278); const [x2, y2] = rimPt(i, 300); return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} strokeWidth={compact ? 4 : 1.4} />; })}
        <g transform="translate(300 300) scale(0.5) translate(-246.7 -250)" strokeLinejoin="round">
          <polygon points={MARK_DOWN} strokeWidth={compact ? 9 : 3.2} />
          <polygon points={MARK_UP} strokeWidth={compact ? 9 : 3.2} />
        </g>
      </g>
      {!compact && label && <>
        <text x="300" y="468" textAnchor="middle" fill={C.ember} fontSize="30" fontFamily="'IM Fell English', Georgia, serif" fontStyle="italic">{label}</text>
        <text x="300" y="502" textAnchor="middle" fill="#c3c4c2" fontSize="20" fontFamily="'Gill Sans', 'Cabin', sans-serif">{sub}</text>
      </>}
      <g data-ember="">
        <circle cx={ex} cy={ey} r={compact ? 60 : 30} fill={`url(#glow${gid})`} />
        <circle cx={ex} cy={ey} r={compact ? 26 : 9} fill={C.ember} />
      </g>
    </svg>
  );
}

function GateAlmanac({ s }) {
  const root = React.useRef(null);
  const rows = React.useRef([]);
  const angle = React.useRef(0);
  const raf = React.useRef(0);
  const [active, setActive] = React.useState(-1); // -1: before the wheel turns; 0 to 7: Imbolc to Alban Arthan
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const all = [{ ...s.before, n: '', theme: '' }, ...s.gates];

  // Which gate is being read: the last row whose top has passed the reading line, 45% down the screen
  React.useEffect(() => {
    const read = () => {
      const line = window.innerHeight * 0.45;
      let a = -1;
      rows.current.forEach((r, i) => { if (r && r.getBoundingClientRect().top <= line) a = i - 1; });
      setActive(a);
    };
    read();
    window.addEventListener('scroll', read, { passive: true });
    window.addEventListener('resize', read);
    return () => { window.removeEventListener('scroll', read); window.removeEventListener('resize', read); };
  }, []);

  // Carry the ember to the active gate: 45 degrees a gate, clockwise forward, anticlockwise back
  React.useEffect(() => {
    const put = (a) => root.current && root.current.querySelectorAll('[data-ember]').forEach(g => g.setAttribute('transform', `rotate(${a} 300 300)`));
    const to = Math.max(active, 0) * 45;
    cancelAnimationFrame(raf.current);
    if (reduced) { angle.current = to; put(to); return; }
    const from = angle.current;
    if (from === to) { put(to); return; }
    const dur = 700 + 220 * Math.min(Math.abs(to - from) / 45, 4);
    const t0 = performance.now();
    const step = (now) => {
      const p = Math.min((now - t0) / dur, 1);
      const e = p < 0.5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2;
      angle.current = from + (to - from) * e;
      put(angle.current);
      if (p < 1) raf.current = requestAnimationFrame(step);
    };
    raf.current = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf.current);
  }, [active]);

  const cur = all[active + 1];
  const label = cur.name;
  const sub = active < 0 ? cur.when : `${cur.n} of 8 · ${cur.theme}`;

  return (
    <Section s={{ ...s, id: 'the-wheel' }}>
      <div ref={root}>
        <div style={{ maxWidth: 760, marginBottom: 48 }}>
          <Heading s={s}>{s.heading}</Heading>
          <Paras s={s} paras={[s.intro]} />
        </div>
        <div className="gw-grid" style={{ display: 'grid', gridTemplateColumns: '1fr clamp(320px, 34vw, 450px)', gap: 'clamp(32px,4vw,56px)', alignItems: 'start' }}>
          <div>
            {/* Phones: a slim bar with a small wheel stays at the top while the gates scroll past, then leaves with them */}
            <div className="gw-chip" style={{ display: 'none', position: 'sticky', top: 68, zIndex: 5, alignItems: 'center', gap: 14, background: 'rgba(23,32,45,0.97)', borderBottom: `1px solid ${C.line}`, padding: '10px 0', margin: '0 0 4px' }}>
              <GateWheel size={56} compact />
              <div style={{ lineHeight: 1.25 }}>
                <span style={{ display: 'block', fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 19, color: C.ember }}>{label}</span>
                <span style={{ display: 'block', fontFamily: T.font, fontSize: 13, color: C.grey4 }}>{sub}</span>
              </div>
            </div>
            <div style={{ borderTop: `1px solid ${C.line}` }}>
              {all.map((gt, i) => {
                const on = i - 1 === active;
                return (
                  <div key={gt.name} ref={el => (rows.current[i] = el)} className="gate-row" aria-current={on ? 'step' : undefined}
                    style={{ display: 'grid', gridTemplateColumns: '52px 1fr', gap: '6px clamp(14px,2vw,24px)', padding: '28px 0 28px 18px', borderBottom: `1px solid ${C.line}`, boxShadow: on ? `inset 2px 0 0 ${C.ember}` : 'inset 2px 0 0 transparent', transition: 'box-shadow .5s ease' }}>
                    <span style={{ fontFamily: T.serif, fontSize: 30, color: on ? C.ember : (gt.n ? 'rgba(221,161,73,0.6)' : C.grey3), lineHeight: 1, transition: 'color .5s ease' }}>{gt.n || '○'}</span>
                    <div>
                      <span style={{ display: 'block', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: C.grey3, fontFamily: T.font, marginBottom: 6 }}>{gt.when}</span>
                      <h3 style={{ fontFamily: T.font, fontWeight: 300, fontSize: 'clamp(24px,2.2vw,28px)', color: C.white, lineHeight: 1.15 }}>{gt.name}</h3>
                      {gt.theme && <span style={{ display: 'block', fontFamily: T.serif, fontStyle: T.serifStyle, fontSize: 19, color: C.ember, marginTop: 4 }}>{gt.theme}</span>}
                      <p style={{ fontSize: 17, lineHeight: 1.75, color: on ? lCream : lSoft, fontFamily: T.font, marginTop: 14, maxWidth: '38em', transition: 'color .5s ease' }}>{gt.body}</p>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
          {/* Desktop: the wheel stays in view beside the gates, then scrolls away with the section */}
          <div className="gw-side" style={{ position: 'sticky', top: 'calc(50vh - min(17vw, 225px) + 30px)' }}>
            <GateWheel size="100%" label={label} sub={sub} />
          </div>
        </div>
      </div>
    </Section>
  );
}

const PROPOSALS = { 'soul-compass': COMPASS, wheel: WHEEL };

// ── The two pages draw with the proposals (approved by Krish, 6 Nov 2026); every other page is unchanged ──
const BasePageView = PageView;
function LaunchPageView({ id, navigate }) {
  if (!LAUNCH_PAGES.includes(id)) return <BasePageView id={id} navigate={navigate} />;
  const over = PROPOSALS[id];
  return window.PAGES[id].sections.map((s, i) => {
    const Comp = over[s.type] || KIT[s.type];
    return Comp ? <Comp key={i} s={s} navigate={navigate} /> : null;
  });
}
window.PageView = LaunchPageView;
PageView = LaunchPageView;
