/* ============================================================================= Otter dark theme tokens Proposal by Christian Sass (csass@binaryranch.com), Binary Ranch. 2026-10-27. Three tiers, one token set. Nothing here filters, inverts or transforms the page, so avatars, screen captures and video keep their exact original colour. Usage: set data-theme on . That is the whole contract. Values in comments are the measured WCAG 2.1 contrast ratio against --ot-canvas unless stated otherwise. ============================================================================= */ /* ---- Midnight: OLED panels and late-night reading ---- */ :root[data-theme="midnight"] { --ot-canvas: #000000; --ot-surface-1: #0B0D10; /* sidebars, nav rails, player bar */ --ot-surface-2: #12151A; /* conversation cards, list rows, panels */ --ot-surface-3: #1A1E24; /* hover, selected row, menus */ --ot-border: #22272E; /* hairlines, card outlines (decorative) */ --ot-border-2: #303740; /* focused input, split-pane divider */ --ot-text: #E8EBEF; /* 17.56:1 on canvas */ --ot-text-2: #A0A8B4; /* 8.75:1 on canvas */ --ot-text-3: #6B7480; /* 4.44:1 on canvas */ --ot-accent: #6FA8FF; /* 8.72:1, links and active nav */ --ot-accent-fill:#6FA8FF; /* solid button / active pill background */ --ot-on-accent: #0A1220; /* 7.78:1 on the fill */ --ot-danger: #FF6B6B; /* 7.57:1 */ --ot-warn: #FFB020; --ot-success: #4ADE80; color-scheme: dark; } /* ---- Dusk: default, mixed lighting ---- */ :root[data-theme="dusk"] { --ot-canvas: #101216; --ot-surface-1: #16191E; /* sidebars, nav rails, player bar */ --ot-surface-2: #1C2027; /* conversation cards, list rows, panels */ --ot-surface-3: #242931; /* hover, selected row, menus */ --ot-border: #2A3038; /* hairlines, card outlines (decorative) */ --ot-border-2: #3A424C; /* focused input, split-pane divider */ --ot-text: #E6E9ED; /* 15.39:1 on canvas */ --ot-text-2: #A6ADB8; /* 8.29:1 on canvas */ --ot-text-3: #737B86; /* 4.38:1 on canvas */ --ot-accent: #7FAEFF; /* 8.39:1, links and active nav */ --ot-accent-fill:#7FAEFF; /* solid button / active pill background */ --ot-on-accent: #0A1220; /* 8.39:1 on the fill */ --ot-danger: #FF7B72; /* 7.43:1 */ --ot-warn: #FFC14D; --ot-success: #5BD98A; color-scheme: dark; } /* ---- Slate: bright rooms and daytime ---- */ :root[data-theme="slate"] { --ot-canvas: #1B1F24; --ot-surface-1: #22272D; /* sidebars, nav rails, player bar */ --ot-surface-2: #282E35; /* conversation cards, list rows, panels */ --ot-surface-3: #30373F; /* hover, selected row, menus */ --ot-border: #363E47; /* hairlines, card outlines (decorative) */ --ot-border-2: #48515C; /* focused input, split-pane divider */ --ot-text: #ECEEF1; /* 14.25:1 on canvas */ --ot-text-2: #B4BAC4; /* 8.49:1 on canvas */ --ot-text-3: #8A919C; /* 5.21:1 on canvas */ --ot-accent: #8FB8FF; /* 8.26:1, links and active nav */ --ot-accent-fill:#8FB8FF; /* solid button / active pill background */ --ot-on-accent: #0A1220; /* 9.34:1 on the fill */ --ot-danger: #FF8A80; /* 7.25:1 */ --ot-warn: #FFCB66; --ot-success: #6FE39B; color-scheme: dark; } /* Opt in to the system preference, defaulting to Dusk. */ @media (prefers-color-scheme: dark) { :root:not([data-theme]) { --ot-canvas: #101216; --ot-surface-1: #16191E; --ot-surface-2: #1C2027; --ot-surface-3: #242931; --ot-border: #2A3038; --ot-border-2: #3A424C; --ot-text: #E6E9ED; --ot-text-2: #A6ADB8; --ot-text-3: #737B86; --ot-accent: #7FAEFF; --ot-accent-fill: #7FAEFF; --ot-on-accent: #0A1220; --ot-danger: #FF7B72; --ot-warn: #FFC14D; --ot-success: #5BD98A; color-scheme: dark; } } /* Reference wiring. Otter's own selectors replace the generic ones; the token names are the part worth keeping. */ [data-theme] body { background: var(--ot-canvas); color: var(--ot-text); } [data-theme] a { color: var(--ot-accent); } [data-theme] ::selection { background: color-mix(in srgb, var(--ot-accent) 30%, transparent); }