@zambon-dev/ui 1.0.0 → 1.1.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/CHANGELOG.md +173 -0
- package/fesm2022/zambon-dev-ui-framework.mjs +65 -13
- package/fesm2022/zambon-dev-ui-framework.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui-library.mjs +250 -34
- package/fesm2022/zambon-dev-ui-library.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui-shared.mjs +304 -51
- package/fesm2022/zambon-dev-ui-shared.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui.mjs +3 -0
- package/i18n/shared/login/en.json +2 -0
- package/i18n/shared/login/pt.json +2 -0
- package/i18n/shared/top-bar/en.json +3 -0
- package/i18n/shared/top-bar/pt.json +3 -0
- package/package.json +1 -1
- package/styles/common.scss +0 -1
- package/styles/components/card.scss +9 -3
- package/styles/components/dropdown-static.scss +15 -17
- package/styles/components/input-group.scss +7 -3
- package/styles/components/input.scss +38 -17
- package/styles/components/label.scss +4 -1
- package/styles/theme.css +232 -0
- package/styles/variables.scss +79 -53
- package/types/zambon-dev-ui-framework.d.ts +15 -4
- package/types/zambon-dev-ui-library.d.ts +83 -1
- package/types/zambon-dev-ui-shared.d.ts +68 -1
- package/types/zambon-dev-ui.d.ts +4 -1
- package/styles/components/button.scss +0 -101
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { ButtonComponent as LibButtonComponent } from "@zambon-dev/ui/library";
|
|
2
|
+
import { ButtonComponent } from "@zambon-dev/ui/framework";
|
|
1
3
|
export * from "@zambon-dev/ui/library";
|
|
2
4
|
export * from "@zambon-dev/ui/framework";
|
|
3
5
|
export * from "@zambon-dev/ui/shared";
|
|
6
|
+
export { ButtonComponent, LibButtonComponent };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"Login-Copyright": "© All rights reserved.",
|
|
2
3
|
"Login-DesignBy": "Design by Ricardo Zambon",
|
|
3
4
|
"Login-Errors-InternalServerError": "Occurred some error with the server, please try again.",
|
|
4
5
|
"Login-Errors-Invalid": "The username or password you entered is incorrect.",
|
|
@@ -7,6 +8,7 @@
|
|
|
7
8
|
"Login-RememberMe": "Remember me",
|
|
8
9
|
"Login-SelectLanguage": "Select language",
|
|
9
10
|
"Login-SignIn": "Sign In",
|
|
11
|
+
"Login-Title": "Welcome back",
|
|
10
12
|
"Login-Username-Required": "Please enter the username",
|
|
11
13
|
"Login-Username": "Type your username",
|
|
12
14
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"Login-Copyright": "© Todos os direitos reservados.",
|
|
2
3
|
"Login-DesignBy": "Design por Ricardo Zambon",
|
|
3
4
|
"Login-Errors-InternalServerError": "Ocorreu algum erro no servidor, por favor tente novamente.",
|
|
4
5
|
"Login-Errors-Invalid": "O usuário ou senha informados são inválidos",
|
|
@@ -7,6 +8,7 @@
|
|
|
7
8
|
"Login-RememberMe": "Lembrar de mim",
|
|
8
9
|
"Login-SelectLanguage": "Selecionar idioma",
|
|
9
10
|
"Login-SignIn": "Entrar",
|
|
11
|
+
"Login-Title": "Bem-vindo de volta",
|
|
10
12
|
"Login-Username-Required": "Por favor informe o usuário",
|
|
11
13
|
"Login-Username": "Digite o seu usuário",
|
|
12
14
|
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"TopBar-Notifications-Title": "Notifications",
|
|
3
3
|
"TopBar-Notifications-Empty": "No notifications",
|
|
4
4
|
"TopBar-Notifications-MarkAllRead": "Mark all as read",
|
|
5
|
+
"TopBar-Theme-Light": "Light theme",
|
|
6
|
+
"TopBar-Theme-Dark": "Dark theme",
|
|
7
|
+
"TopBar-Theme-System": "Theme follows the system",
|
|
5
8
|
|
|
6
9
|
"": ""
|
|
7
10
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"TopBar-Notifications-Title": "Notificações",
|
|
3
3
|
"TopBar-Notifications-Empty": "Nenhuma notificação",
|
|
4
4
|
"TopBar-Notifications-MarkAllRead": "Marcar todas como lidas",
|
|
5
|
+
"TopBar-Theme-Light": "Tema claro",
|
|
6
|
+
"TopBar-Theme-Dark": "Tema escuro",
|
|
7
|
+
"TopBar-Theme-System": "Tema acompanha o sistema",
|
|
5
8
|
|
|
6
9
|
"": ""
|
|
7
10
|
}
|
package/package.json
CHANGED
package/styles/common.scss
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
.card {
|
|
2
|
-
@apply border
|
|
3
|
-
@apply bg-white/80 border-gray-300/90;
|
|
2
|
+
@apply border relative mt-4 pt-3 px-2 pb-2;
|
|
4
3
|
@apply grid gap-3;
|
|
4
|
+
border-radius: var(--radius-control);
|
|
5
|
+
background-color: var(--color-surface-solid);
|
|
6
|
+
border-color: var(--color-line);
|
|
5
7
|
|
|
6
8
|
.title {
|
|
7
|
-
@apply
|
|
9
|
+
@apply absolute -top-4 left-2 px-2;
|
|
10
|
+
font-size: var(--text-title);
|
|
11
|
+
font-weight: var(--font-weight-emphasis);
|
|
12
|
+
background-color: var(--color-surface-solid);
|
|
13
|
+
color: var(--color-content-primary);
|
|
8
14
|
}
|
|
9
15
|
|
|
10
16
|
.input-group:not(:first-child) {
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
.dropdown {
|
|
2
2
|
@apply relative;
|
|
3
3
|
|
|
4
|
-
.btn {
|
|
5
|
-
@apply bg-neutral-600/60 text-white border border-neutral-900/40 backdrop-blur-md;
|
|
6
|
-
|
|
7
|
-
@apply focus:ring-neutral-600/30;
|
|
8
|
-
@apply focus:bg-neutral-600/70 hover:bg-neutral-600/70;
|
|
9
|
-
@apply active:bg-neutral-600/80;
|
|
10
|
-
|
|
11
|
-
&:after {
|
|
12
|
-
@apply content-[''] inline-block ml-1 align-middle;
|
|
13
|
-
@apply border-x-[.3em] border-t-[.3em] border-solid border-x-white/0;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
4
|
&.show ul {
|
|
18
5
|
@apply block;
|
|
19
6
|
}
|
|
@@ -23,13 +10,24 @@
|
|
|
23
10
|
}
|
|
24
11
|
|
|
25
12
|
ul {
|
|
26
|
-
@apply absolute hidden py-1
|
|
27
|
-
|
|
13
|
+
@apply absolute hidden py-1 border;
|
|
14
|
+
border-radius: var(--radius-control);
|
|
15
|
+
border-color: var(--color-line);
|
|
16
|
+
background-color: var(--color-surface-solid);
|
|
17
|
+
box-shadow: var(--shadow-overlay);
|
|
28
18
|
|
|
29
19
|
.dropdown-item {
|
|
30
20
|
@apply block p-2 cursor-pointer whitespace-nowrap select-none;
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
color: var(--color-content-primary);
|
|
22
|
+
|
|
23
|
+
&:hover,
|
|
24
|
+
&:focus-visible {
|
|
25
|
+
background-color: var(--state-hover);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:active {
|
|
29
|
+
background-color: var(--state-pressed);
|
|
30
|
+
}
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
.input-group-text {
|
|
6
6
|
@apply py-1.5 px-3 rounded-l flex flex-row items-center whitespace-nowrap select-none;
|
|
7
|
-
|
|
7
|
+
background-color: var(--color-surface-inset);
|
|
8
|
+
color: var(--color-content-secondary);
|
|
9
|
+
border-color: var(--color-line-strong);
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
input[type='text'].form-input,
|
|
@@ -14,7 +16,8 @@
|
|
|
14
16
|
|
|
15
17
|
&.ng-touched.ng-invalid {
|
|
16
18
|
~ .input-group-text {
|
|
17
|
-
|
|
19
|
+
background-color: var(--color-danger);
|
|
20
|
+
color: var(--color-content-on-accent);
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
}
|
|
@@ -39,6 +42,7 @@
|
|
|
39
42
|
|
|
40
43
|
.validations {
|
|
41
44
|
@apply hidden basis-full mt-1;
|
|
42
|
-
@apply text-
|
|
45
|
+
@apply text-sm;
|
|
46
|
+
color: var(--color-danger);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
.form-input {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
border-color: var(--color-line-strong);
|
|
3
|
+
|
|
4
|
+
&:focus-visible {
|
|
5
|
+
@apply outline-hidden ring-[length:var(--focus-ring-width)];
|
|
6
|
+
--tw-ring-color: var(--color-focus-ring);
|
|
7
|
+
}
|
|
4
8
|
@apply transition-colors transition-shadow;
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
&:invalid {
|
|
11
|
+
border-color: var(--color-danger);
|
|
12
|
+
}
|
|
7
13
|
|
|
8
|
-
|
|
14
|
+
&:disabled {
|
|
15
|
+
background-color: var(--color-surface-inset);
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
&.ng-invalid.ng-touched {
|
|
11
|
-
|
|
19
|
+
border-color: var(--color-danger);
|
|
12
20
|
}
|
|
13
21
|
}
|
|
14
22
|
|
|
@@ -17,11 +25,14 @@ input[type='number'],
|
|
|
17
25
|
input[type='password'],
|
|
18
26
|
textarea {
|
|
19
27
|
&.form-input {
|
|
20
|
-
@apply mt-1 block w-full
|
|
28
|
+
@apply mt-1 block w-full shadow-xs;
|
|
29
|
+
border-radius: var(--radius-field);
|
|
21
30
|
|
|
22
31
|
&.ng-invalid.ng-touched {
|
|
23
32
|
@apply pr-9;
|
|
24
|
-
|
|
33
|
+
&:focus-visible {
|
|
34
|
+
--tw-ring-color: var(--color-danger);
|
|
35
|
+
}
|
|
25
36
|
@apply bg-no-repeat bg-[right_0.5625rem_center] bg-[length:1.125rem_1.125rem];
|
|
26
37
|
background-image: url("data:image/svg+xml,%3csvg class='text-white' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
|
|
27
38
|
}
|
|
@@ -31,12 +42,17 @@ textarea {
|
|
|
31
42
|
input[type='checkbox'].form-input {
|
|
32
43
|
@apply p-0.5 h-5 w-5 rounded-sm relative;
|
|
33
44
|
@apply inline-flex flex-row justify-end;
|
|
34
|
-
@apply appearance-none
|
|
45
|
+
@apply appearance-none;
|
|
46
|
+
background-color: var(--color-surface-solid);
|
|
35
47
|
|
|
36
48
|
@apply disabled:pointer-events-none disabled:opacity-50;
|
|
37
49
|
|
|
38
50
|
&:not(.switch) {
|
|
39
|
-
@apply border-2 shadow-md
|
|
51
|
+
@apply border-2 shadow-md;
|
|
52
|
+
|
|
53
|
+
&:focus-visible {
|
|
54
|
+
@apply shadow-none;
|
|
55
|
+
}
|
|
40
56
|
|
|
41
57
|
&:before {
|
|
42
58
|
@apply content-[''] rounded-sm;
|
|
@@ -47,11 +63,13 @@ input[type='checkbox'].form-input {
|
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
&:checked {
|
|
50
|
-
@apply bg-none
|
|
66
|
+
@apply bg-none;
|
|
67
|
+
background-color: var(--color-accent);
|
|
68
|
+
border-color: var(--color-accent);
|
|
51
69
|
|
|
52
70
|
&:before {
|
|
53
71
|
@apply content-['\f00c'];
|
|
54
|
-
|
|
72
|
+
color: var(--color-content-on-accent);
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
|
|
@@ -68,11 +86,12 @@ input[type='checkbox'].form-input {
|
|
|
68
86
|
|
|
69
87
|
input[type='checkbox'].form-input.switch {
|
|
70
88
|
@apply w-10 rounded-[2rem];
|
|
71
|
-
@apply appearance-none
|
|
89
|
+
@apply appearance-none;
|
|
90
|
+
background-color: var(--color-surface-solid);
|
|
72
91
|
|
|
73
92
|
&:before {
|
|
74
93
|
@apply content-[''] h-full aspect-square rounded-full;
|
|
75
|
-
|
|
94
|
+
background-color: var(--color-content-subtle);
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
&:after {
|
|
@@ -80,16 +99,18 @@ input[type='checkbox'].form-input.switch {
|
|
|
80
99
|
transition: flex-grow 0.15s ease-in-out;
|
|
81
100
|
}
|
|
82
101
|
|
|
83
|
-
&:focus:before {
|
|
84
|
-
|
|
102
|
+
&:focus-visible:before {
|
|
103
|
+
background-color: var(--color-accent);
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
&:checked {
|
|
88
|
-
@apply bg-none
|
|
107
|
+
@apply bg-none;
|
|
108
|
+
background-color: var(--color-accent);
|
|
109
|
+
border-color: var(--color-accent);
|
|
89
110
|
|
|
90
111
|
&:before {
|
|
91
112
|
@apply content-[''];
|
|
92
|
-
|
|
113
|
+
background-color: var(--color-surface-solid);
|
|
93
114
|
}
|
|
94
115
|
|
|
95
116
|
&:after {
|
package/styles/theme.css
CHANGED
|
@@ -30,6 +30,13 @@
|
|
|
30
30
|
|
|
31
31
|
@plugin '@tailwindcss/forms';
|
|
32
32
|
|
|
33
|
+
/*
|
|
34
|
+
* Tailwind's `dark:` has to follow the same switch the tokens do. Left as the default it keys off
|
|
35
|
+
* the operating system, so the one `dark:bg-gray-700` in this repo already fires on a dark OS while
|
|
36
|
+
* nothing else does -- a skeleton that goes dark inside an otherwise light screen.
|
|
37
|
+
*/
|
|
38
|
+
@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));
|
|
39
|
+
|
|
33
40
|
/*
|
|
34
41
|
* Tailwind 4 changed the default border colour from `gray-200` to `currentColor`, so every element
|
|
35
42
|
* with a border and no colour of its own inherits the text colour. Across the Storybooks that was
|
|
@@ -73,3 +80,228 @@
|
|
|
73
80
|
--color-primary-800: #001b2f;
|
|
74
81
|
--color-primary-900: #00070d;
|
|
75
82
|
}
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* ---------------------------------------------------------------------------------------------
|
|
86
|
+
* The semantic core.
|
|
87
|
+
*
|
|
88
|
+
* Everything above this line is Tailwind's own theme: `--color-primary-*` is the raw brand ramp.
|
|
89
|
+
* Everything below names a *job* rather than a value -- a surface, a piece of content, a line, a
|
|
90
|
+
* state -- so that a component asks for the role it needs and a theme decides what that looks
|
|
91
|
+
* like. The component tokens that already shipped (`--sidebar-*`, `--tabs-*`) stay exactly where
|
|
92
|
+
* they are and derive from these; they are the published contract, this is the implementation.
|
|
93
|
+
*
|
|
94
|
+
* Every value here is the one those components already compute today. The core was read out of
|
|
95
|
+
* them, not invented, which is why adopting it changes no pixel.
|
|
96
|
+
*
|
|
97
|
+
* `static` is load-bearing, and not for the reason the `theme(static)` on the import above is.
|
|
98
|
+
* That option covers the theme Tailwind itself imports; a second `@theme` block is pruned on its
|
|
99
|
+
* own terms, and these tokens are referenced from other files, which the pruner cannot see. Built
|
|
100
|
+
* without it, every one of them is dropped and the dark block below is the only thing left --
|
|
101
|
+
* so the light theme resolves to nothing while the dark theme works. Nothing reports this.
|
|
102
|
+
* ---------------------------------------------------------------------------------------------
|
|
103
|
+
*/
|
|
104
|
+
@theme static {
|
|
105
|
+
/*
|
|
106
|
+
* Surfaces name the plane, not the colour. The language is "translucent cards floating over the
|
|
107
|
+
* backdrop", and what separates one level from the next is how much of the backdrop it lets
|
|
108
|
+
* through. The 45/70/88 ladder is the same one the tabs use for rest/hover/active -- not a
|
|
109
|
+
* coincidence, and the reason it lives here: hovering a tab is literally climbing one surface.
|
|
110
|
+
*/
|
|
111
|
+
--color-surface-brand: color-mix(in srgb, var(--color-primary-600) 82%, transparent);
|
|
112
|
+
--color-surface-glass-weak: color-mix(in srgb, white 45%, transparent);
|
|
113
|
+
--color-surface-glass: color-mix(in srgb, white 70%, transparent);
|
|
114
|
+
--color-surface-glass-strong: color-mix(in srgb, white 88%, transparent);
|
|
115
|
+
--color-surface-solid: var(--color-white);
|
|
116
|
+
--color-surface-inset: color-mix(in srgb, var(--color-gray-200) 40%, transparent);
|
|
117
|
+
--color-surface-scrim: color-mix(in srgb, black 50%, transparent);
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* "Content" and not "text": half the consumers are icons, `::before` glyphs and spinners.
|
|
121
|
+
* There is no `-disabled` here because disabled is an opacity on the element everywhere in
|
|
122
|
+
* this repo, never a colour -- see --opacity-disabled.
|
|
123
|
+
*/
|
|
124
|
+
--color-content-primary: var(--color-gray-900);
|
|
125
|
+
--color-content-secondary: var(--color-gray-600);
|
|
126
|
+
--color-content-subtle: var(--color-gray-400);
|
|
127
|
+
--color-content-on-brand: var(--color-gray-100);
|
|
128
|
+
--color-content-on-brand-muted: color-mix(in srgb, var(--color-gray-100) 60%, transparent);
|
|
129
|
+
--color-content-on-accent: var(--color-white);
|
|
130
|
+
|
|
131
|
+
/* "Line" covers border, divider and rule in one word; half of these are 1px pseudo-elements. */
|
|
132
|
+
--color-line: var(--color-gray-200);
|
|
133
|
+
--color-line-strong: color-mix(in srgb, var(--color-gray-400) 90%, transparent);
|
|
134
|
+
--color-line-on-glass: color-mix(in srgb, white 60%, transparent);
|
|
135
|
+
--color-line-on-brand: color-mix(in srgb, white 80%, var(--color-primary-600));
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* "Accent" rather than "primary": `--color-primary-*` is already the raw ramp, so this names the
|
|
139
|
+
* rung we chose. Retuning the brand becomes an edit here instead of a find-and-replace by rung.
|
|
140
|
+
*/
|
|
141
|
+
--color-accent: var(--color-primary-600);
|
|
142
|
+
--color-accent-strong: var(--color-primary-700);
|
|
143
|
+
--color-accent-weak: var(--color-primary-50);
|
|
144
|
+
|
|
145
|
+
/* Focus is its own family because it is the one state that has to survive every theme and every
|
|
146
|
+
surface, and because this repo currently has two generations of it to collapse. */
|
|
147
|
+
--color-focus-ring: var(--color-primary-400);
|
|
148
|
+
|
|
149
|
+
/* Two per role, because each appears exactly two ways: as ink (a validation message, a badge)
|
|
150
|
+
and as a 75% fill (the ribbon button's status). A third variant is a color-mix at the point
|
|
151
|
+
of use. */
|
|
152
|
+
--color-danger: var(--color-red-600);
|
|
153
|
+
--color-danger-surface: color-mix(in srgb, var(--color-red-600) 75%, transparent);
|
|
154
|
+
--color-warning: var(--color-yellow-600);
|
|
155
|
+
--color-warning-surface: color-mix(in srgb, var(--color-yellow-600) 75%, transparent);
|
|
156
|
+
--color-success: var(--color-green-600);
|
|
157
|
+
--color-success-surface: color-mix(in srgb, var(--color-green-600) 75%, transparent);
|
|
158
|
+
--color-info: var(--color-primary-400);
|
|
159
|
+
--color-info-surface: color-mix(in srgb, var(--color-primary-400) 75%, transparent);
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* Shapes, not a t-shirt scale: `sm/md/lg` invites copying a size instead of asking what kind of
|
|
163
|
+
* thing this is. --radius-nested keeps a child's corners parallel to its parent's, which is only
|
|
164
|
+
* true when the inner radius is the outer radius minus the gap between them.
|
|
165
|
+
*/
|
|
166
|
+
--radius-surface: 1.25rem;
|
|
167
|
+
--radius-control: 10px;
|
|
168
|
+
--radius-field: 0.375rem;
|
|
169
|
+
--radius-nested: calc(var(--radius-surface) - 0.5rem - 1px);
|
|
170
|
+
|
|
171
|
+
/* --shadow-overlay is the two-layer pair currently written out by hand in four files. */
|
|
172
|
+
--shadow-float: 0 10px 40px -12px rgb(0 0 0 / 0.25);
|
|
173
|
+
--shadow-float-strong: 0 10px 40px -12px rgb(0 0 0 / 0.45);
|
|
174
|
+
--shadow-overlay: 0 0 4px 0 rgb(0 0 0 / 0.2), 0 3px 20px 0 rgb(0 0 0 / 0.19);
|
|
175
|
+
|
|
176
|
+
/* One value for glass is deliberate: two translucent surfaces only match when the blur beneath
|
|
177
|
+
them matches too. The popover blur exists because a menu shares its plane with nothing. */
|
|
178
|
+
--blur-glass: 16px;
|
|
179
|
+
--blur-popover: 12px;
|
|
180
|
+
|
|
181
|
+
--ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
|
|
182
|
+
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
183
|
+
|
|
184
|
+
/*
|
|
185
|
+
* Roles, not a scale. There is no typographic scale here to preserve -- there are five jobs, and
|
|
186
|
+
* naming them is what stops `text-sm` vs `text-base` from being chosen by feel. These are new
|
|
187
|
+
* names inside Tailwind's `--text-*` namespace; overriding `--text-sm` would move the whole
|
|
188
|
+
* scale. No name may exist in both `--color-*` and `--text-*`, or `text-<name>` turns ambiguous.
|
|
189
|
+
*/
|
|
190
|
+
--text-caption: 0.75rem;
|
|
191
|
+
--text-body: 0.875rem;
|
|
192
|
+
--text-ui: 1rem;
|
|
193
|
+
--text-title: 1.125rem;
|
|
194
|
+
--text-display: 1.5rem;
|
|
195
|
+
--font-weight-ui: 500;
|
|
196
|
+
--font-weight-emphasis: 600;
|
|
197
|
+
--font-weight-strong: 700;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/*
|
|
201
|
+
* The rest of the core. These have no Tailwind namespace to live in -- there is no `--state-*` or
|
|
202
|
+
* `--duration-*` in the framework -- so they are plain custom properties. A declaration in a bare
|
|
203
|
+
* `:root` is never pruned, so they need no help from theme(static).
|
|
204
|
+
*/
|
|
205
|
+
:root {
|
|
206
|
+
/* State is a wash, expressed as a mix rather than a colour, because the established pattern is a
|
|
207
|
+
ladder of opacity over whatever is underneath -- not a different colour per state. */
|
|
208
|
+
--state-hover: color-mix(in srgb, var(--color-gray-900) 6%, transparent);
|
|
209
|
+
--state-pressed: color-mix(in srgb, var(--color-gray-900) 10%, transparent);
|
|
210
|
+
--state-selected: color-mix(in srgb, var(--color-primary-200) 25%, transparent);
|
|
211
|
+
--state-hover-on-brand: color-mix(in srgb, white 12%, transparent);
|
|
212
|
+
--state-selected-on-brand: color-mix(in srgb, white 22%, transparent);
|
|
213
|
+
|
|
214
|
+
--opacity-disabled: 0.6;
|
|
215
|
+
|
|
216
|
+
--focus-ring-width: 2px;
|
|
217
|
+
--focus-ring-offset: 0px;
|
|
218
|
+
|
|
219
|
+
/* Named for how they feel, not what they measure: a `--duration-200` is a number with extra
|
|
220
|
+
steps. Routing every transition through these is what makes the reduced-motion block below a
|
|
221
|
+
single rule instead of an audit. */
|
|
222
|
+
--duration-instant: 120ms;
|
|
223
|
+
--duration-short: 200ms;
|
|
224
|
+
--duration-long: 600ms;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* One rule turns off the 600ms margin/width/rotate transitions across the whole repo, because every
|
|
229
|
+
* transition reads a duration token. This is the return on naming them.
|
|
230
|
+
*/
|
|
231
|
+
@media (prefers-reduced-motion: reduce) {
|
|
232
|
+
:root {
|
|
233
|
+
--duration-instant: 1ms;
|
|
234
|
+
--duration-short: 1ms;
|
|
235
|
+
--duration-long: 1ms;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/*
|
|
240
|
+
* ---------------------------------------------------------------------------------------------
|
|
241
|
+
* The dark theme.
|
|
242
|
+
*
|
|
243
|
+
* An attribute on <html>, not `prefers-color-scheme`. A media query would take the choice away
|
|
244
|
+
* from both sides: a consuming application could not opt out of a dark theme, and a user could not
|
|
245
|
+
* choose light on a dark OS. "Follow the system" is still the behaviour we want, but it is read in
|
|
246
|
+
* TypeScript and written here as `dark` -- so this file holds one block instead of two that have
|
|
247
|
+
* to be kept identical. The CSS never sees "system".
|
|
248
|
+
*
|
|
249
|
+
* Unlayered, so it beats the `@layer theme` block Tailwind emits above without !important.
|
|
250
|
+
*
|
|
251
|
+
* It restates colour and shadow only -- radius, blur, motion and type do not move between themes,
|
|
252
|
+
* and that is verifiable rather than asserted. It touches *only* core tokens, never `--sidebar-*`
|
|
253
|
+
* or `--tabs-*`: an application that overrides one of those keeps its override in both themes
|
|
254
|
+
* without doing anything.
|
|
255
|
+
* ---------------------------------------------------------------------------------------------
|
|
256
|
+
*/
|
|
257
|
+
:root {
|
|
258
|
+
color-scheme: light;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
:root[data-theme='dark'] {
|
|
262
|
+
color-scheme: dark;
|
|
263
|
+
|
|
264
|
+
--app-backdrop: linear-gradient(160deg, var(--color-gray-900) 0%, var(--color-gray-800) 100%);
|
|
265
|
+
|
|
266
|
+
--color-surface-brand: color-mix(in srgb, var(--color-primary-800) 82%, transparent);
|
|
267
|
+
--color-surface-glass-weak: color-mix(in srgb, var(--color-gray-900) 45%, transparent);
|
|
268
|
+
--color-surface-glass: color-mix(in srgb, var(--color-gray-900) 70%, transparent);
|
|
269
|
+
--color-surface-glass-strong: color-mix(in srgb, var(--color-gray-900) 88%, transparent);
|
|
270
|
+
--color-surface-solid: var(--color-gray-900);
|
|
271
|
+
--color-surface-inset: color-mix(in srgb, var(--color-gray-700) 40%, transparent);
|
|
272
|
+
--color-surface-scrim: color-mix(in srgb, black 70%, transparent);
|
|
273
|
+
|
|
274
|
+
--color-content-primary: var(--color-gray-100);
|
|
275
|
+
--color-content-secondary: var(--color-gray-400);
|
|
276
|
+
--color-content-subtle: var(--color-gray-500);
|
|
277
|
+
/* The on-brand pair does not move: the brand surface is dark in both themes. */
|
|
278
|
+
|
|
279
|
+
--color-line: var(--color-gray-700);
|
|
280
|
+
--color-line-strong: var(--color-gray-600);
|
|
281
|
+
--color-line-on-glass: color-mix(in srgb, white 12%, transparent);
|
|
282
|
+
--color-line-on-brand: color-mix(in srgb, white 45%, var(--color-primary-800));
|
|
283
|
+
|
|
284
|
+
--color-accent: var(--color-primary-300);
|
|
285
|
+
--color-accent-strong: var(--color-primary-200);
|
|
286
|
+
--color-accent-weak: color-mix(in srgb, var(--color-primary-300) 18%, transparent);
|
|
287
|
+
--color-focus-ring: var(--color-primary-300);
|
|
288
|
+
|
|
289
|
+
/* The wash inverts from black to white; the on-brand rungs stay white in both themes. */
|
|
290
|
+
--state-hover: color-mix(in srgb, white 8%, transparent);
|
|
291
|
+
--state-pressed: color-mix(in srgb, white 14%, transparent);
|
|
292
|
+
--state-selected: color-mix(in srgb, var(--color-primary-300) 22%, transparent);
|
|
293
|
+
|
|
294
|
+
--color-danger: var(--color-red-400);
|
|
295
|
+
--color-danger-surface: color-mix(in srgb, var(--color-red-400) 75%, transparent);
|
|
296
|
+
--color-warning: var(--color-yellow-400);
|
|
297
|
+
--color-warning-surface: color-mix(in srgb, var(--color-yellow-400) 75%, transparent);
|
|
298
|
+
--color-success: var(--color-green-400);
|
|
299
|
+
--color-success-surface: color-mix(in srgb, var(--color-green-400) 75%, transparent);
|
|
300
|
+
--color-info: var(--color-primary-300);
|
|
301
|
+
--color-info-surface: color-mix(in srgb, var(--color-primary-300) 75%, transparent);
|
|
302
|
+
|
|
303
|
+
/* Shadows carry further on a dark backdrop before they read as depth. */
|
|
304
|
+
--shadow-float: 0 10px 40px -12px rgb(0 0 0 / 0.7);
|
|
305
|
+
--shadow-float-strong: 0 10px 40px -12px rgb(0 0 0 / 0.85);
|
|
306
|
+
--shadow-overlay: 0 0 4px 0 rgb(0 0 0 / 0.5), 0 3px 20px 0 rgb(0 0 0 / 0.6);
|
|
307
|
+
}
|