/* ═══════════════════════════════════════════════════════════
   POCKET JOY — Proposta de Branding e Identidade Visual
   Estrutura: Proposta Geral Anebi · Identidade: Pocket Joy DS
═══════════════════════════════════════════════════════════ */
const { useState, useEffect, useRef } = React;

/* ---------- Ícones (inline SVG, stroke 1.5, cantos redondos) ---------- */
const I = {
  Check: (p) => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="20 6 9 17 4 12" /></svg>,
  Plus: (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg>,
  Calendar: (p) => <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="4" width="18" height="18" rx="3" /><line x1="16" y1="2" x2="16" y2="6" /><line x1="8" y1="2" x2="8" y2="6" /><line x1="3" y1="10" x2="21" y2="10" /></svg>,
  Layers: (p) => <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 2 3 7l9 5 9-5-9-5z" /><path d="M3 17l9 5 9-5" /><path d="M3 12l9 5 9-5" /></svg>,
  Whatsapp: (p) => <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M.057 24l1.687-6.163c-1.041-1.804-1.588-3.849-1.587-5.946.003-6.556 5.338-11.891 11.893-11.891 3.181.001 6.167 1.24 8.413 3.488 2.245 2.248 3.481 5.236 3.48 8.414-.003 6.557-5.338 11.892-11.893 11.892-1.99-.001-3.951-.5-5.688-1.448l-6.305 1.654zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884-.001 2.225.651 3.891 1.746 5.634l-.999 3.648 3.742-.981zm11.387-5.464c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.768.967-.941 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.095 3.2 5.076 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413z" /></svg>,
  Card: (p) => <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="5" width="20" height="14" rx="3" /><line x1="2" y1="10" x2="22" y2="10" /><line x1="6" y1="15" x2="10" y2="15" /></svg>,
  Pix: (p) => <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12L12 3l9 9-9 9-9-9z" /><path d="M8 12L12 8l4 4-4 4-4-4z" /></svg>,
  Handshake: (p) => <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="9.5" /><path d="M8 12.2l2.6 2.6L16 9.4" /></svg>,
  Instagram: (p) => <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {...p}><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" /></svg>,
  Youtube: (p) => <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {...p}><path d="M23.495 6.205a3.007 3.007 0 0 0-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 0 0 .527 6.205a31.247 31.247 0 0 0-.522 5.805 31.247 31.247 0 0 0 .522 5.783 3.007 3.007 0 0 0 2.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 0 0 2.088-2.088 31.247 31.247 0 0 0 .5-5.783 31.247 31.247 0 0 0-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /></svg>,
  Linkedin: (p) => <svg width="17" height="17" fill="currentColor" viewBox="0 0 24 24" {...p}><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" /></svg>,
  Mail: (p) => <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="4" width="20" height="16" rx="3" /><path d="m2 7 10 6 10-6" /></svg>
};

/* ---------- Ícones de processo (64×64, stroke 1.5) ---------- */
const ProcessIcon = {
  strategy: () =>
    <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="32" cy="32" r="20" className="ring-a" />
      <circle cx="32" cy="32" r="12" className="ring-b" />
      <circle cx="32" cy="32" r="3.5" fill="currentColor" stroke="none" />
      <line x1="32" y1="6" x2="32" y2="12" /><line x1="32" y1="52" x2="32" y2="58" />
      <line x1="6" y1="32" x2="12" y2="32" /><line x1="52" y1="32" x2="58" y2="32" />
    </svg>,
  design: () =>
    <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="8" y="12" width="48" height="34" rx="4" />
      <line x1="26" y1="54" x2="38" y2="54" /><line x1="32" y1="46" x2="32" y2="54" />
      <line x1="18" y1="24" x2="42" y2="24" className="typeline-1" />
      <line x1="18" y1="31" x2="34" y2="31" className="typeline-2" />
      <line x1="18" y1="38" x2="28" y2="38" className="typeline-3" />
    </svg>,
  delivery: () =>
    <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M32 8 L50 26 L42 26 L42 46 L22 46 L22 26 L14 26 Z" className="icon-arrow" />
      <line x1="16" y1="54" x2="48" y2="54" />
    </svg>
};

/* ---------- Dados ---------- */
const OPTIONS = [
  {
    id: 'branding',
    tag: 'Para quem quer construir uma marca com mais estratégia',
    accent: '#8B00FF',
    name: 'Branding',
    nameEm: 'Completo',
    tagline: 'Ideal para estúdios e produtos que precisam de uma identidade mais profunda, com direção visual, posicionamento e um sistema completo de aplicação.',
    priceKey: 'price1',
    duration: 'Sob consulta',
    scope: '10 entregas',
    includes: [
      'Estudo estratégico da marca',
      'Direcionamento de posicionamento',
      'Definição de público e personalidade da marca',
      'Criação completa da identidade visual',
      'Logo principal e variações',
      'Paleta de cores e tipografia',
      'Elementos gráficos de apoio e padrões',
      'Kit digital: avatar, banner, overlay e assinatura',
      'Modelos para redes sociais e páginas de loja',
      'Manual da marca com organização e direcionamento']
  },
  {
    id: 'essencial',
    tag: 'Para quem quer uma marca mais completa',
    accent: '#6366f1',
    featured: true,
    badge: 'Mais escolhido',
    name: 'Identidade',
    nameEm: 'Essencial',
    tagline: 'Ideal para quem precisa de uma identidade visual com mais possibilidades de uso no digital e nos materiais da marca.',
    priceKey: 'price2',
    duration: '7 dias úteis',
    scope: '7 entregas',
    includes: [
      'Logo exclusivo + 1 variação',
      'Definição de cores',
      'Definição de fontes',
      'Kit de perfil: avatar e banner',
      'Assinatura de email',
      'Cartão de visita digital',
      '1 modelo de post + 5 destaques para Instagram']
  },
  {
    id: 'inicial',
    tag: 'Para quem precisa começar do jeito certo',
    accent: '#00C2FF',
    name: 'Logo',
    nameEm: 'Inicial',
    tagline: 'Ideal para projetos que precisam de uma apresentação visual básica, organizada e profissional para entrar no mercado.',
    priceKey: 'price3',
    duration: '3 dias úteis',
    scope: '4 entregas',
    includes: [
      'Logotipo exclusivo',
      'Definição de cores',
      'Definição de fontes',
      'Avatar e banner para redes']
  }];

const PROCESS = [
  {
    n: '01',
    label: 'estratégia',
    icon: 'strategy',
    title: 'Imersão &\nEstratégia',
    desc: 'Mergulhamos no universo do seu produto para extrair sua essência técnica. Mapeamos os pontos de contato e as dores do usuário para traçar um mapa que guia o design do conceito até a execução final.'
  },
  {
    n: '02',
    label: 'design',
    icon: 'design',
    title: 'Design &\nExperiência Visual',
    desc: 'Construímos a identidade sob o prisma da imersão. Testamos a marca em aplicação real, no perfil, na loja e na interface, para garantir que ela funcione tão bem no ícone de 32px quanto no letreiro da tela inicial.'
  },
  {
    n: '03',
    label: 'entrega',
    icon: 'delivery',
    title: 'Finalização\n& Entrega',
    desc: 'O encerramento do ciclo criativo com foco em resultados reais. Entregamos sistemas visuais escaláveis e arquivos organizados para garantir que a sua marca funcione em qualquer dispositivo ou plataforma.'
  }];

const PORTFOLIO = [
  { src: 'assets/portfolio/1.webp' },
  { src: 'assets/portfolio/2.webp' },
  { src: 'assets/portfolio/3.webp' },
  { src: 'assets/portfolio/4.webp' },
  { src: 'assets/portfolio/5.webp' },
  { src: 'assets/portfolio/6.webp' },
  { src: 'assets/portfolio/7.webp' },
  { src: 'assets/portfolio/8.webp' },
  { src: 'assets/portfolio/9.webp' },
  { src: 'assets/portfolio/10.webp' },
  { src: 'assets/portfolio/11.webp' },
  { src: 'assets/portfolio/12.webp' },
  { src: 'assets/portfolio/13.webp' },
  { src: 'assets/portfolio/14.webp' },
  { src: 'assets/portfolio/15.webp' }
];

const TESTIMONIALS = [
  {
    quote: 'Que trabalho magnífico!!! Caprichoso e cheio de atenção aos detalhes. Você é muito dedicado em seus projetos e ficou perfeito!',
    name: 'Fabi Passos', role: 'Anebi Studio', photo: 'assets/depoimentos/fabi-passos.png'
  },
  {
    quote: 'A excelência na execução desse projeto é muito boa. Não é apenas um design bonito, é um sistema muito bem construído. O resultado ficou top!!!',
    name: 'Jeova Raycker', role: 'Vero Agência e Produtora', photo: 'assets/depoimentos/jeova-raycker.png'
  },
  {
    quote: 'Como pode você ser o melhor designer gráfico do país e querer desenvolver os meus projetos, que sorte que tenho. Gostei bastante de tudo!!!',
    name: 'Narayan Silva', role: 'Miragem Games', photo: 'assets/depoimentos/narayan-silva.jpg'
  }
];

const FAQ = [
  { q: 'Como começa o projeto após a aprovação?', a: 'Após a aprovação da proposta, você recebe um briefing (formulário) para preencher as informações do seu projeto, junto com o contrato. Com a confirmação do pagamento da entrada, damos início. E claro: se surgir qualquer dúvida nesse processo, podemos agendar uma call para te orientar com calma. Essas informações são importantes para que a criação aconteça de forma alinhada.' },
  { q: 'Quantas rodadas de ajustes estão incluídas?', a: 'Cada projeto inclui rodadas de ajustes dentro do escopo combinado em cada etapa. Os ajustes são feitos sobre as direções aprovadas, sempre dentro do conceito estratégico definido no início.' },
  { q: 'Em quais formatos os arquivos finais são entregues?', a: 'Você recebe os arquivos em SVG, PDF, EPS, PNG com fundo transparente e JPG, organizados em uma pasta única. Isso garante que sua marca esteja pronta para qualquer aplicação: engine, loja, redes sociais, impressão ou interface.' },
  { q: 'Posso parcelar o investimento?', a: 'Sim. Trabalhamos com 50% na assinatura do contrato e 50% na entrega final. Também aceitamos parcelamento no cartão (consulte condições) e Pix com desconto à vista.' },
  { q: 'E se eu já tiver um logotipo? Qual opção é a melhor?', a: 'Se sua marca já existe, desenvolvemos um projeto personalizado para entender o que já funciona, o que faz sentido manter e o que precisa evoluir. A partir desse estudo, direcionamos a melhor construção visual e estratégica para o próximo momento da marca.' },
  { q: 'O que acontece depois da entrega final?', a: 'Você fica com todos os arquivos e o Manual da Marca para usar com qualquer profissional ou equipe. Se quiser, podemos seguir com a interface do jogo, o HUD, o site ou a presença digital da marca. Falamos sobre isso na reunião final.' }];

/* ---------- FX ambiente (fog + grid + sparks + beams) ---------- */
const Ambient = ({ sparks = [], beams = [], variant = '' }) =>
  <div className={`ambient ${variant}`} aria-hidden="true">
    <div className="ambient-fog"></div>
    <div className="bg-sparks">
      {sparks.map((s, i) => <span key={i} className="bg-spark" style={{ top: s[0], left: s[1], animationDelay: s[2] }} />)}
    </div>
    <div className="bg-beams">
      {beams.map((b, i) => <span key={i} className="bg-beam" style={{ left: b[0], animationDelay: b[1], animationDuration: b[2] }} />)}
    </div>
  </div>;

/* ---------- Navbar ---------- */
const Navbar = ({ scrolled }) => {
  const [open, setOpen] = useState(false);
  const links = [
    ['#sobre', 'Sobre'], ['#portfolio', 'Portfólio'], ['#processo', 'Processo'],
    ['#opcoes', 'Investimento'], ['#depoimentos', 'Clientes']
  ];
  return (
    <header className={`navbar ${scrolled ? 'scrolled' : ''}`}>
      <div className="nav-shell">
      <div className="nav-inner">
        <a href="#top" className="brand-logo" data-cursor="Topo">
          <img src="assets/Pocket-Joy.png" alt="Pocket Joy" className="nav-logo" width="131" height="28" />
        </a>
        <nav className="nav-pill">
          {links.map(([href, label]) => <a key={href} href={href}>{label}</a>)}
        </nav>
        <a href="#contato" className="nav-cta" data-magnetic data-cursor="Vamos">
          Aceitar proposta
        </a>
        <button className={`nav-burger ${open ? 'open' : ''}`} onClick={() => setOpen(!open)} aria-label="Menu" aria-expanded={open}>
          <span></span><span></span>
        </button>
      </div>
      <div className={`nav-mobile ${open ? 'open' : ''}`}>
        {links.map(([href, label]) =>
          <a key={href} href={href} onClick={() => setOpen(false)}>{label}</a>
        )}
        <a href="#contato" className="nav-mobile-cta" onClick={() => setOpen(false)}>Aceitar proposta</a>
      </div>
      </div>
    </header>
  );
};

/* ---------- Hero ---------- */
const Hero = ({ tweaks }) =>
  <section className="hero" id="top">
    <video className="hero-video" autoPlay muted loop playsInline poster="assets/background-estatico.webp">
      <source src="assets/background-site.webm" type="video/webm" />
    </video>
    <div className="hero-overlay"></div>
    <Ambient
      sparks={[['20%', '15%', '0s'], ['15%', '70%', '.5s'], ['80%', '20%', '2s'], ['62%', '86%', '1.3s']]}
      beams={[['30%', '2s', '10s'], ['70%', '6s', '14s']]} />

    <div className="hero-inner">
      <div className="hero-client" data-hero="0">
        <div className="hero-client-photo" data-cursor="Rony">
          <img src="assets/cliente/Rony%20Ribeiro.jpg" alt="Rony Ribeiro" width="112" height="112" />
        </div>
        <p className="hero-client-name">Rony Ribeiro</p>
        <p className="hero-client-org">Lobotomy Games</p>
      </div>

      <div className="hero-eyebrow" data-hero="1">
        <span className="dot"></span>
        Proposta Comercial &middot; 2026
      </div>

      <h1 className="hero-headline" id="heroHeadline">
        Branding e <em>identidade visual</em>
      </h1>

      <p className="hero-sub" data-hero="2">
        Para estúdios, games e produtos digitais que valorizam criatividade,<br className="desktop-break" />
        {' '}personalização e uma marca à altura da experiência.
      </p>

      <div className="hero-actions" data-hero="3">
        <a href="#opcoes" className="btn btn-primary btn-lg" data-magnetic data-cursor="Ver">
          Ver as opções <span className="btn-arrow">&#8594;</span>
        </a>
        <a href="#sobre" className="btn btn-ghost btn-lg" data-cursor="Sobre">Conhecer o estúdio</a>
      </div>
    </div>

    <a href="#sobre" className="hero-scroll" aria-label="Rolar para baixo">
      <span className="hero-scroll-mouse"><span className="hero-scroll-wheel"></span></span>
      Role para conhecer
    </a>
  </section>;

/* ---------- Sobre ---------- */
const About = () =>
  <section className="section section-about" id="sobre">
    <Ambient sparks={[['10%', '30%', '.3s'], ['50%', '60%', '1.8s'], ['78%', '12%', '2.6s']]} beams={[['20%', '3s', '13s'], ['80%', '7s', '16s']]} />
    <div className="container">
      <div className="about-grid">

        <div className="about-visual reveal">
          <div className="about-photo-wrap" data-cursor="Marcos">
            <img src="assets/marcos.jpg" alt="Marcos Passos" width="440" height="520" loading="lazy" />
            <div className="photo-caption">
              <p className="photo-name">Marcos Passos</p>
              <p className="photo-role">CEO Pocket Joy</p>
            </div>
          </div>
        </div>

        <div className="about-content">
          <span className="overline reveal">Quem é a Pocket Joy</span>
          <h2 className="section-title reveal">
            Um estúdio de branding, identidade visual{' '}
            <span className="title-nowrap">e interfaces</span>{' '}
            <em>para games &amp; tech</em>.
          </h2>
          <p className="reveal">
            Ao longo de sete anos dedicados ao design, construí uma trajetória guiada por um
            princípio claro: a união entre estética e tecnologia. Como especialista em branding e
            identidade visual, acredito que o design vai além da aparência: ele constrói percepção,
            gera confiança e dá forma ao valor de uma marca.
          </p>
          <p className="reveal">
            Essa visão orienta cada projeto: transformar marcas em experiências consistentes e
            memoráveis, traduzindo estratégia em interfaces inteligentes, envolventes e com
            propósito. Mais do que entregar peças bonitas, meu trabalho busca criar conexões reais
            entre empresas e pessoas.
          </p>
          <div className="about-pills reveal">
            <span className="about-pill"><span className="swatch"></span>Atendimento Brasil e no Mundo</span>
            <span className="about-pill"><span className="swatch"></span>7 anos de experiência</span>
            <span className="about-pill"><span className="swatch"></span>Consultoria e estratégia</span>
          </div>
          <div className="about-skills reveal">
            {['Visual Identity', 'Branding', 'Game UI Design', 'Digital Design', 'Experience'].map((s) =>
              <span key={s} className="skill-tag">{s}</span>
            )}
          </div>
        </div>

      </div>
    </div>
  </section>;

/* ---------- Portfólio (slides + visualizador, igual ao site) ---------- */
const PROJECTS = {
  'balloomia': {
    title: 'Balloomia Sky Playground',
    slideTitle: ['Balloomia', 'Sky Playground'],
    tag: 'Game UI Design',
    desc: 'Interface completa e assets 2D para todo o jogo como Menu, conquista da steam, telas variadas entre outros.',
    cover: 'assets/Balloomia-capa.webp',
    bg: '#1a0050',
    folder: 'assets/balloomia/',
    count: 37, videos: [35], skip: []
  },
  'pocket-joy': {
    title: 'Pocket Joy',
    slideTitle: ['Pocket Joy'],
    tag: 'Brand Identity',
    desc: 'Identidade visual completa logo, paleta, tipografia e sistema de marca para uma experiência memorável.',
    cover: 'assets/Pocket-Joy-capa.webp',
    bg: '#1a0a40',
    folder: 'assets/pocket-joy/',
    count: 21, videos: [2], skip: [7]
  },
  'fin': {
    title: 'FIN Agência Digital',
    slideTitle: ['FIN', 'Agência Digital'],
    tag: 'Brand Identity',
    desc: 'Branding estratégico para agência digital marca, linguagem visual e aplicações institucionais.',
    cover: 'assets/FIN-capa.webp',
    bg: '#0a1530',
    folder: 'assets/fin/',
    count: 15, videos: [2, 9], skip: []
  }
};
const PROJECT_KEYS = ['balloomia', 'pocket-joy', 'fin'];

const Portfolio = ({ onOpen }) => {
  const [current, setCurrent] = useState(0);
  const trackRef = useRef(null);
  const wrapRef = useRef(null);
  const TOTAL = PROJECT_KEYS.length + 1;

  // Desliza o track e revela o conteúdo do slide que entra
  useEffect(() => {
    const track = trackRef.current, wrap = wrapRef.current;
    if (!track || !wrap) return;
    const x = -(current * wrap.clientWidth);

    if (!window.gsap) { track.style.transform = 'translateX(' + x + 'px)'; return; }

    gsap.to(track, { x: x, duration: 0.9, ease: 'power3.inOut' });

    const slide = track.children[current];
    if (!slide) return;
    const bg = slide.querySelector('.slide-bg');
    if (bg) gsap.fromTo(bg, { scale: 1.14 }, { scale: 1, duration: 1.2, ease: 'power3.out' });

    const c = slide.querySelector('.slide-content');
    if (!c) return;
    const tag = c.querySelector('.slide-tag');
    const title = c.querySelector('.slide-title');
    const desc = c.querySelector('.slide-desc');
    const btn = c.querySelector('.btn-view-project');
    gsap.set(c, { opacity: 1 });
    const tl = gsap.timeline({ delay: 0.42 });
    if (tag) tl.fromTo(tag, { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 0.5, ease: 'power3.out' }, 0);
    if (title) tl.fromTo(title, { opacity: 0, y: 34 }, { opacity: 1, y: 0, duration: 0.85, ease: 'power4.out' }, 0.08);
    if (desc) tl.fromTo(desc, { opacity: 0, y: 22 }, { opacity: 1, y: 0, duration: 0.55, ease: 'power3.out' }, 0.24);
    if (btn) tl.fromTo(btn, { opacity: 0, y: 18, scale: 0.92 }, { opacity: 1, y: 0, scale: 1, duration: 0.5, ease: 'back.out(1.6)' }, 0.36);
  }, [current]);

  // Reposiciona o track quando a janela muda de tamanho
  useEffect(() => {
    const onResize = () => {
      const track = trackRef.current, wrap = wrapRef.current;
      if (!track || !wrap) return;
      const x = -(current * wrap.clientWidth);
      if (window.gsap) gsap.set(track, { x: x });
      else track.style.transform = 'translateX(' + x + 'px)';
    };
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, [current]);

  const go = (i) => setCurrent(Math.min(Math.max(i, 0), TOTAL - 1));

  // Swipe no touch
  const touch = useRef(0);
  const onTouchStart = (e) => { touch.current = e.touches[0].clientX; };
  const onTouchEnd = (e) => {
    const dx = e.changedTouches[0].clientX - touch.current;
    if (Math.abs(dx) > 50) go(dx < 0 ? current + 1 : current - 1);
  };

  return (
    <section className="portfolio-section" id="portfolio" ref={wrapRef}>
      <Ambient sparks={[['20%', '15%', '0s'], ['60%', '80%', '1.5s'], ['40%', '45%', '.8s']]} beams={[['10%', '0s', '12s'], ['90%', '4s', '15s']]} />

      <div className="portfolio-track" ref={trackRef} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>

        {/* Slide 0 — intro */}
        <div className="portfolio-slide portfolio-slide--intro">
          <div className="slide-intro-content">
            <div className="intro-left">
              <span className="portfolio-label reveal">Seleção de trabalhos</span>
              <h2 className="portfolio-title reveal">Portfólio</h2>
              <p className="portfolio-subtitle reveal">Brand Identity &amp; Game UI Design</p>
              <button className="portfolio-scroll-hint reveal" onClick={() => go(1)} data-cursor="Explorar">
                <span className="scroll-line"></span>
                Explorar os projetos
              </button>
            </div>
            <div className="intro-right">
              <div className="intro-previews reveal" data-cursor="Portfólio" onClick={() => go(1)}>
                {PROJECT_KEYS.map((k, i) =>
                  <div key={k} className={'preview-card preview-card--' + (i + 1)}
                    style={{ backgroundImage: 'url(' + PROJECTS[k].cover + ')' }} />
                )}
              </div>
              <div className="intro-meta reveal">
                <span className="intro-meta-num">03</span>
                <div className="intro-meta-tags">
                  <span className="intro-meta-tag"><span></span>Game UI Design</span>
                  <span className="intro-meta-tag"><span></span>Brand Identity</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Slides 1..3 — projetos */}
        {PROJECT_KEYS.map((key) => {
          const p = PROJECTS[key];
          return (
            <div key={key} className="portfolio-slide">
              <div className="slide-bg" style={{ backgroundImage: 'url(' + p.cover + ')', backgroundColor: p.bg }} />
              <div className="slide-overlay"></div>
              <div className="slide-content">
                <p className="slide-tag">{p.tag}</p>
                <h3 className="slide-title">
                  {p.slideTitle.map((l, i) =>
                    <span key={i}>{l}{i < p.slideTitle.length - 1 && <br />}</span>
                  )}
                </h3>
                <p className="slide-desc">{p.desc}</p>
                <button className="btn-view-project" onClick={() => onOpen(key)} data-magnetic data-cursor="Ver">
                  Ver Projeto
                  <span className="arrow-icon">&#8599;</span>
                </button>
              </div>
            </div>
          );
        })}
      </div>

      <div className="slide-counter" style={{ opacity: current > 0 ? 1 : 0 }}>
        <span>{String(current).padStart(2, '0')}</span> / 03
      </div>

      <nav className="portfolio-nav" aria-label="Navegar projetos">
        <button className="portfolio-nav-arrow" onClick={() => go(current - 1)} disabled={current === 0} aria-label="Anterior">&#8592;</button>
        <div className="portfolio-dots">
          {Array.from({ length: TOTAL }).map((_, i) =>
            <button key={i} className={'portfolio-dot ' + (i === current ? 'active' : '')}
              onClick={() => go(i)} aria-label={'Slide ' + (i + 1)} />
          )}
        </div>
        <button className="portfolio-nav-arrow" onClick={() => go(current + 1)} disabled={current === TOTAL - 1} aria-label="Próximo">&#8594;</button>
      </nav>
    </section>
  );
};

/* ---------- Visualizador de projeto ---------- */
const ProjectViewer = ({ projectKey, onClose }) => {
  const p = projectKey ? PROJECTS[projectKey] : null;
  const scrollRef = useRef(null);

  useEffect(() => {
    if (!p) return;
    document.body.style.overflow = 'hidden';
    if (window.__lenis) window.__lenis.stop();
    if (scrollRef.current) scrollRef.current.scrollTop = 0;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = '';
      if (window.__lenis) window.__lenis.start();
      document.removeEventListener('keydown', onKey);
    };
  }, [p, onClose]);

  if (!p) return null;

  const media = [];
  for (let i = 1; i <= p.count; i++) {
    if (p.skip.indexOf(i) !== -1) continue;
    media.push(p.videos.indexOf(i) !== -1
      ? <video key={i} src={p.folder + i + '.webm'} autoPlay loop muted playsInline />
      : <img key={i} src={p.folder + i + '.webp'} alt={p.title + ' ' + i} loading={i <= 3 ? 'eager' : 'lazy'} />);
  }

  return (
    <div className="project-modal" role="dialog" aria-modal="true" aria-label={p.title}>
      <div className="project-topbar">
        <div className="project-topbar-left">
          <button className="project-back" onClick={onClose} data-cursor="Voltar">&#8592; Voltar</button>
          <span className="project-topbar-title">{p.title}</span>
          <span className="project-topbar-tag">{p.tag}</span>
        </div>
        <button className="project-close" onClick={onClose} aria-label="Fechar" data-cursor="Fechar">&#10005;</button>
      </div>
      <div className="project-scroll" ref={scrollRef} data-lenis-prevent>
        <div className="project-images">{media}</div>
      </div>
    </div>
  );
};

/* ---------- Processo ---------- */
const Process = () => {
  const [active, setActive] = useState(0);
  return (
    <section className="section section-process" id="processo">
      <Ambient sparks={[['30%', '10%', '1s'], ['70%', '90%', '2.5s']]} beams={[['40%', '2s', '11s']]} />
      <div className="container">
        <div className="section-header">
          <span className="overline reveal">Como trabalhamos</span>
          <h2 className="section-title reveal">Um processo <em>criativo</em>, em três etapas.</h2>
          <p className="section-sub reveal">
            Nada de caixa fechada. Você acompanha cada decisão, do primeiro mapa até o último arquivo.
          </p>
        </div>
        <div className="process-track">
          {PROCESS.map((p, i) => {
            const Icon = ProcessIcon[p.icon];
            return (
              <article
                key={p.n}
                className={`process-card reveal ${active === i ? 'active' : ''}`}
                onMouseEnter={() => setActive(i)}
                onFocus={() => setActive(i)}
                tabIndex={0}
                data-cursor={p.n}>
                <div className="process-card-top">
                  <span className="process-num">{p.n}</span>
                  <span className="process-total">/ 03</span>
                </div>
                <div className="process-icon"><Icon /></div>
                <h3 className="process-step-title">{p.title.split('\n').map((l, k) => <span key={k}>{l}<br /></span>)}</h3>
                <p className="process-step-desc">{p.desc}</p>
                <div className="process-card-bottom">
                  <span className="process-label">{p.label}</span>
                  <span className="process-line"></span>
                </div>
              </article>
            );
          })}
        </div>
      </div>
    </section>
  );
};

/* ---------- Card de opção ---------- */
const OptionCard = ({ opt, tweaks, onChoose }) => {
  const price = tweaks[opt.priceKey];
  const installments = price / 10;
  const fmt2 = (n) => 'R$ ' + n.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const fmt0 = (n) => 'R$ ' + n.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

  return (
    <div
      className={`option-card reveal ${opt.featured ? 'featured' : ''}`}
      style={{ '--card-accent': opt.accent }}
      data-tilt>
      <div className="option-glow" aria-hidden="true"></div>
      {opt.badge && <span className="option-badge">{opt.badge}</span>}

      <div className="option-head">
        <span className="option-tag">{opt.tag}</span>
        <h3 className="option-name">{opt.name}{opt.nameEm && <em> {opt.nameEm}</em>}</h3>
        <p className="option-tagline">{opt.tagline}</p>

        <div className="option-price">
          <span className="currency">10x de</span>
          <span className="amount">{fmt2(installments)}</span>
        </div>
        <div className="option-installment">
          no cartão <span className="sep">&middot;</span> ou <strong>{fmt0(price)}</strong> à vista
        </div>

        <div className="option-meta">
          <div className="option-meta-item"><I.Calendar />Prazo: {opt.duration}</div>
          <div className="option-meta-item"><I.Layers />{opt.scope}</div>
        </div>
      </div>

      <div className="option-body">
        <h4>O que está incluso</h4>
        <ul className="option-includes">
          {opt.includes.map((it, i) =>
            <li key={i}><span className="check"><I.Check /></span>{it}</li>
          )}
        </ul>
        <div className="option-cta">
          <button className="btn btn-primary btn-block" onClick={() => onChoose(opt)} data-magnetic data-cursor="Quero">
            Quero esta opção <span className="btn-arrow">&#8594;</span>
          </button>
        </div>
      </div>
    </div>);
};

const Options = ({ tweaks, onChoose }) =>
  <section className="section section-options" id="opcoes">
    <Ambient sparks={[['12%', '22%', '.4s'], ['58%', '78%', '1.6s'], ['88%', '44%', '2.9s']]} beams={[['25%', '0s', '12s'], ['75%', '4s', '15s']]} />
    <div className="container">
      <div className="section-header">
        <span className="overline reveal">Investimento</span>
        <h2 className="section-title reveal">
          Logotipo, identidade visual{' '}
          <span className="title-nowrap">ou branding</span>{' '}
          <em>completo?</em>
        </h2>
        <p className="section-sub reveal">
          Escolha o ponto de partida da sua marca. Cada opção entrega um nível diferente de
          profundidade estratégica, e todas podem evoluir conforme o projeto cresce.
        </p>
      </div>
      <div className="options-grid">
        {OPTIONS.map((o) => <OptionCard key={o.id} opt={o} tweaks={tweaks} onChoose={onChoose} />)}
      </div>
      <p className="options-foot reveal">
        Todos os planos incluem contrato, briefing guiado e arquivos organizados em pasta única.
      </p>
    </div>
  </section>;

/* ---------- Depoimentos ---------- */
const Testimonials = () =>
  <section className="section section-testimonials" id="depoimentos">
    <Ambient sparks={[['25%', '40%', '.7s'], ['75%', '10%', '2.2s']]} beams={[['45%', '5s', '12s']]} />
    <div className="container">
      <div className="section-header">
        <span className="overline reveal">Depoimentos</span>
        <h2 className="section-title reveal">O que nossos clientes <em>contam</em>.</h2>
      </div>
    </div>
    <div className="feedback-slider">
      <div className="feedback-track">
        {[...TESTIMONIALS, ...TESTIMONIALS, ...TESTIMONIALS].map((t, i) =>
          <article key={i} className="feedback-card">
            <span className="feedback-quote-mark">&ldquo;</span>
            <p className="quote">{t.quote}</p>
            <div className="author">
              <div className="author-avatar"><img src={t.photo} alt={t.name} loading="lazy" /></div>
              <div className="author-info">
                <strong>{t.name}</strong>
                <span>{t.role}</span>
              </div>
              <div className="author-stars">{'★★★★★'.split('').map((s, k) => <span key={k}>{s}</span>)}</div>
            </div>
          </article>
        )}
      </div>
    </div>
  </section>;

/* ---------- Pagamento ---------- */
const Payment = () =>
  <section className="section section-payment" id="pagamento">
    <Ambient sparks={[['18%', '65%', '1.1s'], ['70%', '25%', '2.4s']]} beams={[['60%', '3s', '13s']]} />
    <div className="container">
      <div className="section-header">
        <span className="overline reveal">Forma de pagamento</span>
        <h2 className="section-title reveal">Condições <em>flexíveis</em>, sempre transparentes.</h2>
        <p className="section-sub reveal">
          Escolha a forma que faz mais sentido para o seu momento. Tudo é formalizado em contrato antes do início do projeto.
        </p>
      </div>
      <div className="payment-grid">
        {[
          { icon: <I.Pix />, n: '01', title: 'Pix à vista', desc: <>Pagamento integral por Pix com <strong>5% de desconto</strong> no valor total. Liberação imediata do briefing.</> },
          { icon: <I.Handshake />, n: '02', title: '50% + 50%', desc: <>Metade na assinatura do contrato, metade na entrega final. Forma mais comum entre nossos clientes.</> },
          { icon: <I.Card />, n: '03', title: 'Cartão em até 10x', desc: <>Parcelamento em até 10x no cartão. Consulte os valores de desconto para pagamento à vista no Pix ou com entrada de 50%.</> }
        ].map((c) =>
          <div key={c.n} className="payment-card reveal">
            <span className="payment-num">{c.n}</span>
            <div className="icon-plate">{c.icon}</div>
            <h3>{c.title}</h3>
            <p>{c.desc}</p>
          </div>
        )}
      </div>
    </div>
  </section>;

/* ---------- FAQ ---------- */
const FaqSection = () => {
  const [open, setOpen] = useState(0);
  return (
    <section className="section section-faq" id="faq">
      <Ambient sparks={[['30%', '85%', '.6s'], ['80%', '15%', '2.7s']]} beams={[['15%', '2s', '14s']]} />
      <div className="container">
        <div className="section-header">
          <span className="overline reveal">Perguntas frequentes</span>
          <h2 className="section-title reveal">Tirando suas <em>dúvidas</em>.</h2>
        </div>
        <div className="faq-list">
          {FAQ.map((item, i) =>
            <div key={i} className={`faq-item reveal ${open === i ? 'open' : ''}`}>
              <button className="faq-question" onClick={() => setOpen(open === i ? -1 : i)} aria-expanded={open === i} data-cursor={open === i ? 'Fechar' : 'Abrir'}>
                <span className="faq-index">{String(i + 1).padStart(2, '0')}</span>
                <span className="faq-q-text">{item.q}</span>
                <span className="icon"><I.Plus /></span>
              </button>
              <div className="faq-answer"><p>{item.a}</p></div>
            </div>
          )}
        </div>
      </div>
    </section>);
};

/* ---------- Contato ---------- */
const Contact = ({ tweaks }) => {
  const waMessage = encodeURIComponent('Olá, recebi a proposta de Branding e Identidade Visual da Pocket Joy e gostaria de seguir adiante.');
  const waUrl = `https://wa.me/${tweaks.whatsapp.replace(/\D/g, '')}?text=${waMessage}`;
  return (
    <section className="section section-contact" id="contato">
      <video className="section-video" autoPlay muted loop playsInline>
        <source src="assets/background-rodape.webm" type="video/webm" />
      </video>
      <div className="section-video-overlay"></div>
      <Ambient sparks={[['20%', '18%', '.2s'], ['40%', '82%', '1.4s'], ['72%', '52%', '2.3s']]} beams={[['35%', '1s', '11s'], ['65%', '5s', '14s']]} />
      <div className="container">
        <div className="cta-box reveal">
          <div className="validity-strip">
            <span className="pulse"></span>
            Proposta válida por {tweaks.validity} dias a partir do recebimento
          </div>
          <h2 className="cta-title">Pronto para <em>começar</em>?</h2>
          <p className="cta-sub">
            Nossa agenda funciona com um número limitado de projetos por mês. Para garantir uma vaga,
            orientamos que a aprovação aconteça dentro do prazo da proposta.
          </p>
          <p className="cta-strong">Estamos ansiosos para iniciar seu projeto.</p>

          <div className="cta-pills">
            {['Design personalizado', 'Parceria ativa', 'Evolução constante'].map((p) =>
              <span key={p} className="cta-pill"><span className="cta-pill-dot"></span>{p}</span>
            )}
          </div>

          <div className="cta-actions">
            <a className="btn btn-whatsapp btn-lg" href={waUrl} target="_blank" rel="noopener noreferrer" data-magnetic data-cursor="Falar">
              <I.Whatsapp /> Falar pelo WhatsApp
            </a>
            <a className="btn btn-ghost btn-lg" href="#opcoes" data-cursor="Voltar">
              Rever opções <span className="btn-arrow">&#8594;</span>
            </a>
          </div>
        </div>
      </div>
    </section>);
};

/* ---------- Rodapé ---------- */
const FooterBlock = () =>
  <footer className="footer">
    <div className="container">
      <div className="footer-top">
        <a href="#top" className="footer-logo"><img src="assets/Pocket-Joy.png" alt="Pocket Joy" width="131" height="28" /></a>
        <div className="footer-socials">
          <a className="footer-social-btn" href="https://www.instagram.com/pocketjoygaming/" target="_blank" rel="noopener noreferrer" aria-label="Instagram"><I.Instagram /></a>
          <a className="footer-social-btn" href="https://www.youtube.com/@Pocketjoygaming" target="_blank" rel="noopener noreferrer" aria-label="YouTube"><I.Youtube /></a>
        </div>
      </div>
      <hr className="footer-divider" />
      <div className="footer-bottom">
        <span className="footer-copy">&copy; Pocket Joy. Todos os direitos reservados.</span>
      </div>
    </div>
  </footer>;

/* ---------- Barra fixa de conversão (mobile) ---------- */
const StickyBar = ({ visible, tweaks }) => {
  const waUrl = `https://wa.me/${tweaks.whatsapp.replace(/\D/g, '')}?text=${encodeURIComponent('Olá, recebi a proposta de Branding e Identidade Visual da Pocket Joy e gostaria de seguir adiante.')}`;
  return (
    <div className={`sticky-bar ${visible ? 'visible' : ''}`}>
      <div className="sticky-bar-info">
        <span className="sticky-label">Proposta &middot; Pocket Joy</span>
        <span className="sticky-value">Válida por {tweaks.validity} dias</span>
      </div>
      <a href={waUrl} className="btn btn-whatsapp btn-sm" target="_blank" rel="noopener noreferrer">
        <I.Whatsapp /> Aceitar
      </a>
    </div>
  );
};

/* ---------- App ---------- */
const App = () => {
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "clientName": "Rony Ribeiro",
    "price1": 3000.00,
    "price2": 1400.00,
    "price3": 990.00,
    "validity": 7,
    "whatsapp": "556696909634",
    "accent": "#6366f1"
  } /*EDITMODE-END*/;
  const tweaks = TWEAK_DEFAULTS;
  const [scrolled, setScrolled] = useState(false);
  const [showSticky, setShowSticky] = useState(false);
  const [openProject, setOpenProject] = useState(null);

  useEffect(() => {
    const onScroll = () => {
      setScrolled(window.scrollY > 60);
      setShowSticky(window.scrollY > window.innerHeight * 1.2);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  useEffect(() => {
    document.documentElement.style.setProperty('--accent', tweaks.accent);
  }, [tweaks.accent]);

  // Avisa a camada de motion que o DOM já foi montado
  useEffect(() => {
    window.dispatchEvent(new CustomEvent('pj:mounted'));
  }, []);

  const handleChoose = () => {
    const el = document.getElementById('contato');
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <>
      <Navbar scrolled={scrolled} />
      <Hero tweaks={tweaks} />
      <About />
      <Portfolio onOpen={setOpenProject} />
      <Process />
      <Options tweaks={tweaks} onChoose={handleChoose} />
      <Testimonials />
      <Payment />
      <FaqSection />
      <Contact tweaks={tweaks} />
      <FooterBlock />
      <StickyBar visible={showSticky} tweaks={tweaks} />
      <ProjectViewer projectKey={openProject} onClose={() => setOpenProject(null)} />
    </>);
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
