The cancellation card could only say two lines, an eyebrow and a date label,
because the card has no prose field and the API never passed one. A notice needs
to say what happened and what comes next, so it now carries a body.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Today's webinar was cancelled and the card had no way to say so: it required a
flyer to render at all, and it always drew a Join Google Meet button and the
calendar buttons, so the only shape it could take was an invitation.
It now renders without an image, and with no meetUrl it draws no Join button and
no calendar row. Never invite someone to a meeting that is not happening.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
On a phone the Google Calendar app claims calendar.google.com links and opens
its own home screen, dropping the event. The pop-up now offers one "Add to
Calendar" button that goes to the calendar file on iOS/Android (served inline
so the phone hands it to its calendar) and to the Google event editor on
desktop, with the other route as the second button either way. The .ics is
also folded to RFC 5545 line lengths so Outlook accepts it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Weekly Huddle overlay now reads its content from /api/announce (config-
driven) instead of a baked-in block, and Admin -> Settings -> Event pop-up
exposes a toggle plus editable fields (eyebrow, flyer, join URL, date, times,
auto-hide, event id). Defaults are seeded into config on boot so the panel
reflects real state. Removed the include from join.html so it never interrupts
the join flow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Self-contained /announce.js injects a branded, dismissible event overlay
(the flyer + all four time zones + Join Google Meet button). Included on the
main funnel and member pages. Auto-expires after the huddle and shows once
per browser until dismissed; edit the EV block to reuse for future events.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>