feat: add animated components for enhanced UI/UX

- Introduced DrawLine component for drawing animations.
- Added LazyRevealImage component for lazy loading images with reveal animations.
- Implemented TextDiffuseReveal for animated text reveals with staggered effects.
- Created TopProgressBar for a dynamic loading indicator.
- Added PointCloud mock for testing animations.
- Developed useReducedMotion hook to handle user preferences for reduced motion.
- Centralized animation configurations in config.ts for easier management.
- Defined animation variants in variants.ts for consistent animation effects.
- Established AnimationProvider to supply global animation settings.
- Created tests for AnimationProvider and useReducedMotion hook.
- Added SVG assets for branding and UI elements.
- Documented frontend review plan and hero circuit board animation plan.
This commit is contained in:
Evandro Fonseca Junior committed 2026-03-15 21:06:43 -03:00
1 parent 0ab6930f92
commit 08dd046887
76 files changed
+21682 -1197

No files matched your search

+82 -14
View File
@@ -2,11 +2,14 @@
import type React from "react";
import { useState } from "react";
import { motion, type Variants, useReducedMotion } from "framer-motion";
import { Section } from "./Section";
import { DrawLine } from "./animations/DrawLine";
const WHATSAPP_NUMBER = "5547992742365";
export default function Contact() {
const shouldReduceMotion = useReducedMotion();
const [formData, setFormData] = useState({
name: "",
email: "",
@@ -25,30 +28,88 @@ export default function Contact() {
window.open(whatsappUrl, "_blank", "noopener,noreferrer");
};
const gridVariants: Variants = {
hidden: {},
visible: {
transition: {
delayChildren: 0.05,
staggerChildren: 0.08,
},
},
};
const cardVariants: Variants = {
hidden: shouldReduceMotion
? { opacity: 0 }
: { opacity: 0, y: 18, clipPath: "inset(100% 0 0 0)" },
visible: {
opacity: 1,
y: 0,
clipPath: "inset(0% 0 0 0)",
transition: shouldReduceMotion
? { duration: 0.25 }
: { duration: 0.75, ease: [0.16, 1, 0.3, 1] },
},
};
return (
<Section
id="contact"
eyebrow="CONTACT_PROTOCOL.init"
title="Vamos discutir o próximo sistema"
title="Vamos discutir o proximo sistema"
description="Descreva o contexto, o gargalo ou o produto. O contato abre direto no WhatsApp com briefing estruturado."
dark
disableChildrenAnimation
>
<div className="ds-grid-2">
<div className="ds-card">
<motion.div
className="ds-grid-2"
initial="hidden"
whileInView="visible"
viewport={{ once: true, amount: 0.2 }}
variants={gridVariants}
>
<motion.div
className="ds-card"
variants={cardVariants}
whileHover={
shouldReduceMotion
? undefined
: {
y: -4,
boxShadow: "0 20px 42px rgba(0, 0, 0, 0.4)",
}
}
whileTap={shouldReduceMotion ? undefined : { scale: 0.995 }}
transition={{ type: "spring", stiffness: 180, damping: 18 }}
>
<div className="ds-kicker">Response SLA</div>
<h3 className="ds-card-title">Retorno inicial em até 24h</h3>
<DrawLine delay={0.04} />
<h3 className="ds-card-title">Retorno inicial em ate 24h</h3>
<p className="ds-copy">
Ideal para discovery técnico, revisão de arquitetura, rescue de
projeto, otimização de performance ou construção de produto do zero.
Ideal para discovery tecnico, revisao de arquitetura, rescue de
projeto, otimizacao de performance ou construcao de produto do zero.
</p>
<div className="mt-sp-6 space-y-sp-4 text-[12px] leading-7 text-[rgba(255,255,255,.7)]">
<div>WhatsApp: +55 47 99274-2365</div>
<div>E-mail: evandrofonsecajunior@gmail.com</div>
<div>Base: Garuva, Santa Catarina · atuação remota</div>
<div>Base: Garuva, Santa Catarina | atuacao remota</div>
</div>
</div>
</motion.div>
<form onSubmit={handleSubmit} className="ds-card space-y-sp-5">
<motion.form
onSubmit={handleSubmit}
className="ds-card space-y-sp-5"
variants={cardVariants}
whileHover={
shouldReduceMotion
? undefined
: {
y: -4,
boxShadow: "0 20px 42px rgba(0, 0, 0, 0.4)",
}
}
transition={{ type: "spring", stiffness: 180, damping: 18 }}
>
<div>
<label htmlFor="contact-name" className="ds-kicker block">
Nome completo
@@ -103,7 +164,7 @@ export default function Contact() {
<option value="full-stack">Desenvolvimento Full-Stack</option>
<option value="cloud">Cloud & Infrastructure</option>
<option value="iot">Internet of Things (IoT)</option>
<option value="consultancy">Consultoria Técnica Sênior</option>
<option value="consultancy">Consultoria Tecnica Senior</option>
</select>
</div>
<div>
@@ -125,11 +186,18 @@ export default function Contact() {
}}
/>
</div>
<button type="submit" className="ds-link ds-link-accent border-0">
<motion.button
type="submit"
className="ds-link ds-link-accent border-0"
whileHover={shouldReduceMotion ? undefined : { scale: 1.03 }}
whileTap={shouldReduceMotion ? undefined : { scale: 0.97 }}
transition={{ type: "spring", stiffness: 260, damping: 20 }}
>
Iniciar protocolo de contato
</button>
</form>
</div>
</motion.button>
</motion.form>
</motion.div>
</Section>
);
}