加载中…
创作者 · MotionSites
查看原始来源 ↗Prompt
# PROMPT — 精确复刻 "Apogee" Hero Section
构建一个像素级精确、完全适配移动端的 Hero 落地页区块,名称为 **"Apogee"**。严格遵循下方所有规范——精确的十六进制值、精确的像素数、精确的 class 名称、精确的动画延迟、精确的文案。不得替换、取整、简化或“改进”任何值。如果给出了带方括号的 Tailwind 任意值(例如 `text-[15.5px]`),请原样使用该任意值,不要改用最接近的 Tailwind 预设。
---
## 1. 技术栈与项目设置
- **Vite 5** + **React 18.3** + **TypeScript 5.5** + **Tailwind CSS 3.4** + **PostCSS/Autoprefixer**
- 图标:**`lucide-react`** (v0.446)——仅使用 `ChevronDown`、`Menu`、`X`
- `package.json` 类型:`"module"`。脚本:`dev: vite`、`build: vite build`、`lint: eslint .`、`preview: vite preview`、`typecheck: tsc --noEmit -p tsconfig.app.json`
**`vite.config.ts`:**
```ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { fileURLToPath, URL } from 'node:url';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
optimizeDeps: {
exclude: ['lucide-react'],
},
});
```
**`tsconfig.app.json`** 必须包含匹配的路径别名,以便 `@/foo` 解析到 `src/foo`:
```json
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
```
**`tailwind.config.js`**——使用默认配置,不扩展主题(所有样式均使用任意值):
```js
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: { extend: {} },
plugins: [],
};
```
**文件结构:**
```
index.html
src/main.tsx
src/App.tsx
src/index.css
src/components/Hero.tsx
```
`src/App.tsx` 除 Hero 外不渲染任何内容:
```tsx
import Hero from '@/components/Hero';
function App() {
return <Hero />;
}
export default App;
```
`src/main.tsx` 使用 `createRoot` + `<StrictMode>`,并导入 `./App.tsx` 和 `./index.css`。
---
## 2. `index.html`——字体与 HEAD
页面标题:**`Apogee`**。Viewport meta:`width=device-width, initial-scale=1.0`。
在 `<head>` 中使用以下完全一致的样式表链接加载 **Suisse Intl** webfont:
```html
<link href="https://db.onlinewebfonts.com/c/13ab13418f633c1b0516fed6e30bedbc?family=Suisse+Int%27l" rel="stylesheet">
```
根 div 的 id 为 `root`;module script 为 `/src/main.tsx`。
---
## 3. `src/index.css`——全局 CSS 与 KEYFRAMES
文件内容必须与下方完全一致,并保持此顺序:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Suisse Intl', -apple-system, BlinkMacSystemFont, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fade-down {
from { opacity: 0; transform: translateY(-16px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fade-left {
from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes fade-right {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes fade-scale {
from { opacity: 0; transform: scale(0.92); }
to { opacity: 1; transform: scale(1); }
}
@keyframes bar-grow {
from { transform: scaleY(0); opacity: 0; }
to { transform: scaleY(1); opacity: 1; }
}
.animate-fade-up { animation: fade-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.animate-fade-down { animation: fade-down 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.animate-fade-left { animation: fade-left 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.animate-fade-right { animation: fade-right 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.animate-fade-scale { animation: fade-scale 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.animate-bar-grow {
animation: bar-grow 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
opacity: 0;
}
```
**关键要求:**每个动画均使用 `forwards` 填充模式和缓动函数 `cubic-bezier(0.16, 1, 0.3, 1)`。元素在标记中以 `opacity-0` 开始,并通过动画显示——绝不能通过 JS state 或 IntersectionObserver 显示。
---
## 4. `src/components/Hero.tsx`
单个文件按以下顺序包含四项内容:`BAR_HEIGHTS` 常量、`Animate` 辅助组件、`RevenueCard` 组件、默认导出的 `Hero`,然后是 `Nav` 组件(使用函数声明,因此函数提升允许在 `Hero` 之后定义 `Nav`)。
### 4.1 `BAR_HEIGHTS` 常量——严格按此顺序使用以下 32 个数字
```ts
const BAR_HEIGHTS = [
23, 40, 53, 40, 33, 14, 7, 17, 75, 65,
88, 75, 65, 47, 33, 88, 4, 7, 9, 14,
95, 65, 79, 37, 7, 40, 17, 20, 62, 47,
92, 72,
];
```
### 4.2 `Animate`——可复用的入场动画包装组件
Props:`children: React.ReactNode`、`delay?: number`(默认值 `0`)、`className?: string`(默认值 `''`)、`direction?: 'up' | 'down' | 'left' | 'right' | 'scale'`(默认值 `'up'`)。
它通过查找对象将 direction 映射到 class(`up: 'animate-fade-up'`、`down: 'animate-fade-down'`、`left: 'animate-fade-left'`、`right: 'animate-fade-right'`、`scale: 'animate-fade-scale'`),并渲染:
```tsx
<div
className={`opacity-0 ${directionClass} ${className}`}
style={{ animationDelay: `${delay}ms` }}
>
{children}
</div>
```
### 4.3 `Hero`——外层 section(默认导出)
```
<section class="relative w-full h-screen overflow-hidden bg-[#080A19]">
```
**背景视频**——第一个子元素,使用绝对定位并铺满容器,源 URL 必须与下方完全一致:
```
https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260813_092641_de52eb87-daf2-41db-92cb-7a56eae012a5.mp4
```
```tsx
<video
className="absolute inset-0 w-full h-full object-cover"
src="https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260813_092641_de52eb87-daf2-41db-92cb-7a56eae012a5.mp4"
autoPlay
loop
muted
playsInline
/>
```
(这是一段深暗蓝色/红色星云视频。**没有**深色渐变叠层——`#080A19` section 背景仅在视频加载时显示。)
**内容包装容器:**`<div className="relative z-10 h-full flex flex-col">`,其中先包含 `<Nav />`,然后是:
```
<div class="flex-1 flex items-center py-8">
<div class="w-full max-w-[1800px] mx-auto px-5 sm:px-8 md:px-[82px] flex flex-col lg:flex-row lg:items-center lg:justify-between gap-10 lg:gap-12">
<div class="max-w-[593px]"> …文案区块… </div>
<RevenueCard />
</div>
</div>
```
**文案区块(左栏),顺序如下:**
1. `<Animate delay={300} direction="up">` 包裹一个 `<h1>`:
- classes:`text-white text-[36px] sm:text-[52px] md:text-[64px] lg:text-[72px] font-normal leading-[0.95] mb-5 sm:mb-8`
- 文本:**`Elevate your essential data to new heights`**
2. `<Animate delay={500} direction="up">` 包裹一个 `<p>`:
- classes:`text-white/80 text-[16px] sm:text-[18px] md:text-[20px] font-[450] leading-[1.3] max-w-[370px] mb-7 sm:mb-10`
- 文本:**`Advanced reasoning systems and predictive models built for the unknown`**
3. `<Animate delay={700} direction="up">` 包裹 `<div className="flex flex-wrap gap-3 sm:gap-4">`,其中包含两个按钮:
- **`Book a demo`**——`h-[46px] sm:h-[51px] px-5 sm:px-[27px] bg-[#E9E9E9] rounded-[12px] text-[#0A0707] text-[14px] sm:text-[15.5px] font-[450] leading-[15.5px] transition-opacity hover:opacity-90`
- **`Talk with the team`**——`h-[46px] sm:h-[51px] px-5 sm:px-[27px] rounded-[12px] border border-white text-white text-[14px] sm:text-[15.5px] font-[450] leading-[15.5px] transition-opacity hover:opacity-80`
### 4.4 `RevenueCard`——玻璃拟态统计卡片(右栏)
包装容器:`<Animate delay={900} direction="scale" className="w-full max-w-[405px] mx-auto lg:mx-0">`
(因此它在移动端**居中,在 `lg` 时于其栏中左对齐**)。
卡片外壳:
```
w-full rounded-[24px] sm:rounded-[33px] bg-[rgba(17,16,15,0.35)] backdrop-blur-[20px] p-5 sm:p-8 pb-5 sm:pb-6
```
**内容按以下顺序排列:**
1. 标签 `<p>`:**`Revenue Growth`**——`text-white text-[16px] sm:text-[20px] font-[450] leading-[20px] mb-3 sm:mb-4`
2. 金额 `<p className="mb-2 sm:mb-3">` 包含**两个 span**,从而使小数部分变暗:
- `<span class="text-white text-[28px] sm:text-[46px] font-[450] leading-[1]">$14,205,890</span>`
- `<span class="text-white/20 text-[28px] sm:text-[46px] font-[450] leading-[1]">.00</span>`
3. 变化量行 `<div className="flex items-center gap-[10px] mb-6 sm:mb-8">`:
- 徽章 span **`+32.4%`**——`px-[6px] py-[7px] bg-white/20 rounded-[6px] text-white text-[12px] sm:text-[14px] font-[450] leading-[14px]`
- 说明 span **`vs. previous period ($10.7M)`**——`text-white/80 text-[12px] sm:text-[14px] font-[450] leading-[14px] opacity-70`
4. 图表区块 `<div className="relative">`,包含三个子元素:
**(a) 柱条**——`<div className="flex items-end gap-[1.5px] h-[80px] sm:h-[100px]">`,映射 `BAR_HEIGHTS`。在组件顶部仅计算一次 `const maxHeight = Math.max(...BAR_HEIGHTS);`(= `95`)。对于索引为 `i` 的每根柱条:
- `const isProjected = i >= 28;` ← **最后 4 根柱条**是变暗的“预测”柱条
- `const heightPercent = (h / maxHeight) * 100;`
- className:`flex-1 rounded-[0.5px] animate-bar-grow origin-bottom`
- inline style:
```ts
{
height: `${heightPercent}%`,
backgroundColor: isProjected ? 'rgba(255,255,255,0.1)' : 'white',
animationDelay: `${1100 + i * 30}ms`,
}
```
- 因此柱条从 **1100ms** 到 **2030ms**(`1100 + 31*30`)依次错开,每根柱条以底部为变换原点,在 600ms 内从 `scaleY(0)` 开始增长。
**(b) 垂直网格线**——`<div className="absolute inset-0 pointer-events-none">`,其中包含 `[0,1,2,3,4].map(i => …)`:
- className `absolute top-0 bottom-0 w-px bg-white/10`
- style `{ left: `${((i + 1) / 5) * 100}%` }` → 20%、40%、60%、80%、100%
**(c) 时间轴**——`<div className="flex justify-between mt-3">`,遍历 `['10:00', '12:00', '14:00', '16:00', '16:00']`(是的,最后一个标签重复为 `16:00`——请照样复现):
- className `text-[9px] sm:text-[10px] font-[450] leading-[10px] text-white/80`
- style `{ opacity: i >= 3 ? 0.4 : 1 }` → 最后两个标签变暗
### 4.5 `Nav`——页头 + 移动端菜单
包含 `const [isOpen, setIsOpen] = useState(false);`,并包含一个在菜单打开时**锁定 body 滚动**的 `useEffect`:
```tsx
useEffect(() => {
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
return () => { document.body.style.overflow = ''; };
}, [isOpen]);
```
返回 fragment `<>…</>`,其中 `<nav>` 栏与移动端叠层互为同级元素。
**Nav 栏:**
```
<nav class="w-full max-w-[1800px] mx-auto px-5 sm:px-8 md:px-[82px] pt-[20px] sm:pt-[30px] flex items-center justify-between relative z-50">
```
(注意:Nav 使用与 Hero 主体相同的 `max-w-[1800px]` + `px-5 sm:px-8 md:px-[82px]` 间距规律,使 Logo 与标题对齐。)
**(i) Logo**——`<Animate delay={0} direction="down">` → `<div className="flex items-center gap-2.5">`:
Inline SVG,`width="28" height="28" viewBox="0 0 256 256" fill="none" className="sm:w-[32px] sm:h-[32px]"`,包含一条白色 path——使用以下完全一致的 `d`:
```
M 256 256 L 178 256 C 150.386 256 128 233.614 128 206 L 128 256 L 0 256 L 0 192 C 0 156.654 28.654 128 64 128 C 99.346 128 128 156.654 128 192 L 128 128 L 256 128 Z M 78 0 C 105.614 0 128 22.386 128 50 L 128 0 L 256 0 L 256 64 C 256 99.346 227.346 128 192 128 C 156.654 128 128 99.346 128 64 L 128 128 L 0 128 L 0 0 Z
```
Wordmark span:**`Apogee`**——`text-white text-[22px] sm:text-[26px] font-[450] leading-none tracking-[-0.02em]`
**(ii) 中央 Nav 胶囊**——`<Animate delay={100} direction="down" className="hidden lg:block">` → 玻璃胶囊:
```
h-[52px] px-6 flex items-center gap-[30px] bg-[rgba(10,7,7,0.35)] rounded-[11px] backdrop-blur-[17px]
```
项目(全部使用 `text-white/80 text-[14px] font-[450] leading-[14px] hover:text-white transition-colors`):
- **`Platform`**——一个 `<button className="flex items-center gap-[5px] …">`,末尾带 `<ChevronDown className="w-[10px] h-[10px] opacity-80" />`
- **`Pricing`**、**`Resources`**、**`Blog`**——带有 `cursor-pointer` 的普通 `<span>`
**(iii) 右侧认证胶囊**——`<Animate delay={200} direction="down" className="hidden lg:block">`:
```
h-[52px] p-[3px] bg-[rgba(0,0,0,0.35)] rounded-[13px] backdrop-blur-[17px] flex items-center gap-[5px]
```
- **`Login`**——`h-[46px] px-6 rounded-[11px] text-white text-[14px] font-[450] leading-[14px] hover:bg-white/5 transition-colors`
- **`Book a demo`**——`h-[46px] px-6 bg-[#E9E9E9] rounded-[11px] text-[#0A0707] text-[14px] font-[450] leading-[14px] hover:bg-white transition-colors`
**(iv) 移动端汉堡菜单**——`<Animate delay={100} direction="down" className="lg:hidden">`:
按钮:`w-[44px] h-[44px] flex items-center justify-center rounded-[11px] bg-[rgba(10,7,7,0.35)] backdrop-blur-[17px] transition-colors hover:bg-white/10`,`onClick={() => setIsOpen(!isOpen)}`,`aria-label="Toggle menu"`。
内部包含一个 `<div className="relative w-5 h-5">`,其中**两个图标以绝对定位叠放**并进行交叉淡入淡出(绝不通过条件渲染卸载):
- `<Menu className={\`w-5 h-5 text-white absolute inset-0 transition-all duration-300 ease-out ${isOpen ? 'opacity-0 rotate-90 scale-75' : 'opacity-100 rotate-0 scale-100'}\`} />`
- `<X className={\`w-5 h-5 text-white absolute inset-0 transition-all duration-300 ease-out ${isOpen ? 'opacity-100 rotate-0 scale-100' : 'opacity-0 -rotate-90 scale-75'}\`} />`
**(v) 移动端菜单叠层**(与 `<nav>` 同级):
容器——切换 visibility,绝不卸载,使打开与关闭两个方向的 transition 都能播放:
```
lg:hidden fixed inset-0 z-40 transition-all duration-500 ease-[cubic-bezier(0.32,0.72,0,1)] + (isOpen ? 'visible' : 'invisible')
```
Backdrop(点击后关闭菜单):
```
absolute inset-0 bg-[#080A19]/90 backdrop-blur-[24px] transition-opacity duration-500 + (isOpen ? 'opacity-100' : 'opacity-0')
```
Panel:
```
absolute top-[76px] sm:top-[86px] left-4 right-4 sm:left-6 sm:right-6
bg-[rgba(17,16,15,0.6)] backdrop-blur-[30px] rounded-[20px] border border-white/[0.06]
p-6 sm:p-8 transition-all duration-500 ease-[cubic-bezier(0.32,0.72,0,1)] origin-top
+ (isOpen ? 'opacity-100 translate-y-0 scale-100' : 'opacity-0 -translate-y-4 scale-[0.97]')
```
Panel 链接——`<div className="flex flex-col gap-1">`,遍历 `['Platform', 'Pricing', 'Resources', 'Blog']`,每项都是 `<a href="#">`:
```
flex items-center justify-between px-4 py-4 rounded-[12px] text-white/90 text-[18px] font-[450]
hover:bg-white/[0.06] transition-all duration-300
+ (isOpen ? 'opacity-100 translate-x-0' : 'opacity-0 -translate-x-3')
```
使用错开的 `style={{ transitionDelay: isOpen ? `${100 + i * 50}ms` : '0ms' }}`(→ 100/150/200/250ms),且只有 `Platform` 项末尾带有 `<ChevronDown className="w-4 h-4 opacity-50" />`。
分隔线:`<div className="h-px bg-white/10 my-5" />`
Panel CTA——`<div className="flex flex-col gap-3 transition-all duration-300" style={{ transitionDelay: isOpen ? '350ms' : '0ms' }}>`,并使用 `isOpen ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-2'`:
- **`Book a demo`**——`w-full h-[50px] bg-[#E9E9E9] rounded-[12px] text-[#0A0707] text-[15px] font-[450] transition-colors hover:bg-white`
- **`Login`**——`w-full h-[50px] rounded-[12px] border border-white/30 text-white text-[15px] font-[450] transition-colors hover:bg-white/5`
---
## 5. 精确间距 / BOX-MODEL 表——关键要求,不得估算
**构建前请先阅读本节。**下方每个数字都是从源代码中取得的字面像素值。不要根据截图凭感觉估算比例,不要取整为“看起来差不多”,也不要让自动布局/AI 默认值自行替换 padding。如果某个单元格写着 `24px` padding,则渲染元素的边框与其文本/图标之间必须在对应方向留出 24px 空白——请通过测量验证,不要只靠目测。重建时最常见的失败情况是按钮和胶囊几乎没有内部 padding(文本紧贴边缘)——下方列出的每一行按钮/胶囊数据都是专门用于避免这个问题的。
格式:**属性——base (<640px) → sm (≥640px) → md (≥768px) → lg (≥1024px)**。破折号(`—`)表示“与上一个已声明断点保持不变”。
### 5.1 页面级容器
| 元素 | 属性 | base | sm | md | lg |
|---|---|---|---|---|---|
| `<nav>` 和 Hero 内容行 | 水平 padding | `20px` | `32px` | `82px` | — |
| `<nav>` | 顶部 padding | `20px` | `30px` | — | — |
| `<nav>` | 底部 padding | `0`(无——与 Hero 内容之间的间距来自下方 `flex-1 items-center` 的居中,而非 Nav padding) | | | |
| Hero 内容行(`flex-1`) | 垂直 padding | 顶部和底部各 `32px`(`py-8`) | — | — | — |
| Nav / 内容行 | 最大宽度 | `1800px`,居中(`mx-auto`) | — | — | — |
| 文案栏 ↔ Revenue 卡片 | 两者间距 | `40px`(纵向堆叠,因此这是垂直间距) | — | — | `48px`(水平间距,并排排列) |
| 文案栏 | 最大宽度 | `593px` | — | — | — |
| Revenue 卡片包装容器 | 最大宽度 | `405px`,水平居中(`mx-auto`) | — | — | 左对齐(`mx-0`,不再居中) |
### 5.2 Logo(左上角)
| 属性 | base | sm |
|---|---|---|
| 图标尺寸 | `28×28px` | `32×32px` |
| 图标与 "Apogee" 文本之间的间距 | `10px` | — |
### 5.3 中央 Nav 胶囊("Platform · Pricing · Resources · Blog")——仅桌面端,`≥1024px`
| 属性 | 值 |
|---|---|
| 高度 | `52px`(固定) |
| 水平 padding(左侧 + 右侧) | 每侧 `24px` |
| 垂直 padding | 未设置——高度固定为 52px,内容通过 `flex items-center` 垂直居中 |
| 各 Nav 项之间的间距 | `30px` |
| "Platform" 文本与 chevron 之间的间距 | `5px` |
| Chevron 图标尺寸 | `10×10px` |
| 圆角半径 | `11px` |
**该胶囊必须足够宽,使 "Platform / Pricing / Resources / Blog"、三个 30px 间距以及左右两侧各 24px 的 padding 都能在一行内完整容纳,不得换行或紧贴圆角。**
### 5.4 右侧认证胶囊("Login / Book a demo")——仅桌面端,`≥1024px`
| 属性 | 值 |
|---|---|
| 外层胶囊高度 | `52px` |
| 外层胶囊 padding(四边) | `3px`——这是外层胶囊边缘与内部两个按钮之间的细小间隙 |
| "Login" 按钮与 "Book a demo" 按钮之间的间距 | `5px` |
| 外层胶囊圆角半径 | `13px` |
| **Login 按钮**高度 | `46px`(填满 52px 胶囊扣除 3px+3px padding 后的空间) |
| **Login 按钮**水平 padding | 每侧 `24px` |
| **Login 按钮**圆角半径 | `11px` |
| **Book a demo 按钮**高度 | `46px` |
| **Book a demo 按钮**水平 padding | 每侧 `24px` |
| **Book a demo 按钮**圆角半径 | `11px` |
### 5.5 移动端汉堡菜单按钮——仅 `<1024px`
| 属性 | 值 |
|---|---|
| 按钮尺寸 | `44×44px` 正方形 |
| 图标尺寸(Menu/X) | `20×20px`,在按钮中居中 |
| 圆角半径 | `11px` |
### 5.6 标题、副标题、CTA 行(左栏)
| 元素 | 属性 | base | sm |
|---|---|---|---|
| `<h1>` | margin-bottom(到副标题的间距) | `20px` | `32px` |
| 副标题 `<p>` | margin-bottom(到 CTA 行的间距) | `28px` | `40px` |
| 副标题 `<p>` | 最大宽度(强制形成 mock 中所示的换行) | `370px` | — |
| CTA 按钮行 | 两个按钮之间的间距 | `12px` | `16px` |
### 5.7 CTA 按钮("Book a demo" / "Talk with the team")——两个大型 Hero 按钮,而非 Nav 中的按钮
| 属性 | base | sm |
|---|---|---|
| 高度 | `46px` | `51px` |
| 水平 padding(左侧 + 右侧) | 每侧 `20px` | 每侧 `27px` |
| 垂直 padding | 未设置——高度固定,文本垂直居中 | — |
| 圆角半径 | `12px` | — |
| "Talk with the team" 边框宽度 | `1px` 白色实线 | — |
**这两个按钮正是你截图中几乎没有 padding 的按钮。在 20–27px 的水平 padding 下,按钮圆角边缘与标签首尾字母之间应明显留有舒适空白——文本不得紧贴边框。**
### 5.8 Revenue 卡片外壳
| 属性 | base | sm |
|---|---|---|
| 圆角半径 | `24px` | `33px` |
| Padding——顶部 | `20px` | `32px` |
| Padding——右侧 | `20px` | `32px` |
| Padding——左侧 | `20px` | `32px` |
| Padding——底部(被覆盖,比其他三边更浅) | `20px` | `24px` |
### 5.9 Revenue 卡片内部间距(从上到下,按文档流顺序)
| 属性 | base | sm |
|---|---|---|
| "Revenue Growth" 标签 → margin-bottom | `12px` | `16px` |
| 金额行 → margin-bottom | `8px` | `12px` |
| 变化量行(徽章 + 说明)→ margin-bottom | `24px` | `32px` |
| 变化量行内部徽章与说明文本之间的间距 | `10px` | — |
| 徽章("+32.4%")内部 padding——水平方向 | 每侧 `6px` | — |
| 徽章("+32.4%")内部 padding——垂直方向 | 顶部和底部各 `7px` | — |
| 徽章圆角半径 | `6px` | — |
| 图表高度(柱条) | `80px` | `100px` |
| 各柱条之间的间距 | `1.5px` | — |
| 柱条圆角半径 | `0.5px`(仅略微圆润——顶部接近直角) | — |
| 时间轴行 → margin-top(位于柱条下方、时间轴上方的间距) | `12px` | — |
### 5.10 移动端菜单叠层 Panel——仅 `<1024px`,汉堡菜单打开时
| 属性 | base | sm |
|---|---|---|
| Panel 距屏幕顶部的偏移 | `76px` | `86px` |
| Panel 距屏幕左右边缘的偏移 | `16px` | `24px` |
| Panel 内部 padding(四边) | `24px` | `32px` |
| Panel 圆角半径 | `20px` | — |
| Panel 边框宽度 | `1px`,颜色为 6% 不透明度的 `white` | — |
| 每个 Nav 链接行——内部 padding | 四边各 `16px` | — |
| 每个 Nav 链接行——圆角半径 | `12px` | — |
| 堆叠 Nav 链接行之间的间距 | `4px`(`gap-1`) | — |
| 分隔线 → 垂直 margin(上方和下方) | `20px` | — |
| 底部两个 CTA 按钮之间的间距(纵向堆叠) | `12px` | — |
| 底部 CTA 按钮——高度 | `50px` | — |
---
## 6. 完整颜色参考
| Token | 值 | 用途 |
|---|---|---|
| Section 背景 | `#080A19` | Hero `<section>`,移动端 Backdrop 使用 90% 不透明度 |
| 浅色按钮填充 | `#E9E9E9` | "Book a demo"(所有实例) |
| 浅色按钮文本 | `#0A0707` | `#E9E9E9` 按钮上的文本 |
| Nav 胶囊玻璃 | `rgba(10,7,7,0.35)` | 中央 Nav 胶囊、汉堡菜单按钮 |
| 认证胶囊玻璃 | `rgba(0,0,0,0.35)` | 右侧认证胶囊 |
| 卡片 / Panel 玻璃 | `rgba(17,16,15,0.35)` 卡片 · `rgba(17,16,15,0.6)` 移动端 Panel | Revenue 卡片、移动端菜单 Panel |
| 预测柱条 | `rgba(255,255,255,0.1)` | 索引 ≥ 28 的柱条 |
| 活跃柱条 | `white` | 索引 < 28 的柱条 |
| 网格线 | `white/10` | 5 条垂直图表线 |
| Panel 边框 | `white/[0.06]` | 移动端菜单 Panel |
| 小数部分变暗 | `white/20` | `.00` span |
| 正文/次要文本 | `white/80` | 副标题、Nav 链接、坐标轴标签 |
**Backdrop-blur 级别:**`17px`(Nav 胶囊)· `20px`(Revenue 卡片)· `24px`(移动端 Backdrop)· `30px`(移动端 Panel)。
---
## 7. 完整动画时间线(页面加载,ms)
| 延迟 | 元素 | 动画 |
|---|---|---|
| 0 | Logo + Wordmark | `fade-down` 700ms |
| 100 | 中央 Nav 胶囊(桌面端)/ 汉堡菜单(移动端) | `fade-down` 700ms |
| 200 | 右侧认证胶囊(桌面端) | `fade-down` 700ms |
| 300 | `<h1>` 标题 | `fade-up` 800ms |
| 500 | 副标题 `<p>` | `fade-up` 800ms |
| 700 | CTA 按钮行 | `fade-up` 800ms |
| 900 | Revenue 卡片 | `fade-scale` 900ms |
| 1100 + i×30 | 图表柱条 `i`(0–31) | `bar-grow` 600ms,`origin-bottom` |
全部使用 `cubic-bezier(0.16, 1, 0.3, 1)` 和 `forwards`。整个序列约在 2630ms 时完成。
---
## 8. 响应式行为(Tailwind 默认值:`sm`=640px、`md`=768px、`lg`=1024px)
**布局**
- `< lg`:单栏——文案区块位于 Revenue 卡片上方,`gap-10`;卡片使用 `mx-auto`(居中),最大宽度为 `405px`
- `≥ lg`:`flex-row`、`items-center`、`justify-between`、`gap-12`;卡片改为 `mx-0`
- 水平 padding 依次提升:`px-5` → `sm:px-8` → `md:px-[82px]`;内容限制为 `max-w-[1800px] mx-auto`
- Section 始终使用 `h-screen` 和 `overflow-hidden`;内部行使用 `flex-1 flex items-center py-8`(垂直居中)
**Navigation**
- `≥ lg`:显示中央 Nav 胶囊 + 右侧认证胶囊,隐藏汉堡菜单
- `< lg`:隐藏两个胶囊(`hidden lg:block`),显示 44×44 汉堡菜单,提供全屏叠层菜单;菜单打开时锁定 body 滚动
**字体大小变化**
| 元素 | base | sm | md | lg |
|---|---|---|---|---|
| h1 | 36px | 52px | 64px | 72px |
| 副标题 | 16px | 18px | 20px | — |
| CTA 按钮 | 14px | 15.5px | — | — |
| Wordmark | 22px | 26px | — | — |
| 卡片标签 | 16px | 20px | — | — |
| 卡片金额 | 28px | 46px | — | — |
| 变化量行 | 12px | 14px | — | — |
| 坐标轴标签 | 9px | 10px | — | — |
**尺寸变化**
| 元素 | base | sm |
|---|---|---|
| Logo SVG | 28×28 | 32×32 |
| CTA 高度 | 46px | 51px |
| CTA 水平 padding | 20px(`px-5`) | 27px |
| 卡片圆角 | 24px | 33px |
| 卡片 padding | 20px(`p-5`、`pb-5`) | 32px(`p-8`),底部 24px(`pb-6`) |
| 图表高度 | 80px | 100px |
| Nav 顶部 padding | 20px | 30px |
| 移动端 Panel 顶部位置 | 76px | 86px |
| 移动端 Panel 左右内缩 | `left-4 right-4` | `left-6 right-6` |
| 移动端 Panel padding | 24px | 32px |
---
## 9. 不可妥协的检查清单
- [ ] 视频 `src` 与上方 CloudFront URL 逐字符一致,并带有 `autoPlay loop muted playsInline`(iOS 自动播放必须使用 muted+playsInline)
- [ ] `BAR_HEIGHTS` 按给定顺序包含全部 32 个值;`maxHeight` 使用 `Math.max(...)` 推导,不得硬编码
- [ ] 柱条 28–31 使用 `rgba(255,255,255,0.1)`;柱条 0–27 使用纯 `white`
- [ ] 最后一个时间轴标签为 `16:00`(重复),且索引 ≥ 3 的标签以 `opacity: 0.4` 渲染
- [ ] 金额中的 `.00` 是独立的 `white/20` span
- [ ] 除 `<h1>` 使用 `font-normal` 外,所有位置均使用 `font-[450]`(不得使用 `font-normal`/`font-medium`)
- [ ] 移动端菜单通过 visibility 切换,而非条件渲染,以便关闭 transition 能够播放
- [ ] Menu/X 图标通过旋转+缩放进行交叉淡入淡出;绝不通过卸载来切换
- [ ] 菜单打开时锁定 body 滚动,并在组件卸载时清理
- [ ] 每个动画元素在标记中都带有 `opacity-0`,并仅通过 CSS 动画的 `forwards` 填充显示
- [ ] 不使用滚动触发动画,不使用 IntersectionObserver,不使用动画库——仅使用纯 CSS keyframes + `animationDelay`
- [ ] **两个 Hero CTA 按钮的边框与标签文本之间都必须留有 20–27px 的水平空间——文本绝不能紧贴边缘**(参见 §5.7——这正是上次重建中的缺陷)
- [ ] 中央桌面端 Nav 胶囊应根据内容尺寸加上左右各 24px padding,并保持完整的 52px 高度——不得使用会裁切四个 Nav 链接或使它们显得拥挤的狭窄盒子(参见 §5.3)
- [ ] 右侧认证胶囊的圆角边缘与内部 Login/Book-a-demo 按钮之间应有清晰可见的 3px 外层 padding 间隙,按钮不得与胶囊边框齐平(参见 §5.4)
- [ ] Revenue 卡片顶部/右侧/左侧的 padding 在移动端为 20px、桌面端为 32px;底部有意设置得更浅,为 20px / 24px——请验证这种不对称性,不要将四边设为相同值(参见 §5.8)
- [ ] 在宣布完成前,重新对照 §5 检查渲染输出中的每个值——如果任何 padding 数值不匹配,请修正该值,不得近似处理适用模型与稳定度
建议模型
继续探索
@Oluwaphilemon1 使用 Claude Fable 5 · Three.js · Blender · GSAP完成的网页案例,包含公开结果、完整 Prompt 与原始来源。
提示语
Claude Fable 5 和 GPT-5.6 很强🥵🥵🥵 下面是我如何使用 Claude 构建的 👇 提示词:「设计一个机构网站,把服务以 3D 超市商品包装的形式呈现」 使用 Three.js 和 WebGL 在浏览器中实时渲染所有产品 使用 Blender 制作包装模型,然后导出为 GLTF 以加载到 Three.js 中 使用 GSAP 实现流畅的产品旋转和悬停交互 如果你想做一个让客户感觉像是在购买高级商品的作品集,请保存这条 🛒
Aceternity UI 的 AI Coding (UI) 案例“3D Animated Pin”——GoodCase.ai 上提供完整提示词与原始来源。
提示语
// 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…

提示语
// components/ui/3d-globe.tsx "use client"; import React, { useRef, useMemo, useState, useCallback, Suspense } from "react"; import { Canvas, useFrame, useThree } from "@react-three/fiber"; import { OrbitControls, Html, useTexture } from "…