-
- {t('common.developers')}
+
+
+
+
+ {FEATURE_PANELS.map((panel) => {
+ const Icon = panel.icon;
+ const perks = panel.perks.map((perkKey, index) => t(perkKey, panel.fallbackPerks[index]));
+
+ return (
+
+
+
+
+
+ {t(panel.titleKey, panel.titleDefault)}
+
+
+ {t(panel.descKey, panel.descDefault)}
+
+
+ {perks.map((perk) => (
+ -
+
+ {perk}
+
+ ))}
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+ {t('common.developers')}
+
+
+ {t('pages.developers.ctaTitle')}
+
+
+ {t('pages.developers.ctaSubtitle')}
+
+
+
+
+ {t('pages.developers.openDocs')}
+
+
+
+ {t('pages.developers.getApiKey')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t('home.ctaBannerLabel', 'Get started today')}
-
- {t('pages.developers.ctaTitle')}
+
+ {t('home.ctaBannerTitle', 'Ready to convert your files?')}
-
- {t('pages.developers.ctaSubtitle')}
+
+ {t('home.ctaBannerSubtitle', 'Join thousands of users who convert, compress, and edit their files every day — completely free.')}
-
-
-
- {t('pages.developers.openDocs')}
-
-
-
- {t('pages.developers.getApiKey')}
-
+
+
+ {t('home.ctaBrowseTools', 'Browse All Tools')}
+
+
+
+ {t('home.ctaCreateAccount', 'Create Free Account')}
+
+
+
+
-
- {/* ── Bottom CTA Banner ─────────────────────────────────────── */}
-
- {/* Decorative blobs */}
-
-
-
-
-
- {t('home.ctaBannerLabel', 'Get started today')}
-
-
- {t('home.ctaBannerTitle', 'Ready to convert your files?')}
-
-
- {t('home.ctaBannerSubtitle', 'Join thousands of users who convert, compress, and edit their files every day — completely free.')}
-
-
-
- {t('home.ctaBrowseTools', 'Browse All Tools')}
-
-
-
- {t('home.ctaCreateAccount', 'Create Free Account')}
-
-
-
-
-
- {/* ── Ad Slot - Bottom ──────────────────────────────────────── */}
-
- >
+
);
}
diff --git a/frontend/src/pages/PricingPage.tsx b/frontend/src/pages/PricingPage.tsx
index f48ea58..b6a1861 100644
--- a/frontend/src/pages/PricingPage.tsx
+++ b/frontend/src/pages/PricingPage.tsx
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import SEOHead from '@/components/seo/SEOHead';
import { generateWebPage, getSiteOrigin } from '@/utils/seo';
-import { ArrowRight, Check, Coins, Crown, Loader2, Scale, X, Zap } from 'lucide-react';
+import { ArrowRight, Check, Coins, Crown, Loader2, Scale, Shield, Zap } from 'lucide-react';
import { useAuthStore } from '@/stores/authStore';
import SocialProofStrip from '@/components/shared/SocialProofStrip';
import { getApiClient } from '@/services/api';
@@ -15,35 +15,48 @@ interface PlanFeature {
key: string;
free: boolean | string;
pro: boolean | string;
+ enterprise: boolean | string;
}
const FEATURES: PlanFeature[] = [
- { key: 'credits', free: '50 credits/30 days', pro: '500 credits/30 days' },
- { key: 'apiAccess', free: false, pro: true },
- { key: 'apiRequests', free: '—', pro: '1,000/month' },
- { key: 'maxFileSize', free: '50 MB', pro: '100 MB' },
- { key: 'historyRetention', free: '25 files', pro: '250 files' },
- { key: 'allTools', free: true, pro: true },
- { key: 'aiTools', free: true, pro: true },
- { key: 'priorityProcessing', free: false, pro: true },
- { key: 'noAds', free: false, pro: true },
- { key: 'emailSupport', free: false, pro: true },
+ { key: 'credits', free: '50 credits/30 days', pro: '500 credits/30 days', enterprise: 'Unlimited' },
+ { key: 'apiAccess', free: false, pro: true, enterprise: true },
+ { key: 'apiRequests', free: '—', pro: '1,000/month', enterprise: 'Unlimited' },
+ { key: 'maxFileSize', free: '50 MB', pro: '100 MB', enterprise: '500 MB' },
+ { key: 'historyRetention', free: '25 files', pro: '250 files', enterprise: 'Unlimited' },
+ { key: 'allTools', free: true, pro: true, enterprise: true },
+ { key: 'aiTools', free: true, pro: true, enterprise: true },
+ { key: 'priorityProcessing', free: false, pro: true, enterprise: true },
+ { key: 'noAds', free: false, pro: true, enterprise: true },
+ { key: 'emailSupport', free: false, pro: true, enterprise: true },
+ { key: 'customIntegrations', free: false, pro: false, enterprise: true },
+ { key: 'dedicatedSupport', free: false, pro: false, enterprise: true },
+ { key: 'userManagement', free: false, pro: false, enterprise: true },
];
+const MONTHLY_PRICES = { free: 0, pro: 9.99, enterprise: 29.99 };
+const YEARLY_PRICES = { free: 0, pro: 7.99, enterprise: 24.99 };
+
export default function PricingPage() {
const { t } = useTranslation();
const siteOrigin = getSiteOrigin(typeof window !== 'undefined' ? window.location.origin : '');
const user = useAuthStore((s) => s.user);
const [loading, setLoading] = useState(false);
+ const [billing, setBilling] = useState<'monthly' | 'yearly'>('yearly');
- async function handleUpgrade(billing: 'monthly' | 'yearly') {
+ async function handleUpgrade(plan: 'pro' | 'enterprise') {
// Track interest in paid plan
try {
- await api.post('/internal/admin/plan-interest/record', { plan: 'pro', billing });
+ await api.post('/internal/admin/plan-interest/record', { plan, billing });
} catch {
// Non-critical — don't block the flow
}
+ if (plan === 'enterprise') {
+ window.location.href = '/contact';
+ return;
+ }
+
if (!user) {
window.location.href = '/account?redirect=pricing';
return;
@@ -53,42 +66,64 @@ export default function PricingPage() {
const { data } = await api.post(`${API_BASE}/stripe/create-checkout-session`, { billing });
if (data.url) window.location.href = data.url;
} catch {
- // Stripe not configured yet — show message
alert(t('pages.pricing.stripeNotReady', 'Payment system is being set up. Please try again later.'));
} finally {
setLoading(false);
}
}
- function renderValue(val: boolean | string) {
- if (val === true) return ;
- if (val === false) return ;
- return {val};
- }
+ const prices = billing === 'yearly' ? YEARLY_PRICES : MONTHLY_PRICES;
return (
<>
-
- {/* Header */}
+
+ {/* Header + billing toggle */}
-
+
{t('pages.pricing.title', 'Simple, Transparent Pricing')}
- {t('pages.pricing.subtitle', 'Start free with all tools. Upgrade when you need more power.')}
+ {t('pages.pricing.subtitle', 'Unlock the power of your PDFs with flexible plans.')}
+ {/* Billing toggle */}
+
+
+
+
+
+ {/* Transparency callout */}
@@ -120,88 +155,76 @@ export default function PricingPage() {
- {/* Plan Cards */}
-
+ {/* 3-tier Plan Cards */}
+
{/* Free Plan */}
-
-
-
-
-
-
-
- {t('pages.pricing.freePlan', 'Free')}
-
-
- {t('pages.pricing.freeDesc', 'For personal use')}
-
-
+
+
+
+ {t('pages.pricing.freePlan', 'Free')}
+
- $0
+ ${prices.free}
/ {t('pages.pricing.month', 'month')}
-
+
{FEATURES.filter((f) => f.free !== false).map((f) => (
- -
-
- {t(`pages.pricing.features.${f.key}`, f.key)}
- {typeof f.free === 'string' && (
- ({f.free})
- )}
+
-
+
+
+ {t(`pages.pricing.features.${f.key}`, f.key)}
+ {typeof f.free === 'string' && (
+ ({f.free})
+ )}
+
))}
- {t('pages.pricing.getStarted', 'Get Started Free')}
+ {t('pages.pricing.getStarted', 'Get Started')}
{/* Pro Plan */}
-
-
+
+
{t('pages.pricing.popular', 'MOST POPULAR')}
-
-
-
-
-
-
- {t('pages.pricing.proPlan', 'Pro')}
-
-
- {t('pages.pricing.proDesc', 'For professionals & teams')}
-
-
+
+
+ {t('pages.pricing.proPlan', 'Pro')}
+
- $9
+ ${prices.pro}
/ {t('pages.pricing.month', 'month')}
-
+
+ {/* Enterprise Plan */}
+
+
+
+ {t('pages.pricing.enterprisePlan', 'Enterprise')}
+
+
+
+
+ ${prices.enterprise}
+ / {t('pages.pricing.month', 'month')}
+
+
+
+ {FEATURES.filter((f) => f.enterprise !== false).map((f) => (
+ -
+
+
+ {t(`pages.pricing.features.${f.key}`, f.key)}
+ {typeof f.enterprise === 'string' && (
+ ({f.enterprise})
+ )}
+
+
+ ))}
+
+
+
+ {/* Trust section */}
@@ -244,39 +300,16 @@ export default function PricingPage() {
- {/* Comparison Table */}
-
-
-
-
- |
- {t('pages.pricing.feature', 'Feature')}
- |
-
- {t('pages.pricing.freePlan', 'Free')}
- |
-
- {t('pages.pricing.proPlan', 'Pro')}
- |
-
-
-
- {FEATURES.map((f, idx) => (
-
- |
- {t(`pages.pricing.features.${f.key}`, f.key)}
- |
- {renderValue(f.free)} |
- {renderValue(f.pro)} |
-
- ))}
-
-
+ {/* Bottom trust badges */}
+
+
+
+ {t('pages.pricing.securePayment', 'Secure Payment')}
+
+
+
+ {t('pages.pricing.moneyBack', '30-Day Money Back Guarantee')}
+
{/* FAQ */}
diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css
index 86edbc0..313011d 100644
--- a/frontend/src/styles/global.css
+++ b/frontend/src/styles/global.css
@@ -169,6 +169,40 @@
linear-gradient(180deg, #0f172a 0%, #0f172a 100%);
}
+.marketing-shell {
+ background:
+ radial-gradient(circle at top left, rgba(59, 130, 246, 0.1), transparent 30%),
+ radial-gradient(circle at top right, rgba(14, 165, 233, 0.08), transparent 26%),
+ linear-gradient(180deg, rgba(248, 250, 252, 0.88) 0%, rgba(255, 255, 255, 0.92) 26%, #ffffff 100%);
+}
+
+.dark .marketing-shell {
+ background:
+ radial-gradient(circle at top left, rgba(37, 99, 235, 0.18), transparent 32%),
+ radial-gradient(circle at top right, rgba(14, 165, 233, 0.12), transparent 28%),
+ linear-gradient(180deg, rgba(2, 6, 23, 0.96) 0%, rgba(15, 23, 42, 0.98) 26%, #020617 100%);
+}
+
+.marketing-panel {
+ @apply rounded-[2rem] border border-slate-200/80 bg-white/90 shadow-sm backdrop-blur-sm dark:border-slate-700/70 dark:bg-slate-900/70;
+}
+
+.marketing-card {
+ @apply rounded-[1.75rem] border border-slate-200/80 bg-white/90 p-6 shadow-sm transition-all duration-300 dark:border-slate-700/70 dark:bg-slate-900/75;
+}
+
+.marketing-card:hover {
+ @apply -translate-y-1 shadow-lg shadow-slate-200/70 dark:shadow-slate-950/30;
+}
+
+.metric-card {
+ @apply rounded-3xl border border-slate-200/80 bg-white/85 p-5 shadow-sm backdrop-blur-sm dark:border-slate-700/70 dark:bg-slate-900/70;
+}
+
+.section-kicker {
+ @apply text-xs font-bold uppercase tracking-[0.24em] text-primary-600 dark:text-primary-400;
+}
+
/* ──────────────────────────────────────────────────────────────────────────
Shimmer loading effect
────────────────────────────────────────────────────────────────────────── */