const { Button } = window.MyxotoneDesignSystem_60a319;

// Convierte filas de una hoja de Google Sheets (vía mx-content.js) en el
// shape que cada sección necesita. Mientras no llega nada del sheet (o si no
// se configuró ninguna URL) se usa `fallback`, así el sitio siempre se ve bien.
function useMxContent(section, mapRow, fallback) {
  const [rows, setRows] = React.useState(() => window.MxContent && window.MxContent.get(section));
  React.useEffect(() => {
    if (!window.MxContent) return;
    setRows(window.MxContent.get(section));
    return window.MxContent.subscribe(section, setRows);
  }, [section]);
  return React.useMemo(() => rows && rows.length ? rows.map(mapRow) : fallback, [rows]);
}

function slug(s, i) {
  const withoutAccents = (s || '').toString().normalize('NFD').split('').filter((ch) => {
    const code = ch.codePointAt(0);
    return code < 0x300 || code > 0x36f;
  }).join('');
  const base = withoutAccents.
  toLowerCase().
  replace(/[^a-z0-9]+/g, '-').
  replace(/(^-|-$)/g, '');
  return base || 'item-' + i;
}

function MxIcon({ k, s = 14 }) {
  const P = {
    play: <path d="M8 5.5v13l11-6.5z" fill="currentColor" />,
    pause: <g fill="currentColor"><rect x="7" y="5" width="3.4" height="14" rx="1"></rect><rect x="13.6" y="5" width="3.4" height="14" rx="1"></rect></g>,
    prev: <g fill="currentColor"><rect x="5" y="5" width="2.4" height="14" rx="1"></rect><path d="M19 5.5v13L9.5 12z" /></g>,
    next: <g fill="currentColor"><rect x="16.6" y="5" width="2.4" height="14" rx="1"></rect><path d="M5 5.5v13L14.5 12z" /></g>,
    vol: <g><path d="M11 5 6.5 8.5H3v7h3.5L11 19V5z" fill="currentColor" /><path d="M15.5 8.7a5 5 0 0 1 0 6.6" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /></g>,
    mute: <g><path d="M11 5 6.5 8.5H3v7h3.5L11 19V5z" fill="currentColor" /><path d="m15 9.5 5 5M20 9.5l-5 5" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /></g>
  };
  return <svg width={s} height={s} viewBox="0 0 24 24" aria-hidden="true">{P[k]}</svg>;
}

function MxNav() {
  const [scrolled, setScrolled] = React.useState(false);
  const [active, setActive] = React.useState('');
  React.useEffect(() => {
    const on = () => setScrolled(window.scrollY > 40);
    on();window.addEventListener('scroll', on, { passive: true });
    const ids = ['lanzamientos', 'proceso', 'sistema', 'servicios', 'proyectos', 'contacto'];
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => {if (e.isIntersecting) setActive('#' + e.target.id);});
    }, { rootMargin: '-30% 0px -55% 0px' });
    ids.forEach((id) => {const el = document.getElementById(id);if (el) io.observe(el);});
    return () => {window.removeEventListener('scroll', on);io.disconnect();};
  }, []);
  const links = [['Lanzamientos', '#lanzamientos'], ['Proceso', '#proceso'], ['Sistema', '#sistema'], ['Servicios', '#servicios'], ['Proyectos', '#proyectos'], ['Contacto', '#contacto']];
  return (
    <header className={'mx-nav' + (scrolled ? ' scrolled' : '')}>
      <div className="wrap">
        <div className="nav-inner">
          <a href="#inicio" style={{ display: 'flex', alignItems: 'center' }}><img src="assets/logo/mxtn-wordmark-white.png" alt="MXTN" style={{ height: 26, width: 'auto', display: 'block', position: 'relative', top: 2 }} /></a>
          <nav className="nav-links">{links.map(([l, h]) => <a key={l} href={h} className={active === h ? 'on' : ''}>{l}</a>)}</nav>
          <button className="nav-cta" onClick={() => window.mxQuizOpen()}>Agenda una llamada</button>
        </div>
      </div>
    </header>);

}

function Hero() {
  return (
    <section className="hero hero-center" id="inicio" data-screen-label="Hero">
      <div className="hero-bg">
        
        <div className="hero-veil"></div>
      </div>
      <div className="wrap" style={{ width: '100%', position: 'relative' }}>
        <div>
          <p className="eyebrow" data-rv>Productora musical</p>
          <div className="brandmark" data-rv data-rv-delay="60">
            <span className="hero-word">Myxotone</span>
          </div>
          <h1 data-rv data-rv-delay="140">Tu música.<br />Tu identidad.<br />Tu visión.</h1>
          <p className="hero-sub" data-rv data-rv-delay="200">Transformamos ideas en proyectos musicales con intención, tecnología y un proceso creativo diseñado para artistas que buscan construir algo memorable.</p>
          <div className="hero-cta" data-rv data-rv-delay="260">
            <Button variant="primary" size="md" onClick={() => window.mxQuizOpen()}>Agenda ahora</Button>
            <span className="microcopy">30 min · Sin compromiso · Propuesta personalizada</span>
          </div>
        </div>
      </div>
      <div className="scroll-hint">Scroll</div>
    </section>);

}

const TRUST_NAMES_DEFAULT = ['Corps', 'Gems', 'Marionne'];

function Trust() {
  const names = useMxContent('trust', (r) => r.nombre, TRUST_NAMES_DEFAULT);
  const outerRef = React.useRef(null);
  const trackRef = React.useRef(null);
  const [reps, setReps] = React.useState(4);
  React.useEffect(() => {
    const outer = outerRef.current,track = trackRef.current;
    if (!outer || !track) return;
    // El marquee funciona duplicando un set y desplazándolo -50%. Si el set
    // no es más ancho que el contenedor, al llegar al final del ciclo se
    // queda sin contenido y el loop "salta". Por eso el número de
    // repeticiones se calcula según el ancho real de pantalla.
    const fit = () => {
      const setWidth = track.scrollWidth / 2;
      const containerWidth = outer.getBoundingClientRect().width;
      if (setWidth < containerWidth * 1.4) {
        const perName = setWidth / (names.length * reps);
        const needed = Math.ceil(containerWidth * 1.6 / (perName * names.length));
        setReps((r) => Math.max(r + 1, needed));
      }
    };
    fit();
    window.addEventListener('resize', fit);
    return () => window.removeEventListener('resize', fit);
  }, [reps, names]);
  const set = Array.from({ length: reps }, () => names).flat();
  const items = set.concat(set);
  return (
    <div className="trust" ref={outerRef} data-screen-label="Han confiado">
      <p className="label eyebrow">Han confiado en nosotros</p>
      <div className="mq" ref={trackRef}>{items.map((n, i) => <span key={i}>{n}</span>)}</div>
    </div>);

}

function PlayerBar({ title, artist, coverId, showVolume = true, showLinks = false, className = '' }) {
  const DUR = 214;
  const [playing, setPlaying] = React.useState(false);
  const [t, setT] = React.useState(38);
  const [vol, setVol] = React.useState(72);
  const [menu, setMenu] = React.useState(false);
  React.useEffect(() => {
    if (!menu) return;
    const close = () => setMenu(false);
    window.addEventListener('click', close);
    return () => window.removeEventListener('click', close);
  }, [menu]);
  React.useEffect(() => {
    if (!playing) return;
    const iv = setInterval(() => setT((v) => (v + 1) % DUR), 1000);
    return () => clearInterval(iv);
  }, [playing]);
  React.useEffect(() => {setT(0);setPlaying(false);}, [title]);
  const fmt = (s) => Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0');
  const seek = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    setT(Math.round(DUR * Math.min(1, Math.max(0, (e.clientX - r.left) / r.width))));
  };
  const setVolume = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    setVol(Math.round(100 * Math.min(1, Math.max(0, (e.clientX - r.left) / r.width))));
  };
  return (
    <div className={'player ' + className}>
      <div className="pcover"><image-slot id={coverId} shape="rect" placeholder="Portada"></image-slot></div>
      <div className="pmeta"><div className="pt">{title}</div><div className="pa">{artist}</div></div>
      <div className="pbtns">
        <button aria-label="Anterior" onClick={() => setT((v) => Math.max(0, v - 15))}><MxIcon k="prev" /></button>
        <button className="pplay" aria-label={playing ? 'Pausa' : 'Play'} onClick={() => setPlaying(!playing)}><MxIcon k={playing ? 'pause' : 'play'} s={16} /></button>
        <button aria-label="Siguiente" onClick={() => setT((v) => Math.min(DUR, v + 15))}><MxIcon k="next" /></button>
      </div>
      <div className="ptrack">
        <span className="ptime">{fmt(t)}</span>
        <div className="pbar" style={{ '--p': t / DUR * 100 + '%' }} onClick={seek}><i></i></div>
        <span className="ptime">{fmt(DUR)}</span>
      </div>
      {showVolume && <div className="pvol"><span style={{ color: 'var(--gray-2)', display: 'flex' }}><MxIcon k={vol === 0 ? 'mute' : 'vol'} /></span><div className="pbar" style={{ '--p': vol + '%' }} onClick={setVolume}><i></i></div></div>}
      {showLinks && <div className="pmore">
        <button aria-label="Más opciones" onClick={(e) => {e.stopPropagation();setMenu(!menu);}}>⋯</button>
        {menu && <div className="pmenu mxtn-glass">
          <a href="https://www.youtube.com/@Myxotone" target="_blank" rel="noopener">YouTube</a>
          <a href="https://www.instagram.com/myxotone/" target="_blank" rel="noopener">Instagram</a>
          <a href="https://www.tiktok.com/@myxotone" target="_blank" rel="noopener">TikTok</a>
        </div>}
      </div>}
    </div>);

}

const LANZAMIENTOS_DEFAULT = [
{ id: 'rel-1', t: 'Dónde Estás', a: 'Gems', src: 'assets/audio/donde-estas.mp3' },
{ id: 'rel-2', t: 'Inercia', a: 'Corps' },
{ id: 'rel-3', t: 'Apágame', a: 'Marionne', src: 'assets/audio/apagame.mp3' },
{ id: 'rel-4', t: 'Huellas de tu Aroma', a: 'Gems', src: 'assets/audio/master.mp3' },
{ id: 'rel-5', t: 'El Jardín', a: 'Corps', src: 'assets/audio/el-jardin.mp3' },
{ id: 'rel-6', t: 'The Drift', a: 'Marionne', src: 'assets/audio/the-drift.mp3' },
{ id: 'rel-7', t: 'Eco', a: 'Corps' },
{ id: 'rel-8', t: 'Sur', a: 'Corps', src: 'assets/audio/sur.mp3' }];


// El audio de cada lanzamiento se administra desde el código, no desde el
// Sheet: el Sheet solo controla título, artista y portada. Para dar audio a
// un track hay que agregar su mp3 a assets/audio/ y una entrada aquí.
const LANZAMIENTOS_AUDIO_BY_ID = Object.fromEntries(
  LANZAMIENTOS_DEFAULT.filter((it) => it.src).map((it) => [it.id, it.src])
);

function mapLanzamiento(r, i) {
  const id = slug(r.id || r.titulo, i);
  return {
    id,
    t: r.titulo || '',
    a: r.artista || '',
    src: LANZAMIENTOS_AUDIO_BY_ID[id],
    cover: r.portada ? window.MxContent.driveUrl(r.portada) : undefined
  };
}

function Lanzamientos() {
  const items = useMxContent('lanzamientos', mapLanzamiento, LANZAMIENTOS_DEFAULT);
  const [on, setOn] = React.useState(() => Math.min(3, items.length - 1));
  React.useEffect(() => {if (on > items.length - 1) setOn(Math.max(0, items.length - 1));}, [items]);
  const [playing, setPlaying] = React.useState(false);
  const [vol, setVol] = React.useState(.9);
  const [H, setH] = React.useState(400);
  const aRef = React.useRef(null);
  React.useEffect(() => {if (aRef.current) aRef.current.volume = vol;}, [vol]);
  React.useEffect(() => {
    const h = (e) => {if (e.detail !== 'lanzamientos' && aRef.current) {aRef.current.pause();setPlaying(false);}};
    window.addEventListener('mx-audio', h);
    return () => window.removeEventListener('mx-audio', h);
  }, []);
  const claim = () => window.dispatchEvent(new CustomEvent('mx-audio', { detail: 'lanzamientos' }));
  React.useEffect(() => {
    const upd = () => setH(Math.round(Math.min(window.innerHeight * .52, window.innerWidth * .8, 470)));
    upd();window.addEventListener('resize', upd);
    return () => window.removeEventListener('resize', upd);
  }, []);
  const choose = (i) => {
    setOn(i);
    const a = aRef.current,it = items[i];
    if (!a) return;
    if (it.src) {
      if (!a.src.endsWith(it.src)) a.src = it.src;
      claim();
      a.play().then(() => setPlaying(true)).catch(() => setPlaying(false));
    } else {a.pause();setPlaying(false);}
  };
  const toggle = () => {
    const a = aRef.current,it = items[on];
    if (!a || !it.src) return;
    if (playing) {a.pause();setPlaying(false);} else
    {if (!a.src.endsWith(it.src)) a.src = it.src;claim();a.play().then(() => setPlaying(true)).catch(() => {});}
  };
  const GAP = 8,LABEL = 118;
  const w = (i) => {const d = Math.abs(i - on);return d === 0 ? H : Math.round(H * Math.min(.96, .5 + .16 * d));};
  const ang = (i) => {const d = i - on;if (d === 0) return 0;const k = Math.min(.96, .5 + .16 * Math.abs(d));return (d < 0 ? 1 : -1) * Math.acos(k) * 180 / Math.PI;};
  React.useEffect(() => {
    const sync = () => {
      document.querySelectorAll('#lanzamientos .f2-box').forEach((box) => {
        const slot = box.querySelector('image-slot');
        const img = slot && slot.shadowRoot && slot.shadowRoot.querySelector('.frame img');
        const src = img && img.getAttribute('src');
        if (src && box.__cov !== src) {box.__cov = src;box.style.setProperty('--cov', 'url("' + src + '")');}
      });
    };
    sync();
    const t = setInterval(sync, 1200);
    return () => clearInterval(t);
  }, []);
  const off = items.slice(0, on).reduce((a2, _, i) => a2 + w(i) + GAP, 0) + w(on) / 2;
  const cur = items[on] || items[0] || { t: '', a: '' };
  const swRef = React.useRef(null);
  const onTS = (e) => {swRef.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };};
  const onTE = (e) => {
    const s = swRef.current;if (!s) return;swRef.current = null;
    const dx = e.changedTouches[0].clientX - s.x,dy = e.changedTouches[0].clientY - s.y;
    if (Math.abs(dx) > 42 && Math.abs(dx) > Math.abs(dy) * 1.4) choose(dx < 0 ? Math.min(items.length - 1, on + 1) : Math.max(0, on - 1));
  };
  return (
    <section id="lanzamientos" data-screen-label="Lanzamientos" style={{ paddingBottom: 0 }}>
      <audio ref={aRef} preload="none" onEnded={() => setPlaying(false)}></audio>
      <div className="wrap">
        <div className="sec-head" data-rv>
          <p className="eyebrow">Lanzamientos</p>
          <h2>Escucha lo mejor <span className="it">del trabajo</span> de Myxotone.</h2>
        </div>
      </div>
      <div className="flow2" data-rv data-rv-delay="120" style={{ height: H + LABEL }} onTouchStart={onTS} onTouchEnd={onTE}>
        <div className="f2-track" style={{ transform: 'translateX(' + -off + 'px)' }}>
          {items.map((it, i) => {
            const d = i - on;
            const ad = Math.abs(d);
            const fade = d === 0 ? 0 : Math.min(.8, .22 + .13 * ad);
            const dir = d < 0 ? '90deg' : '270deg';
            return (
              <div key={it.id} className={'f2-item' + (d === 0 ? ' on' : '')} style={{ width: w(i) }} onClick={() => choose(i)} role="button" aria-pressed={d === 0} aria-label={it.t}>
                <div className="f2-label" style={{ opacity: d === 0 ? 1 : Math.max(.45, 1 - .1 * ad), maxWidth: w(i) - 6 }}>
                  <div className="t">{it.t}</div>
                  <div className="a">{it.a}</div>
                  {d !== 0 && <span className="f2-go"><MxIcon k="play" s={9} /></span>}
                </div>
                <div className="f2-stage" style={{ width: H, height: H }}>
                  <div className="f2-box" style={{ transform: 'rotateY(' + ang(i) + 'deg)', filter: 'brightness(' + (d === 0 ? 1.1 : Math.max(.7, 1 - .08 * ad)).toFixed(2) + ')' }}>
                    <div className="f2-edge"></div>
                    <div className="f2-edge r"></div>
                    <div className="f2-edge top"></div>
                    <div className="f2-edge bot"></div>
                    <div className="f2-face front">
                      <image-slot id={it.id} src={it.cover} shape="rect" placeholder={'Portada — ' + it.t}></image-slot>
                      <div className="f2-fade" style={{ background: 'linear-gradient(' + dir + ',transparent 38%,rgba(8,9,10,' + fade + '))' }}></div>
                    </div>
                    <div className="f2-face back"></div>
                  </div>
                </div>
              </div>);
          })}
        </div>
        <div className="f2-cap">
          <span className="f2-ic"><img src="assets/logo/mxtn-icon-white.png" alt="" /></span>
          <div><div className="big">Lanzamientos</div><div className="sm">Curated by Myxotone</div></div>
        </div>
        <div className="f2-ctl">
          <button aria-label="Anterior" onClick={() => choose((on + items.length - 1) % items.length)}><MxIcon k="prev" /></button>
          <button className="pp" aria-label={playing ? 'Pausa' : 'Play'} onClick={toggle}><MxIcon k={playing ? 'pause' : 'play'} s={15} /></button>
          <button aria-label="Siguiente" onClick={() => choose((on + 1) % items.length)}><MxIcon k="next" /></button>
          <span className="vol">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M11 5 6.5 8.5H3v7h3.5L11 19V5z"></path><path d="M15.5 8.7a5 5 0 0 1 0 6.6"></path><path d="M18.4 6a9 9 0 0 1 0 12"></path></svg>
            <input type="range" className="f2-vol" min="0" max="1" step="0.01" value={vol} onChange={(e) => setVol(+e.target.value)} aria-label="Volumen" />
          </span>
        </div>
        <div className="f2-np">
          <div><div className="sm">Now Playing</div><div className="t">{cur.t} · {cur.a}</div></div>
          <span className="f2-vinyl" style={{ animationPlayState: playing ? 'running' : 'paused' }}></span>
        </div>
      </div>
    </section>);

}

const PROBLEMA_DEFAULT = {
  tituloNormal: 'Muchos artistas producen canciones.',
  tituloEnfasis: 'Muy pocos construyen proyectos.',
  cuerpo: 'Hoy producir música es más accesible que nunca. Lo difícil ya no es terminar una canción. Lo difícil es tomar cientos de decisiones creativas que construyan una identidad coherente desde la composición hasta el master.',
  cuerpoDestacado: 'Ahí es donde entra Myxotone.',
  pistaTitulo: 'Huellas de tu Aroma',
  pistaArtista: 'Gems',
  portada: undefined,
  audioAntes: 'assets/audio/demo.mp3',
  audioDespues: 'assets/audio/master.mp3'
};

function mapProblema(r) {
  return {
    tituloNormal: r.titulo_normal || PROBLEMA_DEFAULT.tituloNormal,
    tituloEnfasis: r.titulo_enfasis || PROBLEMA_DEFAULT.tituloEnfasis,
    cuerpo: r.cuerpo || PROBLEMA_DEFAULT.cuerpo,
    cuerpoDestacado: r.cuerpo_destacado || PROBLEMA_DEFAULT.cuerpoDestacado,
    pistaTitulo: r.pista_titulo || PROBLEMA_DEFAULT.pistaTitulo,
    pistaArtista: r.pista_artista || PROBLEMA_DEFAULT.pistaArtista,
    portada: r.portada ? window.MxContent.driveUrl(r.portada) : undefined,
    // Los audios del comparador (antes/después) se administran desde el
    // código, no desde el Sheet.
    audioAntes: PROBLEMA_DEFAULT.audioAntes,
    audioDespues: PROBLEMA_DEFAULT.audioDespues
  };
}

function Problema() {
  const content = useMxContent('problema', mapProblema, [PROBLEMA_DEFAULT])[0];
  const [v, setV] = React.useState(98);
  const [playing, setPlaying] = React.useState(false);
  const [t, setT] = React.useState(0);
  const [dur, setDur] = React.useState(0);
  const [vol, setVol] = React.useState(80);
  const dRef = React.useRef(null),mRef = React.useRef(null);
  const k = v / 100;
  React.useEffect(() => {
    const d = dRef.current;if (!d) return;
    const upd = () => {if (isFinite(d.duration) && d.duration > 0) setDur(d.duration);};
    upd();
    d.addEventListener('loadedmetadata', upd);d.addEventListener('durationchange', upd);d.addEventListener('canplay', upd);
    return () => {d.removeEventListener('loadedmetadata', upd);d.removeEventListener('durationchange', upd);d.removeEventListener('canplay', upd);};
  }, []);
  React.useEffect(() => {
    const d = dRef.current,m = mRef.current;if (!d || !m) return;
    const g = vol / 100;
    d.volume = Math.sin(k * Math.PI / 2) * g;
    m.volume = Math.cos(k * Math.PI / 2) * g;
  }, [v, vol]);
  React.useEffect(() => {
    const h = (e) => {if (e.detail !== 'problema') {dRef.current && dRef.current.pause();mRef.current && mRef.current.pause();setPlaying(false);}};
    window.addEventListener('mx-audio', h);
    return () => window.removeEventListener('mx-audio', h);
  }, []);
  const toggle = () => {
    const d = dRef.current,m = mRef.current;if (!d || !m) return;
    if (playing) {d.pause();m.pause();setPlaying(false);} else
    {window.dispatchEvent(new CustomEvent('mx-audio', { detail: 'problema' }));m.currentTime = d.currentTime;Promise.all([d.play(), m.play()]).then(() => setPlaying(true)).catch(() => {});}
  };
  const seekTo = (s) => {
    const d = dRef.current,m = mRef.current;if (!d || !m) return;
    const max = isFinite(dur) && dur > 0 ? dur : isFinite(d.duration) && d.duration > 0 ? d.duration : 0;
    if (!max) return;
    if (!(isFinite(dur) && dur > 0)) setDur(max);
    const c = Math.max(0, Math.min(max, s));
    d.currentTime = c;m.currentTime = c;setT(c);
  };
  const fmt = (s) => !isFinite(s) || s < 0 ? '0:00' : Math.floor(s / 60) + ':' + String(Math.floor(s % 60)).padStart(2, '0');
  const seekBar = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const d = dRef.current;
    const max = isFinite(dur) && dur > 0 ? dur : d && isFinite(d.duration) && d.duration > 0 ? d.duration : 0;
    if (max) seekTo(max * Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)));
  };
  const volBar = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    setVol(Math.round(100 * Math.min(1, Math.max(0, (e.clientX - r.left) / r.width))));
  };
  const bars = React.useMemo(() => Array.from({ length: 46 }, (_, i) => {
    const demo = 8 + 26 * Math.abs(Math.sin(i * 1.7)) * (i % 4 === 0 ? 1 : .3);
    const master = 18 + 74 * (0.5 + 0.5 * Math.sin(i * .55 + 1)) * (0.65 + 0.35 * Math.sin(i * 2.3));
    return [demo, master];
  }), []);
  return (
    <section className="problema" id="problema" data-screen-label="El problema">
      <audio ref={dRef} src={content.audioAntes} preload="auto" onTimeUpdate={(e) => setT(e.currentTarget.currentTime)} onLoadedMetadata={(e) => {const d = e.currentTarget.duration;if (isFinite(d)) setDur(d);}} onDurationChange={(e) => {const d = e.currentTarget.duration;if (isFinite(d)) setDur(d);}} onEnded={() => {mRef.current && mRef.current.pause();setPlaying(false);}}></audio>
      <audio ref={mRef} src={content.audioDespues} preload="auto"></audio>
      <div className="wrap">
        <p className="eyebrow" data-rv>El problema</p>
        <h2 className="statement" style={{ marginTop: 22 }} data-rv data-rv-delay="80">{content.tituloNormal} <span className="dim">{content.tituloEnfasis}</span></h2>
        <p className="body" data-rv data-rv-delay="160">{content.cuerpo} <strong>{content.cuerpoDestacado}</strong></p>
        <div className="compare" style={{ '--cut': v + '%' }} data-rv data-rv-delay="220">
          <div className="pane">
            <div className="layer"><div className="sketch-disc"></div></div>
            <div className="layer done"><div className="vinyl" style={{ width: 'min(46vw,280px)', aspectRatio: 1 }}></div></div>
            <span className="tag l">De idea</span><span className="tag r">A lanzamiento</span>
            <div className="divider"></div>
            <input type="range" min="2" max="98" value={v} onChange={(e) => setV(+e.target.value)} aria-label="Mezcla entre demo y master" />
          </div>
          <div className="wave-label"><span className={k >= .5 ? 'on' : ''}>Voicenote · demo</span><span className={k < .5 ? 'on' : ''}>Master final</span></div>
          <div className="waves">{bars.map(([d, m], i) => <i key={i} style={{ '--h': m + (d - m) * k + '%', '--wc': k < .5 ? 'var(--accent-hover)' : 'var(--gray-3)' }}></i>)}</div>
        </div>
        <div className="compare-player" data-rv data-rv-delay="280" style={{ maxWidth: 860, margin: '18px auto 0' }}>
          <div className="player">
            <div className="pcover"><image-slot id="compare-track" src={content.portada} shape="rect" placeholder="Portada"></image-slot></div>
            <div className="pmeta"><div className="pt">{content.pistaTitulo}</div><div className="pa">{k < .5 ? 'Master final' : 'Demo'} · {content.pistaArtista}</div></div>
            <div className="pbtns">
              <button aria-label="Atrás 15s" onClick={() => seekTo(t - 15)}><MxIcon k="prev" /></button>
              <button className="pplay" aria-label={playing ? 'Pausa' : 'Play'} onClick={toggle}><MxIcon k={playing ? 'pause' : 'play'} s={16} /></button>
              <button aria-label="Adelante 15s" onClick={() => seekTo(t + 15)}><MxIcon k="next" /></button>
            </div>
            <div className="ptrack">
              <span className="ptime">{fmt(t)}</span>
              <div className="pbar" style={{ '--p': (isFinite(dur) && dur > 0 ? Math.min(100, t / dur * 100) : 0) + '%' }} onClick={seekBar}><i></i></div>
              <span className="ptime">{fmt(dur)}</span>
            </div>
            <div className="pvol"><span style={{ color: 'var(--gray-2)', display: 'flex' }}><MxIcon k={vol === 0 ? 'mute' : 'vol'} /></span><div className="pbar" style={{ '--p': vol + '%' }} onClick={volBar}><i></i></div></div>
          </div>
        </div>
        <div style={{ marginTop: 56 }} data-rv><Button variant="secondary" size="md" onClick={() => window.mxQuizOpen()}>Agenda una llamada de descubrimiento</Button></div>
      </div>
    </section>);

}

Object.assign(window, { MxNav, Hero, Trust, Lanzamientos, Problema, PlayerBar, MxIcon, useMxContent, slug });