diff --git a/app/globals.css b/app/globals.css index c7e4a78..5d979a0 100644 --- a/app/globals.css +++ b/app/globals.css @@ -358,3 +358,130 @@ html { -webkit-text-fill-color: transparent; background-clip: text; } + +/* ================================================ + BOUTONS — animations premium slide-fill + ================================================ */ +.btn { + position: relative; + overflow: hidden; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + font-weight: 700; + cursor: pointer; + text-decoration: none; + transition: transform 0.2s ease, box-shadow 0.3s ease; +} +.btn:active { transform: scale(0.97) !important; } +.btn > span, .btn > svg { position: relative; z-index: 1; } + +/* Primaire rouge brique — slide depuis la gauche */ +.btn-fill { background: var(--color-orange); color: #fff; } +.btn-fill::before { + content: ""; position: absolute; inset: 0; + background: var(--color-orange-hover); + transform: translateX(-101%); + transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; +} +.btn-fill:hover::before { transform: translateX(0); } +.btn-fill:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(139, 26, 26, 0.40); } + +/* Outline dark — s'inverse en navy */ +.btn-outline-dark { background: transparent; color: var(--color-navy); border: 2px solid var(--color-navy); } +.btn-outline-dark::before { + content: ""; position: absolute; inset: 0; + background: var(--color-navy); + transform: translateX(-101%); + transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; +} +.btn-outline-dark:hover::before { transform: translateX(0); } +.btn-outline-dark:hover { color: #fff; transform: translateY(-2px); } +.btn-outline-dark > span, .btn-outline-dark > svg { position: relative; z-index: 1; } + +/* Outline light — pour fonds sombres */ +.btn-outline-light { background: transparent; color: #fff; border: 2px solid rgba(255,255,255,0.35); } +.btn-outline-light::before { + content: ""; position: absolute; inset: 0; + background: rgba(255,255,255,0.12); + transform: translateX(-101%); + transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; +} +.btn-outline-light:hover::before { transform: translateX(0); } +.btn-outline-light:hover { border-color: rgba(255,255,255,0.65); transform: translateY(-2px); } +.btn-outline-light > span, .btn-outline-light > svg { position: relative; z-index: 1; } + +/* Fill blanc — pour sections colorées */ +.btn-fill-white { background: #fff; color: var(--color-navy); } +.btn-fill-white::before { + content: ""; position: absolute; inset: 0; + background: var(--color-bg-muted); + transform: translateX(-101%); + transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); z-index: 0; +} +.btn-fill-white:hover::before { transform: translateX(0); } +.btn-fill-white:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(0,0,0,0.25); } +.btn-fill-white > span, .btn-fill-white > svg { position: relative; z-index: 1; } + +/* Lien-flèche animé */ +.btn-arrow { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 700; transition: color 0.2s ease; } +.btn-arrow .arrow-icon { display: inline-flex; transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1); } +.btn-arrow:hover .arrow-icon { transform: translateX(7px); } + +/* ================================================ + NAVBAR — underline animé + ================================================ */ +.nav-link { position: relative; } +.nav-link::after { + content: ""; position: absolute; bottom: -2px; left: 0; + width: 0; height: 2px; background: var(--color-orange); + transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} +.nav-link:hover::after, .nav-link.active::after { width: 100%; } + +/* ================================================ + RÉALISATION CARD — slide-up overlay + ================================================ */ +.realisation-overlay { + transform: translateY(100%); + transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); +} +.realisation-card:hover .realisation-overlay { transform: translateY(0); } + +/* ================================================ + HERO — panneau diagonal brique + ================================================ */ +.hero-diagonal-panel { + position: absolute; top: 0; right: 0; + width: 44%; height: 100%; + background: var(--color-orange); + clip-path: polygon(14% 0%, 100% 0%, 100% 100%, 0% 100%); + opacity: 0.13; + pointer-events: none; +} +.hero-diagonal-border { + position: absolute; top: 0; right: 0; + width: 44%; height: 100%; + clip-path: polygon(14% 0%, 100% 0%, 100% 100%, 0% 100%); + border-left: 3px solid rgba(139,26,26,0.5); + pointer-events: none; +} + +/* ================================================ + SERVICE CARD — bordure top rouge brique + ================================================ */ +.service-card-dark { + border-top: 3px solid var(--color-orange); + transition: background 0.3s ease, transform 0.2s ease; +} +.service-card-dark:hover { + background: rgba(255,255,255,0.04); + transform: translateY(-4px); +} + +/* ================================================ + FAQ — icône rotation + ================================================ */ +.faq-icon { transition: transform 0.3s ease; } +details[open] .faq-icon { transform: rotate(45deg); } diff --git a/app/page.tsx b/app/page.tsx index 85b5439..8140d9d 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -24,76 +24,90 @@ export async function generateMetadata(): Promise { }; } -function ServiceCard({ service }: { service: Service }) { +/* ── Arrow SVG ── */ +function Arrow({ className = "w-4 h-4" }: { className?: string }) { + return ( + + + + ); +} + +/* ── Service card — dark bg editorial ── */ +function ServiceCard({ service, index }: { service: Service; index: number }) { const href = service.slug === "conseil" ? "/contact" : `/${service.slug}`; return ( - -
{service.icon}
-

+ +
+ {service.icon} +
+

{service.title}

-

{service.shortDescription}

-
- En savoir plus - - - -
+

{service.shortDescription}

+ + Découvrir + + + + ); } -function StarRating({ note }: { note: number }) { - return ( -
- {Array.from({ length: 5 }).map((_, i) => ( - - - - ))} -
- ); -} - +/* ── Testimonial card ── */ function TestimonialCard({ t }: { t: Testimonial }) { const serviceLabel: Record = { - "construction-maison": "Construction de maison", + "construction-maison": "Construction", renovation: "Rénovation", assainissement: "Assainissement", "creation-acces": "Création d'accès", demolition: "Démolition", }; return ( -
- -

“{t.text}”

-
-

{t.name}

-

{t.ville} — {serviceLabel[t.service] ?? t.service}

+
+
+ {Array.from({ length: 5 }).map((_, i) => ( + + + + ))} +
+

“{t.text}”

+
+

{t.name}

+

+ {t.ville} — {serviceLabel[t.service] ?? t.service} +

); } -function FAQAccordion({ item }: { item: FAQItem }) { +/* ── FAQ item ── */ +function FAQItem({ item }: { item: FAQItem }) { return ( -
- - {item.question} - - - +
+ + + {item.question} + + + + + + -
+
{item.answer}
); } +/* ══════════════════════════════════════════════════ + PAGE PRINCIPALE +══════════════════════════════════════════════════ */ export default async function HomePage() { const [config, services, testimonials, faqItems, values, partners, realisations] = await Promise.all([ @@ -106,217 +120,228 @@ export default async function HomePage() { getRealisations(), ]); - const { hero, zones, zoneDescription, partnersTitle, partnersMessage, phone, phoneRaw } = config; + const { hero, zones, zoneDescription, phone, phoneRaw } = config; return (
- {/* ── SECTION 1 — HERO ── */} -
- {/* Accent diagonal brique */} -
-
+ {/* ══ 1 — HERO ══ */} +
+ {/* Panneaux décoratifs diagonaux */} +
+
-
-
- - {hero.badge} -
+
+
-

- Maçon &
- Constructeur
- dans le Nord (59) -

- -

{hero.subtitle}

- -
- - {hero.cta} - - - - - - {hero.ctaSecondary} - -
- -
- {hero.stats.map((s) => ( -
-
{s.val}
-
{s.label}
+ {/* Contenu gauche */} +
+
+
+
+ + {hero.badge} + +
+

+ Maçon
+ &
+ Constructeur +

- ))} -
-
-
- {/* ── SECTION 2 — NOS SERVICES ── */} -
-
- -
- Ce que nous faisons -

Nos services de maçonnerie

-

- De la construction neuve à la rénovation, Benoît Colin et son équipe prennent en charge tous vos travaux de gros œuvre dans le Nord. +

+ {hero.subtitle}

+ +
+ + {hero.cta} + + + + + + + {phone} + +
+ + {/* Stats */} +
+ {hero.stats.map((s) => ( +
+
+ {s.val} +
+
{s.label}
+
+ ))} +
+
+ + {/* Panneau droit — stats éditoriales sur fond diagonal */} +
+
+ {values.slice(0, 3).map((v, i) => ( +
+
+ {v.icon} +
+
+

{v.title}

+

{v.description}

+
+
+ ))} +
-
-
- {services.map((s, i) => ( - - - - ))}
- {/* ── SECTION 3 — POURQUOI CHOISIR OBC ── */} -
-
+ {/* ══ 2 — NOS SERVICES (dark editorial) ══ */} +
+
-
- Notre différence -

Pourquoi choisir OBC Maçonnerie ?

-
-
-
- {values.map((v, i) => ( - -
-
{v.icon}
-

{v.title}

-

{v.description}

-
-
- ))} -
-
-
- - {/* ── SECTION 4 — RÉSEAU PARTENAIRES ── */} -
-
- -
- Un réseau solide -

{partnersTitle}

-

{partnersMessage}

-
-
-
- {partners.map((p, i) => ( - -
-
{p.icon}
- {p.label} -
-
- ))} -
- -
-

- Un seul interlocuteur pour coordonner l'ensemble de votre projet — de la démolition à la remise des clés. -

- - Découvrir notre réseau - - - +
+
+ + Nos savoir-faire + +

+ Nos
services +

+
+ + Tous les services +
-
-
- {/* ── SECTION 5 — ZONE D'INTERVENTION ── */} -
-
- - Secteur d'activité -

Nous intervenons dans toute la région

-

- OBC Maçonnerie intervient dans un rayon de {zoneDescription}. -

-
-
- {zones.map((v, i) => ( - - - 📍{v} - +
+ {services.map((s, i) => ( + + ))}
- -

- Et dans toutes les communes à {zoneDescription} — contactez-nous pour vérifier votre zone. +

+
+ + {/* ══ 3 — BANDE CTA ══ */} +
+
+
+ +

+ Devis gratuit — Réponse sous 24h

- - Demander un devis dans ma commune - +

+ Votre projet mérite
+ un artisan de confiance +

+
+ + Obtenir mon devis gratuit + + + + Appeler Benoît — {phone} + +
- {/* ── SECTION 6 — RÉALISATIONS ── */} + {/* ══ 4 — RÉALISATIONS ══ */}
-
+
-
- Nos chantiers -

Aperçu de nos réalisations

+
+
+ + Nos chantiers + +

+ Réalisations +

+
+ + Voir tout + +
-
+ +
{realisations.map((r, i) => { - const colors = ["bg-navy", "bg-stone", "bg-orange"]; + const bgColors = ["bg-navy", "bg-stone", "bg-navy-light", "bg-stone", "bg-navy", "bg-navy-light"]; return ( - -
-
- {i + 1} + +
+ {/* Fond placeholder */} +
+ 0{i + 1}
-
- {r.ville} -

{r.title}

-

{r.description}

+ {/* Ligne orange bas (repos) */} +
+ {/* Infos au repos */} +
+ {r.ville} +

{r.title}

+
+ {/* Overlay hover — slide from bottom */} +
+ {r.ville} +

{r.title}

+

{r.description}

); })}
- -
- - Voir toutes nos réalisations - - - - -
-
- {/* ── SECTION 7 — TÉMOIGNAGES ── */} -
-
+ {/* ══ 5 — TÉMOIGNAGES (dark) ══ */} +
+
-
- Ce qu'ils en disent -

Témoignages clients

+
+ + Ce qu'ils en disent + +

+ Clients
satisfaits +

-
+
{testimonials.map((t, i) => ( @@ -326,39 +351,199 @@ export default async function HomePage() {
- {/* ── SECTION 8 — FAQ ── */} + {/* ══ 6 — ZONE D'INTERVENTION ══ */}
-
+
+
+ + + Secteur d'activité + +

+ On intervient
dans tout le Nord +

+

+ OBC Maçonnerie rayonne sur {zoneDescription} autour de Mouchin — de Douai à Valenciennes, Orchies et Saint-Amand-les-Eaux. +

+ + Vérifier ma commune + + +
+ + +
+ {zones.map((v, i) => ( + + + {v} + + ))} + + + communes voisines + +
+
+
+
+
+ + {/* ══ 7 — PARTENAIRES ══ */} +
+
-
- Questions fréquentes -

FAQ

+
+
+ + Un réseau solide + +

+ Nos partenaires +

+
+ + Découvrir le réseau + +
-
- {faqItems.map((f, i) => ( - - +
+ {partners.map((p, i) => ( + +
+
{p.icon}
+ + {p.label} + +
))}
- {/* ── SECTION 9 — FORMULAIRE DE CONTACT ── */} -
-
- -
- Devis gratuit -

Parlez-nous de votre projet

-

- Réponse sous 24h — ou appelez directement Benoît au{" "} - {phone} + {/* ══ 8 — FAQ ══ */} +

+
+
+ + + Questions fréquentes + +

+ On répond
à vos questions +

+

+ Pas de réponse à votre question ? Appelez directement Benoît au{" "} + {phone}.

+ + Poser ma question + + +
+ + +
+ {faqItems.map((f) => ( + + ))} +
+
+
+
+
+ + {/* ══ 9 — CONTACT SPLIT ══ */} +
+ {/* Gauche — dark info */} +
+
+ + + Contactez-nous + +

+ Parlons de
votre projet +

+ +
+ +
+ + + +
+
+

Téléphone

+

{phone}

+
+
+ +
+
+ + + + +
+
+

Siège

+

{config.address}

+
+
+ +
+
+ + + +
+
+

Délai de réponse

+

Sous 24h — Du lundi au samedi

+
+
+
+ + {/* Garanties */} +
+ {[ + { val: "Gratuit", label: "Devis" }, + { val: "24h", label: "Réponse" }, + { val: "10+", label: "Ans d'expérience" }, + { val: "100%", label: "Satisfaction" }, + ].map((s) => ( +
+
{s.val}
+
{s.label}
+
+ ))}
- +
+ + {/* Droite — formulaire */} +
+ + + Devis gratuit + +

+ Votre demande +

diff --git a/components/marketing/ContactForm.tsx b/components/marketing/ContactForm.tsx index 8be7bc1..f6b4534 100644 --- a/components/marketing/ContactForm.tsx +++ b/components/marketing/ContactForm.tsx @@ -57,165 +57,95 @@ export default function ContactForm() { if (status === "success") { return ( -
-
-

Demande envoyée !

+
+
+ + + +
+

Demande envoyée !

- Benoît vous rappellera dans les 24h. En cas d'urgence, appelez directement le{" "} - + Benoît vous rappelle sous 24h. En cas d'urgence :{" "} + 06 74 45 30 89 - .

); } + const ic = "w-full border border-border bg-bg-white px-4 py-3 text-sm text-text focus:outline-none focus:border-orange transition-colors"; + const lc = "block text-xs font-bold uppercase tracking-widest text-navy mb-2"; + return ( -
+
- - + +
- - + +
- - + +
- - - {typesProjets.map((t) => ( - - ))} + {typesProjets.map((t) => )}
- -