<!-- https://getkonjo.com/design/patterns/destructive · source: docs/design/patterns/destructive.md -->

# Serious and consequential actions

Legal records, alerts, money, and anything that cannot be undone.

> Part of the [Konjo design language](../konjo-design-language.md). The laws in the spine apply here unless this chapter contradicts them.

> **Before you write a word of consequence copy**, read
> [product-facts.md](../product-facts.md). Who is alerted, what becomes permanent, who
> can read it afterwards and whether it can be undone are decided there — and where they
> are not, that is a blocker rather than something to phrase well.

Some screens create legal records, alert people, or move money. They get three things:

1. **The consequence is stated before the tap, not after** — and what it says is a
   [product fact](../product-facts.md), never a sentence you compose — who gets alerted, what becomes
   permanent, who can see it. In `caption`, next to the control that causes it.
2. **No pre-selected default on a field that carries a judgement.** Severity must not default
   to "Low"; a category, an outcome, or who was responsible must not default to anything. A
   pre-selection nobody corrects becomes the record.

   **A default that states an observable fact is different and is legal**: today's date on a
   form being filled in today, the signed-in instructor as the person *recording* it. The test
   is whether the default could be silently wrong — a judgement always can, a fact about right
   now cannot. Two conditions attach: the value must be **visible, never collapsed or implied**,
   and it must be changeable in one tap. A date default is legal; "Conferred by" is not, because
   who conferred a rank is a claim about someone else.
3. **The copy is clinical-plain**: roles not names, observable facts, no reassurance, no
   apology, no exclamation. "Plain and direct" ([voice](../voice/voice.md)) already forbids cheerfulness; this
   adds that a serious screen also does not soften.

**Which of the two shapes an action takes is decided by what it destroys, not by how serious
it feels.**

| | Shape |
|---|---|
| **Destroys or removes** something that exists — delete, remove from dojo, refund, revoke | **Arm, then fire.** See below. |
| **Creates** something permanent — record a promotion, submit an incident, issue a certificate | **One tap**, with the consequence line above it doing the confirming. |

An irreversible *creation* is not a deletion. Making it arm-then-fire adds a step to the
common, correct path and trains people to tap twice without reading — which makes the pattern
worse everywhere it is genuinely needed. What a permanent creation owes instead is rule 1, in
full: the consequence stated before the tap, naming what becomes permanent, who is alerted, and
whether it can be undone.

## Destructive actions arm, then fire

Never a bare one-tap delete, and never a native `Alert.alert` — an OS dialog is the one surface
this design system has no control over, and it is where a serious action deserves the most.

**Where it lives:** the bottom of the screen, past the content. Not in the header, not beside
the primary action, not above the fold. Reaching it means scrolling past everything the person
actually came for, which is the point.

**What it looks like:** a left-aligned text link, `label` 13/700, in the screen's red role. Not
a filled red button — a destructive action should never be the most attractive thing on a
screen.

**How it behaves:**

| | |
|---|---|
| Resting | "Remove from dojo" |
| First activation | **Arms in place** — relabels to "Really remove Ana Torres?", same colour, same position, no dialog, no layout shift |
| Second activation | Fires. Label → "Removing…", 16pt spinner to its left |
| Success | Navigate back to where the record was listed, with a one-line confirmation naming who was affected |
| Failure | Stay put, bordered error block above the control, label → "Try again", and **disarm** |

**Disarming.** Armed is a state a person can leave: scrolling, tapping anything else on the
screen, **moving focus off the control**, or navigating away all disarm it. **No timer** — a
control that silently re-arms or silently disarms on a clock is worse than either state, and a
person reading slowly is not consenting by being slow.

**Focus leaving is the keyboard's version of "tapped elsewhere", and it is easy to forget.**
Every trigger in that list except this one is a pointer or a page event, so a keyboard-only
person can tab away from an armed control, work somewhere else, come back, and press Enter on
what they believe is an idle button. A timer used to hide this: it disarmed everything after a
few seconds regardless of how the person got there. Take the timer out without adding this and
the pointer path disarms while the keyboard path does not — which is worse than the timer was,
for exactly the people who rely on the keyboard.

The confirming interaction never trips it: a click focuses the control rather than blurring it,
and Enter or Space fire while it still holds focus.

## The armed state has a screen-reader contract, and it is the part that goes wrong

Arm-then-fire is defined in taps, and a screen-reader user does not tap. VoiceOver's activation
gesture *is* a double tap, so one activation is one logical press — the two-step still holds.
The hazard is quieter: **if arming only changes the visible label, a blind person activates,
hears nothing, assumes the first activation failed, and activates again — firing a destructive
action they never knowingly confirmed.**

So arming is not a visual state. It must:

- **Announce itself immediately** — `AccessibilityInfo.announceForAccessibility("Armed.
  Activate again to remove Ana Torres from the dojo.")` The announcement names the consequence,
  because it is now the only place the consequence is heard.
- **Change the accessible label**, not just the visible one, so re-focusing the control reads
  the armed state rather than the resting one.
- **Carry `accessibilityState={{ selected: true }}`** while armed. There is no `armed` state in
  the platform vocabulary; `selected` is the closest true statement — this control is the one
  currently chosen — and it is exposed by every assistive technology.
- **Announce the disarm too** when something else cancels it. A person who scrolled away and
  believes the action is still armed will activate it later expecting a confirmation step that
  no longer exists.

Never rely on colour to carry armed — it is a state change, and colour alone fails SC 1.4.1.

## Bulk destructive actions

State the count and never the word "selected" alone: *Remove 3 students?*, not *Remove
selected?*. The person needs to know the size of what they are about to do, and "selected" is
whatever the list decided a moment ago.
