/* Landing page — full composition combining hero, features, demos, comparison, pricing, FAQ */
const featuresList = [
{ icon: "brain-circuit", title: "Smart Scan", desc: "169 cleanup rules across 5 groups — system junk, caches, leftovers, logs, mail.", tag: null },
{ icon: "package-x", title: "App Uninstaller", desc: "9-level heuristic finds every leftover container, prefs, support, cache.", tag: null },
{ icon: "tombstone", title: "Orphan Finder", desc: "Reclaim disk space from apps you deleted years ago — the bones they left behind.", tag: null },
{ icon: "magnify-stacked", title: "Duplicate Finder", desc: "Three-pass detection: size → hash → bit-by-bit. No false positives.", tag: "Pro" },
{ icon: "chart-treemap", title: "Disk Treemap", desc: "Squarified visualization of every byte on disk. Drill down to any folder.", tag: "Pro" },
{ icon: "rocket", title: "App Updater", desc: "Sparkle, App Store, and Homebrew updates in one place — no more pinging.", tag: "Pro" },
{ icon: "apple", title: "Menu-bar actions", desc: "Quick clean from the menu bar without ever opening the main window." },
{ icon: "tools-cross", title: "Maintenance", desc: "Rebuild Spotlight, flush DNS, restart Finder — every utility you forget exists." },
{ icon: "globe", title: "9 languages", desc: "Localized for every market — including ones the big guys ignore." },
];
const FeatureCard = ({ icon, title, desc, tag }) => (
{
e.currentTarget.style.transform = "translateY(-3px)";
e.currentTarget.style.borderColor = "color-mix(in srgb, var(--brand-500) 30%, transparent)";
e.currentTarget.style.boxShadow = "0 24px 50px -20px rgba(99,102,241,0.35)";
}}
onMouseLeave={e => {
e.currentTarget.style.transform = "";
e.currentTarget.style.borderColor = "var(--hairline)";
e.currentTarget.style.boxShadow = "";
}}>
{tag && (
{tag}
)}
{title}
{desc}
);
/* === Live demos — 4 mini interactive cards === */
const DemoCard = ({ title, kicker, children }) => (
{kicker}
{title}
{children}
);
const TreemapDemo = () => {
// 5-block hand-tuned squarified layout — looks like a real treemap, not a 2x2 grid.
// Coords/sizes in % so it fills the 200px parent regardless of width.
const blocks = [
{ label: "node_modules", v: 8.4, x: 0, y: 0, w: 56, h: 100, intensity: 1.00, big: true },
{ label: "Photos", v: 4.2, x: 56, y: 0, w: 44, h: 52, intensity: 0.65 },
{ label: "DerivedData", v: 3.1, x: 56, y: 52, w: 26, h: 48, intensity: 0.50 },
{ label: "Caches", v: 2.0, x: 82, y: 52, w: 18, h: 28, intensity: 0.38 },
{ label: "Mail", v: 1.2, x: 82, y: 80, w: 18, h: 20, intensity: 0.28 },
];
const maxV = 8.4;
return (
{blocks.map((b, i) => {
const lightness = 0.32 + b.intensity * 0.32;
return (
{b.big && (
~/dev
)}
{b.label}
{b.v.toFixed(1)} GB
);
})}
);
};
const GaugeDemo = () => {
const [pct, setPct] = React.useState(0);
React.useEffect(() => {
const t = setTimeout(() => setPct(67), 200);
return () => clearTimeout(t);
}, []);
return (
);
};
const MenuBarDemo = () => {
const [open, setOpen] = React.useState(false);
React.useEffect(() => {
const i = setInterval(() => setOpen(o => !o), 2400);
return () => clearInterval(i);
}, []);
return (
{/* fake menu bar */}
File Edit View
100%
{/* popover */}
Quick clean
{["trash-fill","memory","drive","bubble-x","eye","globe-network"].map(n => (
))}
);
};
const DuplicateDemo = () => {
const passes = ["Scanning by size", "Hashing candidates", "Bit-by-bit verify"];
const [phase, setPhase] = React.useState(0);
React.useEffect(() => {
const i = setInterval(() => setPhase(p => (p + 1) % 4), 1200);
return () => clearInterval(i);
}, []);
return (
{passes.map((p, i) => {
const done = phase > i || phase === 0;
const active = phase === i + 1;
return (
{done && !active && }
{active && }
Pass {i+1} · {p}
{done && !active &&
12,431 files }
);
})}
);
};
/* === Comparison table — MacFleek vs CleanMyMac === */
const ComparisonRow = ({ label, mac, cmm, highlight }) => (
{label}
{mac}
{cmm}
);
const Yes = () => ;
const No = () => ;
const PricingCard = ({ tier, price, period, features, highlight, cta }) => (
{highlight && (
)}
{tier}
{highlight && Lifetime deal }
${price}
{period}
{highlight ? "One payment. Forever. No subscription." : "Forever free, ad-free, MIT licensed."}
{features.map((f, i) => (
{f}
))}
{cta}
);
const FAQItem = ({ q, a, defaultOpen = false }) => {
const [open, setOpen] = React.useState(defaultOpen);
return (
setOpen(o => !o)} style={{
width: "100%", textAlign: "left", padding: "16px 20px",
background: "transparent", border: "none", cursor: "pointer",
display: "flex", alignItems: "center", gap: 12,
color: "inherit", fontFamily: "inherit", fontSize: 14, fontWeight: 500,
}}>
{q}
);
};
const LandingView = () => {
return (
{/* Atmospheric backdrop */}
{/* LandingNav removed — production uses /shell.js NavBar at the page root */}
{/* Hero */}
v1.4 · 169 cleanup rules · MIT-licensed
The honest macOS cleaner.
Open source. Zero telemetry. $29 once and you own it. The cleaner CleanMyMac wishes it could be — without the panic pop-ups.
Download for macOS
View on GitHub
macOS 13+ · Universal binary · 24 MB · SHA-256: a3f9…02b7
{/* Features grid */}
Everything you need
Nine features. Zero bloat.
Built by developers for developers. Every feature earned its place.
{featuresList.map((f, i) => )}
{/* Live demos */}
Real interactions
Watch it work.
{/* Comparison */}
Side by side
The honest comparison.
Feature
The other one
} cmm={ }/>
} cmm={ }/>
} cmm="Limited"/>
} cmm={ }/>
{/* Pricing */}
One price. Forever.
Pricing
14-day refund · no questions
Encrypted checkout · Stripe
No subscription, ever
{/* FAQ */}
Frequently asked
Answers, not marketing.
{/* Footer removed — production uses /shell.js SiteFooter at the page root.
The prototype's internal footer was for the design-system browser context only. */}
);
};
Object.assign(window, { LandingView });