Vibn — Marketing Site
Production Vite + React 18 + Tailwind CSS implementation of the Vibn marketing homepage and beta-invite signup page.
Stack
- Vite 6 — dev server, HMR, multi-page build
- React 18 — function components + hooks, no router (two static entries)
- Tailwind CSS 3 — utility classes + a small
@layer componentsblock for things that don't compress cleanly to utilities (gradients, pseudo-elements, custom shadows) - No CSS-in-JS, no UI library — design tokens live as CSS custom properties so a tweak panel or theme switcher can runtime-swap the accent palette
- Geist + Geist Mono — loaded from Google Fonts in each entry HTML
Getting started
npm install
npm run dev # http://localhost:5173 (homepage)
# http://localhost:5173/beta.html (signup)
npm run build # production build → dist/
npm run preview # serve the built bundle
Project layout
vibn-app/
├── index.html ← homepage entry
├── beta.html ← beta-signup entry
├── vite.config.js ← multi-page input config
├── tailwind.config.js ← design tokens + named animations
├── postcss.config.js
├── public/
│ └── logo-black.png ← favicon (V_ mark on black)
└── src/
├── main.jsx ← mounts <App />
├── beta-main.jsx ← mounts <BetaApp />
├── styles.css ← Tailwind + tokens + keyframes + .btn / .card / .logo-mark
├── App.jsx ← homepage composition
├── BetaApp.jsx ← signup-page composition
├── lib/
│ └── primitives.jsx ← Logo, LogoMark, Arrow, Eyebrow, Glow, TrustStrip
└── components/
├── Nav.jsx
├── Hero.jsx ← Reddit-quote / promise variants + prompt input
├── Wall.jsx ← faux chat-window "homework wall" scene
├── CrossedOut.jsx ← animated strike-through term wall
├── Journey.jsx ← 4-step path + "where others stop" marker
├── Audience.jsx ← 3 audience cards w/ Reddit-style quotes
├── Closing.jsx
├── Footer.jsx
├── LaunchModal.jsx ← hero prompt-submit modal
└── beta/
├── BetaForm.jsx ← 5-step form
├── Confirmed.jsx ← submitted state w/ queue card + referral
└── Benefits.jsx ← "what you get inside" trio
Design tokens
All colors are exposed as CSS custom properties (see src/styles.css,
:root block) and aliased in tailwind.config.js → theme.extend.colors:
| Tailwind class | CSS var | Default |
|---|---|---|
bg-bg |
--c-bg |
oklch(0.155 0.008 60) |
bg-bg-1 |
--c-bg-1 |
oklch(0.185 0.009 60) |
text-fg |
--c-fg |
oklch(0.97 0.005 80) |
text-fg-dim |
--c-fg-dim |
oklch(0.78 0.006 80) |
text-fg-mute |
--c-fg-mute |
oklch(0.58 0.006 80) |
text-fg-faint |
--c-fg-faint |
oklch(0.42 0.006 80) |
text-accent |
--c-accent |
oklch(0.74 0.175 35) (coral) |
bg-accent |
--c-accent |
(same) |
border-hairline |
--c-hairline |
oklch(0.32 0.010 60 / 0.55) |
text-ok |
--c-ok |
oklch(0.78 0.16 155) |
To re-theme at runtime, set the variables on :root from JS:
document.documentElement.style.setProperty("--c-accent", "#9ee649");
document.documentElement.style.setProperty("--c-accent-glow", "#9ee64959");
document.documentElement.style.setProperty("--c-accent-fg", "#0f1408");
Type scale
Fluid clamp() sizes are used inline:
- Hero headline:
clamp(44px, 7.4vw, 104px) - Section H2:
clamp(36px, 4.8vw, 64px) - Body / sub:
clamp(16–17px, 1.6–2.2vw, 19–28px)
Geist is the body face; Geist Mono is reserved for tags, eyebrows, code, and "trust strip" details.
Animations
Keyframes are defined once in styles.css; some are also registered as named
Tailwind utilities (animate-caret-blink, animate-pulse-ok, etc.) for
ergonomics. Anything not in the config uses an inline style={{ animation: ... }}
with the keyframe name.
Notes & next steps
- No router. Homepage links to
/beta.htmldirectly. Drop inreact-router-domif you need client-side navigation between more pages. - Form submission is a stub.
BetaFormjust waits 700 ms and toggles to the confirmed state. Wire to your real endpoint (e.g.fetch("/api/invite", …)). - Queue position is deterministic on email. Replace with the real one from your backend.
- The hero "Live from minute one" pill is currently not rendered in this
port (the marketing prototype defaults it off). Re-add by uncommenting the
pill in
Hero.jsxif you want it back. - The Tweaks panel from the prototype is not ported. Tweaks are a design-time tool; runtime theming is enough via the CSS-var token system.
Browser support
Uses oklch(), text-wrap: balance, and backdrop-filter. Safari 15.4+,
Chrome 111+, Firefox 113+.