// theme.jsx — Paleta "Mitla" + tipografías + motivos zapotecos de la etiqueta de mezcal.
// Exporta a window: T, Micro, Greca, StepDiamond, AgaveMark, Reveal, Rule, injectThemeCSS.

const T = {
  bg:     '#ece3cf', // crema
  paper:  '#efe7d4', // papel
  card:   '#f3ecdb', // tarjeta (un punto más clara)
  ink:    '#2c4632', // verde agave oscuro
  soft:   '#5a6e54', // verde suave
  accent: '#b1542e', // terracota
  deep:   '#22351f', // verde profundo (pie / overlays)
  line:   'rgba(44,70,50,0.22)',
  display: "'Cormorant Garamond', serif",
  micro:   "'Barlow Semi Condensed', sans-serif",
};

// textura de papel sutil (idéntica a la etiqueta)
const GRAIN = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E\")";

function injectThemeCSS() {
  if (document.getElementById('__inviteTheme')) return;
  const s = document.createElement('style');
  s.id = '__inviteTheme';
  s.textContent = `
    *{margin:0;padding:0;box-sizing:border-box;}
    html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;}
    body{background:${T.bg};color:${T.ink};font-family:${T.micro};
      background-image:${GRAIN};font-weight:500;
      -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden;}
    ::selection{background:${T.accent}33;}
    a{color:inherit;}
    .serif{font-family:${T.display};}
    .ital{font-family:${T.display};font-style:italic;}
    .micro{font-family:${T.micro};text-transform:uppercase;letter-spacing:.24em;font-weight:600;}
    /* scroll reveal */
    .rv{opacity:0;transform:translateY(26px);transition:opacity 1s cubic-bezier(.2,.7,.2,1),transform 1s cubic-bezier(.2,.7,.2,1);will-change:opacity,transform;}
    .rv.in{opacity:1;transform:none;}
    @media (prefers-reduced-motion:reduce){.rv{opacity:1!important;transform:none!important;transition:none!important;}}
    /* image-slot look */
    image-slot{--is-bg:${T.card};--is-fg:${T.soft};--is-border:${T.line};display:block;}
    .lnk{text-decoration:none;border-bottom:1px solid ${T.accent}66;transition:border-color .3s,color .3s;}
    .lnk:hover{border-color:${T.accent};color:${T.accent};}
    input,select,textarea,button{font-family:${T.micro};}
  `;
  document.head.appendChild(s);
}

function Micro({ children, size = 11, ls = '.24em', color = T.soft, weight = 600, as = 'div', style }) {
  const Tag = as;
  return (
    <Tag style={{ fontFamily: T.micro, fontSize: size, letterSpacing: ls, textTransform: 'uppercase',
      fontWeight: weight, color, lineHeight: 1.5, ...style }}>{children}</Tag>
  );
}

// ——— Greca escalonada de Mitla (banda tileable) ———
let __gid = 0;
function Greca({ color = T.ink, strokeWidth = 1.5, step = 6, ups = 3, pad = 3, double = true, opacity = 0.85, style }) {
  const id = React.useMemo(() => `gr-${__gid++}`, []);
  const h = ups * step;
  const period = 2 * ups * step;
  let d = `M0 ${h}`, x = 0, y = h;
  for (let i = 0; i < ups; i++) { x += step; d += ` L${x} ${y}`; y -= step; d += ` L${x} ${y}`; }
  for (let i = 0; i < ups; i++) { x += step; d += ` L${x} ${y}`; y += step; d += ` L${x} ${y}`; }
  const totalH = h + pad * 2;
  return (
    <svg width="100%" height={totalH} style={{ display: 'block', opacity, ...style }} preserveAspectRatio="none">
      <defs>
        <pattern id={id} patternUnits="userSpaceOnUse" width={period} height={totalH}>
          <g transform={`translate(0 ${pad})`}>
            <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinejoin="miter" strokeLinecap="square" />
            {double && <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinejoin="miter"
              strokeLinecap="square" transform={`translate(${period / 2} 0)`} opacity="0.45" />}
          </g>
        </pattern>
      </defs>
      <rect width="100%" height={totalH} fill={`url(#${id})`} />
    </svg>
  );
}

function StepDiamond({ size = 22, color = T.accent, stroke = 1.6, fill = 'none' }) {
  const s = size / 6;
  const pts = [[3,0],[4,1],[5,2],[6,3],[5,4],[4,5],[3,6],[2,5],[1,4],[0,3],[1,2],[2,1]]
    .map(([a,b]) => `${a*s},${b*s}`).join(' ');
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>
      <polygon points={pts} fill={fill} stroke={color} strokeWidth={stroke} strokeLinejoin="miter" />
      <line x1={size*0.5} y1={size*0.28} x2={size*0.5} y2={size*0.72} stroke={color} strokeWidth={stroke*0.7} />
      <line x1={size*0.28} y1={size*0.5} x2={size*0.72} y2={size*0.5} stroke={color} strokeWidth={stroke*0.7} />
    </svg>
  );
}

function AgaveMark({ size = 84, color = T.ink, blades = 11, sw = 1.4 }) {
  const cx = size / 2, baseY = size * 0.92, spread = 78, arr = [];
  for (let i = 0; i < blades; i++) {
    const t = blades === 1 ? 0.5 : i / (blades - 1);
    const ang = (-spread + t * spread * 2) * Math.PI / 180;
    const lenFactor = 0.62 + 0.38 * (1 - Math.abs(t - 0.5) * 2) ** 0.9;
    const len = size * 0.82 * lenFactor;
    const tipX = cx + Math.sin(ang) * len, tipY = baseY - Math.cos(ang) * len;
    const w = size * 0.045 * (0.7 + 0.3 * (1 - Math.abs(t - 0.5) * 2));
    const perp = ang + Math.PI / 2;
    const bx1 = cx + Math.cos(perp) * w, by1 = baseY + Math.sin(perp) * w;
    const bx2 = cx - Math.cos(perp) * w, by2 = baseY - Math.sin(perp) * w;
    arr.push(<polygon key={i} points={`${bx1.toFixed(1)},${by1.toFixed(1)} ${tipX.toFixed(1)},${tipY.toFixed(1)} ${bx2.toFixed(1)},${by2.toFixed(1)}`}
      fill="none" stroke={color} strokeWidth={sw} strokeLinejoin="round" />);
  }
  return <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>{arr}</svg>;
}

// divider con rombo escalonado al centro
function Rule({ width = 220, color = T.line, diamond = T.accent, dSize = 20, style }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, width: `min(${width}px, 78%)`, ...style, marginLeft: 'auto', marginRight: 'auto' }}>
      <div style={{ flex: 1, height: 1, background: color }} />
      <StepDiamond size={dSize} color={diamond} />
      <div style={{ flex: 1, height: 1, background: color }} />
    </div>
  );
}

// Reveal por scroll (IntersectionObserver compartido)
let __io;
function getIO() {
  if (__io) return __io;
  __io = new IntersectionObserver((entries) => {
    entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('in'); __io.unobserve(e.target); } });
  }, { threshold: 0.08, rootMargin: '0px 0px -6% 0px' });
  return __io;
}
// Red de seguridad: si por cualquier razón el observer no dispara (viewport raro,
// JS lento, etc.), revela todo lo pendiente para que nunca quede contenido oculto.
if (typeof window !== 'undefined' && !window.__rvSafety) {
  window.__rvSafety = true;
  const reveal = () => document.querySelectorAll('.rv:not(.in)').forEach((el) => el.classList.add('in'));
  setTimeout(reveal, 2000);
  window.addEventListener('load', () => setTimeout(reveal, 1500));
}
function Reveal({ children, delay = 0, as = 'div', className = '', style }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    el.style.transitionDelay = (delay || 0) + 'ms';
    getIO().observe(el);
  }, [delay]);
  const Tag = as;
  return <Tag ref={ref} className={`rv ${className}`} style={style}>{children}</Tag>;
}

Object.assign(window, { T, GRAIN, injectThemeCSS, Micro, Greca, StepDiamond, AgaveMark, Rule, Reveal });
