Overview
Copy button
A button that copies text, swaps its icon for a check and says what happened.
Principles
Keep one timer. Each result clears the pending reset before it starts a new one, and a slow earlier copy never overwrites a newer result.
Swap the icon in place. The copy, check and error icons share one grid cell, so the state changes without moving the label or resizing the button.
Announce the result. A polite live region beside the button says Copied or Copy failed, so screen reader users hear what happened.
Fall back when refused. When the Clipboard API is missing or refused, it copies through a hidden selection, then restores the selection and focus it found.
Name an icon-only button. A button with no text and no label gets the accessible name Copy.
Restore the button. Destroy clears the timer, removes the icon, the status and the class and label it added, and puts back data-state.