iOS App

Hansard

See how they treat you.

Browse UK Parliament — Members of the Commons, House of Lords, and constituencies with an interactive map, running natively on your iPhone and iPad.

650 seats — map ↔ party share. Parties with fewer than 10 seats are grouped into a single wedge, each dot keeping its party colour.

Learn more

Hansard is a native iOS browser for the UK Parliament. Named after the official record of debates in the Commons and Lords, the app puts every MP, every Lord, and every constituency at your fingertips — with offline-first access to the data that matters.

Built as a tool for the curious citizen, the researcher, and anyone who wants to understand how parliament actually works.

Features

🏛

Members of the Commons

Browse and search every sitting MP. View party affiliation, constituency, contact details, and portrait — all from the official Parliament API.

👑

House of Lords

Explore the full list of Lords, filtered by party or type. Life peers, hereditary peers, and bishops — all searchable and browsable.

🗺

Constituency Map

An interactive MapKit map with every UK constituency boundary drawn as a polygon overlay, coloured by the sitting member's political party.

📡

Offline-First

Bundled JSON snapshots of constituency boundaries and member data. The app works immediately on first launch — no network required.

🗳

Voting History

View how members voted in parliamentary divisions. Filter by date, topic, or member to see voting records at a glance.

📝

Written Questions

Browse parliamentary written questions and answers. Search by topic, member, or department to follow the detail of governance.

Engineering

The animation above renders 650 constituency dots that morph between a UK map and a party-share pie chart. Read how it's put together.

Engineering

Single canvas, two pre-computed layouts

The animation interpolates between two static layouts: map positions (normalised longitude/latitude) and pie positions (concentric arcs grouped by party). Both are computed once on mount. The render loop blends per-dot positions with a single eased morphT ∈ [0, 1].

Packing the pie

Parties are sorted largest-to-smallest and laid out clockwise from 12 o'clock. Each wedge is filled with concentric rings starting at innerR = 0.06, spaced 0.022 apart. Each ring fits as many dots as its arc length allows.

Parties with fewer than 10 seats get merged into a single Otherswedge — adjacent micro-parties don't have enough angular sweep for their innermost dots to clear neighbours. Every dot still keeps its own party colour, so nothing visually disappears.

The bloom is not a filter

Each party has a pre-rendered radial-gradient sprite. The render loop draws those sprites with globalCompositeOperation = "lighter", then a sharp dot on top at 0.78 alpha. Sparse rural seats get a faint halo; dense urban clusters stack their gradients and bloom visibly past saturation — the colour intensity becomes a density readout.

Reduced-motion path

A matchMedia("(prefers-reduced-motion: reduce)") check at startup paints one static map frame and skips the requestAnimationFrame loop entirely. Screen readers see a labelled <canvas role="img"> regardless.

Cycle and data

10s total: 4s map hold, 2s morph, 2s pie hold, 2s morph back. Each morph segment is eased with a smooth in-out cubic. The data — 650 triples of [longitude, latitude, party-colour] — ships inline with the page, no network call.

Hansard app icon

Available now — Free

Download on the App Store