// pesito — shared visual atoms (logo, icons, brand mark)
const PesitoMark = ({ size = 28, color }) => (
);
const Wordmark = ({ color }) => (
);
// Tiny iconset (1.5px hairlines, iOS feel)
const I = {
arrow: (p = {}) => ,
arrowDown: (p = {}) => ,
check: (p = {}) => ,
shield: (p = {}) => ,
bolt: (p = {}) => ,
doc: (p = {}) => ,
plus: (p = {}) => ,
minus: (p = {}) => ,
clock: (p = {}) => ,
spei: (p = {}) => ,
menu: (p = {}) => ,
close: (p = {}) => ,
user: (p = {}) => ,
bank: (p = {}) => ,
sparkle: (p = {}) => ,
ineUp: (p = {}) => ,
};
// Format MX currency
const fmtMX = (n) => '$' + (Math.round(n)).toLocaleString('en-US') + ' MXN';
const fmtMXshort = (n) => '$' + (Math.round(n)).toLocaleString('en-US');
// Animated rolling number
const Rolling = ({ value, format = (v) => v, prefix = '', suffix = '' }) => {
const [display, setDisplay] = React.useState(value);
const ref = React.useRef(value);
React.useEffect(() => {
const start = ref.current;
const end = value;
if (start === end) return;
const t0 = performance.now();
const duration = 280;
let raf;
const step = (t) => {
const e = Math.min(1, (t - t0) / duration);
const eased = 1 - Math.pow(1 - e, 3);
setDisplay(start + (end - start) * eased);
if (e < 1) raf = requestAnimationFrame(step);
else ref.current = end;
};
raf = requestAnimationFrame(step);
return () => cancelAnimationFrame(raf);
}, [value]);
return {prefix}{format(display)}{suffix};
};
Object.assign(window, {
PesitoMark, Wordmark, I, fmtMX, fmtMXshort, Rolling,
});