@invana/styling 0.0.31 → 0.0.32
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/README.md +15 -5
- package/package.json +2 -1
- package/src/base.css +20 -2
- package/src/color.ts +80 -0
- package/src/index.css +125 -44
- package/src/theme.css +20 -10
- package/src/themes/default.css +104 -89
- package/src/themes/presets-base.css +1 -1
- package/src/themes/presets.css +20 -20
package/README.md
CHANGED
|
@@ -95,10 +95,16 @@ All colors follow the CSS variable pattern and can be used with TailwindCSS util
|
|
|
95
95
|
|
|
96
96
|
### Border Radius
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
Three dials set every corner; no component takes a radius prop. See the rationale at the top
|
|
99
|
+
of `src/index.css` and try them live in Storybook (`Others/CornerRadius`).
|
|
100
|
+
|
|
101
|
+
| Dial | Class | Draws | Default |
|
|
102
|
+
| --- | --- | --- | --- |
|
|
103
|
+
| `--radius` | `rounded`, `rounded-sm` … `rounded-4xl` (every step reads `--radius`) | tables, rows, boxes inside a card | `0px` |
|
|
104
|
+
| `--radius-surface` | `rounded-surface` | cards, panels, dialogs, popovers, menus, tooltips | `var(--radius)` |
|
|
105
|
+
| `--radius-control` | `rounded-control` | buttons, badges, chips, inputs, selects, tabs, toggles | `4px` |
|
|
106
|
+
|
|
107
|
+
Round objects (avatars, dots, switch thumbs) keep `rounded-full` and follow no dial.
|
|
102
108
|
|
|
103
109
|
### Animations
|
|
104
110
|
|
|
@@ -120,7 +126,11 @@ You can override any variable by defining it after importing:
|
|
|
120
126
|
|
|
121
127
|
@theme {
|
|
122
128
|
--color-primary: hsl(270 100% 50%); /* Override primary color */
|
|
123
|
-
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:root {
|
|
132
|
+
--radius-surface: 6px; /* Round cards, panels and floating surfaces */
|
|
133
|
+
--radius-control: 2px; /* Soften buttons, badges and inputs less */
|
|
124
134
|
}
|
|
125
135
|
```
|
|
126
136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@invana/styling",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "Invana TailwindCSS 4 Design System - Reusable styling configuration",
|
|
5
5
|
"homepage": "https://github.com/invana/design-kit#readme",
|
|
6
6
|
"type": "module",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"./themes": "./src/themes/index.ts",
|
|
34
34
|
"./themes.config": "./src/themes.config.ts",
|
|
35
|
+
"./color": "./src/color.ts",
|
|
35
36
|
"./themes/default": {
|
|
36
37
|
"style": "./src/themes/default.css",
|
|
37
38
|
"default": "./src/themes/default.css"
|
package/src/base.css
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
/* Base styles */
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/*
|
|
3
|
+
* In the base layer, so a border-colour utility (`border-primary`,
|
|
4
|
+
* `border-l-warning`) wins. Unlayered, this rule beat every utility and each
|
|
5
|
+
* coloured border in the kit drew as the plain border.
|
|
6
|
+
*/
|
|
7
|
+
@layer base {
|
|
8
|
+
* {
|
|
9
|
+
border-color: var(--color-border);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* A ring's offset gap is the page, not Tailwind's default white — so a
|
|
14
|
+
* `ring-offset-2` reads as a gap on a dark theme too. A
|
|
15
|
+
* `ring-offset-<colour>` utility still wins.
|
|
16
|
+
*/
|
|
17
|
+
*,
|
|
18
|
+
::before,
|
|
19
|
+
::after {
|
|
20
|
+
--tw-ring-offset-color: var(--color-background);
|
|
21
|
+
}
|
|
4
22
|
}
|
|
5
23
|
|
|
6
24
|
body {
|
package/src/color.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A colour for any string — a node type, a relationship type, a model's name.
|
|
3
|
+
*
|
|
4
|
+
* Every categorical thing that needs a default colour gets one slot of the data
|
|
5
|
+
* palette (`themes/data-palette.css`), chosen by hashing its name. Same string,
|
|
6
|
+
* same slot, always: a type keeps its colour across canvases, lists and reloads,
|
|
7
|
+
* and it does not shift when a sibling is added or the list is re-sorted —
|
|
8
|
+
* colour follows the entity, never its rank.
|
|
9
|
+
*
|
|
10
|
+
* A set can hold more names than the palette has slots; past the eighth, slots
|
|
11
|
+
* repeat. That is admissible only because every use names the thing beside its
|
|
12
|
+
* swatch — colour is never the only carrier of identity.
|
|
13
|
+
*
|
|
14
|
+
* Three rungs, pick the one the surface can take:
|
|
15
|
+
*
|
|
16
|
+
* | Function | Returns | For |
|
|
17
|
+
* |---|---|---|
|
|
18
|
+
* | `colorSlotByString` | `1`…`8` | storing or binding the slot itself |
|
|
19
|
+
* | `colorVarByString` | `var(--color-data-N)` | anything that takes CSS |
|
|
20
|
+
* | `colorByString` | `rgb(…)`, resolved live | a canvas that needs a concrete value |
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** How many slots the data palette defines. */
|
|
24
|
+
export const DATA_PALETTE_SLOTS = 8;
|
|
25
|
+
|
|
26
|
+
/** Neutral stand-in when a slot will not resolve (older styling, no theme yet). */
|
|
27
|
+
const FALLBACK_VAR = '--color-muted-foreground';
|
|
28
|
+
|
|
29
|
+
/** The palette slot (1-based) a string lands in. Empty → slot 1. */
|
|
30
|
+
export function colorSlotByString(value: string | null | undefined): number {
|
|
31
|
+
if (!value) return 1;
|
|
32
|
+
let h = 0;
|
|
33
|
+
for (let i = 0; i < value.length; i++) h = (h * 31 + value.charCodeAt(i)) >>> 0;
|
|
34
|
+
return (h % DATA_PALETTE_SLOTS) + 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The slot's token as a CSS value, with a neutral fallback baked in. */
|
|
38
|
+
export function colorVarByString(value: string | null | undefined): string {
|
|
39
|
+
return `var(--color-data-${colorSlotByString(value)}, var(${FALLBACK_VAR}))`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* Resolved colours, keyed by the root's theme stamp. A canvas asks once per
|
|
44
|
+
* item on every restyle and each probe forces a style recalc, so reads are
|
|
45
|
+
* cached; the theme lives on the root's class and inline style, so a theme or
|
|
46
|
+
* mode switch changes the stamp and the next read re-resolves.
|
|
47
|
+
*/
|
|
48
|
+
let cacheStamp = '';
|
|
49
|
+
const cache = new Map<string, string | undefined>();
|
|
50
|
+
|
|
51
|
+
/** Resolve any CSS colour value to the concrete `rgb(…)` the browser computes. */
|
|
52
|
+
export function resolveCssColor(css: string): string | undefined {
|
|
53
|
+
if (typeof document === 'undefined') return undefined;
|
|
54
|
+
const root = document.documentElement;
|
|
55
|
+
const stamp = `${root.className}|${root.getAttribute('style') ?? ''}`;
|
|
56
|
+
if (stamp !== cacheStamp) {
|
|
57
|
+
cacheStamp = stamp;
|
|
58
|
+
cache.clear();
|
|
59
|
+
}
|
|
60
|
+
if (cache.has(css)) return cache.get(css);
|
|
61
|
+
const probe = document.createElement('span');
|
|
62
|
+
probe.style.color = css;
|
|
63
|
+
probe.style.display = 'none';
|
|
64
|
+
root.appendChild(probe);
|
|
65
|
+
const rgb = getComputedStyle(probe).color || undefined;
|
|
66
|
+
probe.remove();
|
|
67
|
+
cache.set(css, rgb);
|
|
68
|
+
return rgb;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The live colour for a string: `explicit` if given, else its palette slot
|
|
73
|
+
* resolved against the active theme. Falls back to the token string when there
|
|
74
|
+
* is no DOM to resolve against.
|
|
75
|
+
*/
|
|
76
|
+
export function colorByString(value: string | null | undefined, explicit?: string): string {
|
|
77
|
+
if (explicit) return explicit;
|
|
78
|
+
const css = colorVarByString(value);
|
|
79
|
+
return resolveCssColor(css) ?? css;
|
|
80
|
+
}
|
package/src/index.css
CHANGED
|
@@ -141,6 +141,25 @@
|
|
|
141
141
|
--color-card: hsl(0 0% 100%);
|
|
142
142
|
--color-card-foreground: hsl(210 10% 20%);
|
|
143
143
|
|
|
144
|
+
/* What frames the work — app header and footer, side panels, a panel's
|
|
145
|
+
header strip, a table's header — as distinct from the work itself
|
|
146
|
+
(`card`). A theme that sets no chrome of its own gets the point halfway
|
|
147
|
+
from its card to its background, so the layer exists, and recedes, in
|
|
148
|
+
every theme. */
|
|
149
|
+
--color-chrome: color-mix(in srgb, var(--color-card), var(--color-background));
|
|
150
|
+
|
|
151
|
+
/* shadcn's Sidebar names, mapped onto the kit's own: a sidebar is chrome,
|
|
152
|
+
its hover is accent, so it follows every theme rather than carrying a
|
|
153
|
+
palette of its own. */
|
|
154
|
+
--color-sidebar: var(--color-chrome);
|
|
155
|
+
--color-sidebar-foreground: var(--color-card-foreground);
|
|
156
|
+
--color-sidebar-primary: var(--color-primary);
|
|
157
|
+
--color-sidebar-primary-foreground: var(--color-primary-foreground);
|
|
158
|
+
--color-sidebar-accent: var(--color-accent);
|
|
159
|
+
--color-sidebar-accent-foreground: var(--color-accent-foreground);
|
|
160
|
+
--color-sidebar-border: var(--color-border);
|
|
161
|
+
--color-sidebar-ring: var(--color-ring);
|
|
162
|
+
|
|
144
163
|
/* The line between two things on a canvas — a graph edge, a dependency
|
|
145
164
|
arrow, a connector. Deliberately NOT --color-border: a border separates
|
|
146
165
|
surfaces and may go invisible against them, while an edge is content and
|
|
@@ -148,59 +167,97 @@
|
|
|
148
167
|
--color-edge: hsl(210 6% 78%);
|
|
149
168
|
|
|
150
169
|
/* ------------------------------------------------------------------------
|
|
151
|
-
* Border radius —
|
|
170
|
+
* Border radius — three dials, revised 03-10-2026.
|
|
152
171
|
*
|
|
153
|
-
* STRUCTURE
|
|
154
|
-
*
|
|
155
|
-
*
|
|
172
|
+
* STRUCTURE --radius 0 anything that CONTAINS
|
|
173
|
+
* SURFACES --radius-surface --radius cards, panels, anything floating
|
|
174
|
+
* CONTROLS --radius-control 4px anything you PRESS, TYPE INTO
|
|
175
|
+
* or that labels at control height
|
|
176
|
+
* SHAPE rounded-full 999px only where round IS the object
|
|
156
177
|
*
|
|
157
|
-
* Structure:
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
178
|
+
* Structure: tables, ledger rows, boxes inside a card, tab panels, canvas
|
|
179
|
+
* surfaces, diagram nodes — `rounded`, `rounded-sm` …
|
|
180
|
+
* `rounded-4xl`, every step of which reads `--radius`.
|
|
181
|
+
* Surfaces: the frames a block or a screen section sits in — Card (and so
|
|
182
|
+
* PanelContent), PanelBox — and everything that floats over
|
|
183
|
+
* the page: Dialog, AlertDialog, Popover, HoverCard, Tooltip, dropdown and
|
|
184
|
+
* menubar menus, Select's list, Command, the NavigationMenu viewport —
|
|
185
|
+
* `rounded-surface`, which reads `--radius-surface`. It defaults to
|
|
186
|
+
* `--radius`; set it to round the frames while what is inside them stays
|
|
187
|
+
* cut.
|
|
188
|
+
* Controls: buttons, badges, chips, inputs, selects, textareas, menu items,
|
|
189
|
+
* tab triggers, toggles — `rounded-control`, which reads `--radius-control`.
|
|
161
190
|
* Shape: avatars, status dots, spinners, slider thumbs, switch capsules,
|
|
162
|
-
* scrollbar thumbs
|
|
163
|
-
*
|
|
164
|
-
* a pill, and there are no pills.
|
|
191
|
+
* scrollbar thumbs keep `rounded-full` because they are round objects, not
|
|
192
|
+
* rectangles with soft ends. There are no pills.
|
|
165
193
|
*
|
|
166
194
|
* WHY 0 FOR STRUCTURE. The hairline grid is the house component: cells sit
|
|
167
195
|
* on a `bg-border` backdrop separated by `gap-px`, so the "border" is the
|
|
168
196
|
* backdrop showing through a one-pixel gap. Any radius on a cell lets that
|
|
169
197
|
* backdrop through at every corner as a grey notch — radii and hairline
|
|
170
|
-
* grids cannot both win.
|
|
171
|
-
*
|
|
172
|
-
* chip in a row in a panel in a card stacks four of them into mush. Sharp
|
|
173
|
-
* nests at any size.
|
|
198
|
+
* grids cannot both win. Nesting a chip in a row in a panel in a card would
|
|
199
|
+
* also stack radii into mush. Sharp nests at any size.
|
|
174
200
|
*
|
|
175
|
-
* WHY
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
201
|
+
* WHY A RADIUS FOR CONTROLS. The difference between a surface and a thing
|
|
202
|
+
* you press is information. A badge sits with the controls, not the
|
|
203
|
+
* structure, so a Badge beside a Button of the same height draws the same
|
|
204
|
+
* corner.
|
|
179
205
|
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
206
|
+
* ALL THREE ARE DIALS. Tune any on `:root` or per theme
|
|
207
|
+
* (`[data-theme="…"] { --radius-control: 2px }`) and everything on that side
|
|
208
|
+
* follows. The structure scale is flat on purpose: every step draws the same
|
|
209
|
+
* corner, so a `rounded-lg` typed out of habit cannot drift from the rest.
|
|
210
|
+
* A component with no `rounded-*` class follows neither dial — give it one.
|
|
184
211
|
* ---------------------------------------------------------------------- */
|
|
185
212
|
--radius: 0px;
|
|
186
|
-
--radius-
|
|
187
|
-
--radius-
|
|
188
|
-
--radius-
|
|
189
|
-
--radius-
|
|
190
|
-
--radius-
|
|
191
|
-
--radius-
|
|
213
|
+
--radius-xs: var(--radius);
|
|
214
|
+
--radius-sm: var(--radius);
|
|
215
|
+
--radius-md: var(--radius);
|
|
216
|
+
--radius-lg: var(--radius);
|
|
217
|
+
--radius-xl: var(--radius);
|
|
218
|
+
--radius-2xl: var(--radius);
|
|
219
|
+
--radius-3xl: var(--radius);
|
|
220
|
+
--radius-4xl: var(--radius);
|
|
221
|
+
|
|
222
|
+
/* Cards, panels and floating surfaces (dialogs, popovers, menus) point at
|
|
223
|
+
`rounded-surface`. Follows --radius until set on its own. */
|
|
224
|
+
--radius-surface: var(--radius);
|
|
225
|
+
|
|
226
|
+
/* Every control points at `rounded-control`. */
|
|
227
|
+
--radius-control: 4px;
|
|
192
228
|
|
|
193
|
-
/*
|
|
194
|
-
|
|
195
|
-
--radius-control: 2px;
|
|
229
|
+
/* Retained alias of --radius-control. Prefer `rounded-control`. */
|
|
230
|
+
--radius-2px: var(--radius-control);
|
|
196
231
|
|
|
197
|
-
/*
|
|
198
|
-
|
|
199
|
-
|
|
232
|
+
/* ------------------------------------------------------------------------
|
|
233
|
+
* Control heights — one scale, and a size name means one height.
|
|
234
|
+
*
|
|
235
|
+
* xs 22px a badge or an icon button inside a row
|
|
236
|
+
* sm 26px the application control: search, input, select, filter
|
|
237
|
+
* chip, segmented control, tab, toolbar button
|
|
238
|
+
* md 32px a standalone form, a dialog's buttons — `default` sizes
|
|
239
|
+
* lg 40px a page form, a page's primary action
|
|
240
|
+
*
|
|
241
|
+
* Before this, every component picked its own number for each name — a
|
|
242
|
+
* `sm` badge was 22px, a `sm` button 32px, a `sm` input 26px — so two
|
|
243
|
+
* controls of the same size never lined up in a toolbar. Every component
|
|
244
|
+
* with a `size` now maps the name onto these, and nothing else.
|
|
245
|
+
*
|
|
246
|
+
* Spacing tokens, so they generate `h-control-sm`, `min-h-control-sm`,
|
|
247
|
+
* `size-control-sm` and `w-control-sm`. Ratios of the root like the type:
|
|
248
|
+
* the px above are at the 13px application root, and a 16px site gets
|
|
249
|
+
* proportionally taller controls. `cn` registers the names with
|
|
250
|
+
* tailwind-merge, which does not otherwise know them.
|
|
251
|
+
* ---------------------------------------------------------------------- */
|
|
252
|
+
--spacing-control-xs: calc(22rem / 13);
|
|
253
|
+
--spacing-control-sm: calc(26rem / 13);
|
|
254
|
+
--spacing-control-md: calc(32rem / 13);
|
|
255
|
+
--spacing-control-lg: calc(40rem / 13);
|
|
200
256
|
|
|
201
257
|
/* Animations */
|
|
202
258
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
203
259
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
260
|
+
--animate-row-in: row-in 1s ease-out;
|
|
204
261
|
}
|
|
205
262
|
|
|
206
263
|
/*
|
|
@@ -279,12 +336,13 @@
|
|
|
279
336
|
opacity: 0;
|
|
280
337
|
transform: scale(0.9);
|
|
281
338
|
transition: opacity 150ms ease-out, transform 150ms ease-out;
|
|
339
|
+
--hint-color: color-mix(in srgb, var(--color-foreground) 70%, transparent);
|
|
282
340
|
background-repeat: no-repeat;
|
|
283
341
|
background-image:
|
|
284
|
-
linear-gradient(
|
|
285
|
-
linear-gradient(
|
|
286
|
-
linear-gradient(
|
|
287
|
-
linear-gradient(
|
|
342
|
+
linear-gradient(var(--hint-color), var(--hint-color)),
|
|
343
|
+
linear-gradient(var(--hint-color), var(--hint-color)),
|
|
344
|
+
linear-gradient(var(--hint-color), var(--hint-color)),
|
|
345
|
+
linear-gradient(var(--hint-color), var(--hint-color));
|
|
288
346
|
}
|
|
289
347
|
|
|
290
348
|
&::before {
|
|
@@ -300,9 +358,7 @@
|
|
|
300
358
|
&:hover::before,
|
|
301
359
|
&:hover::after,
|
|
302
360
|
&:focus-visible::before,
|
|
303
|
-
&:focus-visible::after
|
|
304
|
-
&:focus-within::before,
|
|
305
|
-
&:focus-within::after {
|
|
361
|
+
&:focus-visible::after {
|
|
306
362
|
opacity: 1;
|
|
307
363
|
transform: scale(1);
|
|
308
364
|
}
|
|
@@ -326,6 +382,13 @@
|
|
|
326
382
|
}
|
|
327
383
|
}
|
|
328
384
|
|
|
385
|
+
/* A row that just streamed in: arrives tinted, fades to its own ground. */
|
|
386
|
+
@keyframes row-in {
|
|
387
|
+
from {
|
|
388
|
+
background-color: color-mix(in srgb, var(--color-primary) 12%, transparent);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
329
392
|
/* Base styles */
|
|
330
393
|
html,
|
|
331
394
|
body {
|
|
@@ -334,8 +397,26 @@ body {
|
|
|
334
397
|
-webkit-font-smoothing: antialiased;
|
|
335
398
|
}
|
|
336
399
|
|
|
337
|
-
|
|
338
|
-
|
|
400
|
+
/*
|
|
401
|
+
* In the base layer, so a border-colour utility (`border-primary`,
|
|
402
|
+
* `border-l-warning`) wins. Unlayered, this rule beat every utility and each
|
|
403
|
+
* coloured border in the kit drew as the plain border.
|
|
404
|
+
*/
|
|
405
|
+
@layer base {
|
|
406
|
+
* {
|
|
407
|
+
border-color: var(--color-border);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/*
|
|
411
|
+
* A ring's offset gap is the page, not Tailwind's default white — so a
|
|
412
|
+
* `ring-offset-2` reads as a gap on a dark theme too. A
|
|
413
|
+
* `ring-offset-<colour>` utility still wins.
|
|
414
|
+
*/
|
|
415
|
+
*,
|
|
416
|
+
::before,
|
|
417
|
+
::after {
|
|
418
|
+
--tw-ring-offset-color: var(--color-background);
|
|
419
|
+
}
|
|
339
420
|
}
|
|
340
421
|
|
|
341
422
|
body {
|
package/src/theme.css
CHANGED
|
@@ -34,21 +34,27 @@
|
|
|
34
34
|
--color-card-foreground: hsl(222.2 84% 4.9%);
|
|
35
35
|
|
|
36
36
|
/* Border Radius — see the full rationale in `index.css`.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
Three dials: structure `--radius` (0, every step below reads it),
|
|
38
|
+
surfaces `--radius-surface` (card-like frames, `rounded-surface`, follows
|
|
39
|
+
--radius) and controls `--radius-control` (4px, `rounded-control`) ·
|
|
40
|
+
round only where
|
|
41
|
+
round IS the object. */
|
|
40
42
|
--radius: 0px;
|
|
41
|
-
--radius-
|
|
42
|
-
--radius-
|
|
43
|
-
--radius-
|
|
44
|
-
--radius-
|
|
45
|
-
--radius-
|
|
46
|
-
--radius-
|
|
47
|
-
--radius-
|
|
43
|
+
--radius-xs: var(--radius);
|
|
44
|
+
--radius-sm: var(--radius);
|
|
45
|
+
--radius-md: var(--radius);
|
|
46
|
+
--radius-lg: var(--radius);
|
|
47
|
+
--radius-xl: var(--radius);
|
|
48
|
+
--radius-2xl: var(--radius);
|
|
49
|
+
--radius-3xl: var(--radius);
|
|
50
|
+
--radius-4xl: var(--radius);
|
|
51
|
+
--radius-surface: var(--radius);
|
|
52
|
+
--radius-control: 4px;
|
|
48
53
|
|
|
49
54
|
/* Animations */
|
|
50
55
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
51
56
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
57
|
+
--animate-row-in: row-in 1s ease-out;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
@keyframes accordion-down {
|
|
@@ -61,6 +67,10 @@
|
|
|
61
67
|
to { height: 0; }
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
@keyframes row-in {
|
|
71
|
+
from { background-color: color-mix(in srgb, var(--color-primary) 12%, transparent); }
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
/* Dark mode */
|
|
65
75
|
@media (prefers-color-scheme: dark) {
|
|
66
76
|
@theme {
|
package/src/themes/default.css
CHANGED
|
@@ -1,63 +1,76 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Default Theme (Invana Brand Colors)
|
|
3
|
-
* Light and dark variants with green accent
|
|
3
|
+
* Light and dark variants with green accent, on a cool slate neutral.
|
|
4
|
+
*
|
|
5
|
+
* Surfaces are three layers, so a shell reads as structure rather than one
|
|
6
|
+
* colour with lines on it:
|
|
7
|
+
* background the canvas behind everything (gutters, resize handles)
|
|
8
|
+
* chrome what frames the work: app header and footer, side panels,
|
|
9
|
+
* a panel's header strip — it recedes
|
|
10
|
+
* card the work itself: the editor, a panel's body — it comes forward
|
|
11
|
+
* popover what floats over all of them: menus, tooltips, popovers —
|
|
12
|
+
* solid, one step past card, with a border and a shadow
|
|
13
|
+
* Dark runs background < chrome < card; light runs background < chrome < card
|
|
14
|
+
* the same way, ending on white. Primary passes 4.5:1 against card in both.
|
|
4
15
|
*/
|
|
5
16
|
|
|
6
17
|
/* Light mode - Default theme */
|
|
7
18
|
[data-theme="default-light"],
|
|
8
19
|
.theme-default-light {
|
|
9
20
|
/* Raw HSL values for opacity modifiers */
|
|
10
|
-
--background:
|
|
11
|
-
--foreground:
|
|
12
|
-
--
|
|
13
|
-
--muted
|
|
14
|
-
--
|
|
15
|
-
--accent
|
|
16
|
-
--
|
|
17
|
-
--popover
|
|
18
|
-
--
|
|
19
|
-
--
|
|
21
|
+
--background: 220 14% 92%;
|
|
22
|
+
--foreground: 220 15% 15%;
|
|
23
|
+
--chrome: 220 16% 96.5%;
|
|
24
|
+
--muted: 220 12% 93%;
|
|
25
|
+
--muted-foreground: 220 9% 42%;
|
|
26
|
+
--accent: 220 12% 91%;
|
|
27
|
+
--accent-foreground: 220 15% 15%;
|
|
28
|
+
--popover: 0 0% 100%;
|
|
29
|
+
--popover-foreground: 220 15% 15%;
|
|
30
|
+
--border: 220 12% 86%;
|
|
31
|
+
--input: 220 12% 86%;
|
|
20
32
|
--card: 0 0% 100%;
|
|
21
|
-
--card-foreground:
|
|
22
|
-
--primary:
|
|
33
|
+
--card-foreground: 220 15% 15%;
|
|
34
|
+
--primary: 152 68% 30%;
|
|
23
35
|
--primary-foreground: 0 0% 100%;
|
|
24
|
-
--secondary:
|
|
25
|
-
--secondary-foreground:
|
|
26
|
-
--destructive: 0
|
|
36
|
+
--secondary: 152 30% 94%;
|
|
37
|
+
--secondary-foreground: 152 40% 26%;
|
|
38
|
+
--destructive: 0 68% 48%;
|
|
27
39
|
--destructive-foreground: 0 0% 100%;
|
|
28
|
-
--ring:
|
|
29
|
-
--success:
|
|
40
|
+
--ring: 152 68% 30%;
|
|
41
|
+
--success: 152 68% 30%;
|
|
30
42
|
--success-foreground: 0 0% 100%;
|
|
31
|
-
--warning: 38 92%
|
|
43
|
+
--warning: 38 92% 38%;
|
|
32
44
|
--warning-foreground: 0 0% 100%;
|
|
33
|
-
--info:
|
|
45
|
+
--info: 212 85% 45%;
|
|
34
46
|
--info-foreground: 0 0% 100%;
|
|
35
47
|
|
|
36
48
|
/* Full HSL colors for direct use */
|
|
37
|
-
--color-background: hsl(
|
|
38
|
-
--color-foreground: hsl(
|
|
49
|
+
--color-background: hsl(220 14% 92%);
|
|
50
|
+
--color-foreground: hsl(220 15% 15%);
|
|
51
|
+
--color-chrome: hsl(220 16% 96.5%);
|
|
52
|
+
--color-muted: hsl(220 12% 93%);
|
|
53
|
+
--color-muted-foreground: hsl(220 9% 42%);
|
|
54
|
+
--color-accent: hsl(220 12% 91%);
|
|
55
|
+
--color-accent-foreground: hsl(220 15% 15%);
|
|
56
|
+
--color-popover: hsl(0 0% 100%);
|
|
57
|
+
--color-popover-foreground: hsl(220 15% 15%);
|
|
58
|
+
--color-border: hsl(220 12% 86%);
|
|
59
|
+
--color-input: hsl(220 12% 86%);
|
|
39
60
|
--color-card: hsl(0 0% 100%);
|
|
40
|
-
--color-card-foreground: hsl(
|
|
41
|
-
--color-
|
|
42
|
-
--color-popover-foreground: hsl(210 10% 20%);
|
|
43
|
-
--color-primary: hsl(142 70% 43%);
|
|
61
|
+
--color-card-foreground: hsl(220 15% 15%);
|
|
62
|
+
--color-primary: hsl(152 68% 30%);
|
|
44
63
|
--color-primary-foreground: hsl(0 0% 100%);
|
|
45
|
-
--color-secondary: hsl(
|
|
46
|
-
--color-secondary-foreground: hsl(
|
|
47
|
-
--color-
|
|
48
|
-
--color-muted-foreground: hsl(210 8% 45%);
|
|
49
|
-
--color-accent: hsl(210 6% 92%);
|
|
50
|
-
--color-accent-foreground: hsl(210 10% 20%);
|
|
51
|
-
--color-destructive: hsl(0 70% 60%);
|
|
64
|
+
--color-secondary: hsl(152 30% 94%);
|
|
65
|
+
--color-secondary-foreground: hsl(152 40% 26%);
|
|
66
|
+
--color-destructive: hsl(0 68% 48%);
|
|
52
67
|
--color-destructive-foreground: hsl(0 0% 100%);
|
|
53
|
-
--color-
|
|
54
|
-
--color-
|
|
55
|
-
--color-ring: hsl(142 70% 43%);
|
|
56
|
-
--color-success: hsl(142 70% 38%);
|
|
68
|
+
--color-ring: hsl(152 68% 30%);
|
|
69
|
+
--color-success: hsl(152 68% 30%);
|
|
57
70
|
--color-success-foreground: hsl(0 0% 100%);
|
|
58
|
-
--color-warning: hsl(38 92%
|
|
71
|
+
--color-warning: hsl(38 92% 38%);
|
|
59
72
|
--color-warning-foreground: hsl(0 0% 100%);
|
|
60
|
-
--color-info: hsl(
|
|
73
|
+
--color-info: hsl(212 85% 45%);
|
|
61
74
|
--color-info-foreground: hsl(0 0% 100%);
|
|
62
75
|
}
|
|
63
76
|
|
|
@@ -65,56 +78,58 @@
|
|
|
65
78
|
[data-theme="default-dark"],
|
|
66
79
|
.theme-default-dark {
|
|
67
80
|
/* Raw HSL values for opacity modifiers */
|
|
68
|
-
--background:
|
|
69
|
-
--foreground:
|
|
70
|
-
--
|
|
71
|
-
--muted
|
|
72
|
-
--
|
|
73
|
-
--accent
|
|
74
|
-
--
|
|
75
|
-
--popover
|
|
76
|
-
--
|
|
77
|
-
--
|
|
78
|
-
--
|
|
79
|
-
--card
|
|
80
|
-
--
|
|
81
|
-
--primary
|
|
82
|
-
--
|
|
83
|
-
--secondary
|
|
84
|
-
--
|
|
85
|
-
--destructive
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--success
|
|
89
|
-
--
|
|
90
|
-
--warning
|
|
91
|
-
--
|
|
92
|
-
--info
|
|
81
|
+
--background: 220 10% 6%;
|
|
82
|
+
--foreground: 220 10% 92%;
|
|
83
|
+
--chrome: 220 9% 9.5%;
|
|
84
|
+
--muted: 220 8% 17%;
|
|
85
|
+
--muted-foreground: 220 8% 64%;
|
|
86
|
+
--accent: 220 8% 20%;
|
|
87
|
+
--accent-foreground: 220 10% 92%;
|
|
88
|
+
--popover: 220 8% 16%;
|
|
89
|
+
--popover-foreground: 220 10% 92%;
|
|
90
|
+
--border: 220 8% 18%;
|
|
91
|
+
--input: 220 8% 21%;
|
|
92
|
+
--card: 220 8% 11%;
|
|
93
|
+
--card-foreground: 220 10% 92%;
|
|
94
|
+
--primary: 152 52% 52%;
|
|
95
|
+
--primary-foreground: 220 10% 6%;
|
|
96
|
+
--secondary: 220 8% 21%;
|
|
97
|
+
--secondary-foreground: 220 10% 92%;
|
|
98
|
+
--destructive: 0 62% 52%;
|
|
99
|
+
--destructive-foreground: 0 0% 98%;
|
|
100
|
+
--ring: 152 52% 52%;
|
|
101
|
+
--success: 152 52% 52%;
|
|
102
|
+
--success-foreground: 220 10% 6%;
|
|
103
|
+
--warning: 42 88% 58%;
|
|
104
|
+
--warning-foreground: 220 10% 6%;
|
|
105
|
+
--info: 212 85% 64%;
|
|
106
|
+
--info-foreground: 220 10% 6%;
|
|
93
107
|
|
|
94
108
|
/* Full HSL colors for direct use */
|
|
95
|
-
--color-background: hsl(
|
|
96
|
-
--color-foreground: hsl(
|
|
97
|
-
--color-
|
|
98
|
-
--color-
|
|
99
|
-
--color-
|
|
100
|
-
--color-
|
|
101
|
-
--color-
|
|
102
|
-
--color-
|
|
103
|
-
--color-
|
|
104
|
-
--color-
|
|
105
|
-
--color-
|
|
106
|
-
--color-
|
|
107
|
-
--color-
|
|
108
|
-
--color-
|
|
109
|
-
--color-
|
|
110
|
-
--color-
|
|
111
|
-
--color-
|
|
112
|
-
--color-
|
|
113
|
-
--color-
|
|
114
|
-
--color-
|
|
115
|
-
--color-success
|
|
116
|
-
--color-
|
|
117
|
-
--color-warning
|
|
118
|
-
--color-
|
|
119
|
-
--color-info
|
|
109
|
+
--color-background: hsl(220 10% 6%);
|
|
110
|
+
--color-foreground: hsl(220 10% 92%);
|
|
111
|
+
--color-chrome: hsl(220 9% 9.5%);
|
|
112
|
+
--color-muted: hsl(220 8% 17%);
|
|
113
|
+
--color-muted-foreground: hsl(220 8% 64%);
|
|
114
|
+
--color-accent: hsl(220 8% 20%);
|
|
115
|
+
--color-accent-foreground: hsl(220 10% 92%);
|
|
116
|
+
--color-popover: hsl(220 8% 16%);
|
|
117
|
+
--color-popover-foreground: hsl(220 10% 92%);
|
|
118
|
+
--color-border: hsl(220 8% 18%);
|
|
119
|
+
--color-input: hsl(220 8% 21%);
|
|
120
|
+
--color-card: hsl(220 8% 11%);
|
|
121
|
+
--color-card-foreground: hsl(220 10% 92%);
|
|
122
|
+
--color-primary: hsl(152 52% 52%);
|
|
123
|
+
--color-primary-foreground: hsl(220 10% 6%);
|
|
124
|
+
--color-secondary: hsl(220 8% 21%);
|
|
125
|
+
--color-secondary-foreground: hsl(220 10% 92%);
|
|
126
|
+
--color-destructive: hsl(0 62% 52%);
|
|
127
|
+
--color-destructive-foreground: hsl(0 0% 98%);
|
|
128
|
+
--color-ring: hsl(152 52% 52%);
|
|
129
|
+
--color-success: hsl(152 52% 52%);
|
|
130
|
+
--color-success-foreground: hsl(220 10% 6%);
|
|
131
|
+
--color-warning: hsl(42 88% 58%);
|
|
132
|
+
--color-warning-foreground: hsl(220 10% 6%);
|
|
133
|
+
--color-info: hsl(212 85% 64%);
|
|
134
|
+
--color-info-foreground: hsl(220 10% 6%);
|
|
120
135
|
}
|
package/src/themes/presets.css
CHANGED
|
@@ -27,12 +27,12 @@ html[data-theme^="minimal-"] {
|
|
|
27
27
|
--background: 0 0% 4%;
|
|
28
28
|
--color-foreground: #eee1d3;
|
|
29
29
|
--foreground: 31 44% 88%;
|
|
30
|
-
--color-card: #
|
|
31
|
-
--card: 0 0%
|
|
30
|
+
--color-card: #171717;
|
|
31
|
+
--card: 0 0% 9%;
|
|
32
32
|
--color-card-foreground: #eee1d3;
|
|
33
33
|
--card-foreground: 31 44% 88%;
|
|
34
|
-
--color-popover: #
|
|
35
|
-
--popover: 0 0%
|
|
34
|
+
--color-popover: #1f1f1f;
|
|
35
|
+
--popover: 0 0% 12%;
|
|
36
36
|
--color-popover-foreground: #eee1d3;
|
|
37
37
|
--popover-foreground: 31 44% 88%;
|
|
38
38
|
--color-muted: #111111;
|
|
@@ -165,12 +165,12 @@ html[data-theme^="minimal-"] {
|
|
|
165
165
|
--background: 216 33% 6%;
|
|
166
166
|
--color-foreground: #ccdeeb;
|
|
167
167
|
--foreground: 205 44% 86%;
|
|
168
|
-
--color-card: #
|
|
169
|
-
--card: 213 26%
|
|
168
|
+
--color-card: #151b23;
|
|
169
|
+
--card: 213 26% 11%;
|
|
170
170
|
--color-card-foreground: #ccdeeb;
|
|
171
171
|
--card-foreground: 205 44% 86%;
|
|
172
|
-
--color-popover: #
|
|
173
|
-
--popover: 210 29%
|
|
172
|
+
--color-popover: #19242e;
|
|
173
|
+
--popover: 210 29% 14%;
|
|
174
174
|
--color-popover-foreground: #ccdeeb;
|
|
175
175
|
--popover-foreground: 205 44% 86%;
|
|
176
176
|
--color-muted: #111820;
|
|
@@ -303,12 +303,12 @@ html[data-theme^="minimal-"] {
|
|
|
303
303
|
--background: 120 23% 5%;
|
|
304
304
|
--color-foreground: #cfe1d4;
|
|
305
305
|
--foreground: 137 23% 85%;
|
|
306
|
-
--color-card: #
|
|
307
|
-
--card: 120 16%
|
|
306
|
+
--color-card: #151e15;
|
|
307
|
+
--card: 120 16% 10%;
|
|
308
308
|
--color-card-foreground: #cfe1d4;
|
|
309
309
|
--card-foreground: 137 23% 85%;
|
|
310
|
-
--color-popover: #
|
|
311
|
-
--popover: 120 17%
|
|
310
|
+
--color-popover: #1c271c;
|
|
311
|
+
--popover: 120 17% 13%;
|
|
312
312
|
--color-popover-foreground: #cfe1d4;
|
|
313
313
|
--popover-foreground: 137 23% 85%;
|
|
314
314
|
--color-muted: #111811;
|
|
@@ -441,12 +441,12 @@ html[data-theme^="minimal-"] {
|
|
|
441
441
|
--background: 0 23% 5%;
|
|
442
442
|
--color-foreground: #ebd2d7;
|
|
443
443
|
--foreground: 348 38% 87%;
|
|
444
|
-
--color-card: #
|
|
445
|
-
--card: 0 13%
|
|
444
|
+
--color-card: #1d1616;
|
|
445
|
+
--card: 0 13% 10%;
|
|
446
446
|
--color-card-foreground: #ebd2d7;
|
|
447
447
|
--card-foreground: 348 38% 87%;
|
|
448
|
-
--color-popover: #
|
|
449
|
-
--popover: 0 17%
|
|
448
|
+
--color-popover: #271c1c;
|
|
449
|
+
--popover: 0 17% 13%;
|
|
450
450
|
--color-popover-foreground: #ebd2d7;
|
|
451
451
|
--popover-foreground: 348 38% 87%;
|
|
452
452
|
--color-muted: #181111;
|
|
@@ -579,12 +579,12 @@ html[data-theme^="minimal-"] {
|
|
|
579
579
|
--background: 220 17% 6%;
|
|
580
580
|
--color-foreground: #d7dce4;
|
|
581
581
|
--foreground: 218 18% 87%;
|
|
582
|
-
--color-card: #
|
|
583
|
-
--card: 222 13%
|
|
582
|
+
--color-card: #181b20;
|
|
583
|
+
--card: 222 13% 11%;
|
|
584
584
|
--color-card-foreground: #d7dce4;
|
|
585
585
|
--card-foreground: 218 18% 87%;
|
|
586
|
-
--color-popover: #
|
|
587
|
-
--popover: 222 15%
|
|
586
|
+
--color-popover: #1e2229;
|
|
587
|
+
--popover: 222 15% 14%;
|
|
588
588
|
--color-popover-foreground: #d7dce4;
|
|
589
589
|
--popover-foreground: 218 18% 87%;
|
|
590
590
|
--color-muted: #16181d;
|