# 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 components` block 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 ```bash 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 ├── beta-main.jsx ← mounts ├── 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: ```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.html` directly. Drop in `react-router-dom` if you need client-side navigation between more pages. - **Form submission is a stub.** `BetaForm` just 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.jsx` if 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+.