Skip to main content
All Work

CIVITAS

Civic simulation platform where you run a real election — not read about one.

Year

2025

Status

Deployed

Stack

Next.js · TypeScript · Gemini 1.5 Pro · Firebase · Google APIs · Cloud Run

Problem

Every submission in the election education vertical built a chatbot. They shared a broken premise: citizens feel disconnected from elections because they lack information. The actual gap is that most people have never been made responsible for anyone else's democracy — not even in simulation. Information does not create that feeling. Responsibility does.

Why it matters

Civic participation improves through felt accountability, not through reading. A product that creates genuine responsibility — even in a controlled simulation using real tools — produces a qualitatively different kind of understanding, one that transfers to actual civic behavior in a way no explainer can.

Approach

CIVITAS makes you the Returning Officer of a simulated micro-election for your actual neighbourhood. You do not read about constituency design, ballot rules, or dispute resolution — you do them, using real Google tools that produce real artefacts directly in your Google account. The experience is structured as three sequential gated acts. You cannot reach Act 2 without completing Act 1. Progress is gated by task completion, not time. The design is built on three documented behavioral mechanisms. Role-taking theory: occupying the official's role builds faster empathy for system constraints than any explainer. The ownership effect: rules you created are retained far longer than rules you were told. Perspective inversion: running an election from the inside produces richer understanding than observing it from outside.

Architecture

Next.js 14 + TypeScript frontend. Zustand state management with localStorage persistence so progress survives session breaks. Gemini 1.5 Pro with Search Grounding acts as Chief Election Commissioner throughout all three acts — fetching real jurisdiction-specific electoral law, reviewing ballot designs, and providing legal advisories during dispute resolution. Eleven Google APIs integrated as functional infrastructure: Maps for live constituency boundary drawing and 1.2km polling booth coverage validation via haversine calculation. Sheets for auto-generating a 200-voter official voter roll shared to the user's Google account. Calendar for pushing a legal election timeline as real calendar events. Forms for generating the official ballot paper. Cloud Translation for minority language obligations. Firebase Firestore for real-time vote streaming in Act 3. Slides for a 4-slide official results declaration deck. Looker Studio for a live results dashboard (recharts fallback). YouTube Data API for contextual explainer videos at friction points. Google OAuth 2.0 linking all created documents to the user's real account.

System flow

OAuth Sign-inGemini fetches jurisdiction-specific electoral lawDraw constituency boundary (Maps)Place polling booths + validate 1.2km coverageAuto-generate voter roll (Sheets)Certify constituency — Act 1 completeGenerate legal election timeline (Calendar)Register candidatesDesign ballot (Forms)Translate materials (Cloud Translation)Gemini reviews ballot → Certify — Act 2 completeSimulate polling day — votes stream via FirestoreDispute event at 60% → Gemini legal advisoryCertify countGenerate results declaration (Slides)Official results declared

Execution Context

Built in 2 days. I had 2 weeks allocated but was sitting semester exams and practicals simultaneously. The entire build was AI-assisted — Claude Sonnet 4.6 as the primary reasoning layer, with lower-capability models handling completion tasks when credit limits hit. The constraint forced ruthless prioritisation: every integration had to be load-bearing, not decorative.

Result

Placed 325th out of 2,408 submissions across 22,000 participants at PromptWars by Google — top 13.5%.

Tradeoffs

Eleven APIs means eleven failure surfaces. We accepted this complexity because the artefacts produced in the user's actual Google account are load-bearing — they're what makes the simulation feel consequential rather than theatrical. The 200-voter roll uses synthetic data deliberately: real electoral rolls introduce data ethics problems inappropriate at this stage.

Learnings

Responsibility creates comprehension that instruction never can. The hardest design problem wasn't any individual integration — it was keeping the simulation feeling consequential at every step without becoming overwhelming. Every time a real artefact appeared in the user's actual Google account, the stakes felt real. That was the product insight worth keeping.