// 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 (
{children}
); } // ── 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 ( ); } // ── Decorative circuit lines (pragmatic / patrimoine side) ───────────────── function CircuitOrnament({ width = 220, height = 220, color = 'currentColor', opacity = 0.45 }) { const id = React.useId(); return ( ); } // ── 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 ( ); } // ── 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( ); } return ( ); } // ── Hair-line gold rule with central dot (separator) ─────────────────────── function GoldRule({ width = 220, color = 'var(--eq-gold)' }) { return ( ); } // ── Eyebrow label (small mono caps, gold dot) ────────────────────────────── function Eyebrow({ children, color = 'var(--eq-gold)', style }) { return (
{children}
); } // ── 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 ( Equilys ); } // ── 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 ( {/* Real logo, full size of the slot */} {/* Calligraphic ensō halo, drawn OUTSIDE the logo area */} ); } // Lockup — symbole transparent, sans cartouche function LogoLockup({ width = 200, style }) { return ( Equilys); } // 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 });