STARTING PROMPT 2 — Build Your Own Meeting Poll (a Doodle replacement)
Hand this to Claude, or another capable AI coding assistant. Fill in the [bracketed parts] first.

Build this after the booking calendar if you want both. They share one Apps Script project and
one /exec URL, so the second build is much shorter than the first.

---

Build me a free, self-hosted group scheduling poll to replace Doodle.

What it does. I propose a handful of possible meeting times and get back one share link.
Anyone with that link votes on each time — works, works if needed, or no — with their name and
email. A results grid shows who chose what. I also get a private organizer link. When I pick
the winning time from that link, the script creates a calendar event with a video link and
sends the invite to every person who voted.

My setup. I have a Google account at [scheduling@yourdomain.com] whose calendar this uses and
whose address sends the mail. I have static hosting at [host name]. I want the poll pages at
[book.yourdomain.com/poll/].

Architecture I want (keep it free, no subscriptions). The frontend is static HTML, CSS, and JS.
The backend is a Google Apps Script Web App that runs as that Google account. A Google Sheet is
the database — the script creates it on first use and remembers its id in Script Properties,
with one tab for polls and one for votes. Every poll gets a random public id and a separate
secret organizer token. The actions I need are poll-create, poll (read), poll-vote, and
poll-finalize. On finalize, the script writes the calendar event, attaches a video link, and
invites every voter. A time that already carries its own join link keeps it and never gets an
auto-generated room. If the video service fails, fall back to a Google Meet link so the group
is never left without a room.

[If you are adding this to a booking calendar you already built: merge these actions into that
same Apps Script project so both tools share one /exec URL, and reuse its email styling.]

Guardrails I want.
- Creating a poll requires a passphrase stored as a Script Property, so nobody but me can open
  polls on my domain. Voting needs only the poll link. Never link the create page publicly.
- Between 2 and 15 candidate times per poll, future times only.
- Maximum 100 voters, one vote per email address — a repeat email replaces that person's
  earlier answer rather than adding a second row.
- Voter email addresses are never shown to the group. The results grid shows names only.
- Take a script lock on every vote and every finalize, so two submissions arriving together
  cannot cross.
- Storage must tolerate new columns. Read cells through a helper that treats a missing cell
  as empty, and backfill the header row on load, so polls created before I extend the sheet
  still open.

Features I want beyond the free tier of Doodle. [Keep the ones you want.]
- A voting deadline, after which votes are refused and I get a nudge to pick a time.
- An invitee email list — send the invitation at creation, then one automatic reminder to
  people who have not voted, in the final stretch before the deadline.
- A "who hasn't voted yet" view that only I can see.
- Hidden polls, where voters see the totals but only I see the names.
- An email to me each time someone votes.
- A check that flags any proposed time that collides with something already on my calendar,
  before I send the poll out.

Reminders and deadline nudges run from a pollReminders() function on an hourly time-driven
trigger. Tell me to install that trigger in DEPLOY.md. Give each poll a flags column so every
reminder goes out exactly once.

Optional extras. [Keep the ones you want, or delete this block.]
- An edit page, gated by the organizer token, where I can change the title, note, length,
  deadline, invitees, privacy and the times while the poll is open.
- When times change on edit, carry each existing answer across by its time value, never by
  position in the list. A new time starts at "no"; a removed time drops out.
- A switch on the edit page, off by default, to tell everyone who already answered. Fixing a
  typo should not email thirty people. When it is on, the email shows the new list.
  It says that answers on times that did not change are kept, and that a time that moved or is
  new counts as a no until they answer it. People only need to act if the new list no longer
  works for them.
- A platform label and an organizer-supplied join link on each time, shown on the vote page,
  the results, the event and the emails.
- Time zone conversion: I enter times in my zone, and every voter sees the times in their
  own.
- When re-syncing guests onto the event, read the event first, keep any guest who is not a
  voter, preserve RSVPs, and set guestsCanInviteOthers to true, so guests I add from the
  calendar survive.
- Sign-up mode: each time is a session with a set number of places, one claim per person,
  and a session that fills closes itself.
- In sign-up mode the claim is the booking. The person goes straight onto that session's
  calendar event, and switching sessions frees the old place.

Build me the vote and results page, the poll creation page, the complete Apps Script .gs file,
and a DEPLOY.md with setup instructions. Use my colors and fonts — [paste your brand specs, or
write "ask me"]. Ask me any clarifying questions before you start.

---

Why this prompt works: a poll needs somewhere to keep answers between visits, and naming a
Google Sheet as that store is what keeps the whole thing free. The secret organizer token is
the other load-bearing detail — it is what separates the person who picks the time from the
crowd who only votes, with no login system anywhere.
