Free
☁️ SaaS

Neuralyn

Dark analytics-SaaS landing: a parallax hero whose full-bleed video carries a luminosity-blended dashboard, followed by a testimonial that lights up word by word as you scroll.

1.5k views 52 copies 1.9k

Prompt 正文

# Neuralyn — Dark Analytics-Dashboard SaaS Landing

Build a dark landing page for "Neuralyn", an analytics dashboard SaaS, with these exact specs.

## Stack
React + Vite + Tailwind CSS + TypeScript + Framer Motion + shadcn/ui.

## Fonts
- Inter (400, 500, 600, 700) for body/UI, via `@fontsource/inter`
- Instrument Serif (400, 400-italic) for the italic accent word, via `@fontsource/instrument-serif`

## Color Theme
All HSL, dark mode by default in `:root`:
- Background: `0 0% 0%` (pure black)
- Foreground: `0 0% 100%` (pure white)
- Muted foreground: `0 0% 65%`
- Card: `0 0% 5%`
- Border: `0 0% 20%`
- Hero subtitle: `210 17% 95%`

## Section 1: Hero
Full viewport height, `overflow-hidden`.

### Navbar
Horizontal, padded `px-8 md:px-28 py-4`:
- **Left**: logo image + "Neuralyn" text (`text-xl font-bold tracking-tight`) + nav links (Home, Services with a ChevronDown icon, Reviews, Contact us) — links hidden on mobile, `gap-1` between links, `gap-12 md:gap-20` between the logo and the links
- **Right**: "Sign In" button — solid white background (`bg-foreground`), black text (`text-background`), `rounded-lg text-sm font-semibold`, hover opacity transition

### Hero Content
Centered column, `mt-16 md:mt-20 px-4`:
- **Tag pill**: a "liquid glass" styled pill (`liquid-glass` class) holding an inner "New" badge (white bg, black text, `rounded-md text-sm font-medium px-2 py-0.5`) + "Say Hello to Corewave v3.2" in `text-sm font-medium text-muted-foreground`. The pill itself is `px-3 py-2 rounded-lg mb-6`.
- **Title**: `text-5xl md:text-7xl`, `tracking-[-2px]`, `font-medium`, `leading-tight md:leading-[1.15] mb-3`. Text: "Your Insights." / "One Clear Overview." — the word "Overview" is in Instrument Serif italic (`font-serif italic font-normal`)
- **Subtitle**: `text-lg font-normal leading-6 opacity-90 mb-8`, color from the CSS variable `--hero-subtitle`. Text: "Neuralyn helps teams track metrics, goals, and progress with precision." with a `<br/>` after "goals,"
- **CTA button**: "Get Started for Free" — solid white (`bg-foreground text-background`), `rounded-full px-8 py-3.5 text-base font-medium`, `whileHover` scale 1.03, `whileTap` scale 0.98

### Dashboard + Video Area
Full viewport width via `w-screen` with `marginLeft: calc(-50vw + 50%)`, `aspect-ratio: 16/9`, `position: relative`:
- **Background video**: `<video>`, absolutely positioned `inset-0 w-full h-full object-cover`. URL: `https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260307_083826_e938b29f-a43a-41ec-a153-3d4730578ab8.mp4`
- **Dashboard image**: absolutely positioned, centered, `max-w-5xl w-[90%] rounded-2xl`, `mixBlendMode: "luminosity"`. Parallax scroll (`y: 0 → -250`).
- **Bottom gradient fade**: absolutely positioned at the bottom of the section, `h-40`, gradient from background to transparent, `z-30`, `pointer-events-none`.

### Parallax Scroll Effects
`useScroll({ target: sectionRef, offset: ["start start", "end start"] })` + `useTransform`:
- Hero text content group: `y: [0, -200]` and `opacity: [1, 0]` (fades over the first 50% of the scroll)
- Dashboard image: `y: [0, -250]`

### Entrance Animations
Staggered `initial={{ opacity: 0, y }}` / `animate={{ opacity: 1, y: 0 }}`:
- Tag pill: `y: 10`, duration 0.5s, delay 0
- Title: `y: 20`, duration 0.6s, delay 0.1
- Subtitle: `y: 20`, duration 0.6s, delay 0.2
- CTA: `y: 20`, duration 0.6s, delay 0.3
- Dashboard area: `y: 40`, duration 0.8s, delay 0.4

### Liquid Glass CSS
```css
.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;
}
```

## Section 2: Testimonial
`min-h-screen`, centered, `py-24 md:py-32 px-8 md:px-28`. Layout `max-w-3xl mx-auto`, content left-aligned (`items-start`), `gap-10` between elements.

- Quote symbol image (`w-14 h-10 object-contain`)
- Testimonial text (`text-4xl md:text-5xl font-medium leading-[1.2]`, wrapped in `flex flex-wrap`): "Neuralyn revolutionized how we handle financial insights using smart analytics. We are now driving better outcomes quicker than we ever imagined! Neuralyn revolutionized how we handle financial insights using smart analytics."
- **Scroll-driven word reveal**: each word is a `<motion.span>` with `mr-[0.3em]`. Uses `useScroll({ target: containerRef, offset: ["start end", "end center"] })`. Each word maps to a sequential range `[i/total, (i+1)/total]` → `opacity: [0.2, 1]` and `color: ["hsl(0 0% 35%)", "hsl(0 0% 100%)"]`.
- Closing `"` quotation mark in `text-muted-foreground ml-2`
- Author row (`flex items-center gap-4`): avatar image (`w-14 h-14 rounded-full border-[3px] border-foreground object-cover`) + name "Brooklyn Simmons" (`text-base font-semibold leading-7 text-foreground`) + role "Product Manager" (`text-sm font-normal leading-5 text-muted-foreground`)

## Assets
- `logo.png` — small logo icon
- `hero-dashboard.png` — dashboard screenshot
- `quote-symbol.png` — decorative quote mark
- `testimonial-avatar.png` — circular headshot

## File Structure
```
src/App.tsx
src/components/Hero.tsx
src/components/Navbar.tsx
src/components/Testimonial.tsx
src/components/ui/button.tsx
src/lib/utils.ts
src/index.css
```

## Quality Bar
- The dashboard the whole page is built around is mostly never seen. Measured at 1440x900: the 16:9 area is 1440x810 and starts at y=528, so `h-screen overflow-hidden` keeps 372 of its 810px; the image inside is 1024x640 at y=613 and shows 287 of 640. The parallax does not rescue it — the section's bottom edge and the image move together, so the deepest visible row is `287 + 250p`, and rows past 537 (16% of a 2048x1280 asset) never render at any scroll position. Worse, the `h-40` fade covers the section's last 160px, so only the top 127px of the screenshot is ever seen undimmed; at 1280x800 that drops to 72px of a 232px sliver. At 390x844 the area fits whole (219px tall) but the 2048px asset is drawn 351px wide, where the KPI numbers are two pixels tall. Either give the section room, or crop the asset to the band that shows.
- `mixBlendMode: "luminosity"` does not tint the screenshot — it repaints it in the video's colours, and the video is a 10s loop. The PNG is near-greyscale (mean HSV saturation 0.027); composited over the clip at 1440x900 the mean is 0.620, the meadow's own 0.481. Semantic colour is the casualty: the "+12.4%" pill is hue 144 deg / S 0.338 in the asset and hue 246 deg / S 0.139 after the blend, the "-2.3%" pill goes 0 deg / 0.338 to 46 deg / 0.162, and the two differ by 1.06:1 in luminance with no hue left to carry the up/down distinction. Text survives — a white glyph core against its card ground is 19.19:1 before and 19.12:1 after, because luminosity keeps the source's lightness. Use the blend for texture, never for anything whose colour means something.
- The last eight words of the testimonial never light up. `offset: ["start end", "end center"]` reaches progress 1 only when the container's bottom sits at the viewport centre, and this container is in the page's last section, so the page runs out of scroll first. Measured at maximum scroll: 1440x900 tops out at p=0.723 and 390x844 at p=0.728 — 22 of 31 words white, one mid-fade, and 8 frozen at `opacity: 0.2` on `hsl(0 0% 35%)`, which composites to rgb(18,18,18) for 1.12:1 against a pure-black page. `["start end", "end start"]`, or anything at all after the section, ends the sentence.
- The video is specified with a class list and a URL and no attributes. Without `muted` no browser autoplays it; without `autoPlay`, `loop` and `playsInline` it is a still first frame that goes fullscreen when an iOS user taps it. There is no `poster` either — acceptable only because the page behind it is `0 0% 0%` and a black box is the same black box, but say so on purpose. Add `aria-hidden="true"`: it is decoration, and it currently lands in the accessibility tree as an unlabelled media element.
- Nothing on this page renders until Framer Motion runs. All five hero blocks start at `opacity: 0` and the 31 testimonial words start at 0.2 — first paint, a failed bundle, or an SSR port whose hydration is blocked all give a black rectangle with a navbar. If the hero is the LCP element, that is the LCP: gate the entrance on a mounted flag, or animate from a state that is already readable.
- `mr-[0.3em]` is not a space. `textContent` on the quote is `"Neuralynrevolutionizedhowwehandle..."` — one 196-character run-on — and because each `motion.span` is a flex item, selecting and copying the paragraph yields one word per line. Anything that reads the text rather than looks at it (search, translation, share previews, a screen reader's word boundaries) gets that. Put a real space in each span, or set the gap with `word-spacing` on the parent.
- The `@fontsource` imports ask for six faces: Inter latin 400/500/600/700 is 96,744 bytes and Instrument Serif latin 400 normal + italic is 43,160, so 136.6KB before a single glyph is chosen. All four Inter weights do paint (400 body, 500 headline, 600 Sign In and the author name, 700 wordmark) but Instrument Serif normal — 20.5KB of it — never does, because the only element on that family is the `font-serif italic` accent. Subset to what renders: the Inter variable face over the 45 characters on the page, axis kept at the prompt's 400-700, is 11.2KB, and the italic for the six distinct letters of "Overview" is 1.2KB. That is 8.8% of the `@fontsource` path, and both faces are OFL 1.1 so you can ship them yourself.
- `font-serif` alone does not reach Instrument Serif. `@fontsource` registers `@font-face` rules and nothing else; Tailwind's `font-serif` is still `ui-serif, Georgia, serif` until `theme.extend.fontFamily.serif` names the family. Miss it and the one word the page is designed around silently renders in Georgia italic, which is a different width and a different colour of ink.
- `hidden md:flex` deletes Home, Services, Reviews and Contact us below 768px and nothing replaces them — no hamburger is specified. At 390x844 the header is a wordmark and a Sign In button, and four of the page's five destinations have no route on the device most likely to load it.
- Over `0 0% 0%` the liquid glass is a hairline. The pill sits at y 152-192 and the nearest thing with any content is the video area 336px below it, so `backdrop-filter: blur(4px)` is blurring uniform black and `rgba(255,255,255,0.01)` composites to #030303. What you actually see is the `::before` stroke, and its 180deg stop list is fully transparent between 40% and 60%, so the left and right edges are unstroked too — the pill reads as two short arcs. That is a fine look; just do not pay for `backdrop-filter` (which promotes the element and forces a separate compositing layer) to get it. It becomes real glass only if something lands behind it.
- Two pieces of copy look like accidents rather than choices. The tag pill announces "Corewave v3.2" on a page whose product is Neuralyn, and the testimonial's third sentence is its first sentence pasted a second time. Decide both.
- The four assets are all named `.png`. That is right for the dashboard (a UI capture, though 202KB against 56KB as WebP) and wrong for the headshot: 224x224 as PNG is 62.2KB where the same crop is 7.9KB as JPEG q82 and 4.2KB as WebP. A photograph is never a PNG.
- `h-screen` and `min-h-screen` resolve to the large viewport on mobile Safari, the one measured with the toolbar retracted, so both sections are taller than what is visible while it is out. Use `svh` or `dvh`.
- There is no `prefers-reduced-motion` branch, and this page owes one three times over: a scroll-coupled parallax, five staggered entrances, and a permanently looping full-bleed video. Note that the reduced-motion state has to be the reveal's *end* state — freezing the words where they start leaves the entire quote at 1.12:1. Read the query in an effect and re-read it on `change`, not in a `useState` initialiser, which is client-only and would disagree with hydration.

你可能还喜欢

Verified DR - Verified Domain Rating for buildpromptkit.comBuildPromptKit - AI prompts that ship real UI — every one has a live demo | Product HuntBuildPromptKit — AI Website & App Prompts - Featured on YizhanFeatured on saasfame.comFeatured on Twelve Tools