The brief
Pamela and Samuel needed a personal invitation and a practical guide for guests traveling to their wedding. Guests needed event information and a clear way to confirm attendance.
The product goal was to bring printed stationery into a digital invitation while keeping a dependable attendance record.
I worked on content structure, visual design, interaction and implementation. The RSVP backend evolved during delivery, from Google Forms to Supabase.
Guest needs and scope
The Esencial brief included the couple’s story, event details, itinerary, map, travel guidance, lodging, dress code, gifts and RSVP. Later iterations added an album, a wishes mailbox and honeymoon experiences.
| Person | Need | Implementation |
|---|---|---|
| Couple | An invitation with their identity and story | Official monogram, final photography and chronological chapters |
| Household | Know who is invited | Shared family link with named members and individual companion permissions |
| Traveling guest | Prepare for the wedding | Itinerary, directions, lodging suggestions and visual dress guidance |
| Guest confirming | Respond inside the invitation | Member selection, dietary notes and a saved-response state |
| Couple and coordination | Maintain one current attendance record | Persistent responses and a unique invitation constraint |
A household and its members are separate records. One link can include several people. Companion permission belongs to an individual member.
The invitation experience
The opening uses a watercolor envelope, blue wax seal and the couple’s monogram. Guests open the envelope before entering the photographic invitation.
Session state shortens the opening on return visits. Reduced-motion settings abbreviate the transition.

Three chapters tell the couple’s story before the page presents practical details. A vertical progress indicator helps guests follow the page without a persistent navigation bar.
The design combines coastal English Garden colors, paper grain, watercolor washes and the couple’s photography. Serif headings and script accents set the tone. Sans-serif text carries practical information.
Illustration and motion
A central manifest defines four PNG atlases and four standalone illustrations. It records crop coordinates, scale, placement and names for reusable watercolor elements.
The sprite component calculates each crop and reserves its dimensions. Decorative illustrations remain hidden from assistive technologies and do not intercept input.
The hero artwork loads first. Other illustration resources load near the viewport. A development-only calibrator helps inspect and adjust crops.
Shared motion presets control reveals, image entrances and short sequences. Galleries support touch navigation and enlarged views.
Hotels and dress references use horizontal strips on mobile to shorten the page. Ambient audio has a mute control and follows browser interaction permissions.
Public and personal access
The root page introduces the couple without revealing date, venue, address, map or schedule. The full invitation requires a matching server-side invitation ID.
The server reads the CSV and groups rows into households and members. The RSVP receives only its household’s fields. Phone numbers, internal comments and the complete guest list remain outside that component.
Personal routes use private, no-store cache headers and noindex directives. Social previews omit event logistics.
The opaque link grants access. Anyone with a valid link can open it. Guests do not authenticate with accounts.

Family RSVP
The form names the family and lists its members. Guests select attendees and the companions available to individual members. A summary shows the selected names.
The form also collects allergies or dietary restrictions. Leaving everyone unselected records a decline.
The server checks the invitation and selections again. It derives names and counts from authorized member records, rather than trusting browser-supplied totals.

The interface checks for an existing response before showing the form. Returning guests see their saved answer and instructions to contact the couple for changes.
The success state can show a named wedding pass for each attendee. These passes represent the confirmed response. They do not provide QR admission scanning.
Architecture
The application uses Next.js App Router, React, TypeScript and Tailwind CSS. Motion handles interactions. Vercel hosts the site.
Editorial Markdown and typed content define the wedding information. A private CSV defines invitations. Supabase stores responses.
| Part | Responsibility | Rule |
|---|---|---|
| Content | Story, logistics and references | Update Markdown and typed content together |
| Invitation CSV | Household members and companion permissions | Read on the server |
| Interface | Invitation, guidance and RSVP | Supply only necessary data to interactive components |
| RSVP API | Validate selection and derive the response | Reject unauthorized members and companions |
| Supabase | Store one current response | Return a limited receipt without phone or dietary notes |
| Sheets integration | Copy responses for coordination | Use response UUIDs to prevent duplicate delivery |
The original RSVP submitted to Google Forms through the server. Persistence moved to Supabase in September.
The server holds the publishable key in configuration. A limited lookup function returns attendance, names and submission date for the requested invitation.
The database permits one response per invitation, including concurrent submissions. On a uniqueness conflict, the application retrieves the saved answer and returns it as already answered.
Response history and Sheets
The duplicate-response migration archives superseded answers before cleanup. It keeps the latest response for each invitation, then applies the unique constraint.
The prepared Sheets integration uses an outbox, a durable queue of delivery work:
- A database trigger creates a private queue entry.
- A scheduled job sends batches through a protected route.
- The server signs requests to Apps Script.
- Apps Script adds only missing response UUIDs.
The receiver checks signature, request age and destination. A lock controls concurrent deliveries. Retries preserve existing rows and retain pending work after failure.
September 24 installation notes still list Google authorization, webhook deployment and environment configuration as pending. Automatic delivery remains unverified end to end.
The wishes mailbox uses a separate Google Forms integration. This audit did not repeat a live message-delivery test.
Delivery timeline
The initial implementation and several design features appear in July 20 commits. Refinements and operational changes continue through September 24.
| Date in 2026 | Delivery |
|---|---|
| July 20 | Application, map, motion, social previews, watercolor, routing, photography and album |
| July 22–31 | Individual RSVP, wishes, content, monogram, music and tablet refinements |
| August 1–17 | Album, gifts, invitation-list migration and family presentation |
| August 25–September 8 | Honeymoon experiences, lodging, invitation maintenance and Supabase persistence |
| September 24 | Saved responses, duplicate protection, history and Sheets preparation |
Each part could be reviewed independently: identity, envelope, household data, persistence and duplicate handling. Commit dates do not measure working hours or AI-related savings.
Development with AI and specifications
AI assisted implementation against concrete product rules. A family link required grouped records. An individual companion required a member permission and server check.
Preventing repeat confirmations required both a saved-response lookup and a database constraint. Those requirements remained visible in the implementation.
Agent instructions, content, design documents, migrations and integration runbooks retained context between sessions. Instructions require natural Mexican Spanish, approved scope and explicit pending content.
The development sequence was discovery, a defined behavior, implementation, checks and documentation. The evidence does not establish a formal mini-spec for every task, parallel agents or a deployed RAG service.
Verification and remaining work
On October 7, 2026, lint, TypeScript, the production build and the Sheets receiver test passed.
The receiver test uses simulated Google services. It covers signature and freshness checks, destination, duplicate UUIDs, retries, formula-like text, headers and lock release.
The project has no consolidated harness command or broad RSVP unit-test suite. Browser checks and source review supplement the existing tests.
Captures use an isolated copy with a fictitious household and reserved date labels. The demonstration simulates response lookup. It does not read or save actual guest responses.
Invalid members and unauthorized companions returned HTTP 400 before persistence. Desktop and mobile checks found no horizontal overflow.
The delivered site includes the invitation, responsive guidance and household RSVP with saved responses. The next operational check is a complete delivery through the configured Sheets integration.
Completion rate, coordination effort and final attendance accuracy need separate measurements.
Work together
Planning a similar project? Estimate your project or review the related services.
