Build a React + Vite + TypeScript + Tailwind CSS landing page for a creative
studio called Prisma, with three sections — Hero, About, and Features. Use
framer-motion for animations and lucide-react for icons. The design is dark,
moody, and cinematic with a warm cream palette.
Tech stack
- Vite + React 18 + TypeScript
- Tailwind CSS 3
framer-motion— pull-up text, fade-in, scroll-linked opacity, card entranceslucide-react—ArrowRight,Check
npm create vite@latest prisma -- --template react-ts
npm install framer-motion lucide-reactFonts
Load two Google Fonts in index.html:
- Almarai (weights 300, 400, 700, 800) — the global default font.
- Instrument Serif (italic only) — italic accent text in the About section.
Set the global font family in index.css:
* {
font-family: 'Almarai', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
}Extend tailwind.config.js:
export default {
theme: {
extend: {
colors: {
primary: "#DEDBC8", // warm cream — primary text and accents
},
fontFamily: {
serif: ['"Instrument Serif"', "serif"],
},
},
},
};Color system
- Background: black (
#000000) globally,#101010for the About card,#212121for Features cards. - Primary text:
#E1E0CC(applied via inline style — slightly different from the Tailwind primary). - Tailwind primary:
#DEDBC8(used fortext-primary,text-primary/70). - Gray text:
text-gray-400,text-gray-500. - Navbar links:
rgba(225, 224, 204, 0.8), hover#E1E0CC.
Custom CSS utilities
Two SVG noise-texture utilities in index.css, both using inline SVG data URIs with an feTurbulence filter:
.noise-overlay— fractal noise (baseFrequency: 0.85,numOctaves: 3), overlaid on the hero video..bg-noise— fractal noise (baseFrequency: 0.9,numOctaves: 4), a subtle background in the Features section.
Section 1 — Hero
Full viewport height (h-screen). The section has p-4 md:p-6 padding for an inset effect; inside is a container with rounded-2xl md:rounded-[2rem] and overflow-hidden.
Background video — fills the container, object-cover:
<video autoPlay loop muted playsInline className="w-full h-full object-cover">
<source
src="https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260405_170732_8a9ccda6-5cff-4628-b164-059c500a2b41.mp4"
type="video/mp4"
/>
</video>- Noise overlay:
.noise-overlaywithopacity-[0.7] mix-blend-overlay pointer-events-none. - Gradient overlay:
bg-gradient-to-b from-black/30 via-transparent to-black/60.
Navbar — absolutely positioned top-center; a black pill hanging from the top edge (bg-black rounded-b-2xl md:rounded-b-3xl px-4 py-2 md:px-8). Five items — “Our story”, “Collective”, “Workshops”, “Programs”, “Inquiries” — at text-[10px] sm:text-xs md:text-sm, gaps gap-3 sm:gap-6 md:gap-12 lg:gap-14, link color rgba(225, 224, 204, 0.8) / hover #E1E0CC (inline styles).
Hero content — absolutely positioned at the bottom (absolute bottom-0 left-0 right-0), a 12-column grid: left 8 columns for the heading, right 4 columns for text + button.
- Giant heading “Prisma” via the
WordsPullUpcomponent:text-[26vw] sm:text-[24vw] md:text-[22vw] lg:text-[20vw] xl:text-[19vw] 2xl:text-[20vw],font-medium leading-[0.85] tracking-[-0.07em], color#E1E0CC. A superscript asterisk sits on the final “a” (absolute top-[0.65em] -right-[0.3em] text-[0.31em]). Each word slides up fromy:20with a0.08sstagger, triggered byuseInView. - Description (right column): “Prisma is a worldwide network of visual artists, filmmakers and storytellers bound not by place, status or labels but by passion and hunger to unlock potential through our unique perspectives.” —
text-primary/70 text-xs sm:text-sm md:text-base, line-height1.2. Framer-motion: fade up fromy:20, delay0.5s, ease[0.16, 1, 0.3, 1]. - CTA “Join the lab”: pill shape
bg-primary rounded-full, black text,font-medium text-sm sm:text-base. Right side has a black circle (bg-black rounded-full w-9 h-9 sm:w-10 sm:h-10) containing a creamArrowRight. Hover:hover:gap-3, circlegroup-hover:scale-110. Framer-motion: fade up fromy:20, delay0.7s, same ease.
Section 2 — About
bg-black, padded, centered content. Inner card bg-[#101010], centered text, max-w-6xl. Top: a small label “Visual arts” in text-primary text-[10px] sm:text-xs.
Main heading via WordsPullUpMultiStyle with three segments:
- “I am Marcus Chen,” —
font-normal(Almarai) - “a self-taught director.” —
italic font-serif(Instrument Serif italic) - “I have skills in color grading, visual effects, and narrative design.” —
font-normal
Container: text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl:text-7xl max-w-3xl mx-auto leading-[0.95] sm:leading-[0.9]. Each word pulls up (y:20 → y:0) staggered at 0.08s.
Body paragraph with a scroll-linked, per-character opacity reveal: “Over the last seven years, I have worked with Parallax, a Berlin-based production house that crafts cinema, series, and Noir Studio in Paris. Together, we have created work that has earned international acclaim at several major festivals.” — text-[#DEDBC8] text-xs sm:text-sm md:text-base.
- Each character is wrapped in an
AnimatedLettercomponent. - Uses
useScrollwith target offset['start 0.8', 'end 0.2']. - Each character’s opacity transitions
0.2 → 1based on scroll position, for a progressive reveal. - Character staggering:
charProgress = index / totalChars, range[charProgress - 0.1, charProgress + 0.05].
Section 3 — Features
min-h-screen bg-black, with a subtle .bg-noise overlay at opacity-[0.15].
Header via WordsPullUpMultiStyle:
- Line 1: “Studio-grade workflows for visionary creators.” in cream
- Line 2: “Built for pure vision. Powered by art.” in
text-gray-500 - Both:
text-xl sm:text-2xl md:text-3xl lg:text-4xl font-normal
4-column card grid (lg:h-[480px], gap-3 sm:gap-2 md:gap-1). Each card animates in with scale 0.95 + fade, via useInView (once, margin "-100px"), staggered 0.15s with ease [0.22, 1, 0.36, 1].
- Card 1 — Video card: full video background,
autoPlay loop muted playsInline object-cover. Bottom text “Your creative canvas.” in#E1E0CC.
<source
src="https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260406_133058_0504132a-0cf3-4450-a370-8ea3b05c95d4.mp4"
type="video/mp4"
/>- Card 2 — “Project Storyboard.” (01):
bg-[#212121], small image icon at top (10x10 sm:12x12 rounded), title with number, 4 checklist items with greenCheckicons, “Learn more” link with a rotated arrow (-45deg). - Card 3 — “Smart Critiques.” (02): same layout as Card 2. 3 checklist items about AI analysis, creative notes, tool integrations.
- Card 4 — “Immersion Capsule.” (03): same layout. 3 checklist items about notification silencing, ambient soundscapes, schedule syncing.
All checklist items use the Check icon in text-primary with text-gray-400 description text. “Learn more” buttons use ArrowRight rotated -45deg.
Card icon image URLs:
Card 2: https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171918_4a5edc79-d78f-4637-ac8b-53c43c220606.png&w=1280&q=85
Card 3: https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171741_ed9845ab-f5b2-4018-8ce7-07cc01823522.png&w=1280&q=85
Card 4: https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171809_f56666dc-c099-4778-ad82-9ad4f209567b.png&w=1280&q=85Shared animation components
WordsPullUp— splits text by spaces; each word is amotion.spanthat slides up (y:20→0) with a staggered delay, usinguseInView(once: true). Supports ashowAsteriskprop that adds a superscript*after the last “a” of the final word.WordsPullUpMultiStyle— takes an array of{ text, className }segments, splits all into individual words preserving per-wordclassName, same pull-up animation. Words wrap ininline-flex flex-wrap justify-center.
Responsive behavior
Fully responsive across mobile, tablet, and desktop. Features cards go 1-col (mobile) → 2-col (md) → 4-col (lg). Hero text scales from 26vw down to 19vw. Navbar items compress with smaller gaps on mobile. All padding, font sizes, and spacing use Tailwind responsive prefixes (sm/md/lg/xl/2xl).