// Shared UI primitives for MLS Conseil landing
const { useState, useEffect, useRef, useMemo } = React;
// ---- Logo --------------------------------------------------------------
function Logo({ light = false, size = 1 }) {
const ink = light ? '#F4EEE2' : '#14223D';
return (
MLS Conseil
Gestion · Trésorerie
);
}
// ---- Buttons -----------------------------------------------------------
function PrimaryButton({ children, onClick, light = false, icon = true, size = 'md' }) {
const [hover, setHover] = useState(false);
const pad = size === 'lg' ? '18px 28px' : size === 'sm' ? '10px 18px' : '14px 22px';
const fs = size === 'lg' ? 16 : size === 'sm' ? 13 : 14.5;
const bg = light ? '#F4EEE2' : '#14223D';
const fg = light ? '#14223D' : '#F4EEE2';
return (
);
}
function GhostButton({ children, onClick, light=false, underline=true }) {
const [hover, setHover] = useState(false);
const fg = light ? '#F4EEE2' : '#14223D';
return (
);
}
// ---- Section frame -----------------------------------------------------
function Section({ children, bg, py = 120, id, label, style = {} }) {
return (
{label && {label}}
{children}
);
}
function SectionLabel({ children, accent = '#C9A961' }) {
return (
{children}
);
}
// ---- Variant tag (for the 3 hero versions) -----------------------------
function VariantTag({ n, title }) {
return (
Variante {n} · Hero
{title}
);
}
// ---- Eyebrow / pill ----------------------------------------------------
function Pill({ children, dark=false, icon }) {
return (
{icon || }
{children}
);
}
// ---- Mini sparkline / chart helpers (SVG) ------------------------------
function buildPath(values, w, h, padX=4, padY=8) {
if (!values.length) return '';
const min = Math.min(...values), max = Math.max(...values);
const range = max - min || 1;
const stepX = (w - padX*2) / (values.length - 1);
const pts = values.map((v,i)=>[padX + i*stepX, padY + (h - padY*2) * (1 - (v-min)/range)]);
// smooth curve
let d = `M ${pts[0][0]} ${pts[0][1]}`;
for (let i=1; i