## ADDED Requirements

### Requirement: Invitation emails carry a rendered preview block (P1)

An outgoing invitation email SHALL carry a link preview rendered by the system into the
message's HTML part, above the message body. The block SHALL show the event's preview image
when one exists, the event title, its date and venue, and SHALL make the recipient's own
invitation link its action. Mail clients do not read published link metadata, so this block
SHALL be composed by the system rather than relying on any metadata the invitation page
declares.

The block is rendered for exactly one recipient and SHALL be permitted to address that guest
by name.

#### Scenario: Preview above the body

- **WHEN** a guest opens their invitation email
- **THEN** a preview block showing the event image, title, date and venue appears above the message text
- **AND** activating it opens that guest's own invitation link

#### Scenario: Composed, not unfurled

- **WHEN** an invitation email is delivered to a mail client that renders no link previews of its own
- **THEN** the preview block is still visible, because it is part of the message

#### Scenario: Hand-edited message keeps the block

- **WHEN** an admin edits an invitation's message text and sends it
- **THEN** the message carries their edited text and the preview block above it

### Requirement: Preview block survives a hostile mail client (P1)

The preview block SHALL remain legible when remote images are blocked, when styling is
stripped, and in the message's plain-text alternative. With images unavailable the block
SHALL still present the event title, date, venue and link. The plain-text alternative SHALL
continue to carry the invitation link as text and SHALL NOT contain markup.

#### Scenario: Images blocked

- **WHEN** a mail client refuses to load remote images
- **THEN** the event title, date, venue and link remain visible
- **AND** the image's alternative text describes the event rather than showing a broken frame

#### Scenario: Plain-text alternative unchanged

- **WHEN** a message is read as plain text
- **THEN** it carries the invitation link in readable form and contains no HTML

#### Scenario: Body escaping preserved

- **WHEN** a message body contains characters that are significant in markup
- **THEN** they appear literally to the guest, exactly as before this change

### Requirement: Preview block never enters the message log (P0)

The rendered preview block carries the recipient's invitation link and may carry their name,
so it SHALL be composed at send time and SHALL NOT be written to the message log, to an audit
entry, or to any stored job record beyond those that already hold personalised content.

#### Scenario: Log holds no token

- **WHEN** an invitation email carrying a preview block has been sent
- **THEN** the message log entry for it contains neither the invitation token nor the rendered block

### Requirement: Admin compose panel previews the link (P2)

The panel an admin uses to compose one guest's invitation SHALL show the same preview that
guest will receive, rendered from the same model, so that an admin approving a message has
seen what the message will look like. The panel SHALL indicate when the event has no preview
image, and SHALL say what to do about it.

#### Scenario: What is approved is what is sent

- **WHEN** an admin opens the compose panel for a guest
- **THEN** the preview shown matches the block that guest's email will carry

#### Scenario: Missing image called out

- **WHEN** an admin composes an invitation for an event with no preview image
- **THEN** the panel shows the text-only preview and states that publishing a card design with a preview image would add the picture

#### Scenario: Preview reflects edits to the event

- **WHEN** an event's venue is changed and the compose panel is reopened
- **THEN** the preview shows the new venue

### Requirement: Admin can copy a guest's invitation link (P2)

An admin SHALL be able to copy one guest's invitation link to the clipboard from that guest's
compose panel, so it can be delivered by hand to a guest who cannot be emailed. Copying SHALL
be available regardless of whether the guest has an email address, and SHALL be recorded in
the audit log as access to that invitation's link.

Copying a link SHALL NOT send anything, SHALL NOT alter the invitation's send state, and
SHALL NOT be treated as a delivery.

#### Scenario: Copy without sending

- **WHEN** an admin copies a guest's invitation link
- **THEN** the clipboard holds that guest's link
- **AND** the invitation's send state and message log are unchanged

#### Scenario: Available without an email address

- **WHEN** an admin opens the compose panel for a guest who has no email address
- **THEN** the link can still be copied

#### Scenario: Copying is audited

- **WHEN** an admin copies a guest's invitation link
- **THEN** an audit entry records which admin took that invitation's link and when

#### Scenario: Suppressed guest

- **WHEN** an admin opens the compose panel for a guest who has asked not to be contacted
- **THEN** the panel states that the guest is suppressed before offering the link
