/* ════════════════════════════════════════════════════
   toggle.css — the switch, for whichever app draws one
   ════════════════════════════════════════════════════

   These rules were in `chaos-controls.css` until AB#13312, and `js/controls/toggle.js` was already
   shared: the wizard uses it, Chaos's duplicate dialog and sub-task panel use it, and the shared
   notification settings list uses it in both Chaos and Chat.

   `chaos-controls.css` loads with the Chaos app. Every one of those callers outside Chaos was
   therefore drawing a switch whose stylesheet might not be present, and the failure is total but
   silent: the input is deliberately sized to nothing, so with no rules for the slider the control
   renders as a zero-size span — invisible, unclickable, and with nothing on screen to say a switch
   was meant to be there. Chat's notification settings is where that was finally caught, by an E2E
   that could see the three rows and could not click any of them.

   `controls/*.css` is linked from `index.html` for every app, so a shared control's rules belong
   here. The tokens are `shell.css`'s, which is linked the same way. */

.ch-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;

    /* The input is positioned inside this, so the box it positions against has to be this one. */
    position: relative;
}

/* Invisible, but still a checkbox: present in the accessibility tree, reachable by Tab, operable by
   Space. It used to be `display: none`, which took it out of the tree entirely — so a switch was
   unreachable without a mouse, and a screen reader was told nothing was there. On a settings screen
   whose whole job is switching things off, that made the screen unusable rather than awkward.

   Sized to nothing rather than hidden, because a hidden input cannot take focus either. */
.ch-toggle-input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    margin: 0;
    pointer-events: none;
}

/* Focus has to land somewhere visible, and the input is not it. Only on keyboard focus: a ring
   after every mouse click would be noise. */
.ch-toggle-input:focus-visible + .ch-toggle-slider {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Neither an unavailable switch nor a locked one dims. Each is reporting a state that is in effect —
   a locked one usually on, because something requires it — and dimming would say "unavailable" about
   the opposite. What they lose is the pointer, so the row does not invite a click that will not land.

   Both states are matched, not one instead of the other: `disabled` for a switch that is briefly
   unavailable, `aria-disabled` for one that is permanently locked but still worth reading. */
.ch-toggle-input:disabled + .ch-toggle-slider,
.ch-toggle-input[aria-disabled="true"] + .ch-toggle-slider {
    cursor: default;
}

.ch-toggle:has(.ch-toggle-input:disabled),
.ch-toggle:has(.ch-toggle-input[aria-disabled="true"]) {
    cursor: default;
}

.ch-toggle-slider {
    position: relative;
    width: 36px;
    height: 20px;
    background: var(--border);
    border-radius: 10px;
    transition: background 0.15s ease;
    flex-shrink: 0;
}

.ch-toggle-slider::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: var(--text-secondary);
    border-radius: 50%;
    transition: transform 0.15s ease, background 0.15s ease;
}

.ch-toggle-input:checked + .ch-toggle-slider {
    background: var(--accent);
}

.ch-toggle-input:checked + .ch-toggle-slider::after {
    transform: translateX(16px);
    background: #fff;
}

.ch-toggle-label {
    font-size: 13px;
    color: var(--text-primary);
}
