电影感擦洗着陆页 — 黄金模板
构建一个高级的品牌感知着陆页,英雄视频响应鼠标移动,页面其余部分引导观众走过五个节拍的叙事弧。用户提供视频,可选地提供Logo + 产品照片 + 品牌背景——此技能负责调色板提取、排版选择、RTL/LTR、项目搭建、全关键帧视频重新编码、鼠标擦洗效果、部分库和验证。
为什么存在这个技能
参考实现位于 https://github.com/hoodini/bamba —— 一个以色列RTL网站,针对小吃“במבה”,其中婴儿视频跟踪光标跨越整个页面,下方4个不同的部分(亮黄色食谱、奶油色怀旧相册、深色沉思定价、红色行动结尾)引导观众走过 渴望→喜悦→怀旧→沉思→行动。

此技能中的每条规则都是从该构建中提取的。硬规则部分 中的要点都是来之不易的——它们覆盖了通用的“好代码”默认值。
部分画廊(你正在构建的内容)
英雄区保持顶部。在其下方,从库中选择4个部分,按叙事弧顺序排列。每个部分完全不透明(无视频透出)并拥有自己的品牌标识:
| 节拍 | 类型 | 参考 |
|---|---|---|
| 1 — 渴望 | 英雄区(鼠标擦洗视频) | ![]() |
| 2 — 喜悦 | 太阳 — 明亮的主色调强调渐变,浮动主题SVG,巨大幽灵排版,统计卡片 | ![]() |
| 3 — 怀旧 | 相册 — 奶油色纸张,点状微图案,宝丽来弯曲布局,真实产品照片 | ![]() |
| 4 — 沉思 | 烘烤 — 深色带径向强调发光,三个定价卡片,每个具有不同的视觉处理 | ![]() |
| 5 — 行动 | 信号 — 全出血强烈强调色(红/橙/绿),巨大标题+CTA,玻璃容器面板 | ![]() |
对于技术/SaaS品牌,根据需要交换部分类型(见下面的部分库)——但始终以信号部分结束。
如何使用这个技能
-
将资产放入 一个干净的工作目录:
- 英雄视频(任何容器 —
.mp4、.mov、.webm) - Logo(强烈推荐SVG;PNG带透明度可接受)
- 1-3张产品/主题图片(JPG/PNG,透明理想)
- 英雄视频(任何容器 —
-
与用户确认(简要 — 提出默认值,然后继续):
- 产品名称 + 元标语
- 语言代码(驱动RTL/LTR + 字体选择)
- 品牌背景 — 时代、受众、情感核心、调色板感觉
- 可选:明确的调色板十六进制值、叙事弧节拍
-
按顺序执行以下工作流程。 所有阶段都是强制性的。不要跳过ffmpeg重新编码——那是使擦洗感觉流畅的魔法。
-
在报告完成之前进行验证。 阶段9有12项检查。运行所有。
输入 — 从用户处收集这些
PRODUCT_NAME: "<例如 במבה / Bamba / Hope the Cheetah / Acme CRM>"
TAGLINE: "<元消息 — 例如 'it's not a snack, it's lifelong memories'>"
LANGUAGE: "<he | en | ar | es | fr | ja | ...>"
IS_RTL: "<true | false>" # he/ar/fa = true; 其他均为false
HERO_VIDEO_FILE: "<工作目录中的确切文件名 — 例如 baby2.mp4>"
LOGO_FILE: "<确切文件名 — 如果没有则留空>"
PRODUCT_IMAGE_FILE: "<确切文件名 — 如果没有则留空>"
BRAND_CONTEXT: |
<2-4句话:它唤起的时代、目标受众、情感核心、
视觉特性(温暖/冷静/有趣/严肃)。驱动调色板+主题。>
PALETTE: "<可选 — 如果覆盖则用逗号分隔的十六进制值>"
NARRATIVE_ARC: "<可选 — 5个情感节拍;如果空白则AI建议>"
完整文本模板(包含相同的YAML块和提示正文)位于 references/GOLDEN_PROMPT.md —— 当您没有直接技能运行时访问时,将其粘贴到Claude中并填充YAML。
阶段0 — 规划设计(在编码前输出≤200字的简报)
在编写任何代码之前,输出:
-
提取的5色调色板:
background(最深墨水色)、cream(暖色米白文本 — 绝不使用#FFFFFF)、accent(主要品牌颜色)、accent2(次要品牌颜色)、support(第三色调)。如果未提供PALETTE,则从Logo+产品图片中提取。调色板必须在内部协调 — 要么全暖色,要么全冷色,绝不可混合。暖色品牌(食品、自然、怀旧、动物)→ 不含蓝色、蓝绿色、薄荷色、青色。冷色品牌(科技、金融、医疗、科幻)→ 不含暖色调,除了一个小强调色。 -
排版三位一体(显示/正文/手写强调色)针对该语言:
he:Rubik(显示) + Assistant(正文) + Suez One(强调色)en:Anton(显示) + Inter(正文) + Caveat(强调色)ar:Cairo(显示) + Tajawal(正文) + Reem Kufi(强调色)es/fr/it/de:Anton 或 Bebas Neue(显示) + Inter(正文) + Caveat(强调色)ja:Noto Sans JP 权重 900(显示) + Noto Sans JP(正文) + Yusei Magic(强调色)- 其他语言:选择三种匹配该文字系统的Google字体,具有相同的
display-black / body-clean / handwritten-script角色。
-
叙事弧 — 5个情感节拍,映射到
BRAND_CONTEXT。将每个节拍与部分库中的节拍匹配。
然后执行 — 不需要要求确认。
阶段1 — 资产准备(魔法步骤)
1a. 验证ffmpeg
which ffmpeg # 或:PowerShell上使用 Get-Command ffmpeg
如果缺失,停止并告诉用户安装(brew install ffmpeg / Windows:http://ffmpeg.org)。
1b. 重新编码英雄视频,使每一帧都是关键帧
浏览器只能直接跳转到关键帧 — 标准视频大约每250帧有一个关键帧,这使得鼠标擦洗严重卡顿。单条命令就是高级与业余之间的差别:
ffmpeg -y -i <HERO_VIDEO_FILE> -g 1 -keyint_min 1 -c:v libx264 -preset slow -crf 20 -pix_fmt yuv420p -an hero.mp4
验证输出:hero.mp4 应在5-50 MB之间。如果 > 50 MB,重新运行 -crf 25;如果 > 80 MB,使用 -crf 28。剥离音频(-an) — 英雄视频是无声的。
1c. 复制Logo和产品图片
cp <LOGO_FILE> public/logo.<ext>
cp <PRODUCT_IMAGE_FILE> public/product.<ext> # 如果提供
阶段2 — 搭建项目框架
npm create vite@latest site -- --template react-ts
cd site
npm install
npm install lucide-react
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p
mkdir -p public
mv ../hero.mp4 public/hero.mp4
# 同时将Logo+产品图片移动到public/
阶段3 — Tailwind配置
完全替换 tailwind.config.js。使用提取的调色板和语言合适的字体:
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
background: '<墨水色/深色>',
cream: '<暖色米白 — 绝不使用 #FFFFFF>',
accent: '<主要品牌颜色>',
accent2: '<次要>',
support: '<第三色调>',
},
fontFamily: {
sans: ['<正文字体>', 'system-ui', 'sans-serif'],
display: ['<显示字体>', 'sans-serif'],
accent: ['"<手写字体>"', 'cursive'],
},
},
},
plugins: [],
}
阶段4 — index.html
完全替换。遵守 IS_RTL。始终包含指向Logo的favicon链接:
<!DOCTYPE html>
<html lang="<LANGUAGE>" dir="<rtl|ltr>">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<link rel="apple-touch-icon" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="<所选三种字体的Google Fonts URL>" rel="stylesheet">
<title><产品名称> — <标语></title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
阶段5 — index.css(设计系统)
完全替换。下面的每个实用类都是承重的。名称假设之前提取的暖色调色板;对于冷色品牌,将阴影色调中的“黄色”/“红色”提及替换为实际强调色。
必须包含:
html { scroll-behavior: smooth; }+section[id] { scroll-margin-top: 90px; }以便锚定的部分不会落在固定导航下方。body背景 =background颜色(视频失败时的回退)。光标 =crosshair。默认字体 = 正文无衬线字体。.liquid-glass/.liquid-glass-strong— 背景模糊+饱和度+内发光边框+蒙版渐变边缘高光。强变体使用以accent着色的内发光。.glass-pill— 紧凑的圆角药丸形状,具有相同的玻璃效果,用于导航项和小徽章。.cta-primary— 品牌CTA:linear-gradient(135deg, accent-light, accent, accent-shade)+ 强调色发光阴影,在悬停时增强 +translateY(-1px)抬起效果。.brand-mark— 小型正方形/圆形,用于没有提供SVG时的小Logo标记。.grid-bg— 微妙的1px网格,带有径向淡出蒙版,用于暗色部分下方。.reveal/.revealed— IntersectionObserver滚动揭示:opacity 0 → 1+translateY 28 → 0在0.9秒内,使用cubic-bezier(0.16, 1, 0.3, 1)。.scrim-top/.scrim-bottom— 仅用于英雄区的渐变覆盖层。- 按感觉而非颜色命名的各部分背景:
.sun-section— 明亮的主色调强调渐变 + 微妙的点状纹理(“喜悦/打开包装”节拍)。.album-section— 暖色米白纸张,径向强调色调 + 点状微图案,边缘蒙版淡出。.roast-section— 深色,带有在相对角部的径向强调色 + 强调色2发光 + 蒙版网格纹理。.signal-section— 全出血强烈强调色(通常是红/橙/绿色)用于行动终章。
.polaroid— 白色卡片,内边距14px 14px 44px 14px,柔和的分层阴影,悬停时抬起至translateY(-6px) rotate(0)。.polaroid-tape= 黄色/强调色胶带条,绝对定位在顶部居中,旋转-4°,带有虚线侧边提示。.stamp— 强调色虚线边框药丸形状,大写,字母间距0.18em。.ribbon— 定价/热门徽章,带有clip-path三角形底部,深色投影。.highlight-circle— 手绘感觉的椭圆,通过::after绘制:围绕一个内联<span>的旋转3px强调色边框。在大型标题中最重要的单词周围使用它(每个标题最多一个)。- 装饰性主题滤镜:
.peanut-svg/.<主题>-svg带有drop-shadow。 - 遵守
prefers-reduced-motion: reduce— 在媒体查询内停用揭示动画和平滑滚动。
阶段6 — App.tsx 架构
架构不容商量。第一次就做对:
6a. 导入
import { useEffect, useRef, useState } from 'react';
import {
Menu, X, ArrowLeft, ArrowRight, ArrowDown, ArrowUp, MousePointer2,
// …加上4-8个品牌主题图标(Heart, Sparkles, Cookie, PawPrint, Cpu, Leaf, …)
} from 'lucide-react';
6b. 在App.tsx内定义的可复用组件
useReveal<T>()— IntersectionObserver钩子,返回一个ref;在第一次相交时添加revealed类(阈值0.15)。GlassCard— 包装器,带有揭示钩子,可选的strong属性,接受className。Motif— 一个装饰性SVG组件,主题与BRAND_CONTEXT相关(食品用花生,动物用爪子,科技用电路,自然用叶子,饮料用液滴,能源用闪电)。在每个暗/亮部分中以低不透明度浮动在3-6个位置。ScrollToTopButton— 固定定位,RTL中为bottom-6 left-6/ LTR中为bottom-6 right-6。当window.scrollY > window.innerHeight * 0.6时出现。平滑滚动到顶部。简短的语言合适标签("לראש" / "Top" / "أعلى" / "返回顶部")。
6c. 鼠标擦洗效果(核心)
const videoRef = useRef<HTMLVideoElement>(null);
const stateRef = useRef({ targetTime: 0, isSeeking: false });
useEffect(() => {
const video = videoRef.current;
if (!video) return;
const handleLoaded = () => {
const mid = video.duration / 2;
video.currentTime = mid;
stateRef.current.targetTime = mid;
};
const handleSeeked = () => {
const s = stateRef.current;
s.isSeeking = false;
if (Math.abs(s.targetTime - video.currentTime) > 0.01) {
s.isSeeking = true;
video.currentTime = s.targetTime;
}
};
const handleMouseMove = (e: MouseEvent) => {
const s = stateRef.current;
const d = video.duration;
if (!d || isNaN(d)) return;
const normalized = e.clientX / window.innerWidth;
// 如果主体相对于光标“向后”移动且感觉不对,可以选择
// 使用 `1 - (e.clientX / window.innerWidth)` 代替 — 先询问用户。
s.targetTime = Math.max(0, Math.min(d, normalized * d));
if (!s.isSeeking) { s.isSeeking = true; video.currentTime = s.targetTime; }
};
video.addEventListener('loadedmetadata', handleLoaded);
video.addEventListener('seeked', handleSeeked);
window.addEventListener('mousemove', handleMouseMove);
return () => {
video.removeEventListener('loadedmetadata', handleLoaded);
video.removeEventListener('seeked', handleSeeked);
window.removeEventListener('mousemove', handleMouseMove);
};
}, []);
isSeeking 守卫是关键的 — 没有它,鼠标移动触发频率超过浏览器解码能力,导致seek队列溢出和可见卡顿。
6d. 可点击的滚动监视导航
const navItems: { label: string; target: string }[] = [
{ label: '<演示>', target: 'top' },
{ label: '<食谱>', target: 'recipe' },
{ label: '<相册>', target: 'album' },
{ label: '<定价>', target: 'pricing' },
{ label: '<现在获取>', target: 'cta' },
];
导航通过滚动监视高亮当前部分。使用 IntersectionObserver 监视每个部分,并相应更新活动导航项。
阶段7 — 部分库(在英雄区之后选择4-5个)
每个部分封装为一个组件。英雄区固定,其余部分可滚动。每个部分都应包含 useReveal 以实现滚动入动画。
7a. 英雄区(必需)
- 全屏视口,视频作为固定背景,覆盖整个页面
- 视频元素绝对定位,
object-fit: cover,z-index: -1 - 覆盖层:顶部和底部渐变遮罩(
.scrim-top/.scrim-bottom) - 覆盖层内容:Logo + 标题 + 标语 + 可选的下滚动提示
- 标题显示在
.liquid-glass面板中,大号font-display文本
7b. 太阳部分 — 喜悦/主要特征
- 明亮的渐变色背景,带有细微点状纹理
- 大型统计卡片或特征网格,每个卡片带有
GlassCard包装 - 巨大的幽灵排版元素作为装饰背景
- 浮动主题SVG(
Motif)
7c. 相册部分 — 故事/过程
- 暖色米白纸张背景,带有点状微图案
- 宝丽来样式卡片网格(
.polaroid),包含真实产品图片 - 时间线或步骤视觉元素
- 手写字体用于情感化副标题(
font-accent)
7d. 烘烤部分 — 对比/定价
- 深色背景,带有来自相对角的径向强调和强调色2发光
- 三个定价/选项卡片,每个具有不同的视觉处理:
- 标准:干净、简单的卡片
- 特色/热门:突出强调色,带有
.ribbon徽章 - 高级:深色玻璃变体,带有附加元素
.stamp元素用于标签
7e. 信号部分 — 行动呼吁
- 全出血强烈强调色背景(红/橙/绿)
- 大型标题,可能带有
.highlight-circle - 主要的CTA按钮(
.cta-primary) - 玻璃容器面板(
.liquid-glass)包含次要信息
阶段8 — 硬规则(优先级高于任何矛盾的最佳实践)
- 绝不使用
#FFFFFF— 所有浅色背景/文本都应使用从调色板中选择的暖色米白色或微妙的浅色调。 - 文本文本必须足够对比 — 任何身体文本至少达到WCAG AA(4.5:1对比度)。标题可以更宽松(3:1)。
- 一个副标题,一个手写强调字 — 每个部分最多一个手写字体单词/短语。过度使用会稀释效果。
- 每个部分完全独立 — 没有从英雄区视频透出的部分。每个部分有
background-color或渐变覆盖整个视口。 - 叙述弧必须连贯 — 5个节拍必须有情感进展。不能随机排序。
- 无默认动画 — 所有动画通过
useReveal触发。英雄区擦洗是唯一持续运动。 - 全球字体是必需的 — 始终通过Google Fonts加载三种字体。不使用系统字体回退作为主要字体。
- 全部内联 — 无外部CSS文件 — 所有样式通过Tailwind实用类 + index.css完成。无单独的
.module.css文件。 - ffmpeg re-encode 是强制性的 — 不要跳过或替代。没有它,鼠标擦洗感觉混乱。
- isSeeking 守卫必须存在于鼠标擦洗效果中 — 没有它,体验会卡顿。
- 始终包含一个可用CTA — 信号部分必须有一个用户可以点击的按钮或链接。
- 在平板/手机上优雅降级 — 视频擦洗变成触摸滑动擦洗,或简化为静态帧 + 视频上的覆盖播放/暂停按钮。
阶段9 — 验证清单(在报告完成前运行所有)
运行此完整清单。每一项都必须通过:
- V1 —
npm run dev启动无错误 - V2 — 英雄视频加载并全屏显示(发生在
loadedmetadata之后) - V3 — 鼠标左右移动擦洗视频(
isSeeking在工作 — 检查控制台是否快速连续seek) - V4 — 在初始擦洗后视频不会重置为第一帧(
handleLoaded正确设置中间点) - V5 — 所有4-5个部分可见,每个有独立的背景色/渐变
- V6 — 滚动时部分淡入(
revealed类在相交时应用) - V7 — 导航点击滚动到正确的部分
- V8 — 活动导航项随滚动更新
- V9 — 所有链接、CTA和交互元素工作
- V10 — 在RTL语言中,布局适当地镜像(
dir="rtl") - V11 — 文本内容与提供的品牌语境匹配(无默认的Lorem Ipsum)
- V12 —
hero.mp4文件存在于public/中,由ffmpeg编码(不是原始上传文件)
附录A — 参考实现
完整项目在 hoodini/bamba 可用。它是针对以色列品牌במבה的RTL网站,但模式适用于任何品牌。
关于此技能结构的关键文件:
src/App.tsx— 主要组件树src/index.css— 所有样式,包括部分特定的public/hero.mp4— 重新编码的英雄视频src/components/— 包含可复用部分组件
附录B — 常见品牌术语映射
| 品牌类型 | 节拍1(渴望) | 节拍2(喜悦) | 节拍3(怀旧) | 节拍4(沉思) | 节拍5(行动) |
|---|---|---|---|---|---|
| SaaS | “问题” | “解决方案” | “流程” | “定价” | “注册” |
| 食品/饮料 | “第一口” | “食谱” | “起源” | “比较” | “现在购买” |
| 时尚 | “风格困境” | “系列亮点” | “档案” | “定价” | “购物” |
| 非营利/野生动物 | “问题” | “我们做什么” | “成功故事” | “如何帮助” | “捐赠” |
| 音乐/娱乐 | “等待” | “歌曲/专辑” | “灵感” | “巡演” | “现在收听” |
使用此映射将5个叙述节拍转化为具体的部分标题和内容,与品牌语境匹配。








