// website.jsx — The Composer OS marketing website.
// Long-scroll single page: fixed header → 7 sections → footer.
// Each section: banner (from banners v2.jsx) + content block + FCP-style carousel.

const PAGE_BG       = '#faf8f5';
const PAGE_INK      = '#1c1a17';
const PAGE_INK_SOFT = 'rgba(28,26,23,0.62)';
const PAGE_INK_MUTE = 'rgba(28,26,23,0.42)';
const PAGE_LINE     = 'rgba(28,26,23,0.10)';

// ────────────────────────────────────────────────
// Form delivery — Web3Forms (forms POST here; submissions land in the inbox
// tied to this access key). No backend needed; works from any origin.
// ────────────────────────────────────────────────
const WEB3FORMS_KEY = 'daf52102-0251-41e7-92ef-083ce5dd7970';
const WEB3FORMS_NEWSLETTER_KEY = '150e6339-fe99-424a-b853-3a7f4ca82f65';
async function submitToWeb3Forms(fields) {
  const res = await fetch('https://api.web3forms.com/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
    body: JSON.stringify({ access_key: WEB3FORMS_KEY, ...fields }),
  });
  const data = await res.json();
  if (!data.success) throw new Error(data.message || 'Submission failed');
  return data;
}
if (typeof window !== 'undefined') window.submitToWeb3Forms = submitToWeb3Forms;

// ────────────────────────────────────────────────
// Header — fixed, sticky, minimal
// ────────────────────────────────────────────────
// Section → accent color for the hovering logo. Matches the banner tone of each section.
const HEADER_ACCENTS = {
  hero:     '#7a9b7e',  // sage/moss (green)
  home:     '#f7c948',  // bright yellow sun
  studio:   '#b26f5c',  // terracotta
  library:  '#8a5a34',  // warm bronze
  projects: '#6b5d7a',  // plum — set apart from the warm-brown sections
  health:   '#f0b268',  // sunset gold
  aria:     '#c9a34a',  // quiet ochre
};

// Returns the accent of the section currently nearest the top of the viewport.
// Used by CTAs (waitlist / demo) so the modal opens themed to where you are.
function activeSectionAccent() {
  const ids = ['hero','home','studio','library','projects','health','aria'];
  const mid = window.scrollY + window.innerHeight * 0.25;
  let current = 'hero';
  for (const id of ids) {
    const el = document.getElementById(id);
    if (el && el.offsetTop <= mid) current = id;
  }
  return HEADER_ACCENTS[current] || HEADER_ACCENTS.hero;
}

function SiteHeader() {
  const [scrolled, setScrolled] = React.useState(false);
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const [activeSection, setActiveSection] = React.useState('hero');
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  // Track which section's banner is most in view; swap logo accent accordingly.
  React.useEffect(() => {
    const ids = ['hero','home','studio','library','projects','health','aria'];
    const els = ids.map(id => document.getElementById(id)).filter(Boolean);
    if (!els.length) return;
    const pick = () => {
      // Use the viewport midline to decide which section is "active".
      const mid = window.scrollY + window.innerHeight * 0.25;
      let current = 'hero';
      for (const el of els) {
        const top = el.offsetTop;
        if (top <= mid) current = el.id;
      }
      setActiveSection(current);
    };
    pick();
    window.addEventListener('scroll', pick, {passive:true});
    window.addEventListener('resize', pick);
    return () => { window.removeEventListener('scroll', pick); window.removeEventListener('resize', pick); };
  }, []);
  const items = [
    { l: 'Home', h: '#home' },
    { l: 'Studio', h: '#studio' },
    { l: 'Library', h: '#library' },
    { l: 'Projects', h: '#projects' },
    { l: 'Health', h: '#health' },
    { l: 'Aria', h: '#aria' },
  ];
  return (
    <header style={{
      position:'fixed', top:0, left:0, right:0, zIndex:50, height:64,
      background: scrolled ? 'rgba(250,248,245,0.88)' : 'rgba(250,248,245,0.68)',
      backdropFilter:'blur(14px)',
      WebkitBackdropFilter:'blur(14px)',
      borderBottom: scrolled ? `1px solid ${PAGE_LINE}` : '1px solid transparent',
      boxShadow: scrolled ? '0 4px 20px -10px rgba(0,0,0,0.08)' : 'none',
      transition:'border-color 300ms, box-shadow 300ms, background 600ms',
    }}>
      {/* Section-tinted wash — subtle color blend matching the active banner */}
      <div aria-hidden="true" style={{
        position:'absolute', inset:0, pointerEvents:'none',
        background: HEADER_ACCENTS[activeSection] || HEADER_ACCENTS.hero,
        opacity: 0.11,
        transition: 'background 600ms ease, opacity 600ms ease',
        mixBlendMode: 'multiply',
      }}/>
      <div style={{
        maxWidth:1600, margin:'0 auto', height:'100%',
        padding:'0 clamp(20px, 4vw, 48px)',
        display:'flex', alignItems:'center', justifyContent:'space-between', gap:20,
      }}>
        <a href="#hero" style={{display:'flex',alignItems:'center',gap:10,textDecoration:'none',color:PAGE_INK}}>
          <div style={{width:28,height:28,display:'flex',alignItems:'center',justifyContent:'center',
            transition:'filter 400ms ease'}}>
            {(() => {
              const toneMap = {
                hero:'moss', home:'sun', studio:'terracotta', library:'bronze',
                projects:'plum', health:'sunset', aria:'ochre',
              };
              const tone = (typeof ORBIT_PALETTE !== 'undefined')
                ? ORBIT_PALETTE[toneMap[activeSection] || 'moss']
                : null;
              return tone
                ? <OrbitIcon size={28} tone={tone}/>
                : <div style={{width:22,height:22,borderRadius:11,
                    background:`conic-gradient(from 0deg, ${PAGE_INK}, ${HEADER_ACCENTS[activeSection]||'#7a9b7e'}, ${PAGE_INK})`,
                    boxShadow:'0 0 0 1px rgba(0,0,0,0.15)'}}/>;
            })()}
          </div>
          <div style={{fontSize:17,fontWeight:500,letterSpacing:-0.3}}>
            Composer<span style={{opacity:0.55}}>OS</span>
          </div>
        </a>
        <nav className="site-nav-desktop" style={{display:'flex',gap:30,fontSize:14,color:PAGE_INK_SOFT,fontWeight:450}}>
          {items.map(i => (
            <a key={i.l} href={i.h} style={{color:'inherit',textDecoration:'none',transition:'color 150ms'}}
               onMouseOver={e=>e.currentTarget.style.color=PAGE_INK}
               onMouseOut={e=>e.currentTarget.style.color=PAGE_INK_SOFT}>{i.l}</a>
          ))}
        </nav>
        <div className="site-cta-desktop" style={{display:'flex',alignItems:'center',gap:18}}>
          <a href="/waitlist" style={{
            padding:'10px 18px',borderRadius:999,fontSize:14,fontWeight:500,
            background:PAGE_INK,color:PAGE_BG,textDecoration:'none',cursor:'pointer',
            transition:'background-color 180ms ease',whiteSpace:'nowrap',
          }}
          onMouseOver={e=>e.currentTarget.style.background='#5f7d63'}
          onMouseOut={e=>e.currentTarget.style.background=PAGE_INK}>Join the waitlist</a>
        </div>
        {/* mobile hamburger */}
        <button className="site-nav-mobile-btn"
          onClick={()=>setMobileOpen(v=>!v)}
          style={{
            display:'none', background:'transparent', border:'none', cursor:'pointer',
            padding:8, color:PAGE_INK,
          }}>
          <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
            {mobileOpen
              ? <g stroke="currentColor" strokeWidth="1.8"><line x1="5" y1="5" x2="17" y2="17"/><line x1="17" y1="5" x2="5" y2="17"/></g>
              : <g stroke="currentColor" strokeWidth="1.8"><line x1="4" y1="7" x2="18" y2="7"/><line x1="4" y1="11" x2="18" y2="11"/><line x1="4" y1="15" x2="18" y2="15"/></g>}
          </svg>
        </button>
      </div>
      {/* mobile panel */}
      {mobileOpen && (
        <div className="site-mobile-panel" style={{
          background:PAGE_BG, borderTop:`1px solid ${PAGE_LINE}`,
          padding:'12px 20px 20px', display:'flex', flexDirection:'column', gap:4,
        }}>
          {items.map(i=>(
            <a key={i.l} href={i.h} onClick={()=>setMobileOpen(false)}
              style={{padding:'10px 4px',fontSize:16,color:PAGE_INK,textDecoration:'none',
                borderBottom:`1px solid ${PAGE_LINE}`}}>
              {i.l}
            </a>
          ))}
          <div style={{display:'flex',gap:10,marginTop:14}}>
            <a href="/waitlist" onClick={()=>setMobileOpen(false)} style={{flex:1,padding:'12px 0',textAlign:'center',borderRadius:999,
              background:PAGE_INK,color:PAGE_BG,fontSize:14,fontWeight:500,textDecoration:'none'}}>Join the waitlist</a>
          </div>
        </div>
      )}
    </header>
  );
}

// ────────────────────────────────────────────────
// Banner wrapper — scales a 1920×800 banner to container width.
// On small screens, swaps to a portrait recomposition.
// ────────────────────────────────────────────────
function BannerBlock({ id, Comp, tone, portrait }) {
  const wrapRef = React.useRef(null);
  const innerRef = React.useRef(null);
  const [isMobile, setIsMobile] = React.useState(false);

  React.useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 720);
    check();
    window.addEventListener('resize', check);
    return () => window.removeEventListener('resize', check);
  }, []);

  React.useEffect(() => {
    const fit = () => {
      const w = wrapRef.current?.clientWidth || 0;
      if (w && innerRef.current) {
        const base = isMobile ? 720 : 1920;
        const s = w / base;
        innerRef.current.style.transform = `scale(${s})`;
      }
    };
    fit();
    const ro = new ResizeObserver(fit);
    if (wrapRef.current) ro.observe(wrapRef.current);
    window.addEventListener('resize', fit);
    return () => { ro.disconnect(); window.removeEventListener('resize', fit); };
  }, [isMobile]);

  const ratio = isMobile ? '720 / 900' : '1920 / 800';
  const baseW = isMobile ? 720 : 1920;
  const baseH = isMobile ? 900 : 800;

  return (
    <div id={id} ref={wrapRef} style={{
      position:'relative', width:'100%', aspectRatio:ratio, overflow:'hidden',
      background:'#e8e5de', scrollMarginTop:0,
    }}
    className={isMobile ? 'os-banner-mobile' : ''}>
      <div ref={innerRef} style={{
        position:'absolute', top:0, left:0,
        width:baseW, height:baseH, transformOrigin:'0 0',
      }}>
        {isMobile && portrait ? React.createElement(portrait, {tone}) : <Comp tone={tone}/>}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────
// Content block — 2-3 paragraphs below banner
// ────────────────────────────────────────────────
function ContentBlock({ eyebrow, heading, body, accent }) {
  return (
    <div style={{
      maxWidth:1200, margin:'0 auto',
      padding:'clamp(60px, 9vw, 120px) clamp(20px, 4vw, 48px) clamp(40px, 6vw, 72px)',
      display:'grid',
      gridTemplateColumns:'1fr',
      gap:24,
    }} className="content-block">
      <div style={{
        display:'grid', gridTemplateColumns:'1fr 2fr',
        gap:'clamp(30px, 6vw, 80px)', alignItems:'start',
      }} className="content-block-grid">
        <div>
          <div style={{
            fontFamily:"'JetBrains Mono',ui-monospace,monospace",
            fontSize:11, letterSpacing:1.8, textTransform:'uppercase',
            color:accent, fontWeight:600, marginBottom:14,
          }}>{eyebrow}</div>
          <h2 style={{
            fontSize:'clamp(26px, 3.6vw, 42px)', fontWeight:500, letterSpacing:-0.8,
            lineHeight:1.05, margin:0, color:PAGE_INK,
          }}>{heading}</h2>
        </div>
        <div style={{
          fontSize:'clamp(15px, 1.2vw, 17px)', lineHeight:1.65, color:PAGE_INK_SOFT,
          display:'flex', flexDirection:'column', gap:16, paddingTop:4,
        }}>
          {body.map((p,i)=><p key={i} style={{margin:0}}>{p}</p>)}
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────
// Carousel — FCP-style. Fixed card on desktop, fluid card on mobile.
// Horizontal scroll-snap with prev/next arrows bottom-right.
// ────────────────────────────────────────────────
const CARD_W = 520;
const CARD_H = 325;
const CARD_GAP = 22;
const CARD_RATIO = CARD_W / CARD_H; // 1.6 — 16:10

function useCardSize() {
  const [size, setSize] = React.useState({w: CARD_W, h: CARD_H, gap: CARD_GAP});
  React.useEffect(() => {
    const recalc = () => {
      const vw = window.innerWidth;
      if (vw < 720) {
        // Phone: card = viewport minus 40px page padding (20px each side).
        const w = Math.max(280, Math.min(CARD_W, vw - 40));
        const h = Math.round(w / CARD_RATIO);
        setSize({w, h, gap: 16});
      } else {
        setSize({w: CARD_W, h: CARD_H, gap: CARD_GAP});
      }
    };
    recalc();
    window.addEventListener('resize', recalc);
    return () => window.removeEventListener('resize', recalc);
  }, []);
  return size;
}

function Carousel({ items, accent }) {
  const trackRef = React.useRef(null);
  const [idx, setIdx] = React.useState(0);
  const [lightbox, setLightbox] = React.useState(null); // {src, alt, title}
  const {w: cardW, h: cardH, gap: cardGap} = useCardSize();

  React.useEffect(() => {
    if (!lightbox) return;
    const onKey = (e) => { if (e.key === 'Escape') setLightbox(null); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [lightbox]);

  const go = (dir) => {
    const next = Math.max(0, Math.min(items.length - 1, idx + dir));
    setIdx(next);
    if (trackRef.current) {
      trackRef.current.scrollTo({
        left: next * (cardW + cardGap),
        behavior: 'smooth',
      });
    }
  };

  const onScroll = () => {
    if (!trackRef.current) return;
    const p = Math.round(trackRef.current.scrollLeft / (cardW + cardGap));
    if (p !== idx) setIdx(p);
  };

  // Extract the image src from a card if it's a RealScreenshot — that's how we know it's clickable.
  const getRealSrc = (it) => {
    if (!it || typeof it.render !== 'function') return null;
    try {
      const el = it.render();
      // RealScreenshot is a component; inspect its props (name or fullSrc).
      if (el && el.props) {
        const typeName = el.type && (el.type.displayName || el.type.name);
        if (typeName === 'RealScreenshot' || el.props.src) {
          const full = el.props.fullSrc || el.props.src;
          if (full) return {src: full, alt: el.props.alt || ''};
        }
      }
      // Fallback: walk for an <img>.
      const walk = (node) => {
        if (!node) return null;
        if (node.type === 'img' && node.props && node.props.src) return {src: node.props.src, alt: node.props.alt || ''};
        const kids = node.props && node.props.children;
        if (!kids) return null;
        const arr = Array.isArray(kids) ? kids : [kids];
        for (const k of arr) { const r = walk(k); if (r) return r; }
        return null;
      };
      return walk(el);
    } catch { return null; }
  };

  return (
    <div style={{
      maxWidth:1600, margin:'0 auto',
      padding:'0 clamp(20px, 4vw, 48px) clamp(80px, 10vw, 140px)',
    }}>
      <div
        ref={trackRef}
        onScroll={onScroll}
        style={{
          display:'flex',
          overflowX:'auto',
          scrollSnapType:'x mandatory',
          gap: cardGap,
          scrollbarWidth:'none',
          msOverflowStyle:'none',
          paddingBottom:4,
        }}
        className="carousel-track"
      >
        {items.map((it, i) => {
          const real = getRealSrc(it);
          return (
          <div key={i} style={{
            flex:`0 0 ${cardW}px`,
            scrollSnapAlign:'start',
            display:'flex', flexDirection:'column', gap:16,
          }}>
            <div
              onClick={real ? () => setLightbox({src: real.src, alt: real.alt, title: it.title}) : undefined}
              className={real ? 'os-real-card' : ''}
              style={{
                width: cardW, height: cardH,
                background:'#eeeae2', borderRadius:14,
                overflow:'hidden',
                cursor: real ? 'zoom-in' : 'default',
                position:'relative',
              }}
            >
              {(() => {
                const inner = typeof it.render === 'function' ? it.render() : it.render;
                // Scale 520×325-designed content to fit the actual card size.
                const scale = cardW / CARD_W;
                if (scale === 1) return inner;
                return (
                  <div style={{
                    width: CARD_W, height: CARD_H,
                    transform: `scale(${scale})`,
                    transformOrigin: '0 0',
                  }}>{inner}</div>
                );
              })()}
              {real && (
                <div className="os-view-pill" style={{
                  position:'absolute', top:10, right:10,
                  background:'rgba(28,26,23,0.72)', color:'#faf8f5',
                  borderRadius:999, padding:'5px 10px',
                  fontSize:10, fontFamily:"'JetBrains Mono',monospace",
                  letterSpacing:0.4, pointerEvents:'none',
                  backdropFilter:'blur(6px)',
                  WebkitBackdropFilter:'blur(6px)',
                  opacity:0,
                  transform:'translateY(-4px)',
                  transition:'opacity 180ms ease, transform 180ms ease',
                }}>
                  ⤢ VIEW
                </div>
              )}
            </div>
            <div style={{width: cardW}}>
              <div style={{
                fontSize:16, fontWeight:600, color:PAGE_INK, letterSpacing:-0.2,
                marginBottom:6, lineHeight:1.3,
              }}>
                {it.title}
              </div>
              <div style={{
                fontSize:14, lineHeight:1.55, color:PAGE_INK_SOFT,
              }}>
                {it.desc}
              </div>
            </div>
          </div>
          );
        })}
      </div>
      <div style={{
        display:'flex', justifyContent:'flex-end', alignItems:'center',
        gap:10, marginTop:28,
      }}>
        <div style={{fontSize:12,color:PAGE_INK_MUTE,fontFamily:"'JetBrains Mono',monospace",marginRight:10}}>
          {String(idx+1).padStart(2,'0')} / {String(items.length).padStart(2,'0')}
        </div>
        <CarouselArrow dir={-1} disabled={idx===0} onClick={()=>go(-1)} accent={accent}/>
        <CarouselArrow dir={1}  disabled={idx===items.length-1} onClick={()=>go(1)}  accent={accent}/>
      </div>

      {lightbox && (
        <div
          onClick={()=>setLightbox(null)}
          style={{
            position:'fixed', inset:0, zIndex:100,
            background:'rgba(12,11,10,0.88)',
            backdropFilter:'blur(18px)',
            WebkitBackdropFilter:'blur(18px)',
            display:'flex', alignItems:'center', justifyContent:'center',
            padding:'clamp(20px, 4vw, 60px)',
            cursor:'zoom-out',
            animation:'lbFade 220ms cubic-bezier(.2,.7,.2,1)',
          }}
        >
          <div style={{
            position:'relative', maxWidth:'min(1600px, 94vw)', maxHeight:'88vh',
            display:'flex', flexDirection:'column', gap:14,
          }}
            onClick={e=>e.stopPropagation()}
          >
            <img
              src={lightbox.src} alt={lightbox.alt}
              style={{
                maxWidth:'100%', maxHeight:'78vh',
                borderRadius:12, display:'block',
                boxShadow:'0 40px 100px rgba(0,0,0,0.5)',
                background:'#eeeae2',
                cursor:'default',
              }}
            />
            <div style={{
              display:'flex', justifyContent:'space-between', alignItems:'center',
              color:'rgba(244,236,220,0.85)', fontSize:14,
            }}>
              <div style={{fontWeight:500}}>{lightbox.title}</div>
              <button
                onClick={()=>setLightbox(null)}
                style={{
                  background:'transparent', border:'1px solid rgba(244,236,220,0.25)',
                  color:'#f4ecdc', borderRadius:999, padding:'8px 16px',
                  fontSize:12, fontFamily:"'JetBrains Mono',monospace",
                  letterSpacing:1, cursor:'pointer',
                }}
              >
                CLOSE · ESC
              </button>
            </div>
          </div>
          <style>{`@keyframes lbFade{from{opacity:0}to{opacity:1}}`}</style>
        </div>
      )}
    </div>
  );
}

function CarouselArrow({ dir, disabled, onClick, accent, onDark }) {
  const [hover, setHover] = React.useState(false);
  const idle = onDark ? '#f4ecdc' : PAGE_INK;
  const idleLine = onDark ? 'rgba(244,236,220,0.28)' : PAGE_LINE;
  const idleLineDisabled = onDark ? 'rgba(244,236,220,0.12)' : 'rgba(28,26,23,0.08)';
  const disabledCol = onDark ? 'rgba(244,236,220,0.35)' : PAGE_INK_MUTE;
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      onMouseEnter={()=>setHover(true)}
      onMouseLeave={()=>setHover(false)}
      style={{
        width:40, height:40, borderRadius:999,
        border:`1px solid ${disabled ? idleLineDisabled : idleLine}`,
        background: disabled ? 'transparent' : (hover ? accent : 'transparent'),
        color: disabled ? disabledCol : (hover ? '#fff' : idle),
        cursor: disabled ? 'default' : 'pointer',
        display:'flex',alignItems:'center',justifyContent:'center',
        transition:'all 180ms',
        opacity: disabled ? 0.4 : 1,
      }}
      aria-label={dir<0 ? 'Previous' : 'Next'}
    >
      <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
        {dir < 0
          ? <polyline points="8,3 4,7 8,11" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          : <polyline points="6,3 10,7 6,11" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>}
      </svg>
    </button>
  );
}

// ────────────────────────────────────────────────
// FeatureIcon — a small, calm line-icon set. Simple geometric strokes only,
// matching the site's minimal language. Inherits color via currentColor.
// ────────────────────────────────────────────────
function FeatureIcon({ name, size = 26 }) {
  const stk = { fill:'none', stroke:'currentColor', strokeWidth:1.6,
    strokeLinecap:'round', strokeLinejoin:'round' };
  const dot = { fill:'currentColor', stroke:'none' };
  const ICONS = {
    dashboard: (
      <g {...stk}>
        <rect x="3.5" y="3.5" width="7" height="7" rx="1.6"/>
        <rect x="13.5" y="3.5" width="7" height="7" rx="1.6"/>
        <rect x="3.5" y="13.5" width="7" height="7" rx="1.6"/>
        <rect x="13.5" y="13.5" width="7" height="7" rx="1.6"/>
      </g>
    ),
    list: (
      <g {...stk}>
        <line x1="9" y1="6" x2="20" y2="6"/>
        <line x1="9" y1="12" x2="20" y2="12"/>
        <line x1="9" y1="18" x2="20" y2="18"/>
        <circle cx="4.5" cy="6" r="1.2" {...dot}/>
        <circle cx="4.5" cy="12" r="1.2" {...dot}/>
        <circle cx="4.5" cy="18" r="1.2" {...dot}/>
      </g>
    ),
    heart: (
      <g {...stk}>
        <path d="M12 20s-7-4.6-7-10A4 4 0 0 1 12 7a4 4 0 0 1 7 3c0 5.4-7 10-7 10z"/>
      </g>
    ),
    spark: (
      <g {...stk}>
        <path d="M12 3l1.6 6.8L20.4 12l-6.8 1.6L12 20.4l-1.6-6.8L3.6 12l6.8-1.6L12 3z"/>
      </g>
    ),
    timeline: (
      <g {...stk} strokeWidth="1.9">
        <line x1="4" y1="6.5" x2="14" y2="6.5"/>
        <line x1="8.5" y1="12" x2="20" y2="12"/>
        <line x1="5.5" y1="17.5" x2="15.5" y2="17.5"/>
      </g>
    ),
    target: (
      <g {...stk}>
        <circle cx="12" cy="12" r="8.5"/>
        <circle cx="12" cy="12" r="3.6"/>
        <circle cx="12" cy="12" r="0.7" {...dot}/>
      </g>
    ),
    box: (
      <g {...stk}>
        <path d="M12 2.8l8.5 4.8v8.8L12 21.2 3.5 16.4V7.6L12 2.8z"/>
        <path d="M3.7 7.7 12 12.4l8.3-4.7"/>
        <line x1="12" y1="12.4" x2="12" y2="21.2"/>
      </g>
    ),
    key: (
      <g {...stk}>
        <circle cx="8" cy="8" r="4.2"/>
        <line x1="11" y1="11" x2="18.5" y2="18.5"/>
        <line x1="16.5" y1="16.5" x2="18.5" y2="14.5"/>
        <line x1="14" y1="14" x2="16.2" y2="11.8"/>
      </g>
    ),
    cycle: (
      <g {...stk}>
        <path d="M4.5 9.5a8 8 0 0 1 14-2"/>
        <polyline points="18.5,3 18.5,7.5 14,7.5"/>
        <path d="M19.5 14.5a8 8 0 0 1-14 2"/>
        <polyline points="5.5,21 5.5,16.5 10,16.5"/>
      </g>
    ),
    receipt: (
      <g {...stk}>
        <path d="M6 3.5h12v17l-2-1.4-2 1.4-2-1.4-2 1.4-2-1.4-2 1.4V3.5z"/>
        <line x1="9" y1="8" x2="15" y2="8"/>
        <line x1="9" y1="11.5" x2="15" y2="11.5"/>
      </g>
    ),
    book: (
      <g {...stk}>
        <path d="M4 4.5h6.5a2 2 0 0 1 1.5.7 2 2 0 0 1 1.5-.7H20v13h-6.5a2 2 0 0 0-1.5.7 2 2 0 0 0-1.5-.7H4v-13z"/>
        <line x1="12" y1="5.2" x2="12" y2="18.2"/>
      </g>
    ),
    waveform: (
      <g {...stk} strokeWidth="1.9">
        <line x1="4" y1="9.5" x2="4" y2="14.5"/>
        <line x1="8" y1="6.5" x2="8" y2="17.5"/>
        <line x1="12" y1="4" x2="12" y2="20"/>
        <line x1="16" y1="7.5" x2="16" y2="16.5"/>
        <line x1="20" y1="10.5" x2="20" y2="13.5"/>
      </g>
    ),
    note: (
      <g {...stk}>
        <path d="M9.4 17.5V6.2l9.5-2v11.3"/>
        <circle cx="7" cy="17.5" r="2.4" {...dot}/>
        <circle cx="16.5" cy="15.5" r="2.4" {...dot}/>
      </g>
    ),
    plug: (
      <g {...stk}>
        <line x1="9" y1="2.5" x2="9" y2="7"/>
        <line x1="15" y1="2.5" x2="15" y2="7"/>
        <path d="M6.5 7h11v3.5a5.5 5.5 0 0 1-11 0V7z"/>
        <line x1="12" y1="16" x2="12" y2="21.5"/>
      </g>
    ),
    cap: (
      <g {...stk}>
        <path d="M12 4 2.5 8.5 12 13l9.5-4.5L12 4z"/>
        <path d="M6.5 10.8v4.7c0 1.4 2.5 2.8 5.5 2.8s5.5-1.4 5.5-2.8v-4.7"/>
        <line x1="21.5" y1="8.5" x2="21.5" y2="13"/>
      </g>
    ),
    mic: (
      <g {...stk}>
        <rect x="9" y="3" width="6" height="11" rx="3"/>
        <path d="M5.5 11.5a6.5 6.5 0 0 0 13 0"/>
        <line x1="12" y1="18" x2="12" y2="21.5"/>
        <line x1="8.5" y1="21.5" x2="15.5" y2="21.5"/>
      </g>
    ),
    calendar: (
      <g {...stk}>
        <rect x="3.5" y="5" width="17" height="15.5" rx="2"/>
        <line x1="3.5" y1="9.5" x2="20.5" y2="9.5"/>
        <line x1="8" y1="3" x2="8" y2="6.5"/>
        <line x1="16" y1="3" x2="16" y2="6.5"/>
      </g>
    ),
    clock: (
      <g {...stk}>
        <circle cx="12" cy="12" r="8.5"/>
        <polyline points="12,7 12,12 15.5,14"/>
      </g>
    ),
    trend: (
      <g {...stk}>
        <polyline points="3,15.5 9,9.5 13,12.5 21,5"/>
        <polyline points="15.5,5 21,5 21,10.5"/>
      </g>
    ),
    chart: (
      <g {...stk} strokeWidth="1.9">
        <line x1="3" y1="20.5" x2="21" y2="20.5"/>
        <line x1="7" y1="20.5" x2="7" y2="12"/>
        <line x1="12" y1="20.5" x2="12" y2="6.5"/>
        <line x1="17" y1="20.5" x2="17" y2="15"/>
      </g>
    ),
    doc: (
      <g {...stk}>
        <path d="M6 3h8l4 4v14H6V3z"/>
        <polyline points="13.5,3 13.5,7.5 18,7.5"/>
        <line x1="9" y1="12.5" x2="15" y2="12.5"/>
        <line x1="9" y1="16" x2="13.5" y2="16"/>
      </g>
    ),
    chat: (
      <g {...stk}>
        <path d="M4 5h16a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H10l-4 3.5V15H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1z"/>
      </g>
    ),
    contacts: (
      <g {...stk}>
        <circle cx="9" cy="8" r="3.2"/>
        <path d="M3.5 19.5a5.5 5.5 0 0 1 11 0"/>
        <circle cx="17.2" cy="9" r="2.5"/>
        <path d="M16.4 14.3a4.6 4.6 0 0 1 4.1 5"/>
      </g>
    ),
    checkbox: (
      <g {...stk}>
        <rect x="3.5" y="3.5" width="17" height="17" rx="2.5"/>
        <polyline points="8,12.5 11,15.5 16.5,8.5"/>
      </g>
    ),
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{display:'block'}}>
      {ICONS[name] || ICONS.dashboard}
    </svg>
  );
}

// ────────────────────────────────────────────────
// FeatureGrid — static icon + title + description grid.
// Replaces the screenshot carousel for the pre-launch site: same content
// (title + desc), no app imagery. Each card's `icon` names a FeatureIcon.
// The original `render` functions are left untouched in the data so real
// screenshots can be reinstated at launch.
// ────────────────────────────────────────────────
function FeatureGrid({ items, accent }) {
  return (
    <div style={{
      maxWidth:1280, margin:'0 auto',
      padding:'0 clamp(20px, 4vw, 48px) clamp(80px, 10vw, 140px)',
    }}>
      <div className="feature-grid" style={{
        display:'grid',
        gridTemplateColumns:'repeat(3, 1fr)',
        gap:'clamp(36px, 4.5vw, 60px) clamp(30px, 3.5vw, 52px)',
      }}>
        {items.map((it, i) => (
          <div key={i} style={{display:'flex', flexDirection:'column', gap:16}}>
            <div style={{
              width:54, height:54, borderRadius:15,
              background:`${accent}14`,
              border:`1px solid ${accent}33`,
              display:'flex', alignItems:'center', justifyContent:'center',
              color:accent, flexShrink:0,
            }}>
              <FeatureIcon name={it.icon} size={26}/>
            </div>
            <div>
              <div style={{
                fontSize:17, fontWeight:600, color:PAGE_INK, letterSpacing:-0.2,
                marginBottom:8, lineHeight:1.3,
              }}>{it.title}</div>
              <div style={{
                fontSize:14.5, lineHeight:1.6, color:PAGE_INK_SOFT, textWrap:'pretty',
              }}>{it.desc}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────
// Footer
// ────────────────────────────────────────────────
function NewsletterForm() {
  const [email, setEmail] = React.useState('');
  const [status, setStatus] = React.useState('idle'); // idle | submitted
  const [focus, setFocus] = React.useState(false);
  const submit = async (e) => {
    e.preventDefault();
    if (!email || !/\S+@\S+\.\S+/.test(email) || status === 'sending') return;
    setStatus('sending');
    const note = `A new subscriber has signed up for the ComposerOS newsletter:\n${email}`;
    try {
      await submitToWeb3Forms({
        access_key: WEB3FORMS_NEWSLETTER_KEY,
        subject: 'ComposerOS — Newsletter signup',
        from_name: 'ComposerOS Website',
        email,
        message: note,
      });
      setStatus('submitted');
    } catch (_) {
      // Fallback: hand off to the visitor's email client if the POST fails.
      const subject = encodeURIComponent('ComposerOS — Newsletter signup');
      const body = encodeURIComponent(note);
      window.location.href = `mailto:newsletter@nemmgroup.ltd?subject=${subject}&body=${body}`;
      setStatus('submitted');
    }
  };
  return (
    <div id="newsletter" style={{
      marginTop:'clamp(70px, 9vw, 110px)',
      scrollMarginTop:84,
      paddingTop:48,
      borderTop:'1px solid rgba(242,239,232,0.12)',
      display:'grid',
      gridTemplateColumns:'minmax(0, 1fr) minmax(0, 1.15fr)',
      gap:'clamp(28px, 5vw, 80px)',
      alignItems:'start',
    }} className="newsletter-grid">
      <div>
        <div style={{fontFamily:"'JetBrains Mono',monospace",fontSize:11,
          letterSpacing:1.8,textTransform:'uppercase',color:'rgba(242,239,232,0.5)',
          marginBottom:14,fontWeight:600}}>Newsletter</div>
        <div style={{fontSize:'clamp(22px, 2.4vw, 30px)',fontWeight:450,
          letterSpacing:-0.6,lineHeight:1.2,color:'#f2efe8',maxWidth:460}}>
          Tips, tricks, and what's next.
          <span style={{display:'block',fontStyle:'italic',fontWeight:350,color:'#c9a876',
            fontSize:'clamp(14px, 1.05vw, 15px)',lineHeight:1.55,letterSpacing:-0.1,marginTop:14}}>
            Composer OS features explained, workflow shortcuts, and early access to upcoming releases. Monthly insights for power users.
          </span>
        </div>
      </div>
      {status === 'submitted' ? (
        <div style={{
          display:'flex',alignItems:'center',gap:14,minHeight:52,
          color:'rgba(242,239,232,0.85)',fontSize:15,
        }}>
          <div style={{width:28,height:28,borderRadius:99,
            border:'1px solid rgba(242,239,232,0.3)',
            display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
              <polyline points="2,6 5,9 10,3" stroke="#c9a876" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </div>
          <div>
            Thanks — you're on the list.
            <div style={{fontSize:12,color:'rgba(242,239,232,0.45)',marginTop:3}}>We'll be in touch.</div>
          </div>
        </div>
      ) : (
        <form onSubmit={submit} style={{
          display:'flex',alignItems:'stretch',
          borderBottom:`1px solid ${focus?'rgba(242,239,232,0.5)':'rgba(242,239,232,0.22)'}`,
          paddingBottom:14, gap:14, transition:'border-color 200ms',
        }}>
          <input
            type="email"
            value={email}
            onChange={(e)=>setEmail(e.target.value)}
            onFocus={()=>setFocus(true)}
            onBlur={()=>setFocus(false)}
            placeholder="you@studio.com"
            aria-label="Email address"
            style={{
              flex:1, background:'transparent', border:'none', outline:'none',
              color:'#f2efe8', fontSize:16, padding:'10px 0',
              fontFamily:'inherit', letterSpacing:-0.1,
            }}
          />
          <button type="submit" disabled={status==='sending'} style={{
            background:'transparent', border:'none', cursor: status==='sending' ? 'default' : 'pointer',
            color:email ? '#f2efe8' : 'rgba(242,239,232,0.45)',
            fontSize:14, fontWeight:500, padding:'10px 0',
            display:'flex',alignItems:'center',gap:8,
            transition:'color 150ms',fontFamily:'inherit',letterSpacing:0.1,
          }}>
            {status==='sending' ? 'Sending…' : 'Subscribe'}
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
              <line x1="2" y1="7" x2="11" y2="7" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
              <polyline points="8,4 11,7 8,10" stroke="currentColor" strokeWidth="1.4" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
        </form>
      )}
    </div>
  );
}

// ── Contact modal — footer/main-page palette (ink + ivory + ochre) ──
function FooterContactModal({ open, onClose }) {
  const ivory = '#f2efe8';
  const ochre = '#c9a876';
  const [form, setForm] = React.useState({ name:'', email:'', role:'Composer', message:'' });
  const [sent, setSent] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const dialogRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    setTimeout(() => { dialogRef.current && dialogRef.current.querySelector('input')?.focus(); }, 60);
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, [open, onClose]);
  React.useEffect(() => { if (open) setSent(false); }, [open]);

  if (!open) return null;

  const set = k => e => setForm(f => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && /\S+@\S+\.\S+/.test(form.email) && form.message.trim();

  const submit = async e => {
    e.preventDefault();
    if (!valid || sending) return;
    setSending(true);
    try {
      await submitToWeb3Forms({
        subject: `Contact — ${form.name} (${form.role})`,
        from_name: form.name,
        email: form.email,
        role: form.role,
        message: form.message,
      });
      setSent(true);
    } catch (_) {
      const subject = encodeURIComponent(`[${form.role}] ComposerOS — ${form.name}`);
      const body = encodeURIComponent(`Name: ${form.name}\nEmail: ${form.email}\nRole: ${form.role}\n\n${form.message}`);
      window.location.href = `mailto:info@nemmgroup.ltd?subject=${subject}&body=${body}`;
      setSent(true);
    }
    setSending(false);
  };

  const field = {
    width:'100%', padding:'12px 14px', borderRadius:10, boxSizing:'border-box',
    background:'rgba(242,239,232,0.05)', border:'1px solid rgba(242,239,232,0.16)',
    color:ivory, fontSize:15, fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", outline:'none',
    transition:'border-color 150ms, background 150ms',
  };
  const label = { fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1, textTransform:'uppercase', color:'rgba(242,239,232,0.55)', marginBottom:7, display:'block' };
  const onFoc = e => { e.target.style.borderColor = ochre; e.target.style.background = 'rgba(242,239,232,0.08)'; };
  const onBlur = e => { e.target.style.borderColor = 'rgba(242,239,232,0.16)'; e.target.style.background = 'rgba(242,239,232,0.05)'; };

  return (
    <div onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{position:'fixed', inset:0, zIndex:300, display:'flex', alignItems:'center', justifyContent:'center',
        padding:20, background:'rgba(16,14,12,0.7)', backdropFilter:'blur(6px)', WebkitBackdropFilter:'blur(6px)',
        animation:'cos-fade 180ms ease'}}>
      <div ref={dialogRef} role="dialog" aria-modal="true" aria-label="Contact ComposerOS"
        style={{position:'relative', width:'min(520px, 100%)', maxHeight:'90vh', overflowY:'auto',
          background:'#211e1a', border:'1px solid rgba(242,239,232,0.12)', borderRadius:18,
          padding:'clamp(26px, 4vw, 40px)', boxShadow:'0 30px 80px -24px rgba(0,0,0,0.7)',
          animation:'cos-rise 220ms cubic-bezier(0.16,1,0.3,1)', fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif"}}>
        <button onClick={onClose} aria-label="Close"
          style={{position:'absolute', top:16, right:16, width:34, height:34, borderRadius:999,
            background:'rgba(242,239,232,0.06)', border:'1px solid rgba(242,239,232,0.14)', cursor:'pointer',
            display:'flex', alignItems:'center', justifyContent:'center', color:ivory}}>
          <svg width="14" height="14" viewBox="0 0 14 14"><g stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><line x1="3" y1="3" x2="11" y2="11"/><line x1="11" y1="3" x2="3" y2="11"/></g></svg>
        </button>

        {sent ? (
          <div style={{textAlign:'center', padding:'18px 0'}}>
            <div style={{width:54, height:54, borderRadius:999, margin:'0 auto 18px', display:'flex', alignItems:'center', justifyContent:'center', background:'rgba(201,168,118,0.16)', border:`1px solid ${ochre}`}}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none"><polyline points="5,12.5 10,17.5 19,7" stroke={ochre} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
            <h3 style={{margin:'0 0 10px', fontSize:24, fontWeight:500, color:ivory, letterSpacing:-0.5}}>Message sent.</h3>
            <p style={{margin:'0 auto', maxWidth:360, fontSize:15, lineHeight:1.6, color:'rgba(242,239,232,0.62)'}}>
              Thanks — we've received your message and will be in touch. Prefer email? Reach us at{' '}
              <a href="mailto:info@nemmgroup.ltd" style={{color:ivory, borderBottom:`1px solid ${ochre}`, textDecoration:'none'}}>info@nemmgroup.ltd</a>.
            </p>
            <button onClick={onClose} style={{marginTop:24, padding:'12px 26px', borderRadius:999, background:ivory, color:'#1c1a17', border:'none', cursor:'pointer', fontSize:15, fontWeight:500}}>Done</button>
          </div>
        ) : (
          <form onSubmit={submit}>
            <div style={{fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1.6, textTransform:'uppercase', color:ochre, fontWeight:600, marginBottom:10}}>Contact</div>
            <h3 style={{margin:'0 0 8px', fontSize:'clamp(24px, 3.4vw, 30px)', fontWeight:450, letterSpacing:-0.8, color:ivory}}>
              Write to us.
            </h3>
            <p style={{margin:'0 0 24px', fontSize:14.5, lineHeight:1.55, color:'rgba(242,239,232,0.6)'}}>
              Tell us a little about you and what's on your mind. We read every message.
            </p>
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16, marginBottom:16}} className="cos-form-row">
              <div>
                <label style={label} htmlFor="cos-name">Name</label>
                <input id="cos-name" style={field} value={form.name} onChange={set('name')} onFocus={onFoc} onBlur={onBlur} placeholder="Your name"/>
              </div>
              <div>
                <label style={label} htmlFor="cos-email">Email</label>
                <input id="cos-email" type="email" style={field} value={form.email} onChange={set('email')} onFocus={onFoc} onBlur={onBlur} placeholder="you@studio.com"/>
              </div>
            </div>
            <div style={{marginBottom:16}}>
              <label style={label} htmlFor="cos-role">I'm a…</label>
              <select id="cos-role" style={{...field, appearance:'none', WebkitAppearance:'none', cursor:'pointer',
                backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23c9a876' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")`,
                backgroundRepeat:'no-repeat', backgroundPosition:'right 14px center'}}
                value={form.role} onChange={set('role')} onFocus={onFoc} onBlur={onBlur}>
                <option style={{color:'#1c1a17'}}>Composer</option>
                <option style={{color:'#1c1a17'}}>Studio</option>
                <option style={{color:'#1c1a17'}}>Publisher</option>
                <option style={{color:'#1c1a17'}}>Potential partner</option>
                <option style={{color:'#1c1a17'}}>Press</option>
                <option style={{color:'#1c1a17'}}>Just curious</option>
              </select>
            </div>
            <div style={{marginBottom:22}}>
              <label style={label} htmlFor="cos-msg">Message</label>
              <textarea id="cos-msg" rows={4} style={{...field, resize:'vertical', minHeight:96, lineHeight:1.5}} value={form.message} onChange={set('message')} onFocus={onFoc} onBlur={onBlur} placeholder="What's on your mind?"/>
            </div>
            <button type="submit" disabled={!valid}
              style={{width:'100%', padding:'15px 24px', borderRadius:999, border:'none',
                background: valid ? ivory : 'rgba(242,239,232,0.18)',
                color: valid ? '#1c1a17' : 'rgba(242,239,232,0.5)',
                fontSize:16, fontWeight:500, cursor: valid ? 'pointer' : 'not-allowed',
                fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", transition:'transform 150ms, background 150ms'}}
              onMouseOver={e => { if (valid) e.currentTarget.style.transform = 'scale(1.02)'; }}
              onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}>
              {sending ? 'Sending…' : 'Send message'}
            </button>
            <div style={{marginTop:14, fontSize:12.5, textAlign:'center', color:'rgba(242,239,232,0.45)'}}>
              Prefer email? <a href="mailto:info@nemmgroup.ltd" style={{color:'rgba(242,239,232,0.7)', textDecoration:'none', borderBottom:`1px solid ${ochre}`}}>info@nemmgroup.ltd</a>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}

// ── Book a demo modal — demo-specific (best-time picker + group-session note) ──
function BookDemoModal({ open, onClose, accent }) {
  const ivory = '#f2efe8';
  const ochre = accent || '#c9a876';
  const tinted = !!accent;
  const panelBg = tinted
    ? `linear-gradient(180deg, color-mix(in srgb, ${ochre} 24%, transparent), transparent 52%), color-mix(in srgb, ${ochre} 11%, #211e1a)`
    : '#211e1a';
  const panelBorder = tinted ? `color-mix(in srgb, ${ochre} 32%, rgba(242,239,232,0.12))` : 'rgba(242,239,232,0.12)';
  const TIMES = ['Weekday mornings', 'Weekday afternoons', 'Evenings / flexible'];
  const FOCUS = ['Dashboard', 'Projects & cues', 'Studio & invoicing', 'Library', 'Health', 'Aria assistant', 'Sessions', 'Timeline'];
  const [form, setForm] = React.useState({ name:'', email:'', role:'Composer', time:TIMES[0], focus:[], message:'' });
  const [sent, setSent] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const dialogRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    setTimeout(() => { dialogRef.current && dialogRef.current.querySelector('input')?.focus(); }, 60);
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, [open, onClose]);
  React.useEffect(() => { if (open) setSent(false); }, [open]);

  if (!open) return null;

  const set = k => e => setForm(f => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && /\S+@\S+\.\S+/.test(form.email);

  const submit = async e => {
    e.preventDefault();
    if (!valid || sending) return;
    setSending(true);
    try {
      await submitToWeb3Forms({
        subject: `Demo request — ${form.name} (${form.role})`,
        from_name: form.name,
        email: form.email,
        role: form.role,
        best_time: form.time,
        wants_to_see: form.focus.length ? form.focus.join(', ') : '(no preference)',
        message: form.message || '(no message)',
      });
      setSent(true);
    } catch (_) {
      const subject = encodeURIComponent(`Demo request — ${form.name} (${form.role})`);
      const body = encodeURIComponent(
        `Name: ${form.name}\nEmail: ${form.email}\nRole: ${form.role}\nBest time: ${form.time}\nWants to see: ${form.focus.length ? form.focus.join(', ') : '(no preference)'}\n\n${form.message || '(no message)'}`
      );
      window.location.href = `mailto:info@nemmgroup.ltd?subject=${subject}&body=${body}`;
      setSent(true);
    }
    setSending(false);
  };

  const field = {
    width:'100%', padding:'12px 14px', borderRadius:10, boxSizing:'border-box',
    background:'rgba(242,239,232,0.05)', border:'1px solid rgba(242,239,232,0.16)',
    color:ivory, fontSize:15, fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", outline:'none',
    transition:'border-color 150ms, background 150ms',
  };
  const label = { fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1, textTransform:'uppercase', color:'rgba(242,239,232,0.55)', marginBottom:7, display:'block' };
  const onFoc = e => { e.target.style.borderColor = ochre; e.target.style.background = 'rgba(242,239,232,0.08)'; };
  const onBlur = e => { e.target.style.borderColor = 'rgba(242,239,232,0.16)'; e.target.style.background = 'rgba(242,239,232,0.05)'; };

  return (
    <div onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{position:'fixed', inset:0, zIndex:300, display:'flex', alignItems:'center', justifyContent:'center',
        padding:20, background:'rgba(16,14,12,0.7)', backdropFilter:'blur(6px)', WebkitBackdropFilter:'blur(6px)',
        animation:'cos-fade 180ms ease'}}>
      <div ref={dialogRef} role="dialog" aria-modal="true" aria-label="Book a demo"
        style={{position:'relative', width:'min(520px, 100%)', maxHeight:'90vh', overflowY:'auto',
          background:panelBg,
          border:`1px solid ${panelBorder}`, borderRadius:18,
          padding:'clamp(26px, 4vw, 40px)', boxShadow:'0 30px 80px -24px rgba(0,0,0,0.7)',
          animation:'cos-rise 220ms cubic-bezier(0.16,1,0.3,1)', fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif"}}>
        <button onClick={onClose} aria-label="Close"
          style={{position:'absolute', top:16, right:16, width:34, height:34, borderRadius:999,
            background:'rgba(242,239,232,0.06)', border:'1px solid rgba(242,239,232,0.14)', cursor:'pointer',
            display:'flex', alignItems:'center', justifyContent:'center', color:ivory}}>
          <svg width="14" height="14" viewBox="0 0 14 14"><g stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><line x1="3" y1="3" x2="11" y2="11"/><line x1="11" y1="3" x2="3" y2="11"/></g></svg>
        </button>

        {sent ? (
          <div style={{textAlign:'center', padding:'18px 0'}}>
            <div style={{width:54, height:54, borderRadius:999, margin:'0 auto 18px', display:'flex', alignItems:'center', justifyContent:'center', background:'rgba(201,168,118,0.16)', border:`1px solid ${ochre}`}}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none"><polyline points="5,12.5 10,17.5 19,7" stroke={ochre} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
            <h3 style={{margin:'0 0 10px', fontSize:24, fontWeight:500, color:ivory, letterSpacing:-0.5}}>Demo request sent.</h3>
            <p style={{margin:'0 auto', maxWidth:380, fontSize:15, lineHeight:1.6, color:'rgba(242,239,232,0.66)'}}>
              Thanks — we've received your details and preferred time, and we'll be in
              touch with the next available presentation slot.
            </p>
            <button onClick={onClose} style={{marginTop:24, padding:'12px 26px', borderRadius:999, background:ivory, color:'#1c1a17', border:'none', cursor:'pointer', fontSize:15, fontWeight:500}}>Done</button>
          </div>
        ) : (
          <form onSubmit={submit}>
            <div style={{fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1.6, textTransform:'uppercase', color:ochre, fontWeight:600, marginBottom:10}}>Book a demo</div>
            <h3 style={{margin:'0 0 8px', fontSize:'clamp(24px, 3.4vw, 30px)', fontWeight:450, letterSpacing:-0.8, color:ivory}}>
              See ComposerOS live.
            </h3>
            <p style={{margin:'0 0 24px', fontSize:14.5, lineHeight:1.55, color:'rgba(242,239,232,0.6)'}}>
              Tell us who you are and when works best. We'll follow up with a presentation date.
            </p>
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16, marginBottom:16}} className="cos-form-row">
              <div>
                <label style={label} htmlFor="cos-d-name">Name</label>
                <input id="cos-d-name" style={field} value={form.name} onChange={set('name')} onFocus={onFoc} onBlur={onBlur} placeholder="Your name"/>
              </div>
              <div>
                <label style={label} htmlFor="cos-d-email">Email</label>
                <input id="cos-d-email" type="email" style={field} value={form.email} onChange={set('email')} onFocus={onFoc} onBlur={onBlur} placeholder="you@studio.com"/>
              </div>
            </div>
            <div style={{marginBottom:16}}>
              <label style={label} htmlFor="cos-d-role">I'm a…</label>
              <select id="cos-d-role" style={{...field, appearance:'none', WebkitAppearance:'none', cursor:'pointer',
                backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23c9a876' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")`,
                backgroundRepeat:'no-repeat', backgroundPosition:'right 14px center'}}
                value={form.role} onChange={set('role')} onFocus={onFoc} onBlur={onBlur}>
                <option style={{color:'#1c1a17'}}>Composer</option>
                <option style={{color:'#1c1a17'}}>Studio</option>
                <option style={{color:'#1c1a17'}}>Publisher</option>
                <option style={{color:'#1c1a17'}}>Potential partner</option>
                <option style={{color:'#1c1a17'}}>Press</option>
                <option style={{color:'#1c1a17'}}>Just curious</option>
              </select>
            </div>
            <div style={{marginBottom:18}}>
              <label style={label}>Best time for a demo</label>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8}} className="cos-demo-times">
                {TIMES.map(t => {
                  const active = form.time === t;
                  return (
                    <button type="button" key={t} onClick={()=>setForm(f=>({...f, time:t}))}
                      style={{padding:'11px 8px', borderRadius:10, fontSize:13, lineHeight:1.25, textAlign:'center', cursor:'pointer',
                        fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif",
                        background: active ? 'rgba(201,168,118,0.16)' : 'rgba(242,239,232,0.05)',
                        border: `1px solid ${active ? ochre : 'rgba(242,239,232,0.16)'}`,
                        color: active ? ivory : 'rgba(242,239,232,0.7)', transition:'all 150ms', fontWeight: active ? 500 : 400}}>
                      {t}
                    </button>
                  );
                })}
              </div>
            </div>
            <div style={{marginBottom:18}}>
              <label style={label}>What would you like to see? <span style={{textTransform:'none', letterSpacing:0, color:'rgba(242,239,232,0.4)'}}>(pick any)</span></label>
              <div style={{display:'flex', flexWrap:'wrap', gap:8}}>
                {FOCUS.map(f => {
                  const active = form.focus.includes(f);
                  return (
                    <button type="button" key={f}
                      onClick={()=>setForm(prev=>({...prev, focus: active ? prev.focus.filter(x=>x!==f) : [...prev.focus, f]}))}
                      style={{padding:'9px 14px', borderRadius:999, fontSize:13, lineHeight:1, cursor:'pointer',
                        fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", display:'inline-flex', alignItems:'center', gap:6,
                        background: active ? 'rgba(201,168,118,0.18)' : 'rgba(242,239,232,0.05)',
                        border: `1px solid ${active ? ochre : 'rgba(242,239,232,0.16)'}`,
                        color: active ? ivory : 'rgba(242,239,232,0.7)', transition:'all 150ms', fontWeight: active ? 500 : 400}}>
                      {active && (
                        <svg width="11" height="11" viewBox="0 0 12 12" fill="none"><polyline points="2,6.5 5,9 10,3" stroke={ochre} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
                      )}
                      {f}
                    </button>
                  );
                })}
              </div>
            </div>
            <div style={{marginBottom:18}}>
              <label style={label} htmlFor="cos-d-msg">Anything we should know? <span style={{textTransform:'none', letterSpacing:0, color:'rgba(242,239,232,0.4)'}}>(optional)</span></label>
              <textarea id="cos-d-msg" rows={3} style={{...field, resize:'vertical', minHeight:74, lineHeight:1.5}} value={form.message} onChange={set('message')} onFocus={onFoc} onBlur={onBlur} placeholder="Team size, what you'd like to see…"/>
            </div>
            <div style={{display:'flex', gap:10, alignItems:'flex-start', marginBottom:22, padding:'12px 14px', borderRadius:10, background:'rgba(201,168,118,0.07)', border:'1px solid rgba(201,168,118,0.18)'}}>
              <svg width="15" height="15" viewBox="0 0 16 16" fill="none" style={{flexShrink:0, marginTop:1}}>
                <circle cx="8" cy="8" r="7" stroke={ochre} strokeWidth="1.3"/>
                <line x1="8" y1="7" x2="8" y2="11.5" stroke={ochre} strokeWidth="1.3" strokeLinecap="round"/>
                <circle cx="8" cy="4.6" r="0.9" fill={ochre}/>
              </svg>
              <div style={{fontSize:12.5, lineHeight:1.5, color:'rgba(242,239,232,0.62)'}}>
                Demos are run as small group presentations. When a date opens up you may be joined by
                a few other guests — we'll send the details before confirming.
              </div>
            </div>
            <button type="submit" disabled={!valid}
              style={{width:'100%', padding:'15px 24px', borderRadius:999, border:'none',
                background: valid ? ivory : 'rgba(242,239,232,0.18)',
                color: valid ? '#1c1a17' : 'rgba(242,239,232,0.5)',
                fontSize:16, fontWeight:500, cursor: valid ? 'pointer' : 'not-allowed',
                fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", transition:'transform 150ms, background 150ms'}}
              onMouseOver={e => { if (valid) e.currentTarget.style.transform = 'scale(1.02)'; }}
              onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}>
              {sending ? 'Sending…' : 'Request demo'}
            </button>
            <div style={{marginTop:14, fontSize:12.5, textAlign:'center', color:'rgba(242,239,232,0.45)'}}>
              Prefer email? <a href="mailto:info@nemmgroup.ltd" style={{color:'rgba(242,239,232,0.7)', textDecoration:'none', borderBottom:`1px solid ${ochre}`}}>info@nemmgroup.ltd</a>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}

// ── Join the waitlist modal — captures the feature they're most excited about ──
function WaitlistModal({ open, onClose, accent }) {
  const ivory = '#f2efe8';
  const ochre = accent || '#c9a876';
  const tinted = !!accent;
  const panelBg = tinted
    ? `linear-gradient(180deg, color-mix(in srgb, ${ochre} 24%, transparent), transparent 52%), color-mix(in srgb, ${ochre} 11%, #211e1a)`
    : '#211e1a';
  const panelBorder = tinted ? `color-mix(in srgb, ${ochre} 32%, rgba(242,239,232,0.12))` : 'rgba(242,239,232,0.12)';
  const FEATURE_GROUPS = [
    { title:'Workflow speed', items:[
      { label:'Spotting notes \u2192 cues',        desc:'Aria matches your messy notes to cues' },
      { label:'One-click cue sheet export',    desc:'Your template, auto-filled, sent to the producer' },
      { label:'Revision tracking',             desc:'Never lose which notes you\u2019ve addressed' },
    ]},
    { title:'Studio operations', items:[
      { label:'Everything in one place',       desc:'Projects, cues, contacts & files \u2014 no app hopping' },
      { label:'Session time tracking',         desc:'Know exactly how much studio time per cue' },
      { label:'File organization',             desc:'Session folders auto-sync to your DAW' },
    ]},
    { title:'Business', items:[
      { label:'Invoicing & splits',            desc:'Composer, publisher & affiliate splits tracked' },
      { label:'PRO society management',        desc:'IPI, PRS/ASCAP/BMI linked to your cues' },
      { label:'Producer portal',               desc:'Client notes flow straight onto your cues' },
    ]},
    { title:'Creative', items:[
      { label:'Aria reads spotting notes',     desc:'Composer-aware, not generic AI' },
      { label:'Visual production timeline',    desc:'The whole project at a glance, with revisions' },
      { label:'Health & wellness',             desc:'Sleep, focus & energy tied to your output' },
    ]},
    { title:'Integration', items:[
      { label:'Curated composer library',      desc:'Books & tools for film/TV scoring' },
      { label:'Calendar sync',                 desc:'Deadlines & sessions in your calendar' },
    ]},
  ];
  const [form, setForm] = React.useState({ name:'', email:'', role:'Composer', features:[], why:'' });
  const toggleFeature = label => setForm(prev => ({
    ...prev,
    features: prev.features.includes(label) ? prev.features.filter(x => x !== label) : [...prev.features, label],
  }));
  const [sent, setSent] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const dialogRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    setTimeout(() => { dialogRef.current && dialogRef.current.querySelector('input')?.focus(); }, 60);
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, [open, onClose]);
  React.useEffect(() => { if (open) setSent(false); }, [open]);

  if (!open) return null;

  const set = k => e => setForm(f => ({ ...f, [k]: e.target.value }));
  const valid = form.name.trim() && /\S+@\S+\.\S+/.test(form.email);

  const submit = async e => {
    e.preventDefault();
    if (!valid || sending) return;
    setSending(true);
    try {
      await submitToWeb3Forms({
        subject: `Waitlist — ${form.name} (${form.role})`,
        from_name: form.name,
        email: form.email,
        role: form.role,
        interested_in: form.features.length ? form.features.join(', ') : '(none selected)',
        what_would_improve_workflow: form.why || '(no answer)',
      });
      setSent(true);
    } catch (_) {
      const subject = encodeURIComponent(`Waitlist — ${form.name} (${form.role})`);
      const body = encodeURIComponent(
        `Name: ${form.name}\nEmail: ${form.email}\nRole: ${form.role}\nInterested in: ${form.features.length ? form.features.join(', ') : '(none selected)'}\n\nWhat would most improve their workflow:\n${form.why || '(no answer)'}`
      );
      window.location.href = `mailto:info@nemmgroup.ltd?subject=${subject}&body=${body}`;
      setSent(true);
    }
    setSending(false);
  };

  const field = {
    width:'100%', padding:'12px 14px', borderRadius:10, boxSizing:'border-box',
    background:'rgba(242,239,232,0.05)', border:'1px solid rgba(242,239,232,0.16)',
    color:ivory, fontSize:15, fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", outline:'none',
    transition:'border-color 150ms, background 150ms',
  };
  const label = { fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1, textTransform:'uppercase', color:'rgba(242,239,232,0.55)', marginBottom:7, display:'block' };
  const onFoc = e => { e.target.style.borderColor = ochre; e.target.style.background = 'rgba(242,239,232,0.08)'; };
  const onBlur = e => { e.target.style.borderColor = 'rgba(242,239,232,0.16)'; e.target.style.background = 'rgba(242,239,232,0.05)'; };

  return (
    <div onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{position:'fixed', inset:0, zIndex:300, display:'flex', alignItems:'center', justifyContent:'center',
        padding:20, background:'rgba(16,14,12,0.7)', backdropFilter:'blur(6px)', WebkitBackdropFilter:'blur(6px)',
        animation:'cos-fade 180ms ease'}}>
      <div ref={dialogRef} role="dialog" aria-modal="true" aria-label="Join the waitlist"
        style={{position:'relative', width:'min(540px, 100%)', maxHeight:'90vh', overflowY:'auto',
          background:panelBg,
          border:`1px solid ${panelBorder}`, borderRadius:18,
          padding:'clamp(26px, 4vw, 40px)', boxShadow:'0 30px 80px -24px rgba(0,0,0,0.7)',
          animation:'cos-rise 220ms cubic-bezier(0.16,1,0.3,1)', fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif"}}>
        <button onClick={onClose} aria-label="Close"
          style={{position:'absolute', top:16, right:16, width:34, height:34, borderRadius:999,
            background:'rgba(242,239,232,0.06)', border:'1px solid rgba(242,239,232,0.14)', cursor:'pointer',
            display:'flex', alignItems:'center', justifyContent:'center', color:ivory}}>
          <svg width="14" height="14" viewBox="0 0 14 14"><g stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><line x1="3" y1="3" x2="11" y2="11"/><line x1="11" y1="3" x2="3" y2="11"/></g></svg>
        </button>

        {sent ? (
          <div style={{textAlign:'center', padding:'18px 0'}}>
            <div style={{width:54, height:54, borderRadius:999, margin:'0 auto 18px', display:'flex', alignItems:'center', justifyContent:'center', background:'rgba(201,168,118,0.16)', border:`1px solid ${ochre}`}}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none"><polyline points="5,12.5 10,17.5 19,7" stroke={ochre} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
            <h3 style={{margin:'0 0 10px', fontSize:24, fontWeight:500, color:ivory, letterSpacing:-0.5}}>You're on the list.</h3>
            <p style={{margin:'0 auto', maxWidth:380, fontSize:15, lineHeight:1.6, color:'rgba(242,239,232,0.66)'}}>
              You're on the list — we'll be in touch as we open access. Thank you for telling us
              what matters most to your workflow.
            </p>
            <button onClick={onClose} style={{marginTop:24, padding:'12px 26px', borderRadius:999, background:ivory, color:'#1c1a17', border:'none', cursor:'pointer', fontSize:15, fontWeight:500}}>Done</button>
          </div>
        ) : (
          <form onSubmit={submit}>
            <div style={{fontSize:11, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1.6, textTransform:'uppercase', color:ochre, fontWeight:600, marginBottom:10}}>Early access</div>
            <h3 style={{margin:'0 0 8px', fontSize:'clamp(24px, 3.4vw, 30px)', fontWeight:450, letterSpacing:-0.8, color:ivory}}>
              Join the waitlist.
            </h3>
            <p style={{margin:'0 0 24px', fontSize:14.5, lineHeight:1.55, color:'rgba(242,239,232,0.6)'}}>
              Be among the first composers in. Tell us what you're most looking forward to &mdash; it
              helps us prioritize what we ship first.
            </p>
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16, marginBottom:16}} className="cos-form-row">
              <div>
                <label style={label} htmlFor="cos-w-name">Name</label>
                <input id="cos-w-name" style={field} value={form.name} onChange={set('name')} onFocus={onFoc} onBlur={onBlur} placeholder="Your name"/>
              </div>
              <div>
                <label style={label} htmlFor="cos-w-email">Email</label>
                <input id="cos-w-email" type="email" style={field} value={form.email} onChange={set('email')} onFocus={onFoc} onBlur={onBlur} placeholder="you@studio.com"/>
              </div>
            </div>
            <div style={{marginBottom:18}}>
              <label style={label} htmlFor="cos-w-role">I'm a…</label>
              <select id="cos-w-role" style={{...field, appearance:'none', WebkitAppearance:'none', cursor:'pointer',
                backgroundImage:`url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23c9a876' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")`,
                backgroundRepeat:'no-repeat', backgroundPosition:'right 14px center'}}
                value={form.role} onChange={set('role')} onFocus={onFoc} onBlur={onBlur}>
                <option style={{color:'#1c1a17'}}>Composer</option>
                <option style={{color:'#1c1a17'}}>Studio</option>
                <option style={{color:'#1c1a17'}}>Publisher</option>
                <option style={{color:'#1c1a17'}}>Student</option>
                <option style={{color:'#1c1a17'}}>Just curious</option>
              </select>
            </div>
            <div style={{marginBottom:20}}>
              <label style={{...label, marginBottom:4}}>What would solve a real problem for you?</label>
              <div style={{fontSize:12.5, color:'rgba(242,239,232,0.45)', marginBottom:14}}>Select all that apply &mdash; it tells us what matters most to you.</div>
              {FEATURE_GROUPS.map((grp, gi) => (
                <div key={grp.title} style={{marginTop: gi === 0 ? 0 : 16}}>
                  <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:9}}>
                    <span style={{fontSize:10, fontFamily:"'JetBrains Mono',monospace", letterSpacing:1.4, textTransform:'uppercase', color:ochre, fontWeight:600, whiteSpace:'nowrap'}}>{grp.title}</span>
                    <span style={{flex:1, height:1, background:'rgba(242,239,232,0.1)'}}/>
                  </div>
                  <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(195px, 1fr))', gap:8}}>
                    {grp.items.map(it => {
                      const sel = form.features.includes(it.label);
                      return (
                        <button type="button" key={it.label} onClick={() => toggleFeature(it.label)} aria-pressed={sel}
                          onMouseOver={e => { if (!sel) { e.currentTarget.style.borderColor = 'rgba(242,239,232,0.32)'; e.currentTarget.style.background = 'rgba(242,239,232,0.07)'; } }}
                          onMouseOut={e => { if (!sel) { e.currentTarget.style.borderColor = 'rgba(242,239,232,0.13)'; e.currentTarget.style.background = 'rgba(242,239,232,0.04)'; } }}
                          style={{display:'flex', gap:10, alignItems:'flex-start', textAlign:'left', width:'100%', cursor:'pointer',
                            padding:'11px 12px', borderRadius:12, transition:'border-color 150ms, background 150ms',
                            fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif",
                            background: sel ? `color-mix(in srgb, ${ochre} 15%, transparent)` : 'rgba(242,239,232,0.04)',
                            border:`1px solid ${sel ? ochre : 'rgba(242,239,232,0.13)'}`}}>
                          <span aria-hidden="true" style={{flexShrink:0, width:18, height:18, borderRadius:5, marginTop:1,
                            border:`1.5px solid ${sel ? ochre : 'rgba(242,239,232,0.32)'}`, background: sel ? ochre : 'transparent',
                            display:'flex', alignItems:'center', justifyContent:'center', transition:'all 150ms'}}>
                            {sel && <svg width="11" height="11" viewBox="0 0 12 12" fill="none"><polyline points="2.5,6.5 5,9 9.5,3.5" stroke="#1c1a17" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                          </span>
                          <span style={{display:'flex', flexDirection:'column', gap:3, minWidth:0}}>
                            <span style={{fontSize:13.5, fontWeight:500, lineHeight:1.2, color: sel ? ivory : 'rgba(242,239,232,0.88)'}}>{it.label}</span>
                            <span style={{fontSize:11.5, lineHeight:1.35, color: sel ? 'rgba(242,239,232,0.62)' : 'rgba(242,239,232,0.46)'}}>{it.desc}</span>
                          </span>
                        </button>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
            <div style={{marginBottom:22}}>
              <label style={label} htmlFor="cos-w-why">What would most improve your composition workflow? <span style={{textTransform:'none', letterSpacing:0, color:'rgba(242,239,232,0.4)'}}>(optional)</span></label>
              <textarea id="cos-w-why" rows={3} style={{...field, resize:'vertical', minHeight:74, lineHeight:1.5}} value={form.why} onChange={set('why')} onFocus={onFoc} onBlur={onBlur} placeholder="The thing that slows you down today…"/>
            </div>
            <button type="submit" disabled={!valid}
              style={{width:'100%', padding:'15px 24px', borderRadius:999, border:'none',
                background: valid ? ivory : 'rgba(242,239,232,0.18)',
                color: valid ? '#1c1a17' : 'rgba(242,239,232,0.5)',
                fontSize:16, fontWeight:500, cursor: valid ? 'pointer' : 'not-allowed',
                fontFamily:"'Inter Tight',system-ui,-apple-system,BlinkMacSystemFont,sans-serif", transition:'transform 150ms, background 150ms'}}
              onMouseOver={e => { if (valid) e.currentTarget.style.transform = 'scale(1.02)'; }}
              onMouseOut={e => e.currentTarget.style.transform = 'scale(1)'}>
              {sending ? 'Sending…' : 'Join the waitlist'}
            </button>
          </form>
        )}
      </div>
    </div>
  );
}

function SiteFooter() {
  const [contact, setContact] = React.useState(false);
  const [demo, setDemo] = React.useState(false);
  const [demoAccent, setDemoAccent] = React.useState(null);
  const [waitlist, setWaitlist] = React.useState(false);
  const [waitAccent, setWaitAccent] = React.useState(null);
  React.useEffect(() => {
    const openDemo = (e) => { setDemoAccent(e && e.detail && e.detail.accent ? e.detail.accent : null); setDemo(true); };
    const openWait = (e) => { setWaitAccent(e && e.detail && e.detail.accent ? e.detail.accent : null); setWaitlist(true); };
    window.addEventListener('cos-open-demo', openDemo);
    window.addEventListener('cos-open-waitlist', openWait);
    return () => {
      window.removeEventListener('cos-open-demo', openDemo);
      window.removeEventListener('cos-open-waitlist', openWait);
    };
  }, []);
  return (
    <footer style={{
      background:'#1c1a17', color:'#f2efe8',
      padding:'clamp(80px, 10vw, 140px) clamp(20px, 4vw, 48px) 48px',
    }}>
      <div style={{maxWidth:1400, margin:'0 auto'}}>
        <div style={{
          fontSize:'clamp(36px, 6vw, 76px)', fontWeight:450,
          letterSpacing:-2, lineHeight:1.02, maxWidth:1100,
        }}>
          Built for composers.<br/>
          <span style={{fontStyle:'italic',fontWeight:350,color:'#c9a876'}}>Focus on the music.</span>
        </div>
        <div style={{display:'flex',gap:14,marginTop:44,flexWrap:'wrap'}}>
          <a href="/waitlist" style={{
            padding:'18px 26px',background:'#f2efe8',color:'#1c1a17',
            borderRadius:999,fontSize:16,fontWeight:500,textDecoration:'none',cursor:'pointer',
            textAlign:'center',minWidth:180,boxSizing:'border-box',
          }}>Join the waitlist →</a>
          <a href="/about" style={{
            padding:'18px 26px',background:'#f2efe8',color:'#1c1a17',
            borderRadius:999,fontSize:16,fontWeight:500,textDecoration:'none',
            textAlign:'center',minWidth:180,boxSizing:'border-box',
          }}>Read the story</a>
          <a href="#contact" onClick={e=>{e.preventDefault();window.dispatchEvent(new CustomEvent('cos-open-demo'));}} style={{
            padding:'18px 26px',background:'#f2efe8',color:'#1c1a17',
            borderRadius:999,fontSize:16,fontWeight:500,textDecoration:'none',cursor:'pointer',
            textAlign:'center',minWidth:180,boxSizing:'border-box',
          }}>Book a demo</a>
        </div>
        <NewsletterForm/>
        <div style={{
          marginTop:'clamp(60px, 8vw, 100px)',
          display:'grid',
          gridTemplateColumns:'repeat(auto-fit, minmax(180px, 1fr))',
          gap:40,
          borderTop:'1px solid rgba(242,239,232,0.12)',
          paddingTop:44,
        }}>
          <div>
            <div style={{display:'flex',alignItems:'center',gap:10,marginBottom:18}}>
              <div style={{width:28,height:28}}>
                {(typeof ORBIT_PALETTE !== 'undefined')
                  ? <OrbitIcon size={28} tone={ORBIT_PALETTE.ochre}/>
                  : <div style={{width:22,height:22,borderRadius:11,
                      background:'conic-gradient(from 0deg, #f2efe8, #c9a876, #f2efe8)'}}/>}
              </div>
              <div style={{fontSize:17,fontWeight:500}}>Composer<span style={{opacity:0.55}}>OS</span></div>
            </div>
            <div style={{fontSize:13,color:'rgba(242,239,232,0.55)',lineHeight:1.6,maxWidth:360}}>
              The operating system for composers.<br/>
              <span style={{whiteSpace:'nowrap'}}>Your whole studio — one system.</span>
            </div>
          </div>
          {[
            {h:'Product',links:['Home','Studio','Library','Projects','Health','Aria']},
            {h:'Company',links:['About','Contact']},
            {h:'Legal',links:['Privacy Policy','Terms of Service','Security','Cookies','Manage cookies']},
            {h:'Connect',links:['Instagram']},
          ].map(col=>(
            <div key={col.h}>
              <div style={{fontFamily:"'JetBrains Mono',monospace",fontSize:11,
                letterSpacing:1.8,textTransform:'uppercase',color:'rgba(242,239,232,0.5)',
                marginBottom:16,fontWeight:600}}>{col.h}</div>
              <div style={{display:'flex',flexDirection:'column',gap:10}}>
                {col.links.map(l=>{
                  if (l === 'Contact') {
                    return (
                      <a key={l} href="#contact" onClick={e=>{e.preventDefault();setContact(true);}}
                        style={{fontSize:14,color:'rgba(242,239,232,0.85)',textDecoration:'none',cursor:'pointer'}}>{l}</a>
                    );
                  }
                  if (l === 'Instagram') {
                    return (
                      <a key={l} href="https://instagram.com/composeros.studio" target="_blank" rel="noopener"
                        style={{fontSize:14,color:'rgba(242,239,232,0.85)',textDecoration:'none'}}>{l}</a>
                    );
                  }
                  if (l === 'Manage cookies') {
                    return (
                      <button key={l} type="button" data-cc="show-preferencesModal"
                        style={{background:'transparent',border:'none',padding:0,cursor:'pointer',
                          fontSize:14,color:'rgba(242,239,232,0.85)',textDecoration:'none',textAlign:'left',
                          fontFamily:'inherit'}}>{l}</button>
                    );
                  }
                  const SECTION_LINKS = ['Home','Studio','Library','Projects','Health','Aria'];
                  const LEGAL_LINKS = {
                    'Privacy Policy':'/privacy',
                    'Terms of Service':'/terms',
                    'Security':'/security',
                    'Cookies':'/cookies',
                  };
                  const href = l==='About' ? '/about'
                    : LEGAL_LINKS[l] ? LEGAL_LINKS[l]
                    : SECTION_LINKS.includes(l) ? `index.html#${l.toLowerCase()}`
                    : '#';
                  return (
                    <a key={l} href={href} style={{fontSize:14,color:'rgba(242,239,232,0.85)',textDecoration:'none'}}>{l==='About' ? 'Story' : l}</a>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
        <div style={{
          marginTop:48,paddingTop:24,
          borderTop:'1px solid rgba(242,239,232,0.08)',
          display:'flex',justifyContent:'space-between',alignItems:'center',
          flexWrap:'wrap',gap:14,
          fontSize:12,color:'rgba(242,239,232,0.45)',
        }}>
          <div>© 2026 NEMM Software Ltd. All rights reserved.</div>
          <div style={{display:'inline-flex',alignItems:'center',gap:4,color:'rgba(242,239,232,0.45)'}}>
            <span>Smart Website By</span>
            <a href="https://swats.ai" target="_blank" rel="noopener noreferrer"
              aria-label="SWATS — visit swats.ai"
              style={{display:'inline-flex',alignItems:'center',lineHeight:0,textDecoration:'none',color:'inherit'}}>
              <svg role="img" aria-label="SWATS"
                viewBox="-2 -2 569.08 120.04"
                style={{display:'inline-block',height:9,width:'auto',overflow:'visible'}}>
                <defs>
                  <linearGradient id="cos-swats-a" x1="255.99" y1="113.48" x2="352.69" y2="16.79" gradientUnits="userSpaceOnUse">
                    <stop offset=".31" stopColor="#38c6f4"/>
                    <stop offset="1" stopColor="#77c043"/>
                  </linearGradient>
                </defs>
                <path fill="currentColor" fillRule="evenodd" d="M143.19,13.03v69.89s-14.29,9.26-14.87,9.75h32.19V13.03l15.93-13.03h14.33v83.73l-15.94,8.94h32.97V13.03L224.12,0h15.59c.04,3.48,0,108.98,0,108.98l-7.98,6.05h-48.74l-7.49-6.63-7.6,6.63h-48.7l-7.2-5.11V0h16.38l14.81,13.03Z"/>
                <path fill="currentColor" fillRule="evenodd" d="M565.08,0v16.92l-13.17,14.95h-64.18c-.02.14,1.21.5,1.21.5l68.25,29.4s7.89,3.05,7.89,12.93v33.55l-5.35,6.79h-87.43c.02-4.67.07-7.01.07-7.01l14.31-14.79,47.64-.03v-8.07l-25.15-10.48s-18.52-8.18-27.79-12.27c-2.35-1.04-8.59-5.85-8.54-12.8.07-9.95-.08-23.9,0-33.84,0-.6,15.67-15.73,15.67-15.73h76.56Z"/>
                <path fill="currentColor" fillRule="evenodd" d="M92.77,0v16.92l-13.17,14.95H15.42c-.02.14,1.21.5,1.21.5l68.25,29.4s7.89,3.05,7.89,12.93v33.55l-5.34,6.79H0c.02-4.67.06-7.01.06-7.01l14.31-14.79,47.64-.03v-8.07l-25.15-10.48s-18.52-8.18-27.79-12.27c-2.35-1.04-8.58-5.85-8.54-12.8.06-9.7-.11-23.3,0-33.84,0-.6,15.67-15.73,15.67-15.73h76.56Z"/>
                <polygon fill="currentColor" fillRule="evenodd" points="461.04 16.56 446.78 30.83 412.27 30.83 427.04 40.23 427.04 115.04 402.21 115.04 395.92 108.08 395.92 30.77 362.79 30.77 362.79 14.45 378.85 0 461.04 0 461.04 16.56"/>
                <path fill="url(#cos-swats-a)" fillRule="evenodd" d="M335.94.04h-62.18l-16.21,15.79v99.21h17.7l13.3-13.27v-23.73h31v23.73l13.24,13.27h17.76V15.83L335.94.04ZM319.54,66.74l-12.74-12.7h-18.26v-25h31v37.7Z"/>
              </svg>
            </a>
          </div>
          <div style={{fontFamily:"'JetBrains Mono',monospace",letterSpacing:1.2}}>
            VERSION 1.0 · APRIL MMXXVI
          </div>
        </div>
      </div>
      <FooterContactModal open={contact} onClose={()=>setContact(false)}/>
      <BookDemoModal open={demo} onClose={()=>setDemo(false)} accent={demoAccent}/>
      <WaitlistModal open={waitlist} onClose={()=>setWaitlist(false)} accent={waitAccent}/>
    </footer>
  );
}

// ────────────────────────────────────────────────
// QuotesSection — big calm quote carousel, 5s auto-advance.
// Same indicator + arrows vocabulary as Carousel, different container.
// ────────────────────────────────────────────────
const QUOTES = [
  {
    quote: "It’s been a while since I’ve been excited about a piece of software and this is it! The thing I had no idea I needed for so long. ComposerOS is extremely intuitive and can go as deep as you need it to (or not). One of the most comprehensive tools for creatives made by a creative! It truly doesn’t get any better than this.",
    author: "Pieter Schlosser",
    role: "Los Angeles",
  },
  {
    quote: "Powerful stuff. A tremendous tool that allows to spend less time on admin work and more time on what we do best, write music.",
    author: "Kevin Smithers",
    role: "Los Angeles",
  },
  {
    quote: "As someone building ComposerOS, I might be a bit biased, but every time a new feature clicks and saves me hours of my day, I can’t help but think about how much I’m excited and eager to share it with my composer friends. I’m truly proud of this one, and I’m already using it daily on my own projects. Check it out!",
    author: "Marcelo Trevino",
    role: "Squamish",
  },
];

function QuotesSection({ accent = '#c9a876' }) {
  // Dusk plum palette — quiet, reverent, warm ivory text.
  // Pulls from banners palette: plum + burgundy. Only dark moment before footer.
  const bg      = '#3d3448';       // deep plum
  const bgEdge  = '#2f2838';       // deeper plum at edge for vignette
  const ink     = '#f4ecdc';       // warm ivory
  const inkSoft = 'rgba(244,236,220,0.55)';
  const line    = 'rgba(244,236,220,0.14)';

  const [idx, setIdx] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const count = QUOTES.length;

  const go = (dir) => {
    setIdx(i => (i + dir + count) % count);
  };
  const jump = (n) => setIdx(n);

  // Auto-advance every 5s unless paused (hover)
  React.useEffect(() => {
    if (paused) return;
    const t = setInterval(() => {
      setIdx(i => (i + 1) % count);
    }, 10000);
    return () => clearInterval(t);
  }, [paused, count]);

  return (
    <section
      id="quotes"
      data-screen-label="07 quotes"
      style={{
        background:`linear-gradient(180deg, ${bg} 0%, ${bgEdge} 100%)`,
        borderTop:`1px solid ${line}`,
        borderBottom:`1px solid ${line}`,
        padding:'clamp(36px, 6vw, 96px) clamp(18px, 4vw, 48px)',
        position:'relative',
        overflow:'hidden',
        width:'100%',
        minHeight:'min(800px, 42vw)',
        scrollMarginTop:64,
        display:'flex',
        alignItems:'center',
        justifyContent:'center',
      }}
    >
      {/* Giant typographic quote mark, very faded, as ambient background */}
      <div style={{
        position:'absolute',
        top:'clamp(-40px, -4vw, -60px)',
        left:'50%',
        transform:'translateX(-50%)',
        fontFamily:"'Inter Tight', serif",
        fontSize:'clamp(320px, 40vw, 560px)',
        fontWeight:300,
        fontStyle:'italic',
        color:'rgba(244,236,220,0.05)',
        lineHeight:1,
        pointerEvents:'none',
        userSelect:'none',
        letterSpacing:-20,
      }}>
        &ldquo;
      </div>

      <div style={{maxWidth:1200, margin:'0 auto', position:'relative', width:'100%'}}>
        {/* eyebrow */}
        <div style={{
          fontFamily:"'JetBrains Mono',monospace", fontSize:11,
          letterSpacing:1.8, textTransform:'uppercase', color:accent,
          fontWeight:600, marginBottom:'clamp(18px, 3.5vw, 40px)',
          textAlign:'center',
        }}>
          07 · Quotes from composers
        </div>

        {/* Quote stack — each quote fades in/out */}
        <div style={{
          position:'relative',
          minHeight:'clamp(400px, 72vw, 620px)',
          display:'flex', alignItems:'center', justifyContent:'center',
        }}>
          {QUOTES.map((q, i) => (
            <div key={i} style={{
              position:'absolute', inset:0,
              display:'flex', flexDirection:'column',
              alignItems:'center', justifyContent:'center',
              textAlign:'center',
              opacity: i === idx ? 1 : 0,
              transform: i === idx ? 'translateY(0)' : 'translateY(12px)',
              transition:'opacity 600ms cubic-bezier(.2,.7,.2,1), transform 600ms cubic-bezier(.2,.7,.2,1)',
              pointerEvents: i === idx ? 'auto' : 'none',
              padding:'0 clamp(8px, 4vw, 60px)',
            }}>
              <blockquote style={{
                margin:0,
                fontSize: q.quote.length > 220 ? 'clamp(16px, 2.35vw, 32px)' : 'clamp(24px, 3.2vw, 42px)',
                lineHeight: q.quote.length > 220 ? 1.32 : 1.25,
                fontWeight:400,
                letterSpacing: q.quote.length > 220 ? 0 : -0.8,
                color:ink,
                maxWidth: q.quote.length > 220 ? 1080 : 1000,
                fontStyle:'italic',
                textWrap:'balance',
              }}>
                &ldquo;{q.quote}&rdquo;
              </blockquote>
              <div style={{
                marginTop:'clamp(28px, 4vw, 44px)',
                display:'flex', flexDirection:'column', alignItems:'center', gap:4,
              }}>
                <div style={{
                  fontSize: 'clamp(14px, 1.1vw, 16px)',
                  fontWeight: 500,
                  color: ink,
                  letterSpacing: -0.1,
                }}>
                  {q.author}
                </div>
                <div style={{
                  fontFamily: "'JetBrains Mono',monospace",
                  fontSize: 11, letterSpacing: 1.5,
                  textTransform: 'uppercase', color: inkSoft, fontWeight: 500,
                }}>
                  {q.role}
                </div>
              </div>
            </div>
          ))}
        </div>

        {/* Controls row — same vocabulary as Carousel: indicator + arrows */}
        {/* Pause-on-hover is scoped to each control, not the whole row */}
        <div style={{
          display:'flex', alignItems:'center', justifyContent:'center',
          gap:20, marginTop:'clamp(20px, 5vw, 64px)',
        }}>
          <div
            onMouseEnter={()=>setPaused(true)}
            onMouseLeave={()=>setPaused(false)}
          >
            <CarouselArrow dir={-1} onClick={()=>go(-1)} accent={accent} onDark/>
          </div>

          {/* Dot-number indicators — 0 1 2 3 4 style */}
          <div
            onMouseEnter={()=>setPaused(true)}
            onMouseLeave={()=>setPaused(false)}
            style={{display:'flex', alignItems:'center', gap:14}}
          >
            {QUOTES.map((_, i) => (
              <button
                key={i}
                onClick={()=>jump(i)}
                aria-label={`Quote ${i+1}`}
                style={{
                  background:'transparent',
                  border:'none',
                  cursor:'pointer',
                  padding:'6px 2px',
                  fontFamily:"'JetBrains Mono',monospace",
                  fontSize:12,
                  letterSpacing:1,
                  color: i === idx ? ink : 'rgba(244,236,220,0.4)',
                  fontWeight: i === idx ? 600 : 500,
                  transition:'color 200ms',
                  position:'relative',
                }}
                onMouseOver={e=>{ if(i!==idx) e.currentTarget.style.color='rgba(244,236,220,0.7)'; }}
                onMouseOut={e=>{ if(i!==idx) e.currentTarget.style.color='rgba(244,236,220,0.4)'; }}
              >
                {String(i).padStart(2,'0')}
                {/* Underline for active */}
                {i === idx && (
                  <div style={{
                    position:'absolute',
                    left:2, right:2, bottom:-2,
                    height:2, background:accent, borderRadius:2,
                  }}/>
                )}
              </button>
            ))}
          </div>

          <div
            onMouseEnter={()=>setPaused(true)}
            onMouseLeave={()=>setPaused(false)}
          >
            <CarouselArrow dir={1} onClick={()=>go(1)} accent={accent} onDark/>
          </div>
        </div>

        {/* subtle auto-advance progress bar under indicators */}
        <div style={{
          display:'flex', justifyContent:'center', marginTop:'clamp(12px, 2vw, 18px)',
        }}>
          <div style={{
            width:120, height:2, background:'rgba(244,236,220,0.12)',
            borderRadius:2, overflow:'hidden',
          }}>
            <div
              key={`${idx}-${paused}`}
              style={{
                height:'100%', background:accent,
                width: paused ? '100%' : 0,
                animation: paused ? 'none' : 'quoteProgress 10000ms linear forwards',
                opacity: paused ? 0.3 : 0.7,
              }}
            />
          </div>
        </div>
      </div>

      <style>{`
        @keyframes quoteProgress {
          from { width: 0%; }
          to { width: 100%; }
        }
      `}</style>
    </section>
  );
}

Object.assign(window, {
  SiteHeader, BannerBlock, ContentBlock, Carousel, FeatureGrid, FeatureIcon,
  NewsletterForm, SiteFooter, QuotesSection, WaitlistModal,
});
