mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Implement M1.5 visual design foundation: tokens, IBM Plex, theme toggle, chart themes
This commit is contained in:
+116
-35
@@ -1,47 +1,128 @@
|
||||
/*
|
||||
* Design tokens. Borrowed in spirit from Syto: a single source of truth for
|
||||
* colors/spacing/typography, themable by overriding the custom properties on
|
||||
* a [data-theme] root. Concrete values are placeholders pending the design pass.
|
||||
* Design tokens — the settled values from docs/architecture/09-visual-design.md
|
||||
* (ported from visual-specimen.html). A single source of truth for type, spacing,
|
||||
* color, shape, and motion, themed by overriding the role tokens on a
|
||||
* `[data-theme]` root. Components consume these tokens ONLY — never raw hexes.
|
||||
*
|
||||
* Inspired by the IBM Design Language / Carbon (structure borrowed, color free);
|
||||
* Carbon is not a dependency — the values are transcribed. See doc §2 for the
|
||||
* deliberate divergences (square chrome, open accent/theming).
|
||||
*/
|
||||
:root {
|
||||
/* Palette */
|
||||
--color-bg: #ffffff;
|
||||
--color-surface: #f7f7fa;
|
||||
--color-border: #e2e2ea;
|
||||
--color-text: #1a1a2e;
|
||||
--color-text-muted: #6b6b80;
|
||||
--color-accent: #3b5bdb;
|
||||
--color-accent-contrast: #ffffff;
|
||||
|
||||
/* Status */
|
||||
--color-success: #2f9e44;
|
||||
--color-error: #e03131;
|
||||
--color-warning: #f08c00;
|
||||
--color-info: #1971c2;
|
||||
|
||||
/* Typography */
|
||||
--font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
||||
--font-mono: ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, monospace;
|
||||
/* Type — IBM Plex (self-hosted via @fontsource, wired in main.tsx) */
|
||||
--font-sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
--font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, monospace;
|
||||
--font-size-base: 14px;
|
||||
|
||||
/* Spacing scale */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
/* Spacing — 8px base unit (2/4 as sub-steps) */
|
||||
--space-1: 2px;
|
||||
--space-2: 4px;
|
||||
--space-3: 8px;
|
||||
--space-4: 12px;
|
||||
--space-5: 16px;
|
||||
--space-6: 24px;
|
||||
--space-7: 32px;
|
||||
--space-8: 48px;
|
||||
--space-9: 64px;
|
||||
|
||||
/* Shape — square chrome (icons keep their own rounded geometry) */
|
||||
--radius: 0px;
|
||||
--border-width: 1px;
|
||||
|
||||
/* Layout */
|
||||
--header-height: 48px;
|
||||
--radius: 6px;
|
||||
|
||||
/* Motion — productive only; neutralized under prefers-reduced-motion in base.css */
|
||||
--dur-fast: 70ms;
|
||||
--dur-fast-2: 110ms;
|
||||
--dur-moderate: 150ms;
|
||||
--ease: cubic-bezier(0.2, 0, 0.38, 0.9);
|
||||
|
||||
/* Status — color carries meaning only (light defaults; overridden in dark) */
|
||||
--support-error: #da1e28;
|
||||
--support-success: #198038;
|
||||
--support-warning: #f1c21b;
|
||||
--support-info: #0043ce;
|
||||
--on-status: #ffffff;
|
||||
|
||||
/* Focus ring defaults to the accent. */
|
||||
--focus: var(--accent);
|
||||
}
|
||||
|
||||
[data-theme='experimental'] {
|
||||
--color-bg: #16161f;
|
||||
--color-surface: #1f1f2c;
|
||||
--color-border: #2c2c3a;
|
||||
--color-text: #e8e8f0;
|
||||
--color-text-muted: #9a9ab0;
|
||||
--color-accent: #748ffc;
|
||||
--color-accent-contrast: #0b0b12;
|
||||
/* --- Neutral roles: LIGHT theme (Carbon gray ramp) --- */
|
||||
[data-theme='light'] {
|
||||
--bg: #ffffff;
|
||||
--layer-01: #f4f4f4;
|
||||
--layer-02: #e0e0e0;
|
||||
--border: #e0e0e0;
|
||||
--border-strong: #c6c6c6;
|
||||
--text: #161616;
|
||||
--text-secondary: #525252;
|
||||
--text-placeholder: #a8a8a8;
|
||||
}
|
||||
|
||||
/* --- Neutral roles: DARK theme --- */
|
||||
[data-theme='dark'] {
|
||||
--bg: #161616;
|
||||
--layer-01: #262626;
|
||||
--layer-02: #393939;
|
||||
--border: #393939;
|
||||
--border-strong: #525252;
|
||||
--text: #f4f4f4;
|
||||
--text-secondary: #a8a8a8;
|
||||
--text-placeholder: #6f6f6f;
|
||||
--support-error: #fa4d56;
|
||||
--support-success: #42be65;
|
||||
--support-warning: #f1c21b;
|
||||
--support-info: #78a9ff;
|
||||
--on-status: #161616;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accent — the FREE, swappable layer (doc §3.3). Indigo is the default and is
|
||||
* defined on :root / [data-theme='dark'] so `--accent` always resolves even with
|
||||
* no `[data-accent]` attribute. The alternates below are opt-in; an accent
|
||||
* switcher arrives with Settings in M5. Brighter values on the dark canvas keep
|
||||
* accent-on-bg and text-on-accent contrast within AA.
|
||||
*/
|
||||
:root {
|
||||
--accent: #5b54e6;
|
||||
--accent-hover: #4a43d6;
|
||||
--accent-contrast: #ffffff;
|
||||
}
|
||||
[data-theme='dark'] {
|
||||
--accent: #8b85f0;
|
||||
--accent-hover: #a29bf5;
|
||||
--accent-contrast: #161616;
|
||||
}
|
||||
|
||||
[data-accent='teal'] {
|
||||
--accent: #0f766e;
|
||||
--accent-hover: #0c5f59;
|
||||
--accent-contrast: #ffffff;
|
||||
}
|
||||
[data-accent='amber'] {
|
||||
--accent: #b45309;
|
||||
--accent-hover: #92400e;
|
||||
--accent-contrast: #ffffff;
|
||||
}
|
||||
[data-accent='rose'] {
|
||||
--accent: #be123c;
|
||||
--accent-hover: #9f1239;
|
||||
--accent-contrast: #ffffff;
|
||||
}
|
||||
[data-theme='dark'][data-accent='teal'] {
|
||||
--accent: #2dd4bf;
|
||||
--accent-hover: #5eead4;
|
||||
--accent-contrast: #161616;
|
||||
}
|
||||
[data-theme='dark'][data-accent='amber'] {
|
||||
--accent: #fbbf24;
|
||||
--accent-hover: #fcd34d;
|
||||
--accent-contrast: #161616;
|
||||
}
|
||||
[data-theme='dark'][data-accent='rose'] {
|
||||
--accent: #fb7185;
|
||||
--accent-hover: #fda4af;
|
||||
--accent-contrast: #161616;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user