// wow_layouts.jsx v3 — WOW MAX
// 4 layouts: Acquerello / Cornice / Festa / Polaroid
// Photo opzionale → se assente, placeholder grafico forte per tema
// Effetti: 3D tilt (su interazione), foil olografico nome, scintille, coriandoli

const fitW = (name, base) => {
  const len = (name || '').trim().length || 1;
  if (len <= 5) return base;
  if (len <= 7) return Math.round(base * 0.84);
  if (len <= 9) return Math.round(base * 0.7);
  if (len <= 12) return Math.round(base * 0.55);
  if (len <= 15) return Math.round(base * 0.44);
  return Math.round(base * 0.36);
};

const _MM_IT = ['GEN','FEB','MAR','APR','MAG','GIU','LUG','AGO','SET','OTT','NOV','DIC'];
const dParts = (d) => {
  const day = (d || '').slice(8,10) || '01';
  const mi = parseInt((d || '').slice(5,7), 10) - 1;
  return { day, mon: _MM_IT[mi] || 'GEN' };
};

// ────────────────────────────────────────────────
// 3D Tilt wrapper — attivo su hover/touch/giroscopio
// ────────────────────────────────────────────────
function Tilt3D({ children, max = 12, depth = true }) {
  const ref = React.useRef(null);
  const [tilt, setTilt] = React.useState({ x: 0, y: 0, active: false });

  const onMove = (clientX, clientY) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    const dx = (clientX - r.left - r.width/2) / (r.width/2);
    const dy = (clientY - r.top - r.height/2) / (r.height/2);
    setTilt({ x: -dy * max * 0.8, y: dx * max, active: true });
  };
  const reset = () => setTilt({ x: 0, y: 0, active: false });

  React.useEffect(() => {
    const handler = (e) => {
      if (!e.beta || !e.gamma) return;
      const ry = Math.max(-max, Math.min(max, e.gamma * 0.4));
      const rx = Math.max(-max, Math.min(max, (e.beta - 30) * 0.2));
      setTilt({ x: rx, y: ry, active: true });
    };
    if ('DeviceOrientationEvent' in window && !window.DeviceOrientationEvent.requestPermission) {
      window.addEventListener('deviceorientation', handler);
      return () => window.removeEventListener('deviceorientation', handler);
    }
  }, [max]);

  return (
    <div
      ref={ref}
      onMouseMove={(e) => onMove(e.clientX, e.clientY)}
      onMouseLeave={reset}
      onTouchMove={(e) => { if (e.touches[0]) onMove(e.touches[0].clientX, e.touches[0].clientY); }}
      onTouchEnd={reset}
      style={{
        position: 'absolute', inset: 0,
        perspective: 1400,
      }}
    >
      <div style={{
        position: 'absolute', inset: 0,
        transformStyle: depth ? 'preserve-3d' : 'flat',
        transform: `rotateX(${tilt.x}deg) rotateY(${tilt.y}deg)`,
        transition: tilt.active ? 'none' : 'transform 0.5s cubic-bezier(0.2,0.8,0.2,1)',
      }}>
        {children}
        {/* Glare layer */}
        <div style={{
          position: 'absolute', inset: 0, pointerEvents: 'none',
          background: `linear-gradient(${135 + tilt.y * 2}deg, rgba(255,255,255,0.35) 0%, rgba(255,255,255,0) 35%, rgba(255,255,255,0) 65%, rgba(255,255,255,0.18) 100%)`,
          mixBlendMode: 'overlay',
          opacity: tilt.active ? 0.7 : 0,
          transition: 'opacity 0.3s',
          transform: depth ? 'translateZ(60px)' : 'none',
          borderRadius: 'inherit',
        }} />
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────
// Scintille continue + confetti burst (1 volta su mount)
// ────────────────────────────────────────────────
function Sparkles({ colors = ['#FFD24F','#FF6B9D','#7FCFC0','#fff','#FFB94D'], rate = 600 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    let alive = true;
    const spawn = () => {
      if (!alive || !el) return;
      const p = document.createElement('i');
      const c = colors[Math.floor(Math.random() * colors.length)];
      p.style.cssText = `position:absolute;left:${Math.random()*100}%;bottom:-10px;width:4px;height:4px;border-radius:50%;background:${c};box-shadow:0 0 6px ${c};animation:wowParticleUp ${5 + Math.random()*3}s linear forwards;--xd:${(Math.random()-0.5)*40}px`;
      el.appendChild(p);
      setTimeout(() => p.remove(), 8500);
    };
    const iv = setInterval(spawn, rate);
    return () => { alive = false; clearInterval(iv); };
  }, [rate]);
  return <div ref={ref} style={{position:'absolute',inset:0,pointerEvents:'none',overflow:'hidden',zIndex:9}}/>;
}

function ConfettiBurst({ delay = 200 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const colors = ['#FF6B9D','#FFB94D','#5DE89E','#5BC4FF','#B07CE8','#FFD24F'];
    const t = setTimeout(() => {
      for (let i = 0; i < 36; i++) {
        const piece = document.createElement('i');
        const angle = (Math.PI * 2 * i) / 36 + (Math.random() - 0.5) * 0.4;
        const dist = 160 + Math.random() * 140;
        piece.style.cssText = `position:absolute;left:50%;top:35%;width:5px;height:9px;border-radius:1px;background:${colors[i%colors.length]};animation:wowConfettiBurst 1.6s cubic-bezier(0.1,0.7,0.3,1) ${Math.random()*0.15}s forwards;--dx:${Math.cos(angle)*dist}px;--dy:${Math.sin(angle)*dist - 50}px;--rot:${Math.random()*720-360}deg`;
        el.appendChild(piece);
      }
    }, delay);
    return () => clearTimeout(t);
  }, [delay]);
  return <div ref={ref} style={{position:'absolute',inset:0,pointerEvents:'none',overflow:'visible',zIndex:10}}/>;
}

// ────────────────────────────────────────────────
// Nome con foil olografico animato
// ────────────────────────────────────────────────
function FoilName({ children, size, style = {} }) {
  return (
    <span style={{
      display: 'inline-block',
      fontFamily: '"Fraunces", "DM Serif Display", serif', fontStyle: 'italic', fontWeight: 700,
      fontSize: size, lineHeight: 0.92, letterSpacing: '-0.02em',
      background: 'linear-gradient(135deg, #FF6B9D 0%, #FFB94D 25%, #5DE89E 50%, #5BC4FF 75%, #B07CE8 100%)',
      backgroundSize: '200% 200%',
      WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent',
      filter: 'drop-shadow(0 2px 0 rgba(255,255,255,0.8)) drop-shadow(0 4px 8px rgba(196,74,110,0.25))',
      animation: 'wowFoilShift 4s ease-in-out infinite',
      ...style,
    }}>{children}</span>
  );
}

// ────────────────────────────────────────────────
// Placeholder per tema (quando manca la foto)
// ────────────────────────────────────────────────
function ThemePlaceholder({ theme, data, shape = 'circle' }) {
  const p = theme.palette;
  const eta = data.eta || '?';
  const initial = (data.nome || '?').trim().charAt(0).toUpperCase();
  // Cake icon as universal cheerful placeholder + age numeral
  return (
    <div style={{
      width: '100%', height: '100%',
      borderRadius: shape === 'circle' ? '50%' : 0,
      background: `radial-gradient(circle at 30% 30%, ${p.accent || p.bg2 || '#FFEBC1'} 0%, ${p.primary} 80%)`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      position: 'relative', overflow: 'hidden',
    }}>
      <svg viewBox="0 0 200 200" style={{ width: '70%', height: '70%' }}>
        {/* cake */}
        <ellipse cx="100" cy="160" rx="62" ry="10" fill="rgba(0,0,0,0.18)"/>
        <rect x="44" y="110" width="112" height="44" rx="6" fill="#fff" opacity="0.95"/>
        <path d="M44 130 Q 60 122 76 130 T 108 130 T 140 130 T 156 130 L 156 154 L 44 154 Z" fill={p.accent || '#FFB94D'}/>
        <rect x="56" y="86" width="88" height="32" rx="5" fill="#fff" opacity="0.95"/>
        <path d="M56 102 Q 70 96 84 102 T 112 102 T 144 102 L 144 118 L 56 118 Z" fill="#FF6B9D"/>
        {/* candle */}
        <rect x="96" y="62" width="8" height="22" fill="#fff"/>
        <path d="M100 50 Q 96 56 100 62 Q 104 56 100 50 Z" fill="#FFB94D">
          <animate attributeName="opacity" values="1;0.6;1" dur="1.2s" repeatCount="indefinite"/>
        </path>
        {/* age in big letters on cake */}
        <text x="100" y="146" textAnchor="middle" fontFamily="DM Serif Display, serif" fontStyle="italic" fontSize="32" fill={p.primary || '#C42D8E'} fontWeight="700">{eta}</text>
        {/* sparkles */}
        <text x="40" y="40" fontSize="18" fill="#FFD24F">✦</text>
        <text x="160" y="50" fontSize="14" fill="#fff">✦</text>
        <text x="30" y="100" fontSize="12" fill="#fff">✦</text>
        <text x="170" y="110" fontSize="16" fill="#FFD24F">✦</text>
      </svg>
    </div>
  );
}

// Photo or placeholder
function PhotoOrPlaceholder({ data, theme, shape = 'circle' }) {
  if (data.photo) {
    return <img src={data.photo} alt="" style={{
      width: '100%', height: '100%', objectFit: 'cover',
      borderRadius: shape === 'circle' ? '50%' : 0,
      animation: 'polDevelop 1.2s ease-out 0.4s both',
    }}/>;
  }
  return <ThemePlaceholder theme={theme} data={data} shape={shape}/>;
}

// Party hat overlay (decoration layer)
function PartyHat({ size = 40, top = '-8%', left = '50%', color = '#FF6B9D', accent = '#FFB94D' }) {
  return (
    <svg viewBox="0 0 60 70" style={{
      position: 'absolute', left, top, width: size, height: size * 70/60,
      transform: 'translateX(-50%) rotate(-12deg)',
      animation: 'wowHatDrop 0.9s cubic-bezier(0.34,1.5,0.64,1) 0.9s both',
      filter: 'drop-shadow(0 4px 6px rgba(0,0,0,0.18))',
      zIndex: 5,
    }}>
      <path d="M30 0 L 50 50 L 10 50 Z" fill={color} stroke="#2A1810" strokeWidth="1.5" strokeLinejoin="round"/>
      <path d="M12 50 L 50 50 L 48 56 L 14 56 Z" fill={accent}/>
      <circle cx="22" cy="30" r="3" fill="#FFD24F"/>
      <circle cx="36" cy="20" r="2.5" fill="#7FCFC0"/>
      <circle cx="30" cy="-2" r="5" fill="#FFD24F"/>
      <circle cx="30" cy="-2" r="2.5" fill={color}/>
    </svg>
  );
}

// Mini date strip (bottom)
const InfoStrip = ({ data, bg = 'rgba(255,255,255,0.88)', fg = '#2A2438', accent = '#C44A6E', animDelay = 1.8 }) => {
  const { day, mon } = dParts(data.data);
  const luogo = (data.luogo || 'Via Roma 1').split(',')[0];
  return (
    <div style={{
      position: 'absolute', left: '6%', right: '6%', bottom: '5%',
      background: bg, color: fg,
      borderRadius: 12, padding: '8px 12px',
      display: 'grid', gridTemplateColumns: 'auto 1fr', columnGap: 10, rowGap: 2,
      fontSize: 11, fontWeight: 600,
      boxShadow: '0 4px 12px rgba(45,36,56,0.10)',
      animation: `wowFadeUp 0.6s ease-out ${animDelay}s both`,
      zIndex: 7,
    }}>
      <span style={{ fontWeight: 800, letterSpacing: '0.14em', color: accent, fontSize: 9 }}>QUANDO</span>
      <span>{day} {mon} · {data.ora || '16:30'}</span>
      <span style={{ fontWeight: 800, letterSpacing: '0.14em', color: accent, fontSize: 9 }}>DOVE</span>
      <span style={{ overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{luogo}</span>
    </div>
  );
};

// ════════════════════════════════════════════════
// LAYOUT 1 · ACQUERELLO POP (poster)
// ════════════════════════════════════════════════
function LayoutAcquerello({ theme, data }) {
  const p = theme.palette;
  const nome = (data.nome || 'Nome').trim();
  const letters = nome.split('').slice(0, 12);
  const colors = ['#E84A6E','#FFA13D','#4FB890','#4FA9E0','#B96AD9','#E84A6E','#FFA13D','#4FB890','#4FA9E0','#B96AD9','#E84A6E','#FFA13D'];
  return (
    <Tilt3D>
      <div style={{
        position:'absolute', inset:0, overflow:'hidden', borderRadius:'inherit',
        background:`radial-gradient(ellipse 80% 60% at 20% 10%, #FFD9CC 0%, transparent 60%), radial-gradient(ellipse 70% 50% at 90% 30%, #FFC4DE 0%, transparent 60%), radial-gradient(ellipse 60% 60% at 30% 90%, ${p.bg2 || '#FFE3B8'} 0%, transparent 60%), radial-gradient(ellipse 80% 60% at 90% 90%, ${p.bg || '#FFCDDB'} 0%, transparent 60%), linear-gradient(180deg, #FFF5EE 0%, #FFEDF2 100%)`,
        fontFamily:'"Plus Jakarta Sans", sans-serif', color:'#2A2438',
      }}>
        {/* eyebrow */}
        <div style={{
          position:'absolute', left:0, right:0, top:'6%', textAlign:'center',
          fontFamily:'"Caveat", cursive', fontSize:22, fontWeight:700, color:'#C44A6E',
          animation:'wowFadeUp 0.7s ease-out 0.2s both', zIndex:6,
        }}>È la festa di…</div>

        {/* Photo or placeholder */}
        <div style={{
          position:'absolute', left:'50%', top:'13%', transform:'translateX(-50%)',
          width:'52%', aspectRatio:'1', borderRadius:'50%',
          border:'5px solid #fff',
          boxShadow:'0 8px 18px rgba(196,74,110,0.25)',
          overflow:'hidden',
          animation:'wowPhotoIn 0.9s cubic-bezier(0.34,1.5,0.64,1) 0.4s both',
          zIndex:3,
        }}>
          <PhotoOrPlaceholder data={data} theme={theme}/>
        </div>
        {/* party hat sticking out top */}
        <div style={{ position:'absolute', left:'50%', top:'9%', width:'52%', aspectRatio:'1', transform:'translateX(-50%)', pointerEvents:'none' }}>
          <PartyHat size={48} top="-6%" color={p.primary || '#FF6B9D'} accent={p.accent || '#FFB94D'}/>
        </div>

        {/* balloons top-left */}
        <svg viewBox="0 0 100 130" style={{
          position:'absolute', left:'3%', top:'4%', width:'22%',
          animation:'wowBalloonRise 1s ease-out 0.5s both',
        }}>
          <line x1="38" y1="60" x2="34" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <line x1="58" y1="50" x2="60" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <line x1="76" y1="65" x2="78" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <ellipse cx="38" cy="46" rx="18" ry="22" fill={p.primary || '#FF7BAC'}/>
          <ellipse cx="32" cy="38" rx="5" ry="7" fill="#fff" opacity="0.5"/>
          <ellipse cx="58" cy="36" rx="18" ry="22" fill={p.accent || '#FFB94D'}/>
          <ellipse cx="76" cy="50" rx="16" ry="20" fill={p.secondary || '#7FCFC0'}/>
        </svg>

        {/* leaves bottom-right */}
        <svg viewBox="0 0 140 120" style={{
          position:'absolute', right:'-2%', bottom:'-2%', width:'34%',
          animation:'wowFadeUp 0.8s ease-out 0.6s both', zIndex:2,
        }}>
          <path d="M30 100 Q 60 60 100 80 Q 120 100 100 115 Q 60 115 30 100" fill="#7CC56A" opacity="0.85"/>
          <path d="M50 90 Q 80 60 120 80 Q 130 100 110 110 Q 70 110 50 90" fill="#5DA34D" opacity="0.7"/>
          <circle cx="84" cy="98" r="3" fill="#FF7BAC"/>
        </svg>

        {/* name multicolor foil */}
        <div style={{
          position:'absolute', left:0, right:0, top:'60%',
          textAlign:'center', display:'flex', justifyContent:'center', flexWrap:'wrap',
          fontFamily:'"Fraunces", serif', fontStyle:'italic', fontWeight:700,
          fontSize: fitW(nome, 56), lineHeight:0.92, letterSpacing:'-0.02em',
          zIndex:4,
        }}>
          {letters.map((ch, i) => (
            <span key={i} style={{
              display:'inline-block',
              color: colors[i % colors.length],
              filter:'drop-shadow(0 2px 0 #fff)',
              animation: `wowNameDrop 0.55s cubic-bezier(0.34,1.6,0.64,1) ${1.0 + i*0.06}s both, wowLetterFloat 3s ease-in-out ${1.6 + i*0.1}s infinite`,
            }}>{ch === ' ' ? '\u00A0' : ch}</span>
          ))}
        </div>

        {/* age line */}
        <div style={{
          position:'absolute', left:0, right:0, top:'73%', textAlign:'center',
          fontFamily:'"Caveat", cursive', fontWeight:700, fontSize:20, color:'#5A4F69',
          animation:'wowFadeUp 0.6s ease-out 1.7s both', zIndex:4,
        }}>
          compie <b style={{fontFamily:'"DM Serif Display", serif', fontStyle:'italic', fontWeight:'normal', fontSize:30, color:'#E84A6E', margin:'0 4px', verticalAlign:'-3px'}}>{data.eta || '?'}</b> {parseInt(data.eta,10)===1?'anno':'anni'}
        </div>

        <InfoStrip data={data}/>
      </div>
    </Tilt3D>
  );
}

// ════════════════════════════════════════════════
// LAYOUT 2 · CORNICE FLOREALE (riso)
// ════════════════════════════════════════════════
function LayoutCornice({ theme, data }) {
  const p = theme.palette;
  const nome = (data.nome || 'Nome').trim();
  return (
    <Tilt3D max={8}>
      <div style={{
        position:'absolute', inset:0, overflow:'hidden', borderRadius:'inherit',
        background:'radial-gradient(ellipse 60% 50% at 50% 50%, #fff 0%, #FAF1E8 100%)',
        fontFamily:'"Plus Jakarta Sans", sans-serif', color:'#4A2D5E',
      }}>
        {/* wreath SVG */}
        <svg viewBox="0 0 360 480" preserveAspectRatio="none" style={{position:'absolute', inset:0, pointerEvents:'none'}}>
          <g>
            <ellipse cx="80" cy="40" rx="38" ry="22" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="55" cy="38" r="13" fill="#F4B8C4"/><circle cx="55" cy="38" r="6" fill="#E89BB0"/>
            <ellipse cx="160" cy="50" rx="20" ry="14" fill="#A8C8AC" opacity="0.55"/>
            <circle cx="180" cy="42" r="10" fill="#F4D8B8"/>
            <ellipse cx="220" cy="36" rx="22" ry="14" fill="#7CB680" opacity="0.65"/>
            <circle cx="240" cy="48" r="12" fill="#F4B8C4"/><circle cx="240" cy="48" r="6" fill="#E89BB0"/>
            <ellipse cx="280" cy="32" rx="26" ry="16" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="306" cy="44" r="9" fill="#FFE4A8"/>
          </g>
          <g>
            <ellipse cx="22" cy="120" rx="18" ry="32" fill="#9CC2A0" opacity="0.5"/>
            <circle cx="20" cy="240" r="9" fill="#F4B8C4"/><circle cx="20" cy="240" r="4" fill="#E89BB0"/>
            <ellipse cx="32" cy="300" rx="14" ry="22" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="22" cy="350" r="8" fill="#FFE4A8"/>
          </g>
          <g>
            <ellipse cx="338" cy="130" rx="18" ry="30" fill="#7CB680" opacity="0.55"/>
            <circle cx="340" cy="200" r="10" fill="#F4D8B8"/>
            <ellipse cx="328" cy="260" rx="14" ry="22" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="340" cy="320" r="11" fill="#F4B8C4"/><circle cx="340" cy="320" r="5" fill="#E89BB0"/>
          </g>
          <g>
            <ellipse cx="60" cy="442" rx="32" ry="20" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="40" cy="446" r="13" fill="#F4B8C4"/><circle cx="40" cy="446" r="6" fill="#E89BB0"/>
            <ellipse cx="110" cy="450" rx="22" ry="14" fill="#7CB680" opacity="0.65"/>
            <circle cx="140" cy="445" r="9" fill="#FFE4A8"/>
            <ellipse cx="200" cy="440" rx="28" ry="16" fill="#9CC2A0" opacity="0.55"/>
            <circle cx="220" cy="448" r="11" fill="#F4D8B8"/>
            <ellipse cx="270" cy="446" rx="22" ry="14" fill="#7CB680" opacity="0.65"/>
            <circle cx="306" cy="442" r="13" fill="#F4B8C4"/><circle cx="306" cy="442" r="6" fill="#E89BB0"/>
          </g>
        </svg>

        <div style={{
          position:'absolute', left:0, right:0, top:'11%', textAlign:'center',
          fontFamily:'"Caveat", cursive', fontSize:20, color:'#B85A8C',
          animation:'wowFadeUp 0.7s ease-out 0.5s both', zIndex:3,
        }}>È la festa di…</div>

        {/* Photo or placeholder */}
        <div style={{
          position:'absolute', left:'50%', top:'17%', transform:'translateX(-50%)',
          width:'44%', aspectRatio:'1', borderRadius:'50%',
          border:'4px solid #fff', boxShadow:'0 4px 12px rgba(74,45,94,0.18)',
          overflow:'hidden',
          animation:'wowPhotoIn 0.9s cubic-bezier(0.34,1.5,0.64,1) 0.7s both',
          zIndex:3,
        }}>
          <PhotoOrPlaceholder data={data} theme={theme}/>
        </div>

        {/* name foil */}
        <div style={{
          position:'absolute', left:0, right:0, top:'53%', textAlign:'center',
          padding:'0 12%', zIndex:3,
          animation:'wowFadeUp 0.7s ease-out 1.0s both',
        }}>
          <FoilName size={fitW(nome, 44)} style={{fontFamily:'"DM Serif Display", serif'}}>{nome}</FoilName>
        </div>

        <div style={{
          position:'absolute', left:0, right:0, top:'66%', textAlign:'center',
          fontFamily:'"Caveat", cursive', fontSize:18, color:'#B85A8C', zIndex:3,
          animation:'wowFadeUp 0.7s ease-out 1.2s both',
        }}>compie <b style={{fontFamily:'"DM Serif Display", serif', fontStyle:'italic', fontSize:30, color:'#D44C8B', fontWeight:'normal', margin:'0 4px', verticalAlign:'-2px'}}>{data.eta || '?'}</b> anni</div>

        <div style={{
          position:'absolute', left:'50%', top:'76%', transform:'translateX(-50%)',
          width:30, height:1, background:'#B85A8C66', zIndex:3,
        }}/>

        <InfoStrip data={data} accent="#B85A8C"/>
      </div>
    </Tilt3D>
  );
}

// ════════════════════════════════════════════════
// LAYOUT 3 · FESTA (illustrato) — banner + age burst
// ════════════════════════════════════════════════
function LayoutFesta({ theme, data }) {
  const p = theme.palette;
  const nome = (data.nome || 'Nome').trim();
  return (
    <Tilt3D>
      <div style={{
        position:'absolute', inset:0, overflow:'hidden', borderRadius:'inherit',
        background:`radial-gradient(ellipse 90% 50% at 50% 0%, #FFD0E5 0%, transparent 70%), linear-gradient(180deg, #FFF0F8 0%, #F8E0F0 100%)`,
        fontFamily:'"Plus Jakarta Sans", sans-serif', color:'#5C2D4E',
      }}>
        {/* ribbon banner */}
        <svg viewBox="0 0 320 30" preserveAspectRatio="none" style={{
          position:'absolute', left:'4%', right:'4%', top:'6%', width:'92%', height:30,
          animation:'wowScaleIn 0.7s cubic-bezier(0.34,1.4,0.64,1) 0.6s both', zIndex:3,
        }}>
          <path d="M0 6 L 20 2 L 20 28 L 0 24 Z" fill="#C42D8E"/>
          <path d="M320 6 L 300 2 L 300 28 L 320 24 Z" fill="#C42D8E"/>
          <path d="M14 0 L 306 0 L 298 15 L 306 30 L 14 30 L 22 15 Z" fill="#E84A6E"/>
        </svg>
        <div style={{
          position:'absolute', left:0, right:0, top:'6%', height:30,
          display:'flex', alignItems:'center', justifyContent:'center',
          fontFamily:'"Fraunces", serif', fontStyle:'italic', fontWeight:700,
          fontSize:14, color:'#fff', textShadow:'0 1px 1px rgba(150,30,80,0.4)',
          zIndex:4, animation:'wowFadeUp 0.6s ease-out 0.9s both',
        }}>Happy Birthday!</div>

        {/* photo */}
        <div style={{
          position:'absolute', left:'50%', top:'17%', transform:'translateX(-50%)',
          width:'50%', aspectRatio:'1', borderRadius:'50%',
          border:'5px solid #fff', boxShadow:'0 8px 18px rgba(196,45,142,0.25)',
          overflow:'hidden',
          animation:'wowPhotoIn 0.9s cubic-bezier(0.34,1.5,0.64,1) 0.5s both', zIndex:3,
        }}>
          <PhotoOrPlaceholder data={data} theme={theme}/>
        </div>

        {/* age burst */}
        <div style={{
          position:'absolute', right:'5%', top:'20%', width:'18%', aspectRatio:'1', zIndex:6,
          animation:'wowBurstIn 0.7s cubic-bezier(0.34,1.6,0.64,1) 1.3s both',
        }}>
          <svg viewBox="0 0 80 80" style={{position:'absolute', inset:0, animation:'wowSpin 14s linear infinite'}}>
            <defs>
              <radialGradient id="burstG3" cx="50%" cy="50%" r="50%">
                <stop offset="0%" stopColor="#FFB94D"/><stop offset="100%" stopColor="#FF6B9D"/>
              </radialGradient>
            </defs>
            <path d="M40 0 L 47 12 L 60 8 L 56 22 L 70 20 L 60 32 L 76 38 L 60 44 L 70 56 L 56 54 L 60 68 L 47 64 L 40 76 L 33 64 L 20 68 L 24 54 L 10 56 L 20 44 L 4 38 L 20 32 L 10 20 L 24 22 L 20 8 L 33 12 Z" fill="url(#burstG3)" stroke="#fff" strokeWidth="2.5"/>
          </svg>
          <div style={{
            position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'center',
            fontFamily:'"DM Serif Display", serif', fontStyle:'italic', fontSize:'55%', color:'#fff',
            textShadow:'0 2px 4px rgba(196,74,110,0.4)', transform:'rotate(-8deg)',
          }}>{data.eta || '?'}</div>
        </div>

        {/* name foil */}
        <div style={{
          position:'absolute', left:0, right:0, top:'55%', textAlign:'center', padding:'0 6%', zIndex:4,
          animation:'wowFadeUp 0.8s ease-out 1.1s both',
        }}>
          <FoilName size={fitW(nome, 64)} style={{fontFamily:'"Pacifico", "Caveat", cursive', fontStyle:'normal'}}>{nome}</FoilName>
        </div>

        {/* age line */}
        <div style={{
          position:'absolute', left:0, right:0, top:'70%', textAlign:'center',
          fontFamily:'"Caveat", cursive', fontSize:18, color:'#7A4E5C', zIndex:4,
          animation:'wowFadeUp 0.7s ease-out 1.4s both',
        }}>compie <b style={{fontFamily:'"DM Serif Display", serif', fontStyle:'italic', fontSize:26, color:'#B85AAC', fontWeight:'normal'}}>{data.eta || '?'}</b> anni</div>

        {/* balloons */}
        <svg viewBox="0 0 100 130" style={{
          position:'absolute', right:'-3%', bottom:'14%', width:'25%',
          animation:'wowBalloonRise 1s ease-out 1.0s both', zIndex:3,
        }}>
          <line x1="32" y1="55" x2="36" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <line x1="58" y1="40" x2="58" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <line x1="78" y1="60" x2="74" y2="120" stroke="#9D7BB5" strokeWidth="0.8"/>
          <ellipse cx="32" cy="40" rx="18" ry="22" fill="#B07CE8"/>
          <ellipse cx="58" cy="26" rx="18" ry="22" fill="#FF9FCC"/>
          <ellipse cx="78" cy="44" rx="16" ry="20" fill="#7CD9C8"/>
        </svg>

        <InfoStrip data={data} accent="#B85AAC"/>
      </div>
    </Tilt3D>
  );
}

// ════════════════════════════════════════════════
// LAYOUT 4 · POLAROID (tipografico)
// ════════════════════════════════════════════════
function LayoutPolaroid({ theme, data }) {
  const p = theme.palette;
  const nome = (data.nome || 'Nome').trim();
  return (
    <Tilt3D>
      <div style={{
        position:'absolute', inset:0, overflow:'hidden', borderRadius:'inherit',
        background:'radial-gradient(ellipse 70% 50% at 30% 20%, #FFEFC9 0%, transparent 60%), radial-gradient(ellipse 70% 50% at 80% 80%, #C7E8C2 0%, transparent 60%), linear-gradient(180deg, #FFF8E8, #F2F4DE)',
        fontFamily:'"Plus Jakarta Sans", sans-serif', color:'#2D3621',
      }}>
        {/* Arc text */}
        <svg viewBox="0 0 300 60" style={{
          position:'absolute', left:'50%', top:'5%', transform:'translateX(-50%)', width:'84%', height:42,
          animation:'wowFadeUp 0.8s ease-out 0.3s both', zIndex:3,
        }}>
          <defs><path id="arcP4" d="M 20 50 Q 150 -10 280 50" fill="none"/></defs>
          <text fontFamily="Fraunces, serif" fontSize="22" fontWeight="700" fontStyle="italic" fill="#5DA34D">
            <textPath href="#arcP4" startOffset="50%" textAnchor="middle">Happy Birthday!</textPath>
          </text>
        </svg>

        {/* Polaroid */}
        <div style={{
          position:'absolute', left:'50%', top:'18%', transform:'translate(-50%,0) rotate(-3deg)',
          width:'66%', background:'#fff', padding:'8px 8px 30px',
          boxShadow:'0 4px 8px rgba(45,36,56,0.12), 0 16px 32px rgba(45,36,56,0.16)',
          animation:'wowPolDrop 0.9s cubic-bezier(0.34,1.5,0.64,1) 0.5s both', zIndex:4,
        }}>
          <div style={{ width:'100%', aspectRatio:'1', position:'relative', overflow:'hidden' }}>
            <PhotoOrPlaceholder data={data} theme={theme} shape="square"/>
          </div>
          {/* age sticker */}
          <div style={{
            position:'absolute', right:-10, top:-10, width:42, height:42, borderRadius:'50%',
            background:'#FFA13D', color:'#fff', border:'3px solid #fff',
            display:'flex', alignItems:'center', justifyContent:'center',
            fontFamily:'"DM Serif Display", serif', fontStyle:'italic', fontSize:20,
            boxShadow:'0 3px 6px rgba(45,36,56,0.18)', transform:'rotate(8deg)',
            animation:'wowBurstIn 0.6s cubic-bezier(0.34,1.6,0.64,1) 1.0s both', zIndex:5,
          }}>{data.eta || '?'}</div>
          {/* caption */}
          <div style={{
            marginTop:7, textAlign:'center', fontFamily:'"Caveat", cursive', fontWeight:700,
            fontSize:24, color:'#2D3621', lineHeight:1,
            animation:'wowFadeUp 0.7s ease-out 1.1s both',
          }}>{nome}</div>
        </div>

        {/* washi tape */}
        <div style={{
          position:'absolute', top:'16%', left:'18%', width:60, height:14,
          background:'repeating-linear-gradient(45deg, #E89B5A 0 5px, #FFD89A 5px 10px)',
          transform:'rotate(-12deg)', opacity:0.85, zIndex:5,
          animation:'wowFadeUp 0.5s ease-out 0.8s both',
        }}/>

        <InfoStrip data={data} accent="#5DA34D" animDelay={1.3}/>
      </div>
    </Tilt3D>
  );
}

// Inject CSS keyframes once
(function injectKeyframes(){
  if (document.getElementById('wow-v3-kf')) return;
  const s = document.createElement('style');
  s.id = 'wow-v3-kf';
  s.textContent = `
    @keyframes wowFoilShift { 0%,100% {background-position:0% 50%} 50% {background-position:100% 50%} }
    @keyframes wowPhotoIn { 0%{transform:translateX(-50%) scale(0.5) rotate(-10deg);opacity:0} 60%{transform:translateX(-50%) scale(1.08) rotate(2deg);opacity:1} 100%{transform:translateX(-50%) scale(1) rotate(0);opacity:1} }
    @keyframes wowHatDrop { 0%{transform:translateX(-50%) translateY(-50px) rotate(-30deg);opacity:0} 100%{transform:translateX(-50%) translateY(0) rotate(-12deg);opacity:1} }
    @keyframes wowNameDrop { 0%{transform:translateY(-30px) scale(0.5);opacity:0} 60%{transform:translateY(6px) scale(1.15);opacity:1} 100%{transform:translateY(0) scale(1);opacity:1} }
    @keyframes wowLetterFloat { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-4px)} }
    @keyframes wowBalloonRise { 0%{transform:translateY(40px);opacity:0} 100%{transform:translateY(0);opacity:1} }
    @keyframes wowScaleIn { 0%{transform:scale(0.5);opacity:0} 60%{transform:scale(1.06);opacity:1} 100%{transform:scale(1);opacity:1} }
    @keyframes wowBurstIn { 0%{transform:scale(0) rotate(-180deg);opacity:0} 60%{transform:scale(1.15) rotate(15deg);opacity:1} 100%{transform:scale(1) rotate(0);opacity:1} }
    @keyframes wowPolDrop { 0%{transform:translate(-50%,-30px) rotate(-12deg);opacity:0} 60%{transform:translate(-50%,4px) rotate(-1deg);opacity:1} 100%{transform:translate(-50%,0) rotate(-3deg);opacity:1} }
    @keyframes wowParticleUp { 0%{transform:translate(0,0) scale(0);opacity:0} 10%{opacity:1;transform:translate(0,-40px) scale(1)} 90%{opacity:1} 100%{transform:translate(var(--xd,0),-560px) scale(0);opacity:0} }
    @keyframes wowConfettiBurst { 0%{transform:translate(-50%,-50%) scale(0);opacity:0} 10%{opacity:1} 100%{transform:translate(var(--dx),var(--dy)) rotate(var(--rot));opacity:0} }
  `;
  document.head.appendChild(s);
})();

window.LAYOUTS = [
  { id: 'poster', name: 'Acquerello', component: LayoutAcquerello },
  { id: 'riso', name: 'Cornice', component: LayoutCornice },
  { id: 'illustrato', name: 'Festa', component: LayoutFesta },
  { id: 'tipografico', name: 'Polaroid', component: LayoutPolaroid },
];

window.Invitation = function Invitation({ themeId, layoutId, data }) {
  const theme = window.THEMES[themeId] || Object.values(window.THEMES)[0];
  const layout = window.LAYOUTS.find(l => l.id === layoutId) || window.LAYOUTS[0];
  const C = layout.component;
  return <C theme={theme} data={data} />;
};
