// js/tokens.jsx — Equilys design tokens + signature SVG primitives
// Exposes: PALETTES, TYPESETS, DENSITIES, Enso, CircuitOrnament, BrushSplash,
//          VerticalAxis, GoldRule, applyTheme(), useTheme()

const PALETTES = {
  nuit: {
    label: 'Nuit',
    bg: '#1A2735',
    surface: '#1F2E3E',
    surfaceAlt: '#243446',
    ink: '#F1ECDF',
    inkSoft: '#C9C2B0',
    inkMuted: '#8A95A2',
    gold: '#D4B673',
    goldSoft: '#B79856',
    line: 'rgba(241,236,223,0.12)',
    lineSoft: 'rgba(241,236,223,0.06)',
    inkOnGold: '#1A2735',
    cardShadow: '0 1px 0 rgba(255,255,255,.05) inset, 0 24px 60px -20px rgba(0,0,0,0.6)'
  },
  ardoise: {
    label: 'Ardoise',
    // Gris-bleu prélevé du brush droit du logo Equilys (#7F90A3)
    bg: '#7F90A3',
    surface: '#8B9CAF',
    surfaceAlt: '#97A7B8',
    ink: '#F4EFE2',
    inkSoft: 'rgba(244,239,226,0.82)',
    inkMuted: 'rgba(244,239,226,0.6)',
    gold: '#D9B774',
    goldSoft: '#E8CC8E',
    line: 'rgba(244,239,226,0.22)',
    lineSoft: 'rgba(244,239,226,0.10)',
    inkOnGold: '#2A3D4D',
    cardShadow: '0 1px 0 rgba(255,255,255,.10) inset, 0 24px 60px -20px rgba(42,61,77,0.4)'
  }
};

const TYPESETS = {
  editorial: {
    label: 'Éditoriale',
    display: '"Cormorant Garamond", "EB Garamond", Garamond, serif',
    body: '"DM Sans", system-ui, sans-serif',
    mono: '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 500,
    displayTracking: '0.04em',
    bodyWeight: 400,
    displayCase: 'none'
  },
  ceremonial: {
    label: 'Cérémonielle',
    display: '"Cinzel", serif',
    body: '"DM Sans", system-ui, sans-serif',
    mono: '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 500,
    displayTracking: '0.12em',
    bodyWeight: 400,
    displayCase: 'uppercase'
  },
  modern: {
    label: 'Moderne',
    display: '"DM Sans", system-ui, sans-serif',
    body: '"DM Sans", system-ui, sans-serif',
    mono: '"JetBrains Mono", ui-monospace, monospace',
    displayWeight: 300,
    displayTracking: '-0.01em',
    bodyWeight: 400,
    displayCase: 'none'
  }
};

const DENSITIES = {
  aere: { label: 'Aéré', sectionPad: 160, gap: 28, base: 16 },
  riche: { label: 'Riche', sectionPad: 96, gap: 18, base: 15 }
};

// Build the in-frame CSS variables so all components can use them.
function themeVars(paletteKey, typoKey, densityKey) {
  const p = PALETTES[paletteKey] || PALETTES.ivoire;
  const t = TYPESETS[typoKey] || TYPESETS.editorial;
  const d = DENSITIES[densityKey] || DENSITIES.aere;
  return {
    '--eq-bg': p.bg,
    '--eq-surface': p.surface,
    '--eq-surface-alt': p.surfaceAlt,
    '--eq-ink': p.ink,
    '--eq-ink-soft': p.inkSoft,
    '--eq-ink-muted': p.inkMuted,
    '--eq-gold': p.gold,
    '--eq-gold-soft': p.goldSoft,
    '--eq-line': p.line,
    '--eq-line-soft': p.lineSoft,
    '--eq-ink-on-gold': p.inkOnGold,
    '--eq-card-shadow': p.cardShadow,
    '--eq-font-display': t.display,
    '--eq-font-body': t.body,
    '--eq-font-mono': t.mono,
    '--eq-display-weight': t.displayWeight,
    '--eq-display-tracking': t.displayTracking,
    '--eq-body-weight': t.bodyWeight,
    '--eq-display-case': t.displayCase,
    '--eq-section-pad': d.sectionPad + 'px',
    '--eq-gap': d.gap + 'px',
    '--eq-base': d.base + 'px'
  };
}

// Wrap any artboard contents to lock in theme tokens and base text styles.
function ThemeFrame({ palette, typo, density, motifOpacity = 0.55, motifScale = 1,
  smokeDHero = -40, smokeDContact = -200, smokeMHero = -30, smokeMContact = -30,
  fxBtn = true, fxCard = true, fxLink = true, heroLogoSpin = 120,
  children, style, className, fullBleed = true }) {
  const vars = themeVars(palette, typo, density);
  const cls = [className, fxBtn ? 'eq-fx-btn' : '', fxCard ? 'eq-fx-card' : '', fxLink ? 'eq-fx-link' : '']
    .filter(Boolean).join(' ');
  return (
    <div
      className={cls}
      style={{
        ...vars,
        '--eq-motif-opacity': motifOpacity,
        '--eq-motif-scale': motifScale,
        '--eq-smoke-d-hero': smokeDHero + 'px',
        '--eq-smoke-d-contact': smokeDContact + 'px',
        '--eq-smoke-m-hero': smokeMHero + 'px',
        '--eq-smoke-m-contact': smokeMContact + 'px',
        '--eq-logo-spin-dur': heroLogoSpin + 's',
        background: 'var(--eq-bg)',
        color: 'var(--eq-ink)',
        fontFamily: 'var(--eq-font-body)',
        fontWeight: 'var(--eq-body-weight)',
        fontSize: 'var(--eq-base)',
        lineHeight: 1.55,
        minHeight: fullBleed ? '100%' : 'auto',
        position: 'relative',
        ...style, backgroundColor: "rgb(41, 51, 72)"
      }}>
      
      {children}
    </div>);

}

// ── Signature mark: stylised Ensō with vertical axis of points ─────────────
function Enso({ size = 120, color = 'currentColor', accent, animated = false, strokeW = 3 }) {
  const acc = accent || color;
  const id = React.useId();
  return (
    <svg width={size} height={size} viewBox="0 0 120 120" fill="none" aria-hidden="true">
      <defs>
        <linearGradient id={`enso-${id}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.95" />
          <stop offset="55%" stopColor={color} stopOpacity="0.75" />
          <stop offset="100%" stopColor={acc} stopOpacity="0.95" />
        </linearGradient>
        <linearGradient id={`enso-acc-${id}`} x1="0" y1="1" x2="1" y2="0">
          <stop offset="0%" stopColor={acc} stopOpacity="0" />
          <stop offset="60%" stopColor={acc} stopOpacity="0.7" />
          <stop offset="100%" stopColor={acc} stopOpacity="0.95" />
        </linearGradient>
      </defs>
      {/* main ensō arc */}
      <path
        d="M 92 28 A 44 44 0 1 0 95 90"
        stroke={`url(#enso-${id})`}
        strokeWidth={strokeW}
        strokeLinecap="round"
        fill="none">
        
        {animated &&
        <animate attributeName="stroke-dasharray" from="0 300" to="280 300" dur="1.8s" fill="freeze" />
        }
      </path>
      {/* gold inner accent stroke */}
      <path
        d="M 30 84 Q 22 60 35 38"
        stroke={`url(#enso-acc-${id})`}
        strokeWidth={strokeW * 0.9}
        strokeLinecap="round"
        fill="none"
        opacity="0.85" />
      
      {/* small ink kick top-right (brush flick) */}
      <path
        d="M 92 28 q 4 -4 9 -3"
        stroke={color}
        strokeWidth={strokeW * 0.7}
        strokeLinecap="round"
        fill="none"
        opacity="0.7" />
      
      {/* vertical axis of points (colonne énergétique) */}
      <g>
        <circle cx="60" cy="32" r="2.4" fill={color} />
        <circle cx="60" cy="44" r="1.8" fill={color} opacity="0.7" />
        <circle cx="60" cy="56" r="3.2" fill={acc} />
        <line x1="50" y1="60" x2="70" y2="60" stroke={acc} strokeWidth="1" opacity="0.7" />
        <circle cx="60" cy="64" r="2.2" fill={color} opacity="0.85" />
        <circle cx="60" cy="76" r="1.8" fill={color} opacity="0.7" />
        <circle cx="60" cy="88" r="2.4" fill={color} />
      </g>
    </svg>);

}

// ── Decorative circuit lines (pragmatic / patrimoine side) ─────────────────
function CircuitOrnament({ width = 220, height = 220, color = 'currentColor', opacity = 0.45 }) {
  const id = React.useId();
  return (
    <svg width={width} height={height} viewBox="0 0 220 220" fill="none" aria-hidden="true"
    style={{ opacity }}>
      <defs>
        <linearGradient id={`circ-${id}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.0" />
          <stop offset="40%" stopColor={color} stopOpacity="0.6" />
          <stop offset="100%" stopColor={color} stopOpacity="0.95" />
        </linearGradient>
      </defs>
      <g stroke={`url(#circ-${id})`} strokeWidth="0.8" fill="none">
        <path d="M 10 110 L 60 110 L 60 60 L 110 60" />
        <path d="M 10 150 L 50 150 L 50 190 L 90 190" />
        <path d="M 10 70 L 40 70 L 40 30 L 90 30" />
        <path d="M 110 60 L 150 60 L 150 100 L 210 100" />
        <path d="M 90 190 L 130 190 L 130 150 L 180 150" />
        <path d="M 60 110 L 100 110 L 100 140 L 140 140" />
      </g>
      <g fill={color}>
        <circle cx="10" cy="110" r="1.6" opacity="0.6" />
        <circle cx="60" cy="60" r="2.4" />
        <circle cx="110" cy="60" r="1.6" opacity="0.7" />
        <circle cx="50" cy="150" r="1.6" opacity="0.6" />
        <circle cx="90" cy="190" r="2.4" />
        <circle cx="40" cy="30" r="1.6" opacity="0.5" />
        <circle cx="150" cy="100" r="2" opacity="0.8" />
        <circle cx="100" cy="140" r="1.6" opacity="0.6" />
        <circle cx="180" cy="150" r="2.4" />
      </g>
    </svg>);

}

// ── Smoke motif (encre / fumée) — texture utilisateur ─────────────────────
// Image PNG préparée avec fond transparent. Le composant accepte rotate
// (entier en degrés) et flip (boolean) pour la varier selon l'emplacement.
// Conserve le nom BrushSplash pour rester drop-in dans le reste du code.
function BrushSplash({ width = 260, height = 260, color = 'currentColor', opacity, rotate = 0, flip = false }) {
  return (
    <img
      src="assets/smoke-motif.png"
      alt=""
      aria-hidden="true"
      style={{
        width, height, objectFit: 'contain', objectPosition: 'center',
        display: 'block', pointerEvents: 'none',
        opacity: opacity != null ? opacity : 'var(--eq-motif-opacity, 0.55)',
        transform: `${flip ? 'scaleX(-1)' : ''} rotate(${rotate}deg) scale(var(--eq-motif-scale, 1))`,
        transformOrigin: 'center',
      }}
    />
  );
}

// ── Vertical axis of points (colonne énergétique) ──────────────────────────
function VerticalAxis({ height = 200, color = 'currentColor', accent, points = 7, withDash = true }) {
  const acc = accent || color;
  const dots = [];
  for (let i = 0; i < points; i++) {
    const y = (i + 0.5) * (height / points);
    const isCenter = i === Math.floor(points / 2);
    dots.push(
      <circle key={i} cx="6" cy={y} r={isCenter ? 3.2 : 2}
      fill={isCenter ? acc : color}
      opacity={isCenter ? 1 : 0.55 + 0.35 * (1 - Math.abs(i - points / 2) / (points / 2))} />
    );
  }
  return (
    <svg width="12" height={height} viewBox={`0 0 12 ${height}`} fill="none" aria-hidden="true">
      {withDash &&
      <line x1="6" y1="0" x2="6" y2={height} stroke={color} strokeWidth="0.6"
      strokeDasharray="1 3" opacity="0.35" />
      }
      {dots}
    </svg>);

}

// ── Hair-line gold rule with central dot (separator) ───────────────────────
function GoldRule({ width = 220, color = 'var(--eq-gold)' }) {
  return (
    <svg width={width} height="10" viewBox={`0 0 ${width} 10`} fill="none" aria-hidden="true">
      <line x1="0" y1="5" x2={width / 2 - 8} y2="5" stroke={color} strokeWidth="0.8" opacity="0.7" />
      <circle cx={width / 2} cy="5" r="2.2" fill={color} />
      <line x1={width / 2 + 8} y1="5" x2={width} y2="5" stroke={color} strokeWidth="0.8" opacity="0.7" />
    </svg>);

}

// ── Eyebrow label (small mono caps, gold dot) ──────────────────────────────
function Eyebrow({ children, color = 'var(--eq-gold)', style }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      fontFamily: 'var(--eq-font-mono)', fontSize: 11, letterSpacing: '0.22em',
      textTransform: 'uppercase', color: 'var(--eq-ink-soft)',
      ...style
    }}>
      <span style={{ width: 6, height: 6, borderRadius: 99, background: color, flex: '0 0 auto' }} />
      <span>{children}</span>
    </div>);

}

// ── Real Equilys logo — PNG transparent, sans fond, sans cadre ────────────
// Le symbole vit directement sur la palette du site.
// `spinning` : si vrai, le symbole tourne lentement (réservé au hero).
function LogoMark({ size = 40, style, spinning = false }) {
  return (
    <img
      src="assets/logo-equilys-transparent.png"
      alt="Equilys"
      aria-label="Equilys"
      style={{
        display: 'inline-block', flex: '0 0 auto',
        width: size, height: size,
        objectFit: 'cover', objectPosition: 'center',
        animation: spinning ? 'eq-logo-spin 90s linear infinite' : undefined,
        transformOrigin: '50% 50%',
        ...style
      }} />
  );
}

// ── LogoMarkAura — Halo calligraphique autour du logo réel ────────────────
// Variante "hybride" mêlant le motif procédural d'origine et le logo réel.
// Le PNG occupe tout le cadre demandé ; le halo (arc d'ensō + accents +
// points or) s'étend à l'extérieur pour ne pas réduire la lisibilité.
function LogoMarkAura({ size = 40, style }) {
  const id = React.useId();
  const halo = Math.round(size * 1.22);
  return (
    <span aria-label="Equilys" role="img" style={{
      position: 'relative', display: 'inline-block', flex: '0 0 auto',
      width: size, height: size, ...style
    }}>
      {/* Real logo, full size of the slot */}
      <img
        src="assets/logo-equilys-transparent.png"
        alt=""
        style={{
          position: 'absolute', inset: 0,
          width: '100%', height: '100%',
          objectFit: 'contain', objectPosition: 'center',
          zIndex: 1
        }} />
      {/* Calligraphic ensō halo, drawn OUTSIDE the logo area */}
      <svg viewBox="0 0 144 144" width={halo} height={halo} fill="none" aria-hidden="true"
        style={{
          position: 'absolute',
          inset: '50% auto auto 50%',
          transform: 'translate(-50%,-50%)',
          pointerEvents: 'none'
        }}>
        <defs>
          <linearGradient id={`aura-${id}`} x1="0" y1="0" x2="1" y2="1">
            <stop offset="0%" stopColor="var(--eq-ink)" stopOpacity="0.9" />
            <stop offset="55%" stopColor="var(--eq-gold)" stopOpacity="0.9" />
            <stop offset="100%" stopColor="var(--eq-ink)" stopOpacity="0.6" />
          </linearGradient>
          <linearGradient id={`aura2-${id}`} x1="0" y1="1" x2="1" y2="0">
            <stop offset="0%" stopColor="var(--eq-gold)" stopOpacity="0" />
            <stop offset="60%" stopColor="var(--eq-gold)" stopOpacity="0.85" />
            <stop offset="100%" stopColor="var(--eq-gold)" stopOpacity="0.95" />
          </linearGradient>
        </defs>
        {/* Outer brushed arc (calligraphic ensō) — radius 64 around center 72,72 */}
        <path d="M 122 38 A 64 64 0 1 0 122 110"
          stroke={`url(#aura-${id})`} strokeWidth="2.4"
          strokeLinecap="round" fill="none" />
        {/* Brush flick at start */}
        <path d="M 122 38 q 5 -3 10 -2"
          stroke="var(--eq-ink)" strokeWidth="1.8"
          strokeLinecap="round" fill="none" opacity="0.85" />
        {/* Inner gold accent stroke on the left */}
        <path d="M 22 96 Q 12 72 28 46"
          stroke={`url(#aura2-${id})`} strokeWidth="1.8"
          strokeLinecap="round" fill="none" opacity="0.85" />
        {/* Vertical axis of points — colonne énergétique */}
        <g>
          <circle cx="72" cy="4"   r="1.8" fill="var(--eq-ink)"  opacity="0.5" />
          <circle cx="72" cy="11"  r="2.6" fill="var(--eq-gold)" />
          <circle cx="72" cy="133" r="2.6" fill="var(--eq-gold)" />
          <circle cx="72" cy="140" r="1.8" fill="var(--eq-ink)"  opacity="0.5" />
        </g>
      </svg>
    </span>
  );
}

// Lockup — symbole transparent, sans cartouche
function LogoLockup({ width = 200, style }) {
  return (
    <img
      src="assets/logo-equilys-transparent.png"
      alt="Equilys"
      style={{
        display: 'block', width, height: 'auto', objectFit: 'contain',
        ...style
      }} />);


}

// Expose to other scripts
// Empêcher le scroll horizontal sans casser position:sticky
if (typeof document !== 'undefined') {
  document.documentElement.style.overflowX = 'clip';
}

Object.assign(window, {
  PALETTES, TYPESETS, DENSITIES, themeVars,
  ThemeFrame, Enso, CircuitOrnament, BrushSplash, VerticalAxis, GoldRule, Eyebrow,
  LogoMark, LogoMarkAura, LogoLockup
});