feat: pivot complet - agence web artisans BTP Nord + Sanity CMS
Transformation complète du site HookLab de formation TikTok Shop vers une landing page haute conversion pour agence web locale ciblant les artisans du bâtiment dans le Nord (Douai, Orchies, Valenciennes). - Nouveau design system : bleu nuit/orange sur fond clair (mobile-first) - Hero avec promesse artisan + CTA orange "Réserver mon Audit" - Section "Le Système" (3 étapes : Trouvé, Choisi, Contacté) - Portfolio connecté à Sanity.io (fallback data intégré) - Section "Qui suis-je" avec carte OpenStreetMap interactive - FAQ orientée artisans avec JSON-LD pour Google - Formulaire contact audit gratuit - SEO local : 12 keywords artisans, JSON-LD LocalBusiness - Sanity.io schemas (portfolio, siteSettings) + client conditionnel - Accessibilité : skip-to-content, focus-visible, aria-labels https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
This commit is contained in:
151
app/globals.css
151
app/globals.css
@@ -2,118 +2,109 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme inline {
|
||||
--color-primary: #6D5EF6;
|
||||
--color-primary-hover: #5B4FDB;
|
||||
--color-primary-50: #F3F1FF;
|
||||
--color-primary-100: #E9E5FF;
|
||||
--color-primary-light: #9D8FF9;
|
||||
--color-navy: #1B2A4A;
|
||||
--color-navy-light: #2A3D66;
|
||||
--color-navy-dark: #111D36;
|
||||
|
||||
--color-dark: #0B0F19;
|
||||
--color-dark-light: #1A1F2E;
|
||||
--color-dark-lighter: #252A3A;
|
||||
--color-dark-border: #2A2F3F;
|
||||
--color-orange: #E8772E;
|
||||
--color-orange-hover: #D06522;
|
||||
--color-orange-light: #F5A623;
|
||||
|
||||
--color-bg: #F7F8FA;
|
||||
--color-bg-white: #FFFFFF;
|
||||
--color-bg-card: #FFFFFF;
|
||||
--color-bg-muted: #F0F2F5;
|
||||
|
||||
--color-text: #1A1A2E;
|
||||
--color-text-light: #6B7280;
|
||||
--color-text-muted: #9CA3AF;
|
||||
|
||||
--color-border: #E5E7EB;
|
||||
--color-border-light: #F3F4F6;
|
||||
|
||||
--color-success: #10B981;
|
||||
--color-warning: #F59E0B;
|
||||
--color-error: #EF4444;
|
||||
|
||||
--font-sans: "Inter", sans-serif;
|
||||
|
||||
--radius-card: 20px;
|
||||
--radius-button: 12px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--color-dark);
|
||||
color: #ffffff;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
|
||||
/* Smooth scroll for anchor links */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Scrollbar personnalisee */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--color-dark);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--color-dark-lighter);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Animation hover cards */
|
||||
/* Card hover */
|
||||
.card-hover {
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.card-hover:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 20px 40px rgba(109, 94, 246, 0.15);
|
||||
box-shadow: 0 12px 32px rgba(27, 42, 74, 0.12);
|
||||
}
|
||||
|
||||
/* Gradient text */
|
||||
.gradient-text {
|
||||
background: linear-gradient(135deg, #6D5EF6, #9D8FF9);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Gradient background */
|
||||
.gradient-bg {
|
||||
background: linear-gradient(135deg, #6D5EF6, #9D8FF9);
|
||||
}
|
||||
|
||||
/* Glass effect */
|
||||
.glass {
|
||||
background: rgba(26, 31, 46, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(109, 94, 246, 0.1);
|
||||
}
|
||||
|
||||
/* Pulse animation pour CTA */
|
||||
/* Orange CTA glow */
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 20px rgba(109, 94, 246, 0.3);
|
||||
box-shadow: 0 0 16px rgba(232, 119, 46, 0.3);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 40px rgba(109, 94, 246, 0.6);
|
||||
box-shadow: 0 0 32px rgba(232, 119, 46, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.pulse-glow {
|
||||
animation: pulse-glow 2s ease-in-out infinite;
|
||||
animation: pulse-glow 2.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Scale in animation for popups */
|
||||
@keyframes scale-in {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-scale-in {
|
||||
animation: scale-in 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* Selection color */
|
||||
/* Selection */
|
||||
::selection {
|
||||
background: rgba(109, 94, 246, 0.3);
|
||||
color: #ffffff;
|
||||
background: rgba(27, 42, 74, 0.15);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Skip to content */
|
||||
.skip-to-content {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
z-index: 999;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: var(--color-navy);
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
border-radius: 0 0 8px 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.skip-to-content:focus {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/* Focus visible */
|
||||
*:focus-visible {
|
||||
outline: 2px solid var(--color-orange);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--color-border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-navy);
|
||||
}
|
||||
|
||||
103
app/layout.tsx
103
app/layout.tsx
@@ -7,26 +7,26 @@ export const metadata: Metadata = {
|
||||
metadataBase: new URL(BASE_URL),
|
||||
title: {
|
||||
default:
|
||||
"HookLab | Formation TikTok Shop France - Deviens Cr\u00e9ateur Affili\u00e9",
|
||||
"HookLab | Cr\u00e9ation de sites web pour artisans du b\u00e2timent dans le Nord",
|
||||
template: "%s | HookLab",
|
||||
},
|
||||
description:
|
||||
"Formation coaching TikTok Shop en 8 semaines. Deviens cr\u00e9ateur affili\u00e9 et g\u00e9n\u00e8re des revenus avec l\u2019affiliation TikTok Shop en France. Programme complet : strat\u00e9gie, contenu, mon\u00e9tisation.",
|
||||
"Agence web locale sp\u00e9cialis\u00e9e dans la visibilit\u00e9 Google des artisans du b\u00e2timent dans le Nord (Douai, Orchies, Valenciennes). Sites web, r\u00e9f\u00e9rencement local, syst\u00e8me de confiance.",
|
||||
keywords: [
|
||||
"formation TikTok Shop",
|
||||
"coaching TikTok Shop",
|
||||
"affiliation TikTok Shop France",
|
||||
"gagner de l'argent TikTok Shop",
|
||||
"cr\u00e9ateur TikTok Shop France",
|
||||
"commission TikTok Shop",
|
||||
"programme affiliation TikTok",
|
||||
"revenus TikTok Shop",
|
||||
"devenir affili\u00e9 TikTok Shop",
|
||||
"mon\u00e9tisation TikTok France",
|
||||
"tuto TikTok Shop d\u00e9butant",
|
||||
"revenus passifs TikTok",
|
||||
"site web artisan",
|
||||
"cr\u00e9ation site artisan b\u00e2timent",
|
||||
"r\u00e9f\u00e9rencement local artisan",
|
||||
"agence web Nord",
|
||||
"site internet couvreur",
|
||||
"site internet menuisier",
|
||||
"site internet paysagiste",
|
||||
"visibilit\u00e9 Google artisan",
|
||||
"site web Douai",
|
||||
"site web Valenciennes",
|
||||
"agence web Orchies",
|
||||
"site pro artisan Nord",
|
||||
],
|
||||
authors: [{ name: "HookLab" }],
|
||||
authors: [{ name: "HookLab - Enguerrand Ozano" }],
|
||||
creator: "HookLab",
|
||||
publisher: "HookLab",
|
||||
robots: {
|
||||
@@ -46,23 +46,23 @@ export const metadata: Metadata = {
|
||||
url: BASE_URL,
|
||||
siteName: "HookLab",
|
||||
title:
|
||||
"HookLab | Formation TikTok Shop France - Deviens Cr\u00e9ateur Affili\u00e9",
|
||||
"HookLab | Sites web pour artisans du b\u00e2timent dans le Nord",
|
||||
description:
|
||||
"Formation coaching TikTok Shop en 8 semaines. Deviens cr\u00e9ateur affili\u00e9 et g\u00e9n\u00e8re tes premiers revenus avec l\u2019affiliation TikTok Shop en France.",
|
||||
"Transformez votre bouche-\u00e0-oreille en syst\u00e8me automatique. Sites web et r\u00e9f\u00e9rencement Google pour artisans \u00e0 Douai, Orchies, Valenciennes.",
|
||||
images: [
|
||||
{
|
||||
url: "/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "HookLab - Formation TikTok Shop France",
|
||||
alt: "HookLab - Sites web pour artisans du Nord",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "HookLab | Formation TikTok Shop France",
|
||||
title: "HookLab | Sites web pour artisans du Nord",
|
||||
description:
|
||||
"Deviens cr\u00e9ateur affili\u00e9 TikTok Shop et g\u00e9n\u00e8re des revenus en 8 semaines de coaching.",
|
||||
"Agence web locale pour artisans du b\u00e2timent. Douai, Orchies, Valenciennes.",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
alternates: {
|
||||
@@ -80,12 +80,33 @@ export default function RootLayout({
|
||||
}>) {
|
||||
const jsonLdOrganization = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"@type": "LocalBusiness",
|
||||
name: "HookLab",
|
||||
url: BASE_URL,
|
||||
logo: `${BASE_URL}/logo.png`,
|
||||
description:
|
||||
"Programme de coaching TikTok Shop pour devenir cr\u00e9ateur affili\u00e9 en France.",
|
||||
"Agence web sp\u00e9cialis\u00e9e dans la cr\u00e9ation de sites et la visibilit\u00e9 Google pour les artisans du b\u00e2timent dans le Nord.",
|
||||
address: {
|
||||
"@type": "PostalAddress",
|
||||
streetAddress: "35 rue Mo\u00efse Lambert",
|
||||
addressLocality: "Flines-lez-Raches",
|
||||
postalCode: "59148",
|
||||
addressRegion: "Nord",
|
||||
addressCountry: "FR",
|
||||
},
|
||||
geo: {
|
||||
"@type": "GeoCoordinates",
|
||||
latitude: 50.4267,
|
||||
longitude: 3.2372,
|
||||
},
|
||||
areaServed: [
|
||||
{ "@type": "City", name: "Douai" },
|
||||
{ "@type": "City", name: "Orchies" },
|
||||
{ "@type": "City", name: "Valenciennes" },
|
||||
{ "@type": "City", name: "Arleux" },
|
||||
{ "@type": "City", name: "Flines-lez-Raches" },
|
||||
],
|
||||
priceRange: "$$",
|
||||
contactPoint: {
|
||||
"@type": "ContactPoint",
|
||||
contactType: "customer service",
|
||||
@@ -93,31 +114,6 @@ export default function RootLayout({
|
||||
},
|
||||
};
|
||||
|
||||
const jsonLdCourse = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Course",
|
||||
name: "Formation TikTok Shop - HookLab",
|
||||
description:
|
||||
"Programme de coaching intensif de 8 semaines pour devenir cr\u00e9ateur affili\u00e9 TikTok Shop. Apprenez \u00e0 cr\u00e9er du contenu, s\u00e9lectionner des produits et g\u00e9n\u00e9rer des commissions.",
|
||||
provider: {
|
||||
"@type": "Organization",
|
||||
name: "HookLab",
|
||||
url: BASE_URL,
|
||||
},
|
||||
offers: {
|
||||
"@type": "Offer",
|
||||
price: "490",
|
||||
priceCurrency: "EUR",
|
||||
availability: "https://schema.org/LimitedAvailability",
|
||||
},
|
||||
hasCourseInstance: {
|
||||
"@type": "CourseInstance",
|
||||
courseMode: "online",
|
||||
duration: "P8W",
|
||||
inLanguage: "fr",
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<html lang="fr">
|
||||
<head>
|
||||
@@ -127,14 +123,13 @@ export default function RootLayout({
|
||||
__html: JSON.stringify(jsonLdOrganization),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLdCourse),
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
<body className="antialiased">{children}</body>
|
||||
<body className="antialiased">
|
||||
<a href="#main-content" className="skip-to-content">
|
||||
Aller au contenu principal
|
||||
</a>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
65
app/page.tsx
65
app/page.tsx
@@ -1,68 +1,41 @@
|
||||
import AnnouncementBar from "@/components/marketing/AnnouncementBar";
|
||||
import Navbar from "@/components/marketing/Navbar";
|
||||
import Hero from "@/components/marketing/Hero";
|
||||
import ResultsShowcase from "@/components/marketing/ResultsShowcase";
|
||||
import Method from "@/components/marketing/Method";
|
||||
import PersonaCards from "@/components/marketing/PersonaCards";
|
||||
import ComparisonTable from "@/components/marketing/ComparisonTable";
|
||||
import Testimonials from "@/components/marketing/Testimonials";
|
||||
import Pricing from "@/components/marketing/Pricing";
|
||||
import TrustBadges from "@/components/marketing/TrustBadges";
|
||||
import System from "@/components/marketing/System";
|
||||
import Portfolio from "@/components/marketing/Portfolio";
|
||||
import AboutMe from "@/components/marketing/AboutMe";
|
||||
import FAQ from "@/components/marketing/FAQ";
|
||||
import FinalCTA from "@/components/marketing/FinalCTA";
|
||||
import Contact from "@/components/marketing/Contact";
|
||||
import Footer from "@/components/marketing/Footer";
|
||||
import ExitIntentPopup from "@/components/marketing/ExitIntentPopup";
|
||||
import StickyMobileCTA from "@/components/marketing/StickyMobileCTA";
|
||||
import { getPortfolio } from "@/lib/sanity/queries";
|
||||
|
||||
export default async function LandingPage() {
|
||||
const portfolioItems = await getPortfolio();
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
{/* Top announcement bar */}
|
||||
<AnnouncementBar />
|
||||
|
||||
<main id="main-content" className="min-h-screen">
|
||||
{/* Navigation */}
|
||||
<Navbar />
|
||||
|
||||
{/* Hero with SEO-optimized H1 */}
|
||||
{/* Hero - La Promesse */}
|
||||
<Hero />
|
||||
|
||||
{/* Market opportunity + timeline */}
|
||||
<section id="resultats">
|
||||
<ResultsShowcase />
|
||||
</section>
|
||||
{/* Le Système - Dossier de Confiance */}
|
||||
<System />
|
||||
|
||||
{/* 3-step method */}
|
||||
<Method />
|
||||
{/* Portfolio - Preuves */}
|
||||
<Portfolio items={portfolioItems} />
|
||||
|
||||
{/* Target personas */}
|
||||
<PersonaCards />
|
||||
{/* Qui suis-je - Ancrage Local */}
|
||||
<AboutMe />
|
||||
|
||||
{/* Comparison table */}
|
||||
<ComparisonTable />
|
||||
|
||||
{/* Testimonials with disclaimer */}
|
||||
<Testimonials />
|
||||
|
||||
{/* Pricing with urgency */}
|
||||
<Pricing />
|
||||
|
||||
{/* Trust signals */}
|
||||
<TrustBadges />
|
||||
|
||||
{/* FAQ with structured data */}
|
||||
{/* FAQ */}
|
||||
<FAQ />
|
||||
|
||||
{/* Final CTA */}
|
||||
<FinalCTA />
|
||||
{/* Contact / Audit CTA */}
|
||||
<Contact />
|
||||
|
||||
{/* Footer */}
|
||||
<Footer />
|
||||
|
||||
{/* Exit intent popup */}
|
||||
<ExitIntentPopup />
|
||||
|
||||
{/* Sticky mobile CTA bar */}
|
||||
<StickyMobileCTA />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function robots(): MetadataRoute.Robots {
|
||||
{
|
||||
userAgent: "*",
|
||||
allow: "/",
|
||||
disallow: ["/admin/", "/api/", "/setup-admin/", "/dashboard/", "/profil/", "/formations/"],
|
||||
disallow: ["/admin/", "/api/", "/setup-admin/", "/dashboard/", "/profil/", "/formations/", "/login/", "/register/"],
|
||||
},
|
||||
],
|
||||
sitemap: `${BASE_URL}/sitemap.xml`,
|
||||
|
||||
@@ -10,35 +10,17 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||
changeFrequency: "weekly",
|
||||
priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/candidature`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/login`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.3,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/mentions-legales`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/cgv`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
priority: 0.3,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/confidentialite`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
priority: 0.3,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user