Styleguide

Theme switch

On a real page it's fixed to the bottom right. Hidden without JS, and the site is then Clean.

Clean · light

Theme

Clean · dark

Theme

Vector

Theme

Comic

Theme

Markup contract
fieldset.theme-switch > legend + .theme-switch__options > label.theme-switch__option (input[type=radio] + span), then p.theme-switch__status.
Its shape never changes between themes. Only the colours follow, through tokens, and no theme adds decoration.
Native radios give arrow keys, the current state and announcements. The status is a polite live region. On a real page the fieldset starts hidden and theme-switch.js shows it.