Vista previa en vídeo
Gratis—

Finca costera

El prompt
Prompt: Recreate the "noola" Mindfulness App Landing Page (pixel-exact)
Build a React 19 + Vite + Tailwind CSS v4 single-page landing site for a mindfulness app called noola. Use the motion package (motion/react, i.e. Motion One for React / Framer Motion API) for all animations. Everything below must be reproduced exactly — URLs, colors, easings, delays, sizes.
1. Stack & global setup
React 19, Vite, Tailwind CSS v4 via @tailwindcss/vite (CSS import: @import 'tailwindcss';), motion ^13.
src/App.tsx just renders <LandingPage />.
Components: src/components/LandingPage.tsx, src/components/PhoneUI.tsx, src/components/BlurText.tsx.
src/index.css (exact)
css
@import url('https://db.onlinewebfonts.com/c/69f2576e7ca287875bf8d089130e292c?family=TT+Firs+Neue');
@import url('https://db.onlinewebfonts.com/c/0884d17cb11ba81fc10318f784a5133e?family=TT+Firs+Neue+Trl');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');
@import 'tailwindcss';
@theme {
  --font-display: 'TT Firs Neue', sans-serif;
  --font-body: 'TT Firs Neue Trl', sans-serif;
  --font-inter: 'Inter', sans-serif;
}
* { box-sizing: border-box; }
html, body {
  background-color: #6574A4;
  scroll-behavior: smooth;
}
.clouds-position { bottom: 0; }
@media (min-width: 768px)  { .clouds-position { bottom: -15%; } }
@media (min-width: 1024px) { .clouds-position { bottom: -30%; } }
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(144, 146, 227, 0.4); border-radius: 99px; }
Color palette
Page background: 
#6574a4
Accent purple (buttons, arcs): 
#9092e3
Nav-link / CTA text on white: 
#706a9b
Feature-card background: 
#f0f3ff
Feature-card body text: 
#060cd1
Meditation card title text: 
#6b6893
Mood-dial arc: 
#8173F8
Signature ease everywhere: [0.22, 1, 0.36, 1]
2. Assets (exact URLs)
ts
const heroBgVideo  = "https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260808_022325_dcb1b04a-75f8-429b-a8dd-08272d030e7e.mp4";
const imgClouds    = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/d0a957ce-63f6-4277-9fc1-fcda72008221.png";
const imgPeaceSymbol = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/d0740f2b-f53c-46cb-b15e-47971b073432.jpg"; // also used as avatar in PhoneUI
const imgMedThumb1 = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/41a1f15a-691e-4a3b-886d-ad98cf237024.png";
const imgMedThumb2 = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/0ee8d982-9044-483b-a70c-fcf81fc95bbf.png";
const imgMedThumb3 = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/81640521-c9f7-4701-83c5-98ad55326ef2.png";
const imgBottomNav = "https://api.promptsites.net/s3/promptsites/previews/a9d19850-6b90-4e01-9ca2-97bebc6af924/02038a96-e4e1-4454-ab99-155fdd629c28.png"; // phone UI bottom nav bar
3. BlurText component (word-by-word blur reveal)

A motion component that splits text into words (or chars), observes itself with IntersectionObserver (threshold 0.1), and animates each word with staggered keyframes.
Props & defaults: delay=200 (ms per-word stagger), animateBy="words", direction="top", threshold=0.1, rootMargin="0px", stepDuration=0.35, easing = (t) => 1 - Math.pow(1 - t, 3) (easeOutCubic), as="p".

Default from for direction="bottom": { filter: "blur(10px)", opacity: 0, y: 50 } (for "top": y: -50).
Default to keyframes: [{ filter: "blur(5px)", opacity: 0.5, y: -5 }, { filter: "blur(0px)", opacity: 1, y: 0 }] (y: 5 mid-step for "top").
Build combined keyframe arrays [from, ...steps] per property; times evenly spaced; total duration = stepDuration * steps; per-word delay = index * delay / 1000.
Container: display: flex; flex-wrap: wrap; each word an inline-block motion.span with will-change-[transform,filter,opacity], joined by spaces.
4. PhoneUI component (iPhone mockup, prop width default 260)
Height = width * (19.5/9); borderRadius = width * 0.13; boxShadow: "0 0 0 4px white" (white bezel); overflow: hidden; column flex.
Background gradient: linear-gradient(170deg, #b8b4e0 0%, #cac7f0 25%, #dcd9f8 55%, #eceaff 100%).
Status bar: time "9:41" (font-body, 12px, 600, white, letterSpacing -0.3); centered black Dynamic Island pill (absolute, 80×24, top 10, borderRadius 999); right icons drawn as inline SVGs — 5-bar signal (bars at increasing heights, opacities 0.4/0.6/0.8/1/1), wifi arcs, battery (21×11 outline at 35% opacity, filled 17×8 inner rect, nub at 40%).
Greeting row (px-5, mt-3): 32px round avatar (imgPeaceSymbol, bg 
#d0cce8), text "Hello, Kristina!" (font-body 13px; "Hello," at white/50, name at white/90 weight 500). Right: 28px circle (bg white/10, border white/15) with an 11×11 white bell SVG, path:
M9.55718 5.60049L8.81469 2.93313C8.57518 2.07365 8.05532 1.31887 7.33771 0.788685C6.62009 0.258505 5.74588 -0.0166579 4.85397 0.00691348C3.96206 0.0304848 3.1036 0.351439 2.41499 0.918782C1.72638 1.48613 1.24711 2.26732 1.05333 3.13824L0.479518 5.71872C0.403817 6.05941 0.405587 6.41275 0.484697 6.75267C0.563807 7.09258 0.718239 7.41039 0.936593 7.68264C1.15495 7.95489 1.43165 8.17464 1.74628 8.32565C2.06092 8.47667 2.40544 8.55511 2.75444 8.55518H2.92396C3.05882 9.02157 3.34158 9.43151 3.72964 9.72326C4.11771 10.015 4.59006 10.1728 5.07556 10.1728C5.56106 10.1728 6.03341 10.015 6.42148 9.72326C6.80954 9.43151 7.0923 9.02157 7.22716 8.55518H7.30895C7.6683 8.55522 8.02279 8.47217 8.34473 8.31253C8.66667 8.15289 8.94734 7.92097 9.16481 7.63489C9.38228 7.34882 9.53066 7.01634 9.59835 6.66342C9.66605 6.31051 9.65123 5.94672 9.55506 5.60049H9.55718ZM8.15485 6.86509C8.05647 6.99571 7.92897 7.10157 7.78249 7.17426C7.63601 7.24695 7.47459 7.28445 7.31107 7.28379H2.75444C2.59582 7.28376 2.43923 7.24811 2.29622 7.17947C2.15322 7.11083 2.02745 7.01096 1.9282 6.88722C1.82895 6.76349 1.75875 6.61904 1.72278 6.46455C1.68682 6.31006 1.686 6.14946 1.72039 5.99461L2.2942 3.40947C2.42597 2.8145 2.75298 2.2807 3.22318 1.89305C3.69338 1.5054 4.27974 1.28618 4.88893 1.2703C5.49811 1.25441 6.0951 1.44276 6.58487 1.80538C7.07464 2.16799 7.42902 2.68402 7.59162 3.27132L8.33242 5.93867C8.37711 6.09624 8.38433 6.26208 8.3535 6.42294C8.32267 6.5838 8.25464 6.73521 8.15485 6.86509Z (viewBox 0 0 10.171 10.171).
Heading (px-5, mt-3): "How do you\nfeel today?" — font-display, fontSize width * 0.135, weight 500, white, lineHeight 1.05, letterSpacing -1.
Mood dial (centered SVG 200×200, marginTop 12): outer circle r=80 white stroke 1.5 @ 0.9 opacity; inner circle r=58 white stroke 1 @ 0.3; three white dots r=4 @ 0.7 opacity at 270°, 0°, 180° on the outer ring; purple 
#8173F8 arc stroke 2.5 round-cap from 220° to 90° clockwise (large-arc), with a filled 
#8173F8 dot r=7 at the 90° end; labels "12 AM" above (y = cy−R−8) and "12 PM" below (y = cy+R+16), 9px font-body white @ 0.7; "Neutral" centered (y = cy−10, 11px, weight 500); center button: white circle r=12 @ 0.14 opacity at (cx, cy+10) with an upward white triangle @ 0.8 opacity.
Flex spacer, then imgBottomNav image full-width at the bottom.
5. Page layout (LandingPage)

<main class="min-h-screen">, bg 
#6574a4, font-display, relative. Sections in order: Hero → FeaturesIntro → MoodTrackingCard → GuidedMeditationsCard.

5a. Nav (inside hero, z-50, px-5/sm:8/md:10, pt-5/md:6, inner max-w-7xl)
Left: noola logo — white SVG, viewBox="0 0 99 32", h-6 sm:h-7, 7 white paths (see §7).
Desktop (md+): links Features / Therapy / Meditations / About as white pill buttons (px-5 py-3 bg-white rounded-xl, text 
#706a9b, text-xs uppercase tracking-widest, hover bg-white/90); right CTA "Get the app" (px-5 py-2.5 rounded-xl, bg 
#9092e3, white, text-sm uppercase, hover opacity-90).
Mobile: 3-line hamburger (24×2px white bars, gap 1.5) morphing to an X — top bar translateY(8px) rotate(45deg), middle fades/scaleX(0), bottom translateY(-8px) rotate(-45deg), transition 0.35s cubic-bezier(0.4,0,0.2,1). Dropdown absolutely positioned below nav (left-5 right-5): bg-white/10 backdrop-blur-md rounded-2xl, maxHeight 0→400 + opacity, 0.45s cubic-bezier(0.4,0,0.2,1); each link staggers in at i * 40ms with translateY(-8px)→0; ends with a full-width purple "Get the app" button.
5b. Hero
<section> relative flex-col, bg 
#6574a4, overflow: visible, minHeight: 100svh.
Background video: absolute inset-0, full-bleed <video> of heroBgVideo, autoPlay muted loop playsInline, objectFit: cover; objectPosition: center top, pointer-events-none.
Body (z-10, centered column, pt-16 sm:pt-20 md:pt-24, pb-64 sm:pb-72 md:pb-80):
Eyebrow "Find your balance" — white/70, text-sm/sm:base, weight 500; motion fade-up {opacity:0,y:20}→{1,0}, duration 1.0, delay 0.25, ease [0.22,1,0.36,1].
<h1> "Your daily mindfulness companion" — centered white, leading-[0.88] tracking-tighter, fontSize: clamp(2.8rem, 9vw, 7rem), maxWidth: 9ch, mb-20 sm:mb-24; rendered with BlurText delay={190} direction="bottom" stepDuration={0.6}.
Phone mockup — motion {opacity:0, y:40, scale:0.92}→{1,0,1}, duration 1.4, delay 0.6, same ease. Responsive: width 200 (mobile), 240 (sm), 268 (md+).
Sub-block (z-40, pt-16 sm:pt-20 pb-44 sm:pb-52): paragraph "A beautifully designed space to track your emotions, discover guided meditations, and connect with yourself." (white/85, weight 500, clamp(0.875rem, 2vw, 1.125rem), max-w-sm/md) then white button "DOWNLOAD FOR IOS" (rounded-xl bg-white, text 
#706a9b, uppercase). Both whileInView fade-up (y:24→0), duration 1.1, delays 0.4 / 0.6, viewport={{once:true, margin:"-40px"}}.
Clouds: absolute full-width <img> of imgClouds (class clouds-position, z-30, pointer-events-none) — bottom 0 mobile / −15% md / −30% lg — with scroll parallax: useScroll({ target: section, offset: ["start start","end start"] }) → y: useTransform(progress, [0,1], ["0%","-25%"]). Overlay a bottom fade div (height 40%, linear-gradient(to bottom, transparent, #6574a4)).
5c. FeaturesIntro (py-20 sm:py-28 md:py-36, centered, max-w-5xl)
<h2> white, tracking-tighter leading-[1.05], fontSize: clamp(2.5rem, 8vw, 6.5rem), three BlurText lines (delay={160} direction="bottom" stepDuration={0.58}):
Line 1: "Designed"
Line 2 (inline-flex baseline wrap, gap-x-3): "for your" + inline peace-symbol image (imgPeaceSymbol, rounded 8px, clamp(50px,6vw,88px) square, top: 0.05em) + "peace". The "for your" BlurText uses explicit animationFrom={{filter:"blur(10px)",opacity:0,y:50}} and animationTo=[{filter:"blur(5px)",opacity:0.5,y:-5},{filter:"blur(0px)",opacity:1,y:0}].
Line 3: "of mindfull" (sic — intentional spelling).
Below: "Tune into your feelings:" — white/80, weight 500, mt-10 sm:mt-14, max-w-md; whileInView fade-up duration 1.1 delay 0.4.
5d. MoodTrackingCard (px-4 sm:px-6 md:px-10 pb-6)
Card: max-w-5xl, rounded-[24px] sm:rounded-[28px], bg 
#f0f3ff, overflow-hidden; useInView(ref, {once:true, margin:"-80px"}) triggers card fade-up (y:40→0, 1.1s).
Two columns (min-h-[400px] sm:min-h-[420px]; text is order-2 on mobile / order-1 on md):
Left (md:w-[45%], justify-end, p-6→10): label "MOOD TRACKING" (text-xs uppercase tracking-widest, color 
#9092e3) and body "Log your daily emotions with an intuitive, interactive dial. Understand your emotional patterns and reflect on what truly matters to you." (weight 500, clamp(1rem,2.5vw,1.35rem), color 
#060cd1, max 36ch). Both use a blurIn helper: {opacity:0, filter:"blur(10px)", y:20} → {1, blur(0), 0}, duration 1.05, delays 0.3 / 0.55.
Right (overflow-hidden, minHeight 260): PhoneUI cropped from the bottom edge — absolutely positioned at left: 50%, translateX(-50%) with bottom: -88% @ width 220 (mobile), bottom: -165% @ 300 (sm), bottom: -68% @ 300 (md+); enters with {opacity:0,y:40,scale:0.92}, duration 1.4, delay 0.55.
5e. GuidedMeditationsCard (px-4 sm:px-6 md:px-10 pb-16 sm:pb-24)
Same card shell/animations as 5d. Left column: label "GUIDED MEDITATIONS" + body "Recharge your mind with bite-sized meditation plans. Paired with surreal, calming visuals, it's the perfect way to wake up, breathe, or reflect."
Right column: vertical stack (gap-3, maxWidth 320) of three MeditationItem cards, each dropping in from above ({opacity:0, y:-24}→{1,0}, duration 0.85, delay 0.4 + i*0.22):
"We wake up meditation" — 7 min — imgMedThumb2
"Breathe with the clouds" — 7 min — imgMedThumb1
"Monthly stress reflection" — 7 min — imgMedThumb3
MeditationItem: white rounded-2xl horizontal flex. Left (p-3, flex-col justify-between): title in Inter (clamp(1.05rem,3.5vw,1.2rem), color 
#6b6893, medium) and a 32px purple 
#9092e3 circle with a white play triangle (M1 1.5l8 4.5-8 4.5V1.5z). Right: 110px-wide thumbnail, absolute inset-0 object-cover, own rounded-2xl, with the duration badge ("7 min", Inter 11px white, pill padding 2px 8px) at top-right.
6. Animation summary
Signature ease [0.22, 1, 0.36, 1] on every motion transition.
Headlines: BlurText word-stagger blur reveals (blur 10→5→0, y 50→−5→0, opacity 0→0.5→1).
Hero: sequential eyebrow (0.25s) → headline words → phone (0.6s); clouds parallax on scroll.
Cards: whileInView/once — card fade-up, text blur-in staggered, phone rise, list items drop-in staggered 0.22s.
Hamburger ↔ X morph and staggered mobile-menu links, cubic-bezier(0.4,0,0.2,1).
7. noola logo (Just test Noola) (white)

залий медіа на a0271d27-232b-4e08-a143-0471ed6f879f

Ran 3 commands

All 3 unique. Uploading to the new item.

Ran a command

Залито 3 файли:

https://api.promptsites.net/s3/promptsites/previews/a0271d27-232b-4e08-a143-0471ed6f879f/28907f4e-8458-422d-9fdb-c4d242354fe4.webp
https://api.promptsites.net/s3/promptsites/previews/a0271d27-232b-4e08-a143-0471ed6f879f/0e3924c8-b825-4378-91c3-a8d5fef774d4.webp
https://api.promptsites.net/s3/promptsites/previews/a0271d27-232b-4e08-a143-0471ed6f879f/7dfbc03a-66dc-4d53-8013-3da8bf1a20b3.webp

Recreate "SCULPTED BY TIME" Luxury Jewelry Scroll Experience
Build a single-page React + TypeScript + Vite landing page for a luxury jewelry brand. It is a **scroll-driven cinematic experience**: the page is very tall, and scrolling scrubs through two background videos while editorial text fades/blurs away and product panels slide in. Use **Tailwind CSS v4** (via @tailwindcss/vite) and lucide-react for icons. Everything lives in a single src/App.tsx component. No backend / no data persistence is needed.
## Stack & setup
- Dependencies: react@19, react-dom@19, vite@6, @vitejs/plugin-react, @tailwindcss/vite, tailwindcss@4, lucide-react, motion.
- src/main.tsx renders <App /> into #root.
- index.html has <div id="root"></div> and loads /src/main.tsx.
## Fonts (src/index.css)
css
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital,wght@0,400;1,400&family=Manrope:wght@200;300;400;500;600;700;800&display=swap');
@import "tailwindcss";
@theme {
  --font-serif: "Instrument Serif", serif;
  --font-sans: "Manrope", sans-serif;
}

- Serif display font: **Instrument Serif** (font-serif).
- Sans UI font: **Manrope** (font-sans).
## Asset URLs (use exactly)
- Background video 1 (plays during first 40% of scroll):
  https://res.cloudinary.com/dbfd996z4/video/upload/q_auto/f_auto/v1781009724/11111111_gvewuj.mp4
- Background video 2 (plays during second half):
  https://res.cloudinary.com/dbfd996z4/video/upload/q_auto/f_auto/v1781009724/2222222_x4qpet.mp4
- Hero product PNG (ring): https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781009782/rng_awymkj.png
- Panel product 1 (earrings): https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781017114/202606091756_msbh8b.jpg
- Panel product 2 (ring): https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781019866/2606091843_kfonxp.jpg
(Note: there is no CloudFront URL in this project — all media is served from Cloudinary at the dbfd996z4 account. The /public/main and /public/second JPG frame sequences exist as fallbacks but the live page scrubs the two Cloudinary MP4s, not the JPGs.)
## Color & theme
- Page background: #020202 (near-black), text white.
- Signature accent (titles, progress bar, hover states, cart dot): #FBFF8D (luminous pale chartreuse-yellow).
- Slide-in product panel background: #FAF9F5 (warm off-white), text #121212; muted greys #8E8B84, #73716C, #E5E5E2.
- NO purple/violet anywhere.
## Layout structure (single root div, h-[650vh], bg-[#020202], overflow-x-hidden, antialiased, font-sans)
### 1. Fixed background video stage (fixed inset-0 z-0, pointer-events-none)
- Two <video> elements stacked absolutely, object-cover, muted playsInline preload="auto".
- Video 1 opacity 0.85 when progress < 0.48, else 0; Video 2 opacity 0.85 when progress >= 0.48, else 0. Cross-fade with transition-opacity duration-700 ease-in-out.
- A hidden <canvas> (kept in DOM, display:none).
- Three gradient overlays for typography contrast: top (h-44, black 85%→transparent), bottom (h-56, black 90%→transparent), left (w-1/2, black 40%→transparent, only lg:block).
### 2. Top progress bar (fixed top-0 left-0 h-[2.5px] bg-[#FBFF8D] z-50)
- Width = ${progress * 100}%, transition-all duration-75, pointer-events-none.
### 3. Editorial overlay (fixed inset-0 z-10, flex column space-between, padding p-6 md:p-10 lg:p-12)
- pointerEvents: 'none' when progress > 0.45; visibility: hidden when progress >= 0.45.
- **Header** (flex justify-between items-start):
  - Left column (flex flex-col gap-10): a 48×48 white brand crest **SVG** (5-petal abstract floral logo — provide the multi-path SVG), and 40px below it a sub-header: <h3> "Contemporary Luxury For The / Discerning Minimalist" (semibold, 12-13px, tracking -0.03em) + a <p> (11px, white/50, max-width 260px): "Exclusive creations tailored for true aesthetes. We forge more than simple ornaments; we build tactile artifacts of your personal legacy."
  - Right nav (flex items-center gap-5..8, 13px white/70): links **Collections, Atelier, Our story, Contact**, each with animated underline-on-hover (after: pseudo growing from w-0 to w-full) and hover:scale-105. Then a vertical separator, a **User** icon link, and a **ShoppingBag** button (with a pulsing #FBFF8D 6.5px dot badge). The bag button smooth-scrolls to the very bottom of the page.
- **Hero main** (grid grid-cols-1 lg:grid-cols-12, items-end):
  - Left (cols 1-7): giant serif headline #FBFF8D, uppercase, leading-[0.88], fluid fontSize: clamp(2.5rem, 5.6vw, 7.5rem), three lines each as own div: "&nbsp;&nbsp;&nbsp;&nbsp;*SCULPTED*" (italic), "BY TIME. WORN", "BY *YOU*" (italic). Below it two manifesto <p> blocks (11px white/50, width 260px) — text: "We craft modern jewelry that speaks volumes through silence..." and "Every piece acts as a personal manifesto...".
  - Right (cols 8-12, max-w-240px): product caption block — small label "Abyssal Silver Ring", <h2> "18K White Gold & Rough Onyx", a 10.5px description; then a transparent product card (aspect-[4/5], hover:scale-[1.04]) holding the ring PNG (object-contain, group-hover:scale-105); then a centered serif price "$1,850" that turns #FBFF8D on group hover.
### 4. Slide-in product sheet (fixed top-0 left-0 h-full w-full sm:w-[600px] lg:w-[648px] bg-[#FAF9F5] text-[#121212] z-30)
- Transform: translate-x-0 when open else -translate-x-full, transition-transform duration-[1100ms] ease-[cubic-bezier(0.16,1,0.3,1)], shadow 12px 0 45px rgba(0,0,0,0.22), overflow-y-auto.
- Open when progress >= 0.40 && progress < 0.50 (first card) OR progress >= 0.90 (second card).
- Top-left **BACK TO SERIES** button (ArrowLeft icon, uppercase, tracking 0.16em) that smooth-scrolls back: to 82% if progress >= 0.90, else to 35%.
- Centered product header: category label (uppercase, tracking 0.15em, #8E8B84), serif <h2> title, 12px description #73716C; then a centered product image (max-w-[460px]).
- Footer transaction row (border-top, full-bleed via negative margins): a black **ADD TO ATELIER BAG** button (h-[50px], uppercase tracking 0.15em), a #E5E5E2 quantity stepper (− value +), and a large serif dynamic price ${price * quantity}.
- **Dynamic product data** driven by isSecondCard (progress >= 0.90):
  - Second card: category "Atelier Core Edition", title "Sterling Silver Sculpture Ring", price 1350, image = ring JPG, with the sculpture description.
  - Otherwise: category "Aura Fine Earrings", title "18K White Gold & Pink Sapphire", price 1850, image = earrings JPG, with the drop-stud description.
  - Reset quantity to 1 whenever the active product title changes.
## Scroll & animation engine (the core)
Use refs (not state) for animation values to avoid re-renders; only progress and quantity are React state.
- **State refs:** targetScrollFractionRef, currentScrollFractionRef, targetVideoRatioRef, currentVideoTimeRef, targetVideoSecondRatioRef, currentVideoSecondTimeRef, targetFrameRef, currentFrameRef. totalFrames = 480.
- **Scroll listener:** compute scrollTop / (scrollHeight - clientHeight), clamp 0–1, store in targetScrollFractionRef. Passive listener; also run once on mount and once after a 500ms timeout.
- **requestAnimationFrame loop** (smoothUpdate):
  1. Lerp currentScrollFraction toward target by factor **0.05** (snap when very close) — gives a weighted, cinematic, "catch-up" feel. setProgress(currentScrollFraction).
  2. Map activeProgress to phases:
     - <= 0.40: ratio = p/0.40 → video1 ratio = ratio, video2 = 0, frame = 1 + ratio*239.
     - 0.40–0.50: video1 = 1.0, frame = 240 (hold — first panel open).
     - 0.50–0.90: video1 = 1.0, video2 ratio = (p-0.50)/0.40, frame = 241 + ratio*239.
     - > 0.90: both = 1.0, frame = 480 (second panel open).
  3. Scrub each video by lerping currentVideoTime toward targetRatio * video.duration by factor **0.08**, and set video.currentTime — **but only when !video.seeking** (skip issuing a new seek while the browser is still painting the previous frame, to prevent stutter). Same guard for the second video.
  4. Lerp currentFrameRef toward targetFrameRef by 0.08, clamped to [1, 480].
  5. Re-request the frame; cancel on cleanup.
## Stagger helper (getStaggerStyle(start, end))
Maps progress within a [start,end] window to a fade-out: opacity = 1 - ratio, translateY = -75 * ratio, filter: blur(${ratio*16}px), willChange, and a cubic-bezier(0.16,1,0.3,1) 0.35s transition; pointerEvents: 'none' once opacity < 0.15. Apply staggered windows to each editorial element so they melt upward and blur away as you scroll (logo 0.00–0.12, subheader 0.06–0.18, nav 0.03–0.15, title lines 0.09/0.12/0.15 → +0.11, manifesto 0.18/0.21, right caption 0.14–0.25, card 0.18–0.29, price 0.20–0.31).
## Embedded <style> extras
- @keyframes scrollLine.
- Custom dark webkit scrollbar (6px, track #020202, thumb white/15, hover #FBFF8D/40).
- Media query (max-height:780px) and (min-width:1024px): tighten #sculpted-title margin and #product-image-card padding.
## Behavior summary
Scrolling 0→100% of the 650vh page: hero text melts away → video 1 scrubs forward → first earrings panel slides in (~40-50%) → video 2 scrubs → second ring panel slides in (~90%+). The ShoppingBag button jumps to the final panel; the panel BACK button scrolls back into the video sequence. All motion is buttery via double-lerp (scroll smoothing 0.05 + media smoothing 0.08) and the !seeking seek guard. зміни в промті лінки

Ran 2 commands

Всі 3 унікальні. Заливаю.

Ran a command

Залито 3 файли:

https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/080a058c-3903-4827-9398-be6b64d02fd9.png
https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/8595c624-f3f0-4004-8ac8-772f1763dbbf.png
https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/2822a2bb-6318-47ee-be3d-369cd870711b.png

виправи в промті лінки Recreate this **exact** static marketing page pixel-for-pixel. Stack: **Vite 5** (vite-starter), plain HTML + CSS + vanilla JS. No React, no Tailwind, no UI libraries. Files: index.html, style.css, main.js, package.json.
## Brand / page meta
- Title: MAREA — Coast Homes
- theme-color: #29bee4
- Viewport: width=device-width, initial-scale=1.0, viewport-fit=cover
- Language: en
- Body background: #fff
- Ink/text color: #0d2b3a
- Horizontal overflow clipped on html/body
## Design tokens (CSS variables)
css
--sky: #29bee4;
--sky-deep: #1496be;
--ink: #0d2b3a;
--terracotta: #c9705f;
--nav-glass: rgba(255, 255, 255, 0.22);
--nav-glass-border: rgba(255, 255, 255, 0.45);
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in: cubic-bezier(0.7, 0, 0.84, 0);
--dur-open: 0.55s;
--dur-close: 0.35s;
--leaf: clamp(230px, 30vw, 470px);

## Fonts (exact)
Load Google Fonts exactly as:

https://fonts.googleapis.com/css2?family=Iosevka+Charon:wght@400;700&family=Inter:wght@300;400;500;600;700&display=swap

With preconnect to fonts.googleapis.com and fonts.gstatic.com.
Usage:
| Element | Font stack | Weight / size |
|---|---|---|
| Body | "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif | default |
| Hero SVG wordmark MAREA | "Iosevka Charon", "Archivo Black", "Arial Black", sans-serif | 700, SVG font-size: 280px, letter-spacing: -0.01em, fill #fff |
| Nav logo MAREA | same as wordmark | 700, 28px (18px ≤420px), letter-spacing: -0.02em, color #fff |
| Intro title | Inter light | clamp(32px, 5.6vw, 68px), weight 300, line-height 1.12, tracking -0.03em |
| Intro title <strong>calm</strong> | "Archivo Black", "Arial Black", sans-serif | weight 400, tracking -0.02em (Archivo Black is **fallback only** — not loaded from Google Fonts in this build) |
| Intro eyebrow | Inter | 12px, weight 600, uppercase, tracking 0.22em, color terracotta |
| Nav pills | Inter | 14px / 13px / 12px by breakpoint, weight 500 (active/CTA 600) |
| Mobile menu links | Inter | clamp(26px, 7.5vw, 34px), weight 600 |
## Exact asset URLs (do not substitute)
### 1. Hero sky (full-bleed background)

https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260806_125611_c5cd23eb-9a89-49c9-a868-ddf2300ccf10.png

- Class: hero__sky
- object-fit: cover, object-position: center top, inset: 0, z-index: 0
- Decorative: alt="", aria-hidden="true"
### 2. Hero building (foreground PNG over sky)

https://soft-zoom-63098134.figma.site/_assets/v11/35b65ca383f61b2c2f6851c3b6716839291c5904.png

- Class: hero__building
- Alt: MAREA luxury Mediterranean resort residence
- Position: absolute, left: 50%, transform: translateX(-50%), bottom: -7vw, width: 100%, z-index: 2
- Responsive overrides:
  - min-aspect-ratio: 2/1: width: auto; height: 98svh; bottom: -6svh
  - ≤780px: width: auto; height: 68svh; bottom: -3svh
  - ≤420px: height: 62svh
  - landscape short (max-height: 500px + landscape): width: auto; height: 86svh; bottom: -4svh
### 3. Leaves (same image left + right)
Higgs CDN wrapper (use exactly):

https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260806_164633_54c52399-9567-4a5a-b40a-a2f620ddda0b.png&w=1280&q=85

Underlying CloudFront source (encoded in that URL):

https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260806_164633_54c52399-9567-4a5a-b40a-a2f620ddda0b.png

- Both: alt="", aria-hidden="true", pointer-events: none, z-index: 5
- Anchored at seam between hero and intro: position: absolute; top: 100svh; width: var(--leaf)
- Left (.leaf--left): left: -2%
- Right (.leaf--right): right: -2%, also rotate(180deg) so it mirrors
- Size: --leaf: clamp(230px, 30vw, 470px); ≤780px → clamp(150px, 42vw, 260px); ≤420px → 40vw; short landscape → 26vw
## Page structure (exact DOM order)

.page
  section.hero
    img.hero__sky
    svg.hero__wordmark  → text "MAREA"
    img.hero__building
    div.hero__fade
    nav.nav
      a.nav__logo "MAREA"
      ul.nav__links → Stay (active), Broker, Own/Rent, List, Ask Broker
      a.nav__cta "Reserve Now"
      button.burger (3 bars)
    div#mobile-menu.menu
      div.menu__bg
      div.menu__inner
        ul.menu__list (items --i:0..4 same labels)
        a.menu__cta "Reserve Now"
  img.leaf.leaf--left
  img.leaf.leaf--right
  section.intro
    p.intro__eyebrow "Riviera Living Style"
    h2.intro__title "Where the shoreline<br>becomes <strong>calm</strong>"

All nav/menu links are href="#".
## Hero composition (first viewport)
- Full viewport: height: 100vh + 100svh, overflow: hidden, background --sky, isolation: isolate
- **One composition**: sky photo → giant white centered wordmark behind building → building PNG → white bottom fade → glass nav on top
- No cards, no stats, no hero overlays/badges
### Wordmark (SVG)
html
<svg class="hero__wordmark" viewBox="0 0 1000 300" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
  <text x="500" y="260" text-anchor="middle">MAREA</text>
</svg>

- CSS: top: 13%; left: 50%; transform: translateX(-50%); width: 88%; z-index: 1
- Mobile: ≤780px → top: 34%; width: 74%; ≤420px → top: 36%; width: 82%; short landscape → top: 18%; width: 70%
### Bottom fade (.hero__fade)
- height: 34% (30% on mobile), z-index: 3
- Gradient:

to bottom:
  rgba(255,255,255,0) 0%,
  rgba(255,255,255,0.35) 32%,
  rgba(255,255,255,0.78) 58%,
  rgba(255,255,255,0.96) 80%,
  #fff 100%

## Navbar (desktop)
- Absolute over hero, z-index: 60, flex row, gap 24px, padding 26px 40px (safe-area top)
- Parent pointer-events: none; children pointer-events: auto
- Logo left; pill links centered (margin: 0 auto); CTA right
- Pills: glass rgba(255,255,255,0.22), border rgba(255,255,255,0.45), backdrop-filter: blur(6px), border-radius: 999px, padding 11px 26px
- Active (“Stay”) and CTA: solid white bg, ink text
- Hover: glass → rgba(255,255,255,0.4); active/CTA → rgba(255,255,255,0.88)
- Breakpoints: shrink padding/font at 1100px and 900px
- At ≤780px: hide .nav__links and .nav__cta; show burger
## Mobile menu + animations
Show .menu as flex only ≤780px. Open state = body.is-open (also locks overflow: hidden).
### Open / close timings
- Open duration: 0.55s with --ease-out
- Close duration: 0.35s with --ease-in
### Burger → X
- Circular glass button 46px, 3 white bars 20×2 stacked at 0 / 6 / 12px
- Open:
  - bar1: translate: 0 6px; rotate: 45deg
  - bar2: opacity: 0; scale: 0.2 1
  - bar3: translate: 0 -6px; rotate: -45deg
- Transition stagger: translate first, then rotate delayed 0.14s on open (reverse on close)
### Overlay
- Fixed fullscreen, z-index: 50, starts opacity: 0; visibility: hidden
- .menu__bg: diagonal gradient 158deg from sky #29bee4 → #1496be → ink #0d2b3a at ~94–95% alpha; blur(26px) saturate(150%)
- Closed: transform: scale(1.12); open: scale to none over 0.7s --ease-out
- Menu items: start opacity: 0; translateY(18px); open stagger calc(var(--i) * 55ms + 140ms), opacity 0.5s, transform 0.65s --ease-out
- CTA pill: same enter, delay 420ms
- Link active press: translateX(6px)
- Click link or outside .menu__inner closes; Escape closes and refocuses burger; desktop ≥781px forces close
## Intro section
- White, centered grid, min-height: 68svh
- Padding: clamp(96px, 17vh, 190px) 24px clamp(80px, 12vh, 150px)
- Eyebrow: Riviera Living Style
- Title (with line break after “shoreline”): Where the shoreline becomes calm — only **calm** is bold/black display face
- Title max-width: 16ch (13ch on mobile)
## Leaf scroll parallax (JS — exact)
On scroll (rAF-throttled, passive listener), set CSS vars on each leaf:
| Leaf | --parallax-y | --parallax-x |
|---|---|---|
| Left | scrollY * -0.28 | scrollY * -0.06 |
| Right | scrollY * -0.48 | scrollY * 0.08 |
Transforms:
- Left: translate3d(var(--parallax-x), calc(-50% + var(--parallax-y)), 0)
- Right: same + rotate(180deg)
Skip updates when prefers-reduced-motion: reduce. Also respect global reduce-motion: force transition/animation durations near 0.
## Accessibility / behavior details
- Burger: aria-label toggles “Open menu” / “Close menu”, aria-expanded, aria-controls="mobile-menu"
- Wordmark SVG and decorative images: aria-hidden="true"
- Images: user-select: none, -webkit-user-drag: none
- Leaves: will-change: transform
## Tech constraints
- Vite only ("vite": "^5.4.2"), scripts: dev / build / preview
- No framework components; keep BEM-like class names listed above
- Do not invent extra sections, cards, stats, or different imagery
- Match layering z-index exactly: sky 0 → wordmark 1 → building 2 → fade 3 → leaves 5 → menu 50 → nav 60
Build this so the first viewport reads as one branded Mediterranean resort hero (sky + centered white MAREA + building + glass nav), then white intro copy under mirrored leaf decorations that parallax apart while scrolling.
---

Ось промт з підставленими лінками:

Recreate this exact static marketing page pixel-for-pixel. Stack: Vite 5 (vite-starter), plain HTML + CSS + vanilla JS. No React, no Tailwind, no UI libraries. Files: index.html, style.css, main.js, package.json.

Brand / page meta
Title: MAREA — Coast Homes
theme-color: 
#29bee4
Viewport: width=device-width, initial-scale=1.0, viewport-fit=cover
Language: en
Body background: #fff
Ink/text color: 
#0d2b3a
Horizontal overflow clipped on html/body
Design tokens (CSS variables)
css
--sky: #29bee4;
--sky-deep: #1496be;
--ink: #0d2b3a;
--terracotta: #c9705f;
--nav-glass: rgba(255, 255, 255, 0.22);
--nav-glass-border: rgba(255, 255, 255, 0.45);
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in: cubic-bezier(0.7, 0, 0.84, 0);
--dur-open: 0.55s;
--dur-close: 0.35s;
--leaf: clamp(230px, 30vw, 470px);
Fonts (exact)

Load Google Fonts exactly as:

https://fonts.googleapis.com/css2?family=Iosevka+Charon:wght@400;700&family=Inter:wght@300;400;500;600;700&display=swap

With preconnect to fonts.googleapis.com and fonts.gstatic.com.
Usage:

Element	Font stack	Weight / size
Body	"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif	default
Hero SVG wordmark MAREA	"Iosevka Charon", "Archivo Black", "Arial Black", sans-serif	700, SVG font-size: 280px, letter-spacing: -0.01em, fill #fff
Nav logo MAREA	same as wordmark	700, 28px (18px ≤420px), letter-spacing: -0.02em, color #fff
Intro title	Inter light	clamp(32px, 5.6vw, 68px), weight 300, line-height 1.12, tracking -0.03em
Intro title <strong>calm</strong>	"Archivo Black", "Arial Black", sans-serif	weight 400, tracking -0.02em (Archivo Black is fallback only — not loaded from Google Fonts in this build)
Intro eyebrow	Inter	12px, weight 600, uppercase, tracking 0.22em, color terracotta
Nav pills	Inter	14px / 13px / 12px by breakpoint, weight 500 (active/CTA 600)
Mobile menu links	Inter	clamp(26px, 7.5vw, 34px), weight 600
Exact asset URLs (do not substitute)
1. Hero sky (full-bleed background)
https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/8595c624-f3f0-4004-8ac8-772f1763dbbf.png
Class: hero__sky
object-fit: cover, object-position: center top, inset: 0, z-index: 0
Decorative: alt="", aria-hidden="true"
2. Hero building (foreground PNG over sky)
https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/2822a2bb-6318-47ee-be3d-369cd870711b.png
Class: hero__building
Alt: MAREA luxury Mediterranean resort residence
Position: absolute, left: 50%, transform: translateX(-50%), bottom: -7vw, width: 100%, z-index: 2
Responsive overrides:
min-aspect-ratio: 2/1: width: auto; height: 98svh; bottom: -6svh
≤780px: width: auto; height: 68svh; bottom: -3svh
≤420px: height: 62svh
landscape short (max-height: 500px + landscape): width: auto; height: 86svh; bottom: -4svh
3. Leaves (same image left + right)
https://api.promptsites.net/s3/promptsites/previews/940c5d0b-1d78-4d2c-a4be-a17436dc98c6/080a058c-3903-4827-9398-be6b64d02fd9.png
Both: alt="", aria-hidden="true", pointer-events: none, z-index: 5
Anchored at seam between hero and intro: position: absolute; top: 100svh; width: var(--leaf)
Left (.leaf--left): left: -2%
Right (.leaf--right): right: -2%, also rotate(180deg) so it mirrors
Size: --leaf: clamp(230px, 30vw, 470px); ≤780px → clamp(150px, 42vw, 260px); ≤420px → 40vw; short landscape → 26vw
Page structure (exact DOM order)
.page
  section.hero
    img.hero__sky
    svg.hero__wordmark  → text "MAREA"
    img.hero__building
    div.hero__fade
    nav.nav
      a.nav__logo "MAREA"
      ul.nav__links → Stay (active), Broker, Own/Rent, List, Ask Broker
      a.nav__cta "Reserve Now"
      button.burger (3 bars)
    div#mobile-menu.menu
      div.menu__bg
      div.menu__inner
        ul.menu__list (items --i:0..4 same labels)
        a.menu__cta "Reserve Now"
  img.leaf.leaf--left
  img.leaf.leaf--right
  section.intro
    p.intro__eyebrow "Riviera Living Style"
    h2.intro__title "Where the shoreline<br>becomes <strong>calm</strong>"

All nav/menu links are href="#".

Hero composition (first viewport)
Full viewport: height: 100vh + 100svh, overflow: hidden, background --sky, isolation: isolate
One composition: sky photo → giant white centered wordmark behind building → building PNG → white bottom fade → glass nav on top
No cards, no stats, no hero overlays/badges
Wordmark (SVG)
html
<svg class="hero__wordmark" viewBox="0 0 1000 300" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
  <text x="500" y="260" text-anchor="middle">MAREA</text>
</svg>
CSS: top: 13%; left: 50%; transform: translateX(-50%); width: 88%; z-index: 1
Mobile: ≤780px → top: 34%; width: 74%; ≤420px → top: 36%; width: 82%; short landscape → top: 18%; width: 70%
Bottom fade (.hero__fade)
height: 34% (30% on mobile), z-index: 3
Gradient:
to bottom:
  rgba(255,255,255,0) 0%,
  rgba(255,255,255,0.35) 32%,
  rgba(255,255,255,0.78) 58%,
  rgba(255,255,255,0.96) 80%,
  #fff 100%
Navbar (desktop)
Absolute over hero, z-index: 60, flex row, gap 24px, padding 26px 40px (safe-area top)
Parent pointer-events: none; children pointer-events: auto
Logo left; pill links centered (margin: 0 auto); CTA right
Pills: glass rgba(255,255,255,0.22), border rgba(255,255,255,0.45), backdrop-filter: blur(6px), border-radius: 999px, padding 11px 26px
Active (“Stay”) and CTA: solid white bg, ink text
Hover: glass → rgba(255,255,255,0.4); active/CTA → rgba(255,255,255,0.88)
Breakpoints: shrink padding/font at 1100px and 900px
At ≤780px: hide .nav__links and .nav__cta; show burger
Mobile menu + animations

Show .menu as flex only ≤780px. Open state = body.is-open (also locks overflow: hidden).

Open / close timings
Open duration: 0.55s with --ease-out
Close duration: 0.35s with --ease-in
Burger → X
Circular glass button 46px, 3 white bars 20×2 stacked at 0 / 6 / 12px
Open:
bar1: translate: 0 6px; rotate: 45deg
bar2: opacity: 0; scale: 0.2 1
bar3: translate: 0 -6px; rotate: -45deg
Transition stagger: translate first, then rotate delayed 0.14s on open (reverse on close)
Overlay
Fixed fullscreen, z-index: 50, starts opacity: 0; visibility: hidden
.menu__bg: diagonal gradient 158deg from sky 
#29bee4 → 
#1496be → ink 
#0d2b3a at ~94–95% alpha; blur(26px) saturate(150%)
Closed: transform: scale(1.12); open: scale to none over 0.7s --ease-out
Menu items: start opacity: 0; translateY(18px); open stagger calc(var(--i) * 55ms + 140ms), opacity 0.5s, transform 0.65s --ease-out
CTA pill: same enter, delay 420ms
Link active press: translateX(6px)
Click link or outside .menu__inner closes; Escape closes and refocuses burger; desktop ≥781px forces close
Intro section
White, centered grid, min-height: 68svh
Padding: clamp(96px, 17vh, 190px) 24px clamp(80px, 12vh, 150px)
Eyebrow: Riviera Living Style
Title (with line break after “shoreline”): Where the shoreline becomes calm — only calm is bold/black display face
Title max-width: 16ch (13ch on mobile)
Leaf scroll parallax (JS — exact)

On scroll (rAF-throttled, passive listener), set CSS vars on each leaf:

Leaf	--parallax-y	--parallax-x
Left	scrollY * -0.28	scrollY * -0.06
Right	scrollY * -0.48	scrollY * 0.08
Transforms:		
Left: translate3d(var(--parallax-x), calc(-50% + var(--parallax-y)), 0)
Right: same + rotate(180deg)
Skip updates when prefers-reduced-motion: reduce. Also respect global reduce-motion: force transition/animation durations near 0.
Accessibility / behavior details
Burger: aria-label toggles “Open menu” / “Close menu”, aria-expanded, aria-controls="mobile-menu"
Wordmark SVG and decorative images: aria-hidden="true"
Images: user-select: none, -webkit-user-drag: none
Leaves: will-change: transform
Tech constraints
Vite only ("vite": "^5.4.2"), scripts: dev / build / preview
No framework components; keep BEM-like class names listed above
Do not invent extra sections, cards, stats, or different imagery
Match layering z-index exactly: sky 0 → wordmark 1 → building 2 → fade 3 → leaves 5 → menu 50 → nav 60
Build this so the first viewport reads as one branded Mediterranean resort hero (sky + centered white MAREA + building + glass nav), then white intro copy under mirrored leaf decorations that parallax apart while scrolling.