Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
An unhandled error has occurred.
Sedna.UI
v0.17.0 · main

Checks and switches

tier 2 — classes

.form-check wraps a checkbox or a radio, .switch is the flip that applies at once. All three are a native <input> with a class on the label, so none of them needs ARIA.

Checkboxes

The whole label toggles the box. The check mark is drawn in CSS, so it picks up the brand token.

<div style="display:flex; flex-direction:column; gap:10px">
    <label class="form-check"><input type="checkbox" checked /> Desktop notifications</label>
    <label class="form-check"><input type="checkbox" /> Play a sound on new items</label>
    <label class="form-check"><input type="checkbox" checked /> Compact table density</label>
    <label class="form-check"><input type="checkbox" disabled /> Auto-advance (unavailable in demo)</label>
</div>

Radio buttons

The same wrapper — the type decides the shape. A radio is an unfilled circle with a brand dot rather than a filled disc, so which one is exclusive reads without colour. Give every radio in a set the same name and wrap the set in a <fieldset>, so its legend is announced with each option.

On failure
<fieldset class="form-section" style="max-width:420px">
    <legend>On failure</legend>
    <div class="form-section-body">
        <label class="form-check"><input type="radio" name="onfail" checked /> Retry three times, then alert</label>
        <label class="form-check"><input type="radio" name="onfail" /> Alert immediately</label>
        <label class="form-check"><input type="radio" name="onfail" /> Log only</label>
    </div>
</fieldset>

Switches

.switch is for a setting that takes effect the moment it is flipped, so there is no Save to wait for.

<div style="display:flex; flex-direction:column; gap:14px; max-width:460px">
    <label class="switch">
        <input type="checkbox" checked />
        <span class="choice-text">
            <span>Auto-refresh the queue</span>
            <span class="choice-hint">Applies at once. Turn off while comparing two snapshots.</span>
        </span>
    </label>
    <label class="switch"><input type="checkbox" /> Play a sound on new items</label>
    <label class="switch"><input type="checkbox" checked disabled /> Managed by policy</label>
</div>

Which of the two

The difference is when it applies, not how it looks. Pick the wrong one and the reader is misled about whether Save is still needed — the same setting, drawn both ways.

Saved with the form

A checkbox. Nothing happens until Save, so the reader can change their mind.

Applies on flip

A switch. It takes effect at once, so there is no Save and no undo.

<div class="sedna-grid sedna-grid--sm sedna-grid--fit" style="max-width:660px">
    <fieldset class="form-section" style="margin:0">
        <legend>Saved with the form</legend>
        <p class="form-section-hint">A checkbox. Nothing happens until Save, so the reader can change their mind.</p>
        <div class="form-section-body">
            <label class="form-check"><input type="checkbox" checked /> Notify the customer on dispatch</label>
            <label class="form-check"><input type="checkbox" /> Require a signature</label>
            <div class="form-actions form-actions--start">
                <button class="btn btn-primary" type="button">Save</button>
            </div>
        </div>
    </fieldset>
    <fieldset class="form-section" style="margin:0">
        <legend>Applies on flip</legend>
        <p class="form-section-hint">A switch. It takes effect at once, so there is no Save and no undo.</p>
        <div class="form-section-body">
            <label class="switch"><input type="checkbox" checked /> Auto-refresh the queue</label>
            <label class="switch"><input type="checkbox" /> Compact table density</label>
        </div>
    </fieldset>
</div>

Options that need explaining

.choice-text takes the place of the label text and .choice-hint goes inside it, so the hint starts where the label does. The same slot works in a .form-check and a .switch.

On failure
<fieldset class="form-section" style="max-width:520px">
    <legend>On failure</legend>
    <div class="form-section-body">
        <label class="form-check">
            <input type="radio" name="rc-fail" checked />
            <span class="choice-text">
                <span>Retry three times, then alert</span>
                <span class="choice-hint">Roughly 90 seconds before anyone is paged.</span>
            </span>
        </label>
        <label class="form-check">
            <input type="radio" name="rc-fail" />
            <span class="choice-text">
                <span>Alert immediately</span>
                <span class="choice-hint">For a queue where a single failure already means data loss.</span>
            </span>
        </label>
        <label class="form-check">
            <input type="radio" name="rc-fail" />
            <span class="choice-text">
                <span>Log only</span>
                <span class="choice-hint">Nobody is paged. The run still appears in the history.</span>
            </span>
        </label>
    </div>
</fieldset>

Options that depend on another

Put a .choice-dependent straight after the checkbox, radio or switch it belongs to. It indents by that control's inset, --choice-inset-check or --choice-inset-switch, so its fields line up with the label, and one inside another indents again. A hint between the control and the block breaks the pairing — put it in .choice-hint.

Comma-separated. Each gets one message per approval.

days
<div style="display:flex; flex-direction:column; gap:12px; max-width:520px">
    <label class="switch"><input type="checkbox" checked /> E-mail notifications</label>
    <div class="choice-dependent">
        <div class="form-field">
            <label class="form-label" for="dep-recipients">Recipients</label>
            <input class="form-input" id="dep-recipients" type="text" value="alex.fischer@example.com, ops@example.com" />
            <p class="form-hint">Comma-separated. Each gets one message per approval.</p>
        </div>
        <div class="form-field">
            <label class="form-label" for="dep-url">Link target</label>
            <input class="form-input" id="dep-url" type="url" value="https://approvals.example.com" />
        </div>
    </div>

    <label class="switch">
        <input type="checkbox" checked />
        <span class="choice-text">
            <span>Housekeeping</span>
            <span class="choice-hint">Runs nightly. Each task below can be turned off on its own.</span>
        </span>
    </label>
    <div class="choice-dependent">
        <label class="form-check"><input type="checkbox" checked /> Reconcile assignments</label>
        <label class="form-check"><input type="checkbox" checked /> Close stale topics</label>
        <div class="choice-dependent">
            <div class="form-field">
                <label class="form-label" for="dep-stale">Stale after</label>
                <div class="input-group" style="max-width:160px">
                    <input class="form-input" id="dep-stale" type="number" value="7" />
                    <span class="input-affix">days</span>
                </div>
            </div>
        </div>
        <label class="form-check"><input type="checkbox" /> Prune the audit trail</label>
    </div>
</div>

Inactive while off

Opt in with .choice-dependent--dim, which fades the block and makes it inert, or .choice-dependent--hide. Both follow the control's live state, so they need no round trip. Without either, the block stays as it is.

hours
<div style="display:flex; flex-direction:column; gap:12px; max-width:520px">
    <label class="form-check"><input type="checkbox" /> Forward rejected requests</label>
    <div class="choice-dependent choice-dependent--dim">
        <div class="form-field">
            <label class="form-label" for="inact-forward">Forward to</label>
            <input class="form-input" id="inact-forward" type="email" value="review@example.com" />
        </div>
    </div>

    <label class="switch"><input type="checkbox" /> Escalate after a deadline</label>
    <div class="choice-dependent choice-dependent--hide">
        <div class="form-field">
            <label class="form-label" for="inact-hours">Escalate after</label>
            <div class="input-group" style="max-width:160px">
                <input class="form-input" id="inact-hours" type="number" value="24" />
                <span class="input-affix">hours</span>
            </div>
        </div>
    </div>
</div>