# Newsletter Signup

## Objective

Collect email addresses with proof that the person actually asked to hear from you.

An email capture form with a confirmation step, stored consent metadata, and a working unsubscribe.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Place the capture box where it makes sense and keep it to one field plus a button. Ask for a name only if you will actually use it.
2. Send a confirmation email containing a signed, expiring link and only mark the subscriber active when it is clicked. Store the source, the timestamp, and the address of the request alongside the subscription as the record of consent.
3. Reuse the app's existing Email Verification mechanism for the confirmation link rather than writing a second token scheme, and route unsubscribes through the existing Email Preference Center if one exists.
4. If the app already syncs contacts to an external marketing platform, make this feature feed that same pipeline instead of creating a second list that immediately diverges.
5. Do not add the address to your sending list before confirmation. Sending to unconfirmed addresses is how a domain's sending reputation is destroyed, and it is difficult to recover.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- A misspelled common domain silently loses the subscriber forever. Validate the address format and warn on near-miss domains before storing, while still allowing the user to override.
- Someone who signs up twice should see the same success message as a first-time signup. Telling them the address is already registered leaks who is on your list.
- Unconfirmed opt-in links must expire after a defined window, and the pending record should be cleaned up rather than sitting in the table forever.
- Every subscriber needs the source, exact timestamp, and consent context recorded. Without that you cannot answer a complaint or a regulator asking where the address came from.
- An address that has unsubscribed must not be silently reactivated by a later form submission. Treat the resubscribe as a deliberate act requiring a fresh confirmation.
- The unsubscribe link in every sent email must work without a login and must take effect immediately, not at the next send.
- The form is a spam target. Rate-limit by address and by session so it cannot be used to send confirmation emails to arbitrary third parties.
- Success and error states must be announced accessibly, and the form must not clear itself before the visitor has seen the confirmation message.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] An address becomes an active subscriber only after a confirmation link is clicked.
- [ ] Consent source, timestamp, and context are stored for every subscriber.
- [ ] Confirmation links expire after a defined window and expired attempts explain what to do next.
- [ ] A repeat signup returns the same success response as a first signup.
- [ ] A previously unsubscribed address is not reactivated without a fresh confirmation.
- [ ] Unsubscribe works from any sent email without a login and takes effect immediately.
- [ ] The form is rate-limited and cannot be used to mail arbitrary addresses.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
