Free
🏢 Agency

Outlast

Dark two-screen studio landing in React, Tailwind and Framer Motion: liquid-glass nav, badge, stat cards and capability cards with masked gradient strokes, a word-by-word blur-in Instrument Serif headline, and cinematic background films whose loop seams fade in and out.

1.4k views 435 copies 1.9k mots

Le prompt

# Outlast — Liquid Glass Studio Landing

## Prompt

Build a single-page React + Vite + TypeScript + Tailwind CSS site with exactly two full-screen sections (Hero and Capabilities). The page is a dark, cinematic web design agency landing page with "liquid glass" morphism UI elements and smooth blur/fade animations using Framer Motion.

---

### Fonts (Google Fonts)

Load via `<link>` in `index.html`:
- **Instrument Serif** (italic) -- used for all headings (`font-heading`)
- **Barlow** (weights 300, 400, 500, 600) -- used for body text (`font-body`)

Tailwind config extends `fontFamily`:
```js
heading: ["'Instrument Serif'", 'serif'],
body: ["'Barlow'", 'sans-serif'],
```

Base CSS: `html, body { background: #000; color: #fff; font-family: 'Barlow', sans-serif; }`

---

### Liquid Glass CSS (in index.css)

Two variants defined as plain CSS classes:

**`.liquid-glass`** (subtle):
- `background: rgba(255, 255, 255, 0.01)` with `background-blend-mode: luminosity`
- `backdrop-filter: blur(4px)` / `-webkit-backdrop-filter: blur(4px)`
- No border; `box-shadow: inset 0 1px 1px rgba(255,255,255,0.1)`
- `position: relative; overflow: hidden`
- `::before` pseudo-element creates a gradient stroke border:
- `position: absolute; inset: 0; border-radius: inherit; padding: 1.4px`
- `background: linear-gradient(180deg, rgba(255,255,255,0.45) 0%, rgba(255,255,255,0.15) 20%, rgba(255,255,255,0) 40%, rgba(255,255,255,0) 60%, rgba(255,255,255,0.15) 80%, rgba(255,255,255,0.45) 100%)`
- Masked with `-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude;`
- `pointer-events: none`

**`.liquid-glass-strong`** (bolder):
- Same structure but `backdrop-filter: blur(50px)`
- `box-shadow: 4px 4px 4px rgba(0,0,0,0.05), inset 0 1px 1px rgba(255,255,255,0.15)`
- `::before` gradient uses 0.5 alpha at edges, 0.2 at 20%/80%

---

### FadingVideo Component

A reusable `<video>` component accepting `src` (string or string[]), `className`, and `style`. It:
1. Starts with `opacity: 0`
2. On `loadeddata`, fades in over 500ms using `requestAnimationFrame`
3. On `timeupdate`, when remaining time <= 0.55s, fades out over 550ms
4. On `ended`, if single source: resets `currentTime` to 0, replays, fades back in. If array: advances to next index (cycling).
5. Video is `autoPlay`, `muted`, `playsInline`, `preload="auto"`

---

### BlurText Component

A word-by-word staggered blur-in animation component using Framer Motion:
- Splits `text` prop by spaces
- Each word is a `motion.span` with `display: inline-block`, `marginRight: 0.28em`
- Triggers on IntersectionObserver (threshold 0.1)
- Each word animates: `filter` from `blur(10px)` to `blur(0px)`, `opacity` 0 to 1, `y` from 50 to 0
- Duration 0.7s per word, stagger delay of 100ms per word index
- Container uses `display: flex; flexWrap: wrap; justifyContent: center; rowGap: 0.1em`

---

### Section 1: Hero

- Full viewport height (`h-screen`), `overflow-hidden`, `bg-black`
- **Background video**: Single `<FadingVideo>` with:
- `src="https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260619_191346_9d19d66e-86a4-47f7-8dc6-712c1788c3b2.mp4"`
- Positioned: `absolute left-1/2 top-0 -translate-x-1/2 object-cover object-top z-0`
- Inline style: `width: 120%; height: 120%`

- **Content** (`relative z-10, flex flex-col h-full`):

**Navbar** (fixed, `top-4 left-0 right-0 z-50`, flex between, `px-8 lg:px-16`):
- Left: `liquid-glass` circle (h-12 w-12 rounded-full) with italic "a" in `font-heading text-2xl`
- Center (hidden on mobile, `md:flex`): `liquid-glass rounded-full px-1.5 py-1.5` pill containing links ["Work", "Studio", "Services", "Journal", "Contact"] as `px-3 py-2 text-sm font-medium text-white/90 font-body` + a white CTA button "Start a Project" with ArrowUpRight icon
- Right: empty `h-12 w-12` spacer div

**Main content** (centered, `flex-1 flex flex-col items-center justify-center pt-24 px-4 text-center`):
- **Badge** (motion.div, delay 0.4): `liquid-glass rounded-full` pill with a white "New" badge inside + text "Booking Q3 2026 engagements -- limited capacity"
- **Headline** (mt-6, max-w-3xl): `<BlurText>` with text "Crafted Digital Experiences Built to Outlast Trends", classes: `text-6xl md:text-7xl lg:text-[5.5rem] font-heading italic text-white leading-[0.8] tracking-[-4px]`
- **Subtext** (motion.p, delay 0.8, mt-4): "We are a small studio of designers and engineers shaping brand-defining websites for ambitious companies. Precise typography, cinematic motion, and code you can be proud of." -- `text-sm md:text-base text-white max-w-2xl font-body font-light leading-tight`
- **CTA buttons** (motion.div, delay 1.1, mt-6, flex gap-6): "Start a Project" in `liquid-glass-strong rounded-full px-5 py-2.5` with ArrowUpRight + "Watch Showreel" plain text with Play icon
- **Stats cards** (motion.div, delay 1.3, mt-8, flex gap-4): Two `liquid-glass p-5 w-[220px] rounded-[1.25rem]` cards:
- Card 1: ClockIcon, "6 Weeks", "Average End-to-End Launch Time"
- Card 2: GlobeIcon, "140+", "Brands Shipped Across Four Continents"
- Numbers: `text-4xl font-heading italic tracking-[-1px] leading-none mt-4`

**Bottom trust bar** (motion.div, delay 1.4, flex-col items-center gap-4 pb-8):
- `liquid-glass rounded-full` pill: "Trusted by founders, operators, and creative directors worldwide"
- Logo names in a flex row (gap-12 md:gap-16): ["Aeon", "Vela", "Apex", "Orbit", "Zeno"] each as `font-heading italic text-2xl md:text-3xl tracking-tight`

- **All motion elements** use shared initial/animate: `{ filter: 'blur(10px)', opacity: 0, y: 20 }` -> `{ filter: 'blur(0px)', opacity: 1, y: 0 }`, duration 0.8s, easeOut

---

### Section 2: Capabilities

- `min-h-screen`, `overflow-hidden`, `bg-black`, relative
- **Background video**: `<FadingVideo>` with:
- `src="https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260622_093722_ccfc7ebf-182f-419f-8a62-2dc02db7dd9d.mp4"`
- `absolute inset-0 w-full h-full object-cover z-0`

- **Content** (`relative z-10 px-8 md:px-16 lg:px-20 pt-24 pb-10 flex flex-col min-h-screen`):
- **Header** (mb-auto):
- Label: `text-sm font-body text-white/80 mb-6` -- "// Capabilities"
- Heading: `font-heading italic text-6xl md:text-7xl lg:text-[6rem] leading-[0.9] tracking-[-3px]` -- "Studio craft,\nend to end"

- **Cards grid** (mt-16, `grid grid-cols-1 md:grid-cols-3 gap-6`), three cards:
1. **Design** -- Icon: ImageIcon (filled image icon), Tags: ["Brand Systems", "Art Direction", "Visual Identity", "Motion"], Body: "We shape identities and interfaces that feel unmistakably yours -- typographic systems, component libraries, and art-directed pages that scale without losing soul."
2. **Engineering** -- Icon: MovieIcon (film/clapboard), Tags: ["React", "Next.js", "Headless CMS", "Edge-Ready"], Body: "Production-grade front-ends built on modern stacks. Performant, accessible, and instrumented -- with code your team will enjoy extending long after launch."
3. **Growth** -- Icon: LightbulbIcon, Tags: ["SEO", "Analytics", "A/B Testing", "Retention"], Body: "Launch is the starting line. We partner with your team on conversion, content, and iteration loops that turn a beautiful site into a compounding asset."

- Each card: `liquid-glass rounded-[1.25rem] p-6 min-h-[360px] flex flex-col`
- Top row: icon in a nested `liquid-glass h-11 w-11 rounded-[0.75rem]` square + tags (flex-wrap, gap-1.5) right-aligned, each tag is `liquid-glass rounded-full px-3 py-1 text-[11px] text-white/90 font-body whitespace-nowrap`
- Spacer: `flex-1`
- Bottom: title in `font-heading italic text-3xl md:text-4xl tracking-[-1px] leading-none` + body in `text-sm text-white/90 font-body font-light leading-snug max-w-[32ch]`

---

### Custom SVG Icons (no external icon library needed for these)

- **ArrowUpRight**: 24x24, stroke, paths "M7 17L17 7" and "M7 7h10v10"
- **Play**: 24x24, filled polygon "6 4 20 12 6 20 6 4"
- **ClockIcon**: 24x24, stroke (1.5), circle r=9 + "M12 7v5l3 2"
- **GlobeIcon**: 24x24, stroke (1.5), circle r=9 + horizontal line + two arc paths
- **ImageIcon**: 24x24, filled Material-style image icon
- **MovieIcon**: 24x24, filled Material-style movie icon
- **LightbulbIcon**: 24x24, filled Material-style bulb icon

---

### Dependencies

- react, react-dom
- framer-motion
- tailwindcss, postcss, autoprefixer
- vite, @vitejs/plugin-react
- typescript

---

### Key Design Principles

- Everything is on a pure black (#000) background
- All text is white; subtle text uses `white/80` or `white/90`
- Liquid glass elements have near-invisible fills with gradient-stroke borders via CSS masks
- Videos cover sections as atmospheric backgrounds, fading in/out smoothly
- Typography: heading font is always italic with very tight tracking (negative), body font is light weight
- Responsive: nav links hidden on mobile, grid collapses to single column, text sizes scale with breakpoints
- Animations: staggered blur-in on load for hero content, intersection-triggered for BlurText

## Quality Bar

- **The spec'd styles land as written.** Driven in headless Chrome 153, `.liquid-glass` computes to `blur(4px)`, `rgba(255,255,255,0.01)`, `luminosity`, `inset 0 1px 1px rgba(255,255,255,.1)`; its `::before` to `padding:1.4px`, the 0.45/0.15 gradient and `mask-composite: exclude`. `.liquid-glass-strong` computes to `blur(50px)`, the two-part shadow and the 0.5/0.2 gradient. Instrument Serif italic 400 and Barlow 300/400/500 are the faces that load (600 is declared but nothing uses it). There are no console errors, and both videos are `autoplay muted playsInline preload="auto"` with no `loop`.
- **The gradient stroke needs a declaration the spec leaves out.** The `::before` list has no `content`, and a pseudo-element without `content` is never generated — the 1.4px stroke, which is the whole "liquid glass" look, would not exist. This build adds `content: ""`.
- **Scrolling into Capabilities makes the navbar unclickable.** The fixed nav sits inside the hero's `relative z-10` wrapper, which forms its own stacking context. Capabilities' content wrapper is also `relative z-10` and comes later in the DOM, so it stacks above the entire hero context — nav included. Hit-testing at 1440×900 with the page scrolled to Capabilities, the centre of the "Studio" link and of the "a" logo both return the Capabilities content `div`, not the link. On a 390×844 phone, with the second card scrolled to y=60, the logo's centre hits the card grid. The nav is still visible, but it can't be clicked, and on phones the cards paint over it as they scroll past.
- **The hero's content is taller than many screens, and `h-screen overflow-hidden` cuts it off.** At 1440×900 the column fits exactly (trust bar bottom = hero bottom). At **1280×720** the trust bar ends **144px** below the hero and is clipped along with the lower half of the stat cards. At 360×640 it ends **207px** below, with the headline on four lines. The site's own 1200×750 card thumbnail shows the cut.
- **The stat row cannot fit a phone.** Two fixed `w-[220px]` cards plus `gap-4` are 456px in a row that never wraps. At 390×844 it spans **x=−33 to 423**, and at 360×640 from **−48**, so both cards lose their outer edges ("6 Weeks" is cut). At 360px the logo row is 383px wide and also clips "Aeon" and "Zeno".
- **The loop seam never reaches black.** Fade-out is triggered from `timeupdate`, which Chrome fires roughly every 250ms, so it starts with **0.44s and 0.32s** left on two measured loops. That is less than its own 550ms duration: opacity was still **0.18 and 0.40** when the video wrapped to 0, then climbed back to 1 over 517ms. The seam the component exists to hide stays visible, and how badly varies from loop to loop.
- **The below-the-fold film downloads and plays at load.** `preload="auto"` plus `autoPlay` on the Capabilities video meant that 4.5s after load both videos were fully buffered (8.04s) and playing (currentTime ≈ 4.3), while that section was a full screen away. With the CloudFront files the prompt names, that is **5,737,760 B** (a 3828×2164 hero) plus **15,369,135 B** (1920×1080 at 15.3 Mbps) before the user scrolls. This demo serves re-encoded copies from `./assets`, because the site's demo pages make no external requests: hero 2560 wide at CRF 26 (**1,096,343 B**) and Capabilities at CRF 28 (**2,744,596 B**). Fonts are self-hosted too, from the same Google Latin files the `<link>` would load (~15.6 KB each).
- **Reduced motion is ignored.** Framer Motion does not honour `prefers-reduced-motion` unless told to, and the spec doesn't tell it. With `reduce` emulated, 900ms after load the badge was still at `blur(2.84px)` and opacity 0.72; the per-word headline blur and the video fades run regardless.
- **The type settings strain at the small end.** `tracking-[-4px]` is a fixed pixel value: −0.045em at 88px, but −0.067em at the 60px mobile size. With `leading-[0.8]`, the four-line headline at 360px has descenders touching the line below. At `md` (768px) the three capability cards are **197px** wide; every card's tags stack four rows deep, and the cards grow past `min-h-[360px]` to 370px.
- **Where the spec leaves choices, this build makes them.** "--" in the badge and card copy is set as an em dash (—). "Studio craft,\nend to end" breaks with `<br />`. `BlurText` takes an `as` prop so the hero headline is an `h1` (the spec never names a tag, which would leave the page without one); the Capabilities heading is an `h2`. The white nav CTA's padding, the "New" chip, the stat label style (`text-sm font-light text-white/80`), icon sizes (16px arrows, 24px stat icons, 20px card icons) and the `mt-3` between card title and body are not specified and are filled in here. Every link points to `#top`, since the spec gives no destinations.

Vous aimerez aussi

Verified DR - Verified Domain Rating for buildpromptkit.comBuildPromptKit - AI prompts that ship real UI — every one has a live demo | Product HuntBuildPromptKit — AI Website & App Prompts - Featured on YizhanFeatured on saasfame.comFeatured on Twelve Tools