You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/lib/themes/base.ts

526 lines
11 KiB

import {
defineEidosConfig,
extendEidosConfig,
type EidosConfigPatch
} from '../options'
import { STATIC_PRIMITIVES } from '../primitives/static'
import type {
ColorRoleMap,
ColorScales,
EidosConfig,
ShadowScale,
ThemeColorSet
} from '../config-types'
import { THEME_BASE_RECIPE_TOKENS } from '../recipes/base'
import { RADIX_EXTRA_LIGHT_SCALES, RADIX_EXTRA_DARK_SCALES } from './color-scales'
import {
BUILTIN_KEYFRAMES,
BUILTIN_SIGNATURES,
BUILTIN_CSS_PRESETS
} from '../motion/presets/css'
export const THEME_BASE_COLOR_ROLES: ColorRoleMap = {
primary: 'purple',
secondary: 'slate',
// Tertiary is a SATURATED accent — distinct from the near-gray secondary (slate)
// and the gray neutral. Indigo is purple's cool ~60° neighbor (Material 3's
// tertiary-hue rule) and sits in a hue band no intent occupies, so it reads as
// hierarchy, not a signal. (Was `gray` — collided with neutral.)
// RESERVED (2026-06-15 audit): defined + emitted (`--color-tertiary-*`) but no
// component consumes it yet — a deliberate third-hierarchy slot apps/themes can
// reach for. Not dead code; not to be removed.
tertiary: 'indigo',
// `gray-9` (el sólido neutral) es un gris medio: ni blanco ni negro
// contrastan por defecto. El slot `contrast` se fija al step 12 — casi-negro
// en light, casi-blanco en dark — para que el texto sobre el sólido neutral
// supere AA en ambos modos (5.0:1 light / 4.6:1 dark). Ver THEMING_AUDIT P0-2.
neutral: { scale: 'gray', slots: { contrast: '12' } },
affirm: 'teal',
fulfill: 'green',
risk: 'orange',
threat: 'red',
// `plum` (canonical loss) — distinct from primary=purple. (Was `purple`, which
// collided with primary. plum is a graver, more magenta violet.)
loss: 'plum'
}
export const THEME_BASE_LIGHT_COLOR_SCALES: ColorScales = {
gray: {
1: '#fcfcfc',
2: '#f9f9f9',
3: '#f0f0f0',
4: '#e8e8e8',
5: '#e0e0e0',
6: '#d9d9d9',
7: '#cecece',
8: '#bbbbbb',
9: '#8d8d8d',
10: '#838383',
11: '#646464',
12: '#202020'
},
slate: {
1: '#fcfcfd',
2: '#f9f9fb',
3: '#f0f0f3',
4: '#e8e8ec',
5: '#e0e1e6',
6: '#d9d9e0',
7: '#cdced6',
8: '#b9bbc6',
9: '#8b8d98',
10: '#80838d',
11: '#60646c',
12: '#1c2024'
},
blue: {
1: '#fbfdff',
2: '#f4faff',
3: '#e6f4fe',
4: '#d5efff',
5: '#c2e5ff',
6: '#acd8fc',
7: '#8ec8f6',
8: '#5eb1ef',
9: '#0090ff',
10: '#0588f0',
11: '#0d74ce',
12: '#113264'
},
cyan: {
1: '#fafdfe',
2: '#f2fafb',
3: '#def7f9',
4: '#caf1f6',
5: '#b5e9f0',
6: '#9ddde7',
7: '#7dcedc',
8: '#3db9cf',
9: '#00a2c7',
10: '#0797b9',
11: '#107d98',
12: '#0d3c48'
},
teal: {
1: '#fafefd',
2: '#f3fbf9',
3: '#e0f8f3',
4: '#ccf3ea',
5: '#b8eae0',
6: '#a1ded2',
7: '#83cdc1',
8: '#53b9ab',
9: '#12a594',
10: '#0d9b8a',
11: '#008573',
12: '#0d3d38'
},
green: {
1: '#fbfefc',
2: '#f4fbf6',
3: '#e6f6eb',
4: '#d6f1df',
5: '#c4e8d1',
6: '#adddc0',
7: '#8eceaa',
8: '#5bb98b',
9: '#30a46c',
10: '#2b9a66',
11: '#218358',
12: '#193b2d'
},
yellow: {
1: '#fdfdf9',
2: '#fffce8',
3: '#fffbd1',
4: '#fff8bb',
5: '#fef2a4',
6: '#f9e68c',
7: '#efd36c',
8: '#ebbc00',
9: '#f5d90a',
10: '#f7ce00',
11: '#946800',
12: '#35290f'
},
amber: {
1: '#fefdfb',
2: '#fefbe9',
3: '#fff7c2',
4: '#ffee9c',
5: '#fbe577',
6: '#f3d673',
7: '#e9c162',
8: '#e2a336',
9: '#ffc53d',
10: '#ffba18',
11: '#ab6400',
12: '#4f3422'
},
orange: {
1: '#fefcfb',
2: '#fff7ed',
3: '#ffefd6',
4: '#ffdfb5',
5: '#ffd19a',
6: '#ffc182',
7: '#f5ae73',
8: '#ec9455',
9: '#f76b15',
10: '#ef5f00',
11: '#cc4e00',
12: '#582d1d'
},
red: {
1: '#fffcfc',
2: '#fff7f7',
3: '#feebec',
4: '#ffdbdc',
5: '#ffcdce',
6: '#fdbdbe',
7: '#f4a9aa',
8: '#eb8e90',
9: '#e5484d',
10: '#dc3e42',
11: '#ce2c31',
12: '#641723'
},
pink: {
1: '#fffcfe',
2: '#fff7fc',
3: '#feeef8',
4: '#fce5f3',
5: '#f9d8ec',
6: '#f3c6e2',
7: '#ecadd4',
8: '#e38ec3',
9: '#d6409f',
10: '#d23197',
11: '#cd1d8d',
12: '#651249'
},
purple: {
1: '#fefcfe',
2: '#fbf7fe',
3: '#f7edfe',
4: '#f2e2fc',
5: '#ead5f9',
6: '#e0c4f4',
7: '#d1afec',
8: '#be93e4',
9: '#8e4ec6',
10: '#8347b9',
11: '#8145b5',
12: '#402060'
},
...RADIX_EXTRA_LIGHT_SCALES
}
export const THEME_BASE_DARK_COLOR_SCALES: ColorScales = {
gray: {
1: '#111111',
2: '#191919',
3: '#222222',
4: '#2a2a2a',
5: '#313131',
6: '#3a3a3a',
7: '#484848',
8: '#606060',
9: '#6e6e6e',
10: '#7b7b7b',
11: '#b4b4b4',
12: '#eeeeee'
},
slate: {
1: '#111113',
2: '#18191b',
3: '#212225',
4: '#272a2d',
5: '#2e3135',
6: '#363a3f',
7: '#43484e',
8: '#5a6169',
9: '#696e77',
10: '#777b84',
11: '#b0b4ba',
12: '#edeef0'
},
blue: {
1: '#0d1520',
2: '#111927',
3: '#0d2847',
4: '#003362',
5: '#004074',
6: '#104d87',
7: '#205d9e',
8: '#2870bd',
9: '#0090ff',
10: '#3b9eff',
11: '#70b8ff',
12: '#c2e6ff'
},
cyan: {
1: '#0b161a',
2: '#101b20',
3: '#082c36',
4: '#003848',
5: '#004558',
6: '#045468',
7: '#12677e',
8: '#11809c',
9: '#00a2c7',
10: '#23afd0',
11: '#4ccce6',
12: '#b6ecf7'
},
teal: {
1: '#0d1514',
2: '#111c1b',
3: '#0d2d2a',
4: '#023b37',
5: '#084843',
6: '#145750',
7: '#1c6961',
8: '#207e73',
9: '#12a594',
10: '#0eb39e',
11: '#0bd8b6',
12: '#adf0dd'
},
green: {
1: '#0e1512',
2: '#121b17',
3: '#132d21',
4: '#113b29',
5: '#174933',
6: '#20573e',
7: '#28684a',
8: '#2f7c57',
9: '#30a46c',
10: '#33b074',
11: '#3dd68c',
12: '#b1f1cb'
},
yellow: {
1: '#14120b',
2: '#1b180f',
3: '#2d2305',
4: '#362b00',
5: '#433500',
6: '#524202',
7: '#665417',
8: '#836a21',
9: '#ffe629',
10: '#ffff57',
11: '#f5e147',
12: '#f6eeb4'
},
amber: {
1: '#16120c',
2: '#1d180f',
3: '#302008',
4: '#3f2700',
5: '#4d3000',
6: '#5c3d05',
7: '#714f19',
8: '#8f6424',
9: '#ffc53d',
10: '#ffd60a',
11: '#ffca16',
12: '#ffe7b3'
},
orange: {
1: '#17120e',
2: '#1e160f',
3: '#331e0b',
4: '#462100',
5: '#562800',
6: '#66350c',
7: '#7e451d',
8: '#a35829',
9: '#f76b15',
10: '#ff801f',
11: '#ffa057',
12: '#ffe0c2'
},
red: {
1: '#191111',
2: '#201314',
3: '#3b1219',
4: '#500f1c',
5: '#611623',
6: '#72232d',
7: '#8c333a',
8: '#b54548',
9: '#e5484d',
10: '#ec5d5e',
11: '#ff9592',
12: '#ffd1d9'
},
pink: {
1: '#191117',
2: '#21121d',
3: '#37172f',
4: '#4b143d',
5: '#591c47',
6: '#692955',
7: '#833869',
8: '#a84885',
9: '#d6409f',
10: '#de51a8',
11: '#ff8dcc',
12: '#fdd1ea'
},
purple: {
1: '#18111b',
2: '#1e1523',
3: '#301c3b',
4: '#3d224e',
5: '#48295c',
6: '#54346b',
7: '#664282',
8: '#8457aa',
9: '#8e4ec6',
10: '#9a5cd0',
11: '#d19dff',
12: '#ecd9fa'
},
...RADIX_EXTRA_DARK_SCALES
}
export const THEME_BASE_LIGHT_COLOR_SEMANTICS: Pick<
ThemeColorSet,
'surface' | 'content' | 'border' | 'focus'
> = {
surface: {
default: 'var(--primitive-neutral-1)',
raised: 'var(--primitive-neutral-2)',
// overlay sits ABOVE muted (consistent ladder default<raised<muted<overlay,
// matching dark). Was neutral-3 == muted, so popovers/menus were
// indistinguishable from muted panels in light mode.
overlay: 'var(--primitive-neutral-4)',
muted: 'var(--primitive-neutral-3)',
backdrop: 'rgb(28 25 23 / 0.42)'
},
content: {
primary: 'var(--primitive-neutral-12)',
secondary: 'var(--primitive-neutral-11)',
muted: 'var(--primitive-neutral-10)',
disabled: 'var(--primitive-neutral-8)',
onSolid: '#ffffff',
onSolidContrast: '#1c1917'
},
border: {
subtle: 'var(--primitive-neutral-4)',
default: 'var(--primitive-neutral-6)',
strong: 'var(--primitive-neutral-8)'
},
focus: {
ring: 'color-mix(in srgb, var(--primitive-primary-8) 48%, transparent)',
ringError: 'color-mix(in srgb, var(--primitive-risk-8) 52%, transparent)'
}
}
export const THEME_BASE_DARK_COLOR_SEMANTICS: Pick<
ThemeColorSet,
'surface' | 'content' | 'border' | 'focus'
> = {
surface: {
default: 'var(--primitive-neutral-1)',
raised: 'var(--primitive-neutral-2)',
overlay: 'var(--primitive-neutral-4)',
muted: 'var(--primitive-neutral-3)',
backdrop: 'rgb(0 0 0 / 0.66)'
},
content: {
primary: 'var(--primitive-neutral-12)',
secondary: 'var(--primitive-neutral-11)',
muted: 'var(--primitive-neutral-10)',
disabled: 'var(--primitive-neutral-8)',
onSolid: '#ffffff',
onSolidContrast: '#1c1917'
},
border: {
subtle: 'var(--primitive-neutral-4)',
default: 'var(--primitive-neutral-6)',
strong: 'var(--primitive-neutral-8)'
},
focus: {
ring: 'color-mix(in srgb, var(--primitive-primary-8) 52%, transparent)',
ringError: 'color-mix(in srgb, var(--primitive-risk-8) 56%, transparent)'
}
}
export const THEME_BASE_LIGHT_SHADOW: ShadowScale = {
none: 'none',
subtle: 'var(--shadow-1)',
raised: 'var(--shadow-3)',
overlay: 'var(--shadow-5)',
'1': '0 1px 2px rgb(15 23 42 / 0.08)',
'2': '0 4px 12px rgb(15 23 42 / 0.10)',
'3': '0 8px 24px rgb(15 23 42 / 0.12)',
'4': '0 14px 36px rgb(15 23 42 / 0.15)',
'5': '0 18px 48px rgb(15 23 42 / 0.18)',
'6': '0 28px 72px rgb(15 23 42 / 0.22)',
// Inner-shadow tier (recessed wells). Same slate base as the drop shadows; soft + inset.
'inset-subtle': 'inset 0 1px 2px rgb(15 23 42 / 0.08)',
'inset-deep': 'inset 0 2px 4px rgb(15 23 42 / 0.12)'
}
export const THEME_BASE_DARK_SHADOW: ShadowScale = {
none: 'none',
subtle: 'var(--shadow-1)',
raised: 'var(--shadow-3)',
overlay: 'var(--shadow-5)',
'1': '0 1px 2px rgb(0 0 0 / 0.28)',
'2': '0 5px 16px rgb(0 0 0 / 0.34)',
'3': '0 10px 30px rgb(0 0 0 / 0.42)',
'4': '0 16px 44px rgb(0 0 0 / 0.48)',
'5': '0 22px 60px rgb(0 0 0 / 0.55)',
'6': '0 34px 88px rgb(0 0 0 / 0.62)',
// Inner-shadow tier (recessed wells). Dark wells read as a darker inset (not a
// light rim) — black base, deeper alpha, mode-correct unlike a contrast-mix.
'inset-subtle': 'inset 0 1px 2px rgb(0 0 0 / 0.30)',
'inset-deep': 'inset 0 2px 4px rgb(0 0 0 / 0.45)'
}
export const THEME_BASE_OPTIONS: EidosConfig = defineEidosConfig({
primitives: STATIC_PRIMITIVES,
semantics: {
color: {
roles: THEME_BASE_COLOR_ROLES
}
},
recipes: THEME_BASE_RECIPE_TOKENS,
motion: {
keyframes: BUILTIN_KEYFRAMES,
signatures: BUILTIN_SIGNATURES,
// CSS presets only — the EidosConfig is serializable (deep-cloned via
// `clonePlain`), and JS presets carry functions (`MotionRun`). The JS
// (`spring`) tier is registered DIRECTLY with the engine in `ActiveEidos`.
presets: BUILTIN_CSS_PRESETS
},
themes: {
'base-light': {
color: {
scales: THEME_BASE_LIGHT_COLOR_SCALES,
...THEME_BASE_LIGHT_COLOR_SEMANTICS
},
shadow: THEME_BASE_LIGHT_SHADOW
},
'base-dark': {
color: {
scales: THEME_BASE_DARK_COLOR_SCALES,
...THEME_BASE_DARK_COLOR_SEMANTICS
},
shadow: THEME_BASE_DARK_SHADOW
}
}
})
export function createThemeBaseEidosConfig(
patch?: EidosConfigPatch
): EidosConfig {
return extendEidosConfig(THEME_BASE_OPTIONS, patch)
}

Powered by TurnKey Linux.