Prompts · for Claude
AI website build-prompts for Claude
Hand a Meez prompt to Claude or Claude Code and it writes the full component — Claude follows a detailed structured spec closely, getting the fonts, color system, sections and animation right on the first pass. The more precise the prompt, the less generic the result, and Meez prompts are about as precise as they get.
How to use a Meez prompt in Claude
- Pick a prompt below (4 on this page are free) or browse the full library — every prompt is a complete art-direction spec: fonts, layout, color system, motion and real asset URLs.
- Copy the whole prompt and paste it into Claude, or the Claude Code terminal. Don’t trim it — the detail is what stops Claude from defaulting to a generic layout.
- Let it build, then iterate: swap the copy, point the asset URLs at your own media, and ship. The sites you build are yours, commercially.
Free prompts to try in Claude right now
Wellness BalanceHero Section · free prompt · copy-paste
Create a single-page hero landing for a wellness/supplements brand called "TerraElix" using React + Tailwind CSS + Lucide React icons. The page is a full-viewport hero with a background image, navbar, headline with word-by-word reveal animations, CTA section, and a 3-panel footer strip. It must be fully responsive (mobile, tablet, desktop).
---
## Fonts
Import from Google Fonts:
- **DM Sans** (weights 400, 500) -- used for brand name, nav links, headline, panel 1 text
- **Inter** (weights 400, 500) -- used for buttons, body text, panel 2/3 text
---
## Background
Full-screen background image covering the entire viewport:
```
url: https://meez.design/web/media/ext/4dfc1a4b05bd693d.webp
background-size: cover; background-position: center; background-repeat: no-repeat;
```
---
## Layout Structure
```
<div> (min-h-screen, flex flex-col, relative, overflow-hidden)
<nav> -- navbar
<section> -- hero content (flex-1, flex col, justify-center)
<div> -- mobile/tablet product image (visible below lg)
<div> -- 3-panel grid footer
<img> -- desktop floating product image (absolute, hidden below lg)
</div>
```
---
## Navbar
- **Left:** Brand name "TerraElix" -- white, DM Sans 500, 30px, letter-spacing -0.05em
- **Center (desktop only, hidden on mobile):** Nav links "About", "Products", "Promotions", "Contact" -- DM Sans 500, 18px, text-white/90, gap 10 (lg)
- **Right:** Row of icon buttons + avatar + mobile menu toggle
- Search icon (Lucide `Search`, size 20, strokeWidth 1.5)
- Shopping bag icon (Lucide `ShoppingBag`, size 20, strokeWidth 1.5)
- Return icon (Lucide `CornerUpLeft`, size 20, strokeWidth 1.5)
- Round avatar image (w-8 h-8, lg:w-10 lg:h-10, rounded-full, object-cover):
```
https://meez.design/web/media/ext/933e27c46b639e84.png
```
- Hamburger menu button (md:hidden, Lucide `Menu` / `X` toggle)
- **Mobile overlay menu:** fixed inset-0 bg-black/90 z-30 with centered nav links (text-2xl, white)
Padding: px-5 sm:px-8 lg:px-10, py-4 lg:py-5
---
## Hero Headline
Font: DM Sans, weight 400, letter-spacing -0.05em
Responsive sizes:
- Base: 48px/50px line-height
- sm: 80px/72px
- md: 110px/95px
- lg: 130px/110px
- xl: 155px/125px
Text layout (3 lines):
```
Line 1: "The" (white) "Power" (white) "of" (white/45 -- dimmed)
Line 2: "Nature" (dimmed) "in" (dimmed) "Every" (white)
Line 3: "Capsule" (white) + inline image
```
Each word is wrapped in a container with overflow-hidden, and the inner span animates with `wordReveal` (translateY 100% + blur to visible). Staggered delays: 0.3s, 0.4s, 0.5s, 0.6s, 0.7s, 0.8s, 0.9s.
**Inline image** after "Capsule" (hidden on mobile, sm:inline-block, align-middle, ml-2 lg:ml-4):
```
https://meez.design/web/media/ext/014f4c2bed24ce90.png
height: clamp(60px, 10vw, 160px); width: auto;
```
---
## CTA Section
Below the headline, mt-8 sm:mt-12 lg:mt-[75px]. Flex row on sm+, column on mobile. Gap: 5 (mobile), 8 (sm), 50px (lg).
- **Button:** "Explore Now" + ArrowUpRight icon. bg-black text-white rounded-md. Sizes: w-full sm:w-[240px] md:w-[280px] lg:w-[310px], h-14 sm:h-16 lg:h-[72px]. Font: Inter 500, responsive text (base to 2xl), letter-spacing -0.03em.
- **Paragraph:** "Discover our new plant-based supplements for daily balance and clean energy." -- white, max-w-[310px], Inter 400, text-sm sm:text-base lg:text-lg, line-height 1.45, letter-spacing -0.03em.
---
## Mobile/Tablet Product Image (lg:hidden)
Visible below lg breakpoint. Oversized, bleeding off edges:
```
https://meez.design/web/media/ext/8f861b7c00ec34fe.png
w-[180%] sm:w-[151%] max-w-[1296px], object-contain, mx-auto, drop-shadow-2xl
margin-bottom: -180px sm:-220px (overlaps panels below)
```
---
## Bottom 3-Panel Grid
`grid grid-cols-1 md:grid-cols-[2fr_1fr_2fr]`, relative z-10.
### Panel 1 (bg-[#ECEDEC])
- Text: "Start your personalized path to natural balance" -- DM Sans 400, text-2xl sm:text-[28px] lg:text-[35px], leading-[1.1], letter-spacing -0.05em, max-w-[350px]
- Link: "Personal Assessment" -- underline, Inter 400, text-base lg:text-lg, letter-spacing -0.03em
- Decorative image (absolute right-0 bottom-0, h-full, mix-blend-multiply):
```
https://meez.design/web/media/ext/c79bc389cb0bf9d4.png
```
### Panel 2 (bg-[#FEFDF9]) -- Auto-rotating card carousel
4 cards cycling every 3500ms with fade/slide transition:
1. FlaskConical icon, bg-black circle: "Experience our newly enhanced natural formula"
2. Leaf icon, bg-emerald-800 circle: "Pure organic ingredients sourced sustainably"
3. Droplets icon, bg-cyan-800 circle: "Advanced bioavailability for maximum absorption"
4. Sun icon, bg-amber-700 circle: "Clinically tested for daily energy & vitality"
Each card: icon in a 40px (sm:48px) round colored circle + text (Inter 400, text-sm sm:text-base lg:text-lg, text-black/80, line-height 1.2, letter-spacing -0.03em).
Active card: opacity-100 translate-y-0. Inactive: opacity-0 translate-y-4 absolute.
Bottom dots: 4 thin bars (h-0.5, flex-1, rounded-full). Active: bg-black. Inactive: bg-black/20.
### Panel 3 (bg-black)
- Left: Product image (w-[120px] h-[82px] sm:w-[160px] h-[110px] lg:w-[208px] h-[142px]):
```
https://meez.design/web/media/ext/300c2e1eb0264eef.png
```
- Right: "+14K" (white, Inter 400, text-2xl sm:text-3xl lg:text-[35px], letter-spacing -0.05em) + "People have already optimized their wellness" (text-white/60, Inter 400, text-sm sm:text-base lg:text-lg, line-height 1.2)
---
## Desktop Floating Product (lg+ only)
Same image as mobile product, but absolutely positioned for desktop:
```
https://meez.design/web/media/ext/8f861b7c00ec34fe.png
position: absolute; z-0; hidden lg:block;
width: clamp(600px, 80vw, 1412px); height: auto;
bottom: -10%; right: clamp(-400px, -20vw, -100px);
```
---
## Animations (CSS keyframes)
```css
@keyframes fadeUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInRight {
from { opacity: 0; transform: translateX(40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
@keyframes wordReveal {
from { opacity: 0; transform: translateY(100%); filter: blur(4px); }
to { opacity: 1; transform: translateY(0); filter: blur(0px); }
}
```
All use `cubic-bezier(0.16, 1, 0.3, 1)` easing with `both` fill mode.
**Classes and their animations:**
- `.animate-fade-up` -- fadeUp 0.8s
- `.animate-fade-in` -- fadeIn 0.7s
- `.animate-slide-left` -- slideInLeft 0.8s
- `.animate-slide-right` -- slideInRight 0.8s
- `.animate-scale-in` -- scaleIn 1s
- `.animate-word-reveal > span` -- wordReveal 0.7s
**Delay classes:** .delay-200 through .delay-1100 (increments of 0.1s)
**Animation assignments:**
- Navbar container: animate-fade-in
- Brand name: animate-slide-left delay-200
- Nav links: animate-fade-in delay-400
- Right icons: animate-slide-right delay-300
- CTA row: animate-fade-up delay-600
- Desktop product image: animate-scale-in delay-700
- Mobile product image: animate-scale-in delay-800
- Panel 1: animate-fade-up delay-900
- Panel 2: animate-fade-up delay-1000
- Panel 3: animate-fade-up delay-1100
- Inline capsule image: animate-scale-in delay-1000
### Source Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TerraElix</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500&family=Inter:wght@400;500&display=swap" rel="stylesheet" />
<style>
@keyframes fadeUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInRight {
from { opacity: 0; transform: translateX(40px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
@keyframes wordReveal {
from { opacity: 0; transform: translateY(100%); filter: blur(4px); }
to { opacity: 1; transform: translateY(0); filter: blur(0px); }
}
.animate-fade-up { animation: fadeUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; }
.animate-fade-in { animation: fadeIn 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; }
.animate-slide-left { animation: slideInLeft 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; }
.animate-slide-right { animation: slideInRight 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; }
.animate-scale-in { animation: scaleIn 1s cubic-bezier(0.16, 1, 0.3, 1) both; }
.animate-word-reveal { display: inline-block; overflow: hidden; }
.animate-word-reveal > span { display: inline-block; animation: wordReveal 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; }
.delay-200 { animation-delay: 0.2s; }
.delay-300 { animation-delay: 0.3s; }
.delay-400 { animation-delay: 0.4s; }
.delay-600 { animation-delay: 0.6s; }
.delay-700 { animation-delay: 0.7s; }
.delay-800 { animation-delay: 0.8s; }
.delay-900 { animation-delay: 0.9s; }
.delay-1000 { animation-delay: 1.0s; }
.delay-1100 { animation-delay: 1.1s; }
</style>
</head>
<body class="m-0 p-0">
<div
class="min-h-screen font-sans flex flex-col relative overflow-hidden"
style="background-image: url('https://meez.design/web/media/ext/4dfc1a4b05bd693d.webp'); background-size: cover; background-position: center; background-repeat: no-repeat;"
>
<!-- Navbar -->
<nav class="flex items-center justify-between px-5 sm:px-8 lg:px-10 py-4 lg:py-5 relative z-20 animate-fade-in">
<span class="text-white animate-slide-left delay-200" style="font-family: 'DM Sans', sans-serif; font-size: 30px; line-height: 38px; letter-spacing: -0.05em; font-weight: 500;">TerraElix</span>
<!-- Desktop nav -->
<ul class="hidden md:flex gap-6 lg:gap-10 text-white/90 animate-fade-in delay-400 list-none m-0 p-0" style="font-family: 'DM Sans', sans-serif; font-size: 18px; line-height: 120%; letter-spacing: -0.01em; font-weight: 500;">
<li class="cursor-pointer hover:text-white transition-colors">About</li>
<li class="cursor-pointer hover:text-white transition-colors">Products</li>
<li class="cursor-pointer hover:text-white transition-colors">Promotions</li>
<li class="cursor-pointer hover:text-white transition-colors">Contact</li>
</ul>
<div class="flex items-center gap-3 lg:gap-4 animate-slide-right delay-300">
<button class="text-white/80 hover:text-white transition-colors bg-transparent border-none cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
</button>
<button class="text-white/80 hover:text-white transition-colors bg-transparent border-none cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
</button>
<button class="text-white/80 hover:text-white transition-colors bg-transparent border-none cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/></svg>
</button>
<img src="https://meez.design/web/media/ext/933e27c46b639e84.png" class="w-8 h-8 lg:w-10 lg:h-10 rounded-full object-cover" alt="Avatar" />
<!-- Mobile menu button -->
<button id="menuBtn" class="md:hidden text-white/80 hover:text-white transition-colors ml-2 bg-transparent border-none cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
</button>
</div>
</nav>
<!-- Mobile menu overlay -->
<div id="mobileMenu" class="fixed inset-0 bg-black/90 z-30 flex-col items-center justify-center gap-8 md:hidden" style="display: none;">
<button id="closeMenuBtn" class="absolute top-5 right-5 text-white bg-transparent border-none cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
</button>
<ul class="flex flex-col gap-6 text-white text-2xl font-medium text-center list-none m-0 p-0">
<li class="cursor-pointer hover:text-white/70 transition-colors">About</li>
<li class="cursor-pointer hover:text-white/70 transition-colors">Products</li>
<li class="cursor-pointer hover:text-white/70 transition-colors">Promotions</li>
<li class="cursor-pointer hover:text-white/70 transition-colors">Contact</li>
</ul>
</div>
<!-- Hero -->
<section class="px-5 sm:px-8 lg:px-10 flex-1 relative overflow-visible z-10 flex flex-col justify-center">
<h1
class="text-[48px] leading-[50px] sm:text-[80px] sm:leading-[72px] md:text-[110px] md:leading-[95px] lg:text-[130px] lg:leading-[110px] xl:text-[155px] xl:leading-[125px] m-0"
style="font-family: 'DM Sans', sans-serif; font-weight: 400; letter-spacing: -0.05em;"
>
<span class="animate-word-reveal"><span class="text-white" style="animation-delay: 0.3s;">The</span></span>
<span class="animate-word-reveal"><span class="text-white" style="animation-delay: 0.4s;">Power</span></span>
<span class="animate-word-reveal"><span class="text-white/45" style="animation-delay: 0.5s;">of</span></span>
<br />
<span class="animate-word-reveal"><span class="text-white/45" style="animation-delay: 0.6s;">Nature</span></span>
<span class="animate-word-reveal"><span class="text-white/45" style="animation-delay: 0.7s;">in</span></span>
<span class="animate-word-reveal"><span class="text-white" style="animation-delay: 0.8s;">Every</span></span>
<br />
<span class="animate-word-reveal"><span class="text-white" style="animation-delay: 0.9s;">Capsule</span></span>
<img
src="https://meez.design/web/media/ext/014f4c2bed24ce90.png"
alt=""
class="hidden sm:inline-block align-middle ml-2 lg:ml-4 animate-scale-in delay-1000"
style="height: clamp(60px, 10vw, 160px); width: auto;"
/>
</h1>
<div class="flex flex-col sm:flex-row sm:items-center mt-8 sm:mt-12 lg:mt-[75px] gap-5 sm:gap-8 lg:gap-[50px] animate-fade-up delay-600">
<button
class="flex items-center justify-center gap-2 sm:gap-3 bg-black text-white rounded-md hover:bg-neutral-900 transition-colors flex-shrink-0 w-full sm:w-[240px] md:w-[280px] lg:w-[310px] h-14 sm:h-16 lg:h-[72px] text-base sm:text-lg md:text-xl lg:text-2xl border-none cursor-pointer"
style="font-family: 'Inter', sans-serif; font-weight: 500; letter-spacing: -0.03em;"
>
Explore Now
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 7h10v10"/><path d="M7 17 17 7"/></svg>
</button>
<p
class="text-white max-w-[310px] text-sm sm:text-base lg:text-lg m-0"
style="font-family: 'Inter', sans-serif; font-weight: 400; line-height: 1.45; letter-spacing: -0.03em;"
>
Discover our new plant-based supplements for daily balance and clean energy.
</p>
</div>
</section>
<!-- Mobile/Tablet product image -->
<div class="relative z-10 flex items-center justify-center pt-0 sm:pt-2 pb-0 sm:block lg:hidden overflow-visible mb-[-180px] sm:mb-[-220px] animate-scale-in delay-800">
<img
src="https://meez.design/web/media/ext/8f861b7c00ec34fe.png"
alt="Product capsules"
class="w-[180%] sm:w-[151%] max-w-[1296px] h-auto object-contain mx-auto drop-shadow-2xl"
/>
</div>
<!-- Bottom panels -->
<div class="grid grid-cols-1 md:grid-cols-[2fr_1fr_2fr] relative z-10">
<!-- Panel 1 -->
<div class="bg-[#ECEDEC] px-5 sm:px-8 py-6 sm:py-8 flex flex-col justify-between relative overflow-hidden min-h-[180px] sm:min-h-[200px] animate-fade-up delay-900">
<p
class="relative z-10 text-black max-w-[350px] text-2xl sm:text-[28px] lg:text-[35px] leading-[1.1] m-0"
style="font-family: 'DM Sans', sans-serif; font-weight: 400; letter-spacing: -0.05em;"
>
Start your personalized path to natural balance
</p>
<span
class="relative z-10 text-black underline underline-offset-2 cursor-pointer hover:opacity-70 transition-opacity mt-4 text-base lg:text-lg"
style="font-family: 'Inter', sans-serif; font-weight: 400; letter-spacing: -0.03em;"
>
Personal Assessment
</span>
<img
src="https://meez.design/web/media/ext/c79bc389cb0bf9d4.png"
alt=""
class="absolute right-0 bottom-0 h-full w-auto object-contain pointer-events-none z-0"
style="mix-blend-mode: multiply;"
/>
</div>
<!-- Panel 2 - Gallery -->
<div class="bg-[#FEFDF9] px-5 sm:px-8 py-6 sm:py-8 flex flex-col justify-between min-h-[150px] sm:min-h-[180px] animate-fade-up delay-1000 overflow-hidden">
<div class="relative flex-1" id="cardContainer">
<!-- Cards injected by JS -->
</div>
<div class="flex gap-2 mt-6" id="cardDots"></div>
</div>
<!-- Panel 3 -->
<div class="bg-black px-5 sm:px-8 py-6 sm:py-8 flex items-center gap-4 sm:gap-6 min-h-[150px] sm:min-h-[180px] animate-fade-up delay-1100">
<div class="flex-shrink-0">
<img
src="https://meez.design/web/media/ext/300c2e1eb0264eef.png"
alt=""
class="object-contain w-[120px] h-[82px] sm:w-[160px] sm:h-[110px] lg:w-[208px] lg:h-[142px]"
/>
</div>
<div>
<p
class="text-white text-2xl sm:text-3xl lg:text-[35px] leading-tight m-0"
style="font-family: 'Inter', sans-serif; font-weight: 400; letter-spacing: -0.05em;"
>
+14K
</p>
<p
class="text-white/60 mt-1 text-sm sm:text-base lg:text-lg m-0"
style="font-family: 'Inter', sans-serif; font-weight: 400; line-height: 1.2; letter-spacing: -0.03em;"
>
People have already optimized their wellness
</p>
</div>
</div>
</div>
<!-- Background decorative image - desktop only -->
<img
src="https://meez.design/web/media/ext/8f861b7c00ec34fe.png"
alt=""
class="absolute pointer-events-none z-0 hidden lg:block animate-scale-in delay-700"
style="width: clamp(600px, 80vw, 1412px); height: auto; bottom: -10%; right: clamp(-400px, -20vw, -100px);"
/>
</div>
<script>
// Mobile menu toggle
const menuBtn = document.getElementById('menuBtn');
const mobileMenu = document.getElementById('mobileMenu');
const closeMenuBtn = document.getElementById('closeMenuBtn');
menuBtn.addEventListener('click', () => {
mobileMenu.style.display = 'flex';
});
closeMenuBtn.addEventListener('click', () => {
mobileMenu.style.display = 'none';
});
// Card carousel
const cards = [
{ icon: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2"/><path d="M8.5 2h7"/><path d="M7 16h10"/></svg>', text: 'Experience our newly enhanced natural formula', color: 'bg-black' },
{ icon: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M11 20A7 7 0 0 1 9.8 6.9C15.5 4.9 17 3.5 17 3.5s1.5 0 2.8 1.3c1 .9 1.1 2.2 1.1 2.2s-1.5 1.5-3.5 7.2A7 7 0 0 1 11 20Z"/><path d="M2 21c0-3 1.9-5.6 4.4-6.3"/><path d="M12.3 7.4C14.2 5.5 17 4.5 17 4.5"/></svg>', text: 'Pure organic ingredients sourced sustainably', color: 'bg-emerald-800' },
{ icon: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M7 16.3c2.2 0 4-1.83 4-4.05 0-1.16-.57-2.26-1.71-3.19S7.29 6.75 7 5.3c-.29 1.45-1.14 2.84-2.29 3.76S3 11.1 3 12.25c0 2.22 1.8 4.05 4 4.05z"/><path d="M12.56 6.6A10.97 10.97 0 0 0 14 3.02c.5 2.5 2 4.9 4 6.5s3 3.5 3 5.5a6.98 6.98 0 0 1-11.91 4.97"/></svg>', text: 'Advanced bioavailability for maximum absorption', color: 'bg-cyan-800' },
{ icon: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>', text: 'Clinically tested for daily energy & vitality', color: 'bg-amber-700' },
];
let activeCard = 0;
const container = document.getElementById('cardContainer');
const dotsContainer = document.getElementById('cardDots');
function renderCards() {
container.innerHTML = cards.map((card, i) => `
<div class="flex items-start gap-4 transition-all duration-500 ease-out ${i === activeCard ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4 absolute inset-0'}">
<div class="w-10 h-10 sm:w-12 sm:h-12 rounded-full ${card.color} flex items-center justify-center flex-shrink-0 transition-colors duration-500 text-white">
${card.icon}
</div>
<p class="text-black/80 mt-1 text-sm sm:text-base lg:text-lg m-0" style="font-family: 'Inter', sans-serif; font-weight: 400; line-height: 1.2; letter-spacing: -0.03em;">
${card.text}
</p>
</div>
`).join('');
dotsContainer.innerHTML = cards.map((_, i) => `
<button data-index="${i}" class="h-0.5 flex-1 rounded-full transition-all duration-500 border-none cursor-pointer ${i === activeCard ? 'bg-black' : 'bg-black/20 hover:bg-black/40'}"></button>
`).join('');
}
dotsContainer.addEventListener('click', (e) => {
const btn = e.target.closest('button');
if (btn && btn.dataset.index !== undefined) {
activeCard = parseInt(btn.dataset.index);
renderCards();
}
});
renderCards();
setInterval(() => {
activeCard = (activeCard + 1) % cards.length;
renderCards();
}, 3500);
</script>
</body>
</html>
Mostar GuideLanding Page · free prompt · copy-paste
# PROMPT — Recreate "Mostar city" cinematic scroll page exactly
Build a **single standalone page** (`index.html` + `styles.css` + `script.js`, vanilla — no frameworks, no build step, no local assets). Every image and font must be loaded from the **remote URLs below**. Reproduce all values verbatim; they are not approximations.
---
## 1. Remote assets (the only allowed sources)
**Font — display serif, family name must be `"Ogg Medium"`**
```
https://meez.design/web/media/ext/82338cefef84b6d9.woff2
```
**Scene photographs (transparent-edge PNG layers)**
| Layer role | URL |
|---|---|
| Sky / farthest background | `https://meez.design/web/media/ext/125a599d710ae651.png` |
| Back "four" glow layer | `https://meez.design/web/media/ext/4c30cbf7df6db74e.png` |
| Bazaar mid-back | `https://meez.design/web/media/ext/1f88ffb89428a24c.png` |
| Splitframe LEFT | `https://meez.design/web/media/ext/11592a51c13f27ef.png` |
| Splitframe RIGHT | `https://meez.design/web/media/ext/e70e8bc6286f9f7a.png` |
| Bridge foreground | `https://meez.design/web/media/ext/020f8fce312ef368.png` |
| Frame-two river close-up | `https://meez.design/web/media/ext/2ff7d0d330a8773b.png` |
**Sight-card pin icons (transparent cutouts, square)**
| Icon | URL |
|---|---|
| icon1 | `https://meez.design/web/media/ext/1fbbb2933f1ed0af.png` |
| icon2 | `https://meez.design/web/media/ext/f9b3de4cb836bb8d.png` |
| icon3 | `https://meez.design/web/media/ext/cc430f6929d14950.png` |
Favicon: `<link rel="icon" href="data:," />`
---
## 2. Document head
```html
<html lang="en">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mostar city</title>
<meta name="description" content="A cinematic three-screen scroll story for Mostar city." />
```
Stylesheet linked normally; script linked with `defer`.
---
## 3. Exact DOM tree and source order
Source order **is** the paint order for equal z-index, so keep it exactly:
```
main.site-shell
└─ section.cinema-scroll#cinema [aria-label="Mostar cinematic scroll story"]
└─ div.stage
├─ div.world
│ ├─ img.scene-img.sky-img → sky URL
│ ├─ header.site-header [aria-label="Primary navigation"]
│ │ ├─ a.site-logo[href="#cinema"] "Bosnia and Herzegovina"
│ │ ├─ nav.site-nav [aria-label="Main menu"] Intro/#cinema, Bridge/#bridge,
│ │ │ Bazaar/#bazaar, Routes/#routes
│ │ └─ button.language-switcher [aria-label="Change language"]
│ │ ├─ span "EN"
│ │ └─ span[aria-hidden="true"] "⌄"
│ ├─ div.back-stack
│ │ ├─ img.scene-img.back-img.back-four → back-four URL
│ │ ├─ section.sights-slider [aria-label="Mostar sights slider"]
│ │ │ └─ div.sights-track
│ │ │ └─ 5 × article.sight-card [tabindex="0" role="button"]
│ │ └─ img.scene-img.back-img.back-bazaar → bazaar URL
│ ├─ div.sights-controls [aria-label="Slider controls"]
│ │ ├─ button.sight-nav.sight-prev "←" [aria-label="Previous sight"]
│ │ └─ button.sight-nav.sight-next "→" [aria-label="Next sight"]
│ ├─ h1.hero-title "MOSTAR"
│ ├─ img.scene-img.splitframe-img.splitframe-left → splitframe-1 URL
│ ├─ img.scene-img.splitframe-img.splitframe-right → splitframe-2 URL
│ ├─ img.scene-img.bridge-img → bridge URL
│ ├─ img.scene-img.frame-two-img → frame-two URL
│ └─ div.shade
├─ section.intro-copy [aria-label="Mostar overview"]
├─ section.story-panel.story-panel-bridge [aria-label="Old Bridge details"]
└─ section.story-panel.story-panel-bazaar [aria-label="Old town details"]
```
All `img.scene-img` have `alt=""`.
**Sight card internal order (per card):** `span.sight-kicker` → `img.sight-pin` → `h3` → `p`.
| # | aria-label | kicker | h3 | p | pin |
|---|---|---|---|---|---|
| 1 | Open Stari Most card | Old Bridge | Stari Most | The stone arch over the Neretva and Mostar's main landmark. | icon1 |
| 2 | Open Kujundziluk card | Bazaar Street | Kujundziluk | Copper shops, souvenirs, and the old bazaar lane by the bridge. | icon2 |
| 3 | Open Koski Mehmed Pasha Mosque card | Viewpoint | Koski Mehmed Pasha Mosque | A classic minaret view back toward Stari Most and the river. | icon3 |
| 4 | Open Kajtaz House card | Ottoman House | Kajtaz House | A preserved residential house showing Mostar's Ottoman layers. | icon1 |
| 5 | Open War Photo Exhibition card | Museum | War Photo Exhibition | A compact, moving stop for context on the city's recent history. | icon2 |
**intro-copy content:** `<p>A stone arch, emerald water, and a compact old city made for slow mornings, late light, and one unforgettable crossing.</p>` then `div.hero-tags[aria-label="Mostar highlights"]` with three spans: `Old Bridge`, `Neretva River`, `UNESCO old city`.
**story-panel-bridge:** `h2` = `The bridge is the city's compass.`; `p` = `Stari Most links the banks of the Neretva and anchors a historic quarter shaped by Ottoman, Mediterranean, and European layers.`; then `dl.facts` with two `div` groups: `dt 1566 / dd Original bridge completed` and `dt 2005 / dd Old Bridge Area inscribed by UNESCO`.
**story-panel-bazaar:** `h2` = `The bazaar keeps Mostar close.`; `p` = `Stone lanes, mosque courtyards, copper stalls, and riverside coffee stay within a short walk of Stari Most.`; then `button.note-button` containing `span[aria-hidden="true"] ↗` and `span Open old town notes`.
---
## 4. CSS custom properties — exact `:root` block
```css
:root {
--mx: 0; --my: 0;
--back-opacity: 1; --back-x: 0px; --back-y: 0px; --back-scale: 0.76;
--four-y: 10vh; --four-scale: 0.78;
--bazaar-y: 20vh;
--blur-px: 0px; --back-brightness: 1;
--bazaar-blur-px: 0px; --bazaar-brightness: 1; --bazaar-saturation: 1;
--shade-opacity: 1; --shade-z: 2;
--shade-top-alpha: 0; --shade-mid-alpha: 0; --shade-bottom-alpha: 0;
--blur-tint: 74, 181, 224;
--title-y: 0px; --title-scale: 1; --title-opacity: 1;
--bridge-x: -50%; --bridge-y: 0px; --bridge-bottom: 5vh;
--bridge-width: 67.2vw; --bridge-scale: 1.02;
--split-left-x: -50%; --split-left-y: 0px; --split-left-scale: 1;
--split-right-x: -50%; --split-right-y: 0px; --split-right-scale: 1;
--frame2-opacity: 0; --frame2-x: -50%; --frame2-y: -50%; --frame2-scale: 1.06;
--intro-copy-y: 0px; --intro-copy-opacity: 1;
--panel2-opacity: 0; --panel2-y: calc(-50% + 58px);
--panel3-opacity: 0; --panel3-y: calc(-50% + 58px);
--sights-opacity: 0; --sights-controls-opacity: 0; --sights-y: 0px;
--sights-enter-x: 420vw; --sights-visibility: hidden;
--sights-shift: 0px; --sights-scale: 1;
--sights-top: clamp(112px, 19vh, 220px);
--sights-screen-top: clamp(112px, 19vh, 220px);
--ink: #111411; --paper: #fdf1e1; --shadow: rgba(0, 0, 0, 0.32);
font-family: Inter, Satoshi, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: var(--paper);
background: #0b1110;
letter-spacing: 0;
}
```
Global: `* { box-sizing: border-box }`; `html { min-height:100%; scroll-behavior:smooth; background:#0b1110 }`; `body { min-height:100%; margin:0; overflow-x:clip; background:#0b1110 }`; `button { border:0; font:inherit }`; `.site-shell { min-height:100vh }`.
---
## 5. Exact positioning of every element
**Scroll rig**
- `.cinema-scroll { position: relative; height: calc(100vh + 3700px) }`
- `.stage { position: sticky; top: 0; height: 100vh; min-height: 620px; overflow: hidden; isolation: isolate; background: #7fb4d4 }`
- These are all `position: absolute`: `.world, .back-stack, .sky-img, .shade, .scene-img, .site-header, .sights-slider, .sights-controls, .hero-title, .intro-copy, .story-panel`
- `.world { inset: 0; overflow: hidden; background: #79b7dd }`
**Header (z-index 10)** — `top:0; left:0; right:0;` `display:grid; grid-template-columns: minmax(260px,1fr) auto minmax(260px,1fr); align-items:center; gap:32px; padding:32px; color:rgba(253,241,225,0.86); pointer-events:auto`
- `.site-logo` — `justify-self:start`, Ogg Medium 24px/1 weight 500, `rgba(253,241,225,0.92)`, no underline, `white-space:nowrap`
- `.site-nav` — flex, centered, `gap: clamp(24px, 2.2vw, 44px)`
- `.site-nav a, .language-switcher` — `rgba(253,241,225,0.86)`, `font-weight:700`, `line-height:1`, `text-shadow: 0 2px 16px rgba(0,0,0,0.2)`; `.site-nav a` overrides to `font-size:20px; font-weight:400`
- `.language-switcher` — `justify-self:end`, inline-flex centered, `gap:5px`, `padding:0`, transparent bg, `font-size:16px`, `cursor:pointer`; its spans are inline-flex, `line-height:1`
**Scene images (shared)** — `display:block; user-select:none; -webkit-user-drag:none; will-change: transform, opacity, filter; pointer-events:none`
**Sky (z 0)** — `inset:0; width:100%; height:100%; object-fit:cover; transform:none;` `filter: blur(var(--blur-px)) brightness(var(--back-brightness))`
**`.back-stack` (z 1)** — `top:0; bottom:0; left:-3vw; right:-3vw;` `opacity: var(--back-opacity)`; `transform: translate3d(var(--back-x), var(--back-y), 0) scale(var(--back-scale))`; `transform-origin: 50% 100%`; `will-change: transform, filter, opacity`
**`.back-img` base** — `inset:0; width:100%; height:100%; object-fit:cover;` `filter: blur(var(--blur-px)) brightness(var(--back-brightness))`
**Both `.back-bazaar` and `.back-four` override** — `top:auto; bottom:0; left:48%; right:auto; width:112%; height:auto; object-fit:contain`
- `.back-bazaar` — `z-index:3; opacity:1;` `filter: blur(var(--bazaar-blur-px)) brightness(var(--bazaar-brightness)) saturate(var(--bazaar-saturation));` `transform: translate3d(-50%, var(--bazaar-y), 0) scale(0.86)`
- `.back-four` — `z-index:1; opacity:0.72; mix-blend-mode:screen;` `transform: translate3d(-50%, calc(var(--four-y) - 110px), 0) scale(var(--four-scale))`
**`.sights-slider` (z 2)** — `left:0; right:0; top: var(--sights-top); padding:0;` `opacity:1` (literal — the fade is done by `visibility` + X translate, not opacity); `visibility: var(--sights-visibility);` `transform: translate3d(var(--sights-enter-x), var(--sights-y), 0) scale(var(--sights-scale));` `transform-origin: 0 0; pointer-events:auto; will-change:transform`
**`.sights-track`** — `display:flex; gap: clamp(16px, 1.15vw, 24px); align-items:stretch;` `transform: translate3d(calc(var(--sights-shift) - 18vw), 0, 0);` `transition: transform 640ms cubic-bezier(0.22, 1, 0.36, 1); will-change:transform`. Class `.is-jumping { transition: none }`
**`.sight-card`** — `position:relative; flex: 0 0 clamp(360px, 19.4vw, 430px); height:220px; padding:24px; overflow:hidden; border:1px solid rgba(253,241,225,0.42); border-radius:24px; color:#000; background:#fdf1e1; box-shadow: 0 18px 52px rgba(2,47,64,0.12); backdrop-filter:none; cursor:pointer; pointer-events:auto; user-select:none`. `::before/::after { content:none }`. Kicker/h3/p carry `text-shadow:none` and `position:relative; z-index:1`. `:focus-visible` and `.is-active` → `outline:none`.
- `.sight-kicker` — `display:block; margin-bottom:56px; color:#000; font-size:12px; font-weight:500; line-height:1.05; text-transform:uppercase`
- `.sight-pin` — `position:absolute; top:24px; right:24px; width:67.2px; height:67.2px; pointer-events:none`
- `.sight-card h3` — `position:absolute; left:24px; right:24px; bottom: calc(24px + (16px * 1.16 * 2) + 12px); max-width: calc(100% - 76px); margin:0; color:#000; font-size:24px; font-weight:800; line-height:0.95; overflow:hidden; text-overflow:ellipsis; white-space:nowrap`
- `.sight-card p` — `position:absolute; left:24px; right:24px; bottom:24px; max-width:100%; margin:12px 0 0; color:#000; font-size:16px; font-weight:400; line-height:1.16; display:-webkit-box; max-height: calc(2em * 1.16); overflow:hidden; -webkit-box-orient:vertical; -webkit-line-clamp:2`
**`.sights-controls` (z 5)** — `left:48px; right:auto; top: calc(var(--sights-screen-top) + 220px + 16px); display:flex; justify-content:flex-start; gap:14px;` `opacity: var(--sights-controls-opacity);` `transform: translate3d(0, var(--sights-y), 0);` `pointer-events:none; will-change:transform, opacity`. `.is-ready { pointer-events:auto }`
- `.sight-nav` — `54px × 54px`, inline-flex centered, `border-radius:999px; color:#111411; background:rgba(253,241,225,0.94); box-shadow: 0 18px 36px rgba(0,0,0,0.2); cursor:pointer`
**`.hero-title` (z 3)** — `left:50%; top: clamp(122px, 19vh, 205px); width: min(94vw, 1780px); margin:0; color:#fdf1e1;` Ogg Medium `font-size:14rem; font-weight:500; line-height:0.78; text-align:center; text-shadow:none;` `transform: translate3d(-50%, var(--title-y), 0) scale(var(--title-scale));` `opacity: var(--title-opacity); will-change: transform, opacity`
**`.bridge-img` (z 4)** — `left:50%; bottom: var(--bridge-bottom); width: min(var(--bridge-width), 2140px); height:auto;` `transform: translate3d(var(--bridge-x), var(--bridge-y), 0) scale(var(--bridge-scale));` `transform-origin: 50% 48%`
**`.splitframe-img` (z 6)** — `left:50%; bottom:-2vh; width: min(118vw, 2240px); height:auto; pointer-events:none`
- `.splitframe-left` — `transform: translate3d(var(--split-left-x), var(--split-left-y), 0) scale(var(--split-left-scale)); transform-origin: 21% 52%`
- `.splitframe-right` — `transform: translate3d(var(--split-right-x), var(--split-right-y), 0) scale(var(--split-right-scale)); transform-origin: 79% 52%`
**`.frame-two-img` (z 5)** — `filter: none !important; backdrop-filter:none; left:50%; top:50%; width: min(122vw, 2160px); height:auto;` `opacity: var(--frame2-opacity);` `transform: translate3d(var(--frame2-x), var(--frame2-y), 0) scale(var(--frame2-scale)); transform-origin: 50% 48%`
**`.shade`** — `inset:0; z-index: var(--shade-z); pointer-events:none; opacity: var(--shade-opacity);`
```css
background: linear-gradient(180deg,
rgba(var(--blur-tint), var(--shade-top-alpha)) 0%,
rgba(var(--blur-tint), var(--shade-mid-alpha)) 48%,
rgba(var(--blur-tint), var(--shade-bottom-alpha)) 100%);
```
**`.intro-copy` (z 9)** — `left:50%; bottom: clamp(56px, 28vh, 400px); width: min(560px, calc(100vw - 40px)); text-align:center;` `transform: translate3d(-50%, var(--intro-copy-y), 0); opacity: var(--intro-copy-opacity); will-change: transform, opacity`
- `p` — `margin:0 auto; max-width:560px; color:#fdf1e1; font-size:1.18rem; font-weight:500; line-height:1.18; text-shadow: 0 2px 18px rgba(0,0,0,0.42)`
- `.hero-tags` — flex, wrap, centered, `gap:10px; margin-top:26px`
- `.hero-tags span` — `min-height:42px`, inline-flex centered, `padding:0 25px; color:var(--ink); border-radius:999px; background:#fdf1e1; font-size:0.98rem; font-weight:500; box-shadow: 0 12px 30px rgba(0,0,0,0.18)`
**`.story-panel` (z 10)** — `left:50%; top:45%; width: min(760px, calc(100vw - 42px)); text-align:center; pointer-events:none; transform: translate3d(-50%, -50%, 0); will-change: transform, opacity`
- `h2` — `margin:0; color:#fdf1e1;` Ogg Medium `font-size:4.75rem; font-weight:500; line-height:0.95; text-shadow: 0 16px 38px var(--shadow)`
- `p` — `width: min(520px, 100%); margin:26px auto 0; color:#fdf1e1; font-size:1.14rem; font-weight:500; line-height:1.18; text-shadow: 0 2px 18px rgba(0,0,0,0.42)`
- `.story-panel-bridge` — `top:60%; opacity: var(--panel2-opacity); transform: translate3d(-50%, var(--panel2-y), 0)`
- `.story-panel-bazaar` — `top:29%; opacity: var(--panel3-opacity); transform: translate3d(-50%, var(--panel3-y), 0)`
- `.facts` — `display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:86px; width: min(470px, 100%); margin:72px auto 0`
- `.facts dt` — `color:#fdf1e1;` Ogg Medium `font-size:4.2rem; font-weight:500; line-height:0.9; text-shadow: 0 14px 34px var(--shadow)`
- `.facts dd` — `margin:18px 0 0; color:#fdf1e1; font-size:1rem; font-weight:500; line-height:1.14; text-shadow: 0 2px 18px rgba(0,0,0,0.42)`
- `.note-button` — `min-height:50px; margin-top:28px;` inline-flex centered `gap:12px; padding:0 28px; border-radius:999px; color:var(--ink); background:#fdf1e1; box-shadow: 0 16px 34px rgba(0,0,0,0.18); pointer-events:auto; cursor:pointer`; first span `font-size:1.25rem; line-height:1`
---
## 6. Media queries (exact)
```css
@media (max-width: 1500px) {
.hero-title { font-size: 11rem; }
.story-panel h2 { font-size: 4.1rem; }
}
@media (max-width: 1100px) {
.hero-title { top: 15vh; font-size: 7.5rem; }
.bridge-img { width: 138vw; }
.frame-two-img { width: 132vw; }
.story-panel h2 { font-size: 3.2rem; }
.facts { gap: 34px; margin-top: 44px; }
.facts dt { font-size: 3.2rem; }
.sight-card { flex-basis: clamp(320px, 40vw, 390px); min-height: 178px; }
}
@media (max-width: 640px) {
.stage { min-height: 640px; }
.site-header { grid-template-columns: 1fr auto; gap: 18px; padding: 24px; }
.site-nav { grid-column: 1 / -1; grid-row: 2; justify-content: flex-start;
gap: 18px; overflow-x: auto; scrollbar-width: none; }
.site-nav::-webkit-scrollbar { display: none; }
.hero-title { top: 16vh; font-size: 4.5rem; }
.bridge-img { bottom: 2vh; width: 190vw; }
.frame-two-img { width: 176vw; }
.intro-copy { bottom: 42px; }
.intro-copy p, .story-panel p { font-size: 1rem; }
.hero-tags { gap: 8px; }
.hero-tags span { min-height: 38px; padding: 0 16px; font-size: 0.88rem; }
.story-panel { top: 42%; }
.story-panel-bazaar { top: 26%; }
.story-panel h2 { font-size: 2.45rem; }
.facts { gap: 18px; margin-top: 34px; }
.facts dt { font-size: 2.5rem; }
.sights-slider { padding: 0; }
.sights-track { gap: 12px; transform: translate3d(calc(var(--sights-shift) - 18vw), 0, 0); }
.sight-card { flex-basis: min(82vw, 330px); height: 220px; padding: 24px; border-radius: 24px; }
.sights-controls { top: calc(var(--sights-screen-top) + 236px); }
.sight-card h3 { max-width: 78%; }
.sight-card p { max-width: 100%; margin-top: 10px; }
.sight-kicker { margin-bottom: 56px; }
.sight-pin { top: 24px; right: 24px; width: 57.6px; height: 57.6px; }
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.scene-img, .back-stack, .hero-title, .intro-copy,
.story-panel, .sights-track, .sights-slider { transition: none; }
}
```
---
## 7. JavaScript — animation engine, exact math
Query on load: `.cinema-scroll`, `document.documentElement`, `matchMedia("(prefers-reduced-motion: reduce)")`, `.sights-track`, `.sights-controls`, `.sight-prev`, `.sight-next`, and the original `.sight-card` list.
State: `targetMouseX/Y`, `mouseX/Y`, `targetScroll`, `smoothScroll`, `initialized`, `rafPending`, `sightCards`, `originalSightCount`, `activeSight = originalSightCount`.
**Helpers**
```js
clamp(v, min = 0, max = 1) => Math.min(max, Math.max(min, v))
smoothstep(e0, e1, v) => { const x = clamp((v - e0) / (e1 - e0)); return x * x * (3 - 2 * x); }
lerp(a, b, t) => a + (b - a) * t
segmentInOut(s, a, b, c, d) => {
const enter = smoothstep(a, b, s), exit = smoothstep(c, d, s);
return { enter, exit, active: enter * (1 - exit) };
}
getScrollDistance() => clamp(-section.getBoundingClientRect().top, 0,
section.offsetHeight - window.innerHeight)
```
**Per-frame `update()`**
```js
targetScroll = getScrollDistance();
if (!initialized || reduceMotion.matches) { smoothScroll = targetScroll; initialized = true; }
else { smoothScroll = lerp(smoothScroll, targetScroll, 0.14); }
if (Math.abs(smoothScroll - targetScroll) < 0.08) smoothScroll = targetScroll;
mouseX = lerp(mouseX, targetMouseX, 0.12);
mouseY = lerp(mouseY, targetMouseY, 0.12);
const frame2 = segmentInOut(smoothScroll, 560, 900, 1300, 1620);
const frame3 = segmentInOut(smoothScroll, 1760, 2140, 2540, 2700);
const progress = clamp(smoothScroll / 2700);
const introExit = smoothstep(90, 650, smoothScroll);
const sightsEnterRaw = smoothstep(2760, 3560, smoothScroll);
const sightsEnter = Math.pow(sightsEnterRaw, 1.55);
const sightsControlsEnter = smoothstep(3360, 3660, smoothScroll);
const blurActive = clamp(frame2.active + frame3.active);
const frame2Opacity = frame2.active * (1 - frame3.enter);
const splitDrift = Math.pow(frame2.enter, 1.5);
const panel2Opacity = frame2.active * (1 - frame2.exit);
const panel3Opacity = frame3.active * (1 - frame3.exit);
const backScale = 0.76 + progress * 0.2 + frame2.enter * 0.18 + frame3.enter * 0.16;
const sharedHeroY = progress * -74;
const sharedHeroScale = progress * 0.23;
const sightsScreenTop = Math.min(220, Math.max(112, window.innerHeight * 0.19)) - 50;
const sightsParentTop = window.innerHeight - (window.innerHeight - sightsScreenTop) / backScale;
```
**Variable writes (verbatim, `.toFixed` precision included)**
```js
--mx = reduceMotion.matches ? 0 : mouseX (4 decimals)
--my = reduceMotion.matches ? 0 : mouseY (4 decimals)
--back-opacity = (1 - frame2.active * 0.06)
--back-x = `${mouseX * -12}px`
--back-y = `${mouseY * -4}px`
--back-scale = backScale
--four-y = `${10 + progress * 10}vh`
--four-scale = 0.78 + progress * 0.16
--bazaar-y = `${20 - progress * 8}vh`
--blur-px = `${blurActive * 14}px`
--back-brightness = 1 - blurActive * 0.255
--bazaar-blur-px = `${frame2.active * 14}px`
--bazaar-brightness= 1 - frame2.active * 0.255 - frame3.active * 0.06
--bazaar-saturation= 1 + frame3.active * 0.18
--shade-opacity = "1"
--shade-z = frame2.active > 0.02 ? "2" : "0"
--shade-top-alpha = blurActive * 0.465
--shade-mid-alpha = blurActive * 0.42
--shade-bottom-alpha = blurActive * 0.51
--title-y = `${introExit * -210}px`
--title-scale = 1 - introExit * 0.08
--title-opacity = 1 - introExit
--bridge-x = `calc(-50% + ${mouseX * 18}px)`
--bridge-y = `${mouseY * 8 + sharedHeroY - frame2.exit * 760}px`
--bridge-bottom = `${5 - frame2.enter * 13}vh`
--bridge-width = `${67.2 + frame2.enter * 37.8}vw`
--bridge-scale = 1.02 + sharedHeroScale + frame2.exit * 0.46
--split-left-x = `calc(-50% + ${-splitDrift * 46}vw + ${mouseX * 22}px)`
--split-left-y = `${mouseY * 10 + sharedHeroY - splitDrift * 180}px`
--split-left-scale = 1 + sharedHeroScale + frame2.enter * 0.74
--split-right-x = `calc(-50% + ${ splitDrift * 46}vw + ${mouseX * 22}px)`
--split-right-y = `${mouseY * 10 + sharedHeroY - splitDrift * 180}px`
--split-right-scale = 1 + sharedHeroScale + frame2.enter * 0.74
--frame2-opacity = frame2Opacity
--frame2-x = `calc(-50% + ${mouseX * 10}px)`
--frame2-y = `calc(-50% + ${mouseY * 8 - frame2.exit * 150}px)`
--frame2-scale = 1.06 + frame2.enter * 0.08 + frame2.exit * 0.08
--intro-copy-y = `${introExit * 90}px`
--intro-copy-opacity = 1 - introExit
--panel2-opacity = panel2Opacity
--panel2-y = `calc(-50% + ${-frame2.exit * 86 + (1 - frame2.enter) * 58}px)`
--panel3-opacity = panel3Opacity
--panel3-y = `calc(-50% + ${-frame3.exit * 86 + (1 - frame3.enter) * 58}px)`
--sights-opacity = sightsEnter
--sights-controls-opacity = sightsControlsEnter
sightsControls.classList.toggle("is-ready", sightsControlsEnter > 0.98)
--sights-visibility = sightsEnter > 0.01 ? "visible" : "hidden"
--sights-y = "0px"
--sights-enter-x = `${(1 - sightsEnter) * 420}vw`
--sights-scale = 1 / backScale
--sights-top = `${sightsParentTop}px`
--sights-screen-top = `${sightsScreenTop}px`
```
Re-request a frame while `|smoothScroll - targetScroll| > 0.08` or `|mouseX - targetMouseX| > 0.001` or `|mouseY - targetMouseY| > 0.001`. `requestTick()` guards with `rafPending` and calls `requestAnimationFrame(update)`.
**Listeners**
- `window scroll` → `requestTick`, `{ passive: true }`
- `window resize` → `updateSightSlider(); requestTick();`
- `window pointermove` → `targetMouseX = clientX / innerWidth - 0.5; targetMouseY = clientY / innerHeight - 0.5; requestTick();` `{ passive: true }`
- `.sight-prev` click → `moveSightSlider(-1)`; `.sight-next` click → `moveSightSlider(1)`
- On load: `setupSightSlider(); requestTick();`
---
## 8. Infinite slider logic (exact behavior)
```js
setupSightSlider():
clear .sights-track (replaceChildren)
for setIndex 0..2: // 3 identical sets = 15 cards
for each original card:
clone = card.cloneNode(true)
clone.dataset.sightIndex = setIndex * originalCount + cardIndex
append clone
sightCards = all cloned cards
activeSight = originalCount // start in middle set
per card: click → selectSightCard(card)
keydown Enter or " " → preventDefault, selectSightCard(card)
track transitionend → normalizeSightSlider
updateSightSlider()
updateSightSlider():
cardWidth = sightCards[0].offsetWidth
gap = parseFloat(getComputedStyle(track).columnGap || "0")
--sights-shift = `${-(cardWidth + gap) * activeSight}px`
toggle .is-active on the card whose index === activeSight
moveSightSlider(dir): activeSight += dir; updateSightSlider()
selectSightCard(card): activeSight = Number(card.dataset.sightIndex) (if finite); updateSightSlider()
jumpSightSlider(i): add .is-jumping; activeSight = i; updateSightSlider();
double requestAnimationFrame → remove .is-jumping
normalizeSightSlider(): if activeSight >= originalCount * 2 → jump(activeSight - originalCount)
else if activeSight < originalCount → jump(activeSight + originalCount)
```
---
## 9. Resulting choreography (acceptance criteria)
Scrubbing ~3700px through the sticky stage must produce, in order:
1. **0–650px:** `MOSTAR` rises `-210px` while scaling to `0.92` and fading out; intro paragraph + 3 cream pills sink `+90px` and fade. Sky, back-stack, bridge, and splitframes drift subtly with the pointer the whole time.
2. **560–1620px:** bridge widens `67.2vw → 105vw`, its bottom lifts `5vh → -8vh`, then it launches up `-760px` and scales `+0.46` on exit. The two splitframe halves part symmetrically to ∓`46vw` (eased `enter^1.5`), rise `-180px`, scale `+0.74`. The frame-two river close-up fades in behind them. Global blur ramps to `14px`, brightness drops ~25.5%, and the blue `74,181,224` shade gradient rises to alphas `0.465 / 0.42 / 0.51`. Bridge story panel fades in at `top:60%`, sliding from `+58px` to `-86px`.
3. **1760–2700px:** bazaar layer gains `+0.18` saturation while the bridge panel exits; bazaar story panel fades in at `top:29%` with the same `+58px → -86px` slide and its `Open old town notes` pill.
4. **2760–3560px:** the sights slider flies in from `420vw` on X (`enter^1.55` easing), becoming visible past `0.01`, counter-scaled by `1 / backScale` so cards stay screen-true while the back stack keeps zooming; its top is solved so cards sit at `clamp(innerHeight*0.19, 112, 220) - 50` px on screen.
5. **3360–3660px:** the two round `←` `→` buttons fade in at `left:48px` beneath the cards and become clickable only past `0.98`. Prev/next and card clicks slide the track with the `640ms cubic-bezier(0.22, 1, 0.36, 1)` transition and loop seamlessly via the 3-set clone + instant-jump normalization.
Under `prefers-reduced-motion`, scroll smoothing and pointer parallax are bypassed (values snap, `--mx`/`--my` forced to 0) and layer transitions are disabled — the composition still scrubs, just without inertia.
Intelligent OperationsAgency · free prompt · copy-paste
# Exact recreation prompt — NovaAI landing page
Recreate this page **pixel-faithfully**. Stack: React + TypeScript + Vite + Tailwind CSS + lucide-react. Do not invent alternate copy, layout, fonts, colors, or effects.
---
## Page identity
- **Title:** `NOVA_AI — Today AI Aligns With Bold Dreams`
- **Brand:** lowercase `novaai` with a Lucide `Hexagon` icon (size 24, strokeWidth 1.5) to the left
- **Overall feel:** dark cinematic AI marketing site; full-viewport scroll-scrubbed video background; white typography with drop shadows; frosted glass UI chips; sparse editorial layout; no purple gradients, no cream paper look, no card grids of icons
---
## Assets (use these exact URLs)
**Hero scroll video (CloudFront — required):**
```
https://meez.design/web/media/prompt-media/v/256a995befea43be.mp4
```
Video content: abstract 3D forms (hanging white cables with glowing gold tips → organic white spherical / brain-like folds with warm orange core), soft blue-grey mist / grain background, floating bokeh particles. 1920×1080.
**Optional local mirrors for reliability:** `/hero.mp4` (same file) and `/hero-poster.jpg` (first-frame still). Prefer CloudFront URL in production code; local copy is fine for offline/dev.
**Portrait (“Talk with Mitha”) — exact URL:**
```
https://meez.design/web/media/ext/7c6fb70f3e54bac9.webp
```
Display as `h-24 w-20` (`96×80px`), `rounded-lg`, `object-cover`. Alt: `Mitha, co-founder of NovaAI`.
---
## Fonts
- Load Google Fonts Inter weights **400, 500, 600, 700**
- Body: `font-family: 'Inter', system-ui, sans-serif`
- Tailwind: both `font-sans` and `font-mono` map to Inter (mono labels still use `font-mono` class but render Inter)
- Antialiased text; selection color `rgba(255,255,255,0.2)`
- Page bg: `#0a0a0a`; default text white
---
## Global structure
```
relative root
ScrollVideo (fixed inset-0 z-0, pointer-events-none)
relative z-10 wrapper
Navbar (fixed top)
main
SectionOne (min-h-screen / 100svh)
spacer div h-[80vh] (aria-hidden) ← critical for scroll video length
SectionTwo (min-h-screen / 100svh)
```
Horizontal padding rhythm everywhere: `px-5 sm:px-8 md:px-12`.
Section top padding under fixed nav: `pt-24 sm:pt-28`.
Bottom padding: `pb-12 md:pb-16`.
---
## Scroll-scrubbed video background (exact behavior)
Fixed full-bleed layer `z-0`, bg `#0a0a0a`, `overflow-hidden`, `pointer-events-none`.
**Layers (bottom → top):**
1. Poster `<img>` — full cover; fades out (`opacity-0`, 500ms) once video has a decoded frame or frame cache is ready
2. `<video>` — muted, playsInline, preload=auto, object-cover; visible only while video has a frame and canvas frame-cache is not ready; then fade out
3. `<canvas>` — full cover; draws scrubbed frames; fades in when ready
**Scroll mapping:**
- `progress = scrollY / (scrollHeight - innerHeight)`, clamped 0–1
- Smooth with lerp: `smoothed += (target - smoothed) * 0.12` each `requestAnimationFrame`
- Draw with **object-cover** math (scale max, center crop)
**Frame cache (preferred smooth path):**
- Offscreen video loads same URL
- Extract up to **90** frames (or `duration * 12`, min 24), max width **960px**
- Wait until visible video has `loadeddata` + 300ms yield before extraction starts
- On ready, canvas draws cached `ImageBitmap`s by smoothed progress index
**Fallback:** seek the visible `<video>` to `smoothed * (duration - 0.05)` when frames aren’t ready (seek if delta > 0.04s)
**Canvas DPR:** `min(devicePixelRatio, 2)`
Do **not** autoplay as a normal looping background — motion is **scroll-driven only**.
---
## Reveal animation (every text/UI block)
IntersectionObserver, threshold `0.15`.
Hidden: `translate-y-8 opacity-0`
Visible: `translate-y-0 opacity-100`
Transition: `all 700ms ease-out`, `will-change-transform`
Per-element `transition-delay` in ms as specified below.
---
## Glass / material system (exact tokens)
Reuse these consistently:
| Token | Classes |
|--------|---------|
| Glass panel | `bg-white/15 backdrop-blur-md` (or `bg-white/10` for larger panels) |
| Glass border | `border border-white/15` or `border-white/20` or `border-white/25` |
| Left-accent badge | `border-l-2 border-white bg-white/15 px-3 py-1.5 backdrop-blur-md` + mono uppercase label |
| Primary CTA | solid white pill/rounded, black text, hover `bg-white/85` |
| Secondary CTA | glass border + `bg-white/10` or `bg-white/15`, white text |
| Text over video | white + `drop-shadow-md` / `drop-shadow-lg` |
| Mono labels | `font-mono text-[10px]` or `text-[11px]` or `text-xs`, `uppercase`, `tracking-[0.15em]` |
---
## Navbar (fixed, z-50)
- Full width, `border-b border-white/15`
- Row: logo left | center nav (md+) | CTA right
- Logo: Hexagon + `novaai` (`text-lg sm:text-xl font-medium tracking-tight`)
- Links (hidden below md): `Projects` with superscript `6` (`font-mono text-[10px] text-white/60`), `About`, `Blog`, `Contact` — `text-sm text-white/85`, hover `text-white`, gap `gap-8 lg:gap-10`
- CTA: `Get Free Consultation` — `rounded-md border border-white/20 bg-white/15 backdrop-blur-md px-4 py-2 text-xs sm:px-5 sm:text-sm`, hover `bg-white/25`
- Reveal delays: logo 0; links `100 + i*100` ms; CTA `500` ms
---
## Section One — Hero
Full viewport flex column `justify-between`.
**Top row** (`flex-col gap-8` → `sm:flex-row justify-between`):
**Left — service list** (gap-2), each reveal delay `150 + i*120`:
```
/ AI AUTOMATION
/ AI INTEGRATION
/ AI AGENT DEVELOPMENT
```
Style: `font-mono text-xs uppercase tracking-[0.15em] text-white/90 drop-shadow-md`
**Right — intro** (`max-w-xs sm:text-right`, delay 300):
> We design automation that brings clarity, precision, and efficiency to the way your company operates.
`text-lg sm:text-xl leading-relaxed text-white drop-shadow-md`
**Bottom row** (`flex-col gap-8` → `md:flex-row items-end justify-between`):
**Left:**
1. Badge delay 150: `We Automate 100+ Businesses` — left-accent glass badge, `font-mono text-[11px] uppercase tracking-[0.15em]`, `mb-5`
2. H1 delay 280:
```
Clear. Precise.
Automated.
```
`text-5xl sm:text-6xl lg:text-7xl font-normal leading-[1.05] tracking-tight text-white drop-shadow-lg`
**Right — glass contact card** (delay 420):
- Container: `flex items-center gap-4 rounded-xl bg-white/15 p-3 backdrop-blur-md`
- Image: portrait URL above, `h-24 w-20 rounded-lg object-cover`
- Text column (`gap-1.5 pr-2`):
- `Talk with Mitha` — `text-sm font-medium text-white`
- `Co-founder of NovaAI` — mono `text-[10px] uppercase tracking-[0.15em] text-white/60`
- Button: `Book 15-mins call` + Lucide `ChevronRight` size 14 — `rounded-full bg-white px-4 py-2 text-xs font-medium text-black`, hover `bg-white/85`, `mt-1.5`
---
## Mid spacer
`div` with `h-[80vh]` between sections so scroll progress has room to scrub the video between hero and section two.
---
## Section Two — Capability
Same full-viewport flex `justify-between` shell.
**Top row:**
**Left badge** delay 120: `Insight On Demand` — same left-accent glass badge as hero.
**Right copy** delay 220 (`max-w-sm sm:text-right`):
> Our AI doesn't just respond — it interprets, sharpens, and delivers the signal you need.
`text-lg sm:text-xl leading-relaxed text-white drop-shadow-md`
**Bottom area** (`flex-1 justify-end`, `flex-col gap-12` → `md:flex-row items-end justify-between gap-16`):
**Left column** (`max-w-xl`):
1. H2 delay 180:
```
Learn to see
brilliantly.
```
Same headline scale as H1 (`text-5xl sm:text-6xl lg:text-7xl … drop-shadow-lg`)
2. Body delay 320 (`mt-6 max-w-md text-sm sm:text-base text-white/80 drop-shadow-md`):
> From the first sketch to the final render, Nova turns raw intent into decisions your team can act on — quietly, precisely, at speed.
3. CTAs delay 420 (`mt-8 flex flex-wrap gap-3`):
- Primary pill: `Run the demo` + ChevronRight 14 — `rounded-full bg-white px-5 py-2.5 text-xs sm:text-sm font-medium text-black`, hover `bg-white/85`
- Secondary: `Free consultation` — `rounded-full border border-white/25 bg-white/10 backdrop-blur-md px-5 py-2.5 text-xs sm:text-sm`, hover `bg-white/20`
**Right — frosted capability panel**
`w-full max-w-md rounded-2xl border border-white/15 bg-white/10 backdrop-blur-md px-5 sm:px-6`
Three rows (dividers `border-b border-white/15` except last), each `flex gap-5 py-5`, reveal delay `300 + i*110`:
| # | Title | Body |
|---|--------|------|
| 01 | Real-time vision | Reads context as it happens and surfaces what matters before you ask. |
| 02 | Layered insight | Moves from rough outline to sharp output without losing the thread. |
| 03 | Adaptive speed | Learns your cadence and tightens every pass as you work. |
- Index: `font-mono text-[11px] tracking-[0.15em] text-white/55`
- Title: `text-base sm:text-lg font-medium text-white` + ChevronRight 16 (`text-white/40`, hover: translate-x-0.5 + `text-white`)
- Body: `mt-1.5 text-sm leading-relaxed text-white/70`
---
## Interactions / motion checklist
1. Scroll scrub maps page scroll → video timeline (smoothed)
2. Staggered fade-up reveals on enter viewport (700ms, per-delay)
3. Button / link color transitions `duration-300`
4. Capability chevrons nudge right on hover
5. Poster → video → canvas opacity crossfades `duration-500`
6. No looping autoplay of hero video
---
## Responsive rules
- Nav links hidden below `md`
- Hero/section stacks vertically on mobile; side-by-side from `sm`/`md` as specified
- Prefer `supports-[height:100svh]:min-h-[100svh]` plus `min-h-screen`
- Touch: video `playsInline` + muted
---
## Do not
- Do not replace Inter with another display font
- Do not use a different video URL than the CloudFront URL above
- Do not use the old Pexels portrait
- Do not rebuild section two as icon card stacks
- Do not put opaque solid backgrounds over the video (only glass / transparent wrappers)
- Do not remove the `80vh` spacer
---
## Acceptance
Top of page: fixed glass nav + service list + intro + “Clear. Precise. Automated.” + Mitha glass card over scroll video.
Scrolling scrubbing advances the CloudFront video smoothly.
After spacer: “Insight On Demand” + “Learn to see brilliantly.” + dual CTAs + three-item frosted capability panel.
Visual match to current NovaAI page at `localhost:5199`.
Forecast CenterMobile App · free prompt · copy-paste
Recreate this EXACT weather dashboard UI as a single self-contained HTML page (inline CSS, SVG icon sprite, no frameworks, no JS required). Pixel-faithful to the reference “Aurora Weather / Weather Forecast — Central Jakarta” liquid-glass dashboard.
═══════════════════════════════════════
TITLE / META
═══════════════════════════════════════
- Document title: Weather Forecast — Central Jakarta
- lang="en"
- viewport: width=device-width, initial-scale=1, viewport-fit=cover
- Fallback page bg: #04121b
- Color ink: #ffffff
- Antialiased Inter stack; font-feature-settings: "kern" 1
- html/body: height 100%; overflow hidden on desktop
═══════════════════════════════════════
FONTS (exact families + weights)
═══════════════════════════════════════
Use Inter + Inter Tight (SIL OFL). Preferred load:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Inter+Tight:wght@500&display=swap" rel="stylesheet">
OR embed WOFF2 @font-face for:
- Inter 400, 500, 600, 700
- Inter Tight 500 only
Body font-family:
'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif
Headline (h1) font-family:
'Inter Tight', 'Inter', sans-serif
Weight 500, size calc(63*u), line-height calc(78*u), letter-spacing calc(.25*u)
═══════════════════════════════════════
ASSETS (exact URLs / files)
═══════════════════════════════════════
1) FULL-BLEED BACKGROUND (storm landscape photo, 1600×1200 JPEG):
Local export from original file:
./assets/storm-background.jpg
(Originally embedded as a data:image/jpeg;base64 URI inside CSS.)
Subject: dramatic dark cumulonimbus storm clouds with multiple lightning bolts over a green field; cool teal-green / deep blue-black atmosphere.
CSS:
background-image: url("./assets/storm-background.jpg");
background-size: cover;
background-position: center 25%;
background-repeat: no-repeat;
2) AVATAR PHOTO (only remote image in the original):
https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&h=160&fit=crop&crop=faces&q=80&auto=format
alt="Calfin Danang"
loading="eager" decoding="async"
onerror="this.remove()" (falls back to inline SVG avatar #i-avatar)
Circular crop 52×52 (desktop).
3) NO other remote assets. All icons are inline SVG <symbol>s.
═══════════════════════════════════════
SCALING SYSTEM (critical)
═══════════════════════════════════════
Reference canvas: 1357 × 871 CSS px.
Define:
:root {
--u: min(100vw / 1357, 100dvh / 871);
--ink: #ffffff;
--glass: rgba(255,255,255,.155);
--glass-line: rgba(255,255,255,.20);
--e-out: cubic-bezier(.16,1,.3,1);
--e-soft: cubic-bezier(.22,.61,.36,1);
--e-pen: cubic-bezier(.37,.01,.2,1);
}
@supports not (height: 100dvh) {
:root { --u: min(100vw / 1357, 100vh / 871); }
}
Every size/spacing uses calc(N * var(--u)). Layout is absolute / edge-anchored so there is never a blank band.
═══════════════════════════════════════
LIQUID GLASS LANGUAGE (exact recipes)
═══════════════════════════════════════
Stage vignette (::after on .stage, pointer-events:none):
linear-gradient(105deg, rgba(4,16,24,.34) 0%, rgba(4,16,24,.20) 40%, rgba(4,16,24,.06) 78%, transparent 100%),
linear-gradient(180deg, rgba(4,16,24,.12) 0%, transparent 22%),
linear-gradient(0deg, rgba(4,16,24,.07), rgba(4,16,24,.07));
SIDEBAR glass:
background: linear-gradient(180deg,
rgba(255,255,255,.125) 0%,
rgba(255,255,255,.135) 13%,
rgba(255,255,255,.098) 34%,
rgba(255,255,255,.092) 100%);
backdrop-filter: blur(calc(18*var(--u))) saturate(115%);
-webkit-backdrop-filter: same;
border-radius: calc(26*var(--u));
TOOL BUTTONS / CHIP glass:
background: rgba(255,255,255,.15) /* tools */ / rgba(255,255,255,.175) /* chip */
backdrop-filter: blur(calc(16*var(--u))) saturate(115%);
tools: circle 52×52; chip: pill height 36, radius 18, padding-x 15
RIGHT RAIL CARDS glass (the main “liquid glass” panels):
background: linear-gradient(180deg,
rgba(255,255,255,.20) 0%,
rgba(255,255,255,.258) 24%,
rgba(255,255,255,.252) 78%,
rgba(255,255,255,.232) 100%);
backdrop-filter: blur(calc(26*var(--u))) saturate(118%);
border-radius: calc(24*var(--u)) /* big card: 26 */
Specular sheen coda (cards + chip):
::after width 38%, gradient
linear-gradient(100deg, transparent 0%, rgba(255,255,255,.17) 50%, transparent 100%);
skewX(-18deg); animation sheen 1.15s var(--e-soft) 2.55s 1 both;
@keyframes sheen { from { transform: translate3d(-150%,0,0) skewX(-18deg) }
to { transform: translate3d(260%,0,0) skewX(-18deg) } }
Do NOT use opaque white cards, heavy drop shadows, or purple gradients. Glass must feel frosted over the storm photo.
═══════════════════════════════════════
LAYOUT STRUCTURE (desktop absolute positions)
═══════════════════════════════════════
.stage { position:fixed; inset:0; overflow:hidden; }
1) LEFT SIDEBAR (.sidebar)
left:16u top:14u bottom:7u width:72u
flex column, align center
padding-top:22u padding-bottom:52u
- Active white pip: left:-2u top:131u width:5u height:29u radius:3u
box-shadow: 0 0 10u rgba(255,255,255,.55)
- Logo SVG 40×40 (wave-circle mark, rounded square rx=12, white stroke waves)
- Nav: margin-top 57.5u, gap 43u, icons 23×23 white
Links aria-labels: Dashboard (aria-current=page), Reports, Explore regions, Calendar, Settings
- Logout at bottom: Sign out
2) HEADER (.header)
top:22u left:126u right:37u height:52u
Left:
"Welcome" — 16u / weight 400 / color rgba(255,255,255,.93)
"Calfin Danang" — 19.5u / weight 700 / letter-spacing -0.35u / margin-top 13u
Right tools gap 16u: Add location (+), Search, Notifications, avatar
3) HERO (.hero)
left:126u top:136u max-width:560u
Chip text EXACTLY: Weather Forecast
H1 EXACT spelling (keep the typo):
line1: "Strom"
line2: "with Heavy Rain"
Each line wrapped as <span class="ln"><span>…</span></span> for mask reveal
Blurb EXACT copy (with soft line breaks as in original):
"Partly cloudy with occasional snow showers. High around 50°F.
Wind from the east 11 to 21 mph. Snow chance is 40%, with
rainfall expected to be less than an inch."
Blurb: width 480u, 15.2u / lh 24u / weight 500 / tracking -0.3u / color rgba(255,255,255,.95)
4) FORECAST STRIP (.forecast)
left:126u right:396u bottom:99u
Hourly/daily temps row (space-between):
11° cloud | 13° cloud2 | 14° cloud2 | 10° hail | 19° sun | 12° cloud
Temp type: 37u weight 400 tracking -0.7u
SVG wave chart viewBox="0 0 835 230" preserveAspectRatio="none"
height 230u, margin-top 43u, width 100%
Fill path + 3 stroked outline paths (stroke-width 6.2@opacity.17, 4.6@.26, 3.4@1)
Stroke uses horizontal white opacity gradient #wg
Fill uses #wf + vertical fade mask #wfade + clipPath #wclip / #wclipr for wipe-in
Use pathLength="1" + stroke-dasharray:1 for drawLine animation
Exact cubic path (start M0,79 … end L835,86 then fill closes to bottom)
Days under chart (margin-top -31u):
Sunday Monday Tuesday Wednesday(on/active weight 600) Thursday Friday
Font 18u weight 500 color rgba(255,255,255,.88); .on = #fff weight 600
5) RIGHT RAIL (.rail)
right:38u top:134u bottom:95u width:310u
flex column gap 20u
Card A (.card.big):
Central Jakarta + pin icon
10° C (big-temp 92u weight 500 tracking -4.4u; “C” in <i>)
metrics: 19 mph (wind) | 40% (drop) | 15km/h (gust)
Card B (.card.row height 120u):
Indonesia / North Jakarta / Mostly Sunny | 12° cloud
Card C:
Indonesia / Bandung / Cloudy | 10° cloud
Card D:
Indonesia / South Jakarta / Sunny | 14° cloud2
═══════════════════════════════════════
ICON SPRITE (inline SVG symbols, white/currentColor)
═══════════════════════════════════════
Implement exact symbols: i-grid, i-chart, i-globe, i-cal, i-gear, i-out,
i-plus, i-search, i-bell, i-pin, i-wind, i-drop, i-gust,
i-cloud, i-cloud2, i-hail, i-sun, i-avatar (vector fallback portrait).
Logo: circular clip with 7 horizontal wavy polyline strokes + soft square.
═══════════════════════════════════════
ENTRY CHOREOGRAPHY (must match timings)
═══════════════════════════════════════
Keyframes:
- riseIn: opacity 0 → 1, translateY(var(--ry,14px)) → none
- slideL: from -26px X
- slideR: from +30px X + scale(.985)
- popIn: scale .7 → 1
- growY: scaleY 0 → 1 (pip)
- lineUp: translateY(115%) → none (headline mask)
- wipeDown / wipeRight (clip-path)
- drawLine: stroke-dashoffset 1 → 0
- wipeX: scaleX 0 → 1 on #wclipr (fill follows pen)
- sheen: as above
Beat timing (animation-fill-mode: both):
1. Sidebar slideL .92s delay .05s; logo popIn .70s @.26s;
nav items riseIn .60s delays .36/.41/.46/.51/.56s; logout @.70s; pip growY .50s @.68s
2. hello riseIn .70s @.14s; who .80s @.22s;
tools popIn .58s delays .30/.365/.43/.495s
3. chip wipeRight .80s @.44s;
h1 line1 lineUp 1.05s @.56s; line2 @.67s;
blurb wipeDown .90s @.90s (--e-soft)
4. cards slideR .95s delays .80/.92/1.03/1.14s;
place/big-temp/metrics + row children staggered ~1.04–1.36s
5. temps riseIn delays 1.26…1.61s step ~.07s
6. Signature: .wline drawLine 1.60s --e-pen @1.50s;
#wclipr wipeX 1.42s --e-pen @1.72s (fill ~220ms behind pen)
7. days riseIn from 2.10s step .055s
8. Coda sheen @2.55s
prefers-reduced-motion: reduce → kill all animations/transitions; hide sheen ::after; show chart fully drawn.
Mobile ≤860px: reflow to single scrolling column; --u: min(100vw/430, 1.22px);
sidebar becomes fixed bottom dock height 64u; cards/forecast order change; pip hidden;
sidebar/cards use riseIn instead of slideL/slideR.
≤420px: --u: calc(100vw / 430).
═══════════════════════════════════════
INTERACTION MICROSTATES
═══════════════════════════════════════
.nav a:hover → opacity 1 + translateY(-1u)
.tool:hover → background rgba(255,255,255,.24)
:focus-visible → 2u white outline, offset 2u
═══════════════════════════════════════
HARD CONSTRAINTS
═══════════════════════════════════════
- Keep the typo “Strom” (not Storm).
- Keep all copy, temps, cities, metrics exactly as listed.
- Absolute desktop composition on the 1357×871 unit grid — not a generic CSS Grid dashboard.
- Liquid glass via backdrop-filter + translucent white gradients + final specular sheen — not solid frosted panels.
- Chart must DRAW itself (stroke dash) then FILL wipe left→right.
- No purple theme, no Inter-default marketing look-alikes beyond the specified Inter/Inter Tight, no card shadows stacks, no emoji.
- Single HTML file preferred; background may be external file at ./assets/storm-background.jpg and avatar at the Unsplash URL above.
```
```
---
**Asset notes**
- **Background:** not a public CDN URL in the original — it was a ~238KB embedded JPEG. Use `./assets/storm-background.jpg` (exported from this project) or re-embed the same data URI.
- **Avatar:**
`https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&h=160&fit=crop&crop=faces&q=80&auto=format`
- **Fonts:** Google Fonts Inter 400–700 + Inter Tight 500, or the embedded WOFF2s already in `index.html`.
From the library
AI for Business Design System
Amplemarket Design System
Claude Design System
Air Design System
Airbnb Design System
Titan Design System
Factory.ai Design System
Base44 Design System
Geniestudio Design System
Perplexity AI Design System
Slash Design System
Revenue-Grade Automation Design System
Vercel Design System
Clarity Core
Neural Interface
3D Story
404 Planet
SaaS Value
Luxury Focus
Synthesis
Neon Logic
Yoga Coach
Glitch Pulse
Golden Portal
Investment Gate
Health Portal
Digital Experiences
Apex Pulse
Financial Suite
Cinematic Landing Page
Creative Agency
Investor Deck
Browse & preview free Unlock everything — from $19/mo
Frequently asked questions
Do Meez prompts work with Claude?
Yes. Every Meez prompt is a complete written spec — fonts, layout, color tokens, motion and asset URLs — so Claude can build it in one paste. The 32 free prompts on this site work exactly like the premium ones; copy one above and try it.
What does Claude generate from a prompt?
Claude Code (Anthropic's terminal agent) is stack-agnostic and unusually faithful to long structured specs — it will follow a 3,000-character art-direction brief to the letter across as many files as the build needs, which makes it the strongest fit for pasting a complete Meez prompt in one go.
How do I use a Meez prompt in Claude?
Copy the full prompt text and paste it into Claude, or the Claude Code terminal. Don't shorten it — the specificity is what keeps Claude from producing a generic layout. Then iterate: swap the copy and point the asset URLs at your own media.
How many prompts are free?
32 prompts are free to copy in full, no account needed. The other 495 unlock with Unlimited — $19/mo, $99/yr, or $199 once for lifetime — along with all 198 motion backgrounds.
Also for: Lovable · Bolt · v0 · Cursor · Replit · Windsurf · Framer · Webflow · ChatGPT · Figma Make · Gemini · GitHub Copilot · Wix
Not sure which tool? Lovable vs v0 vs Bolt vs Cursor, compared → · All free prompts on one page → · All prompt categories →