Skip to content

Commit c55aedd

Browse files
committed
styles(website): add InView animations
1 parent 7a37ca7 commit c55aedd

12 files changed

Lines changed: 177 additions & 63 deletions

File tree

app/src/app/layout.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export default function RootLayout({ children }: LayoutProps) {
4949
<Header />
5050
{children}
5151
<Footer />
52-
<Cursor />
5352
</body>
5453
</html>
5554
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useEffect, useState } from "react"
2+
3+
export const useMouse = () => {
4+
const [isMoving, setIsMoving] = useState(false)
5+
const [position, setPosition] = useState({ x: 0, y: 0 })
6+
7+
useEffect(() => {
8+
const handleMouseMove = (event: MouseEvent) => {
9+
setPosition({ x: event.clientX, y: event.clientY })
10+
setIsMoving(true)
11+
}
12+
13+
const handleMouseLeave = () => {
14+
setIsMoving(false)
15+
}
16+
17+
window.addEventListener("mousemove", handleMouseMove)
18+
window.addEventListener("mouseleave", handleMouseLeave)
19+
20+
return () => {
21+
window.removeEventListener("mousemove", handleMouseMove)
22+
window.removeEventListener("mouseleave", handleMouseLeave)
23+
}
24+
}, [])
25+
return { isMoving, position }
26+
}

app/src/lib/@types/props.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,8 @@ export interface TextScrambleProps {
7373
as?: React.ElementType
7474
characterSet?: string
7575
}
76+
77+
export interface SegmentAnimationProps {
78+
title: string
79+
description: string
80+
}

app/src/lib/content.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export const whyChooseUsContent = [
2+
{
3+
number: "/01",
4+
title: "Native",
5+
desc: `Our utilities are built using Tailwind’s new API — no legacy plugins, no PostCSS. Just clean, modern extension.`,
6+
},
7+
{
8+
number: "/02",
9+
title: "Dynamic Styling",
10+
desc: `Use Tailwind’s new syntax like [margin:12px] to update our utility styles inline, without modifying config files.`,
11+
},
12+
{
13+
number: "/03",
14+
title: "Variant Support",
15+
desc: `Create custom variants easily with our utilities. Built on v4’s JIT engine, you get dynamic variant control out of the box.`,
16+
},
17+
{
18+
number: "/04",
19+
title: "Clean Integration",
20+
desc: `We follow Tailwind’s core design philosophy — fast builds, atomic classes, and a unified, zero-runtime experience.`,
21+
},
22+
]

app/src/ui/animations/segment.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"use client"
2+
import { useRef } from "react"
3+
import { useInView, AnimatePresence } from "motion/react"
4+
import { TextEffect } from "@/ui/text-effect"
5+
import { SegmentAnimationProps } from "@/lib/@types/props"
6+
7+
export const SegmentAnimation = ({ title, description }: SegmentAnimationProps) => {
8+
const containerRef = useRef<HTMLDivElement>(null)
9+
const isView = useInView(containerRef, {
10+
once: true,
11+
margin: "-100px 0px -100px 0px",
12+
})
13+
14+
return (
15+
<div className="py-16 px-4 grid sm:px-6 md:px-8 base:px-10 base:items-center base:grid-cols-2" ref={containerRef}>
16+
<AnimatePresence>
17+
{isView ? (
18+
<TextEffect
19+
className="mb-6 text-primary text-2xl md:text-fluid-3xl"
20+
as="h2"
21+
preset="fade-in-blur"
22+
speedReveal={1.1}
23+
speedSegment={0.5}
24+
>
25+
{title}
26+
</TextEffect>
27+
) : (
28+
<span className="opacity-0">{title}</span>
29+
)}
30+
</AnimatePresence>
31+
<AnimatePresence>
32+
{isView ? (
33+
<TextEffect className="text-muted text-fluid-base" preset="fade-in-blur" speedReveal={1.1} speedSegment={0.5}>
34+
{description}
35+
</TextEffect>
36+
) : (
37+
<span className="opacity-0">{description}</span>
38+
)}
39+
</AnimatePresence>
40+
</div>
41+
)
42+
}

app/src/ui/cursor.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"use client"
2+
import { motion } from "motion/react"
3+
import { useMouse } from "@/hooks/use-mouse-position"
4+
5+
export const Cursor = () => {
6+
const {
7+
position: { x, y },
8+
} = useMouse()
9+
10+
return (
11+
<motion.span
12+
className="size-10 block rounded-full bg-white pointer-events-none mix-blend-difference fixed z-50"
13+
animate={{ x, y }}
14+
transition={{ type: "spring", stiffness: 300, damping: 30, mass: 0.5 }}
15+
style={{ translateX: "-50%", translateY: "-50%" }}
16+
/>
17+
)
18+
}

app/src/ui/developer-experience.tsx

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,47 @@
1+
"use client"
2+
import { useState } from "react"
13
import { Separator } from "./separator"
4+
import { motion } from "motion/react"
5+
import { SegmentAnimation } from "./animations/segment"
6+
import { cardVariants } from "./motion/card.motion"
7+
import { whyChooseUsContent } from "@/lib/content"
28

39
export const DeveloperExperienceSection = () => {
10+
const [hovered, setHovered] = useState<number | null>(null)
11+
412
return (
513
<section>
614
<Separator index={1}>Built for real projects</Separator>
715
<section className="min-h-[calc(100dvh-4rem)] mx-10 flex flex-col border-x border-solid border-border base:mx-16 xl:min-h-auto">
8-
<div className="py-16 px-4 grid sm:px-6 md:px-8 base:px-10 base:items-center base:grid-cols-2">
9-
<h2 className="mb-6 text-primary text-2xl md:text-fluid-3xl">Why Choose Us</h2>
10-
<p className="text-muted text-fluid-base">
11-
Tailwind CSS v4 brings a modern engine — and our utilities are built for it. We’ve designed every package
12-
to integrate seamlessly using the new configuration API, variant generator, and dynamic styling support.
13-
</p>
14-
</div>
16+
<SegmentAnimation
17+
title="Why Choose Us"
18+
description="Tailwind CSS v4 brings a modern engine — and our utilities are built for it. We’ve designed every package to integrate seamlessly using the new configuration API, variant generator, and dynamic styling support."
19+
/>
1520
<div className="grid text-primary text-left article:border-t article:border-solid article:border-border lg:flex-100 lg:grid-cols-2 lg:article:border-r lg:article:even:border-r-0 xl:min-h-[30dvw] xl:grid-cols-4 xl:article:nth-[2]:border-r">
16-
<article className="w-full h-full py-14 px-4 flex items-center justify-between gap-x-6 sm:px-6 sm:gap-x-10 md:px-8 md:gap-x-12 base:px-10 base:gap-x-16 lg:flex-col lg:items-start">
17-
<span>/01</span>
18-
<div className="text-left self-end xl:text-right">
19-
<p>Native</p>
20-
<p className="mt-1 text-muted text-sm">
21-
Our utilities are built using Tailwind’s new API — no legacy plugins, no PostCSS. Just clean,
22-
modern extension.
23-
</p>
24-
</div>
25-
</article>
26-
<article className="w-full h-full py-14 px-4 flex items-center justify-between gap-x-6 sm:px-6 sm:gap-x-10 md:px-8 md:gap-x-12 base:px-10 base:gap-x-16 lg:flex-col lg:items-start">
27-
<span>/02</span>
28-
<div className="text-left self-end xl:text-right">
29-
<p>Dynamic Styling</p>
30-
<p className="mt-1 text-muted text-sm">
31-
Use Tailwind’s new syntax like `[margin:12px]` to update our utility styles inline, without
32-
modifying config files.
33-
</p>
34-
</div>
35-
</article>
36-
<article className="w-full h-full py-14 px-4 flex items-center justify-between gap-x-6 sm:px-6 sm:gap-x-10 md:px-8 md:gap-x-12 base:px-10 base:gap-x-16 lg:flex-col lg:items-start">
37-
<span>/03</span>
38-
<div className="text-left self-end xl:text-right">
39-
<p>Variant Support</p>
40-
<p className="mt-1 text-muted text-sm">
41-
Create custom variants easily with our utilities. Built on v4’s JIT engine, you get dynamic
42-
variant control out of the box.
43-
</p>
44-
</div>
45-
</article>
46-
<article className="w-full h-full py-14 px-4 flex items-center justify-between gap-x-6 sm:px-6 sm:gap-x-10 md:px-8 md:gap-x-12 base:px-10 base:gap-x-16 lg:flex-col lg:items-start">
47-
<span>/04</span>
48-
<div className="text-left self-end xl:text-right">
49-
<p>Clean Integration</p>
50-
<p className="mt-1 text-muted text-sm">
51-
We follow Tailwind’s core design philosophy — fast builds, atomic classes, and a unified,
52-
zero-runtime experience.
53-
</p>
54-
</div>
55-
</article>
21+
{whyChooseUsContent.map((item, idx) => (
22+
<motion.article
23+
key={item.number}
24+
className="group w-full h-full py-14 px-4 flex items-center justify-between gap-x-6 relative z-10 overflow-hidden sm:px-6 sm:gap-x-10 md:px-8 md:gap-x-12 base:px-10 base:gap-x-16 lg:flex-col lg:items-start hover:bg-surface hover:cursor-pointer"
25+
onMouseEnter={() => setHovered(idx)}
26+
onMouseLeave={() => setHovered(null)}
27+
transition={cardVariants}
28+
>
29+
<span>{item.number}</span>
30+
<div className="text-left self-end xl:text-right overflow-hidden">
31+
<p className="text-lg font-medium group-hover:text-primary">{item.title}</p>
32+
<motion.p
33+
className="mt-1 text-muted overflow-hidden group-hover:text-primary"
34+
animate={
35+
hovered === idx ? { opacity: 1, y: 0, height: "auto" } : { opacity: 0, y: 20, height: 0 }
36+
}
37+
initial={{ opacity: 0, y: 20, height: 0 }}
38+
transition={{ duration: 0.4, ease: [0.4, 0, 0.2, 1] }}
39+
>
40+
{item.desc}
41+
</motion.p>
42+
</div>
43+
</motion.article>
44+
))}
5645
</div>
5746
</section>
5847
</section>

app/src/ui/docs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const DocsSection = () => {
66
return (
77
<section>
88
<Separator index={4}>Start Building</Separator>
9-
<div className="mx-10 py-16 px-4 flex items-center justify-center flex-col text-center border-x border-solid border-border sm:px-6 md:px-8 base:mx-16 base:px-10">
9+
<div className="min-h-[50dvh] mx-10 py-16 px-4 flex items-center justify-center flex-col text-center border-x border-solid border-border sm:px-6 md:px-8 base:mx-16 base:px-10">
1010
<h2 className="text-primary text-2xl md:text-fluid-3xl">Explore the Docs</h2>
1111
<p className="mt-6 mb-8 text-muted text-fluid-base">
1212
Get everything you need to start building with our utilities — from installation to deep usage examples.

app/src/ui/footer.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ export const Footer = () => {
1010
<footer>
1111
<Separator index={4}>Stay connected</Separator>
1212
<section className="mx-10 text-primary border-x border-solid border-border base:grid md:grid-cols-2 base:mx-16">
13-
<h2 className="py-16 px-4 text-fluid-xl text-center border-b border-solid border-border sm:px-6 md:px-8 base:px-10 base:col-span-2">
13+
<h2 className="py-16 px-4 text-fluid-xl text-center border-b border-solid border-border sm:px-6 md:px-8 base:px-10 base:col-span-2 hover:bg-surface">
1414
@halvaradop/tailwindcss
1515
</h2>
16-
<p className="py-16 px-4 border-b border-border sm:px-6 md:px-8 base:px-10">
16+
<p className="py-16 px-4 border-b border-border sm:px-6 md:px-8 base:px-10 hover:bg-surface">
1717
An open-source toolkit that brings missing utility classes to Tailwind CSS. Built to simplify your setup and
1818
boost productivity — with minimal configuration.
1919
</p>
20-
<div className="py-16 px-4 flex justify-evenly gap-10 text-muted text-sm font-medium border-b border-solid border-border sm:px-6 md:px-8 base:px-10 base:row-span-2 base:justify-around base:border-b-0 base:border-l">
20+
<div className="py-16 px-4 flex justify-evenly gap-10 text-muted text-sm font-medium border-b border-solid border-border hover:bg-surface sm:px-6 md:px-8 base:px-10 base:row-span-2 base:justify-around base:border-b-0 base:border-l">
2121
<ul className="text-left space-y-4 li:hover:text-primary">
2222
<li className="text-primary text-lg font-semibold">Product</li>
2323
<li>
@@ -47,7 +47,7 @@ export const Footer = () => {
4747
</li>
4848
</ul>
4949
</div>
50-
<div className="grid grid-cols-3">
50+
<div className="grid grid-cols-3 figure:hover:bg-surface">
5151
<figure className="py-10 grid place-content-center md:py-16">
5252
<Image src={githubLogo} alt="Github Logo" />
5353
</figure>
@@ -60,7 +60,7 @@ export const Footer = () => {
6060
</div>
6161
</section>
6262
<Separator index={5} rotate>
63-
<span className="mx-auto">&#169; 2025 halvaradop</span>
63+
<span className="mx-auto">&#169; 2025 halvaradop.</span>
6464
</Separator>
6565
</footer>
6666
)

app/src/ui/globals.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ It is generating errors to load animations styles
2020
--color-success: oklch(75% 0.18 140);
2121
--color-danger: oklch(65% 0.2 25);
2222

23-
--color-surface: oklch(98% 0 0);
23+
--color-surface: #0a0a0b;
2424
--color-on-surface: oklch(20% 0.02 260);
2525

2626
--color-primary: #f7f8f8;

0 commit comments

Comments
 (0)