// Eu Faço Parte — App shell + Tweaks panel
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"accentHue": 250,
"accentChroma": 0.11,
"accentLightness": 0.40,
"paperWarmth": 75,
"paperLightness": 0.975,
"serif": "Crimson Pro",
"sans": "Inter Tight",
"mono": "JetBrains Mono",
"displayScale": 1.0
}/*EDITMODE-END*/;
const SERIF_OPTIONS = ['Crimson Pro', 'Source Serif 4', 'EB Garamond', 'Cormorant Garamond', 'Libre Caslon Text', 'Playfair Display'];
const SANS_OPTIONS = ['Inter Tight', 'Geist', 'DM Sans', 'Manrope', 'Work Sans', 'Plus Jakarta Sans'];
const MONO_OPTIONS = ['JetBrains Mono', 'IBM Plex Mono', 'Space Mono', 'Geist Mono', 'Fira Code'];
const ACCENT_PRESETS = [
{ name: 'Azul Inst.', h: 250, c: 0.11, l: 0.40 },
{ name: 'Terracotta', h: 38, c: 0.135, l: 0.55 },
{ name: 'Burnt Sienna', h: 50, c: 0.135, l: 0.50 },
{ name: 'Forest', h: 145, c: 0.07, l: 0.40 },
{ name: 'Indigo', h: 270, c: 0.10, l: 0.40 },
{ name: 'Charcoal', h: 60, c: 0.015, l: 0.25 },
];
function applyTweaks(t) {
const r = document.documentElement.style;
r.setProperty('--accent',
`oklch(${t.accentLightness} ${t.accentChroma} ${t.accentHue})`);
r.setProperty('--bordeaux',
`oklch(${t.accentLightness} ${t.accentChroma} ${t.accentHue})`);
r.setProperty('--bordeaux-2',
`oklch(${Math.max(0.18, t.accentLightness - 0.08)} ${t.accentChroma * 0.9} ${t.accentHue})`);
r.setProperty('--terracotta',
`oklch(${Math.min(0.7, t.accentLightness + 0.18)} ${t.accentChroma * 1.15} ${t.accentHue + 10})`);
r.setProperty('--verdegrowth', 'rgb(105, 216, 128)');
r.setProperty('--paper', `oklch(${t.paperLightness} 0.008 ${t.paperWarmth})`);
r.setProperty('--paper-2', `oklch(${t.paperLightness - 0.03} 0.015 ${t.paperWarmth - 5})`);
r.setProperty('--paper-3', `oklch(${t.paperLightness - 0.07} 0.02 ${t.paperWarmth - 10})`);
r.setProperty('--serif', `'${t.serif}', Georgia, serif`);
r.setProperty('--sans', `'${t.sans}', -apple-system, sans-serif`);
r.setProperty('--mono', `'${t.mono}', ui-monospace, monospace`);
// ensure fonts loaded
ensureFont(t.serif);
ensureFont(t.sans);
ensureFont(t.mono);
}
const _loadedFonts = new Set();
function ensureFont(family) {
if (!family || _loadedFonts.has(family)) return;
_loadedFonts.add(family);
const name = family.replace(/ /g, '+');
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = `https://fonts.googleapis.com/css2?family=${name}:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap`;
document.head.appendChild(link);
}
// --- Donorbox Widget ---
const DonorboxWidget = () => {
const ref = React.useRef(null);
React.useEffect(() => {
if (!ref.current) return;
// Insere o elemento antes do script para o upgrade funcionar
ref.current.innerHTML =
'';
if (!document.querySelector('script[data-dbox]')) {
const s = document.createElement('script');
s.type = 'module';
s.src = 'https://donorbox.org/widgets.js';
s.async = true;
s.setAttribute('data-dbox', '');
document.head.appendChild(s);
}
}, []);
return
;
};
// --- Modal de Doação ---
const DonationModal = ({ onClose }) => {
const [stack, setStack] = React.useState(['region']);
const step = stack[stack.length - 1];
const go = (s) => setStack(prev => [...prev, s]);
const back = () => setStack(prev => prev.slice(0, -1));
const [copied, setCopied] = React.useState(false);
const copyPix = () => {
navigator.clipboard?.writeText('58009272/001-32');
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
React.useEffect(() => {
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
document.addEventListener('keydown', onKey);
document.body.style.overflow = 'hidden';
return () => {
document.removeEventListener('keydown', onKey);
document.body.style.overflow = '';
};
}, [onClose]);
return (
e.stopPropagation()}>
{stack.length > 1 && (
)}
{step === 'region' && (
Doação
Onde você reside?
Selecione seu país para ver as opções de doação disponíveis.
)}
{step === 'br-method' && (
Brasil
Como deseja doar?
)}
{step === 'pix' && (
PIX · Brasil
Chave PIX
Copie a chave abaixo e realize a transferência pelo seu banco de preferência.
CNPJ
58009272/001-32
Após o pagamento, envie o comprovante para contato@eufacoparte.org.
)}
{step === 'form' && (
)}
);
};
const LiquidGlassFilter = () => (
);
// ---- Page Loader ----
const PageLoader = ({ onDone }) => {
const [progress, setProgress] = React.useState(0);
const [fading, setFading] = React.useState(false);
React.useEffect(() => {
let current = 0;
let raf;
let finished = false;
const complete = () => {
if (finished) return;
finished = true;
cancelAnimationFrame(raf);
const rush = () => {
current = Math.min(100, current + 4);
setProgress(current);
if (current < 100) requestAnimationFrame(rush);
else setTimeout(() => { setFading(true); setTimeout(onDone, 500); }, 150);
};
requestAnimationFrame(rush);
};
const tick = () => {
if (finished) return;
const step = current < 30 ? 1.8 : current < 60 ? 0.9 : current < 80 ? 0.4 : 0.08;
current = Math.min(88, current + step);
setProgress(current);
if (current < 88) raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
let pageLoaded = false, minElapsed = false;
const tryComplete = () => { if (pageLoaded && minElapsed) complete(); };
const onLoad = () => { pageLoaded = true; tryComplete(); };
setTimeout(() => { minElapsed = true; tryComplete(); }, 3500);
if (document.readyState === 'complete') onLoad();
else window.addEventListener('load', onLoad, { once: true });
return () => { cancelAnimationFrame(raf); window.removeEventListener('load', onLoad); };
}, []);
return (
Estamos personalizando sua experiência
);
};
const App = () => {
const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
const [donationOpen, setDonationOpen] = React.useState(false);
const [loading, setLoading] = React.useState(true);
React.useEffect(() => { applyTweaks(tweaks); }, [tweaks]);
React.useEffect(() => { window.openDonationModal = () => setDonationOpen(true); }, []);
return (
<>
{loading && setLoading(false)} />}
{donationOpen && setDonationOpen(false)} />}
{ACCENT_PRESETS.map(p => (
))}
setTweak('accentHue', v)} />
setTweak('accentChroma', v)} />
setTweak('accentLightness', v)} />
setTweak('paperWarmth', v)} />
setTweak('paperLightness', v)} />
setTweak('serif', v)} />
setTweak('sans', v)} />
setTweak('mono', v)} />
>
);
};
ReactDOM.createRoot(document.getElementById('root')).render();