// 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 (
m
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