Campaigns, movements & advocacy

A public accountability roster with the districts drawn in.

A statewide pledge site: a filterable candidate roster, interactive district maps, and CRM-backed pledge intake.

accountability pledge
Sector
Civic accountability
Engagement
Product build
Stack
Next.js · D3 · Postgres · CRM
Status
Built · pre-deploy

Context

An accountability campaign needed to show, publicly and clearly, which candidates had taken a specific pledge. It wanted constituents to find their own district, see who was on their ballot, and add their name, without living on a slow WordPress site.

What we built

We built the accountability platform off WordPress on a modern stack: a filterable public candidate roster, interactive US and district maps (D3-geo with TopoJSON) so a visitor can find their own district and see who’s on their ballot, and a sign/pledge form proxied server-side into the CRM’s intake endpoint. Incremental static regeneration keeps the roster fast and current, Turnstile guards the forms, and the whole thing deploys via Docker/Coolify.

The value

  • Turns an accountability message into an interactive tool: constituents find their district, see their candidates, and act, all in one place.
  • The roster is public, filterable, and fast (incremental static regeneration), accountability you can actually browse, not a PDF.
  • Pledge signatures flow straight into the CRM with source attribution. The campaign captures the relationship, not just a signature.
  • District mapping makes it personal: “here’s who represents you” beats “here’s a list.”
Filterable

public candidate roster

District maps

find your district + who’s on your ballot

CRM-wired

pledge intake with attribution

Fast

always-current public roster

Client name and identifying details withheld by design. Every figure here is drawn from the system we actually delivered.

Your work would get the same discretion.

Tell us what's breaking. We'll tell you whether we've solved something like it. And if we take it on, your name stays yours.

Start with a diagnostic