Halcyonn
aadmin2026-10-17 发布Site模板0 阅读

Halcyonn

类型:Site模板 · 收录:2026-10-17 12:02:23 · 源码:会员可见

[hidecontent type="vip1"]
# Prompt: Recreate the Synaptiq Hero Section (exact spec)

Copy everything below the line into your AI coding tool.

---

Build a single-file `index.html` (inline CSS + vanilla JS, no frameworks, no build step) that recreates the **Synaptiq** hero section **exactly** as specified. It is a full-viewport, dark, grainy "neuro-tech studio" landing hero with a dotted blueprint frame, a centered two-line headline, monospace body copy, two CTAs, a stats row, and three frosted-glass cards that play looping videos. Follow every value literally.

## 1. Media assets (use these exact URLs)

Three cards, each a looping muted video with a still poster:

| # | Video (`src`) | Poster (`poster`) | Accessible label |
|---|---|---|---|
| 01 | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_112045_3d09b14a-44a9-4830-bc86-d6d8e460bedf.mp4` | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_111754_0c3978f2-425f-4ae0-99c8-c780e92a324c.png` | Translucent glass head with orange and blue light refracting through it like neural pathways |
| 02 | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_112045_fc31ee88-6c5a-4665-847a-e9b407066c57.mp4` | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_111752_ae6b51f4-e325-4738-9e67-dade05812a36.png` | Open palm beneath a floating glass prism refracting blue and orange light |
| 03 | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_112045_b9226ac8-aa60-41f7-92d5-3a6cfa93575d.mp4` | `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20261014_111752_01ce2f34-8072-41a2-8379-d69c699e6fd1.png` | Person in fog wearing a minimal visor headset lit by a thin orange line |

Videos are 834×1112 H.264, 5 s, no audio, and were generated so the last frame returns to the first, so they loop.
Markup per card:

```html
<video src="VIDEO_URL" poster="POSTER_URL" aria-label="LABEL" width="1058" height="1152"
       muted loop playsinline preload="metadata"></video>
```

**Grain texture:** the background uses a tiling 256×256 film-grain image. If you don't have `grain.webp`, generate it inline as an SVG data URI:
`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='256' height='256'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")`
Store it in a CSS variable `--grain`.

## 2. Fonts

- **Geist** weights 400 / 500 / 600 (headline, logo)
- **Geist Mono** weights 400 / 500 (nav, paragraph, buttons, stats, labels)

Load from Google Fonts:
```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=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500&display=block" rel="stylesheet">
```
Stacks:
`--sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;`
`--mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;`
Body: `-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: geometricPrecision;`

## 3. Head

```html
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#0f0f0f">
<title>Synaptiq</title>
<meta name="description" content="Synaptiq — calm neural interfaces that turn intent into action.">
```

## 4. Design tokens (`:root`)

```css
color-scheme: dark;
--bg: #0f0f0f;
--ink: #ededed;        /* headline, logo */
--ink-2: #d3d3d3;      /* side label, stats */
--nav: #a6a6a6;        /* nav links */
--sub: #afafaf;        /* hero paragraph */
--meta: #a4a4a4;       /* footer meta */
--accent: #d2582b;     /* primary CTA, stat dividers */
--accent-hi: #e0653a;  /* CTA hover, card index tags */
--on-accent: #0f0f0f;
--cta-ink: #e9e9e9;
--guide: rgba(255,255,255,.17);
--dash: rgba(255,255,255,.47);
--rim-a: rgba(255,255,255,.78);
--rim-b: rgba(255,255,255,.22);
--rim-c: rgba(255,255,255,.58);
--card-veil: rgba(130,130,130,.08);
--frost: rgba(190,205,255,.20);   /* inner glow of glass cards */
--halo: rgba(120,150,255,.12);    /* outer glow of glass cards */
```

### The unit system (critical)
On desktop the whole hero is a **1440 × 1024 artboard** scaled to fit. Every desktop measurement below is in "design px" and is written `calc(var(--u) * N)`:

```css
--vh: 1vh;   /* use 1dvh inside @supports (height:1dvh) */
--u: min(calc(100vw / 1440), calc(var(--vh) * 100 / 1024));
--ex: max(0px, calc(var(--vh) * 100 - var(--u) * 1024)); /* leftover height, shared into layout */
```

Global: `box-sizing: border-box` on everything; `html, body` margin/padding 0. `html` background `--bg`. `body` background is `var(--bg) var(--grain) 0 0 / calc(var(--u)*256) repeat`. Text color `--ink`. Links inherit color and have no underline. `:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px }`.

### Dashed boxes (`.dash-box`)
Exact 2px-dash / 2px-gap borders built from 4 background gradients, not `border-style: dashed`:
```css
.dash-box{ --d:var(--dash); --t:max(1px,var(--u));
 background:
  repeating-linear-gradient(90deg,var(--d) 0 calc(var(--u)*2),transparent 0 calc(var(--u)*4)) left top / 100% var(--t) no-repeat,
  repeating-linear-gradient(90deg,var(--d) 0 calc(var(--u)*2),transparent 0 calc(var(--u)*4)) left bottom / 100% var(--t) no-repeat,
  repeating-linear-gradient(180deg,var(--d) 0 calc(var(--u)*2),transparent 0 calc(var(--u)*4)) left top / var(--t) 100% no-repeat,
  repeating-linear-gradient(180deg,var(--d) 0 calc(var(--u)*2),transparent 0 calc(var(--u)*4)) right top / var(--t) 100% no-repeat; }
```

## 5. Structure (exact DOM order)

```
div.frame#frame
  span.guide.guide--v.guide--l   span.guide.guide--v.guide--r
  span.guide.guide--h.guide--t   span.guide.guide--h.guide--b
  span.cross.cross--tl  .cross--tr  .cross--bl  .cross--br     (all aria-hidden)
  header.header
    a.logo[aria-label="Synaptiq home"]  "Synaptiq"
    nav.menu#menu[aria-label="Primary"]
      ul.nav > li > a  "Studio"(#vision) "Signals"(#systems) "Careers"(#join) "Connect"(#contact)
      a.btn-call.dash-box(#contact)  "Book A Demo"
    button.menu-toggle.dash-box[aria-controls=menu][aria-expanded=false]
      span.bars[aria-hidden]  span.sr-only "Menu"
  main.hero#vision
    h1 > span.heading-line > span.heading-line-inner "Wiring Thought Into Form"
       > span.heading-line > span.heading-line-inner "One Pulse At A Time"
    p  "Synaptiq builds quiet neural tools that sense intent, not clicks —<br> so each new idea travels from mind to screen, intact."
    div.ctas
      a.btn.btn--primary(#vision)          "Watch The Showreel"
      a.btn.btn--ghost.dash-box(#join)     "Join The Pilot Cohort"
    ul.stats[aria-label="Studio at a glance"]
      li "340 test pilots"  li "12 labs"  li "zero keystrokes"
  ul.cards#systems[aria-label="Featured work"]
    li.card > span.card-tag[aria-hidden] "01" + video (card 01)
    li.card > span.card-tag[aria-hidden] "02" + video (card 02)
    li.card > span.card-tag[aria-hidden] "03" + video (card 03)
  footer.foot
    div.side  "// Clinical pilot v3"
    p.meta    "// Synaptiq Labs · OSLO | 09:41 CET"
```

## 6. Desktop layout (artboard mode, default)

`.frame`: `position:relative; width:100%; height:calc(var(--vh)*100); overflow:hidden; isolation:isolate`.

**Guide frame** (dotted lines, z-index 0, pointer-events none):
- Vertical guides: `top:0; bottom:0; width:max(1px,var(--u))`, background `repeating-linear-gradient(180deg, var(--guide) 0 calc(u*2), transparent 0 calc(u*4))`.
- Horizontal guides: `left:0; right:0; height:max(1px,var(--u))`, same gradient at 90deg.
- Positions: `.guide--l left: u*64.35` · `.guide--r right: u*63.5` · `.guide--t top: u*63` · `.guide--b bottom: u*65`.

**Registration crosses** (`+`, z-index 1): `u*7` square, two centered white `#fff` 1px gradient bars (horizontal + vertical).
- `.cross--tl` left `u*65`, top `u*63.5`, `translate(-50%,-50%)`
- `.cross--tr` right `u*64`, top `u*63.5`, `translate(50%,-50%)`
- `.cross--bl` left `u*65`, bottom `u*65.5`, `translate(-50%,50%)`
- `.cross--br` right `u*64`, bottom `u*65.5`, `translate(50%,50%)`

**Header** (absolute, top, height `u*63`, z-index 3):
- `.logo`: left `u*87.3`, top `u*22.1`; `font: 500 max(u*22, 15px)/1 var(--sans)`; letter-spacing `-.02em`; color `--ink`.
- `.nav`: left 50%, top `u*25.8`, `translateX(-50%)`, flex, gap `u*16.5`, no list styles; `font: 500 max(u*13.4, 11px)/1 var(--mono)`; color `--nav`; links transition color .2s.
- `.btn-call`: right `u*81.25`, top `u*15.8`, size `u*161.65 × u*33.1`, flex-centered; `font: 500 max(u*13.3, 11px)/1 var(--mono)`; color `--cta-ink`; transition background-color .2s.
- `.menu-toggle`: `display:none` on desktop.

**Side label** `.side`: absolute, left `u*38.8`, top `u*83`, z-index 2, `writing-mode: vertical-rl; transform: rotate(180deg)` (reads bottom-to-top); `font: 400 max(u*11.36, 9.5px)/1 var(--mono)`; color `--ink-2`.

**Footer meta** `.meta`: absolute, right `u*81.8`, bottom `u*25`; `font: 400 max(u*11.4, 9.5px)/1 var(--mono)`; color `--meta`.

**Hero** `.hero`: absolute, left/right 0, `top: calc(var(--ex) * .30)`, height `u*512`, z-index 2, text-align center.
- `h1`: absolute, top `u*136`; `font: 600 calc(u*64.4)/1.2 var(--sans)`; letter-spacing `-.03em`; color `--ink`. Each `.heading-line` is `display:block; overflow:hidden` (mask for the slide-up reveal); `.heading-line-inner` is `display:block`.
- `p`: absolute, top `u*314.5`; `font: 400 max(u*17.09, 12px)/max(u*21.8, 15.3px) var(--mono)`; color `--sub`.
- `.ctas`: absolute, left 50%, top `u*404.5`, `transform: translateX(calc(-50% + u*1.05))`, flex, gap `u*21`.
- `.btn`: inline-flex centered, height `u*46`, padding `u*2.8 u*36 0`; `font: 500 max(u*17.12, 12px)/1 var(--mono)`; transitions on background-color and color, .2s.
  - `.btn--primary`: background `--accent`, color `--on-accent` (dark text on orange).
  - `.btn--ghost`: dashed box, color `--cta-ink`, horizontal padding `u*37.05`.
- `.stats`: absolute, left/right 0, top `u*476`, flex centered, gap `u*28`; `font: 400 max(u*14, 11px)/1 var(--mono)`; color `--ink-2`. Between items (`li + li::before`): an inline-block **orange vertical bar**, width `max(1px,u)`, height `1em`, background `--accent`, margin-right `u*28`, `vertical-align: -.12em`.

**Cards** `.cards`: absolute, z-index 2, left 50%, `translateX(-50%)`, `top: calc(u*527.9 + var(--ex)*.42)`, `height: calc(u*388.3 + var(--ex)*.45)`, `width: calc(u*(371.55*3 + 24.3*2))`, 3-column grid, gap `u*24.3`, no list styles.

**Card = frosted glass tile** `.card`:
- `position:relative; overflow:hidden; border-radius: u*16; background:#0f0f0f; transform: translateZ(0); box-shadow: 0 0 calc(u*44) var(--halo)`.
- `video`: `display:block; width:100%; height:100%; object-fit:cover; transition: transform .8s cubic-bezier(.2,.7,.2,1)`.
- `::before` (frost layer, z-index 1, inset 0, radius inherit, pointer-events none):
  `background: linear-gradient(160deg, rgba(255,255,255,.10), transparent 38%, transparent 70%, rgba(150,170,255,.07)), var(--card-veil); box-shadow: inset 0 0 calc(u*26) var(--frost);`
- `::after` (glass rim, a 1px gradient stroke):
  `inset:0; border-radius:inherit; padding:max(1px,u); background: linear-gradient(to top right, var(--rim-a) 0%, var(--rim-b) 25%, var(--rim-b) 75%, var(--rim-c) 100%);`
  masked to only the stroke: `-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);`
- `.card-tag`: absolute, left `u*22`, top `u*21`, z-index 2; `font: 500 max(u*15, 11px)/1 var(--mono)`; color `--accent-hi` (orange "01", "02", "03").

## 7. Responsive

### Tablet / tall screens
Media query: `@media not all and (min-aspect-ratio: 11/10) and (min-width: 835px) and (min-height: 595px)`. Same DOM, re-flowed into a column:
```css
--tp: clamp(.82px, min(calc(100vw/1000), calc(var(--vh)*100/900)), 1px);
--g: clamp(12px, 4vw, 40px);                       /* guide inset */
--e: calc(var(--g) + clamp(12px, 3vw, 28px));      /* content inset */
--hh: calc(var(--tp)*63);  --fh: calc(var(--tp)*65);
--cg: calc(var(--tp)*24.3);
--row: min(calc(100vw - 2*var(--e)), calc(var(--tp)*1164.3));
--cw: calc((var(--row) - 2*var(--cg)) / 3);
```
- body grain size 256px; `.frame` becomes `height:auto; min-height:100vh; overflow:visible; display:flex; flex-direction:column`.
- Guides: `--u:1px`; l/r at `--g`, t at `--hh`, b at `--fh`; crosses 7px, offset `+.5px` from those lines.
- `.header`, `.hero`, `.cards`, `.foot`, `.side` set `--u: var(--tp)`. Header is relative, height `--hh`; logo left `--e`; Book A Demo right `--e`.
- `.hero`: relative, `margin-top:auto`, padding `tp*72.5 var(--e) 0`; h1/p/ctas/stats become static (no transforms).
  - h1 font-size `min(tp*64.4, (100vw - 2*--e)/11.7, vh*10)`.
  - p margin `tp*24 auto 0`, font-size `min(tp*17.09, (100vw - 2*--e)/40)`, line-height 1.276.
  - ctas flex centered, margin-top `tp*46.5`; stats margin-top `tp*26`.
- `.cards`: relative, `flex:1 1 0`, width `--row`, margin `tp*38 auto tp*42`, `min-height: calc(var(--cw)/.918)`, `max-height: calc(var(--cw)/.5)`, `grid-template-rows: minmax(0,1fr)`.
- `.foot`: flex, height `--fh`, `margin-top:auto`, items end, justify end, padding `0 var(--e) tp*25`; `.meta` static; `.side` left `calc(var(--g)/2 - .5em)`, top `calc(var(--hh) + tp*20)`.

### Mobile (`max-width: 619.98px`)
```css
--tp: clamp(.92px, calc(100vw/390), 1.12px);
--g: clamp(10px, 3.2vw, 16px);
--e: calc(var(--g) + clamp(10px, 3.2vw, 16px));
--hh: calc(var(--tp)*58);  --fh: calc(var(--tp)*60);  --mg: calc(var(--tp)*10);
```
- Logo vertically centred. Nav and Book A Demo move into a **dropdown sheet** (`.menu`): absolute, z-index 20, from `--hh + 1px` down to the bottom of the viewport, inset between the guides, grain background, hidden with `opacity:0; visibility:hidden; translateY(-8px)`. It opens with a .25s opacity/transform transition when `.frame.menu-open`.
  - Nav becomes a vertical list, `tp*18` mono text, each link padded `tp*18 0` with a dotted bottom rule. Book A Demo: static, margin-top `tp*30`, width `tp*161.65`, height 44px.
- `.menu-toggle`: visible 42×42 dashed box, right `calc(var(--e) - 9px)`. Two 16px×1px white bars at top 17px and +7px. When open they rotate into an **X** (top bar to 20.5px and 45°, second bar -90°), .25s.
- h1 `min((100vw - 2*--e)/11.7, 40px)`, line-height 1.16. p: margin-top `tp*16`, max-width 34em, `max(12.5px, tp*13.2)`, line-height 1.6, `text-wrap: pretty`, the `<br>` hidden.
- CTAs stack as a grid of equal width (`width: fit-content`), gap `tp*10`, margin `tp*26 auto 0`; `.btn` font `tp*14.5`, inline padding `tp*28`.
- Stats: margin-top `tp*20`, `flex-wrap: wrap`, gap `6px tp*14`, font `tp*12`; divider margin-right `tp*14`.
- **Cards become a mosaic**: width `100% - 2*--e`, gap `--mg`, 2 columns, areas `"a b" "c b"` (card 02 runs the full height on the right), `min-height: tp*300`, `max-height: calc((100vw - 2*--e - --mg)/2/.45)`, radius `tp*14`. Card tag at `tp*14 / tp*13`, font `tp*13`.
- Footer: side label goes horizontal and joins the meta line (flex-wrap, space-between, font `tp*10`, safe-area bottom padding).

## 8. Interactions

- Hover (only inside `@media (hover:hover)`): nav links go to `#fff`; Book A Demo and ghost CTA get background `rgba(255,255,255,.06)`; primary CTA goes to `--accent-hi`; a card's video scales to `1.03` (0.8s ease above).
- `@media (prefers-reduced-motion: reduce) { * { transition: none !important } }`.
- `html.menu-lock { overflow: hidden }` while the mobile menu is open.

**Video playback script:** if `prefers-reduced-motion: reduce` matches, pause every `.card video`, so only the poster shows. Otherwise call `play()` and catch any rejection. Re-run whenever that media query changes.

**Mobile menu script:**
- The toggle opens and closes the menu: it toggles `.menu-open` on the frame and `menu-lock` on html, and updates `aria-expanded` and the sr-only label ("Menu" / "Close menu").
- When opened from the keyboard (`event.detail === 0`), focus moves to the first link.
- Clicking a link inside the menu on mobile closes it.
- Escape closes it and returns focus to the toggle.
- Tab is trapped between the toggle and the menu's links.
- The menu closes automatically when the viewport leaves mobile width.

## 9. First-load entrance animation (exact timeline)

**Pre-paint guard** in `<head>`, before the CSS: if `'animate' in Element.prototype` and reduced motion is NOT requested, add `entrance-pending` to `<html>`. Also set a 4000 ms fallback timeout that removes it.

While `.entrance-pending`:
- `.logo, .nav, .btn-call, .menu-toggle, .hero p, .ctas .btn, .stats, .side, .meta` → `opacity:0`
- `.heading-line-inner` → `transform: translate3d(0,105%,0)`
- `.card` → `clip-path: inset(0 0 100% 0 round 16px)`

**On `window.load`**, in the next animation frame, run one Web Animations timeline:
- Every animation uses easing `cubic-bezier(.22,1,.36,1)` and `fill:'both'`.
- Animate only elements that are visible in the opening viewport.
- `rise` = 10px on desktop, 6px on mobile.

| Element | Effect | Delay (ms) | Duration (ms) |
|---|---|---|---|
| `.logo` | opacity 0→1 | 50 | 430 |
| `.nav` (desktop) / `.menu-toggle` (mobile, delay 130, 390) | opacity | 120 | 430 |
| `.btn-call` (desktop) | opacity | 210 | 430 |
| `.side` | opacity | 250 | 450 |
| heading line 1 | translateY 105% → 0 (masked slide-up) | 210 | 760 |
| heading line 2 | translateY 105% → 0 | 330 | 790 |
| `.hero p` | opacity 0→1 + translateY(rise)→0 | 610 | 540 |
| `.btn--primary` | opacity + rise | 810 | 510 |
| `.btn--ghost` | opacity + rise | 910 | 510 |
| `.stats` | opacity + rise | 1000 | 510 |
| card 1 / 2 / 3 | clip-path `inset(0 0 100% 0 round 16px)` → `inset(0 0 0 0 round 16px)` (reveal top-down) | 850 / 960 / 1070 | 820 |
| `.meta` | opacity | 1270 | 400 |

Remove `entrance-pending` right after creating the animations. When all of them finish, cancel them so no inline effects remain, clear the fallback timeout, and mark the timeline complete. Wrap the timeline in try/catch so any error jumps straight to the finished state.

## 10. Acceptance check

At 1440×900 you should see:
- Logo "Synaptiq" at top-left, the four nav links centred, and a dashed "Book A Demo" box at top-right.
- A dotted frame inset ~64px with white `+` marks at its four corners. The vertical label "// Clinical pilot v3" sits in the left gutter.
- The centred headline "Wiring Thought Into Form / One Pulse At A Time" in Geist Semibold, with the two-line monospace paragraph below it.
- An orange "Watch The Showreel" button beside the dashed "Join The Pilot Cohort" button.
- The stats row "340 test pilots | 12 labs | zero keystrokes" with orange dividers.
- Three glowing frosted-glass cards with orange 01/02/03 tags, each playing its looping video.
- "// Synaptiq Labs · OSLO | 09:41 CET" bottom-right.
[/hidecontent]
← 返回首页