feat(ui): vague 4 — la zone de dépôt répond, l'or devient lisible, tarifs binaires, avant/après réel
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m58s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m58s
Zone de dépôt : le contour s'allume en doré et la carte s'agrandit quand on la survole avec un fichier (l'information existait, elle n'était jamais affichée). Or lisible : nouveau jeton « or encre » (#8B6F47) pour les textes, l'or clair reste aux traits, fonds et au mode sombre ; 52 textes dorés convertis, pastille comprises ; plus aucun texte sous 10 px (8,5 px → 11 px dans le sélecteur de moteurs). Tarifs : le choix redevient binaire — les trois abonnements payants en grandes cartes, le gratuit en ligne discrète au-dessus, le sur mesure en ligne dorée dessous. Le tableau comparatif complet reste dessous. Accueil : le mur de six cartes génériques est remplacé par un vrai avant/après — une page « Cahier des charges — Traitement d'air » à côté de sa traduction anglaise, structure identique au mot près (terme technique en gras des deux côtés), sceau « Même mise en page, mot pour mot » entre les deux, et trois preuves précises (SmartArt reconstruits, séries de graphiques traduites, tables des matières régénérées) à la place des promesses vagues.
This commit is contained in:
@@ -7,7 +7,6 @@ import {
|
||||
Layers,
|
||||
MousePointer2,
|
||||
Download,
|
||||
Globe,
|
||||
Cpu,
|
||||
CheckCircle2,
|
||||
ArrowRight,
|
||||
@@ -17,7 +16,6 @@ import {
|
||||
Presentation,
|
||||
MessageSquare,
|
||||
ShieldCheck,
|
||||
Zap,
|
||||
Menu,
|
||||
X,
|
||||
Languages,
|
||||
@@ -36,7 +34,7 @@ const Logo = () => (
|
||||
W
|
||||
</div>
|
||||
<span className="text-2xl font-bold tracking-tighter text-brand-dark dark:text-white">
|
||||
Wordly<span className="text-brand-accent">.art</span>
|
||||
Wordly<span className="text-brand-goldink dark:text-brand-accent">.art</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@@ -215,34 +213,91 @@ const FeaturesContext = () => {
|
||||
|
||||
const LayoutFeatures = () => {
|
||||
const { t } = useI18n();
|
||||
const points = [
|
||||
{ title: t('landing.layout.p1.title'), desc: t('landing.layout.p1.desc'), icon: <Layers size={22} /> },
|
||||
{ title: t('landing.layout.p2.title'), desc: t('landing.layout.p2.desc'), icon: <Layout size={22} /> },
|
||||
{ title: t('landing.layout.p3.title'), desc: t('landing.layout.p3.desc'), icon: <PieChart size={22} /> },
|
||||
{ title: t('landing.layout.p4.title'), desc: t('landing.layout.p4.desc'), icon: <Zap size={22} /> },
|
||||
{ title: t('landing.layout.p5.title'), desc: t('landing.layout.p5.desc'), icon: <MessageSquare size={22} /> },
|
||||
{ title: t('landing.layout.p6.title'), desc: t('landing.layout.p6.desc'), icon: <Globe size={22} /> },
|
||||
];
|
||||
|
||||
// Deux vraies pages de document : même structure, deux langues.
|
||||
// Le terme en gras montre le respect de la terminologie (glossaire).
|
||||
const DocPage = ({ side }: { side: "source" | "target" }) => (
|
||||
<div className="flex flex-col rounded-2xl bg-white p-8 text-start shadow-2xl dark:bg-[#181818] lg:p-10">
|
||||
<span className={`mb-6 w-fit rounded-full border px-3 py-1 text-[10px] font-black uppercase tracking-widest ${side === "source" ? "border-black/10 text-brand-dark/50 dark:border-white/15 dark:text-white/50" : "border-brand-accent/40 bg-brand-accent/10 text-brand-goldink dark:text-brand-accent"}`}>
|
||||
{side === "source" ? "FR — original" : "EN — traduit"}
|
||||
</span>
|
||||
<h4 className="mb-4 font-serif text-xl font-medium tracking-tight text-brand-dark dark:text-white lg:text-2xl">
|
||||
{side === "source" ? t("landing.beforeAfter.sourceTitle") : t("landing.beforeAfter.targetTitle")}
|
||||
</h4>
|
||||
<p className="mb-4 text-sm leading-relaxed text-brand-dark/75 dark:text-white/75">
|
||||
{side === "source" ? t("landing.beforeAfter.sourcePara1") : t("landing.beforeAfter.targetPara1")}
|
||||
</p>
|
||||
<p className="mb-6 text-sm leading-relaxed text-brand-dark/75 dark:text-white/75">
|
||||
{side === "source" ? (
|
||||
<>
|
||||
{t("landing.beforeAfter.sourcePara2Before")}{" "}
|
||||
<strong className="font-bold text-brand-dark dark:text-white">{t("landing.beforeAfter.sourceTerm")}</strong>{" "}
|
||||
{t("landing.beforeAfter.sourcePara2After")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{t("landing.beforeAfter.targetPara2Before")}{" "}
|
||||
<strong className="font-bold text-brand-dark dark:text-white">{t("landing.beforeAfter.targetTerm")}</strong>{" "}
|
||||
{t("landing.beforeAfter.targetPara2After")}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
<ul className="mb-8 space-y-2 text-sm text-brand-dark/75 dark:text-white/75">
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="mt-2 size-1 shrink-0 rounded-full bg-brand-accent" />
|
||||
{side === "source" ? t("landing.beforeAfter.sourceItem1") : t("landing.beforeAfter.targetItem1")}
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="mt-2 size-1 shrink-0 rounded-full bg-brand-accent" />
|
||||
{side === "source" ? t("landing.beforeAfter.sourceItem2") : t("landing.beforeAfter.targetItem2")}
|
||||
</li>
|
||||
</ul>
|
||||
<div className="mt-auto flex items-center justify-between border-t border-black/[0.06] pt-4 dark:border-white/[0.08]">
|
||||
<span className="font-mono text-[10px] uppercase tracking-wider text-brand-dark/45 dark:text-white/45">cahier-des-charges.docx</span>
|
||||
<span className="font-mono text-[10px] uppercase tracking-wider text-brand-dark/45 dark:text-white/45">3 pages · 2 481 mots</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="py-32 px-4 bg-brand-dark dark:bg-[#0a0a0a] text-white">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="text-center mb-32">
|
||||
<h2 className="text-4xl md:text-6xl mb-10 leading-tight font-serif font-medium tracking-tight">
|
||||
{t('landing.layout.title')}<br /> <span className="italic">{t('landing.layout.title2')}</span>
|
||||
<section id="features" className="px-4 py-32 text-white">
|
||||
<div className="mx-auto max-w-7xl">
|
||||
<div className="mb-16 text-center">
|
||||
<h2 className="mb-8 font-serif text-4xl font-medium leading-tight tracking-tight md:text-6xl">
|
||||
{t("landing.layout.title")}<br /> <span className="italic">{t("landing.layout.title2")}</span>
|
||||
</h2>
|
||||
<p className="text-white/40 max-w-2xl mx-auto text-xl font-light tracking-widest">
|
||||
{t('landing.layout.subtitle')}
|
||||
<p className="mx-auto max-w-2xl text-xl font-light tracking-wide text-white/45">
|
||||
{t("landing.layout.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-px bg-white/5 border border-white/10 rounded-3xl overflow-hidden shadow-2xl">
|
||||
{points.map((p, i) => (
|
||||
<div key={i} className="group p-14 bg-brand-dark dark:bg-[#0a0a0a] hover:bg-white/[0.02] transition-all duration-700">
|
||||
<div className="w-12 h-12 border border-white/10 rounded-xl flex items-center justify-center text-brand-accent mb-10 group-hover:scale-110 group-hover:border-white/20 transition-all">
|
||||
{p.icon}
|
||||
</div>
|
||||
<h4 className="text-xl font-serif font-medium mb-6 leading-none">{p.title}</h4>
|
||||
<p className="text-white/30 text-sm leading-relaxed font-light">{p.desc}</p>
|
||||
|
||||
<div className="relative grid gap-6 md:grid-cols-2 md:gap-10">
|
||||
<DocPage side="source" />
|
||||
<DocPage side="target" />
|
||||
|
||||
{/* sceau central : la promesse, entre les deux pages */}
|
||||
<div className="pointer-events-none absolute inset-0 hidden items-center justify-center md:flex">
|
||||
<div className="flex items-center gap-2 rounded-full border border-brand-accent/40 bg-brand-dark px-5 py-2.5 shadow-2xl dark:bg-[#0a0a0a]">
|
||||
<CheckCircle2 size={14} className="text-brand-accent" />
|
||||
<span className="text-[10px] font-black uppercase tracking-widest text-brand-accent">
|
||||
{t("landing.beforeAfter.seal")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* trois preuves précises, pas des promesses vagues */}
|
||||
<div className="mt-14 grid gap-4 sm:grid-cols-3">
|
||||
{[
|
||||
{ icon: <Layout size={16} />, label: t("landing.beforeAfter.proof1") },
|
||||
{ icon: <PieChart size={16} />, label: t("landing.beforeAfter.proof2") },
|
||||
{ icon: <MessageSquare size={16} />, label: t("landing.beforeAfter.proof3") },
|
||||
].map((proof, i) => (
|
||||
<div key={i} className="flex items-center gap-3 rounded-2xl border border-white/10 px-5 py-4">
|
||||
<span className="flex size-8 shrink-0 items-center justify-center rounded-lg border border-brand-accent/30 text-brand-accent">
|
||||
{proof.icon}
|
||||
</span>
|
||||
<span className="text-sm font-light text-white/70">{proof.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -275,7 +330,7 @@ const FormatsSection = () => {
|
||||
<div className="w-12 h-12 bg-brand-muted dark:bg-[#1f1f1f] rounded-xl flex items-center justify-center text-xl group-hover:bg-brand-dark dark:group-hover:bg-brand-accent group-hover:text-white dark:group-hover:text-brand-dark transition-all">
|
||||
{f.icon}
|
||||
</div>
|
||||
<span className="text-[9px] font-bold text-brand-dark/50 dark:text-white/50 uppercase tracking-[0.2em]">{f.id}</span>
|
||||
<span className="text-[10px] font-bold text-brand-dark/50 dark:text-white/50 uppercase tracking-[0.2em]">{f.id}</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-serif font-medium mb-6 text-brand-dark dark:text-white tracking-tight">{f.name}</h3>
|
||||
<ul className="space-y-4">
|
||||
@@ -347,7 +402,7 @@ const PricingSection = () => {
|
||||
</button>
|
||||
<button onClick={() => setIsAnnual(true)} className={`text-sm font-bold uppercase tracking-widest transition-all relative ${isAnnual ? 'text-brand-dark dark:text-white underline underline-offset-8' : 'text-brand-dark/55 dark:text-white/55 hover:text-brand-dark dark:hover:text-white'}`}>
|
||||
{t('landing.pricing.annual')}
|
||||
<span className="absolute -top-6 left-1/2 -translate-x-1/2 text-[9px] font-bold text-brand-accent whitespace-nowrap italic">
|
||||
<span className="absolute -top-6 left-1/2 -translate-x-1/2 text-[10px] font-bold text-brand-goldink dark:text-brand-accent whitespace-nowrap italic">
|
||||
(-20%)
|
||||
</span>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user