diff --git a/frontend/src/app/contatti/page.tsx b/frontend/src/app/contatti/page.tsx index 4c70183..bad8b8d 100644 --- a/frontend/src/app/contatti/page.tsx +++ b/frontend/src/app/contatti/page.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import Image from "next/image"; import { LazySection } from "@/components/LazySection"; import { Skeleton, SkeletonWave } from "@/components/Skeleton"; +import MaterialSymbolsFont from "@/components/MaterialSymbolsFont"; export const metadata: Metadata = { title: "Contatti | CiMa Progetti", @@ -11,6 +12,7 @@ export const metadata: Metadata = { export default function Contatti() { return (
+ {/* Hero Section - Priority render */}
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index e89ca68..2093684 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -69,11 +69,21 @@ img { decoding: async; } -/* Hero entrance animations */ +/* Hero entrance animations — headline uses slide-only (no opacity) + so LCP fires immediately; CTAs fade in after. */ +@keyframes hero-slide-up { + from { + transform: translateY(40px); + } + to { + transform: translateY(0); + } +} + @keyframes hero-fade-up { from { opacity: 0; - transform: translateY(60px); + transform: translateY(30px); } to { opacity: 1; @@ -81,18 +91,20 @@ img { } } +.hero-slide-up { + animation: hero-slide-up 0.8s cubic-bezier(0.33, 1, 0.68, 1) both; +} + .hero-fade-up { - animation: hero-fade-up 1s cubic-bezier(0.33, 1, 0.68, 1) both; + animation: hero-fade-up 0.6s cubic-bezier(0.33, 1, 0.68, 1) both; } .hero-fade-up-delay-1 { - animation-delay: 0.6s; - animation-duration: 0.6s; + animation-delay: 0.5s; } .hero-fade-up-delay-2 { - animation-delay: 0.75s; - animation-duration: 0.6s; + animation-delay: 0.65s; } /* Skeleton wave animation */ diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index d33cf10..48eb13a 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -43,24 +43,9 @@ export default function RootLayout({ return ( - {/* Preconnect to Google Fonts for faster loading */} - - - - {/* DNS prefetch for third-party domains */} + {/* Preconnect to Google Fonts — used by Material Symbols loaded lazily */} - - {/* Material Symbols — reduced to single weight/fill, display=swap prevents render blocking */} - - - {/* Inter font is self-hosted by next/font — no external preload needed */} + diff --git a/frontend/src/components/HomeSections.tsx b/frontend/src/components/HomeSections.tsx index b452598..9fa16c2 100644 --- a/frontend/src/components/HomeSections.tsx +++ b/frontend/src/components/HomeSections.tsx @@ -1,6 +1,7 @@ "use client"; import dynamic from "next/dynamic"; import { useGsapScrollTrigger } from "@/components/hooks/useGsapScrollTrigger"; +import MaterialSymbolsFont from "@/components/MaterialSymbolsFont"; const ApproccioSection = dynamic(() => import("@/components/sections/ApproccioSection"), { ssr: false }); const BeforeAfterSection = dynamic(() => import("@/components/sections/BeforeAfterSection"), { ssr: false }); @@ -14,6 +15,7 @@ export default function HomeSections() { return ( <> + diff --git a/frontend/src/components/MaterialSymbolsFont.tsx b/frontend/src/components/MaterialSymbolsFont.tsx new file mode 100644 index 0000000..08256fe --- /dev/null +++ b/frontend/src/components/MaterialSymbolsFont.tsx @@ -0,0 +1,19 @@ +"use client"; +import { useEffect } from "react"; + +const MATERIAL_SYMBOLS_URL = + "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@400,0&display=swap"; + +let loaded = false; + +export default function MaterialSymbolsFont() { + useEffect(() => { + if (loaded) return; + loaded = true; + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = MATERIAL_SYMBOLS_URL; + document.head.appendChild(link); + }, []); + return null; +} diff --git a/frontend/src/components/sections/HeroSection.tsx b/frontend/src/components/sections/HeroSection.tsx index 45eb463..3006d0c 100644 --- a/frontend/src/components/sections/HeroSection.tsx +++ b/frontend/src/components/sections/HeroSection.tsx @@ -4,7 +4,7 @@ export default function HeroSection() { return (
-

+

La struttura digitale del tuo business.