// Pricing page function PricingPage() { const { go } = useNav(); const { authed, setPlan } = useAuth(); const { toast } = useToast(); const [billing, setBilling] = useState('monthly'); const pickPlan = (id) => { setPlan(id); go('billing'); }; const sales = () => { window.location.href = 'mailto:eri@getfossyl.dev?subject=Fossyl%20%E2%80%94%20Sales%20enquiry'; }; return (
go('signup')} onLogin={() => go('login')}/>
§ Plans — 2026 edition

Pay per excavation.
Or for the whole season.

Most teams buy a one-off scan before a migration. Teams running several Plone sites subscribe. Consulting firms take the Agency plan. All reports are self-contained HTML — yours to keep, forever.

setBilling('monthly')}>Monthly setBilling('annual')}>Annual · save 20%
pickPlan('specimen')} /> pickPlan('field')} /> pickPlan('team')} />
{/* Field notes strip */}
On-premise

Need Fossyl to run inside your network?

The Agency plan ships a Docker image that runs against your ZODB on air-gapped infrastructure. Hospitals, government, defense. Nothing leaves your perimeter.

); } function BillingSeg({ active, onClick, children }) { return ( ); } function PlanCard({ name, tag, price, priceUnit, sub, features, ctaLabel, onCta, featured }) { return (
{featured && (
)}
{tag} plan_{name.toLowerCase()}

{name}

{sub}

{price} {priceUnit}
); } function FieldLine({ label, value }) { return (
{label}

{value}

); } function PlanMatrix() { const rows = [ ['Scans / month', 'One', '5', 'Unlimited', 'Unlimited'], ['ZODB records / scan', '10k', '25k', '100k', 'Unlimited'], ['HTML report', '✓', '✓', '✓', '✓'], ['PDF export', '✓', '✓', '✓', '✓'], ['AI explanations', '✓', '✓', '✓', '✓'], ['Dependency graph export (GraphML)', '—', '✓', '✓', '✓'], ['MySQL schema mapping', '—', '✓', '✓', '✓'], ['Shared workspace', '—', '—', '✓', '✓'], ['Slack / email integrations', '—', '—', '✓', '✓'], ['SSO (SAML / OIDC)', '—', '—', '—', '✓'], ['White-label reports', '—', '—', '—', '✓'], ['On-premise deployment', '—', '—', '—', '✓'], ['Support SLA', '48h', '24h', '8h', '4h · named CSM'], ['Report retention', '30 days', '90 days', '1 year', 'Unlimited'], ]; return (
§ Matrix — feature by plan

Every feature, every plan.

{rows.map((r, i) => ( {r.slice(1).map((c, j) => ( ))} ))}
Feature Specimen Field Team Agency
{r[0]}{c}
); } // shared top bar for logged-out pages that aren't landing function AppTopBar({ onCta, onLogin, authed }) { const { go } = useNav(); return (
go('landing')} style={{ cursor: 'pointer' }}>
{authed ? : <> }
); } Object.assign(window, { PricingPage, AppTopBar });