further improvements
This commit is contained in:
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { LazySection } from "@/components/LazySection";
|
import { LazySection } from "@/components/LazySection";
|
||||||
import { Skeleton, SkeletonWave } from "@/components/Skeleton";
|
import { Skeleton, SkeletonWave } from "@/components/Skeleton";
|
||||||
|
import MaterialSymbolsFont from "@/components/MaterialSymbolsFont";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Contatti | CiMa Progetti",
|
title: "Contatti | CiMa Progetti",
|
||||||
@@ -11,6 +12,7 @@ export const metadata: Metadata = {
|
|||||||
export default function Contatti() {
|
export default function Contatti() {
|
||||||
return (
|
return (
|
||||||
<div className="pt-24 sm:pt-32 pb-16 sm:pb-24 px-6 lg:px-8 max-w-7xl mx-auto overflow-x-hidden">
|
<div className="pt-24 sm:pt-32 pb-16 sm:pb-24 px-6 lg:px-8 max-w-7xl mx-auto overflow-x-hidden">
|
||||||
|
<MaterialSymbolsFont />
|
||||||
{/* Hero Section - Priority render */}
|
{/* Hero Section - Priority render */}
|
||||||
<section className="grid grid-cols-1 lg:grid-cols-12 mb-16 lg:mb-24">
|
<section className="grid grid-cols-1 lg:grid-cols-12 mb-16 lg:mb-24">
|
||||||
<div className="col-span-12 md:col-span-8">
|
<div className="col-span-12 md:col-span-8">
|
||||||
|
|||||||
@@ -69,11 +69,21 @@ img {
|
|||||||
decoding: async;
|
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 {
|
@keyframes hero-fade-up {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(60px);
|
transform: translateY(30px);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
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 {
|
.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 {
|
.hero-fade-up-delay-1 {
|
||||||
animation-delay: 0.6s;
|
animation-delay: 0.5s;
|
||||||
animation-duration: 0.6s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-fade-up-delay-2 {
|
.hero-fade-up-delay-2 {
|
||||||
animation-delay: 0.75s;
|
animation-delay: 0.65s;
|
||||||
animation-duration: 0.6s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skeleton wave animation */
|
/* Skeleton wave animation */
|
||||||
|
|||||||
@@ -43,24 +43,9 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="it" className={`${inter.variable} scroll-smooth`}>
|
<html lang="it" className={`${inter.variable} scroll-smooth`}>
|
||||||
<head>
|
<head>
|
||||||
{/* Preconnect to Google Fonts for faster loading */}
|
{/* Preconnect to Google Fonts — used by Material Symbols loaded lazily */}
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
||||||
<link
|
|
||||||
rel="preconnect"
|
|
||||||
href="https://fonts.gstatic.com"
|
|
||||||
crossOrigin="anonymous"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* DNS prefetch for third-party domains */}
|
|
||||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />
|
||||||
{/* Material Symbols — reduced to single weight/fill, display=swap prevents render blocking */}
|
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@400,0&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Inter font is self-hosted by next/font — no external preload needed */}
|
|
||||||
</head>
|
</head>
|
||||||
<body className="min-h-screen flex flex-col">
|
<body className="min-h-screen flex flex-col">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { useGsapScrollTrigger } from "@/components/hooks/useGsapScrollTrigger";
|
import { useGsapScrollTrigger } from "@/components/hooks/useGsapScrollTrigger";
|
||||||
|
import MaterialSymbolsFont from "@/components/MaterialSymbolsFont";
|
||||||
|
|
||||||
const ApproccioSection = dynamic(() => import("@/components/sections/ApproccioSection"), { ssr: false });
|
const ApproccioSection = dynamic(() => import("@/components/sections/ApproccioSection"), { ssr: false });
|
||||||
const BeforeAfterSection = dynamic(() => import("@/components/sections/BeforeAfterSection"), { ssr: false });
|
const BeforeAfterSection = dynamic(() => import("@/components/sections/BeforeAfterSection"), { ssr: false });
|
||||||
@@ -14,6 +15,7 @@ export default function HomeSections() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<MaterialSymbolsFont />
|
||||||
<ApproccioSection />
|
<ApproccioSection />
|
||||||
<BeforeAfterSection />
|
<BeforeAfterSection />
|
||||||
<ServicesSection />
|
<ServicesSection />
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ export default function HeroSection() {
|
|||||||
return (
|
return (
|
||||||
<section className="snap-section min-h-screen flex items-center justify-center px-6 lg:px-8 pt-20">
|
<section className="snap-section min-h-screen flex items-center justify-center px-6 lg:px-8 pt-20">
|
||||||
<div className="max-w-5xl mx-auto text-center">
|
<div className="max-w-5xl mx-auto text-center">
|
||||||
<h1 className="text-huge font-black uppercase mb-8 sm:mb-12 hero-fade-up">
|
<h1 className="text-huge font-black uppercase mb-8 sm:mb-12 hero-slide-up">
|
||||||
La <span className="text-primary">struttura</span> digitale del
|
La <span className="text-primary">struttura</span> digitale del
|
||||||
tuo business.
|
tuo business.
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
Reference in New Issue
Block a user