The Velvet Note Vintage Jazz Bar

One-tap Chinese-English switching, a typewriter-style booking form with key sounds, and six photos spinning on a 3D vinyl disc — matte black with gold and burgundy.

Loading preview...
Start from this prompt

A Chinese-English bilingual, front-end-only one-pager for the vintage jazz bar The Velvet Note, built with React and GSAP in matte black with gold and burgundy, Lenis smooth scrolling, and lineup, menu and reservations on one scrolling page.

Switch to a craft beer bar

Swaps the venue from a jazz bar to a craft beer bar and the lineup for a signature tap list (IPA / Stout / Tripel); colors and animations stay.

Try Kimi Build
Build me a vintage jazz bar immersive experience website named "The Velvet Note", with Chinese-English bilingual switching (Chinese and English only, no other languages). It is a pure front-end single-page app with no backend.

## 1. Tech stack

- React 19 + TypeScript + Vite 7
- react-router v7 (BrowserRouter)
- Tailwind CSS 3.4 + tailwindcss-animate plugin
- GSAP 3.14 (with ScrollTrigger and Observer plugins)
- @studio-freight/lenis (smooth scrolling, lerp:0.1, smoothWheel:true)
- shadcn/ui (Radix UI + class-variance-authority)
- lucide-react icon library

## 2. Color system

| Name | Value | Usage |
|------|-----|------|
| Matte black | #0a0a0a | Global background, Hero overlay, Footer |
| Light grey-white | #e0e0e0 | Body text, headings |
| Gold | #d4af37 | Brand color, nav hover, heading highlight, button borders, SVG strokes |
| Wine red / burgundy | #4a0e16 | Lineup text, card hover overlay rgba(74,14,22,0.6) |
| Parchment | #f0e6d2 | Lineup section background |
| Dark grey line | #333333 | Default input underline, language menu border |
| Dim grey | #1a1a1a | Menu hover background, Footer divider, vinyl record texture |
| CSS variable primary | hsl(43,65%,52%) | Gold |
| CSS variable secondary | hsl(350,70%,18%) | Wine red |

## 3. Type system

| Class | font-family | Weights | Usage |
|-----|------------|------|------|
| font-display | 'Playfair Display', serif | 400-900 incl. italic | All headings, brand name |
| font-body | 'Inter', sans-serif | 300-700 | Body, nav, forms |
| font-mono | 'Courier Prime', monospace | 400/700 | Time labels, "Est.1957", copyright |

## 4. i18n implementation

Use React Context (LanguageContext), no i18n library:
- Language type: 'en' | 'zh'
- t(key) supports nested dot keys like 'lineup.musician1.name'

### Translation content
- hero.title: "The Velvet Note" ↔ "丝绒音符"
- hero.subtitle: "A journey through sound and time" ↔ "一场穿越声音与时光的私密旅程"
- nav: Lineup/Story/Reservations/Gallery ↔ 演出阵容/我们的故事/预订/画廊
- Three musicians: Marcus Cole, sax, 21:00 / Elena Voss, vocals, 22:45 / James Parker, double bass, 00:30
- story.title: "Our Story" ↔ "我们的故事"
- reservations.title: "Reserve Your Seat" ↔ "预订您的座位"
- gallery: "Gallery" ↔ "画廊"

## 5. Film grain effect (FilmGrain)

- fixed full-screen overlay, z-index:9999, pointer-events:none
- opacity: 0.04, mix-blend-mode: overlay
- SVG feTurbulence: type="fractalNoise" baseFrequency="0.85" numOctaves="4" stitchTiles="stitch"
- inline data URI background image

## 6. Section-by-section design

### 6.1 Navbar
- fixed, z-[100], mix-blend-mode: difference (blends inverted against the background)
- after scrolling past 80px: rgba(10,10,10,0.92) + blur(12px), otherwise transparent
- Logo SVG: 4 concentric circles (r=14/10/6/2), all gold #d4af37, rotate-180 500ms on hover
- "TVN" beside it in Playfair Display text-lg tracking-wide
- Nav links: uppercase, letter-spacing:0.1em, font-size:0.8rem, #e0e0e0
- Hover underline: ::after expands from the center, h:1px bg:#d4af37, 0.3s ease

### 6.2 Hero
- h-screen, video background /videos/hero.mp4, autoPlay muted loop playsInline
- Vignette overlay: radial-gradient(circle at center, transparent 0%, #0a0a0a 120%)
- Loading overlay: pure black #0a0a0a, GSAP opacity 1→0, 2s power2.out delay 0.5
- Title: Playfair Display, fontSize clamp(3rem,8vw,7rem), letterSpacing -0.02em, textShadow 0 4px 30px rgba(0,0,0,0.8)
  - GSAP: opacity 0→1 + y 40→0, 1.5s power3.out (starts at '-=1' of the overlay animation)
- Subtitle: Inter 1rem, letterSpacing 0.2em, uppercase, textShadow 0 2px 15px
  - GSAP: opacity 0→1 + y 20→0, 1s power3.out ('-=0.8')
- Scroll indicator: "Scroll" text-xs + gold arrow SVG stroke:#d4af37 strokeWidth:1.5, animate-pulse + bounce

### 6.3 Lineup
- Background #f0e6d2 (parchment)
- Dynamic typography layer z-[100] pointer-events-none: three big lines clamp(2rem,8vw,6rem) Playfair Display uppercase
  - Line 1 "TONIGHT" / "今晚": solid #4a0e16
  - Line 2 "'S": outline hollow -webkit-text-stroke:2px #4a0e16, color:transparent
  - Line 3 "LINEUP" / "演出": solid #4a0e16
  - GSAP scrub: line 1 xPercent 0→-100, line 2 yPercent 0→100, line 3 xPercent 0→100
- Background thumbnails: 3-column grid grayscale opacity-30, GSAP scrub yPercent 0→20
- Musician cards z-[50], md:grid-cols-3:
  - Image aspect-[3/4] grayscale; hover removes grayscale + scale-105 700ms
  - Name Playfair Display 2xl #4a0e16
  - Instrument Inter sm uppercase tracking-widest
  - Time Courier Prime sm
  - GSAP entrance: opacity 0→1 + y 60→0, 0.8s, stagger 0.15, power3.out, start 'top 80%'

### 6.4 Story
- Background #0a0a0a
- Gold Playfair Display heading clamp(2.5rem,6vw,5rem) centered
- Two columns lg:flex-row: left image aspect-[16/10] + bottom gradient; right three paragraphs text-lg
- Bottom decorative line w-12 h-[1px] #d4af37 + "Est. 1957" Courier Prime
- GSAP: image x:-60→0 1.2s power3.out; paragraphs y:40→0 0.8s stagger 0.2

### 6.5 Reservations
- Background #4a0e16 (wine red)
- Typewriter-style inputs .analog-input: transparent background + 2px #333 bottom underline, turns #d4af37 on focus
- Floating labels .analog-label: gold uppercase, rotateX(-90deg) flips away on focus, 0.4s cubic-bezier(0.2,1,0.3,1)
- 4 fields: name / email / date / party size (1-8)
- Submit button: bg-#0a0a0a text-#d4af37 border-#d4af37, inverted on hover, 500ms
- Typing sound: Web Audio API 20ms decaying white noise, gain:0.08
- GSAP: .form-element opacity+y:30→0, 0.6s stagger 0.1

### 6.6 Gallery — 3D vinyl carousel
- 100vh, background #0a0a0a
- 6 images: The Crowd / The Bar / Vinyl / The Stage / The Keys / The Quartet
- 3D circular layout: perspective:1000px, radius=min(w,h)*0.32
  - Evenly spread over 360°, GSAP.set x=sin(angle)*r, z=cos(angle)*r-r, rotateY=angle
  - Active item: .decks__img opacity 0→1 + scale 0.5→1, 0.5s
- Interaction: GSAP Observer wheel/touch, deltaY*0.002 incremental rotation
- Vinyl record style: border-radius:50%, repeating-radial-gradient(#1a1a1a 4px, #000 5px), border 8px #0a0a0a
- Scroll hint: spinning gold SVG 3s + "Scroll to browse"

### 6.7 Footer
- bg-#0a0a0a, border-t #222
- Three columns: brand (SVG Logo + "The Velvet Note" + opening hours) / Location (address) / Follow (Instagram/Facebook/Twitter)
- Social white/50, gold on hover 300ms
- Copyright Courier Prime #e0e0e0/30

## 7. Static assets

### Images (/public/images/) — 10 total
- bar-interior.jpg (16:10 bar interior)
- musician-1/2/3.jpg (3:4 musicians)
- gallery-1~6.jpg (circle-cropped gallery)

### Videos (/public/videos/)
- hero.mp4 — jazz bar atmosphere (dark, full-screen loop)

## 8. Lenis smooth scrolling
- lerp:0.1, smoothWheel:true
- lenis.on('scroll', ScrollTrigger.update)
- gsap.ticker.add drives RAF
- gsap.ticker.lagSmoothing(0)

## 9. Key animation parameters

| Effect | Parameters |
|------|------|
| Loading overlay fade-out | opacity 1→0, 2s power2.out delay 0.5 |
| Hero title entrance | opacity+y:40→0, 1.5s power3.out ('-=1') |
| Hero subtitle entrance | opacity+y:20→0, 1s power3.out ('-=0.8') |
| Lineup typography line 1 | xPercent 0→-100, scrub |
| Lineup typography line 2 | yPercent 0→100, scrub |
| Lineup typography line 3 | xPercent 0→100, scrub |
| Lineup thumbnails | yPercent 0→20, scrub |
| Musician card entrance | opacity+y:60→0, 0.8s stagger 0.15, power3.out |
| Story image | x:-60→0, 1.2s power3.out |
| Story text | y:40→0, 0.8s stagger 0.2 |
| Reservation form elements | opacity+y:30→0, 0.6s stagger 0.1 |
| Gallery active item | opacity+scale 0.5→1, 0.5s |
| Nav logo hover | rotate-180, 500ms |
| Nav underline | width 0→100%, 0.3s ease |
| Button hover | bg/text invert, 500ms |
Add online reservations

Adds a time-slot picker to the existing booking form, with a confirmation card showing a booking reference after submit.

Try Kimi Build
Build me a vintage jazz bar immersive experience website named "The Velvet Note", with Chinese-English bilingual switching (Chinese and English only, no other languages). It is a pure front-end single-page app with no backend.

## 1. Tech stack

- React 19 + TypeScript + Vite 7
- react-router v7 (BrowserRouter)
- Tailwind CSS 3.4 + tailwindcss-animate plugin
- GSAP 3.14 (with ScrollTrigger and Observer plugins)
- @studio-freight/lenis (smooth scrolling, lerp:0.1, smoothWheel:true)
- shadcn/ui (Radix UI + class-variance-authority)
- lucide-react icon library

## 2. Color system

| Name | Value | Usage |
|------|-----|------|
| Matte black | #0a0a0a | Global background, Hero overlay, Footer |
| Light grey-white | #e0e0e0 | Body text, headings |
| Gold | #d4af37 | Brand color, nav hover, heading highlight, button borders, SVG strokes |
| Wine red / burgundy | #4a0e16 | Lineup text, card hover overlay rgba(74,14,22,0.6) |
| Parchment | #f0e6d2 | Lineup section background |
| Dark grey line | #333333 | Default input underline, language menu border |
| Dim grey | #1a1a1a | Menu hover background, Footer divider, vinyl record texture |
| CSS variable primary | hsl(43,65%,52%) | Gold |
| CSS variable secondary | hsl(350,70%,18%) | Wine red |

## 3. Type system

| Class | font-family | Weights | Usage |
|-----|------------|------|------|
| font-display | 'Playfair Display', serif | 400-900 incl. italic | All headings, brand name |
| font-body | 'Inter', sans-serif | 300-700 | Body, nav, forms |
| font-mono | 'Courier Prime', monospace | 400/700 | Time labels, "Est.1957", copyright |

## 4. i18n implementation

Use React Context (LanguageContext), no i18n library:
- Language type: 'en' | 'zh'
- t(key) supports nested dot keys like 'lineup.musician1.name'

### Translation content
- hero.title: "The Velvet Note" ↔ "丝绒音符"
- hero.subtitle: "A journey through sound and time" ↔ "一场穿越声音与时光的私密旅程"
- nav: Lineup/Story/Reservations/Gallery ↔ 演出阵容/我们的故事/预订/画廊
- Three musicians: Marcus Cole, sax, 21:00 / Elena Voss, vocals, 22:45 / James Parker, double bass, 00:30
- story.title: "Our Story" ↔ "我们的故事"
- reservations.title: "Reserve Your Seat" ↔ "预订您的座位"
- gallery: "Gallery" ↔ "画廊"

## 5. Film grain effect (FilmGrain)

- fixed full-screen overlay, z-index:9999, pointer-events:none
- opacity: 0.04, mix-blend-mode: overlay
- SVG feTurbulence: type="fractalNoise" baseFrequency="0.85" numOctaves="4" stitchTiles="stitch"
- inline data URI background image

## 6. Section-by-section design

### 6.1 Navbar
- fixed, z-[100], mix-blend-mode: difference (blends inverted against the background)
- after scrolling past 80px: rgba(10,10,10,0.92) + blur(12px), otherwise transparent
- Logo SVG: 4 concentric circles (r=14/10/6/2), all gold #d4af37, rotate-180 500ms on hover
- "TVN" beside it in Playfair Display text-lg tracking-wide
- Nav links: uppercase, letter-spacing:0.1em, font-size:0.8rem, #e0e0e0
- Hover underline: ::after expands from the center, h:1px bg:#d4af37, 0.3s ease

### 6.2 Hero
- h-screen, video background /videos/hero.mp4, autoPlay muted loop playsInline
- Vignette overlay: radial-gradient(circle at center, transparent 0%, #0a0a0a 120%)
- Loading overlay: pure black #0a0a0a, GSAP opacity 1→0, 2s power2.out delay 0.5
- Title: Playfair Display, fontSize clamp(3rem,8vw,7rem), letterSpacing -0.02em, textShadow 0 4px 30px rgba(0,0,0,0.8)
  - GSAP: opacity 0→1 + y 40→0, 1.5s power3.out (starts at '-=1' of the overlay animation)
- Subtitle: Inter 1rem, letterSpacing 0.2em, uppercase, textShadow 0 2px 15px
  - GSAP: opacity 0→1 + y 20→0, 1s power3.out ('-=0.8')
- Scroll indicator: "Scroll" text-xs + gold arrow SVG stroke:#d4af37 strokeWidth:1.5, animate-pulse + bounce

### 6.3 Lineup
- Background #f0e6d2 (parchment)
- Dynamic typography layer z-[100] pointer-events-none: three big lines clamp(2rem,8vw,6rem) Playfair Display uppercase
  - Line 1 "TONIGHT" / "今晚": solid #4a0e16
  - Line 2 "'S": outline hollow -webkit-text-stroke:2px #4a0e16, color:transparent
  - Line 3 "LINEUP" / "演出": solid #4a0e16
  - GSAP scrub: line 1 xPercent 0→-100, line 2 yPercent 0→100, line 3 xPercent 0→100
- Background thumbnails: 3-column grid grayscale opacity-30, GSAP scrub yPercent 0→20
- Musician cards z-[50], md:grid-cols-3:
  - Image aspect-[3/4] grayscale; hover removes grayscale + scale-105 700ms
  - Name Playfair Display 2xl #4a0e16
  - Instrument Inter sm uppercase tracking-widest
  - Time Courier Prime sm
  - GSAP entrance: opacity 0→1 + y 60→0, 0.8s, stagger 0.15, power3.out, start 'top 80%'

### 6.4 Story
- Background #0a0a0a
- Gold Playfair Display heading clamp(2.5rem,6vw,5rem) centered
- Two columns lg:flex-row: left image aspect-[16/10] + bottom gradient; right three paragraphs text-lg
- Bottom decorative line w-12 h-[1px] #d4af37 + "Est. 1957" Courier Prime
- GSAP: image x:-60→0 1.2s power3.out; paragraphs y:40→0 0.8s stagger 0.2

### 6.5 Reservations
- Background #4a0e16 (wine red)
- Typewriter-style inputs .analog-input: transparent background + 2px #333 bottom underline, turns #d4af37 on focus
- Floating labels .analog-label: gold uppercase, rotateX(-90deg) flips away on focus, 0.4s cubic-bezier(0.2,1,0.3,1)
- 4 fields: name / email / date / party size (1-8)
- Submit button: bg-#0a0a0a text-#d4af37 border-#d4af37, inverted on hover, 500ms
- Typing sound: Web Audio API 20ms decaying white noise, gain:0.08
- GSAP: .form-element opacity+y:30→0, 0.6s stagger 0.1

### 6.6 Gallery — 3D vinyl carousel
- 100vh, background #0a0a0a
- 6 images: The Crowd / The Bar / Vinyl / The Stage / The Keys / The Quartet
- 3D circular layout: perspective:1000px, radius=min(w,h)*0.32
  - Evenly spread over 360°, GSAP.set x=sin(angle)*r, z=cos(angle)*r-r, rotateY=angle
  - Active item: .decks__img opacity 0→1 + scale 0.5→1, 0.5s
- Interaction: GSAP Observer wheel/touch, deltaY*0.002 incremental rotation
- Vinyl record style: border-radius:50%, repeating-radial-gradient(#1a1a1a 4px, #000 5px), border 8px #0a0a0a
- Scroll hint: spinning gold SVG 3s + "Scroll to browse"

### 6.7 Footer
- bg-#0a0a0a, border-t #222
- Three columns: brand (SVG Logo + "The Velvet Note" + opening hours) / Location (address) / Follow (Instagram/Facebook/Twitter)
- Social white/50, gold on hover 300ms
- Copyright Courier Prime #e0e0e0/30

## 7. Static assets

### Images (/public/images/) — 10 total
- bar-interior.jpg (16:10 bar interior)
- musician-1/2/3.jpg (3:4 musicians)
- gallery-1~6.jpg (circle-cropped gallery)

### Videos (/public/videos/)
- hero.mp4 — jazz bar atmosphere (dark, full-screen loop)

## 8. Lenis smooth scrolling
- lerp:0.1, smoothWheel:true
- lenis.on('scroll', ScrollTrigger.update)
- gsap.ticker.add drives RAF
- gsap.ticker.lagSmoothing(0)

## 9. Key animation parameters

| Effect | Parameters |
|------|------|
| Loading overlay fade-out | opacity 1→0, 2s power2.out delay 0.5 |
| Hero title entrance | opacity+y:40→0, 1.5s power3.out ('-=1') |
| Hero subtitle entrance | opacity+y:20→0, 1s power3.out ('-=0.8') |
| Lineup typography line 1 | xPercent 0→-100, scrub |
| Lineup typography line 2 | yPercent 0→100, scrub |
| Lineup typography line 3 | xPercent 0→100, scrub |
| Lineup thumbnails | yPercent 0→20, scrub |
| Musician card entrance | opacity+y:60→0, 0.8s stagger 0.15, power3.out |
| Story image | x:-60→0, 1.2s power3.out |
| Story text | y:40→0, 0.8s stagger 0.2 |
| Reservation form elements | opacity+y:30→0, 0.6s stagger 0.1 |
| Gallery active item | opacity+scale 0.5→1, 0.5s |
| Nav logo hover | rotate-180, 500ms |
| Nav underline | width 0→100%, 0.3s ease |
| Button hover | bg/text invert, 500ms |
Swap the hero for live footage

Replaces the hero video background with live footage from a jazz bar — gold neon and close-ups of the musicians.

Try Kimi Build
Build me a vintage jazz bar immersive experience website named "The Velvet Note", with Chinese-English bilingual switching (Chinese and English only, no other languages). It is a pure front-end single-page app with no backend.

## 1. Tech stack

- React 19 + TypeScript + Vite 7
- react-router v7 (BrowserRouter)
- Tailwind CSS 3.4 + tailwindcss-animate plugin
- GSAP 3.14 (with ScrollTrigger and Observer plugins)
- @studio-freight/lenis (smooth scrolling, lerp:0.1, smoothWheel:true)
- shadcn/ui (Radix UI + class-variance-authority)
- lucide-react icon library

## 2. Color system

| Name | Value | Usage |
|------|-----|------|
| Matte black | #0a0a0a | Global background, Hero overlay, Footer |
| Light grey-white | #e0e0e0 | Body text, headings |
| Gold | #d4af37 | Brand color, nav hover, heading highlight, button borders, SVG strokes |
| Wine red / burgundy | #4a0e16 | Lineup text, card hover overlay rgba(74,14,22,0.6) |
| Parchment | #f0e6d2 | Lineup section background |
| Dark grey line | #333333 | Default input underline, language menu border |
| Dim grey | #1a1a1a | Menu hover background, Footer divider, vinyl record texture |
| CSS variable primary | hsl(43,65%,52%) | Gold |
| CSS variable secondary | hsl(350,70%,18%) | Wine red |

## 3. Type system

| Class | font-family | Weights | Usage |
|-----|------------|------|------|
| font-display | 'Playfair Display', serif | 400-900 incl. italic | All headings, brand name |
| font-body | 'Inter', sans-serif | 300-700 | Body, nav, forms |
| font-mono | 'Courier Prime', monospace | 400/700 | Time labels, "Est.1957", copyright |

## 4. i18n implementation

Use React Context (LanguageContext), no i18n library:
- Language type: 'en' | 'zh'
- t(key) supports nested dot keys like 'lineup.musician1.name'

### Translation content
- hero.title: "The Velvet Note" ↔ "丝绒音符"
- hero.subtitle: "A journey through sound and time" ↔ "一场穿越声音与时光的私密旅程"
- nav: Lineup/Story/Reservations/Gallery ↔ 演出阵容/我们的故事/预订/画廊
- Three musicians: Marcus Cole, sax, 21:00 / Elena Voss, vocals, 22:45 / James Parker, double bass, 00:30
- story.title: "Our Story" ↔ "我们的故事"
- reservations.title: "Reserve Your Seat" ↔ "预订您的座位"
- gallery: "Gallery" ↔ "画廊"

## 5. Film grain effect (FilmGrain)

- fixed full-screen overlay, z-index:9999, pointer-events:none
- opacity: 0.04, mix-blend-mode: overlay
- SVG feTurbulence: type="fractalNoise" baseFrequency="0.85" numOctaves="4" stitchTiles="stitch"
- inline data URI background image

## 6. Section-by-section design

### 6.1 Navbar
- fixed, z-[100], mix-blend-mode: difference (blends inverted against the background)
- after scrolling past 80px: rgba(10,10,10,0.92) + blur(12px), otherwise transparent
- Logo SVG: 4 concentric circles (r=14/10/6/2), all gold #d4af37, rotate-180 500ms on hover
- "TVN" beside it in Playfair Display text-lg tracking-wide
- Nav links: uppercase, letter-spacing:0.1em, font-size:0.8rem, #e0e0e0
- Hover underline: ::after expands from the center, h:1px bg:#d4af37, 0.3s ease

### 6.2 Hero
- h-screen, video background /videos/hero.mp4, autoPlay muted loop playsInline
- Vignette overlay: radial-gradient(circle at center, transparent 0%, #0a0a0a 120%)
- Loading overlay: pure black #0a0a0a, GSAP opacity 1→0, 2s power2.out delay 0.5
- Title: Playfair Display, fontSize clamp(3rem,8vw,7rem), letterSpacing -0.02em, textShadow 0 4px 30px rgba(0,0,0,0.8)
  - GSAP: opacity 0→1 + y 40→0, 1.5s power3.out (starts at '-=1' of the overlay animation)
- Subtitle: Inter 1rem, letterSpacing 0.2em, uppercase, textShadow 0 2px 15px
  - GSAP: opacity 0→1 + y 20→0, 1s power3.out ('-=0.8')
- Scroll indicator: "Scroll" text-xs + gold arrow SVG stroke:#d4af37 strokeWidth:1.5, animate-pulse + bounce

### 6.3 Lineup
- Background #f0e6d2 (parchment)
- Dynamic typography layer z-[100] pointer-events-none: three big lines clamp(2rem,8vw,6rem) Playfair Display uppercase
  - Line 1 "TONIGHT" / "今晚": solid #4a0e16
  - Line 2 "'S": outline hollow -webkit-text-stroke:2px #4a0e16, color:transparent
  - Line 3 "LINEUP" / "演出": solid #4a0e16
  - GSAP scrub: line 1 xPercent 0→-100, line 2 yPercent 0→100, line 3 xPercent 0→100
- Background thumbnails: 3-column grid grayscale opacity-30, GSAP scrub yPercent 0→20
- Musician cards z-[50], md:grid-cols-3:
  - Image aspect-[3/4] grayscale; hover removes grayscale + scale-105 700ms
  - Name Playfair Display 2xl #4a0e16
  - Instrument Inter sm uppercase tracking-widest
  - Time Courier Prime sm
  - GSAP entrance: opacity 0→1 + y 60→0, 0.8s, stagger 0.15, power3.out, start 'top 80%'

### 6.4 Story
- Background #0a0a0a
- Gold Playfair Display heading clamp(2.5rem,6vw,5rem) centered
- Two columns lg:flex-row: left image aspect-[16/10] + bottom gradient; right three paragraphs text-lg
- Bottom decorative line w-12 h-[1px] #d4af37 + "Est. 1957" Courier Prime
- GSAP: image x:-60→0 1.2s power3.out; paragraphs y:40→0 0.8s stagger 0.2

### 6.5 Reservations
- Background #4a0e16 (wine red)
- Typewriter-style inputs .analog-input: transparent background + 2px #333 bottom underline, turns #d4af37 on focus
- Floating labels .analog-label: gold uppercase, rotateX(-90deg) flips away on focus, 0.4s cubic-bezier(0.2,1,0.3,1)
- 4 fields: name / email / date / party size (1-8)
- Submit button: bg-#0a0a0a text-#d4af37 border-#d4af37, inverted on hover, 500ms
- Typing sound: Web Audio API 20ms decaying white noise, gain:0.08
- GSAP: .form-element opacity+y:30→0, 0.6s stagger 0.1

### 6.6 Gallery — 3D vinyl carousel
- 100vh, background #0a0a0a
- 6 images: The Crowd / The Bar / Vinyl / The Stage / The Keys / The Quartet
- 3D circular layout: perspective:1000px, radius=min(w,h)*0.32
  - Evenly spread over 360°, GSAP.set x=sin(angle)*r, z=cos(angle)*r-r, rotateY=angle
  - Active item: .decks__img opacity 0→1 + scale 0.5→1, 0.5s
- Interaction: GSAP Observer wheel/touch, deltaY*0.002 incremental rotation
- Vinyl record style: border-radius:50%, repeating-radial-gradient(#1a1a1a 4px, #000 5px), border 8px #0a0a0a
- Scroll hint: spinning gold SVG 3s + "Scroll to browse"

### 6.7 Footer
- bg-#0a0a0a, border-t #222
- Three columns: brand (SVG Logo + "The Velvet Note" + opening hours) / Location (address) / Follow (Instagram/Facebook/Twitter)
- Social white/50, gold on hover 300ms
- Copyright Courier Prime #e0e0e0/30

## 7. Static assets

### Images (/public/images/) — 10 total
- bar-interior.jpg (16:10 bar interior)
- musician-1/2/3.jpg (3:4 musicians)
- gallery-1~6.jpg (circle-cropped gallery)

### Videos (/public/videos/)
- hero.mp4 — jazz bar atmosphere (dark, full-screen loop)

## 8. Lenis smooth scrolling
- lerp:0.1, smoothWheel:true
- lenis.on('scroll', ScrollTrigger.update)
- gsap.ticker.add drives RAF
- gsap.ticker.lagSmoothing(0)

## 9. Key animation parameters

| Effect | Parameters |
|------|------|
| Loading overlay fade-out | opacity 1→0, 2s power2.out delay 0.5 |
| Hero title entrance | opacity+y:40→0, 1.5s power3.out ('-=1') |
| Hero subtitle entrance | opacity+y:20→0, 1s power3.out ('-=0.8') |
| Lineup typography line 1 | xPercent 0→-100, scrub |
| Lineup typography line 2 | yPercent 0→100, scrub |
| Lineup typography line 3 | xPercent 0→100, scrub |
| Lineup thumbnails | yPercent 0→20, scrub |
| Musician card entrance | opacity+y:60→0, 0.8s stagger 0.15, power3.out |
| Story image | x:-60→0, 1.2s power3.out |
| Story text | y:40→0, 0.8s stagger 0.2 |
| Reservation form elements | opacity+y:30→0, 0.6s stagger 0.1 |
| Gallery active item | opacity+scale 0.5→1, 0.5s |
| Nav logo hover | rotate-180, 500ms |
| Nav underline | width 0→100%, 0.3s ease |
| Button hover | bg/text invert, 500ms |