# Newsletter Archive

## Objective

Turn sent email issues into browsable web pages that new readers can find and read.

A public archive of past newsletter issues, each with its own permanent page and a subscribe path.

## 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. Store the sent version of each issue rather than regenerating it. An archive built by re-rendering a template will drift the moment the template changes, and old issues will stop matching what subscribers actually received.
2. Convert the email markup to web markup on the way in: strip the table scaffolding, the fixed pixel widths, and the inline styles that only exist to survive an email client, and render the result in the app's normal article styles.
3. Reuse the app's existing publishing states rather than adding a second one. An issue should move from sent to archived through the same Draft and Publish States machinery the rest of the content uses.
4. Give each issue a stable URL, a title, an excerpt, and a published date, and wire those into the existing SEO Setup so archived issues can be indexed and shared.
5. Do not archive every issue automatically. Sends aimed at a single segment, a win-back list, or an internal test must default to unlisted and require an explicit decision to publish.

## 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

- Email markup renders badly as a web page. Nested layout tables, fixed 600-pixel widths, and spacer images produce a cramped column with horizontal scroll on a phone unless they are stripped during conversion.
- Personalisation tokens must be resolved or removed before publishing. An archive page reading as a greeting to a first name that no longer has a recipient, or worse showing the raw placeholder, tells every visitor the page was not checked.
- Issues sent to a narrow segment can contain pricing, offers, or account details meant for that segment only. Default those to unlisted and require someone to opt them into the public archive.
- Tracking and redirect links expire once a campaign closes, leaving archive readers clicking through to a dead redirector. Rewrite outbound links to their final destinations when archiving.
- Backfilled issues arrive out of sequence. Order the archive by the date the issue was sent, not the date the record was created, or an issue imported last week will sit at the top of the list.
- The unsubscribe footer, the view-in-browser link, and the physical mailing address belong in the email, not on the web page. Strip them and replace them with a subscribe control.
- Embedded images hosted by the sending platform can disappear. Copy them into the app's own storage at archive time rather than hotlinking.
- An issue unpublished after the fact must stop resolving and stop appearing in feeds and sitemaps, not merely be hidden from the index page.

## 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

- [ ] Every archived issue has a permanent URL, a title, an excerpt, and a send date.
- [ ] Archived pages render in the app's article styles with no email layout tables and no horizontal scroll at 320px.
- [ ] No personalisation placeholder or unresolved token appears in any published issue.
- [ ] Segment-targeted sends are unlisted until someone explicitly publishes them.
- [ ] Outbound links in archived issues resolve without passing through an expired tracking redirect.
- [ ] The archive lists issues by send date, including issues imported after later ones.
- [ ] Each archive page offers a way to subscribe.
- [ ] 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.
