vojo/src/colors.css.ts

245 lines
7.2 KiB
TypeScript

import { createTheme } from '@vanilla-extract/css';
import { color } from 'folds';
// Dawn / Stream-v2 palette — see docs/plans/dm_1x1_redesign.md §1, §6 and
// docs/design/new-direct-messages-design/project/stream-v2-dawn.jsx const DAWN.
//
// Tier mapping vs. the canon (DAWN.{bg2, bg, surface}):
// bg2 #0d0e11 — app/window deepest level. The DM list panel AND the chat
// content area share this tone in the canon (ChatListDawn
// line 130 `<div ... background: DAWN.bg2 ...>` ===
// DawnDesktopV3 line 220 `<WindowFrame bg={DAWN.bg2} ...>`).
// We use it for both `Background.Container` (sidebar / nav
// panels) and `Surface.Container` (room view) so the two big
// areas read as one uniform surface, divided only by a
// 1-pixel line — matches the canon.
// bg #181a20 — raised one notch. In the canon this paints chat bubbles,
// file cards, the composer container. Mapped to
// `SurfaceVariant.Container`.
// surface #21232b — raised two notches. Used for chips, reactions, active /
// hover rows. Mapped to `*.ContainerActive` family.
const darkThemeData = {
Background: {
Container: '#0d0e11',
ContainerHover: '#181a20',
ContainerActive: '#21232b',
ContainerLine: '#1f2228',
OnContainer: '#e6e6e9',
},
Surface: {
Container: '#0d0e11',
ContainerHover: '#181a20',
ContainerActive: '#21232b',
ContainerLine: '#1f2228',
OnContainer: '#e6e6e9',
},
SurfaceVariant: {
Container: '#181a20',
ContainerHover: '#21232b',
ContainerActive: '#2a2d36',
ContainerLine: '#2f3340',
OnContainer: '#e6e6e9',
},
Primary: {
Main: '#9580ff',
MainHover: '#a59cff',
MainActive: '#b0a8ff',
MainLine: '#bcb5ff',
OnMain: '#0c0c0e',
Container: '#3a3260',
ContainerHover: '#443878',
ContainerActive: '#4d3f87',
ContainerLine: '#564796',
OnContainer: '#e0dcff',
},
Secondary: {
Main: '#e6e6e9',
MainHover: '#d6d6d9',
MainActive: '#c6c6c9',
MainLine: '#b6b6b9',
OnMain: '#181a20',
Container: '#21232b',
ContainerHover: '#2a2d36',
ContainerActive: '#34384a',
ContainerLine: '#3a3e54',
OnContainer: '#e6e6e9',
},
Success: {
Main: '#7dd3a8',
MainHover: '#90dcb5',
MainActive: '#9ee0bf',
MainLine: '#abe5c8',
OnMain: '#0e2e1f',
Container: '#1a4a32',
ContainerHover: '#1f5638',
ContainerActive: '#23613f',
ContainerLine: '#286c46',
OnContainer: '#caf2d9',
},
Warning: {
Main: '#d4b88a',
MainHover: '#dabf95',
MainActive: '#dfc59e',
MainLine: '#e3cba8',
OnMain: '#3a2c14',
Container: '#5a4422',
ContainerHover: '#664e27',
ContainerActive: '#71562b',
ContainerLine: '#7c5e30',
OnContainer: '#f3e2c5',
},
Critical: {
Main: '#c08e7b',
MainHover: '#c89a88',
MainActive: '#cea591',
MainLine: '#d4ad9a',
OnMain: '#3a1f17',
Container: '#592e22',
ContainerHover: '#653527',
ContainerActive: '#6f3a2a',
ContainerLine: '#7a402d',
OnContainer: '#f0d4c8',
},
Other: {
FocusRing: 'rgba(149, 128, 255, 0.5)',
Shadow: 'rgba(0, 0, 0, 1)',
Overlay: 'rgba(0, 0, 0, 0.85)',
},
};
export const darkTheme = createTheme(color, darkThemeData);
// Vojo light palette — companion to the Dawn dark theme. Source colors come
// from the user-supplied light design pack:
// sidebarBg #f2f2f7 — Background.Container (DM list, nav panels)
// sidebarSel #e2e2ef — Background.ContainerActive (selected row)
// mainBg #ffffff — Surface.Container (chat content surface)
// bubbleBg #ededf6 — SurfaceVariant.Container (bubbles, composer card)
// inputBg #f2f2f7 — informational; reuses Background.Container
// headerBorder #e8e8f2 — *.ContainerLine (1-pixel seam between panels)
// accent #5b6aff — Primary.Main (badges, focus ring, brand)
// textPrimary #111118 — *.OnContainer
// textSecondary #7878a0 — Secondary.Main (muted body text)
// textMuted #a8a8c0 — Secondary.MainLine (placeholder, captions)
// dot #c4c4d8 — neutral dot for stream rail
// dotAccent #5b6aff — own/accent dot — same as Primary.Main
//
// Unlike dark, Background.Container (`#f2f2f7`) and Surface.Container
// (`#ffffff`) intentionally differ in light: sidebar reads as a tinted panel,
// chat surface reads as the lightest. The 1-pixel seam (`headerBorder`)
// between them maps to `ContainerLine`.
const lightThemeData = {
Background: {
Container: '#f2f2f7',
ContainerHover: '#ededf3',
ContainerActive: '#e2e2ef',
ContainerLine: '#e8e8f2',
OnContainer: '#111118',
},
Surface: {
Container: '#ffffff',
ContainerHover: '#f7f7fb',
ContainerActive: '#ededf6',
ContainerLine: '#e8e8f2',
OnContainer: '#111118',
},
SurfaceVariant: {
Container: '#ededf6',
ContainerHover: '#e2e2ef',
ContainerActive: '#d7d7e4',
// ContainerLine is intentionally lighter than ContainerActive in
// light theme — it's a 1-pixel seam between raised surfaces, not a
// "fully pressed" tier, and the dark theme's monotone progression
// would make the line too prominent on a light background.
ContainerLine: '#dcdce6',
OnContainer: '#111118',
},
Primary: {
Main: '#5b6aff',
MainHover: '#6e7bff',
MainActive: '#8190ff',
MainLine: '#a0acff',
OnMain: '#ffffff',
Container: '#e0e3ff',
ContainerHover: '#d2d7ff',
ContainerActive: '#c3caff',
ContainerLine: '#b3bbff',
OnContainer: '#2a3399',
},
Secondary: {
Main: '#7878a0',
MainHover: '#6b6b92',
MainActive: '#5e5e84',
// MainLine intentionally inverts the Main→MainActive darkening run:
// in light theme it doubles as the muted/placeholder ink (the user-
// supplied `textMuted #a8a8c0`), which has to be lighter than
// Main (#7878a0 = textSecondary) to actually read as muted.
MainLine: '#a8a8c0',
OnMain: '#ffffff',
Container: '#e2e2ef',
ContainerHover: '#d7d7e4',
ContainerActive: '#ccccd9',
ContainerLine: '#c4c4d8',
OnContainer: '#111118',
},
Success: {
Main: '#2ea874',
MainHover: '#34b97f',
MainActive: '#3bc789',
MainLine: '#46d699',
OnMain: '#ffffff',
Container: '#d4f5e3',
ContainerHover: '#c0eed5',
ContainerActive: '#abe6c8',
ContainerLine: '#9adfba',
OnContainer: '#0e3a23',
},
Warning: {
Main: '#c08a36',
MainHover: '#cb953f',
MainActive: '#d4a049',
MainLine: '#dcab57',
OnMain: '#ffffff',
Container: '#fbe9c8',
ContainerHover: '#f9e0b3',
ContainerActive: '#f6d69e',
ContainerLine: '#f3cb8a',
OnContainer: '#553a14',
},
Critical: {
Main: '#c44c3a',
MainHover: '#cf5645',
MainActive: '#d6614f',
MainLine: '#dc6e5b',
OnMain: '#ffffff',
Container: '#fadcd5',
ContainerHover: '#f6cabf',
ContainerActive: '#f3b8ab',
ContainerLine: '#efa898',
OnContainer: '#5a1f17',
},
Other: {
FocusRing: 'rgba(91, 106, 255, 0.5)',
Shadow: 'rgba(17, 17, 24, 0.15)',
Overlay: 'rgba(17, 17, 24, 0.5)',
},
};
export const lightTheme = createTheme(color, lightThemeData);