feat(site): Print, share, credit partners and invite to stay - #14
Merged
Merged
Conversation
People who don't use a smartphone, and partners who hand out cards at events, can now print the same card everyone plays on their phones. The Bingo page has a Print section under "Share your card" with "Include my marks", "Large print (2 pages)" and "Print a card". Both paper layouts are built into the page from the square list, so the printed text always matches the card on screen. The print styles show only the chosen layout: a one-page, black-and-white card on US Letter paper with every square's full text, or a two-page large-print list with rows 3 to 5 on the second page. With "Include my marks" ticked, marked squares print with a check mark and a thick border and the progress line prints under the dates. Without JavaScript, the browser's own Print still prints the blank card. The old /bingo/print page redirects to /bingo. The Bingo page now sends a `bingochange` event with the marks and the progress line after loading and after every change, which is all the Print section reads. The card's QR code opens lvwwd.org/bingo at error correction level M. The build-time QR encoder now splits longer codes into blocks as the standard says and picks the mask with the lowest penalty, so partner links can use level M too. A test decoder written apart from the encoder reads every code back and checks its error correction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Share your card" on the Bingo page, and in the "Bingo!" message, now opens a share screen with a picture of the player's card instead of sharing a link. The picture is 1080 by 1920 pixels, the size of a phone story: the card with a check on every marked square, an outline on every finished line, and a count line such as "4 squares · 1 bingo". The share screen shows the picture, "Share image" (or "Save image" where the browser can't share files), "Copy image description", the written description a screen reader reads for the picture, and two lines: the image is made on the phone, and a bingo card doesn't count as a trip for the giveaway. Close, Escape and the phone's back gesture close it and return focus to "Share your card". The picture is drawn on the phone from the marks on screen, with the site's own fonts, and nothing is uploaded or stored. The drawing lives in bingo-picture.js and the screen in share-screen.js, so another picture can use the same screen later. Unit tests run the shipped script for the description and label fitting; browser tests read the drawn pixels, the texts drawn on the canvas, and the screen's keyboard and back-button behavior. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every partner now lives in one list, src/data/partners.ts. A volunteer adds an organization by adding one item there and publishing the site; the Partners page, the home page's partner wall and the QR code files all follow. The build checks each item and stops with a message naming the organization when a field is missing, a slug is malformed, taken or "general", a website doesn't start with https://, a type isn't one of the six, or a sentence runs past 200 characters. The Partners page lists partners by name, ignoring capitals and a leading "The", each with its name linking to its website, its type and its sentence, in one column on a phone and two from 768 pixels. With no partner yet, the roster is left out and the page opens with "Bring your organization". "Copy email address" now announces "Copied" to screen readers. From 12:00 am October 9, by the phone's clock, the roster heading reads "Took part in 2026" and the join section gives way to a note about next year. For each partner, and for LVBT's general materials, the build writes QR code files at /partners/qr/<slug>.png (1024 pixels square) and .svg, each opening the partner's giveaway link at error correction level M. A small PNG writer uses Node's own zlib. The logo wall, the logo request, the sample posts and the staff email leave the page: partners are listed by name only, and the partner kit in the next change replaces the banner mockups. A how-to explains how to add, change or remove a partner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Partners page now ends with the partner kit. A partner picks its name under "Your organization" and gets its giveaway link with "Copy link", its QR code with PNG and SVG downloads, the four banners with "Download" and "Copy image description", a posting tip, and an embed snippet for its website in two sizes with a live preview. The page address becomes /partners#kit-<slug>, so the choice can be bookmarked or sent on, and opening that address picks it again. "None (general materials)" gives LVBT's own link, which credits no one; with no partner in the roster yet, it is the only choice. The flyer link sits at the end of the kit. The four banners are real images at lvwwd.org/partners/banners/: a square post, a story, a website box and a website strip. Each shows "Week Without Driving Las Vegas", "October 1 to 8, 2026" and "Sign up to win at lvwwd.org" in the site's own fonts and colors, every text at 4.5 to 1 or more, and weighs under 45 KB. scripts/build-banners.mjs draws them with the Chromium the tests already use, so a new design is one command away, and LVBT's media committee can replace any file with its own at the same address. The embed snippet is only a link and an image, so partners' pages load no script and set no cookie. The Worker sends the banners with Access-Control-Allow-Origin, Cross-Origin-Resource-Policy and a day of caching, so any site can show them. The kit shows only a closing note from 12:00 am October 9, and asks for an email with JavaScript off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
My week's "Keep going after the week" card is now the full card: the
invitation, LVBT's newsletter, the note that the newsletter comes from
LVBT and isn't deleted on November 30, "Ready to do more?" and "Become
a member". It sits right after "Remind me to share my trip", and
/my-week#keep-going opens the page at it.
From 12:00 am October 9, 2026, by the phone's clock, Home tells a
visitor who isn't signed in that the week has ended, swaps "Sign up to
win" for "Stay involved with LVBT", and shows the same card in place of
the closing call to sign up. The button moves focus to the section's
heading. A signed-in visitor keeps their way back to My week, and
without JavaScript Home stays as it was during the campaign.
The one-tap sign-up is built and tested but ships turned off. Joining
LVBT's newsletter from the site needs the Worker's POST /api/newsletter
and a Beehiiv key, which don't exist yet, so for now the card links to
LVBT's newsletter page, which works today. Turned on, the card shows
the participant's own address when their contact is an email ("Use a
different email" swaps in a field), asks Turnstile for a token only
when someone taps "Join the newsletter", sends the source and token,
and shows the exact message for every reply, with an offline notice on
Home. My week and Home get the Turnstile site key from the Worker, so
turning it on is a one-line change in src/lib/newsletter.ts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WillieCubed
force-pushed
the
feat/wwd-play-partners
branch
from
September 24, 2026 02:08
a8aed4c to
26a7f7d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
Anyone can now print the Digital Transit Bingo card or share a picture of it. Partner organizations
have a real Partners page, with a partner kit giving each one its own link, QR code, banners and an
embed snippet. My week also gains a "Keep going after the week" card inviting participants to stay
with LVBT.
Overview of Changes
Printing a paper bingo card
Many of the people Week Without Driving is for, including older adults who have stopped driving,
don't use a smartphone, and partner groups want paper cards for their events. The Bingo page now has
a Print section with "Include my marks", "Large print (2 pages)" and "Print a card", built from the
same square list as the on-screen card so the two never disagree. The standard layout is one
black-and-white US Letter page with every square's full text, a name line, how to play, a QR code to
lvwwd.org/bingo and the giveaway's free way to enter; the large-print layout spreads the same squares
at 18 point over exactly two pages. Ticking "Include my marks" prints a check mark and thick border
on each marked square and the progress line under the dates. The old
/bingo/printaddress redirectsto
/bingo, since the print choices depend on the marks on this phone.Sharing a picture of the card
"Share your card" now opens a share screen instead of only sharing a link. The phone draws a 1080 by
1920 picture of the card, with a check on every marked square, an outline on every finished line, and
a count line such as "4 squares · 1 bingo". The screen offers "Share image" or "Save image" where the
browser can't share files, and "Copy image description," showing the full description and noting
that a bingo card doesn't count as a trip for the giveaway. Nothing is uploaded or stored, and the
picture never shows a name. The site's QR encoder was rebuilt to make codes of any size with the
standard's error-correction blocks, so the printed card's QR code and partner links both get level M
codes, which still scan with about 15 percent of the code damaged.
One roster for every partner
Every partner now lives in one list,
apps/site/src/data/partners.ts. A volunteer adds anorganization by adding one item there and publishing the site; the Partners page, the home page's
partner wall, the partner kit and the QR code files all follow from it. The build stops with a
message naming the organization when something is wrong: a missing field, an invalid or taken slug,
a website that isn't
https://, an unlisted type, or a sentence over 200 characters. A new how-to,Add a partner organization,
walks a volunteer through it. The roster is empty today, so the page opens with "Bring your
organization" and the home page's partner wall stays hidden, as before.
The partner kit, banners and embed snippet
A partner picks its name under "Your organization" and gets its giveaway link, a QR code with PNG
and SVG downloads, four banners with "Download" and "Copy image description," a posting tip, and an
embed snippet in two sizes with a live preview. The page address becomes
/partners#kit-<slug>, so achoice can be bookmarked or sent to a colleague; "None (general materials)" gives LVBT's own link,
which credits no one. The four banners are real PNG images at fixed lvwwd.org addresses, each under
45 KB, redrawn in one command by
apps/site/scripts/build-banners.mjs; LVBT's media committee canreplace any file with its own design of the same size. The embed snippet is only a link and an image,
so partner websites load no script and set no cookie; the Worker serves the banner files with headers
that let any other website show them.
Partner credit — crediting a sign-up to the
?ref=link that brought it — now works: see the roster'ssign-up count on the admin page. From 12:00 am October 9, the roster heading reads "Took part in
2026," "Bring your organization" gives way to a note about next year, and the kit shows only a
closing message.
Keep going after the week
The week lasts eight days, but what participants notice about getting around the valley matters all
year. My week's new "Keep going after the week" card sits right after "Remind me to share my trip"
and carries an invitation to LVBT's newsletter and "Become a member";
/my-week#keep-goingopens thepage at it. From 12:00 am October 9, Home tells a visitor who isn't signed in that the week has
ended, replacing "Sign up to win" with "Stay involved with LVBT" and showing the same card in place
of the closing call to sign up. A signed-in visitor keeps their way back to My week.
The one-tap newsletter sign-up on the card is fully built and checked, but ships turned off: it needs
a Worker newsletter route and Beehiiv key that don't exist yet, so the card links to LVBT's own
newsletter page instead, which works today. Turning the built sign-up on will be one line in
apps/site/src/lib/newsletter.tsonce the route exists.Follow-ups
🤖 Generated with Claude Code