Banner

Now shipping: the Harbour block system.

Explore the blocks

Hero

The default variant: opening copy and calls to action, over a full-bleed textured band carrying a card that shows an agent mid-instruction.

  • Claude
  • OpenAI
  • v0
Edit with agents

Your website, editable by any AI agent

Harbour is a starter marketing site. Your developers keep working in git; your team edits through the agent they already use.

Or lead from the left

Same Block, different variant, set through a literal prop rather than a new component.

CTA

Start from this template.Edit it with any agent.

Swap the tokens, write the copy in MDX, and let the build tell you when something is wrong.

Each Block lives inside its own <BlockSpec> wrapper in this file's raw MDX source, closed like this:

<BlockSpec name="CTA">
<CTA title="Example" />
</BlockSpec>

Comparison

How it compares

How this approach compares

A quick view of what changes when content and layout live in the same system.

  • Starting a project

    Harbour
    Compose a page from existing Blocks
    The old way
    Design and build each section from scratch
  • Making changes

    Harbour
    Edit plain-text content in git
    The old way
    Wait for a developer or CMS workflow
  • Reviewing work

    Harbour
    See the exact change in a pull request
    The old way
    Review a preview or a handoff thread
  • Keeping layouts consistent

    Harbour
    Reuse Blocks with validated props
    The old way
    Maintain styles across custom components
  • Rebranding

    Harbour
    Update the design tokens once
    The old way
    Search through the codebase for scattered styles

FeatureGrid

What you get

A template that stays out of your way once the client signs off.

Six pieces, each one doing a single job well.

  • Block system

    Compose pages from a growing library of pre-built sections instead of hand-rolling layout for every client.

  • Bring your own content

    Wire pages to Markdown, Sanity, or a JSON file. The block components never know which one is behind them.

  • One token file

    Rebrand a client site by editing a handful of CSS variables, not hunting hex codes through the codebase.

  • Schemas that catch mistakes

    Every block validates its props at build time, so a bad edit fails the build, not the client demo.

  • No client JS by default

    Sections render on the server. A block only ships a bundle when it actually needs one.

  • Ships in an afternoon

    Clone the repo, swap the tokens and copy, push. Most rebuilds go live the same day.

FeatureSplit

Real content

Every block ships with real content, not lorem ipsum.

Preview a block and it already reads like a finished page. Swap the copy when the client is ready, not before.

  • Every block preview ships with client-ready copy
  • Content stays wired to the same schema in production
  • Nothing on the page reads like a placeholder

FeatureRows

What you get

A template that stays out of your way once the client signs off.

  • 01

    Block system

    Compose pages from a library of finished sections instead of hand-rolling a layout for every client.

    Browse the blocks
  • 02

    Content lives in git

    Pages are plain-text MDX, so a change is diffable, reviewable as a pull request, revertible, and editable by an agent.

    Read how it works
  • 03

    One token file

    Rebrand a site by editing a handful of CSS variables instead of hunting hex codes through components.

    Open the style guide

PreviewStage

In place

See the edit on the page, not in a diff.

An agent's change arrives as a pull request with its own preview, so the client approves the page itself.

ImageCards

In practice

Built from the same Blocks.

Agency portfolio

A five-page site for a three-person studio, live two days after the kickoff call.

SaaS marketing site

Pricing, changelog, and docs pulled from three different content sources.

Client rebrand

Same block tree, new tokens: the whole site retheme took an afternoon.

Gallery

Wallpapers

Wallpapers, ready for a hero background.

A wide crop for full-bleed heroes, square crops for everything smaller.

Arctic fjord wallpaper
Basalt plateau wallpaper
Fossil cliffs wallpaper
Highland moors wallpaper
Rolling hills wallpaper
Pampas grassland wallpaper
Limestone karst wallpaper
Misty marshland wallpaper

PostGrid

Unlike every other Block on this page, the cards above are not props: eyebrow, title, and count are the only literal values this section carries. The posts themselves come straight from content/blog/, sorted newest first, the same way /blog itself does, so a card can never show a stale title. Each card's picture is that post's own cover in its frontmatter; a post without one gets the site's texture instead. Add category="Guides" to show only one category's posts.

Faq

Questions

The questions every agency asks first.

Still unsure?Ask us directly

Do I need to know Sanity, or can I use plain Markdown?

Neither is required. Block components read from a shared content shape, and the shape ships with a Markdown adapter and a Sanity adapter already wired. Point the config at whichever one matches the client's comfort level. The sections themselves never know which backend is behind them.

How long does a client rebuild actually take?

Most agencies using this go from clone to a live client preview in an afternoon: swap the token file, drop in the client's copy and logo, pick block variants per section. The parts that used to take a week (layout, spacing, responsive behavior) are already decided.

What happens when a client wants a block that doesn't exist yet?

You build it once, following the same props-and-schema pattern as every other block, and it slots into the registry alongside the built-ins. It is an addition to the template rather than a fork of it, so the next client project gets it for free too.

Is the block registry locked to a specific CMS?

No. The registry is just a mapping from a type string to a component. Whatever's supplying that type (Sanity, a JSON file, a headless CMS you bolt on later), the registry doesn't care, as long as the props match the schema.

Can I white-label this for resale?

Yes. It ships MIT-licensed specifically so agencies can rebrand, resell, and reuse it across client engagements without asking permission or crediting the template anywhere client-facing.

Does it support multiple languages?

Not yet natively: routing and copy are single-locale today. Multi-language support is on the roadmap, but if a client needs it now, the content layer is thin enough that most teams wire in next-intl themselves in under a day.

Testimonial

From the agencies

What agencies say once they've shipped a client site.

We reskinned two sites in a single afternoon and the client never noticed a freeze. Nothing broke.

Rhea SandovalPartner
Meridian
  • The block registry is the first thing I show new hires. They're shipping client sections in their first week, not their first month.

    Casey OkaforFounder
    Northbound
  • The client edits their own copy now. I haven't been in a “can you change this word” thread since March.

    Jordan EllisCreative Director
    Fernwood Studio
  • A bad edit fails the build, not the demo. That's the whole pitch, and it holds.

    Morgan ValeLead Engineer
    Attic Digital

FeaturedQuote

From the agencies

Nothing ships client JS unless a block actually needs it. Our Lighthouse scores stopped being a monthly fire drill.

Morgan ValeLead Engineer, Attic Digital
Attic Digital

LogoCloud

Powering marketing teams at

40+ teams
  • MERIDIAN
  • Northbeam
  • halcyon
  • LUMEN.
  • tessera
  • KESTREL
  • Foundry & Co
  • OPENLANE
  • ATLASGRID
  • Prism
  • Cairn
  • VANTAGE

Team

The team

The people building the block registry.

Six people across design, engineering and operations.

  • Jordan Reyes

    Design Lead

  • Casey Whitfield

    Engineering Lead

  • Morgan Ito

    Product Manager

  • Riley Sandoval

    Front-End Engineer

  • Avery Kwan

    Design Systems

  • Sasha Novak

    Operations

Stats

By the numbers

The numbers behind the pitch.

Measured across 40+ client builds
19

Blocks in the registry today
3.2 hrs

/ 8 HR DAY

Average time to reskin a client site
94%

Sections shipped without custom code
0kb

Client JS shipped by default

Newsletter

Newsletter

Get notified when new blocks ship.

One email a month, unsubscribe anytime.

Pricing

Pricing

One template, three ways to license it.

Start free, upgrade the day you take on a second client.

  • Starter

    Free

    For a single portfolio or personal project.

    • 1 site
    • Full block library
    • Community support
    • MIT-licensed
    Clone the repo
  • Studio

    Popular

    $249one-time

    For agencies shipping client sites every month.

    • Unlimited sites
    • Block registry updates
    • Figma kit included
    • Priority support
    Get Studio
  • Agency

    Custom

    For teams running a full client roster.

    • Everything in Studio
    • Custom blocks on request
    • Dedicated Slack channel
    • Single sign-on
    Talk to us

Button primitive

src/components/ui/button.tsx · 6 variants × 9 sizes

variant \ sizemarketingdefaultlgsmxsiconicon-lgicon-smicon-xs
default
outline
secondary
ghost
destructive
link

Type scale

Geist Sans (--font-sans) · Geist Mono (--font-mono) · 10 roles

Eyebrowfont-mono text-eyebrow uppercase text-muted-foreground· SectionHeader, above a title
What you get
Displaytext-5xl lg:text-display· Hero, /blog, a post title; one per page
Your website, editable by any AI agent
Statementtext-3xl sm:text-title lg:text-statement· The CTA band and Newsletter
Compose pages from Blocks.
Titletext-title· SectionHeader, every other section
Every section opens with a statement
Subtitletext-subtitle· An item inside a section: FAQ, grid cells, plans
Content lives in git
Ledetext-lede text-muted-foreground· Under or opposite a title
One supporting sentence, never two paragraphs.
Stattext-stat font-light tabular-nums· Stats and plan prices, at font-light
2.6 hrs
Bodytext-base text-muted-foreground· Prose and cell copy
The size everything falls back to when nothing else applies.
Metadatafont-mono text-sm text-muted-foreground· Dates, categories, indexes
Product · 27 August 2026
Labelfont-mono text-label uppercase text-subtle-foreground· The footer's column headings only
Design system

Section header slots

src/components/blocks/section-header.tsx · eyebrow, meta, split

eyebrow + meta

By the numbers

The numbers behind the pitch.

Measured across 40+ client builds

One supporting sentence, never two paragraphs.

SectionHeaderSplit: lede opposite the title

Pricing

One template, three ways to license it.

Start free, upgrade the day you take on a second client.

Grid texture

src/components/texture/grid-field.tsx · server SVG + canvas · 2 presets

dense: animated, pointer={true}; move the cursor over it

coarse: animate={false}, ships no client JS