> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibestrap.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Marketing blocks

> How the home page is composed from block components and how to extend it.

The Vibestrap home page is a stack of self-contained "block" components in
`src/components/blocks/`. Each block owns its layout, pulls its copy from
`messages/{en,zh}.json`, and is independently re-orderable. Composition lives
in a single file: `src/app/[locale]/(marketing)/page.tsx`.

## Prerequisites

None. The blocks are already wired in.

## The block lineup

Current order in `page.tsx`:

```tsx theme={null}
<Hero />            // Headline + primary CTA + sparkle badge
<LogoCloud />       // "As featured in" / proof bar
<Features />        // Grid of feature cards
<UseCases />        // Tool-station example use cases
<WhyVibestrap />    // Differentiators vs. building from scratch
<Quickstart />      // 3-4 step "ship it today" flow
<Pricing />         // Single-product pricing card
<FAQ />             // Accordion of common questions
<NewsletterCard />  // Email capture
<CTA />             // Final conversion push
```

Each component is a single file in `src/components/blocks/`. None of them take
props — all variation is via i18n keys.

## How a block reads its copy

Every block calls `useTranslations` with a `Home.<block>` namespace:

```tsx theme={null}
import { useTranslations } from 'next-intl';

export function Hero() {
  const t = useTranslations('Home.hero');
  return <h1>{t('title')}</h1>;
}
```

Find the matching keys in `messages/en.json` under `Home.hero`, and the same
keys in `messages/zh.json`. Editing copy is editing JSON — never touch
component source for words.

## Re-order or remove blocks

Open `src/app/[locale]/(marketing)/page.tsx` and rearrange the JSX. To drop a
block, delete the line. To move pricing above features, swap the order. There
is no nav data structure — visual order is JSX order.

## Add a new block

1. Create `src/components/blocks/<my-block>.tsx`. Default-export a server
   component that calls `useTranslations('Home.myBlock')`.
2. Add `Home.myBlock` to both `messages/en.json` and `messages/zh.json`.
3. Import and render in `page.tsx` at the desired position.
4. Run `node scripts/check-i18n.mjs` to confirm key parity.

A minimal block:

```tsx theme={null}
import { useTranslations } from 'next-intl';

export function MyBlock() {
  const t = useTranslations('Home.myBlock');
  return (
    <section className="border-b py-24">
      <h2 className="text-3xl font-bold">{t('title')}</h2>
    </section>
  );
}
```

## Theme tokens

Brand colors and radii are CSS variables defined in the `@theme` block of
`src/app/globals.css` (Tailwind v4 directive). Change `--primary` once and
every block re-skins. Three swappable themes (`cream` / `white` / `ash`) live
under `.theme-*` selectors — switch with `siteConfig.ui.theme`.

## Verify it works

```bash theme={null}
pnpm dev                              # eyeball /, /zh, and resize to 360px
node scripts/check-i18n.mjs           # confirm key parity
pnpm typecheck && pnpm lint           # types + style
pnpm build                            # production check
```

Open Chrome DevTools, toggle device mode to iPhone SE (360px), and scroll the
home page top to bottom. Every block must look right.

## Common pitfalls

1. **Hardcoded English in components** — always use `useTranslations`. If you
   write a literal string, the Chinese site shows English. The reviewer will
   catch it but you'll already have wasted commits.
2. **Block order matters for visual rhythm** — alternate dense and breathing
   sections (e.g. Features then Quickstart, not two grids in a row).
3. **Mobile responsiveness at 360px** — the iPhone SE width is the floor.
   Test it. Hero subtitles love to overflow on narrow screens.
4. **Adding keys to `en.json` only** — the validator blocks the build.
   Always add to both locale files.
5. **Importing `next/link` directly** — use `Link` from `@/i18n/navigation`
   so locale prefixes are preserved on click.

## Official docs

* [tailwindcss.com](https://tailwindcss.com/) — utility classes and the v4 `@theme` directive
* [ui.shadcn.com](https://ui.shadcn.com/) — the component primitives blocks use
* [Lucide icons](https://lucide.dev/) — icon set imported throughout the blocks
* [next-intl useTranslations](https://next-intl.dev/docs/usage/messages) — i18n inside blocks
