Build startup websites that convert

Ship the company online

Build startup websites that convert

From zero to a fundraising-ready marketing site: IA, tokens, React sections, waitlist, pricing, and Hostinger deploy — with copy-paste prompts and real code patterns SuperGrok Heavy executes well.

HeavyBest on Web Build Mode for speed, or CLI + /design for repo control. See Get what you want.

The startup site playbook

PhaseWhat you ask Heavy forDone looks like
1. PositioningOne-sentence offer + audience + primary CTAHero copy you would put on a pitch deck
2. Design tokens/design: dark or light brand, 1 accent, 2 fontsCSS variables, no purple-gradient slop
3. Page shellNav + footer + mobile menu + sticky CTAWorks at 390px, no overflow
4. Conversion coreHero, logos, features, pricing, FAQ, formReal copy, empty states, form validation
5. Trust layerTeam, security, customers, metricsSpecific numbers, not “trusted by many”
6. ShipSEO, OG, Hostinger notes, formsDeploy + form smoke test on real domain

Gold one-shot brief (Web Build or CLI)

Startup marketing site — full brief
Build a production marketing site for a B2B SaaS startup.

Product: [name] — [one sentence value prop]
Audience: [role] at [company stage]
Primary CTA: "Start free trial" → /signup
Secondary CTA: "Book a demo" → calendar link
Tone: confident, calm, technical but not jargon-heavy
Brand: near-black background, one teal accent, Syne + IBM Plex Sans
Ban: purple gradients, emoji icons, lorem ipsum, stock "team smiling at laptop"

Pages/sections:
1. Sticky nav with logo, Product, Pricing, Docs, CTA
2. Hero: headline, subhead, dual CTAs, product UI mock (not photo)
3. Logo bar: 6 fictional customers (initials in monograms)
4. Problem → solution: 3 pain cards → 3 feature deep-dives
5. How it works: 3 steps
6. Pricing: 3 tiers (Starter / Growth / Enterprise) with monthly toggle
7. Social proof: 3 quotes with role + company
8. FAQ accordion (8 real questions)
9. Footer: product, company, legal, status

Technical:
- React + TypeScript + Tailwind
- Mobile-first 390px, then desktop
- SEO title/description + Open Graph tags
- Accessible: keyboard FAQ, focus rings, labels on inputs
- Static-export friendly for Hostinger Cloud Startup (dedicated IP + CDN)
- Real sample content only

Done when: clean console, no horizontal overflow at 390px, primary CTA visible above fold on mobile.

Token system Heavy should produce first

Force tokens before large UI dumps. In CLI: /design then “do not implement pages until I approve tokens.”

startup-tokens.css (example)
@theme {
  --color-bg: #07080a;
  --color-surface: #0e1014;
  --color-elevated: #151922;
  --color-fg: #eef0f4;
  --color-muted: #9aa3b2;
  --color-subtle: #6b7380;
  --color-accent: #2dd4bf;
  --color-accent-fg: #042f2e;
  --color-border: #232833;
  --color-border-strong: #343b4a;
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Syne", ui-sans-serif, system-ui, sans-serif;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
}

/* Concentric radii: card 16px + 16px pad → inner control 8px */
.card { border-radius: var(--radius-lg); padding: 16px; }
.card .btn { border-radius: calc(var(--radius-lg) - 16px + 8px); }

Section patterns (what “good” code looks like)

Paste these as reference when iterating — tell Heavy: “match this density and structure, keep our tokens.”

Hero.tsx pattern
export function Hero() {
  return (
    <section className="relative overflow-hidden border-b border-border">
      <div className="mx-auto grid max-w-6xl gap-10 px-4 py-16 sm:px-6 lg:grid-cols-2 lg:py-24">
        <div className="flex flex-col justify-center">
          <p className="text-xs font-semibold uppercase tracking-[0.18em] text-accent">
            For revenue teams
          </p>
          <h1 className="mt-3 font-display text-4xl font-semibold tracking-tight text-fg text-balance sm:text-5xl">
            Close pipeline your CRM still thinks is open
          </h1>
          <p className="mt-4 max-w-xl text-lg text-muted leading-relaxed">
            Northline syncs calls, email, and product usage into one forecast
            your board will actually believe.
          </p>
          <div className="mt-8 flex flex-wrap gap-3">
            <a
              href="/signup"
              className="inline-flex h-11 items-center rounded-md bg-accent px-5 text-sm font-semibold text-accent-fg hover:opacity-90"
            >
              Start free trial
            </a>
            <a
              href="/demo"
              className="inline-flex h-11 items-center rounded-md border border-border-strong px-5 text-sm font-medium text-fg hover:bg-elevated"
            >
              Book a demo
            </a>
          </div>
          <p className="mt-4 text-xs text-subtle">
            No credit card · SOC 2 Type II · 14-day trial
          </p>
        </div>
        {/* Product mock — CSS frame, not stock photo */}
        <div className="rounded-xl border border-border bg-surface p-2 shadow-2xl">
          <div className="rounded-lg border border-border bg-elevated p-4 min-h-[280px]">
            {/* charts / table mock */}
          </div>
        </div>
      </div>
    </section>
  );
}
Pricing card pattern
type Tier = {
  name: string;
  price: number | "Custom";
  blurb: string;
  features: string[];
  cta: string;
  highlighted?: boolean;
};

export function PricingCard({ tier }: { tier: Tier }) {
  return (
    <div
      className={`flex flex-col rounded-xl border p-6 ${
        tier.highlighted
          ? "border-accent bg-surface shadow-[0_0_0_1px_var(--color-accent)]"
          : "border-border bg-surface"
      }`}
    >
      <h3 className="font-display text-lg font-semibold text-fg">{tier.name}</h3>
      <p className="mt-1 text-sm text-muted">{tier.blurb}</p>
      <p className="mt-6 font-display text-4xl font-semibold text-fg tabular-nums">
        {tier.price === "Custom" ? "Custom" : `$${tier.price}`}
        {tier.price !== "Custom" && (
          <span className="text-base font-normal text-subtle">/mo</span>
        )}
      </p>
      <ul className="mt-6 flex-1 space-y-2 text-sm text-muted">
        {tier.features.map((f) => (
          <li key={f} className="flex gap-2">
            <span className="text-accent">✓</span> {f}
          </li>
        ))}
      </ul>
      <a
        href="/signup"
        className={`mt-8 inline-flex h-11 items-center justify-center rounded-md text-sm font-semibold ${
          tier.highlighted
            ? "bg-accent text-accent-fg"
            : "border border-border-strong text-fg hover:bg-elevated"
        }`}
      >
        {tier.cta}
      </a>
    </div>
  );
}

Waitlist / lead form (static-host friendly)

WaitlistForm.tsx — client validation + Formspree/Hostinger PHP
import { useState } from "react";

export function WaitlistForm() {
  const [email, setEmail] = useState("");
  const [status, setStatus] = useState<"idle" | "ok" | "err">("idle");

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(email)) {
      setStatus("err");
      return;
    }
    // Hostinger: point action to form.php or use Formspree / Basin
    const res = await fetch("https://formspree.io/f/YOUR_ID", {
      method: "POST",
      headers: { "Content-Type": "application/json", Accept: "application/json" },
      body: JSON.stringify({ email, source: "startup-landing" }),
    });
    setStatus(res.ok ? "ok" : "err");
  }

  return (
    <form onSubmit={onSubmit} className="flex flex-col gap-3 sm:flex-row">
      <label className="sr-only" htmlFor="email">Work email</label>
      <input
        id="email"
        type="email"
        required
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="you@company.com"
        className="h-11 flex-1 rounded-md border border-border bg-bg px-3 text-sm text-fg outline-none focus:border-accent"
      />
      <button
        type="submit"
        className="h-11 rounded-md bg-accent px-5 text-sm font-semibold text-accent-fg"
      >
        Join waitlist
      </button>
      {status === "ok" && (
        <p className="text-sm text-accent sm:basis-full">You're on the list.</p>
      )}
      {status === "err" && (
        <p className="text-sm text-red-400 sm:basis-full">Check the email and try again.</p>
      )}
    </form>
  );
}

SEO + social head (every startup site)

root head meta pattern
// TanStack Start / React head example
export const Route = createRootRoute({
  head: () => ({
    meta: [
      { title: "Northline — Forecast revenue your board trusts" },
      {
        name: "description",
        content:
          "Northline unifies calls, email, and product usage into board-ready forecasts.",
      },
      { property: "og:title", content: "Northline" },
      {
        property: "og:description",
        content: "Board-ready revenue forecasts for B2B teams.",
      },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
    links: [{ rel: "canonical", href: "https://northline.example" }],
  }),
});

SuperGrok Heavy prompts that actually work

Iteration — tighten conversion
Keep layout and brand tokens.
Rewrite hero for CTOs who already tried 2 CRMs.
Make pricing Growth tier the visual default.
Add objection-handling FAQ items about security and data residency.
Do not change routes or form endpoints.
CLI sequence
/design Startup marketing system for [product]. Tokens + section map only.
# approve tokens
/plan Implement homepage + pricing + waitlist form per design brief.
# approve plan
# after ship
/skillify Capture our startup landing pattern as skill "startup-landing"

Ship checklist

  • Primary CTA above fold on mobile
  • Real metrics, not “10x growth” without context
  • Pricing answers “who is this for?” per tier
  • Form tested on production domain
  • Legal: Privacy + Terms links (even stubs)
  • Favicon + OG image path valid after Hostinger upload
  • Hostinger Cloud Startup: dedicated IP + CDN + backup — see Websites + Hostinger