Files
scrying-pool/styles/tokens/_states.less
T
2026-05-21 23:08:34 +02:00

102 lines
4.1 KiB
Plaintext

/**
* styles/tokens/_states.less
*
* Layer 2 — SP Participant State Tokens
*
* All 8 participant states + 1 pending state (9 total).
* Each state provides three CSS custom properties:
* --sp-state-{name}-text — foreground / icon colour
* --sp-state-{name}-border — ring / border colour
* --sp-state-{name}-bg — background tint colour
*
* SECOND-SIGNAL RULE (WCAG):
* Every state conveys meaning via THREE independent channels:
* colour + icon (Font Awesome codepoint) + shape (ring variant).
* States marked ⚠️ below have low contrast ratios and MUST NOT
* appear as text or small-pill foreground — icon + shape carry the signal.
*
* State precedence (VisibilityManager/RoleRenderer resolves; CSS never handles multi-state):
* pending > cam-lost > reconnecting > offline > never-connected > self-muted > hidden > ghost > active
*
* LESS state map — single source of truth for loop-generated component CSS.
*/
/* ─── State colour variables ─────────────────────────────────────────────── */
:root {
/* active — Intentional / positive */
/* ✅ WCAG AA safe */
--sp-state-active-text: #4a9e6b;
--sp-state-active-border: #4a9e6b;
--sp-state-active-bg: rgba(74, 158, 107, 0.12);
/* hidden — Intentional / deliberate (GM action) */
/* ⚠️ Low contrast (~3.75:1) — icon + dashed ring carry the signal */
--sp-state-hidden-text: #6b7280;
--sp-state-hidden-border: #6b7280;
--sp-state-hidden-bg: rgba(107, 114, 128, 0.10);
/* self-muted — Self / player's own choice */
/* ✅ WCAG AA safe */
--sp-state-self-muted-text: #8b92a5;
--sp-state-self-muted-border: #8b92a5;
--sp-state-self-muted-bg: rgba(139, 146, 165, 0.10);
/* offline — Technical / disconnected */
/* ⚠️ Low contrast (~2.4:1) — icon + no-ring shape carry the signal */
--sp-state-offline-text: #4b5563;
--sp-state-offline-border: #4b5563;
--sp-state-offline-bg: rgba(75, 85, 99, 0.08);
/* cam-lost — Technical / camera failure */
/* ✅ WCAG AA safe */
--sp-state-cam-lost-text: #9ca3af;
--sp-state-cam-lost-border: #9ca3af;
--sp-state-cam-lost-bg: rgba(156, 163, 175, 0.10);
/* reconnecting — Technical / in-progress */
/* ✅ WCAG AA safe */
--sp-state-reconnecting-text: #c8982a;
--sp-state-reconnecting-border: #c8982a;
--sp-state-reconnecting-bg: rgba(200, 152, 42, 0.12);
/* never-connected — Passive / never joined */
/* ⚠️ Low contrast (~1.76:1) — empty circle + no icon carries the signal */
--sp-state-never-connected-text: #374151;
--sp-state-never-connected-border: #374151;
--sp-state-never-connected-bg: rgba(55, 65, 81, 0.06);
/* ghost — Passive / placeholder slot */
/* ⚠️ Very low contrast (~1.24:1) — ghost icon + dotted ring, lowest opacity */
--sp-state-ghost-text: #1f2937;
--sp-state-ghost-border: #1f2937;
--sp-state-ghost-bg: rgba(31, 41, 55, 0.04);
/* pending — Optimistic UI in-flight (transient; never persisted) */
--sp-state-pending-text: #7a8390;
--sp-state-pending-border: #7a8390;
--sp-state-pending-bg: rgba(122, 131, 144, 0.10);
}
/* ─── Font Awesome icon codepoints (used in component CSS via content: "\f...") ── */
/*
active: '\f06e' (eye)
hidden: '\f070' (eye-slash)
self-muted: '\f131' (microphone-slash)
offline: '\f00d' (times / user-slash)
cam-lost: '\f03d' (video-slash / film)
reconnecting: '\f021' (sync/spinner)
never-connected: '\f068' (minus / em-dash)
ghost: '\f2be' (ghost / user-secret)
pending: '\f110' (spinner)
*/
/* ─── State ring shape variants (applied via sp-state-ring--* modifier) ──── */
/*
solid → active, self-muted
dashed → hidden, cam-lost
pulse → reconnecting, pending (animation in _motion.less)
dotted → ghost
none → offline, never-connected
*/