npx claudepluginhub sacredvoid/skillkit --plugin skillkitThis skill is limited to using the following tools:
Build agency-quality hero sections and landing pages with cinematic video backgrounds, liquid glass morphism, and editorial typography. This skill encodes the patterns, CSS techniques, and design system extracted from 20 pixel-perfect design prompts and the Viktor Oddy methodology.
Builds complete frontend pages with React/Next.js, Tailwind, cinematic animations, AI-generated media assets, persuasive copy, and generative art for landing pages, marketing sites, and dashboards.
Designs agency-grade UIs with premium fonts, spatial rhythm, soft depth, and fluid microinteractions for landing pages, portfolios, and SaaS apps.
Generates production-quality React and Next.js UI components and full pages using Tailwind CSS and Framer Motion for hero sections, SaaS dashboards, pricing pages, bento grids, forms, cards, and animated elements.
Share bugs, ideas, or general feedback.
Build agency-quality hero sections and landing pages with cinematic video backgrounds, liquid glass morphism, and editorial typography. This skill encodes the patterns, CSS techniques, and design system extracted from 20 pixel-perfect design prompts and the Viktor Oddy methodology.
"AI will not replace you, but designers who use AI will replace those who don't."
The difference between generic AI output and premium results is prompt specificity. Generic prompts produce template-looking sites. Detailed prompts with exact fonts, sizes, colors, spacing, and effects produce agency-quality work.
The formula:
| Display Font | Body Font | Vibe |
|---|---|---|
| Instrument Serif (italic) | Inter / Barlow / Geist | Editorial, Apple-like |
| General Sans | Inter | Web3, Modern |
| Rubik (bold, uppercase) | Rubik (regular) | Industrial, Bold |
| Poppins + Source Serif 4 | Poppins | Botanical, Refined |
| Instrument Sans | Instrument Serif (italic accent) | SaaS, Clean |
Rule: Display font for headlines (big, dramatic). Body font for nav, descriptions, buttons. One italic serif accent word inside a sans-serif headline creates instant editorial feel.
Pure Black (most common):
--background: #000000;
--foreground: #ffffff;
--muted: #888888 or hsl(0 0% 65%);
Deep Navy:
--background: hsl(201 100% 13%); /* or hsl(260 87% 3%) */
--foreground: #ffffff;
Dark Purple:
--background: #070612;
--primary: #7b39fc;
--secondary: #2b2344;
This is THE signature effect. Two tiers - subtle and strong.
/* Tier 1: Subtle liquid glass */
.liquid-glass {
background: rgba(255, 255, 255, 0.01);
background-blend-mode: luminosity;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
border: none;
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}
.liquid-glass::before {
content: '';
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%);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
/* Tier 2: Strong liquid glass (for CTAs, panels) */
.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;
}
Direct MP4 (simplest):
<video
autoPlay loop muted playsInline
className="absolute inset-0 w-full h-full object-cover z-0"
src="VIDEO_URL"
/>
HLS Streaming (for Mux URLs):
import Hls from "hls.js";
useEffect(() => {
const video = videoRef.current;
if (!video) return;
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(hlsUrl);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
video.play().catch(() => {});
});
return () => hls.destroy();
} else if (video.canPlayType("application/vnd.apple.mpegurl")) {
video.src = hlsUrl;
video.addEventListener("loadedmetadata", () => video.play().catch(() => {}));
}
}, []);
Video with fade-in/out loop (manual):
Use requestAnimationFrame to read currentTime and duration. Fade opacity 0->1 over 0.5s at start, 1->0 over 0.5s before end. On ended, reset and replay.
Video fade overlays (top + bottom blend to background):
<div className="absolute inset-0 bg-gradient-to-b from-background via-transparent to-background" />
For taller sections, use two separate 200px-tall gradients at top and bottom.
Every section gets a small pill badge above the heading:
<span className="liquid-glass rounded-full px-3.5 py-1 text-xs font-medium text-white inline-block mb-4">
Badge Text
</span>
<h2 className="text-4xl md:text-5xl lg:text-6xl font-heading italic text-white tracking-tight leading-[0.9]">
Heading Text
</h2>
Staggered fade-rise using Framer Motion:
@keyframes fade-rise {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-rise { animation: fade-rise 0.8s ease-out both; }
.animate-fade-rise-delay { animation: fade-rise 0.8s ease-out 0.2s both; }
.animate-fade-rise-delay-2 { animation: fade-rise 0.8s ease-out 0.4s both; }
Or with motion/react:
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.15, duration: 0.6 }}
Splits heading by words. Each word animates via IntersectionObserver:
Infinite horizontal scroll of partner logos:
@keyframes marquee {
0% { transform: translateX(0%); }
100% { transform: translateX(-50%); }
}
.animate-marquee { animation: marquee 20s linear infinite; }
Duplicate the logo set for seamless loop. Apply brightness-0 invert to make logos white.
A complete premium landing page follows this structure (5-7 sections):
After building, rewrite all text using Apple.com principles:
Below are 20 complete design specifications. Each is a self-contained recipe. When building, pick the closest pattern and adapt it.
Vibe: Dark, purple CTA, blurred pill overlay, dashboard preview Fonts: Manrope (nav/body), Inter (headline L1), Instrument Serif italic (headline L2), Cabin (buttons) Key specs:
Vibe: Ultra-minimal, cinematic, navy deep background Fonts: Instrument Serif (display), Inter 400/500 (body) Key specs:
text-muted-foreground for color depthVibe: Pure black, giant gradient headline word, purple accents Fonts: General Sans (headline), Geist Sans (body) Key specs:
Vibe: Pure black, Instrument Serif italic headings, multi-section Fonts: Instrument Serif italic (headings), Barlow 300-600 (body) Key specs:
Vibe: Dark, blue/indigo gradients, serif + sans pairing Fonts: Instrument Serif (pre-headline), Instrument Sans (main headline + body) Key specs:
Vibe: Video background (no overlay), purple buttons, glassmorphic badge Fonts: Manrope (nav), Instrument Serif (headline), Inter (body), Cabin (buttons) Key specs:
Vibe: Background video (no overlay), white floating nav, large serif text Fonts: Barlow (body/buttons), Instrument Serif italic (headline L2) Key specs:
Vibe: Full-screen video, two-panel layout, botanical/organic feel Fonts: Poppins 500 (display/body), Source Serif 4 (italic accents) Key specs:
Vibe: Minimalist loading animation, monochrome Fonts: Instrument Serif italic 400 (display) Key specs:
Vibe: Light/white, editorial serif accent, email input hero Fonts: Geist (body), Instrument Serif italic (accent word) Key specs:
Vibe: Background video (no overlay), white floating nav, Barlow + Serif Fonts: Barlow medium (body), Instrument Serif italic (headline L2) Key specs:
Vibe: Pure black, serif accent word, parallax dashboard Fonts: Inter 400-700 (body), Instrument Serif 400-italic (accent) Key specs:
Vibe: Black + brand red (#EE3F2C), uppercase, industrial Fonts: Rubik bold uppercase (headlines), Rubik (body) Key specs:
Vibe: Dark purple-black #070612, left-aligned content, HLS video Fonts: Custom (not specified, likely sans-serif) Key specs:
Vibe: Pure black, gradient-fading headline text, minimal Fonts: General Sans from Fontshare Key specs:
Vibe: Black, gradient buttons, glass badges, HLS video Fonts: Custom sans-serif (medium, tight tracking) Key specs:
Vibe: Dark #010101, purple-pink gradient accents, mix-blend-screen video Fonts: Modern sans-serif Key specs:
Vibe: Dark, orange gradient CTA, HLS video, social proof Fonts: Switzer medium (headings), Geist (body) Key specs:
Vibe: Dark, interactive pricing, red accent #FF5656 Fonts: Standard sans-serif Key specs:
Vibe: Video background, industrial uppercase, custom SVG button Fonts: Rubik bold uppercase Key specs:
When the user asks you to build a premium hero or landing page:
Creating a premium hero requires custom video backgrounds - not stock footage. This is the full pipeline from inspiration to hosted video URL.
Browse Pinterest for visual direction. Search terms that work well:
What to look for: Backgrounds that would look cinematic with slow, subtle motion. Avoid busy/cluttered images. The best backgrounds have depth layers (foreground/midground/background) that create parallax potential.
When you find one you like, screenshot just the background area (crop out any UI/text).
Take your screenshot to an AI image generator to recreate it in high quality without text/UI.
Tool: Higgsfield AI / Nano Banana (higgsfield.ai/image/nano_banana_flash)
Prompt template:
Give me the background of this exact image - no text, no buttons, no logos, no UI elements.
Same color grading and atmosphere as the original but in higher quality.
Clean background only.
Upload your screenshot with this prompt. Pick the best result from the generated options.
Alternative tools:
Take your upscaled image and turn it into a seamless looping video.
Tool: Kling 3.0 (klingai.com)
Prompt template (THE key prompt):
Fixed camera, locked lens, no camera movement.
Ultra slow cinematic motion. A very gentle breeze moves through the scene.
Foreground flowers/elements sway very slightly and naturally, minimal movement.
The motion should be extremely slow, smooth, and elegant. No fast movements.
Calm, peaceful, aesthetic atmosphere. Natural physics, soft wind effect.
Settings:
Alternative video generators:
Tips for best results:
Your video needs a publicly accessible URL. Options:
Mux (recommended for HLS streaming):
https://stream.mux.com/PLAYBACK_ID.m3u8CloudFront/S3 (recommended for direct MP4):
https://your-distribution.cloudfront.net/video.mp4<video> tagsOther hosts:
Reference the hosted URL in your component:
// Direct MP4 (CloudFront, S3, etc.)
<video autoPlay loop muted playsInline
className="absolute inset-0 w-full h-full object-cover z-0"
src="https://your-cdn.com/hero-bg.mp4"
/>
// HLS stream (Mux)
// See HLS implementation in Design System section above
If you want to skip the generation pipeline:
What CAN be automated (with API access):
| Step | Tool | API Available? | How |
|---|---|---|---|
| Image generation | Midjourney | Via Discord bot API | Send prompt, poll for result |
| Image generation | DALL-E 3 | Yes (OpenAI API) | client.images.generate() |
| Image generation | Stable Diffusion | Yes (Stability AI API, or local) | img2img endpoint |
| Video generation | Runway Gen-3 | Yes (API waitlist) | Upload image + prompt |
| Video generation | Luma | Yes (API) | POST /generations |
| Video hosting | Mux | Yes (full API) | Upload asset, get playback ID |
| Video hosting | Cloudflare Stream | Yes (full API) | Upload via API, get HLS URL |
| Video hosting | S3/CloudFront | Yes (AWS SDK) | s3.putObject() + CloudFront distribution |
What CANNOT be automated easily:
Realistic automation flow (with Playwright):
1. User provides: inspiration image or description
2. Script generates background via DALL-E 3 API (automated)
3. Script generates video via Luma API (automated)
4. Script uploads to Mux via API (automated)
5. Script returns HLS URL ready for the hero component
This could be built as a companion MCP server or CLI script. The main bottleneck is video generation quality - Kling 3.0 produces the best results but has no API, while Luma/Runway have APIs but slightly different aesthetics.
Playwright automation for Kling (possible but fragile): You could automate Kling's web UI with Playwright (upload image, paste prompt, click generate, wait, download), but web UIs change frequently and this approach is brittle. Better to use API-first tools (Luma, Runway) for automation and reserve Kling for manual, high-stakes hero sections.
| Package | Purpose |
|---|---|
motion (framer-motion) | Entrance animations, parallax, transitions |
hls.js | HLS video streaming (Mux URLs) |
lucide-react | Icons |
tailwindcss | Styling |
shadcn/ui | Component primitives |
Inspired by superwhisper.com's day/dusk/night switcher. Instead of toggling a CSS class and instantly swapping colors, stack multiple gradient layers and crossfade between them with a slow opacity transition. The result is a gorgeous, cinematic color shift.
Architecture: 3+ absolute-positioned gradient layers stacked on top of each other. Only the active theme's layer has opacity: 1. All others are opacity: 0. A 1.2s ease-in-out transition creates the crossfade.
// ThemeProvider state manages the active theme
const [theme, setTheme] = useState<"day" | "dusk" | "night">("day");
/* Container holds all gradient layers */
.theme-gradient-container {
position: relative;
overflow: hidden;
}
/* Each gradient layer is fullscreen, stacked, and crossfades */
.gradient-layer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 1.2s ease-in-out;
z-index: 0;
}
/* Active layer becomes visible */
.theme-day .gradient-layer.day,
.theme-dusk .gradient-layer.dusk,
.theme-night .gradient-layer.night {
opacity: 1;
}
/* Day - warm sky blue, golden undertones */
.gradient-layer.day {
background:
linear-gradient(90deg, rgba(25, 74, 232, 0.2) 2.75%, rgba(255, 190, 10, 0.2) 99.26%),
radial-gradient(170% 104% at 50% 0%, rgba(38, 84, 144, 0.5) 17%, rgba(255, 255, 255, 0.5) 100%),
radial-gradient(570% 155% at 50% -38%, rgba(0,0,0,0.5) 0%, rgba(2, 32, 68, 0.5) 21%,
rgba(31, 93, 135, 0.5) 46%, rgba(93, 109, 142, 0.5) 62%, rgba(159, 138, 145, 0.5) 74%,
rgba(205, 155, 142, 0.5) 80%, rgba(255, 226, 97, 0.5) 88%, rgba(255, 126, 30, 0.5) 100%),
rgb(115, 175, 235);
}
/* Dusk - purple/pink twilight */
.gradient-layer.dusk {
background:
linear-gradient(90deg, rgba(25, 153, 232, 0.15) 2.75%, rgba(164, 91, 242, 0.15) 99.26%),
linear-gradient(rgba(0,0,0,0.5) 0.85%, rgba(0, 5, 46, 0.5) 26%, rgba(41, 40, 94, 0.5) 58%,
rgba(84, 60, 123, 0.5) 80%, rgba(133, 90, 146, 0.5) 96%, rgba(195, 134, 171, 0.5) 107%),
linear-gradient(rgb(0,0,0) 0.85%, rgb(17, 45, 114) 33%, rgb(75, 82, 170) 50%,
rgb(168, 135, 220) 71%, rgb(230, 196, 231) 96%, rgb(252, 219, 239) 107%),
rgb(0, 0, 0);
}
/* Night - deep dark blue, subtle warm edge */
.gradient-layer.night {
background:
linear-gradient(90deg, rgba(25, 153, 232, 0.1) 2.75%, rgba(164, 91, 242, 0.1) 99.26%),
radial-gradient(83% 104% at 50% 0%, rgba(38, 84, 144, 0) 72%, rgba(255, 117, 117, 0) 100%),
radial-gradient(610% 214% at 50% -38%, rgba(0,0,0,0.5) 0%, rgba(2, 32, 68, 0.5) 21%,
rgba(31, 93, 135, 0.5) 46%, rgba(93, 109, 142, 0.5) 62%, rgba(159, 138, 145, 0.5) 74%,
rgba(205, 155, 142, 0.5) 80%, rgba(255, 162, 97, 0.5) 88%, rgba(255, 126, 30, 0.5) 100%),
rgb(0, 0, 0);
}
"use client";
import { useState } from "react";
import { Sun, Sunset, Moon } from "lucide-react";
const themes = [
{ id: "day", icon: Sun, label: "Day" },
{ id: "dusk", icon: Sunset, label: "Dusk" },
{ id: "night", icon: Moon, label: "Night" },
] as const;
type Theme = typeof themes[number]["id"];
export function ThemeHero() {
const [theme, setTheme] = useState<Theme>("day");
return (
<section className={`theme-gradient-container relative min-h-screen theme-${theme}`}>
{/* Stacked gradient layers - all render, only active one is visible */}
<div className="gradient-layer day" />
<div className="gradient-layer dusk" />
<div className="gradient-layer night" />
{/* Theme toggle - small pill in top-right */}
<div className="absolute top-4 right-4 z-20 flex gap-1 rounded-full bg-black/20 p-1 backdrop-blur-sm">
{themes.map(({ id, icon: Icon, label }) => (
<button
key={id}
onClick={() => setTheme(id)}
className={`rounded-full p-2 transition-colors ${
theme === id ? "bg-white/20 text-white" : "text-white/50 hover:text-white/80"
}`}
aria-label={label}
>
<Icon className="size-4" />
</button>
))}
</div>
{/* Content sits above gradients */}
<div className="relative z-10">
{/* Your hero content here */}
</div>
</section>
);
}
Images that swap per theme: Stack multiple versions of the same image and crossfade:
<div className="relative">
<img src="/hero-day.jpg" className={`absolute inset-0 transition-opacity duration-[1200ms] ${theme === "day" ? "opacity-100" : "opacity-0"}`} />
<img src="/hero-dusk.jpg" className={`absolute inset-0 transition-opacity duration-[1200ms] ${theme === "dusk" ? "opacity-100" : "opacity-0"}`} />
<img src="/hero-night.jpg" className={`absolute inset-0 transition-opacity duration-[1200ms] ${theme === "night" ? "opacity-100" : "opacity-0"}`} />
</div>
Text color that shifts: Use CSS variables that transition:
.theme-day { --text-hero: rgba(0, 0, 0, 0.9); --text-muted: rgba(0, 0, 0, 0.6); }
.theme-dusk { --text-hero: rgba(255, 255, 255, 0.95); --text-muted: rgba(255, 255, 255, 0.7); }
.theme-night { --text-hero: rgba(255, 255, 255, 1); --text-muted: rgba(255, 255, 255, 0.8); }
Key details: