Skip to content

Toronto election pages: ward silence, the split panel, and the survey link - #90

Merged
mikaalnaik merged 4 commits into
mainfrom
mikaal/ward-no-responses
Sep 17, 2026
Merged

mikaalnaik merged 4 commits into
mainfrom
mikaal/ward-no-responses

Conversation

@mikaalnaik

@mikaalnaik mikaalnaik commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Four commits across the Toronto election pages. The first is the original subject of this PR; the rest were added after.


1. A ward where nobody answered says so

A ward where not one candidate answered printed all thirty-odd questions with nobody's answers on them. The argument was that a ward of non-respondents still deserved to see what it was they did not answer. Eight of Toronto's twenty-five wards are in that state, and what it gave them was nine screens of questions burying the one thing the section had to report.

The questions are not the ward's news; the silence is.

  • The questionnaire body is a single statement — "No candidate has responded" — with How the whole city answered beneath it for a reader who wants the questions with answers on them.
  • The lead-in "Nobody in this ward has answered yet. These are the questions we asked." is gone; its second half was a promise the page no longer keeps. The "no one has registered" case keeps its own sentence.
  • The roster above is labelled "On the ballot" rather than "Also on the ballot, yet to answer our questionnaire" — "also" needs something to be also to.

Wards with answers are untouched. QuestionnaireOutline was rendered from this one branch and goes with it, along with the shape plumbing that fed it (surveyShape through WardDetail, shape off rosterSurvey). questionnaireShape stays — /issues, /mayor and the survey results still call it.

2. The split panel opens on its answer

On /issues, the panel of names behind a pie slice opened on a bare count — "38 candidates" — and nothing else. Which thirty-eight, of the three or four splits on the card, was something the reader had to carry from the row they clicked, and on a pie they may not have come from a row at all: a wedge of colour carries no wording.

The answer the candidates were shown now heads the panel, dotted in the slice's own colour and set the way the legend sets it, with the count under it as the caption. The heading sits outside the scroller, so it stays put while the names move under it.

3. And it is sized to hold the names

The cap was 14rem — about ten names, against a largest slice of fifty-five in the Toronto field, so the rest sat behind a scrollbar inside an overlay. Three changes got the names on screen:

  • The ballot line comes off each name. "· Ward 17" after every name was longer than most of the names it trailed and set the width of every column, for a fact the reader is not in the panel for. The ward pages are where a name is matched to a ballot.
  • Height is bought with columns, not a taller box: ~110px a column, two or three to a card, so a fifty-five-name slice is nineteen rows rather than twenty-eight. The breakpoints are the panel's own width, since these cards run one, two and three to a row.
  • The panel is exactly the card's width — the figure sits inside the card's padding, so the panel gives that padding back and lands flush inside the card's border. A version that broke out past the card was shorter still and looked wrong: wider than the card it belongs to, it reads as something arriving over the page rather than coming out of the card, and it cannot be caught in a screenshot of that card.

The question heading drops to 1.25rem with it — ninety characters over a card three to a row took three and four lines at 1.45rem, and the page read as a stack of headlines with charts attached.

4. The Toronto compare card links the survey

The landing card sold a signup because the questions were written and the answers were not in. They are now, so it links SURVEY_PATH and the stand-in modal copy comes off.


Testing

tsc --noEmit and npm run lint clean (4 pre-existing warnings, 0 errors). Against the local dev server: /toronto, /toronto/vote/2026/issues, and wards 1 and 2 all 200. Wards 2, 3, 5, 6 render the new empty state; wards 1 and 13 still render the full answer grid; /mayor and /issues unchanged by the ward work.

No browser was available in the session, so this is DOM-level verification rather than a look at the rendered pages. Two things want an eyeball before merge: a quiet ward, and the panel open on the fifty-five-name slice on /issues.

🤖 Generated with Claude Code

mikaalnaik and others added 4 commits September 17, 2026 09:26
A ward where nobody answered printed the questionnaire's thirty-odd
questions with no answers on them, on the argument that a reader deserved
to see what it was the candidates did not answer. Eight of Toronto's
twenty-five wards are in that state, and what it gave them was nine
screens of questions burying the one thing the section had to report.

The questions are not the ward's news; the silence is. So the outline
comes off and the finding stands on its own — "No candidate has
responded", with the city-wide read a click away for anyone who wants the
questions with answers on them. The ballot is still named in full in the
roster above, now labelled "On the ballot": "also on the ballot" needs
something to be also to.

QuestionnaireOutline was rendered from this one branch and goes with it,
as does the questionnaire-shape plumbing that fed it — rosterSurvey no
longer computes a shape no page reads. questionnaireShape itself stays;
/issues, /mayor and the survey results still call it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two faults in the panel behind a slice on /issues.

It opened on a bare count — "38 candidates" — and nothing else. Which
thirty-eight, of the three or four splits on the card, was something the
reader had to carry from the row they clicked, and on a pie they may not
have come from a row at all: a wedge of colour carries no wording. The
answer the candidates were shown now heads the panel, dotted in the
slice's own colour and set the way the legend sets it, with the count
under it as the caption.

And it was capped at fourteen rem, about ten names. The largest slice in
the Toronto field is fifty-five, so the rest sat behind a scrollbar inside
an overlay — a place readers do not look. The cap is now forty-six rem,
what fifty-five names come to in two columns, or three-quarters of the
window, whichever is smaller, so the panel shows everything it has and
still cannot run off the screen. The heading sits outside the scroller so
it stays put while the names move under it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follow-on to the panel opening on its answer. Three changes, all about
the shape of it.

The ballot line comes off the names. "· Ward 17" or "· For mayor" after
every name was longer than most of the names it trailed, and it set the
width of every column in the panel — for a fact the reader is not in the
panel for. They opened it to see who took a position; the ward pages are
where a name is matched to a ballot.

With short names the panel buys height with columns instead of a taller
box: around a hundred and ten pixels a column, two or three to a card, so
a slice of fifty-five is nineteen rows rather than twenty-eight. The
breakpoints are the panel's own width, since these cards run one, two and
three to a row and the same window gives the panel three widths.

And the panel is exactly the card's width — the figure sits inside the
card's padding, so the panel gives that padding back and lands flush
inside the card's border. A version that broke out past the card was
shorter still and looked wrong: wider than the card it belongs to, it
reads as something arriving over the page rather than coming out of the
card, and it cannot be caught in a screenshot of that card.

The question heading drops to 1.25rem with it. Ninety characters over a
card three to a row took three and four lines at 1.45rem, and the page
read as a stack of headlines with charts attached.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The card sold a signup because the questions were written and the answers
were not in. They are now, so it links the survey itself and the modal
copy that stood in for it comes off.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mikaalnaik mikaalnaik changed the title Say it plainly when a ward's field stayed quiet Toronto election pages: ward silence, the split panel, and the survey link Sep 17, 2026
@mikaalnaik
mikaalnaik merged commit 9bc4d79 into main Sep 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant