// =========================================================================
//  capas-especiais / _shared.jsx
//  Primitivas reutilizadas por todas as capas (namorados, natal, são joão...)
//  Carrega ANTES de cada banner.jsx no preview.
//  Tudo é exportado em `window` no fim do arquivo.
// =========================================================================

const { useState, useEffect, useMemo, useRef } = React;

// ---------- countdown hook ----------
function useCountdown(targetIso) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    if (!targetIso) return;
    const i = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(i);
  }, [targetIso]);
  if (!targetIso) return { d: 0, h: 0, m: 0, s: 0, expired: false, none: true };
  const target = new Date(targetIso).getTime();
  const diff = Math.max(0, target - now);
  const d = Math.floor(diff / 86400000);
  const h = Math.floor((diff % 86400000) / 3600000);
  const m = Math.floor((diff % 3600000) / 60000);
  const s = Math.floor((diff % 60000) / 1000);
  return { d, h, m, s, expired: diff === 0, none: false };
}

// ---------- watercolor splash (aquarela em cantos) ----------
function WatercolorSplash({
  pos = 'tl', color = '#7a9cd9', size = 380, rotation = 0, opacity = 0.55,
}) {
  const id = useMemo(() => 'wc-' + Math.random().toString(36).slice(2), []);
  const posStyle = {
    tl: { top: -size * 0.35, left: -size * 0.25 },
    tr: { top: -size * 0.35, right: -size * 0.25 },
    bl: { bottom: -size * 0.35, left: -size * 0.25 },
    br: { bottom: -size * 0.35, right: -size * 0.25 },
    c:  { top: '50%', left: '50%', transform: `translate(-50%,-50%) rotate(${rotation}deg)` },
  }[pos] || {};
  const transform = pos === 'c' ? posStyle.transform : `rotate(${rotation}deg)`;
  return (
    <svg
      width={size} height={size} viewBox="0 0 200 200"
      style={{
        position: 'absolute', pointerEvents: 'none',
        transform, opacity, ...posStyle,
      }}
    >
      <defs>
        <filter id={`${id}-rough`} x="-20%" y="-20%" width="140%" height="140%">
          <feTurbulence type="fractalNoise" baseFrequency="0.022" numOctaves="3" seed="7"/>
          <feDisplacementMap in="SourceGraphic" scale="22"/>
        </filter>
        <radialGradient id={`${id}-g1`} cx="0.45" cy="0.5" r="0.55">
          <stop offset="0%"   stopColor={color} stopOpacity="0.0"/>
          <stop offset="55%"  stopColor={color} stopOpacity="0.35"/>
          <stop offset="100%" stopColor={color} stopOpacity="0.75"/>
        </radialGradient>
        <radialGradient id={`${id}-g2`} cx="0.5" cy="0.5" r="0.5">
          <stop offset="0%"   stopColor={color} stopOpacity="0.10"/>
          <stop offset="100%" stopColor={color} stopOpacity="0"/>
        </radialGradient>
      </defs>
      <g filter={`url(#${id}-rough)`}>
        <ellipse cx="100" cy="100" rx="78" ry="60" fill={`url(#${id}-g1)`}/>
        <ellipse cx="120" cy="80"  rx="48" ry="34" fill={color} opacity="0.18"/>
        <ellipse cx="80"  cy="120" rx="40" ry="28" fill={color} opacity="0.14"/>
      </g>
      <g fill={color} opacity="0.35">
        {[[30,40],[170,55],[20,150],[180,140],[160,170],[40,170],[160,30]].map(([x,y],i)=>(
          <circle key={i} cx={x} cy={y} r={1 + (i%3)*0.6}/>
        ))}
      </g>
      <ellipse cx="100" cy="100" rx="60" ry="46" fill={`url(#${id}-g2)`}/>
    </svg>
  );
}

// ---------- countdown pip ----------
function CountPip({ n, label, color = '#0b2e36', sublabel = 'rgba(0,0,0,0.45)' }) {
  return (
    <div className="cap-pip" style={{ textAlign: 'center', minWidth: 52 }}>
      <div className="cap-serif cap-countdown-pip-val" style={{
        fontSize: 'clamp(28px, 3.2vw, 44px)', fontWeight: 500, lineHeight: 1,
        color, fontFeatureSettings: '"tnum" 1',
      }}>
        {String(n).padStart(2, '0')}
      </div>
      <div style={{
        fontSize: 10, fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
        letterSpacing: '0.16em', textTransform: 'uppercase',
        color: sublabel, marginTop: 6,
      }}>{label}</div>
    </div>
  );
}

// ---------- Countdown bar (caixa com d/h/m/s) ----------
function CountdownBar({ targetIso, accent = '#0b2e36', label = 'Faltam', dark = false }) {
  const { d, h, m, s, none } = useCountdown(targetIso);
  if (none) return null;
  const bg = dark ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.78)';
  const border = dark ? 'rgba(212,175,106,0.4)' : 'rgba(255,255,255,0.9)';
  const sublabel = dark ? 'rgba(255,255,255,0.55)' : 'rgba(0,0,0,0.45)';
  const colon = dark ? 'rgba(255,255,255,0.35)' : 'rgba(0,0,0,0.3)';
  const divider = dark ? 'rgba(255,255,255,0.18)' : 'rgba(0,0,0,0.1)';
  return (
    <div className="cap-countdown" style={{
      marginTop: 28, padding: '18px 22px',
      background: bg,
      backdropFilter: 'blur(8px)',
      border: `1px solid ${border}`,
      borderRadius: 18,
      boxShadow: dark
        ? '0 12px 32px -16px rgba(0,0,0,0.5)'
        : '0 12px 32px -16px rgba(11,46,54,0.25)',
      display: 'inline-flex', alignItems: 'center', gap: 8,
      maxWidth: '100%',
    }}>
      <div className="cap-countdown-label" style={{
        fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
        fontSize: 10, letterSpacing: '0.16em',
        textTransform: 'uppercase', color: sublabel,
        writingMode: 'vertical-rl', transform: 'rotate(180deg)',
        paddingRight: 8, borderRight: `1px solid ${divider}`,
        marginRight: 6,
      }}>{label}</div>
      <CountPip n={d} label="Dias" color={accent} sublabel={sublabel}/>
      <span style={{ color: colon, fontSize: 24, fontWeight: 300 }}>:</span>
      <CountPip n={h} label="Horas" color={accent} sublabel={sublabel}/>
      <span style={{ color: colon, fontSize: 24, fontWeight: 300 }}>:</span>
      <CountPip n={m} label="Min" color={accent} sublabel={sublabel}/>
      <span style={{ color: colon, fontSize: 24, fontWeight: 300 }}>:</span>
      <CountPip n={s} label="Seg" color={accent} sublabel={sublabel}/>
    </div>
  );
}

// ---------- Eyebrow chip (badge "Dia X · DD.MM") ----------
function ThemeChip({ icon, color, soft, children }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      background: 'white', border: `1px solid ${soft}`,
      padding: '8px 14px 8px 10px', borderRadius: 999,
      boxShadow: `0 6px 20px -10px ${color}55`,
      marginBottom: 22,
    }}>
      <span style={{
        width: 26, height: 26, borderRadius: '50%',
        background: soft, color,
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 14, lineHeight: 1,
      }}>{icon}</span>
      <span style={{
        fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
        fontSize: 11, letterSpacing: '0.18em',
        textTransform: 'uppercase', color, fontWeight: 600,
      }}>{children}</span>
    </div>
  );
}

// ---------- Sketchy underline ----------
function Squiggle({ color, width = '108%' }) {
  return (
    <svg width="120" height="14" viewBox="0 0 120 14" style={{
      position: 'absolute', left: -4, bottom: -6, width, height: 14,
    }}>
      <path d="M2 9 C 20 3, 40 12, 60 6 S 100 10, 118 5"
        fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" opacity="0.75"/>
    </svg>
  );
}

// ---------- BeadedBracelet — joia em SVG (re-usada em todas as capas) ----------
function BeadedBracelet({ hue = 200, size = '100%', metal = '#d4af6a' }) {
  const id = useMemo(() => 'bb-' + Math.random().toString(36).slice(2), []);
  const stone = `oklch(0.72 0.14 ${hue})`;
  const stoneB = `oklch(0.58 0.16 ${hue + 4})`;
  const accent = `oklch(0.78 0.10 ${(hue + 40) % 360})`;
  const pearl = '#f6f1ea';
  const beads = [];
  const N = 18;
  for (let i = 0; i < N; i++) {
    const a = (i / N) * Math.PI * 2 - Math.PI / 2;
    const r = 92;
    const x = 150 + Math.cos(a) * r;
    const y = 150 + Math.sin(a) * r;
    beads.push({ x, y, type: i % 4 });
  }
  return (
    <svg viewBox="0 0 300 300" width={size} height={size}
         preserveAspectRatio="xMidYMid meet"
         style={{ display: 'block', width: '100%', height: '100%' }}>
      <defs>
        <radialGradient id={`${id}-p`} cx="0.35" cy="0.3"><stop offset="0%" stopColor="#fff" stopOpacity="0.95"/><stop offset="100%" stopColor={pearl}/></radialGradient>
        <radialGradient id={`${id}-s`} cx="0.35" cy="0.3"><stop offset="0%" stopColor="#fff" stopOpacity="0.7"/><stop offset="60%" stopColor={stone}/><stop offset="100%" stopColor={stoneB}/></radialGradient>
        <radialGradient id={`${id}-a`} cx="0.35" cy="0.3"><stop offset="0%" stopColor="#fff" stopOpacity="0.7"/><stop offset="100%" stopColor={accent}/></radialGradient>
      </defs>
      <circle cx="150" cy="150" r="92" stroke={metal} strokeWidth="1" fill="none" opacity="0.4"/>
      {beads.map((b, i) => {
        const fill = b.type === 0 ? `url(#${id}-p)` : b.type === 1 ? `url(#${id}-s)` : b.type === 2 ? `url(#${id}-p)` : `url(#${id}-a)`;
        const r = b.type === 1 ? 11 : b.type === 3 ? 9 : 10;
        return (
          <g key={i}>
            <circle cx={b.x} cy={b.y} r={r} fill={fill} stroke="rgba(0,0,0,0.08)" strokeWidth="0.5"/>
            <circle cx={b.x - r * 0.32} cy={b.y - r * 0.32} r={r * 0.25} fill="#fff" opacity="0.7"/>
          </g>
        );
      })}
      <circle cx="150" cy="58" r="6" fill={metal} opacity="0.7"/>
    </svg>
  );
}

// ---------- FloatingCard — card flutuante de produto (re-usado) ----------
function FloatingCard({ item, style, big = false, accent = '#0b2e36', tileBg = '#f6f2ec' }) {
  const [hover, setHover] = useState(false);
  const img1 = item?.image || (item?.images && item.images[0]?.url);
  const img2 = (item?.images && item.images[1]?.url) || img1;
  const href = item?.slug ? `/produto?slug=${item.slug}` : null;
  return (
    <div
      className="cap-floating-card"
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        background: 'white', borderRadius: 22, overflow: 'hidden',
        boxShadow: hover
          ? '0 30px 60px -16px rgba(11,46,54,0.32)'
          : '0 20px 40px -16px rgba(11,46,54,0.22)',
        transition: 'box-shadow .25s ease, transform .25s ease',
        ...style,
      }}
    >
      {href
        ? <a href={href} style={{ display: 'block', aspectRatio: '1/1', background: tileBg, position: 'relative', overflow: 'hidden' }}>
            {img1
              ? <>
                  <img src={img1} alt={item.name} style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', transition:'opacity .35s', opacity: hover ? 0 : 1 }}/>
                  <img src={img2} alt={item.name} style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', transition:'opacity .35s', opacity: hover ? 1 : 0 }}/>
                </>
              : <BeadedBracelet hue={item.hue} metal={item.metal}/>
            }
          </a>
        : <div style={{ aspectRatio: '1/1', background: tileBg, position: 'relative', overflow: 'hidden' }}>
            {img1
              ? <>
                  <img src={img1} alt={item.name} style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover' }}/>
                </>
              : <BeadedBracelet hue={item.hue} metal={item.metal}/>
            }
          </div>
      }
      <div style={{ padding: big ? '14px 16px' : '10px 12px' }}>
        <div className="cap-serif" style={{ fontSize: big ? 18 : 14, fontWeight: 500, color: accent }}>
          {item.name}
        </div>
        <div style={{
          fontSize: big ? 11 : 10, color: 'rgba(0,0,0,0.5)',
          fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
          letterSpacing: '0.06em', marginTop: 2,
        }}>{item.sub || item.short || ''}</div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: big ? 8 : 6 }}>
          <span className="cap-serif" style={{ fontSize: big ? 19 : 15, fontWeight: 600, color: accent }}>
            R$ {Number(item.price || 0).toFixed(2).replace('.', ',')}
          </span>
        </div>
      </div>
    </div>
  );
}

// ---------- SpecialProductCard — padronizado com ProductCard da home ----------
// Mesmo layout do ProductsSection (sections.jsx) pra consistência visual:
// imagem 1:1 + badge gold + cat uppercase + name serif + preço + parcelamento
// + 2 botões pílula (Sacola ghost + Comprar gradient).
function SpecialProductCard({ item, accent = '#0b2e36', cart }) {
  const [hover, setHover] = useState(false);
  const img1 = item.image || (item.images && item.images[0]?.url);
  const img2 = (item.images && item.images[1]?.url) || img1;
  const href = item.slug ? `/produto?slug=${item.slug}` : '#';
  const brl = (v) => 'R$ ' + Number(v || 0).toFixed(2).replace('.', ',');
  const off = item.old && item.old > item.price ? Math.round((1 - item.price / item.old) * 100) : 0;
  const badge = item.badge || (off ? `-${off}%` : null);

  return (
    <a
      href={href}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        background: 'white', borderRadius: 20, overflow: 'hidden',
        border: '1px solid ' + (hover ? 'rgba(212,175,106,0.4)' : 'var(--line)'),
        transition: 'transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s ease, border-color .25s ease',
        transform: hover ? 'translateY(-6px)' : 'translateY(0)',
        boxShadow: hover
          ? '0 30px 60px -20px rgba(10,31,61,0.22), 0 4px 12px -4px rgba(212,175,106,0.18)'
          : '0 2px 6px rgba(10,31,61,0.04)',
        display: 'flex', flexDirection: 'column',
        color: 'inherit', textDecoration: 'none',
      }}
    >
      <div style={{ position: 'relative', aspectRatio: '1/1', background: '#f6f2ec', overflow: 'hidden' }}>
        {img1
          ? <>
              <img src={img1} alt={item.name} loading="lazy" style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', transition:'opacity .35s, transform .5s ease', opacity: hover ? 0 : 1, transform: hover ? 'scale(1.04)' : 'scale(1)' }}/>
              <img src={img2} alt="" loading="lazy" style={{ position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', transition:'opacity .35s, transform .5s ease', opacity: hover ? 1 : 0, transform: hover ? 'scale(1.04)' : 'scale(1)' }}/>
            </>
          : <BeadedBracelet hue={item.hue || 200}/>
        }
        {badge && (
          <span style={{
            position: 'absolute', top: 12, left: 12,
            background: badge.startsWith('-')
              ? 'linear-gradient(135deg, #ef4444, #b91c1c)'
              : (badge === 'Novo' ? 'var(--grad-navy)' : 'var(--grad-gold)'),
            color: badge.startsWith('-') || badge === 'Novo' ? 'white' : '#0a1f3d',
            fontSize: 10, fontFamily: 'var(--mono)',
            letterSpacing: '0.12em', textTransform: 'uppercase', fontWeight: 700,
            padding: '6px 11px', borderRadius: 999,
            boxShadow: '0 6px 14px -6px rgba(0,0,0,0.25)',
          }}>{badge}</span>
        )}
      </div>
      <div style={{ padding: '18px 20px 20px', display: 'flex', flexDirection: 'column', gap: 4 }}>
        <div style={{ fontSize: 10, fontFamily: 'var(--mono)', color: 'var(--gold-deep, #b48a3f)', letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 600 }}>{item.cat || ''}</div>
        <div className="serif" style={{ fontSize: 20, fontWeight: 500, color: 'var(--navy, #0a1f3d)', letterSpacing: '-0.005em' }}>
          {item.name}
        </div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 6 }}>
          <span className="serif" style={{ fontSize: 22, fontWeight: 600, color: 'var(--navy, #0a1f3d)', letterSpacing: '-0.01em' }}>
            {brl(item.price)}
          </span>
          {item.old && <span style={{ fontSize: 13, color: 'var(--ink-3)', textDecoration: 'line-through' }}>{brl(item.old)}</span>}
        </div>
        <div style={{ fontSize: 11, color: 'var(--ink-2)', marginTop: 4, fontWeight: 500 }}>
          ou <strong style={{ color: 'var(--gold-deep, #b48a3f)', fontFamily: 'var(--mono)' }}>6x</strong> de <strong style={{ color: 'var(--navy-2, #142a4f)' }}>{brl(item.price / 6)}</strong>
        </div>
        <div className="cta-row" style={{ display: 'flex', gap: 8, marginTop: 14 }}>
          <button
            onClick={(e) => { e.preventDefault(); e.stopPropagation(); if (cart) cart.add({ ...item, cat: item.cat || '' }); }}
            className="btn btn-ghost cta-sacola"
            style={{ flex: '1 1 0', minWidth: 0, height: 40, fontSize: 12, borderRadius: 999, background: 'white', border: '1px solid var(--line)', color: 'var(--ink)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6, cursor: 'pointer', padding: '0 8px', whiteSpace: 'nowrap' }}
          >
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><path d="M3 6h18M16 10a4 4 0 0 1-8 0"/></svg>
            Sacola
          </button>
          <button
            onClick={(e) => { e.preventDefault(); e.stopPropagation(); if (cart) cart.buyNow ? cart.buyNow(item) : cart.add({ ...item, cat: item.cat || '' }); }}
            className="btn btn-primary cta-buy"
            style={{ flex: '1 1 0', minWidth: 0, height: 40, fontSize: 12, fontWeight: 600, borderRadius: 999, background: 'var(--grad)', color: 'white', border: 'none', cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6, boxShadow: '0 8px 20px -8px rgba(6,182,212,0.5)', padding: '0 8px', whiteSpace: 'nowrap' }}
          >
            Comprar
          </button>
        </div>
      </div>
    </a>
  );
}

// ---------- SpecialProductsGrid — grid de 4 produtos do especial ativo ----------
// Lógica: se o tema tem produtos cadastrados com a tag (ex: special=namorados),
// mostra esses. Senão, pega 4 aleatórios do catálogo geral pra ainda valorizar
// o tema visualmente. Padrão sempre usa catálogo geral.
function SpecialProductsGrid({ special, accent = 'var(--blue-600)', sectionLabel = 'Peças em destaque', sectionTitle = 'Para presentear' }) {
  const [items, setItems] = useState([]);
  const cart = useCart();

  useEffect(() => {
    if (!special) return;
    const ts = Date.now();
    const themeUrl = '/api/products?special=' + encodeURIComponent(special) + '&_=' + ts;
    const allUrl   = '/api/products?_=' + ts;

    const pickRandom = (arr, n) => {
      const copy = arr.slice();
      for (let i = copy.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [copy[i], copy[j]] = [copy[j], copy[i]];
      }
      return copy.slice(0, n);
    };

    if (special === 'padrao') {
      fetch(allUrl, { cache: 'no-store' })
        .then(r => r.ok ? r.json() : null)
        .then(data => {
          if (data?.products?.length) setItems(pickRandom(data.products, 4));
        })
        .catch(() => {});
      return;
    }

    fetch(themeUrl, { cache: 'no-store' })
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (data?.products?.length) {
          setItems(data.products.slice(0, 4));
        } else {
          // Sem produtos taggeados: fallback aleatório do catálogo geral.
          return fetch(allUrl, { cache: 'no-store' })
            .then(r => r.ok ? r.json() : null)
            .then(all => {
              if (all?.products?.length) setItems(pickRandom(all.products, 4));
            });
        }
      })
      .catch(() => {});
  }, [special]);

  if (!items.length) return null;

  return (
    <section id={special + '-grid'} style={{ padding: '56px 0 72px', background: 'white', borderBottom: '1px solid var(--line)' }}>
      <div className="container">
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12, marginBottom: 28 }}>
          <div>
            <div className="eyebrow" style={{ color: accent, marginBottom: 8 }}>{sectionLabel}</div>
            <h3 className="serif" style={{ margin: 0, fontSize: 'clamp(28px, 3vw, 42px)', fontWeight: 400, letterSpacing: '-0.01em' }}>
              {sectionTitle}
            </h3>
          </div>
          <a href={'categoria.html?especial=' + special} style={{ fontSize: 13, color: 'var(--blue-700)', display: 'inline-flex', alignItems: 'center', gap: 6, borderBottom: '1px solid var(--blue-200)', paddingBottom: 2, textDecoration: 'none' }}>
            Ver coleção completa →
          </a>
        </div>
        <div className="four-up" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 22 }}>
          {items.map(item => (
            <SpecialProductCard key={item.slug || item.id} item={item} accent={accent} cart={cart}/>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------- Banner Shell — layout reutilizado por todas as capas ----------
function BannerShell({
  bg, accent, accentSoft, ink = '#0b2e36',
  chip, headline, italicWord, italicColor,
  copy, perks, ctaPrimary, ctaSecondary,
  targetIso, countdownLabel = 'Faltam',
  decorations,  // function(): nodes (splashes + motivos)
  hero,         // node — visual da direita
  bottomBorder = true,
  dark = false, // tema escuro (ex: Ano Novo)
}) {
  // Injetar CSS responsivo das capas na home também (não só nas preview pages).
  // Sem isso, .cap-two-up / .cap-section etc. ficam sem media queries no site
  // principal e os temas quebram no mobile/tablet.
  useEffect(() => { if (typeof injectPreviewCSS === 'function') injectPreviewCSS(); }, []);
  const copyColor = dark ? 'rgba(246,239,217,0.78)' : 'rgba(0,0,0,0.66)';
  const dashed = dark ? 'rgba(212,175,106,0.3)' : 'rgba(0,0,0,0.12)';
  const perkColor = dark ? 'rgba(246,239,217,0.62)' : 'rgba(0,0,0,0.56)';
  return (
    <section className="cap-section" style={{
      position: 'relative', overflow: 'hidden',
      background: bg, padding: '64px 0 72px',
      borderBottom: bottomBorder ? '1px solid rgba(0,0,0,0.06)' : 'none',
      color: ink,
    }}>
      {decorations && decorations()}

      <div className="cap-container" style={{
        position: 'relative', zIndex: 2,
        maxWidth: 1240, margin: '0 auto', padding: '0 28px',
      }}>
        <div className="cap-two-up" style={{
          display: 'grid', gridTemplateColumns: '1.05fr 1fr',
          gap: 56, alignItems: 'center',
        }}>
          <div>
            {chip}
            <h2 className="cap-serif" style={{
              fontSize: 'clamp(36px, 5.6vw, 78px)', lineHeight: 1.02,
              margin: 0, fontWeight: 400, letterSpacing: '-0.02em',
              color: ink, textWrap: 'balance',
            }}>
              {headline}
              {italicWord && (
                <em style={{
                  fontStyle: 'italic',
                  color: italicColor || accent,
                  position: 'relative', display: 'inline-block',
                }}>
                  {italicWord}
                  <Squiggle color={italicColor || accent}/>
                </em>
              )}
              .
            </h2>

            {copy && (
              <p style={{
                fontSize: 17, lineHeight: 1.6, color: copyColor,
                margin: '24px 0 0', maxWidth: 480, textWrap: 'pretty',
              }}>{copy}</p>
            )}

            {targetIso && <CountdownBar targetIso={targetIso} accent={dark ? accent : ink} label={countdownLabel} dark={dark}/>}

            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginTop: 28 }}>
              {ctaPrimary && (
                <a href={ctaPrimary.href} className="cap-btn" style={{
                  height: 54, padding: '0 28px', fontSize: 15,
                  display: 'inline-flex', alignItems: 'center', gap: 10,
                  borderRadius: 999, textDecoration: 'none',
                  background: `linear-gradient(135deg, ${accent}, ${ctaPrimary.dark || accent})`,
                  color: ctaPrimary.textColor || (dark ? '#1a1206' : 'white'),
                  boxShadow: `0 14px 28px -8px ${accent}80`,
                  fontWeight: 600,
                }}>
                  {ctaPrimary.label} <span style={{ fontSize: 18 }}>→</span>
                </a>
              )}
              {ctaSecondary && (
                <a href={ctaSecondary.href} target="_blank" rel="noreferrer" className="cap-btn-ghost" style={{
                  height: 54, padding: '0 22px', fontSize: 14,
                  display: 'inline-flex', alignItems: 'center', gap: 8,
                  borderRadius: 999, textDecoration: 'none',
                  background: dark ? 'rgba(255,255,255,0.06)' : 'white',
                  color: dark ? ink : '#0b2e36',
                  border: dark ? '1px solid rgba(212,175,106,0.4)' : '1px solid rgba(0,0,0,0.1)',
                  fontWeight: 500,
                }}>
                  {ctaSecondary.icon} {ctaSecondary.label}
                </a>
              )}
            </div>

            {perks && perks.length > 0 && (
              <div style={{
                display: 'flex', flexWrap: 'wrap', gap: 18,
                marginTop: 28, paddingTop: 24,
                borderTop: `1px dashed ${dashed}`,
                fontSize: 12, fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
                textTransform: 'uppercase', letterSpacing: '0.1em',
                color: perkColor,
              }}>
                {perks.map((p, i) => (
                  <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                    {p.icon} {p.label}
                  </span>
                ))}
              </div>
            )}
          </div>

          <div className="cap-hero" style={{ position: 'relative', minHeight: 480 }}>
            {hero}
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- Strip pequeno (anúncio do topo, listras coloridas) ----------
function AnnouncementStrip({ gradient, children, icon }) {
  return (
    <div style={{
      background: gradient,
      color: 'white', textAlign: 'center',
      fontSize: 12, letterSpacing: '0.08em', padding: '9px 12px',
      fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
      display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
      textTransform: 'uppercase',
    }}>
      {icon}{children}{icon}
    </div>
  );
}

// ---------- mount helper para o preview.html ----------
function mountPreview(BannerComp, StripComp) {
  const root = ReactDOM.createRoot(document.getElementById('app'));
  root.render(
    <>
      {StripComp && <StripComp/>}
      <BannerComp/>
    </>
  );
}

// ---------- estilos globais para preview ----------
function injectPreviewCSS() {
  if (document.getElementById('cap-css')) return;
  const s = document.createElement('style');
  s.id = 'cap-css';
  s.textContent = `
    *,*::before,*::after{box-sizing:border-box}
    body{margin:0;font-family:'Inter',-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;
         color:#0b2e36;background:#f6f4ef;-webkit-font-smoothing:antialiased}
    .cap-serif{font-family:'Cormorant Garamond','Playfair Display',Georgia,serif}
    @keyframes cap-float-y { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-12px)} }
    @keyframes cap-spin-slow { from{transform:rotate(0)} to{transform:rotate(360deg)} }
    @keyframes cap-twinkle { 0%,100%{opacity:.35;transform:scale(0.9)} 50%{opacity:1;transform:scale(1.1)} }
    @keyframes cap-sway { 0%,100%{transform:rotate(-4deg)} 50%{transform:rotate(4deg)} }
    .cap-btn:hover{filter:brightness(1.05)}
    .cap-btn-ghost:hover{background:#fafafa}

    /* ====== TABLET (≤ 1024px) ====== */
    @media (max-width: 1024px){
      .cap-section{padding:44px 0 52px !important}
      .cap-container{padding:0 22px !important}
      .cap-two-up{gap:36px !important; grid-template-columns: 1fr !important}
      .cap-hero{min-height:380px !important; max-width: 540px; margin: 0 auto}
    }

    /* ====== MOBILE (≤ 720px) ====== */
    @media (max-width: 720px){
      .cap-section{padding:32px 0 40px !important}
      .cap-container{padding:0 16px !important}
      .cap-two-up{
        grid-template-columns:1fr !important;
        gap:28px !important;
      }
      /* Hero collage vira carrossel auto-rotativo de 5s por card.
         Cada FloatingCard (.cap-floating-card) é absoluto, sobreposto
         no centro, com fade+scale animando em ciclo. */
      .cap-hero{
        position: relative !important;
        min-height: 380px !important;
        display: block !important;
        overflow: visible !important;
        padding: 0 !important;
      }
      /* Esconde decorativos do hero em mobile (orbs, moon, splashes
         posicionados absolute que poluem a tela pequena). Mantém só
         os cards. */
      .cap-hero > *:not(.cap-floating-card) {
        display: none !important;
      }
      /* Cards centrais sobrepostos, 5s cada, fade in/out + scale */
      .cap-floating-card {
        position: absolute !important;
        top: 50% !important; left: 50% !important;
        width: 78% !important;
        max-width: 300px !important;
        aspect-ratio: auto !important;
        transform: translate(-50%, -50%) scale(.94) !important;
        animation: cap-mobile-carousel 15s infinite !important;
        animation-delay: 0s !important;
        opacity: 0;
      }
      .cap-floating-card:nth-of-type(2) { animation-delay: 5s !important; }
      .cap-floating-card:nth-of-type(3) { animation-delay: 10s !important; }
    }
    @keyframes cap-mobile-carousel {
      0%, 33.33%, 100% {
        opacity: 0;
        transform: translate(-50%, -50%) scale(.94);
        z-index: 1;
      }
      2%, 31.33% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1);
        z-index: 2;
      }
    }
      .cap-serif{ font-size: clamp(30px, 8.5vw, 48px) !important }
      /* paragraph tighten */
      .cap-section p{ font-size: 15px !important; line-height: 1.55 !important }
      /* countdown: deixar quebrar */
      .cap-countdown{
        flex-wrap:wrap !important;
        padding:12px 14px !important;
        gap:4px !important;
        width: 100%;
        justify-content: center !important;
      }
      .cap-countdown-label{display:none !important}
      .cap-pip{min-width:42px !important}
      /* CTAs full-width */
      .cap-btn, .cap-btn-ghost{
        height:50px !important; padding:0 18px !important;
        font-size:14px !important;
        flex: 1 1 100% !important;
        justify-content:center !important;
      }
      /* hero collage scale-friendly */
      .cap-hero > *{transform-origin:center !important}
    }

    /* ====== EXTRA SMALL (≤ 420px) ====== */
    @media (max-width: 420px){
      .cap-section{padding:24px 0 32px !important}
      .cap-container{padding:0 14px !important}
      .cap-hero{min-height:280px !important}
      .cap-countdown-pip-val{font-size:22px !important}
      .cap-pip{min-width:36px !important}
      .cap-serif{ font-size: clamp(26px, 9vw, 40px) !important }
    }
  `;
  document.head.appendChild(s);
  // fonts
  if (!document.getElementById('cap-fonts')) {
    const l = document.createElement('link');
    l.id = 'cap-fonts';
    l.rel = 'stylesheet';
    l.href = 'https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Inter:wght@400;500;600&display=swap';
    document.head.appendChild(l);
  }
}

Object.assign(window, {
  useCountdown, WatercolorSplash, CountPip, CountdownBar,
  ThemeChip, Squiggle, BannerShell, AnnouncementStrip,
  BeadedBracelet, FloatingCard,
  SpecialProductCard, SpecialProductsGrid,
  mountPreview, injectPreviewCSS,
});
