/* MagicVocalsApp.jsx — Landing page with sample×preset A/B player. */

const { useState: _us, useEffect: _ue, useRef: _ur, useMemo: _um } = React;

// ─── Helpers ────────────────────────────────────────────────────────
const mmss = (s) => {
  if (!s || !isFinite(s)) return '0:00';
  const m = Math.floor(s / 60);
  const r = Math.floor(s % 60);
  return `${m}:${String(r).padStart(2, '0')}`;
};

// ─── A/B Bar (above plugin) ─────────────────────────────────────────
const ABBar = ({ engine, activeSampleId, activePreset }) => {
  const isPlaying = engine.isPlaying;
  const isWet = engine.isWet;
  const dur = engine.duration || 0;
  const pos = engine.position;
  const isReal = engine.hasRealWet(activeSampleId, activePreset.id);

  const bars = _um(() => Array.from({ length: 80 }, (_, i) => 0.3 + 0.7 * Math.abs(Math.sin(i * 0.7) * Math.cos(i * 0.22))), []);

  return (
    <div className={`ab-bar ${isReal ? 'ab-bar--real' : ''}`}>
      <div className="ab-cluster">
        <button className={`ab-transport ${isPlaying ? 'is-playing' : ''}`}
                onClick={() => engine.togglePlay(activeSampleId, activePreset)}
                title={isPlaying ? 'Pause' : 'Play'}>
          {isPlaying
            ? <svg width="12" height="12" viewBox="0 0 12 12"><rect x="2.4" y="1.6" width="2.6" height="8.8" fill="currentColor"/><rect x="7" y="1.6" width="2.6" height="8.8" fill="currentColor"/></svg>
            : <svg width="12" height="12" viewBox="0 0 12 12"><path d="M2.6 1.4 L10.4 6 L2.6 10.6 Z" fill="currentColor"/></svg>}
        </button>
        <div className="ab-now">
          <div className="ab-now__label">{MV_SAMPLES.find(s => s.id === activeSampleId)?.label || 'Sample'}</div>
          <div className="ab-now__name">{activePreset.name}</div>
        </div>
      </div>

      <div className="ab-seg" role="tablist" aria-label="Compare raw vs processed">
        <button className={`ab-seg__btn ${!isWet ? 'on ab-seg__btn--a' : ''}`}
                role="tab" aria-selected={!isWet}
                aria-label="A — raw signal"
                onClick={() => engine.setWet(false)}>
          <span className="ab-seg__letter">A</span>
          <span className="ab-seg__name">RAW</span>
        </button>
        <button className={`ab-seg__btn ${isWet ? 'on ab-seg__btn--b' : ''}`}
                role="tab" aria-selected={isWet}
                aria-label="B — processed by Magic Vocals"
                onClick={() => engine.setWet(true)}>
          <span className="ab-seg__letter">B</span>
          <span className="ab-seg__name">MAGIC VOCALS</span>
        </button>
      </div>

      <div className="ab-scrub-wrap">
        <div className="scrub" onClick={(e) => {
          const r = e.currentTarget.getBoundingClientRect();
          if (dur) engine.seek(((e.clientX - r.left) / r.width) * dur);
        }}>
          {bars.map((h, i) => {
            const pct = dur ? pos / dur : 0;
            const lit = i / bars.length <= pct;
            return <div key={i} className={`scrub__bar ${lit ? 'on' : ''}`}
                        style={{ height: `${Math.max(4, h * 28)}px` }} />;
          })}
        </div>
        <div className="ab-time">
          <span>{mmss(pos)}</span>
          <span className="ab-time__sep">/</span>
          <span className="ab-time__total">{mmss(dur)}</span>
        </div>
      </div>

      <div className={`ab-status ${isReal ? 'ab-status--real' : (!isWet ? 'ab-status--raw' : 'ab-status--wet')}`}>
        <span className="ab-status__dot"/>
        {isReal ? 'REAL STEMS' : (!isWet ? 'RAW SIGNAL' : 'PROCESSED')}
      </div>
    </div>
  );
};

// ─── Sample tabs ────────────────────────────────────────────────────
const SampleTabs = ({ activeId, onSelect }) => (
  <div className="sample-tabs" role="tablist" aria-label="Select voice sample">
    <div className="sample-tabs__label">VOCAL</div>
    {MV_SAMPLES.map(s => (
      <button key={s.id}
              role="tab"
              aria-selected={activeId === s.id}
              aria-label={`Sample: ${s.label}`}
              className={`sample-tab ${activeId === s.id ? 'on' : ''}`}
              onClick={() => onSelect(s.id)}>
        {s.label}
      </button>
    ))}
  </div>
);

// ─── Preset chip strip ──────────────────────────────────────────────
const PresetChipStrip = ({ presets, activeId, activeSampleId, onChoose }) => (
  <div className="preset-strip" role="tablist" aria-label="Hero preset selector">
    <div className="preset-strip__label">PRESET</div>
    <div className="preset-strip__chips">
      {presets.map(p => {
        const isReal = p.real && p.real[activeSampleId];
        return (
          <button key={p.id}
                  role="tab"
                  aria-selected={activeId === p.id}
                  aria-label={`Preset: ${p.name}${isReal ? ' (real audio)' : ''}`}
                  className={`preset-chip ${activeId === p.id ? 'on' : ''}`}
                  style={{ '--chip-color': p.color }}
                  onClick={() => onChoose(p)}>
            <span className="preset-chip__dot"/>
            {p.name}
            {isReal && <span className="preset-chip__real">REAL</span>}
          </button>
        );
      })}
    </div>
  </div>
);

// ─── Preset tile (gallery section) ──────────────────────────────────
const PresetTile = ({ preset, isActive, isPlaying, activeSampleId, onClick }) => {
  const isReal = preset.real && preset.real[activeSampleId];
  return (
    <div className={`preset-tile ${isActive ? 'on' : ''} ${isReal ? 'preset-tile--real' : ''}`} onClick={onClick}>
      <div className="preset-tile__play">
        <svg width="10" height="10" viewBox="0 0 10 10">
          {isPlaying
            ? <g fill="#0a0820"><rect x="2" y="1" width="2.2" height="8"/><rect x="5.8" y="1" width="2.2" height="8"/></g>
            : <path d="M2 1 L9 5 L2 9 Z" fill="currentColor"/>}
        </svg>
      </div>
      {isReal && (
        <div className="preset-tile__badge"><span className="preset-tile__badge-dot"/> REAL A/B</div>
      )}
      <div className="preset-tile__genre">{preset.genre}</div>
      <div className="preset-tile__name">{preset.name}</div>
      <div className="preset-tile__mini">
        {Array.from({ length: 28 }, (_, i) => {
          const h = 4 + Math.abs(Math.sin(i * 0.6 + preset.id.length)) * 26;
          return <div key={i} className="preset-tile__bar"
                      style={{ height: h,
                               background: isActive ? preset.color : 'rgba(255,255,255,0.15)',
                               boxShadow: isActive ? `0 0 8px ${preset.color}` : 'none' }}/>;
        })}
      </div>
    </div>
  );
};

// ─── Effect solo card ───────────────────────────────────────────────
// Maps each effect key to the brand icon used in the plugin shell so
// each EffectStory card visually anchors to the same icon the visitor
// sees on the actual plugin above.
const EFFECT_ICON = {
  focus:   'target',
  fat:     'cat',
  doubler: 'user',
  reverb:  'reverb',
  delay:   'group',
  clarity: 'diamond',
  deess:   'deess',
  power:   'bars',
};

// Canonical fader position shown on each EffectStory card. Static —
// the cards are pure visual references for the audio stems, not
// interactive controls. 75% across the board, except DE-ESS which
// sits at its sweet-spot value (45%).
const EFFECT_DISPLAY_VALUE = {
  focus:   0.75,
  fat:     0.75,
  doubler: 0.75,
  reverb:  0.75,
  delay:   0.75,
  clarity: 0.75,
  deess:   0.45,
  power:   0.75,
};

const noop = () => {};

const EffectStory = ({ effect, activeEffect, audioMode, audioPlaying, onIsolate, onPlayDry, onPlayEffect, onTogglePlay, onExit }) => {
  const isActive = activeEffect === effect.key;
  const isDim = activeEffect != null && activeEffect !== effect.key;
  const isPlaying = isActive && audioPlaying;
  const displayValue = EFFECT_DISPLAY_VALUE[effect.key] ?? 0.75;
  const niceLabel = effect.label.charAt(0) + effect.label.slice(1).toLowerCase();
  const cardClass = `effect-card effect-card--with-control${isActive ? ' is-active' : ''}${isDim ? ' is-dim' : ''}${isPlaying ? ' is-playing' : ''}`;
  // Pre-compute meter bar styles. Static delays/durations create a
  // chaotic-but-cyclic pulse pattern that feels like real audio
  // metering without wiring an AnalyserNode for the marketing demo.
  const METER_BARS = 14;
  const meterBars = Array.from({ length: METER_BARS }, (_, i) => ({
    delay: `${(i * 71) % 700}ms`,
    duration: `${550 + (i * 53) % 380}ms`,
  }));
  return (
    <div className={cardClass} style={{ borderColor: isActive ? effect.color : undefined, boxShadow: isActive ? `0 0 0 1px ${effect.color}, 0 20px 48px -12px ${effect.color}55` : undefined }}>
      {isActive && (
        <button
          type="button"
          className="effect-card__close"
          onClick={onExit}
          aria-label="Stop preview and close"
          title="Stop preview (Esc)">
          ×
        </button>
      )}
      <div className="effect-card__head">
        <div className="effect-card__control-wrap">
          <Control
            label={niceLabel}
            icon={EFFECT_ICON[effect.key] || 'target'}
            value={displayValue}
            setValue={noop}
            color={effect.color}
            bypassed={false}
          />
        </div>
        <div className="effect-card__copy">
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div className="effect-card__dot" style={{ background: effect.color, color: effect.color }}/>
            <div className="effect-card__tag" style={{ color: effect.color }}>{effect.label}</div>
          </div>
          <div className="h3" style={{ fontSize: 22, marginTop: 8 }}>{effect.headline}</div>
        </div>
      </div>
      <div className="body" style={{ fontSize: 14, lineHeight: 1.55 }}>{effect.body}</div>
      {isActive ? (
        <div className={`effect-card__transport${audioMode === 'dry' ? ' is-dry' : ''}`} style={{ '--effect-color': effect.color }}>
          <div className="effect-card__transport-row">
            <button
              type="button"
              className="effect-card__play-btn"
              onClick={onTogglePlay}
              aria-label={audioPlaying ? 'Pause preview' : 'Play preview'}
              title={audioPlaying ? 'Pause' : 'Play'}>
              {audioPlaying ? (
                <svg width="11" height="11" viewBox="0 0 12 12"><rect x="2.4" y="1.6" width="2.6" height="8.8" fill="currentColor"/><rect x="7" y="1.6" width="2.6" height="8.8" fill="currentColor"/></svg>
              ) : (
                <svg width="11" height="11" viewBox="0 0 12 12"><path d="M2.6 1.4 L10.4 6 L2.6 10.6 Z" fill="currentColor"/></svg>
              )}
            </button>
            <div className="effect-card__meters" aria-hidden="true">
              {meterBars.map((b, i) => (
                <span key={i}
                      className="effect-card__meter-bar"
                      style={{ animationDelay: b.delay, animationDuration: b.duration }}/>
              ))}
            </div>
          </div>
          <div className="effect-card__bypass-toggle" role="tablist" aria-label="Bypass toggle">
            <button
              type="button"
              role="tab"
              className={`effect-card__bypass-btn ${audioMode === 'dry' ? 'on' : ''}`}
              aria-selected={audioMode === 'dry'}
              onClick={onPlayDry}>
              <span className="effect-card__bypass-letter">A</span>
              <span className="effect-card__bypass-label">DRY</span>
            </button>
            <button
              type="button"
              role="tab"
              className={`effect-card__bypass-btn ${audioMode === 'effect' ? 'on' : ''}`}
              aria-selected={audioMode === 'effect'}
              onClick={onPlayEffect}>
              <span className="effect-card__bypass-letter">B</span>
              <span className="effect-card__bypass-label">{effect.label}</span>
            </button>
          </div>
        </div>
      ) : (
        <div style={{ display: 'flex', gap: 10, marginTop: 'auto' }}>
          <button className="btn btn--sm"
                  style={{ background: 'rgba(255,255,255,0.06)', color: '#fff', border: '1px solid rgba(255,255,255,0.14)' }}
                  onClick={() => onIsolate(effect.key)}>
            Isolate {effect.label}  →
          </button>
        </div>
      )}
    </div>
  );
};

// ─── Playground (below-the-fold) ────────────────────────────────────
// Fully independent from the hero player: owns its own plugin state,
// its own preset cursor, and never touches the audio engine. Changing
// presets here only animates the faders — no playback, no sync with
// the hero mockup above.
const PlaygroundPlugin = ({ scale, initialPresetId }) => {
  const [tourOpen, setTourOpen] = _us(false);
  const ref = _ur(null);
  const startPreset = _um(
    () => MV_PRESETS.find(p => p.id === initialPresetId) || MV_PRESETS[0],
    [initialPresetId]
  );
  const [pgState, setPgState] = _us({ ...defaultPluginState, ...startPreset.state });
  const [pgPresetId, setPgPresetId] = _us(startPreset.id);
  const [bypass, setBypass] = _us(false);
  const pgPreset = MV_PRESETS.find(p => p.id === pgPresetId) || MV_PRESETS[0];

  const pgNudge = (dir) => {
    const idx = MV_PRESETS.findIndex(p => p.id === pgPresetId);
    const next = MV_PRESETS[(idx + dir + MV_PRESETS.length) % MV_PRESETS.length];
    setPgPresetId(next.id);
    setPgState({ ...defaultPluginState, ...next.state, solo: null, bypass: {} });
  };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 24 }}>
      <div ref={ref} style={{ position: 'relative', transform: `scale(${scale})`, transformOrigin: 'center top' }}>
        <PluginShell state={pgState} setState={setPgState}
                     preset={pgPreset.name}
                     onPresetNudge={pgNudge}
                     onPresetClick={() => { const el = document.getElementById('presets'); if (el) el.scrollIntoView({ behavior: 'smooth' }); }}
                     globalBypass={bypass}
                     isPlaying={false}
                     onGlobalBypass={() => setBypass(b => !b)}/>
        {tourOpen && <TourOverlay rootRef={ref} pluginState={pgState} onClose={() => setTourOpen(false)}/>}
      </div>
      <div style={{ display: 'flex', gap: 10 }}>
        <button onClick={() => setTourOpen(v => !v)}
                className="playground-tour-btn"
                aria-pressed={tourOpen}
                style={{
                  display: 'inline-flex', alignItems: 'center', gap: 14,
                  height: 64, padding: '0 28px',
                  borderRadius: 6,
                  border: `2px solid ${tourOpen ? '#a7a5ff' : 'rgba(167,165,255,0.55)'}`,
                  background: tourOpen ? '#a7a5ff' : 'rgba(167,165,255,0.10)',
                  color: tourOpen ? '#0a0820' : '#a7a5ff',
                  fontSize: 14, fontWeight: 900, letterSpacing: '.12em', textTransform: 'uppercase',
                  cursor: 'pointer', fontFamily: 'var(--font-main)',
                  boxShadow: tourOpen
                    ? '0 0 0 1px #a7a5ff, 0 0 36px rgba(167,165,255,.55), inset 0 1px 0 rgba(255,255,255,.15)'
                    : '0 0 24px rgba(167,165,255,.22), inset 0 1px 0 rgba(255,255,255,.06)',
                  transition: 'all .15s',
                }}>
          <span style={{
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            width: 34, height: 34, borderRadius: 4,
            background: tourOpen ? 'rgba(10,8,32,.16)' : 'rgba(167,165,255,.14)',
            border: `1.5px solid ${tourOpen ? 'rgba(10,8,32,.35)' : 'rgba(167,165,255,.55)'}`,
            fontSize: 17, fontWeight: 900, lineHeight: 1,
          }}>?</span>
          {tourOpen ? 'Close guided tour' : 'Start guided tour'}
        </button>
      </div>
    </div>
  );
};

// ─── Top Nav ────────────────────────────────────────────────────────
const TopNav = () => {
  const [open, setOpen] = _us(false);
  return (
    <div className={`nav ${open ? 'is-open' : ''}`}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <button
          type="button"
          className="nav-burger"
          onClick={() => setOpen(o => !o)}
          aria-label={open ? 'Close menu' : 'Open menu'}
          aria-expanded={open}>
          {open ? (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
          ) : (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="17" x2="20" y2="17"/></svg>
          )}
        </button>
        <div style={{ fontSize: 14, fontWeight: 900, letterSpacing: '.14em', color: '#fff' }}>
          MAGIC <span style={{ color: 'var(--iris)' }}>VOCALS</span>
        </div>
      </div>
      <div className="nav__links" onClick={() => setOpen(false)}>
        <a href="#try">Try it</a><a href="#presets">Presets</a><a href="#granular">Control</a><a href="#effects">Effects</a><a href="#chrys">About Chrys</a><a href="#faq">FAQ</a>
      </div>
      <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
        <button className="btn btn--gold btn--sm">Buy now — $19.99</button>
      </div>
    </div>
  );
};

// ─── App ────────────────────────────────────────────────────────────
const MagicVocalsApp = ({ tweakDefaults = {} }) => {
  const engine = useEngine();
  const [t, setTweak] = useTweaks(tweakDefaults);

  _ue(() => {
    const r = document.documentElement.style;
    if (t.accentIris) { r.setProperty('--iris', t.accentIris); r.setProperty('--primary', t.accentIris); }
    if (t.accentRose) r.setProperty('--rose', t.accentRose);
    if (t.accentGold) r.setProperty('--gold', t.accentGold);
  }, [t.accentIris, t.accentRose, t.accentGold]);

  const initialPreset = MV_PRESETS.find(p => p.id === t.defaultPresetId) || MV_PRESETS[0];
  const [pluginState, setPluginState] = _us({ ...defaultPluginState, ...initialPreset.state });
  const [activePresetId, setActivePresetId] = _us(initialPreset.id);
  const [activeSampleId, setActiveSampleId] = _us(MV_SAMPLES[0].id);
  const [browserCurrent, setBrowserCurrent] = _us('');
  const pluginRef = _ur(null);

  // ─── FX walkthrough audio state ────────────────────────────────────
  // activeEffect: which effect card is highlighted ('focus', 'fat', ...)
  //               or null when the section is at rest. While an effect is
  //               active, audioMode toggles between the isolated stem
  //               ({key}.mp3) and the dry stem (dry.mp3) — letting the
  //               visitor A/B that single FX against the original.
  // Audio files convention: live/audio/effects/{key}.mp3 + dry.mp3,
  // mp3 stereo 160 kbps CBR @ 44.1 kHz, normalized to -14 LUFS.
  // activeEffect: which card is highlighted. null = no card active.
  // audioMode:    which stem the active card is playing — 'effect' or
  //               'dry'. Persists across pause; toggling DRY/FX while
  //               paused queues the swap for the next play.
  // audioPlaying: whether the audio element is actually running. Decoupled
  //               from audioMode so pausing doesn't lose the FX/DRY
  //               selection, and toggling FX/DRY doesn't auto-resume.
  const [activeEffect, setActiveEffect] = _us(null);
  const [audioMode, setAudioMode] = _us('effect');
  const [audioPlaying, setAudioPlaying] = _us(false);
  const fxAudioRef = _ur(null);
  _ue(() => {
    const audio = fxAudioRef.current;
    if (!audio) return;
    if (activeEffect == null) {
      audio.pause();
      audio.removeAttribute('src');
      audio.load();
      return;
    }
    const file = audioMode === 'dry' ? 'dry.mp3' : `${activeEffect}.mp3`;
    const next = `live/audio/effects/${file}`;
    if (audio.getAttribute('src') !== next) {
      audio.src = next;
      audio.loop = true;
    }
    if (audioPlaying) {
      const p = audio.play();
      if (p && typeof p.catch === 'function') p.catch(() => {});
    } else {
      audio.pause();
    }
  }, [activeEffect, audioMode, audioPlaying]);
  const pauseHero = () => {
    if (engine && typeof engine.pause === 'function' && engine.isPlaying) engine.pause();
  };
  const fxIsolate = (key) => {
    pauseHero();
    setActiveEffect(key);
    setAudioMode('effect');
    setAudioPlaying(true);
  };
  const fxPlayDry = () => setAudioMode('dry');
  const fxPlayEffect = () => setAudioMode('effect');
  const fxTogglePlay = () => {
    setAudioPlaying(prev => {
      const next = !prev;
      if (next) pauseHero();
      return next;
    });
  };
  const fxExit = () => {
    setActiveEffect(null);
    setAudioPlaying(false);
    setAudioMode('effect');
  };
  // ESC exits FX isolation. Power-user shortcut on top of the visible
  // ✕ button on the active card.
  _ue(() => {
    if (activeEffect == null) return;
    const onKey = (e) => { if (e.key === 'Escape') fxExit(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [activeEffect]);
  // Click-outside also exits — any pointerdown that didn't land inside
  // an FX walkthrough card (.effect-card--with-control) closes the
  // preview. Bound at the document level via mousedown so it fires
  // before any inner click handlers; clicks inside the card bubble
  // through their own handlers normally because the closest() check
  // short-circuits.
  _ue(() => {
    if (activeEffect == null) return;
    const onDown = (e) => {
      const inside = e.target.closest && e.target.closest('.effect-card--with-control');
      if (!inside) fxExit();
    };
    window.addEventListener('mousedown', onDown);
    return () => window.removeEventListener('mousedown', onDown);
  }, [activeEffect]);

  const isRaw = !engine.isWet;
  const activePreset = MV_PRESETS.find(p => p.id === activePresetId) || MV_PRESETS[0];

  const choosePreset = (p) => {
    setActivePresetId(p.id);
    setPluginState({ ...defaultPluginState, ...p.state, solo: null, bypass: {} });
    // Only re-trigger playback if the A/B player is currently playing —
    // otherwise, just arm the new preset so the next Play uses it.
    engine.switchTo(activeSampleId, p);
  };

  const chooseSample = (sampleId) => {
    setActiveSampleId(sampleId);
    engine.switchTo(sampleId, activePreset);
  };

  const nudgePreset = (dir) => {
    const idx = MV_PRESETS.findIndex(p => p.id === activePresetId);
    const next = MV_PRESETS[(idx + dir + MV_PRESETS.length) % MV_PRESETS.length];
    choosePreset(next);
  };

  return (
    <div className="live">
      <TopNav />

      {/* HERO */}
      <section id="try" className="section hero" style={{ paddingTop: 56, paddingBottom: 56 }}>
        <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>
          <div className="glow-iris" style={{ position: 'absolute', top: -200, left: '50%', transform: 'translateX(-50%)', width: 1200, height: 800 }}/>
          <div className="glow-rose" style={{ position: 'absolute', bottom: -200, right: -200, width: 700, height: 700 }}/>
        </div>

        <div className="hero-head" style={{ position: 'relative' }}>
          <div className="h1" style={{ fontSize: 'clamp(40px, 11vw, 96px)', fontWeight: t.globalFontWeight || 900, marginTop: 10, lineHeight: 1.02, letterSpacing: '-0.04em' }}>
            {t.heroHeadline === 'studio' ? (
              <>The studio sound,<br/><span style={{ background: 'linear-gradient(90deg, #ff7ca8 0%, #a7a5ff 60%, #f5c518 120%)', WebkitBackgroundClip: 'text', color: 'transparent' }}>without the studio.</span></>
            ) : t.heroHeadline === 'finished' ? (
              <>Sing it once.<br/><span style={{ background: 'linear-gradient(90deg, #ff7ca8 0%, #a7a5ff 60%, #f5c518 120%)', WebkitBackgroundClip: 'text', color: 'transparent' }}>Leave it finished.</span></>
            ) : (
              <>Your voice,<br/>
              <span className="hero-gold">produced in</span> <span style={{ background: 'linear-gradient(90deg, #ff7ca8 0%, #a7a5ff 60%, #f5c518 120%)', WebkitBackgroundClip: 'text', color: 'transparent' }}>one click.</span></>
            )}
          </div>
          <div className="body-lg hero-sub" style={{ maxWidth: 720, margin: '26px auto 0', fontSize: 19, lineHeight: 1.55 }}>
            Magic Vocals is the vocal processing suite <b style={{ color: '#fff' }}>Chrys Gringo</b> built for <b style={{ color: '#fff' }}>artists and producers</b> who don't want to <span style={{ color: 'rgba(255,255,255,0.45)', textDecoration: 'line-through', textDecorationColor: 'rgba(255,124,168,0.55)', textDecorationThickness: '2px' }}>expend much time mixing</span> &mdash; they want to <b style={{ color: '#fff' }}>make music</b>, <b style={{ color: 'var(--gold)' }}>make money</b>, and <b style={{ color: '#fff' }}>sound finished, now</b>.
            <br/><br/>
            <span style={{ color: 'rgba(255,255,255,0.72)' }}>Press <b style={{ color: '#fff' }}>Play</b>, flip <b style={{ color: '#fff' }}>A/B</b>, and hear what your voice sounds like through it.</span>
          </div>
        </div>

        <div className="hero-stage" style={{ position: 'relative' }}>
          <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>

            <ABBar engine={engine} activeSampleId={activeSampleId} activePreset={activePreset}/>

            <div ref={pluginRef} className="mv-plugin-wrap" style={{ position: 'relative', transform: `scale(${t.pluginScale || 1})`, transformOrigin: 'center top' }}>
              <PluginShell state={pluginState} setState={setPluginState}
                           preset={activePreset.name}
                           onPresetNudge={nudgePreset}
                           onPresetClick={() => { const el = document.getElementById('presets'); if (el) el.scrollIntoView({ behavior: 'smooth' }); }}
                           globalBypass={isRaw}
                           hintPreset={engine.isPlaying}
                           hintBypass={engine.isPlaying}
                           isPlaying={engine.isPlaying}
                           locked={true}
                           onGlobalBypass={() => engine.setWet(!engine.isWet)}/>
              {/* Mobile-only static print of the plugin with the
                  current preset baked in. PNGs are real screenshots
                  of the desktop shell (one per preset), captured by
                  scripts/snap-preset-pngs.js using Playwright. Re-run
                  that script whenever the preset state changes. */}
              <img
                key={activePreset.id}
                className="mv-plugin-mobile-img"
                src={`live/img/presets/${activePreset.id}.png`}
                alt={`Magic Vocals plugin loaded with the ${activePreset.name} preset`}
                onError={(e) => { if (e.target.src.indexOf('plugin-hero.png') === -1) e.target.src = 'kv/plugin-hero.png'; }}
              />
            </div>

            <SampleTabs activeId={activeSampleId} onSelect={chooseSample}/>
            <PresetChipStrip presets={MV_PRESETS} activeId={activePresetId}
                             activeSampleId={activeSampleId} onChoose={choosePreset}/>
          </div>
        </div>
      </section>

      {/* PRESETS BROWSER (was: legacy 7-tile gallery → now the
          redesigned 58-preset browser, ported from the plugin). Lifted
          to position #1 after the hero per the conversion order in
          directives/17_magic_vocals_lp_reorg.md — "find your sound"
          is the strongest "this is for me" moment in the funnel. */}
      {t.showPresetsSection && (
      <section id="presets" className="section" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding }}>
        <div style={{ maxWidth: 1240, margin: '0 auto' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.2fr', gap: 80, alignItems: 'start', marginBottom: 48 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 18 }}>01 — Find your sound</div>
              <div className="h2">58 sounds, organized<br/>the way you actually search.</div>
            </div>
            <div className="body-lg" style={{ alignSelf: 'end' }}>
              Seven genre buckets — North America, Europe, Brazil, Latin, Global, plus Essentials and Character. Eleven mood tags that combine. Favorites and Recent always one click away. Try it.
            </div>
          </div>
          <PresetBrowser current={browserCurrent} onLoad={(name) => setBrowserCurrent(name)}/>
        </div>
      </section>
      )}

      {/* PLAYGROUND */}
      {t.showPlaygroundSection && (
      <section id="playground" className="section" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding, background: 'linear-gradient(180deg, transparent, rgba(167,165,255,0.03) 50%, transparent)' }}>
        <div style={{ maxWidth: 1240, margin: '0 auto' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.2fr', gap: 80, alignItems: 'start', marginBottom: 40 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 18 }}>02 — Drive it yourself</div>
              <div className="h2">Now grab the faders.</div>
            </div>
            <div className="body-lg" style={{ alignSelf: 'end' }}>
              This is a <b style={{ color: '#fff' }}>mockup of the plugin</b> — try the buttons and faders yourself. The icons are <b style={{ color: '#fff' }}>individual bypasses</b>; the faders glide smoothly and <b style={{ color: '#fff' }}>light up as you dial each effect in</b>, turning the tedious job of mixing into an artistic, auditory, sensorial process — <b style={{ color: 'var(--gold)' }}>simple and fun</b>. Play with the controls.
            </div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
            <PlaygroundPlugin scale={t.pluginScale || 1} initialPresetId={t.defaultPresetId}/>
          </div>
        </div>
      </section>
      )}

      {/* GRANULAR CONTROL — Auto Gain + icon bypass + zone bypass.
          Sits between Playground (drive the faders) and Effects (what
          each fader does) so the visitor learns the granular controls
          right after touching the plugin themselves. */}
      <section id="granular" className="section" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding }}>
        <div style={{ maxWidth: 1240, margin: '0 auto' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.2fr', gap: 80, alignItems: 'start', marginBottom: 56 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 18 }}>03 — Total control, on the rare day you need it</div>
              <div className="h2">One click for the preset.<br/>One more for everything else.</div>
            </div>
            <div className="body-lg" style={{ alignSelf: 'end' }}>
              The presets cover 90% of the moves. The other 10% — bypass an effect, kill a whole zone, or let <b style={{ color: '#fff' }}>Auto Gain</b> handle level-matching — sits one click away on the same plugin you just played with above.
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
            {/* Card 1 — AUTO GAIN */}
            <div className="effect-card effect-card--with-widget">
              <div className="effect-card__widget-frame">
                {/* The exact pill from the plugin's End Here zone, in 'on' state. */}
                <button type="button" className="mv-auto-toggle on" tabIndex="-1" aria-hidden="true">
                  <span className="mv-auto-led"/>
                  <span className="mv-auto-label">AUTO</span>
                </button>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div className="effect-card__dot" style={{ background: 'var(--iris)', color: 'var(--iris)' }}/>
                <div className="effect-card__tag" style={{ color: 'var(--iris)' }}>AUTO GAIN</div>
              </div>
              <div className="h3" style={{ fontSize: 22 }}>Match output to input,<br/>automatically.</div>
              <div className="body" style={{ fontSize: 14, lineHeight: 1.55 }}>
                The <b style={{ color: '#fff' }}>AUTO</b> pill below the Output knob keeps your processed level matched to the dry signal, so EQ and compression moves are heard as <i>shape</i>, not as <i>level</i>. Saves you from second-guessing every fader.
              </div>
              <div className="body" style={{ fontSize: 12, color: 'var(--ink-mute)', marginTop: 'auto' }}>
                End Here zone → AUTO pill below Output.
              </div>
            </div>

            {/* Card 2 — BYPASS PER FX */}
            <div className="effect-card effect-card--with-widget">
              <div className="effect-card__widget-frame effect-card__widget-frame--row">
                {/* Two states of the same icon: active (rose glow) and
                    bypassed (gray). Shows the user the affordance: tap
                    the icon, that effect goes from glowing to dim. */}
                <div className="mv-control-icon mv-control-icon--top" style={{
                  width: 38, height: 38,
                  color: 'color-mix(in srgb, #ff7ca8 80%, #8a8a9a)',
                  filter: 'saturate(160%) drop-shadow(0 0 6px rgba(255,124,168,0.55))'
                }}>
                  <Icon name="target"/>
                </div>
                <span className="mv-bypass-arrow" aria-hidden="true">→</span>
                <div className="mv-control-icon mv-control-icon--top" style={{
                  width: 38, height: 38,
                  color: '#4a4a52',
                  filter: 'none',
                  opacity: 0.85,
                }}>
                  <Icon name="target"/>
                </div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div className="effect-card__dot" style={{ background: 'var(--rose)', color: 'var(--rose)' }}/>
                <div className="effect-card__tag" style={{ color: 'var(--rose)' }}>BYPASS PER FX</div>
              </div>
              <div className="h3" style={{ fontSize: 22 }}>Click an icon,<br/>kill that effect.</div>
              <div className="body" style={{ fontSize: 14, lineHeight: 1.55 }}>
                Every effect's icon is a button. Tap it to bypass that single FX, tap again to bring it back. Useful for A/B-ing one element of the chain without unraveling the whole preset.
              </div>
              <div className="body" style={{ fontSize: 12, color: 'var(--ink-mute)', marginTop: 'auto' }}>
                Try it: tap a fader's icon on the playground above.
              </div>
            </div>

            {/* Card 3 — BYPASS PER ZONE */}
            <div className="effect-card effect-card--with-widget">
              <div className="effect-card__widget-frame">
                {/* The actual zone-head element pulled out of the plugin
                    so the visitor recognizes it from the shell above. */}
                <div className="mv-zone-head" style={{ marginBottom: 0, cursor: 'pointer' }}>
                  <div className="mv-zone-num">2</div>
                  <div className="mv-zone-title">Creative</div>
                </div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div className="effect-card__dot" style={{ background: 'var(--gold)', color: 'var(--gold)' }}/>
                <div className="effect-card__tag" style={{ color: 'var(--gold)' }}>BYPASS PER ZONE</div>
              </div>
              <div className="h3" style={{ fontSize: 22 }}>Click a zone label,<br/>silence the whole group.</div>
              <div className="body" style={{ fontSize: 14, lineHeight: 1.55 }}>
                Tap <b style={{ color: '#fff' }}>1 Start Here</b>, <b style={{ color: '#fff' }}>2 Creative</b>, or <b style={{ color: '#fff' }}>3 Clean Up</b> to bypass everything inside that zone in one click. Tap again to bring the whole group back.
              </div>
              <div className="body" style={{ fontSize: 12, color: 'var(--ink-mute)', marginTop: 'auto' }}>
                Try it: tap a zone label on the playground above.
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* EFFECTS STORY */}
      {t.showEffectsSection && (
      <section id="effects" className="section section--dim" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding }}>
        <div style={{ maxWidth: 1240, margin: '0 auto' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.2fr', gap: 80, alignItems: 'start', marginBottom: 80 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 18 }}>04 — What each fader does</div>
              <div className="h2">Seven effects.<br/>Dialed for voice, not for show.</div>
            </div>
            <div className="body-lg" style={{ alignSelf: 'end' }}>
              Every knob in Magic Vocals is doing a specific, musical job — voiced by Chrys across hundreds of sessions.
              Click <b>Isolate</b> on any effect below to hear it by itself, then bring the chain back.
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
            {MV_EFFECTS_STORY.map(ef => (
              <EffectStory key={ef.key} effect={ef}
                           activeEffect={activeEffect}
                           audioMode={audioMode}
                           audioPlaying={audioPlaying}
                           onIsolate={fxIsolate}
                           onPlayDry={fxPlayDry}
                           onPlayEffect={fxPlayEffect}
                           onTogglePlay={fxTogglePlay}
                           onExit={fxExit}/>
            ))}
          </div>
          <audio ref={fxAudioRef} preload="none" aria-hidden="true"/>
        </div>
      </section>
      )}

      {/* THE CREATOR */}
      {t.showChrysSection && (
      <section id="chrys" className="section section--dim creator-section" style={{ paddingTop: 0, paddingBottom: 0, padding: 0, position: 'relative', overflow: 'hidden' }}>
        <div className="creator-stage">
          {/* Background photo — subject on the right, preserved via object-position */}
          <img src="live/chrys-studio.jpg" alt="Chrys Gringo in his studio" className="creator-photo" style={{
            /* Driven by tweaks so the framing can be dialed live */
            ['--creator-photo-x' ]: (t.creatorPhotoX ?? 78) + '%',
            ['--creator-photo-y' ]: (t.creatorPhotoY ?? 18) + '%',
            ['--creator-photo-x-mobile']: (t.creatorPhotoXMobile ?? 66) + '%',
            ['--creator-photo-y-mobile']: (t.creatorPhotoYMobile ?? 14) + '%',
            ['--creator-photo-h-mobile']: (t.creatorPhotoHeightMobile ?? 460) + 'px',
          }}/>
          {/* Left-side dim + blur gradient so copy sits cleanly over dark area */}
          <div className="creator-scrim"/>
          <div className="creator-vignette"/>

          {/* Editorial content */}
          <div className="creator-grid">
            <div className="creator-copy">
              <div className="kicker" style={{ marginBottom: 22, color: 'var(--iris)' }}>05 — The Creator</div>

              <h2 className="creator-headline">
                Built by <span style={{ color: 'var(--iris)' }}>Chrys Gringo</span>.<br/>
                <span style={{ color: 'rgba(255,255,255,.6)', fontWeight: 300, fontStyle: 'italic' }}>The vocal chain I wish I had when I started.</span>
              </h2>

              <div className="creator-lede">
                Music producer, educator, plugin developer, and <b style={{ color: '#fff' }}>Full Sail University ambassador</b> —
                connected to one of the most respected names in audio and music production education —
                trusted by <b style={{ color: '#fff' }}>290k+ creators</b> learning how to make better music from
                home studios, not million-dollar rooms.
              </div>

              <div className="creator-badges">
                <div className="creator-badge">
                  <div className="creator-badge__num">290k+</div>
                  <div className="creator-badge__lbl">YouTube subscribers</div>
                </div>
                <div className="creator-badge">
                  <div className="creator-badge__num">20 yrs</div>
                  <div className="creator-badge__lbl">teaching audio</div>
                </div>
                <div className="creator-badge">
                  <div className="creator-badge__num">Full Sail</div>
                  <div className="creator-badge__lbl">Ambassador</div>
                </div>
              </div>

              {/* Pull quote — the emotional anchor */}
              <blockquote className="creator-quote">
                <div className="creator-quote__mark" aria-hidden>“</div>
                <div className="creator-quote__body">
                  After 20 years of teaching audio and music production, I built Magic Vocals for
                  <b style={{ color: '#fff' }}> the version of me</b> who was just trying to make songs sound finished —
                  without getting lost in EQ curves, compression ratios, expensive gear, or plugins I couldn't afford.
                  <br/><br/>
                  I didn't want another complicated tool. <span style={{ color: 'var(--iris)' }}>I just wanted the mix to feel done</span> —
                  and the vocals to sound <b style={{ color: '#fff' }}>clean, full, present, and ready to release.</b>
                </div>
                <div className="creator-quote__cite">— Chrys Gringo</div>
              </blockquote>

              {/* Closing paragraph — what he built */}
              <div className="creator-outro">
                After years of helping creators fix vocals that sounded <span className="creator-strike">too raw, too processed, too thin, or buried in the mix</span>,
                Chrys built Magic Vocals to make the process simple:
                <ol className="creator-steps">
                  <li><span className="creator-steps__n">1</span>Choose your <b style={{ color: '#fff' }}>Voice Type</b>.</li>
                  <li><span className="creator-steps__n">2</span>Pick a <b style={{ color: '#fff' }}>style</b>.</li>
                  <li><span className="creator-steps__n">3</span>Shape the sound <b style={{ color: '#fff' }}>by ear</b>.</li>
                </ol>
                <div style={{ marginTop: 18, fontSize: 15, color: 'rgba(255,255,255,.7)' }}>
                  No confusing ratios. No endless tutorial rabbit holes. No subscription trap.
                  Just an <b style={{ color: 'var(--gold)' }}>affordable vocal chain</b> you
                  <b style={{ color: '#fff' }}> buy once</b> for a fair price, <b style={{ color: '#fff' }}>own forever</b>,
                  and use whenever your vocal needs to <b style={{ color: '#fff' }}>feel finished.</b>
                </div>
              </div>
            </div>
          </div>
        </div>

        <style dangerouslySetInnerHTML={{__html: `
          .creator-section { min-height: 860px; display: flex; }
          .creator-stage {
            position: relative; width: 100%;
            min-height: 860px;
            display: flex;
          }
          .creator-photo {
            position: absolute; inset: 0;
            width: 100%; height: 100%;
            object-fit: cover;
            object-position: var(--creator-photo-x, 78%) var(--creator-photo-y, 18%);
            z-index: 0;
          }
          /* Left-side dark gradient + blur to host the text */
          .creator-scrim {
            position: absolute; inset: 0; z-index: 1;
            background: linear-gradient(
              90deg,
              rgba(6,6,14,.97) 0%,
              rgba(6,6,14,.94) 38%,
              rgba(6,6,14,.78) 52%,
              rgba(6,6,14,.4) 66%,
              rgba(6,6,14,.0) 82%
            );
            backdrop-filter: blur(0);
          }
          /* Soft vignette to sink the studio slightly behind the subject */
          .creator-vignette {
            position: absolute; inset: 0; z-index: 2; pointer-events: none;
            background:
              radial-gradient(ellipse 60% 80% at 78% 48%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,.35) 100%),
              linear-gradient(180deg, rgba(6,6,14,.3) 0%, rgba(6,6,14,0) 20%, rgba(6,6,14,0) 75%, rgba(6,6,14,.55) 100%);
          }
          .creator-grid {
            position: relative; z-index: 3;
            max-width: 1320px; margin: 0 auto;
            padding: 140px 60px;
            display: grid;
            grid-template-columns: minmax(0, 600px) 1fr;
            width: 100%;
          }
          .creator-copy { max-width: 600px; }

          .creator-headline {
            font-size: 64px; line-height: 1.02; font-weight: 900;
            letter-spacing: -0.025em; margin: 0 0 26px;
            color: #fff;
            text-wrap: balance;
          }
          .creator-lede {
            font-size: 18px; line-height: 1.55;
            color: rgba(255,255,255,.82);
            max-width: 520px; margin-bottom: 28px;
          }

          .creator-badges {
            display: flex; gap: 14px; margin-bottom: 40px; flex-wrap: wrap;
          }
          .creator-badge {
            padding: 12px 16px;
            background: rgba(167,165,255,.08);
            border: 1px solid rgba(167,165,255,.25);
            border-radius: 8px;
            backdrop-filter: blur(6px);
          }
          .creator-badge__num {
            font-size: 18px; font-weight: 900; color: #fff;
            letter-spacing: -0.01em; line-height: 1;
          }
          .creator-badge__lbl {
            font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
            color: var(--iris); margin-top: 6px;
          }

          .creator-quote {
            position: relative;
            padding: 26px 26px 22px 56px;
            margin: 0 0 36px;
            background: linear-gradient(180deg, rgba(167,165,255,.05), rgba(167,165,255,.02));
            border: 1px solid rgba(167,165,255,.18);
            border-left: 3px solid var(--iris);
            border-radius: 10px;
            backdrop-filter: blur(8px);
          }
          .creator-quote__mark {
            position: absolute;
            left: 16px; top: 2px;
            font-size: 72px; font-weight: 900;
            color: var(--iris); opacity: .55;
            line-height: 1; font-family: Georgia, serif;
          }
          .creator-quote__body {
            font-size: 17px; line-height: 1.6;
            color: rgba(255,255,255,.88);
            font-weight: 400;
          }
          .creator-quote__cite {
            margin-top: 16px;
            font-size: 11px; font-weight: 800; letter-spacing: .18em;
            color: var(--iris); text-transform: uppercase;
          }

          .creator-outro {
            font-size: 16px; line-height: 1.6;
            color: rgba(255,255,255,.78);
          }
          .creator-strike {
            color: rgba(255,255,255,.45);
            text-decoration: line-through;
            text-decoration-color: rgba(255,124,168,.55);
            text-decoration-thickness: 2px;
          }
          .creator-steps {
            list-style: none; padding: 0; margin: 20px 0 0;
            display: flex; flex-direction: column; gap: 10px;
          }
          .creator-steps li {
            display: flex; align-items: center; gap: 14px;
            font-size: 16px; color: rgba(255,255,255,.82);
            padding: 10px 14px;
            background: rgba(255,255,255,.03);
            border: 1px solid rgba(255,255,255,.06);
            border-radius: 6px;
          }
          .creator-steps__n {
            display: inline-flex; align-items: center; justify-content: center;
            width: 28px; height: 28px; border-radius: 4px;
            background: rgba(167,165,255,.15);
            border: 1px solid rgba(167,165,255,.35);
            color: var(--iris);
            font-size: 12px; font-weight: 900; letter-spacing: .04em;
            flex-shrink: 0;
          }

          /* Tablet — keep face visible, widen scrim */
          @media (max-width: 1100px) {
            .creator-grid { padding: 100px 40px; grid-template-columns: 1fr; }
            .creator-headline { font-size: 52px; }
            .creator-photo { object-position: calc(var(--creator-photo-x, 78%) - 3%) calc(var(--creator-photo-y, 18%) + 2%); }
            .creator-scrim {
              background: linear-gradient(
                90deg,
                rgba(6,6,14,.96) 0%,
                rgba(6,6,14,.9) 45%,
                rgba(6,6,14,.6) 65%,
                rgba(6,6,14,.2) 85%,
                rgba(6,6,14,.0) 100%
              );
            }
          }

          /* Mobile — stacked: photo on top framed on face, copy below with breathing room */
          @media (max-width: 720px) {
            .creator-section { min-height: 0; }
            .creator-stage {
              min-height: 0;
              display: flex; flex-direction: column;
            }
            .creator-photo {
              position: relative;
              height: var(--creator-photo-h-mobile, 460px);
              object-position: var(--creator-photo-x-mobile, 66%) var(--creator-photo-y-mobile, 14%);
            }
            .creator-scrim {
              position: absolute; inset: auto 0 0 0; height: var(--creator-photo-h-mobile, 460px); top: 0;
              background: linear-gradient(180deg, rgba(6,6,14,0) 58%, rgba(6,6,14,.98) 100%);
            }
            .creator-vignette { display: none; }
            .creator-grid {
              padding: 32px 24px 90px;
              margin-top: -40px;
            }
            .creator-copy { max-width: 100%; }
            .creator-headline { font-size: 38px; }
            .creator-lede { font-size: 16px; }
            .creator-quote { padding: 22px 20px 18px 44px; }
            .creator-quote__mark { font-size: 56px; left: 12px; }
            .creator-quote__body { font-size: 15px; }
          }
        `}}/>
      </section>
      )}

      {/* FINAL CTA */}
      <section className="section" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding, textAlign: 'center', position: 'relative', overflow: 'hidden' }}>
        <div className="glow-iris" style={{ position: 'absolute', inset: 0 }}/>
        <div style={{ position: 'relative', maxWidth: 820, margin: '0 auto' }}>
          <div className="kicker" style={{ marginBottom: 22 }}>Final step</div>
          <div className="h1" style={{ fontSize: 'clamp(36px, 10vw, 88px)', marginBottom: 28, lineHeight: 1.04, letterSpacing: '-0.03em' }}>
            Stop fighting your vocal.<br/><span style={{ color: 'var(--iris)' }}>Start releasing it.</span>
          </div>
          <div className="body-lg" style={{ marginBottom: 40, maxWidth: 560, margin: '0 auto 40px' }}>
            VST3 / AU / AAX. Installs alongside your DAW in under a minute. Buy once, own forever.
          </div>
          <div style={{ display: 'flex', gap: 20, justifyContent: 'center', alignItems: 'center', flexWrap: 'wrap' }}>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
                <span style={{ fontSize: 18, color: 'rgba(255,255,255,.45)', textDecoration: 'line-through', fontWeight: 600 }}>$24.99</span>
                <span style={{ fontSize: 11, fontWeight: 800, letterSpacing: '.14em', color: 'var(--gold)', textTransform: 'uppercase' }}>Launch price</span>
              </div>
              <button className="btn btn--gold btn--lg">Buy now — $19.99</button>
            </div>
          </div>
          <div className="body-sm" style={{ marginTop: 22, fontSize: 12, color: 'var(--ink-mute)' }}>
            Mac & Windows · VST3 · AU · AAX · Stand-alone · Works with Pro Tools, Logic, Ableton, FL Studio, Cubase, Reaper, Studio One.
          </div>
        </div>
      </section>

      {/* FAQ */}
      {t.showFAQSection && (
      <section id="faq" className="section section--dim" style={{ paddingTop: t.sectionPadding, paddingBottom: t.sectionPadding }}>
        <div style={{ maxWidth: 1080, margin: '0 auto' }}>
          <div className="kicker" style={{ marginBottom: 18 }}>06 — Questions</div>
          <div className="h2" style={{ marginBottom: 48 }}>Everything you're about to ask.</div>
          {[
            ['Is this actually the plugin, or a mockup?', 'The interface you drive above is the real Magic Vocals UI, ported to the browser. The processing here is a faithful simulation — the real plugin runs the tuned DSP Chrys designed in your DAW.'],
            ['Do I need to know how to mix?', 'No. Pick a preset that matches the song, hit play, move on. If you want to ride faders later, they\'re all there with the same labels your favorite producer uses.'],
            ['Which DAWs does it work in?', 'Every major one. VST3 on Windows/Mac, AU on Mac, AAX for Pro Tools. Stand-alone mode too — open it, plug in a mic, sing.'],
            ['Will it replace my whole vocal chain?', 'For 90% of vocal moves, yes. If you\'re chasing a very specific sound with a specific chain, keep that chain — drop Magic Vocals on the bus for the last 10%.'],
            ['Can I get a refund?', '14-day no-questions refund. If it\'s not for you, write in and you\'re out — no guilt.'],
            ['What does the price include?', 'Lifetime license on up to 3 of your own machines, all future updates within the major version, priority email support, and access to the Magic Plugins community.'],
            ['System requirements (macOS / Windows / formats)', <SysReqs key="sysreqs"/>],
          ].map(([q, a], i) => <FaqRow key={i} q={q} a={a}/>)}
        </div>
      </section>
      )}

      {/* Footer */}
      <footer className="footer">
        <div className="footer__grid" style={{ maxWidth: 1240, margin: '0 auto' }}>
          <div>
            <div style={{ fontSize: 20, fontWeight: 900, letterSpacing: '.14em', color: '#fff', marginBottom: 14 }}>
              MAGIC <span style={{ color: 'var(--iris)' }}>VOCALS</span>
            </div>
            <div className="body-sm" style={{ fontSize: 13, maxWidth: 300 }}>
              By <b style={{ color: '#fff' }}>Gringo Audio</b> — a Chrys Gringo project. Made in the USA.
              <br/><br/>
              <b style={{ color: 'rgba(255,255,255,.75)' }}>Clear Note LLC</b> · Florida — USA
            </div>
          </div>
          {[['Plugin',['Buy now — $19.99','System requirements','Manual (PDF)']],['Learn',['Preset walkthroughs','Produtor Pro course','YouTube tutorials','Blog']],['Support',['Help center','Contact','Community','Refund policy']],['Chrys',['Instagram','YouTube','Spotify','Press kit']]].map(([h,links]) => (
            <div key={h} className="footer__col">
              <div className="footer__heading">{h}</div>
              {links.map(l => <a key={l}>{l}</a>)}
            </div>
          ))}
        </div>
        <div style={{ maxWidth: 1240, margin: '32px auto 0', paddingTop: 24, borderTop: '1px solid rgba(255,255,255,0.06)', display: 'flex', flexWrap: 'wrap', gap: 20, fontSize: 12, color: 'var(--ink-mute)', lineHeight: 1.6 }}>
          <div style={{ flex: '1 1 100%', fontSize: 12, color: 'rgba(255,255,255,.55)' }}>
            <b style={{ color: 'rgba(255,255,255,.8)', letterSpacing: '.08em', textTransform: 'uppercase', fontSize: 11 }}>System Requirements</b> · macOS 11+ (Apple Silicon + Intel), Windows 10 1809+ / Windows 11 (64-bit). Hosts VST3 / AU / AAX. Under 2 % CPU on M1 Max @ buffer 256.
          </div>
        </div>
        <div style={{ maxWidth: 1240, margin: '20px auto 0', paddingTop: 20, borderTop: '1px solid rgba(255,255,255,0.06)', display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12, fontSize: 12, color: 'var(--ink-mute)' }}>
          <div>&copy; 2025 Clear Note LLC · Gringo Audio. All rights reserved.</div>
          <div style={{ display: 'flex', gap: 24 }}><span>Privacy</span><span>Terms</span><span>Cookies</span></div>
        </div>
      </footer>

      <TweaksPanel title="Magic Vocals — Tweaks">
        <TweakSection label="Plugin"/>
        <TweakSlider label="Plugin scale" value={t.pluginScale} min={0.6} max={1.3} step={0.05} onChange={(v) => setTweak('pluginScale', v)}/>
        <TweakSelect label="Default preset" value={t.defaultPresetId} options={MV_PRESETS.map(p => ({ value: p.id, label: p.name }))}
                     onChange={(v) => { setTweak('defaultPresetId', v); const p = MV_PRESETS.find(x => x.id === v); if (p) choosePreset(p); }}/>
        <TweakToggle label="Start bypassed" value={!!t.startBypassed} onChange={(v) => { setTweak('startBypassed', v); engine.setWet(!v); }}/>
        <TweakSection label="Hero"/>
        <TweakRadio label="Headline variant" value={t.heroHeadline} options={[{value:'one-click',label:'One click'},{value:'studio',label:'Studio sound'},{value:'finished',label:'Sing once'}]} onChange={(v) => setTweak('heroHeadline', v)}/>
        <TweakSlider label="Headline weight" value={t.globalFontWeight} min={600} max={900} step={100} onChange={(v) => setTweak('globalFontWeight', v)}/>
        <TweakSection label="Sections"/>
        <TweakToggle label="Playground + tour" value={!!t.showPlaygroundSection} onChange={(v) => setTweak('showPlaygroundSection', v)}/>
        <TweakToggle label="Effects story" value={!!t.showEffectsSection} onChange={(v) => setTweak('showEffectsSection', v)}/>
        <TweakToggle label="Preset gallery" value={!!t.showPresetsSection} onChange={(v) => setTweak('showPresetsSection', v)}/>
        <TweakToggle label="About Chrys" value={!!t.showChrysSection} onChange={(v) => setTweak('showChrysSection', v)}/>
        <TweakSection label="Creator photo framing"/>
        <TweakSlider label="Desktop X (right ← →)" value={t.creatorPhotoX ?? 78} min={0} max={100} step={1} unit="%" onChange={(v) => setTweak('creatorPhotoX', v)}/>
        <TweakSlider label="Desktop Y (up ↑ ↓)" value={t.creatorPhotoY ?? 18} min={0} max={100} step={1} unit="%" onChange={(v) => setTweak('creatorPhotoY', v)}/>
        <TweakSlider label="Mobile X" value={t.creatorPhotoXMobile ?? 66} min={0} max={100} step={1} unit="%" onChange={(v) => setTweak('creatorPhotoXMobile', v)}/>
        <TweakSlider label="Mobile Y" value={t.creatorPhotoYMobile ?? 14} min={0} max={100} step={1} unit="%" onChange={(v) => setTweak('creatorPhotoYMobile', v)}/>
        <TweakSlider label="Mobile photo height" value={t.creatorPhotoHeightMobile ?? 460} min={320} max={640} step={10} unit="px" onChange={(v) => setTweak('creatorPhotoHeightMobile', v)}/>
        <TweakToggle label="FAQ" value={!!t.showFAQSection} onChange={(v) => setTweak('showFAQSection', v)}/>
        <TweakSlider label="Section padding" value={t.sectionPadding} min={60} max={180} step={10} unit="px" onChange={(v) => setTweak('sectionPadding', v)}/>
        <TweakSection label="Palette"/>
        <TweakColor label="Iris (primary)" value={t.accentIris} onChange={(v) => setTweak('accentIris', v)}/>
        <TweakColor label="Rose" value={t.accentRose} onChange={(v) => setTweak('accentRose', v)}/>
        <TweakColor label="Gold" value={t.accentGold} onChange={(v) => setTweak('accentGold', v)}/>
      </TweaksPanel>
    </div>
  );
};

const SysReqs = () => {
  const col = { flex: '1 1 240px', minWidth: 0 };
  const heading = { fontSize: 11, fontWeight: 800, letterSpacing: '.14em', textTransform: 'uppercase', color: 'var(--iris)', marginBottom: 10 };
  const list = { margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 6, fontSize: 14, color: 'rgba(255,255,255,.78)', lineHeight: 1.5 };
  const dot = { display: 'inline-block', width: 4, height: 4, borderRadius: 50, background: 'var(--iris)', marginRight: 10, verticalAlign: 'middle', opacity: .6 };
  const Bullet = ({ children }) => <li><span style={dot}/>{children}</li>;
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 28, marginTop: 14, padding: 20, background: 'rgba(167,165,255,.04)', border: '1px solid rgba(167,165,255,.12)', borderRadius: 10 }}>
      <div style={col}>
        <div style={heading}>macOS</div>
        <ul style={list}>
          <Bullet>macOS 11 (Big Sur) or later</Bullet>
          <Bullet>Apple Silicon (M1–M4) or Intel 64-bit · universal binary</Bullet>
          <Bullet>4 GB RAM</Bullet>
          <Bullet>100 MB free disk space</Bullet>
          <Bullet>Host supporting VST3, AU, or AAX</Bullet>
        </ul>
      </div>
      <div style={col}>
        <div style={heading}>Windows</div>
        <ul style={list}>
          <Bullet>Windows 10 64-bit (1809+) or Windows 11</Bullet>
          <Bullet>Intel or AMD 64-bit CPU</Bullet>
          <Bullet>4 GB RAM · 100 MB free disk space</Bullet>
          <Bullet>Microsoft Edge WebView2 Runtime — pre-installed on Win 11; installed automatically on Win 10 if missing (needs internet on first install)</Bullet>
          <Bullet>Host supporting VST3 or AAX</Bullet>
        </ul>
      </div>
      <div style={col}>
        <div style={heading}>Plug-in formats</div>
        <ul style={list}>
          <Bullet>VST3 (64-bit) — macOS, Windows</Bullet>
          <Bullet>Audio Unit (64-bit) — macOS</Bullet>
          <Bullet>AAX Native (64-bit) — Pro Tools 2022.7 or later</Bullet>
        </ul>
      </div>
      <div style={col}>
        <div style={heading}>Audio</div>
        <ul style={list}>
          <Bullet>Sample rates: 44.1 kHz – 192 kHz</Bullet>
          <Bullet>32-bit float internal processing</Bullet>
          <Bullet>Any buffer size supported by the host</Bullet>
        </ul>
      </div>
      <div style={{ flex: '1 1 100%', paddingTop: 16, borderTop: '1px solid rgba(255,255,255,.06)' }}>
        <div style={heading}>CPU footprint</div>
        <ul style={list}>
          <Bullet>Under <b style={{ color: '#fff' }}>2% CPU</b> on an Apple M1 Max @ 48 kHz / 256-sample buffer</Bullet>
          <Bullet>GUI scales linearly (VST3 only) — runs comfortably on any modern 64-bit CPU</Bullet>
        </ul>
        <div style={{ marginTop: 14, fontSize: 12, color: 'rgba(255,255,255,.5)', fontStyle: 'italic' }}>
          Magic Vocals by <b style={{ color: 'rgba(255,255,255,.8)', fontStyle: 'normal' }}>Gringo Audio</b> — a Chrys Gringo project. Made in the USA.
        </div>
      </div>
    </div>
  );
};

const FaqRow = ({ q, a }) => {
  const [open, setOpen] = _us(false);
  return (
    <div className="faq-row" onClick={() => setOpen(o => !o)}>
      <div style={{ display: 'flex', alignItems: 'start', gap: 18 }}>
        <div style={{ width: 28, height: 28, borderRadius: 50, border: '1px solid rgba(255,255,255,0.2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2, transform: open ? 'rotate(45deg)' : 'none', transition: 'transform .2s' }}>
          <svg width="12" height="12" viewBox="0 0 12 12"><line x1="6" y1="1" x2="6" y2="11" stroke="currentColor" strokeWidth="1.5"/><line x1="1" y1="6" x2="11" y2="6" stroke="currentColor" strokeWidth="1.5"/></svg>
        </div>
        <div className="h4">{q}</div>
      </div>
      <div className="body" style={{ opacity: open ? 1 : 0.55, transition: 'opacity .2s' }}>{a}</div>
    </div>
  );
};

Object.assign(window, { MagicVocalsApp });
