site: point the landing page at the reader's problem, not the mechanics

The hero explained the architecture before saying why anyone would care:
'task files in stage directories', 'stdlib-only', 'narrates' are words
that mean something once you already use bench. Every line now maps to
something the audience has actually hit — agents outrunning the person
supposed to be tracking them.

- Hero: 'Run a team of coding agents. Stay in control.' The old headline
  keeps its job as the brand line, in the footer of every layout.
- A new section between hero and doors: three sentences a reader has
  said out loud, each answered by a mechanism rather than a promise.
  Deliberately unboxed — the doors below are the page's one grid of
  cards, and repeating that shape would make the eye work twice.
- The six doors lead with the outcome and keep one mechanism as the
  evidence for it, which is the inversion of what they did before.
- Title and description follow, since a pasted url is the same pitch in
  another form.

Two lines that were quietly false are fixed too: the strip's comment
still said this site counts nothing (Fathom counts pageviews now), and
'no per-seat pricing' would have tripped the fiction guard in
tests/test_site_landing.py, which forbids the word outright.
This commit is contained in:
istos
2026-07-31 16:04:03 +02:00
parent d5c999fa79
commit 26e6bb333d
5 changed files with 95 additions and 33 deletions
+3 -3
View File
@@ -2,7 +2,7 @@
"site": {
"title": "bench",
"tagline": "docs",
"description": "A live kanban for coding-agent work: task files in stage directories are the only source of truth.",
"description": "Run a team of coding agents without losing track of what they are doing.",
"base_url": "https://bench.12vectors.com",
"repo_url": "https://github.com/12vectors/bench",
"issues_url": "https://github.com/12vectors/bench/issues",
@@ -15,10 +15,10 @@
"pages": [
{
"path": "/",
"title": "bench — a live kanban for coding-agent work",
"title": "bench — run a team of coding agents, stay in control",
"layout": "home",
"section": null,
"description": "Task files in stage directories are the only source of truth. A stdlib-only board narrates what happens to them — agents working in git worktrees, PRs opening on review, CI on the cards — and never merges anything itself.",
"description": "Your agents ship faster than you can keep track. Every task is a card, every agent gets its own worktree, every change waits as a PR. Nothing merges without you.",
"source": null
},
{
+31
View File
@@ -114,6 +114,10 @@ a:hover{color:var(--text);text-decoration:underline}
.footer-mark{margin:0;font:9.5px/1.25 var(--mono);color:var(--muted)}
.footer-id{display:flex;flex-direction:column;gap:4px}
.footer-name{font:600 15px/1 var(--display);color:var(--canvas)}
/* The line that used to be the h1. It says what bench is about in the
register the product speaks in; the h1 above now says what it does
for you. */
.footer-line{font-size:var(--t-ui);color:var(--ink-muted)}
.footer-id .mono,.footer-repo{font-size:11px}
.footer-repo{color:#a9c4c9}
@@ -301,6 +305,29 @@ a:hover{color:var(--text);text-decoration:underline}
.t-muted{color:var(--ink-muted)}
.t-dim{color:var(--ink-dim)}
/* The three sentences between the hero and the doors. Quiet on purpose:
no cards, no borders, no colour — the doors below are the page's one
grid of boxes, and repeating that shape here would make the reader
look twice at the same thing. The said-out-loud line takes the
display face; its answer is body copy. */
.snags{padding:8px 44px 30px}
.snags-title{
margin:0 0 20px;font:600 var(--t-h2)/1.3 var(--display);
letter-spacing:-.01em;color:var(--text);
}
.snag-list{
display:grid;grid-template-columns:repeat(3,1fr);gap:22px;
}
.snag{display:flex;flex-direction:column;gap:6px}
.snag-said{
font:600 var(--t-h3)/1.4 var(--display);color:var(--text);
text-wrap:pretty;
}
.snag-answer{
font-size:var(--t-ui);line-height:1.6;color:var(--muted);
text-wrap:pretty;
}
/* Every door is a link to a page this site builds — the whole card is
the target, so the hover is the card's border rather than an
underline under three words of it. */
@@ -416,6 +443,8 @@ a:hover{color:var(--text);text-decoration:underline}
.menu-contents{display:block}
.hero{grid-template-columns:minmax(0,1fr);gap:28px;padding:32px 24px}
.doors{grid-template-columns:repeat(2,minmax(0,1fr));padding:0 24px 28px}
.snags{padding:8px 24px 26px}
.snag-list{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.strip{padding:18px 24px}
/* Only a code block or a table may scroll sideways, so a token that
@@ -460,6 +489,7 @@ a:hover{color:var(--text);text-decoration:underline}
.menu{display:block}
.page-article .prose{padding:24px 20px 36px}
.doors{grid-template-columns:minmax(0,1fr)}
.snag-list{grid-template-columns:minmax(0,1fr);gap:18px}
.masthead{padding:12px 18px;gap:12px;flex-wrap:wrap}
.crumbs{flex-wrap:wrap}
.footer{flex-wrap:wrap;gap:16px 20px;padding:20px 18px}
@@ -500,6 +530,7 @@ a:hover{color:var(--text);text-decoration:underline}
.hero-actions{gap:8px}
.hero-actions .button{width:100%}
.doors{padding:0 16px 24px}
.snags{padding:8px 16px 22px}
.strip{padding:16px}
.page-article .prose{padding:20px 16px 32px}
.menu-summary{padding:9px 14px}
+1
View File
@@ -114,6 +114,7 @@ $toc
|| ||</pre>
<div class="footer-id">
<span class="footer-name">$site_title</span>
<span class="footer-line">Put the agents on the bench.</span>
<span class="mono">a 12vectors product · built in the open</span>
</div>
<span class="spacer"></span>
+59 -30
View File
@@ -65,13 +65,14 @@ $nav
<section class="hero">
<div class="hero-copy">
<span class="eyebrow">Documentation</span>
<h1>Put the agents<br>on the bench.</h1>
<p class="lede">Task files in stage directories are the only source of
truth. A stdlib-only board narrates what happens to them — agents
working in git worktrees, PRs opening on review, CI on the cards —
and never merges anything itself.</p>
<h1>Run a team of coding agents.<br>Stay in control.</h1>
<p class="lede">Your agents can ship faster than you can keep track.
bench turns your repo into mission control: every task is a card,
every agent works in its own isolated worktree, every change waits
as a PR for your review. You see everything. Nothing merges
without you.</p>
<div class="hero-actions">
<a class="button button-solid button-lg" href="/guides/install/">Install into a repo</a>
<a class="button button-solid button-lg" href="/guides/install/">Install into a repo — running in 2 minutes</a>
<a class="button button-lg" href="$repo_url">bench on GitHub ↗</a>
</div>
<span class="mono aside-note">no account, no service, no database. it is
@@ -105,51 +106,78 @@ Task board for ~/your-repo/.task-manager/tasks
</div>
</section>
<!-- Three sentences a reader has said out loud before finding this page.
Each one is answered by a mechanism rather than a promise, and each
mechanism has a door below it that explains itself. -->
<section class="snags">
<h2 class="snags-title">You've got agents. Now you've got a coordination problem.</h2>
<div class="snag-list">
<div class="snag">
<span class="snag-said">“Which tab was that in?”</span>
<span class="snag-answer">Every agent's task, branch and status on one
board — not scattered across chat sessions that forget everything.</span>
</div>
<div class="snag">
<span class="snag-said">“They keep stepping on each other.”</span>
<span class="snag-answer">Each agent works in its own git worktree.
Parallel work, zero collisions.</span>
</div>
<div class="snag">
<span class="snag-said">“Did something just merge?”</span>
<span class="snag-answer">Never. bench opens PRs and puts CI on the
card — the merge button is yours alone.</span>
</div>
</div>
</section>
<section class="doors">
<a class="door" href="/guides/install/">
<span class="mono door-index">01</span>
<span class="door-title">Install and first run</span>
<span class="door-text">Untar it into <span class="mono">.task-manager/</span>,
run <span class="mono">start.sh</span>, answer three questions.
Port 26071, pinned.</span>
<span class="door-title">Running in two minutes</span>
<span class="door-text">Drop it into any repo, run one script, open the
board. No account, no config sprawl — it untars into
<span class="mono">.task-manager/</span> and serves on port 26071.</span>
</a>
<a class="door" href="/concepts/stages/">
<span class="mono door-index">02</span>
<span class="door-title">The five stages</span>
<span class="door-text">backlog to-do → in-progress → review → done.
The directory a file sits in <i>is</i> its status.</span>
<span class="door-title">Always know what every agent is doing</span>
<span class="door-text">Backlog to done at a glance. The board cannot
drift from reality, because tasks <i>are</i> files in your repo: the
directory a card sits in is its status.</span>
</a>
<a class="door" href="/concepts/agents-on-the-board/">
<span class="mono door-index">03</span>
<span class="door-title">Agents on the board</span>
<span class="door-text">▸ start work makes a worktree and a branch, runs
the agent headless, and moves the card when it exits.</span>
<span class="door-title">Parallel agents, zero collisions</span>
<span class="door-text">Every agent gets its own git worktree and branch.
Run five at once without them overwriting each other.</span>
</a>
<a class="door" href="/concepts/pull-requests/">
<span class="mono door-index">04</span>
<span class="door-title">PRs &amp; review</span>
<span class="door-text">A card entering review gets a PR opened for it.
Then ◔ review PR, ⚑ copilot, ↻ act on PR — until it settles.</span>
<span class="door-title">Nothing ships without you</span>
<span class="door-text">Finished work arrives as a PR with CI status on
the card. bench never merges — you stay the gate, without being the
bottleneck.</span>
</a>
<a class="door" href="/concepts/team-mode/">
<span class="mono door-index">05</span>
<span class="door-title">Team mode</span>
<span class="door-text"><span class="mono">BOARD_SYNC=1</span> makes
origin/main the truth. Moves commit and push themselves; boards pull
on a beat.</span>
<span class="door-title">One board for the whole team</span>
<span class="door-text">Synced through git itself
(<span class="mono">BOARD_SYNC=1</span>) — no shared server, no
per-seat billing, no “who updated the ticket?”</span>
</a>
<a class="door door-dark" href="/concepts/three-layer-law/">
<span class="mono door-index">06</span>
<span class="door-title">The three-layer law</span>
<span class="door-text">Core knows tasks, worktrees, PRs and events.
Drivers know apps, adapters know vendors, local/ knows your
project.</span>
<span class="door-title">Swap agents without rewiring</span>
<span class="door-text">Vendors are adapters. Change your coding agent,
or run several, without changing your workflow.</span>
</a>
</section>
<!-- The strip turn 1 of the design filled with a most-read ranking. This
site counts nothing and never will, so it says the one thing about
itself it can prove: which version it was built from. -->
<!-- The strip turn 1 of the design filled with a most-read ranking. The
analytics here counts pageviews and nothing about a person, so it
could not honestly rank anything for a reader anyway; the strip says
the one thing this page can prove about itself instead — which
version it was built from. -->
<section class="strip">
<span class="mono strip-label">Version</span>
<span class="mono strip-version">$version</span>
@@ -168,6 +196,7 @@ Task board for ~/your-repo/.task-manager/tasks
|| ||</pre>
<div class="footer-id">
<span class="footer-name">$site_title</span>
<span class="footer-line">Put the agents on the bench.</span>
<span class="mono">a 12vectors product · built in the open</span>
</div>
<span class="spacer"></span>
+1
View File
@@ -66,6 +66,7 @@ $nav
|| ||</pre>
<div class="footer-id">
<span class="footer-name">$site_title</span>
<span class="footer-line">Put the agents on the bench.</span>
<span class="mono">a 12vectors product · built in the open</span>
</div>
<span class="spacer"></span>