feat(sprint3-step1-2): vision B2B + Tailwind tokens + LandingPage + Pricing B2B
This commit is contained in:
241
frontend/src/pages/LandingPage.tsx
Normal file
241
frontend/src/pages/LandingPage.tsx
Normal file
@@ -0,0 +1,241 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
// ─── Pricing data ─────────────────────────────────────────────────────────────
|
||||
|
||||
interface Tier {
|
||||
name: string;
|
||||
price: string;
|
||||
period: string;
|
||||
tagline: string;
|
||||
features: string[];
|
||||
cta: string;
|
||||
highlighted: boolean;
|
||||
}
|
||||
|
||||
const TIERS: Tier[] = [
|
||||
{
|
||||
name: 'Starter',
|
||||
price: '29€',
|
||||
period: '/mois',
|
||||
tagline: 'Pour démarrer proprement.',
|
||||
features: [
|
||||
'1 projet',
|
||||
'Domaine custom',
|
||||
'White-label basique',
|
||||
'Support communauté',
|
||||
],
|
||||
cta: 'Commencer',
|
||||
highlighted: false,
|
||||
},
|
||||
{
|
||||
name: 'Studio',
|
||||
price: '99€',
|
||||
period: '/mois',
|
||||
tagline: 'Pour les studios actifs.',
|
||||
features: [
|
||||
'5 projets',
|
||||
'Analytics intégrés',
|
||||
'SuperOAuth Tier 3',
|
||||
'White-label complet',
|
||||
'Support email',
|
||||
],
|
||||
cta: 'Choisir Studio',
|
||||
highlighted: true,
|
||||
},
|
||||
{
|
||||
name: 'Pro',
|
||||
price: '249€',
|
||||
period: '/mois',
|
||||
tagline: 'Pour les opérations à fort volume.',
|
||||
features: [
|
||||
'Projets illimités',
|
||||
'API access complet',
|
||||
'Support prioritaire',
|
||||
'SuperOAuth Tier 3',
|
||||
'SLA 99.9%',
|
||||
],
|
||||
cta: 'Choisir Pro',
|
||||
highlighted: false,
|
||||
},
|
||||
];
|
||||
|
||||
// ─── Component ────────────────────────────────────────────────────────────────
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="flex flex-col gap-24 pb-16">
|
||||
|
||||
{/* ── Hero ──────────────────────────────────────────────────────────── */}
|
||||
<section className="pt-16 flex flex-col gap-6 max-w-3xl">
|
||||
|
||||
{/* Badge */}
|
||||
<div className="inline-flex w-fit items-center gap-2 rounded border border-od-border bg-od-surface px-3 py-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-od-accent" />
|
||||
<span className="font-mono text-2xs text-od-muted tracking-widest uppercase">
|
||||
SuperOAuth Tier 3 — multi-tenant natif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Headline */}
|
||||
<h1 className="font-display text-5xl font-bold leading-[1.1] tracking-tight text-od-text">
|
||||
La plateforme des{' '}
|
||||
<span className="text-od-accent">studios indépendants.</span>
|
||||
</h1>
|
||||
|
||||
{/* Sous-titre */}
|
||||
<p className="text-base text-od-muted leading-relaxed max-w-xl">
|
||||
Lancez votre vitrine de contenu en quelques minutes.
|
||||
Auth multi-tenant, domaine custom, white-label complet —
|
||||
sans compromis sur la qualité.
|
||||
</p>
|
||||
|
||||
{/* CTAs */}
|
||||
<div className="flex items-center gap-4 pt-2">
|
||||
<Link
|
||||
to="/login"
|
||||
className="inline-flex items-center gap-2 rounded border border-od-accent bg-od-accent px-6 py-2.5 font-mono text-sm font-semibold text-od-bg transition-all duration-150 hover:bg-od-accent-dim hover:border-od-accent-dim"
|
||||
>
|
||||
Se connecter
|
||||
</Link>
|
||||
<a
|
||||
href="#pricing"
|
||||
className="inline-flex items-center gap-2 rounded border border-od-border px-6 py-2.5 font-mono text-sm text-od-muted transition-all duration-150 hover:border-od-border-hi hover:text-od-text"
|
||||
>
|
||||
Voir les tarifs
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Social proof minimal */}
|
||||
<p className="font-mono text-2xs text-od-muted pt-2">
|
||||
Intégration SuperOAuth Tier 3 · Auth per-tenant · CNAME custom
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
{/* ── Différenciateur ───────────────────────────────────────────────── */}
|
||||
<section className="grid grid-cols-3 gap-4">
|
||||
{[
|
||||
{
|
||||
label: 'Auth multi-tenant',
|
||||
desc: 'SuperOAuth Tier 3 intégré nativement. Per-tenant providers, isolation complète des données.',
|
||||
},
|
||||
{
|
||||
label: 'White-label total',
|
||||
desc: 'Logo, domaine, emails, couleurs — votre marque, pas la nôtre. CNAME custom inclus dès Starter.',
|
||||
},
|
||||
{
|
||||
label: 'Prévisible',
|
||||
desc: 'Abonnement fixe, pas de commission, pas de per-seat. Votre croissance ne nous rémunère pas.',
|
||||
},
|
||||
].map(({ label, desc }) => (
|
||||
<div
|
||||
key={label}
|
||||
className="flex flex-col gap-3 rounded border border-od-border bg-od-surface p-5 transition-colors duration-150 hover:border-od-border-hi"
|
||||
>
|
||||
<div className="h-px w-8 bg-od-accent" />
|
||||
<p className="text-sm font-semibold text-od-text">{label}</p>
|
||||
<p className="text-xs text-od-muted leading-relaxed">{desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* ── Pricing ───────────────────────────────────────────────────────── */}
|
||||
<section id="pricing" className="flex flex-col gap-8 scroll-mt-20">
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<span className="font-mono text-2xs uppercase tracking-widest text-od-muted">Tarifs</span>
|
||||
<h2 className="font-display text-3xl font-bold text-od-text tracking-tight">
|
||||
Simple. Sans surprise.
|
||||
</h2>
|
||||
<p className="text-sm text-od-muted max-w-md">
|
||||
Abonnement mensuel sans engagement. Pas de commission sur vos revenus.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
{TIERS.map((tier) => (
|
||||
<PricingCard key={tier.name} tier={tier} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Enterprise mention */}
|
||||
<div className="flex items-center justify-between rounded border border-od-border bg-od-surface px-6 py-4">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-sm font-semibold text-od-text">Enterprise</span>
|
||||
<span className="text-xs text-od-muted">SLA, déploiement dédié, onboarding personnalisé</span>
|
||||
</div>
|
||||
<a
|
||||
href="mailto:contact@originsdigital.com"
|
||||
className="rounded border border-od-border px-4 py-2 font-mono text-xs text-od-muted hover:border-od-accent hover:text-od-accent transition-all duration-150"
|
||||
>
|
||||
Nous contacter
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── PricingCard ──────────────────────────────────────────────────────────────
|
||||
|
||||
function PricingCard({ tier }: { tier: Tier }) {
|
||||
const base =
|
||||
'relative flex flex-col gap-5 rounded border p-6 transition-all duration-150';
|
||||
const highlighted =
|
||||
tier.highlighted
|
||||
? 'border-od-accent bg-od-surface shadow-accent-glow'
|
||||
: 'border-od-border bg-od-surface hover:border-od-border-hi';
|
||||
|
||||
return (
|
||||
<div className={`${base} ${highlighted}`}>
|
||||
|
||||
{tier.highlighted && (
|
||||
<div className="absolute -top-px left-0 right-0 h-px bg-od-accent" />
|
||||
)}
|
||||
|
||||
{tier.highlighted && (
|
||||
<div className="absolute -top-3 right-4 rounded-full border border-od-accent bg-od-bg px-2 py-0.5">
|
||||
<span className="font-mono text-2xs text-od-accent tracking-wider">Populaire</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="font-mono text-xs uppercase tracking-widest text-od-muted">{tier.name}</span>
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="font-display text-4xl font-bold text-od-text">{tier.price}</span>
|
||||
<span className="font-mono text-xs text-od-muted">{tier.period}</span>
|
||||
</div>
|
||||
<span className="text-xs text-od-muted">{tier.tagline}</span>
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div className="border-t border-od-border" />
|
||||
|
||||
{/* Features */}
|
||||
<ul className="flex flex-col gap-2.5 flex-1">
|
||||
{tier.features.map((f) => (
|
||||
<li key={f} className="flex items-start gap-2 text-xs text-od-muted">
|
||||
<span className="mt-0.5 text-od-accent">—</span>
|
||||
<span>{f}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{/* CTA */}
|
||||
<Link
|
||||
to="/login"
|
||||
className={
|
||||
tier.highlighted
|
||||
? 'inline-flex items-center justify-center rounded border border-od-accent bg-od-accent px-4 py-2 font-mono text-xs font-semibold text-od-bg transition-all duration-150 hover:bg-od-accent-dim hover:border-od-accent-dim'
|
||||
: 'inline-flex items-center justify-center rounded border border-od-border px-4 py-2 font-mono text-xs text-od-muted transition-all duration-150 hover:border-od-accent hover:text-od-accent'
|
||||
}
|
||||
>
|
||||
{tier.cta}
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user