Build a "CTA + Footer" section component for a React + Vite + Tailwind CSS project. This is a cinematic full-width call-to-action section with an HLS video background, centered text, two CTA buttons, and a minimal footer bar at the bottom. Black background, white text, liquid glassmorphism effects. --- ### FONTS (import in index.css or HTML head) ``` https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Barlow:wght@300;400;500;600&display=swap ``` - Headings: `Instrument Serif` italic -- Tailwind class `font-heading` - Body: `Barlow` -- Tailwind class `font-body` Add to `tailwind.config.ts` under `theme.extend.fontFamily`: ```js heading: ["'Instrument Serif'", "serif"], body: ["'Barlow'", "sans-serif"], ``` Base styles in `index.css`: ```css body { font-family: 'Barlow', sans-serif; background: #000; color: #fff; } h1, h2, h3 { font-family: 'Instrument Serif', serif;…
View original source ↗.webp)
Prompt
Build a "CTA + Footer" section component for a React + Vite + Tailwind CSS project. This is a cinematic full-width call-to-action section with an HLS video background, centered text, two CTA buttons, and a minimal footer bar at the bottom. Black background, white text, liquid glassmorphism effects.
---
### FONTS (import in index.css or HTML head)
```
https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Barlow:wght@300;400;500;600&display=swap
```
- Headings: `Instrument Serif` italic -- Tailwind class `font-heading`
- Body: `Barlow` -- Tailwind class `font-body`
Add to `tailwind.config.ts` under `theme.extend.fontFamily`:
```js
heading: ["'Instrument Serif'", "serif"],
body: ["'Barlow'", "sans-serif"],
```
Base styles in `index.css`:
```css
body {
font-family: 'Barlow', sans-serif;
background: #000;
color: #fff;
}
h1, h2, h3 {
font-family: 'Instrument Serif', serif;
}
```
---
### LIQUID GLASS CSS (add to index.css inside `@layer components`)
```css
@layer components {
.liquid-glass-strong {
background: rgba(255, 255, 255, 0.01);
background-blend-mode: luminosity;
backdrop-filter: blur(50px);
-webkit-backdrop-filter: blur(50px);
border: none;
box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.05),
inset 0 1px 1px rgba(255, 255, 255, 0.15);
position: relative;
overflow: hidden;
}
.liquid-glass-strong::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1.4px;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0.5) 0%,
rgba(255, 255, 255, 0.2) 20%,
rgba(255, 255, 255, 0) 40%,
rgba(255, 255, 255, 0) 60%,
rgba(255, 255, 255, 0.2) 80%,
rgba(255, 255, 255, 0.5) 100%
);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
}
```
The `::before` pseudo-element uses a mask-composite trick to render a thin glowing gradient border that fades out in the middle of each side.
---
### DEPENDENCIES
```
npm install lucide-react hls.js
```
- `ArrowUpRight` icon from `lucide-react`
- `hls.js` for streaming the Mux HLS video
---
### HLS VIDEO URL (Mux)
```
https://stream.mux.com/8wrHPCX2dC3msyYU9ObwqNdm00u3ViXvOSHUMRYSEe5Q.m3u8
```
This is an HLS stream that requires `hls.js` to play in non-Safari browsers. Safari supports HLS natively via `<video>`.
---
### EXACT COMPONENT CODE
```tsx
import { useEffect, useRef } from "react";
import { ArrowUpRight } from "lucide-react";
import Hls from "hls.js";
const CtaFooter = () => {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const video = videoRef.current;
if (!video) return;
const src = "https://stream.mux.com/8wrHPCX2dC3msyYU9ObwqNdm00u3ViXvOSHUMRYSEe5Q.m3u8";
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(src);
hls.attachMedia(video);
return () => hls.destroy();
} else if (video.canPlayType("application/vnd.apple.mpegurl")) {
video.src = src;
}
}, []);
return (
<section className="relative py-32 px-6 md:px-16 lg:px-24 text-center overflow-hidden">
{/* Background HLS Video */}
<video
ref={videoRef}
autoPlay
loop
muted
playsInline
className="absolute inset-0 w-full h-full object-cover z-0"
/>
{/* Top fade */}
<div
className="absolute top-0 left-0 right-0 z-[1] pointer-events-none"
style={{ height: '200px', background: 'linear-gradient(to bottom, black, transparent)' }}
/>
{/* Bottom fade */}
<div
className="absolute bottom-0 left-0 right-0 z-[1] pointer-events-none"
style={{ height: '200px', background: 'linear-gradient(to top, black, transparent)' }}
/>
{/* Content */}
<div className="relative z-10">
<h2 className="text-5xl md:text-6xl lg:text-7xl font-heading italic text-white tracking-tight leading-[0.85] max-w-3xl mx-auto mb-4">
Your next website starts here.
</h2>
<p className="text-white/60 font-body font-light text-sm md:text-base max-w-xl mx-auto mb-8">
Book a free strategy call. See what AI‑powered design can do. No commitment, no pressure. Just possibilities.
</p>
<div className="flex items-center justify-center gap-6">
<button className="liquid-glass-strong rounded-full px-6 py-3 text-sm font-medium text-white flex items-center gap-2 hover:bg-white/10 transition-all font-body">
Book a Call
<ArrowUpRight className="h-5 w-5" />
</button>
<button className="bg-white text-black rounded-full px-6 py-3 text-sm font-medium flex items-center gap-2 hover:bg-white/90 transition-colors font-body">
View Pricing
<ArrowUpRight className="h-4 w-4" />
</button>
</div>
{/* Footer */}
<div className="mt-32 pt-8 border-t border-white/10 flex flex-col md:flex-row items-center justify-between gap-4">
<p className="text-white/40 font-body font-light text-xs">
© 2026 Studio. All rights reserved.
</p>
<div className="flex items-center gap-6">
{["Privacy", "Terms", "Contact"].map((link) => (
<a key={link} href="#" className="text-white/40 hover:text-white/70 font-body font-light text-xs transition-colors">
{link}
</a>
))}
</div>
</div>
</div>
</section>
);
};
export default CtaFooter;
```
---
### SECTION STRUCTURE BREAKDOWN
```
<section> (relative, py-32, px-6 md:px-16 lg:px-24, text-center, overflow-hidden)
|
+-- <video> (absolute inset-0, full cover, z-0, autoPlay loop muted playsInline)
|
+-- Top gradient fade (absolute top-0, 200px tall, black->transparent, z-[1])
+-- Bottom gradient fade (absolute bottom-0, 200px tall, transparent<-black, z-[1])
|
+-- Content wrapper (relative z-10)
|
+-- <h2> heading
+-- <p> subtext
+-- Button row (flex, centered, gap-6)
| +-- "Book a Call" (liquid-glass-strong, rounded-full)
| +-- "View Pricing" (bg-white text-black, rounded-full)
|
+-- Footer bar (mt-32, border-t border-white/10)
+-- Copyright (left)
+-- Links: Privacy, Terms, Contact (right)
```
---
### HLS VIDEO SETUP PATTERN
The `useEffect` hook initializes `hls.js` for non-Safari browsers and falls back to native HLS for Safari:
1. Check `Hls.isSupported()` -- if true, create an `Hls` instance, load the `.m3u8` source, attach to the `<video>` element
2. If not supported but the browser can play `application/vnd.apple.mpegurl` (Safari), set `video.src` directly
3. Cleanup: `hls.destroy()` on unmount
The `<video>` element uses `autoPlay loop muted playsInline` -- all four attributes are required for autoplay to work across browsers (especially mobile).
---
### VIDEO OVERLAY FADE PATTERN
Two absolutely positioned `<div>` elements create black gradient fades at the top and bottom edges, making the video blend seamlessly into the surrounding black background:
- **Top fade**: `height: 200px`, `background: linear-gradient(to bottom, black, transparent)`, `z-[1]`, `pointer-events-none`
- **Bottom fade**: `height: 200px`, `background: linear-gradient(to top, black, transparent)`, `z-[1]`, `pointer-events-none`
Content sits at `z-10` above both the video and the fades.
---
### RESPONSIVE BEHAVIOR
| Breakpoint | Heading size | Padding | Footer layout |
|---|---|---|---|
| Mobile (default) | `text-5xl` | `px-6` | Stacked column (`flex-col`) |
| Tablet (`md:`) | `text-6xl` | `px-16` | Horizontal row (`md:flex-row`) |
| Desktop (`lg:`) | `text-7xl` | `px-24` | Horizontal row |
- Button row always horizontal (`flex items-center justify-center gap-6`), buttons stack naturally if viewport is very narrow
- Footer: `flex-col md:flex-row` -- copyright and links stack on mobile, sit side-by-side on tablet+
- Subtext constrained to `max-w-xl mx-auto`
- Heading constrained to `max-w-3xl mx-auto`
---
### TYPOGRAPHY DETAILS
| Element | Classes |
|---|---|
| Heading | `text-5xl md:text-6xl lg:text-7xl font-heading italic text-white tracking-tight leading-[0.85] max-w-3xl mx-auto mb-4` |
| Subtext | `text-white/60 font-body font-light text-sm md:text-base max-w-xl mx-auto mb-8` |
| Glass button text | `text-sm font-medium text-white font-body` |
| Solid button text | `text-sm font-medium` (inherits `text-black` from `bg-white text-black`) |
| Copyright | `text-white/40 font-body font-light text-xs` |
| Footer links | `text-white/40 hover:text-white/70 font-body font-light text-xs transition-colors` |
---
### BUTTON DETAILS
**Primary CTA ("Book a Call"):**
`liquid-glass-strong rounded-full px-6 py-3 text-sm font-medium text-white flex items-center gap-2 hover:bg-white/10 transition-all font-body`
- Glass background with gradient border via `::before`
- `ArrowUpRight` icon at `h-5 w-5`
**Secondary CTA ("View Pricing"):**
`bg-white text-black rounded-full px-6 py-3 text-sm font-medium flex items-center gap-2 hover:bg-white/90 transition-colors font-body`
- Solid white background, black text
- `ArrowUpRight` icon at `h-4 w-4` (slightly smaller than the primary)
---
### EXACT TEXT CONTENT
**Heading**: "Your next website starts here."
**Subtext**: "Book a free strategy call. See what AI-powered design can do. No commitment, no pressure. Just possibilities."
**Button 1**: "Book a Call"
**Button 2**: "View Pricing"
**Copyright**: "(c) 2026 Studio. All rights reserved."
**Footer links**: "Privacy", "Terms", "Contact"
---
### PARENT CONTEXT
This section sits on a `bg-black` parent container as the last section of the page. The top gradient fade blends the video into the section above (which also has a black background). The footer bar is part of this same component -- there is no separate footer component.Reusable method
Key decisions
Check whether information hierarchy, module order, and CTA clarity all hold in the final result.
Adapt it to your subject
Extract “target result → the product name, audience, page modules, and primary button → constraints” as a reusable template for similar work.
Where it breaks
Run single-variable comparisons around module order, value proposition, and CTA placement. Record the model, cost, and failures; turn it into a Skill only after it repeats reliably.
Recommended models
Derived Skill
Skills are derived from repeated patterns in published cases. They are not a separate submission type.
Creator
MotionSites focuses on production-ready AI interfaces and is active on MotionSites. “Modern Agency” is the current representative case, built with 待补充模型 with its stability retest open to votes.
Keep exploring
A webpage case by @Oluwaphilemon1 using Claude Fable 5 · Three.js · Blender · GSAP, including the public result, full prompt, and original source.
Prompt
Claude Fable 5 and GPT-5.6 are powerful🥵🥵🥵 Here Is How I built with Claude 👇 Prompt: "Design an agency site where services are presented as supermarket product packaging in 3D" Use Three.js with WebGL to render al
// components/ui/3d-pin.tsx "use client"; import React, { useState } from "react"; import { motion } from "motion/react"; import { cn } from "@/lib/utils"; export const PinContainer = ({ children, title, href, className, containerClassName, }: { children: React.ReactNode; title?: string; href?: string; className?: string; containerClassName?: string; }) => { const [transform, setTransform] = useState( "translate(-50%,-50%) rotateX(0deg)" ); const onMouseEnter = () => { setTransform("translate(-50%,-50%) rotateX(40deg) scale(0.8)"); }; const onMouseLeave = () => { setTransform("translate(-50%,-50%) rotateX(0deg) scale(1)"); }; return ( <a className={cn( "relative group/pin z-50 cursor-pointer", containerClassName )} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} href={href || "/"} > <div style={{ perspective: "1000px", transform: "rotateX(70deg) translateZ(0deg)", }} className="…
Prompt
// components/ui/3d-pin.tsx "use client"; import React, { useState } from "react"; import { motion } from "motion/react"; import { cn } from "@/lib/utils"; export const PinContainer = ({ children, title, href, className, containerClassName…
.webp)
Build a single full-viewport hero section in React + TypeScript + Vite + Tailwind CSS, using `lucide-react` for icons. The component is a character-figurine carousel called "TOONHUB". **Fonts (load in `index.html` head):** ```html <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=Anton&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" /> ``` Body font: `'Inter', sans-serif`. Display font (huge ghost text + bottom-right link): `'Anton', sans-serif`. **Image data (4 items, exact URLs and colors):** ```ts const IMAGES = [ { src: 'https://fifth-gentle-45902158.figma.site/_components/v2/4de492f6d9cf8244ad5293233e5c6f52407d42fc/1.02464a56.png', bg: '#F4845F', panel: '#F79B7F' }, { src: 'https://fifth-gentle-45902158.figma.site/_components/v2/4d…
Prompt
Build a single full-viewport hero section in React + TypeScript + Vite + Tailwind CSS, using `lucide-react` for icons. The component is a character-figurine carousel called "TOONHUB". **Fonts (load in `index.html` head):** ```html <link re…