@adea-ai/ui 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/appearance.d.ts +245 -0
- package/dist/components/appearance.js +768 -0
- package/dist/components/theme-provider.d.ts +35 -10
- package/dist/components/theme-provider.js +86 -55
- package/dist/components/theme-swatch.d.ts +12 -0
- package/dist/components/theme-swatch.js +66 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/package.json +2 -1
- package/src/components/appearance.ts +1055 -0
- package/src/components/theme-provider.tsx +150 -66
- package/src/components/theme-swatch.tsx +49 -0
- package/src/index.tsx +1 -0
- package/src/styles/conventional-workspace.css +63 -2
- package/src/styles/theme.css +122 -0
|
@@ -9,108 +9,192 @@ import {
|
|
|
9
9
|
type ParentProps,
|
|
10
10
|
} from 'solid-js'
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
import {
|
|
13
|
+
appearanceThemeScript,
|
|
14
|
+
applyAppearanceToDocument,
|
|
15
|
+
DARK_QUERY,
|
|
16
|
+
defaultAppearancePreferences,
|
|
17
|
+
type AppearanceMode,
|
|
18
|
+
type AppearancePreferencesV2,
|
|
19
|
+
type ResolvedAppearance,
|
|
20
|
+
readAppearancePreferences,
|
|
21
|
+
REDUCED_TRANSPARENCY_QUERY,
|
|
22
|
+
resolveAppearanceState,
|
|
23
|
+
writeAppearancePreferences,
|
|
24
|
+
} from './appearance'
|
|
25
|
+
|
|
26
|
+
export type Theme = AppearanceMode
|
|
27
|
+
export type ResolvedTheme = ResolvedAppearance
|
|
28
|
+
|
|
29
|
+
export type { AppearanceMode, AppearancePreferencesV2, ResolvedAppearance } from './appearance'
|
|
14
30
|
|
|
15
31
|
type ThemeContextValue = {
|
|
32
|
+
/** The persisted v2 appearance preferences. */
|
|
33
|
+
preferences: Accessor<AppearancePreferencesV2>
|
|
34
|
+
/** Mode after combining the user choice with the OS report. */
|
|
35
|
+
resolvedMode: Accessor<ResolvedAppearance>
|
|
36
|
+
/** The active theme variant id (`documentElement.dataset.theme`). */
|
|
37
|
+
variantId: Accessor<string>
|
|
38
|
+
/** Surface after reduced-transparency and capability resolution. */
|
|
39
|
+
effectiveSurface: Accessor<'opaque' | 'frosted' | 'translucent'>
|
|
40
|
+
/** True while the OS or the user forces opaque surfaces. */
|
|
41
|
+
reduceTransparencyActive: Accessor<boolean>
|
|
42
|
+
/** Persist a field update immediately (Zeron's `SavePolicy::Immediate`). */
|
|
43
|
+
update: (patch: Partial<AppearancePreferencesV2>) => void
|
|
44
|
+
/** Apply a draft against the visible app without persisting it. */
|
|
45
|
+
preview: (preferences: AppearancePreferencesV2 | undefined) => void
|
|
46
|
+
|
|
47
|
+
/** Legacy single-mode seam (settings toggle and existing consumers). */
|
|
16
48
|
theme: Accessor<Theme>
|
|
17
49
|
resolvedTheme: Accessor<ResolvedTheme>
|
|
18
50
|
setTheme: (theme: Theme) => void
|
|
19
51
|
}
|
|
20
52
|
|
|
21
|
-
const STORAGE_KEY = 'theme'
|
|
22
|
-
const DARK_QUERY = '(prefers-color-scheme: dark)'
|
|
23
|
-
|
|
24
53
|
const ThemeContext = createContext<ThemeContextValue>()
|
|
25
54
|
|
|
26
|
-
function readStoredTheme(): Theme {
|
|
27
|
-
if (typeof window === 'undefined') return 'system'
|
|
28
|
-
try {
|
|
29
|
-
const stored = window.localStorage.getItem(STORAGE_KEY)
|
|
30
|
-
return stored === 'light' || stored === 'dark' || stored === 'system' ? stored : 'system'
|
|
31
|
-
} catch {
|
|
32
|
-
return 'system'
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
55
|
function systemPrefersDark(): boolean {
|
|
37
56
|
return typeof window !== 'undefined' && window.matchMedia(DARK_QUERY).matches
|
|
38
57
|
}
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* frame that carries the change, so a theme switch cannot animate page-wide.
|
|
43
|
-
*/
|
|
44
|
-
function applyTheme(theme: ResolvedTheme, disableTransitionOnChange: boolean): void {
|
|
45
|
-
if (typeof document === 'undefined') return
|
|
46
|
-
|
|
47
|
-
const root = document.documentElement
|
|
48
|
-
let restoreTransitions: (() => void) | undefined
|
|
49
|
-
|
|
50
|
-
if (disableTransitionOnChange) {
|
|
51
|
-
const style = document.createElement('style')
|
|
52
|
-
style.appendChild(document.createTextNode('*{transition:none !important}'))
|
|
53
|
-
document.head.appendChild(style)
|
|
54
|
-
void style.offsetHeight
|
|
55
|
-
restoreTransitions = () => style.remove()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
root.classList.toggle('dark', theme === 'dark')
|
|
59
|
-
root.style.colorScheme = theme
|
|
60
|
-
|
|
61
|
-
if (restoreTransitions) {
|
|
62
|
-
requestAnimationFrame(() => requestAnimationFrame(() => restoreTransitions?.()))
|
|
63
|
-
}
|
|
59
|
+
function systemReducesTransparency(): boolean {
|
|
60
|
+
return typeof window !== 'undefined' && window.matchMedia(REDUCED_TRANSPARENCY_QUERY).matches
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
type ThemeProviderProps = ParentProps<{
|
|
67
64
|
defaultTheme?: Theme
|
|
68
65
|
disableTransitionOnChange?: boolean
|
|
66
|
+
/**
|
|
67
|
+
* Whether the host window can render OS translucency. The web lane keeps
|
|
68
|
+
* the default `false` and renders tokenized frosted surfaces instead of
|
|
69
|
+
* pretending to OS vibrancy.
|
|
70
|
+
*/
|
|
71
|
+
nativeTranslucency?: boolean
|
|
69
72
|
}>
|
|
70
73
|
|
|
71
74
|
/**
|
|
72
|
-
* The shared Solid
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* the
|
|
75
|
+
* The shared Solid appearance provider. It owns the versioned appearance
|
|
76
|
+
* preference (mode, independent light/dark themes, accent, surface) on top of
|
|
77
|
+
* the contract the previous provider exposed to the token layer: a `dark`
|
|
78
|
+
* class on the document element plus a `color-scheme` style, persisted in
|
|
79
|
+
* `localStorage` and defaulting to the system preference. The legacy single
|
|
80
|
+
* `theme` key migrates on read and is never deleted.
|
|
76
81
|
*/
|
|
77
82
|
export function ThemeProvider(props: ThemeProviderProps) {
|
|
78
|
-
const
|
|
83
|
+
const storage = typeof window === 'undefined' ? undefined : window.localStorage
|
|
84
|
+
const stored = readAppearancePreferences(storage)
|
|
85
|
+
// A legacy or default record keeps the historical `defaultTheme` escape
|
|
86
|
+
// hatch meaningful for embedders.
|
|
87
|
+
const initial =
|
|
88
|
+
stored === defaultAppearancePreferences && props.defaultTheme
|
|
89
|
+
? { ...stored, mode: props.defaultTheme }
|
|
90
|
+
: stored
|
|
91
|
+
const [preferences, setPreferences] = createSignal<AppearancePreferencesV2>(initial)
|
|
79
92
|
const [prefersDark, setPrefersDark] = createSignal(systemPrefersDark())
|
|
93
|
+
const [osReducedTransparency, setOsReducedTransparency] = createSignal(
|
|
94
|
+
systemReducesTransparency()
|
|
95
|
+
)
|
|
96
|
+
const nativeTranslucency = () => props.nativeTranslucency ?? false
|
|
80
97
|
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
if (typeof window !== 'undefined') {
|
|
99
|
+
const darkMedia = window.matchMedia(DARK_QUERY)
|
|
100
|
+
const onDarkChange = (event: MediaQueryListEvent) => setPrefersDark(event.matches)
|
|
101
|
+
darkMedia.addEventListener('change', onDarkChange)
|
|
102
|
+
onCleanup(() => darkMedia.removeEventListener('change', onDarkChange))
|
|
103
|
+
|
|
104
|
+
const transparencyMedia = window.matchMedia(REDUCED_TRANSPARENCY_QUERY)
|
|
105
|
+
const onTransparencyChange = (event: MediaQueryListEvent) =>
|
|
106
|
+
setOsReducedTransparency(event.matches)
|
|
107
|
+
transparencyMedia.addEventListener('change', onTransparencyChange)
|
|
108
|
+
onCleanup(() => transparencyMedia.removeEventListener('change', onTransparencyChange))
|
|
85
109
|
}
|
|
86
110
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
111
|
+
const resolvedState = () =>
|
|
112
|
+
resolveAppearanceState(preferences(), {
|
|
113
|
+
systemAppearance: prefersDark() ? 'dark' : 'light',
|
|
114
|
+
osReducedTransparency: osReducedTransparency(),
|
|
115
|
+
nativeTranslucency: nativeTranslucency(),
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const persist = (next: AppearancePreferencesV2) => {
|
|
119
|
+
setPreferences(next)
|
|
120
|
+
writeAppearancePreferences(storage, next)
|
|
92
121
|
}
|
|
93
122
|
|
|
94
123
|
createEffect(() => {
|
|
95
|
-
|
|
124
|
+
applyResolved(resolvedState(), props.disableTransitionOnChange ?? true)
|
|
96
125
|
})
|
|
97
126
|
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
127
|
+
const update = (patch: Partial<AppearancePreferencesV2>) => {
|
|
128
|
+
persist({ ...preferences(), ...patch })
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const preview = (draft: AppearancePreferencesV2 | undefined) => {
|
|
132
|
+
if (!draft) {
|
|
133
|
+
applyResolved(resolvedState(), props.disableTransitionOnChange ?? true)
|
|
134
|
+
return
|
|
104
135
|
}
|
|
136
|
+
applyResolved(
|
|
137
|
+
resolveAppearanceState(draft, {
|
|
138
|
+
systemAppearance: prefersDark() ? 'dark' : 'light',
|
|
139
|
+
osReducedTransparency: osReducedTransparency(),
|
|
140
|
+
nativeTranslucency: nativeTranslucency(),
|
|
141
|
+
}),
|
|
142
|
+
props.disableTransitionOnChange ?? true
|
|
143
|
+
)
|
|
105
144
|
}
|
|
106
145
|
|
|
146
|
+
// Legacy seam: the single `theme` value is the v2 mode.
|
|
147
|
+
const theme = (): Theme => preferences().mode
|
|
148
|
+
const resolvedTheme = (): ResolvedTheme => resolvedState().resolvedMode
|
|
149
|
+
const setTheme = (next: Theme) => update({ mode: next })
|
|
150
|
+
|
|
107
151
|
return (
|
|
108
|
-
<ThemeContext.Provider
|
|
152
|
+
<ThemeContext.Provider
|
|
153
|
+
value={{
|
|
154
|
+
preferences,
|
|
155
|
+
resolvedMode: resolvedTheme,
|
|
156
|
+
variantId: () => resolvedState().variant.id,
|
|
157
|
+
effectiveSurface: () => resolvedState().effectiveSurface,
|
|
158
|
+
reduceTransparencyActive: () => resolvedState().reduceTransparencyActive,
|
|
159
|
+
update,
|
|
160
|
+
preview,
|
|
161
|
+
theme,
|
|
162
|
+
resolvedTheme,
|
|
163
|
+
setTheme,
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
109
166
|
{props.children}
|
|
110
167
|
</ThemeContext.Provider>
|
|
111
168
|
)
|
|
112
169
|
}
|
|
113
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Applies the resolved theme to the document and suppresses transitions for the
|
|
173
|
+
* frame that carries the change, so a theme switch cannot animate page-wide.
|
|
174
|
+
*/
|
|
175
|
+
function applyResolved(
|
|
176
|
+
state: ReturnType<typeof resolveAppearanceState>,
|
|
177
|
+
disableTransitionOnChange: boolean
|
|
178
|
+
): void {
|
|
179
|
+
if (typeof document === 'undefined') return
|
|
180
|
+
|
|
181
|
+
let restoreTransitions: (() => void) | undefined
|
|
182
|
+
|
|
183
|
+
if (disableTransitionOnChange) {
|
|
184
|
+
const style = document.createElement('style')
|
|
185
|
+
style.appendChild(document.createTextNode('*{transition:none !important}'))
|
|
186
|
+
document.head.appendChild(style)
|
|
187
|
+
void style.offsetHeight
|
|
188
|
+
restoreTransitions = () => style.remove()
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
applyAppearanceToDocument(document, state)
|
|
192
|
+
|
|
193
|
+
if (restoreTransitions) {
|
|
194
|
+
requestAnimationFrame(() => requestAnimationFrame(() => restoreTransitions?.()))
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
114
198
|
export function useTheme(): ThemeContextValue {
|
|
115
199
|
const context = useContext(ThemeContext)
|
|
116
200
|
if (!context) {
|
|
@@ -120,11 +204,11 @@ export function useTheme(): ThemeContextValue {
|
|
|
120
204
|
}
|
|
121
205
|
|
|
122
206
|
/**
|
|
123
|
-
* Pre-paint
|
|
124
|
-
* document head, it
|
|
125
|
-
* hydration never shows the
|
|
207
|
+
* Pre-paint appearance restore for server-rendered documents. Rendered in the
|
|
208
|
+
* document head, it resolves the stored (or legacy) preference against the OS
|
|
209
|
+
* and applies the palette before first paint so hydration never shows the
|
|
210
|
+
* wrong theme.
|
|
126
211
|
*/
|
|
127
212
|
export function ThemeScript(): JSX.Element {
|
|
128
|
-
|
|
129
|
-
return <script innerHTML={script} />
|
|
213
|
+
return <script innerHTML={appearanceThemeScript()} />
|
|
130
214
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { For } from 'solid-js'
|
|
2
|
+
|
|
3
|
+
import type { ThemeVariant } from './appearance'
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Preview swatches for the appearance pickers: small role-colored dots so a
|
|
7
|
+
* palette can be previewed without applying it. Colors arrive as runtime
|
|
8
|
+
* token data from the theme manifest, so painting them must inline them —
|
|
9
|
+
* this component is the one sanctioned bridge between token data and the DOM
|
|
10
|
+
* (token data may never become a component color literal).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** The three-dot preview for a theme variant (background, primary, card). */
|
|
14
|
+
export function ThemeSwatch(props: { class?: string; variant: ThemeVariant }) {
|
|
15
|
+
const swatches = () => [
|
|
16
|
+
{ role: 'Background', color: props.variant.colors.background },
|
|
17
|
+
{ role: 'Primary', color: props.variant.colors.primary },
|
|
18
|
+
{ role: 'Card', color: props.variant.colors.card },
|
|
19
|
+
]
|
|
20
|
+
return (
|
|
21
|
+
// Decorative next to the variant name; the dots duplicate information the
|
|
22
|
+
// adjacent text already gives assistive technology.
|
|
23
|
+
<span class={props.class} aria-hidden="true">
|
|
24
|
+
<For each={swatches()}>
|
|
25
|
+
{(swatch) => (
|
|
26
|
+
<span
|
|
27
|
+
class="theme-swatch__dot"
|
|
28
|
+
title={swatch.role}
|
|
29
|
+
// oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
|
|
30
|
+
style={{ 'background-color': swatch.color }}
|
|
31
|
+
/>
|
|
32
|
+
)}
|
|
33
|
+
</For>
|
|
34
|
+
</span>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Single-color swatch (accent presets and custom accents). */
|
|
39
|
+
export function ColorSwatch(props: { class?: string; color: string; label: string }) {
|
|
40
|
+
return (
|
|
41
|
+
<span class={props.class} role="img" aria-label={props.label}>
|
|
42
|
+
<span
|
|
43
|
+
class="theme-swatch__dot"
|
|
44
|
+
// oxlint-disable-next-line no-inline-styles -- dynamic token data, see file docstring
|
|
45
|
+
style={{ 'background-color': props.color }}
|
|
46
|
+
/>
|
|
47
|
+
</span>
|
|
48
|
+
)
|
|
49
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -4,6 +4,7 @@ export { Toggle } from './components/ui/toggle'
|
|
|
4
4
|
export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'
|
|
5
5
|
export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'
|
|
6
6
|
export { ThemeToggle } from './components/theme-toggle'
|
|
7
|
+
export { ColorSwatch, ThemeSwatch } from './components/theme-swatch'
|
|
7
8
|
export {
|
|
8
9
|
ThemeProvider,
|
|
9
10
|
ThemeScript,
|
|
@@ -2063,11 +2063,17 @@
|
|
|
2063
2063
|
padding: 0;
|
|
2064
2064
|
}
|
|
2065
2065
|
.plugins-browser {
|
|
2066
|
-
display:
|
|
2067
|
-
|
|
2066
|
+
display: flex;
|
|
2067
|
+
flex-direction: column;
|
|
2068
2068
|
gap: 0;
|
|
2069
2069
|
min-height: 0;
|
|
2070
2070
|
}
|
|
2071
|
+
.plugins-browser__body {
|
|
2072
|
+
display: flex;
|
|
2073
|
+
flex: 1;
|
|
2074
|
+
flex-direction: column;
|
|
2075
|
+
min-height: 0;
|
|
2076
|
+
}
|
|
2071
2077
|
.plugins-browser__tabs {
|
|
2072
2078
|
align-self: end;
|
|
2073
2079
|
margin: 0.5rem 1.25rem 0;
|
|
@@ -2113,9 +2119,64 @@
|
|
|
2113
2119
|
}
|
|
2114
2120
|
.plugins-browser__list {
|
|
2115
2121
|
min-height: 0;
|
|
2122
|
+
flex: 1;
|
|
2116
2123
|
overflow: auto;
|
|
2117
2124
|
padding: 0.8rem 1.25rem 1.25rem;
|
|
2118
2125
|
}
|
|
2126
|
+
.plugins-navigation {
|
|
2127
|
+
display: flex;
|
|
2128
|
+
flex: 1;
|
|
2129
|
+
flex-direction: column;
|
|
2130
|
+
gap: 0.9rem;
|
|
2131
|
+
min-height: 0;
|
|
2132
|
+
overflow: auto;
|
|
2133
|
+
padding: 0.9rem 1.25rem 1.25rem;
|
|
2134
|
+
}
|
|
2135
|
+
.plugins-navigation__hint {
|
|
2136
|
+
margin: 0;
|
|
2137
|
+
color: var(--cw-muted);
|
|
2138
|
+
font-size: 0.8rem;
|
|
2139
|
+
}
|
|
2140
|
+
.plugins-navigation__list {
|
|
2141
|
+
display: flex;
|
|
2142
|
+
flex-direction: column;
|
|
2143
|
+
gap: 0.4rem;
|
|
2144
|
+
margin: 0;
|
|
2145
|
+
padding: 0;
|
|
2146
|
+
list-style: none;
|
|
2147
|
+
}
|
|
2148
|
+
.plugins-navigation__row {
|
|
2149
|
+
display: flex;
|
|
2150
|
+
align-items: center;
|
|
2151
|
+
justify-content: space-between;
|
|
2152
|
+
gap: 0.75rem;
|
|
2153
|
+
padding: 0.55rem 0.7rem;
|
|
2154
|
+
border: 1px solid var(--cw-border);
|
|
2155
|
+
border-radius: 0.6rem;
|
|
2156
|
+
}
|
|
2157
|
+
.plugins-navigation__label {
|
|
2158
|
+
display: flex;
|
|
2159
|
+
align-items: center;
|
|
2160
|
+
gap: 0.5rem;
|
|
2161
|
+
color: var(--cw-text);
|
|
2162
|
+
font-size: 0.85rem;
|
|
2163
|
+
}
|
|
2164
|
+
.plugins-navigation__name {
|
|
2165
|
+
color: var(--cw-text);
|
|
2166
|
+
}
|
|
2167
|
+
.plugins-navigation__controls {
|
|
2168
|
+
display: flex;
|
|
2169
|
+
align-items: center;
|
|
2170
|
+
gap: 0.2rem;
|
|
2171
|
+
}
|
|
2172
|
+
.plugins-navigation__visibility {
|
|
2173
|
+
display: flex;
|
|
2174
|
+
align-items: center;
|
|
2175
|
+
gap: 0.4rem;
|
|
2176
|
+
margin-left: 0.5rem;
|
|
2177
|
+
color: var(--cw-muted);
|
|
2178
|
+
font-size: 0.78rem;
|
|
2179
|
+
}
|
|
2119
2180
|
.plugins-browser[data-filter-open='true'] .plugins-browser__list {
|
|
2120
2181
|
pointer-events: none;
|
|
2121
2182
|
}
|
package/src/styles/theme.css
CHANGED
|
@@ -72,6 +72,62 @@
|
|
|
72
72
|
--z-dialog: 120;
|
|
73
73
|
--z-menu: 140;
|
|
74
74
|
--z-tooltip: 160;
|
|
75
|
+
/* Surface glass. The appearance provider resolves the effective surface
|
|
76
|
+
(opaque/frosted/translucent) and reduced-transparency policy; these
|
|
77
|
+
declarations are the opaque defaults plus the frost amounts the resolved
|
|
78
|
+
values modulate. */
|
|
79
|
+
--surface-alpha: 1;
|
|
80
|
+
--surface-frost: 0.92;
|
|
81
|
+
--surface-translucent: 0.8;
|
|
82
|
+
/* Terminal roles for the default light variant (xterm ANSI, cursor,
|
|
83
|
+
selection). Non-default variants apply their manifest values inline; the
|
|
84
|
+
terminal consumes the custom properties so a theme switch updates a live
|
|
85
|
+
session without remounting. */
|
|
86
|
+
--terminal-background: #ffffff;
|
|
87
|
+
--terminal-foreground: #1b1f24;
|
|
88
|
+
--terminal-cursor: #24292f;
|
|
89
|
+
--terminal-selection: #b6c7ff;
|
|
90
|
+
--terminal-ansi-black: #1b1f24;
|
|
91
|
+
--terminal-ansi-red: #b91c1c;
|
|
92
|
+
--terminal-ansi-green: #116a2e;
|
|
93
|
+
--terminal-ansi-yellow: #8a5a1b;
|
|
94
|
+
--terminal-ansi-blue: #0b57d0;
|
|
95
|
+
--terminal-ansi-magenta: #a0186f;
|
|
96
|
+
--terminal-ansi-cyan: #0e7490;
|
|
97
|
+
--terminal-ansi-white: #57606a;
|
|
98
|
+
--terminal-ansi-bright-black: #57606a;
|
|
99
|
+
--terminal-ansi-bright-red: #c94d4d;
|
|
100
|
+
--terminal-ansi-bright-green: #1f9d4f;
|
|
101
|
+
--terminal-ansi-bright-yellow: #a9752c;
|
|
102
|
+
--terminal-ansi-bright-blue: #3b82f6;
|
|
103
|
+
--terminal-ansi-bright-magenta: #c04a92;
|
|
104
|
+
--terminal-ansi-bright-cyan: #0891b2;
|
|
105
|
+
--terminal-ansi-bright-white: #24292f;
|
|
106
|
+
/* Editor roles (CodeMirror syntax/diff/search) for the default light
|
|
107
|
+
variant. */
|
|
108
|
+
--editor-keyword: #0b57d0;
|
|
109
|
+
--editor-string: #116a2e;
|
|
110
|
+
--editor-number: #8a5a1b;
|
|
111
|
+
--editor-comment: #57606a;
|
|
112
|
+
--editor-function: #a0186f;
|
|
113
|
+
--editor-variable: #1b1f24;
|
|
114
|
+
--editor-type: #0e7490;
|
|
115
|
+
--editor-tag: #b91c1c;
|
|
116
|
+
--editor-attribute: #8a5a1b;
|
|
117
|
+
--editor-operator: #1b1f24;
|
|
118
|
+
--editor-heading: #1b1f24;
|
|
119
|
+
--editor-link: #0b57d0;
|
|
120
|
+
--editor-diff-add: #116a2e;
|
|
121
|
+
--editor-diff-delete: #b91c1c;
|
|
122
|
+
--editor-diff-hunk: #57606a;
|
|
123
|
+
--editor-search-match: #8a5a1b;
|
|
124
|
+
/* Chart series roles. */
|
|
125
|
+
--chart-1: #0b57d0;
|
|
126
|
+
--chart-2: #116a2e;
|
|
127
|
+
--chart-3: #8a5a1b;
|
|
128
|
+
--chart-4: #a0186f;
|
|
129
|
+
--chart-5: #0e7490;
|
|
130
|
+
--chart-6: #57606a;
|
|
75
131
|
}
|
|
76
132
|
|
|
77
133
|
.dark {
|
|
@@ -94,6 +150,72 @@
|
|
|
94
150
|
--border: oklch(1 0 0 / 10%);
|
|
95
151
|
--input: oklch(1 0 0 / 15%);
|
|
96
152
|
--ring: oklch(0.556 0 0);
|
|
153
|
+
/* Terminal/editor/chart roles for the default dark variant. */
|
|
154
|
+
--terminal-background: #0d1117;
|
|
155
|
+
--terminal-foreground: #e6edf3;
|
|
156
|
+
--terminal-cursor: #e6edf3;
|
|
157
|
+
--terminal-selection: #264f78;
|
|
158
|
+
--terminal-ansi-black: #2f3742;
|
|
159
|
+
--terminal-ansi-red: #ff8183;
|
|
160
|
+
--terminal-ansi-green: #56d364;
|
|
161
|
+
--terminal-ansi-yellow: #e3b341;
|
|
162
|
+
--terminal-ansi-blue: #6ca4f8;
|
|
163
|
+
--terminal-ansi-magenta: #db61a2;
|
|
164
|
+
--terminal-ansi-cyan: #39c5cf;
|
|
165
|
+
--terminal-ansi-white: #d5dde5;
|
|
166
|
+
--terminal-ansi-bright-black: #57606a;
|
|
167
|
+
--terminal-ansi-bright-red: #ff9494;
|
|
168
|
+
--terminal-ansi-bright-green: #79dd8a;
|
|
169
|
+
--terminal-ansi-bright-yellow: #f0c264;
|
|
170
|
+
--terminal-ansi-bright-blue: #8db9ff;
|
|
171
|
+
--terminal-ansi-bright-magenta: #e87cb4;
|
|
172
|
+
--terminal-ansi-bright-cyan: #66d3dc;
|
|
173
|
+
--terminal-ansi-bright-white: #eef2f6;
|
|
174
|
+
--editor-keyword: #6ca4f8;
|
|
175
|
+
--editor-string: #56d364;
|
|
176
|
+
--editor-number: #e3b341;
|
|
177
|
+
--editor-comment: #8b949e;
|
|
178
|
+
--editor-function: #db61a2;
|
|
179
|
+
--editor-variable: #e6edf3;
|
|
180
|
+
--editor-type: #39c5cf;
|
|
181
|
+
--editor-tag: #ff8183;
|
|
182
|
+
--editor-attribute: #e3b341;
|
|
183
|
+
--editor-operator: #e6edf3;
|
|
184
|
+
--editor-heading: #e6edf3;
|
|
185
|
+
--editor-link: #6ca4f8;
|
|
186
|
+
--editor-diff-add: #56d364;
|
|
187
|
+
--editor-diff-delete: #ff8183;
|
|
188
|
+
--editor-diff-hunk: #8b949e;
|
|
189
|
+
--editor-search-match: #e3b341;
|
|
190
|
+
--chart-1: #6ca4f8;
|
|
191
|
+
--chart-2: #56d364;
|
|
192
|
+
--chart-3: #e3b341;
|
|
193
|
+
--chart-4: #db61a2;
|
|
194
|
+
--chart-5: #39c5cf;
|
|
195
|
+
--chart-6: #8b949e;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Surface glass amounts. The provider resolves the effective surface and the
|
|
199
|
+
reduced-transparency policy; this media query is the OS-level backstop so a
|
|
200
|
+
frost amount can never outlive a system Reduce Transparency setting. */
|
|
201
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
202
|
+
:root {
|
|
203
|
+
--surface-alpha: 1;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Appearance picker swatches (see components/theme-swatch.tsx). The dot
|
|
208
|
+
color itself is runtime token data applied by the component. */
|
|
209
|
+
.theme-swatch {
|
|
210
|
+
display: inline-flex;
|
|
211
|
+
gap: 0.25rem;
|
|
212
|
+
}
|
|
213
|
+
.theme-swatch__dot {
|
|
214
|
+
display: inline-block;
|
|
215
|
+
width: 0.875rem;
|
|
216
|
+
height: 0.875rem;
|
|
217
|
+
border-radius: calc(infinity * 1px);
|
|
218
|
+
border: 1px solid var(--border);
|
|
97
219
|
}
|
|
98
220
|
|
|
99
221
|
@layer base {
|