## ADDED Requirements

### Requirement: Guest rows are selectable (P0)
Each row of the guest list SHALL carry a selection control, and the list SHALL carry a
control that selects and clears every row currently displayed. The number of selected guests
SHALL be visible while a selection exists. Selection SHALL be cleared whenever the search
term, event, status, side or tag filter changes, so a selection can never describe rows the
admin is no longer looking at.

#### Scenario: Selecting one guest
- **WHEN** an admin activates a row's selection control
- **THEN** that guest is selected and the count of selected guests reflects it

#### Scenario: Selecting the displayed rows
- **WHEN** an admin activates the list-level selection control
- **THEN** every row currently displayed becomes selected, and activating it again clears them

#### Scenario: Filters clear the selection
- **WHEN** an admin changes any filter or the search term while guests are selected
- **THEN** the selection is emptied before the new results are shown

#### Scenario: Selection survives paging
- **WHEN** an admin selects guests on one page and moves to another page without changing filters
- **THEN** the guests selected on the first page remain selected

#### Scenario: Reachable by keyboard
- **WHEN** an admin moves through the guest list by keyboard
- **THEN** each selection control is focusable and its accessible name identifies the guest it belongs to

### Requirement: Selecting every guest matching the filters (P1)
When the current filters match more guests than are displayed, the list SHALL offer an
explicit control to select every matching guest, and SHALL state how many that is. A
selection made this way SHALL be described by the filters rather than by a list of rows, and
SHALL be discarded when those filters change.

#### Scenario: Offered only when it means something
- **WHEN** the filters match no more guests than are displayed
- **THEN** no select-all-matching control is offered

#### Scenario: Selecting all matches
- **WHEN** an admin activates the select-all-matching control
- **THEN** every guest matching the current filters is selected and the stated count is the total number of matches, not the number displayed

#### Scenario: Clearing it
- **WHEN** an admin clears a select-all-matching selection
- **THEN** no guests are selected and the ordinary row-by-row selection resumes

### Requirement: Send-invitations action on the guest list (P0)
The guest list SHALL offer a send-invitations action alongside its other list-level actions.
The action SHALL be disabled, with the reason stated on it, until an event is chosen and at
least one guest is selected. It SHALL be offered only to an admin holding the send-messages
permission. Activating it SHALL open the send-invitations composer for the selected guests.

#### Scenario: Disabled without an event
- **WHEN** guests are selected but no event filter is chosen
- **THEN** the action is disabled and states that an event must be chosen first

#### Scenario: Disabled without a selection
- **WHEN** an event is chosen but no guest is selected
- **THEN** the action is disabled and states that guests must be selected first

#### Scenario: Enabled
- **WHEN** an event is chosen and at least one guest is selected
- **THEN** the action is enabled and names how many guests are selected

#### Scenario: Permission
- **WHEN** an admin without the send-messages permission views the guest list
- **THEN** the send-invitations action is not offered

#### Scenario: Opening the composer
- **WHEN** an admin activates the enabled action
- **THEN** the send-invitations composer opens for exactly the selected guests of that event

### Requirement: Side-by-side composition for both invitation types (P0)
The send-invitations composer SHALL present two compositions at once — the message for guests
whose invitation type is single, and the message for guests whose invitation type is
family/multiple — each showing its full message as editable subject, header, body and footer.
Each composition SHALL state how many of the selected guests it will be sent to. A
composition whose type has no selected guests SHALL still be shown, and SHALL be visibly
marked as sending to nobody.

#### Scenario: Both compositions visible
- **WHEN** the composer opens for a selection containing both single and family guests
- **THEN** both compositions are shown together, each fully editable, each stating its recipient count

#### Scenario: Only one type selected
- **WHEN** the selection contains only single guests
- **THEN** both compositions are still shown, and the family composition is marked as sending to nobody

#### Scenario: Counts reflect the selection
- **WHEN** the composer opens
- **THEN** each composition's stated count equals the number of selected guests of that invitation type who can be emailed

#### Scenario: Headings are structural
- **WHEN** the composer is read by assistive technology
- **THEN** each composition is a labelled region whose accessible name identifies which invitation type it is for

### Requirement: Excluded guests are stated before sending (P0)
The composer SHALL state how many of the selected guests will not be emailed and why —
distinguishing guests with no address, guests who have opted out of this event and guests
whose address has hard-bounced — before any message is sent. These guests SHALL NOT be
counted in either composition's recipient count.

#### Scenario: Exclusions summarised
- **WHEN** the selection contains guests who cannot be emailed
- **THEN** the composer states how many are excluded, broken down by reason

#### Scenario: Nothing excluded
- **WHEN** every selected guest can be emailed
- **THEN** no exclusion summary is shown

#### Scenario: Every guest excluded
- **WHEN** no selected guest can be emailed
- **THEN** the send control is disabled and the composer states that there is nobody to send to

### Requirement: One send control for both compositions (P0)
The composer SHALL send both compositions with a single action: the single-guest message to
the selected single guests and the family/multiple message to the selected family guests. The
send control SHALL be disabled while a send is being recorded, and the composer SHALL NOT be
dismissible in a way that leaves the admin unsure whether the send happened.

#### Scenario: One action sends both
- **WHEN** an admin activates the send control with guests of both types selected
- **THEN** each selected guest is sent the message belonging to their own invitation type

#### Scenario: No double send
- **WHEN** an admin activates the send control twice in quick succession
- **THEN** each guest is sent at most one message

#### Scenario: Outcome before dismissal
- **WHEN** a send has been started
- **THEN** the composer shows its progress and outcome rather than closing on the click
