/* FreeToolzHub — Home */ function Pillar({ icon, tone, label }) { const { Icon } = window.DesignSystem_3a7ab0; const [bg, fg] = window.FTH.TONE_MAP[tone]; return ( {label} ); } function AdSlot({ label, h=90 }) { return (
Advertisement {label}
); } function Stat({ value, label }) { const ref = React.useRef(null); const [disp, setDisp] = React.useState(value); React.useEffect(() => { const m = String(value).match(/^([\d.]+)(.*)$/); if (!m || !ref.current || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const target = parseFloat(m[1]), suffix = m[2], dec = (m[1].split('.')[1]||'').length; const io = new IntersectionObserver((es) => { es.forEach(en => { if (!en.isIntersecting) return; io.disconnect(); const t0 = performance.now(), dur = 1100; const step = (t) => { const p = Math.min(1, (t - t0) / dur), e = 1 - Math.pow(1 - p, 3); setDisp((target * e).toFixed(dec) + suffix); if (p < 1) requestAnimationFrame(step); }; requestAnimationFrame(step); }); }, { threshold: 0.4 }); io.observe(ref.current); return () => io.disconnect(); }, [value]); return (
{disp}
{label}
); } function FaqItem({ q, a }) { const { Icon } = window.DesignSystem_3a7ab0; const [open, setOpen] = React.useState(false); return (
{open &&
{a}
}
); } function Home({ go }) { const { ToolCard, Tabs, Badge, Button, Icon } = window.DesignSystem_3a7ab0; const { TOOLS, CATS, working, count } = window.FTH; const [cat, setCat] = React.useState('all'); const popular = (cat==='all' ? working.filter(t=>t.pop) : working.filter(t => t.cat===cat)); const tabs = [{ id:'all', label:'Popular' }, { id:'pdf', label:'PDF' }, { id:'image', label:'Image' }, { id:'text', label:'Text' }, { id:'dev', label:'Dev' }, { id:'calc', label:'Calc' }]; const pillars = [ { icon:'shield-check', tone:'green', label:'No Watermark' }, { icon:'user-x', tone:'blue', label:'No Registration' }, { icon:'zap', tone:'amber', label:'Fast' }, { icon:'lock', tone:'teal', label:'Secure' }, { icon:'infinity', tone:'sky', label:'Unlimited' }, ]; const steps = [ ['upload-cloud','Drop your file','Drag & drop or browse. Files stay in your browser — nothing is uploaded.'], ['sliders-horizontal','Adjust & preview','Tune settings with a live preview. Watch it process in real time.'], ['download','Download free','Grab your clean result instantly. No watermark, no email, no limit.'], ]; const faqs = [ ['Is everything really free?','Yes — every working tool is 100% free with no hidden limits, trial, or premium upsell.'], ['Will my files have a watermark?','Never. Your exports come out clean, exactly as you made them.'], ['Do I need an account?','No registration required. Open a tool and start immediately.'], ['Are my files private?','PDF and image tools run entirely in your browser — your files never leave your device.'], ['Is there any catch?','None. No watermark, no sign-up, no limits — every tool is free and runs right in your browser.'], ]; // Entrance is CSS transform-only (never hides content). Scroll-reveal just // adds an `.in` class that triggers a transform slide on inner cards — it // never hides anything, so no JS/observer failure can blank the page. React.useEffect(() => { if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; if (!('IntersectionObserver' in window)) return; const els = Array.from(document.querySelectorAll('.fth-reveal')); const io = new IntersectionObserver((ents) => { ents.forEach(en => { if (en.isIntersecting) { en.target.classList.add('in'); io.unobserve(en.target); } }); }, { threshold: 0.08, rootMargin: '0px 0px -5% 0px' }); els.forEach(el => io.observe(el)); return () => io.disconnect(); }, []); // hero typing effect (respects reduced motion) const PHRASES = ['100% free, forever.', 'No watermark, ever.', 'Private by design.']; const [typed, setTyped] = React.useState(PHRASES[0]); React.useEffect(() => { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; let pi = 0, ci = PHRASES[0].length, del = true, alive = true; const tick = () => { if (!alive) return; if (del) { ci--; if (ci <= 0) { del = false; pi = (pi + 1) % PHRASES.length; } } else { ci++; if (ci >= PHRASES[pi].length) { del = true; setTyped(PHRASES[pi]); setTimeout(tick, 2600); return; } } setTyped(PHRASES[pi].slice(0, Math.max(0, ci)) || '\u00a0'); setTimeout(tick, del ? 32 : 60); }; const t = setTimeout(tick, 2400); return () => { alive = false; clearTimeout(t); }; }, []); return (
{/* HERO */}
100% Free • No Registration • No Watermark

Every tool you need.
{typed}

Convert, compress, and edit files right in your browser. No account, no watermark, no limits — your files never leave your device.

{[['merge-pdf','Merge PDF'],['compress-pdf','Compress PDF'],['image-compressor','Image Compressor'],['remove-background','Remove Background'],['json-formatter','JSON Formatter']].map(([id,label]) => ( ))}
{pillars.map(p => )}
{/* POPULAR / WORKING TOOLS */}

Ready-to-use tools

Fully functional, right now — drop a file and go.

{popular.map(t => ( go('/tool/'+t.id)} /> ))}
{/* CATEGORY GRID */}

Browse by category

{count} tools across {CATS.length} categories — more shipping every week.

{CATS.map(c => { const [bg,fg] = window.FTH.TONE_MAP[c.tone]; const n = TOOLS.filter(t => t.cat===c.id).length; return (
go('/tools/'+c.id)} className="fth-cat-card" style={{ display:'flex', alignItems:'center', gap:14, padding:18, cursor:'pointer', background:'var(--bg-page)', border:'1px solid var(--border-color)', borderRadius:'var(--radius-xl)', transition:'transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow)', }}> {c.label} {n} tools
); })}
{/* PDF + IMAGE SHOWCASE (full captions) */} {[ { id:'pdf', blurb:'Merge, split, convert, compress, protect and sign — every PDF task, completely free and watermark-free.' }, { id:'image', blurb:'Compress, resize, crop, convert and enhance your images right in the browser — nothing is uploaded.' }, ].map((sec, si) => { const meta = CATS.find(c => c.id===sec.id) || {}; const [bg,fg] = window.FTH.TONE_MAP[meta.tone] || ['var(--blue-50)','var(--color-primary)']; const list = TOOLS.filter(t => t.cat===sec.id).slice(0,8); return (

{meta.label} Tools

{sec.blurb}

{list.map(t => ( go('/tool/'+t.id)} /> ))}
); })} {/* HOW IT WORKS */}

From file to finished in seconds

Everything runs locally. Your files are never uploaded to a server.

{steps.map((s,i) => (
{i+1}

{s[1]}

{s[2]}

))}
{/* STATS */}
{/* FAQ */}

Frequently asked questions

{faqs.map((f,i) => )}
{/* CTA */}

Ready to get started?

Pick a tool and drop your file. No account, no watermark, no limits.

Follow us for new tools & tips

{[['twitter','Twitter'],['github','GitHub'],['linkedin','LinkedIn'],['youtube','YouTube'],['instagram','Instagram'],['facebook','Facebook']].map(([s,label]) => ( ))}
); } window.FTHHome = Home; window.FTHAdSlot = AdSlot;