);
}
// ============================================================
// Buttons
// ============================================================
function Button({ as: As = 'a', variant = 'primary', size = 'md', icon, className = '', children, ...rest }) {
const base = 'inline-flex items-center justify-center gap-2 font-semibold rounded-full transition-all duration-300 will-change-transform';
const sizes = {
sm: 'px-4 py-2 text-[13px]',
md: 'px-5 py-3 text-[14px]',
lg: 'px-7 py-4 text-[15px]'
};
const variants = {
primary: 'bg-grad-turq text-white shadow-[0_10px_24px_-10px_rgba(30,199,230,0.65)] hover:shadow-[0_18px_36px_-12px_rgba(30,199,230,0.75)] hover:-translate-y-0.5',
petrol: 'bg-petrol text-white hover:bg-petrol-600 shadow-[0_10px_24px_-12px_rgba(10,91,126,0.55)] hover:-translate-y-0.5',
accent: 'bg-accent text-white hover:bg-accent-600 shadow-[0_10px_24px_-12px_rgba(215,48,69,0.55)] hover:-translate-y-0.5',
ghost: 'bg-white text-petrol border border-ink-200 hover:border-petrol/40 hover:text-petrol-800 hover:-translate-y-0.5',
outline: 'bg-transparent text-petrol border border-petrol/30 hover:bg-petrol hover:text-white',
soft: 'bg-turq-100 text-petrol hover:bg-turq-100/70',
onDark: 'bg-white text-petrol-900 hover:bg-turq-100 hover:-translate-y-0.5',
onDarkGhost: 'bg-transparent text-white border border-white/30 hover:bg-white/10'
};
return (
{children}
{icon && {icon}}
);
}
// ============================================================
// Lucide-style icons (inline SVG, no external dep)
// ============================================================
const Ic = {
base: { width: 22, height: 22, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round' }
};
function Icon({ name, size = 22, className = '', strokeWidth = 1.8 }) {
const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round', className };
switch (name) {
case 'foot':
return ;
case 'spine':
return ;
case 'knee':
return ;
case 'walk':
return ;
case 'posture':
return ;
case 'activity':
return ;
case 'heart':
return ;
case 'shield':
return ;
case 'sparkle':
return ;
case 'balance':
return ;
case 'check':
return ;
case 'arrow':
return ;
case 'whatsapp':
return ;
case 'phone':
return ;
case 'mail':
return ;
case 'pin':
return ;
case 'clock':
return ;
case 'menu':
return ;
case 'x':
return ;
case 'plus':
return ;
case 'chev':
return ;
case 'star':
return ;
case 'instagram':
return ;
case 'facebook':
return ;
case 'yt':
return ;
case 'scan':
return ;
case 'layers':
return ;
case 'cpu':
return ;
case 'target':
return ;
case 'send':
return ;
default:
return null;
}
}
// ============================================================
// FOOT + INSOLE shared path (anatomical, foot-shaped insole)
// ============================================================
// Mirrored, anatomically inspired left-foot insole outline
const INSOLE_PATH = "M120 14 C 96 14, 78 28, 70 50 C 64 68, 60 86, 58 110 C 56 134, 54 160, 56 184 C 58 208, 60 232, 66 254 C 72 274, 88 290, 110 294 C 130 298, 156 296, 172 286 C 184 278, 188 264, 188 246 C 188 220, 186 192, 184 168 C 182 144, 180 118, 176 92 C 172 64, 162 36, 148 24 C 140 18, 130 14, 120 14 Z";
// Real plantar foot photo (assets/pe.png, 1086x1448). Two traced silhouettes:
// FOOT_PX in image pixel coords (for the heat-overlay SVG, viewBox 0 0 1086 1448)
// FOOT_BB normalized 0..1 (for CSS clip-path on the , objectBoundingBox).
const FOOT_PX = "M 445 107 L 554 147 L 612 187 L 625 227 L 677 267 L 712 307 L 737 347 L 744 387 L 744 427 L 754 467 L 764 507 L 767 547 L 762 587 L 753 627 L 746 667 L 741 707 L 735 747 L 727 787 L 717 827 L 706 867 L 697 907 L 690 947 L 684 987 L 678 1027 L 674 1067 L 675 1107 L 673 1147 L 668 1187 L 658 1227 L 639 1267 L 602 1307 L 540 1325 L 529 1325 L 471 1307 L 433 1267 L 415 1227 L 407 1187 L 405 1147 L 406 1107 L 406 1067 L 403 1027 L 399 987 L 394 947 L 388 907 L 385 867 L 384 827 L 383 787 L 381 747 L 376 707 L 369 667 L 360 627 L 350 587 L 338 547 L 327 507 L 322 467 L 324 427 L 331 387 L 340 347 L 345 307 L 341 267 L 339 227 L 349 187 L 367 147 L 416 107 Z";
const FOOT_BB = "M 0.4098 0.0739 L 0.5101 0.1015 L 0.5635 0.1291 L 0.5755 0.1568 L 0.6234 0.1844 L 0.6556 0.2120 L 0.6786 0.2396 L 0.6851 0.2673 L 0.6851 0.2949 L 0.6943 0.3225 L 0.7035 0.3501 L 0.7063 0.3778 L 0.7017 0.4054 L 0.6934 0.4330 L 0.6869 0.4606 L 0.6823 0.4883 L 0.6768 0.5159 L 0.6694 0.5435 L 0.6602 0.5711 L 0.6501 0.5988 L 0.6418 0.6264 L 0.6354 0.6540 L 0.6298 0.6816 L 0.6243 0.7093 L 0.6206 0.7369 L 0.6215 0.7645 L 0.6197 0.7921 L 0.6151 0.8198 L 0.6059 0.8474 L 0.5884 0.8750 L 0.5543 0.9026 L 0.4972 0.9151 L 0.4871 0.9151 L 0.4337 0.9026 L 0.3987 0.8750 L 0.3821 0.8474 L 0.3748 0.8198 L 0.3729 0.7921 L 0.3738 0.7645 L 0.3738 0.7369 L 0.3711 0.7093 L 0.3674 0.6816 L 0.3628 0.6540 L 0.3573 0.6264 L 0.3545 0.5988 L 0.3536 0.5711 L 0.3527 0.5435 L 0.3508 0.5159 L 0.3462 0.4883 L 0.3398 0.4606 L 0.3315 0.4330 L 0.3223 0.4054 L 0.3112 0.3778 L 0.3011 0.3501 L 0.2965 0.3225 L 0.2983 0.2949 L 0.3048 0.2673 L 0.3131 0.2396 L 0.3177 0.2120 L 0.3140 0.1844 L 0.3122 0.1568 L 0.3214 0.1291 L 0.3379 0.1015 L 0.3831 0.0739 Z";
// Foot photo + pressure heatmap module. `id` must be unique per instance so the
// clip/gradient ids don't collide. `heat` = [{x,y,rx,ry,c,o}] in image px coords.
function FootPhoto({ id, heat = [], blend = 'multiply', edge = '#1EC7E6', pad = 'px-8 pt-12 pb-20', points = [] }) {
return (