Cancer50Pledge.ca — Phase B
Cancer50Pledge.ca — Phase B
Section titled “Cancer50Pledge.ca — Phase B”Date: 2026-04-08
Background
Section titled “Background”The Cancer50Pledge scaffold is already live at https://cancer50pledge.pages.dev. It was built in Phase A with SvelteKit + Cloudflare Pages. All routes exist: / (homepage), /pledge (pledge form), /about, /impact.
The /pledge page currently has Google Form placeholder links instead of a real backend. Phase B connects the pledge form to real infrastructure, adds the Founding Pledgers wall, shareable certificate, Fathom analytics, and activates the custom domain (cancer50pledge.ca).
This is a Claude Code task, to be run after Tasks 1, 2, 3, and 4 are complete.
Code location: /home/ta/projects/mbr/cancer50pledge/
Current deploy: https://cancer50pledge.pages.dev
Target domain: cancer50pledge.ca
Existing Structure
Section titled “Existing Structure”cancer50pledge/├── src/routes/│ ├── +layout.svelte│ ├── +layout.ts│ ├── +page.svelte # Homepage — complete, good quality│ ├── about/+page.svelte # Story page│ ├── impact/+page.svelte # Impact page│ └── pledge/+page.svelte # Pledge form — Google Form placeholders to replace├── static/├── svelte.config.js└── package.json (uses npm — MUST migrate to pnpm)Note: package.json shows npm scripts. Per GlobalDevRules, migrate to pnpm as part of this task.
1. Migrate from npm to pnpm
Section titled “1. Migrate from npm to pnpm”- Remove
node_modules/,package-lock.json - Install dependencies with
pnpm install - Update any scripts that reference
npm runtopnpm run - Verify
pnpm buildandpnpm devwork correctly
2. Real Pledge Form Backend (Cloudflare Worker)
Section titled “2. Real Pledge Form Backend (Cloudflare Worker)”Replace Google Form placeholders in /pledge/+page.svelte with a real form that submits to a Cloudflare Worker.
Individual Pledge form fields:
- Name (required)
- Email (required)
- Message (optional, max 200 chars): “Why do you stand with the Cancer50Pledge?”
- Consent checkbox: “I agree to be listed on the public pledger wall” (default checked)
- Hidden field:
pledge_type: "individual"
Corporate Pledge form fields:
- Organization name (required)
- Contact name (required)
- Contact email (required)
- Pledge percentage (required, e.g. “5% of annual net profit”)
- Message (optional)
- Consent checkbox: “I agree to be listed on the public Founding Pledgers wall”
- Hidden field:
pledge_type: "corporate",founding_pledger: true(first 50)
Cloudflare Worker (cancer50pledge/worker/pledge-handler.js):
- Accept POST from form
- Validate required fields, basic email format
- Append row to Google Sheets via Sheets API (or Airtable — use whichever was chosen for the MBR website waitlist in Task 3 for consistency)
- Assign Founding Pledger number if
pledge_type === "corporate"and counter < 50 (store counter in Cloudflare KV) - Return:
{ success: true, founding_pledger_number: N | null, message: "..." }
Post-submission UX:
- Show confirmation inline (no page redirect)
- Individual: “You’re signed. Share this with someone who should join.”
- Corporate Founding Pledger: “You’re Founding Pledger #N. Your certificate is being prepared.”
3. Public Founding Pledgers Wall
Section titled “3. Public Founding Pledgers Wall”Add a section to the homepage / showing the first Founding Pledgers.
Implementation:
- Add a
data/founding-pledgers.jsonstatic file to the repo (seeded manually by Talbot with first pledgers) - On the homepage, render: numbered list of pledgers (#1, #2, …), org name, pledge %, date signed
- Individual pledgers shown separately below Corporate Founding Pledgers
- “Join the next [N] open spots” CTA linking to
/pledge#corporate
Static data structure:
{ "founding_pledgers": [ { "number": 1, "name": "MyBetterRates", "type": "corporate", "pledge_pct": 50, "signed_date": "2026-04-08", "public": true } ], "individual_pledgers": []}Note: Talbot will populate the first entry (MBR itself is Founding Pledger #1). Leave the data file as a stub — do not invent pledgers.
4. Shareable Certificate Generator
Section titled “4. Shareable Certificate Generator”Add a /certificate/[id] route that generates a shareable pledge certificate.
Certificate design:
- Full-page layout (printable / screenshot-friendly)
- Includes: Cancer50Pledge logo, pledger name/org, pledge percentage, date signed, Founding Pledger number (if applicable)
- “Download as PNG” button — use HTML Canvas or a simple SVG-to-PNG approach
- LinkedIn share button with pre-filled text: “I just signed the #Cancer50Pledge. [org] commits [X]% of profits to cancer research. Join the movement at cancer50pledge.ca”
- OG meta tags on the certificate page for social sharing previews
For Phase B, keep certificate generation client-side (no server-side image rendering). A styled HTML page that screenshots well is sufficient.
5. Fathom Analytics
Section titled “5. Fathom Analytics”Add Fathom analytics (privacy-first, no GDPR cookie banner needed).
- Add Fathom script to
+layout.svelte - Configure site ID in environment variable (
PUBLIC_FATHOM_SITE_ID) - Track custom goals:
individual-pledge-submittedcorporate-pledge-submittedcertificate-downloaded
- Do NOT add Google Analytics or any cookie-requiring tracker
6. Custom Domain Activation
Section titled “6. Custom Domain Activation”Connect cancer50pledge.ca to the Cloudflare Pages project.
- Verify the domain is already registered (check with Talbot if unclear)
- Add custom domain in Cloudflare Pages dashboard (this is a manual step — document the exact steps in a
DEPLOY.mdfile in the project root so Talbot can do this without needing Claude) - Update all internal links that reference
cancer50pledge.pages.devto use relative paths (so they work on both domains) - Update OG/meta tags to use
https://cancer50pledge.caas canonical URL
7. Audit and Polish Existing Pages
Section titled “7. Audit and Polish Existing Pages”Before completing, review all existing pages against the F.A.S.T. Standard:
- Frictionless: Can a first-time visitor understand what to do in 10 seconds?
- Adaptive: Does it look good on mobile (390px)?
- Simple: No unnecessary complexity or jargon
- Tailored: Does the tone match the Cancer50Pledge brand (serious, survivor-led, not corporate)?
Fix any obvious issues found. Do not redesign — only fix clear problems.
Testing Requirements (MANDATORY before reporting complete)
Section titled “Testing Requirements (MANDATORY before reporting complete)”-
pnpm build— zero errors -
pnpm dev— all pages render, no console errors - Individual pledge form submits → row appears in Google Sheets/Airtable → confirmation shown in UI
- Corporate pledge form submits → Founding Pledger number assigned → confirmation shown
- Founding Pledgers wall renders with at least the seed data (MBR as #1)
- Certificate page loads and displays correctly for a test pledger
- “Download as PNG” button produces a usable image
- Fathom goals fire on form submission (verify in Fathom dashboard or browser network tab)
- Mobile responsive at 390px — no horizontal overflow
- All internal
cancer50pledge.pages.devreferences replaced with relative paths
GlobalDevRules Compliance
Section titled “GlobalDevRules Compliance”pnpmonly (migrate from npm first)- SvelteKit + adapter-static
- Tailwind CSS v3
- No hardcoded credentials — all secrets in
.env,.env.examplewith placeholders only
Context (Auto-Prepared) — 2026-04-22
Section titled “Context (Auto-Prepared) — 2026-04-22”CRITICAL: Backend Decision Update
Section titled “CRITICAL: Backend Decision Update”The brief says “Google Sheets or Airtable” — this is superseded. Use Cloudflare D1 (same decision as the MBR website waitlist, made 2026-04-09). Keeps all data on CF edge infrastructure, ~1ms, no external API keys.
Resolved File Paths
Section titled “Resolved File Paths”| Path | Status |
|---|---|
| Project code | /home/ta/projects/mbr/cancer50pledge/ — verified exists |
| Current deploy | https://cancer50pledge.pages.dev — live |
| Brand reference | /mnt/d/FSS/KB/MBR/02_Strategy/Brand.md — verified exists |
| Target domain | cancer50pledge.ca — registration status unknown, do NOT configure DNS |
Current Project State
Section titled “Current Project State”- Tailwind CSS v4 already installed (v4.2.2) — do NOT downgrade to v3 (GlobalDevRules says v3 but project has v4; work with what’s there)
- npm scripts currently in use → migrate to pnpm as Task 1 (remove
node_modules/, nopackage-lock.jsonexists, runpnpm install) - Routes already exist:
/,/pledge,/about,/impact— do not delete any - SvelteKit + adapter-static + Cloudflare Pages — established and working
Backend: Cloudflare D1
Section titled “Backend: Cloudflare D1”Create: wrangler d1 create cancer50pledge-pledges
Schema:
CREATE TABLE individual_pledges ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL, message TEXT, consent INTEGER NOT NULL DEFAULT 1, created_at TEXT NOT NULL);
CREATE TABLE corporate_pledges ( id INTEGER PRIMARY KEY AUTOINCREMENT, org_name TEXT NOT NULL, contact_name TEXT NOT NULL, contact_email TEXT NOT NULL, pledge_pct TEXT NOT NULL, message TEXT, consent INTEGER NOT NULL DEFAULT 1, founding_pledger_number INTEGER, created_at TEXT NOT NULL);Founding Pledger counter: Cloudflare KV binding CANCER50_KV, key founding_pledger_counter.
Worker file: cancer50pledge/worker/pledge-handler.js
Brand (Cancer50Pledge Variant)
Section titled “Brand (Cancer50Pledge Variant)”- Logo: mBR mark with Pledge Rose dot (
#E8627A) instead of Wealth Gold - Primary: Treasury Emerald
#004425 - Accent: Pledge Rose
#E8627A - Background:
#f5f5f0 - Font: Inter (variable)
- Tone: serious, survivor-led, not corporate — authentic and direct
Fathom Analytics
Section titled “Fathom Analytics”PUBLIC_FATHOM_SITE_IDenv var — Talbot must provide from Fathom dashboard- Site must build and run without this var set (conditional include only)
- Custom goals:
individual-pledge-submitted,corporate-pledge-submitted,certificate-downloaded
Domain Note
Section titled “Domain Note”Do NOT configure DNS or custom domain in Cloudflare Pages dashboard. Instead:
- Use relative paths for all internal links (not
cancer50pledge.pages.devhardcoded) - Create
DEPLOY.mdwith exact steps for Talbot to connectcancer50pledge.ca
Founding Pledgers Wall Seed Data
Section titled “Founding Pledgers Wall Seed Data”Do NOT invent pledgers. Leave data/founding-pledgers.json as a stub — MBR is Founding Pledger #1, but Talbot populates this manually:
{ "founding_pledgers": [], "individual_pledgers": []}Dependencies
Section titled “Dependencies”- Cloudflare D1: create new DB as part of this task
- Cloudflare KV: create namespace for founding pledger counter
- Fathom: Talbot provides
PUBLIC_FATHOM_SITE_ID(site builds without it) - No dependency on MBR website task — this task is fully independent
Execution Notes
Section titled “Execution Notes”- Model recommendation: Sonnet (SvelteKit component + Cloudflare Worker)
- Assignee: Cursor / Claude Code (fresh session)
- Key constraints:
- Backend = Cloudflare D1 — ignore “Google Sheets or Airtable” in brief
- Tailwind v4 is installed — do NOT change to v3
- pnpm migration is Task 1 — do it before anything else
- Do NOT populate founding-pledgers.json with invented data
- Domain DNS = Talbot’s job — document in DEPLOY.md, do not configure
pnpm buildzero errors before reporting complete- Test D1 write end-to-end before reporting complete