Vexon
aadmin2026-11-05 发布Site模板2 阅读

Vexon

类型:Site模板 · 收录:2026-11-05 01:12:46 · 源码:会员可见

[hidecontent type="vip1"]
# Recreate this site as a single HTML file: Vexon

You are an expert creative front-end developer. Produce a **single self-contained `index.html`**
that reproduces the project below **exactly** — same layout, sections, visuals, motion, and
interaction. Pure HTML/CSS/JS in one file: no build step, no framework, no bundler. Use ES modules
with a CDN importmap for Three.js. Hardcode every value given here as a fixed constant. Rebuild each
component described below as a section of the one file.

## What it is

A dark, premium one-page landing for a fictional AI intelligence company called **VEXON**. The whole
page sits on pure black; behind everything is a fixed full-screen **Three.js GPU particle halo** —
~160,000 additively-blended points forming a fuzzy glowing donut/ring with a dark void at its center,
lit cool deep-blue → mid-blue → hot-white from the top, slowly rotating and shimmering with simplex
turbulence, drifting with a soft pointer parallax. On load, a black **preloader** shows a rotating
2D canvas particle sphere with a counter that ticks `000% → 100%` and cycling system tags; when it
hits 100% it blurs and scales away, and the particle halo plays a dramatic staggered **fly-through
entrance** (particles rush past the camera, spiral, and coalesce into the ring) while the page content
fades in. As you scroll (smoothed Lenis-style), the halo gently scales up (parallax zoom). Content is
four blocks: a giant hero headline (`WHERE RAW DATA / BECOMES YOUR / UNFAIR ADVANTAGE`) with
per-character blur-in text, an About section with three glassy image cards that have a custom
"Read More" cursor-follow chip and a parallax image on hover, a modular bordered "mission" grid with
another giant headline and a logo marquee, and a minimal footer. Type: Orbitron for the logo, Space
Grotesk for display headlines, Inter body, JetBrains Mono for labels. A custom cursor (a small
mix-blend-difference white dot plus a lagging ring that grows over interactive elements) replaces the
system pointer everywhere.

## Page shell & libraries

- Importmap loading **Three.js r0.160+** as an ES module from a CDN, e.g.
  `https://unpkg.com/three@0.160.0/build/three.module.js`. No other JS libraries — reimplement smooth
  scroll, scroll-reveal, the per-char text reveal, the marquee, and both cursor systems in vanilla JS.
  Lucide `arrow-up-right` icons are drawn as inline SVG.
- Fonts via a single Google Fonts `@import` at the top of the stylesheet (verbatim):
  `https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@700&family=Orbitron:wght@700&family=Playfair+Display:ital,wght@1,400&display=swap`
  - `--font-sans: "Inter"`, `--font-mono: "JetBrains Mono"`, `--font-display: "Space Grotesk"`,
    `--font-logo: "Orbitron"`, `--font-serif: "Playfair Display"`.
- Global CSS: `body { background:#000; color:#fff; -webkit-font-smoothing:antialiased; cursor:none; }`,
  `*` box-sizing border-box, no margins. **Hide the scrollbar entirely** on `html` and `body`
  (`scrollbar-width:none; -ms-overflow-style:none; ::-webkit-scrollbar{display:none}`). Selection:
  `::selection { background:#fff; color:#000 }`. Set `cursor:none` on `a, button, [role=button]` too —
  the custom cursor replaces the native one site-wide.
- Default text accent color used throughout for body/labels is `#E6E6E6`; muted nav links are `#8E9299`.
- Page structure (z-order): the Three.js halo lives in a `position:fixed; inset:0; z-index:0;
  transform-origin:center` div (the canvas fills it, `pointer-events` may stay on for parallax). All
  page content is in a `position:relative; z-index:10` wrapper. The fixed nav is `z-index:50`. The
  preloader is `z-index:200`. The custom cursor layer is `z-index:300` (the lagging ring/dot) — the
  in-card cursor-follow chips use `z-index:9998/9999`.

### Smooth scroll (Lenis-style), vanilla

Reproduce Lenis with these exact options: `duration: 1.2`,
`easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t))`, vertical orientation, `smoothWheel:true`,
`wheelMultiplier:1`, `touchMultiplier:2`. Intercept `wheel`, accumulate a target scroll, and each rAF
ease the page toward target with this easing applied over the 1.2s feel; drive `window.scrollTo` (or a
transform on the content wrapper). On first init, jump to top immediately (`scrollTo(0,{immediate})`).
**Smooth scroll only starts after the preloader completes.** While loading: set
`history.scrollRestoration='manual'`, `window.scrollTo(0,0)`, and `document.body.style.overflow='hidden'`;
when loading ends, set overflow back to default and start the Lenis loop.

### Scroll → halo parallax zoom

While loaded, map `window.scrollY` `[0, 800]` → `scale [1, 1.2]` and apply it to the fixed halo
container (`transform: scale(...)`, `transform-origin:center`). While loading, keep scale `1`. Ease it
so it tracks the smoothed scroll, not raw jumps.

## The preloader (the hero moment — describe precisely)

A `position:fixed; inset:0; z-index:200` black panel, `display:flex; flex-direction:column;
align-items:center; justify-content:space-between; padding:2.5rem; cursor:none`. It is shown
immediately on load and removed when complete.

**Three rows, top-to-bottom:**

1. **Top counter row** (`width:100%`, flex space-between, JetBrains Mono, `font-size:0.75rem`,
   `letter-spacing:0.4em`, color `rgba(255,255,255,0.4)`; it animates in from `y:-20, opacity:0` to
   `y:0, opacity:1`):
   - Left: `[ SYSTEM_READY ]`
   - Right: the percentage, **zero-padded to 3 digits**, color white: `000%` … `100%`.
2. **Center**: a `position:relative; flex:1; width:100%; display:flex; align-items:center;
   justify-content:center; overflow:hidden` area containing a `<canvas>` (`width:100%; height:100%`)
   that draws a rotating 3D particle **sphere** (see below).
3. **Bottom**: a centered column, `gap:1.5rem`:
   - A cycling tag (JetBrains Mono, `font-size:0.875rem`, `letter-spacing:0.5em`, white), prefixed
     `/ `, that switches every **400ms** through this list in order, looping:
     `DATA INTELLIGENCE`, `NEURAL WORKFLOWS`, `SYSTEM AUTOMATION`, `SCALABLE SIGNALS`, `VEXON®`. Each
     switch animates the new tag in from `y:10, opacity:0` → `y:0, opacity:1` (and old out to `y:-10`).
   - A static line: JetBrains Mono, `font-size:10px`, uppercase, `letter-spacing:0.2em`,
     color `rgba(255,255,255,0.2)`: `Initializing Secure Environment`.

**Counter logic:** a `setInterval` every **20ms** increments progress by 1 up to 100. When it reaches
100: after **400ms**, hide the preloader (play its exit), then **600ms** after that, call the page's
`onComplete` (which flips `loading=false`, starts Lenis, and sets the halo's `start=true`).

**Exit animation:** the whole preloader animates out with `opacity:0`, `scale:1.05`,
`filter:blur(40px)` over **0.6s**, ease `cubic-bezier(0.76,0,0.24,1)`, then is removed.

### Preloader 2D particle sphere (canvas — verbatim)

Sized to its parent in device pixels (`canvas.width = width*dpr` etc., context scaled by dpr).
600 particles on a unit sphere via Fibonacci sphere, projected with perspective, rotated each frame,
radius growing with progress, fading in with progress. Reproduce exactly:

```js
const particles = [];
const particleCount = 600;
for (let i = 0; i < particleCount; i++) {
  const phi = Math.acos(-1 + (2 * i) / particleCount);
  const theta = Math.sqrt(particleCount * Math.PI) * phi;
  particles.push({
    x: Math.cos(theta) * Math.sin(phi),
    y: Math.sin(theta) * Math.sin(phi),
    z: Math.cos(phi),
    size: Math.random() * 1.5 + 0.3,
    alpha: Math.random() * 0.7 + 0.3,
    color: Math.random() > 0.4 ? '#FFFFFF' : '#444444',
  });
}
let rotation = 0;
let finishTime = null;

function render() {
  // w,h = parent client size; clear full canvas, re-apply dpr scale
  const currentProgress = progress / 100;          // progress is the 0..100 counter
  let animProgress = currentProgress;
  if (currentProgress >= 1) {
    if (!finishTime) finishTime = Date.now();
    const elapsed = (Date.now() - finishTime) / 1000;
    animProgress = 1 + elapsed * 0.1;              // keep growing 10%/s after 100%
  }
  const rotationSpeed = 0.006 * (1 + (1 - Math.min(1, animProgress)) * 0.5);
  rotation += Math.max(0.001, rotationSpeed);

  const baseRadius = Math.min(w, h) * 0.35;
  const radius = baseRadius * (0.2 + animProgress * 0.8);

  ctx.save();
  ctx.translate(w / 2, h / 2);
  const sorted = particles.map(p => {
    const rx = p.x * Math.cos(rotation) - p.z * Math.sin(rotation);
    const rz = p.x * Math.sin(rotation) + p.z * Math.cos(rotation);
    return { ...p, rx, rz };
  }).sort((a, b) => a.rz - b.rz);

  for (const p of sorted) {
    const perspective = 1000 / (1000 + p.rz * radius);
    const px = p.rx * radius * perspective;
    const py = p.y * radius * perspective;
    const size = p.size * perspective;
    const alpha = p.alpha * Math.min(1, currentProgress) * perspective;
    ctx.beginPath();
    ctx.arc(px, py, size, 0, Math.PI * 2);
    ctx.fillStyle = p.color;
    ctx.globalAlpha = Math.max(0, Math.min(1, alpha));
    ctx.fill();
  }
  ctx.restore();
  requestAnimationFrame(render);
}
```

## The WebGL / canvas scene — the particle halo (this is the project; reproduce exactly)

A Three.js `Points` cloud rendered into the fixed full-screen background div. All constants and math
below are verbatim and must be baked in.

### Renderer / camera / setup (verbatim)

```js
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, mount.clientWidth / mount.clientHeight, 0.1, 100);
camera.position.z = 4.2;

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, powerPreference: "high-performance" });
const pixelRatio = Math.min(window.devicePixelRatio, 2);
renderer.setPixelRatio(pixelRatio);
renderer.setSize(mount.clientWidth, mount.clientHeight);
renderer.setClearColor(0x000000, 0);
mount.appendChild(renderer.domElement);

const isMobile = mount.clientWidth < 768;
const count = isMobile ? 70000 : 160000;
const geometry = buildGeometry(count);

const material = new THREE.ShaderMaterial({
  vertexShader, fragmentShader,
  uniforms: {
    uTime:       { value: 0 },
    uSize:       { value: 14.0 },
    uPixelRatio: { value: pixelRatio },
    uProgress:   { value: 0 },
  },
  transparent: true,
  depthWrite: false,
  depthTest: false,
  blending: THREE.AdditiveBlending,
});

const points = new THREE.Points(geometry, material);
scene.add(points);
```

Also set the mount div's CSS background to the hot top-light plume (verbatim):
`radial-gradient(60% 50% at 50% 22%, rgba(120,170,255,0.18), rgba(40,80,180,0.05) 40%, transparent 70%)`.

### Geometry construction (verbatim — the donut/halo shape)

A fuzzy radial band: inner void radius `0.95`, band width `0.9`, soft-edged via a Box–Muller gaussian,
flattened toward the XY plane with a little Z depth. Per-particle `aScale` and `aSeed` attributes.

```js
function buildGeometry(count) {
  const positions = new Float32Array(count * 3);
  const scales = new Float32Array(count);
  const seeds = new Float32Array(count);

  const innerR = 0.95;     // radius of the dark void
  const bandWidth = 0.9;   // thickness of the glowing ring

  const gaussian = () => {
    let u = 0, v = 0;
    while (u === 0) u = Math.random();
    while (v === 0) v = Math.random();
    return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
  };

  for (let i = 0; i < count; i++) {
    const theta = Math.random() * Math.PI * 2;
    const r = innerR + Math.abs(gaussian()) * bandWidth * 0.55 + Math.random() * 0.15;
    const z = gaussian() * 0.18;
    positions[i * 3 + 0] = Math.cos(theta) * r;
    positions[i * 3 + 1] = Math.sin(theta) * r;
    positions[i * 3 + 2] = z;
    scales[i] = 0.5 + Math.random() * 1.6;
    seeds[i] = Math.random();
  }

  const geometry = new THREE.BufferGeometry();
  geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
  geometry.setAttribute("aScale", new THREE.BufferAttribute(scales, 1));
  geometry.setAttribute("aSeed", new THREE.BufferAttribute(seeds, 1));
  return geometry;
}
```

### Vertex shader (VERBATIM — copy exactly)

```glsl
  uniform float uTime;
  uniform float uSize;
  uniform float uPixelRatio;
  uniform float uProgress;

  attribute float aScale;
  attribute float aSeed;

  varying float vIntensity;
  varying vec3 vColor;

  // Ashima simplex noise (3D)
  vec4 permute(vec4 x){ return mod(((x*34.0)+1.0)*x, 289.0); }
  vec4 taylorInvSqrt(vec4 r){ return 1.79284291400159 - 0.85373472095314 * r; }

  float snoise(vec3 v){
    const vec2 C = vec2(1.0/6.0, 1.0/3.0);
    const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
    vec3 i  = floor(v + dot(v, C.yyy));
    vec3 x0 = v - i + dot(i, C.xxx);
    vec3 g = step(x0.yzx, x0.xyz);
    vec3 l = 1.0 - g;
    vec3 i1 = min(g.xyz, l.zxy);
    vec3 i2 = max(g.xyz, l.zxy);
    vec3 x1 = x0 - i1 + 1.0 * C.xxx;
    vec3 x2 = x0 - i2 + 2.0 * C.xxx;
    vec3 x3 = x0 - 1.0 + 3.0 * C.xxx;
    i = mod(i, 289.0);
    vec4 p = permute(permute(permute(
              i.z + vec4(0.0, i1.z, i2.z, 1.0))
            + i.y + vec4(0.0, i1.y, i2.y, 1.0))
            + i.x + vec4(0.0, i1.x, i2.x, 1.0));
    float n_ = 1.0/7.0;
    vec3 ns = n_ * D.wyz - D.xzx;
    vec4 j = p - 49.0 * floor(p * ns.z * ns.z);
    vec4 x_ = floor(j * ns.z);
    vec4 y_ = floor(j - 7.0 * x_);
    vec4 x = x_ * ns.x + ns.yyyy;
    vec4 y = y_ * ns.x + ns.yyyy;
    vec4 h = 1.0 - abs(x) - abs(y);
    vec4 b0 = vec4(x.xy, y.xy);
    vec4 b1 = vec4(x.zw, y.zw);
    vec4 s0 = floor(b0) * 2.0 + 1.0;
    vec4 s1 = floor(b1) * 2.0 + 1.0;
    vec4 sh = -step(h, vec4(0.0));
    vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
    vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
    vec3 p0 = vec3(a0.xy, h.x);
    vec3 p1 = vec3(a0.zw, h.y);
    vec3 p2 = vec3(a1.xy, h.z);
    vec3 p3 = vec3(a1.zw, h.w);
    vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));
    p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;
    vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
    m = m * m;
    return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));
  }

  void main() {
    vec3 pos = position;

    // --- Immersive entrance: a staggered fly-through that coalesces ---
    // Each particle resolves at its own moment for a sweeping, layered reveal.
    float stagger = aSeed * 0.45;
    float lp = clamp((uProgress - stagger) / 0.55, 0.0, 1.0);
    float entrance = 1.0 - pow(1.0 - lp, 4.0); // strong ease-out

    // Start scattered + blown outward, then converge inward.
    float expand = mix(2.4, 1.0, entrance);
    pos.xy *= expand;

    // Rush past the camera: particles begin large/close, then settle back.
    pos.z += (1.0 - entrance) * 3.4;

    // Spiral the whole field as it assembles.
    float swirl = (1.0 - entrance) * 4.5;
    float scs = cos(swirl);
    float ssn = sin(swirl);
    pos.xy = mat2(scs, -ssn, ssn, scs) * pos.xy;

    // Slow rotation of the whole halo around the view axis for life.
    float ang = uTime * 0.05;
    float cs = cos(ang);
    float sn = sin(ang);
    pos.xy = mat2(cs, -sn, sn, cs) * pos.xy;

    // Time-animated turbulence — heavier while entering, settling to a shimmer.
    float t = uTime * 0.18;
    vec3 noiseInput = pos * 1.2 + aSeed * 10.0;
    float nx = snoise(noiseInput + vec3(t, 0.0, 0.0));
    float ny = snoise(noiseInput + vec3(0.0, t, 5.0));
    float nz = snoise(noiseInput + vec3(0.0, 0.0, t + 9.0));
    vec3 turb = vec3(nx, ny, nz);
    pos += turb * 0.22 * mix(3.0, 1.0, entrance);

    // Subtle breathing pulse.
    pos *= 1.0 + 0.015 * sin(uTime * 0.6 + aSeed * 6.28);

    vec4 mvPosition = modelViewMatrix * vec4(pos, 1.0);

    // Lighting: brighter toward the top (+y), with a hot top-center plume.
    float vertical = clamp(pos.y * 0.5 + 0.5, 0.0, 1.0);
    float topGlow = smoothstep(0.55, 1.0, vertical);

    vec3 deepBlue = vec3(0.05, 0.18, 0.55);
    vec3 midBlue  = vec3(0.20, 0.45, 0.95);
    vec3 hotWhite = vec3(0.80, 0.92, 1.00);
    vec3 col = mix(deepBlue, midBlue, smoothstep(0.0, 0.7, vertical));
    col = mix(col, hotWhite, topGlow * 0.9);

    // Per-particle brightness jitter for the noisy, grainy texture.
    float spark = 0.6 + 0.5 * snoise(pos * 4.0 + aSeed * 3.0);
    vIntensity = (0.35 + 0.65 * vertical) * spark * entrance;
    vColor = col;

    gl_Position = projectionMatrix * mvPosition;
    gl_PointSize = uSize * aScale * uPixelRatio * (1.0 / -mvPosition.z);
  }
```

### Fragment shader (VERBATIM — copy exactly)

```glsl
  precision highp float;

  varying float vIntensity;
  varying vec3 vColor;

  void main() {
    // Soft round sprite with a bright core.
    vec2 uv = gl_PointCoord - 0.5;
    float d = length(uv);
    float alpha = smoothstep(0.5, 0.0, d);
    alpha *= alpha;
    float core = smoothstep(0.18, 0.0, d) * 0.6;

    vec3 color = vColor * (vIntensity + core);
    gl_FragColor = vec4(color, (alpha + core) * vIntensity);
  }
```

### Pointer parallax + animation loop (verbatim — this is the motion)

A soft pointer parallax rotates the whole point cloud; the entrance plays once `start` becomes true
(the preloader completion). `ENTRANCE_DURATION = 3.2` seconds.

```js
const pointer = { x: 0, y: 0 };
const target = { x: 0, y: 0 };
window.addEventListener("pointermove", (e) => {
  target.x = (e.clientX / window.innerWidth - 0.5) * 0.3;
  target.y = (e.clientY / window.innerHeight - 0.5) * 0.3;
});

const clock = new THREE.Clock();
const ENTRANCE_DURATION = 3.2;
let entranceStart = null;     // set on the first frame `start` is true
let running = true;

function animate() {
  if (!running) return;
  requestAnimationFrame(animate);
  const t = clock.getElapsedTime();
  material.uniforms.uTime.value = t;

  if (entranceStart === null && start) entranceStart = t;
  const progress = entranceStart === null ? 0 : Math.min((t - entranceStart) / ENTRANCE_DURATION, 1);
  material.uniforms.uProgress.value = progress;

  pointer.x += (target.x - pointer.x) * 0.04;
  pointer.y += (target.y - pointer.y) * 0.04;
  points.rotation.y = pointer.x;
  points.rotation.x = pointer.y;

  renderer.render(scene, camera);
}
animate();
```

On resize: update `camera.aspect`, `camera.updateProjectionMatrix()`, `renderer.setSize(w,h)`.
On `visibilitychange`: pause the loop when `document.hidden` (cancel rAF), resume on return
(call `clock.getDelta()` once to discard the gap so the shimmer doesn't jump, then `animate()`).

> Wiring: `start` is `false` while the preloader runs and flips to `true` the moment the preloader's
> `onComplete` fires — that single frame is when `entranceStart` latches and the fly-through begins.

## Page reveal & shared motion primitives

When `loading` becomes false, the entire content wrapper fades in (`opacity:0 → 1` over **1s**,
ease-out). Inside, use these reusable behaviors (reimplement Motion-style variants in vanilla JS,
driven by `IntersectionObserver`, trigger once):

- **itemVariants** (used for nav/hero blocks): from
  `{ y:100, opacity:0, rotateX:15deg, scale:0.9, filter:blur(10px) }` to
  `{ y:0, opacity:1, rotateX:0, scale:1, filter:blur(0) }` over **0.8s**, ease `cubic-bezier(0.16,1,0.3,1)`.
- **cardVariants** (the three image cards): same from/to but duration **1.6s**, ease `cubic-bezier(0.16,1,0.3,1)`.
- **containerVariants**: a container that staggers its children — `staggerChildren:0.1s`,
  `delayChildren:0.2s`. Apply per-child delay accordingly.
- Reveal-on-scroll containers use `viewport once`, and the card/about sections trigger at ~40% visible.

### TextEffect (per-character / per-word blur reveal)

A heading whose text is split into segments (per `char` or per `word`) each wrapped in an inline span;
on entering view (once, with a `-50px`/`-50px` margin) the spans stagger in. Per-char stagger
**0.03s**, per-word stagger **0.05s**. Each segment: `hidden { opacity:0, filter:blur(12px) }` →
`visible { opacity:1, filter:blur(0) }`. The whole effect supports a `delay` (delays the first child).
Spaces are preserved (`white-space:pre`). Use this for the hero headline lines and the two big section
headlines noted below.

## Layout & sections (in order). All copy is verbatim.

### Navigation (fixed, z-50)

`position:fixed; top:0; left:0; width:100%; display:flex; align-items:flex-start; justify-content:
space-between; padding:1.5rem` (mobile) / `padding:2rem 2.5rem` (md+).

- **Left** (animates in from `x:-20, opacity:0` → `x:0, opacity:1`): a column `gap:1.5rem`(md `2.5rem`):
  - Logo wordmark `VEXON` — `font-logo` (Orbitron), bold, `font-size:1.5rem`(md `1.875rem`),
    `letter-spacing:-0.05em` (tracking-tighter), color white.
  - (md+ only) JetBrains Mono `font-size:11px`, `letter-spacing:0.2em`, uppercase, color `#E6E6E6`
    at `opacity:0.5`: `[ V.01.3.N ]`.
- **Right** (animates in from `y:-10, opacity:0` → `y:0, opacity:1`): a column
  `align-items:flex-end; gap:0.5rem`. Three links, each: `font-size:11px`, `font-weight:500`,
  `letter-spacing:0.1em` (tracking-widest), uppercase, color `#8E9299`, hover color white,
  `display:flex; align-items:center; gap:0.25rem`, each followed by a lucide `arrow-up-right`
  SVG `w-3 h-3` that on group-hover translates `-0.125rem` up and `0.125rem` right. Links (href, label):
  - `#ai-intelligence` → `AI INTELLIGENCE`
  - `#about-vexon` → `ABOUT VEXON`
  - `#mission-intelligence` → `MISSION INTELLIGENCE`

### Section 1 — HERO (`#ai-intelligence`, `min-height:100vh`)

`display:flex; align-items:center; padding:8rem 1.5rem 10rem` (mobile) /
`padding:5rem 2.5rem 5rem` (md+). Inside, a `containerVariants` grid: `grid; grid-cols-1;
lg:grid-cols-12; lg:gap:2.5rem; width:100%`.

- **Left column** (`lg:col-span-8`, `display:flex; flex-direction:column; justify-content:center`):
  - Eyebrow (itemVariants): JetBrains Mono `font-size:10px`(md `11px`), `letter-spacing:0.2em`,
    color `#E6E6E6`, `margin-bottom:1.5rem`: `[ AI INTELLIGENCE ]`.
  - Headline `<h1>` (itemVariants wrapper): `font-display`, `font-weight:bold`, uppercase,
    `line-height:0.9`, `letter-spacing:-0.025em` (tracking-tight), color white, font-size
    `12vw` (mobile) / `8vw` (md) / `7vw` (lg). Three stacked lines, each a flex row:
    - Line 1 (a `div`, `display:flex; align-items:center; gap:1rem`): a **TextEffect** per-char blur,
      text `WHERE RAW DATA`, with style `mask-image: linear-gradient(to right, rgba(0,0,0,0.15),
      white 85%)`, `display:inline-block`, color white, `text-shadow / drop-shadow:0 0 15px
      rgba(255,255,255,0.2)`.
    - Line 2 (a `div`, `display:flex; align-items:center; gap:1rem`(md `2rem`), color `#E6E6E6`): a
      **DiamondStar** spinner sized `0.8em × 0.8em` (white), then a TextEffect per-char blur with
      `delay:0.5`, text `BECOMES YOUR`, white, `drop-shadow:0 0 20px rgba(255,255,255,0.3)`.
    - Line 3 (a `div`, `display:flex; align-items:center; gap:1rem`): a TextEffect per-char blur with
      `delay:1`, text `UNFAIR ADVANTAGE`, style `mask-image: linear-gradient(to right, white 15%,
      rgba(0,0,0,0.15))`, `display:inline-block`, white, `drop-shadow:0 0 15px rgba(255,255,255,0.2)`.
- **Right column** (`lg:col-span-4`, `display:flex; flex-direction:column; justify-content:flex-end;
  gap:2rem`(md `3rem`); `padding-top:3rem`; `padding-bottom:3rem`(md `5rem`); `transform:translateY(58px)`):
  - (itemVariants) a row `display:flex; align-items:center; justify-content:space-between`:
    - Left: `font-size:1.875rem`(md `2.25rem`), `font-weight:300`, color `#E6E6E6`,
      `letter-spacing:-0.05em`: `( ` then a `<span>` (JetBrains Mono, bold) `A` then ` )` →
      renders as `( A )`.
    - Right: JetBrains Mono `font-size:10px`(md `11px`), `letter-spacing:0.2em`, color `#E6E6E6`:
      `[ 001 / 003 ]`.
  - (itemVariants) a paragraph `max-width:20rem`, `font-size:0.75rem`(md `0.875rem`),
    `line-height:relaxed`, color `#E6E6E6`:
    `Vexon AI unifies data, workflows, and signals into one intelligence system so SaaS teams can automate decisions and scale smarter.`
  - (itemVariants) an actions row `display:flex; flex-wrap:wrap; align-items:center; gap:1rem`(md `1.5rem`):
    - A **button** `position:relative; overflow:hidden; border-radius:2px; background:rgba(0,0,0,0.6);
      backdrop-filter:blur(64px); padding:0.75rem 1.5rem`(md `1rem 2rem`); `font-size:12px`(md `14px`);
      `font-weight:500`; `letter-spacing:0.025em`; color white; `border:1px solid rgba(255,255,255,0.3)`;
      hover `background:rgba(0,0,0,0.8)`. It has two **corner brackets**: top-right
      `position:absolute; top:0; right:0; width:1rem; height:1rem; border-top:2px; border-right:2px;
      border-color:rgba(255,255,255,0.6)`; bottom-left mirrored (`border-bottom + border-left`); both
      scale `1.1` on group-hover. Label `<span>` `position:relative; z-index:10; uppercase;
      letter-spacing:0.1em`: `building with ai`.
    - A text button: `font-size:12px`(md `14px`), `font-weight:500`, color white, hover `opacity:0.7`:
      `Watch Demo`.

**DiamondStar** = a `<div>` spinning `rotateY:0→360deg` over **3s linear infinite**
(`transform-style:preserve-3d`) wrapping an SVG `viewBox="0 0 100 100"` `fill:currentColor` with path
`M50 0C50 35 65 50 100 50C65 50 50 65 50 100C50 65 35 50 0 50C35 50 50 35 50 0Z` (a four-point
diamond/star). Used in the hero (white) and in section 3.

### Section 2 — ABOUT / CARDS (`#about-vexon`, `min-height:100vh`)

`background:rgba(0,0,0,0.4); backdrop-filter:blur(64px); border-top:1px solid rgba(255,255,255,0.05);
display:flex; flex-direction:column; justify-content:center; padding:5rem 1.5rem`(md `5rem 2.5rem`).

**Intro grid** (containerVariants, reveal at 40% once): `margin-bottom:5rem; display:grid;
grid-cols-1; lg:grid-cols-12; gap:3rem`:
- Left (`lg:col-span-4`, itemVariants): JetBrains Mono `font-size:11px`, `letter-spacing:0.2em`,
  color `#E6E6E6` at `opacity:0.5`, uppercase: `/ about vexon`.
- Right (`lg:col-span-8`):
  - An `<h2>` **TextEffect per-word** blur: `font-display`, `margin-bottom:2rem`, `font-size:1.875rem`
    (md `3rem`), `font-weight:500`, `line-height:tight`, color white, `lg:max-width:56rem`,
    `letter-spacing:-0.025em`, text:
    `Our technology analyzes subtle data cues, emotional patterns, and visual energy signatures to generate a personalized reading just for you.`
  - A paragraph (itemVariants): `max-width:42rem`, `font-size:0.875rem`(md `1rem`),
    `line-height:relaxed`, color `#E6E6E6` at `opacity:0.6`, `font-weight:300`:
    `Think of it as a mirror for your inner world—revealing the colors, moods, and energy you project into the universe. Whether you're here for self-discovery, spiritual curiosity, or just for fun.`

**Cards grid** (containerVariants, reveal at 40% once): `display:grid; grid-cols-1; md:grid-cols-3;
gap:1rem`. Three cards, each (cardVariants): `group; position:relative; aspect-ratio:4/5;
overflow:hidden; border-radius:0.375rem; background:rgba(0,0,0,0.1); backdrop-filter:blur(12px);
border:1px solid rgba(255,255,255,0.1)`.

Each card contains, layered:
- Top-right corner bracket (`z-40; w-5 h-5; border-top:2px; border-right:2px;
  border-color:rgba(255,255,255,0.4)`) and bottom-left mirrored bracket.
- Top-left index label (`z-40; top-4 left-4`): JetBrains Mono `font-size:10px`,
  `color:rgba(255,255,255,0.4)`, uppercase, `letter-spacing:0.1em`: `[1]` / `[2]` / `[3]`.
- A **CursorProvider** region (full size) that hosts a **CursorFollow** chip (see "In-card cursor"):
  a pill `z-50; padding:0.375rem 0.75rem; border-radius:9999px; background:white; color:black;
  font-size:10px; font-mono; uppercase; letter-spacing:0.1em; box-shadow:2xl; display:flex;
  align-items:center; gap:0.375rem; border:1px solid rgba(0,0,0,0.1); white-space:nowrap` with a label
  + a lucide `arrow-up-right` `w-3.5 h-3.5 stroke-[2.5]`. Card labels: `Read More`, `Explore`, `Deploy`.
- A **HoverCardImage** (the parallax image, see below) using the card's image URL.
- A bottom gradient caption block (`z-10; position:absolute; inset-x:0; bottom:0; height:50%;
  background:linear-gradient(to top, rgba(0,0,0,0.9), rgba(0,0,0,0.2) ~50%, transparent); padding:2rem;
  display:flex; flex-direction:column; justify-content:flex-end; pointer-events:none`):
  - Title: `font-display; font-size:1.5rem; font-weight:500; color:white; letter-spacing:-0.025em`.
  - Description: `margin-top:0.5rem; font-size:0.875rem; line-height:relaxed; color:#E6E6E6;
    opacity:0.7; font-weight:300`.

The three cards (image URL, alt, chip, title, description):
1. img `/assets/card-signal-capture.png`, alt `Digital Architecture`,
   chip `Read More`, title **Signal Capture**, desc:
   `Every click, churn signal, and revenue event — ingested in real time. No SQL. No data team required.`
2. img `/assets/card-pattern-engine.png`, alt `Perception Network`,
   chip `Explore`, title **Pattern Engine**, desc:
   `AI surfaces what matters: who's about to convert, who's about to leave, and why — before it happens.`
3. img `/assets/card-action-layer.png`, alt `Energy Background`,
   chip `Deploy`, title **Action Layer**, desc:
   `Triggers that fire automatically. Slack alerts, CRM updates, onboarding flows — driven by data, not gut feeling.`

**HoverCardImage** (parallax image inside each card): two stacked layers. A top transparent
hit-layer (`absolute inset-0 z-30`) tracks the mouse within the card and the image (below it,
`absolute inset-0 z-0; display:flex; align-items:center; justify-content:center; overflow:hidden`):
the `<img>` is `height:100%; width:100%; object-fit:cover; opacity:0.6` (group-hover `opacity:0.9`
over `0.7s`), `referrerpolicy="no-referrer"`. Its motion:
- `scale` springs between **0.65** (idle) and **0.95** (hovered), spring `stiffness:60, damping:25`.
- An x/y parallax: track normalized cursor `[0..1]` within the card, spring it (`stiffness:80,
  damping:20`), and map `[0,1] → [-25px, 25px]` for both `x` and `y` translate. On mouse-leave reset
  cursor to `0.5, 0.5` and unhover.

### Section 3 — MISSION / MODULAR GRID (`#mission-intelligence`, z-10)

`position:relative; border-top:1px solid rgba(255,255,255,0.05); background:#000; font-sans`.

**Top grid** (`display:grid; grid-cols-1; md:grid-cols-4; border-bottom:1px solid rgba(255,255,255,0.05)`):
- **Box 1** (`min-height:200px; display:flex; flex-direction:column; justify-content:space-between;
  padding:2rem; border-bottom:1px solid rgba(255,255,255,0.05)` (md: no bottom border)):
  - Top: `font-logo` (Orbitron) `font-size:1.25rem; font-weight:bold; letter-spacing:-0.05em;
    color:white; opacity:0.8`: `VEXON®`.
  - Bottom: JetBrains Mono `font-size:9px; uppercase; letter-spacing:0.3em; color:white; opacity:0.4`:
    `[ established 2024 ]`.
- **Box 2** (`md:col-span-3; display:flex; flex-direction:column; justify-content:center;
  padding:2rem`(lg `3rem`); `border-bottom:1px solid rgba(255,255,255,0.05)`):
  - Label: JetBrains Mono `font-size:10px; uppercase; letter-spacing:0.4em; color:white; opacity:0.3;
    margin-bottom:1rem`: `/ mission intelligence:`.
  - An `<h3>` `font-display; font-weight:bold; line-height:0.9; uppercase; letter-spacing:-0.025em;
    color:white`, font-size `12vw`(md `8vw`/lg `7vw`). Inside, a `span` `display:flex; flex-wrap:wrap;
    align-items:center; column-gap:1rem`: TextEffect per-char `Figures for any` (white), then TextEffect
    per-char `delay:0.5` `innovation` (with `mask-image:linear-gradient(to right, rgba(0,0,0,0.15),
    white 85%)`, `drop-shadow:0 0 15px rgba(255,255,255,0.2)`), then a DiamondStar `0.8em × 0.8em` (white).

**Bottom grid** (`display:grid; grid-cols-1; md:grid-cols-4`):
- **Box 3** (`display:none` on mobile, `md:block`) — an empty spacer column.
- **Box 4** (`display:flex; flex-direction:column; gap:1.5rem; padding:2rem; border-bottom:1px solid
  rgba(255,255,255,0.05)` (md none)):
  - A `w-8 h-8` square `display:flex; align-items:center; justify-content:center; border-radius:2px;
    border:1px solid rgba(255,255,255,0.1); background:rgba(255,255,255,0.05)` containing a
    `w-1 h-1 rounded-full bg-white` dot that **pulses** (opacity animation, ~2s ease-in-out infinite).
  - JetBrains Mono `font-size:10px; uppercase; letter-spacing:0.2em; color:white; opacity:0.4`:
    `propulsion systems for modern workflows.`
- **Box 5** (`md:col-span-2; display:flex; flex-direction:column; justify-content:center;
  padding:2rem`(lg `3rem`)):
  - A paragraph `max-width:36rem; font-size:0.875rem`(md `1rem`); `font-weight:300; line-height:relaxed;
    color:white; opacity:0.6`:
    `Transform your raw data signatures into high-fidelity patent figures and technical schemas. Our rendering engine produces clean, publication-ready visuals across complex diagrams, UI architecture, and neural mapping patterns.`
  - `margin-top:2rem`, a button row: a group button `display:flex; align-items:center; gap:0.5rem;
    font-size:11px; font-weight:500; uppercase; letter-spacing:0.2em; color:white; hover opacity:0.7`:
    `Read philosophy` + lucide `arrow-up-right` `w-3 h-3` (translates up-right on group-hover).

**Marquee** (`width:100%; overflow:hidden; border-top:1px solid rgba(255,255,255,0.05);
padding:3rem 0`(md `5rem 0`)): an inline-flex track `white-space:nowrap` animating
`transform: translateX(0) → translateX(-50%)` via `@keyframes marquee` over **40s linear infinite**,
`hover` pauses it (`animation-play-state:paused`). The track contains the company list **twice** (for
seamless loop): `Medium, Outreach, Adobe, Framer, Amazon, GitHub, Hopin, Notion, Linear, Vercel`. Each
item: `margin:0 2rem`(md `0 4rem`); `font-size:32px`(md `48px`); `font-weight:bold;
letter-spacing:-0.05em; color:rgba(255,255,255,0.2)`; on hover `scale:1.1` and color white
(transition all); `cursor:default`.

### Footer

`position:relative; z-10; width:100%; padding:5rem 1.5rem 3rem`(md `… 4rem 2.5rem`); `background:#000`.
Contains one decorative element: an `absolute inset-x-0 top-0 h-40 -z-10 backdrop-blur-xl` div with the
`.progressive-blur` mask: `mask-image: linear-gradient(to top, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 40%,
rgba(0,0,0,0.8) 60%, rgba(0,0,0,0) 100%)` — a soft top-edge blur fade. No footer text content.

## The custom cursor systems

### Global cursor (CursorFollower) — site-wide, z-300

A `pointer-events:none; position:fixed; inset:0; z-index:300` layer with two children that lerp toward
the mouse each rAF (reimplement verbatim):
- A **dot**: `width:10px; height:10px; border-radius:9999px; background:white; mix-blend-mode:difference;
  transform:translate(-50%,-50%)`; its position lerps to the mouse with factor **0.2** each frame.
- A **ring**: `border-radius:9999px; border:1px solid rgba(255,255,255,0.3); transform:translate(-50%,
  -50%); transition: width 0.3s, height 0.3s`; position lerps with factor **0.1** (lags behind). Size
  is **40px × 40px** normally, **80px × 80px** while hovering an interactive element. Attach
  `mouseenter`/`mouseleave` to all `a, button, img, input, textarea, select` (use a `MutationObserver`
  to re-bind as DOM changes) to toggle the hovering state.

```js
dotPos.x = lerp(dotPos.x, mouse.x, 0.2);
dotPos.y = lerp(dotPos.y, mouse.y, 0.2);
borderPos.x = lerp(borderPos.x, mouse.x, 0.1);
borderPos.y = lerp(borderPos.y, mouse.y, 0.1);
```

### In-card cursor (CursorFollow chip) — per card

Inside each image card, when the mouse moves over the card the white "Read More / Explore / Deploy"
chip appears and **springs to follow the cursor** with spring `stiffness:500, damping:50, bounce:0`,
positioned bottom-right of the cursor with a `sideOffset:15`. It mounts in from `scale:0, opacity:0`
→ `scale:1, opacity:1` and exits the reverse when the mouse leaves the card. While active over a card,
set that card's cursor to `none` (the chip + the global dot stand in). Track the cursor relative to the
card's parent bounding rect.

## Fixed parameters (bake these in)

- Halo: `PerspectiveCamera(45, aspect, 0.1, 100)`, `camera.position.z = 4.2`. Renderer pixelRatio
  `min(dpr, 2)`, `alpha:true`, `setClearColor(0x000000, 0)`, AdditiveBlending, `depthWrite:false`,
  `depthTest:false`. Point count **160000** desktop / **70000** mobile (`<768px`). Uniforms:
  `uSize=14.0`, `uPixelRatio=min(dpr,2)`. Geometry: innerR `0.95`, bandWidth `0.9`, z `gaussian*0.18`,
  `aScale = 0.5 + rand*1.6`. Entrance duration **3.2s**; pointer parallax lerp **0.04**, mapped from
  cursor `(e/win - 0.5) * 0.3`; idle halo spin `uTime*0.05`; turbulence time `uTime*0.18`.
- Preloader: 600 sphere particles, counter tick **20ms**/+1, tag switch **400ms**, hold **400ms** at
  100% then exit (`opacity:0, scale:1.05, blur(40px)`, **0.6s**, `cubic-bezier(0.76,0,0.24,1)`), then
  **600ms** before `onComplete`. Sphere `baseRadius = min(w,h)*0.35`, `radius = baseRadius*(0.2 +
  animProgress*0.8)`, perspective `1000/(1000 + rz*radius)`, post-100% growth `+0.1/s`.
- Lenis: `duration:1.2`, easing `Math.min(1, 1.001 - Math.pow(2, -10*t))`, `wheelMultiplier:1`,
  `touchMultiplier:2`. Halo scroll-zoom: `scrollY [0,800] → scale [1,1.2]`.
- Motion: itemVariants 0.8s, cardVariants 1.6s, container stagger 0.1s / delayChildren 0.2s, all ease
  `cubic-bezier(0.16,1,0.3,1)`; page-in 1s ease-out. TextEffect: char stagger 0.03s, word stagger
  0.05s, item blur 12px→0. Card image scale 0.65↔0.95 spring(60,25); parallax ±25px spring(80,20).
- DiamondStar spin 3s linear infinite. Marquee 40s linear infinite (pause on hover).
- Global cursor: dot 10px white mix-blend-difference lerp 0.2; ring 40↔80px border `rgba(255,255,255,
  0.3)` lerp 0.1. In-card chip spring (500,50,0), sideOffset 15, bottom-right.
- Colors: page `#000`; accent text `#E6E6E6`; muted nav `#8E9299`; shader palette deepBlue
  `vec3(0.05,0.18,0.55)`, midBlue `vec3(0.20,0.45,0.95)`, hotWhite `vec3(0.80,0.92,1.00)`; mount
  plume `radial-gradient(60% 50% at 50% 22%, rgba(120,170,255,0.18), rgba(40,80,180,0.05) 40%,
  transparent 70%)`. Fonts: Orbitron (logo), Space Grotesk (display), Inter (body), JetBrains Mono (labels).

## Assets

No local model/texture/font files — the halo and preloader sphere are fully procedural. The only
card images are the three About-card photos bundled under `public/assets/`, served from these real
local paths (keep `referrerpolicy="no-referrer"`):
- `/assets/card-signal-capture.png` (card 1 — Signal Capture)
- `/assets/card-pattern-engine.png` (card 2 — Pattern Engine)
- `/assets/card-action-layer.png` (card 3 — Action Layer)

## MOTDES 源码对照说明

以上完整保留原下载页面的单 HTML 重建要求,仅将三张卡片图片换成源码包已有的真实本地路径。若目标是复现本次源码包,而不是早期重建要求,请以本次源码为准并注意以下差异:

- 本次参考实现是 Next.js 16.3.7、React 19.3.0、Tailwind CSS 4 项目;页面由 `src/app/page.tsx` 委托 `src/views/home.tsx`,全部文案在 `src/data/mocks/home.ts`。原文要求生成单文件 HTML,不代表源码包本身就是单文件 HTML
- 源码使用 `@react-spring/web` 实现页面动效,使用 Lenis 平滑滚动,Three.js 固定为 0.169.0;字体经 `next/font/google` 构建时获取并自托管。不要将原文的 vanilla JS 约束误当成现有 Next.js 依赖清单
- 当前源码保留原生鼠标指针,细指针设备额外显示跟随圆点与圆环;触屏设备关闭浮动指针及卡片跟随标签。原文隐藏原生指针的要求属于早期版本,现有源码已调整
- 当前源码包含 cookie 偏好栏、`/privacy-policy` 通用隐私文案和用于爬虫的 `/robot-view` 静态首页;普通用户访问 `/robot-view` 会跳回首页。这些是下载包已有内容,不是新加业务页面
- 首页三处 CTA `building with ai`、`Watch Demo`、`Read philosophy` 均未绑定业务操作,三张卡片也没有目标文章页面;请保持这一实际状态,不虚构注册、视频播放、提交、部署或文章跳转
- `public/assets/card-signal-capture.png`、`card-pattern-engine.png`、`card-action-layer.png` 为完整随包图片;`public/assets/robot/orb-desktop.webp` 和 `orb-mobile.webp` 是爬虫/降级静态粒子图。素材不依赖原平台 CDN
- `src/app/api/contact/route.ts` 是未在首页使用的联系 API 示例,可选择 `CONTACT_ENDPOINT` 上游,默认不连接外部业务。示例隐私文案及品牌横排不是实际客户证明
- 手机端逐字标题按单词整体换行,并使用 `--text-hero-fit` 适配宽度;减少动态效果和爬虫静态模式按源码保留。上文参数描述是原始重建要求,不代表本次已通过真机验收或性能复测
[/hidecontent]
← 返回首页